diff --git a/build/examples/examples.test.d.ts b/build/examples/examples.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/examples/examples.test.js b/build/examples/examples.test.js new file mode 100644 index 0000000000..6e24127274 --- /dev/null +++ b/build/examples/examples.test.js @@ -0,0 +1,64 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Ajv = require("ajv"); +var chai_1 = require("chai"); +var compile_1 = require("../src/compile/compile"); +var inspect = require('util').inspect; +var fs = require('fs'); +var path = require('path'); +var vlSchema = require('../../build/vega-lite-schema.json'); +var vgSchema = require('vega/build/vega-schema.json'); +var ajv = new Ajv({ + validateSchema: true, + allErrors: true, + extendRefs: 'fail' +}); +ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'), 'http://json-schema.org/draft-04/schema#'); +var validateVl = ajv.compile(vlSchema); +var validateVg = ajv.compile(vgSchema); +function validateVL(spec) { + var valid = validateVl(spec); + var errors = validateVl.errors; + if (!valid) { + console.log(inspect(errors, { depth: 10, colors: true })); + } + chai_1.assert(valid, errors && errors.map(function (err) { return err.message; }).join(', ')); + chai_1.assert.equal(spec.$schema, 'https://vega.github.io/schema/vega-lite/v2.json'); +} +function validateVega(spec) { + var vegaSpec = compile_1.compile(spec).spec; + var valid = validateVg(vegaSpec); + var errors = validateVg.errors; + if (!valid) { + console.log(inspect(errors, { depth: 10, colors: true })); + } + chai_1.assert(valid, errors && errors.map(function (err) { return err.message; }).join(', ')); +} +var suffixLength = '_future.vl.json'.length; +describe('Examples', function () { + var examples = fs.readdirSync('examples/specs'); + examples.forEach(function (example) { + if (path.extname(example) !== '.json') { + return; + } + var jsonSpec = JSON.parse(fs.readFileSync('examples/specs/' + example)); + describe(example, function () { + it('should be valid vega-lite with proper $schema', function () { + if ( + // Do not validate overlay example until we have redesigned it + example.indexOf('overlay') >= 0 || + // Also ignore box-plot examples until we support selections + example.indexOf('box-plot') >= 0 || + // Also ignore all examples with "_future" suffix + example.lastIndexOf('_future.vl.json', example.length - suffixLength) >= 0) { + return; + } + validateVL(jsonSpec); + }); + it('should produce valid vega', function () { + validateVega(jsonSpec); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhhbXBsZXMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2V4YW1wbGVzL2V4YW1wbGVzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5QkFBMkI7QUFDM0IsNkJBQTRCO0FBQzVCLGtEQUErQztBQUcvQyxJQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDO0FBQ3hDLElBQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6QixJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFN0IsSUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFDOUQsSUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFFeEQsSUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDbEIsY0FBYyxFQUFFLElBQUk7SUFDcEIsU0FBUyxFQUFFLElBQUk7SUFDZixVQUFVLEVBQUUsTUFBTTtDQUNuQixDQUFDLENBQUM7QUFFSCxHQUFHLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyx3Q0FBd0MsQ0FBQyxFQUFFLHlDQUF5QyxDQUFDLENBQUM7QUFFaEgsSUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN6QyxJQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRXpDLG9CQUFvQixJQUEwQjtJQUM1QyxJQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDL0IsSUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztJQUNqQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDWCxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUNELGFBQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBQyxHQUFvQixJQUFLLE9BQUEsR0FBRyxDQUFDLE9BQU8sRUFBWCxDQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUV0RixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaURBQWlELENBQUMsQ0FBQztBQUNoRixDQUFDO0FBRUQsc0JBQXNCLElBQTBCO0lBQzlDLElBQU0sUUFBUSxHQUFHLGlCQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDO0lBRXBDLElBQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxJQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO0lBQ2pDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNYLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBQ0QsYUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFDLEdBQW9CLElBQUssT0FBQSxHQUFHLENBQUMsT0FBTyxFQUFYLENBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hGLENBQUM7QUFFRCxJQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUM7QUFDOUMsUUFBUSxDQUFDLFVBQVUsRUFBRTtJQUNuQixJQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFFbEQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFTLE9BQWU7UUFDdkMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sQ0FBQztRQUNULENBQUM7UUFDRCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUUxRSxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQ2hCLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRTtnQkFDbEQsRUFBRSxDQUFDLENBQUM7Z0JBQ0YsOERBQThEO2dCQUM5RCxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7b0JBQy9CLDREQUE0RDtvQkFDNUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO29CQUNoQyxpREFBaUQ7b0JBQ2pELE9BQU8sQ0FBQyxXQUFXLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsSUFBSSxDQUN6RSxDQUFDLENBQUMsQ0FBQztvQkFDSCxNQUFNLENBQUM7Z0JBQ1QsQ0FBQztnQkFDRCxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkIsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsMkJBQTJCLEVBQUU7Z0JBQzlCLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN6QixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIEFqdiBmcm9tICdhanYnO1xuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtjb21waWxlfSBmcm9tICcuLi9zcmMvY29tcGlsZS9jb21waWxlJztcbmltcG9ydCB7VG9wTGV2ZWxFeHRlbmRlZFNwZWN9IGZyb20gJy4uL3NyYy9zcGVjJztcblxuY29uc3QgaW5zcGVjdCA9IHJlcXVpcmUoJ3V0aWwnKS5pbnNwZWN0O1xuY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuY29uc3QgdmxTY2hlbWEgPSByZXF1aXJlKCcuLi8uLi9idWlsZC92ZWdhLWxpdGUtc2NoZW1hLmpzb24nKTtcbmNvbnN0IHZnU2NoZW1hID0gcmVxdWlyZSgndmVnYS9idWlsZC92ZWdhLXNjaGVtYS5qc29uJyk7XG5cbmNvbnN0IGFqdiA9IG5ldyBBanYoe1xuICB2YWxpZGF0ZVNjaGVtYTogdHJ1ZSxcbiAgYWxsRXJyb3JzOiB0cnVlLFxuICBleHRlbmRSZWZzOiAnZmFpbCdcbn0pO1xuXG5hanYuYWRkTWV0YVNjaGVtYShyZXF1aXJlKCdhanYvbGliL3JlZnMvanNvbi1zY2hlbWEtZHJhZnQtMDQuanNvbicpLCAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNC9zY2hlbWEjJyk7XG5cbmNvbnN0IHZhbGlkYXRlVmwgPSBhanYuY29tcGlsZSh2bFNjaGVtYSk7XG5jb25zdCB2YWxpZGF0ZVZnID0gYWp2LmNvbXBpbGUodmdTY2hlbWEpO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVZMKHNwZWM6IFRvcExldmVsRXh0ZW5kZWRTcGVjKSB7XG4gIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVWbChzcGVjKTtcbiAgY29uc3QgZXJyb3JzID0gdmFsaWRhdGVWbC5lcnJvcnM7XG4gIGlmICghdmFsaWQpIHtcbiAgICBjb25zb2xlLmxvZyhpbnNwZWN0KGVycm9ycywge2RlcHRoOiAxMCwgY29sb3JzOiB0cnVlfSkpO1xuICB9XG4gIGFzc2VydCh2YWxpZCwgZXJyb3JzICYmIGVycm9ycy5tYXAoKGVycjogQWp2LkVycm9yT2JqZWN0KSA9PiBlcnIubWVzc2FnZSkuam9pbignLCAnKSk7XG5cbiAgYXNzZXJ0LmVxdWFsKHNwZWMuJHNjaGVtYSwgJ2h0dHBzOi8vdmVnYS5naXRodWIuaW8vc2NoZW1hL3ZlZ2EtbGl0ZS92Mi5qc29uJyk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlVmVnYShzcGVjOiBUb3BMZXZlbEV4dGVuZGVkU3BlYykge1xuICBjb25zdCB2ZWdhU3BlYyA9IGNvbXBpbGUoc3BlYykuc3BlYztcblxuICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlVmcodmVnYVNwZWMpO1xuICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVZnLmVycm9ycztcbiAgaWYgKCF2YWxpZCkge1xuICAgIGNvbnNvbGUubG9nKGluc3BlY3QoZXJyb3JzLCB7ZGVwdGg6IDEwLCBjb2xvcnM6IHRydWV9KSk7XG4gIH1cbiAgYXNzZXJ0KHZhbGlkLCBlcnJvcnMgJiYgZXJyb3JzLm1hcCgoZXJyOiBBanYuRXJyb3JPYmplY3QpID0+IGVyci5tZXNzYWdlKS5qb2luKCcsICcpKTtcbn1cblxuY29uc3Qgc3VmZml4TGVuZ3RoID0gJ19mdXR1cmUudmwuanNvbicubGVuZ3RoO1xuZGVzY3JpYmUoJ0V4YW1wbGVzJywgZnVuY3Rpb24oKSB7XG4gIGNvbnN0IGV4YW1wbGVzID0gZnMucmVhZGRpclN5bmMoJ2V4YW1wbGVzL3NwZWNzJyk7XG5cbiAgZXhhbXBsZXMuZm9yRWFjaChmdW5jdGlvbihleGFtcGxlOiBzdHJpbmcpIHtcbiAgICBpZiAocGF0aC5leHRuYW1lKGV4YW1wbGUpICE9PSAnLmpzb24nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGpzb25TcGVjID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoJ2V4YW1wbGVzL3NwZWNzLycgKyBleGFtcGxlKSk7XG5cbiAgICBkZXNjcmliZShleGFtcGxlLCBmdW5jdGlvbigpIHtcbiAgICAgIGl0KCdzaG91bGQgYmUgdmFsaWQgdmVnYS1saXRlIHdpdGggcHJvcGVyICRzY2hlbWEnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIC8vIERvIG5vdCB2YWxpZGF0ZSBvdmVybGF5IGV4YW1wbGUgdW50aWwgd2UgaGF2ZSByZWRlc2lnbmVkIGl0XG4gICAgICAgICAgZXhhbXBsZS5pbmRleE9mKCdvdmVybGF5JykgPj0gMCB8fFxuICAgICAgICAgIC8vIEFsc28gaWdub3JlIGJveC1wbG90IGV4YW1wbGVzIHVudGlsIHdlIHN1cHBvcnQgc2VsZWN0aW9uc1xuICAgICAgICAgIGV4YW1wbGUuaW5kZXhPZignYm94LXBsb3QnKSA+PSAwIHx8XG4gICAgICAgICAgLy8gQWxzbyBpZ25vcmUgYWxsIGV4YW1wbGVzIHdpdGggXCJfZnV0dXJlXCIgc3VmZml4XG4gICAgICAgICAgZXhhbXBsZS5sYXN0SW5kZXhPZignX2Z1dHVyZS52bC5qc29uJywgZXhhbXBsZS5sZW5ndGggLSBzdWZmaXhMZW5ndGgpID49IDBcbiAgICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVWTChqc29uU3BlYyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwcm9kdWNlIHZhbGlkIHZlZ2EnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFsaWRhdGVWZWdhKGpzb25TcGVjKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ No newline at end of file diff --git a/build/examples/schema.test.d.ts b/build/examples/schema.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/examples/schema.test.js b/build/examples/schema.test.js new file mode 100644 index 0000000000..31d2382eeb --- /dev/null +++ b/build/examples/schema.test.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Ajv = require("ajv"); +var chai_1 = require("chai"); +var util_1 = require("util"); +var specSchema = require('../../build/vega-lite-schema.json'); +var metaSchema = require('ajv/lib/refs/json-schema-draft-04.json'); +describe('Schema', function () { + it('should be valid', function () { + var ajv = new Ajv({ + allErrors: true, + verbose: true, + extendRefs: 'fail' + }); + ajv.addMetaSchema(metaSchema, 'http://json-schema.org/draft-04/schema#'); + // now validate our data against the schema + var valid = ajv.validateSchema(specSchema); + if (!valid) { + console.log(util_1.inspect(ajv.errors, { depth: 10, colors: true })); + } + chai_1.assert.equal(valid, true); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9leGFtcGxlcy9zY2hlbWEudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlCQUEyQjtBQUMzQiw2QkFBNEI7QUFDNUIsNkJBQTZCO0FBRTdCLElBQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO0FBQ2hFLElBQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0FBRXJFLFFBQVEsQ0FBQyxRQUFRLEVBQUU7SUFDakIsRUFBRSxDQUFDLGlCQUFpQixFQUFFO1FBQ3BCLElBQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO1lBQ2xCLFNBQVMsRUFBRSxJQUFJO1lBQ2YsT0FBTyxFQUFFLElBQUk7WUFDYixVQUFVLEVBQUUsTUFBTTtTQUNuQixDQUFDLENBQUM7UUFFSCxHQUFHLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSx5Q0FBeUMsQ0FBQyxDQUFDO1FBRXpFLDJDQUEyQztRQUMzQyxJQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTdDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNYLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUNELGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzVCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBBanYgZnJvbSAnYWp2JztcbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7aW5zcGVjdH0gZnJvbSAndXRpbCc7XG5cbmNvbnN0IHNwZWNTY2hlbWEgPSByZXF1aXJlKCcuLi8uLi9idWlsZC92ZWdhLWxpdGUtc2NoZW1hLmpzb24nKTtcbmNvbnN0IG1ldGFTY2hlbWEgPSByZXF1aXJlKCdhanYvbGliL3JlZnMvanNvbi1zY2hlbWEtZHJhZnQtMDQuanNvbicpO1xuXG5kZXNjcmliZSgnU2NoZW1hJywgZnVuY3Rpb24oKSB7XG4gIGl0KCdzaG91bGQgYmUgdmFsaWQnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBhanYgPSBuZXcgQWp2KHtcbiAgICAgIGFsbEVycm9yczogdHJ1ZSxcbiAgICAgIHZlcmJvc2U6IHRydWUsXG4gICAgICBleHRlbmRSZWZzOiAnZmFpbCdcbiAgICB9KTtcblxuICAgIGFqdi5hZGRNZXRhU2NoZW1hKG1ldGFTY2hlbWEsICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMnKTtcblxuICAgIC8vIG5vdyB2YWxpZGF0ZSBvdXIgZGF0YSBhZ2FpbnN0IHRoZSBzY2hlbWFcbiAgICBjb25zdCB2YWxpZCA9IGFqdi52YWxpZGF0ZVNjaGVtYShzcGVjU2NoZW1hKTtcblxuICAgIGlmICghdmFsaWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKGluc3BlY3QoYWp2LmVycm9ycywge2RlcHRoOiAxMCwgY29sb3JzOiB0cnVlfSkpO1xuICAgIH1cbiAgICBhc3NlcnQuZXF1YWwodmFsaWQsIHRydWUpO1xuICB9KTtcbn0pO1xuIl19 \ No newline at end of file diff --git a/build/package.json b/build/package.json new file mode 100644 index 0000000000..ff0bf5e233 --- /dev/null +++ b/build/package.json @@ -0,0 +1,136 @@ +{ + "name": "vega-lite", + "author": "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat", + "version": "2.0.4", + "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 provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.", + "main": "build/src/index.js", + "types": "typings/vega-lite.d.ts", + "bin": { + "vl2png": "./bin/vl2png", + "vl2svg": "./bin/vl2svg", + "vl2vg": "./bin/vl2vg" + }, + "directories": { + "test": "test" + }, + "scripts": { + "pretsc": "mkdir -p build && rm -rf build/*/** && cp package.json build/", + "tsc": "tsc", + "prebuild": "mkdir -p build/site build/test-gallery", + "build": "npm run build:only", + "build:only": "npm run tsc && cp package.json build && browserify src/index.ts -p tsify -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js", + "postbuild": "node node_modules/uglify-js/bin/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 && npm run build:only && npm run build:examples-only", + "build:examples-only": "npm run build:example && npm run build:examples-normalized", + "build:examples-normalized": "rm -f examples/specs/normalized/*.vl.json && scripts/build-normalized-examples", + "build:example": "TZ=America/Los_Angeles scripts/build-examples.sh", + + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "browserify site/static/main.ts -p [tsify -p site] -d | exorcist build/site/main.js.map > build/site/main.js", + "build:versions": "scripts/update-version.sh", + "build:test-gallery": "browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js", + "check:examples": "scripts/check-examples.sh", + "check:schema": "scripts/check-schema.sh", + "clean": "rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\.(js|js.map|d.ts)' -delete && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -exec rm -f {} +", + "data": "rsync -r node_modules/vega-datasets/data/* data", + "link": "npm link && npm link vega-lite", + + "deploy": "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + + "prestart": "npm run data && npm run build && scripts/index-examples", + "start": "nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'", + "poststart": "rm examples/all-examples.json", + + "preschema": "npm run prebuild", + "schema": "ts-json-schema-generator --path tsconfig.json --type TopLevelExtendedSpec > 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": "npm run build:only && npm run test:only && npm run test:runtime && npm run lint", + "posttest": "npm run schema && npm run data && npm run mocha:examples", + "test:nocompile": "npm run test:only && npm run test:runtime && npm run lint && npm run mocha:examples", + "test:only": "nyc --reporter=html --reporter=text-summary npm run mocha:test", + "test:runtime": "TZ=America/Los_Angeles wdio wdio.conf.js", + "test:runtime:generate": "rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime", + "test:debug": "npm run tsc && mocha --recursive --debug-brk --inspect build/test", + "test:debug-examples": "npm run tsc && npm run schema && mocha --recursive --debug-brk --inspect build/examples", + "mocha:test": "mocha --require source-map-support/register --reporter dot --recursive build/test", + "mocha:examples": "mocha --require source-map-support/register --reporter dot --recursive build/examples", + + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json", + "watch:build": "watchify src/index.ts -p tsify -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'", + "watch:tsc": "npm run tsc -- -w", + "watch:test": "nodemon -x 'npm test'", + "watch": "nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build" + }, + "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.0.6", + "@types/d3": "^4.12.0", + "@types/highlight.js": "^9.12.2", + "@types/json-stable-stringify": "^1.0.32", + "@types/mkdirp": "^0.5.1", + "@types/mocha": "^2.2.44", + "@types/node": "^8.0.53", + "@types/webdriverio": "^4.8.6", + "ajv": "^5.5.0", + "browser-sync": "^2.18.13", + "browserify": "^14.5.0", + "browserify-shim": "^3.8.14", + "chai": "^4.1.2", + "cheerio": "^1.0.0-rc.2", + "chromedriver": "^2.33.2", + "codecov": "^3.0.0", + "d3": "^4.12.0", + "exorcist": "^1.0.0", + "highlight.js": "^9.12.0", + "mkdirp": "^0.5.1", + "mocha": "^4.0.1", + "nodemon": "^1.12.1", + "nyc": "^11.3.0", + "source-map-support": "^0.5.0", + "svg2png-many": "^0.0.7", + "ts-json-schema-generator": "^0.18.0", + "ts-node": "^3.3.0", + "tsify": "^3.0.3", + "tslint": "5.4.3", + "tslint-eslint-rules": "^4.1.1", + "typescript": "^2.6.2", + "uglify-js": "^3.2.0", + "vega": "^3.0.8", + "vega-datasets": "^1.11.0", + "vega-embed": "^3.0.0-rc7", + "vega-tooltip": "^0.4.4", + "watchify": "^3.9.0", + "wdio-chromedriver-service": "^0.1.1", + "wdio-dot-reporter": "0.0.9", + "wdio-mocha-framework": "^0.5.11", + "wdio-static-server-service": "^1.0.1", + "webdriverio": "^4.9.11", + "yaml-front-matter": "^3.4.0" + }, + "dependencies": { + "json-stable-stringify": "^1.0.1", + "tslib": "^1.8.0", + "vega-event-selector": "^2.0.0", + "vega-util": "^1.6.2", + "yargs": "^10.0.3" + } +} diff --git a/build/src/aggregate.d.ts b/build/src/aggregate.d.ts new file mode 100644 index 0000000000..01d4bca63e --- /dev/null +++ b/build/src/aggregate.d.ts @@ -0,0 +1,14 @@ +export declare type AggregateOp = 'argmax' | 'argmin' | 'average' | 'count' | 'distinct' | 'max' | 'mean' | 'median' | 'min' | 'missing' | 'q1' | 'q3' | 'ci0' | 'ci1' | 'stdev' | 'stdevp' | 'sum' | 'valid' | 'values' | 'variance' | 'variancep'; +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]: boolean; +}; diff --git a/build/src/aggregate.js b/build/src/aggregate.js new file mode 100644 index 0000000000..04a31238bf --- /dev/null +++ b/build/src/aggregate.js @@ -0,0 +1,58 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var AGGREGATE_OP_INDEX = { + values: 1, + count: 1, + valid: 1, + missing: 1, + distinct: 1, + sum: 1, + mean: 1, + average: 1, + variance: 1, + variancep: 1, + stdev: 1, + stdevp: 1, + median: 1, + q1: 1, + q3: 1, + ci0: 1, + ci1: 1, + min: 1, + max: 1, + argmin: 1, + argmax: 1, +}; +exports.AGGREGATE_OPS = util_1.flagKeys(AGGREGATE_OP_INDEX); +function isAggregateOp(a) { + return !!AGGREGATE_OP_INDEX[a]; +} +exports.isAggregateOp = isAggregateOp; +exports.COUNTING_OPS = ['count', 'valid', 'missing', 'distinct']; +function isCountingAggregateOp(aggregate) { + return aggregate && util_1.contains(exports.COUNTING_OPS, aggregate); +} +exports.isCountingAggregateOp = isCountingAggregateOp; +/** Additive-based aggregation operations. These can be applied to stack. */ +exports.SUM_OPS = [ + 'count', + 'sum', + 'distinct', + 'valid', + 'missing' +]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +exports.SHARED_DOMAIN_OPS = [ + 'mean', + 'average', + 'median', + 'q1', + 'q3', + 'min', + 'max', +]; +exports.SHARED_DOMAIN_OP_INDEX = util_1.toSet(exports.SHARED_DOMAIN_OPS); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FnZ3JlZ2F0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLCtCQUF1RDtBQVN2RCxJQUFNLGtCQUFrQixHQUFzQjtJQUM1QyxNQUFNLEVBQUUsQ0FBQztJQUNULEtBQUssRUFBRSxDQUFDO0lBQ1IsS0FBSyxFQUFFLENBQUM7SUFDUixPQUFPLEVBQUUsQ0FBQztJQUNWLFFBQVEsRUFBRSxDQUFDO0lBQ1gsR0FBRyxFQUFFLENBQUM7SUFDTixJQUFJLEVBQUUsQ0FBQztJQUNQLE9BQU8sRUFBRSxDQUFDO0lBQ1YsUUFBUSxFQUFFLENBQUM7SUFDWCxTQUFTLEVBQUUsQ0FBQztJQUNaLEtBQUssRUFBRSxDQUFDO0lBQ1IsTUFBTSxFQUFFLENBQUM7SUFDVCxNQUFNLEVBQUUsQ0FBQztJQUNULEVBQUUsRUFBRSxDQUFDO0lBQ0wsRUFBRSxFQUFFLENBQUM7SUFDTCxHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLE1BQU0sRUFBRSxDQUFDO0lBQ1QsTUFBTSxFQUFFLENBQUM7Q0FDVixDQUFDO0FBRVcsUUFBQSxhQUFhLEdBQUcsZUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFMUQsdUJBQThCLENBQVM7SUFDckMsTUFBTSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQyxDQUFDO0FBRkQsc0NBRUM7QUFFWSxRQUFBLFlBQVksR0FBa0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUVyRiwrQkFBc0MsU0FBaUI7SUFDckQsTUFBTSxDQUFDLFNBQVMsSUFBSSxlQUFRLENBQUMsb0JBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBRkQsc0RBRUM7QUFFRCw2RUFBNkU7QUFDaEUsUUFBQSxPQUFPLEdBQWtCO0lBQ2xDLE9BQU87SUFDUCxLQUFLO0lBQ0wsVUFBVTtJQUNWLE9BQU87SUFDUCxTQUFTO0NBQ1osQ0FBQztBQUVGOztHQUVHO0FBQ1UsUUFBQSxpQkFBaUIsR0FBa0I7SUFDNUMsTUFBTTtJQUNOLFNBQVM7SUFDVCxRQUFRO0lBQ1IsSUFBSTtJQUNKLElBQUk7SUFDSixLQUFLO0lBQ0wsS0FBSztDQUNSLENBQUM7QUFFVyxRQUFBLHNCQUFzQixHQUFHLFlBQUssQ0FBQyx5QkFBaUIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjb250YWlucywgRmxhZywgZmxhZ0tleXMsIHRvU2V0fSBmcm9tICcuL3V0aWwnO1xuXG5cbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0ZU9wID0gJ2FyZ21heCcgfCAnYXJnbWluJyB8ICdhdmVyYWdlJyB8ICdjb3VudCdcbiAgfCAnZGlzdGluY3QnIHwgJ21heCcgfCAnbWVhbicgfCAnbWVkaWFuJyB8ICdtaW4nIHwgJ21pc3NpbmcnXG4gIHwgJ3ExJyB8ICdxMycgfCAnY2kwJyB8ICdjaTEnIHwgJ3N0ZGV2JyB8ICdzdGRldnAnIHwgJ3N1bScgfCAndmFsaWQnIHwgJ3ZhbHVlcycgfCAndmFyaWFuY2UnXG4gIHwgJ3ZhcmlhbmNlcCc7XG5cblxuY29uc3QgQUdHUkVHQVRFX09QX0lOREVYOiBGbGFnPEFnZ3JlZ2F0ZU9wPiA9IHtcbiAgdmFsdWVzOiAxLFxuICBjb3VudDogMSxcbiAgdmFsaWQ6IDEsXG4gIG1pc3Npbmc6IDEsXG4gIGRpc3RpbmN0OiAxLFxuICBzdW06IDEsXG4gIG1lYW46IDEsXG4gIGF2ZXJhZ2U6IDEsXG4gIHZhcmlhbmNlOiAxLFxuICB2YXJpYW5jZXA6IDEsXG4gIHN0ZGV2OiAxLFxuICBzdGRldnA6IDEsXG4gIG1lZGlhbjogMSxcbiAgcTE6IDEsXG4gIHEzOiAxLFxuICBjaTA6IDEsXG4gIGNpMTogMSxcbiAgbWluOiAxLFxuICBtYXg6IDEsXG4gIGFyZ21pbjogMSxcbiAgYXJnbWF4OiAxLFxufTtcblxuZXhwb3J0IGNvbnN0IEFHR1JFR0FURV9PUFMgPSBmbGFnS2V5cyhBR0dSRUdBVEVfT1BfSU5ERVgpO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNBZ2dyZWdhdGVPcChhOiBzdHJpbmcpOiBhIGlzIEFnZ3JlZ2F0ZU9wIHtcbiAgcmV0dXJuICEhQUdHUkVHQVRFX09QX0lOREVYW2FdO1xufVxuXG5leHBvcnQgY29uc3QgQ09VTlRJTkdfT1BTOiBBZ2dyZWdhdGVPcFtdID0gWydjb3VudCcsICd2YWxpZCcsICdtaXNzaW5nJywgJ2Rpc3RpbmN0J107XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvdW50aW5nQWdncmVnYXRlT3AoYWdncmVnYXRlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGFnZ3JlZ2F0ZSAmJiBjb250YWlucyhDT1VOVElOR19PUFMsIGFnZ3JlZ2F0ZSk7XG59XG5cbi8qKiBBZGRpdGl2ZS1iYXNlZCBhZ2dyZWdhdGlvbiBvcGVyYXRpb25zLiAgVGhlc2UgY2FuIGJlIGFwcGxpZWQgdG8gc3RhY2suICovXG5leHBvcnQgY29uc3QgU1VNX09QUzogQWdncmVnYXRlT3BbXSA9IFtcbiAgICAnY291bnQnLFxuICAgICdzdW0nLFxuICAgICdkaXN0aW5jdCcsXG4gICAgJ3ZhbGlkJyxcbiAgICAnbWlzc2luZydcbl07XG5cbi8qKlxuICogQWdncmVnYXRpb24gb3BlcmF0b3JzIHRoYXQgYWx3YXlzIHByb2R1Y2UgdmFsdWVzIHdpdGhpbiB0aGUgcmFuZ2UgW2RvbWFpbk1pbiwgZG9tYWluTWF4XS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNIQVJFRF9ET01BSU5fT1BTOiBBZ2dyZWdhdGVPcFtdID0gW1xuICAgICdtZWFuJyxcbiAgICAnYXZlcmFnZScsXG4gICAgJ21lZGlhbicsXG4gICAgJ3ExJyxcbiAgICAncTMnLFxuICAgICdtaW4nLFxuICAgICdtYXgnLFxuXTtcblxuZXhwb3J0IGNvbnN0IFNIQVJFRF9ET01BSU5fT1BfSU5ERVggPSB0b1NldChTSEFSRURfRE9NQUlOX09QUyk7XG4iXX0= \ 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..0dbac4eadb --- /dev/null +++ b/build/src/axis.d.ts @@ -0,0 +1,132 @@ +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](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[] | 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; +} +/** + * 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'; +}; +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" | "values" | "scale" | "domain" | "orient" | "format" | "offset" | "tickCount" | "zindex" | "encode" | "grid" | "gridScale" | "labels" | "labelBound" | "labelFlush" | "labelPadding" | "labelOverlap" | "maxExtent" | "minExtent" | "position" | "ticks" | "tickSize" | "titlePadding")[]; +export declare const AXIS_PROPERTIES: ("title" | "values" | "domain" | "orient" | "format" | "offset" | "tickCount" | "zindex" | "grid" | "labels" | "labelBound" | "labelFlush" | "labelPadding" | "labelOverlap" | "maxExtent" | "minExtent" | "position" | "ticks" | "tickSize" | "titlePadding" | "labelAngle" | "encoding" | "titleMaxLength")[]; +export interface AxisConfigMixins { + /** + * Axis configuration, which determines default properties for all `x` and `y` [axes](axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](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..1a318faef2 --- /dev/null +++ b/build/src/axis.js @@ -0,0 +1,53 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +/** + * 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) + */ +exports.AXIS_PROPERTY_TYPE = { + grid: 'grid', + labelOverlap: 'main', + offset: 'main', + title: 'main' +}; +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]; +} +exports.isAxisProperty = isAxisProperty; +exports.VG_AXIS_PROPERTIES = util_1.flagKeys(VG_AXIS_PROPERTIES_INDEX); +// Export for dependent projects +exports.AXIS_PROPERTIES = util_1.flagKeys(AXIS_PROPERTIES_INDEX); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9heGlzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFFQSwrQkFBc0M7QUF5RXRDOzs7R0FHRztBQUNVLFFBQUEsa0JBQWtCLEdBRzNCO0lBQ0YsSUFBSSxFQUFFLE1BQU07SUFDWixZQUFZLEVBQUUsTUFBTTtJQUNwQixNQUFNLEVBQUUsTUFBTTtJQUNkLEtBQUssRUFBRSxNQUFNO0NBQ2QsQ0FBQztBQWtDRixJQUFNLDRCQUE0QixHQUFnQztJQUNoRSxNQUFNLEVBQUUsQ0FBQztJQUVULE1BQU0sRUFBRSxDQUFDO0lBQ1QsTUFBTSxFQUFFLENBQUM7SUFDVCxJQUFJLEVBQUUsQ0FBQztJQUNQLFVBQVUsRUFBRSxDQUFDO0lBQ2IsVUFBVSxFQUFFLENBQUM7SUFDYixZQUFZLEVBQUUsQ0FBQztJQUNmLE1BQU0sRUFBRSxDQUFDO0lBQ1QsWUFBWSxFQUFFLENBQUM7SUFDZixTQUFTLEVBQUUsQ0FBQztJQUNaLFNBQVMsRUFBRSxDQUFDO0lBQ1osTUFBTSxFQUFFLENBQUM7SUFDVCxRQUFRLEVBQUUsQ0FBQztJQUNYLFNBQVMsRUFBRSxDQUFDO0lBQ1osS0FBSyxFQUFFLENBQUM7SUFDUixRQUFRLEVBQUUsQ0FBQztJQUNYLEtBQUssRUFBRSxDQUFDO0lBQ1IsWUFBWSxFQUFFLENBQUM7SUFDZixNQUFNLEVBQUUsQ0FBQztJQUNULE1BQU0sRUFBRSxDQUFDO0NBQ1YsQ0FBQztBQUVGLElBQU0scUJBQXFCLGdCQUN0Qiw0QkFBNEIsSUFDL0IsUUFBUSxFQUFFLENBQUMsRUFDWCxVQUFVLEVBQUUsQ0FBQyxFQUNiLGNBQWMsRUFBRSxDQUFDLEdBQ2xCLENBQUM7QUFFRixJQUFNLHdCQUF3QixjQUM1QixLQUFLLEVBQUUsQ0FBQyxJQUNMLDRCQUE0QixJQUMvQixTQUFTLEVBQUUsQ0FBQyxFQUNaLE1BQU0sRUFBRSxDQUFDLEdBQ1YsQ0FBQztBQUVGLHdCQUErQixJQUFZO0lBQ3pDLE1BQU0sQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUZELHdDQUVDO0FBRVksUUFBQSxrQkFBa0IsR0FBRyxlQUFRLENBQUMsd0JBQXdCLENBQUMsQ0FBQztBQUVyRSxnQ0FBZ0M7QUFDbkIsUUFBQSxlQUFlLEdBQUcsZUFBUSxDQUFDLHFCQUFxQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RhdGVUaW1lfSBmcm9tICcuL2RhdGV0aW1lJztcbmltcG9ydCB7R3VpZGUsIEd1aWRlRW5jb2RpbmdFbnRyeSwgVmxPbmx5R3VpZGVDb25maWd9IGZyb20gJy4vZ3VpZGUnO1xuaW1wb3J0IHtGbGFnLCBmbGFnS2V5c30gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7QXhpc09yaWVudCwgVmdBeGlzLCBWZ0F4aXNCYXNlLCBWZ0F4aXNDb25maWd9IGZyb20gJy4vdmVnYS5zY2hlbWEnO1xuXG5cblxuZXhwb3J0IGludGVyZmFjZSBBeGlzQ29uZmlnIGV4dGVuZHMgVmdBeGlzQ29uZmlnLCBWbE9ubHlHdWlkZUNvbmZpZyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIEF4aXMgZXh0ZW5kcyBWZ0F4aXNCYXNlLCBHdWlkZSB7XG4gIC8qKlxuICAgKiBUaGUgb3JpZW50YXRpb24gb2YgdGhlIGF4aXMuIE9uZSBvZiBgXCJ0b3BcImAsIGBcImJvdHRvbVwiYCwgYFwibGVmdFwiYCBvciBgXCJyaWdodFwiYC4gVGhlIG9yaWVudGF0aW9uIGNhbiBiZSB1c2VkIHRvIGZ1cnRoZXIgc3BlY2lhbGl6ZSB0aGUgYXhpcyB0eXBlIChlLmcuLCBhIHkgYXhpcyBvcmllbnRlZCBmb3IgdGhlIHJpZ2h0IGVkZ2Ugb2YgdGhlIGNoYXJ0KS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGBcImJvdHRvbVwiYCBmb3IgeC1heGVzIGFuZCBgXCJsZWZ0XCJgIGZvciB5LWF4ZXMuXG4gICAqL1xuICBvcmllbnQ/OiBBeGlzT3JpZW50O1xuXG4gIC8qKlxuICAgKiBUaGUgb2Zmc2V0LCBpbiBwaXhlbHMsIGJ5IHdoaWNoIHRvIGRpc3BsYWNlIHRoZSBheGlzIGZyb20gdGhlIGVkZ2Ugb2YgdGhlIGVuY2xvc2luZyBncm91cCBvciBkYXRhIHJlY3RhbmdsZS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGRlcml2ZWQgZnJvbSB0aGUgW2F4aXMgY29uZmlnXShjb25maWcuaHRtbCNmYWNldC1zY2FsZS1jb25maWcpJ3MgYG9mZnNldGAgKGAwYCBieSBkZWZhdWx0KVxuICAgKi9cbiAgb2Zmc2V0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgYW5jaG9yIHBvc2l0aW9uIG9mIHRoZSBheGlzIGluIHBpeGVscy4gRm9yIHgtYXhpcyB3aXRoIHRvcCBvciBib3R0b20gb3JpZW50YXRpb24sIHRoaXMgc2V0cyB0aGUgYXhpcyBncm91cCB4IGNvb3JkaW5hdGUuIEZvciB5LWF4aXMgd2l0aCBsZWZ0IG9yIHJpZ2h0IG9yaWVudGF0aW9uLCB0aGlzIHNldHMgdGhlIGF4aXMgZ3JvdXAgeSBjb29yZGluYXRlLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWVfXzogYDBgXG4gICAqL1xuICBwb3NpdGlvbj86IG51bWJlcjtcblxuXG4gIC8qKlxuICAgKiBUaGUgcm90YXRpb24gYW5nbGUgb2YgdGhlIGF4aXMgbGFiZWxzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYC05MGAgZm9yIG5vbWluYWwgYW5kIG9yZGluYWwgZmllbGRzOyBgMGAgb3RoZXJ3aXNlLlxuICAgKlxuICAgKiBAbWluaW11bSAtMzYwXG4gICAqIEBtYXhpbXVtIDM2MFxuICAgKi9cbiAgbGFiZWxBbmdsZT86IG51bWJlcjtcblxuICAvKipcbiAgICogQSBkZXNpcmVkIG51bWJlciBvZiB0aWNrcywgZm9yIGF4ZXMgdmlzdWFsaXppbmcgcXVhbnRpdGF0aXZlIHNjYWxlcy4gVGhlIHJlc3VsdGluZyBudW1iZXIgbWF5IGJlIGRpZmZlcmVudCBzbyB0aGF0IHZhbHVlcyBhcmUgXCJuaWNlXCIgKG11bHRpcGxlcyBvZiAyLCA1LCAxMCkgYW5kIGxpZSB3aXRoaW4gdGhlIHVuZGVybHlpbmcgc2NhbGUncyByYW5nZS5cbiAgICogQG1pbmltdW0gMFxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWVfXzogRGV0ZXJtaW5lIHVzaW5nIGEgZm9ybXVsYSBgY2VpbCh3aWR0aC80MClgIGZvciB4IGFuZCBgY2VpbChoZWlnaHQvNDApYCBmb3IgeS5cbiAgICovXG4gIHRpY2tDb3VudD86IG51bWJlcjtcblxuICAvKipcbiAgICogRXhwbGljaXRseSBzZXQgdGhlIHZpc2libGUgYXhpcyB0aWNrIHZhbHVlcy5cbiAgICovXG4gIHZhbHVlcz86IG51bWJlcltdIHwgRGF0ZVRpbWVbXTtcblxuICAvKipcbiAgICogQSBub24tcG9zaXRpdmUgaW50ZWdlciBpbmRpY2F0aW5nIHotaW5kZXggb2YgdGhlIGF4aXMuXG4gICAqIElmIHppbmRleCBpcyAwLCBheGVzIHNob3VsZCBiZSBkcmF3biBiZWhpbmQgYWxsIGNoYXJ0IGVsZW1lbnRzLlxuICAgKiBUbyBwdXQgdGhlbSBpbiBmcm9udCwgdXNlIGBcInppbmRleCA9IDFcImAuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMWAgKGluIGZyb250IG9mIHRoZSBtYXJrcykgZm9yIGFjdHVhbCBheGlzIGFuZCBgMGAgKGJlaGluZCB0aGUgbWFya3MpIGZvciBncmlkcy5cbiAgICpcbiAgICogQFRKUy10eXBlIGludGVnZXJcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgemluZGV4PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBNYXJrIGRlZmluaXRpb25zIGZvciBjdXN0b20gYXhpcyBlbmNvZGluZy5cbiAgICpcbiAgICogQGhpZGVcbiAgICovXG4gIGVuY29kaW5nPzogQXhpc0VuY29kaW5nO1xufVxuXG4vKipcbiAqIEEgZGljdGlvbmFyeSBsaXN0aW5nIHdoZXRoZXIgYSBjZXJ0YWluIGF4aXMgcHJvcGVydHkgaXMgYXBwbGljYWJsZSBmb3Igb25seSBtYWluIGF4ZXMgb3Igb25seSBncmlkIGF4ZXMuXG4gKiAoUHJvcGVydGllcyBub3QgbGlzdGVkIGFyZSBhcHBsaWNhYmxlIGZvciBib3RoKVxuICovXG5leHBvcnQgY29uc3QgQVhJU19QUk9QRVJUWV9UWVBFOiB7XG4gIC8vIFVzaW5nIE1hcHBlZCBUeXBlIHRvIGRlY2xhcmUgdHlwZSAoaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svYWR2YW5jZWQtdHlwZXMuaHRtbCNtYXBwZWQtdHlwZXMpXG4gIFtrIGluIGtleW9mIFZnQXhpc10/OiAnbWFpbicgfCAnZ3JpZCdcbn0gPSB7XG4gIGdyaWQ6ICdncmlkJyxcbiAgbGFiZWxPdmVybGFwOiAnbWFpbicsXG4gIG9mZnNldDogJ21haW4nLFxuICB0aXRsZTogJ21haW4nXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEF4aXNFbmNvZGluZyB7XG4gIC8qKlxuICAgKiBDdXN0b20gZW5jb2RpbmcgZm9yIHRoZSBheGlzIGNvbnRhaW5lci5cbiAgICovXG4gIGF4aXM/OiBHdWlkZUVuY29kaW5nRW50cnk7XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBlbmNvZGluZyBmb3IgdGhlIGF4aXMgZG9tYWluIHJ1bGUgbWFyay5cbiAgICovXG4gIGRvbWFpbj86IEd1aWRlRW5jb2RpbmdFbnRyeTtcblxuICAvKipcbiAgICogQ3VzdG9tIGVuY29kaW5nIGZvciBheGlzIGdyaWRsaW5lIHJ1bGUgbWFya3MuXG4gICAqL1xuICBncmlkPzogR3VpZGVFbmNvZGluZ0VudHJ5O1xuXG4gIC8qKlxuICAgKiBDdXN0b20gZW5jb2RpbmcgZm9yIGF4aXMgbGFiZWwgdGV4dCBtYXJrcy5cbiAgICovXG4gIGxhYmVscz86IEd1aWRlRW5jb2RpbmdFbnRyeTtcblxuICAvKipcbiAgICogQ3VzdG9tIGVuY29kaW5nIGZvciBheGlzIHRpY2sgcnVsZSBtYXJrcy5cbiAgICovXG4gIHRpY2tzPzogR3VpZGVFbmNvZGluZ0VudHJ5O1xuXG4gIC8qKlxuICAgKiBDdXN0b20gZW5jb2RpbmcgZm9yIHRoZSBheGlzIHRpdGxlIHRleHQgbWFyay5cbiAgICovXG4gIHRpdGxlPzogR3VpZGVFbmNvZGluZ0VudHJ5O1xufVxuXG5jb25zdCBDT01NT05fQVhJU19QUk9QRVJUSUVTX0lOREVYOiBGbGFnPGtleW9mIChWZ0F4aXMgfCBBeGlzKT4gPSB7XG4gIG9yaWVudDogMSwgLy8gb3RoZXIgdGhpbmdzIGNhbiBkZXBlbmQgb24gb3JpZW50XG5cbiAgZG9tYWluOiAxLFxuICBmb3JtYXQ6IDEsXG4gIGdyaWQ6IDEsXG4gIGxhYmVsQm91bmQ6IDEsXG4gIGxhYmVsRmx1c2g6IDEsXG4gIGxhYmVsUGFkZGluZzogMSxcbiAgbGFiZWxzOiAxLFxuICBsYWJlbE92ZXJsYXA6IDEsXG4gIG1heEV4dGVudDogMSxcbiAgbWluRXh0ZW50OiAxLFxuICBvZmZzZXQ6IDEsXG4gIHBvc2l0aW9uOiAxLFxuICB0aWNrQ291bnQ6IDEsXG4gIHRpY2tzOiAxLFxuICB0aWNrU2l6ZTogMSxcbiAgdGl0bGU6IDEsXG4gIHRpdGxlUGFkZGluZzogMSxcbiAgdmFsdWVzOiAxLFxuICB6aW5kZXg6IDEsXG59O1xuXG5jb25zdCBBWElTX1BST1BFUlRJRVNfSU5ERVg6IEZsYWc8a2V5b2YgQXhpcz4gPSB7XG4gIC4uLkNPTU1PTl9BWElTX1BST1BFUlRJRVNfSU5ERVgsXG4gIGVuY29kaW5nOiAxLFxuICBsYWJlbEFuZ2xlOiAxLFxuICB0aXRsZU1heExlbmd0aDogMVxufTtcblxuY29uc3QgVkdfQVhJU19QUk9QRVJUSUVTX0lOREVYOiBGbGFnPGtleW9mIFZnQXhpcz4gPSB7XG4gIHNjYWxlOiAxLFxuICAuLi5DT01NT05fQVhJU19QUk9QRVJUSUVTX0lOREVYLFxuICBncmlkU2NhbGU6IDEsXG4gIGVuY29kZTogMVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzQXhpc1Byb3BlcnR5KHByb3A6IHN0cmluZyk6IHByb3AgaXMga2V5b2YgQXhpcyB7XG4gIHJldHVybiAhIUFYSVNfUFJPUEVSVElFU19JTkRFWFtwcm9wXTtcbn1cblxuZXhwb3J0IGNvbnN0IFZHX0FYSVNfUFJPUEVSVElFUyA9IGZsYWdLZXlzKFZHX0FYSVNfUFJPUEVSVElFU19JTkRFWCk7XG5cbi8vIEV4cG9ydCBmb3IgZGVwZW5kZW50IHByb2plY3RzXG5leHBvcnQgY29uc3QgQVhJU19QUk9QRVJUSUVTID0gZmxhZ0tleXMoQVhJU19QUk9QRVJUSUVTX0lOREVYKTtcblxuZXhwb3J0IGludGVyZmFjZSBBeGlzQ29uZmlnTWl4aW5zIHtcbiAgLyoqXG4gICAqIEF4aXMgY29uZmlndXJhdGlvbiwgd2hpY2ggZGV0ZXJtaW5lcyBkZWZhdWx0IHByb3BlcnRpZXMgZm9yIGFsbCBgeGAgYW5kIGB5YCBbYXhlc10oYXhpcy5odG1sKS4gRm9yIGEgZnVsbCBsaXN0IG9mIGF4aXMgY29uZmlndXJhdGlvbiBvcHRpb25zLCBwbGVhc2Ugc2VlIHRoZSBbY29ycmVzcG9uZGluZyBzZWN0aW9uIG9mIHRoZSBheGlzIGRvY3VtZW50YXRpb25dKGF4aXMuaHRtbCNjb25maWcpLlxuICAgKi9cbiAgYXhpcz86IEF4aXNDb25maWc7XG5cbiAgLyoqXG4gICAqIFgtYXhpcyBzcGVjaWZpYyBjb25maWcuXG4gICAqL1xuICBheGlzWD86IFZnQXhpc0NvbmZpZztcblxuICAvKipcbiAgICogWS1heGlzIHNwZWNpZmljIGNvbmZpZy5cbiAgICovXG4gIGF4aXNZPzogVmdBeGlzQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpYyBheGlzIGNvbmZpZyBmb3IgeS1heGlzIGFsb25nIHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIGNoYXJ0LlxuICAgKi9cbiAgYXhpc0xlZnQ/OiBWZ0F4aXNDb25maWc7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmljIGF4aXMgY29uZmlnIGZvciB5LWF4aXMgYWxvbmcgdGhlIHJpZ2h0IGVkZ2Ugb2YgdGhlIGNoYXJ0LlxuICAgKi9cbiAgYXhpc1JpZ2h0PzogVmdBeGlzQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpYyBheGlzIGNvbmZpZyBmb3IgeC1heGlzIGFsb25nIHRoZSB0b3AgZWRnZSBvZiB0aGUgY2hhcnQuXG4gICAqL1xuICBheGlzVG9wPzogVmdBeGlzQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpYyBheGlzIGNvbmZpZyBmb3IgeC1heGlzIGFsb25nIHRoZSBib3R0b20gZWRnZSBvZiB0aGUgY2hhcnQuXG4gICAqL1xuICBheGlzQm90dG9tPzogVmdBeGlzQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpYyBheGlzIGNvbmZpZyBmb3IgYXhlcyB3aXRoIFwiYmFuZFwiIHNjYWxlcy5cbiAgICovXG4gIGF4aXNCYW5kPzogVmdBeGlzQ29uZmlnO1xufVxuIl19 \ 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..f2f5657df8 --- /dev/null +++ b/build/src/bin.d.ts @@ -0,0 +1,58 @@ +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; + /** + * 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 autoMaxBins(channel: Channel): number; diff --git a/build/src/bin.js b/build/src/bin.js new file mode 100644 index 0000000000..93beca7899 --- /dev/null +++ b/build/src/bin.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var util_1 = require("./util"); +function binToString(bin) { + if (util_1.isBoolean(bin)) { + return 'bin'; + } + return 'bin' + util_1.keys(bin).map(function (p) { return ("_" + p + "_" + bin[p]).replace(',', '_'); }).join(''); +} +exports.binToString = binToString; +function autoMaxBins(channel) { + switch (channel) { + case channel_1.ROW: + case channel_1.COLUMN: + case channel_1.SIZE: + case channel_1.COLOR: + case channel_1.OPACITY: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule + case channel_1.SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } +} +exports.autoMaxBins = autoMaxBins; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFDQUE0RTtBQUM1RSwrQkFBdUM7QUE2RHZDLHFCQUE0QixHQUF3QjtJQUNsRCxFQUFFLENBQUMsQ0FBQyxnQkFBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQixNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sQ0FBQyxLQUFLLEdBQUcsV0FBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLENBQUEsTUFBSSxDQUFDLFNBQUksR0FBRyxDQUFDLENBQUMsQ0FBRyxDQUFBLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBbkMsQ0FBbUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsRixDQUFDO0FBTEQsa0NBS0M7QUFFRCxxQkFBNEIsT0FBZ0I7SUFDMUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNoQixLQUFLLGFBQUcsQ0FBQztRQUNULEtBQUssZ0JBQU0sQ0FBQztRQUNaLEtBQUssY0FBSSxDQUFDO1FBQ1YsS0FBSyxlQUFLLENBQUM7UUFDWCxLQUFLLGlCQUFPLENBQUM7UUFDWCwrQ0FBK0M7UUFDL0MsOENBQThDO1FBQ2hELEtBQUssZUFBSztZQUNSLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyx1Q0FBdUM7UUFDbkQ7WUFDRSxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQ2QsQ0FBQztBQUNILENBQUM7QUFkRCxrQ0FjQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbm5lbCwgQ09MT1IsIENPTFVNTiwgT1BBQ0lUWSwgUk9XLCBTSEFQRSwgU0laRX0gZnJvbSAnLi9jaGFubmVsJztcbmltcG9ydCB7aXNCb29sZWFuLCBrZXlzfSBmcm9tICcuL3V0aWwnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUJpbiB7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIGJhc2UgdG8gdXNlIGZvciBhdXRvbWF0aWMgYmluIGRldGVybWluYXRpb24gKGRlZmF1bHQgaXMgYmFzZSAxMCkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMTBgXG4gICAqXG4gICAqL1xuICBiYXNlPzogbnVtYmVyO1xuICAvKipcbiAgICogQW4gZXhhY3Qgc3RlcCBzaXplIHRvIHVzZSBiZXR3ZWVuIGJpbnMuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBJZiBwcm92aWRlZCwgb3B0aW9ucyBzdWNoIGFzIG1heGJpbnMgd2lsbCBiZSBpZ25vcmVkLlxuICAgKi9cbiAgc3RlcD86IG51bWJlcjtcbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGFsbG93YWJsZSBzdGVwIHNpemVzIHRvIGNob29zZSBmcm9tLlxuICAgKiBAbWluSXRlbXMgMVxuICAgKi9cbiAgc3RlcHM/OiBudW1iZXJbXTtcbiAgLyoqXG4gICAqIEEgbWluaW11bSBhbGxvd2FibGUgc3RlcCBzaXplIChwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBpbnRlZ2VyIHZhbHVlcykuXG4gICAqL1xuICBtaW5zdGVwPzogbnVtYmVyO1xuICAvKipcbiAgICogU2NhbGUgZmFjdG9ycyBpbmRpY2F0aW5nIGFsbG93YWJsZSBzdWJkaXZpc2lvbnMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFs1LCAyXSwgd2hpY2ggaW5kaWNhdGVzIHRoYXQgZm9yIGJhc2UgMTAgbnVtYmVycyAodGhlIGRlZmF1bHQgYmFzZSksIHRoZSBtZXRob2QgbWF5IGNvbnNpZGVyIGRpdmlkaW5nIGJpbiBzaXplcyBieSA1IGFuZC9vciAyLiBGb3IgZXhhbXBsZSwgZm9yIGFuIGluaXRpYWwgc3RlcCBzaXplIG9mIDEwLCB0aGUgbWV0aG9kIGNhbiBjaGVjayBpZiBiaW4gc2l6ZXMgb2YgMiAoPSAxMC81KSwgNSAoPSAxMC8yKSwgb3IgMSAoPSAxMC8oNSoyKSkgbWlnaHQgYWxzbyBzYXRpc2Z5IHRoZSBnaXZlbiBjb25zdHJhaW50cy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGBbNSwgMl1gXG4gICAqXG4gICAqIEBtaW5JdGVtcyAxXG4gICAqL1xuICBkaXZpZGU/OiBudW1iZXJbXTtcbiAgLyoqXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIGJpbnMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgNmAgZm9yIGByb3dgLCBgY29sdW1uYCBhbmQgYHNoYXBlYCBjaGFubmVsczsgYDEwYCBmb3Igb3RoZXIgY2hhbm5lbHNcbiAgICpcbiAgICogQG1pbmltdW0gMlxuICAgKi9cbiAgbWF4Ymlucz86IG51bWJlcjtcbiAgLyoqXG4gICAqIElmIHRydWUgKHRoZSBkZWZhdWx0KSwgYXR0ZW1wdHMgdG8gbWFrZSB0aGUgYmluIGJvdW5kYXJpZXMgdXNlIGh1bWFuLWZyaWVuZGx5IGJvdW5kYXJpZXMsIHN1Y2ggYXMgbXVsdGlwbGVzIG9mIHRlbi5cbiAgICovXG4gIG5pY2U/OiBib29sZWFuO1xufVxuXG5cbi8qKlxuICogQmlubmluZyBwcm9wZXJ0aWVzIG9yIGJvb2xlYW4gZmxhZyBmb3IgZGV0ZXJtaW5pbmcgd2hldGhlciB0byBiaW4gZGF0YSBvciBub3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmluUGFyYW1zIGV4dGVuZHMgQmFzZUJpbiB7XG4gIC8qKlxuICAgKiBBIHR3by1lbGVtZW50IChgW21pbiwgbWF4XWApIGFycmF5IGluZGljYXRpbmcgdGhlIHJhbmdlIG9mIGRlc2lyZWQgYmluIHZhbHVlcy5cbiAgICogQG1pbkl0ZW1zIDJcbiAgICogQG1heEl0ZW1zIDJcbiAgICovXG4gIGV4dGVudD86IG51bWJlcltdOyAgLy8gVmdCaW5UcmFuc2Zvcm0gdXNlcyBhIGRpZmZlcmVudCBleHRlbnQgc28gd2UgbmVlZCB0byBwdWxsIHRoaXMgb3V0LlxufVxuXG5leHBvcnQgZnVuY3Rpb24gYmluVG9TdHJpbmcoYmluOiBCaW5QYXJhbXMgfCBib29sZWFuKSB7XG4gIGlmIChpc0Jvb2xlYW4oYmluKSkge1xuICAgIHJldHVybiAnYmluJztcbiAgfVxuICByZXR1cm4gJ2JpbicgKyBrZXlzKGJpbikubWFwKHAgPT4gYF8ke3B9XyR7YmluW3BdfWAucmVwbGFjZSgnLCcsICdfJykpLmpvaW4oJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXV0b01heEJpbnMoY2hhbm5lbDogQ2hhbm5lbCk6IG51bWJlciB7XG4gIHN3aXRjaCAoY2hhbm5lbCkge1xuICAgIGNhc2UgUk9XOlxuICAgIGNhc2UgQ09MVU1OOlxuICAgIGNhc2UgU0laRTpcbiAgICBjYXNlIENPTE9SOlxuICAgIGNhc2UgT1BBQ0lUWTpcbiAgICAgIC8vIEZhY2V0cyBhbmQgU2l6ZSBzaG91bGRuJ3QgaGF2ZSB0b28gbWFueSBiaW5zXG4gICAgICAvLyBXZSBjaG9vc2UgNiBsaWtlIHNoYXBlIHRvIHNpbXBsaWZ5IHRoZSBydWxlXG4gICAgY2FzZSBTSEFQRTpcbiAgICAgIHJldHVybiA2OyAvLyBWZWdhJ3MgXCJzaGFwZVwiIGhhcyA2IGRpc3RpbmN0IHZhbHVlc1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gMTA7XG4gIH1cbn1cbiJdfQ== \ 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..6eb1737780 --- /dev/null +++ b/build/src/channel.d.ts @@ -0,0 +1,85 @@ +import { RangeType } from './compile/scale/type'; +import { Encoding } from './encoding'; +import { FacetMapping } from './facet'; +import { Mark } from './mark'; +export declare namespace Channel { + const ROW: 'row'; + const COLUMN: 'column'; + const X: 'x'; + const Y: 'y'; + const X2: 'x2'; + const Y2: 'y2'; + const COLOR: 'color'; + const SHAPE: 'shape'; + const SIZE: 'size'; + const OPACITY: 'opacity'; + const TEXT: 'text'; + const ORDER: 'order'; + const DETAIL: 'detail'; + const TOOLTIP: 'tooltip'; +} +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 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 TEXT: "text"; +export declare const DETAIL: "detail"; +export declare const ORDER: "order"; +export declare const OPACITY: "opacity"; +export declare const TOOLTIP: "tooltip"; +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 projecttion won't work with "detail" and "order".) + */ +export declare const SINGLE_DEF_CHANNELS: SingleDefChannel[]; +export declare type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' | 'row' | 'column' | 'size' | 'shape' | 'color' | 'opacity' | 'text' | 'tooltip'; +export declare function isChannel(str: string): str is Channel; +export declare const UNIT_CHANNELS: ("text" | "x" | "y" | "x2" | "y2" | "color" | "opacity" | "size" | "shape" | "detail" | "tooltip" | "order")[]; +export declare const NONPOSITION_CHANNELS: ("text" | "color" | "opacity" | "size" | "shape" | "detail" | "tooltip" | "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: ("color" | "opacity" | "size" | "shape")[]; +export declare type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0]; +/** List of channels with scales */ +export declare const SCALE_CHANNELS: ("x" | "y" | "color" | "opacity" | "size" | "shape")[]; +export declare type ScaleChannel = typeof SCALE_CHANNELS[0]; +export declare function isScaleChannel(channel: Channel): channel is ScaleChannel; +export interface SupportedMark { + point?: boolean; + tick?: boolean; + rule?: boolean; + circle?: boolean; + square?: boolean; + bar?: boolean; + rect?: boolean; + line?: boolean; + area?: boolean; + text?: boolean; + tooltip?: 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..3728b603b7 --- /dev/null +++ b/build/src/channel.js @@ -0,0 +1,198 @@ +"use strict"; +/* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var Channel; +(function (Channel) { + // Facet + Channel.ROW = 'row'; + Channel.COLUMN = 'column'; + // Position + Channel.X = 'x'; + Channel.Y = 'y'; + Channel.X2 = 'x2'; + Channel.Y2 = 'y2'; + // Mark property with scale + Channel.COLOR = 'color'; + Channel.SHAPE = 'shape'; + Channel.SIZE = 'size'; + Channel.OPACITY = 'opacity'; + // Non-scale channel + Channel.TEXT = 'text'; + Channel.ORDER = 'order'; + Channel.DETAIL = 'detail'; + Channel.TOOLTIP = 'tooltip'; +})(Channel = exports.Channel || (exports.Channel = {})); +exports.X = Channel.X; +exports.Y = Channel.Y; +exports.X2 = Channel.X2; +exports.Y2 = Channel.Y2; +exports.ROW = Channel.ROW; +exports.COLUMN = Channel.COLUMN; +exports.SHAPE = Channel.SHAPE; +exports.SIZE = Channel.SIZE; +exports.COLOR = Channel.COLOR; +exports.TEXT = Channel.TEXT; +exports.DETAIL = Channel.DETAIL; +exports.ORDER = Channel.ORDER; +exports.OPACITY = Channel.OPACITY; +exports.TOOLTIP = Channel.TOOLTIP; +var UNIT_CHANNEL_INDEX = { + x: 1, + y: 1, + x2: 1, + y2: 1, + size: 1, + shape: 1, + color: 1, + order: 1, + opacity: 1, + text: 1, + detail: 1, + tooltip: 1 +}; +var FACET_CHANNEL_INDEX = { + row: 1, + column: 1 +}; +var CHANNEL_INDEX = __assign({}, UNIT_CHANNEL_INDEX, FACET_CHANNEL_INDEX); +exports.CHANNELS = util_1.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 projecttion won't work with "detail" and "order".) + */ +exports.SINGLE_DEF_CHANNELS = util_1.flagKeys(SINGLE_DEF_CHANNEL_INDEX); +function isChannel(str) { + return !!CHANNEL_INDEX[str]; +} +exports.isChannel = isChannel; +// CHANNELS without COLUMN, ROW +exports.UNIT_CHANNELS = util_1.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, +// The rest of unit channels then have scale +NONPOSITION_CHANNEL_INDEX = __rest(UNIT_CHANNEL_INDEX, ["x", "y", "x2", "y2"]); +exports.NONPOSITION_CHANNELS = util_1.flagKeys(NONPOSITION_CHANNEL_INDEX); +// POSITION_SCALE_CHANNELS = X and Y; +var POSITION_SCALE_CHANNEL_INDEX = { x: 1, y: 1 }; +exports.POSITION_SCALE_CHANNELS = util_1.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 has format instead of scale +_t = NONPOSITION_CHANNEL_INDEX.text, _tt = NONPOSITION_CHANNEL_INDEX.tooltip, +// detail and order have no scale +_dd = NONPOSITION_CHANNEL_INDEX.detail, _oo = NONPOSITION_CHANNEL_INDEX.order, NONPOSITION_SCALE_CHANNEL_INDEX = __rest(NONPOSITION_CHANNEL_INDEX, ["text", "tooltip", "detail", "order"]); +exports.NONPOSITION_SCALE_CHANNELS = util_1.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 */ +exports.SCALE_CHANNELS = util_1.flagKeys(SCALE_CHANNEL_INDEX); +function isScaleChannel(channel) { + return !!SCALE_CHANNEL_INDEX[channel]; +} +exports.isScaleChannel = isScaleChannel; +/** + * 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); +} +exports.supportMark = supportMark; +/** + * 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 exports.X: + case exports.Y: + case exports.COLOR: + case exports.DETAIL: + case exports.TOOLTIP: + case exports.ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case exports.OPACITY: + case exports.ROW: + case exports.COLUMN: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, area: true, text: true + }; + case exports.X2: + case exports.Y2: + return { + rule: true, bar: true, rect: true, area: true + }; + case exports.SIZE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, text: true, line: true + }; + case exports.SHAPE: + return { point: true }; + case exports.TEXT: + return { text: true }; + } +} +exports.getSupportedMark = getSupportedMark; +function rangeType(channel) { + switch (channel) { + case exports.X: + case exports.Y: + case exports.SIZE: + case exports.OPACITY: + // X2 and Y2 use X and Y scales, so they similarly have continuous range. + case exports.X2: + case exports.Y2: + return 'continuous'; + case exports.ROW: + case exports.COLUMN: + case exports.SHAPE: + // TEXT and TOOLTIP have no scale but have discrete output + case exports.TEXT: + case exports.TOOLTIP: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case exports.COLOR: + return 'flexible'; + // No scale, no range type. + case exports.DETAIL: + case exports.ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('getSupportedRole not implemented for ' + channel); +} +exports.rangeType = rangeType; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jaGFubmVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPSCwrQkFBZ0Q7QUFFaEQsSUFBaUIsT0FBTyxDQXNCdkI7QUF0QkQsV0FBaUIsT0FBTztJQUN0QixRQUFRO0lBQ0ssV0FBRyxHQUFVLEtBQUssQ0FBQztJQUNuQixjQUFNLEdBQWEsUUFBUSxDQUFDO0lBRXpDLFdBQVc7SUFDRSxTQUFDLEdBQVEsR0FBRyxDQUFDO0lBQ2IsU0FBQyxHQUFRLEdBQUcsQ0FBQztJQUNiLFVBQUUsR0FBUyxJQUFJLENBQUM7SUFDaEIsVUFBRSxHQUFTLElBQUksQ0FBQztJQUU3QiwyQkFBMkI7SUFDZCxhQUFLLEdBQVksT0FBTyxDQUFDO0lBQ3pCLGFBQUssR0FBWSxPQUFPLENBQUM7SUFDekIsWUFBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixlQUFPLEdBQWMsU0FBUyxDQUFDO0lBRTVDLG9CQUFvQjtJQUNQLFlBQUksR0FBVyxNQUFNLENBQUM7SUFDdEIsYUFBSyxHQUFZLE9BQU8sQ0FBQztJQUN6QixjQUFNLEdBQWEsUUFBUSxDQUFDO0lBQzVCLGVBQU8sR0FBYyxTQUFTLENBQUM7QUFDOUMsQ0FBQyxFQXRCZ0IsT0FBTyxHQUFQLGVBQU8sS0FBUCxlQUFPLFFBc0J2QjtBQUlZLFFBQUEsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDZCxRQUFBLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ2QsUUFBQSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQztBQUNoQixRQUFBLEVBQUUsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDO0FBQ2hCLFFBQUEsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7QUFDbEIsUUFBQSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUN4QixRQUFB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QUMsS0FBSyxFQUFFLElBQUksRUFBQyxDQUFDO1FBQ3ZCLEtBQUssWUFBSTtZQUNQLE1BQU0sQ0FBQyxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQztJQUN4QixDQUFDO0FBQ0gsQ0FBQztBQTlCRCw0Q0E4QkM7QUFFRCxtQkFBMEIsT0FBZ0I7SUFDeEMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNoQixLQUFLLFNBQUMsQ0FBQztRQUNQLEtBQUssU0FBQyxDQUFDO1FBQ1AsS0FBSyxZQUFJLENBQUM7UUFDVixLQUFLLGVBQU8sQ0FBQztRQUNiLHlFQUF5RTtRQUN6RSxLQUFLLFVBQUUsQ0FBQztRQUNSLEtBQUssVUFBRTtZQUNMLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFFdEIsS0FBSyxXQUFHLENBQUM7UUFDVCxLQUFLLGNBQU0sQ0FBQztRQUNaLEtBQUssYUFBSyxDQUFDO1FBQ1gsMERBQTBEO1FBQzFELEtBQUssWUFBSSxDQUFDO1FBQ1YsS0FBSyxlQUFPO1lBQ1YsTUFBTSxDQUFDLFVBQVUsQ0FBQztRQUVwQix1RUFBdUU7UUFDdkUsS0FBSyxhQUFLO1lBQ1IsTUFBTSxDQUFDLFVBQVUsQ0FBQztRQUVwQiwyQkFBMkI7UUFDM0IsS0FBSyxjQUFNLENBQUM7UUFDWixLQUFLLGFBQUs7WUFDUixNQUFNLENBQUMsU0FBUyxDQUFDO0lBQ3JCLENBQUM7SUFDRCxvREFBb0Q7SUFDcEQsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsR0FBRyxPQUFPLENBQUMsQ0FBQztBQUNyRSxDQUFDO0FBOUJELDhCQThCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb25zdGFudHMgYW5kIHV0aWxpdGllcyBmb3IgZW5jb2RpbmcgY2hhbm5lbHMgKFZpc3VhbCB2YXJpYWJsZXMpXG4gKiBzdWNoIGFzICd4JywgJ3knLCAnY29sb3InLlxuICovXG5cbmltcG9ydCB7UmFuZ2VUeXBlfSBmcm9tICcuL2NvbXBpbGUvc2NhbGUvdHlwZSc7XG5pbXBvcnQge0VuY29kaW5nfSBmcm9tICcuL2VuY29kaW5nJztcbmltcG9ydCB7RmFjZXRNYXBwaW5nfSBmcm9tICcuL2ZhY2V0JztcbmltcG9ydCB7TWFya30gZnJvbSAnLi9tYXJrJztcbmltcG9ydCB7U0NBTEVfVFlQRVMsIFNjYWxlVHlwZX0gZnJvbSAnLi9zY2FsZSc7XG5pbXBvcnQge2NvbnRhaW5zLCBGbGFnLCBmbGFnS2V5c30gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IG5hbWVzcGFjZSBDaGFubmVsIHtcbiAgLy8gRmFjZXRcbiAgZXhwb3J0IGNvbnN0IFJPVzogJ3JvdycgPSAncm93JztcbiAgZXhwb3J0IGNvbnN0IENPTFVNTjogJ2NvbHVtbicgPSAnY29sdW1uJztcblxuICAvLyBQb3NpdGlvblxuICBleHBvcnQgY29uc3QgWDogJ3gnID0gJ3gnO1xuICBleHBvcnQgY29uc3QgWTogJ3knID0gJ3knO1xuICBleHBvcnQgY29uc3QgWDI6ICd4MicgPSAneDInO1xuICBleHBvcnQgY29uc3QgWTI6ICd5MicgPSAneTInO1xuXG4gIC8vIE1hcmsgcHJvcGVydHkgd2l0aCBzY2FsZVxuICBleHBvcnQgY29uc3QgQ09MT1I6ICdjb2xvcicgPSAnY29sb3InO1xuICBleHBvcnQgY29uc3QgU0hBUEU6ICdzaGFwZScgPSAnc2hhcGUnO1xuICBleHBvcnQgY29uc3QgU0laRTogJ3NpemUnID0gJ3NpemUnO1xuICBleHBvcnQgY29uc3QgT1BBQ0lUWTogJ29wYWNpdHknID0gJ29wYWNpdHknO1xuXG4gIC8vIE5vbi1zY2FsZSBjaGFubmVsXG4gIGV4cG9ydCBjb25zdCBURVhUOiAndGV4dCcgPSAndGV4dCc7XG4gIGV4cG9ydCBjb25zdCBPUkRFUjogJ29yZGVyJyA9ICdvcmRlcic7XG4gIGV4cG9ydCBjb25zdCBERVRBSUw6ICdkZXRhaWwnID0gJ2RldGFpbCc7XG4gIGV4cG9ydCBjb25zdCBUT09MVElQOiAndG9vbHRpcCcgPSAndG9vbHRpcCc7XG59XG5cbmV4cG9ydCB0eXBlIENoYW5uZWwgPSBrZXlvZiBFbmNvZGluZzxhbnk+IHwga2V5b2YgRmFjZXRNYXBwaW5nPGFueT47XG5cbmV4cG9ydCBjb25zdCBYID0gQ2hhbm5lbC5YO1xuZXhwb3J0IGNvbnN0IFkgPSBDaGFubmVsLlk7XG5leHBvcnQgY29uc3QgWDIgPSBDaGFubmVsLlgyO1xuZXhwb3J0IGNvbnN0IFkyID0gQ2hhbm5lbC5ZMjtcbmV4cG9ydCBjb25zdCBST1cgPSBDaGFubmVsLlJPVztcbmV4cG9ydCBjb25zdCBDT0xVTU4gPSBDaGFubmVsLkNPTFVNTjtcbmV4cG9ydCBjb25zdCBTSEFQRSA9IENoYW5uZWwuU0hBUEU7XG5leHBvcnQgY29uc3QgU0laRSA9IENoYW5uZWwuU0laRTtcbmV4cG9ydCBjb25zdCBDT0xPUiA9IENoYW5uZWwuQ09MT1I7XG5leHBvcnQgY29uc3QgVEVYVCA9IENoYW5uZWwuVEVYVDtcbmV4cG9ydCBjb25zdCBERVRBSUwgPSBDaGFubmVsLkRFVEFJTDtcbmV4cG9ydCBjb25zdCBPUkRFUiA9IENoYW5uZWwuT1JERVI7XG5leHBvcnQgY29uc3QgT1BBQ0lUWSA9IENoYW5uZWwuT1BBQ0lUWTtcbmV4cG9ydCBjb25zdCBUT09MVElQID0gQ2hhbm5lbC5UT09MVElQO1xuXG5jb25zdCBVTklUX0NIQU5ORUxfSU5ERVg6IEZsYWc8a2V5b2YgRW5jb2Rpbmc8YW55Pj4gPSB7XG4gIHg6IDEsXG4gIHk6IDEsXG4gIHgyOiAxLFxuICB5MjogMSxcbiAgc2l6ZTogMSxcbiAgc2hhcGU6IDEsXG4gIGNvbG9yOiAxLFxuICBvcmRlcjogMSxcbiAgb3BhY2l0eTogMSxcbiAgdGV4dDogMSxcbiAgZGV0YWlsOiAxLFxuICB0b29sdGlwOiAxXG59O1xuXG5jb25zdCBGQUNFVF9DSEFOTkVMX0lOREVYOiBGbGFnPGtleW9mIEZhY2V0TWFwcGluZzxhbnk+PiA9IHtcbiAgcm93OiAxLFxuICBjb2x1bW46IDFcbn07XG5cbmNvbnN0IENIQU5ORUxfSU5ERVggPSB7XG4gIC4uLlVOSVRfQ0hBTk5FTF9JTkRFWCxcbiAgLi4uRkFDRVRfQ0hBTk5FTF9JTkRFWFxufTtcblxuZXhwb3J0IGNvbnN0IENIQU5ORUxTID0gZmxhZ0tleXMoQ0hBTk5FTF9JTkRFWCk7XG5cbmNvbnN0IHtvcmRlcjogX28sIGRldGFpbDogX2QsIC4uLlNJTkdMRV9ERUZfQ0hBTk5FTF9JTkRFWH0gPSBDSEFOTkVMX0lOREVYO1xuLyoqXG4gKiBDaGFubmVscyB0aGF0IGNhbm5vdCBoYXZlIGFuIGFycmF5IG9mIGNoYW5uZWxEZWYuXG4gKiBtb2RlbC5maWVsZERlZiwgZ2V0RmllbGREZWYgb25seSB3b3JrIGZvciB0aGVzZSBjaGFubmVscy5cbiAqXG4gKiAoVGhlIG9ubHkgdHdvIGNoYW5uZWxzIHRoYXQgY2FuIGhhdmUgYW4gYXJyYXkgb2YgY2hhbm5lbERlZnMgYXJlIFwiZGV0YWlsXCIgYW5kIFwib3JkZXJcIi5cbiAqIFNpbmNlIHRoZXJlIGNhbiBiZSBtdWx0aXBsZSBmaWVsZERlZnMgZm9yIGRldGFpbCBhbmQgb3JkZXIsIGdldEZpZWxkRGVmL21vZGVsLmZpZWxkRGVmXG4gKiBhcmUgbm90IGFwcGxpY2FibGUgZm9yIHRoZW0uICBTaW1pbGFybHksIHNlbGVjdGlvbiBwcm9qZWN0dGlvbiB3b24ndCB3b3JrIHdpdGggXCJkZXRhaWxcIiBhbmQgXCJvcmRlclwiLilcbiAqL1xuXG5leHBvcnQgY29uc3QgU0lOR0xFX0RFRl9DSEFOTkVMUzogU2luZ2xlRGVmQ2hhbm5lbFtdID0gZmxhZ0tleXMoU0lOR0xFX0RFRl9DSEFOTkVMX0lOREVYKTtcblxuLy8gVXNpbmcgdGhlIGZvbGxvd2luZyBsaW5lIGxlYWRzIHRvIFR5cGVFcnJvcjogQ2Fubm90IHJlYWQgcHJvcGVydHkgJ2VsZW1lbnRUeXBlcycgb2YgdW5kZWZpbmVkXG4vLyB3aGVuIHJ1bm5pbmcgdGhlIHNjaGVtYSBnZW5lcmF0b3Jcbi8vIGV4cG9ydCB0eXBlIFNpbmdsZURlZkNoYW5uZWwgPSB0eXBlb2YgU0lOR0xFX0RFRl9DSEFOTkVMU1swXTtcbmV4cG9ydCB0eXBlIFNpbmdsZURlZkNoYW5uZWwgPSAneCcgfCAneScgfCAneDInIHwgJ3kyJyB8ICdyb3cnIHwgJ2NvbHVtbicgfCAnc2l6ZScgfCAnc2hhcGUnIHwgJ2NvbG9yJyB8ICdvcGFjaXR5JyB8ICd0ZXh0JyB8ICd0b29sdGlwJztcblxuXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NoYW5uZWwoc3RyOiBzdHJpbmcpOiBzdHIgaXMgQ2hhbm5lbCB7XG4gIHJldHVybiAhIUNIQU5ORUxfSU5ERVhbc3RyXTtcbn1cblxuLy8gQ0hBTk5FTFMgd2l0aG91dCBDT0xVTU4sIFJPV1xuZXhwb3J0IGNvbnN0IFVOSVRfQ0hBTk5FTFMgPSBmbGFnS2V5cyhVTklUX0NIQU5ORUxfSU5ERVgpO1xuXG5cbi8vIE5PTlBPU0lUSU9OX0NIQU5ORUxTID0gVU5JVF9DSEFOTkVMUyB3aXRob3V0IFgsIFksIFgyLCBZMjtcbmNvbnN0IHtcbiAgeDogX3gsIHk6IF95LFxuICAvLyB4MiBhbmQgeTIgc2hhcmUgdGhlIHNhbWUgc2NhbGUgYXMgeCBhbmQgeVxuICB4MjogX3gyLCB5MjogX3kyLFxuICAvLyBUaGUgcmVzdCBvZiB1bml0IGNoYW5uZWxzIHRoZW4gaGF2ZSBzY2FsZVxuICAuLi5OT05QT1NJVElPTl9DSEFOTkVMX0lOREVYXG59ID0gVU5JVF9DSEFOTkVMX0lOREVYO1xuXG5leHBvcnQgY29uc3QgTk9OUE9TSVRJT05fQ0hBTk5FTFMgPSBmbGFnS2V5cyhOT05QT1NJVElPTl9DSEFOTkVMX0lOREVYKTtcbmV4cG9ydCB0eXBlIE5vblBvc2l0aW9uQ2hhbm5lbCA9IHR5cGVvZiBOT05QT1NJVElPTl9DSEFOTkVMU1swXTtcblxuLy8gUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMgPSBYIGFuZCBZO1xuY29uc3QgUE9TSVRJT05fU0NBTEVfQ0hBTk5FTF9JTkRFWDoge3g6MSwgeToxfSA9IHt4OjEsIHk6MX07XG5leHBvcnQgY29uc3QgUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMgPSBmbGFnS2V5cyhQT1NJVElPTl9TQ0FMRV9DSEFOTkVMX0lOREVYKTtcbmV4cG9ydCB0eXBlIFBvc2l0aW9uU2NhbGVDaGFubmVsID0gdHlwZW9mIFBPU0lUSU9OX1NDQUxFX0NIQU5ORUxTWzBdO1xuXG4vLyBOT05fUE9TSVRJT05fU0NBTEVfQ0hBTk5FTCA9IFNDQUxFX0NIQU5ORUxTIHdpdGhvdXQgWCwgWVxuY29uc3Qge1xuICAgIC8vIHgyIGFuZCB5MiBzaGFyZSB0aGUgc2FtZSBzY2FsZSBhcyB4IGFuZCB5XG4gIC8vIHRleHQgYW5kIHRvb2x0aXAgaGFzIGZvcm1hdCBpbnN0ZWFkIG9mIHNjYWxlXG4gIHRleHQ6IF90LCB0b29sdGlwOiBfdHQsXG4gIC8vIGRldGFpbCBhbmQgb3JkZXIgaGF2ZSBubyBzY2FsZVxuICBkZXRhaWw6IF9kZCwgb3JkZXI6IF9vbyxcbiAgLi4uTk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTF9JTkRFWFxufSA9IE5PTlBPU0lUSU9OX0NIQU5ORUxfSU5ERVg7XG5leHBvcnQgY29uc3QgTk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMgPSBmbGFnS2V5cyhOT05QT1NJVElPTl9TQ0FMRV9DSEFOTkVMX0lOREVYKTtcbmV4cG9ydCB0eXBlIE5vblBvc2l0aW9uU2NhbGVDaGFubmVsID0gdHlwZW9mIE5PTlBPU0lUSU9OX1NDQUxFX0NIQU5ORUxTWzBdO1xuXG4vLyBEZWNsYXJlIFNDQUxFX0NIQU5ORUxfSU5ERVhcbmNvbnN0IFNDQUxFX0NIQU5ORUxfSU5ERVggPSB7XG4gIC4uLlBPU0lUSU9OX1NDQUxFX0NIQU5ORUxfSU5ERVgsXG4gIC4uLk5PTlBPU0lUSU9OX1NDQUxFX0NIQU5ORUxfSU5ERVhcbn07XG5cbi8qKiBMaXN0IG9mIGNoYW5uZWxzIHdpdGggc2NhbGVzICovXG5leHBvcnQgY29uc3QgU0NBTEVfQ0hBTk5FTFMgPSBmbGFnS2V5cyhTQ0FMRV9DSEFOTkVMX0lOREVYKTtcbmV4cG9ydCB0eXBlIFNjYWxlQ2hhbm5lbCA9IHR5cGVvZiBTQ0FMRV9DSEFOTkVMU1swXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2NhbGVDaGFubmVsKGNoYW5uZWw6IENoYW5uZWwpOiBjaGFubmVsIGlzIFNjYWxlQ2hhbm5lbCB7XG4gIHJldHVybiAhIVNDQUxFX0NIQU5ORUxfSU5ERVhbY2hhbm5lbF07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VwcG9ydGVkTWFyayB7XG4gIHBvaW50PzogYm9vbGVhbjtcbiAgdGljaz86IGJvb2xlYW47XG4gIHJ1bGU/OiBib29sZWFuO1xuICBjaXJjbGU/OiBib29sZWFuO1xuICBzcXVhcmU/OiBib29sZWFuO1xuICBiYXI/OiBib29sZWFuO1xuICByZWN0PzogYm9vbGVhbjtcbiAgbGluZT86IGJvb2xlYW47XG4gIGFyZWE/OiBib29sZWFuO1xuICB0ZXh0PzogYm9vbGVhbjtcbiAgdG9vbHRpcD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgYSBjaGFubmVsIHN1cHBvcnRzIGEgcGFydGljdWxhciBtYXJrIHR5cGUuXG4gKiBAcGFyYW0gY2hhbm5lbCAgY2hhbm5lbCBuYW1lXG4gKiBAcGFyYW0gbWFyayB0aGUgbWFyayB0eXBlXG4gKiBAcmV0dXJuIHdoZXRoZXIgdGhlIG1hcmsgc3VwcG9ydHMgdGhlIGNoYW5uZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRNYXJrKGNoYW5uZWw6IENoYW5uZWwsIG1hcms6IE1hcmspIHtcbiAgcmV0dXJuIG1hcmsgaW4gZ2V0U3VwcG9ydGVkTWFyayhjaGFubmVsKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBkaWN0aW9uYXJ5IHNob3dpbmcgd2hldGhlciBhIGNoYW5uZWwgc3VwcG9ydHMgbWFyayB0eXBlLlxuICogQHBhcmFtIGNoYW5uZWxcbiAqIEByZXR1cm4gQSBkaWN0aW9uYXJ5IG1hcHBpbmcgbWFyayB0eXBlcyB0byBib29sZWFuIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN1cHBvcnRlZE1hcmsoY2hhbm5lbDogQ2hhbm5lbCk6IFN1cHBvcnRlZE1hcmsge1xuICBzd2l0Y2ggKGNoYW5uZWwpIHtcbiAgICBjYXNlIFg6XG4gICAgY2FzZSBZOlxuICAgIGNhc2UgQ09MT1I6XG4gICAgY2FzZSBERVRBSUw6XG4gICAgY2FzZSBUT09MVElQOlxuICAgIGNhc2UgT1JERVI6ICAgIC8vIFRPRE86IHJldmlzZSAob3JkZXIgbWlnaHQgbm90IHN1cHBvcnQgcmVjdCwgd2hpY2ggaXMgbm90IHN0YWNrYWJsZT8pXG4gICAgY2FzZSBPUEFDSVRZOlxuICAgIGNhc2UgUk9XOlxuICAgIGNhc2UgQ09MVU1OOlxuICAgICAgcmV0dXJuIHsgLy8gYWxsIG1hcmtzXG4gICAgICAgIHBvaW50OiB0cnVlLCB0aWNrOiB0cnVlLCBydWxlOiB0cnVlLCBjaXJjbGU6IHRydWUsIHNxdWFyZTogdHJ1ZSxcbiAgICAgICAgYmFyOiB0cnVlLCByZWN0OiB0cnVlLCBsaW5lOiB0cnVlLCBhcmVhOiB0cnVlLCB0ZXh0OiB0cnVlXG4gICAgICB9O1xuICAgIGNhc2UgWDI6XG4gICAgY2FzZSBZMjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJ1bGU6IHRydWUsIGJhcjogdHJ1ZSwgcmVjdDogdHJ1ZSwgYXJlYTogdHJ1ZVxuICAgICAgfTtcbiAgICBjYXNlIFNJWkU6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwb2ludDogdHJ1ZSwgdGljazogdHJ1ZSwgcnVsZTogdHJ1ZSwgY2lyY2xlOiB0cnVlLCBzcXVhcmU6IHRydWUsXG4gICAgICAgIGJhcjogdHJ1ZSwgdGV4dDogdHJ1ZSwgbGluZTogdHJ1ZVxuICAgICAgfTtcbiAgICBjYXNlIFNIQVBFOlxuICAgICAgcmV0dXJuIHtwb2ludDogdHJ1ZX07XG4gICAgY2FzZSBURVhUOlxuICAgICAgcmV0dXJuIHt0ZXh0OiB0cnVlfTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2VUeXBlKGNoYW5uZWw6IENoYW5uZWwpOiBSYW5nZVR5cGUge1xuICBzd2l0Y2ggKGNoYW5uZWwpIHtcbiAgICBjYXNlIFg6XG4gICAgY2FzZSBZOlxuICAgIGNhc2UgU0laRTpcbiAgICBjYXNlIE9QQUNJVFk6XG4gICAgLy8gWDIgYW5kIFkyIHVzZSBYIGFuZCBZIHNjYWxlcywgc28gdGhleSBzaW1pbGFybHkgaGF2ZSBjb250aW51b3VzIHJhbmdlLlxuICAgIGNhc2UgWDI6XG4gICAgY2FzZSBZMjpcbiAgICAgIHJldHVybiAnY29udGludW91cyc7XG5cbiAgICBjYXNlIFJPVzpcbiAgICBjYXNlIENPTFVNTjpcbiAgICBjYXNlIFNIQVBFOlxuICAgIC8vIFRFWFQgYW5kIFRPT0xUSVAgaGF2ZSBubyBzY2FsZSBidXQgaGF2ZSBkaXNjcmV0ZSBvdXRwdXRcbiAgICBjYXNlIFRFWFQ6XG4gICAgY2FzZSBUT09MVElQOlxuICAgICAgcmV0dXJuICdkaXNjcmV0ZSc7XG5cbiAgICAvLyBDb2xvciBjYW4gYmUgZWl0aGVyIGNvbnRpbnVvdXMgb3IgZGlzY3JldGUsIGRlcGVuZGluZyBvbiBzY2FsZSB0eXBlLlxuICAgIGNhc2UgQ09MT1I6XG4gICAgICByZXR1cm4gJ2ZsZXhpYmxlJztcblxuICAgIC8vIE5vIHNjYWxlLCBubyByYW5nZSB0eXBlLlxuICAgIGNhc2UgREVUQUlMOlxuICAgIGNhc2UgT1JERVI6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBzaG91bGQgbmV2ZXIgcmVhY2ggaGVyZS4gKi9cbiAgdGhyb3cgbmV3IEVycm9yKCdnZXRTdXBwb3J0ZWRSb2xlIG5vdCBpbXBsZW1lbnRlZCBmb3IgJyArIGNoYW5uZWwpO1xufVxuIl19 \ 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..93eb3ee608 --- /dev/null +++ b/build/src/compile/axis/assemble.d.ts @@ -0,0 +1,3 @@ +import { VgAxis } from '../../vega.schema'; +import { AxisComponentIndex } from './component'; +export declare function assembleAxes(axisComponents: AxisComponentIndex): VgAxis[]; diff --git a/build/src/compile/axis/assemble.js b/build/src/compile/axis/assemble.js new file mode 100644 index 0000000000..ad04a2de2e --- /dev/null +++ b/build/src/compile/axis/assemble.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var mainAxisReducer = getAxisReducer('main'); +var gridAxisReducer = getAxisReducer('grid'); +function getAxisReducer(axisType) { + return function (axes, axis) { + if (axis[axisType]) { + // Need to cast here so it's not longer partial type. + axes.push(axis[axisType].combine()); + } + return axes; + }; +} +function assembleAxes(axisComponents) { + return [].concat(axisComponents.x ? [].concat(axisComponents.x.reduce(mainAxisReducer, []), axisComponents.x.reduce(gridAxisReducer, [])) : [], axisComponents.y ? [].concat(axisComponents.y.reduce(mainAxisReducer, []), axisComponents.y.reduce(gridAxisReducer, [])) : []); +} +exports.assembleAxes = assembleAxes; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9heGlzL2Fzc2VtYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBSUEsSUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQy9DLElBQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUUvQyx3QkFBd0IsUUFBeUI7SUFDL0MsTUFBTSxDQUFDLFVBQUMsSUFBYyxFQUFFLElBQW1CO1FBQ3pDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkIscURBQXFEO1lBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sRUFBWSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsc0JBQTZCLGNBQWtDO0lBQzdELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUNkLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQzFCLGNBQWMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsRUFDNUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUM3QyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQ04sY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FDMUIsY0FBYyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxFQUM1QyxjQUFjLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQzdDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDUCxDQUFDO0FBQ0osQ0FBQztBQVhELG9DQVdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtWZ0F4aXN9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7QXhpc0NvbXBvbmVudCwgQXhpc0NvbXBvbmVudEluZGV4fSBmcm9tICcuL2NvbXBvbmVudCc7XG5cblxuY29uc3QgbWFpbkF4aXNSZWR1Y2VyID0gZ2V0QXhpc1JlZHVjZXIoJ21haW4nKTtcbmNvbnN0IGdyaWRBeGlzUmVkdWNlciA9IGdldEF4aXNSZWR1Y2VyKCdncmlkJyk7XG5cbmZ1bmN0aW9uIGdldEF4aXNSZWR1Y2VyKGF4aXNUeXBlOiAnbWFpbicgfCAnZ3JpZCcpIHtcbiAgcmV0dXJuIChheGVzOiBWZ0F4aXNbXSwgYXhpczogQXhpc0NvbXBvbmVudCkgPT4ge1xuICAgIGlmIChheGlzW2F4aXNUeXBlXSkge1xuICAgICAgLy8gTmVlZCB0byBjYXN0IGhlcmUgc28gaXQncyBub3QgbG9uZ2VyIHBhcnRpYWwgdHlwZS5cbiAgICAgIGF4ZXMucHVzaChheGlzW2F4aXNUeXBlXS5jb21iaW5lKCkgYXMgVmdBeGlzKTtcbiAgICB9XG4gICAgcmV0dXJuIGF4ZXM7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlbWJsZUF4ZXMoYXhpc0NvbXBvbmVudHM6IEF4aXNDb21wb25lbnRJbmRleCk6IFZnQXhpc1tdIHtcbiAgcmV0dXJuIFtdLmNvbmNhdChcbiAgICBheGlzQ29tcG9uZW50cy54ID8gW10uY29uY2F0KFxuICAgICAgYXhpc0NvbXBvbmVudHMueC5yZWR1Y2UobWFpbkF4aXNSZWR1Y2VyLCBbXSksXG4gICAgICBheGlzQ29tcG9uZW50cy54LnJlZHVjZShncmlkQXhpc1JlZHVjZXIsIFtdKVxuICAgICkgOiBbXSxcbiAgICBheGlzQ29tcG9uZW50cy55ID8gW10uY29uY2F0KFxuICAgICAgYXhpc0NvbXBvbmVudHMueS5yZWR1Y2UobWFpbkF4aXNSZWR1Y2VyLCBbXSksXG4gICAgICBheGlzQ29tcG9uZW50cy55LnJlZHVjZShncmlkQXhpc1JlZHVjZXIsIFtdKSxcbiAgICApIDogW11cbiAgKTtcbn1cblxuIl19 \ 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..a265b8305b --- /dev/null +++ b/build/src/compile/axis/component.d.ts @@ -0,0 +1,17 @@ +import { Axis } from '../../axis'; +import { VgAxis } from '../../vega.schema'; +import { Split } from '../split'; +export declare class AxisComponentPart extends Split> { +} +export interface AxisComponent { + main?: AxisComponentPart; + grid?: AxisComponentPart; +} +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..00f5d90e0e --- /dev/null +++ b/build/src/compile/axis/component.js @@ -0,0 +1,22 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var split_1 = require("../split"); +var AxisComponentPart = /** @class */ (function (_super) { + __extends(AxisComponentPart, _super); + function AxisComponentPart() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AxisComponentPart; +}(split_1.Split)); +exports.AxisComponentPart = AxisComponentPart; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvYXhpcy9jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBRUEsa0NBQStCO0FBRS9CO0lBQXVDLHFDQUFzQjtJQUE3RDs7SUFBK0QsQ0FBQztJQUFELHdCQUFDO0FBQUQsQ0FBQyxBQUFoRSxDQUF1QyxhQUFLLEdBQW9CO0FBQW5ELDhDQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QXhpc30gZnJvbSAnLi4vLi4vYXhpcyc7XG5pbXBvcnQge1ZnQXhpc30gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtTcGxpdH0gZnJvbSAnLi4vc3BsaXQnO1xuXG5leHBvcnQgY2xhc3MgQXhpc0NvbXBvbmVudFBhcnQgZXh0ZW5kcyBTcGxpdDxQYXJ0aWFsPFZnQXhpcz4+IHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXhpc0NvbXBvbmVudCB7XG4gIG1haW4/OiBBeGlzQ29tcG9uZW50UGFydDtcbiAgZ3JpZD86IEF4aXNDb21wb25lbnRQYXJ0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF4aXNDb21wb25lbnRJbmRleCB7XG4gIHg/OiBBeGlzQ29tcG9uZW50W107XG4gIHk/OiBBeGlzQ29tcG9uZW50W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXhpc0luZGV4IHtcbiAgeD86IEF4aXM7XG4gIHk/OiBBeGlzO1xufVxuIl19 \ 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..74a8c4d4bc --- /dev/null +++ b/build/src/compile/axis/config.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +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; +} +exports.getAxisConfig = getAxisConfig; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvYXhpcy9jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFJQSx1QkFBOEIsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsT0FBNkIsRUFBRSxNQUFtQixFQUFFLFNBQW9CO0lBQXpDLHVCQUFBLEVBQUEsV0FBbUI7SUFDaEgsdURBQXVEO0lBQ3ZELElBQU0sV0FBVyxHQUFHLENBQUMsU0FBUyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ3BFLE9BQU8sS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTztRQUNuQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDNUQsTUFBTTtLQUNQLENBQUMsQ0FBQztJQUNILEdBQUcsQ0FBQyxDQUFxQixVQUFXLEVBQVgsMkJBQVcsRUFBWCx5QkFBVyxFQUFYLElBQVc7UUFBL0IsSUFBTSxVQUFVLG9CQUFBO1FBQ25CLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNyRSxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7S0FDRjtJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQWRELHNDQWNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtQb3NpdGlvblNjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vLi4vY29uZmlnJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBeGlzQ29uZmlnKHByb3BlcnR5OiBzdHJpbmcsIGNvbmZpZzogQ29uZmlnLCBjaGFubmVsOiBQb3NpdGlvblNjYWxlQ2hhbm5lbCwgb3JpZW50OiBzdHJpbmcgPSAnJywgc2NhbGVUeXBlOiBTY2FsZVR5cGUpIHtcbiAgLy8gY29uZmlnVHlwZXMgdG8gbG9vcCwgc3RhcnRpbmcgZnJvbSBoaWdoZXIgcHJlY2VkZW5jZVxuICBjb25zdCBjb25maWdUeXBlcyA9IChzY2FsZVR5cGUgPT09ICdiYW5kJyA/IFsnYXhpc0JhbmQnXSA6IFtdKS5jb25jYXQoW1xuICAgIGNoYW5uZWwgPT09ICd4JyA/ICdheGlzWCcgOiAnYXhpc1knLFxuICAgICdheGlzJyArIG9yaWVudC5zdWJzdHIoMCwxKS50b1VwcGVyQ2FzZSgpICsgb3JpZW50LnN1YnN0cigxKSwgLy8gYXhpc1RvcCwgYXhpc0JvdHRvbSwgLi4uXG4gICAgJ2F4aXMnXG4gIF0pO1xuICBmb3IgKGNvbnN0IGNvbmZpZ1R5cGUgb2YgY29uZmlnVHlwZXMpIHtcbiAgICBpZiAoY29uZmlnW2NvbmZpZ1R5cGVdICYmIGNvbmZpZ1tjb25maWdUeXBlXVtwcm9wZXJ0eV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGNvbmZpZ1tjb25maWdUeXBlXVtwcm9wZXJ0eV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiJdfQ== \ 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..219ed28864 --- /dev/null +++ b/build/src/compile/axis/encode.d.ts @@ -0,0 +1,8 @@ +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 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..c4c3ff2ed0 --- /dev/null +++ b/build/src/compile/axis/encode.js @@ -0,0 +1,83 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var config_1 = require("./config"); +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 (fielddef_1.isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === scale_1.ScaleType.UTC; + labelsSpec.text = { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale) + }; + } + // Label Angle + var angle = config_1.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 && channel === 'x') { + var align = labelAlign(angle, orient); + if (align) { + labelsSpec.align = { value: align }; + } + // Auto set baseline if x is rotated by 90, or -90 + if (util_1.contains([90, 270], angle)) { + labelsSpec.baseline = { value: 'middle' }; + } + } + labelsSpec = __assign({}, labelsSpec, specifiedLabelsSpec); + return util_1.keys(labelsSpec).length === 0 ? undefined : labelsSpec; +} +exports.labels = labels; +function labelAngle(axis, channel, fieldDef) { + if (axis.labelAngle !== undefined) { + // Make angle within [0,360) + return ((axis.labelAngle % 360) + 360) % 360; + } + else { + if (channel === channel_1.X && util_1.contains([type_1.NOMINAL, type_1.ORDINAL], fieldDef.type)) { + return 270; + } + } + return undefined; +} +exports.labelAngle = labelAngle; +function labelAlign(angle, orient) { + if (angle > 0) { + if (angle % 360 > 180) { + return orient === 'top' ? 'left' : 'right'; + } + else if (angle % 360 < 180) { + return orient === 'top' ? 'right' : 'left'; + } + } + else if (angle < 0) { + return labelAlign((angle % 360) + 360 /* convert to positive value*/, orient); + } + return undefined; +} +exports.labelAlign = labelAlign; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvYXhpcy9lbmNvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUNBLHlDQUErRDtBQUMvRCwyQ0FBd0Q7QUFDeEQscUNBQXNDO0FBQ3RDLG1DQUE0QztBQUM1QyxtQ0FBMEM7QUFFMUMsb0NBQStDO0FBRS9DLG1DQUF1QztBQUV2QyxnQkFBdUIsS0FBZ0IsRUFBRSxPQUE2QixFQUFFLG1CQUF3QixFQUFFLE1BQWtCO0lBQ2xILElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1FBQ3RDLENBQ0UsT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLE9BQU8sS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDeEMsU0FBUyxDQUNWLENBQUM7SUFDSixJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pDLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFFNUIsSUFBSSxVQUFVLEdBQVEsRUFBRSxDQUFDO0lBRXpCLE9BQU87SUFDUCxFQUFFLENBQUMsQ0FBQyx5QkFBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLGlCQUFTLENBQUMsR0FBRyxDQUFDO1FBRWxGLFVBQVUsQ0FBQyxJQUFJLEdBQUc7WUFDaEIsTUFBTSxFQUFFLDZCQUFvQixDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxN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QUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsOEJBQThCLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUNELE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQVhELGdDQVdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBeGlzfSBmcm9tICcuLi8uLi9heGlzJztcbmltcG9ydCB7Q2hhbm5lbCwgUG9zaXRpb25TY2FsZUNoYW5uZWwsIFh9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtGaWVsZERlZiwgaXNUaW1lRmllbGREZWZ9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge05PTUlOQUwsIE9SRElOQUx9IGZyb20gJy4uLy4uL3R5cGUnO1xuaW1wb3J0IHtjb250YWlucywga2V5c30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge0F4aXNPcmllbnQsIEhvcml6b250YWxBbGlnbn0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHt0aW1lRm9ybWF0RXhwcmVzc2lvbn0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7Z2V0QXhpc0NvbmZpZ30gZnJvbSAnLi9jb25maWcnO1xuXG5leHBvcnQgZnVuY3Rpb24gbGFiZWxzKG1vZGVsOiBVbml0TW9kZWwsIGNoYW5uZWw6IFBvc2l0aW9uU2NhbGVDaGFubmVsLCBzcGVjaWZpZWRMYWJlbHNTcGVjOiBhbnksIG9yaWVudDogQXhpc09yaWVudCkge1xuICBjb25zdCBmaWVsZERlZiA9IG1vZGVsLmZpZWxkRGVmKGNoYW5uZWwpIHx8XG4gICAgKFxuICAgICAgY2hhbm5lbCA9PT0gJ3gnID8gbW9kZWwuZmllbGREZWYoJ3gyJykgOlxuICAgICAgY2hhbm5lbCA9PT0gJ3knID8gbW9kZWwuZmllbGREZWYoJ3kyJykgOlxuICAgICAgdW5kZWZpbmVkXG4gICAgKTtcbiAgY29uc3QgYXhpcyA9IG1vZGVsLmF4aXMoY2hhbm5lbCk7XG4gIGNvbnN0IGNvbmZpZyA9IG1vZGVsLmNvbmZpZztcblxuICBsZXQgbGFiZWxzU3BlYzogYW55ID0ge307XG5cbiAgLy8gVGV4dFxuICBpZiAoaXNUaW1lRmllbGREZWYoZmllbGREZWYpKSB7XG4gICAgY29uc3QgaXNVVENTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpLmdldCgndHlwZScpID09PSBTY2FsZVR5cGUuVVRDO1xuXG4gICAgbGFiZWxzU3BlYy50ZXh0ID0ge1xuICAgICAgc2lnbmFsOiB0aW1lRm9ybWF0RXhwcmVzc2lvbignZGF0dW0udmFsdWUnLCBmaWVsZERlZi50aW1lVW5pdCwgYXhpcy5mb3JtYXQsIGNvbmZpZy5heGlzLnNob3J0VGltZUxhYmVscywgY29uZmlnLnRpbWVGb3JtYXQsIGlzVVRDU2NhbGUpXG4gICAgfTtcbiAgfVxuXG4gIC8vIExhYmVsIEFuZ2xlXG4gIGxldCBhbmdsZSA9IGdldEF4aXNDb25maWcoJ2xhYmVsQW5nbGUnLCBtb2RlbC5jb25maWcsIGNoYW5uZWwsIG9yaWVudCwgbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoY2hhbm5lbCkuZ2V0KCd0eXBlJykpO1xuICBpZiAoYW5nbGUgPT09IHVuZGVmaW5lZCkge1xuICAgIGFuZ2xlID0gbGFiZWxBbmdsZShheGlzLCBjaGFubmVsLCBmaWVsZERlZik7XG4gICAgaWYgKGFuZ2xlKSB7XG4gICAgICBsYWJlbHNTcGVjLmFuZ2xlID0ge3ZhbHVlOiBhbmdsZX07XG4gICAgfVxuICB9XG5cbiAgaWYgKGFuZ2xlICE9PSB1bmRlZmluZWQgJiYgY2hhbm5lbCA9PT0gJ3gnKSB7XG4gICAgY29uc3QgYWxpZ24gPSBsYWJlbEFsaWduKGFuZ2xlLCBvcmllbnQpO1xuICAgIGlmIChhbGlnbikge1xuICAgICAgbGFiZWxzU3BlYy5hbGlnbiA9IHt2YWx1ZTogYWxpZ259O1xuICAgIH1cblxuICAgIC8vIEF1dG8gc2V0IGJhc2VsaW5lIGlmIHggaXMgcm90YXRlZCBieSA5MCwgb3IgLTkwXG4gICAgaWYgKGNvbnRhaW5zKFs5MCwgMjcwXSwgYW5nbGUpKSB7XG4gICAgICBsYWJlbHNTcGVjLmJhc2VsaW5lID0ge3ZhbHVlOiAnbWlkZGxlJ307XG4gICAgfVxuICB9XG5cbiAgbGFiZWxzU3BlYyA9IHtcbiAgICAuLi5sYWJlbHNTcGVjLFxuICAgIC4uLnNwZWNpZmllZExhYmVsc1NwZWNcbiAgfTtcblxuICByZXR1cm4ga2V5cyhsYWJlbHNTcGVjKS5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBsYWJlbHNTcGVjO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGxhYmVsQW5nbGUoYXhpczogQXhpcywgY2hhbm5lbDogQ2hhbm5lbCwgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4pIHtcbiAgaWYgKGF4aXMubGFiZWxBbmdsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gTWFrZSBhbmdsZSB3aXRoaW4gWzAsMzYwKVxuICAgIHJldHVybiAoKGF4aXMubGFiZWxBbmdsZSAlIDM2MCkgKyAzNjApICUgMzYwO1xuICB9IGVsc2Uge1xuICAgIGlmIChjaGFubmVsID09PSBYICYmIGNvbnRhaW5zKFtOT01JTkFMLCBPUkRJTkFMXSwgZmllbGREZWYudHlwZSkpIHtcbiAgICAgIHJldHVybiAyNzA7XG4gICAgfVxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsYWJlbEFsaWduKGFuZ2xlOiBudW1iZXIsIG9yaWVudDogQXhpc09yaWVudCk6IEhvcml6b250YWxBbGlnbiB7XG4gIGlmIChhbmdsZSA+IDApIHtcbiAgICBpZiAoYW5nbGUgJSAzNjAgPiAxODApIHtcbiAgICAgIHJldHVybiBvcmllbnQgPT09ICd0b3AnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICB9IGVsc2UgaWYgKGFuZ2xlICUgMzYwIDwgMTgwKSB7XG4gICAgICByZXR1cm4gb3JpZW50ID09PSAndG9wJyA/ICdyaWdodCc6ICdsZWZ0JztcbiAgICB9XG4gIH0gZWxzZSBpZiAoYW5nbGUgPCAwKSB7XG4gICAgcmV0dXJuIGxhYmVsQWxpZ24oKGFuZ2xlICUgMzYwKSArIDM2MCAvKiBjb252ZXJ0IHRvIHBvc2l0aXZlIHZhbHVlKi8sIG9yaWVudCk7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuIl19 \ 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..e5b682454a --- /dev/null +++ b/build/src/compile/axis/parse.d.ts @@ -0,0 +1,11 @@ +import { PositionScaleChannel } from '../../channel'; +import { LayerModel } from '../layer'; +import { UnitModel } from '../unit'; +import { AxisComponentIndex, AxisComponentPart } from './component'; +export declare function parseUnitAxis(model: UnitModel): AxisComponentIndex; +export declare function parseLayerAxis(model: LayerModel): void; +/** + * Make an inner axis for showing grid for shared axis. + */ +export declare function parseGridAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponentPart; +export declare function parseMainAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponentPart; diff --git a/build/src/compile/axis/parse.js b/build/src/compile/axis/parse.js new file mode 100644 index 0000000000..c0c358f1c2 --- /dev/null +++ b/build/src/compile/axis/parse.js @@ -0,0 +1,298 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var axis_1 = require("../../axis"); +var channel_1 = require("../../channel"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var resolve_1 = require("../resolve"); +var split_1 = require("../split"); +var component_1 = require("./component"); +var config_1 = require("./config"); +var encode = require("./encode"); +var properties = require("./properties"); +var AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title']; +function parseUnitAxis(model) { + return channel_1.POSITION_SCALE_CHANNELS.reduce(function (axis, channel) { + if (model.axis(channel)) { + var axisComponent = {}; + // TODO: support multiple axis + var main = parseMainAxis(channel, model); + if (main && isVisibleAxis(main)) { + axisComponent.main = main; + } + var grid = parseGridAxis(channel, model); + if (grid && isVisibleAxis(grid)) { + axisComponent.grid = grid; + } + axis[channel] = [axisComponent]; + } + return axis; + }, {}); +} +exports.parseUnitAxis = parseUnitAxis; +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 = util_1.keys(child.component.axes); _c < _d.length; _c++) { + var channel = _d[_c]; + resolve.axis[channel] = resolve_1.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.main.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.main.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]; + } + } +} +exports.parseLayerAxis = parseLayerAxis; +function mergeAxisComponents(mergedAxisCmpts, childAxisCmpts) { + if (mergedAxisCmpts) { + 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 mergedMain = mergedAxisCmpts[i].main; + var childMain = childAxisCmpts[i].main; + if ((!!mergedMain) !== (!!childMain)) { + return undefined; + } + else if (mergedMain && childMain) { + var mergedOrient = mergedMain.getWithExplicit('orient'); + var childOrient = childMain.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].main = mergeAxisComponentPart(mergedMain, childMain); + } + } + var mergedGrid = mergedAxisCmpts[i].grid; + var childGrid = childAxisCmpts[i].grid; + if ((!!mergedGrid) !== (!!childGrid)) { + return undefined; + } + else if (mergedGrid && childGrid) { + mergedAxisCmpts[i].grid = mergeAxisComponentPart(mergedGrid, childGrid); + } + } + } + else { + // For first one, return a copy of the child + return childAxisCmpts.map(function (axisComponent) { return (__assign({}, (axisComponent.main ? { main: axisComponent.main.clone() } : {}), (axisComponent.grid ? { grid: axisComponent.grid.clone() } : {}))); }); + } + return mergedAxisCmpts; +} +function mergeAxisComponentPart(merged, child) { + var _loop_1 = function (prop) { + var mergedValueWithExplicit = split_1.mergeValuesWithExplicit(merged.getWithExplicit(prop), child.getWithExplicit(prop), prop, 'axis', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return common_1.titleMerger(v1, v2); + case 'gridScale': + return { + explicit: v1.explicit, + value: v1.value || v2.value + }; + } + return split_1.defaultTieBreaker(v1, v2, prop, 'axis'); + }); + merged.setWithExplicit(prop, mergedValueWithExplicit); + }; + for (var _i = 0, VG_AXIS_PROPERTIES_1 = axis_1.VG_AXIS_PROPERTIES; _i < VG_AXIS_PROPERTIES_1.length; _i++) { + var prop = VG_AXIS_PROPERTIES_1[_i]; + _loop_1(prop); + } + return merged; +} +function isFalseOrNull(v) { + return v === false || v === null; +} +/** + * Return if an axis is visible (shows at least one part of the axis). + */ +function isVisibleAxis(axis) { + return util_1.some(AXIS_PARTS, function (part) { return hasAxisPart(axis, part); }); +} +function hasAxisPart(axis, part) { + // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme. + if (part === 'axis') { + return true; + } + if (part === 'grid' || part === 'title') { + return !!axis.get(part); + } + // Other parts are enabled by default, so they should not be false or null. + return !isFalseOrNull(axis.get(part)); +} +/** + * Make an inner axis for showing grid for shared axis. + */ +function parseGridAxis(channel, model) { + // FIXME: support adding ticks for grid axis that are inner axes of faceted plots. + return parseAxis(channel, model, true); +} +exports.parseGridAxis = parseGridAxis; +function parseMainAxis(channel, model) { + return parseAxis(channel, model, false); +} +exports.parseMainAxis = parseMainAxis; +function parseAxis(channel, model, isGridAxis) { + var axis = model.axis(channel); + var axisComponent = new component_1.AxisComponentPart(); + // 1.2. Add properties + axis_1.VG_AXIS_PROPERTIES.forEach(function (property) { + var value = getProperty(property, axis, channel, model, isGridAxis); + 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 : + value === axis[property]; + var configValue = config_1.getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type')); + if (explicit || configValue === undefined || + // A lot of rules need to be applied for the grid axis + // FIXME: this is not perfectly correct, but we need to rewrite axis component to have one axis and separate them later during assembly anyway. + isGridAxis) { + // Do not apply implicit rule if there is a config value + axisComponent.set(property, value, explicit); + } + } + }); + // 2) Add guide encode definition groups + var axisEncoding = axis.encoding || {}; + var axisEncode = AXIS_PARTS.reduce(function (e, part) { + if (!hasAxisPart(axisComponent, part)) { + // No need to create encode for a disabled part. + return e; + } + var value = part === 'labels' ? + encode.labels(model, channel, axisEncoding.labels || {}, axisComponent.get('orient')) : + axisEncoding[part] || {}; + if (value !== undefined && util_1.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 (util_1.keys(axisEncode).length > 0) { + axisComponent.set('encode', axisEncode, !!axis.encoding || !!axis.labelAngle); + } + return axisComponent; +} +function getProperty(property, specifiedAxis, channel, model, isGridAxis) { + var fieldDef = model.fieldDef(channel); + if ((isGridAxis && axis_1.AXIS_PROPERTY_TYPE[property] === 'main') || + (!isGridAxis && axis_1.AXIS_PROPERTY_TYPE[property] === 'grid')) { + // Do not apply unapplicable properties + return undefined; + } + switch (property) { + case 'scale': + return model.scaleName(channel); + case 'gridScale': + return properties.gridScale(model, channel, isGridAxis); + case 'domain': + return properties.domain(property, specifiedAxis, isGridAxis, channel); + case 'format': + // We don't include temporal field here as we apply format in encode block + return common_1.numberFormat(fieldDef, specifiedAxis.format, model.config); + case 'grid': { + var scaleType = model.getScaleComponent(channel).get('type'); + return common_1.getSpecifiedOrDefaultValue(specifiedAxis.grid, properties.grid(scaleType, fieldDef)); + } + case 'labels': + return isGridAxis ? false : specifiedAxis.labels; + case 'labelFlush': + return properties.labelFlush(fieldDef, channel, specifiedAxis, isGridAxis); + case 'labelOverlap': { + var scaleType = model.getScaleComponent(channel).get('type'); + return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType); + } + case 'minExtent': { + return properties.minMaxExtent(specifiedAxis.minExtent, isGridAxis); + } + case 'maxExtent': { + return properties.minMaxExtent(specifiedAxis.maxExtent, isGridAxis); + } + case 'orient': + return common_1.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 common_1.getSpecifiedOrDefaultValue(specifiedAxis.tickCount, properties.tickCount(channel, fieldDef, scaleType, size)); + } + case 'ticks': + return properties.ticks(property, specifiedAxis, isGridAxis, channel); + case 'title': + return common_1.getSpecifiedOrDefaultValue(specifiedAxis.title, properties.title(specifiedAxis.titleMaxLength, fieldDef, model.config)); + case 'values': + return properties.values(specifiedAxis, model, fieldDef); + case 'zindex': + return common_1.getSpecifiedOrDefaultValue(specifiedAxis.zindex, properties.zindex(isGridAxis)); + } + // Otherwise, return specified property. + return axis_1.isAxisProperty(property) ? specifiedAxis[property] : undefined; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9heGlzL3BhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSxtQ0FBc0c7QUFDdEcseUNBQTRFO0FBQzVFLG1DQUFzQztBQUV0QyxvQ0FBZ0Y7QUFFaEYsc0NBQTZDO0FBQzdDLGtDQUE4RTtBQUU5RSx5Q0FBaUY7QUFDakYsbUNBQXVDO0FBQ3ZDLGlDQUFtQztBQUNuQyx5Q0FBMkM7QUFHM0MsSUFBTSxVQUFVLEdBQWUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFOUUsdUJBQThCLEtBQWdCO0lBQzVDLE1BQU0sQ0FBQyxpQ0FBdUIsQ0FBQyxNQUFNLENBQUMsVUFBUyxJQUFJLEVBQUUsT0FBTztRQUMxRCxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixJQUFNLGFBQWEsR0FBa0IsRUFBRSxDQUFDO1lBQ3hDLDhCQUE4QjtZQUM5QixJQUFNLElBQUksR0FBRyxhQUFhLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoQyxhQUFhLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztZQUM1QixDQUFDO1lBRUQsSUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEMsYUFBYSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7WUFDNUIsQ0FBQztZQUVELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxD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QWEsRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEUsS0FBSyxPQUFPO1lBQ1YsTUFBTSxDQUFDLG1DQUEwQixDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNqSSxLQUFLLFFBQVE7WUFDWCxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNELEtBQUssUUFBUTtZQUNYLE1BQU0sQ0FBQyxtQ0FBMEIsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUMzRixDQUFDO0lBQ0Qsd0NBQXdDO0lBQ3hDLE1BQU0sQ0FBQyxxQkFBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUN4RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBeGlzLCBBWElTX1BST1BFUlRZX1RZUEUsIEF4aXNFbmNvZGluZywgaXNBeGlzUHJvcGVydHksIFZHX0FYSVNfUFJPUEVSVElFU30gZnJvbSAnLi4vLi4vYXhpcyc7XG5pbXBvcnQge1BPU0lUSU9OX1NDQUxFX0NIQU5ORUxTLCBQb3NpdGlvblNjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge2tleXMsIHNvbWV9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtBeGlzT3JpZW50LCBWZ0F4aXMsIFZnQXhpc0VuY29kZX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtnZXRTcGVjaWZpZWRPckRlZmF1bHRWYWx1ZSwgbnVtYmVyRm9ybWF0LCB0aXRsZU1lcmdlcn0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7TGF5ZXJNb2RlbH0gZnJvbSAnLi4vbGF5ZXInO1xuaW1wb3J0IHtwYXJzZUd1aWRlUmVzb2x2ZX0gZnJvbSAnLi4vcmVzb2x2ZSc7XG5pbXBvcnQge2RlZmF1bHRUaWVCcmVha2VyLCBFeHBsaWNpdCwgbWVyZ2VWYWx1ZXNXaXRoRXhwbGljaXR9IGZyb20gJy4uL3NwbGl0JztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7QXhpc0NvbXBvbmVudCwgQXhpc0NvbXBvbmVudEluZGV4LCBBeGlzQ29tcG9uZW50UGFydH0gZnJvbSAnLi9jb21wb25lbnQnO1xuaW1wb3J0IHtnZXRBeGlzQ29uZmlnfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgKiBhcyBlbmNvZGUgZnJvbSAnLi9lbmNvZGUnO1xuaW1wb3J0ICogYXMgcHJvcGVydGllcyBmcm9tICcuL3Byb3BlcnRpZXMnO1xuXG50eXBlIEF4aXNQYXJ0ID0ga2V5b2YgQXhpc0VuY29kaW5nO1xuY29uc3QgQVhJU19QQVJUUzogQXhpc1BhcnRbXSA9IFsnZG9tYWluJywgJ2dyaWQnLCAnbGFiZWxzJywgJ3RpY2tzJywgJ3RpdGxlJ107XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVVuaXRBeGlzKG1vZGVsOiBVbml0TW9kZWwpOiBBeGlzQ29tcG9uZW50SW5kZXgge1xuICByZXR1cm4gUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMucmVkdWNlKGZ1bmN0aW9uKGF4aXMsIGNoYW5uZWwpIHtcbiAgICBpZiAobW9kZWwuYXhpcyhjaGFubmVsKSkge1xuICAgICAgY29uc3QgYXhpc0NvbXBvbmVudDogQXhpc0NvbXBvbmVudCA9IHt9O1xuICAgICAgLy8gVE9ETzogc3VwcG9ydCBtdWx0aXBsZSBheGlzXG4gICAgICBjb25zdCBtYWluID0gcGFyc2VNYWluQXhpcyhjaGFubmVsLCBtb2RlbCk7XG4gICAgICBpZiAobWFpbiAmJiBpc1Zpc2libGVBeGlzKG1haW4pKSB7XG4gICAgICAgIGF4aXNDb21wb25lbnQubWFpbiA9IG1haW47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdyaWQgPSBwYXJzZUdyaWRBeGlzKGNoYW5uZWwsIG1vZGVsKTtcbiAgICAgIGlmIChncmlkICYmIGlzVmlzaWJsZUF4aXMoZ3JpZCkpIHtcbiAgICAgICAgYXhpc0NvbXBvbmVudC5ncmlkID0gZ3JpZDtcbiAgICAgIH1cblxuICAgICAgYXhpc1tjaGFubmVsXSA9IFtheGlzQ29tcG9uZW50XTtcbiAgICB9XG4gICAgcmV0dXJuIGF4aXM7XG4gIH0sIHt9IGFzIEF4aXNDb21wb25lbnRJbmRleCk7XG59XG5cbmNvbnN0IE9QUE9TSVRFX09SSUVOVDoge1tLIGluIEF4aXNPcmllbnRdOiBBeGlzT3JpZW50fSA9IHtcbiAgYm90dG9tOiAndG9wJyxcbiAgdG9wOiAnYm90dG9tJyxcbiAgbGVmdDogJ3JpZ2h0JyxcbiAgcmlnaHQ6ICdsZWZ0J1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGF5ZXJBeGlzKG1vZGVsOiBMYXllck1vZGVsKSB7XG4gIGNvbnN0IHtheGVzLCByZXNvbHZlfSA9IG1vZGVsLmNvbXBvbmVudDtcbiAgY29uc3QgYXhpc0NvdW50OiB7XG4gICAgLy8gVXNpbmcgTWFwcGVkIFR5cGUgdG8gZGVjbGFyZSB0eXBlIChodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay9hZHZhbmNlZC10eXBlcy5odG1sI21hcHBlZC10eXBlcylcbiAgICBbayBpbiBBeGlzT3JpZW50XTogbnVtYmVyXG4gIH0gPSB7dG9wOiAwLCBib3R0b206IDAsIHJpZ2h0OiAwLCBsZWZ0OiAwfTtcblxuICBmb3IgKGNvbnN0IGNoaWxkIG9mIG1vZGVsLmNoaWxkcmVuKSB7XG4gICAgY2hpbGQucGFyc2VBeGlzQW5kSGVhZGVyKCk7XG5cbiAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2Yga2V5cyhjaGlsZC5jb21wb25lbnQuYXhlcykpIHtcbiAgICAgIHJlc29sdmUuYXhpc1tjaGFubmVsXSA9IHBhcnNlR3VpZGVSZXNvbHZlKG1vZGVsLmNvbXBvbmVudC5yZXNvbHZlLCBjaGFubmVsKTtcbiAgICAgIGlmIChyZXNvbHZlLmF4aXNbY2hhbm5lbF0gPT09ICdzaGFyZWQnKSB7XG4gICAgICAgIC8vIElmIHRoZSByZXNvbHZlIHNheXMgc2hhcmVkIChhbmQgaGFzIG5vdCBiZWVuIG92ZXJyaWRkZW4pXG4gICAgICAgIC8vIFdlIHdpbGwgdHJ5IHRvIG1lcmdlIGFuZCBzZWUgaWYgdGhlcmUgaXMgYSBjb25mbGljdFxuXG4gICAgICAgIGF4ZXNbY2hhbm5lbF0gPSBtZXJnZUF4aXNDb21wb25lbnRzKGF4ZXNbY2hhbm5lbF0sIGNoaWxkLmNvbXBvbmVudC5heGVzW2NoYW5uZWxdKTtcblxuICAgICAgICBpZiAoIWF4ZXNbY2hhbm5lbF0pIHtcbiAgICAgICAgICAvLyBJZiBtZXJnZSByZXR1cm5zIG5vdGhpbmcsIHRoZXJlIGlzIGEgY29uZmxpY3Qgc28gd2UgY2Fubm90IG1ha2UgdGhlIGF4aXMgc2hhcmVkLlxuICAgICAgICAgIC8vIFRodXMsIG1hcmsgYXhpcyBhcyBpbmRlcGVuZGVudCBhbmQgcmVtb3ZlIHRoZSBheGlzIGNvbXBvbmVudC5cbiAgICAgICAgICByZXNvbHZlLmF4aXNbY2hhbm5lbF0gPSAnaW5kZXBlbmRlbnQnO1xuICAgICAgICAgIGRlbGV0ZSBheGVzW2NoYW5uZWxdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTW92ZSBheGVzIHRvIGxheWVyJ3MgYXhpcyBjb21wb25lbnQgYW5kIG1lcmdlIHNoYXJlZCBheGVzXG4gIGZvciAoY29uc3QgY2hhbm5lbCBvZiBbJ3gnLCAneSddKSB7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgICAgaWYgKCFjaGlsZC5jb21wb25lbnQuYXhlc1tjaGFubmVsXSkge1xuICAgICAgICAvLyBza2lwIGlmIHRoZSBjaGlsZCBkb2VzIG5vdCBoYXZlIGEgcGFydGljdWxhciBheGlzXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzb2x2ZS5heGlzW2NoYW5uZWxdID09PSAnaW5kZXBlbmRlbnQnKSB7XG4gICAgICAgIC8vIElmIGF4ZXMgYXJlIGluZGVwZW5kZW50LCBjb25jYXQgdGhlIGF4aXNDb21wb25lbnQgYXJyYXkuXG4gICAgICAgIGF4ZXNbY2hhbm5lbF0gPSAoYXhlc1tjaGFubmVsXSB8fCBbXSkuY29uY2F0KGNoaWxkLmNvbXBvbmVudC5heGVzW2NoYW5uZWxdKTtcblxuICAgICAgICAvLyBBdXRvbWF0aWNhbGx5IGFkanVzdCBvcmllbnRcbiAgICAgICAgZm9yIChjb25zdCBheGlzQ29tcG9uZW50IG9mIGNoaWxkLmNvbXBvbmVudC5heGVzW2NoYW5uZWxdKSB7XG4gICAgICAgICAgY29uc3Qge3ZhbHVlOiBvcmllbnQsIGV4cGxpY2l0fSA9IGF4aXNDb21wb25lbnQubWFpbi5nZXRXaXRoRXhwbGljaXQoJ29yaWVudCcpO1xuICAgICAgICAgIGlmIChheGlzQ291bnRbb3JpZW50XSA+IDAgJiYgIWV4cGxpY2l0KSB7XG4gICAgICAgICAgICAvLyBDaGFuZ2UgYXhpcyBvcmllbnQgaWYgdGhlIG51bWJlciBkbyBub3QgbWF0Y2hcbiAgICAgICAgICAgIGNvbnN0IG9wcG9zaXRlT3JpZW50ID0gT1BQT1NJVEVfT1JJRU5UW29yaWVudF07XG4gICAgICAgICAgICBpZiAoYXhpc0NvdW50W29yaWVudF0gPiBheGlzQ291bnRbb3Bwb3NpdGVPcmllbnRdKSB7XG4gICAgICAgICAgICAgIGF4aXNDb21wb25lbnQubWFpbi5zZXQoJ29yaWVudCcsIG9wcG9zaXRlT3JpZW50LCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGF4aXNDb3VudFtvcmllbnRdKys7XG5cbiAgICAgICAgICAvLyBUT0RPKGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EtbGl0ZS9pc3N1ZXMvMjYzNCk6IGF1dG9tYXRpY2FseSBhZGQgZXh0cmEgb2Zmc2V0P1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFmdGVyIG1lcmdpbmcsIG1ha2Ugc3VyZSB0byByZW1vdmUgYXhlcyBmcm9tIGNoaWxkXG4gICAgICBkZWxldGUgY2hpbGQuY29tcG9uZW50LmF4ZXNbY2hhbm5lbF07XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1lcmdlQXhpc0NvbXBvbmVudHMobWVyZ2VkQXhpc0NtcHRzOiBBeGlzQ29tcG9uZW50W10sIGNoaWxkQXhpc0NtcHRzOiBBeGlzQ29tcG9uZW50W10pOiBBeGlzQ29tcG9uZW50W10ge1xuICBpZiAobWVyZ2VkQXhpc0NtcHRzKSB7XG4gICAgaWYgKG1lcmdlZEF4aXNDbXB0cy5sZW5ndGggIT09IGNoaWxkQXhpc0NtcHRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy8gQ2Fubm90IG1lcmdlIGF4aXMgY29tcG9uZW50IHdpdGggZGlmZmVyZW50IG51bWJlciBvZiBheGVzLlxuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBtZXJnZWRBeGlzQ21wdHMubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoIDsgaSsrKSB7XG4gICAgICBjb25zdCBtZXJnZWRNYWluID0gbWVyZ2VkQXhpc0NtcHRzW2ldLm1haW47XG4gICAgICBjb25zdCBjaGlsZE1haW4gPSBjaGlsZEF4aXNDbXB0c1tpXS5tYWluO1xuXG4gICAgICBpZiAoKCEhbWVyZ2VkTWFpbikgIT09ICghIWNoaWxkTWFpbikpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSBpZiAobWVyZ2VkTWFpbiAmJiBjaGlsZE1haW4pIHtcbiAgICAgICAgY29uc3QgbWVyZ2VkT3JpZW50ID0gbWVyZ2VkTWFpbi5nZXRXaXRoRXhwbGljaXQoJ29yaWVudCcpO1xuICAgICAgICBjb25zdCBjaGlsZE9yaWVudCA9IGNoaWxkTWFpbi5nZXRXaXRoRXhwbGljaXQoJ29yaWVudCcpO1xuXG4gICAgICAgIGlmIChtZXJnZWRPcmllbnQuZXhwbGljaXQgJiYgY2hpbGRPcmllbnQuZXhwbGljaXQgJiYgbWVyZ2VkT3JpZW50LnZhbHVlICE9PSBjaGlsZE9yaWVudC52YWx1ZSkge1xuICAgICAgICAgIC8vIFRPRE86IHRocm93IHdhcm5pbmcgaWYgcmVzb2x2ZSBpcyBleHBsaWNpdCAoV2UgZG9uJ3QgaGF2ZSBpbmZvIGFib3V0IGV4cGxpY2l0L2ltcGxpY2l0IHJlc29sdmUgeWV0LilcbiAgICAgICAgICAvLyBDYW5ub3QgbWVyZ2UgZHVlIHRvIGluY29uc2lzdGVudCBvcmllbnRcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lcmdlZEF4aXNDbXB0c1tpXS5tYWluID0gbWVyZ2VBeGlzQ29tcG9uZW50UGFydChtZXJnZWRNYWluLCBjaGlsZE1haW4pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1lcmdlZEdyaWQgPSBtZXJnZWRBeGlzQ21wdHNbaV0uZ3JpZDtcbiAgICAgIGNvbnN0IGNoaWxkR3JpZCA9IGNoaWxkQXhpc0NtcHRzW2ldLmdyaWQ7XG4gICAgICBpZiAoKCEhbWVyZ2VkR3JpZCkgIT09ICghIWNoaWxkR3JpZCkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSBpZiAobWVyZ2VkR3JpZCAmJiBjaGlsZEdyaWQpIHtcbiAgICAgICAgbWVyZ2VkQXhpc0NtcHRzW2ldLmdyaWQgPSBtZXJnZUF4aXNDb21wb25lbnRQYXJ0KG1lcmdlZEdyaWQsIGNoaWxkR3JpZCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIEZvciBmaXJzdCBvbmUsIHJldHVybiBhIGNvcHkgb2YgdGhlIGNoaWxkXG4gICAgcmV0dXJuIGNoaWxkQXhpc0NtcHRzLm1hcChheGlzQ29tcG9uZW50ID0+ICh7XG4gICAgICAuLi4oYXhpc0NvbXBvbmVudC5tYWluID8ge21haW46IGF4aXNDb21wb25lbnQubWFpbi5jbG9uZSgpfSA6IHt9KSxcbiAgICAgIC4uLihheGlzQ29tcG9uZW50LmdyaWQgPyB7Z3JpZDogYXhpc0NvbXBvbmVudC5ncmlkLmNsb25lKCl9IDoge30pXG4gICAgfSkpO1xuICB9XG4gIHJldHVybiBtZXJnZWRBeGlzQ21wdHM7XG59XG5cbmZ1bmN0aW9uIG1lcmdlQXhpc0NvbXBvbmVudFBhcnQobWVyZ2VkOiBBeGlzQ29tcG9uZW50UGFydCwgY2hpbGQ6IEF4aXNDb21wb25lbnRQYXJ0KTogQXhpc0NvbXBvbmVudFBhcnQge1xuICBmb3IgKGNvbnN0IHByb3Agb2YgVkdfQVhJU19QUk9QRVJUSUVTKSB7XG4gICAgY29uc3QgbWVyZ2VkVmFsdWVXaXRoRXhwbGljaXQgPSBtZXJnZVZhbHVlc1dpdGhFeHBsaWNpdDxWZ0F4aXMsIGFueT4oXG4gICAgICBtZXJnZWQuZ2V0V2l0aEV4cGxpY2l0KHByb3ApLFxuICAgICAgY2hpbGQuZ2V0V2l0aEV4cGxpY2l0KHByb3ApLFxuICAgICAgcHJvcCwgJ2F4aXMnLFxuXG4gICAgICAvLyBUaWUgYnJlYWtlciBmdW5jdGlvblxuICAgICAgKHYxOiBFeHBsaWNpdDxhbnk+LCB2MjogRXhwbGljaXQ8YW55PikgPT4ge1xuICAgICAgICBzd2l0Y2ggKHByb3ApIHtcbiAgICAgICAgICBjYXNlICd0aXRsZSc6XG4gICAgICAgICAgICByZXR1cm4gdGl0bGVNZXJnZXIodjEsIHYyKTtcbiAgICAgICAgICBjYXNlICdncmlkU2NhbGUnOlxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZXhwbGljaXQ6IHYxLmV4cGxpY2l0LCAvLyBrZWVwIHRoZSBvbGQgZXhwbGljaXRcbiAgICAgICAgICAgICAgdmFsdWU6IHYxLnZhbHVlIHx8IHYyLnZhbHVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWZhdWx0VGllQnJlYWtlcjxWZ0F4aXMsIGFueT4odjEsIHYyLCBwcm9wLCAnYXhpcycpO1xuICAgICAgfVxuICAgICk7XG4gICAgbWVyZ2VkLnNldFdpdGhFeHBsaWNpdChwcm9wLCBtZXJnZWRWYWx1ZVdpdGhFeHBsaWNpdCk7XG4gIH1cbiAgcmV0dXJuIG1lcmdlZDtcbn1cblxuZnVuY3Rpb24gaXNGYWxzZU9yTnVsbCh2OiBib29sZWFuIHwgbnVsbCkge1xuICByZXR1cm4gdiA9PT0gZmFsc2UgfHwgdiA9PT0gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gaWYgYW4gYXhpcyBpcyB2aXNpYmxlIChzaG93cyBhdCBsZWFzdCBvbmUgcGFydCBvZiB0aGUgYXhpcykuXG4gKi9cbmZ1bmN0aW9uIGlzVmlzaWJsZUF4aXMoYXhpczogQXhpc0NvbXBvbmVudFBhcnQpIHtcbiAgcmV0dXJuIHNvbWUoQVhJU19QQVJUUywgKHBhcnQpID0+IGhhc0F4aXNQYXJ0KGF4aXMsIHBhcnQpKTtcbn1cblxuZnVuY3Rpb24gaGFzQXhpc1BhcnQoYXhpczogQXhpc0NvbXBvbmVudFBhcnQsIHBhcnQ6IEF4aXNQYXJ0KSB7XG4gIC8vIEZJWE1FKGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EtbGl0ZS9pc3N1ZXMvMjU1MikgdGhpcyBtZXRob2QgY2FuIGJlIHdyb25nIGlmIHVzZXJzIHVzZSBhIFZlZ2EgdGhlbWUuXG5cbiAgaWYgKHBhcnQgPT09ICdheGlzJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHBhcnQgPT09ICdncmlkJyB8fCBwYXJ0ID09PSAndGl0bGUnKSB7XG4gICAgcmV0dXJuICEhYXhpcy5nZXQocGFydCk7XG4gIH1cbiAgLy8gT3RoZXIgcGFydHMgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdCwgc28gdGhleSBzaG91bGQgbm90IGJlIGZhbHNlIG9yIG51bGwuXG4gIHJldHVybiAhaXNGYWxzZU9yTnVsbChheGlzLmdldChwYXJ0KSk7XG59XG5cbi8qKlxuICogTWFrZSBhbiBpbm5lciBheGlzIGZvciBzaG93aW5nIGdyaWQgZm9yIHNoYXJlZCBheGlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VHcmlkQXhpcyhjaGFubmVsOiBQb3NpdGlvblNjYWxlQ2hhbm5lbCwgbW9kZWw6IFVuaXRNb2RlbCk6IEF4aXNDb21wb25lbnRQYXJ0IHtcbiAgLy8gRklYTUU6IHN1cHBvcnQgYWRkaW5nIHRpY2tzIGZvciBncmlkIGF4aXMgdGhhdCBhcmUgaW5uZXIgYXhlcyBvZiBmYWNldGVkIHBsb3RzLlxuICByZXR1cm4gcGFyc2VBeGlzKGNoYW5uZWwsIG1vZGVsLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTWFpbkF4aXMoY2hhbm5lbDogUG9zaXRpb25TY2FsZUNoYW5uZWwsIG1vZGVsOiBVbml0TW9kZWwpOiBBeGlzQ29tcG9uZW50UGFydCB7XG4gIHJldHVybiBwYXJzZUF4aXMoY2hhbm5lbCwgbW9kZWwsIGZhbHNlKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VBeGlzKGNoYW5uZWw6IFBvc2l0aW9uU2NhbGVDaGFubmVsLCBtb2RlbDogVW5pdE1vZGVsLCBpc0dyaWRBeGlzOiBib29sZWFuKTogQXhpc0NvbXBvbmVudFBhcnQge1xuICBjb25zdCBheGlzID0gbW9kZWwuYXhpcyhjaGFubmVsKTtcblxuICBjb25zdCBheGlzQ29tcG9uZW50ID0gbmV3IEF4aXNDb21wb25lbnRQYXJ0KCk7XG5cbiAgLy8gMS4yLiBBZGQgcHJvcGVydGllc1xuICBWR19BWElTX1BST1BFUlRJRVMuZm9yRWFjaChmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgIGNvbnN0IHZhbHVlID0gZ2V0UHJvcGVydHkocHJvcGVydHksIGF4aXMsIGNoYW5uZWwsIG1vZGVsLCBpc0dyaWRBeGlzKTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZXhwbGljaXQgPVxuICAgICAgICAvLyBzcGVjaWZpZWQgYXhpcy52YWx1ZXMgaXMgYWxyZWFkeSByZXNwZWN0ZWQsIGJ1dCBtYXkgZ2V0IHRyYW5zZm9ybWVkLlxuICAgICAgICBwcm9wZXJ0eSA9PT0gJ3ZhbHVlcycgPyAhIWF4aXMudmFsdWVzIDpcbiAgICAgICAgLy8gYm90aCBWTCBheGlzLmVuY29kaW5nIGFuZCBheGlzLmxhYmVsQW5nbGUgYWZmZWN0IFZHIGF4aXMuZW5jb2RlXG4gICAgICAgIHByb3BlcnR5ID09PSAnZW5jb2RlJyA/ICEhYXhpcy5lbmNvZGluZyB8fCAhIWF4aXMubGFiZWxBbmdsZSA6XG4gICAgICAgIHZhbHVlID09PSBheGlzW3Byb3BlcnR5XTtcblxuICAgICAgY29uc3QgY29uZmlnVmFsdWUgPSBnZXRBeGlzQ29uZmlnKHByb3BlcnR5LCBtb2RlbC5jb25maWcsIGNoYW5uZWwsIGF4aXNDb21wb25lbnQuZ2V0KCdvcmllbnQnKSwgbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoY2hhbm5lbCkuZ2V0KCd0eXBlJykpO1xuXG4gICAgICBpZiAoXG4gICAgICAgIGV4cGxpY2l0IHx8IGNvbmZpZ1ZhbHVlID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgLy8gQSBsb3Qgb2YgcnVsZXMgbmVlZCB0byBiZSBhcHBsaWVkIGZvciB0aGUgZ3JpZCBheGlzXG4gICAgICAgIC8vIEZJWE1FOiB0aGlzIGlzIG5vdCBwZXJmZWN0bHkgY29ycmVjdCwgYnV0IHdlIG5lZWQgdG8gcmV3cml0ZSBheGlzIGNvbXBvbmVudCB0byBoYXZlIG9uZSBheGlzIGFuZCBzZXBhcmF0ZSB0aGVtIGxhdGVyIGR1cmluZyBhc3NlbWJseSBhbnl3YXkuXG4gICAgICAgIGlzR3JpZEF4aXNcbiAgICAgICkge1xuICAgICAgICAvLyBEbyBub3QgYXBwbHkgaW1wbGljaXQgcnVsZSBpZiB0aGVyZSBpcyBhIGNvbmZpZyB2YWx1ZVxuICAgICAgICBheGlzQ29tcG9uZW50LnNldChwcm9wZXJ0eSwgdmFsdWUsIGV4cGxpY2l0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIDIpIEFkZCBndWlkZSBlbmNvZGUgZGVmaW5pdGlvbiBncm91cHNcbiAgY29uc3QgYXhpc0VuY29kaW5nID0gYXhpcy5lbmNvZGluZyB8fCB7fTtcbiAgY29uc3QgYXhpc0VuY29kZSA9IEFYSVNfUEFSVFMucmVkdWNlKChlOiBWZ0F4aXNFbmNvZGUsIHBhcnQpID0+IHtcbiAgICBpZiAoIWhhc0F4aXNQYXJ0KGF4aXNDb21wb25lbnQsIHBhcnQpKSB7XG4gICAgICAvLyBObyBuZWVkIHRvIGNyZWF0ZSBlbmNvZGUgZm9yIGEgZGlzYWJsZWQgcGFydC5cbiAgICAgIHJldHVybiBlO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gcGFydCA9PT0gJ2xhYmVscycgP1xuICAgICAgZW5jb2RlLmxhYmVscyhtb2RlbCwgY2hhbm5lbCwgYXhpc0VuY29kaW5nLmxhYmVscyB8fCB7fSwgYXhpc0NvbXBvbmVudC5nZXQoJ29yaWVudCcpKSA6XG4gICAgICBheGlzRW5jb2RpbmdbcGFydF0gfHwge307XG5cbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiBrZXlzKHZhbHVlKS5sZW5ndGggPiAwKSB7XG4gICAgICBlW3BhcnRdID0ge3VwZGF0ZTogdmFsdWV9O1xuICAgIH1cbiAgICByZXR1cm4gZTtcbiAgfSwge30gYXMgVmdBeGlzRW5jb2RlKTtcblxuICAvLyBGSVhNRTogQnkgaGF2aW5nIGVuY29kZSBhcyBvbmUgcHJvcGVydHksIHdlIHdvbid0IGhhdmUgZmluZSBncmFpbmVkIGVuY29kZSBtZXJnaW5nLlxuICBpZiAoa2V5cyhheGlzRW5jb2RlKS5sZW5ndGggPiAwKSB7XG4gICAgYXhpc0NvbXBvbmVudC5zZXQoJ2VuY29kZScsIGF4aXNFbmNvZGUsICEhYXhpcy5lbmNvZGluZyB8fCAhIWF4aXMubGFiZWxBbmdsZSk7XG4gIH1cblxuICByZXR1cm4gYXhpc0NvbXBvbmVudDtcbn1cblxuZnVuY3Rpb24gZ2V0UHJvcGVydHk8SyBleHRlbmRzIGtleW9mIFZnQXhpcz4ocHJvcGVydHk6IEssIHNwZWNpZmllZEF4aXM6IEF4aXMsIGNoYW5uZWw6IFBvc2l0aW9uU2NhbGVDaGFubmVsLCBtb2RlbDogVW5pdE1vZGVsLCBpc0dyaWRBeGlzOiBib29sZWFuKTogVmdBeGlzW0tdIHtcbiAgY29uc3QgZmllbGREZWYgPSBtb2RlbC5maWVsZERlZihjaGFubmVsKTtcblxuICBpZiAoKGlzR3JpZEF4aXMgJiYgQVhJU19QUk9QRVJUWV9UWVBFW3Byb3BlcnR5XSA9PT0gJ21haW4nKSB8fFxuICAgICAgKCFpc0dyaWRBeGlzICYmIEFYSVNfUFJPUEVSVFlfVFlQRVtwcm9wZXJ0eV0gPT09ICdncmlkJykpIHtcbiAgICAvLyBEbyBub3QgYXBwbHkgdW5hcHBsaWNhYmxlIHByb3BlcnRpZXNcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgc3dpdGNoIChwcm9wZXJ0eSkge1xuICAgIGNhc2UgJ3NjYWxlJzpcbiAgICAgIHJldHVybiBtb2RlbC5zY2FsZU5hbWUoY2hhbm5lbCk7XG4gICAgY2FzZSAnZ3JpZFNjYWxlJzpcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzLmdyaWRTY2FsZShtb2RlbCwgY2hhbm5lbCwgaXNHcmlkQXhpcyk7XG5cbiAgICBjYXNlICdkb21haW4nOlxuICAgICAgcmV0dXJuIHByb3BlcnRpZXMuZG9tYWluKHByb3BlcnR5LCBzcGVjaWZpZWRBeGlzLCBpc0dyaWRBeGlzLCBjaGFubmVsKTtcbiAgICBjYXNlICdmb3JtYXQnOlxuICAgICAgLy8gV2UgZG9uJ3QgaW5jbHVkZSB0ZW1wb3JhbCBmaWVsZCBoZXJlIGFzIHdlIGFwcGx5IGZvcm1hdCBpbiBlbmNvZGUgYmxvY2tcbiAgICAgIHJldHVybiBudW1iZXJGb3JtYXQoZmllbGREZWYsIHNwZWNpZmllZEF4aXMuZm9ybWF0LCBtb2RlbC5jb25maWcpO1xuICAgIGNhc2UgJ2dyaWQnOiB7XG4gICAgICBjb25zdCBzY2FsZVR5cGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKS5nZXQoJ3R5cGUnKTtcbiAgICAgIHJldHVybiBnZXRTcGVjaWZpZWRPckRlZmF1bHRWYWx1ZShzcGVjaWZpZWRBeGlzLmdyaWQsIHByb3BlcnRpZXMuZ3JpZChzY2FsZVR5cGUsIGZpZWxkRGVmKSk7XG4gICAgfVxuICAgIGNhc2UgJ2xhYmVscyc6XG4gICAgICByZXR1cm4gaXNHcmlkQXhpcyA/IGZhbHNlIDogc3BlY2lmaWVkQXhpcy5sYWJlbHM7XG4gICAgY2FzZSAnbGFiZWxGbHVzaCc6XG4gICAgICByZXR1cm4gcHJvcGVydGllcy5sYWJlbEZsdXNoKGZpZWxkRGVmLCBjaGFubmVsLCBzcGVjaWZpZWRBeGlzLCBpc0dyaWRBeGlzKTtcbiAgICBjYXNlICdsYWJlbE92ZXJsYXAnOiB7XG4gICAgICBjb25zdCBzY2FsZVR5cGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKS5nZXQoJ3R5cGUnKTtcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzLmxhYmVsT3ZlcmxhcChmaWVsZERlZiwgc3BlY2lmaWVkQXhpcywgY2hhbm5lbCwgc2NhbGVUeXBlKTtcbiAgICB9XG4gICAgY2FzZSAnbWluRXh0ZW50Jzoge1xuICAgICAgcmV0dXJuIHByb3BlcnRpZXMubWluTWF4RXh0ZW50KHNwZWNpZmllZEF4aXMubWluRXh0ZW50LCBpc0dyaWRBeGlzKTtcbiAgICB9XG4gICAgY2FzZSAnbWF4RXh0ZW50Jzoge1xuICAgICAgcmV0dXJuIHByb3BlcnRpZXMubWluTWF4RXh0ZW50KHNwZWNpZmllZEF4aXMubWF4RXh0ZW50LCBpc0dyaWRBeGlzKTtcbiAgICB9XG4gICAgY2FzZSAnb3JpZW50JzpcbiAgICAgIHJldHVybiBnZXRTcGVjaWZpZWRPckRlZmF1bHRWYWx1ZShzcGVjaWZpZWRBeGlzLm9yaWVudCwgcHJvcGVydGllcy5vcmllbnQoY2hhbm5lbCkpO1xuICAgIGNhc2UgJ3RpY2tDb3VudCc6IHtcbiAgICAgIGNvbnN0IHNjYWxlVHlwZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpLmdldCgndHlwZScpO1xuICAgICAgY29uc3Qgc2l6ZVR5cGUgPSBjaGFubmVsID09PSAneCcgPyAnd2lkdGgnIDogY2hhbm5lbCA9PT0gJ3knID8gJ2hlaWdodCcgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBzaXplID0gc2l6ZVR5cGUgPyBtb2RlbC5nZXRTaXplU2lnbmFsUmVmKHNpemVUeXBlKVxuICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGdldFNwZWNpZmllZE9yRGVmYXVsdFZhbHVlKHNwZWNpZmllZEF4aXMudGlja0NvdW50LCBwcm9wZXJ0aWVzLnRpY2tDb3VudChjaGFubmVsLCBmaWVsZERlZiwgc2NhbGVUeXBlLCBzaXplKSk7XG4gICAgfVxuICAgIGNhc2UgJ3RpY2tzJzpcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzLnRpY2tzKHByb3BlcnR5LCBzcGVjaWZpZWRBeGlzLCBpc0dyaWRBeGlzLCBjaGFubmVsKTtcbiAgICBjYXNlICd0aXRsZSc6XG4gICAgICByZXR1cm4gZ2V0U3BlY2lmaWVkT3JEZWZhdWx0VmFsdWUoc3BlY2lmaWVkQXhpcy50aXRsZSwgcHJvcGVydGllcy50aXRsZShzcGVjaWZpZWRBeGlzLnRpdGxlTWF4TGVuZ3RoLCBmaWVsZERlZiwgbW9kZWwuY29uZmlnKSk7XG4gICAgY2FzZSAndmFsdWVzJzpcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzLnZhbHVlcyhzcGVjaWZpZWRBeGlzLCBtb2RlbCwgZmllbGREZWYpO1xuICAgIGNhc2UgJ3ppbmRleCc6XG4gICAgICByZXR1cm4gZ2V0U3BlY2lmaWVkT3JEZWZhdWx0VmFsdWUoc3BlY2lmaWVkQXhpcy56aW5kZXgsIHByb3BlcnRpZXMuemluZGV4KGlzR3JpZEF4aXMpKTtcbiAgfVxuICAvLyBPdGhlcndpc2UsIHJldHVybiBzcGVjaWZpZWQgcHJvcGVydHkuXG4gIHJldHVybiBpc0F4aXNQcm9wZXJ0eShwcm9wZXJ0eSkgPyBzcGVjaWZpZWRBeGlzW3Byb3BlcnR5XSA6IHVuZGVmaW5lZDtcbn1cbiJdfQ== \ 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..0456ff0d6f --- /dev/null +++ b/build/src/compile/axis/properties.d.ts @@ -0,0 +1,31 @@ +import { Axis } from '../../axis'; +import { PositionScaleChannel } from '../../channel'; +import { Config } from '../../config'; +import { DateTime } from '../../datetime'; +import { FieldDef } from '../../fielddef'; +import { ScaleType } from '../../scale'; +import { VgSignalRef } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function domainAndTicks(property: 'domain' | 'ticks', specifiedAxis: Axis, isGridAxis: boolean, channel: PositionScaleChannel): boolean; +export declare const domain: typeof domainAndTicks; +export declare const ticks: typeof domainAndTicks; +/** + * 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, isGridAxis: boolean): string; +export declare function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis, isGridAxis: boolean): number | boolean; +export declare function labelOverlap(fieldDef: FieldDef, specifiedAxis: Axis, channel: PositionScaleChannel, scaleType: ScaleType): boolean | "parity" | "greedy"; +export declare function minMaxExtent(specifiedExtent: number, isGridAxis: boolean): number; +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): number[] | DateTime[] | { + signal: string; +}[] | { + signal: string; +}; +export declare function zindex(isGridAxis: boolean): 0 | 1; diff --git a/build/src/compile/axis/properties.js b/build/src/compile/axis/properties.js new file mode 100644 index 0000000000..5dbbb686aa --- /dev/null +++ b/build/src/compile/axis/properties.js @@ -0,0 +1,128 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bin_1 = require("../../bin"); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function domainAndTicks(property, specifiedAxis, isGridAxis, channel) { + if (isGridAxis) { + return false; + } + return specifiedAxis[property]; +} +exports.domainAndTicks = domainAndTicks; +exports.domain = domainAndTicks; +exports.ticks = domainAndTicks; +// 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 !scale_1.hasDiscreteDomain(scaleType) && !fieldDef.bin; +} +exports.grid = grid; +function gridScale(model, channel, isGridAxis) { + if (isGridAxis) { + var gridChannel = channel === 'x' ? 'y' : 'x'; + if (model.getScaleComponent(gridChannel)) { + return model.scaleName(gridChannel); + } + } + return undefined; +} +exports.gridScale = gridScale; +function labelFlush(fieldDef, channel, specifiedAxis, isGridAxis) { + if (isGridAxis) { + return undefined; + } + if (specifiedAxis.labelFlush !== undefined) { + return specifiedAxis.labelFlush; + } + if (channel === 'x' && util_1.contains(['quantitative', 'temporal'], fieldDef.type)) { + return true; + } + return undefined; +} +exports.labelFlush = labelFlush; +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; +} +exports.labelOverlap = labelOverlap; +function minMaxExtent(specifiedExtent, isGridAxis) { + if (isGridAxis) { + // Always return 0 to make sure that `config.axis*.minExtent` and `config.axis*.maxExtent` + // would not affect gridAxis + return 0; + } + else { + return specifiedExtent; + } +} +exports.minMaxExtent = minMaxExtent; +function orient(channel) { + switch (channel) { + case channel_1.X: + return 'bottom'; + case channel_1.Y: + return 'left'; + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS); +} +exports.orient = orient; +function tickCount(channel, fieldDef, scaleType, size) { + if (!scale_1.hasDiscreteDomain(scaleType) && scaleType !== 'log' && !util_1.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; +} +exports.tickCount = tickCount; +function title(maxLength, fieldDef, config) { + // if not defined, automatically determine axis title from field def + var fieldTitle = fielddef_1.title(fieldDef, config); + return maxLength ? util_1.truncate(fieldTitle, maxLength) : fieldTitle; +} +exports.title = title; +function values(specifiedAxis, model, fieldDef) { + var vals = specifiedAxis.values; + if (specifiedAxis.values && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return { signal: datetime_1.dateTimeExpr(dt, true) }; + }); + } + if (!vals && fieldDef.bin && fieldDef.type === type_1.QUANTITATIVE) { + var signal = model.getName(bin_1.binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return { signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }; + } + return vals; +} +exports.values = values; +function zindex(isGridAxis) { + if (isGridAxis) { + // if grid is true, need to put layer on the back so that grid is behind marks + return 0; + } + return 1; // otherwise return undefined and use Vega's default. +} +exports.zindex = zindex; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2F4aXMvcHJvcGVydGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLGlDQUFzQztBQUN0Qyx5Q0FBeUQ7QUFFekQsMkNBQWtFO0FBQ2xFLDJDQUFnRTtBQUNoRSwrQkFBaUM7QUFDakMscUNBQXlEO0FBQ3pELG1DQUF3QztBQUN4QyxtQ0FBOEM7QUFLOUMsd0JBQStCLFFBQTRCLEVBQUUsYUFBbUIsRUFBRSxVQUFtQixFQUFFLE9BQTZCO0lBQ2xJLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDZixNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUxELHdDQUtDO0FBRVksUUFBQSxNQUFNLEdBQUcsY0FBYyxDQUFDO0FBQ3hCLFFBQUEsS0FBSyxHQUFHLGNBQWMsQ0FBQztBQUVwQyxpRkFBaUY7QUFDakY7OztHQUdHO0FBQ0gsY0FBcUIsU0FBb0IsRUFBRSxRQUEwQjtJQUNuRSxNQUFNLENBQUMsQ0FBQyx5QkFBaUIsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7QUFDeEQsQ0FBQztBQUZELG9CQUVDO0FBRUQsbUJBQTBCLEtBQWdCLEVBQUUsT0FBNkIsRUFBRSxVQUFtQjtJQUM1RixFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2YsSUFBTSxXQUFXLEdBQXlCLE9BQU8sS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3RFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENB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QUFRLEVBQUMsQ0FBQztJQUNoRyxDQUFDO0lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQztBQUNkLENBQUM7QUFmRCx3QkFlQztBQUVELGdCQUF1QixVQUFtQjtJQUN4QyxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2YsOEVBQThFO1FBQzlFLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLHFEQUFxRDtBQUNqRSxDQUFDO0FBTkQsd0JBTUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0F4aXN9IGZyb20gJy4uLy4uL2F4aXMnO1xuaW1wb3J0IHtiaW5Ub1N0cmluZ30gZnJvbSAnLi4vLi4vYmluJztcbmltcG9ydCB7UG9zaXRpb25TY2FsZUNoYW5uZWwsIFgsIFl9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQge0RhdGVUaW1lLCBkYXRlVGltZUV4cHIsIGlzRGF0ZVRpbWV9IGZyb20gJy4uLy4uL2RhdGV0aW1lJztcbmltcG9ydCB7RmllbGREZWYsIHRpdGxlIGFzIGZpZWxkRGVmVGl0bGV9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi9sb2cnO1xuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbiwgU2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge1FVQU5USVRBVElWRX0gZnJvbSAnLi4vLi4vdHlwZSc7XG5pbXBvcnQge2NvbnRhaW5zLCB0cnVuY2F0ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnU2lnbmFsUmVmfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vdW5pdCc7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGRvbWFpbkFuZFRpY2tzKHByb3BlcnR5OiAnZG9tYWluJyB8ICd0aWNrcycsIHNwZWNpZmllZEF4aXM6IEF4aXMsIGlzR3JpZEF4aXM6IGJvb2xlYW4sIGNoYW5uZWw6IFBvc2l0aW9uU2NhbGVDaGFubmVsKSB7XG4gIGlmIChpc0dyaWRBeGlzKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBzcGVjaWZpZWRBeGlzW3Byb3BlcnR5XTtcbn1cblxuZXhwb3J0IGNvbnN0IGRvbWFpbiA9IGRvbWFpbkFuZFRpY2tzO1xuZXhwb3J0IGNvbnN0IHRpY2tzID0gZG9tYWluQW5kVGlja3M7XG5cbi8vIFRPRE86IHdlIG5lZWQgdG8gcmVmYWN0b3IgdGhpcyBtZXRob2QgYWZ0ZXIgd2UgdGFrZSBjYXJlIG9mIGNvbmZpZyByZWZhY3RvcmluZ1xuLyoqXG4gKiBEZWZhdWx0IHJ1bGVzIGZvciB3aGV0aGVyIHRvIHNob3cgYSBncmlkIHNob3VsZCBiZSBzaG93biBmb3IgYSBjaGFubmVsLlxuICogSWYgYGdyaWRgIGlzIHVuc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBpcyBgdHJ1ZWAgZm9yIG9yZGluYWwgc2NhbGVzIHRoYXQgYXJlIG5vdCBiaW5uZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyaWQoc2NhbGVUeXBlOiBTY2FsZVR5cGUsIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+KSB7XG4gIHJldHVybiAhaGFzRGlzY3JldGVEb21haW4oc2NhbGVUeXBlKSAmJiAhZmllbGREZWYuYmluO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ3JpZFNjYWxlKG1vZGVsOiBVbml0TW9kZWwsIGNoYW5uZWw6IFBvc2l0aW9uU2NhbGVDaGFubmVsLCBpc0dyaWRBeGlzOiBib29sZWFuKSB7XG4gIGlmIChpc0dyaWRBeGlzKSB7XG4gICAgY29uc3QgZ3JpZENoYW5uZWw6IFBvc2l0aW9uU2NhbGVDaGFubmVsID0gY2hhbm5lbCA9PT0gJ3gnID8gJ3knIDogJ3gnO1xuICAgIGlmIChtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChncmlkQ2hhbm5lbCkpIHtcbiAgICAgIHJldHVybiBtb2RlbC5zY2FsZU5hbWUoZ3JpZENoYW5uZWwpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGFiZWxGbHVzaChmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgY2hhbm5lbDogUG9zaXRpb25TY2FsZUNoYW5uZWwsIHNwZWNpZmllZEF4aXM6IEF4aXMsIGlzR3JpZEF4aXM6IGJvb2xlYW4pIHtcbiAgaWYgKGlzR3JpZEF4aXMpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKHNwZWNpZmllZEF4aXMubGFiZWxGbHVzaCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHNwZWNpZmllZEF4aXMubGFiZWxGbHVzaDtcbiAgfVxuICBpZiAoY2hhbm5lbCA9PT0gJ3gnICYmIGNvbnRhaW5zKFsncXVhbnRpdGF0aXZlJywgJ3RlbXBvcmFsJ10sIGZpZWxkRGVmLnR5cGUpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxhYmVsT3ZlcmxhcChmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgc3BlY2lmaWVkQXhpczogQXhpcywgY2hhbm5lbDogUG9zaXRpb25TY2FsZUNoYW5uZWwsIHNjYWxlVHlwZTogU2NhbGVUeXBlKSB7XG4gIGlmIChzcGVjaWZpZWRBeGlzLmxhYmVsT3ZlcmxhcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHNwZWNpZmllZEF4aXMubGFiZWxPdmVybGFwO1xuICB9XG5cbiAgLy8gZG8gbm90IHByZXZlbnQgb3ZlcmxhcCBmb3Igbm9taW5hbCBkYXRhIGJlY2F1c2UgdGhlcmUgaXMgbm8gd2F5IHRvIGluZmVyIHdoYXQgdGhlIG1pc3NpbmcgbGFiZWxzIGFyZVxuICBpZiAoZmllbGREZWYudHlwZSAhPT0gJ25vbWluYWwnKSB7XG4gICAgaWYgKHNjYWxlVHlwZSA9PT0gJ2xvZycpIHtcbiAgICAgIHJldHVybiAnZ3JlZWR5JztcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWluTWF4RXh0ZW50KHNwZWNpZmllZEV4dGVudDogbnVtYmVyLCBpc0dyaWRBeGlzOiBib29sZWFuKSB7XG4gIGlmIChpc0dyaWRBeGlzKSB7XG4gICAgLy8gQWx3YXlzIHJldHVybiAwIHRvIG1ha2Ugc3VyZSB0aGF0IGBjb25maWcuYXhpcyoubWluRXh0ZW50YCBhbmQgYGNvbmZpZy5heGlzKi5tYXhFeHRlbnRgXG4gICAgLy8gd291bGQgbm90IGFmZmVjdCBncmlkQXhpc1xuICAgIHJldHVybiAwO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzcGVjaWZpZWRFeHRlbnQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9yaWVudChjaGFubmVsOiBQb3NpdGlvblNjYWxlQ2hhbm5lbCkge1xuICBzd2l0Y2ggKGNoYW5uZWwpIHtcbiAgICBjYXNlIFg6XG4gICAgICByZXR1cm4gJ2JvdHRvbSc7XG4gICAgY2FzZSBZOlxuICAgICAgcmV0dXJuICdsZWZ0JztcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLiAqL1xuICB0aHJvdyBuZXcgRXJyb3IobG9nLm1lc3NhZ2UuSU5WQUxJRF9DSEFOTkVMX0ZPUl9BWElTKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRpY2tDb3VudChjaGFubmVsOiBQb3NpdGlvblNjYWxlQ2hhbm5lbCwgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIHNjYWxlVHlwZTogU2NhbGVUeXBlLCBzaXplOiBWZ1NpZ25hbFJlZikge1xuICBpZiAoIWhhc0Rpc2NyZXRlRG9tYWluKHNjYWxlVHlwZSkgJiYgc2NhbGVUeXBlICE9PSAnbG9nJyAmJiAhY29udGFpbnMoWydtb250aCcsICdob3VycycsICdkYXknLCAncXVhcnRlciddLCBmaWVsZERlZi50aW1lVW5pdCkpIHtcblxuICAgIGlmIChmaWVsZERlZi5iaW4pIHtcbiAgICAgIC8vIGZvciBiaW5uZWQgZGF0YSwgd2UgZG9uJ3Qgd2FudCBtb3JlIHRpY2tzIHRoYW4gbWF4Ymluc1xuICAgICAgcmV0dXJuIHtzaWduYWw6IGBjZWlsKCR7c2l6ZS5zaWduYWx9LzIwKWB9O1xuICAgIH1cbiAgICByZXR1cm4ge3NpZ25hbDogYGNlaWwoJHtzaXplLnNpZ25hbH0vNDApYH07XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGl0bGUobWF4TGVuZ3RoOiBudW1iZXIsIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBjb25maWc6IENvbmZpZykge1xuICAvLyBpZiBub3QgZGVmaW5lZCwgYXV0b21hdGljYWxseSBkZXRlcm1pbmUgYXhpcyB0aXRsZSBmcm9tIGZpZWxkIGRlZlxuICBjb25zdCBmaWVsZFRpdGxlID0gZmllbGREZWZUaXRsZShmaWVsZERlZiwgY29uZmlnKTtcbiAgcmV0dXJuIG1heExlbmd0aCA/IHRydW5jYXRlKGZpZWxkVGl0bGUsIG1heExlbmd0aCkgOiBmaWVsZFRpdGxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVzKHNwZWNpZmllZEF4aXM6IEF4aXMsIG1vZGVsOiBVbml0TW9kZWwsIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+KSB7XG4gIGNvbnN0IHZhbHMgPSBzcGVjaWZpZWRBeGlzLnZhbHVlcztcbiAgaWYgKHNwZWNpZmllZEF4aXMudmFsdWVzICYmIGlzRGF0ZVRpbWUodmFsc1swXSkpIHtcbiAgICByZXR1cm4gKHZhbHMgYXMgRGF0ZVRpbWVbXSkubWFwKChkdCkgPT4ge1xuICAgICAgLy8gbm9ybWFsaXplID0gdHJ1ZSBhcyBlbmQgdXNlciB3b24ndCBwdXQgMCA9IEphbnVhcnlcbiAgICAgIHJldHVybiB7c2lnbmFsOiBkYXRlVGltZUV4cHIoZHQsIHRydWUpfTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmICghdmFscyAmJiBmaWVsZERlZi5iaW4gJiYgZmllbGREZWYudHlwZSA9PT0gUVVBTlRJVEFUSVZFKSB7XG4gICAgY29uc3Qgc2lnbmFsID0gbW9kZWwuZ2V0TmFtZShgJHtiaW5Ub1N0cmluZyhmaWVsZERlZi5iaW4pfV8ke2ZpZWxkRGVmLmZpZWxkfV9iaW5zYCk7XG4gICAgcmV0dXJuIHtzaWduYWw6IGBzZXF1ZW5jZSgke3NpZ25hbH0uc3RhcnQsICR7c2lnbmFsfS5zdG9wICsgJHtzaWduYWx9LnN0ZXAsICR7c2lnbmFsfS5zdGVwKWB9O1xuICB9XG5cbiAgcmV0dXJuIHZhbHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB6aW5kZXgoaXNHcmlkQXhpczogYm9vbGVhbikge1xuICBpZiAoaXNHcmlkQXhpcykge1xuICAgIC8vIGlmIGdyaWQgaXMgdHJ1ZSwgbmVlZCB0byBwdXQgbGF5ZXIgb24gdGhlIGJhY2sgc28gdGhhdCBncmlkIGlzIGJlaGluZCBtYXJrc1xuICAgIHJldHVybiAwO1xuICB9XG4gIHJldHVybiAxOyAvLyBvdGhlcndpc2UgcmV0dXJuIHVuZGVmaW5lZCBhbmQgdXNlIFZlZ2EncyBkZWZhdWx0LlxufVxuIl19 \ 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..86f4ef085d --- /dev/null +++ b/build/src/compile/baseconcat.d.ts @@ -0,0 +1,17 @@ +import { Config } from '../config'; +import { Resolve } from '../resolve'; +import { BaseSpec } from '../spec'; +import { VgData, VgSignal } from '../vega.schema'; +import { Model } from './model'; +export declare abstract class BaseConcatModel extends Model { + constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, 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..9e823140bc --- /dev/null +++ b/build/src/compile/baseconcat.js @@ -0,0 +1,97 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../util"); +var parse_1 = require("./data/parse"); +var assemble_1 = require("./layoutsize/assemble"); +var model_1 = require("./model"); +var BaseConcatModel = /** @class */ (function (_super) { + __extends(BaseConcatModel, _super); + function BaseConcatModel(spec, parent, parentGivenName, config, resolve) { + return _super.call(this, spec, parent, parentGivenName, config, resolve) || this; + } + BaseConcatModel.prototype.parseData = function () { + this.component.data = parse_1.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(); + util_1.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()); + }, assemble_1.assembleLayoutSignals(this)); + }; + BaseConcatModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, []); + }; + 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_1.Model)); +exports.BaseConcatModel = BaseConcatModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZWNvbmNhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL2Jhc2Vjb25jYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFHQSxnQ0FBNkI7QUFFN0Isc0NBQXVDO0FBQ3ZDLGtEQUE0RDtBQUM1RCxpQ0FBOEI7QUFFOUI7SUFBOEMsbUNBQUs7SUFDakQseUJBQVksSUFBYyxFQUFFLE1BQWEsRUFBRSxlQUF1QixFQUFFLE1BQWMsRUFBRSxPQUFnQjtlQUNsRyxrQkFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDO0lBQ3ZELENBQUM7SUFFTSxtQ0FBUyxHQUFoQjtRQUNFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLGlCQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLO1lBQzFCLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDTSx3Q0FBYyxHQUFyQjtRQUFBLGlCQVdDO1FBVkMsbUVBQW1FO1FBQ25FLGlFQUFpRTtRQUNqRSxtRUFBbUU7UUFDbkUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO2dDQUNuQixLQUFLO1lBQ2QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLFdBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEdBQUc7Z0JBQzFDLEtBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUxELEdBQUcsQ0FBQyxD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QUE3RUQsQ0FBOEMsYUFBSyxHQTZFbEQ7QUE3RXFCLDBDQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQge1Jlc29sdmV9IGZyb20gJy4uL3Jlc29sdmUnO1xuaW1wb3J0IHtCYXNlU3BlY30gZnJvbSAnLi4vc3BlYyc7XG5pbXBvcnQge2tleXN9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0RhdGEsIFZnU2lnbmFsfSBmcm9tICcuLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3BhcnNlRGF0YX0gZnJvbSAnLi9kYXRhL3BhcnNlJztcbmltcG9ydCB7YXNzZW1ibGVMYXlvdXRTaWduYWxzfSBmcm9tICcuL2xheW91dHNpemUvYXNzZW1ibGUnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi9tb2RlbCc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlQ29uY2F0TW9kZWwgZXh0ZW5kcyBNb2RlbCB7XG4gIGNvbnN0cnVjdG9yKHNwZWM6IEJhc2VTcGVjLCBwYXJlbnQ6IE1vZGVsLCBwYXJlbnRHaXZlbk5hbWU6IHN0cmluZywgY29uZmlnOiBDb25maWcsIHJlc29sdmU6IFJlc29sdmUpIHtcbiAgICBzdXBlcihzcGVjLCBwYXJlbnQsIHBhcmVudEdpdmVuTmFtZSwgY29uZmlnLCByZXNvbHZlKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZURhdGEoKSB7XG4gICAgdGhpcy5jb21wb25lbnQuZGF0YSA9IHBhcnNlRGF0YSh0aGlzKTtcbiAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICBjaGlsZC5wYXJzZURhdGEoKTtcbiAgICB9KTtcbiAgfVxuICBwdWJsaWMgcGFyc2VTZWxlY3Rpb24oKSB7XG4gICAgLy8gTWVyZ2Ugc2VsZWN0aW9ucyB1cCB0aGUgaGllcmFyY2h5IHNvIHRoYXQgdGhleSBtYXkgYmUgcmVmZXJlbmNlZFxuICAgIC8vIGFjcm9zcyB1bml0IHNwZWNzLiBQZXJzaXN0IHRoZWlyIGRlZmluaXRpb25zIHdpdGhpbiBlYWNoIGNoaWxkXG4gICAgLy8gdG8gYXNzZW1ibGUgc2lnbmFscyB3aGljaCByZW1haW4gd2l0aGluIG91dHB1dCBWZWdhIHVuaXQgZ3JvdXBzLlxuICAgIHRoaXMuY29tcG9uZW50LnNlbGVjdGlvbiA9IHt9O1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgY2hpbGQucGFyc2VTZWxlY3Rpb24oKTtcbiAgICAgIGtleXMoY2hpbGQuY29tcG9uZW50LnNlbGVjdGlvbikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIHRoaXMuY29tcG9uZW50LnNlbGVjdGlvbltrZXldID0gY2hpbGQuY29tcG9uZW50LnNlbGVjdGlvbltrZXldO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBhcnNlTWFya0dyb3VwKCkge1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgY2hpbGQucGFyc2VNYXJrR3JvdXAoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcGFyc2VBeGlzQW5kSGVhZGVyKCkge1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgY2hpbGQucGFyc2VBeGlzQW5kSGVhZGVyKCk7XG4gICAgfVxuXG4gICAgLy8gVE9ETygjMjQxNSk6IHN1cHBvcnQgc2hhcmVkIGF4ZXNcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZVNlbGVjdGlvblRvcExldmVsU2lnbmFscyhzaWduYWxzOiBhbnlbXSk6IFZnU2lnbmFsW10ge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLnJlZHVjZSgoc2csIGNoaWxkKSA9PiBjaGlsZC5hc3NlbWJsZVNlbGVjdGlvblRvcExldmVsU2lnbmFscyhzZyksIHNpZ25hbHMpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlU2VsZWN0aW9uU2lnbmFscygpOiBWZ1NpZ25hbFtdIHtcbiAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiBjaGlsZC5hc3NlbWJsZVNlbGVjdGlvblNpZ25hbHMoKSk7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTGF5b3V0U2lnbmFscygpOiBWZ1NpZ25hbFtdIHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5yZWR1Y2UoKHNpZ25hbHMsIGNoaWxkKSA9PiB7XG4gICAgICByZXR1cm4gc2lnbmFscy5jb25jYXQoY2hpbGQuYXNzZW1ibGVMYXlvdXRTaWduYWxzKCkpO1xuICAgIH0sIGFzc2VtYmxlTGF5b3V0U2lnbmFscyh0aGlzKSk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVTZWxlY3Rpb25EYXRhKGRhdGE6IFZnRGF0YVtdKTogVmdEYXRhW10ge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLnJlZHVjZSgoZGIsIGNoaWxkKSA9PiBjaGlsZC5hc3NlbWJsZVNlbGVjdGlvbkRhdGEoZGIpLCBbXSk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVNYXJrcygpOiBhbnlbXSB7XG4gICAgLy8gb25seSBjaGlsZHJlbiBoYXZlIG1hcmtzXG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4ubWFwKGNoaWxkID0+IHtcbiAgICAgIGNvbnN0IHRpdGxlID0gY2hpbGQuYXNzZW1ibGVUaXRsZSgpO1xuICAgICAgY29uc3Qgc3R5bGUgPSBjaGlsZC5hc3NlbWJsZUdyb3VwU3R5bGUoKTtcbiAgICAgIGNvbnN0IGxheW91dFNpemVFbmNvZGVFbnRyeSA9IGNoaWxkLmFzc2VtYmxlTGF5b3V0U2l6ZSgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2dyb3VwJyxcbiAgICAgICAgbmFtZTogY2hpbGQuZ2V0TmFtZSgnZ3JvdXAnKSxcbiAgICAgICAgLi4uKHRpdGxlID8ge3RpdGxlfSA6IHt9KSxcbiAgICAgICAgLi4uKHN0eWxlID8ge3N0eWxlfSA6IHt9KSxcbiAgICAgICAgLi4uKGxheW91dFNpemVFbmNvZGVFbnRyeSA/IHtcbiAgICAgICAgICBlbmNvZGU6IHtcbiAgICAgICAgICAgIHVwZGF0ZTogbGF5b3V0U2l6ZUVuY29kZUVudHJ5XG4gICAgICAgICAgfVxuICAgICAgICB9IDoge30pLFxuICAgICAgICAuLi5jaGlsZC5hc3NlbWJsZUdyb3VwKClcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ 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..007bb85466 --- /dev/null +++ b/build/src/compile/buildmodel.d.ts @@ -0,0 +1,5 @@ +import { Config } from '../config'; +import { LayoutSizeMixins, Spec } from '../spec'; +import { Model } from './model'; +import { RepeaterValue } from './repeater'; +export declare function buildModel(spec: Spec, 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..aae99de9ea --- /dev/null +++ b/build/src/compile/buildmodel.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var spec_1 = require("../spec"); +var concat_1 = require("./concat"); +var facet_1 = require("./facet"); +var layer_1 = require("./layer"); +var repeat_1 = require("./repeat"); +var unit_1 = require("./unit"); +function buildModel(spec, parent, parentGivenName, unitSize, repeater, config, fit) { + if (spec_1.isFacetSpec(spec)) { + return new facet_1.FacetModel(spec, parent, parentGivenName, repeater, config); + } + if (spec_1.isLayerSpec(spec)) { + return new layer_1.LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (spec_1.isUnitSpec(spec)) { + return new unit_1.UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (spec_1.isRepeatSpec(spec)) { + return new repeat_1.RepeatModel(spec, parent, parentGivenName, repeater, config); + } + if (spec_1.isConcatSpec(spec)) { + return new concat_1.ConcatModel(spec, parent, parentGivenName, repeater, config); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.buildModel = buildModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRtb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL2J1aWxkbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQSw0QkFBOEI7QUFDOUIsZ0NBQWlIO0FBQ2pILG1DQUFxQztBQUNyQyxpQ0FBbUM7QUFDbkMsaUNBQW1DO0FBRW5DLG1DQUFxQztBQUVyQywrQkFBaUM7QUFFakMsb0JBQTJCLElBQVUsRUFBRSxNQUFhLEVBQUUsZUFBdUIsRUFDM0UsUUFBMEIsRUFBRSxRQUF1QixFQUFFLE1BQWMsRUFBRSxHQUFZO0lBQ2pGLEVBQUUsQ0FBQyxDQUFDLGtCQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxJQUFJLGtCQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxrQkFBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsSUFBSSxrQkFBVSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxpQkFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsSUFBSSxnQkFBUyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxtQkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsSUFBSSxvQkFBVyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsbUJBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLElBQUksb0JBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBdkJELGdDQXVCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL2xvZyc7XG5pbXBvcnQge2lzQ29uY2F0U3BlYywgaXNGYWNldFNwZWMsIGlzTGF5ZXJTcGVjLCBpc1JlcGVhdFNwZWMsIGlzVW5pdFNwZWMsIExheW91dFNpemVNaXhpbnMsIFNwZWN9IGZyb20gJy4uL3NwZWMnO1xuaW1wb3J0IHtDb25jYXRNb2RlbH0gZnJvbSAnLi9jb25jYXQnO1xuaW1wb3J0IHtGYWNldE1vZGVsfSBmcm9tICcuL2ZhY2V0JztcbmltcG9ydCB7TGF5ZXJNb2RlbH0gZnJvbSAnLi9sYXllcic7XG5pbXBvcnQge01vZGVsfSBmcm9tICcuL21vZGVsJztcbmltcG9ydCB7UmVwZWF0TW9kZWx9IGZyb20gJy4vcmVwZWF0JztcbmltcG9ydCB7UmVwZWF0ZXJWYWx1ZX0gZnJvbSAnLi9yZXBlYXRlcic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi91bml0JztcblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkTW9kZWwoc3BlYzogU3BlYywgcGFyZW50OiBNb2RlbCwgcGFyZW50R2l2ZW5OYW1lOiBzdHJpbmcsXG4gIHVuaXRTaXplOiBMYXlvdXRTaXplTWl4aW5zLCByZXBlYXRlcjogUmVwZWF0ZXJWYWx1ZSwgY29uZmlnOiBDb25maWcsIGZpdDogYm9vbGVhbik6IE1vZGVsIHtcbiAgaWYgKGlzRmFjZXRTcGVjKHNwZWMpKSB7XG4gICAgcmV0dXJuIG5ldyBGYWNldE1vZGVsKHNwZWMsIHBhcmVudCwgcGFyZW50R2l2ZW5OYW1lLCByZXBlYXRlciwgY29uZmlnKTtcbiAgfVxuXG4gIGlmIChpc0xheWVyU3BlYyhzcGVjKSkge1xuICAgIHJldHVybiBuZXcgTGF5ZXJNb2RlbChzcGVjLCBwYXJlbnQsIHBhcmVudEdpdmVuTmFtZSwgdW5pdFNpemUsIHJlcGVhdGVyLCBjb25maWcsIGZpdCk7XG4gIH1cblxuICBpZiAoaXNVbml0U3BlYyhzcGVjKSkge1xuICAgIHJldHVybiBuZXcgVW5pdE1vZGVsKHNwZWMsIHBhcmVudCwgcGFyZW50R2l2ZW5OYW1lLCB1bml0U2l6ZSwgcmVwZWF0ZXIsIGNvbmZpZywgZml0KTtcbiAgfVxuXG4gIGlmIChpc1JlcGVhdFNwZWMoc3BlYykpIHtcbiAgICByZXR1cm4gbmV3IFJlcGVhdE1vZGVsKHNwZWMsIHBhcmVudCwgcGFyZW50R2l2ZW5OYW1lLCByZXBlYXRlciwgY29uZmlnKTtcbiAgfVxuXG4gIGlmIChpc0NvbmNhdFNwZWMoc3BlYykpIHtcbiAgICByZXR1cm4gbmV3IENvbmNhdE1vZGVsKHNwZWMsIHBhcmVudCwgcGFyZW50R2l2ZW5OYW1lLCByZXBlYXRlciwgY29uZmlnKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihsb2cubWVzc2FnZS5JTlZBTElEX1NQRUMpO1xufVxuIl19 \ 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..2113d48d7b --- /dev/null +++ b/build/src/compile/common.d.ts @@ -0,0 +1,48 @@ +import { Channel } from '../channel'; +import { Config, ViewConfig } from '../config'; +import { FieldDef, FieldRefOption, OrderFieldDef } from '../fielddef'; +import { MarkConfig, MarkDef, TextConfig } from '../mark'; +import { TimeUnit } from '../timeunit'; +import { VgEncodeEntry, VgSort } from '../vega.schema'; +import { Explicit } from './split'; +import { UnitModel } from './unit'; +export declare function applyConfig(e: VgEncodeEntry, config: ViewConfig | 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): string; +/** + * Return Vega sort parameters (tuple of field and order). + */ +export declare function sortParams(orderDef: OrderFieldDef | OrderFieldDef[], fieldRefOption?: FieldRefOption): VgSort; +export declare function titleMerger(v1: Explicit, v2: Explicit): { + 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; diff --git a/build/src/compile/common.js b/build/src/compile/common.js new file mode 100644 index 0000000000..b3679394aa --- /dev/null +++ b/build/src/compile/common.js @@ -0,0 +1,178 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var fielddef_1 = require("../fielddef"); +var scale_1 = require("../scale"); +var timeunit_1 = require("../timeunit"); +var type_1 = require("../type"); +var util_1 = require("../util"); +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; +} +exports.applyConfig = applyConfig; +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; +} +exports.applyMarkConfig = applyMarkConfig; +function getStyles(mark) { + return [].concat(mark.type, mark.style || []); +} +exports.getStyles = getStyles; +/** + * 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; +} +exports.getMarkConfig = getMarkConfig; +function formatSignalRef(fieldDef, specifiedFormat, expr, config) { + var format = numberFormat(fieldDef, specifiedFormat, config); + if (fieldDef.bin) { + var startField = fielddef_1.field(fieldDef, { expr: expr }); + var endField = fielddef_1.field(fieldDef, { expr: expr, binSuffix: 'end' }); + return { + signal: binFormatExpression(startField, endField, format, config) + }; + } + else if (fieldDef.type === 'quantitative') { + return { + signal: "" + formatExpr(fielddef_1.field(fieldDef, { expr: expr }), format) + }; + } + else if (fielddef_1.isTimeFieldDef(fieldDef)) { + var isUTCScale = fielddef_1.isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === scale_1.ScaleType.UTC; + return { + signal: timeFormatExpression(fielddef_1.field(fieldDef, { expr: expr }), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale) + }; + } + else { + return { + signal: "''+" + fielddef_1.field(fieldDef, { expr: expr }) + }; + } +} +exports.formatSignalRef = formatSignalRef; +function getSpecifiedOrDefaultValue(specifiedValue, defaultValue) { + if (specifiedValue !== undefined) { + return specifiedValue; + } + return defaultValue; +} +exports.getSpecifiedOrDefaultValue = getSpecifiedOrDefaultValue; +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +function numberFormat(fieldDef, specifiedFormat, config) { + if (fieldDef.type === type_1.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; +} +exports.numberFormat = numberFormat; +function formatExpr(field, format) { + return "format(" + field + ", \"" + (format || '') + "\")"; +} +function numberFormatExpr(field, specifiedFormat, config) { + return formatExpr(field, specifiedFormat || config.numberFormat); +} +exports.numberFormatExpr = numberFormatExpr; +function binFormatExpression(startField, endField, format, config) { + return startField + " === null || isNaN(" + startField + ") ? \"null\" : " + numberFormatExpr(startField, format, config) + " + \" - \" + " + numberFormatExpr(endField, format, config); +} +exports.binFormatExpression = binFormatExpression; +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +function timeFormatExpression(field, timeUnit, format, shortTimeLabels, timeFormatConfig, isUTCScale) { + if (!timeUnit || format) { + // If there is not time unit, or if user explicitly specify format for axis/legend/text. + var _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit. + if (isUTCScale) { + return "utcFormat(" + field + ", '" + _format + "')"; + } + else { + return "timeFormat(" + field + ", '" + _format + "')"; + } + } + else { + return timeunit_1.formatExpression(timeUnit, field, shortTimeLabels, isUTCScale); + } +} +exports.timeFormatExpression = timeFormatExpression; +/** + * Return Vega sort parameters (tuple of field and order). + */ +function sortParams(orderDef, fieldRefOption) { + return (util_1.isArray(orderDef) ? orderDef : [orderDef]).reduce(function (s, orderChannelDef) { + s.field.push(fielddef_1.field(orderChannelDef, fieldRefOption)); + s.order.push(orderChannelDef.sort || 'ascending'); + return s; + }, { field: [], order: [] }); +} +exports.sortParams = sortParams; +function titleMerger(v1, v2) { + return { + explicit: v1.explicit, + value: v1.value === v2.value ? + v1.value : // if title is the same just use one of them + v1.value + ', ' + v2.value // join title with comma if different + }; +} +exports.titleMerger = titleMerger; +/** + * 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 channel_1.isScaleChannel(channel) && util_1.contains(['ordinal', 'nominal'], fieldDef.type); +} +exports.binRequiresRange = binRequiresRange; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGUvY29tbW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsc0NBQW1EO0FBRW5ELHdDQUE0RztBQUU1RyxrQ0FBbUM7QUFFbkMsd0NBQTZDO0FBQzdDLGdDQUFxQztBQUNyQyxnQ0FBMEM7QUFNMUMscUJBQTRCLENBQWdCLEVBQ3hDLE1BQTRDLEVBQUUsb0RBQW9EO0lBQ2xHLFNBQW1CO0lBQ3JCLEdBQUcsQ0FBQyxDQUFtQixVQUFTLEVBQVQsdUJBQVMsRUFBVCx1QkFBUyxFQUFULElBQVM7UUFBM0IsSUFBTSxRQUFRLGtCQUFBO1FBQ2pCLElBQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvQixFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUN4QixDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUM7UUFDL0IsQ0FBQztLQUNGO0lBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNYLENBQUM7QUFWRCxrQ0FVQztBQUVELHlCQUFnQyxDQUFnQixFQUFFLEtBQWdCLEVBQUUsU0FBK0I7SUFDakcsR0FBRyxDQUFDLENBQW1CLFVBQVMsRUFBVCx1QkFBUyxFQUFULHVCQUFTLEVBQVQsSUFBUztRQUEzQixJQUFNLFFBQVEsa0JBQUE7UUFDakIsSUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUN4QixDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUM7UUFDL0IsQ0FBQztLQUNGO0lBQ0QsTUFBTSxDQUFD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QUFDLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3BGLENBQUM7QUFURCw0Q0FTQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbm5lbCwgaXNTY2FsZUNoYW5uZWx9IGZyb20gJy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtDb25maWcsIFZpZXdDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQge2ZpZWxkLCBGaWVsZERlZiwgRmllbGRSZWZPcHRpb24sIGlzU2NhbGVGaWVsZERlZiwgaXNUaW1lRmllbGREZWYsIE9yZGVyRmllbGREZWZ9IGZyb20gJy4uL2ZpZWxkZGVmJztcbmltcG9ydCB7TWFya0NvbmZpZywgTWFya0RlZiwgVGV4dENvbmZpZ30gZnJvbSAnLi4vbWFyayc7XG5pbXBvcnQge1NjYWxlVHlwZX0gZnJvbSAnLi4vc2NhbGUnO1xuaW1wb3J0IHtUaW1lVW5pdH0gZnJvbSAnLi4vdGltZXVuaXQnO1xuaW1wb3J0IHtmb3JtYXRFeHByZXNzaW9ufSBmcm9tICcuLi90aW1ldW5pdCc7XG5pbXBvcnQge1FVQU5USVRBVElWRX0gZnJvbSAnLi4vdHlwZSc7XG5pbXBvcnQge2NvbnRhaW5zLCBpc0FycmF5fSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7VmdFbmNvZGVFbnRyeSwgVmdNYXJrQ29uZmlnLCBWZ1NvcnR9IGZyb20gJy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7RXhwbGljaXR9IGZyb20gJy4vc3BsaXQnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4vdW5pdCc7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5Q29uZmlnKGU6IFZnRW5jb2RlRW50cnksXG4gICAgY29uZmlnOiBWaWV3Q29uZmlnIHwgTWFya0NvbmZpZyB8IFRleHRDb25maWcsIC8vIFRPRE8oIzE4NDIpOiBjb25zb2xpZGF0ZSBNYXJrQ29uZmlnIHwgVGV4dENvbmZpZz9cbiAgICBwcm9wc0xpc3Q6IHN0cmluZ1tdKSB7XG4gIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcHNMaXN0KSB7XG4gICAgY29uc3QgdmFsdWUgPSBjb25maWdbcHJvcGVydHldO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBlW3Byb3BlcnR5XSA9IHt2YWx1ZTogdmFsdWV9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5TWFya0NvbmZpZyhlOiBWZ0VuY29kZUVudHJ5LCBtb2RlbDogVW5pdE1vZGVsLCBwcm9wc0xpc3Q6IChrZXlvZiBNYXJrQ29uZmlnKVtdKSB7XG4gIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcHNMaXN0KSB7XG4gICAgY29uc3QgdmFsdWUgPSBnZXRNYXJrQ29uZmlnKHByb3BlcnR5LCBtb2RlbC5tYXJrRGVmLCBtb2RlbC5jb25maWcpO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBlW3Byb3BlcnR5XSA9IHt2YWx1ZTogdmFsdWV9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0eWxlcyhtYXJrOiBNYXJrRGVmKTogc3RyaW5nW10ge1xuICByZXR1cm4gW10uY29uY2F0KG1hcmsudHlwZSwgbWFyay5zdHlsZSB8fCBbXSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHByb3BlcnR5IHZhbHVlIGZyb20gc3R5bGUgb3IgbWFyayBzcGVjaWZpYyBjb25maWcgcHJvcGVydHkgaWYgZXhpc3RzLlxuICogT3RoZXJ3aXNlLCByZXR1cm4gZ2VuZXJhbCBtYXJrIHNwZWNpZmljIGNvbmZpZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcmtDb25maWc8UCBleHRlbmRzIGtleW9mIE1hcmtDb25maWc+KHByb3A6IFAsIG1hcms6IE1hcmtEZWYsIGNvbmZpZzogQ29uZmlnKTogTWFya0NvbmZpZ1tQXSB7XG4gIC8vIEJ5IGRlZmF1bHQsIHJlYWQgZnJvbSBtYXJrIGNvbmZpZyBmaXJzdCFcbiAgbGV0IHZhbHVlID0gY29uZmlnLm1hcmtbcHJvcF07XG5cbiAgLy8gVGhlbiByZWFkIG1hcmsgc3BlY2lmaWMgY29uZmlnLCB3aGljaCBoYXMgaGlnaGVyIHByZWNlZGVuY2VcbiAgY29uc3QgbWFya1NwZWNpZmljQ29uZmlnID0gY29uZmlnW21hcmsudHlwZV07XG4gIGlmIChtYXJrU3BlY2lmaWNDb25maWdbcHJvcF0gIT09IHVuZGVmaW5lZCkge1xuICAgIHZhbHVlID0gbWFya1NwZWNpZmljQ29uZmlnW3Byb3BdO1xuICB9XG5cbiAgLy8gVGhlbiByZWFkIHN0eWxlIGNvbmZpZywgd2hpY2ggaGFzIGV2ZW4gaGlnaGVyIHByZWNlZGVuY2UuXG4gIGNvbnN0IHN0eWxlcyA9IGdldFN0eWxlcyhtYXJrKTtcbiAgZm9yIChjb25zdCBzdHlsZSBvZiBzdHlsZXMpIHtcbiAgICBjb25zdCBzdHlsZUNvbmZpZyA9IGNvbmZpZy5zdHlsZVtzdHlsZV07XG5cbiAgICAvLyBNYXJrQ29uZmlnIGV4dGVuZHMgVmdNYXJrQ29uZmlnIHNvIGEgcHJvcCBtYXkgbm90IGJlIGEgdmFsaWQgcHJvcGVydHkgZm9yIHN0eWxlXG4gICAgLy8gSG93ZXZlciBoZXJlIHdlIGFsc28gY2hlY2sgaWYgaXQgaXMgZGVmaW5lZCwgc28gaXQgaXMgb2theSB0byBjYXN0IGhlcmVcbiAgICBjb25zdCBwID0gcHJvcCBhcyBrZXlvZiBWZ01hcmtDb25maWc7XG4gICAgaWYgKHN0eWxlQ29uZmlnICYmIHN0eWxlQ29uZmlnW3BdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhbHVlID0gc3R5bGVDb25maWdbcF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0U2lnbmFsUmVmKGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBzcGVjaWZpZWRGb3JtYXQ6IHN0cmluZywgZXhwcjogJ2RhdHVtJyB8ICdwYXJlbnQnLCBjb25maWc6IENvbmZpZykge1xuICBjb25zdCBmb3JtYXQgPSBudW1iZXJGb3JtYXQoZmllbGREZWYsIHNwZWNpZmllZEZvcm1hdCwgY29uZmlnKTtcbiAgaWYgKGZpZWxkRGVmLmJpbikge1xuICAgIGNvbnN0IHN0YXJ0RmllbGQgPSBmaWVsZChmaWVsZERlZiwge2V4cHJ9KTtcbiAgICBjb25zdCBlbmRGaWVsZCA9IGZpZWxkKGZpZWxkRGVmLCB7ZXhwciwgYmluU3VmZml4OiAnZW5kJ30pO1xuICAgIHJldHVybiB7XG4gICAgICBzaWduYWw6IGJpbkZvcm1hdEV4cHJlc3Npb24oc3RhcnRGaWVsZCwgZW5kRmllbGQsIGZvcm1hdCwgY29uZmlnKVxuICAgIH07XG4gIH0gZWxzZSBpZiAoZmllbGREZWYudHlwZSA9PT0gJ3F1YW50aXRhdGl2ZScpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2lnbmFsOiBgJHtmb3JtYXRFeHByKGZpZWxkKGZpZWxkRGVmLCB7ZXhwcn0pLCBmb3JtYXQpfWBcbiAgICB9O1xuICB9IGVsc2UgaWYgKGlzVGltZUZpZWxkRGVmKGZpZWxkRGVmKSkge1xuICAgIGNvbnN0IGlzVVRDU2NhbGUgPSBpc1NjYWxlRmllbGREZWYoZmllbGREZWYpICYmIGZpZWxkRGVmWydzY2FsZSddICYmIGZpZWxkRGVmWydzY2FsZSddLnR5cGUgPT09IFNjYWxlVHlwZS5VVEM7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNpZ25hbDogdGltZUZvcm1hdEV4cHJlc3Npb24oZmllbGQoZmllbGREZWYsIHtleHByfSksIGZpZWxkRGVmLnRpbWVVbml0LCBzcGVjaWZpZWRGb3JtYXQsIGNvbmZpZy50ZXh0LnNob3J0VGltZUxhYmVscywgY29uZmlnLnRpbWVGb3JtYXQsIGlzVVRDU2NhbGUpXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2lnbmFsOiBgJycrJHtmaWVsZChmaWVsZERlZiwge2V4cHJ9KX1gXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3BlY2lmaWVkT3JEZWZhdWx0VmFsdWU8VD4oc3BlY2lmaWVkVmFsdWU6IFQsIGRlZmF1bHRWYWx1ZTogVCB8IHtzaWduYWw6IHN0cmluZ30pIHtcbiAgaWYgKHNwZWNpZmllZFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gc3BlY2lmaWVkVmFsdWU7XG4gIH1cbiAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIG51bWJlciBmb3JtYXQgZm9yIGEgZmllbGREZWZcbiAqXG4gKiBAcGFyYW0gZm9ybWF0IGV4cGxpY2l0bHkgc3BlY2lmaWVkIGZvcm1hdFxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVtYmVyRm9ybWF0KGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBzcGVjaWZpZWRGb3JtYXQ6IHN0cmluZywgY29uZmlnOiBDb25maWcpIHtcbiAgaWYgKGZpZWxkRGVmLnR5cGUgPT09IFFVQU5USVRBVElWRSkge1xuICAgIC8vIGFkZCBudW1iZXIgZm9ybWF0IGZvciBxdWFudGl0YXRpdmUgdHlwZSBvbmx5XG5cbiAgICAvLyBTcGVjaWZpZWQgZm9ybWF0IGluIGF4aXMvbGVnZW5kIGhhcyBoaWdoZXIgcHJlY2VkZW5jZSB0aGFuIGZpZWxkRGVmLmZvcm1hdFxuICAgIGlmIChzcGVjaWZpZWRGb3JtYXQpIHtcbiAgICAgIHJldHVybiBzcGVjaWZpZWRGb3JtYXQ7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogbmVlZCB0byBtYWtlIHRoaXMgd29yayBjb3JyZWN0bHkgZm9yIG51bWVyaWMgb3JkaW5hbCAvIG5vbWluYWwgdHlwZVxuICAgIHJldHVybiBjb25maWcubnVtYmVyRm9ybWF0O1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEV4cHIoZmllbGQ6IHN0cmluZywgZm9ybWF0OiBzdHJpbmcpIHtcbiAgcmV0dXJuIGBmb3JtYXQoJHtmaWVsZH0sIFwiJHtmb3JtYXQgfHwgJyd9XCIpYDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlckZvcm1hdEV4cHIoZmllbGQ6IHN0cmluZywgc3BlY2lmaWVkRm9ybWF0OiBzdHJpbmcsIGNvbmZpZzogQ29uZmlnKSB7XG4gIHJldHVybiBmb3JtYXRFeHByKGZpZWxkLCBzcGVjaWZpZWRGb3JtYXQgfHwgY29uZmlnLm51bWJlckZvcm1hdCk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGJpbkZvcm1hdEV4cHJlc3Npb24oc3RhcnRGaWVsZDogc3RyaW5nLCBlbmRGaWVsZDogc3RyaW5nLCBmb3JtYXQ6IHN0cmluZywgY29uZmlnOiBDb25maWcpIHtcbiAgcmV0dXJuIGAke3N0YXJ0RmllbGR9ID09PSBudWxsIHx8IGlzTmFOKCR7c3RhcnRGaWVsZH0pID8gXCJudWxsXCIgOiAke251bWJlckZvcm1hdEV4cHIoc3RhcnRGaWVsZCwgZm9ybWF0LCBjb25maWcpfSArIFwiIC0gXCIgKyAke251bWJlckZvcm1hdEV4cHIoZW5kRmllbGQsIGZvcm1hdCwgY29uZmlnKX1gO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgdGltZSBleHByZXNzaW9uIHVzZWQgZm9yIGF4aXMvbGVnZW5kIGxhYmVscyBvciB0ZXh0IG1hcmsgZm9yIGEgdGVtcG9yYWwgZmllbGRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVGb3JtYXRFeHByZXNzaW9uKGZpZWxkOiBzdHJpbmcsIHRpbWVVbml0OiBUaW1lVW5pdCwgZm9ybWF0OiBzdHJpbmcsIHNob3J0VGltZUxhYmVsczogYm9vbGVhbiwgdGltZUZvcm1hdENvbmZpZzogc3RyaW5nLCBpc1VUQ1NjYWxlOiBib29sZWFuKTogc3RyaW5nIHtcbiAgaWYgKCF0aW1lVW5pdCB8fCBmb3JtYXQpIHtcbiAgICAvLyBJZiB0aGVyZSBpcyBub3QgdGltZSB1bml0LCBvciBpZiB1c2VyIGV4cGxpY2l0bHkgc3BlY2lmeSBmb3JtYXQgZm9yIGF4aXMvbGVnZW5kL3RleHQuXG4gICAgY29uc3QgX2Zvcm1hdCA9IGZvcm1hdCB8fCB0aW1lRm9ybWF0Q29uZmlnOyAvLyBvbmx5IHVzZSBjb25maWcudGltZUZvcm1hdCBpZiB0aGVyZSBpcyBubyB0aW1lVW5pdC5cbiAgICBpZiAoaXNVVENTY2FsZSkge1xuICAgICAgcmV0dXJuIGB1dGNGb3JtYXQoJHtmaWVsZH0sICcke19mb3JtYXR9JylgO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYHRpbWVGb3JtYXQoJHtmaWVsZH0sICcke19mb3JtYXR9JylgO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZm9ybWF0RXhwcmVzc2lvbih0aW1lVW5pdCwgZmllbGQsIHNob3J0VGltZUxhYmVscywgaXNVVENTY2FsZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gVmVnYSBzb3J0IHBhcmFtZXRlcnMgKHR1cGxlIG9mIGZpZWxkIGFuZCBvcmRlcikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb3J0UGFyYW1zKG9yZGVyRGVmOiBPcmRlckZpZWxkRGVmPHN0cmluZz4gfCBPcmRlckZpZWxkRGVmPHN0cmluZz5bXSwgZmllbGRSZWZPcHRpb24/OiBGaWVsZFJlZk9wdGlvbik6IFZnU29ydCB7XG4gIHJldHVybiAoaXNBcnJheShvcmRlckRlZikgPyBvcmRlckRlZiA6IFtvcmRlckRlZl0pLnJlZHVjZSgocywgb3JkZXJDaGFubmVsRGVmKSA9PiB7XG4gICAgcy5maWVsZC5wdXNoKGZpZWxkKG9yZGVyQ2hhbm5lbERlZiwgZmllbGRSZWZPcHRpb24pKTtcbiAgICBzLm9yZGVyLnB1c2gob3JkZXJDaGFubmVsRGVmLnNvcnQgfHwgJ2FzY2VuZGluZycpO1xuICAgIHJldHVybiBzO1xuICB9LCB7ZmllbGQ6W10sIG9yZGVyOiBbXX0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGl0bGVNZXJnZXIodjE6IEV4cGxpY2l0PHN0cmluZz4sIHYyOiBFeHBsaWNpdDxzdHJpbmc+KSB7XG4gIHJldHVybiB7XG4gICAgZXhwbGljaXQ6IHYxLmV4cGxpY2l0LCAvLyBrZWVwIHRoZSBvbGQgZXhwbGljaXRcbiAgICB2YWx1ZTogdjEudmFsdWUgPT09IHYyLnZhbHVlID9cbiAgICAgIHYxLnZhbHVlIDogLy8gaWYgdGl0bGUgaXMgdGhlIHNhbWUganVzdCB1c2Ugb25lIG9mIHRoZW1cbiAgICAgIHYxLnZhbHVlICsgJywgJyArIHYyLnZhbHVlIC8vIGpvaW4gdGl0bGUgd2l0aCBjb21tYSBpZiBkaWZmZXJlbnRcbiAgfTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIGZpZWxkRGVmIGZvciBhIHBhcnRpY3VsYXIgY2hhbm5lbCByZXF1aXJlcyBhIGNvbXB1dGVkIGJpbiByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpblJlcXVpcmVzUmFuZ2UoZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIGNoYW5uZWw6IENoYW5uZWwpIHtcbiAgaWYgKCFmaWVsZERlZi5iaW4pIHtcbiAgICBjb25zb2xlLndhcm4oJ09ubHkgdXNlIHRoaXMgbWV0aG9kIHdpdGggYmlubmVkIGZpZWxkIGRlZnMnKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBXZSBuZWVkIHRoZSByYW5nZSBvbmx5IHdoZW4gdGhlIHVzZXIgZXhwbGljaXRseSBmb3JjZXMgYSBiaW5uZWQgZmllbGQgdG8gYmUgdXNlIGRpc2NyZXRlIHNjYWxlLiBJbiB0aGlzIGNhc2UsIGJpbiByYW5nZSBpcyB1c2VkIGluIGF4aXMgYW5kIGxlZ2VuZCBsYWJlbHMuXG4gIC8vIFdlIGNvdWxkIGNoZWNrIHdoZXRoZXIgdGhlIGF4aXMgb3IgbGVnZW5kIGV4aXN0cyAobm90IGRpc2FibGVkKSBidXQgdGhhdCBzZWVtcyBvdmVya2lsbC5cbiAgcmV0dXJuIGlzU2NhbGVDaGFubmVsKGNoYW5uZWwpICYmIGNvbnRhaW5zKFsnb3JkaW5hbCcsICdub21pbmFsJ10sIGZpZWxkRGVmLnR5cGUpO1xufVxuIl19 \ 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..af2632e11f --- /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 { TopLevelExtendedSpec } 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 + * | + * | (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: TopLevelExtendedSpec, opt?: CompileOptions): { + spec: any; +}; diff --git a/build/src/compile/compile.js b/build/src/compile/compile.js new file mode 100644 index 0000000000..e2b767af22 --- /dev/null +++ b/build/src/compile/compile.js @@ -0,0 +1,128 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var config_1 = require("../config"); +var vlFieldDef = require("../fielddef"); +var log = require("../log"); +var spec_1 = require("../spec"); +var toplevelprops_1 = require("../toplevelprops"); +var util_1 = require("../util"); +var buildmodel_1 = require("./buildmodel"); +var assemble_1 = require("./data/assemble"); +var optimize_1 = require("./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 + * | + * | (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 + 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 = config_1.initConfig(util_1.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 = spec_1.normalize(inputSpec, config); + // - Normalize autosize to be a autosize properties object. + var autosize = toplevelprops_1.normalizeAutoSize(inputSpec.autosize, config.autosize, spec_1.isLayerSpec(spec) || spec_1.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_1.buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit'); + // 4 Parse: Model --> Model with components (components = intermediate that can be merged + // and assembled easily) + // 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. + optimize_1.optimizeDataflow(model.component.data); + // 6. Assemble: convert model and 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(); + } + } +} +exports.compile = compile; +function getTopLevelProperties(topLevelSpec, config, autosize) { + return __assign({ autosize: util_1.keys(autosize).length === 1 && autosize.type ? autosize.type : autosize }, toplevelprops_1.extractTopLevelProperties(config), toplevelprops_1.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 ? config_1.stripAndRedirectConfig(model.config) : undefined; + 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 = __assign({ $schema: 'https://vega.github.io/schema/vega/v3.0.json' }, (model.description ? { description: model.description } : {}), topLevelProperties, (title ? { title: title } : {}), (style ? { style: style } : {}), { data: [].concat(model.assembleSelectionData([]), + // only assemble data in the root + assemble_1.assembleRootData(model.component.data)) }, model.assembleGroup(layoutSignals.concat(model.assembleSelectionTopLevelSignals([]))), (vgConfig ? { config: vgConfig } : {})); + return { + spec: output + // TODO: add warning / errors here + }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL2NvbXBpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLG9DQUFxRTtBQUNyRSx3Q0FBMEM7QUFDMUMsNEJBQThCO0FBQzlCLGdDQUE2RztBQUM3RyxrREFBa0g7QUFDbEgsZ0NBQXdDO0FBQ3hDLDJDQUF3QztBQUN4Qyw0Q0FBaUQ7QUFDakQsNENBQWlEO0FBVWpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBCRztBQUNILGlCQUF3QixTQUErQixFQUFFLEdBQXdCO0lBQXhCLG9CQUFBLEVBQUEsUUFBd0I7SUFDL0UsbUNBQW1DO0lBQ25DLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ2Ysa0RBQWtEO1FBQ2xELEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNuQiwwQ0FBMEM7UUFDMUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0gsOEdBQThHO1FBQzlHLElBQU0sTUFBTSxHQUFHLG1CQUFVLENBQUMsZ0JBQVMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUV2RSxzREFBc0Q7UUFFdEQsOE5BQThOO1FBQzlOLElBQU0sSUFBSSxHQUFHLGdCQUFTLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLDJEQUEyRDtRQUMzRCxJQUFNLFFBQVEsR0FBRyxpQ0FBaUIsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsa0JB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QyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDM0Qsa0JBQWtCLEVBQ2xCLENBQUMsS0FBSyxDQUFBLENBQUMsQ0FBQyxFQUFDLEtBQUssT0FBQSxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUNyQixDQUFDLEtBQUssQ0FBQSxDQUFDLENBQUMsRUFBQyxLQUFLLE9BQUEsRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFDeEIsSUFBSSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQ2IsS0FBSyxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQztRQUMvQixpQ0FBaUM7UUFDakMsMkJBQWdCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FDdkMsSUFDRSxLQUFLLENBQUMsYUFBYSxDQUNqQixhQUFhLFFBQ2IsS0FBSyxDQUFDLGdDQUFnQyxDQUFDLEVBQUUsQ0FBQyxFQUM3QyxFQUNDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQ3hDLENBQUM7SUFFRixNQUFNLENBQUM7UUFDTCxJQUFJLEVBQUUsTUFBTTtRQUNaLGtDQUFrQztLQUNuQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29uZmlnLCBpbml0Q29uZmlnLCBzdHJpcEFuZFJlZGlyZWN0Q29uZmlnfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0ICogYXMgdmxGaWVsZERlZiBmcm9tICcuLi9maWVsZGRlZic7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vbG9nJztcbmltcG9ydCB7aXNMYXllclNwZWMsIGlzVW5pdFNwZWMsIExheW91dFNpemVNaXhpbnMsIG5vcm1hbGl6ZSwgVG9wTGV2ZWwsIFRvcExldmVsRXh0ZW5kZWRTcGVjfSBmcm9tICcuLi9zcGVjJztcbmltcG9ydCB7QXV0b1NpemVQYXJhbXMsIGV4dHJhY3RUb3BMZXZlbFByb3BlcnRpZXMsIG5vcm1hbGl6ZUF1dG9TaXplLCBUb3BMZXZlbFByb3BlcnRpZXN9IGZyb20gJy4uL3RvcGxldmVscHJvcHMnO1xuaW1wb3J0IHtrZXlzLCBtZXJnZURlZXB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHtidWlsZE1vZGVsfSBmcm9tICcuL2J1aWxkbW9kZWwnO1xuaW1wb3J0IHthc3NlbWJsZVJvb3REYXRhfSBmcm9tICcuL2RhdGEvYXNzZW1ibGUnO1xuaW1wb3J0IHtvcHRpbWl6ZURhdGFmbG93fSBmcm9tICcuL2RhdGEvb3B0aW1pemUnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi9tb2RlbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGlsZU9wdGlvbnMge1xuICBjb25maWc/OiBDb25maWc7XG4gIGxvZ2dlcj86IGxvZy5Mb2dnZXJJbnRlcmZhY2U7XG5cbiAgZmllbGRUaXRsZT86IHZsRmllbGREZWYuRmllbGRUaXRsZUZvcm1hdHRlcjtcbn1cblxuLyoqXG4gKiBWZWdhLUxpdGUncyBtYWluIGZ1bmN0aW9uLCBmb3IgY29tcGlsaW5nIFZlZ2EtbGl0ZSBzcGVjIGludG8gVmVnYSBzcGVjLlxuICpcbiAqIEF0IGEgaGlnaC1sZXZlbCwgd2UgbWFrZSB0aGUgZm9sbG93aW5nIHRyYW5zZm9ybWF0aW9ucyBpbiBkaWZmZXJlbnQgcGhhc2VzOlxuICpcbiAqIElucHV0IHNwZWNcbiAqICAgICB8XG4gKiAgICAgfCAgKE5vcm1hbGl6YXRpb24pXG4gKiAgICAgdlxuICogTm9ybWFsaXplZCBTcGVjXG4gKiAgICAgfFxuICogICAgIHwgIChCdWlsZCBNb2RlbClcbiAqICAgICB2XG4gKiBBIG1vZGVsIHRyZWUgb2YgdGhlIHNwZWNcbiAqICAgICB8XG4gKiAgICAgfCAgKFBhcnNlKVxuICogICAgIHZcbiAqIEEgbW9kZWwgdHJlZSB3aXRoIHBhcnNlZCBjb21wb25lbnRzIChpbnRlcm1lZGlhdGUgc3RydWN0dXJlIG9mIHZpc3VhbGl6YXRpb24gcHJpbWl0aXZlcyBpbiBhIGZvcm1hdCB0aGF0IGNhbiBiZSBlYXNpbHkgbWVyZ2VkKVxuICogICAgIHxcbiAqICAgICB8IChPcHRpbWl6ZSlcbiAqICAgICB2XG4gKiBBIG1vZGVsIHRyZWUgd2l0aCBwYXJzZWQgY29tcG9uZW50cyB3aXRoIHRoZSBkYXRhIGNvbXBvbmVudCBvcHRpbWl6ZWRcbiAqICAgICB8XG4gKiAgICAgfCAoQXNzZW1ibGUpXG4gKiAgICAgdlxuICogVmVnYSBzcGVjXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlKGlucHV0U3BlYzogVG9wTGV2ZWxFeHRlbmRlZFNwZWMsIG9wdDogQ29tcGlsZU9wdGlvbnMgPSB7fSkge1xuICAvLyAwLiBBdWdtZW50IG9wdCB3aXRoIGRlZmF1bHQgb3B0c1xuICBpZiAob3B0LmxvZ2dlcikge1xuICAgIC8vIHNldCB0aGUgc2luZ2xldG9uIGxvZ2dlciB0byB0aGUgcHJvdmlkZWQgbG9nZ2VyXG4gICAgbG9nLnNldChvcHQubG9nZ2VyKTtcbiAgfVxuXG4gIGlmIChvcHQuZmllbGRUaXRsZSkge1xuICAgIC8vIHNldCB0aGUgc2luZ2xldG9uIGZpZWxkIHRpdGxlIGZvcm1hdHRlclxuICAgIHZsRmllbGREZWYuc2V0VGl0bGVGb3JtYXR0ZXIob3B0LmZpZWxkVGl0bGUpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyAxLiBJbml0aWFsaXplIGNvbmZpZyBieSBkZWVwIG1lcmdpbmcgZGVmYXVsdCBjb25maWcgd2l0aCB0aGUgY29uZmlnIHByb3ZpZGVkIHZpYSBvcHRpb24gYW5kIHRoZSBpbnB1dCBzcGVjLlxuICAgIGNvbnN0IGNvbmZpZyA9IGluaXRDb25maWcobWVyZ2VEZWVwKHt9LCBvcHQuY29uZmlnLCBpbnB1dFNwZWMuY29uZmlnKSk7XG5cbiAgICAvLyAyLiBOb3JtYWxpemU6IENvbnZlcnQgaW5wdXQgc3BlYyAtPiBub3JtYWxpemVkIHNwZWNcblxuICAgIC8vIC0gRGVjb21wb3NlIGFsbCBleHRlbmRlZCB1bml0IHNwZWNzIGludG8gY29tcG9zaXRpb24gb2YgdW5pdCBzcGVjLiAgRm9yIGV4YW1wbGUsIGEgYm94IHBsb3QgZ2V0IGV4cGFuZGVkIGludG8gbXVsdGlwbGUgbGF5ZXJzIG9mIGJhcnMsIHRpY2tzLCBhbmQgcnVsZXMuIFRoZSBzaG9ydGhhbmQgcm93L2NvbHVtbiBjaGFubmVsIGlzIGFsc28gZXhwYW5kZWQgdG8gYSBmYWNldCBzcGVjLlxuICAgIGNvbnN0IHNwZWMgPSBub3JtYWxpemUoaW5wdXRTcGVjLCBjb25maWcpO1xuICAgIC8vIC0gTm9ybWFsaXplIGF1dG9zaXplIHRvIGJlIGEgYXV0b3NpemUgcHJvcGVydGllcyBvYmplY3QuXG4gICAgY29uc3QgYXV0b3NpemUgPSBub3JtYWxpemVBdXRvU2l6ZShpbnB1dFNwZWMuYXV0b3NpemUsIGNvbmZpZy5hdXRvc2l6ZSwgaXNMYXllclNwZWMoc3BlYykgfHwgaXNVbml0U3BlYyhzcGVjKSk7XG5cbiAgICAvLyAzLiBCdWlsZCBNb2RlbDogbm9ybWFsaXplZCBzcGVjIC0+IE1vZGVsIChhIHRyZWUgc3RydWN0dXJlKVxuXG4gICAgLy8gVGhpcyBwaGFzZXMgaW5zdGFudGlhdGVzIHRoZSBtb2RlbHMgd2l0aCBkZWZhdWx0IGNvbmZpZyBieSBkb2luZyBhIHRvcC1kb3duIHRyYXZlcnNhbC4gVGhpcyBhbGxvd3MgdXMgdG8gcGFzcyBwcm9wZXJ0aWVzIHRoYXQgY2hpbGQgbW9kZWxzIGRlcml2ZSBmcm9tIHRoZWlyIHBhcmVudHMgdmlhIHRoZWlyIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgdGhlIGFic3RyYWN0IGBNb2RlbGAgY2xhc3MgYW5kIGl0cyBjaGlsZHJlbiAoVW5pdE1vZGVsLCBMYXllck1vZGVsLCBGYWNldE1vZGVsLCBSZXBlYXRNb2RlbCwgQ29uY2F0TW9kZWwpIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgbW9kZWxzLlxuICAgIGNvbnN0IG1vZGVsOiBNb2RlbCA9IGJ1aWxkTW9kZWwoc3BlYywgbnVsbCwgJycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBjb25maWcsIGF1dG9zaXplLnR5cGUgPT09ICdmaXQnKTtcblxuICAgIC8vIDQgUGFyc2U6IE1vZGVsIC0tPiBNb2RlbCB3aXRoIGNvbXBvbmVudHMgKGNvbXBvbmVudHMgPSBpbnRlcm1lZGlhdGUgdGhhdCBjYW4gYmUgbWVyZ2VkXG4gICAgLy8gYW5kIGFzc2VtYmxlZCBlYXNpbHkpXG5cbiAgICAvLyBJbiB0aGlzIHBoYXNlLCB3ZSBkbyBhIGJvdHRvbS11cCB0cmF2ZXJzYWwgb3ZlciB0aGUgd2hvbGUgdHJlZSB0b1xuICAgIC8vIHBhcnNlIGZvciBlYWNoIHR5cGUgb2YgY29tcG9uZW50cyBvbmNlIChlLmcuLCBkYXRhLCBsYXlvdXQsIG1hcmssIHNjYWxlKS5cbiAgICAvLyBCeSBkb2luZyBib3R0b20tdXAgdHJhdmVyc2FsLCB3ZSBzdGFydCBwYXJzaW5nIGNvbXBvbmVudHMgb2YgdW5pdCBzcGVjcyBhbmRcbiAgICAvLyB0aGVuIG1lcmdlIGNoaWxkIGNvbXBvbmVudHMgb2YgcGFyZW50IGNvbXBvc2l0ZSBzcGVjcy5cbiAgICAvL1xuICAgIC8vIFBsZWFzZSBzZWUgaW5zaWRlIG1vZGVsLnBhcnNlKCkgZm9yIG9yZGVyIG9mIGRpZmZlcmVudCBjb21wb25lbnRzIHBhcnNlZC5cbiAgICBtb2RlbC5wYXJzZSgpO1xuXG4gICAgLy8gNS4gT3B0aW1pemUgdGhlIGRhdGFmbG93LiAgVGhpcyB3aWxsIG1vZGlmeSB0aGUgZGF0YSBjb21wb25lbnQgb2YgdGhlIG1vZGVsLlxuICAgIG9wdGltaXplRGF0YWZsb3cobW9kZWwuY29tcG9uZW50LmRhdGEpO1xuXG4gICAgLy8gNi4gQXNzZW1ibGU6IGNvbnZlcnQgbW9kZWwgYW5kIGNvbXBvbmVudHMgLS0+IFZlZ2EgU3BlYy5cbiAgICByZXR1cm4gYXNzZW1ibGVUb3BMZXZlbE1vZGVsKG1vZGVsLCBnZXRUb3BMZXZlbFByb3BlcnRpZXMoaW5wdXRTcGVjLCBjb25maWcsIGF1dG9zaXplKSk7XG4gIH0gZmluYWxseSB7XG4gICAgLy8gUmVzZXQgdGhlIHNpbmdsZXRvbiBsb2dnZXIgaWYgYSBsb2dnZXIgaXMgcHJvdmlkZWRcbiAgICBpZiAob3B0LmxvZ2dlcikge1xuICAgICAgbG9nLnJlc2V0KCk7XG4gICAgfVxuICAgIC8vIFJlc2V0IHRoZSBzaW5nbGV0b24gZmllbGQgdGl0bGUgZm9ybWF0dGVyIGlmIHByb3ZpZGVkXG4gICAgaWYgKG9wdC5maWVsZFRpdGxlKSB7XG4gICAgICB2bEZpZWxkRGVmLnJlc2V0VGl0bGVGb3JtYXR0ZXIoKTtcbiAgICB9XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBnZXRUb3BMZXZlbFByb3BlcnRpZXModG9wTGV2ZWxTcGVjOiBUb3BMZXZlbDxhbnk+LCBjb25maWc6IENvbmZpZywgYXV0b3NpemU6IEF1dG9TaXplUGFyYW1zKSB7XG4gIHJldHVybiB7XG4gICAgYXV0b3NpemU6IGtleXMoYXV0b3NpemUpLmxlbmd0aCA9PT0gMSAmJiBhdXRvc2l6ZS50eXBlID8gYXV0b3NpemUudHlwZSA6IGF1dG9zaXplLFxuICAgIC4uLmV4dHJhY3RUb3BMZXZlbFByb3BlcnRpZXMoY29uZmlnKSxcbiAgICAuLi5leHRyYWN0VG9wTGV2ZWxQcm9wZXJ0aWVzKHRvcExldmVsU3BlYylcbiAgfTtcbn1cblxuLypcbiAqIEFzc2VtYmxlIHRoZSB0b3AtbGV2ZWwgbW9kZWwuXG4gKlxuICogTm90ZTogdGhpcyBjb3VsZG4ndCBiZSBgbW9kZWwuYXNzZW1ibGUoKWAgc2luY2UgdGhlIHRvcC1sZXZlbCBtb2RlbFxuICogbmVlZHMgc29tZSBzcGVjaWFsIHRyZWF0bWVudCB0byBnZW5lcmF0ZSB0b3AtbGV2ZWwgcHJvcGVydGllcy5cbiAqL1xuZnVuY3Rpb24gYXNzZW1ibGVUb3BMZXZlbE1vZGVsKG1vZGVsOiBNb2RlbCwgdG9wTGV2ZWxQcm9wZXJ0aWVzOiBUb3BMZXZlbFByb3BlcnRpZXMgJiBMYXlvdXRTaXplTWl4aW5zKSB7XG4gIC8vIFRPRE86IGNoYW5nZSB0eXBlIHRvIGJlY29tZSBWZ1NwZWNcblxuICAvLyBDb25maWcgd2l0aCBWZWdhLUxpdGUgb25seSBjb25maWcgcmVtb3ZlZC5cbiAgY29uc3QgdmdDb25maWcgPSBtb2RlbC5jb25maWcgPyBzdHJpcEFuZFJlZGlyZWN0Q29uZmlnKG1vZGVsLmNvbmZpZykgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHRpdGxlID0gbW9kZWwuYXNzZW1ibGVUaXRsZSgpO1xuICBjb25zdCBzdHlsZSA9IG1vZGVsLmFzc2VtYmxlR3JvdXBTdHlsZSgpO1xuXG4gIGxldCBsYXlvdXRTaWduYWxzID0gbW9kZWwuYXNzZW1ibGVMYXlvdXRTaWduYWxzKCk7XG5cbiAgLy8gbW92ZSB3aWR0aCBhbmQgaGVpZ2h0IHNpZ25hbHMgd2l0aCB2YWx1ZXMgdG8gdG9wIGxldmVsXG4gIGxheW91dFNpZ25hbHMgPSBsYXlvdXRTaWduYWxzLmZpbHRlcihzaWduYWwgPT4ge1xuICAgIGlmICgoc2lnbmFsLm5hbWUgPT09ICd3aWR0aCcgfHwgc2lnbmFsLm5hbWUgPT09ICdoZWlnaHQnKSAmJiBzaWduYWwudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdG9wTGV2ZWxQcm9wZXJ0aWVzW3NpZ25hbC5uYW1lXSA9ICtzaWduYWwudmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSB7XG4gICAgJHNjaGVtYTogJ2h0dHBzOi8vdmVnYS5naXRodWIuaW8vc2NoZW1hL3ZlZ2EvdjMuMC5qc29uJyxcbiAgICAuLi4obW9kZWwuZGVzY3JpcHRpb24gPyB7ZGVzY3JpcHRpb246IG1vZGVsLmRlc2NyaXB0aW9ufSA6IHt9KSxcbiAgICAuLi50b3BMZXZlbFByb3BlcnRpZXMsXG4gICAgLi4uKHRpdGxlPyB7dGl0bGV9IDoge30pLFxuICAgIC4uLihzdHlsZT8ge3N0eWxlfSA6IHt9KSxcbiAgICBkYXRhOiBbXS5jb25jYXQoXG4gICAgICBtb2RlbC5hc3NlbWJsZVNlbGVjdGlvbkRhdGEoW10pLFxuICAgICAgLy8gb25seSBhc3NlbWJsZSBkYXRhIGluIHRoZSByb290XG4gICAgICBhc3NlbWJsZVJvb3REYXRhKG1vZGVsLmNvbXBvbmVudC5kYXRhKVxuICAgICksXG4gICAgLi4ubW9kZWwuYXNzZW1ibGVHcm91cChbXG4gICAgICAuLi5sYXlvdXRTaWduYWxzLFxuICAgICAgLi4ubW9kZWwuYXNzZW1ibGVTZWxlY3Rpb25Ub3BMZXZlbFNpZ25hbHMoW10pXG4gICAgXSksXG4gICAgLi4uKHZnQ29uZmlnID8ge2NvbmZpZzogdmdDb25maWd9IDoge30pXG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBzcGVjOiBvdXRwdXRcbiAgICAvLyBUT0RPOiBhZGQgd2FybmluZyAvIGVycm9ycyBoZXJlXG4gIH07XG59XG4iXX0= \ 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..a516ba90b2 --- /dev/null +++ b/build/src/compile/concat.d.ts @@ -0,0 +1,15 @@ +import { Config } from '../config'; +import { ConcatSpec } 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: ConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config); + parseLayoutSize(): void; + parseAxisGroup(): void; + assembleLayout(): VgLayout; +} diff --git a/build/src/compile/concat.js b/build/src/compile/concat.js new file mode 100644 index 0000000000..f903883b73 --- /dev/null +++ b/build/src/compile/concat.js @@ -0,0 +1,55 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var spec_1 = require("../spec"); +var baseconcat_1 = require("./baseconcat"); +var buildmodel_1 = require("./buildmodel"); +var parse_1 = require("./layoutsize/parse"); +var ConcatModel = /** @class */ (function (_super) { + __extends(ConcatModel, _super); + function ConcatModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, 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 = spec_1.isVConcatSpec(spec); + _this.children = (spec_1.isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map(function (child, i) { + return buildmodel_1.buildModel(child, _this, _this.getName('concat_' + i), undefined, repeater, config, false); + }); + return _this; + } + ConcatModel.prototype.parseLayoutSize = function () { + parse_1.parseConcatLayoutSize(this); + }; + ConcatModel.prototype.parseAxisGroup = function () { + return null; + }; + ConcatModel.prototype.assembleLayout = function () { + // TODO: allow customization + return __assign({ padding: { row: 10, column: 10 }, offset: 10 }, (this.isVConcat ? { columns: 1 } : {}), { bounds: 'full', + // Use align each so it can work with multiple plots with different size + align: 'each' }); + }; + return ConcatModel; +}(baseconcat_1.BaseConcatModel)); +exports.ConcatModel = ConcatModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uY2F0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGUvY29uY2F0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsNEJBQThCO0FBQzlCLGdDQUFrRDtBQUVsRCwyQ0FBNkM7QUFDN0MsMkNBQXdDO0FBQ3hDLDRDQUF5RDtBQUl6RDtJQUFpQywrQkFBZTtJQU85QyxxQkFBWSxJQUFnQixFQUFFLE1BQWEsRUFBRSxlQUF1QixFQUFFLFFBQXVCLEVBQUUsTUFBYztRQUE3RyxZQUNFLGtCQUFNLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBVzNEO1FBbEJlLFVBQUksR0FBYSxRQUFRLENBQUM7UUFTeEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoSCxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsS0FBSSxDQUFDLFNBQVMsR0FBRyxvQkFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXJDLEtBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxvQkFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQUMsS0FBSyxFQUFFLENBQUM7WUFDL0UsTUFBTSxDQUFDLHVCQUFVLENBQUMsS0FBSyxFQUFFLEtBQUksRUFBRSxLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRyxDQUFDLENBQUMsQ0FBQzs7SUFDTCxDQUFDO0lBRU0scUNBQWUsR0FBdEI7UUFDRSw2QkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBR00sb0NBQWMsR0FBckI7UUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLG9DQUFjLEdBQXJCO1FBQ0UsNEJBQTRCO1FBQzVCLE1BQU0sWUFDSixPQUFPLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUMsRUFDOUIsTUFBTSxFQUFFLEVBQUUsSUFDUCxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUMsT0FBTyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFDdkMsTUFBTSxFQUFFLE1BQU07WUFDZCx3RUFBd0U7WUFDeEUsS0FBSyxFQUFFLE1BQU0sSUFDYjtJQUNKLENBQUM7SUFDSCxrQkFBQztBQUFELENBQUMsQUF6Q0QsQ0FBaUMsNEJBQWUsR0F5Qy9DO0FBekNZLGtDQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vbG9nJztcbmltcG9ydCB7Q29uY2F0U3BlYywgaXNWQ29uY2F0U3BlY30gZnJvbSAnLi4vc3BlYyc7XG5pbXBvcnQge1ZnTGF5b3V0fSBmcm9tICcuLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge0Jhc2VDb25jYXRNb2RlbH0gZnJvbSAnLi9iYXNlY29uY2F0JztcbmltcG9ydCB7YnVpbGRNb2RlbH0gZnJvbSAnLi9idWlsZG1vZGVsJztcbmltcG9ydCB7cGFyc2VDb25jYXRMYXlvdXRTaXplfSBmcm9tICcuL2xheW91dHNpemUvcGFyc2UnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQge1JlcGVhdGVyVmFsdWV9IGZyb20gJy4vcmVwZWF0ZXInO1xuXG5leHBvcnQgY2xhc3MgQ29uY2F0TW9kZWwgZXh0ZW5kcyBCYXNlQ29uY2F0TW9kZWwge1xuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogJ2NvbmNhdCcgPSAnY29uY2F0JztcblxuICBwdWJsaWMgcmVhZG9ubHkgY2hpbGRyZW46IE1vZGVsW107XG5cbiAgcHVibGljIHJlYWRvbmx5IGlzVkNvbmNhdDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihzcGVjOiBDb25jYXRTcGVjLCBwYXJlbnQ6IE1vZGVsLCBwYXJlbnRHaXZlbk5hbWU6IHN0cmluZywgcmVwZWF0ZXI6IFJlcGVhdGVyVmFsdWUsIGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoc3BlYywgcGFyZW50LCBwYXJlbnRHaXZlbk5hbWUsIGNvbmZpZywgc3BlYy5yZXNvbHZlKTtcblxuICAgIGlmIChzcGVjLnJlc29sdmUgJiYgc3BlYy5yZXNvbHZlLmF4aXMgJiYgKHNwZWMucmVzb2x2ZS5heGlzLnggPT09ICdzaGFyZWQnIHx8IHNwZWMucmVzb2x2ZS5heGlzLnkgPT09ICdzaGFyZWQnKSkge1xuICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuQ09OQ0FUX0NBTk5PVF9TSEFSRV9BWElTKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzVkNvbmNhdCA9IGlzVkNvbmNhdFNwZWMoc3BlYyk7XG5cbiAgICB0aGlzLmNoaWxkcmVuID0gKGlzVkNvbmNhdFNwZWMoc3BlYykgPyBzcGVjLnZjb25jYXQgOiBzcGVjLmhjb25jYXQpLm1hcCgoY2hpbGQsIGkpID0+IHtcbiAgICAgIHJldHVybiBidWlsZE1vZGVsKGNoaWxkLCB0aGlzLCB0aGlzLmdldE5hbWUoJ2NvbmNhdF8nICsgaSksIHVuZGVmaW5lZCwgcmVwZWF0ZXIsIGNvbmZpZywgZmFsc2UpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHBhcnNlTGF5b3V0U2l6ZSgpIHtcbiAgICBwYXJzZUNvbmNhdExheW91dFNpemUodGhpcyk7XG4gIH1cblxuXG4gIHB1YmxpYyBwYXJzZUF4aXNHcm91cCgpOiB2b2lkIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZUxheW91dCgpOiBWZ0xheW91dCB7XG4gICAgLy8gVE9ETzogYWxsb3cgY3VzdG9taXphdGlvblxuICAgIHJldHVybiB7XG4gICAgICBwYWRkaW5nOiB7cm93OiAxMCwgY29sdW1uOiAxMH0sXG4gICAgICBvZmZzZXQ6IDEwLFxuICAgICAgLi4uKHRoaXMuaXNWQ29uY2F0ID8ge2NvbHVtbnM6IDF9IDoge30pLFxuICAgICAgYm91bmRzOiAnZnVsbCcsXG4gICAgICAvLyBVc2UgYWxpZ24gZWFjaCBzbyBpdCBjYW4gd29yayB3aXRoIG11bHRpcGxlIHBsb3RzIHdpdGggZGlmZmVyZW50IHNpemVcbiAgICAgIGFsaWduOiAnZWFjaCdcbiAgICB9O1xuICB9XG59XG4iXX0= \ 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..7edb9f4584 --- /dev/null +++ b/build/src/compile/data/aggregate.d.ts @@ -0,0 +1,25 @@ +import { AggregateOp } from '../../aggregate'; +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(dimensions: StringSet, measures: Dict<{ + [key in AggregateOp]?: string; + }>); + static makeFromEncoding(model: UnitModel): AggregateNode; + static makeFromTransform(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..a70a95daf7 --- /dev/null +++ b/build/src/compile/data/aggregate.js @@ -0,0 +1,191 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var dataflow_1 = require("./dataflow"); +function addDimension(dims, channel, fieldDef) { + if (fieldDef.bin) { + dims[fielddef_1.field(fieldDef, {})] = true; + dims[fielddef_1.field(fieldDef, { binSuffix: 'end' })] = true; + if (common_1.binRequiresRange(fieldDef, channel)) { + dims[fielddef_1.field(fieldDef, { binSuffix: 'range' })] = true; + } + } + else { + dims[fielddef_1.field(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(dimensions, measures) { + var _this = _super.call(this) || this; + _this.dimensions = dimensions; + _this.measures = measures; + return _this; + } + AggregateNode.prototype.clone = function () { + return new AggregateNode(__assign({}, this.dimensions), util_1.duplicate(this.measures)); + }; + AggregateNode.makeFromEncoding = function (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) { + if (fieldDef.aggregate) { + if (fieldDef.aggregate === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = fielddef_1.field(fieldDef, { aggregate: 'count' }); + } + else { + meas[fieldDef.field] = meas[fieldDef.field] || {}; + meas[fieldDef.field][fieldDef.aggregate] = fielddef_1.field(fieldDef); + // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain + if (channel_1.isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') { + meas[fieldDef.field]['min'] = fielddef_1.field(fieldDef, { aggregate: 'min' }); + meas[fieldDef.field]['max'] = fielddef_1.field(fieldDef, { aggregate: 'max' }); + } + } + } + else { + addDimension(dims, channel, fieldDef); + } + }); + if ((util_1.keys(dims).length + util_1.keys(meas).length) === 0) { + return null; + } + return new AggregateNode(dims, meas); + }; + AggregateNode.makeFromTransform = function (t) { + var dims = {}; + var meas = {}; + for (var _i = 0, _a = t.aggregate; _i < _a.length; _i++) { + var s = _a[_i]; + if (s.op) { + if (s.op === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = s.as || fielddef_1.field(s); + } + else { + meas[s.field] = meas[s.field] || {}; + meas[s.field][s.op] = s.as || fielddef_1.field(s); + } + } + } + for (var _b = 0, _c = t.groupby; _b < _c.length; _b++) { + var s = _c[_b]; + dims[s] = true; + } + if ((util_1.keys(dims).length + util_1.keys(meas).length) === 0) { + return null; + } + return new AggregateNode(dims, meas); + }; + AggregateNode.prototype.merge = function (other) { + if (!util_1.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 = {}; + util_1.keys(this.dimensions).forEach(function (f) { return out[f] = true; }); + util_1.keys(this.measures).forEach(function (m) { return out[m] = true; }); + return out; + }; + AggregateNode.prototype.producedFields = function () { + var _this = this; + var out = {}; + util_1.keys(this.measures).forEach(function (field) { + util_1.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 = util_1.keys(this.measures); _i < _a.length; _i++) { + var field_1 = _a[_i]; + for (var _b = 0, _c = util_1.keys(this.measures[field_1]); _b < _c.length; _b++) { + var op = _c[_b]; + as.push(this.measures[field_1][op]); + ops.push(op); + fields.push(field_1); + } + } + var result = { + type: 'aggregate', + groupby: util_1.keys(this.dimensions), + ops: ops, + fields: fields, + as: as + }; + return result; + }; + return AggregateNode; +}(dataflow_1.DataFlowNode)); +exports.AggregateNode = AggregateNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9hZ2dyZWdhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSx5Q0FBc0Q7QUFDdEQsMkNBQStDO0FBQy9DLCtCQUFpQztBQUVqQyxtQ0FBb0U7QUFFcEUsb0NBQTJDO0FBRTNDLHVDQUF3QztBQUV4QyxzQkFBc0IsSUFBZ0MsRUFBRSxPQUFnQixFQUFFLFFBQTBCO0lBQ2xHLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxnQkFBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztRQUNqQyxJQUFJLENBQUMsZ0JBQUssQ0FBQyxRQUFRLEVBQUUsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztRQUVqRCxFQUFFLENBQUMsQ0FBQyx5QkFBZ0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxnQkFBSyxDQUFDLFFBQVEsRUFBRSxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3JELENBQUM7SUFDSCxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixJQUFJLENBQUMsZ0JBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztJQUMvQixDQUFDO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCx1QkFBdUIsY0FBa0MsRUFBRSxhQUFpQztJQUMxRixHQUFHLENBQUMsQ0FBQyxJQUFNLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBQzlCLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsQ0FB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QyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVNLGdDQUFRLEdBQWY7UUFDRSxJQUFNLEdBQUcsR0FBa0IsRUFBRSxDQUFDO1FBQzlCLElBQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixJQUFNLEVBQUUsR0FBYSxFQUFFLENBQUM7UUFFeEIsR0FBRyxDQUFDLENBQWdCLFVBQW1CLEVBQW5CLEtBQUEsV0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBbkIsY0FBbUIsRUFBbkIsSUFBbUI7WUFBbEMsSUFBTSxPQUFLLFNBQUE7WUFDZCxHQUFHLENBQUMsQ0FBYSxVQUEwQixFQUExQixLQUFBLFdBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQUssQ0FBQyxDQUFDLEVBQTFCLGNBQTBCLEVBQTFCLElBQTBCO2dCQUF0QyxJQUFNLEVBQUUsU0FBQTtnQkFDWCxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbEMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDYixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQUssQ0FBQyxDQUFDO2FBQ3BCO1NBQ0Y7UUFFRCxJQUFNLE1BQU0sR0FBeUI7WUFDbkMsSUFBSSxFQUFFLFdBQVc7WUFDakIsT0FBTyxFQUFFLFdBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLEdBQUcsS0FBQTtZQUNILE1BQU0sUUFBQTtZQUNOLEVBQUUsSUFBQTtTQUNILENBQUM7UUFFRixNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFDSCxvQkFBQztBQUFELENBQUMsQUEzSUQsQ0FBbUMsdUJBQVksR0EySTlDO0FBM0lZLHNDQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBZ2dyZWdhdGVPcH0gZnJvbSAnLi4vLi4vYWdncmVnYXRlJztcbmltcG9ydCB7Q2hhbm5lbCwgaXNTY2FsZUNoYW5uZWx9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtmaWVsZCwgRmllbGREZWZ9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi9sb2cnO1xuaW1wb3J0IHtBZ2dyZWdhdGVUcmFuc2Zvcm19IGZyb20gJy4uLy4uL3RyYW5zZm9ybSc7XG5pbXBvcnQge0RpY3QsIGRpZmZlciwgZHVwbGljYXRlLCBrZXlzLCBTdHJpbmdTZXR9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtiaW5SZXF1aXJlc1JhbmdlfSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4vLi4vdW5pdCc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZX0gZnJvbSAnLi9kYXRhZmxvdyc7XG5cbmZ1bmN0aW9uIGFkZERpbWVuc2lvbihkaW1zOiB7W2ZpZWxkOiBzdHJpbmddOiBib29sZWFufSwgY2hhbm5lbDogQ2hhbm5lbCwgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4pIHtcbiAgaWYgKGZpZWxkRGVmLmJpbikge1xuICAgIGRpbXNbZmllbGQoZmllbGREZWYsIHt9KV0gPSB0cnVlO1xuICAgIGRpbXNbZmllbGQoZmllbGREZWYsIHtiaW5TdWZmaXg6ICdlbmQnfSldID0gdHJ1ZTtcblxuICAgIGlmIChiaW5SZXF1aXJlc1JhbmdlKGZpZWxkRGVmLCBjaGFubmVsKSkge1xuICAgICAgZGltc1tmaWVsZChmaWVsZERlZiwge2JpblN1ZmZpeDogJ3JhbmdlJ30pXSA9IHRydWU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRpbXNbZmllbGQoZmllbGREZWYpXSA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIGRpbXM7XG59XG5cbmZ1bmN0aW9uIG1lcmdlTWVhc3VyZXMocGFyZW50TWVhc3VyZXM6IERpY3Q8RGljdDxzdHJpbmc+PiwgY2hpbGRNZWFzdXJlczogRGljdDxEaWN0PHN0cmluZz4+KSB7XG4gIGZvciAoY29uc3QgZiBpbiBjaGlsZE1lYXN1cmVzKSB7XG4gICAgaWYgKGNoaWxkTWVhc3VyZXMuaGFzT3duUHJvcGVydHkoZikpIHtcbiAgICAgIC8vIHdoZW4gd2UgbWVyZ2UgYSBtZWFzdXJlLCB3ZSBlaXRoZXIgaGF2ZSB0byBhZGQgYW4gYWdncmVnYXRpb24gb3BlcmF0b3Igb3IgZXZlbiBhIG5ldyBmaWVsZFxuICAgICAgY29uc3Qgb3BzID0gY2hpbGRNZWFzdXJlc1tmXTtcbiAgICAgIGZvciAoY29uc3Qgb3AgaW4gb3BzKSB7XG4gICAgICAgIGlmIChvcHMuaGFzT3duUHJvcGVydHkob3ApKSB7XG4gICAgICAgICAgaWYgKGYgaW4gcGFyZW50TWVhc3VyZXMpIHtcbiAgICAgICAgICAgIC8vIGFkZCBvcGVyYXRvciB0byBleGlzdGluZyBtZWFzdXJlIGZpZWxkXG4gICAgICAgICAgICBwYXJlbnRNZWFzdXJlc1tmXVtvcF0gPSBvcHNbb3BdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJlbnRNZWFzdXJlc1tmXSA9IHtvcDogb3BzW29wXX07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBZ2dyZWdhdGVOb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHVibGljIGNsb25lKCkge1xuICAgIHJldHVybiBuZXcgQWdncmVnYXRlTm9kZSh7Li4udGhpcy5kaW1lbnNpb25zfSwgZHVwbGljYXRlKHRoaXMubWVhc3VyZXMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gZGltZW5zaW9ucyBzdHJpbmcgc2V0IGZvciBkaW1lbnNpb25zXG4gICAqIEBwYXJhbSBtZWFzdXJlcyBkaWN0aW9uYXJ5IG1hcHBpbmcgZmllbGQgbmFtZSA9PiBkaWN0IG9mIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9ucyBhbmQgbmFtZXMgdG8gdXNlXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRpbWVuc2lvbnM6IFN0cmluZ1NldCwgcHJpdmF0ZSBtZWFzdXJlczogRGljdDx7W2tleSBpbiBBZ2dyZWdhdGVPcF0/OiBzdHJpbmd9Pikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIG1ha2VGcm9tRW5jb2RpbmcobW9kZWw6IFVuaXRNb2RlbCk6IEFnZ3JlZ2F0ZU5vZGUge1xuICAgIGxldCBpc0FnZ3JlZ2F0ZSA9IGZhbHNlO1xuICAgIG1vZGVsLmZvckVhY2hGaWVsZERlZihmZCA9PiB7XG4gICAgICBpZiAoZmQuYWdncmVnYXRlKSB7XG4gICAgICAgIGlzQWdncmVnYXRlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IG1lYXMgPSB7fTtcbiAgICBjb25zdCBkaW1zID0ge307XG5cbiAgICBpZiAoIWlzQWdncmVnYXRlKSB7XG4gICAgICAvLyBubyBuZWVkIHRvIGNyZWF0ZSB0aGlzIG5vZGUgaWYgdGhlIG1vZGVsIGhhcyBubyBhZ2dyZWdhdGlvblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbW9kZWwuZm9yRWFjaEZpZWxkRGVmKChmaWVsZERlZiwgY2hhbm5lbCkgPT4ge1xuICAgICAgaWYgKGZpZWxkRGVmLmFnZ3JlZ2F0ZSkge1xuICAgICAgICBpZiAoZmllbGREZWYuYWdncmVnYXRlID09PSAnY291bnQnKSB7XG4gICAgICAgICAgbWVhc1snKiddID0gbWVhc1snKiddIHx8IHt9O1xuICAgICAgICAgIG1lYXNbJyonXVsnY291bnQnXSA9IGZpZWxkKGZpZWxkRGVmLCB7YWdncmVnYXRlOiAnY291bnQnfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWVhc1tmaWVsZERlZi5maWVsZF0gPSBtZWFzW2ZpZWxkRGVmLmZpZWxkXSB8fCB7fTtcbiAgICAgICAgICBtZWFzW2ZpZWxkRGVmLmZpZWxkXVtmaWVsZERlZi5hZ2dyZWdhdGVdID0gZmllbGQoZmllbGREZWYpO1xuXG4gICAgICAgICAgLy8gRm9yIHNjYWxlIGNoYW5uZWwgd2l0aCBkb21haW4gPT09ICd1bmFnZ3JlZ2F0ZWQnLCBhZGQgbWluL21heCBzbyB3ZSBjYW4gdXNlIHRoZWlyIHVuaW9uIGFzIHVuYWdncmVnYXRlZCBkb21haW5cbiAgICAgICAgICBpZiAoaXNTY2FsZUNoYW5uZWwoY2hhbm5lbCkgJiYgbW9kZWwuc2NhbGVEb21haW4oY2hhbm5lbCkgPT09ICd1bmFnZ3JlZ2F0ZWQnKSB7XG4gICAgICAgICAgICBtZWFzW2ZpZWxkRGVmLmZpZWxkXVsnbWluJ10gPSBmaWVsZChmaWVsZERlZiwge2FnZ3JlZ2F0ZTogJ21pbid9KTtcbiAgICAgICAgICAgIG1lYXNbZmllbGREZWYuZmllbGRdWydtYXgnXSA9IGZpZWxkKGZpZWxkRGVmLCB7YWdncmVnYXRlOiAnbWF4J30pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWRkRGltZW5zaW9uKGRpbXMsIGNoYW5uZWwsIGZpZWxkRGVmKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICgoa2V5cyhkaW1zKS5sZW5ndGggKyBrZXlzKG1lYXMpLmxlbmd0aCkgPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQWdncmVnYXRlTm9kZShkaW1zLCBtZWFzKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgbWFrZUZyb21UcmFuc2Zvcm0odDogQWdncmVnYXRlVHJhbnNmb3JtKTogQWdncmVnYXRlTm9kZSB7XG4gICAgY29uc3QgZGltcyA9IHt9O1xuICAgIGNvbnN0IG1lYXMgPSB7fTtcbiAgICBmb3IoY29uc3QgcyBvZiB0LmFnZ3JlZ2F0ZSkge1xuICAgICAgaWYgKHMub3ApIHtcbiAgICAgICAgaWYgKHMub3AgPT09ICdjb3VudCcpIHtcbiAgICAgICAgICBtZWFzWycqJ10gPSBtZWFzWycqJ10gfHwge307XG4gICAgICAgICAgbWVhc1snKiddWydjb3VudCddID0gcy5hcyB8fCBmaWVsZChzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtZWFzW3MuZmllbGRdID0gbWVhc1tzLmZpZWxkXSB8fCB7fTtcbiAgICAgICAgICBtZWFzW3MuZmllbGRdW3Mub3BdID0gcy5hcyB8fCBmaWVsZChzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvcihjb25zdCBzIG9mIHQuZ3JvdXBieSkge1xuICAgICAgZGltc1tzXSA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKChrZXlzKGRpbXMpLmxlbmd0aCArIGtleXMobWVhcykubGVuZ3RoKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBZ2dyZWdhdGVOb2RlKGRpbXMsIG1lYXMpO1xuICB9XG5cbiAgcHVibGljIG1lcmdlKG90aGVyOiBBZ2dyZWdhdGVOb2RlKSB7XG4gICAgaWYgKCFkaWZmZXIodGhpcy5kaW1lbnNpb25zLCBvdGhlci5kaW1lbnNpb25zKSkge1xuICAgICAgbWVyZ2VNZWFzdXJlcyh0aGlzLm1lYXN1cmVzLCBvdGhlci5tZWFzdXJlcyk7XG4gICAgICBvdGhlci5yZW1vdmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nLmRlYnVnKCdkaWZmZXJlbnQgZGltZW5zaW9ucywgY2Fubm90IG1lcmdlJyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZERpbWVuc2lvbnMoZmllbGRzOiBzdHJpbmdbXSkge1xuICAgIGZpZWxkcy5mb3JFYWNoKGYgPT4gdGhpcy5kaW1lbnNpb25zW2ZdID0gdHJ1ZSk7XG4gIH1cblxuICBwdWJsaWMgZGVwZW5kZW50RmllbGRzKCkge1xuICAgIGNvbnN0IG91dCA9IHt9O1xuXG4gICAga2V5cyh0aGlzLmRpbWVuc2lvbnMpLmZvckVhY2goZiA9PiBvdXRbZl0gPSB0cnVlKTtcbiAgICBrZXlzKHRoaXMubWVhc3VyZXMpLmZvckVhY2gobSA9PiBvdXRbbV0gPSB0cnVlKTtcblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBwdWJsaWMgcHJvZHVjZWRGaWVsZHMoKSB7XG4gICAgY29uc3Qgb3V0ID0ge307XG5cbiAgICBrZXlzKHRoaXMubWVhc3VyZXMpLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAga2V5cyh0aGlzLm1lYXN1cmVzW2ZpZWxkXSkuZm9yRWFjaChvcCA9PiB7XG4gICAgICAgIG91dFtgJHtvcH1fJHtmaWVsZH1gXSA9IHRydWU7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGUoKTogVmdBZ2dyZWdhdGVUcmFuc2Zvcm0ge1xuICAgIGNvbnN0IG9wczogQWdncmVnYXRlT3BbXSA9IFtdO1xuICAgIGNvbnN0IGZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBhczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZmllbGQgb2Yga2V5cyh0aGlzLm1lYXN1cmVzKSkge1xuICAgICAgZm9yIChjb25zdCBvcCBvZiBrZXlzKHRoaXMubWVhc3VyZXNbZmllbGRdKSkge1xuICAgICAgICBhcy5wdXNoKHRoaXMubWVhc3VyZXNbZmllbGRdW29wXSk7XG4gICAgICAgIG9wcy5wdXNoKG9wKTtcbiAgICAgICAgZmllbGRzLnB1c2goZmllbGQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdDogVmdBZ2dyZWdhdGVUcmFuc2Zvcm0gPSB7XG4gICAgICB0eXBlOiAnYWdncmVnYXRlJyxcbiAgICAgIGdyb3VwYnk6IGtleXModGhpcy5kaW1lbnNpb25zKSxcbiAgICAgIG9wcyxcbiAgICAgIGZpZWxkcyxcbiAgICAgIGFzXG4gICAgfTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiJdfQ== \ 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..e7734a1b6a --- /dev/null +++ b/build/src/compile/data/assemble.d.ts @@ -0,0 +1,15 @@ +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): VgData[]; diff --git a/build/src/compile/data/assemble.js b/build/src/compile/data/assemble.js new file mode 100644 index 0000000000..bbc558c735 --- /dev/null +++ b/build/src/compile/data/assemble.js @@ -0,0 +1,219 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var aggregate_1 = require("./aggregate"); +var bin_1 = require("./bin"); +var calculate_1 = require("./calculate"); +var dataflow_1 = require("./dataflow"); +var facet_1 = require("./facet"); +var filter_1 = require("./filter"); +var filterinvalid_1 = require("./filterinvalid"); +var formatparse_1 = require("./formatparse"); +var indentifier_1 = require("./indentifier"); +var lookup_1 = require("./lookup"); +var source_1 = require("./source"); +var stack_1 = require("./stack"); +var timeunit_1 = require("./timeunit"); +/** + * 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 source_1.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 (!data_1.isUrlData(node.data)) { + data.push(dataSource); + var newData = { + name: null, + source: dataSource.name, + transform: [] + }; + dataSource = newData; + } + } + if (node instanceof formatparse_1.ParseNode) { + if (node.parent instanceof source_1.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() }); + } + else { + // Otherwise use Vega expression to parse + dataSource.transform = dataSource.transform.concat(node.assembleTransforms()); + } + } + if (node instanceof facet_1.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 filter_1.FilterNode || + node instanceof calculate_1.CalculateNode || + node instanceof aggregate_1.AggregateNode || + node instanceof lookup_1.LookupNode || + node instanceof indentifier_1.IdentifierNode) { + dataSource.transform.push(node.assemble()); + } + if (node instanceof filterinvalid_1.FilterInvalidNode || + node instanceof bin_1.BinNode || + node instanceof timeunit_1.TimeUnitNode || + node instanceof stack_1.StackNode) { + dataSource.transform = dataSource.transform.concat(node.assemble()); + } + if (node instanceof aggregate_1.AggregateNode) { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + } + if (node instanceof dataflow_1.OutputNode) { + if (dataSource.source && dataSource.transform.length === 0) { + node.setSource(dataSource.source); + } + else if (node.parent instanceof dataflow_1.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 dataflow_1.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_2 = dataSource.name; + if (!dataSource.source || dataSource.transform.length > 0) { + data.push(dataSource); + } + else { + source_2 = dataSource.source; + } + node.children.forEach(function (child) { + var newData = { + name: null, + source: source_2, + 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; +} +exports.assembleFacetData = assembleFacetData; +/** + * 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) { + var roots = util_1.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 + data.sort(function (a, b) { return (a.transform || []).length === 0 ? -1 : ((b.transform || []).length === 0 ? 1 : 0); }); + // now fix the from references in lookup transforms + for (var _i = 0, data_2 = data; _i < data_2.length; _i++) { + var d = data_2[_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(); + } + } + } + return data; +} +exports.assembleRootData = assembleRootData; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2Fzc2VtYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSxtQ0FBcUM7QUFDckMsbUNBQWdDO0FBR2hDLHlDQUEwQztBQUMxQyw2QkFBOEI7QUFDOUIseUNBQTBDO0FBQzFDLHVDQUFvRDtBQUNwRCxpQ0FBa0M7QUFDbEMsbUNBQW9DO0FBQ3BDLGlEQUFrRDtBQUNsRCw2Q0FBd0M7QUFDeEMsNkNBQTZDO0FBQzdDLG1DQUFvQztBQUNwQyxtQ0FBb0M7QUFDcEMsaUNBQWtDO0FBQ2xDLHVDQUF3QztBQUV4Qzs7R0FFRztBQUNILDJCQUEyQjtBQUMzQixlQUFlLElBQWtCO0lBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSSxJQUFJLENBQUMsV0FBbUIsQ0FBQyxJQUFJLElBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBSyxJQUFJLENBQUMsU0FBUyxNQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFDMUYsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUM7UUFDbEIsTUFBTSxDQUFDLEtBQUksQ0FBQyxDQUFDLFdBQW1CLENBQUMsSUFBSSxJQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE9BQUssQ0FBQyxDQUFDLFNBQVMsTUFBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUUsQ0FBQztJQUNuRixDQUFDLENBQUMsQ0FDRixDQUFDLENBQUM7SUFDSixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xCLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFFRCxzQkFBc0IsSUFBYztJQUNsQyxzQkFBc0I7SUFDdEIsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0lBRXJCOztP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LENBQUMsQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDeEIsQ0FBQyxDQUFDLElBQUksR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN6RCxDQUFDO1NBQ0Y7S0FDRjtJQUVELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBekNELDRDQXlDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aXNVcmxEYXRhfSBmcm9tICcuLi8uLi9kYXRhJztcbmltcG9ydCB7dmFsc30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnRGF0YX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtEYXRhQ29tcG9uZW50fSBmcm9tICcuLyc7XG5pbXBvcnQge0FnZ3JlZ2F0ZU5vZGV9IGZyb20gJy4vYWdncmVnYXRlJztcbmltcG9ydCB7QmluTm9kZX0gZnJvbSAnLi9iaW4nO1xuaW1wb3J0IHtDYWxjdWxhdGVOb2RlfSBmcm9tICcuL2NhbGN1bGF0ZSc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZSwgT3V0cHV0Tm9kZX0gZnJvbSAnLi9kYXRhZmxvdyc7XG5pbXBvcnQge0ZhY2V0Tm9kZX0gZnJvbSAnLi9mYWNldCc7XG5pbXBvcnQge0ZpbHRlck5vZGV9IGZyb20gJy4vZmlsdGVyJztcbmltcG9ydCB7RmlsdGVySW52YWxpZE5vZGV9IGZyb20gJy4vZmlsdGVyaW52YWxpZCc7XG5pbXBvcnQge1BhcnNlTm9kZX0gZnJvbSAnLi9mb3JtYXRwYXJzZSc7XG5pbXBvcnQge0lkZW50aWZpZXJOb2RlfSBmcm9tICcuL2luZGVudGlmaWVyJztcbmltcG9ydCB7TG9va3VwTm9kZX0gZnJvbSAnLi9sb29rdXAnO1xuaW1wb3J0IHtTb3VyY2VOb2RlfSBmcm9tICcuL3NvdXJjZSc7XG5pbXBvcnQge1N0YWNrTm9kZX0gZnJvbSAnLi9zdGFjayc7XG5pbXBvcnQge1RpbWVVbml0Tm9kZX0gZnJvbSAnLi90aW1ldW5pdCc7XG5cbi8qKlxuICogUHJpbnQgZGVidWcgaW5mb3JtYXRpb24gZm9yIGRhdGFmbG93IHRyZWUuXG4gKi9cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxuZnVuY3Rpb24gZGVidWcobm9kZTogRGF0YUZsb3dOb2RlKSB7XG4gIGNvbnNvbGUubG9nKGAkeyhub2RlLmNvbnN0cnVjdG9yIGFzIGFueSkubmFtZX0ke25vZGUuZGVidWdOYW1lID8gYCAoJHtub2RlLmRlYnVnTmFtZX0pYCA6ICcnfSAtPiAke1xuICAgIChub2RlLmNoaWxkcmVuLm1hcChjID0+IHtcbiAgICAgIHJldHVybiBgJHsoYy5jb25zdHJ1Y3RvciBhcyBhbnkpLm5hbWV9JHtjLmRlYnVnTmFtZSA/IGAgKCR7Yy5kZWJ1Z05hbWV9KWAgOiAnJ31gO1xuICAgIH0pKVxuICB9YCk7XG4gIGNvbnNvbGUubG9nKG5vZGUpO1xuICBub2RlLmNoaWxkcmVuLmZvckVhY2goZGVidWcpO1xufVxuXG5mdW5jdGlvbiBtYWtlV2Fsa1RyZWUoZGF0YTogVmdEYXRhW10pIHtcbiAgLy8gdG8gbmFtZSBkYXRhc291cmNlc1xuICBsZXQgZGF0YXNldEluZGV4ID0gMDtcblxuICAvKipcbiAgICogUmVjdXJzaXZlbHkgd2FsayBkb3duIHRoZSB0cmVlLlxuICAgKi9cbiAgZnVuY3Rpb24gd2Fsa1RyZWUobm9kZTogRGF0YUZsb3dOb2RlLCBkYXRhU291cmNlOiBWZ0RhdGEpIHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFNvdXJjZU5vZGUpIHtcbiAgICAgIC8vIElmIHRoZSBzb3VyY2UgaXMgYSBuYW1lZCBkYXRhIHNvdXJjZSBvciBhIGRhdGEgc291cmNlIHdpdGggdmFsdWVzLCB3ZSBuZWVkXG4gICAgICAvLyB0byBwdXQgaXQgaW4gYSBkaWZmZXJlbnQgZGF0YSBzb3VyY2UuIE90aGVyd2lzZSwgVmVnYSBtYXkgb3ZlcnJpZGUgdGhlIGRhdGEuXG4gICAgICBpZiAoIWlzVXJsRGF0YShub2RlLmRhdGEpKSB7XG4gICAgICAgIGRhdGEucHVzaChkYXRhU291cmNlKTtcbiAgICAgICAgY29uc3QgbmV3RGF0YTogVmdEYXRhID0ge1xuICAgICAgICAgIG5hbWU6IG51bGwsXG4gICAgICAgICAgc291cmNlOiBkYXRhU291cmNlLm5hbWUsXG4gICAgICAgICAgdHJhbnNmb3JtOiBbXVxuICAgICAgICB9O1xuICAgICAgICBkYXRhU291cmNlID0gbmV3RGF0YTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFBhcnNlTm9kZSkge1xuICAgICAgaWYgKG5vZGUucGFyZW50IGluc3RhbmNlb2YgU291cmNlTm9kZSAmJiAhZGF0YVNvdXJjZS5zb3VyY2UpIHtcbiAgICAgICAgLy8gSWYgbm9kZSdzIHBhcmVudCBpcyBhIHJvb3Qgc291cmNlIGFuZCB0aGUgZGF0YSBzb3VyY2UgZG9lcyBub3QgcmVmZXIgdG8gYW5vdGhlciBkYXRhIHNvdXJjZSwgdXNlIG5vcm1hbCBmb3JtYXQgcGFyc2VcbiAgICAgICAgZGF0YVNvdXJjZS5mb3JtYXQgPSB7XG4gICAgICAgICAgLi4uZGF0YVNvdXJjZS5mb3JtYXQgfHwge30sXG4gICAgICAgICAgcGFyc2U6IG5vZGUuYXNzZW1ibGVGb3JtYXRQYXJzZSgpXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBPdGhlcndpc2UgdXNlIFZlZ2EgZXhwcmVzc2lvbiB0byBwYXJzZVxuICAgICAgICBkYXRhU291cmNlLnRyYW5zZm9ybSA9IGRhdGFTb3VyY2UudHJhbnNmb3JtLmNvbmNhdChub2RlLmFzc2VtYmxlVHJhbnNmb3JtcygpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEZhY2V0Tm9kZSkge1xuICAgICAgaWYgKCFkYXRhU291cmNlLm5hbWUpIHtcbiAgICAgICAgZGF0YVNvdXJjZS5uYW1lID0gYGRhdGFfJHtkYXRhc2V0SW5kZXgrK31gO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWRhdGFTb3VyY2Uuc291cmNlIHx8IGRhdGFTb3VyY2UudHJhbnNmb3JtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZGF0YS5wdXNoKGRhdGFTb3VyY2UpO1xuICAgICAgICBub2RlLmRhdGEgPSBkYXRhU291cmNlLm5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLmRhdGEgPSBkYXRhU291cmNlLnNvdXJjZTtcbiAgICAgIH1cblxuICAgICAgbm9kZS5hc3NlbWJsZSgpLmZvckVhY2goZCA9PiBkYXRhLnB1c2goZCkpO1xuXG4gICAgICAvLyBicmVhayBoZXJlIGJlY2F1c2UgdGhlIHJlc3Qgb2YgdGhlIHRyZWUgaGFzIHRvIGJlIHRha2VuIGNhcmUgb2YgYnkgdGhlIGZhY2V0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgRmlsdGVyTm9kZSB8fFxuICAgICAgbm9kZSBpbnN0YW5jZW9mIENhbGN1bGF0ZU5vZGUgfHxcbiAgICAgIG5vZGUgaW5zdGFuY2VvZiBBZ2dyZWdhdGVOb2RlIHx8XG4gICAgICBub2RlIGluc3RhbmNlb2YgTG9va3VwTm9kZSB8fFxuICAgICAgbm9kZSBpbnN0YW5jZW9mIElkZW50aWZpZXJOb2RlKSB7XG4gICAgICBkYXRhU291cmNlLnRyYW5zZm9ybS5wdXNoKG5vZGUuYXNzZW1ibGUoKSk7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBGaWx0ZXJJbnZhbGlkTm9kZSB8fFxuICAgICAgbm9kZSBpbnN0YW5jZW9mIEJpbk5vZGUgfHxcbiAgICAgIG5vZGUgaW5zdGFuY2VvZiBUaW1lVW5pdE5vZGUgfHxcbiAgICAgIG5vZGUgaW5zdGFuY2VvZiBTdGFja05vZGUpIHtcbiAgICAgIGRhdGFTb3VyY2UudHJhbnNmb3JtID0gZGF0YVNvdXJjZS50cmFuc2Zvcm0uY29uY2F0KG5vZGUuYXNzZW1ibGUoKSk7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBBZ2dyZWdhdGVOb2RlKSB7XG4gICAgICBpZiAoIWRhdGFTb3VyY2UubmFtZSkge1xuICAgICAgICBkYXRhU291cmNlLm5hbWUgPSBgZGF0YV8ke2RhdGFzZXRJbmRleCsrfWA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBPdXRwdXROb2RlKSB7XG4gICAgICBpZiAoZGF0YVNvdXJjZS5zb3VyY2UgJiYgZGF0YVNvdXJjZS50cmFuc2Zvcm0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIG5vZGUuc2V0U291cmNlKGRhdGFTb3VyY2Uuc291cmNlKTtcbiAgICAgIH0gZWxzZSBpZiAobm9kZS5wYXJlbnQgaW5zdGFuY2VvZiBPdXRwdXROb2RlKSB7XG4gICAgICAgIC8vIE5vdGUgdGhhdCBhbiBvdXRwdXQgbm9kZSBtYXkgYmUgcmVxdWlyZWQgYnV0IHdlIHN0aWxsIGRvIG5vdCBhc3NlbWJsZSBhXG4gICAgICAgIC8vIHNlcGFyYXRlIGRhdGEgc291cmNlIGZvciBpdC5cbiAgICAgICAgbm9kZS5zZXRTb3VyY2UoZGF0YVNvdXJjZS5uYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghZGF0YVNvdXJjZS5uYW1lKSB7XG4gICAgICAgICAgZGF0YVNvdXJjZS5uYW1lID0gYGRhdGFfJHtkYXRhc2V0SW5kZXgrK31gO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGVyZSB3ZSBzZXQgdGhlIG5hbWUgb2YgdGhlIGRhdGFzb3VyY2Ugd2UgZ2VuZXJhdGVkLiBGcm9tIG5vdyBvblxuICAgICAgICAvLyBvdGhlciBhc3NlbWJsZXJzIGNhbiB1c2UgaXQuXG4gICAgICAgIG5vZGUuc2V0U291cmNlKGRhdGFTb3VyY2UubmFtZSk7XG5cbiAgICAgICAgLy8gaWYgdGhpcyBub2RlIGhhcyBtb3JlIHRoYW4gb25lIGNoaWxkLCB3ZSB3aWxsIGFkZCBhIGRhdGFzb3VyY2UgYXV0b21hdGljYWxseVxuICAgICAgICBpZiAobm9kZS5udW1DaGlsZHJlbigpID09PSAxKSB7XG4gICAgICAgICAgZGF0YS5wdXNoKGRhdGFTb3VyY2UpO1xuICAgICAgICAgIGNvbnN0IG5ld0RhdGE6IFZnRGF0YSA9IHtcbiAgICAgICAgICAgIG5hbWU6IG51bGwsXG4gICAgICAgICAgICBzb3VyY2U6IGRhdGFTb3VyY2UubmFtZSxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogW11cbiAgICAgICAgICB9O1xuICAgICAgICAgIGRhdGFTb3VyY2UgPSBuZXdEYXRhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3dpdGNoIChub2RlLm51bUNoaWxkcmVuKCkpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgLy8gZG9uZVxuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIE91dHB1dE5vZGUgJiYgKCFkYXRhU291cmNlLnNvdXJjZSB8fCBkYXRhU291cmNlLnRyYW5zZm9ybS5sZW5ndGggPiAwKSkge1xuICAgICAgICAgIC8vIGRvIG5vdCBwdXNoIGVtcHR5IGRhdGFzb3VyY2VzIHRoYXQgYXJlIHNpbXBseSByZWZlcmVuY2VzXG4gICAgICAgICAgZGF0YS5wdXNoKGRhdGFTb3VyY2UpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICB3YWxrVHJlZShub2RlLmNoaWxkcmVuWzBdLCBkYXRhU291cmNlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAoIWRhdGFTb3VyY2UubmFtZSkge1xuICAgICAgICAgIGRhdGFTb3VyY2UubmFtZSA9IGBkYXRhXyR7ZGF0YXNldEluZGV4Kyt9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzb3VyY2UgPSBkYXRhU291cmNlLm5hbWU7XG4gICAgICAgIGlmICghZGF0YVNvdXJjZS5zb3VyY2UgfHwgZGF0YVNvdXJjZS50cmFuc2Zvcm0ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGRhdGEucHVzaChkYXRhU291cmNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzb3VyY2UgPSBkYXRhU291cmNlLnNvdXJjZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUuY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgICAgY29uc3QgbmV3RGF0YTogVmdEYXRhID0ge1xuICAgICAgICAgICAgbmFtZTogbnVsbCxcbiAgICAgICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICAgICAgdHJhbnNmb3JtOiBbXVxuICAgICAgICAgIH07XG4gICAgICAgICAgd2Fsa1RyZWUoY2hpbGQsIG5ld0RhdGEpO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdhbGtUcmVlO1xufVxuXG4vKipcbiAqIEFzc2VtYmxlIGRhdGEgc291cmNlcyB0aGF0IGFyZSBkZXJpdmVkIGZyb20gZmFjZXRlZCBkYXRhLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZW1ibGVGYWNldERhdGEocm9vdDogRmFjZXROb2RlKTogVmdEYXRhW10ge1xuICBjb25zdCBkYXRhOiBWZ0RhdGFbXSA9IFtdO1xuICBjb25zdCB3YWxrVHJlZSA9IG1ha2VXYWxrVHJlZShkYXRhKTtcblxuICByb290LmNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4gd2Fsa1RyZWUoY2hpbGQsIHtcbiAgICBzb3VyY2U6IHJvb3QubmFtZSxcbiAgICBuYW1lOiBudWxsLFxuICAgIHRyYW5zZm9ybTogW11cbiAgfSkpO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG4vKipcbiAqIENyZWF0ZSBWZWdhIERhdGEgYXJyYXkgZnJvbSBhIGdpdmVuIGNvbXBpbGVkIG1vZGVsIGFuZCBhcHBlbmQgYWxsIG9mIHRoZW0gdG8gdGhlIGdpdmVuIGFycmF5XG4gKlxuICogQHBhcmFtICBtb2RlbFxuICogQHBhcmFtICBkYXRhIGFycmF5XG4gKiBAcmV0dXJuIG1vZGlmaWVkIGRhdGEgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlUm9vdERhdGEoZGF0YUNvbXBvbmVudDogRGF0YUNvbXBvbmVudCk6IFZnRGF0YVtdIHtcbiAgY29uc3Qgcm9vdHM6IFNvdXJjZU5vZGVbXSA9IHZhbHMoZGF0YUNvbXBvbmVudC5zb3VyY2VzKTtcbiAgY29uc3QgZGF0YTogVmdEYXRhW10gPSBbXTtcblxuICAvLyByb290cy5mb3JFYWNoKGRlYnVnKTtcblxuICBjb25zdCB3YWxrVHJlZSA9IG1ha2VXYWxrVHJlZShkYXRhKTtcblxuICBsZXQgc291cmNlSW5kZXggPSAwO1xuXG4gIHJvb3RzLmZvckVhY2gocm9vdCA9PiB7XG4gICAgLy8gYXNzaWduIGEgbmFtZSBpZiB0aGUgc291cmNlIGRvZXMgbm90IGhhdmUgYSBuYW1lIHlldFxuICAgIGlmICghcm9vdC5oYXNOYW1lKCkpIHtcbiAgICAgIHJvb3QuZGF0YU5hbWUgPSBgc291cmNlXyR7c291cmNlSW5kZXgrK31gO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld0RhdGE6IFZnRGF0YSA9IHJvb3QuYXNzZW1ibGUoKTtcblxuICAgIHdhbGtUcmVlKHJvb3QsIG5ld0RhdGEpO1xuICB9KTtcblxuICAvLyByZW1vdmUgZW1wdHkgdHJhbnNmb3JtIGFycmF5cyBmb3IgY2xlYW5lciBvdXRwdXRcbiAgZGF0YS5mb3JFYWNoKGQgPT4ge1xuICAgIGlmIChkLnRyYW5zZm9ybS5sZW5ndGggPT09IDApIHtcbiAgICAgIGRlbGV0ZSBkLnRyYW5zZm9ybTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIG1vdmUgc291cmNlcyB3aXRob3V0IHRyYW5zZm9ybXMgKHRoZSBvbmVzIHRoYXQgYXJlIHBvdGVudGlhbGx5IHVzZWQgaW4gbG9va3VwcykgdG8gdGhlIGJlZ2lubmluZ1xuICBkYXRhLnNvcnQoKGEsIGIpID0+IChhLnRyYW5zZm9ybSB8fCBbXSkubGVuZ3RoID09PSAwID8gLTEgOiAoKGIudHJhbnNmb3JtIHx8IFtdKS5sZW5ndGggPT09IDAgPyAxIDogMCkpO1xuXG4gIC8vIG5vdyBmaXggdGhlIGZyb20gcmVmZXJlbmNlcyBpbiBsb29rdXAgdHJhbnNmb3Jtc1xuICBmb3IgKGNvbnN0IGQgb2YgZGF0YSkge1xuICAgIGZvciAoY29uc3QgdCBvZiBkLnRyYW5zZm9ybSB8fCBbXSkge1xuICAgICAgaWYgKHQudHlwZSA9PT0gJ2xvb2t1cCcpIHtcbiAgICAgICAgdC5mcm9tID0gZGF0YUNvbXBvbmVudC5vdXRwdXROb2Rlc1t0LmZyb21dLmdldFNvdXJjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkYXRhO1xufVxuIl19 \ 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..8ed03a264b --- /dev/null +++ b/build/src/compile/data/bin.d.ts @@ -0,0 +1,35 @@ +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(bins: Dict); + static makeBinFromEncoding(model: ModelWithField): BinNode; + /** + * Creates a bin node from BinTransform. + * The optional parameter should provide + */ + static makeFromTransform(t: BinTransform, params: { + model: Model; + } | { + signal?: string; + extentSignal?: string; + }): 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..2c55e6eae8 --- /dev/null +++ b/build/src/compile/data/bin.js @@ -0,0 +1,151 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var bin_1 = require("../../bin"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var model_1 = require("../model"); +var dataflow_1 = require("./dataflow"); +function rangeFormula(model, fieldDef, channel, config) { + if (common_1.binRequiresRange(fieldDef, channel)) { + // read format from axis or legend, if there is no format then use config.numberFormat + var guide = model_1.isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {}; + var startField = fielddef_1.field(fieldDef, { expr: 'datum', }); + var endField = fielddef_1.field(fieldDef, { expr: 'datum', binSuffix: 'end' }); + return { + formulaAs: fielddef_1.field(fieldDef, { binSuffix: 'range' }), + formula: common_1.binFormatExpression(startField, endField, guide.format, config) + }; + } + return {}; +} +function binKey(bin, field) { + return bin_1.binToString(bin) + "_" + field; +} +function isModelParams(p) { + return !!p['model']; +} +function getSignalsFromParams(params, key) { + if (isModelParams(params)) { + var model = params.model; + return { + signal: model.getName(key + "_bins"), + extentSignal: model.getName(key + "_extent") + }; + } + return params; +} +function isBinTransform(t) { + return 'as' in t; +} +function createBinComponent(t, params) { + var as; + if (isBinTransform(t)) { + as = [t.as, t.as + "_end"]; + } + else { + as = [fielddef_1.field(t, {}), fielddef_1.field(t, { binSuffix: 'end' })]; + } + var bin = fielddef_1.normalizeBin(t.bin, undefined) || {}; + var key = binKey(bin, t.field); + var _a = getSignalsFromParams(params, key), 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, binComponent: binComponent }; +} +var BinNode = /** @class */ (function (_super) { + __extends(BinNode, _super); + function BinNode(bins) { + var _this = _super.call(this) || this; + _this.bins = bins; + return _this; + } + BinNode.prototype.clone = function () { + return new BinNode(util_1.duplicate(this.bins)); + }; + BinNode.makeBinFromEncoding = function (model) { + var bins = model.reduceFieldDef(function (binComponentIndex, fieldDef, channel) { + if (fieldDef.bin) { + var _a = createBinComponent(fieldDef, { model: model }), key = _a.key, binComponent = _a.binComponent; + binComponentIndex[key] = __assign({}, binComponent, binComponentIndex[key], rangeFormula(model, fieldDef, channel, model.config)); + } + return binComponentIndex; + }, {}); + if (util_1.keys(bins).length === 0) { + return null; + } + return new BinNode(bins); + }; + /** + * Creates a bin node from BinTransform. + * The optional parameter should provide + */ + BinNode.makeFromTransform = function (t, params) { + var _a = createBinComponent(t, params), key = _a.key, binComponent = _a.binComponent; + return new BinNode((_b = {}, + _b[key] = binComponent, + _b)); + var _b; + }; + BinNode.prototype.merge = function (other) { + this.bins = __assign({}, this.bins, other.bins); + other.remove(); + }; + BinNode.prototype.producedFields = function () { + var out = {}; + util_1.vals(this.bins).forEach(function (c) { + c.as.forEach(function (f) { return out[f] = true; }); + }); + return out; + }; + BinNode.prototype.dependentFields = function () { + var out = {}; + util_1.vals(this.bins).forEach(function (c) { + out[c.field] = true; + }); + return out; + }; + BinNode.prototype.assemble = function () { + return util_1.flatten(util_1.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; +}(dataflow_1.DataFlowNode)); +exports.BinNode = BinNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9iaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxpQ0FBaUQ7QUFHakQsMkNBQTZEO0FBRTdELG1DQUFnRTtBQUVoRSxvQ0FBZ0U7QUFDaEUsa0NBQTREO0FBQzVELHVDQUF3QztBQUd4QyxzQkFBc0IsS0FBcUIsRUFBRSxRQUEwQixFQUFFLE9BQWdCLEVBQUUsTUFBYztJQUNyRyxFQUFFLENBQUMsQ0FBQyx5QkFBZ0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLHNGQUFzRjtRQUV0RixJQUFNLEtBQUssR0FBRyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRTdGLElBQU0sVUFBVSxHQUFHLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsSUFBSSxFQUFFLE9BQU8sR0FBRSxDQUFDLENBQUM7UUFDckQsSUFBTSxRQUFRLEdBQUcsZ0JBQUssQ0FBQyxRQUFRLEVBQUUsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO1FBRXBFLE1BQU0sQ0FBQztZQUNMLFNBQVMsRUFBRSxnQkFBSyxDQUFDLFFBQVEsRUFBRSxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQztZQUNoRCxPQUFPLEVBQUUsNEJBQW1CLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQztTQUN6RSxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sQ0FBQyxFQUFFLENBQUM7QUFDZCxD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QixTQUFTLENBQUMsSUFBSSxDQUFDO29CQUNiLElBQUksRUFBRSxTQUFTO29CQUNmLElBQUksRUFBRSxHQUFHLENBQUMsT0FBTztvQkFDakIsRUFBRSxFQUFFLEdBQUcsQ0FBQyxTQUFTO2lCQUNsQixDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUNILGNBQUM7QUFBRCxDQUFDLEFBbkdELENBQTZCLHVCQUFZLEdBbUd4QztBQW5HWSwwQkFBTyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QmluUGFyYW1zLCBiaW5Ub1N0cmluZ30gZnJvbSAnLi4vLi4vYmluJztcbmltcG9ydCB7Q2hhbm5lbH0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vLi4vY29uZmlnJztcbmltcG9ydCB7ZmllbGQsIEZpZWxkRGVmLCBub3JtYWxpemVCaW59IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCB7QmluVHJhbnNmb3JtfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0nO1xuaW1wb3J0IHtEaWN0LCBkdXBsaWNhdGUsIGZsYXR0ZW4sIGtleXMsIHZhbHN9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0JpblRyYW5zZm9ybSwgVmdUcmFuc2Zvcm19IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7YmluRm9ybWF0RXhwcmVzc2lvbiwgYmluUmVxdWlyZXNSYW5nZX0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7aXNVbml0TW9kZWwsIE1vZGVsLCBNb2RlbFdpdGhGaWVsZH0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtEYXRhRmxvd05vZGV9IGZyb20gJy4vZGF0YWZsb3cnO1xuXG5cbmZ1bmN0aW9uIHJhbmdlRm9ybXVsYShtb2RlbDogTW9kZWxXaXRoRmllbGQsIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBjaGFubmVsOiBDaGFubmVsLCBjb25maWc6IENvbmZpZykge1xuICAgIGlmIChiaW5SZXF1aXJlc1JhbmdlKGZpZWxkRGVmLCBjaGFubmVsKSkge1xuICAgICAgLy8gcmVhZCBmb3JtYXQgZnJvbSBheGlzIG9yIGxlZ2VuZCwgaWYgdGhlcmUgaXMgbm8gZm9ybWF0IHRoZW4gdXNlIGNvbmZpZy5udW1iZXJGb3JtYXRcblxuICAgICAgY29uc3QgZ3VpZGUgPSBpc1VuaXRNb2RlbChtb2RlbCkgPyAobW9kZWwuYXhpcyhjaGFubmVsKSB8fCBtb2RlbC5sZWdlbmQoY2hhbm5lbCkgfHwge30pIDoge307XG5cbiAgICAgIGNvbnN0IHN0YXJ0RmllbGQgPSBmaWVsZChmaWVsZERlZiwge2V4cHI6ICdkYXR1bScsfSk7XG4gICAgICBjb25zdCBlbmRGaWVsZCA9IGZpZWxkKGZpZWxkRGVmLCB7ZXhwcjogJ2RhdHVtJywgYmluU3VmZml4OiAnZW5kJ30pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBmb3JtdWxhQXM6IGZpZWxkKGZpZWxkRGVmLCB7YmluU3VmZml4OiAncmFuZ2UnfSksXG4gICAgICAgIGZvcm11bGE6IGJpbkZvcm1hdEV4cHJlc3Npb24oc3RhcnRGaWVsZCwgZW5kRmllbGQsIGd1aWRlLmZvcm1hdCwgY29uZmlnKVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHt9O1xufVxuXG5mdW5jdGlvbiBiaW5LZXkoYmluOiBCaW5QYXJhbXMsIGZpZWxkOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGAke2JpblRvU3RyaW5nKGJpbil9XyR7ZmllbGR9YDtcbn1cblxuZnVuY3Rpb24gaXNNb2RlbFBhcmFtcyhwOiB7bW9kZWw6IE1vZGVsfSB8IHtzaWduYWw/OiBzdHJpbmcsIGV4dGVudFNpZ25hbD86IHN0cmluZ30pOiBwIGlzIHttb2RlbDogTW9kZWx9IHtcbiAgcmV0dXJuICEhcFsnbW9kZWwnXTtcbn1cblxuZnVuY3Rpb24gZ2V0U2lnbmFsc0Zyb21QYXJhbXMoXG4gIHBhcmFtczoge21vZGVsOiBNb2RlbH0gfCB7c2lnbmFsPzogc3RyaW5nLCBleHRlbnRTaWduYWw/OiBzdHJpbmd9LFxuICBrZXk6IHN0cmluZ1xuKSB7XG4gIGlmIChpc01vZGVsUGFyYW1zKHBhcmFtcykpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcmFtcy5tb2RlbDtcbiAgICByZXR1cm4ge1xuICAgICAgc2lnbmFsOiBtb2RlbC5nZXROYW1lKGAke2tleX1fYmluc2ApLFxuICAgICAgZXh0ZW50U2lnbmFsOiBtb2RlbC5nZXROYW1lKGAke2tleX1fZXh0ZW50YClcbiAgICB9O1xuICB9XG4gIHJldHVybiBwYXJhbXM7XG59XG5cbmZ1bmN0aW9uIGlzQmluVHJhbnNmb3JtKHQ6IEZpZWxkRGVmPHN0cmluZz4gfCBCaW5UcmFuc2Zvcm0pOiB0IGlzIEJpblRyYW5zZm9ybSB7XG4gIHJldHVybiAnYXMnIGluIHQ7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJpbkNvbXBvbmVudChcbiAgdDogRmllbGREZWY8c3RyaW5nPiB8IEJpblRyYW5zZm9ybSxcbiAgcGFyYW1zOiB7bW9kZWw6IE1vZGVsfSB8IHtzaWduYWw/OiBzdHJpbmcsIGV4dGVudFNpZ25hbD86IHN0cmluZ31cbikge1xuICBsZXQgYXM6IFtzdHJpbmcsIHN0cmluZ107XG5cbiAgaWYgKGlzQmluVHJhbnNmb3JtKHQpKSB7XG4gICAgYXMgPSBbdC5hcywgYCR7dC5hc31fZW5kYF07XG4gIH0gZWxzZSB7XG4gICAgYXMgPSBbZmllbGQodCwge30pLCBmaWVsZCh0LCB7YmluU3VmZml4OiAnZW5kJ30pXTtcbiAgfVxuXG4gIGNvbnN0IGJpbiA9IG5vcm1hbGl6ZUJpbih0LmJpbiwgdW5kZWZpbmVkKSB8fCB7fTtcbiAgY29uc3Qga2V5ID0gYmluS2V5KGJpbiwgdC5maWVsZCk7XG4gIGNvbnN0IHtzaWduYWwsIGV4dGVudFNpZ25hbH0gPSBnZXRTaWduYWxzRnJvbVBhcmFtcyhwYXJhbXMsIGtleSk7XG5cbiAgY29uc3QgYmluQ29tcG9uZW50OiBCaW5Db21wb25lbnQgPSB7XG4gICAgYmluOiBiaW4sXG4gICAgZmllbGQ6IHQuZmllbGQsXG4gICAgYXM6IGFzLFxuICAgIC4uLnNpZ25hbCA/IHtzaWduYWx9IDoge30sXG4gICAgLi4uZXh0ZW50U2lnbmFsID8ge2V4dGVudFNpZ25hbH0gOiB7fVxuICB9O1xuXG4gIHJldHVybiB7a2V5LCBiaW5Db21wb25lbnR9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJpbkNvbXBvbmVudCB7XG4gIGJpbjogQmluUGFyYW1zO1xuICBmaWVsZDogc3RyaW5nO1xuICBleHRlbnRTaWduYWw/OiBzdHJpbmc7XG4gIHNpZ25hbD86IHN0cmluZztcbiAgYXM6IHN0cmluZ1tdO1xuXG4gIC8vIFJhbmdlIEZvcm11bGFcblxuICBmb3JtdWxhPzogc3RyaW5nO1xuICBmb3JtdWxhQXM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBCaW5Ob2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHVibGljIGNsb25lKCkge1xuICAgIHJldHVybiBuZXcgQmluTm9kZShkdXBsaWNhdGUodGhpcy5iaW5zKSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJpbnM6IERpY3Q8QmluQ29tcG9uZW50Pikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIG1ha2VCaW5Gcm9tRW5jb2RpbmcobW9kZWw6IE1vZGVsV2l0aEZpZWxkKSB7XG4gICAgY29uc3QgYmlucyA9IG1vZGVsLnJlZHVjZUZpZWxkRGVmKChiaW5Db21wb25lbnRJbmRleDogRGljdDxCaW5Db21wb25lbnQ+LCBmaWVsZERlZiwgY2hhbm5lbCkgPT4ge1xuICAgICAgaWYgKGZpZWxkRGVmLmJpbikge1xuICAgICAgICBjb25zdCB7a2V5LCBiaW5Db21wb25lbnR9ID0gY3JlYXRlQmluQ29tcG9uZW50KGZpZWxkRGVmLCB7bW9kZWx9KTtcbiAgICAgICAgYmluQ29tcG9uZW50SW5kZXhba2V5XSA9IHtcbiAgICAgICAgICAuLi5iaW5Db21wb25lbnQsXG4gICAgICAgICAgLi4uYmluQ29tcG9uZW50SW5kZXhba2V5XSxcbiAgICAgICAgICAuLi5yYW5nZUZvcm11bGEobW9kZWwsIGZpZWxkRGVmLCBjaGFubmVsLCBtb2RlbC5jb25maWcpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gYmluQ29tcG9uZW50SW5kZXg7XG4gICAgfSwge30pO1xuXG4gICAgaWYgKGtleXMoYmlucykubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEJpbk5vZGUoYmlucyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGJpbiBub2RlIGZyb20gQmluVHJhbnNmb3JtLlxuICAgKiBUaGUgb3B0aW9uYWwgcGFyYW1ldGVyIHNob3VsZCBwcm92aWRlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG1ha2VGcm9tVHJhbnNmb3JtKHQ6IEJpblRyYW5zZm9ybSwgcGFyYW1zOiB7bW9kZWw6IE1vZGVsfSB8IHtzaWduYWw/OiBzdHJpbmcsIGV4dGVudFNpZ25hbD86IHN0cmluZ30pIHtcbiAgICBjb25zdCB7a2V5LCBiaW5Db21wb25lbnR9ID0gY3JlYXRlQmluQ29tcG9uZW50KHQsIHBhcmFtcyk7XG4gICAgcmV0dXJuIG5ldyBCaW5Ob2RlKHtcbiAgICAgIFtrZXldOiBiaW5Db21wb25lbnRcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXJnZShvdGhlcjogQmluTm9kZSkge1xuICAgIHRoaXMuYmlucyA9IHsuLi50aGlzLmJpbnMsIC4uLm90aGVyLmJpbnN9O1xuICAgIG90aGVyLnJlbW92ZSgpO1xuICB9XG5cbiAgcHVibGljIHByb2R1Y2VkRmllbGRzKCkge1xuICAgIGNvbnN0IG91dCA9IHt9O1xuXG4gICAgdmFscyh0aGlzLmJpbnMpLmZvckVhY2goYyA9PiB7XG4gICAgICBjLmFzLmZvckVhY2goZiA9PiBvdXRbZl0gPSB0cnVlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBwdWJsaWMgZGVwZW5kZW50RmllbGRzKCkge1xuICAgIGNvbnN0IG91dCA9IHt9O1xuXG4gICAgdmFscyh0aGlzLmJpbnMpLmZvckVhY2goYyA9PiB7XG4gICAgICBvdXRbYy5maWVsZF0gPSB0cnVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZSgpOiBWZ1RyYW5zZm9ybVtdIHtcbiAgICByZXR1cm4gZmxhdHRlbih2YWxzKHRoaXMuYmlucykubWFwKGJpbiA9PiB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm06IFZnVHJhbnNmb3JtW10gPSBbXTtcblxuICAgICAgY29uc3QgYmluVHJhbnM6IFZnQmluVHJhbnNmb3JtID0ge1xuICAgICAgICAgIHR5cGU6ICdiaW4nLFxuICAgICAgICAgIGZpZWxkOiBiaW4uZmllbGQsXG4gICAgICAgICAgYXM6IGJpbi5hcyxcbiAgICAgICAgICBzaWduYWw6IGJpbi5zaWduYWwsXG4gICAgICAgICAgLi4uYmluLmJpblxuICAgICAgfTtcblxuICAgICAgaWYgKCFiaW4uYmluLmV4dGVudCAmJiBiaW4uZXh0ZW50U2lnbmFsKSB7XG4gICAgICAgIHRyYW5zZm9ybS5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnZXh0ZW50JyxcbiAgICAgICAgICBmaWVsZDogYmluLmZpZWxkLFxuICAgICAgICAgIHNpZ25hbDogYmluLmV4dGVudFNpZ25hbFxuICAgICAgICB9KTtcbiAgICAgICAgYmluVHJhbnMuZXh0ZW50ID0ge3NpZ25hbDogYmluLmV4dGVudFNpZ25hbH07XG4gICAgICB9XG5cbiAgICAgIHRyYW5zZm9ybS5wdXNoKGJpblRyYW5zKTtcblxuICAgICAgaWYgKGJpbi5mb3JtdWxhKSB7XG4gICAgICAgIHRyYW5zZm9ybS5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnZm9ybXVsYScsXG4gICAgICAgICAgZXhwcjogYmluLmZvcm11bGEsXG4gICAgICAgICAgYXM6IGJpbi5mb3JtdWxhQXNcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cmFuc2Zvcm07XG4gICAgfSkpO1xuICB9XG59XG4iXX0= \ 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..b3e82f6573 --- /dev/null +++ b/build/src/compile/data/calculate.d.ts @@ -0,0 +1,13 @@ +import { CalculateTransform } from '../../transform'; +import { VgFormulaTransform } from '../../vega.schema'; +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(transform: CalculateTransform); + producedFields(): {}; + assemble(): VgFormulaTransform; +} diff --git a/build/src/compile/data/calculate.js b/build/src/compile/data/calculate.js new file mode 100644 index 0000000000..a2297c8513 --- /dev/null +++ b/build/src/compile/data/calculate.js @@ -0,0 +1,43 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var dataflow_1 = require("./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) { + __extends(CalculateNode, _super); + function CalculateNode(transform) { + var _this = _super.call(this) || this; + _this.transform = transform; + return _this; + } + CalculateNode.prototype.clone = function () { + return new CalculateNode(util_1.duplicate(this.transform)); + }; + 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; +}(dataflow_1.DataFlowNode)); +exports.CalculateNode = CalculateNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9jYWxjdWxhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQ0EsbUNBQXFDO0FBRXJDLHVDQUF3QztBQUV4Qzs7R0FFRztBQUNIO0lBQW1DLGlDQUFZO0lBSzdDLHVCQUFvQixTQUE2QjtRQUFqRCxZQUNFLGlCQUFPLFNBQ1I7UUFGbUIsZUFBUyxHQUFULFNBQVMsQ0FBb0I7O0lBRWpELENBQUM7SUFOTSw2QkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksYUFBYSxDQUFDLGdCQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQU1NLHNDQUFjLEdBQXJCO1FBQ0UsSUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ2YsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRU0sZ0NBQVEsR0FBZjtRQUNFLE1BQU0sQ0FBQztZQUNMLElBQUksRUFBRSxTQUFTO1lBQ2YsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUztZQUM5QixFQUFFLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1NBQ3RCLENBQUM7SUFDSixDQUFDO0lBQ0gsb0JBQUM7QUFBRCxDQUFDLEFBdEJELENBQW1DLHVCQUFZLEdBc0I5QztBQXRCWSxzQ0FBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2FsY3VsYXRlVHJhbnNmb3JtfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0nO1xuaW1wb3J0IHtkdXBsaWNhdGV9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0Zvcm11bGFUcmFuc2Zvcm19IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7RGF0YUZsb3dOb2RlfSBmcm9tICcuL2RhdGFmbG93JztcblxuLyoqXG4gKiBXZSBkb24ndCBrbm93IHdoYXQgYSBjYWxjdWxhdGUgbm9kZSBkZXBlbmRzIG9uIHNvIHdlIHNob3VsZCBuZXZlciBtb3ZlIGl0IGJleW9uZCBhbnl0aGluZyB0aGF0IHByb2R1Y2VzIGZpZWxkcy5cbiAqL1xuZXhwb3J0IGNsYXNzIENhbGN1bGF0ZU5vZGUgZXh0ZW5kcyBEYXRhRmxvd05vZGUge1xuICBwdWJsaWMgY2xvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBDYWxjdWxhdGVOb2RlKGR1cGxpY2F0ZSh0aGlzLnRyYW5zZm9ybSkpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0cmFuc2Zvcm06IENhbGN1bGF0ZVRyYW5zZm9ybSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgcHJvZHVjZWRGaWVsZHMoKSB7XG4gICAgY29uc3Qgb3V0ID0ge307XG4gICAgb3V0W3RoaXMudHJhbnNmb3JtLmFzXSA9IHRydWU7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZSgpOiBWZ0Zvcm11bGFUcmFuc2Zvcm0ge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnZm9ybXVsYScsXG4gICAgICBleHByOiB0aGlzLnRyYW5zZm9ybS5jYWxjdWxhdGUsXG4gICAgICBhczogdGhpcy50cmFuc2Zvcm0uYXNcbiAgICB9O1xuICB9XG59XG4iXX0= \ 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..5084868bd6 --- /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(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(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..4d688eba12 --- /dev/null +++ b/build/src/compile/data/dataflow.js @@ -0,0 +1,154 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * A node in the dataflow tree. + */ +var DataFlowNode = /** @class */ (function () { + function DataFlowNode(debugName) { + this.debugName = debugName; + this._children = []; + this._parent = null; + } + /** + * 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; +}()); +exports.DataFlowNode = 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(source, type, refCounts) { + var _this = _super.call(this, 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)); +exports.OutputNode = OutputNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWZsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2RhdGFmbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUtBOztHQUVHO0FBQ0g7SUFLRSxzQkFBNEIsU0FBa0I7UUFBbEIsY0FBUyxHQUFULFNBQVMsQ0FBUztRQUp0QyxjQUFTLEdBQW1CLEVBQUUsQ0FBQztRQUUvQixZQUFPLEdBQWlCLElBQUksQ0FBQztJQUVhLENBQUM7SUFFbkQ7O09BRUc7SUFDSSw0QkFBSyxHQUFaO1FBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7T0FFRztJQUNJLHFDQUFjLEdBQXJCO1FBQ0UsTUFBTSxDQUFDLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxzQ0FBZSxHQUF0QjtRQUNFLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsc0JBQUksZ0NBQU07YUFBVjtZQUNFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQ3RCLENBQUM7UUFFRDs7V0FFRzthQUNILFVBQVcsTUFBb0I7WUFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7WUFDdEIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QixDQUFDOzs7T0FSQTtJQVVELHNCQUFJLGtDQUFRO2FBQVo7WUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUN4QixDQUFDOzs7T0FBQTtJQUVNLGtDQUFXLEdBQWxCO1FBQ0UsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQy9CLENBQUM7SUFFTSwrQkFBUSxHQUFmLFVBQWdCLEtBQW1CO1FBQ2pDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFTSxrQ0FBVyxH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Q0FBQyxTQUFTLENBQUM7UUFDcEMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQWlCRDs7Ozs7Ozs7T0FRRztJQUNJLDhCQUFTLEdBQWhCO1FBQ0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM3QixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRU0sK0JBQVUsR0FBakI7UUFDRSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTSw4QkFBUyxHQUFoQixVQUFpQixNQUFjO1FBQzdCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0lBQ3hCLENBQUM7SUFDSCxpQkFBQztBQUFELENBQUMsQUFwREQsQ0FBZ0MsWUFBWSxHQW9EM0M7QUFwRFksZ0NBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7RGF0YVNvdXJjZVR5cGV9IGZyb20gJy4uLy4uL2RhdGEnO1xuaW1wb3J0IHtEaWN0LCBTdHJpbmdTZXR9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5cbi8qKlxuICogQSBub2RlIGluIHRoZSBkYXRhZmxvdyB0cmVlLlxuICovXG5leHBvcnQgY2xhc3MgRGF0YUZsb3dOb2RlIHtcbiAgcHJpdmF0ZSBfY2hpbGRyZW46IERhdGFGbG93Tm9kZVtdID0gW107XG5cbiAgcHJpdmF0ZSBfcGFyZW50OiBEYXRhRmxvd05vZGUgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBkZWJ1Z05hbWU/OiBzdHJpbmcpIHsgfVxuXG4gIC8qKlxuICAgKiBDbG9uZSB0aGlzIG5vZGUgd2l0aCBhIGRlZXAgY29weSBidXQgZG9uJ3QgY2xvbmUgbGlua3MgdG8gY2hpbGRyZW4gb3IgcGFyZW50cy5cbiAgICovXG4gIHB1YmxpYyBjbG9uZSgpOiBEYXRhRmxvd05vZGUge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNsb25lIG5vZGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgb2YgZmllbGRzIHRoYXQgYXJlIGJlaW5nIGNyZWF0ZWQgYnkgdGhpcyBub2RlLlxuICAgKi9cbiAgcHVibGljIHByb2R1Y2VkRmllbGRzKCk6IFN0cmluZ1NldCB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgcHVibGljIGRlcGVuZGVudEZpZWxkcygpOiBTdHJpbmdTZXQge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGdldCBwYXJlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhcmVudCBvZiB0aGUgbm9kZSBhbmQgYWxzbyBhZGQgdGhpcyBub3QgdG8gdGhlIHBhcmVudCdzIGNoaWxkcmVuLlxuICAgKi9cbiAgc2V0IHBhcmVudChwYXJlbnQ6IERhdGFGbG93Tm9kZSkge1xuICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcbiAgICBwYXJlbnQuYWRkQ2hpbGQodGhpcyk7XG4gIH1cblxuICBnZXQgY2hpbGRyZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoaWxkcmVuO1xuICB9XG5cbiAgcHVibGljIG51bUNoaWxkcmVuKCkge1xuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbi5sZW5ndGg7XG4gIH1cblxuICBwdWJsaWMgYWRkQ2hpbGQoY2hpbGQ6IERhdGFGbG93Tm9kZSkge1xuICAgIHRoaXMuX2NoaWxkcmVuLnB1c2goY2hpbGQpO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZUNoaWxkKG9sZENoaWxkOiBEYXRhRmxvd05vZGUpIHtcbiAgICB0aGlzLl9jaGlsZHJlbi5zcGxpY2UodGhpcy5fY2hpbGRyZW4uaW5kZXhPZihvbGRDaGlsZCksIDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBub2RlIGZyb20gdGhlIGRhdGFmbG93LlxuICAgKi9cbiAgcHVibGljIHJlbW92ZSgpIHtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuX2NoaWxkcmVuKSB7XG4gICAgICBjaGlsZC5wYXJlbnQgPSB0aGlzLl9wYXJlbnQ7XG4gICAgfVxuICAgIHRoaXMuX3BhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnQgYW5vdGhlciBub2RlIGFzIGEgcGFyZW50IG9mIHRoaXMgbm9kZS5cbiAgICovXG4gIHB1YmxpYyBpbnNlcnRBc1BhcmVudE9mKG90aGVyOiBEYXRhRmxvd05vZGUpIHtcbiAgICBjb25zdCBwYXJlbnQgPSBvdGhlci5wYXJlbnQ7XG4gICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgIG90aGVyLnBhcmVudCA9IHRoaXM7XG4gIH1cblxuICBwdWJsaWMgc3dhcFdpdGhQYXJlbnQoKSB7XG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5fcGFyZW50O1xuICAgIGNvbnN0IG5ld1BhcmVudCA9IHBhcmVudC5wYXJlbnQ7XG5cbiAgICAvLyByZWNvbm5lY3QgdGhlIGNoaWxkcmVuXG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiB0aGlzLl9jaGlsZHJlbikge1xuICAgICAgY2hpbGQucGFyZW50ID0gcGFyZW50O1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBvbGQgbGlua3NcbiAgICB0aGlzLl9jaGlsZHJlbiA9IFtdOyAgLy8gZXF1aXZhbGVudCB0byByZW1vdmluZyBldmVyeSBjaGlsZCBsaW5rIG9uZSBieSBvbmVcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7XG4gICAgcGFyZW50LnBhcmVudC5yZW1vdmVDaGlsZChwYXJlbnQpO1xuXG5cbiAgICAvLyBzd2FwIHR3byBub2Rlc1xuICAgIHRoaXMucGFyZW50ID0gbmV3UGFyZW50O1xuICAgIHBhcmVudC5wYXJlbnQgPSB0aGlzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBPdXRwdXROb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHJpdmF0ZSBfc291cmNlOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBfbmFtZTogc3RyaW5nO1xuXG4gIHB1YmxpYyBjbG9uZSgpOiB0aGlzIHtcbiAgICBjb25zdCBjbG9uZU9iaiA9IG5ldyAoPGFueT50aGlzLmNvbnN0cnVjdG9yKTtcbiAgICBjbG9uZU9iai5kZWJ1Z05hbWUgPSAnY2xvbmVfJyArIHRoaXMuZGVidWdOYW1lO1xuICAgIGNsb25lT2JqLl9zb3VyY2UgPSB0aGlzLl9zb3VyY2U7XG4gICAgY2xvbmVPYmouX25hbWUgPSAnY2xvbmVfJyArIHRoaXMuX25hbWU7XG4gICAgY2xvbmVPYmoudHlwZSA9IHRoaXMudHlwZTtcbiAgICBjbG9uZU9iai5yZWZDb3VudHMgPSB0aGlzLnJlZkNvdW50cztcbiAgICBjbG9uZU9iai5yZWZDb3VudHNbY2xvbmVPYmouX25hbWVdID0gMDtcbiAgICByZXR1cm4gY2xvbmVPYmo7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHNvdXJjZSBUaGUgbmFtZSBvZiB0aGUgc291cmNlLiBXaWxsIGNoYW5nZSBpbiBhc3NlbWJsZS5cbiAgICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2YgdGhlIG91dHB1dCBub2RlLlxuICAgKiBAcGFyYW0gcmVmQ291bnRzIEEgZ2xvYmFsIHJlZiBjb3VudGVyIG1hcC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHNvdXJjZTogc3RyaW5nLCBwdWJsaWMgcmVhZG9ubHkgdHlwZTogRGF0YVNvdXJjZVR5cGUsIHByaXZhdGUgcmVhZG9ubHkgcmVmQ291bnRzOiBEaWN0PG51bWJlcj4pIHtcbiAgICBzdXBlcihzb3VyY2UpO1xuXG4gICAgdGhpcy5fc291cmNlID0gdGhpcy5fbmFtZSA9IHNvdXJjZTtcblxuICAgIGlmICh0aGlzLnJlZkNvdW50cyAmJiAhKHRoaXMuX25hbWUgaW4gdGhpcy5yZWZDb3VudHMpKSB7XG4gICAgICB0aGlzLnJlZkNvdW50c1t0aGlzLl9uYW1lXSA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVlc3QgdGhlIGRhdGFzb3VyY2UgbmFtZSBhbmQgaW5jcmVhc2UgdGhlIHJlZiBjb3VudGVyLlxuICAgKlxuICAgKiBEdXJpbmcgdGhlIHBhcnNpbmcgcGhhc2UsIHRoaXMgd2lsbCByZXR1cm4gdGhlIHNpbXBsZSBuYW1lIHN1Y2ggYXMgJ21haW4nIG9yICdyYXcnLlxuICAgKiBJdCBpcyBjcnVjaWFsIHRvIHJlcXVlc3QgdGhlIG5hbWUgZnJvbSBhbiBvdXRwdXQgbm9kZSB0byBtYXJrIGl0IGFzIGEgcmVxdWlyZWQgbm9kZS5cbiAgICogSWYgbm9ib2R5IGV2ZXIgcmVxdWVzdHMgdGhlIG5hbWUsIHRoaXMgZGF0YXNvdXJjZSB3aWxsIG5vdCBiZSBpbnN0YW50aWF0ZWQgaW4gdGhlIGFzc2VtYmxlIHBoYXNlLlxuICAgKlxuICAgKiBJbiB0aGUgYXNzZW1ibGUgcGhhc2UsIHRoaXMgd2lsbCByZXR1cm4gdGhlIGNvcnJlY3QgbmFtZS5cbiAgICovXG4gIHB1YmxpYyBnZXRTb3VyY2UoKSB7XG4gICAgdGhpcy5yZWZDb3VudHNbdGhpcy5fbmFtZV0rKztcbiAgICByZXR1cm4gdGhpcy5fc291cmNlO1xuICB9XG5cbiAgcHVibGljIGlzUmVxdWlyZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5yZWZDb3VudHNbdGhpcy5fbmFtZV07XG4gIH1cblxuICBwdWJsaWMgc2V0U291cmNlKHNvdXJjZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fc291cmNlID0gc291cmNlO1xuICB9XG59XG4iXX0= \ 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..d0110dfbf1 --- /dev/null +++ b/build/src/compile/data/facet.d.ts @@ -0,0 +1,30 @@ +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 columnFields; + private readonly columnName; + private readonly rowFields; + private readonly rowName; + 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(model: FacetModel, name: string, data: string); + readonly fields: string[]; + /** + * The name to reference this source is its name. + */ + getSource(): string; + private getChildIndependentFieldsWithStep(); + private assembleRowColumnData(channel, crossedDataName, childIndependentFieldsWithStep); + assemble(): VgData[]; +} diff --git a/build/src/compile/data/facet.js b/build/src/compile/data/facet.js new file mode 100644 index 0000000000..718a79c32f --- /dev/null +++ b/build/src/compile/data/facet.js @@ -0,0 +1,160 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var domain_1 = require("../scale/domain"); +var dataflow_1 = require("./dataflow"); +/** + * 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(model, name, data) { + var _this = _super.call(this) || this; + _this.model = model; + _this.name = name; + _this.data = data; + if (model.facet.column) { + _this.columnFields = [model.field(channel_1.COLUMN)]; + _this.columnName = model.getName('column_domain'); + if (model.fieldDef(channel_1.COLUMN).bin) { + _this.columnFields.push(model.field(channel_1.COLUMN, { binSuffix: 'end' })); + } + } + if (model.facet.row) { + _this.rowFields = [model.field(channel_1.ROW)]; + _this.rowName = model.getName('row_domain'); + if (model.fieldDef(channel_1.ROW).bin) { + _this.rowFields.push(model.field(channel_1.ROW, { binSuffix: 'end' })); + } + } + _this.childModel = model.child; + return _this; + } + Object.defineProperty(FacetNode.prototype, "fields", { + get: function () { + var fields = []; + if (this.columnFields) { + fields = fields.concat(this.columnFields); + } + if (this.rowFields) { + fields = fields.concat(this.rowFields); + } + return 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 (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var domain = domain_1.assembleDomain(this.childModel, channel); + var field = domain_1.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 aggregateChildField = {}; + var childChannel = channel === 'row' ? 'y' : 'x'; + if (childIndependentFieldsWithStep[childChannel]) { + if (crossedDataName) { + aggregateChildField = { + // If there is a crossed data, calculate max + fields: ["distinct_" + childIndependentFieldsWithStep[childChannel]], + ops: ['max'], + // Although it is technically a max, just name it distinct so it's easier to refer to it + as: ["distinct_" + childIndependentFieldsWithStep[childChannel]] + }; + } + else { + aggregateChildField = { + // If there is no crossed data, just calculate distinct + fields: [childIndependentFieldsWithStep[childChannel]], + ops: ['distinct'] + }; + } + } + return { + name: channel === 'row' ? this.rowName : this.columnName, + // Use data from the crossed one if it exist + source: crossedDataName || this.data, + transform: [__assign({ type: 'aggregate', groupby: channel === 'row' ? this.rowFields : this.columnFields }, aggregateChildField)] + }; + }; + FacetNode.prototype.assemble = function () { + var data = []; + var crossedDataName = null; + var childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep(); + if (this.columnName && this.rowName && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) { + // Need to create a cross dataset to correctly calculate cardinality + crossedDataName = "cross_" + this.columnName + "_" + this.rowName; + 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.columnFields.concat(this.rowFields), + fields: fields, + ops: ops + }] + }); + } + if (this.columnName) { + data.push(this.assembleRowColumnData('column', crossedDataName, childIndependentFieldsWithStep)); + } + if (this.rowName) { + data.push(this.assembleRowColumnData('row', crossedDataName, childIndependentFieldsWithStep)); + } + return data; + }; + return FacetNode; +}(dataflow_1.DataFlowNode)); +exports.FacetNode = FacetNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2ZhY2V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EseUNBQXdEO0FBQ3hELCtCQUFpQztBQUNqQyxxQ0FBOEM7QUFDOUMsaURBQThFO0FBRzlFLDBDQUFtRTtBQUNuRSx1Q0FBd0M7QUFPeEM7O0dBRUc7QUFDSDtJQUErQiw2QkFBWTtJQVN6Qzs7OztPQUlHO0lBQ0gsbUJBQW1DLEtBQWlCLEVBQWtCLElBQVksRUFBUyxJQUFZO1FBQXZHLFlBQ0UsaUJBQU8sU0FtQlI7UUFwQmtDLFdBQUssR0FBTCxLQUFLLENBQVk7UUFBa0IsVUFBSSxHQUFKLElBQUksQ0FBUTtRQUFTLFVBQUksR0FBSixJQUFJLENBQVE7UUFHckcsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLEtBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGdCQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzFDLEtBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNqRCxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMvQixLQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGdCQUFNLEVBQUUsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLENBQUM7UUFDSCxDQUFDO1FBRUQsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLEtBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxLQUFLLENB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RSw4QkFBOEIsQ0FBQyxDQUFDLENBQUM7UUFDbkcsQ0FBQztRQUVELEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsOEJBQThCLENBQUMsQ0FBQyxDQUFDO1FBQ2hHLENBQUM7UUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNILGdCQUFDO0FBQUQsQ0FBQyxBQXJKRCxDQUErQix1QkFBWSxHQXFKMUM7QUFySlksOEJBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FnZ3JlZ2F0ZU9wfSBmcm9tICcuLi8uLi9hZ2dyZWdhdGUnO1xuaW1wb3J0IHtDT0xVTU4sIFJPVywgU2NhbGVDaGFubmVsfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi9sb2cnO1xuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbn0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtpc1ZnUmFuZ2VTdGVwLCBWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybSwgVmdEYXRhfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge0ZhY2V0TW9kZWx9IGZyb20gJy4uL2ZhY2V0JztcbmltcG9ydCB7TW9kZWx9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7YXNzZW1ibGVEb21haW4sIGdldEZpZWxkRnJvbURvbWFpbn0gZnJvbSAnLi4vc2NhbGUvZG9tYWluJztcbmltcG9ydCB7RGF0YUZsb3dOb2RlfSBmcm9tICcuL2RhdGFmbG93JztcblxudHlwZSBDaGlsZEluZGVwZW5kZW50RmllbGRzV2l0aFN0ZXAgPSB7XG4gIHg/OiBzdHJpbmcsXG4gIHk/OiBzdHJpbmdcbn07XG5cbi8qKlxuICogQSBub2RlIHRoYXQgaGVscHMgdXMgdHJhY2sgd2hhdCBmaWVsZHMgd2UgYXJlIGZhY2V0aW5nIGJ5LlxuICovXG5leHBvcnQgY2xhc3MgRmFjZXROb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBjb2x1bW5GaWVsZHM6IHN0cmluZ1tdO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbHVtbk5hbWU6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHJvd0ZpZWxkczogc3RyaW5nW107XG4gIHByaXZhdGUgcmVhZG9ubHkgcm93TmFtZTogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2hpbGRNb2RlbDogTW9kZWw7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBtb2RlbCBUaGUgZmFjZXQgbW9kZWwuXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIHRoYXQgdGhpcyBmYWNldCBzb3VyY2Ugd2lsbCBoYXZlLlxuICAgKiBAcGFyYW0gZGF0YSBUaGUgc291cmNlIGRhdGEgZm9yIHRoaXMgZmFjZXQgZGF0YS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgbW9kZWw6IEZhY2V0TW9kZWwsIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmcsIHB1YmxpYyBkYXRhOiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKG1vZGVsLmZhY2V0LmNvbHVtbikge1xuICAgICAgdGhpcy5jb2x1bW5GaWVsZHMgPSBbbW9kZWwuZmllbGQoQ09MVU1OKV07XG4gICAgICB0aGlzLmNvbHVtbk5hbWUgPSBtb2RlbC5nZXROYW1lKCdjb2x1bW5fZG9tYWluJyk7XG4gICAgICBpZiAobW9kZWwuZmllbGREZWYoQ09MVU1OKS5iaW4pIHtcbiAgICAgICAgdGhpcy5jb2x1bW5GaWVsZHMucHVzaChtb2RlbC5maWVsZChDT0xVTU4sIHtiaW5TdWZmaXg6ICdlbmQnfSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtb2RlbC5mYWNldC5yb3cpIHtcbiAgICAgIHRoaXMucm93RmllbGRzID0gW21vZGVsLmZpZWxkKFJPVyldO1xuICAgICAgdGhpcy5yb3dOYW1lID0gbW9kZWwuZ2V0TmFtZSgncm93X2RvbWFpbicpO1xuICAgICAgaWYgKG1vZGVsLmZpZWxkRGVmKFJPVykuYmluKSB7XG4gICAgICAgIHRoaXMucm93RmllbGRzLnB1c2gobW9kZWwuZmllbGQoUk9XLCB7YmluU3VmZml4OiAnZW5kJ30pKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNoaWxkTW9kZWwgPSBtb2RlbC5jaGlsZDtcbiAgfVxuXG4gIGdldCBmaWVsZHMoKSB7XG4gICAgbGV0IGZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAodGhpcy5jb2x1bW5GaWVsZHMpIHtcbiAgICAgIGZpZWxkcyA9IGZpZWxkcy5jb25jYXQodGhpcy5jb2x1bW5GaWVsZHMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yb3dGaWVsZHMpIHtcbiAgICAgIGZpZWxkcyA9IGZpZWxkcy5jb25jYXQodGhpcy5yb3dGaWVsZHMpO1xuICAgIH1cbiAgICByZXR1cm4gZmllbGRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIHRvIHJlZmVyZW5jZSB0aGlzIHNvdXJjZSBpcyBpdHMgbmFtZS5cbiAgICovXG4gIHB1YmxpYyBnZXRTb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwKCkge1xuICAgIGNvbnN0IGNoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcDogQ2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwID0ge307XG5cbiAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWyd4JywgJ3knXSBhcyBTY2FsZUNoYW5uZWxbXSkge1xuICAgICAgY29uc3QgY2hpbGRTY2FsZUNvbXBvbmVudCA9IHRoaXMuY2hpbGRNb2RlbC5jb21wb25lbnQuc2NhbGVzW2NoYW5uZWxdO1xuICAgICAgaWYgKGNoaWxkU2NhbGVDb21wb25lbnQgJiYgIWNoaWxkU2NhbGVDb21wb25lbnQubWVyZ2VkKSB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBjaGlsZFNjYWxlQ29tcG9uZW50LmdldCgndHlwZScpO1xuICAgICAgICBjb25zdCByYW5nZSA9IGNoaWxkU2NhbGVDb21wb25lbnQuZ2V0KCdyYW5nZScpO1xuXG4gICAgICAgIGlmIChoYXNEaXNjcmV0ZURvbWFpbih0eXBlKSAmJiBpc1ZnUmFuZ2VTdGVwKHJhbmdlKSkge1xuICAgICAgICAgIGNvbnN0IGRvbWFpbiA9IGFzc2VtYmxlRG9tYWluKHRoaXMuY2hpbGRNb2RlbCwgY2hhbm5lbCk7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBnZXRGaWVsZEZyb21Eb21haW4oZG9tYWluKTtcbiAgICAgICAgICBpZiAoZmllbGQpIHtcbiAgICAgICAgICAgIGNoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcFtjaGFubmVsXSA9IGZpZWxkO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2cud2FybignVW5rbm93biBmaWVsZCBmb3IgJHtjaGFubmVsfS4gIENhbm5vdCBjYWxjdWxhdGUgdmlldyBzaXplLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjaGlsZEluZGVwZW5kZW50RmllbGRzV2l0aFN0ZXA7XG4gIH1cblxuICBwcml2YXRlIGFzc2VtYmxlUm93Q29sdW1uRGF0YShjaGFubmVsOiAncm93JyB8ICdjb2x1bW4nLCBjcm9zc2VkRGF0YU5hbWU6IHN0cmluZywgY2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwOiBDaGlsZEluZGVwZW5kZW50RmllbGRzV2l0aFN0ZXApOiBWZ0RhdGEge1xuICAgIGxldCBhZ2dyZWdhdGVDaGlsZEZpZWxkOiBQYXJ0aWFsPFZnQWdncmVnYXRlVHJhbnNmb3JtPiA9IHt9O1xuICAgIGNvbnN0IGNoaWxkQ2hhbm5lbCA9IGNoYW5uZWwgPT09ICdyb3cnID8gJ3knIDogJ3gnO1xuXG4gICAgaWYgKGNoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcFtjaGlsZENoYW5uZWxdKSB7XG4gICAgICBpZiAoY3Jvc3NlZERhdGFOYW1lKSB7XG4gICAgICAgIGFnZ3JlZ2F0ZUNoaWxkRmllbGQgPSB7XG4gICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBjcm9zc2VkIGRhdGEsIGNhbGN1bGF0ZSBtYXhcbiAgICAgICAgICBmaWVsZHM6IFtgZGlzdGluY3RfJHtjaGlsZEluZGVwZW5kZW50RmllbGRzV2l0aFN0ZXBbY2hpbGRDaGFubmVsXX1gXSxcbiAgICAgICAgICBvcHM6IFsnbWF4J10sXG4gICAgICAgICAgLy8gQWx0aG91Z2ggaXQgaXMgdGVjaG5pY2FsbHkgYSBtYXgsIGp1c3QgbmFtZSBpdCBkaXN0aW5jdCBzbyBpdCdzIGVhc2llciB0byByZWZlciB0byBpdFxuICAgICAgICAgIGFzOiBbYGRpc3RpbmN0XyR7Y2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwW2NoaWxkQ2hhbm5lbF19YF1cbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFnZ3JlZ2F0ZUNoaWxkRmllbGQgPSB7XG4gICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY3Jvc3NlZCBkYXRhLCBqdXN0IGNhbGN1bGF0ZSBkaXN0aW5jdFxuICAgICAgICAgIGZpZWxkczogW2NoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcFtjaGlsZENoYW5uZWxdXSxcbiAgICAgICAgICBvcHM6IFsnZGlzdGluY3QnXVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBjaGFubmVsID09PSAncm93JyA/IHRoaXMucm93TmFtZSA6IHRoaXMuY29sdW1uTmFtZSxcbiAgICAgIC8vIFVzZSBkYXRhIGZyb20gdGhlIGNyb3NzZWQgb25lIGlmIGl0IGV4aXN0XG4gICAgICBzb3VyY2U6IGNyb3NzZWREYXRhTmFtZSB8fCB0aGlzLmRhdGEsXG4gICAgICB0cmFuc2Zvcm06IFt7XG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICBncm91cGJ5OiBjaGFubmVsID09PSAncm93JyA/IHRoaXMucm93RmllbGRzIDogdGhpcy5jb2x1bW5GaWVsZHMsXG4gICAgICAgIC4uLmFnZ3JlZ2F0ZUNoaWxkRmllbGRcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZSgpIHtcbiAgICBjb25zdCBkYXRhOiBWZ0RhdGFbXSA9IFtdO1xuICAgIGxldCBjcm9zc2VkRGF0YU5hbWUgPSBudWxsO1xuICAgIGNvbnN0IGNoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcCA9IHRoaXMuZ2V0Q2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwKCk7XG5cbiAgICBpZiAodGhpcy5jb2x1bW5OYW1lICYmIHRoaXMucm93TmFtZSAmJiAoY2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwLnggfHwgY2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwLnkpKSB7XG4gICAgICAvLyBOZWVkIHRvIGNyZWF0ZSBhIGNyb3NzIGRhdGFzZXQgdG8gY29ycmVjdGx5IGNhbGN1bGF0ZSBjYXJkaW5hbGl0eVxuICAgICAgY3Jvc3NlZERhdGFOYW1lID0gYGNyb3NzXyR7dGhpcy5jb2x1bW5OYW1lfV8ke3RoaXMucm93TmFtZX1gO1xuXG4gICAgICBjb25zdCBmaWVsZHMgPSBbXS5jb25jYXQoXG4gICAgICAgIGNoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcC54ID8gW2NoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcC54XSA6IFtdLFxuICAgICAgICBjaGlsZEluZGVwZW5kZW50RmllbGRzV2l0aFN0ZXAueSA/IFtjaGlsZEluZGVwZW5kZW50RmllbGRzV2l0aFN0ZXAueV0gOiBbXSxcbiAgICAgICk7XG4gICAgICBjb25zdCBvcHMgPSBmaWVsZHMubWFwKCgpOiBBZ2dyZWdhdGVPcCA9PiAnZGlzdGluY3QnKTtcblxuICAgICAgZGF0YS5wdXNoKHtcbiAgICAgICAgbmFtZTogY3Jvc3NlZERhdGFOYW1lLFxuICAgICAgICBzb3VyY2U6IHRoaXMuZGF0YSxcbiAgICAgICAgdHJhbnNmb3JtOiBbe1xuICAgICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICAgIGdyb3VwYnk6IHRoaXMuY29sdW1uRmllbGRzLmNvbmNhdCh0aGlzLnJvd0ZpZWxkcyksXG4gICAgICAgICAgZmllbGRzOiBmaWVsZHMsXG4gICAgICAgICAgb3BzXG4gICAgICAgIH1dXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb2x1bW5OYW1lKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5hc3NlbWJsZVJvd0NvbHVtbkRhdGEoJ2NvbHVtbicsIGNyb3NzZWREYXRhTmFtZSwgY2hpbGRJbmRlcGVuZGVudEZpZWxkc1dpdGhTdGVwKSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucm93TmFtZSkge1xuICAgICAgZGF0YS5wdXNoKHRoaXMuYXNzZW1ibGVSb3dDb2x1bW5EYXRhKCdyb3cnLCBjcm9zc2VkRGF0YU5hbWUsIGNoaWxkSW5kZXBlbmRlbnRGaWVsZHNXaXRoU3RlcCkpO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XG59XG4iXX0= \ 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..75e2fc7e8c --- /dev/null +++ b/build/src/compile/data/filter.d.ts @@ -0,0 +1,13 @@ +import { Filter } from '../../filter'; +import { LogicalOperand } from '../../logical'; +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(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..d0e415c94c --- /dev/null +++ b/build/src/compile/data/filter.js @@ -0,0 +1,37 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var filter_1 = require("../../filter"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var FilterNode = /** @class */ (function (_super) { + __extends(FilterNode, _super); + function FilterNode(model, filter) { + var _this = _super.call(this) || this; + _this.model = model; + _this.filter = filter; + _this.expr = filter_1.expression(_this.model, _this.filter, _this); + return _this; + } + FilterNode.prototype.clone = function () { + return new FilterNode(this.model, util_1.duplicate(this.filter)); + }; + FilterNode.prototype.assemble = function () { + return { + type: 'filter', + expr: this.expr + }; + }; + return FilterNode; +}(dataflow_1.DataFlowNode)); +exports.FilterNode = FilterNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9maWx0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsdUNBQWdEO0FBRWhELG1DQUFxQztBQUdyQyx1Q0FBd0M7QUFFeEM7SUFBZ0MsOEJBQVk7SUFNMUMsb0JBQTZCLEtBQVksRUFBVSxNQUE4QjtRQUFqRixZQUNFLGlCQUFPLFNBRVI7UUFINEIsV0FBSyxHQUFMLEtBQUssQ0FBTztRQUFVLFlBQU0sR0FBTixNQUFNLENBQXdCO1FBRS9FLEtBQUksQ0FBQyxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxLQUFJLENBQUMsS0FBSyxFQUFFLEtBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSSxDQUFDLENBQUM7O0lBQ3hELENBQUM7SUFQTSwwQkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsZ0JBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBT00sNkJBQVEsR0FBZjtRQUNFLE1BQU0sQ0FBQztZQUNMLElBQUksRUFBRSxRQUFRO1lBQ2QsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1NBQ2hCLENBQUM7SUFDSixDQUFDO0lBQ0gsaUJBQUM7QUFBRCxDQUFDLEFBakJELENBQWdDLHVCQUFZLEdBaUIzQztBQWpCWSxnQ0FBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7ZXhwcmVzc2lvbiwgRmlsdGVyfSBmcm9tICcuLi8uLi9maWx0ZXInO1xuaW1wb3J0IHtMb2dpY2FsT3BlcmFuZH0gZnJvbSAnLi4vLi4vbG9naWNhbCc7XG5pbXBvcnQge2R1cGxpY2F0ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnRmlsdGVyVHJhbnNmb3JtfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge01vZGVsfSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZX0gZnJvbSAnLi9kYXRhZmxvdyc7XG5cbmV4cG9ydCBjbGFzcyBGaWx0ZXJOb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHJpdmF0ZSBleHByOiBzdHJpbmc7XG4gIHB1YmxpYyBjbG9uZSgpIHtcbiAgICByZXR1cm4gbmV3IEZpbHRlck5vZGUodGhpcy5tb2RlbCwgZHVwbGljYXRlKHRoaXMuZmlsdGVyKSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG1vZGVsOiBNb2RlbCwgcHJpdmF0ZSBmaWx0ZXI6IExvZ2ljYWxPcGVyYW5kPEZpbHRlcj4pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuZXhwciA9IGV4cHJlc3Npb24odGhpcy5tb2RlbCwgdGhpcy5maWx0ZXIsIHRoaXMpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlKCk6IFZnRmlsdGVyVHJhbnNmb3JtIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ2ZpbHRlcicsXG4gICAgICBleHByOiB0aGlzLmV4cHJcbiAgICB9O1xuICB9XG59XG4iXX0= \ 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..fabacda6c2 --- /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 { ModelWithField } from '../model'; +import { DataFlowNode } from './dataflow'; +export declare class FilterInvalidNode extends DataFlowNode { + private fieldDefs; + clone(): FilterInvalidNode; + constructor(fieldDefs: Dict>); + static make(model: ModelWithField): 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..8335e28b8b --- /dev/null +++ b/build/src/compile/data/filterinvalid.js @@ -0,0 +1,84 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var FilterInvalidNode = /** @class */ (function (_super) { + __extends(FilterInvalidNode, _super); + function FilterInvalidNode(fieldDefs) { + var _this = _super.call(this) || this; + _this.fieldDefs = fieldDefs; + return _this; + } + FilterInvalidNode.prototype.clone = function () { + return new FilterInvalidNode(__assign({}, this.fieldDefs)); + }; + FilterInvalidNode.make = function (model) { + if (model.config.invalidValues !== 'filter') { + return null; + } + var filter = model.reduceFieldDef(function (aggregator, fieldDef, channel) { + var scaleComponent = channel_1.isScaleChannel(channel) && model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + // only automatically filter null for continuous domain since discrete domain scales can handle invalid values. + if (scale_1.hasContinuousDomain(scaleType) && !fieldDef.aggregate) { + aggregator[fieldDef.field] = fieldDef; + } + } + return aggregator; + }, {}); + if (!util_1.keys(filter).length) { + return null; + } + return new FilterInvalidNode(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 = util_1.keys(this.filter).reduce(function (vegaFilters, field) { + var fieldDef = _this.fieldDefs[field]; + var ref = fielddef_1.field(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; +}(dataflow_1.DataFlowNode)); +exports.FilterInvalidNode = FilterInvalidNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyaW52YWxpZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvZmlsdGVyaW52YWxpZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlDQUE2QztBQUM3QywyQ0FBMkQ7QUFDM0QscUNBQTJEO0FBQzNELG1DQUFzQztBQUd0Qyx1Q0FBd0M7QUFFeEM7SUFBdUMscUNBQVk7SUFLakQsMkJBQW9CLFNBQWlDO1FBQXJELFlBQ0MsaUJBQU8sU0FDUDtRQUZtQixlQUFTLEdBQVQsU0FBUyxDQUF3Qjs7SUFFckQsQ0FBQztJQU5NLGlDQUFLLEdBQVo7UUFDRSxNQUFNLENBQUMsSUFBSSxpQkFBaUIsY0FBSyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDcEQsQ0FBQztJQU1hLHNCQUFJLEdBQWxCLFVBQW1CLEtBQXFCO1FBQ3RDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsYUFBYSxLQUFLLFFBQVMsQ0FBQyxDQUFDLENBQUM7WUFDN0MsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLFVBQUMsVUFBa0MsRUFBRSxRQUFRLEVBQUUsT0FBTztZQUN4RixJQUFNLGNBQWMsR0FBRyx3QkFBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNuRixFQUFFLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixJQUFNLFNBQVMsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUU3QywrR0FBK0c7Z0JBQy9HLEVBQUUsQ0FBQyxDQUFDLDJCQUFtQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7b0JBQzFELFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsUUFBUSxDQUFDO2dCQUN4QyxDQUFDO1lBQ0gsQ0FBQztZQUNELE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFDcEIsQ0FBQyxFQUFFLEVBQTRCLENBQUMsQ0FBQztRQUVqQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsTUFBTSxDQUFDLElBQUksaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELHNCQUFJLHFDQUFNO2FBQVY7WUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUN4QixDQUFDOzs7T0FBQTtJQUVELDBEQUEwRDtJQUNuRCxvQ0FBUSxHQUFmO1FBQUEsaUJBa0JDO1FBaEJDLElBQU0sT0FBTyxHQUFHLFdBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQUMsV0FBVyxFQUFFLEtBQUs7WUFDMUQsSUFBTSxRQUFRLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QyxJQUFNLEdBQUcsR0FBRyxnQkFBUSxDQUFDLFFBQVEsRUFBRSxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDO1lBRWhELEVBQUUsQ0FBQyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUN0QixXQUFXLENBQUMsSUFBSSxDQUFJLEdBQUcsY0FBVyxDQUFDLENBQUM7Z0JBQ3BDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBVSxHQUFHLE1BQUcsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7WUFDRCxNQUFNLENBQUMsV0FBVyxDQUFDO1FBQ3JCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVQLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzNCO2dCQUNJLElBQUksRUFBRSxRQUFRO2dCQUNkLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQzthQUM3QixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDWCxDQUFDO0lBQ0gsd0JBQUM7QUFBRCxDQUFDLEFBMURELENBQXVDLHVCQUFZLEdBMERsRDtBQTFEWSw4Q0FBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzU2NhbGVDaGFubmVsfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7ZmllbGQgYXMgZmllbGRSZWYsIEZpZWxkRGVmfSBmcm9tICcuLi8uLi9maWVsZGRlZic7XG5pbXBvcnQge2hhc0NvbnRpbnVvdXNEb21haW4sIFNjYWxlVHlwZX0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtEaWN0LCBrZXlzfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7VmdGaWx0ZXJUcmFuc2Zvcm19IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7TW9kZWxXaXRoRmllbGR9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7RGF0YUZsb3dOb2RlfSBmcm9tICcuL2RhdGFmbG93JztcblxuZXhwb3J0IGNsYXNzIEZpbHRlckludmFsaWROb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHVibGljIGNsb25lKCkge1xuICAgIHJldHVybiBuZXcgRmlsdGVySW52YWxpZE5vZGUoey4uLnRoaXMuZmllbGREZWZzfSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGZpZWxkRGVmczogRGljdDxGaWVsZERlZjxzdHJpbmc+Pikge1xuICAgc3VwZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgbWFrZShtb2RlbDogTW9kZWxXaXRoRmllbGQpOiBGaWx0ZXJJbnZhbGlkTm9kZSB7XG4gICAgaWYgKG1vZGVsLmNvbmZpZy5pbnZhbGlkVmFsdWVzICE9PSAnZmlsdGVyJyApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbHRlciA9IG1vZGVsLnJlZHVjZUZpZWxkRGVmKChhZ2dyZWdhdG9yOiBEaWN0PEZpZWxkRGVmPHN0cmluZz4+LCBmaWVsZERlZiwgY2hhbm5lbCkgPT4ge1xuICAgICAgY29uc3Qgc2NhbGVDb21wb25lbnQgPSBpc1NjYWxlQ2hhbm5lbChjaGFubmVsKSAmJiBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKTtcbiAgICAgIGlmIChzY2FsZUNvbXBvbmVudCkge1xuICAgICAgICBjb25zdCBzY2FsZVR5cGUgPSBzY2FsZUNvbXBvbmVudC5nZXQoJ3R5cGUnKTtcblxuICAgICAgICAvLyBvbmx5IGF1dG9tYXRpY2FsbHkgZmlsdGVyIG51bGwgZm9yIGNvbnRpbnVvdXMgZG9tYWluIHNpbmNlIGRpc2NyZXRlIGRvbWFpbiBzY2FsZXMgY2FuIGhhbmRsZSBpbnZhbGlkIHZhbHVlcy5cbiAgICAgICAgaWYgKGhhc0NvbnRpbnVvdXNEb21haW4oc2NhbGVUeXBlKSAmJiAhZmllbGREZWYuYWdncmVnYXRlKSB7XG4gICAgICAgICAgYWdncmVnYXRvcltmaWVsZERlZi5maWVsZF0gPSBmaWVsZERlZjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFnZ3JlZ2F0b3I7XG4gICAgfSwge30gYXMgRGljdDxGaWVsZERlZjxzdHJpbmc+Pik7XG5cbiAgICBpZiAoIWtleXMoZmlsdGVyKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRmlsdGVySW52YWxpZE5vZGUoZmlsdGVyKTtcbiAgfVxuXG4gIGdldCBmaWx0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGREZWZzO1xuICB9XG5cbiAgLy8gY3JlYXRlIHRoZSBWZ1RyYW5zZm9ybXMgZm9yIGVhY2ggb2YgdGhlIGZpbHRlcmVkIGZpZWxkc1xuICBwdWJsaWMgYXNzZW1ibGUoKTogVmdGaWx0ZXJUcmFuc2Zvcm0ge1xuXG4gICAgY29uc3QgZmlsdGVycyA9IGtleXModGhpcy5maWx0ZXIpLnJlZHVjZSgodmVnYUZpbHRlcnMsIGZpZWxkKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IHRoaXMuZmllbGREZWZzW2ZpZWxkXTtcbiAgICAgIGNvbnN0IHJlZiA9IGZpZWxkUmVmKGZpZWxkRGVmLCB7ZXhwcjogJ2RhdHVtJ30pO1xuXG4gICAgICBpZiAoZmllbGREZWYgIT09IG51bGwpIHtcbiAgICAgICAgdmVnYUZpbHRlcnMucHVzaChgJHtyZWZ9ICE9PSBudWxsYCk7XG4gICAgICAgIHZlZ2FGaWx0ZXJzLnB1c2goYCFpc05hTigke3JlZn0pYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmVnYUZpbHRlcnM7XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIGZpbHRlcnMubGVuZ3RoID4gMCA/XG4gICAge1xuICAgICAgICB0eXBlOiAnZmlsdGVyJyxcbiAgICAgICAgZXhwcjogZmlsdGVycy5qb2luKCcgJiYgJylcbiAgICB9IDogbnVsbDtcbiAgfVxufVxuIl19 \ 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..43efd6295d --- /dev/null +++ b/build/src/compile/data/formatparse.d.ts @@ -0,0 +1,20 @@ +import { Dict } 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(parse: Dict); + static make(model: Model): ParseNode; + readonly parse: Dict; + merge(other: ParseNode): void; + assembleFormatParse(): Dict; + producedFields(): { + [T: string]: boolean; + }; + dependentFields(): { + [T: string]: boolean; + }; + assembleTransforms(): VgFormulaTransform[]; +} diff --git a/build/src/compile/data/formatparse.js b/build/src/compile/data/formatparse.js new file mode 100644 index 0000000000..892b586665 --- /dev/null +++ b/build/src/compile/data/formatparse.js @@ -0,0 +1,161 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var aggregate_1 = require("../../aggregate"); +var fielddef_1 = require("../../fielddef"); +var filter_1 = require("../../filter"); +var log = require("../../log"); +var logical_1 = require("../../logical"); +var transform_1 = require("../../transform"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var dataflow_1 = require("./dataflow"); +function parseExpression(field, parse) { + var f = "datum" + util_1.accessPath(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.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) { + __extends(ParseNode, _super); + function ParseNode(parse) { + var _this = _super.call(this) || this; + _this._parse = {}; + _this._parse = parse; + return _this; + } + ParseNode.prototype.clone = function () { + return new ParseNode(util_1.duplicate(this.parse)); + }; + ParseNode.make = function (model) { + var parse = {}; + var calcFieldMap = {}; + (model.transforms || []).forEach(function (transform) { + if (transform_1.isCalculate(transform)) { + calcFieldMap[transform.as] = true; + } + else if (transform_1.isFilter(transform)) { + logical_1.forEachLeave(transform.filter, function (filter) { + if (filter_1.isEqualFilter(filter) || filter_1.isRangeFilter(filter) || filter_1.isOneOfFilter(filter)) { + if (filter.timeUnit) { + parse[filter.field] = 'date'; + } + } + }); + } + }, {}); + if (model_1.isUnitModel(model) || model_1.isFacetModel(model)) { + // Parse encoded fields + model.forEachFieldDef(function (fieldDef) { + if (fielddef_1.isTimeFieldDef(fieldDef)) { + parse[fieldDef.field] = 'date'; + } + else if (fielddef_1.isNumberFieldDef(fieldDef)) { + if (calcFieldMap[fieldDef.field] || aggregate_1.isCountingAggregateOp(fieldDef.aggregate)) { + return; + } + parse[fieldDef.field] = 'number'; + } + }); + } + // Custom parse should override inferred parse + var data = model.data; + if (data && data.format && data.format.parse) { + var p_1 = data.format.parse; + util_1.keys(p_1).forEach(function (field) { + parse[field] = p_1[field]; + }); + } + // We should not parse what has already been parsed in a parent + var modelParse = model.component.data.ancestorParse; + util_1.keys(modelParse).forEach(function (field) { + if (parse[field] !== modelParse[field]) { + log.warn(log.message.differentParse(field, parse[field], modelParse[field])); + } + else { + delete parse[field]; + } + }); + if (util_1.keys(parse).length === 0) { + return null; + } + return new ParseNode(parse); + }; + 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(); + }; + ParseNode.prototype.assembleFormatParse = function () { + return this._parse; + }; + // format parse depends and produces all fields in its parse + ParseNode.prototype.producedFields = function () { + return util_1.toSet(util_1.keys(this.parse)); + }; + ParseNode.prototype.dependentFields = function () { + return util_1.toSet(util_1.keys(this.parse)); + }; + ParseNode.prototype.assembleTransforms = function () { + var _this = this; + return util_1.keys(this._parse).map(function (field) { + var expr = parseExpression(field, _this._parse[field]); + if (!expr) { + return null; + } + var formula = { + type: 'formula', + expr: expr, + as: field + }; + return formula; + }).filter(function (t) { return t !== null; }); + }; + return ParseNode; +}(dataflow_1.DataFlowNode)); +exports.ParseNode = ParseNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0cGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2Zvcm1hdHBhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQXNEO0FBQ3RELDJDQUFnRTtBQUNoRSx1Q0FBeUU7QUFDekUsK0JBQWlDO0FBQ2pDLHlDQUEyQztBQUMzQyw2Q0FBaUU7QUFDakUsbUNBQW9FO0FBRXBFLGtDQUEwRDtBQUMxRCx1Q0FBd0M7QUFHeEMseUJBQXlCLEtBQWEsRUFBRSxLQUFhO0lBQ25ELElBQU0sQ0FBQyxHQUFHLFVBQVEsaUJBQVUsQ0FBQyxLQUFLLENBQUcsQ0FBQztJQUN0QyxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsY0FBWSxDQUFDLE1BQUcsQ0FBQztJQUMxQixDQUFDO0lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxlQUFhLENBQUMsTUFBRyxDQUFDO0lBQzNCLENBQUM7SUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLGNBQVksQ0FBQyxNQUFHLENBQUM7SUFDMUIsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztRQUM1QixNQUFNLENBQUMsWUFBVSxDQUFDLE1BQUcsQ0FBQztJQUN4QixDQUFDO0lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QyxJQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMs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QUF1QjtnQkFDbEMsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsSUFBSSxNQUFBO2dCQUNKLEVBQUUsRUFBRSxLQUFLO2FBQ1YsQ0FBQztZQUNGLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxLQUFLLElBQUksRUFBVixDQUFVLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBQ0gsZ0JBQUM7QUFBRCxDQUFDLEFBM0dELENBQStCLHVCQUFZLEdBMkcxQztBQTNHWSw4QkFBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aXNDb3VudGluZ0FnZ3JlZ2F0ZU9wfSBmcm9tICcuLi8uLi9hZ2dyZWdhdGUnO1xuaW1wb3J0IHtpc051bWJlckZpZWxkRGVmLCBpc1RpbWVGaWVsZERlZn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0IHtpc0VxdWFsRmlsdGVyLCBpc09uZU9mRmlsdGVyLCBpc1JhbmdlRmlsdGVyfSBmcm9tICcuLi8uLi9maWx0ZXInO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge2ZvckVhY2hMZWF2ZX0gZnJvbSAnLi4vLi4vbG9naWNhbCc7XG5pbXBvcnQge2lzQ2FsY3VsYXRlLCBpc0ZpbHRlciwgVHJhbnNmb3JtfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0nO1xuaW1wb3J0IHthY2Nlc3NQYXRoLCBEaWN0LCBkdXBsaWNhdGUsIGtleXMsIHRvU2V0fSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7VmdGb3JtdWxhVHJhbnNmb3JtfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge2lzRmFjZXRNb2RlbCwgaXNVbml0TW9kZWwsIE1vZGVsfSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZX0gZnJvbSAnLi9kYXRhZmxvdyc7XG5cblxuZnVuY3Rpb24gcGFyc2VFeHByZXNzaW9uKGZpZWxkOiBzdHJpbmcsIHBhcnNlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBmID0gYGRhdHVtJHthY2Nlc3NQYXRoKGZpZWxkKX1gO1xuICBpZiAocGFyc2UgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIGB0b051bWJlcigke2Z9KWA7XG4gIH0gZWxzZSBpZiAocGFyc2UgPT09ICdib29sZWFuJykge1xuICAgIHJldHVybiBgdG9Cb29sZWFuKCR7Zn0pYDtcbiAgfSBlbHNlIGlmIChwYXJzZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gYHRvU3RyaW5nKCR7Zn0pYDtcbiAgfSBlbHNlIGlmIChwYXJzZSA9PT0gJ2RhdGUnKSB7XG4gICAgcmV0dXJuIGB0b0RhdGUoJHtmfSlgO1xuICB9IGVsc2UgaWYgKHBhcnNlLmluZGV4T2YoJ2RhdGU6JykgPT09IDApIHtcbiAgICBjb25zdCBzcGVjaWZpZXIgPSBwYXJzZS5zbGljZSg1LCBwYXJzZS5sZW5ndGgpO1xuICAgIHJldHVybiBgdGltZVBhcnNlKCR7Zn0sJHtzcGVjaWZpZXJ9KWA7XG4gIH0gZWxzZSBpZiAocGFyc2UuaW5kZXhPZigndXRjOicpID09PSAwKSB7XG4gICAgY29uc3Qgc3BlY2lmaWVyID0gcGFyc2Uuc2xpY2UoNCwgcGFyc2UubGVuZ3RoKTtcbiAgICByZXR1cm4gYHV0Y1BhcnNlKCR7Zn0sJHtzcGVjaWZpZXJ9KWA7XG4gIH0gZWxzZSB7XG4gICAgbG9nLndhcm4obG9nLm1lc3NhZ2UudW5yZWNvZ25pemVkUGFyc2UocGFyc2UpKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VOb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgcHJpdmF0ZSBfcGFyc2U6IERpY3Q8c3RyaW5nPiA9IHt9O1xuXG4gIHB1YmxpYyBjbG9uZSgpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlTm9kZShkdXBsaWNhdGUodGhpcy5wYXJzZSkpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocGFyc2U6IERpY3Q8c3RyaW5nPikge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9wYXJzZSA9IHBhcnNlO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBtYWtlKG1vZGVsOiBNb2RlbCkge1xuICAgIGNvbnN0IHBhcnNlID0ge307XG4gICAgY29uc3QgY2FsY0ZpZWxkTWFwID0ge307XG5cbiAgICAobW9kZWwudHJhbnNmb3JtcyB8fCBbXSkuZm9yRWFjaCgodHJhbnNmb3JtOiBUcmFuc2Zvcm0pID0+IHtcbiAgICAgIGlmIChpc0NhbGN1bGF0ZSh0cmFuc2Zvcm0pKSB7XG4gICAgICAgIGNhbGNGaWVsZE1hcFt0cmFuc2Zvcm0uYXNdID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAoaXNGaWx0ZXIodHJhbnNmb3JtKSkge1xuICAgICAgICBmb3JFYWNoTGVhdmUodHJhbnNmb3JtLmZpbHRlciwgKGZpbHRlcikgPT4ge1xuICAgICAgICAgIGlmIChpc0VxdWFsRmlsdGVyKGZpbHRlcikgfHwgaXNSYW5nZUZpbHRlcihmaWx0ZXIpIHx8IGlzT25lT2ZGaWx0ZXIoZmlsdGVyKSkge1xuICAgICAgICAgICAgaWYgKGZpbHRlci50aW1lVW5pdCkge1xuICAgICAgICAgICAgICBwYXJzZVtmaWx0ZXIuZmllbGRdID0gJ2RhdGUnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwge30pO1xuXG4gICAgaWYgKGlzVW5pdE1vZGVsKG1vZGVsKSB8fCBpc0ZhY2V0TW9kZWwobW9kZWwpKSB7XG4gICAgICAvLyBQYXJzZSBlbmNvZGVkIGZpZWxkc1xuICAgICAgbW9kZWwuZm9yRWFjaEZpZWxkRGVmKGZpZWxkRGVmID0+IHtcbiAgICAgICAgaWYgKGlzVGltZUZpZWxkRGVmKGZpZWxkRGVmKSkge1xuICAgICAgICAgIHBhcnNlW2ZpZWxkRGVmLmZpZWxkXSA9ICdkYXRlJztcbiAgICAgICAgfSBlbHNlIGlmIChpc051bWJlckZpZWxkRGVmKGZpZWxkRGVmKSkge1xuICAgICAgICAgIGlmIChjYWxjRmllbGRNYXBbZmllbGREZWYuZmllbGRdIHx8IGlzQ291bnRpbmdBZ2dyZWdhdGVPcChmaWVsZERlZi5hZ2dyZWdhdGUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcnNlW2ZpZWxkRGVmLmZpZWxkXSA9ICdudW1iZXInO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDdXN0b20gcGFyc2Ugc2hvdWxkIG92ZXJyaWRlIGluZmVycmVkIHBhcnNlXG4gICAgY29uc3QgZGF0YSA9IG1vZGVsLmRhdGE7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5mb3JtYXQgJiYgZGF0YS5mb3JtYXQucGFyc2UpIHtcbiAgICAgIGNvbnN0IHAgPSBkYXRhLmZvcm1hdC5wYXJzZTtcbiAgICAgIGtleXMocCkuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgIHBhcnNlW2ZpZWxkXSA9IHBbZmllbGRdO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gV2Ugc2hvdWxkIG5vdCBwYXJzZSB3aGF0IGhhcyBhbHJlYWR5IGJlZW4gcGFyc2VkIGluIGEgcGFyZW50XG4gICAgY29uc3QgbW9kZWxQYXJzZSA9IG1vZGVsLmNvbXBvbmVudC5kYXRhLmFuY2VzdG9yUGFyc2U7XG4gICAga2V5cyhtb2RlbFBhcnNlKS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGlmIChwYXJzZVtmaWVsZF0gIT09IG1vZGVsUGFyc2VbZmllbGRdKSB7XG4gICAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmRpZmZlcmVudFBhcnNlKGZpZWxkLCBwYXJzZVtmaWVsZF0sIG1vZGVsUGFyc2VbZmllbGRdKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgcGFyc2VbZmllbGRdO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGtleXMocGFyc2UpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQYXJzZU5vZGUocGFyc2UpO1xuICB9XG5cbiAgcHVibGljIGdldCBwYXJzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFyc2U7XG4gIH1cblxuICBwdWJsaWMgbWVyZ2Uob3RoZXI6IFBhcnNlTm9kZSkge1xuICAgIHRoaXMuX3BhcnNlID0gey4uLnRoaXMuX3BhcnNlLCAuLi5vdGhlci5wYXJzZX07XG4gICAgb3RoZXIucmVtb3ZlKCk7XG4gIH1cbiAgcHVibGljIGFzc2VtYmxlRm9ybWF0UGFyc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcnNlO1xuICB9XG5cbiAgLy8gZm9ybWF0IHBhcnNlIGRlcGVuZHMgYW5kIHByb2R1Y2VzIGFsbCBmaWVsZHMgaW4gaXRzIHBhcnNlXG4gIHB1YmxpYyBwcm9kdWNlZEZpZWxkcygpIHtcbiAgICByZXR1cm4gdG9TZXQoa2V5cyh0aGlzLnBhcnNlKSk7XG4gIH1cblxuICBwdWJsaWMgZGVwZW5kZW50RmllbGRzKCkge1xuICAgIHJldHVybiB0b1NldChrZXlzKHRoaXMucGFyc2UpKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZVRyYW5zZm9ybXMoKTogVmdGb3JtdWxhVHJhbnNmb3JtW10ge1xuICAgIHJldHVybiBrZXlzKHRoaXMuX3BhcnNlKS5tYXAoZmllbGQgPT4ge1xuICAgICAgY29uc3QgZXhwciA9IHBhcnNlRXhwcmVzc2lvbihmaWVsZCwgdGhpcy5fcGFyc2VbZmllbGRdKTtcbiAgICAgIGlmICghZXhwcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZm9ybXVsYTogVmdGb3JtdWxhVHJhbnNmb3JtID0ge1xuICAgICAgICB0eXBlOiAnZm9ybXVsYScsXG4gICAgICAgIGV4cHIsXG4gICAgICAgIGFzOiBmaWVsZFxuICAgICAgfTtcbiAgICAgIHJldHVybiBmb3JtdWxhO1xuICAgIH0pLmZpbHRlcih0ID0+IHQgIT09IG51bGwpO1xuICB9XG59XG4iXX0= \ 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..e0acfe5c99 --- /dev/null +++ b/build/src/compile/data/indentifier.d.ts @@ -0,0 +1,10 @@ +import { VgIdentifierTransform } from '../../vega.schema'; +import { DataFlowNode } from './dataflow'; +export declare class IdentifierNode extends DataFlowNode { + clone(): IdentifierNode; + constructor(); + producedFields(): { + [SELECTION_ID]: boolean; + }; + assemble(): VgIdentifierTransform; +} diff --git a/build/src/compile/data/indentifier.js b/build/src/compile/data/indentifier.js new file mode 100644 index 0000000000..12ee12f526 --- /dev/null +++ b/build/src/compile/data/indentifier.js @@ -0,0 +1,33 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("../../selection"); +var dataflow_1 = require("./dataflow"); +var IdentifierNode = /** @class */ (function (_super) { + __extends(IdentifierNode, _super); + function IdentifierNode() { + return _super.call(this) || this; + } + IdentifierNode.prototype.clone = function () { + return new IdentifierNode(); + }; + IdentifierNode.prototype.producedFields = function () { + return _a = {}, _a[selection_1.SELECTION_ID] = true, _a; + var _a; + }; + IdentifierNode.prototype.assemble = function () { + return { type: 'identifier', as: selection_1.SELECTION_ID }; + }; + return IdentifierNode; +}(dataflow_1.DataFlowNode)); +exports.IdentifierNode = IdentifierNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZW50aWZpZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2luZGVudGlmaWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLDZDQUE2QztBQUU3Qyx1Q0FBd0M7QUFFeEM7SUFBb0Msa0NBQVk7SUFLOUM7ZUFDRSxpQkFBTztJQUNULENBQUM7SUFOTSw4QkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksY0FBYyxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQU1NLHVDQUFjLEdBQXJCO1FBQ0UsTUFBTSxVQUFFLEdBQUMsd0JBQVksSUFBRyxJQUFJLEtBQUU7O0lBQ2hDLENBQUM7SUFFTSxpQ0FBUSxHQUFmO1FBQ0UsTUFBTSxDQUFDLEVBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsd0JBQVksRUFBQyxDQUFDO0lBQ2hELENBQUM7SUFDSCxxQkFBQztBQUFELENBQUMsQUFoQkQsQ0FBb0MsdUJBQVksR0FnQi9DO0FBaEJZLHdDQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTRUxFQ1RJT05fSUR9IGZyb20gJy4uLy4uL3NlbGVjdGlvbic7XG5pbXBvcnQge1ZnSWRlbnRpZmllclRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtEYXRhRmxvd05vZGV9IGZyb20gJy4vZGF0YWZsb3cnO1xuXG5leHBvcnQgY2xhc3MgSWRlbnRpZmllck5vZGUgZXh0ZW5kcyBEYXRhRmxvd05vZGUge1xuICBwdWJsaWMgY2xvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBJZGVudGlmaWVyTm9kZSgpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBwcm9kdWNlZEZpZWxkcygpIHtcbiAgICByZXR1cm4ge1tTRUxFQ1RJT05fSURdOiB0cnVlfTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZSgpOiBWZ0lkZW50aWZpZXJUcmFuc2Zvcm0ge1xuICAgIHJldHVybiB7dHlwZTogJ2lkZW50aWZpZXInLCBhczogU0VMRUNUSU9OX0lEfTtcbiAgfVxufVxuIl19 \ 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..4c11ee620e --- /dev/null +++ b/build/src/compile/data/index.d.ts @@ -0,0 +1,35 @@ +import { Dict } from '../../util'; +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; + /** + * Parse properties passed down from ancestors. + */ + ancestorParse: Dict; +} diff --git a/build/src/compile/data/index.js b/build/src/compile/data/index.js new file mode 100644 index 0000000000..54180bd5bb --- /dev/null +++ b/build/src/compile/data/index.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RpY3R9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtPdXRwdXROb2RlfSBmcm9tICcuL2RhdGFmbG93JztcbmltcG9ydCB7RmFjZXROb2RlfSBmcm9tICcuL2ZhY2V0JztcbmltcG9ydCB7U291cmNlTm9kZX0gZnJvbSAnLi9zb3VyY2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFDb21wb25lbnQge1xuICAvKipcbiAgICogQSBkaWN0aW9uYXJ5IG9mIHNvdXJjZXMgaW5kZXhlZCBieSBhIGhhc2guXG4gICAqL1xuICBzb3VyY2VzOiBEaWN0PFNvdXJjZU5vZGU+O1xuXG4gIC8qKlxuICAgKiBSZWdpc3RyeSBvZiBvdXRwdXQgbm9kZXMuXG4gICAqL1xuICBvdXRwdXROb2RlczogRGljdDxPdXRwdXROb2RlIHwgRmFjZXROb2RlPjtcblxuICAvKipcbiAgICogSG93IG9mdGVuIGlzIGFuIG91dHB1dCBub2RlIHVzZWQuIElmIGl0IGlzIG5vdCB1c2VkLCB3ZSBkb24ndCBuZWVkIHRvXG4gICAqIGluc3RhbnRpYXRlIGl0IGluIHRoZSBhc3NlbWJsZSBzdGVwLlxuICAgKi9cbiAgb3V0cHV0Tm9kZVJlZkNvdW50czogRGljdDxudW1iZXI+O1xuXG4gIC8qKlxuICAgKiBUaGUgb3V0cHV0IG5vZGUgYmVmb3JlIGFnZ3JlZ2F0aW9uLlxuICAgKi9cbiAgcmF3PzogT3V0cHV0Tm9kZTtcblxuICAvKipcbiAgICogVGhlIG1haW4gb3V0cHV0IG5vZGUuXG4gICAqL1xuICBtYWluPzogT3V0cHV0Tm9kZTtcblxuICAvKipcbiAgICogRm9yIGZhY2V0cywgd2Ugc3RvcmUgdGhlIHJlZmVyZW5jZSB0byB0aGUgcm9vdCBub2RlLlxuICAgKi9cbiAgZmFjZXRSb290PzogRmFjZXROb2RlO1xuXG4gIC8qKlxuICAgKiBQYXJzZSBwcm9wZXJ0aWVzIHBhc3NlZCBkb3duIGZyb20gYW5jZXN0b3JzLlxuICAgKi9cbiAgYW5jZXN0b3JQYXJzZTogRGljdDxzdHJpbmc+O1xufVxuIl19 \ 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..b2b0907000 --- /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(transform: LookupTransform, secondary: string); + static make(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..7508cad5ec --- /dev/null +++ b/build/src/compile/data/lookup.js @@ -0,0 +1,72 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var log = require("../../log"); +var dataflow_1 = require("./dataflow"); +var source_1 = require("./source"); +var LookupNode = /** @class */ (function (_super) { + __extends(LookupNode, _super); + function LookupNode(transform, secondary) { + var _this = _super.call(this) || this; + _this.transform = transform; + _this.secondary = secondary; + return _this; + } + LookupNode.make = function (model, transform, counter) { + var sources = model.component.data.sources; + var s = new source_1.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 dataflow_1.OutputNode(fromOutputName, 'lookup', model.component.data.outputNodeRefCounts); + fromOutputNode.parent = fromSource; + model.component.data.outputNodes[fromOutputName] = fromOutputNode; + return new LookupNode(transform, fromOutputNode.getSource()); + }; + LookupNode.prototype.producedFields = function () { + return vega_util_1.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 (!vega_util_1.isString(asName)) { + log.warn(log.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; +}(dataflow_1.DataFlowNode)); +exports.LookupNode = LookupNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9va3VwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9sb29rdXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBMEM7QUFDMUMsK0JBQWlDO0FBS2pDLHVDQUFvRDtBQUNwRCxtQ0FBb0M7QUFFcEM7SUFBZ0MsOEJBQVk7SUFDMUMsb0JBQTRCLFNBQTBCLEVBQWtCLFNBQWlCO1FBQXpGLFlBQ0UsaUJBQU8sU0FDUjtRQUYyQixlQUFTLEdBQVQsU0FBUyxDQUFpQjtRQUFrQixlQUFTLEdBQVQsU0FBUyxDQUFROztJQUV6RixDQUFDO0lBRWEsZUFBSSxHQUFsQixVQUFtQixLQUFZLEVBQUUsU0FBMEIsRUFBRSxPQUFlO1FBQzFFLElBQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM3QyxJQUFNLENBQUMsR0FBRyxJQUFJLG1CQUFVLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QyxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkMsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ2hCLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEIsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNqQixDQUFDO1FBRUQsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFVLE9BQVMsQ0FBQyxDQUFDO1FBQzFELElBQU0sY0FBYyxHQUFHLElBQUkscUJBQVUsQ0FBQyxjQUFjLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDMUcsY0FBYyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUM7UUFFbkMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxHQUFHLGNBQWMsQ0FBQztRQUVsRSxNQUFNLENBQUMsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFTSxtQ0FBYyxHQUFyQjtRQUNFLE1BQU0sQ0FBQyxpQkFBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9ILENBQUM7SUFFTSw2QkFBUSxHQUFmO1FBQ0UsSUFBSSxPQUFtQyxDQUFDO1FBRXhDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDL0IsbURBQW1EO1lBQ25ELE9BQU8sY0FDTCxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUNwSCxDQUFDO1FBQ0osQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04saUNBQWlDO1lBQ2pDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQy9CLEVBQUUsQ0FBQyxDQUFDLENBQUMsb0JBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUN6QyxNQUFNLEdBQUcsU0FBUyxDQUFDO1lBQ3JCLENBQUM7WUFFRCxPQUFPLEdBQUc7Z0JBQ1IsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDO2FBQ2IsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLFlBQ0osSUFBSSxFQUFFLFFBQVEsRUFDZCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFDcEIsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFDNUIsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFDNUIsT0FBTyxFQUNQLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUNwRTtJQUNKLENBQUM7SUFDSCxpQkFBQztBQUFELENBQUMsQUExREQsQ0FBZ0MsdUJBQVksR0EwRDNDO0FBMURZLGdDQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtpc1N0cmluZywgdG9TZXR9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vbG9nJztcbmltcG9ydCB7TG9va3VwVHJhbnNmb3JtfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0nO1xuaW1wb3J0IHtTdHJpbmdTZXR9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0xvb2t1cFRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtEYXRhRmxvd05vZGUsIE91dHB1dE5vZGV9IGZyb20gJy4vZGF0YWZsb3cnO1xuaW1wb3J0IHtTb3VyY2VOb2RlfSBmcm9tICcuL3NvdXJjZSc7XG5cbmV4cG9ydCBjbGFzcyBMb29rdXBOb2RlIGV4dGVuZHMgRGF0YUZsb3dOb2RlIHtcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHRyYW5zZm9ybTogTG9va3VwVHJhbnNmb3JtLCBwdWJsaWMgcmVhZG9ubHkgc2Vjb25kYXJ5OiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBtYWtlKG1vZGVsOiBNb2RlbCwgdHJhbnNmb3JtOiBMb29rdXBUcmFuc2Zvcm0sIGNvdW50ZXI6IG51bWJlcikge1xuICAgIGNvbnN0IHNvdXJjZXMgPSBtb2RlbC5jb21wb25lbnQuZGF0YS5zb3VyY2VzO1xuICAgIGNvbnN0IHMgPSBuZXcgU291cmNlTm9kZSh0cmFuc2Zvcm0uZnJvbS5kYXRhKTtcbiAgICBsZXQgZnJvbVNvdXJjZSA9IHNvdXJjZXNbcy5oYXNoKCldO1xuICAgIGlmICghZnJvbVNvdXJjZSkge1xuICAgICAgc291cmNlc1tzLmhhc2goKV0gPSBzO1xuICAgICAgZnJvbVNvdXJjZSA9IHM7XG4gICAgfVxuXG4gICAgY29uc3QgZnJvbU91dHB1dE5hbWUgPSBtb2RlbC5nZXROYW1lKGBsb29rdXBfJHtjb3VudGVyfWApO1xuICAgIGNvbnN0IGZyb21PdXRwdXROb2RlID0gbmV3IE91dHB1dE5vZGUoZnJvbU91dHB1dE5hbWUsICdsb29rdXAnLCBtb2RlbC5jb21wb25lbnQuZGF0YS5vdXRwdXROb2RlUmVmQ291bnRzKTtcbiAgICBmcm9tT3V0cHV0Tm9kZS5wYXJlbnQgPSBmcm9tU291cmNlO1xuXG4gICAgbW9kZWwuY29tcG9uZW50LmRhdGEub3V0cHV0Tm9kZXNbZnJvbU91dHB1dE5hbWVdID0gZnJvbU91dHB1dE5vZGU7XG5cbiAgICByZXR1cm4gbmV3IExvb2t1cE5vZGUodHJhbnNmb3JtLCBmcm9tT3V0cHV0Tm9kZS5nZXRTb3VyY2UoKSk7XG4gIH1cblxuICBwdWJsaWMgcHJvZHVjZWRGaWVsZHMoKTogU3RyaW5nU2V0IHtcbiAgICByZXR1cm4gdG9TZXQodGhpcy50cmFuc2Zvcm0uZnJvbS5maWVsZHMgfHwgKCh0aGlzLnRyYW5zZm9ybS5hcyBpbnN0YW5jZW9mIEFycmF5KSA/IHRoaXMudHJhbnNmb3JtLmFzIDogW3RoaXMudHJhbnNmb3JtLmFzXSkpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlKCk6IFZnTG9va3VwVHJhbnNmb3JtIHtcbiAgICBsZXQgZm9yZWlnbjogUGFydGlhbDxWZ0xvb2t1cFRyYW5zZm9ybT47XG5cbiAgICBpZiAodGhpcy50cmFuc2Zvcm0uZnJvbS5maWVsZHMpIHtcbiAgICAgIC8vIGxvb2t1cCBhIGZldyBmaWVsZHMgYW5kIGFkZCBjcmVhdGUgYSBmbGF0IG91dHB1dFxuICAgICAgZm9yZWlnbiA9IHtcbiAgICAgICAgdmFsdWVzOiB0aGlzLnRyYW5zZm9ybS5mcm9tLmZpZWxkcyxcbiAgICAgICAgLi4uIHRoaXMudHJhbnNmb3JtLmFzID8ge2FzOiAoKHRoaXMudHJhbnNmb3JtLmFzIGluc3RhbmNlb2YgQXJyYXkpID8gdGhpcy50cmFuc2Zvcm0uYXMgOiBbdGhpcy50cmFuc2Zvcm0uYXNdKX0gOiB7fVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbG9va3VwIGZ1bGwgcmVjb3JkIGFuZCBuZXN0IGl0XG4gICAgICBsZXQgYXNOYW1lID0gdGhpcy50cmFuc2Zvcm0uYXM7XG4gICAgICBpZiAoIWlzU3RyaW5nKGFzTmFtZSkpIHtcbiAgICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuTk9fRklFTERTX05FRURTX0FTKTtcbiAgICAgICAgYXNOYW1lID0gJ19sb29rdXAnO1xuICAgICAgfVxuXG4gICAgICBmb3JlaWduID0ge1xuICAgICAgICBhczogW2FzTmFtZV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdsb29rdXAnLFxuICAgICAgZnJvbTogdGhpcy5zZWNvbmRhcnksXG4gICAgICBrZXk6IHRoaXMudHJhbnNmb3JtLmZyb20ua2V5LFxuICAgICAgZmllbGRzOiBbdGhpcy50cmFuc2Zvcm0ubG9va3VwXSxcbiAgICAgIC4uLmZvcmVpZ24sXG4gICAgICAuLi4odGhpcy50cmFuc2Zvcm0uZGVmYXVsdCA/IHtkZWZhdWx0OiB0aGlzLnRyYW5zZm9ybS5kZWZhdWx0fSA6IHt9KVxuICAgIH07XG4gIH1cbn1cbiJdfQ== \ 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..145a06e1ca --- /dev/null +++ b/build/src/compile/data/optimize.js @@ -0,0 +1,122 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var aggregate_1 = require("./aggregate"); +var dataflow_1 = require("./dataflow"); +var facet_1 = require("./facet"); +var filterinvalid_1 = require("./filterinvalid"); +var optimizers = require("./optimizers"); +var stack_1 = require("./stack"); +exports.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 facet_1.FacetNode)) { + var copy_1 = node.clone(); + if (copy_1 instanceof dataflow_1.OutputNode) { + var newName = exports.FACET_SCALE_PREFIX + copy_1.getSource(); + copy_1.setSource(newName); + facet.model.component.data.outputNodes[newName] = copy_1; + } + else if (copy_1 instanceof aggregate_1.AggregateNode || copy_1 instanceof stack_1.StackNode) { + copy_1.addDimensions(facet.fields); + } + util_1.flatten(node.children.map(clone)).forEach(function (n) { return n.parent = copy_1; }); + return [copy_1]; + } + return util_1.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 facet_1.FacetNode) { + if (node.numChildren() === 1 && !(node.children[0] instanceof dataflow_1.OutputNode)) { + // move down until we hit a fork or output node + var child = node.children[0]; + if (child instanceof aggregate_1.AggregateNode || child instanceof stack_1.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 = util_1.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 dataflow_1.OutputNode && node.type === data_1.MAIN) { + if (node.numChildren() === 1) { + var child = node.children[0]; + if (!(child instanceof facet_1.FacetNode)) { + child.swapWithParent(); + moveMainDownToFacet(node); + } + } + } +} +/** + * Start optimization path from the root. Useful for removing nodes. + */ +function removeUnnecessaryNodes(node) { + // remove empty null filter nodes + if (node instanceof filterinvalid_1.FilterInvalidNode && util_1.every(util_1.vals(node.filter), function (f) { return f === null; })) { + node.remove(); + } + // remove output nodes that are not required + if (node instanceof dataflow_1.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 = util_1.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); + util_1.keys(dataComponent.sources).forEach(function (s) { + if (dataComponent.sources[s].numChildren() === 0) { + delete dataComponent.sources[s]; + } + }); +} +exports.optimizeDataflow = optimizeDataflow; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW1pemUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL29wdGltaXplLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQWdDO0FBQ2hDLG1DQUFzRDtBQUN0RCx5Q0FBMEM7QUFDMUMsdUNBQW9EO0FBQ3BELGlDQUFrQztBQUNsQyxpREFBa0Q7QUFFbEQseUNBQTJDO0FBRTNDLGlDQUFrQztBQUVyQixRQUFBLGtCQUFrQixHQUFHLFFBQVEsQ0FBQztBQUUzQzs7R0FFRztBQUNILHNCQUFzQixLQUFnQjtJQUNwQyxlQUFlLElBQWtCO1FBQy9CLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLFlBQVksaUJBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqQyxJQUFNLE1BQUksR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFMUIsRUFBRSxDQUFDLENBQUMsTUFBSSxZQUFZLHFCQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUMvQixJQUFNLE9BQU8sR0FBRywwQkFBa0IsR0FBRyxNQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ3RELE1BQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRXhCLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsTUFBSSxDQUFDO1lBQ3pELENBQUM7WUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBSSxZQUFZLHlCQUFhLElBQUksTUFBSSxZQUFZLGlCQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUN0RSxNQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNuQyxDQUFDO1lBQ0QsY0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsQ0FB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QUFDLENBQUMsQ0FBQztJQUN4RixLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLEVBQW5CLENBQW1CLENBQUMsQ0FBQztJQUUvQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztJQUMvRSxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBRTlELEtBQUssQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7SUFFN0IsV0FBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQSxDQUFDO1FBQ25DLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRCxPQUFPLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQXBCRCw0Q0FvQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge01BSU59IGZyb20gJy4uLy4uL2RhdGEnO1xuaW1wb3J0IHtldmVyeSwgZmxhdHRlbiwga2V5cywgdmFsc30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge0FnZ3JlZ2F0ZU5vZGV9IGZyb20gJy4vYWdncmVnYXRlJztcbmltcG9ydCB7RGF0YUZsb3dOb2RlLCBPdXRwdXROb2RlfSBmcm9tICcuL2RhdGFmbG93JztcbmltcG9ydCB7RmFjZXROb2RlfSBmcm9tICcuL2ZhY2V0JztcbmltcG9ydCB7RmlsdGVySW52YWxpZE5vZGV9IGZyb20gJy4vZmlsdGVyaW52YWxpZCc7XG5pbXBvcnQge0RhdGFDb21wb25lbnR9IGZyb20gJy4vaW5kZXgnO1xuaW1wb3J0ICogYXMgb3B0aW1pemVycyBmcm9tICcuL29wdGltaXplcnMnO1xuaW1wb3J0IHtTb3VyY2VOb2RlfSBmcm9tICcuL3NvdXJjZSc7XG5pbXBvcnQge1N0YWNrTm9kZX0gZnJvbSAnLi9zdGFjayc7XG5cbmV4cG9ydCBjb25zdCBGQUNFVF9TQ0FMRV9QUkVGSVggPSAnc2NhbGVfJztcblxuLyoqXG4gKiBDbG9uZXMgdGhlIHN1YnRyZWUgYW5kIGlnbm9yZXMgb3V0cHV0IG5vZGVzIGV4Y2VwdCBmb3IgdGhlIGxlYWZzLCB3aGljaCBhcmUgcmVuYW1lZC5cbiAqL1xuZnVuY3Rpb24gY2xvbmVTdWJ0cmVlKGZhY2V0OiBGYWNldE5vZGUpIHtcbiAgZnVuY3Rpb24gY2xvbmUobm9kZTogRGF0YUZsb3dOb2RlKTogRGF0YUZsb3dOb2RlW10ge1xuICAgIGlmICghKG5vZGUgaW5zdGFuY2VvZiBGYWNldE5vZGUpKSB7XG4gICAgICBjb25zdCBjb3B5ID0gbm9kZS5jbG9uZSgpO1xuXG4gICAgICBpZiAoY29weSBpbnN0YW5jZW9mIE91dHB1dE5vZGUpIHtcbiAgICAgICAgY29uc3QgbmV3TmFtZSA9IEZBQ0VUX1NDQUxFX1BSRUZJWCArIGNvcHkuZ2V0U291cmNlKCk7XG4gICAgICAgIGNvcHkuc2V0U291cmNlKG5ld05hbWUpO1xuXG4gICAgICAgIGZhY2V0Lm1vZGVsLmNvbXBvbmVudC5kYXRhLm91dHB1dE5vZGVzW25ld05hbWVdID0gY29weTtcbiAgICAgIH0gZWxzZSBpZiAoY29weSBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZU5vZGUgfHwgY29weSBpbnN0YW5jZW9mIFN0YWNrTm9kZSkge1xuICAgICAgICBjb3B5LmFkZERpbWVuc2lvbnMoZmFjZXQuZmllbGRzKTtcbiAgICAgIH1cbiAgICAgIGZsYXR0ZW4obm9kZS5jaGlsZHJlbi5tYXAoY2xvbmUpKS5mb3JFYWNoKChuOiBEYXRhRmxvd05vZGUpID0+IG4ucGFyZW50ID0gY29weSk7XG5cbiAgICAgIHJldHVybiBbY29weV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZsYXR0ZW4obm9kZS5jaGlsZHJlbi5tYXAoY2xvbmUpKTtcbiAgfVxuICByZXR1cm4gY2xvbmU7XG59XG5cbi8qKlxuICogTW92ZSBmYWNldCBub2RlcyBkb3duIHRvIHRoZSBuZXh0IGZvcmsgb3Igb3V0cHV0IG5vZGUuIEFsc28gcHVsbCB0aGUgbWFpbiBvdXRwdXQgd2l0aCB0aGUgZmFjZXQgbm9kZS5cbiAqIEFmdGVyIG1vdmluZyBkb3duIHRoZSBmYWNldCBub2RlLCBtYWtlIGEgY29weSBvZiB0aGUgc3VidHJlZSBhbmQgbWFrZSBpdCBhIGNoaWxkIG9mIHRoZSBtYWluIG91dHB1dC5cbiAqL1xuZnVuY3Rpb24gbW92ZUZhY2V0RG93bihub2RlOiBEYXRhRmxvd05vZGUpIHtcbiAgaWYgKG5vZGUgaW5zdGFuY2VvZiBGYWNldE5vZGUpIHtcbiAgICBpZiAobm9kZS5udW1DaGlsZHJlbigpID09PSAxICYmICEobm9kZS5jaGlsZHJlblswXSBpbnN0YW5jZW9mIE91dHB1dE5vZGUpKSB7XG4gICAgICAvLyBtb3ZlIGRvd24gdW50aWwgd2UgaGl0IGEgZm9yayBvciBvdXRwdXQgbm9kZVxuXG4gICAgICBjb25zdCBjaGlsZCA9IG5vZGUuY2hpbGRyZW5bMF07XG5cbiAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZU5vZGUgfHwgY2hpbGQgaW5zdGFuY2VvZiBTdGFja05vZGUpIHtcbiAgICAgICAgY2hpbGQuYWRkRGltZW5zaW9ucyhub2RlLmZpZWxkcyk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkLnN3YXBXaXRoUGFyZW50KCk7XG4gICAgICBtb3ZlRmFjZXREb3duKG5vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBtb3ZlIG1haW4gdG8gZmFjZXRcbiAgICAgIG1vdmVNYWluRG93blRvRmFjZXQobm9kZS5tb2RlbC5jb21wb25lbnQuZGF0YS5tYWluKTtcblxuICAgICAgLy8gcmVwbGljYXRlIHRoZSBzdWJ0cmVlIGFuZCBwbGFjZSBpdCBiZWZvcmUgdGhlIGZhY2V0J3MgbWFpbiBub2RlXG4gICAgICBjb25zdCBjb3B5OiBEYXRhRmxvd05vZGVbXSA9IGZsYXR0ZW4obm9kZS5jaGlsZHJlbi5tYXAoY2xvbmVTdWJ0cmVlKG5vZGUpKSk7XG4gICAgICBjb3B5LmZvckVhY2goYyA9PiBjLnBhcmVudCA9IG5vZGUubW9kZWwuY29tcG9uZW50LmRhdGEubWFpbik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG5vZGUuY2hpbGRyZW4uZm9yRWFjaChtb3ZlRmFjZXREb3duKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb3ZlTWFpbkRvd25Ub0ZhY2V0KG5vZGU6IERhdGFGbG93Tm9kZSkge1xuICBpZiAobm9kZSBpbnN0YW5jZW9mIE91dHB1dE5vZGUgJiYgbm9kZS50eXBlID09PSBNQUlOKSB7XG4gICAgaWYgKG5vZGUubnVtQ2hpbGRyZW4oKSA9PT0gMSkge1xuICAgICAgY29uc3QgY2hpbGQgPSBub2RlLmNoaWxkcmVuWzBdO1xuXG4gICAgICBpZiAoIShjaGlsZCBpbnN0YW5jZW9mIEZhY2V0Tm9kZSkpIHtcbiAgICAgICAgY2hpbGQuc3dhcFdpdGhQYXJlbnQoKTtcbiAgICAgICAgbW92ZU1haW5Eb3duVG9GYWNldChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTdGFydCBvcHRpbWl6YXRpb24gcGF0aCBmcm9tIHRoZSByb290LiBVc2VmdWwgZm9yIHJlbW92aW5nIG5vZGVzLlxuICovXG5mdW5jdGlvbiByZW1vdmVVbm5lY2Vzc2FyeU5vZGVzKG5vZGU6IERhdGFGbG93Tm9kZSkge1xuXG4gIC8vIHJlbW92ZSBlbXB0eSBudWxsIGZpbHRlciBub2Rlc1xuICBpZiAobm9kZSBpbnN0YW5jZW9mIEZpbHRlckludmFsaWROb2RlICYmIGV2ZXJ5KHZhbHMobm9kZS5maWx0ZXIpLCBmID0+IGYgPT09IG51bGwpKSB7XG4gICAgbm9kZS5yZW1vdmUoKTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBvdXRwdXQgbm9kZXMgdGhhdCBhcmUgbm90IHJlcXVpcmVkXG4gIGlmIChub2RlIGluc3RhbmNlb2YgT3V0cHV0Tm9kZSAmJiAhbm9kZS5pc1JlcXVpcmVkKCkpIHtcbiAgICBub2RlLnJlbW92ZSgpO1xuICB9XG5cbiAgbm9kZS5jaGlsZHJlbi5mb3JFYWNoKHJlbW92ZVVubmVjZXNzYXJ5Tm9kZXMpO1xufVxuXG4vKipcbiAqIFJldHVybiBhbGwgbGVhZiBub2Rlcy5cbiAqL1xuZnVuY3Rpb24gZ2V0TGVhdmVzKHJvb3RzOiBEYXRhRmxvd05vZGVbXSkge1xuICBjb25zdCBsZWF2ZXM6IERhdGFGbG93Tm9kZVtdID0gW107XG4gIGZ1bmN0aW9uIGFwcGVuZChub2RlOiBEYXRhRmxvd05vZGUpIHtcbiAgICBpZiAobm9kZS5udW1DaGlsZHJlbigpID09PSAwKSB7XG4gICAgICBsZWF2ZXMucHVzaChub2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5jaGlsZHJlbi5mb3JFYWNoKGFwcGVuZCk7XG4gICAgfVxuICB9XG5cbiAgcm9vdHMuZm9yRWFjaChhcHBlbmQpO1xuICByZXR1cm4gbGVhdmVzO1xufVxuXG4vKipcbiAqIE9wdGltaXplcyB0aGUgZGF0YWZsb3cgb2YgdGhlIHBhc3NlZCBpbiBkYXRhIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wdGltaXplRGF0YWZsb3coZGF0YUNvbXBvbmVudDogRGF0YUNvbXBvbmVudCkge1xuICBsZXQgcm9vdHM6IFNvdXJjZU5vZGVbXSA9IHZhbHMoZGF0YUNvbXBvbmVudC5zb3VyY2VzKTtcblxuICByb290cy5mb3JFYWNoKHJlbW92ZVVubmVjZXNzYXJ5Tm9kZXMpO1xuXG4gIC8vIHJlbW92ZSBzb3VyY2Ugbm9kZXMgdGhhdCBkb24ndCBoYXZlIGFueSBjaGlsZHJlbiBiZWNhdXNlIHRoZXkgYWxzbyBkb24ndCBoYXZlIG91dHB1dCBub2Rlc1xuICByb290cyA9IHJvb3RzLmZpbHRlcihyID0+IHIubnVtQ2hpbGRyZW4oKSA+IDApO1xuICBnZXRMZWF2ZXMocm9vdHMpLmZvckVhY2gob3B0aW1pemVycy5pdGVyYXRlRnJvbUxlYXZlcyhvcHRpbWl6ZXJzLnJlbW92ZVVudXNlZFN1YnRyZWVzKSk7XG4gIHJvb3RzID0gcm9vdHMuZmlsdGVyKHIgPT4gci5udW1DaGlsZHJlbigpID4gMCk7XG5cbiAgZ2V0TGVhdmVzKHJvb3RzKS5mb3JFYWNoKG9wdGltaXplcnMuaXRlcmF0ZUZyb21MZWF2ZXMob3B0aW1pemVycy5tb3ZlUGFyc2VVcCkpO1xuICBnZXRMZWF2ZXMocm9vdHMpLmZvckVhY2gob3B0aW1pemVycy5yZW1vdmVEdXBsaWNhdGVUaW1lVW5pdHMpO1xuXG4gIHJvb3RzLmZvckVhY2gobW92ZUZhY2V0RG93bik7XG5cbiAga2V5cyhkYXRhQ29tcG9uZW50LnNvdXJjZXMpLmZvckVhY2gocyA9PiB7XG4gICAgaWYgKGRhdGFDb21wb25lbnQuc291cmNlc1tzXS5udW1DaGlsZHJlbigpID09PSAwKSB7XG4gICAgICBkZWxldGUgZGF0YUNvbXBvbmVudC5zb3VyY2VzW3NdO1xuICAgIH1cbiAgfSk7XG59XG4iXX0= \ 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..9357fc5996 --- /dev/null +++ b/build/src/compile/data/optimizers.d.ts @@ -0,0 +1,22 @@ +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 nodes. + * The reason is that we don't need subtrees that don't have any output nodes. + */ +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..f89457156f --- /dev/null +++ b/build/src/compile/data/optimizers.js @@ -0,0 +1,99 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var formatparse_1 = require("./formatparse"); +var source_1 = require("./source"); +var timeunit_1 = require("./timeunit"); +/** + * 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 source_1.SourceNode) { + return; + } + var next = node.parent; + if (f(node)) { + optimizeNextFromLeaves(next); + } + } + return optimizeNextFromLeaves; +} +exports.iterateFromLeaves = iterateFromLeaves; +/** + * Move parse nodes up to forks. + */ +function moveParseUp(node) { + var parent = node.parent; + // move parse up by merging or swapping + if (node instanceof formatparse_1.ParseNode) { + if (parent instanceof source_1.SourceNode) { + return false; + } + if (parent.numChildren() > 1) { + // don't move parse further up but continue with parent. + return true; + } + if (parent instanceof formatparse_1.ParseNode) { + parent.merge(node); + } + else { + // don't swap with nodes that produce something that the parse node depends on (e.g. lookup) + if (util_1.hasIntersection(parent.producedFields(), node.dependentFields())) { + return true; + } + node.swapWithParent(); + } + } + return true; +} +exports.moveParseUp = moveParseUp; +/** + * Repeatedly remove leaf nodes that are not output nodes. + * The reason is that we don't need subtrees that don't have any output nodes. + */ +function removeUnusedSubtrees(node) { + if (node instanceof dataflow_1.OutputNode || node.numChildren() > 0) { + // 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; +} +exports.removeUnusedSubtrees = removeUnusedSubtrees; +/** + * 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 timeunit_1.TimeUnitNode) { + var pfields = node.producedFields(); + var dupe = util_1.keys(pfields).every(function (k) { return !!fields[k]; }); + if (dupe) { + node.remove(); + } + else { + fields = __assign({}, fields, pfields); + } + } + return true; + })(leaf); +} +exports.removeDuplicateTimeUnits = removeDuplicateTimeUnits; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW1pemVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvb3B0aW1pemVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsbUNBQWlEO0FBQ2pELHVDQUFvRDtBQUNwRCw2Q0FBd0M7QUFDeEMsbUNBQW9DO0FBQ3BDLHVDQUF3QztBQUd4Qzs7OztHQUlHO0FBQ0gsMkJBQWtDLENBQWtDO0lBQ2xFLGdDQUFnQyxJQUFrQjtRQUNoRCxFQUFFLENBQUMsQ0FBQyxJQUFJLFlBQVksbUJBQVUsQ0FBQyxDQUFDLENBQUM7WUFDL0IsTUFBTSxDQUFDO1FBQ1QsQ0FBQztRQUVELElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNaLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLHNCQUFzQixDQUFDO0FBQ2hDLENBQUM7QUFiRCw4Q0FhQztBQUVEOztHQUVHO0FBQ0gscUJBQTRCLElBQWtCO0lBQzVDLElBQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFFM0IsdUNBQXVDO0lBQ3ZDLEVBQUUsQ0FBQyxDQUFDLElBQUksWUFBWSx1QkFBUyxDQUFDLENBQUMsQ0FBQztRQUM5QixFQUFFLENBQUMsQ0FBQyxNQUFNLFlBQVksbUJBQVUsQ0FBQyxDQUFDLENBQUM7WUFDakMsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3Qix3REFBd0Q7WUFDeEQsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxFQUFFLENBQUMsQ0FBQyxNQUFNLFlBQVksdUJBQVMsQ0FBQyxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTiw0RkFBNEY7WUFDNUYsRUFBRSxDQUFDLENBQUMsc0JBQWUsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNyRSxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBM0JELGtDQTJCQztBQUVEOzs7R0FHRztBQUNILDhCQUFxQyxJQUFrQjtJQUNyRCxFQUFFLENBQUMsQ0FBQyxJQUFJLFlBQVkscUJBQVUsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6RCxxR0FBcUc7UUFDckcsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUNmLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQztBQUNkLENBQUM7QUFSRCxvREFRQztBQUVEOzs7O0dBSUc7QUFDSCxrQ0FBeUMsSUFBa0I7SUFDekQsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ2hCLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxVQUFDLElBQWtCO1FBQzFDLEVBQUUsQ0FBQyxDQUFDLElBQUksWUFBWSx1QkFBWSxDQUFDLENBQUMsQ0FBQztZQUNqQyxJQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEMsSUFBTSxJQUFJLEdBQUcsV0FBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQVgsQ0FBVyxDQUFDLENBQUM7WUFFckQsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDVCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEIsQ0FBQztZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNOLE1BQU0sZ0JBQU8sTUFBTSxFQUFLLE9BQU8sQ0FBQyxDQUFDO1lBQ25DLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQWhCRCw0REFnQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhc0ludGVyc2VjdGlvbiwga2V5c30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZSwgT3V0cHV0Tm9kZX0gZnJvbSAnLi9kYXRhZmxvdyc7XG5pbXBvcnQge1BhcnNlTm9kZX0gZnJvbSAnLi9mb3JtYXRwYXJzZSc7XG5pbXBvcnQge1NvdXJjZU5vZGV9IGZyb20gJy4vc291cmNlJztcbmltcG9ydCB7VGltZVVuaXROb2RlfSBmcm9tICcuL3RpbWV1bml0JztcblxuXG4vKipcbiAqIFN0YXJ0IG9wdGltaXphdGlvbiBwYXRoIGF0IHRoZSBsZWF2ZXMuIFVzZWZ1bCBmb3IgbWVyZ2luZyB1cCBvciByZW1vdmluZyB0aGluZ3MuXG4gKlxuICogSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgdHJ1ZSwgdGhlIHJlY3Vyc2lvbiBjb250aW51ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpdGVyYXRlRnJvbUxlYXZlcyhmOiAobm9kZTogRGF0YUZsb3dOb2RlKSA9PiBib29sZWFuKSB7XG4gIGZ1bmN0aW9uIG9wdGltaXplTmV4dEZyb21MZWF2ZXMobm9kZTogRGF0YUZsb3dOb2RlKSB7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBTb3VyY2VOb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbmV4dCA9IG5vZGUucGFyZW50O1xuICAgIGlmIChmKG5vZGUpKSB7XG4gICAgICBvcHRpbWl6ZU5leHRGcm9tTGVhdmVzKG5leHQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcHRpbWl6ZU5leHRGcm9tTGVhdmVzO1xufVxuXG4vKipcbiAqIE1vdmUgcGFyc2Ugbm9kZXMgdXAgdG8gZm9ya3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlUGFyc2VVcChub2RlOiBEYXRhRmxvd05vZGUpIHtcbiAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG5cbiAgLy8gbW92ZSBwYXJzZSB1cCBieSBtZXJnaW5nIG9yIHN3YXBwaW5nXG4gIGlmIChub2RlIGluc3RhbmNlb2YgUGFyc2VOb2RlKSB7XG4gICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFNvdXJjZU5vZGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocGFyZW50Lm51bUNoaWxkcmVuKCkgPiAxKSB7XG4gICAgICAvLyBkb24ndCBtb3ZlIHBhcnNlIGZ1cnRoZXIgdXAgYnV0IGNvbnRpbnVlIHdpdGggcGFyZW50LlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFBhcnNlTm9kZSkge1xuICAgICAgcGFyZW50Lm1lcmdlKG5vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBkb24ndCBzd2FwIHdpdGggbm9kZXMgdGhhdCBwcm9kdWNlIHNvbWV0aGluZyB0aGF0IHRoZSBwYXJzZSBub2RlIGRlcGVuZHMgb24gKGUuZy4gbG9va3VwKVxuICAgICAgaWYgKGhhc0ludGVyc2VjdGlvbihwYXJlbnQucHJvZHVjZWRGaWVsZHMoKSwgbm9kZS5kZXBlbmRlbnRGaWVsZHMoKSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIG5vZGUuc3dhcFdpdGhQYXJlbnQoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXBlYXRlZGx5IHJlbW92ZSBsZWFmIG5vZGVzIHRoYXQgYXJlIG5vdCBvdXRwdXQgbm9kZXMuXG4gKiBUaGUgcmVhc29uIGlzIHRoYXQgd2UgZG9uJ3QgbmVlZCBzdWJ0cmVlcyB0aGF0IGRvbid0IGhhdmUgYW55IG91dHB1dCBub2Rlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVVudXNlZFN1YnRyZWVzKG5vZGU6IERhdGFGbG93Tm9kZSkge1xuICBpZiAobm9kZSBpbnN0YW5jZW9mIE91dHB1dE5vZGUgfHwgbm9kZS5udW1DaGlsZHJlbigpID4gMCkge1xuICAgIC8vIG5vIG5lZWQgdG8gY29udGludWUgd2l0aCBwYXJlbnQgYmVjYXVzZSBpdCBpcyBvdXRwdXQgbm9kZSBvciB3aWxsIGhhdmUgY2hpbGRyZW4gKHRoZXJlIHdhcyBhIGZvcmspXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIG5vZGUucmVtb3ZlKCk7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogUmVtb3ZlcyBkdXBsaWNhdGUgdGltZSB1bml0IG5vZGVzIChhcyBkZXRlcm1pbmVkIGJ5IHRoZSBuYW1lIG9mIHRoZVxuICogb3V0cHV0IGZpZWxkKSB0aGF0IG1heSBiZSBnZW5lcmF0ZWQgZHVlIHRvIHNlbGVjdGlvbnMgcHJvamVjdGVkIG92ZXJcbiAqIHRpbWUgdW5pdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVEdXBsaWNhdGVUaW1lVW5pdHMobGVhZjogRGF0YUZsb3dOb2RlKSB7XG4gIGxldCBmaWVsZHMgPSB7fTtcbiAgcmV0dXJuIGl0ZXJhdGVGcm9tTGVhdmVzKChub2RlOiBEYXRhRmxvd05vZGUpID0+IHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFRpbWVVbml0Tm9kZSkge1xuICAgICAgY29uc3QgcGZpZWxkcyA9IG5vZGUucHJvZHVjZWRGaWVsZHMoKTtcbiAgICAgIGNvbnN0IGR1cGUgPSBrZXlzKHBmaWVsZHMpLmV2ZXJ5KChrKSA9PiAhIWZpZWxkc1trXSk7XG5cbiAgICAgIGlmIChkdXBlKSB7XG4gICAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmaWVsZHMgPSB7Li4uZmllbGRzLCAuLi5wZmllbGRzfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSkobGVhZik7XG59XG4iXX0= \ 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..a26446780d --- /dev/null +++ b/build/src/compile/data/parse.d.ts @@ -0,0 +1,11 @@ +import { Model } from '../model'; +import { DataFlowNode } from './dataflow'; +import { DataComponent } from './index'; +/** + * Parses a transforms array into a chain of connected dataflow nodes. + */ +export declare function parseTransformArray(model: Model): { + first: DataFlowNode; + last: 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..d430fb9fa1 --- /dev/null +++ b/build/src/compile/data/parse.js @@ -0,0 +1,296 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var data_1 = require("../../data"); +var datetime_1 = require("../../datetime"); +var filter_1 = require("../../filter"); +var log = require("../../log"); +var transform_1 = require("../../transform"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var selection_1 = require("../selection/selection"); +var aggregate_1 = require("./aggregate"); +var bin_1 = require("./bin"); +var calculate_1 = require("./calculate"); +var dataflow_1 = require("./dataflow"); +var facet_1 = require("./facet"); +var filter_2 = require("./filter"); +var filterinvalid_1 = require("./filterinvalid"); +var formatparse_1 = require("./formatparse"); +var indentifier_1 = require("./indentifier"); +var lookup_1 = require("./lookup"); +var source_1 = require("./source"); +var stack_1 = require("./stack"); +var timeunit_1 = require("./timeunit"); +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 source_1.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. + */ +function parseTransformArray(model) { + var first = null; + var node; + var previous; + var lookupCounter = 0; + function insert(newNode) { + if (!first) { + // A parent may be inserted during node construction + // (e.g., selection FilterNodes may add a TimeUnitNode). + first = newNode.parent || newNode; + } + else if (newNode.parent) { + previous.insertAsParentOf(newNode); + } + else { + newNode.parent = previous; + } + previous = newNode; + } + model.transforms.forEach(function (t) { + if (transform_1.isCalculate(t)) { + node = new calculate_1.CalculateNode(t); + } + else if (transform_1.isFilter(t)) { + // Automatically add a parse node for filters with filter objects + var parse = {}; + var filter = t.filter; + 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 (filter_1.isEqualFilter(filter)) { + val = filter.equal; + } + else if (filter_1.isRangeFilter(filter)) { + val = filter.range[0]; + } + else if (filter_1.isOneOfFilter(filter)) { + val = (filter.oneOf || filter['in'])[0]; + } // else -- for filter expression, we can't infer anything + if (val) { + if (datetime_1.isDateTime(val)) { + parse[filter['field']] = 'date'; + } + else if (vega_util_1.isNumber(val)) { + parse[filter['field']] = 'number'; + } + else if (vega_util_1.isString(val)) { + parse[filter['field']] = 'string'; + } + } + if (util_1.keys(parse).length > 0) { + var parseNode = new formatparse_1.ParseNode(parse); + insert(parseNode); + } + node = new filter_2.FilterNode(model, t.filter); + } + else if (transform_1.isBin(t)) { + node = bin_1.BinNode.makeFromTransform(t, { model: model }); + } + else if (transform_1.isTimeUnit(t)) { + node = timeunit_1.TimeUnitNode.makeFromTransform(t); + } + else if (transform_1.isAggregate(t)) { + node = aggregate_1.AggregateNode.makeFromTransform(t); + if (selection_1.requiresSelectionId(model)) { + insert(node); + node = new indentifier_1.IdentifierNode(); + } + } + else if (transform_1.isLookup(t)) { + node = lookup_1.LookupNode.make(model, t, lookupCounter++); + } + else { + log.warn(log.message.invalidTransformIgnored(t)); + return; + } + insert(node); + }); + var last = node; + return { first: first, last: last }; +} +exports.parseTransformArray = parseTransformArray; +/* +Description of the dataflow (http://asciiflow.com/): + +--------+ + | Source | + +---+----+ + | + v + Transforms +(Filter, Calculate, ...) + | + v + FormatParse + | + v + Binning + | + v + Timeunit + | + v + +--+--+ + | Raw | + +-----+ + | + v + Aggregate + | + v + Stack + | + v + Path Order + | + v + Invalid Filter + | + v + +----------+ + | Main | + +----------+ + | + v + +-------+ + | Facet |----> "column", "column-layout", and "row" + +-------+ + | + v + ...Child data... +*/ +function parseData(model) { + var root = parseRoot(model, model.component.data.sources); + var outputNodes = model.component.data.outputNodes; + var outputNodeRefCounts = model.component.data.outputNodeRefCounts; + // the current head of the tree that we are appending to + var head = root; + // 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 (selection_1.requiresSelectionId(model) && !model.parent) { + var ident = new indentifier_1.IdentifierNode(); + ident.parent = head; + head = ident; + } + // 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 && model_1.isLayerModel(model.parent); + if (model_1.isUnitModel(model) || model_1.isFacetModel(model)) { + if (parentIsLayer) { + var bin = bin_1.BinNode.makeBinFromEncoding(model); + if (bin) { + bin.parent = head; + head = bin; + } + } + } + if (model.transforms.length > 0) { + var _a = parseTransformArray(model), first = _a.first, last = _a.last; + first.parent = head; + head = last; + } + var parse = formatparse_1.ParseNode.make(model); + if (parse) { + parse.parent = head; + head = parse; + } + if (model_1.isUnitModel(model) || model_1.isFacetModel(model)) { + if (!parentIsLayer) { + var bin = bin_1.BinNode.makeBinFromEncoding(model); + if (bin) { + bin.parent = head; + head = bin; + } + } + var tu = timeunit_1.TimeUnitNode.makeFromEncoding(model); + if (tu) { + tu.parent = head; + head = tu; + } + } + // add an output node pre aggregation + var rawName = model.getName(data_1.RAW); + var raw = new dataflow_1.OutputNode(rawName, data_1.RAW, outputNodeRefCounts); + outputNodes[rawName] = raw; + raw.parent = head; + head = raw; + if (model_1.isUnitModel(model)) { + var agg = aggregate_1.AggregateNode.makeFromEncoding(model); + if (agg) { + agg.parent = head; + head = agg; + if (selection_1.requiresSelectionId(model)) { + var ident = new indentifier_1.IdentifierNode(); + ident.parent = head; + head = ident; + } + } + var stack = stack_1.StackNode.make(model); + if (stack) { + stack.parent = head; + head = stack; + } + } + if (model_1.isUnitModel(model)) { + var filter = filterinvalid_1.FilterInvalidNode.make(model); + if (filter) { + filter.parent = head; + head = filter; + } + } + // output node for marks + var mainName = model.getName(data_1.MAIN); + var main = new dataflow_1.OutputNode(mainName, data_1.MAIN, outputNodeRefCounts); + outputNodes[mainName] = main; + main.parent = head; + head = main; + // add facet marker + var facetRoot = null; + if (model_1.isFacetModel(model)) { + var facetName = model.getName('facet'); + facetRoot = new facet_1.FacetNode(model, facetName, main.getSource()); + outputNodes[facetName] = facetRoot; + facetRoot.parent = head; + head = facetRoot; + } + // add the format parse from this model so that children don't parse the same field again + var ancestorParse = __assign({}, model.component.data.ancestorParse, (parse ? parse.parse : {})); + return __assign({}, model.component.data, { outputNodes: outputNodes, + outputNodeRefCounts: outputNodeRefCounts, + raw: raw, + main: main, + facetRoot: facetRoot, + ancestorParse: ancestorParse }); +} +exports.parseData = parseData; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3BhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSx1Q0FBNkM7QUFDN0MsbUNBQXFDO0FBQ3JDLDJDQUFvRDtBQUNwRCx1Q0FBeUU7QUFDekUsK0JBQWlDO0FBQ2pDLDZDQUFnRztBQUNoRyxtQ0FBc0M7QUFDdEMsa0NBQXdFO0FBQ3hFLG9EQUEyRDtBQUMzRCx5Q0FBMEM7QUFDMUMsNkJBQThCO0FBQzlCLHlDQUEwQztBQUMxQyx1Q0FBb0Q7QUFDcEQsaUNBQWtDO0FBQ2xDLG1DQUFvQztBQUNwQyxpREFBa0Q7QUFDbEQsNkNBQXdDO0FBQ3hDLDZDQUE2QztBQUU3QyxtQ0FBb0M7QUFDcEMsbUNBQW9DO0FBQ3BDLGlDQUFrQztBQUNsQyx1Q0FBd0M7QUFFeEMsbUJBQW1CLEtBQVksRUFBRSxPQUF5QjtJQUN4RCxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDaEMsMEVBQTBFO1FBQzFFLElBQU0sTUFBTSxHQUFHLElBQUksbUJBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsSUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNCLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLDhDQUE4QztZQUM5QyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLDBCQUEwQjtZQUMxQixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDO1lBQ3ZCLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDaEIsQ0FBQztJQUNILENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztR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SUFBSSxDQUFDO0lBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ25CLElBQUksR0FBRyxJQUFJLENBQUM7SUFFWixtQkFBbUI7SUFDbkIsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLEVBQUUsQ0FBQyxDQUFDLG9CQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLElBQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDekMsU0FBUyxHQUFHLElBQUksaUJBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzlELFdBQVcsQ0FBQyxTQUFTLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDbkMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxHQUFHLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQseUZBQXlGO0lBQ3pGLElBQU0sYUFBYSxnQkFBTyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFN0YsTUFBTSxjQUNELEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUN2QixXQUFXLGFBQUE7UUFDWCxtQkFBbUIscUJBQUE7UUFDbkIsR0FBRyxLQUFBO1FBQ0gsSUFBSSxNQUFBO1FBQ0osU0FBUyxXQUFBO1FBQ1QsYUFBYSxlQUFBLElBQ2I7QUFDSixDQUFDO0FBL0hELDhCQStIQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aXNOdW1iZXIsIGlzU3RyaW5nfSBmcm9tICd2ZWdhLXV0aWwnO1xuaW1wb3J0IHtNQUlOLCBSQVd9IGZyb20gJy4uLy4uL2RhdGEnO1xuaW1wb3J0IHtEYXRlVGltZSwgaXNEYXRlVGltZX0gZnJvbSAnLi4vLi4vZGF0ZXRpbWUnO1xuaW1wb3J0IHtpc0VxdWFsRmlsdGVyLCBpc09uZU9mRmlsdGVyLCBpc1JhbmdlRmlsdGVyfSBmcm9tICcuLi8uLi9maWx0ZXInO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge2lzQWdncmVnYXRlLCBpc0JpbiwgaXNDYWxjdWxhdGUsIGlzRmlsdGVyLCBpc0xvb2t1cCwgaXNUaW1lVW5pdH0gZnJvbSAnLi4vLi4vdHJhbnNmb3JtJztcbmltcG9ydCB7RGljdCwga2V5c30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge2lzRmFjZXRNb2RlbCwgaXNMYXllck1vZGVsLCBpc1VuaXRNb2RlbCwgTW9kZWx9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7cmVxdWlyZXNTZWxlY3Rpb25JZH0gZnJvbSAnLi4vc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge0FnZ3JlZ2F0ZU5vZGV9IGZyb20gJy4vYWdncmVnYXRlJztcbmltcG9ydCB7QmluTm9kZX0gZnJvbSAnLi9iaW4nO1xuaW1wb3J0IHtDYWxjdWxhdGVOb2RlfSBmcm9tICcuL2NhbGN1bGF0ZSc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZSwgT3V0cHV0Tm9kZX0gZnJvbSAnLi9kYXRhZmxvdyc7XG5pbXBvcnQge0ZhY2V0Tm9kZX0gZnJvbSAnLi9mYWNldCc7XG5pbXBvcnQge0ZpbHRlck5vZGV9IGZyb20gJy4vZmlsdGVyJztcbmltcG9ydCB7RmlsdGVySW52YWxpZE5vZGV9IGZyb20gJy4vZmlsdGVyaW52YWxpZCc7XG5pbXBvcnQge1BhcnNlTm9kZX0gZnJvbSAnLi9mb3JtYXRwYXJzZSc7XG5pbXBvcnQge0lkZW50aWZpZXJOb2RlfSBmcm9tICcuL2luZGVudGlmaWVyJztcbmltcG9ydCB7RGF0YUNvbXBvbmVudH0gZnJvbSAnLi9pbmRleCc7XG5pbXBvcnQge0xvb2t1cE5vZGV9IGZyb20gJy4vbG9va3VwJztcbmltcG9ydCB7U291cmNlTm9kZX0gZnJvbSAnLi9zb3VyY2UnO1xuaW1wb3J0IHtTdGFja05vZGV9IGZyb20gJy4vc3RhY2snO1xuaW1wb3J0IHtUaW1lVW5pdE5vZGV9IGZyb20gJy4vdGltZXVuaXQnO1xuXG5mdW5jdGlvbiBwYXJzZVJvb3QobW9kZWw6IE1vZGVsLCBzb3VyY2VzOiBEaWN0PFNvdXJjZU5vZGU+KTogRGF0YUZsb3dOb2RlIHtcbiAgaWYgKG1vZGVsLmRhdGEgfHwgIW1vZGVsLnBhcmVudCkge1xuICAgIC8vIGlmIHRoZSBtb2RlbCBkZWZpbmVzIGEgZGF0YSBzb3VyY2Ugb3IgaXMgdGhlIHJvb3QsIGNyZWF0ZSBhIHNvdXJjZSBub2RlXG4gICAgY29uc3Qgc291cmNlID0gbmV3IFNvdXJjZU5vZGUobW9kZWwuZGF0YSk7XG4gICAgY29uc3QgaGFzaCA9IHNvdXJjZS5oYXNoKCk7XG4gICAgaWYgKGhhc2ggaW4gc291cmNlcykge1xuICAgICAgLy8gdXNlIGEgcmVmZXJlbmNlIGlmIHdlIGFscmVhZHkgaGF2ZSBhIHNvdXJjZVxuICAgICAgcmV0dXJuIHNvdXJjZXNbaGFzaF07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG90aGVyd2lzZSBhZGQgYSBuZXcgb25lXG4gICAgICBzb3VyY2VzW2hhc2hdID0gc291cmNlO1xuICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhIHNvdXJjZSBkZWZpbmVkIChvdmVycmlkaW5nIHBhcmVudCdzIGRhdGEpLCB1c2UgdGhlIHBhcmVudCdzIGZhY2V0IHJvb3Qgb3IgbWFpbi5cbiAgICByZXR1cm4gbW9kZWwucGFyZW50LmNvbXBvbmVudC5kYXRhLmZhY2V0Um9vdCA/IG1vZGVsLnBhcmVudC5jb21wb25lbnQuZGF0YS5mYWNldFJvb3QgOiBtb2RlbC5wYXJlbnQuY29tcG9uZW50LmRhdGEubWFpbjtcbiAgfVxufVxuXG5cbi8qKlxuICogUGFyc2VzIGEgdHJhbnNmb3JtcyBhcnJheSBpbnRvIGEgY2hhaW4gb2YgY29ubmVjdGVkIGRhdGFmbG93IG5vZGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUcmFuc2Zvcm1BcnJheShtb2RlbDogTW9kZWwpIHtcbiAgbGV0IGZpcnN0OiBEYXRhRmxvd05vZGUgPSBudWxsO1xuICBsZXQgbm9kZTogRGF0YUZsb3dOb2RlO1xuICBsZXQgcHJldmlvdXM6IERhdGFGbG93Tm9kZTtcbiAgbGV0IGxvb2t1cENvdW50ZXIgPSAwO1xuXG4gIGZ1bmN0aW9uIGluc2VydChuZXdOb2RlOiBEYXRhRmxvd05vZGUpIHtcbiAgICBpZiAoIWZpcnN0KSB7XG4gICAgICAvLyBBIHBhcmVudCBtYXkgYmUgaW5zZXJ0ZWQgZHVyaW5nIG5vZGUgY29uc3RydWN0aW9uXG4gICAgICAvLyAoZS5nLiwgc2VsZWN0aW9uIEZpbHRlck5vZGVzIG1heSBhZGQgYSBUaW1lVW5pdE5vZGUpLlxuICAgICAgZmlyc3QgPSBuZXdOb2RlLnBhcmVudCB8fCBuZXdOb2RlO1xuICAgIH0gZWxzZSBpZiAobmV3Tm9kZS5wYXJlbnQpIHtcbiAgICAgIHByZXZpb3VzLmluc2VydEFzUGFyZW50T2YobmV3Tm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld05vZGUucGFyZW50ID0gcHJldmlvdXM7XG4gICAgfVxuXG4gICAgcHJldmlvdXMgPSBuZXdOb2RlO1xuICB9XG5cbiAgbW9kZWwudHJhbnNmb3Jtcy5mb3JFYWNoKHQgPT4ge1xuICAgIGlmIChpc0NhbGN1bGF0ZSh0KSkge1xuICAgICAgbm9kZSA9IG5ldyBDYWxjdWxhdGVOb2RlKHQpO1xuICAgIH0gZWxzZSBpZiAoaXNGaWx0ZXIodCkpIHtcbiAgICAgIC8vIEF1dG9tYXRpY2FsbHkgYWRkIGEgcGFyc2Ugbm9kZSBmb3IgZmlsdGVycyB3aXRoIGZpbHRlciBvYmplY3RzXG4gICAgICBjb25zdCBwYXJzZSA9IHt9O1xuICAgICAgY29uc3QgZmlsdGVyID0gdC5maWx0ZXI7XG4gICAgICBsZXQgdmFsOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgRGF0ZVRpbWUgPSBudWxsO1xuICAgICAgLy8gRm9yIEVxdWFsRmlsdGVyLCBqdXN0IHVzZSB0aGUgZXF1YWwgcHJvcGVydHkuXG4gICAgICAvLyBGb3IgUmFuZ2VGaWx0ZXIgYW5kIE9uZU9mRmlsdGVyLCBhbGwgYXJyYXkgbWVtYmVycyBzaG91bGQgaGF2ZVxuICAgICAgLy8gdGhlIHNhbWUgdHlwZSwgc28gd2Ugb25seSB1c2UgdGhlIGZpcnN0IG9uZS5cbiAgICAgIGlmIChpc0VxdWFsRmlsdGVyKGZpbHRlcikpIHtcbiAgICAgICAgdmFsID0gZmlsdGVyLmVxdWFsO1xuICAgICAgfSBlbHNlIGlmIChpc1JhbmdlRmlsdGVyKGZpbHRlcikpIHtcbiAgICAgICAgdmFsID0gZmlsdGVyLnJhbmdlWzBdO1xuICAgICAgfSBlbHNlIGlmIChpc09uZU9mRmlsdGVyKGZpbHRlcikpIHtcbiAgICAgICAgdmFsID0gKGZpbHRlci5vbmVPZiB8fCBmaWx0ZXJbJ2luJ10pWzBdO1xuICAgICAgfSAvLyBlbHNlIC0tIGZvciBmaWx0ZXIgZXhwcmVzc2lvbiwgd2UgY2FuJ3QgaW5mZXIgYW55dGhpbmdcblxuICAgICAgaWYgKHZhbCkge1xuICAgICAgICBpZiAoaXNEYXRlVGltZSh2YWwpKSB7XG4gICAgICAgICAgcGFyc2VbZmlsdGVyWydmaWVsZCddXSA9ICdkYXRlJztcbiAgICAgICAgfSBlbHNlIGlmIChpc051bWJlcih2YWwpKSB7XG4gICAgICAgICAgcGFyc2VbZmlsdGVyWydmaWVsZCddXSA9ICdudW1iZXInO1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKHZhbCkpIHtcbiAgICAgICAgICBwYXJzZVtmaWx0ZXJbJ2ZpZWxkJ11dID0gJ3N0cmluZyc7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGtleXMocGFyc2UpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgcGFyc2VOb2RlID0gbmV3IFBhcnNlTm9kZShwYXJzZSk7XG4gICAgICAgIGluc2VydChwYXJzZU5vZGUpO1xuICAgICAgfVxuXG4gICAgICBub2RlID0gbmV3IEZpbHRlck5vZGUobW9kZWwsIHQuZmlsdGVyKTtcbiAgICB9IGVsc2UgaWYgKGlzQmluKHQpKSB7XG4gICAgICBub2RlID0gQmluTm9kZS5tYWtlRnJvbVRyYW5zZm9ybSh0LCB7bW9kZWx9KTtcbiAgICB9IGVsc2UgaWYgKGlzVGltZVVuaXQodCkpIHtcbiAgICAgIG5vZGUgPSBUaW1lVW5pdE5vZGUubWFrZUZyb21UcmFuc2Zvcm0odCk7XG4gICAgfSBlbHNlIGlmIChpc0FnZ3JlZ2F0ZSh0KSkge1xuICAgICAgbm9kZSA9IEFnZ3JlZ2F0ZU5vZGUubWFrZUZyb21UcmFuc2Zvcm0odCk7XG5cbiAgICAgIGlmIChyZXF1aXJlc1NlbGVjdGlvbklkKG1vZGVsKSkge1xuICAgICAgICBpbnNlcnQobm9kZSk7XG4gICAgICAgIG5vZGUgPSBuZXcgSWRlbnRpZmllck5vZGUoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzTG9va3VwKHQpKSB7XG4gICAgICBub2RlID0gTG9va3VwTm9kZS5tYWtlKG1vZGVsLCB0LCBsb29rdXBDb3VudGVyKyspO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5pbnZhbGlkVHJhbnNmb3JtSWdub3JlZCh0KSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaW5zZXJ0KG5vZGUpO1xuICB9KTtcblxuICBjb25zdCBsYXN0ID0gbm9kZTtcblxuICByZXR1cm4ge2ZpcnN0LCBsYXN0fTtcbn1cblxuLypcbkRlc2NyaXB0aW9uIG9mIHRoZSBkYXRhZmxvdyAoaHR0cDovL2FzY2lpZmxvdy5jb20vKTpcbiAgICAgKy0tLS0tLS0tK1xuICAgICB8IFNvdXJjZSB8XG4gICAgICstLS0rLS0tLStcbiAgICAgICAgIHxcbiAgICAgICAgIHZcbiAgICAgVHJhbnNmb3Jtc1xuKEZpbHRlciwgQ2FsY3VsYXRlLCAuLi4pXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gICAgIEZvcm1hdFBhcnNlXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gICAgICBCaW5uaW5nXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gICAgICBUaW1ldW5pdFxuICAgICAgICAgfFxuICAgICAgICAgdlxuICAgICAgKy0tKy0tK1xuICAgICAgfCBSYXcgfFxuICAgICAgKy0tLS0tK1xuICAgICAgICAgfFxuICAgICAgICAgdlxuICAgICBBZ2dyZWdhdGVcbiAgICAgICAgIHxcbiAgICAgICAgIHZcbiAgICAgICBTdGFja1xuICAgICAgICAgfFxuICAgICAgICAgdlxuICAgICBQYXRoIE9yZGVyXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gIEludmFsaWQgRmlsdGVyXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gICArLS0tLS0tLS0tLStcbiAgIHwgICBNYWluICAgfFxuICAgKy0tLS0tLS0tLS0rXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gICAgICstLS0tLS0tK1xuICAgICB8IEZhY2V0IHwtLS0tPiBcImNvbHVtblwiLCBcImNvbHVtbi1sYXlvdXRcIiwgYW5kIFwicm93XCJcbiAgICAgKy0tLS0tLS0rXG4gICAgICAgICB8XG4gICAgICAgICB2XG4gIC4uLkNoaWxkIGRhdGEuLi5cbiovXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURhdGEobW9kZWw6IE1vZGVsKTogRGF0YUNvbXBvbmVudCB7XG4gIGNvbnN0IHJvb3QgPSBwYXJzZVJvb3QobW9kZWwsIG1vZGVsLmNvbXBvbmVudC5kYXRhLnNvdXJjZXMpO1xuXG4gIGNvbnN0IG91dHB1dE5vZGVzID0gbW9kZWwuY29tcG9uZW50LmRhdGEub3V0cHV0Tm9kZXM7XG4gIGNvbnN0IG91dHB1dE5vZGVSZWZDb3VudHMgPSBtb2RlbC5jb21wb25lbnQuZGF0YS5vdXRwdXROb2RlUmVmQ291bnRzO1xuXG4gIC8vIHRoZSBjdXJyZW50IGhlYWQgb2YgdGhlIHRyZWUgdGhhdCB3ZSBhcmUgYXBwZW5kaW5nIHRvXG4gIGxldCBoZWFkID0gcm9vdDtcblxuICAvLyBEZWZhdWx0IGRpc2NyZXRlIHNlbGVjdGlvbnMgcmVxdWlyZSBhbiBpZGVudGlmaWVyIHRyYW5zZm9ybSB0b1xuICAvLyB1bmlxdWVseSBpZGVudGlmeSBkYXRhIHBvaW50cyBhcyB0aGUgX2lkIGZpZWxkIGlzIHZvbGF0aWxlLiBBZGRcbiAgLy8gdGhpcyB0cmFuc2Zvcm0gYXQgdGhlIGhlYWQgb2Ygb3VyIHBpcGVsaW5lIHN1Y2ggdGhhdCB0aGUgaWRlbnRpZmllclxuICAvLyBmaWVsZCBpcyBhdmFpbGFibGUgZm9yIGFsbCBzdWJzZXF1ZW50IGRhdGFzZXRzLiBBZGRpdGlvbmFsIGlkZW50aWZpZXJcbiAgLy8gdHJhbnNmb3JtcyB3aWxsIGJlIG5lY2Vzc2FyeSB3aGVuIG5ldyB0dXBsZXMgYXJlIGNvbnN0cnVjdGVkXG4gIC8vIChlLmcuLCBwb3N0LWFnZ3JlZ2F0aW9uKS5cbiAgaWYgKHJlcXVpcmVzU2VsZWN0aW9uSWQobW9kZWwpICYmICFtb2RlbC5wYXJlbnQpIHtcbiAgICBjb25zdCBpZGVudCA9IG5ldyBJZGVudGlmaWVyTm9kZSgpO1xuICAgIGlkZW50LnBhcmVudCA9IGhlYWQ7XG4gICAgaGVhZCA9IGlkZW50O1xuICB9XG5cbiAgLy8gSEFDSzogVGhpcyBpcyBlcXVpdmFsZW50IGZvciBtZXJnaW5nIGJpbiBleHRlbnQgZm9yIHVuaW9uIHNjYWxlLlxuICAvLyBGSVhNRShodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzIyNzApOiBDb3JyZWN0bHkgbWVyZ2UgZXh0ZW50IC8gYmluIG5vZGUgZm9yIHNoYXJlZCBiaW4gc2NhbGVcbiAgY29uc3QgcGFyZW50SXNMYXllciA9IG1vZGVsLnBhcmVudCAmJiBpc0xheWVyTW9kZWwobW9kZWwucGFyZW50KTtcbiAgaWYgKGlzVW5pdE1vZGVsKG1vZGVsKSB8fCBpc0ZhY2V0TW9kZWwobW9kZWwpKSB7XG4gICAgaWYgKHBhcmVudElzTGF5ZXIpIHtcbiAgICAgIGNvbnN0IGJpbiA9IEJpbk5vZGUubWFrZUJpbkZyb21FbmNvZGluZyhtb2RlbCk7XG4gICAgICBpZiAoYmluKSB7XG4gICAgICAgIGJpbi5wYXJlbnQgPSBoZWFkO1xuICAgICAgICBoZWFkID0gYmluO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChtb2RlbC50cmFuc2Zvcm1zLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCB7Zmlyc3QsIGxhc3R9ID0gcGFyc2VUcmFuc2Zvcm1BcnJheShtb2RlbCk7XG4gICAgZmlyc3QucGFyZW50ID0gaGVhZDtcbiAgICBoZWFkID0gbGFzdDtcbiAgfVxuXG4gIGNvbnN0IHBhcnNlID0gUGFyc2VOb2RlLm1ha2UobW9kZWwpO1xuICBpZiAocGFyc2UpIHtcbiAgICBwYXJzZS5wYXJlbnQgPSBoZWFkO1xuICAgIGhlYWQgPSBwYXJzZTtcbiAgfVxuXG4gIGlmIChpc1VuaXRNb2RlbChtb2RlbCkgfHwgaXNGYWNldE1vZGVsKG1vZGVsKSkge1xuXG4gICAgaWYgKCFwYXJlbnRJc0xheWVyKSB7XG4gICAgICBjb25zdCBiaW4gPSBCaW5Ob2RlLm1ha2VCaW5Gcm9tRW5jb2RpbmcobW9kZWwpO1xuICAgICAgaWYgKGJpbikge1xuICAgICAgICBiaW4ucGFyZW50ID0gaGVhZDtcbiAgICAgICAgaGVhZCA9IGJpbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0dSA9IFRpbWVVbml0Tm9kZS5tYWtlRnJvbUVuY29kaW5nKG1vZGVsKTtcbiAgICBpZiAodHUpIHtcbiAgICAgIHR1LnBhcmVudCA9IGhlYWQ7XG4gICAgICBoZWFkID0gdHU7XG4gICAgfVxuICB9XG5cbiAgLy8gYWRkIGFuIG91dHB1dCBub2RlIHByZSBhZ2dyZWdhdGlvblxuICBjb25zdCByYXdOYW1lID0gbW9kZWwuZ2V0TmFtZShSQVcpO1xuICBjb25zdCByYXcgPSBuZXcgT3V0cHV0Tm9kZShyYXdOYW1lLCBSQVcsIG91dHB1dE5vZGVSZWZDb3VudHMpO1xuICBvdXRwdXROb2Rlc1tyYXdOYW1lXSA9IHJhdztcbiAgcmF3LnBhcmVudCA9IGhlYWQ7XG4gIGhlYWQgPSByYXc7XG5cbiAgaWYgKGlzVW5pdE1vZGVsKG1vZGVsKSkge1xuICAgIGNvbnN0IGFnZyA9IEFnZ3JlZ2F0ZU5vZGUubWFrZUZyb21FbmNvZGluZyhtb2RlbCk7XG4gICAgaWYgKGFnZykge1xuICAgICAgYWdnLnBhcmVudCA9IGhlYWQ7XG4gICAgICBoZWFkID0gYWdnO1xuXG4gICAgICBpZiAocmVxdWlyZXNTZWxlY3Rpb25JZChtb2RlbCkpIHtcbiAgICAgICAgY29uc3QgaWRlbnQgPSBuZXcgSWRlbnRpZmllck5vZGUoKTtcbiAgICAgICAgaWRlbnQucGFyZW50ID0gaGVhZDtcbiAgICAgICAgaGVhZCA9IGlkZW50O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrID0gU3RhY2tOb2RlLm1ha2UobW9kZWwpO1xuICAgIGlmIChzdGFjaykge1xuICAgICAgc3RhY2sucGFyZW50ID0gaGVhZDtcbiAgICAgIGhlYWQgPSBzdGFjaztcbiAgICB9XG4gIH1cblxuICBpZiAoaXNVbml0TW9kZWwobW9kZWwpKSB7XG4gICAgY29uc3QgZmlsdGVyID0gRmlsdGVySW52YWxpZE5vZGUubWFrZShtb2RlbCk7XG4gICAgaWYgKGZpbHRlcikge1xuICAgICAgZmlsdGVyLnBhcmVudCA9IGhlYWQ7XG4gICAgICBoZWFkID0gZmlsdGVyO1xuICAgIH1cbiAgfVxuXG4gIC8vIG91dHB1dCBub2RlIGZvciBtYXJrc1xuICBjb25zdCBtYWluTmFtZSA9IG1vZGVsLmdldE5hbWUoTUFJTik7XG4gIGNvbnN0IG1haW4gPSBuZXcgT3V0cHV0Tm9kZShtYWluTmFtZSwgTUFJTiwgb3V0cHV0Tm9kZVJlZkNvdW50cyk7XG4gIG91dHB1dE5vZGVzW21haW5OYW1lXSA9IG1haW47XG4gIG1haW4ucGFyZW50ID0gaGVhZDtcbiAgaGVhZCA9IG1haW47XG5cbiAgLy8gYWRkIGZhY2V0IG1hcmtlclxuICBsZXQgZmFjZXRSb290ID0gbnVsbDtcbiAgaWYgKGlzRmFjZXRNb2RlbChtb2RlbCkpIHtcbiAgICBjb25zdCBmYWNldE5hbWUgPSBtb2RlbC5nZXROYW1lKCdmYWNldCcpO1xuICAgIGZhY2V0Um9vdCA9IG5ldyBGYWNldE5vZGUobW9kZWwsIGZhY2V0TmFtZSwgbWFpbi5nZXRTb3VyY2UoKSk7XG4gICAgb3V0cHV0Tm9kZXNbZmFjZXROYW1lXSA9IGZhY2V0Um9vdDtcbiAgICBmYWNldFJvb3QucGFyZW50ID0gaGVhZDtcbiAgICBoZWFkID0gZmFjZXRSb290O1xuICB9XG5cbiAgLy8gYWRkIHRoZSBmb3JtYXQgcGFyc2UgZnJvbSB0aGlzIG1vZGVsIHNvIHRoYXQgY2hpbGRyZW4gZG9uJ3QgcGFyc2UgdGhlIHNhbWUgZmllbGQgYWdhaW5cbiAgY29uc3QgYW5jZXN0b3JQYXJzZSA9IHsuLi5tb2RlbC5jb21wb25lbnQuZGF0YS5hbmNlc3RvclBhcnNlLCAuLi4ocGFyc2UgPyBwYXJzZS5wYXJzZSA6IHt9KX07XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5tb2RlbC5jb21wb25lbnQuZGF0YSxcbiAgICBvdXRwdXROb2RlcyxcbiAgICBvdXRwdXROb2RlUmVmQ291bnRzLFxuICAgIHJhdyxcbiAgICBtYWluLFxuICAgIGZhY2V0Um9vdCxcbiAgICBhbmNlc3RvclBhcnNlXG4gIH07XG59XG4iXX0= \ 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..821ff58e74 --- /dev/null +++ b/build/src/compile/data/source.js @@ -0,0 +1,121 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var SourceNode = /** @class */ (function (_super) { + __extends(SourceNode, _super); + function SourceNode(data) { + var _this = _super.call(this) || this; + data = data || { name: 'source' }; + if (data_1.isInlineData(data)) { + _this._data = { values: data.values }; + } + else if (data_1.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 (!util_1.contains(['json', 'csv', 'tsv', 'topojson'], defaultExtension)) { + defaultExtension = 'json'; + } + // defaultExtension has type string but we ensure that it is DataFormatType above + data.format.type = defaultExtension; + } + } + else if (data_1.isNamedData(data)) { + _this._name = data.name; + _this._data = {}; + } + if (!data_1.isNamedData(data) && data.format) { + var _a = data.format, _b = _a.parse, parse = _b === void 0 ? null : _b, 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 (data_1.isInlineData(this._data)) { + if (!this._hash) { + // Hashing can be expensive for large inline datasets. + this._hash = util_1.hash(this._data); + } + return this._hash; + } + else if (data_1.isUrlData(this._data)) { + return util_1.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; +}(dataflow_1.DataFlowNode)); +exports.SourceNode = SourceNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9zb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtQ0FBa0c7QUFDbEcsbUNBQTJEO0FBRTNELHVDQUF3QztBQUV4QztJQUFnQyw4QkFBWTtJQU8xQyxvQkFBWSxJQUFVO1FBQXRCLFlBQ0UsaUJBQU8sU0FpQ1I7UUEvQkMsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFDLElBQUksRUFBRSxRQUFRLEVBQUMsQ0FBQztRQUVoQyxFQUFFLENBQUMsQ0FBQyxtQkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QixLQUFJLENBQUMsS0FBSyxHQUFHLEVBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGdCQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNCLEtBQUksQ0FBQyxLQUFLLEdBQUcsRUFBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBQyxDQUFDO1lBRTdCLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1lBQ25CLENBQUM7WUFFRCxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3RDLGdEQUFnRDtnQkFDaEQsd0dBQXdHO2dCQUN4RyxJQUFJLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNELEVBQUUsQ0FBQyxDQUFD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VHlwZSwgaXNJbmxpbmVEYXRhLCBpc05hbWVkRGF0YSwgaXNVcmxEYXRhfSBmcm9tICcuLi8uLi9kYXRhJztcbmltcG9ydCB7Y29udGFpbnMsIGR1cGxpY2F0ZSwgaGFzaCwga2V5c30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnRGF0YX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtEYXRhRmxvd05vZGV9IGZyb20gJy4vZGF0YWZsb3cnO1xuXG5leHBvcnQgY2xhc3MgU291cmNlTm9kZSBleHRlbmRzIERhdGFGbG93Tm9kZSB7XG4gIHByaXZhdGUgX2RhdGE6IFBhcnRpYWw8VmdEYXRhPjtcblxuICBwcml2YXRlIF9uYW1lOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBfaGFzaDogc3RyaW5nIHwgbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IERhdGEpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgZGF0YSA9IGRhdGEgfHwge25hbWU6ICdzb3VyY2UnfTtcblxuICAgIGlmIChpc0lubGluZURhdGEoZGF0YSkpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSB7dmFsdWVzOiBkYXRhLnZhbHVlc307XG4gICAgfSBlbHNlIGlmIChpc1VybERhdGEoZGF0YSkpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSB7dXJsOiBkYXRhLnVybH07XG5cbiAgICAgIGlmICghZGF0YS5mb3JtYXQpIHtcbiAgICAgICAgZGF0YS5mb3JtYXQgPSB7fTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFkYXRhLmZvcm1hdCB8fCAhZGF0YS5mb3JtYXQudHlwZSkge1xuICAgICAgICAvLyBFeHRyYWN0IGV4dGVuc2lvbiBmcm9tIFVSTCB1c2luZyBzbmlwcGV0IGZyb21cbiAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82ODA5MjkvaG93LXRvLWV4dHJhY3QtZXh0ZW5zaW9uLWZyb20tZmlsZW5hbWUtc3RyaW5nLWluLWphdmFzY3JpcHRcbiAgICAgICAgbGV0IGRlZmF1bHRFeHRlbnNpb24gPSAvKD86XFwuKFteLl0rKSk/JC8uZXhlYyhkYXRhLnVybClbMV07XG4gICAgICAgIGlmICghY29udGFpbnMoWydqc29uJywgJ2NzdicsICd0c3YnLCAndG9wb2pzb24nXSwgZGVmYXVsdEV4dGVuc2lvbikpIHtcbiAgICAgICAgICBkZWZhdWx0RXh0ZW5zaW9uID0gJ2pzb24nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZGVmYXVsdEV4dGVuc2lvbiBoYXMgdHlwZSBzdHJpbmcgYnV0IHdlIGVuc3VyZSB0aGF0IGl0IGlzIERhdGFGb3JtYXRUeXBlIGFib3ZlXG4gICAgICAgIGRhdGEuZm9ybWF0LnR5cGUgPSBkZWZhdWx0RXh0ZW5zaW9uIGFzIERhdGFGb3JtYXRUeXBlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNOYW1lZERhdGEoZGF0YSkpIHtcbiAgICAgIHRoaXMuX25hbWUgPSBkYXRhLm5hbWU7XG4gICAgICB0aGlzLl9kYXRhID0ge307XG4gICAgfVxuXG4gICAgaWYgKCFpc05hbWVkRGF0YShkYXRhKSAmJiBkYXRhLmZvcm1hdCkge1xuICAgICAgY29uc3Qge3BhcnNlID0gbnVsbCwgLi4uZm9ybWF0fSA9IGRhdGEuZm9ybWF0O1xuICAgICAgdGhpcy5fZGF0YS5mb3JtYXQgPSBmb3JtYXQ7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGRhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gIH1cblxuICBwdWJsaWMgaGFzTmFtZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLl9uYW1lO1xuICB9XG5cbiAgZ2V0IGRhdGFOYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9uYW1lO1xuICB9XG5cbiAgc2V0IGRhdGFOYW1lKG5hbWU6IHN0cmluZykge1xuICAgIHRoaXMuX25hbWUgPSBuYW1lO1xuICB9XG5cbiAgc2V0IHBhcmVudChwYXJlbnQ6IERhdGFGbG93Tm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU291cmNlIG5vZGVzIGhhdmUgdG8gYmUgcm9vdHMuJyk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU291cmNlIG5vZGVzIGFyZSByb290cyBhbmQgY2Fubm90IGJlIHJlbW92ZWQuJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoaXMgZGF0YSBzb3VyY2UuXG4gICAqL1xuICBwdWJsaWMgaGFzaCgpIHtcbiAgICBpZiAoaXNJbmxpbmVEYXRhKHRoaXMuX2RhdGEpKSB7XG4gICAgICBpZiAoIXRoaXMuX2hhc2gpIHtcbiAgICAgICAgLy8gSGFzaGluZyBjYW4gYmUgZXhwZW5zaXZlIGZvciBsYXJnZSBpbmxpbmUgZGF0YXNldHMuXG4gICAgICAgIHRoaXMuX2hhc2ggPSBoYXNoKHRoaXMuX2RhdGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX2hhc2g7XG4gICAgfSBlbHNlIGlmIChpc1VybERhdGEodGhpcy5fZGF0YSkpIHtcbiAgICAgIHJldHVybiBoYXNoKFt0aGlzLl9kYXRhLnVybCwgdGhpcy5fZGF0YS5mb3JtYXRdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuX25hbWU7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlKCk6IFZnRGF0YSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHRoaXMuX25hbWUsXG4gICAgICAuLi50aGlzLl9kYXRhLFxuICAgICAgdHJhbnNmb3JtOiBbXVxuICAgIH07XG4gIH1cbn1cbiJdfQ== \ 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..885ceb66da --- /dev/null +++ b/build/src/compile/data/stack.d.ts @@ -0,0 +1,42 @@ +import { FieldDef } from '../../fielddef'; +import { StackOffset } from '../../stack'; +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 + */ + field: string; + /** + * Level of detail fields for each level in the stacked charts such as color or detail. + */ + stackby: string[]; + /** + * Field that determines order of levels in the stacked charts. + */ + sort: VgSort; + /** Mode for stacking marks. */ + offset: StackOffset; + /** + * Whether to impute the data before stacking. + */ + impute: boolean; +} +export declare class StackNode extends DataFlowNode { + private _stack; + clone(): StackNode; + constructor(stack: StackComponent); + static make(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..ec42de7145 --- /dev/null +++ b/build/src/compile/data/stack.js @@ -0,0 +1,161 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var dataflow_1 = require("./dataflow"); +function getStackByFields(model) { + return model.stack.stackBy.reduce(function (fields, by) { + var fieldDef = by.fieldDef; + var _field = fielddef_1.field(fieldDef); + if (_field) { + fields.push(_field); + } + return fields; + }, []); +} +var StackNode = /** @class */ (function (_super) { + __extends(StackNode, _super); + function StackNode(stack) { + var _this = _super.call(this) || this; + _this._stack = stack; + return _this; + } + StackNode.prototype.clone = function () { + return new StackNode(util_1.duplicate(this._stack)); + }; + StackNode.make = function (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 (orderDef) { + sort = common_1.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: [] }); + } + return new StackNode({ + dimensionFieldDef: dimensionFieldDef, + field: model.field(stackProperties.fieldChannel), + facetby: [], + stackby: stackby, + sort: sort, + offset: stackProperties.offset, + impute: stackProperties.impute, + }); + }; + 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.field] = 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; + vega_util_1.isArray(field) ? field.forEach(function (f) { return out[f] = true; }) : out[field] = true; + return out; + }; + StackNode.prototype.producedFields = function () { + var out = {}; + out[this._stack.field + '_start'] = true; + out[this._stack.field + '_end'] = true; + return out; + }; + StackNode.prototype.getGroupbyFields = function () { + var _a = this._stack, dimensionFieldDef = _a.dimensionFieldDef, impute = _a.impute; + 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 [fielddef_1.field(dimensionFieldDef, { binSuffix: 'mid' })]; + } + return [ + // For binned group by field without impute, we need both bin (start) and bin_end + fielddef_1.field(dimensionFieldDef, {}), + fielddef_1.field(dimensionFieldDef, { binSuffix: 'end' }) + ]; + } + return [fielddef_1.field(dimensionFieldDef)]; + } + return []; + }; + StackNode.prototype.assemble = function () { + var transform = []; + var _a = this._stack, facetby = _a.facetby, stackField = _a.field, dimensionFieldDef = _a.dimensionFieldDef, impute = _a.impute, offset = _a.offset, sort = _a.sort, stackby = _a.stackby; + // Impute + if (impute && dimensionFieldDef) { + var dimensionField = dimensionFieldDef ? fielddef_1.field(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: '(' + + fielddef_1.field(dimensionFieldDef, { expr: 'datum' }) + + '+' + + fielddef_1.field(dimensionFieldDef, { expr: 'datum', binSuffix: 'end' }) + + ')/2', + as: dimensionField + }); + } + transform.push({ + type: 'impute', + field: stackField, + groupby: stackby, + key: dimensionField, + method: 'value', + value: 0 + }); + } + // Stack + transform.push({ + type: 'stack', + groupby: this.getGroupbyFields().concat(facetby), + field: stackField, + sort: sort, + as: [ + stackField + '_start', + stackField + '_end' + ], + offset: offset + }); + return transform; + }; + return StackNode; +}(dataflow_1.DataFlowNode)); +exports.StackNode = StackNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3N0YWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLHVDQUFrQztBQUNsQywyQ0FBK0M7QUFFL0MsbUNBQXFDO0FBRXJDLG9DQUFxQztBQUVyQyx1Q0FBd0M7QUFHeEMsMEJBQTBCLEtBQWdCO0lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQyxNQUFNLEVBQUUsRUFBRTtRQUMzQyxJQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDO1FBRTdCLElBQU0sTUFBTSxHQUFHLGdCQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0IsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNYLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEIsQ0FBQztRQUNELE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxFQUFFLEVBQWMsQ0FBQyxDQUFDO0FBQ3JCLENBQUM7QUFrQ0Q7SUFBK0IsNkJBQVk7SUFPekMsbUJBQVksS0FBcUI7UUFBakMsWUFDRSxpQkFBTyxTQUdSO1FBREMsS0FBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7O0lBQ3RCLENBQUM7SUFSTSx5QkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksU0FBUyxDQUFDLGdCQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQVFhLGNBQUksR0FBbEIsVUFBbUIsS0FBZ0I7UUFFakMsSUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUVwQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDckIsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJ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LEdBQUcsTUFBTTthQUNwQjtZQUNELE1BQU0sUUFBQTtTQUNQLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNILGdCQUFDO0FBQUQsQ0FBQyxBQXZKRCxDQUErQix1QkFBWSxHQXVKMUM7QUF2SlksOEJBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzQXJyYXl9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5pbXBvcnQge2ZpZWxkLCBGaWVsZERlZn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0IHtTdGFja09mZnNldH0gZnJvbSAnLi4vLi4vc3RhY2snO1xuaW1wb3J0IHtkdXBsaWNhdGV9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtWZ1NvcnQsIFZnVHJhbnNmb3JtfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3NvcnRQYXJhbXN9IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi8uLi91bml0JztcbmltcG9ydCB7RGF0YUZsb3dOb2RlfSBmcm9tICcuL2RhdGFmbG93JztcblxuXG5mdW5jdGlvbiBnZXRTdGFja0J5RmllbGRzKG1vZGVsOiBVbml0TW9kZWwpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBtb2RlbC5zdGFjay5zdGFja0J5LnJlZHVjZSgoZmllbGRzLCBieSkgPT4ge1xuICAgIGNvbnN0IGZpZWxkRGVmID0gYnkuZmllbGREZWY7XG5cbiAgICBjb25zdCBfZmllbGQgPSBmaWVsZChmaWVsZERlZik7XG4gICAgaWYgKF9maWVsZCkge1xuICAgICAgZmllbGRzLnB1c2goX2ZpZWxkKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpZWxkcztcbiAgfSwgW10gYXMgc3RyaW5nW10pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YWNrQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIEZhY2V0ZWQgZmllbGQuXG4gICAqL1xuICBmYWNldGJ5OiBzdHJpbmdbXTtcblxuICBkaW1lbnNpb25GaWVsZERlZjogRmllbGREZWY8c3RyaW5nPjtcblxuICAvKipcbiAgICogU3RhY2sgbWVhc3VyZSdzIGZpZWxkXG4gICAqL1xuICBmaWVsZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMZXZlbCBvZiBkZXRhaWwgZmllbGRzIGZvciBlYWNoIGxldmVsIGluIHRoZSBzdGFja2VkIGNoYXJ0cyBzdWNoIGFzIGNvbG9yIG9yIGRldGFpbC5cbiAgICovXG4gIHN0YWNrYnk6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBGaWVsZCB0aGF0IGRldGVybWluZXMgb3JkZXIgb2YgbGV2ZWxzIGluIHRoZSBzdGFja2VkIGNoYXJ0cy5cbiAgICovXG4gIHNvcnQ6IFZnU29ydDtcblxuICAvKiogTW9kZSBmb3Igc3RhY2tpbmcgbWFya3MuICovXG4gIG9mZnNldDogU3RhY2tPZmZzZXQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gaW1wdXRlIHRoZSBkYXRhIGJlZm9yZSBzdGFja2luZy5cbiAgICovXG4gIGltcHV0ZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFN0YWNrTm9kZSBleHRlbmRzIERhdGFGbG93Tm9kZSB7XG4gIHByaXZhdGUgX3N0YWNrOiBTdGFja0NvbXBvbmVudDtcblxuICBwdWJsaWMgY2xvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBTdGFja05vZGUoZHVwbGljYXRlKHRoaXMuX3N0YWNrKSk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihzdGFjazogU3RhY2tDb21wb25lbnQpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fc3RhY2sgPSBzdGFjaztcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgbWFrZShtb2RlbDogVW5pdE1vZGVsKSB7XG5cbiAgICBjb25zdCBzdGFja1Byb3BlcnRpZXMgPSBtb2RlbC5zdGFjaztcblxuICAgIGlmICghc3RhY2tQcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgZGltZW5zaW9uRmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz47XG4gICAgaWYgKHN0YWNrUHJvcGVydGllcy5ncm91cGJ5Q2hhbm5lbCkge1xuICAgICAgZGltZW5zaW9uRmllbGREZWYgPSBtb2RlbC5maWVsZERlZihzdGFja1Byb3BlcnRpZXMuZ3JvdXBieUNoYW5uZWwpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrYnkgPSBnZXRTdGFja0J5RmllbGRzKG1vZGVsKTtcbiAgICBjb25zdCBvcmRlckRlZiA9IG1vZGVsLmVuY29kaW5nLm9yZGVyO1xuXG4gICAgbGV0IHNvcnQ6IFZnU29ydDtcbiAgICBpZiAob3JkZXJEZWYpIHtcbiAgICAgIHNvcnQgPSBzb3J0UGFyYW1zKG9yZGVyRGVmKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZGVmYXVsdCA9IGRlc2NlbmRpbmcgYnkgc3RhY2tGaWVsZHNcbiAgICAgIC8vIEZJWE1FIGlzIHRoZSBkZWZhdWx0IGhlcmUgY29ycmVjdCBmb3IgYmlubmVkIGZpZWxkcz9cbiAgICAgIHNvcnQgPSBzdGFja2J5LnJlZHVjZSgocywgZmllbGQpID0+IHtcbiAgICAgICAgcy5maWVsZC5wdXNoKGZpZWxkKTtcbiAgICAgICAgcy5vcmRlci5wdXNoKCdkZXNjZW5kaW5nJyk7XG4gICAgICAgIHJldHVybiBzO1xuICAgICAgfSwge2ZpZWxkOltdLCBvcmRlcjogW119KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFN0YWNrTm9kZSh7XG4gICAgICBkaW1lbnNpb25GaWVsZERlZixcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChzdGFja1Byb3BlcnRpZXMuZmllbGRDaGFubmVsKSxcbiAgICAgIGZhY2V0Ynk6IFtdLFxuICAgICAgc3RhY2tieSxcbiAgICAgIHNvcnQsXG4gICAgICBvZmZzZXQ6IHN0YWNrUHJvcGVydGllcy5vZmZzZXQsXG4gICAgICBpbXB1dGU6IHN0YWNrUHJvcGVydGllcy5pbXB1dGUsXG4gICAgfSk7XG4gIH1cblxuICBnZXQgc3RhY2soKTogU3RhY2tDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLl9zdGFjaztcbiAgfVxuXG4gIHB1YmxpYyBhZGREaW1lbnNpb25zKGZpZWxkczogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9zdGFjay5mYWNldGJ5ID0gdGhpcy5fc3RhY2suZmFjZXRieS5jb25jYXQoZmllbGRzKTtcbiAgfVxuXG4gIHB1YmxpYyBkZXBlbmRlbnRGaWVsZHMoKSB7XG4gICAgY29uc3Qgb3V0ID0ge307XG5cbiAgICBvdXRbdGhpcy5fc3RhY2suZmllbGRdID0gdHJ1ZTtcblxuICAgIHRoaXMuZ2V0R3JvdXBieUZpZWxkcygpLmZvckVhY2goZiA9PiBvdXRbZl0gPSB0cnVlKTtcbiAgICB0aGlzLl9zdGFjay5mYWNldGJ5LmZvckVhY2goZiA9PiBvdXRbZl0gPSB0cnVlKTtcbiAgICBjb25zdCBmaWVsZCA9IHRoaXMuX3N0YWNrLnNvcnQuZmllbGQ7XG4gICAgaXNBcnJheShmaWVsZCkgPyBmaWVsZC5mb3JFYWNoKGYgPT4gb3V0W2ZdID0gdHJ1ZSkgOiBvdXRbZmllbGRdID0gdHJ1ZTtcblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBwdWJsaWMgcHJvZHVjZWRGaWVsZHMoKSB7XG4gICAgY29uc3Qgb3V0ID0ge307XG5cbiAgICBvdXRbdGhpcy5fc3RhY2suZmllbGQgKyAnX3N0YXJ0J10gPSB0cnVlO1xuICAgIG91dFt0aGlzLl9zdGFjay5maWVsZCArICdfZW5kJ10gPSB0cnVlO1xuXG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0R3JvdXBieUZpZWxkcygpIHtcbiAgICBjb25zdCB7ZGltZW5zaW9uRmllbGREZWYsIGltcHV0ZX0gPSB0aGlzLl9zdGFjaztcbiAgICBpZiAoZGltZW5zaW9uRmllbGREZWYpIHtcbiAgICAgIGlmIChkaW1lbnNpb25GaWVsZERlZi5iaW4pIHtcbiAgICAgICAgaWYgKGltcHV0ZSkge1xuICAgICAgICAgIC8vIEZvciBiaW5uZWQgZ3JvdXAgYnkgZmllbGQgd2l0aCBpbXB1dGUsIHdlIGNhbGN1bGF0ZSBiaW5fbWlkXG4gICAgICAgICAgLy8gYXMgd2UgY2Fubm90IGltcHV0ZSB0d28gZmllbGRzIHNpbXVsdGFuZW91c2x5XG4gICAgICAgICAgcmV0dXJuIFtmaWVsZChkaW1lbnNpb25GaWVsZERlZiwge2JpblN1ZmZpeDogJ21pZCd9KV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAvLyBGb3IgYmlubmVkIGdyb3VwIGJ5IGZpZWxkIHdpdGhvdXQgaW1wdXRlLCB3ZSBuZWVkIGJvdGggYmluIChzdGFydCkgYW5kIGJpbl9lbmRcbiAgICAgICAgICBmaWVsZChkaW1lbnNpb25GaWVsZERlZiwge30pLFxuICAgICAgICAgIGZpZWxkKGRpbWVuc2lvbkZpZWxkRGVmLCB7YmluU3VmZml4OiAnZW5kJ30pXG4gICAgICAgIF07XG4gICAgICB9XG4gICAgICByZXR1cm4gW2ZpZWxkKGRpbWVuc2lvbkZpZWxkRGVmKV07XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZSgpOiBWZ1RyYW5zZm9ybVtdIHtcbiAgICBjb25zdCB0cmFuc2Zvcm06IFZnVHJhbnNmb3JtW10gPSBbXTtcblxuICAgIGNvbnN0IHtmYWNldGJ5LCBmaWVsZDogc3RhY2tGaWVsZCwgZGltZW5zaW9uRmllbGREZWYsIGltcHV0ZSwgb2Zmc2V0LCBzb3J0LCBzdGFja2J5fSA9IHRoaXMuX3N0YWNrO1xuXG4gICAgLy8gSW1wdXRlXG4gICAgaWYgKGltcHV0ZSAmJiBkaW1lbnNpb25GaWVsZERlZikge1xuICAgICAgY29uc3QgZGltZW5zaW9uRmllbGQgPSBkaW1lbnNpb25GaWVsZERlZiA/IGZpZWxkKGRpbWVuc2lvbkZpZWxkRGVmLCB7YmluU3VmZml4OiAnbWlkJ30pOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChkaW1lbnNpb25GaWVsZERlZi5iaW4pIHtcbiAgICAgICAgLy8gQXMgd2UgY2FuIG9ubHkgaW1wdXRlIG9uZSBmaWVsZCBhdCBhIHRpbWUsIHdlIG5lZWQgdG8gY2FsY3VsYXRlXG4gICAgICAgIC8vIG1pZCBwb2ludCBmb3IgYSBiaW5uZWQgZmllbGRcbiAgICAgICAgdHJhbnNmb3JtLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdmb3JtdWxhJyxcbiAgICAgICAgICBleHByOiAnKCcgK1xuICAgICAgICAgICAgZmllbGQoZGltZW5zaW9uRmllbGREZWYsIHtleHByOiAnZGF0dW0nfSkgK1xuICAgICAgICAgICAgJysnICtcbiAgICAgICAgICAgIGZpZWxkKGRpbWVuc2lvbkZpZWxkRGVmLCB7ZXhwcjogJ2RhdHVtJywgYmluU3VmZml4OiAnZW5kJ30pICtcbiAgICAgICAgICAgICcpLzInLFxuICAgICAgICAgIGFzOiBkaW1lbnNpb25GaWVsZFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdHJhbnNmb3JtLnB1c2goe1xuICAgICAgICB0eXBlOiAnaW1wdXRlJyxcbiAgICAgICAgZmllbGQ6IHN0YWNrRmllbGQsXG4gICAgICAgIGdyb3VwYnk6IHN0YWNrYnksXG4gICAgICAgIGtleTogZGltZW5zaW9uRmllbGQsXG4gICAgICAgIG1ldGhvZDogJ3ZhbHVlJyxcbiAgICAgICAgdmFsdWU6IDBcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFN0YWNrXG4gICAgdHJhbnNmb3JtLnB1c2goe1xuICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgIGdyb3VwYnk6IHRoaXMuZ2V0R3JvdXBieUZpZWxkcygpLmNvbmNhdChmYWNldGJ5KSxcbiAgICAgIGZpZWxkOiBzdGFja0ZpZWxkLFxuICAgICAgc29ydCxcbiAgICAgIGFzOiBbXG4gICAgICAgIHN0YWNrRmllbGQgKyAnX3N0YXJ0JyxcbiAgICAgICAgc3RhY2tGaWVsZCArICdfZW5kJ1xuICAgICAgXSxcbiAgICAgIG9mZnNldFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRyYW5zZm9ybTtcbiAgfVxufVxuIl19 \ 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..a2cbec4191 --- /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(formula: Dict); + static makeFromEncoding(model: ModelWithField): TimeUnitNode; + static makeFromTransform(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..b52134e58a --- /dev/null +++ b/build/src/compile/data/timeunit.js @@ -0,0 +1,92 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../../fielddef"); +var timeunit_1 = require("../../timeunit"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var TimeUnitNode = /** @class */ (function (_super) { + __extends(TimeUnitNode, _super); + function TimeUnitNode(formula) { + var _this = _super.call(this) || this; + _this.formula = formula; + return _this; + } + TimeUnitNode.prototype.clone = function () { + return new TimeUnitNode(util_1.duplicate(this.formula)); + }; + TimeUnitNode.makeFromEncoding = function (model) { + var formula = model.reduceFieldDef(function (timeUnitComponent, fieldDef) { + if (fieldDef.timeUnit) { + var f = fielddef_1.field(fieldDef); + timeUnitComponent[f] = { + as: f, + timeUnit: fieldDef.timeUnit, + field: fieldDef.field + }; + } + return timeUnitComponent; + }, {}); + if (util_1.keys(formula).length === 0) { + return null; + } + return new TimeUnitNode(formula); + }; + TimeUnitNode.makeFromTransform = function (t) { + return new TimeUnitNode((_a = {}, + _a[t.field] = { + as: t.as, + timeUnit: t.timeUnit, + field: t.field + }, + _a)); + var _a; + }; + TimeUnitNode.prototype.merge = function (other) { + this.formula = __assign({}, this.formula, other.formula); + other.remove(); + }; + TimeUnitNode.prototype.producedFields = function () { + var out = {}; + util_1.vals(this.formula).forEach(function (f) { + out[f.as] = true; + }); + return out; + }; + TimeUnitNode.prototype.dependentFields = function () { + var out = {}; + util_1.vals(this.formula).forEach(function (f) { + out[f.field] = true; + }); + return out; + }; + TimeUnitNode.prototype.assemble = function () { + return util_1.vals(this.formula).map(function (c) { + return { + type: 'formula', + as: c.as, + expr: timeunit_1.fieldExpr(c.timeUnit, c.field) + }; + }); + }; + return TimeUnitNode; +}(dataflow_1.DataFlowNode)); +exports.TimeUnitNode = TimeUnitNode; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3RpbWV1bml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkNBQXFDO0FBQ3JDLDJDQUFtRDtBQUVuRCxtQ0FBdUQ7QUFHdkQsdUNBQXdDO0FBU3hDO0lBQWtDLGdDQUFZO0lBSzVDLHNCQUFvQixPQUFnQztRQUFwRCxZQUNFLGlCQUFPLFNBQ1I7UUFGbUIsYUFBTyxHQUFQLE9BQU8sQ0FBeUI7O0lBRXBELENBQUM7SUFOTSw0QkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksWUFBWSxDQUFDLGdCQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQU1hLDZCQUFnQixHQUE5QixVQUErQixLQUFxQjtRQUNsRCxJQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLFVBQUMsaUJBQW9DLEVBQUUsUUFBUTtZQUNsRixFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDdEIsSUFBTSxDQUFDLEdBQUcsZ0JBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDMUIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEdBQUc7b0JBQ3JCLEVBQUUsRUFBRSxDQUFDO29CQUNMLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUTtvQkFDM0IsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO2lCQUN0QixDQUFDO1lBQ0osQ0FBQztZQUNELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUMzQixDQUFDLEVBQUUsRUFBNkIsQ0FBQyxDQUFDO1FBRWxDLEVBQUUsQ0FBQyxDQUFDLFdBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQixNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sQ0FBQyxJQUFJLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRWEsOEJBQWlCLEdBQS9CLFVBQWdDLENBQW9CO1FBQ2xELE1BQU0sQ0FBQyxJQUFJLFlBQVk7WUFDckIsR0FBQyxDQUFDLENBQUMsS0FBSyxJQUFHO2dCQUNULEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRTtnQkFDUixRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVE7Z0JBQ3BCLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSzthQUNmO2dCQUNELENBQUM7O0lBQ0wsQ0FBQztJQUVNLDRCQUFLLEdBQVosVUFBYSxLQUFtQjtRQUM5QixJQUFJLENBQUMsT0FBTyxnQkFBTyxJQUFJLENBQUMsT0FBTyxFQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRCxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVNLHFDQUFjLEdBQXJCO1FBQ0UsSUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBRWYsV0FBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQSxDQUFDO1lBQzFCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFTSxzQ0FBZSxHQUF0QjtRQUNFLElBQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUVmLFdBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUEsQ0FBQztZQUMxQixHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztRQUN0QixDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRU0sK0JBQVEsR0FBZjtRQUNFLE1BQU0sQ0FBQyxXQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUM7WUFDN0IsTUFBTSxDQUFDO2dCQUNMLElBQUksRUFBRSxTQUFTO2dCQUNmLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRTtnQkFDUixJQUFJLEVBQUUsb0JBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUM7YUFDZixDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNILG1CQUFDO0FBQUQsQ0FBQyxBQXpFRCxDQUFrQyx1QkFBWSxHQXlFN0M7QUF6RVksb0NBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2ZpZWxkfSBmcm9tICcuLi8uLi9maWVsZGRlZic7XG5pbXBvcnQge2ZpZWxkRXhwciwgVGltZVVuaXR9IGZyb20gJy4uLy4uL3RpbWV1bml0JztcbmltcG9ydCB7VGltZVVuaXRUcmFuc2Zvcm19IGZyb20gJy4uLy4uL3RyYW5zZm9ybSc7XG5pbXBvcnQge0RpY3QsIGR1cGxpY2F0ZSwga2V5cywgdmFsc30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnRm9ybXVsYVRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtNb2RlbFdpdGhGaWVsZH0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtEYXRhRmxvd05vZGV9IGZyb20gJy4vZGF0YWZsb3cnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGltZVVuaXRDb21wb25lbnQge1xuICBhczogc3RyaW5nO1xuICB0aW1lVW5pdDogVGltZVVuaXQ7XG4gIGZpZWxkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBUaW1lVW5pdE5vZGUgZXh0ZW5kcyBEYXRhRmxvd05vZGUge1xuICBwdWJsaWMgY2xvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lVW5pdE5vZGUoZHVwbGljYXRlKHRoaXMuZm9ybXVsYSkpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmb3JtdWxhOiBEaWN0PFRpbWVVbml0Q29tcG9uZW50Pikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIG1ha2VGcm9tRW5jb2RpbmcobW9kZWw6IE1vZGVsV2l0aEZpZWxkKSB7XG4gICAgY29uc3QgZm9ybXVsYSA9IG1vZGVsLnJlZHVjZUZpZWxkRGVmKCh0aW1lVW5pdENvbXBvbmVudDogVGltZVVuaXRDb21wb25lbnQsIGZpZWxkRGVmKSA9PiB7XG4gICAgICBpZiAoZmllbGREZWYudGltZVVuaXQpIHtcbiAgICAgICAgY29uc3QgZiA9IGZpZWxkKGZpZWxkRGVmKTtcbiAgICAgICAgdGltZVVuaXRDb21wb25lbnRbZl0gPSB7XG4gICAgICAgICAgYXM6IGYsXG4gICAgICAgICAgdGltZVVuaXQ6IGZpZWxkRGVmLnRpbWVVbml0LFxuICAgICAgICAgIGZpZWxkOiBmaWVsZERlZi5maWVsZFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRpbWVVbml0Q29tcG9uZW50O1xuICAgIH0sIHt9IGFzIERpY3Q8VGltZVVuaXRDb21wb25lbnQ+KTtcblxuICAgIGlmIChrZXlzKGZvcm11bGEpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUaW1lVW5pdE5vZGUoZm9ybXVsYSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIG1ha2VGcm9tVHJhbnNmb3JtKHQ6IFRpbWVVbml0VHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lVW5pdE5vZGUoe1xuICAgICAgW3QuZmllbGRdOiB7XG4gICAgICAgIGFzOiB0LmFzLFxuICAgICAgICB0aW1lVW5pdDogdC50aW1lVW5pdCxcbiAgICAgICAgZmllbGQ6IHQuZmllbGRcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXJnZShvdGhlcjogVGltZVVuaXROb2RlKSB7XG4gICAgdGhpcy5mb3JtdWxhID0gey4uLnRoaXMuZm9ybXVsYSwgLi4ub3RoZXIuZm9ybXVsYX07XG4gICAgb3RoZXIucmVtb3ZlKCk7XG4gIH1cblxuICBwdWJsaWMgcHJvZHVjZWRGaWVsZHMoKSB7XG4gICAgY29uc3Qgb3V0ID0ge307XG5cbiAgICB2YWxzKHRoaXMuZm9ybXVsYSkuZm9yRWFjaChmID0+IHtcbiAgICAgIG91dFtmLmFzXSA9IHRydWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgcHVibGljIGRlcGVuZGVudEZpZWxkcygpIHtcbiAgICBjb25zdCBvdXQgPSB7fTtcblxuICAgIHZhbHModGhpcy5mb3JtdWxhKS5mb3JFYWNoKGYgPT4ge1xuICAgICAgb3V0W2YuZmllbGRdID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGUoKSB7XG4gICAgcmV0dXJuIHZhbHModGhpcy5mb3JtdWxhKS5tYXAoYyA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnZm9ybXVsYScsXG4gICAgICAgIGFzOiBjLmFzLFxuICAgICAgICBleHByOiBmaWVsZEV4cHIoYy50aW1lVW5pdCwgYy5maWVsZClcbiAgICAgIH0gYXMgVmdGb3JtdWxhVHJhbnNmb3JtO1xuICAgIH0pO1xuICB9XG59XG4iXX0= \ 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..0cbfc2f1b3 --- /dev/null +++ b/build/src/compile/facet.d.ts @@ -0,0 +1,40 @@ +import { Channel } from '../channel'; +import { Config } from '../config'; +import { FacetMapping } from '../facet'; +import { FieldDef } from '../fielddef'; +import { FacetSpec } from '../spec'; +import { VgData, VgLayout, VgMarkGroup, VgSignal } from '../vega.schema'; +import { Model, ModelWithField } from './model'; +import { RepeaterValue } from './repeater'; +export declare class FacetModel extends ModelWithField { + readonly type: 'facet'; + readonly facet: FacetMapping; + readonly child: Model; + readonly children: Model[]; + constructor(spec: FacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config); + private initFacet(facet); + channelHasField(channel: Channel): boolean; + fieldDef(channel: Channel): FieldDef; + parseData(): void; + parseLayoutSize(): void; + parseSelection(): void; + parseMarkGroup(): void; + parseAxisAndHeader(): void; + private parseHeader(channel); + private makeHeaderComponent(channel, labels); + private mergeChildAxis(channel); + assembleSelectionTopLevelSignals(signals: any[]): VgSignal[]; + assembleSelectionSignals(): VgSignal[]; + assembleSelectionData(data: VgData[]): VgData[]; + private getLayoutBandMixins(headerType); + assembleLayout(): VgLayout; + assembleLayoutSignals(): VgSignal[]; + private columnDistinctSignal(); + assembleGroup(signals: VgSignal[]): any; + /** + * Aggregate cardinality for calculating size + */ + private getCardinalityAggregateForChild(); + 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..274bbcab19 --- /dev/null +++ b/build/src/compile/facet.js @@ -0,0 +1,283 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var log = require("../log"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +var vega_schema_1 = require("../vega.schema"); +var buildmodel_1 = require("./buildmodel"); +var assemble_1 = require("./data/assemble"); +var parse_1 = require("./data/parse"); +var header_1 = require("./layout/header"); +var parse_2 = require("./layoutsize/parse"); +var model_1 = require("./model"); +var repeater_1 = require("./repeater"); +var resolve_1 = require("./resolve"); +var domain_1 = require("./scale/domain"); +var FacetModel = /** @class */ (function (_super) { + __extends(FacetModel, _super); + function FacetModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, spec.resolve) || this; + _this.type = 'facet'; + _this.child = buildmodel_1.buildModel(spec.spec, _this, _this.getName('child'), undefined, repeater, config, false); + _this.children = [_this.child]; + var facet = repeater_1.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 encoding_1.reduce(facet, function (normalizedFacet, fieldDef, channel) { + if (!util_1.contains([channel_1.ROW, channel_1.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] = fielddef_1.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 = parse_1.parseData(this); + this.child.parseData(); + }; + FacetModel.prototype.parseLayoutSize = function () { + parse_2.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 = header.title !== undefined ? header.title : fielddef_1.title(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] = resolve_1.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 mainAxis = axisComponent.main; + var headerType = header_1.getHeaderType(mainAxis.get('orient')); + layoutHeader[headerType] = layoutHeader[headerType] || + [this.makeHeaderComponent(headerChannel, false)]; + // LayoutHeader no longer keep track of property precedence, thus let's combine. + layoutHeader[headerType][0].axes.push(mainAxis.combine()); + delete axisComponent.main; + } + } + 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.getLayoutBandMixins = function (headerType) { + var bandMixins = {}; + var bandType = headerType === 'header' ? 'headerBand' : 'footerBand'; + for (var _i = 0, _a = ['row', 'column']; _i < _a.length; _i++) { + var channel = _a[_i]; + var layoutHeaderComponent = this.component.layoutHeaders[channel]; + var headerComponent = layoutHeaderComponent[headerType]; + if (headerComponent && headerComponent[0]) { + var sizeType = channel === 'row' ? 'height' : 'width'; + if (!this.child.component.layoutSize.get(sizeType)) { + // If facet child does not have size signal, then apply headerBand + bandMixins[bandType] = bandMixins[bandType] || {}; + bandMixins[bandType][channel] = 0.5; + } + } + } + return bandMixins; + }; + FacetModel.prototype.assembleLayout = function () { + var columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1; + // TODO: determine default align based on shared / independent scales + return __assign({ padding: { row: 10, column: 10 } }, this.getLayoutBandMixins('header'), this.getLayoutBandMixins('footer'), { + // TODO: support offset for rowHeader/rowFooter/rowTitle/columnHeader/columnFooter/columnTitle + offset: 10, 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: fielddef_1.field(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 = []; + if (this.child instanceof FacetModel) { + if (this.child.channelHasField('column')) { + fields.push(fielddef_1.field(this.child.facet.column)); + ops.push('distinct'); + } + } + 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 (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var domain = domain_1.assembleDomain(this.child, channel); + var field_1 = domain_1.getFieldFromDomain(domain); + if (field_1) { + fields.push(field_1); + ops.push('distinct'); + } + else { + log.warn('Unknown field for ${channel}. Cannot calculate view size.'); + } + } + } + } + } + return fields.length ? { fields: fields, ops: ops } : undefined; + }; + FacetModel.prototype.assembleMarks = function () { + var _a = this, child = _a.child, facet = _a.facet; + var facetRoot = this.component.data.facetRoot; + var data = assemble_1.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 hasRow = this.channelHasField(channel_1.ROW); + var hasColumn = this.channelHasField(channel_1.COLUMN); + var layoutSizeEncodeEntry = child.assembleLayoutSize(); + var aggregateMixins = {}; + if (hasRow && hasColumn) { + aggregateMixins.aggregate = { cross: true }; + } + var cardinalityAggregateForChild = this.getCardinalityAggregateForChild(); + if (cardinalityAggregateForChild) { + aggregateMixins.aggregate = __assign({}, aggregateMixins.aggregate, cardinalityAggregateForChild); + } + var title = child.assembleTitle(); + var style = child.assembleGroupStyle(); + var markGroup = __assign({ name: this.getName('cell'), type: 'group' }, (title ? { title: title } : {}), (style ? { style: style } : {}), { from: { + facet: __assign({ name: facetRoot.name, data: facetRoot.data, groupby: [].concat(hasRow ? [this.field(channel_1.ROW)] : [], hasColumn ? [this.field(channel_1.COLUMN)] : []) }, aggregateMixins) + }, sort: { + field: [].concat(hasRow ? [this.field(channel_1.ROW, { expr: 'datum', })] : [], hasColumn ? [this.field(channel_1.COLUMN, { expr: 'datum' })] : []), + order: [].concat(hasRow ? [(facet.row.sort) || 'ascending'] : [], hasColumn ? [(facet.column.sort) || 'ascending'] : []) + } }, (data.length > 0 ? { data: data } : {}), (layoutSizeEncodeEntry ? { encode: { update: layoutSizeEncodeEntry } } : {}), child.assembleGroup()); + return [markGroup]; + }; + FacetModel.prototype.getMapping = function () { + return this.facet; + }; + return FacetModel; +}(model_1.ModelWithField)); +exports.FacetModel = FacetModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9mYWNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLHNDQUE4RDtBQUU5RCx3Q0FBbUM7QUFFbkMsd0NBQStFO0FBQy9FLDRCQUE4QjtBQUM5QixrQ0FBMkM7QUFFM0MsZ0NBQWlDO0FBQ2pDLDhDQUErRztBQUMvRywyQ0FBd0M7QUFDeEMsNENBQWtEO0FBQ2xELHNDQUF1QztBQUN2QywwQ0FBOEU7QUFDOUUsNENBQTJEO0FBQzNELGlDQUE4QztBQUM5Qyx1Q0FBaUU7QUFDakUscUNBQTRDO0FBRTVDLHlDQUFrRTtBQUVsRTtJQUFnQyw4QkFBYztJQVE1QyxvQkFBWSxJQUFlLEVBQUUsTUFBYSxFQUFFLGVBQXVCLEVBQUUsUUFBdUIsRUFBRSxNQUFjO1FBQTVHLFlBQ0Usa0JBQU0sSUFBSSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsU0FTM0Q7UUFqQmUsVUFBSSxHQUFZLE9BQU8sQ0FBQztRQVd0QyxLQUFJLENBQUMsS0FBSyxHQUFHLHVCQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFJLEVBQUUsS0FBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNwRyxLQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTdCLElBQU0sS0FBSyxHQUF5QixpQ0FBc0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBRWpGLEtBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQzs7SUFDckMsQ0FBQztJQUVPLDhCQUFTLEdBQWpCLFVBQWtCLEtBQTJC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Li4vYWdncmVnYXRlJztcbmltcG9ydCB7Q2hhbm5lbCwgQ09MVU1OLCBST1csIFNjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vY2hhbm5lbCc7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7cmVkdWNlfSBmcm9tICcuLi9lbmNvZGluZyc7XG5pbXBvcnQge0ZhY2V0TWFwcGluZ30gZnJvbSAnLi4vZmFjZXQnO1xuaW1wb3J0IHtmaWVsZCwgRmllbGREZWYsIG5vcm1hbGl6ZSwgdGl0bGUgYXMgZmllbGREZWZUaXRsZX0gZnJvbSAnLi4vZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL2xvZyc7XG5pbXBvcnQge2hhc0Rpc2NyZXRlRG9tYWlufSBmcm9tICcuLi9zY2FsZSc7XG5pbXBvcnQge0ZhY2V0U3BlY30gZnJvbSAnLi4vc3BlYyc7XG5pbXBvcnQge2NvbnRhaW5zfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7aXNWZ1JhbmdlU3RlcCwgUm93Q29sLCBWZ0F4aXMsIFZnRGF0YSwgVmdMYXlvdXQsIFZnTWFya0dyb3VwLCBWZ1NjYWxlLCBWZ1NpZ25hbH0gZnJvbSAnLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtidWlsZE1vZGVsfSBmcm9tICcuL2J1aWxkbW9kZWwnO1xuaW1wb3J0IHthc3NlbWJsZUZhY2V0RGF0YX0gZnJvbSAnLi9kYXRhL2Fzc2VtYmxlJztcbmltcG9ydCB7cGFyc2VEYXRhfSBmcm9tICcuL2RhdGEvcGFyc2UnO1xuaW1wb3J0IHtnZXRIZWFkZXJUeXBlLCBIZWFkZXJDaGFubmVsLCBIZWFkZXJDb21wb25lbnR9IGZyb20gJy4vbGF5b3V0L2hlYWRlcic7XG5pbXBvcnQge3BhcnNlQ2hpbGRyZW5MYXlvdXRTaXplfSBmcm9tICcuL2xheW91dHNpemUvcGFyc2UnO1xuaW1wb3J0IHtNb2RlbCwgTW9kZWxXaXRoRmllbGR9IGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0IHtSZXBlYXRlclZhbHVlLCByZXBsYWNlUmVwZWF0ZXJJbkZhY2V0fSBmcm9tICcuL3JlcGVhdGVyJztcbmltcG9ydCB7cGFyc2VHdWlkZVJlc29sdmV9IGZyb20gJy4vcmVzb2x2ZSc7XG5pbXBvcnQge2Fzc2VtYmxlU2NhbGVzRm9yTW9kZWx9IGZyb20gJy4vc2NhbGUvYXNzZW1ibGUnO1xuaW1wb3J0IHthc3NlbWJsZURvbWFpbiwgZ2V0RmllbGRGcm9tRG9tYWlufSBmcm9tICcuL3NjYWxlL2RvbWFpbic7XG5cbmV4cG9ydCBjbGFzcyBGYWNldE1vZGVsIGV4dGVuZHMgTW9kZWxXaXRoRmllbGQge1xuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogJ2ZhY2V0JyA9ICdmYWNldCc7XG4gIHB1YmxpYyByZWFkb25seSBmYWNldDogRmFjZXRNYXBwaW5nPHN0cmluZz47XG5cbiAgcHVibGljIHJlYWRvbmx5IGNoaWxkOiBNb2RlbDtcblxuICBwdWJsaWMgcmVhZG9ubHkgY2hpbGRyZW46IE1vZGVsW107XG5cbiAgY29uc3RydWN0b3Ioc3BlYzogRmFjZXRTcGVjLCBwYXJlbnQ6IE1vZGVsLCBwYXJlbnRHaXZlbk5hbWU6IHN0cmluZywgcmVwZWF0ZXI6IFJlcGVhdGVyVmFsdWUsIGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoc3BlYywgcGFyZW50LCBwYXJlbnRHaXZlbk5hbWUsIGNvbmZpZywgc3BlYy5yZXNvbHZlKTtcblxuXG4gICAgdGhpcy5jaGlsZCA9IGJ1aWxkTW9kZWwoc3BlYy5zcGVjLCB0aGlzLCB0aGlzLmdldE5hbWUoJ2NoaWxkJyksIHVuZGVmaW5lZCwgcmVwZWF0ZXIsIGNvbmZpZywgZmFsc2UpO1xuICAgIHRoaXMuY2hpbGRyZW4gPSBbdGhpcy5jaGlsZF07XG5cbiAgICBjb25zdCBmYWNldDogRmFjZXRNYXBwaW5nPHN0cmluZz4gPSByZXBsYWNlUmVwZWF0ZXJJbkZhY2V0KHNwZWMuZmFjZXQsIHJlcGVhdGVyKTtcblxuICAgIHRoaXMuZmFjZXQgPSB0aGlzLmluaXRGYWNldChmYWNldCk7XG4gIH1cblxuICBwcml2YXRlIGluaXRGYWNldChmYWNldDogRmFjZXRNYXBwaW5nPHN0cmluZz4pOiBGYWNldE1hcHBpbmc8c3RyaW5nPiB7XG4gICAgLy8gY2xvbmUgdG8gcHJldmVudCBzaWRlIGVmZmVjdCB0byB0aGUgb3JpZ2luYWwgc3BlY1xuICAgIHJldHVybiByZWR1Y2UoZmFjZXQsIGZ1bmN0aW9uKG5vcm1hbGl6ZWRGYWNldCwgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIGNoYW5uZWw6IENoYW5uZWwpIHtcbiAgICAgIGlmICghY29udGFpbnMoW1JPVywgQ09MVU1OXSwgY2hhbm5lbCkpIHtcbiAgICAgICAgLy8gRHJvcCB1bnN1cHBvcnRlZCBjaGFubmVsXG4gICAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmluY29tcGF0aWJsZUNoYW5uZWwoY2hhbm5lbCwgJ2ZhY2V0JykpO1xuICAgICAgICByZXR1cm4gbm9ybWFsaXplZEZhY2V0O1xuICAgICAgfVxuXG4gICAgICBpZiAoZmllbGREZWYuZmllbGQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5lbXB0eUZpZWxkRGVmKGZpZWxkRGVmLCBjaGFubmVsKSk7XG4gICAgICAgIHJldHVybiBub3JtYWxpemVkRmFjZXQ7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnZlcnQgdHlwZSB0byBmdWxsLCBsb3dlcmNhc2UgdHlwZSwgb3IgYXVnbWVudCB0aGUgZmllbGREZWYgd2l0aCBhIGRlZmF1bHQgdHlwZSBpZiBtaXNzaW5nLlxuICAgICAgbm9ybWFsaXplZEZhY2V0W2NoYW5uZWxdID0gbm9ybWFsaXplKGZpZWxkRGVmLCBjaGFubmVsKTtcbiAgICAgIHJldHVybiBub3JtYWxpemVkRmFjZXQ7XG4gICAgfSwge30pO1xuICB9XG5cbiAgcHVibGljIGNoYW5uZWxIYXNGaWVsZChjaGFubmVsOiBDaGFubmVsKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5mYWNldFtjaGFubmVsXTtcbiAgfVxuXG4gIHB1YmxpYyBmaWVsZERlZihjaGFubmVsOiBDaGFubmVsKTogRmllbGREZWY8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuZmFjZXRbY2hhbm5lbF07XG4gIH1cblxuICBwdWJsaWMgcGFyc2VEYXRhKCkge1xuICAgIHRoaXMuY29tcG9uZW50LmRhdGEgPSBwYXJzZURhdGEodGhpcyk7XG4gICAgdGhpcy5jaGlsZC5wYXJzZURhdGEoKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZUxheW91dFNpemUoKSB7XG4gICAgcGFyc2VDaGlsZHJlbkxheW91dFNpemUodGhpcyk7XG4gIH1cblxuICBwdWJsaWMgcGFyc2VTZWxlY3Rpb24oKSB7XG4gICAgLy8gQXMgYSBmYWNldCBoYXMgYSBzaW5nbGUgY2hpbGQsIHRoZSBzZWxlY3Rpb24gY29tcG9uZW50cyBhcmUgdGhlIHNhbWUuXG4gICAgLy8gVGhlIGNoaWxkIG1haW50YWlucyBpdHMgc2VsZWN0aW9ucyB0byBhc3NlbWJsZSBzaWduYWxzLCB3aGljaCByZW1haW5cbiAgICAvLyB3aXRoaW4gaXRzIHVuaXQuXG4gICAgdGhpcy5jaGlsZC5wYXJzZVNlbGVjdGlvbigpO1xuICAgIHRoaXMuY29tcG9uZW50LnNlbGVjdGlvbiA9IHRoaXMuY2hpbGQuY29tcG9uZW50LnNlbGVjdGlvbjtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZU1hcmtHcm91cCgpIHtcbiAgICB0aGlzLmNoaWxkLnBhcnNlTWFya0dyb3VwKCk7XG4gIH1cblxuICBwdWJsaWMgcGFyc2VBeGlzQW5kSGVhZGVyKCkge1xuICAgIHRoaXMuY2hpbGQucGFyc2VBeGlzQW5kSGVhZGVyKCk7XG5cbiAgICB0aGlzLnBhcnNlSGVhZGVyKCdjb2x1bW4nKTtcbiAgICB0aGlzLnBhcnNlSGVhZGVyKCdyb3cnKTtcblxuICAgIHRoaXMubWVyZ2VDaGlsZEF4aXMoJ3gnKTtcbiAgICB0aGlzLm1lcmdlQ2hpbGRBeGlzKCd5Jyk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSGVhZGVyKGNoYW5uZWw6IEhlYWRlckNoYW5uZWwpIHtcblxuICAgIGlmICh0aGlzLmNoYW5uZWxIYXNGaWVsZChjaGFubmVsKSkge1xuICAgICAgY29uc3QgZmllbGREZWYgPSB0aGlzLmZhY2V0W2NoYW5uZWxdO1xuICAgICAgY29uc3QgaGVhZGVyID0gZmllbGREZWYuaGVhZGVyIHx8IHt9O1xuICAgICAgbGV0IHRpdGxlID0gaGVhZGVyLnRpdGxlICE9PSB1bmRlZmluZWQgPyBoZWFkZXIudGl0bGUgOiBmaWVsZERlZlRpdGxlKGZpZWxkRGVmLCB0aGlzLmNvbmZpZyk7XG5cbiAgICAgIGlmICh0aGlzLmNoaWxkLmNvbXBvbmVudC5sYXlvdXRIZWFkZXJzW2NoYW5uZWxdLnRpdGxlKSB7XG4gICAgICAgIC8vIG1lcmdlIHRpdGxlIHdpdGggY2hpbGQgdG8gcHJvZHVjZSBcIlRpdGxlIC8gU3VidGl0bGUgLyBTdWItc3VidGl0bGVcIlxuICAgICAgICB0aXRsZSArPSAnIC8gJyArIHRoaXMuY2hpbGQuY29tcG9uZW50LmxheW91dEhlYWRlcnNbY2hhbm5lbF0udGl0bGU7XG4gICAgICAgIHRoaXMuY2hpbGQuY29tcG9uZW50LmxheW91dEhlYWRlcnNbY2hhbm5lbF0udGl0bGUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNvbXBvbmVudC5sYXlvdXRIZWFkZXJzW2NoYW5uZWxdID0ge1xuICAgICAgICB0aXRsZSxcbiAgICAgICAgZmFjZXRGaWVsZERlZjogZmllbGREZWYsXG4gICAgICAgIC8vIFRPRE86IHN1cHBvcnQgYWRkaW5nIGxhYmVsIHRvIGZvb3RlciBhcyB3ZWxsXG4gICAgICAgIGhlYWRlcjogW3RoaXMubWFrZUhlYWRlckNvbXBvbmVudChjaGFubmVsLCB0cnVlKV1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtYWtlSGVhZGVyQ29tcG9uZW50KGNoYW5uZWw6IEhlYWRlckNoYW5uZWwsIGxhYmVsczogYm9vbGVhbik6IEhlYWRlckNvbXBvbmVudCB7XG4gICAgY29uc3Qgc2l6ZVR5cGUgPSBjaGFubmVsID09PSAncm93JyA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICAgIHJldHVybiB7XG4gICAgICBsYWJlbHMsXG4gICAgICBzaXplU2lnbmFsOiB0aGlzLmNoaWxkLmNvbXBvbmVudC5sYXlvdXRTaXplLmdldChzaXplVHlwZSkgPyB0aGlzLmNoaWxkLmdldFNpemVTaWduYWxSZWYoc2l6ZVR5cGUpIDogdW5kZWZpbmVkLFxuICAgICAgYXhlczogW11cbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBtZXJnZUNoaWxkQXhpcyhjaGFubmVsOiAneCcgfCAneScpIHtcbiAgICBjb25zdCB7Y2hpbGR9ID0gdGhpcztcbiAgICBpZiAoY2hpbGQuY29tcG9uZW50LmF4ZXNbY2hhbm5lbF0pIHtcbiAgICAgIGNvbnN0IHtsYXlvdXRIZWFkZXJzLCByZXNvbHZlfSA9IHRoaXMuY29tcG9uZW50O1xuICAgICAgcmVzb2x2ZS5heGlzW2NoYW5uZWxdID0gcGFyc2VHdWlkZVJlc29sdmUocmVzb2x2ZSwgY2hhbm5lbCk7XG5cbiAgICAgIGlmIChyZXNvbHZlLmF4aXNbY2hhbm5lbF0gPT09ICdzaGFyZWQnKSB7XG4gICAgICAgIC8vIEZvciBzaGFyZWQgYXhpcywgbW92ZSB0aGUgYXhlcyB0byBmYWNldCdzIGhlYWRlciBvciBmb290ZXJcbiAgICAgICAgY29uc3QgaGVhZGVyQ2hhbm5lbCA9IGNoYW5uZWwgPT09ICd4JyA/ICdjb2x1bW4nIDogJ3Jvdyc7XG5cbiAgICAgICAgY29uc3QgbGF5b3V0SGVhZGVyID0gbGF5b3V0SGVhZGVyc1toZWFkZXJDaGFubmVsXTtcbiAgICAgICAgZm9yIChjb25zdCBheGlzQ29tcG9uZW50IG9mIGNoaWxkLmNvbXBvbmVudC5heGVzW2NoYW5uZWxdKSB7XG4gICAgICAgICAgY29uc3QgbWFpbkF4aXMgPSBheGlzQ29tcG9uZW50Lm1haW47XG4gICAgICAgICAgY29uc3QgaGVhZGVyVHlwZSA9IGdldEhlYWRlclR5cGUobWFpbkF4aXMuZ2V0KCdvcmllbnQnKSk7XG4gICAgICAgICAgbGF5b3V0SGVhZGVyW2hlYWRlclR5cGVdID0gbGF5b3V0SGVhZGVyW2hlYWRlclR5cGVdIHx8XG4gICAgICAgICAgICBbdGhpcy5tYWtlSGVhZGVyQ29tcG9uZW50KGhlYWRlckNoYW5uZWwsIGZhbHNlKV07XG5cbiAgICAgICAgICAvLyBMYXlvdXRIZWFkZXIgbm8gbG9uZ2VyIGtlZXAgdHJhY2sgb2YgcHJvcGVydHkgcHJlY2VkZW5jZSwgdGh1cyBsZXQncyBjb21iaW5lLlxuICAgICAgICAgIGxheW91dEhlYWRlcltoZWFkZXJUeXBlXVswXS5heGVzLnB1c2gobWFpbkF4aXMuY29tYmluZSgpIGFzIFZnQXhpcyk7XG4gICAgICAgICAgZGVsZXRlIGF4aXNDb21wb25lbnQubWFpbjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gT3RoZXJ3aXNlIGRvIG5vdGhpbmcgZm9yIGluZGVwZW5kZW50IGF4ZXNcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVTZWxlY3Rpb25Ub3BMZXZlbFNpZ25hbHMoc2lnbmFsczogYW55W10pOiBWZ1NpZ25hbFtdIHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZC5hc3NlbWJsZVNlbGVjdGlvblRvcExldmVsU2lnbmFscyhzaWduYWxzKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZVNlbGVjdGlvblNpZ25hbHMoKTogVmdTaWduYWxbXSB7XG4gICAgdGhpcy5jaGlsZC5hc3NlbWJsZVNlbGVjdGlvblNpZ25hbHMoKTtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVTZWxlY3Rpb25EYXRhKGRhdGE6IFZnRGF0YVtdKTogVmdEYXRhW10ge1xuICAgIHJldHVybiB0aGlzLmNoaWxkLmFzc2VtYmxlU2VsZWN0aW9uRGF0YShkYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TGF5b3V0QmFuZE1peGlucyhoZWFkZXJUeXBlOiAnaGVhZGVyJyB8ICdmb290ZXInKToge1xuICAgIGhlYWRlckJhbmQ/OiBSb3dDb2w8bnVtYmVyPixcbiAgICBmb290ZXJCYW5kPzogUm93Q29sPG51bWJlcj5cbiAgfSB7XG4gICAgY29uc3QgYmFuZE1peGlucyA9IHt9O1xuXG4gICAgY29uc3QgYmFuZFR5cGUgPSBoZWFkZXJUeXBlID09PSAnaGVhZGVyJyA/ICdoZWFkZXJCYW5kJyA6ICdmb290ZXJCYW5kJztcblxuICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBbJ3JvdycsICdjb2x1bW4nXSBhcyAoJ3JvdycgfCAnY29sdW1uJylbXSkge1xuICAgICAgY29uc3QgbGF5b3V0SGVhZGVyQ29tcG9uZW50ID0gdGhpcy5jb21wb25lbnQubGF5b3V0SGVhZGVyc1tjaGFubmVsXTtcbiAgICAgIGNvbnN0IGhlYWRlckNvbXBvbmVudCA9IGxheW91dEhlYWRlckNvbXBvbmVudFtoZWFkZXJUeXBlXTtcbiAgICAgIGlmIChoZWFkZXJDb21wb25lbnQgJiYgaGVhZGVyQ29tcG9uZW50WzBdKSB7XG4gICAgICAgIGNvbnN0IHNpemVUeXBlID0gY2hhbm5lbCA9PT0gJ3JvdycgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgICAgICAgaWYgKCF0aGlzLmNoaWxkLmNvbXBvbmVudC5sYXlvdXRTaXplLmdldChzaXplVHlwZSkpIHtcbiAgICAgICAgICAvLyBJZiBmYWNldCBjaGlsZCBkb2VzIG5vdCBoYXZlIHNpemUgc2lnbmFsLCB0aGVuIGFwcGx5IGhlYWRlckJhbmRcbiAgICAgICAgICBiYW5kTWl4aW5zW2JhbmRUeXBlXSA9IGJhbmRNaXhpbnNbYmFuZFR5cGVdIHx8IHt9O1xuICAgICAgICAgIGJhbmRNaXhpbnNbYmFuZFR5cGVdW2NoYW5uZWxdID0gMC41O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBiYW5kTWl4aW5zO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTGF5b3V0KCk6IFZnTGF5b3V0IHtcbiAgICBjb25zdCBjb2x1bW5zID0gdGhpcy5jaGFubmVsSGFzRmllbGQoJ2NvbHVtbicpID8gdGhpcy5jb2x1bW5EaXN0aW5jdFNpZ25hbCgpIDogMTtcblxuICAgIC8vIFRPRE86IGRldGVybWluZSBkZWZhdWx0IGFsaWduIGJhc2VkIG9uIHNoYXJlZCAvIGluZGVwZW5kZW50IHNjYWxlc1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBhZGRpbmc6IHtyb3c6IDEwLCBjb2x1bW46IDEwfSxcbiAgICAgIC4uLnRoaXMuZ2V0TGF5b3V0QmFuZE1peGlucygnaGVhZGVyJyksXG4gICAgICAuLi50aGlzLmdldExheW91dEJhbmRNaXhpbnMoJ2Zvb3RlcicpLFxuXG4gICAgICAvLyBUT0RPOiBzdXBwb3J0IG9mZnNldCBmb3Igcm93SGVhZGVyL3Jvd0Zvb3Rlci9yb3dUaXRsZS9jb2x1bW5IZWFkZXIvY29sdW1uRm9vdGVyL2NvbHVtblRpdGxlXG4gICAgICBvZmZzZXQ6IDEwLFxuICAgICAgY29sdW1ucyxcbiAgICAgIGJvdW5kczogJ2Z1bGwnLFxuICAgICAgYWxpZ246ICdhbGwnXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZUxheW91dFNpZ25hbHMoKTogVmdTaWduYWxbXSB7XG4gICAgLy8gRklYTUUoaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8xMTkzKTogdGhpcyBjYW4gYmUgaW5jb3JyZWN0IGlmIHdlIGhhdmUgaW5kZXBlbmRlbnQgc2NhbGVzLlxuICAgIHJldHVybiB0aGlzLmNoaWxkLmFzc2VtYmxlTGF5b3V0U2lnbmFscygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb2x1bW5EaXN0aW5jdFNpZ25hbCgpIHtcbiAgICBpZiAodGhpcy5wYXJlbnQgJiYgKHRoaXMucGFyZW50IGluc3RhbmNlb2YgRmFjZXRNb2RlbCkpIHtcbiAgICAgIC8vIEZvciBuZXN0ZWQgZmFjZXQsIHdlIHdpbGwgYWRkIGNvbHVtbnMgdG8gZ3JvdXAgbWFyayBpbnN0ZWFkXG4gICAgICAvLyBTZWUgZGlzY3Vzc2lvbiBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhL2lzc3Vlcy85NTJcbiAgICAgIC8vIGFuZCBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLXZpZXcvcmVsZWFzZXMvdGFnL3YxLjIuNlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSW4gZmFjZXROb2RlLmFzc2VtYmxlKCksIHRoZSBuYW1lIGlzIGFsd2F5cyB0aGlzLmdldE5hbWUoJ2NvbHVtbicpICsgJ19sYXlvdXQnLlxuICAgICAgY29uc3QgZmFjZXRMYXlvdXREYXRhTmFtZSA9IHRoaXMuZ2V0TmFtZSgnY29sdW1uX2RvbWFpbicpO1xuICAgICAgcmV0dXJuIHtzaWduYWw6IGBsZW5ndGgoZGF0YSgnJHtmYWNldExheW91dERhdGFOYW1lfScpKWB9O1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZUdyb3VwKHNpZ25hbHM6IFZnU2lnbmFsW10pIHtcbiAgICBpZiAodGhpcy5wYXJlbnQgJiYgKHRoaXMucGFyZW50IGluc3RhbmNlb2YgRmFjZXRNb2RlbCkpIHtcbiAgICAgIC8vIFByb3ZpZGUgbnVtYmVyIG9mIGNvbHVtbnMgZm9yIGxheW91dC5cbiAgICAgIC8vIFNlZSBkaXNjdXNzaW9uIGluIGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EvaXNzdWVzLzk1MlxuICAgICAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2Etdmlldy9yZWxlYXNlcy90YWcvdjEuMi42XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4odGhpcy5jaGFubmVsSGFzRmllbGQoJ2NvbHVtbicpID8ge1xuICAgICAgICAgIGVuY29kZToge1xuICAgICAgICAgICAgdXBkYXRlOiB7XG4gICAgICAgICAgICAgIC8vIFRPRE8oaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yNzU5KTpcbiAgICAgICAgICAgICAgLy8gQ29ycmVjdCB0aGUgc2lnbmFsIGZvciBmYWNldCBvZiBjb25jYXQgb2YgZmFjZXRfY29sdW1uXG4gICAgICAgICAgICAgIGNvbHVtbnM6IHtmaWVsZDogZmllbGQodGhpcy5mYWNldC5jb2x1bW4sIHtwcmVmaXg6ICdkaXN0aW5jdCd9KX1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gOiB7fSksXG4gICAgICAgIC4uLnN1cGVyLmFzc2VtYmxlR3JvdXAoc2lnbmFscylcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBzdXBlci5hc3NlbWJsZUdyb3VwKHNpZ25hbHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFnZ3JlZ2F0ZSBjYXJkaW5hbGl0eSBmb3IgY2FsY3VsYXRpbmcgc2l6ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRDYXJkaW5hbGl0eUFnZ3JlZ2F0ZUZvckNoaWxkKCkge1xuICAgIGNvbnN0IGZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBvcHM6IEFnZ3JlZ2F0ZU9wW10gPSBbXTtcbiAgICBpZiAodGhpcy5jaGlsZCBpbnN0YW5jZW9mIEZhY2V0TW9kZWwpIHtcbiAgICAgIGlmICh0aGlzLmNoaWxkLmNoYW5uZWxIYXNGaWVsZCgnY29sdW1uJykpIHtcbiAgICAgICAgZmllbGRzLnB1c2goZmllbGQodGhpcy5jaGlsZC5mYWNldC5jb2x1bW4pKTtcbiAgICAgICAgb3BzLnB1c2goJ2Rpc3RpbmN0Jyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBbJ3gnLCAneSddIGFzIFNjYWxlQ2hhbm5lbFtdKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkU2NhbGVDb21wb25lbnQgPSB0aGlzLmNoaWxkLmNvbXBvbmVudC5zY2FsZXNbY2hhbm5lbF07XG4gICAgICAgIGlmIChjaGlsZFNjYWxlQ29tcG9uZW50ICYmICFjaGlsZFNjYWxlQ29tcG9uZW50Lm1lcmdlZCkge1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBjaGlsZFNjYWxlQ29tcG9uZW50LmdldCgndHlwZScpO1xuICAgICAgICAgIGNvbnN0IHJhbmdlID0gY2hpbGRTY2FsZUNvbXBvbmVudC5nZXQoJ3JhbmdlJyk7XG5cbiAgICAgICAgICBpZiAoaGFzRGlzY3JldGVEb21haW4odHlwZSkgJiYgaXNWZ1JhbmdlU3RlcChyYW5nZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRvbWFpbiA9IGFzc2VtYmxlRG9tYWluKHRoaXMuY2hpbGQsIGNoYW5uZWwpO1xuICAgICAgICAgICAgY29uc3QgZmllbGQgPSBnZXRGaWVsZEZyb21Eb21haW4oZG9tYWluKTtcbiAgICAgICAgICAgIGlmIChmaWVsZCkge1xuICAgICAgICAgICAgICBmaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgICAgICAgIG9wcy5wdXNoKCdkaXN0aW5jdCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbG9nLndhcm4oJ1Vua25vd24gZmllbGQgZm9yICR7Y2hhbm5lbH0uICBDYW5ub3QgY2FsY3VsYXRlIHZpZXcgc2l6ZS4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZpZWxkcy5sZW5ndGggPyB7ZmllbGRzLCBvcHN9IDogdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTWFya3MoKTogVmdNYXJrR3JvdXBbXSB7XG4gICAgY29uc3Qge2NoaWxkLCBmYWNldH0gPSB0aGlzO1xuICAgIGNvbnN0IGZhY2V0Um9vdCA9IHRoaXMuY29tcG9uZW50LmRhdGEuZmFjZXRSb290O1xuICAgIGNvbnN0IGRhdGEgPSBhc3NlbWJsZUZhY2V0RGF0YShmYWNldFJvb3QpO1xuXG4gICAgLy8gSWYgd2UgZmFjZXQgYnkgdHdvIGRpbWVuc2lvbnMsIHdlIG5lZWQgdG8gYWRkIGEgY3Jvc3Mgb3BlcmF0b3IgdG8gdGhlIGFnZ3JlZ2F0aW9uXG4gICAgLy8gc28gdGhhdCB3ZSBjcmVhdGUgYWxsIGdyb3Vwc1xuICAgIGNvbnN0IGhhc1JvdyA9IHRoaXMuY2hhbm5lbEhhc0ZpZWxkKFJPVyk7XG4gICAgY29uc3QgaGFzQ29sdW1uID0gdGhpcy5jaGFubmVsSGFzRmllbGQoQ09MVU1OKTtcbiAgICBjb25zdCBsYXlvdXRTaXplRW5jb2RlRW50cnkgPSBjaGlsZC5hc3NlbWJsZUxheW91dFNpemUoKTtcblxuICAgIGNvbnN0IGFnZ3JlZ2F0ZU1peGluczogYW55ID0ge307XG4gICAgaWYgKGhhc1JvdyAmJiBoYXNDb2x1bW4pIHtcbiAgICAgIGFnZ3JlZ2F0ZU1peGlucy5hZ2dyZWdhdGUgPSB7Y3Jvc3M6IHRydWV9O1xuICAgIH1cbiAgICBjb25zdCBjYXJkaW5hbGl0eUFnZ3JlZ2F0ZUZvckNoaWxkID0gdGhpcy5nZXRDYXJkaW5hbGl0eUFnZ3JlZ2F0ZUZvckNoaWxkKCk7XG4gICAgaWYgKGNhcmRpbmFsaXR5QWdncmVnYXRlRm9yQ2hpbGQpIHtcbiAgICAgIGFnZ3JlZ2F0ZU1peGlucy5hZ2dyZWdhdGUgPSB7XG4gICAgICAgIC4uLmFnZ3JlZ2F0ZU1peGlucy5hZ2dyZWdhdGUsXG4gICAgICAgIC4uLmNhcmRpbmFsaXR5QWdncmVnYXRlRm9yQ2hpbGRcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGUgPSBjaGlsZC5hc3NlbWJsZVRpdGxlKCk7XG4gICAgY29uc3Qgc3R5bGUgPSBjaGlsZC5hc3NlbWJsZUdyb3VwU3R5bGUoKTtcblxuICAgIGNvbnN0IG1hcmtHcm91cCA9IHtcbiAgICAgIG5hbWU6IHRoaXMuZ2V0TmFtZSgnY2VsbCcpLFxuICAgICAgdHlwZTogJ2dyb3VwJyxcbiAgICAgIC4uLih0aXRsZT8ge3RpdGxlfSA6IHt9KSxcbiAgICAgIC4uLihzdHlsZT8ge3N0eWxlfSA6IHt9KSxcbiAgICAgIGZyb206IHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICBuYW1lOiBmYWNldFJvb3QubmFtZSxcbiAgICAgICAgICBkYXRhOiBmYWNldFJvb3QuZGF0YSxcbiAgICAgICAgICBncm91cGJ5OiBbXS5jb25jYXQoXG4gICAgICAgICAgICBoYXNSb3cgPyBbdGhpcy5maWVsZChST1cpXSA6IFtdLFxuICAgICAgICAgICAgaGFzQ29sdW1uID8gW3RoaXMuZmllbGQoQ09MVU1OKV0gOiBbXVxuICAgICAgICAgICksXG4gICAgICAgICAgLi4uYWdncmVnYXRlTWl4aW5zXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzb3J0OiB7XG4gICAgICAgIGZpZWxkOiBbXS5jb25jYXQoXG4gICAgICAgICAgaGFzUm93ID8gW3RoaXMuZmllbGQoUk9XLCB7ZXhwcjogJ2RhdHVtJyx9KV0gOiBbXSxcbiAgICAgICAgICBoYXNDb2x1bW4gPyBbdGhpcy5maWVsZChDT0xVTU4sIHtleHByOiAnZGF0dW0nfSldIDogW11cbiAgICAgICAgKSxcbiAgICAgICAgb3JkZXI6IFtdLmNvbmNhdChcbiAgICAgICAgICBoYXNSb3cgPyBbIChmYWNldC5yb3cuc29ydCkgfHwgJ2FzY2VuZGluZyddIDogW10sXG4gICAgICAgICAgaGFzQ29sdW1uID8gWyAoZmFjZXQuY29sdW1uLnNvcnQpIHx8ICdhc2NlbmRpbmcnXSA6IFtdXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICAuLi4oZGF0YS5sZW5ndGggPiAwID8ge2RhdGE6IGRhdGF9IDoge30pLFxuICAgICAgLi4uKGxheW91dFNpemVFbmNvZGVFbnRyeSA/IHtlbmNvZGU6IHt1cGRhdGU6IGxheW91dFNpemVFbmNvZGVFbnRyeX19IDoge30pLFxuICAgICAgLi4uY2hpbGQuYXNzZW1ibGVHcm91cCgpXG4gICAgfTtcblxuICAgIHJldHVybiBbbWFya0dyb3VwXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRNYXBwaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmZhY2V0O1xuICB9XG59XG4iXX0= \ 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..f4a55e72e0 --- /dev/null +++ b/build/src/compile/layer.d.ts @@ -0,0 +1,23 @@ +import { Config } from '../config'; +import { LayerSpec, LayoutSizeMixins } 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: LayerSpec, 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..14aa739993 --- /dev/null +++ b/build/src/compile/layer.js @@ -0,0 +1,134 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var spec_1 = require("../spec"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var parse_2 = require("./data/parse"); +var assemble_1 = require("./layoutsize/assemble"); +var parse_3 = require("./layoutsize/parse"); +var assemble_2 = require("./legend/assemble"); +var model_1 = require("./model"); +var selection_1 = require("./selection/selection"); +var unit_1 = require("./unit"); +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, 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 (spec_1.isLayerSpec(layer)) { + return new LayerModel(layer, _this, _this.getName('layer_' + i), layoutSize, repeater, config, fit); + } + if (spec_1.isUnitSpec(layer)) { + return new unit_1.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 = parse_2.parseData(this); + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseData(); + } + }; + LayerModel.prototype.parseLayoutSize = function () { + parse_3.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(); + util_1.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 () { + parse_1.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()); + }, assemble_1.assembleLayoutSignals(this)); + }; + LayerModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, []); + }; + 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 selection_1.assembleLayerSelectionMarks(this, util_1.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()); + }, assemble_2.assembleLegends(this)); + }; + return LayerModel; +}(model_1.Model)); +exports.LayerModel = LayerModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9sYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLDRCQUE4QjtBQUM5QixnQ0FBNkU7QUFDN0UsZ0NBQXNDO0FBRXRDLHNDQUE0QztBQUM1QyxzQ0FBdUM7QUFDdkMsa0RBQTREO0FBQzVELDRDQUF3RDtBQUN4RCw4Q0FBa0Q7QUFDbEQsaUNBQThCO0FBRTlCLG1EQUFrRTtBQUNsRSwrQkFBaUM7QUFHakM7SUFBZ0MsOEJBQUs7SUFTbkMsb0JBQVksSUFBZSxFQUFFLE1BQWEsRUFBRSxlQUF1QixFQUNqRSxlQUFpQyxFQUFFLFFBQXVCLEVBQUUsTUFBYyxFQUFFLEdBQVk7UUFEMUYsWUFHRSxrQkFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQXFCM0Q7UUFoQ2UsVUFBSSxHQUFZLE9BQU8sQ0FBQztRQWF0QyxJQUFNLFVBQVUsZ0JBQ1gsZUFBZSxFQUNmLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDdkMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUM5QyxDQUFDO1FBRUYsS0FBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUUxQixLQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEMsRUFBRSxDQUFDLENBQUMsa0JBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JB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QUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBQyxLQUFLO1lBQ3ZFLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVNLG9DQUFlLEdBQXRCO1FBQ0UsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQUMsT0FBTyxFQUFFLEtBQUs7WUFDekMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDakQsQ0FBQyxFQUFFLDBCQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBQ0gsaUJBQUM7QUFBRCxDQUFDLEFBekhELENBQWdDLGFBQUssR0F5SHBDO0FBekhZLGdDQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vbG9nJztcbmltcG9ydCB7aXNMYXllclNwZWMsIGlzVW5pdFNwZWMsIExheWVyU3BlYywgTGF5b3V0U2l6ZU1peGluc30gZnJvbSAnLi4vc3BlYyc7XG5pbXBvcnQge2ZsYXR0ZW4sIGtleXN9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0RhdGEsIFZnTGF5b3V0LCBWZ0xlZ2VuZCwgVmdTaWduYWwsIFZnVGl0bGV9IGZyb20gJy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7cGFyc2VMYXllckF4aXN9IGZyb20gJy4vYXhpcy9wYXJzZSc7XG5pbXBvcnQge3BhcnNlRGF0YX0gZnJvbSAnLi9kYXRhL3BhcnNlJztcbmltcG9ydCB7YXNzZW1ibGVMYXlvdXRTaWduYWxzfSBmcm9tICcuL2xheW91dHNpemUvYXNzZW1ibGUnO1xuaW1wb3J0IHtwYXJzZUxheWVyTGF5b3V0U2l6ZX0gZnJvbSAnLi9sYXlvdXRzaXplL3BhcnNlJztcbmltcG9ydCB7YXNzZW1ibGVMZWdlbmRzfSBmcm9tICcuL2xlZ2VuZC9hc3NlbWJsZSc7XG5pbXBvcnQge01vZGVsfSBmcm9tICcuL21vZGVsJztcbmltcG9ydCB7UmVwZWF0ZXJWYWx1ZX0gZnJvbSAnLi9yZXBlYXRlcic7XG5pbXBvcnQge2Fzc2VtYmxlTGF5ZXJTZWxlY3Rpb25NYXJrc30gZnJvbSAnLi9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuL3VuaXQnO1xuXG5cbmV4cG9ydCBjbGFzcyBMYXllck1vZGVsIGV4dGVuZHMgTW9kZWwge1xuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogJ2xheWVyJyA9ICdsYXllcic7XG5cbiAgLy8gSEFDSzogVGhpcyBzaG91bGQgYmUgKExheWVyTW9kZWwgfCBVbml0TW9kZWwpW10sIGJ1dCBzZXR0aW5nIHRoZSBjb3JyZWN0IHR5cGUgbGVhZHMgdG8gd2VpcmQgZXJyb3IuXG4gIC8vIFNvIEknbSBqdXN0IHB1dHRpbmcgZ2VuZXJpYyBNb2RlbCBmb3Igbm93LlxuICBwdWJsaWMgcmVhZG9ubHkgY2hpbGRyZW46IE1vZGVsW107XG5cblxuXG4gIGNvbnN0cnVjdG9yKHNwZWM6IExheWVyU3BlYywgcGFyZW50OiBNb2RlbCwgcGFyZW50R2l2ZW5OYW1lOiBzdHJpbmcsXG4gICAgcGFyZW50R2l2ZW5TaXplOiBMYXlvdXRTaXplTWl4aW5zLCByZXBlYXRlcjogUmVwZWF0ZXJWYWx1ZSwgY29uZmlnOiBDb25maWcsIGZpdDogYm9vbGVhbikge1xuXG4gICAgc3VwZXIoc3BlYywgcGFyZW50LCBwYXJlbnRHaXZlbk5hbWUsIGNvbmZpZywgc3BlYy5yZXNvbHZlKTtcblxuICAgIGNvbnN0IGxheW91dFNpemUgPSB7XG4gICAgICAuLi5wYXJlbnRHaXZlblNpemUsXG4gICAgICAuLi4oc3BlYy53aWR0aCA/IHt3aWR0aDogc3BlYy53aWR0aH0gOiB7fSksXG4gICAgICAuLi4oc3BlYy5oZWlnaHQgPyB7aGVpZ2h0OiBzcGVjLmhlaWdodH0gOiB7fSlcbiAgICB9O1xuXG4gICAgdGhpcy5pbml0U2l6ZShsYXlvdXRTaXplKTtcblxuICAgIHRoaXMuY2hpbGRyZW4gPSBzcGVjLmxheWVyLm1hcCgobGF5ZXIsIGkpID0+IHtcbiAgICAgIGlmIChpc0xheWVyU3BlYyhsYXllcikpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBMYXllck1vZGVsKGxheWVyLCB0aGlzLCB0aGlzLmdldE5hbWUoJ2xheWVyXycraSksIGxheW91dFNpemUsIHJlcGVhdGVyLCBjb25maWcsIGZpdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1VuaXRTcGVjKGxheWVyKSkge1xuICAgICAgICByZXR1cm4gbmV3IFVuaXRNb2RlbChsYXllciwgdGhpcywgdGhpcy5nZXROYW1lKCdsYXllcl8nK2kpLCBsYXlvdXRTaXplLCByZXBlYXRlciwgY29uZmlnLCBmaXQpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IobG9nLm1lc3NhZ2UuSU5WQUxJRF9TUEVDKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZURhdGEoKSB7XG4gICAgdGhpcy5jb21wb25lbnQuZGF0YSA9IHBhcnNlRGF0YSh0aGlzKTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHtcbiAgICAgIGNoaWxkLnBhcnNlRGF0YSgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBwYXJzZUxheW91dFNpemUoKSB7XG4gICAgcGFyc2VMYXllckxheW91dFNpemUodGhpcyk7XG4gIH1cblxuICBwdWJsaWMgcGFyc2VTZWxlY3Rpb24oKSB7XG4gICAgLy8gTWVyZ2Ugc2VsZWN0aW9ucyB1cCB0aGUgaGllcmFyY2h5IHNvIHRoYXQgdGhleSBtYXkgYmUgcmVmZXJlbmNlZFxuICAgIC8vIGFjcm9zcyB1bml0IHNwZWNzLiBQZXJzaXN0IHRoZWlyIGRlZmluaXRpb25zIHdpdGhpbiBlYWNoIGNoaWxkXG4gICAgLy8gdG8gYXNzZW1ibGUgc2lnbmFscyB3aGljaCByZW1haW4gd2l0aGluIG91dHB1dCBWZWdhIHVuaXQgZ3JvdXBzLlxuICAgIHRoaXMuY29tcG9uZW50LnNlbGVjdGlvbiA9IHt9O1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgY2hpbGQucGFyc2VTZWxlY3Rpb24oKTtcbiAgICAgIGtleXMoY2hpbGQuY29tcG9uZW50LnNlbGVjdGlvbikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIHRoaXMuY29tcG9uZW50LnNlbGVjdGlvbltrZXldID0gY2hpbGQuY29tcG9uZW50LnNlbGVjdGlvbltrZXldO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBhcnNlTWFya0dyb3VwKCkge1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgY2hpbGQucGFyc2VNYXJrR3JvdXAoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcGFyc2VBeGlzQW5kSGVhZGVyKCkge1xuICAgIHBhcnNlTGF5ZXJBeGlzKHRoaXMpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlU2VsZWN0aW9uVG9wTGV2ZWxTaWduYWxzKHNpZ25hbHM6IGFueVtdKTogVmdTaWduYWxbXSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4ucmVkdWNlKChzZywgY2hpbGQpID0+IGNoaWxkLmFzc2VtYmxlU2VsZWN0aW9uVG9wTGV2ZWxTaWduYWxzKHNnKSwgc2lnbmFscyk7XG4gIH1cblxuICAvLyBUT0RPOiBTdXBwb3J0IHNhbWUgbmFtZWQgc2VsZWN0aW9ucyBhY3Jvc3MgY2hpbGRyZW4uXG4gIHB1YmxpYyBhc3NlbWJsZVNlbGVjdGlvblNpZ25hbHMoKTogVmdTaWduYWxbXSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4ucmVkdWNlKChzaWduYWxzLCBjaGlsZCkgPT4ge1xuICAgICAgcmV0dXJuIHNpZ25hbHMuY29uY2F0KGNoaWxkLmFzc2VtYmxlU2VsZWN0aW9uU2lnbmFscygpKTtcbiAgICB9LCBbXSk7XG4gIH1cblxuXG4gIHB1YmxpYyBhc3NlbWJsZUxheW91dFNpZ25hbHMoKTogVmdTaWduYWxbXSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4ucmVkdWNlKChzaWduYWxzLCBjaGlsZCkgPT4ge1xuICAgICAgcmV0dXJuIHNpZ25hbHMuY29uY2F0KGNoaWxkLmFzc2VtYmxlTGF5b3V0U2lnbmFscygpKTtcbiAgICB9LCBhc3NlbWJsZUxheW91dFNpZ25hbHModGhpcykpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlU2VsZWN0aW9uRGF0YShkYXRhOiBWZ0RhdGFbXSk6IFZnRGF0YVtdIHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5yZWR1Y2UoKGRiLCBjaGlsZCkgPT4gY2hpbGQuYXNzZW1ibGVTZWxlY3Rpb25EYXRhKGRiKSwgW10pO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlVGl0bGUoKTogVmdUaXRsZSB7XG4gICAgbGV0IHRpdGxlID0gc3VwZXIuYXNzZW1ibGVUaXRsZSgpO1xuICAgIGlmICh0aXRsZSkge1xuICAgICAgcmV0dXJuIHRpdGxlO1xuICAgIH1cbiAgICAvLyBJZiB0aXRsZSBkb2VzIG5vdCBwcm92aWRlIGxheWVyLCBsb29rIGludG8gY2hpbGRyZW5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHtcbiAgICAgIHRpdGxlID0gY2hpbGQuYXNzZW1ibGVUaXRsZSgpO1xuICAgICAgaWYgKHRpdGxlKSB7XG4gICAgICAgIHJldHVybiB0aXRsZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZUxheW91dCgpOiBWZ0xheW91dCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVNYXJrcygpOiBhbnlbXSB7XG4gICAgcmV0dXJuIGFzc2VtYmxlTGF5ZXJTZWxlY3Rpb25NYXJrcyh0aGlzLCBmbGF0dGVuKHRoaXMuY2hpbGRyZW4ubWFwKChjaGlsZCkgPT4ge1xuICAgICAgcmV0dXJuIGNoaWxkLmFzc2VtYmxlTWFya3MoKTtcbiAgICB9KSkpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTGVnZW5kcygpOiBWZ0xlZ2VuZFtdIHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5yZWR1Y2UoKGxlZ2VuZHMsIGNoaWxkKSA9PiB7XG4gICAgICByZXR1cm4gbGVnZW5kcy5jb25jYXQoY2hpbGQuYXNzZW1ibGVMZWdlbmRzKCkpO1xuICAgIH0sIGFzc2VtYmxlTGVnZW5kcyh0aGlzKSk7XG4gIH1cbn1cbiJdfQ== \ 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..250a9c4f23 --- /dev/null +++ b/build/src/compile/layout/header.d.ts @@ -0,0 +1,55 @@ +/** + * Utility for generating row / column headers + */ +import { FacetFieldDef } from '../../facet'; +import { AxisOrient, VgAxis } 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: { + type: string; + role: string; + style: string; + }[]; +}; +export declare function getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent): { + name: string; + type: string; + role: string; +}; diff --git a/build/src/compile/layout/header.js b/build/src/compile/layout/header.js new file mode 100644 index 0000000000..1b83d5fcd9 --- /dev/null +++ b/build/src/compile/layout/header.js @@ -0,0 +1,70 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +exports.HEADER_CHANNELS = ['row', 'column']; +exports.HEADER_TYPES = ['header', 'footer']; +function getHeaderType(orient) { + if (orient === 'top' || orient === 'left') { + return 'header'; + } + return 'footer'; +} +exports.getHeaderType = getHeaderType; +function getTitleGroup(model, channel) { + var title = model.component.layoutHeaders[channel].title; + var textOrient = channel === 'row' ? 'vertical' : undefined; + var update = __assign({ align: { value: 'center' }, text: { value: title } }, (textOrient === 'vertical' ? { angle: { value: 270 } } : {})); + return { + name: model.getName(channel + "_title"), + role: channel + "-title", + type: 'group', + marks: [__assign({ type: 'text', role: channel + "-title-text", style: 'guide-title' }, (util_1.keys(update).length > 0 ? { encode: { update: update } } : {}))] + }; +} +exports.getTitleGroup = getTitleGroup; +function getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt) { + if (headerCmpt) { + var title = null; + if (layoutHeader.facetFieldDef && headerCmpt.labels) { + var facetFieldDef = layoutHeader.facetFieldDef; + var _a = facetFieldDef.header, header = _a === void 0 ? {} : _a; + var format = header.format, labelAngle = header.labelAngle; + var update = __assign({}, (labelAngle ? { angle: { value: labelAngle } } : {}) + // TODO(https://github.com/vega/vega-lite/issues/2446): apply label* (e.g, labelAlign, labelBaseline) here + ); + title = __assign({ text: common_1.formatSignalRef(facetFieldDef, format, 'parent', model.config), offset: 10, orient: channel === 'row' ? 'left' : 'top', style: 'guide-label' }, (util_1.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 __assign({ name: model.getName(channel + "_" + headerType), type: 'group', role: channel + "-" + headerType }, (layoutHeader.facetFieldDef ? { + from: { data: model.getName(channel + '_domain') }, + sort: { + field: fielddef_1.field(layoutHeader.facetFieldDef, { expr: 'datum' }), + order: (layoutHeader.facetFieldDef.header && layoutHeader.facetFieldDef.sort) || 'ascending' + } + } : {}), (title ? { title: title } : {}), (headerCmpt.sizeSignal ? { + encode: { + update: (_b = {}, + _b[sizeChannel] = headerCmpt.sizeSignal, + _b) + } + } : {}), (hasAxes ? { axes: axes } : {})); + } + } + return null; + var _b; +} +exports.getHeaderGroup = getHeaderGroup; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGF5b3V0L2hlYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBSUEsMkNBQXFDO0FBQ3JDLG1DQUFnQztBQUVoQyxvQ0FBMEM7QUFJN0IsUUFBQSxlQUFlLEdBQW9CLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBR3JELFFBQUEsWUFBWSxHQUFpQixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQXdDL0QsdUJBQThCLE1BQWtCO0lBQzlDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sS0FBSyxLQUFLLElBQUksTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBTEQsc0NBS0M7QUFFRCx1QkFBOEIsS0FBWSxFQUFFLE9BQXNCO0lBQ2hFLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUMzRCxJQUFNLFVBQVUsR0FBRyxPQUFPLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUU5RCxJQUFNLE1BQU0sY0FDVixLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLEVBQ3hCLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUMsSUFDakIsQ0FBQyxVQUFVLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsRUFBQyxDQUFBLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FHM0QsQ0FBQztJQUVGLE1BQU0sQ0FBQztRQUNMLElBQUksRUFBRyxLQUFLLENBQUMsT0FB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LENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFDLEtBQUssT0FBQSxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUN0QixDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUMxQixNQUFNLEVBQUU7b0JBQ04sTUFBTTt3QkFDSixHQUFDLFdBQVcsSUFBRyxVQUFVLENBQUMsVUFBVTsyQkFDckM7aUJBQ0Y7YUFDRixDQUFBLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDSCxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLE1BQUEsRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDMUI7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7O0FBQ2QsQ0FBQztBQXZERCx3Q0F1REMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFV0aWxpdHkgZm9yIGdlbmVyYXRpbmcgcm93IC8gY29sdW1uIGhlYWRlcnNcbiAqL1xuaW1wb3J0IHtGYWNldEZpZWxkRGVmfSBmcm9tICcuLi8uLi9mYWNldCc7XG5pbXBvcnQge2ZpZWxkfSBmcm9tICcuLi8uLi9maWVsZGRlZic7XG5pbXBvcnQge2tleXN9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtBeGlzT3JpZW50LCBWZ0F4aXN9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7Zm9ybWF0U2lnbmFsUmVmfSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi4vbW9kZWwnO1xuXG5leHBvcnQgdHlwZSBIZWFkZXJDaGFubmVsID0gJ3JvdycgfCAnY29sdW1uJztcbmV4cG9ydCBjb25zdCBIRUFERVJfQ0hBTk5FTFM6IEhlYWRlckNoYW5uZWxbXSA9IFsncm93JywgJ2NvbHVtbiddO1xuXG5leHBvcnQgdHlwZSBIZWFkZXJUeXBlID0gJ2hlYWRlcicgfCAnZm9vdGVyJztcbmV4cG9ydCBjb25zdCBIRUFERVJfVFlQRVM6IEhlYWRlclR5cGVbXSA9IFsnaGVhZGVyJywgJ2Zvb3RlciddO1xuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgcmVwcmVzZW50cyBhbGwgaGVhZGVyLCBmb290ZXJzIGFuZCB0aXRsZSBvZiBhIFZlZ2EgZ3JvdXAgd2l0aCBsYXlvdXQgZGlyZWN0aXZlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExheW91dEhlYWRlckNvbXBvbmVudCB7XG4gIHRpdGxlPzogc3RyaW5nO1xuXG4gIC8vIFRPRE86IHJlcGVhdCBhbmQgY29uY2F0IGNhbiBoYXZlIG11bHRpcGxlIGhlYWRlciAvIGZvb3Rlci5cbiAgLy8gTmVlZCB0byByZWRlc2lnbiB0aGlzIHBhcnQgYSBiaXQuXG5cbiAgZmFjZXRGaWVsZERlZj86IEZhY2V0RmllbGREZWY8c3RyaW5nPjtcblxuICAvKipcbiAgICogQW4gYXJyYXkgb2YgaGVhZGVyIGNvbXBvbmVudHMgZm9yIGhlYWRlcnMuXG4gICAqIEZvciBmYWNldCwgdGhlcmUgc2hvdWxkIGJlIG9ubHkgb25lIGhlYWRlciBjb21wb25lbnQsIHdoaWNoIGlzIGRhdGEtZHJpdmVuLlxuICAgKiBGb3IgcmVwZWF0IGFuZCBjb25jYXQsIHRoZXJlIGNhbiBiZSBtdWx0aXBsZSBoZWFkZXIgY29tcG9uZW50cyB0aGF0IGV4cGxpY2l0bHkgbGlzdCBkaWZmZXJlbnQgYXhlcy5cbiAgICovXG4gIGhlYWRlcj86IEhlYWRlckNvbXBvbmVudFtdO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBoZWFkZXIgY29tcG9uZW50cyBmb3IgZm9vdGVycy5cbiAgICogRm9yIGZhY2V0LCB0aGVyZSBzaG91bGQgYmUgb25seSBvbmUgaGVhZGVyIGNvbXBvbmVudCwgd2hpY2ggaXMgZGF0YS1kcml2ZW4uXG4gICAqIEZvciByZXBlYXQgYW5kIGNvbmNhdCwgdGhlcmUgY2FuIGJlIG11bHRpcGxlIGhlYWRlciBjb21wb25lbnRzIHRoYXQgZXhwbGljaXRseSBsaXN0IGRpZmZlcmVudCBheGVzLlxuICAgKi9cbiAgZm9vdGVyPzogSGVhZGVyQ29tcG9uZW50W107XG59XG5cbi8qKlxuICogQSBjb21wb25lbnQgdGhhdCByZXByZXNlbnRzIG9uZSBncm91cCBvZiByb3cvY29sdW1uLWhlYWRlci9mb290ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGVhZGVyQ29tcG9uZW50IHtcblxuICBsYWJlbHM6IGJvb2xlYW47XG5cbiAgc2l6ZVNpZ25hbDoge3NpZ25hbDogc3RyaW5nfTtcblxuICBheGVzOiBWZ0F4aXNbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhlYWRlclR5cGUob3JpZW50OiBBeGlzT3JpZW50KSB7XG4gIGlmIChvcmllbnQgPT09ICd0b3AnIHx8IG9yaWVudCA9PT0gJ2xlZnQnKSB7XG4gICAgcmV0dXJuICdoZWFkZXInO1xuICB9XG4gIHJldHVybiAnZm9vdGVyJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpdGxlR3JvdXAobW9kZWw6IE1vZGVsLCBjaGFubmVsOiBIZWFkZXJDaGFubmVsKSB7XG4gIGNvbnN0IHRpdGxlID0gbW9kZWwuY29tcG9uZW50LmxheW91dEhlYWRlcnNbY2hhbm5lbF0udGl0bGU7XG4gIGNvbnN0IHRleHRPcmllbnQgPSBjaGFubmVsID09PSAncm93JyA/ICd2ZXJ0aWNhbCcgOiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgdXBkYXRlID0ge1xuICAgIGFsaWduOiB7dmFsdWU6ICdjZW50ZXInfSxcbiAgICB0ZXh0OiB7dmFsdWU6IHRpdGxlfSxcbiAgICAuLi4odGV4dE9yaWVudCA9PT0gJ3ZlcnRpY2FsJyA/IHthbmdsZToge3ZhbHVlOiAyNzB9fToge30pLFxuICAgIC8vIFRPRE8qaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yNDQ2KTogYWRkIHRpdGxlKiBwcm9wZXJ0aWVzIChlLmcuLCB0aXRsZUFsaWduKVxuICAgIC8vIGFsc28gbWFrZSBzdXJlIHRoYXQgZ3VpZGUtdGl0bGUgY29uZmlnIG92ZXJyaWRlIHRoZXNlIFZlZ2EtbGl0ZSBkZWZhdWx0XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAgbW9kZWwuZ2V0TmFtZShgJHtjaGFubmVsfV90aXRsZWApLFxuICAgIHJvbGU6IGAke2NoYW5uZWx9LXRpdGxlYCxcbiAgICB0eXBlOiAnZ3JvdXAnLFxuICAgIG1hcmtzOiBbe1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgcm9sZTogYCR7Y2hhbm5lbH0tdGl0bGUtdGV4dGAsXG4gICAgICBzdHlsZTogJ2d1aWRlLXRpdGxlJyxcbiAgICAgIC4uLihrZXlzKHVwZGF0ZSkubGVuZ3RoID4gMCA/IHtlbmNvZGU6IHt1cGRhdGV9fSA6IHt9KVxuICAgIH1dXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZWFkZXJHcm91cChtb2RlbDogTW9kZWwsIGNoYW5uZWw6IEhlYWRlckNoYW5uZWwsIGhlYWRlclR5cGU6IEhlYWRlclR5cGUsIGxheW91dEhlYWRlcjogTGF5b3V0SGVhZGVyQ29tcG9uZW50LCBoZWFkZXJDbXB0OiBIZWFkZXJDb21wb25lbnQpIHtcbiAgaWYgKGhlYWRlckNtcHQpIHtcbiAgICBsZXQgdGl0bGUgPSBudWxsO1xuICAgIGlmIChsYXlvdXRIZWFkZXIuZmFjZXRGaWVsZERlZiAmJiBoZWFkZXJDbXB0LmxhYmVscykge1xuICAgICAgY29uc3Qge2ZhY2V0RmllbGREZWZ9ID0gbGF5b3V0SGVhZGVyO1xuICAgICAgY29uc3Qge2hlYWRlciA9IHt9fSA9IGZhY2V0RmllbGREZWY7XG4gICAgICBjb25zdCB7Zm9ybWF0LCBsYWJlbEFuZ2xlfSA9IGhlYWRlcjtcblxuICAgICAgY29uc3QgdXBkYXRlID0ge1xuICAgICAgICAuLi4oXG4gICAgICAgICAgbGFiZWxBbmdsZSA/IHthbmdsZToge3ZhbHVlOiBsYWJlbEFuZ2xlfX0gOiB7fVxuICAgICAgICApXG5cbiAgICAgICAgLy8gVE9ETyhodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzI0NDYpOiBhcHBseSBsYWJlbCogKGUuZywgbGFiZWxBbGlnbiwgbGFiZWxCYXNlbGluZSkgaGVyZVxuICAgICAgfTtcblxuICAgICAgdGl0bGUgPSB7XG4gICAgICAgIHRleHQ6IGZvcm1hdFNpZ25hbFJlZihmYWNldEZpZWxkRGVmLCBmb3JtYXQsICdwYXJlbnQnLCBtb2RlbC5jb25maWcpLFxuICAgICAgICBvZmZzZXQ6IDEwLFxuICAgICAgICBvcmllbnQ6IGNoYW5uZWwgPT09ICdyb3cnID8gJ2xlZnQnIDogJ3RvcCcsXG4gICAgICAgIHN0eWxlOiAnZ3VpZGUtbGFiZWwnLFxuICAgICAgICAuLi4oa2V5cyh1cGRhdGUpLmxlbmd0aCA+IDAgPyB7ZW5jb2RlOiB7dXBkYXRlfX0gOiB7fSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgYXhlcyA9IGhlYWRlckNtcHQuYXhlcztcblxuICAgIGNvbnN0IGhhc0F4ZXMgPSBheGVzICYmIGF4ZXMubGVuZ3RoID4gMDtcbiAgICBpZiAodGl0bGUgfHwgaGFzQXhlcykge1xuICAgICAgY29uc3Qgc2l6ZUNoYW5uZWwgPSBjaGFubmVsID09PSAncm93JyA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogbW9kZWwuZ2V0TmFtZShgJHtjaGFubmVsfV8ke2hlYWRlclR5cGV9YCksXG4gICAgICAgIHR5cGU6ICdncm91cCcsXG4gICAgICAgIHJvbGU6IGAke2NoYW5uZWx9LSR7aGVhZGVyVHlwZX1gLFxuICAgICAgICAuLi4obGF5b3V0SGVhZGVyLmZhY2V0RmllbGREZWYgPyB7XG4gICAgICAgICAgZnJvbToge2RhdGE6IG1vZGVsLmdldE5hbWUoY2hhbm5lbCArICdfZG9tYWluJyl9LFxuICAgICAgICAgIHNvcnQ6IHtcbiAgICAgICAgICAgIGZpZWxkOiBmaWVsZChsYXlvdXRIZWFkZXIuZmFjZXRGaWVsZERlZiwge2V4cHI6ICdkYXR1bSd9KSxcbiAgICAgICAgICAgIG9yZGVyOiAobGF5b3V0SGVhZGVyLmZhY2V0RmllbGREZWYuaGVhZGVyICYmIGxheW91dEhlYWRlci5mYWNldEZpZWxkRGVmLnNvcnQpIHx8ICdhc2NlbmRpbmcnXG4gICAgICAgICAgfVxuICAgICAgICB9IDoge30pLFxuICAgICAgICAuLi4odGl0bGUgPyB7dGl0bGV9IDoge30pLFxuICAgICAgICAuLi4oaGVhZGVyQ21wdC5zaXplU2lnbmFsID8ge1xuICAgICAgICAgIGVuY29kZToge1xuICAgICAgICAgICAgdXBkYXRlOiB7XG4gICAgICAgICAgICAgIFtzaXplQ2hhbm5lbF06IGhlYWRlckNtcHQuc2l6ZVNpZ25hbFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfToge30pLFxuICAgICAgICAuLi4oaGFzQXhlcyA/IHtheGVzfSA6IHt9KVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG4iXX0= \ 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..a4cc811f42 --- /dev/null +++ b/build/src/compile/layoutsize/assemble.js @@ -0,0 +1,75 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var model_1 = require("../model"); +function assembleLayoutSignals(model) { + return [].concat(sizeSignals(model, 'width'), sizeSignals(model, 'height')); +} +exports.assembleLayoutSignals = assembleLayoutSignals; +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 (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var scaleName = model.scaleName(channel); + if (model_1.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 + }]; + } +} +exports.sizeSignals = sizeSignals; +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"; +} +exports.sizeExpr = sizeExpr; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9sYXlvdXRzaXplL2Fzc2VtYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EscUNBQThDO0FBQzlDLGlEQUF1RTtBQUN2RSxrQ0FBNkM7QUFHN0MsK0JBQXNDLEtBQVk7SUFDaEQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQ2QsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsRUFDM0IsV0FBVyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FDN0IsQ0FBQztBQUNKLENBQUM7QUFMRCxzREFLQztBQUVELHFCQUE0QixLQUFZLEVBQUUsUUFBNEI7SUFDcEUsSUFBTSxPQUFPLEdBQUcsUUFBUSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDakQsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3RELEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsc0dBQXNHO0lBQ3RHLElBQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFFckQsRUFBRSxDQUFDLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDMUIsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXhELEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDbkIsSUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4QyxJQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRTFDLEVBQUUsQ0FBQyxDQUFDLHlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLDJCQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxJQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUUzQyxFQUFFLENBQUMsQ0FBQyxvQkFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQy9CLGlGQUFpRjtvQkFDakYsb0VBQW9FO29CQUNwRSwwREFBMEQ7b0JBQzFELElBQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztvQkFDckQsRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDO3dCQUNuRCxNQUFNLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ3hDLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxNQUFNLENBQUM7b0JBQ0wsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUM7b0JBQzVCO3dCQUNFLElBQUksTUFBQTt3QkFDSixNQUFNLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxjQUFjLEVBQUUsYUFBVyxTQUFTLGNBQVcsQ0FBQztxQkFDN0U7aUJBQ0YsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBQ0QsMkZBQTJGO1FBQzNGLE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixNQUFNLENBQUMsQ0FBQztnQkFDTixJQUFJLE1BQUE7Z0JBQ0osS0FBSyxFQUFFLElBQUk7YUFDWixDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQztBQS9DRCxrQ0ErQ0M7QUFFRCxvQkFBb0IsU0FBaUIsRUFBRSxLQUFrQjtJQUN2RCxNQUFNLENBQUM7UUFDTCxJQUFJLEVBQUUsU0FBUyxHQUFHLE9BQU87UUFDekIsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJO0tBQ2xCLENBQUM7QUFDSixDQUFDO0FBRUQsa0JBQXlCLFNBQWlCLEVBQUUsY0FBOEIsRUFBRSxXQUFtQjtJQUM3RixJQUFNLElBQUksR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3hDLElBQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDOUMsSUFBSSxZQUFZLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN0RCxZQUFZLEdBQUcsWUFBWSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFFbkUsSUFBSSxZQUFZLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN0RCxZQUFZLEdBQUcsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDO1FBQzlCLGtDQUFrQztRQUNsQyxDQUFDLFlBQVksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUN2RCwrRkFBK0Y7UUFDL0YsMkZBQTJGO1FBQzNGLENBQUMsQ0FBQztJQUNKLE1BQU0sQ0FBQyxlQUFhLFdBQVcsVUFBSyxZQUFZLFVBQUssWUFBWSxZQUFPLFNBQVMsVUFBTyxDQUFDO0FBQzNGLENBQUM7QUFkRCw0QkFjQyIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbn0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtpc1ZnUmFuZ2VTdGVwLCBWZ1JhbmdlU3RlcCwgVmdTaWduYWx9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7aXNGYWNldE1vZGVsLCBNb2RlbH0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtTY2FsZUNvbXBvbmVudH0gZnJvbSAnLi4vc2NhbGUvY29tcG9uZW50JztcblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlTGF5b3V0U2lnbmFscyhtb2RlbDogTW9kZWwpOiBWZ1NpZ25hbFtdIHtcbiAgcmV0dXJuIFtdLmNvbmNhdChcbiAgICBzaXplU2lnbmFscyhtb2RlbCwgJ3dpZHRoJyksXG4gICAgc2l6ZVNpZ25hbHMobW9kZWwsICdoZWlnaHQnKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2l6ZVNpZ25hbHMobW9kZWw6IE1vZGVsLCBzaXplVHlwZTogJ3dpZHRoJyB8ICdoZWlnaHQnKTogVmdTaWduYWxbXSB7XG4gIGNvbnN0IGNoYW5uZWwgPSBzaXplVHlwZSA9PT0gJ3dpZHRoJyA/ICd4JyA6ICd5JztcbiAgY29uc3Qgc2l6ZSA9IG1vZGVsLmNvbXBvbmVudC5sYXlvdXRTaXplLmdldChzaXplVHlwZSk7XG4gIGlmICghc2l6ZSB8fCBzaXplID09PSAnbWVyZ2VkJykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8vIFJlYWQgc2l6ZSBzaWduYWwgbmFtZSBmcm9tIG5hbWUgbWFwLCBqdXN0IGluIGNhc2UgaXQgaXMgdGhlIHRvcC1sZXZlbCBzaXplIHNpZ25hbCB0aGF0IGdvdCByZW5hbWVkLlxuICBjb25zdCBuYW1lID0gbW9kZWwuZ2V0U2l6ZVNpZ25hbFJlZihzaXplVHlwZSkuc2lnbmFsO1xuXG4gIGlmIChzaXplID09PSAncmFuZ2Utc3RlcCcpIHtcbiAgICBjb25zdCBzY2FsZUNvbXBvbmVudCA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpO1xuXG4gICAgaWYgKHNjYWxlQ29tcG9uZW50KSB7XG4gICAgICBjb25zdCB0eXBlID0gc2NhbGVDb21wb25lbnQuZ2V0KCd0eXBlJyk7XG4gICAgICBjb25zdCByYW5nZSA9IHNjYWxlQ29tcG9uZW50LmdldCgncmFuZ2UnKTtcblxuICAgICAgaWYgKGhhc0Rpc2NyZXRlRG9tYWluKHR5cGUpICYmIGlzVmdSYW5nZVN0ZXAocmFuZ2UpKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlTmFtZSA9IG1vZGVsLnNjYWxlTmFtZShjaGFubmVsKTtcblxuICAgICAgICBpZiAoaXNGYWNldE1vZGVsKG1vZGVsLnBhcmVudCkpIHtcbiAgICAgICAgICAvLyBJZiBwYXJlbnQgaXMgZmFjZXQgYW5kIHRoaXMgaXMgYW4gaW5kZXBlbmRlbnQgc2NhbGUsIHJldHVybiBvbmx5IHNpZ25hbCBzaWduYWxcbiAgICAgICAgICAvLyBhcyB0aGUgd2lkdGgvaGVpZ2h0IHdpbGwgYmUgY2FsY3VsYXRlZCB1c2luZyB0aGUgY2FyZGluYWxpdHkgZnJvbVxuICAgICAgICAgIC8vIGZhY2V0J3MgYWdncmVnYXRlIHJhdGhlciB0aGFuIHJlYWRpbmcgZnJvbSBzY2FsZSBkb21haW5cbiAgICAgICAgICBjb25zdCBwYXJlbnRSZXNvbHZlID0gbW9kZWwucGFyZW50LmNvbXBvbmVudC5yZXNvbHZlO1xuICAgICAgICAgIGlmIChwYXJlbnRSZXNvbHZlLnNjYWxlW2NoYW5uZWxdID09PSAnaW5kZXBlbmRlbnQnKSB7XG4gICAgICAgICAgICByZXR1cm4gW3N0ZXBTaWduYWwoc2NhbGVOYW1lLCByYW5nZSldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgc3RlcFNpZ25hbChzY2FsZU5hbWUsIHJhbmdlKSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgdXBkYXRlOiBzaXplRXhwcihzY2FsZU5hbWUsIHNjYWxlQ29tcG9uZW50LCBgZG9tYWluKCcke3NjYWxlTmFtZX0nKS5sZW5ndGhgKVxuICAgICAgICAgIH1cbiAgICAgICAgXTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IENvbmRpdGlvbiBzaG91bGQgbm90IGhhcHBlbiAtLSBvbmx5IGZvciB3YXJuaW5nIGluIGRldmVsb3BtZW50LiAqL1xuICAgIHRocm93IG5ldyBFcnJvcignbGF5b3V0IHNpemUgaXMgcmFuZ2Ugc3RlcCBhbHRob3VnaCB0aGVyZSBpcyBubyByYW5nZVN0ZXAuJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFt7XG4gICAgICBuYW1lLFxuICAgICAgdmFsdWU6IHNpemVcbiAgICB9XTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzdGVwU2lnbmFsKHNjYWxlTmFtZTogc3RyaW5nLCByYW5nZTogVmdSYW5nZVN0ZXApOiBWZ1NpZ25hbCB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogc2NhbGVOYW1lICsgJ19zdGVwJyxcbiAgICB2YWx1ZTogcmFuZ2Uuc3RlcCxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNpemVFeHByKHNjYWxlTmFtZTogc3RyaW5nLCBzY2FsZUNvbXBvbmVudDogU2NhbGVDb21wb25lbnQsIGNhcmRpbmFsaXR5OiBzdHJpbmcpIHtcbiAgY29uc3QgdHlwZSA9IHNjYWxlQ29tcG9uZW50LmdldCgndHlwZScpO1xuICBjb25zdCBwYWRkaW5nID0gc2NhbGVDb21wb25lbnQuZ2V0KCdwYWRkaW5nJyk7XG4gIGxldCBwYWRkaW5nT3V0ZXIgPSBzY2FsZUNvbXBvbmVudC5nZXQoJ3BhZGRpbmdPdXRlcicpO1xuICBwYWRkaW5nT3V0ZXIgPSBwYWRkaW5nT3V0ZXIgIT09IHVuZGVmaW5lZCA/IHBhZGRpbmdPdXRlciA6IHBhZGRpbmc7XG5cbiAgbGV0IHBhZGRpbmdJbm5lciA9IHNjYWxlQ29tcG9uZW50LmdldCgncGFkZGluZ0lubmVyJyk7XG4gIHBhZGRpbmdJbm5lciA9IHR5cGUgPT09ICdiYW5kJyA/XG4gICAgLy8gb25seSBiYW5kIGhhcyByZWFsIHBhZGRpbmdJbm5lclxuICAgIChwYWRkaW5nSW5uZXIgIT09IHVuZGVmaW5lZCA/IHBhZGRpbmdJbm5lciA6IHBhZGRpbmcpIDpcbiAgICAvLyBGb3IgcG9pbnQsIGFzIGNhbGN1bGF0ZWQgaW4gaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1zY2FsZS9ibG9iL21hc3Rlci9zcmMvYmFuZC5qcyNMMTI4LFxuICAgIC8vIGl0J3MgZXF1aXZhbGVudCB0byBoYXZlIHBhZGRpbmdJbm5lciA9IDEgc2luY2UgdGhlcmUgaXMgb25seSBuLTEgc3RlcHMgYmV0d2VlbiBuIHBvaW50cy5cbiAgICAxO1xuICByZXR1cm4gYGJhbmRzcGFjZSgke2NhcmRpbmFsaXR5fSwgJHtwYWRkaW5nSW5uZXJ9LCAke3BhZGRpbmdPdXRlcn0pICogJHtzY2FsZU5hbWV9X3N0ZXBgO1xufVxuXG5cbiJdfQ== \ 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..b0195aae69 --- /dev/null +++ b/build/src/compile/layoutsize/component.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGF5b3V0c2l6ZS9jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7U3BsaXR9IGZyb20gJy4uL3NwbGl0JztcblxuZXhwb3J0IHR5cGUgTGF5b3V0U2l6ZSA9IG51bWJlciB8ICdyYW5nZS1zdGVwJyB8ICdtZXJnZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIExheW91dFNpemVJbmRleCB7XG4gIHdpZHRoPzogTGF5b3V0U2l6ZTtcbiAgaGVpZ2h0PzogTGF5b3V0U2l6ZTtcbn1cblxuZXhwb3J0IHR5cGUgTGF5b3V0U2l6ZUNvbXBvbmVudCA9IFNwbGl0PExheW91dFNpemVJbmRleD47XG4iXX0= \ 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..8996e62a36 --- /dev/null +++ b/build/src/compile/layoutsize/parse.js @@ -0,0 +1,110 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var split_1 = require("../split"); +function parseLayerLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width')); + layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height')); +} +exports.parseLayerLayoutSize = parseLayerLayoutSize; +exports.parseRepeatLayoutSize = parseLayerLayoutSize; +function parseConcatLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + var sizeTypeToMerge = model.isVConcat ? 'width' : 'height'; + layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge)); +} +exports.parseConcatLayoutSize = parseConcatLayoutSize; +function parseChildrenLayoutSize(model) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseLayoutSize(); + } +} +exports.parseChildrenLayoutSize = parseChildrenLayoutSize; +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 = split_1.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); + } +} +exports.parseUnitLayoutSize = parseUnitLayoutSize; +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 (scale_1.hasDiscreteDomain(scaleType) && vega_schema_1.isVgRangeStep(range)) { + // For discrete domain with range.step, use dynamic width/height + return 'range-step'; + } + else { + 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 || scale_1.defaultScaleConfig.rangeStep; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9sYXlvdXRzaXplL3BhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEscUNBQWtFO0FBQ2xFLGlEQUFnRDtBQUdoRCxrQ0FBMkQ7QUFJM0QsOEJBQXFDLEtBQVk7SUFDL0MsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFL0IsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7SUFDbEQsY0FBYyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsZ0NBQWdDLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDMUYsY0FBYyxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsZ0NBQWdDLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDOUYsQ0FBQztBQU5ELG9EQU1DO0FBRVksUUFBQSxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQztBQUUxRCwrQkFBc0MsS0FBa0I7SUFDdEQsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7SUFFbEQsSUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7SUFDN0QsY0FBYyxDQUFDLGVBQWUsQ0FBQyxlQUFlLEVBQUUsZ0NBQWdDLENBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUM7QUFDNUcsQ0FBQztBQU5ELHNEQU1DO0FBRUQsaUNBQXdDLEtBQVk7SUFDbEQsR0FBRyxDQUFDLENBQWdCLFVBQWMsRUFBZCxLQUFBLEtBQUssQ0FBQyxRQUFRLEVBQWQsY0FBYyxFQUFkLElBQWM7UUFBN0IsSUFBTSxLQUFLLFNBQUE7UUFDZCxLQUFLLENBQUMsZUFBZSxFQUFF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QWMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsMkdBQTJHO1FBQzNHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsSUFBSSwwQkFBa0IsQ0FBQyxTQUFTLENBQUM7SUFDaEUsQ0FBQztBQUVILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2RlZmF1bHRTY2FsZUNvbmZpZywgaGFzRGlzY3JldGVEb21haW59IGZyb20gJy4uLy4uL3NjYWxlJztcbmltcG9ydCB7aXNWZ1JhbmdlU3RlcH0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtDb25jYXRNb2RlbH0gZnJvbSAnLi4vY29uY2F0JztcbmltcG9ydCB7TW9kZWx9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7RXhwbGljaXQsIG1lcmdlVmFsdWVzV2l0aEV4cGxpY2l0fSBmcm9tICcuLi9zcGxpdCc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vdW5pdCc7XG5pbXBvcnQge0xheW91dFNpemUsIExheW91dFNpemVJbmRleH0gZnJvbSAnLi9jb21wb25lbnQnO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VMYXllckxheW91dFNpemUobW9kZWw6IE1vZGVsKSB7XG4gIHBhcnNlQ2hpbGRyZW5MYXlvdXRTaXplKG1vZGVsKTtcblxuICBjb25zdCBsYXlvdXRTaXplQ21wdCA9IG1vZGVsLmNvbXBvbmVudC5sYXlvdXRTaXplO1xuICBsYXlvdXRTaXplQ21wdC5zZXRXaXRoRXhwbGljaXQoJ3dpZHRoJywgcGFyc2VOb25Vbml0TGF5b3V0U2l6ZUZvckNoYW5uZWwobW9kZWwsICd3aWR0aCcpKTtcbiAgbGF5b3V0U2l6ZUNtcHQuc2V0V2l0aEV4cGxpY2l0KCdoZWlnaHQnLCBwYXJzZU5vblVuaXRMYXlvdXRTaXplRm9yQ2hhbm5lbChtb2RlbCwgJ2hlaWdodCcpKTtcbn1cblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVwZWF0TGF5b3V0U2l6ZSA9IHBhcnNlTGF5ZXJMYXlvdXRTaXplO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb25jYXRMYXlvdXRTaXplKG1vZGVsOiBDb25jYXRNb2RlbCkge1xuICBwYXJzZUNoaWxkcmVuTGF5b3V0U2l6ZShtb2RlbCk7XG4gIGNvbnN0IGxheW91dFNpemVDbXB0ID0gbW9kZWwuY29tcG9uZW50LmxheW91dFNpemU7XG5cbiAgY29uc3Qgc2l6ZVR5cGVUb01lcmdlID0gbW9kZWwuaXNWQ29uY2F0ID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICBsYXlvdXRTaXplQ21wdC5zZXRXaXRoRXhwbGljaXQoc2l6ZVR5cGVUb01lcmdlLCBwYXJzZU5vblVuaXRMYXlvdXRTaXplRm9yQ2hhbm5lbChtb2RlbCwgc2l6ZVR5cGVUb01lcmdlKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNoaWxkcmVuTGF5b3V0U2l6ZShtb2RlbDogTW9kZWwpIHtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgIGNoaWxkLnBhcnNlTGF5b3V0U2l6ZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlTm9uVW5pdExheW91dFNpemVGb3JDaGFubmVsKG1vZGVsOiBNb2RlbCwgc2l6ZVR5cGU6ICd3aWR0aCcgfCAnaGVpZ2h0Jyk6IEV4cGxpY2l0PExheW91dFNpemU+IHtcbiAgY29uc3QgY2hhbm5lbCA9IHNpemVUeXBlID09PSAnd2lkdGgnID8gJ3gnIDogJ3knO1xuICBjb25zdCByZXNvbHZlID0gbW9kZWwuY29tcG9uZW50LnJlc29sdmU7XG5cbiAgbGV0IG1lcmdlZFNpemU6IEV4cGxpY2l0PExheW91dFNpemU+O1xuICAvLyBUcnkgdG8gbWVyZ2UgbGF5b3V0IHNpemVcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgIGNvbnN0IGNoaWxkU2l6ZSA9IGNoaWxkLmNvbXBvbmVudC5sYXlvdXRTaXplLmdldFdpdGhFeHBsaWNpdChzaXplVHlwZSk7XG4gICAgY29uc3Qgc2NhbGVSZXNvbHZlID0gcmVzb2x2ZS5zY2FsZVtjaGFubmVsXTtcbiAgICBpZiAoc2NhbGVSZXNvbHZlID09PSAnaW5kZXBlbmRlbnQnICYmIGNoaWxkU2l6ZS52YWx1ZSA9PT0gJ3JhbmdlLXN0ZXAnKSB7XG4gICAgICAvLyBEbyBub3QgbWVyZ2UgaW5kZXBlbmRlbnQgc2NhbGVzIHdpdGggcmFuZ2Utc3RlcCBhcyB0aGVpciBzaXplIGRlcGVuZHNcbiAgICAgIC8vIG9uIHRoZSBzY2FsZSBkb21haW5zLCB3aGljaCBjYW4gYmUgZGlmZmVyZW50IGJldHdlZW4gc2NhbGVzLlxuICAgICAgbWVyZ2VkU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChtZXJnZWRTaXplKSB7XG4gICAgICBpZiAoc2NhbGVSZXNvbHZlID09PSAnaW5kZXBlbmRlbnQnICYmIG1lcmdlZFNpemUudmFsdWUgIT09IGNoaWxkU2l6ZS52YWx1ZSkge1xuICAgICAgICAvLyBGb3IgaW5kZXBlbmRlbnQgc2NhbGUsIG9ubHkgbWVyZ2UgaWYgYWxsIHRoZSBzaXplcyBhcmUgdGhlIHNhbWUuXG4gICAgICAgIC8vIElmIHRoZSB2YWx1ZXMgYXJlIGRpZmZlcmVudCwgYWJhbmRvbiB0aGUgbWVyZ2UhXG4gICAgICAgIG1lcmdlZFNpemUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgbWVyZ2VkU2l6ZSA9IG1lcmdlVmFsdWVzV2l0aEV4cGxpY2l0PExheW91dFNpemVJbmRleCwgTGF5b3V0U2l6ZT4oXG4gICAgICAgIG1lcmdlZFNpemUsIGNoaWxkU2l6ZSwgc2l6ZVR5cGUsICcnXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBtZXJnZWRTaXplID0gY2hpbGRTaXplO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtZXJnZWRTaXplKSB7XG4gICAgLy8gSWYgbWVyZ2VkLCByZW5hbWUgc2l6ZSBhbmQgc2V0IHNpemUgb2YgYWxsIGNoaWxkcmVuLlxuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgbW9kZWwuY2hpbGRyZW4pIHtcbiAgICAgIG1vZGVsLnJlbmFtZUxheW91dFNpemUoY2hpbGQuZ2V0TmFtZShzaXplVHlwZSksIG1vZGVsLmdldE5hbWUoc2l6ZVR5cGUpKTtcbiAgICAgIGNoaWxkLmNvbXBvbmVudC5sYXlvdXRTaXplLnNldChzaXplVHlwZSwgJ21lcmdlZCcsIGZhbHNlKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlZFNpemU7XG4gIH0gZWxzZSB7XG4gICAgLy8gT3RoZXJ3aXNlLCB0aGVyZSBpcyBubyBtZXJnZWQgc2l6ZS5cbiAgICByZXR1cm4ge1xuICAgICAgZXhwbGljaXQ6IGZhbHNlLFxuICAgICAgdmFsdWU6IHVuZGVmaW5lZFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVW5pdExheW91dFNpemUobW9kZWw6IFVuaXRNb2RlbCkge1xuICBjb25zdCBsYXlvdXRTaXplQ29tcG9uZW50ID0gbW9kZWwuY29tcG9uZW50LmxheW91dFNpemU7XG4gIGlmICghbGF5b3V0U2l6ZUNvbXBvbmVudC5leHBsaWNpdC53aWR0aCkge1xuICAgIGNvbnN0IHdpZHRoID0gZGVmYXVsdFVuaXRTaXplKG1vZGVsLCAnd2lkdGgnKTtcbiAgICBsYXlvdXRTaXplQ29tcG9uZW50LnNldCgnd2lkdGgnLCB3aWR0aCwgZmFsc2UpO1xuICB9XG5cbiAgaWYgKCFsYXlvdXRTaXplQ29tcG9uZW50LmV4cGxpY2l0LmhlaWdodCkge1xuICAgIGNvbnN0IGhlaWdodCA9IGRlZmF1bHRVbml0U2l6ZShtb2RlbCwgJ2hlaWdodCcpO1xuICAgIGxheW91dFNpemVDb21wb25lbnQuc2V0KCdoZWlnaHQnLCBoZWlnaHQsIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0VW5pdFNpemUobW9kZWw6IFVuaXRNb2RlbCwgc2l6ZVR5cGU6ICd3aWR0aCcgfCAnaGVpZ2h0Jyk6IExheW91dFNpemUge1xuICBjb25zdCBjaGFubmVsID0gc2l6ZVR5cGUgPT09ICd3aWR0aCcgPyAneCcgOiAneSc7XG4gIGNvbnN0IGNvbmZpZyA9IG1vZGVsLmNvbmZpZztcbiAgY29uc3Qgc2NhbGVDb21wb25lbnQgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKTtcblxuICBpZiAoc2NhbGVDb21wb25lbnQpIHtcbiAgICBjb25zdCBzY2FsZVR5cGUgPSBzY2FsZUNvbXBvbmVudC5nZXQoJ3R5cGUnKTtcbiAgICBjb25zdCByYW5nZSA9IHNjYWxlQ29tcG9uZW50LmdldCgncmFuZ2UnKTtcblxuICAgIGlmIChoYXNEaXNjcmV0ZURvbWFpbihzY2FsZVR5cGUpICYmIGlzVmdSYW5nZVN0ZXAocmFuZ2UpKSB7XG4gICAgICAvLyBGb3IgZGlzY3JldGUgZG9tYWluIHdpdGggcmFuZ2Uuc3RlcCwgdXNlIGR5bmFtaWMgd2lkdGgvaGVpZ2h0XG4gICAgICByZXR1cm4gJ3JhbmdlLXN0ZXAnO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY29uZmlnLnZpZXdbc2l6ZVR5cGVdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBObyBzY2FsZSAtIHNldCBkZWZhdWx0IHNpemVcbiAgICBpZiAoc2l6ZVR5cGUgPT09ICd3aWR0aCcgJiYgbW9kZWwubWFyaygpID09PSAndGV4dCcpIHtcbiAgICAgIC8vIHdpZHRoIGZvciB0ZXh0IG1hcmsgd2l0aG91dCB4LWZpZWxkIGlzIGEgYml0IHdpZGVyIHRoYW4gdHlwaWNhbCByYW5nZSBzdGVwXG4gICAgICByZXR1cm4gY29uZmlnLnNjYWxlLnRleHRYUmFuZ2VTdGVwO1xuICAgIH1cblxuICAgIC8vIFNldCB3aWR0aC9oZWlnaHQgZXF1YWwgdG8gcmFuZ2VTdGVwIGNvbmZpZyBvciBpZiByYW5nZVN0ZXAgaXMgbnVsbCwgdXNlIHZhbHVlIGZyb20gZGVmYXVsdCBzY2FsZSBjb25maWcuXG4gICAgcmV0dXJuIGNvbmZpZy5zY2FsZS5yYW5nZVN0ZXAgfHwgZGVmYXVsdFNjYWxlQ29uZmlnLnJhbmdlU3RlcDtcbiAgfVxuXG59XG4iXX0= \ 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..573d6c0711 --- /dev/null +++ b/build/src/compile/legend/assemble.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var util_1 = require("../../util"); +var parse_1 = require("./parse"); +function assembleLegends(model) { + var legendComponentIndex = model.component.legends; + var legendByDomain = {}; + for (var _i = 0, _a = util_1.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 = parse_1.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 util_1.flatten(util_1.vals(legendByDomain)).map(function (legendCmpt) { return legendCmpt.combine(); }); +} +exports.assembleLegends = assembleLegends; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9sZWdlbmQvYXNzZW1ibGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpREFBbUQ7QUFFbkQsbUNBQStDO0FBSS9DLGlDQUE2QztBQUU3Qyx5QkFBZ0MsS0FBWTtJQUMxQyxJQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDO0lBQ3JELElBQU0sY0FBYyxHQUE4QyxFQUFFLENBQUM7SUFFckUsR0FBRyxDQUFDLENBQWtCLFVBQTBCLEVBQTFCLEtBQUEsV0FBSSxDQUFDLG9CQUFvQixDQUFDLEVBQTFCLGNBQTBCLEVBQTFCLElBQTBCO1FBQTNDLElBQU0sT0FBTyxTQUFBO1FBQ2hCLElBQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4RCxJQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0IsR0FBRyxDQUFDLENBQWdDLFVBQTBCLEVBQTFCLEtBQUEsY0FBYyxDQUFDLFVBQVUsQ0FBQyxFQUExQixjQUEwQixFQUExQixJQUEwQjtnQkFBekQsSUFBTSxxQkFBcUIsU0FBQTtnQkFDOUIsSUFBTSxNQUFNLEdBQUcsNEJBQW9CLENBQUMscUJBQXFCLEVBQUUsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDMUYsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO29CQUNaLHNEQUFzRDtvQkFDdEQsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNqRSxDQUFDO2FBQ0Y7UUFFSCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixjQUFjLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7S0FDRjtJQUVELE1BQU0sQ0FBQyxjQUFPLENBQUMsV0FBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQUMsVUFBMkIsSUFBSyxPQUFBLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBcEIsQ0FBb0IsQ0FBQyxDQUFDO0FBQ2xHLENBQUM7QUF0QkQsMENBc0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc3RyaW5naWZ5IGZyb20gJ2pzb24tc3RhYmxlLXN0cmluZ2lmeSc7XG5cbmltcG9ydCB7ZmxhdHRlbiwga2V5cywgdmFsc30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnTGVnZW5kfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge01vZGVsfSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge0xlZ2VuZENvbXBvbmVudH0gZnJvbSAnLi9jb21wb25lbnQnO1xuaW1wb3J0IHttZXJnZUxlZ2VuZENvbXBvbmVudH0gZnJvbSAnLi9wYXJzZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlbWJsZUxlZ2VuZHMobW9kZWw6IE1vZGVsKTogVmdMZWdlbmRbXSB7XG4gIGNvbnN0IGxlZ2VuZENvbXBvbmVudEluZGV4ID0gbW9kZWwuY29tcG9uZW50LmxlZ2VuZHM7XG4gIGNvbnN0IGxlZ2VuZEJ5RG9tYWluOiB7W2RvbWFpbkhhc2g6IHN0cmluZ106IExlZ2VuZENvbXBvbmVudFtdfSA9IHt9O1xuXG4gIGZvciAoY29uc3QgY2hhbm5lbCBvZiBrZXlzKGxlZ2VuZENvbXBvbmVudEluZGV4KSkge1xuICAgIGNvbnN0IHNjYWxlQ29tcG9uZW50ID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoY2hhbm5lbCk7XG4gICAgY29uc3QgZG9tYWluSGFzaCA9IHN0cmluZ2lmeShzY2FsZUNvbXBvbmVudC5kb21haW5zKTtcbiAgICBpZiAobGVnZW5kQnlEb21haW5bZG9tYWluSGFzaF0pIHtcbiAgICAgIGZvciAoY29uc3QgbWVyZ2VkTGVnZW5kQ29tcG9uZW50IG9mIGxlZ2VuZEJ5RG9tYWluW2RvbWFpbkhhc2hdKSB7XG4gICAgICAgIGNvbnN0IG1lcmdlZCA9IG1lcmdlTGVnZW5kQ29tcG9uZW50KG1lcmdlZExlZ2VuZENvbXBvbmVudCwgbGVnZW5kQ29tcG9uZW50SW5kZXhbY2hhbm5lbF0pO1xuICAgICAgICBpZiAoIW1lcmdlZCkge1xuICAgICAgICAgIC8vIElmIGNhbm5vdCBtZXJnZSwgbmVlZCB0byBhZGQgdGhpcyBsZWdlbmQgc2VwYXJhdGVseVxuICAgICAgICAgIGxlZ2VuZEJ5RG9tYWluW2RvbWFpbkhhc2hdLnB1c2gobGVnZW5kQ29tcG9uZW50SW5kZXhbY2hhbm5lbF0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICB9IGVsc2Uge1xuICAgICAgbGVnZW5kQnlEb21haW5bZG9tYWluSGFzaF0gPSBbbGVnZW5kQ29tcG9uZW50SW5kZXhbY2hhbm5lbF0uY2xvbmUoKV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZsYXR0ZW4odmFscyhsZWdlbmRCeURvbWFpbikpLm1hcCgobGVnZW5kQ21wdDogTGVnZW5kQ29tcG9uZW50KSA9PiBsZWdlbmRDbXB0LmNvbWJpbmUoKSk7XG59XG4iXX0= \ 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..aaa351bfa0 --- /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..b179e12f2a --- /dev/null +++ b/build/src/compile/legend/component.js @@ -0,0 +1,22 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var split_1 = require("../split"); +var LegendComponent = /** @class */ (function (_super) { + __extends(LegendComponent, _super); + function LegendComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return LegendComponent; +}(split_1.Split)); +exports.LegendComponent = LegendComponent; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGVnZW5kL2NvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFHQSxrQ0FBK0I7QUFHL0I7SUFBcUMsbUNBQXdCO0lBQTdEOztJQUErRCxDQUFDO0lBQUQsc0JBQUM7QUFBRCxDQUFDLEFBQWhFLENBQXFDLGFBQUssR0FBc0I7QUFBbkQsMENBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0xlZ2VuZH0gZnJvbSAnLi4vLi4vL2xlZ2VuZCc7XG5pbXBvcnQge05vblBvc2l0aW9uU2NhbGVDaGFubmVsfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7VmdMZWdlbmR9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7U3BsaXR9IGZyb20gJy4uL3NwbGl0JztcblxuXG5leHBvcnQgY2xhc3MgTGVnZW5kQ29tcG9uZW50IGV4dGVuZHMgU3BsaXQ8UGFydGlhbDxWZ0xlZ2VuZD4+IHt9XG5cbi8vIFVzaW5nIE1hcHBlZCBUeXBlIHRvIGRlY2xhcmUgdHlwZSAoaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svYWR2YW5jZWQtdHlwZXMuaHRtbCNtYXBwZWQtdHlwZXMpXG5leHBvcnQgdHlwZSBMZWdlbmRDb21wb25lbnRJbmRleCA9IHtbUCBpbiBOb25Qb3NpdGlvblNjYWxlQ2hhbm5lbF0/OiBMZWdlbmRDb21wb25lbnR9O1xuXG5leHBvcnQgdHlwZSBMZWdlbmRJbmRleCA9IHtbUCBpbiBOb25Qb3NpdGlvblNjYWxlQ2hhbm5lbF0/OiBMZWdlbmR9O1xuIl19 \ 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..f706f69252 --- /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 } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel, type: LegendType): any; +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..79b121e0b2 --- /dev/null +++ b/build/src/compile/legend/encode.js @@ -0,0 +1,114 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var mark_1 = require("../../mark"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var mixins = require("../mark/mixins"); +function symbols(fieldDef, symbolsSpec, model, channel, type) { + if (type === 'gradient') { + return undefined; + } + var symbols = {}; + var mark = model.mark(); + switch (mark) { + case mark_1.BAR: + case mark_1.TICK: + case mark_1.TEXT: + symbols.shape = { value: 'square' }; + break; + case mark_1.CIRCLE: + case mark_1.SQUARE: + symbols.shape = { value: mark }; + break; + case mark_1.POINT: + case mark_1.LINE: + case mark_1.AREA: + // use default circle + break; + } + var filled = model.markDef.filled; + var config = channel === channel_1.COLOR ? + /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */ + util_1.without(mark_1.FILL_STROKE_CONFIG, [filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) : + /* For other legend, no need to omit. */ + mark_1.FILL_STROKE_CONFIG; + config = util_1.without(config, ['strokeDash', 'strokeDashOffset']); + common_1.applyMarkConfig(symbols, model, config); + if (channel !== channel_1.COLOR) { + var colorMixins = mixins.color(model); + // If there are field for fill or stroke, remove them as we already apply channels. + if (colorMixins.fill && (colorMixins.fill['field'] || colorMixins.fill['value'] === 'transparent')) { + delete colorMixins.fill; + } + if (colorMixins.stroke && (colorMixins.stroke['field'] || colorMixins.stroke['value'] === 'transparent')) { + delete colorMixins.stroke; + } + symbols = __assign({}, symbols, colorMixins); + } + if (channel !== channel_1.SHAPE) { + var shapeDef = model.encoding.shape; + if (fielddef_1.isValueDef(shapeDef)) { + symbols.shape = { value: shapeDef.value }; + } + } + if (channel !== channel_1.OPACITY) { + var opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity; + if (opacity) { + symbols.opacity = { value: opacity }; + } + } + symbols = __assign({}, symbols, symbolsSpec); + return util_1.keys(symbols).length > 0 ? symbols : undefined; +} +exports.symbols = symbols; +function gradient(fieldDef, gradientSpec, model, channel, type) { + var gradient = {}; + if (type === 'gradient') { + var opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity; + if (opacity) { + gradient.opacity = { value: opacity }; + } + } + gradient = __assign({}, gradient, gradientSpec); + return util_1.keys(gradient).length > 0 ? gradient : undefined; +} +exports.gradient = gradient; +function labels(fieldDef, labelsSpec, model, channel, type) { + var legend = model.legend(channel); + var config = model.config; + var labels = {}; + if (fielddef_1.isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === scale_1.ScaleType.UTC; + labelsSpec = __assign({ text: { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale) + } }, labelsSpec); + } + labels = __assign({}, labels, labelsSpec); + return util_1.keys(labels).length > 0 ? labels : undefined; +} +exports.labels = labels; +function getOpacityValue(opacityDef) { + if (fielddef_1.isValueDef(opacityDef)) { + if (fielddef_1.hasConditionalValueDef(opacityDef)) { + var values = vega_util_1.isArray(opacityDef.condition) ? opacityDef.condition.map(function (c) { return c.value; }) : [opacityDef.condition.value]; + return Math.max.apply(null, [opacityDef.value].concat(values)); + } + else { + return opacityDef.value; + } + } + return undefined; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGVnZW5kL2VuY29kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsdUNBQWtDO0FBQ2xDLHlDQUFzRjtBQUN0RiwyQ0FBNEo7QUFDNUosbUNBQWtHO0FBQ2xHLHFDQUFzQztBQUN0QyxtQ0FBeUM7QUFFekMsb0NBQWdFO0FBQ2hFLHVDQUF5QztBQUd6QyxpQkFBd0IsUUFBMEIsRUFBRSxXQUFnQixFQUFFLEtBQWdCLEVBQUUsT0FBZ0IsRUFBRSxJQUFnQjtJQUN4SCxFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxJQUFJLE9BQU8sR0FBTyxFQUFFLENBQUM7SUFDckIsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBRTFCLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDYixLQUFLLFVBQUcsQ0FBQztRQUNULEtBQUssV0FBSSxDQUFDO1FBQ1YsS0FBSyxXQUFJO1lBQ1AsT0FBTyxDQUFDLEtBQUssR0FBRyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQztZQUNsQyxLQUFLLENBQUM7UUFDUixLQUFLLGFBQU0sQ0FBQztRQUNaLEtBQUssYUFBTTtZQUNULE9BQU8sQ0FBQyxLQUFLLEdBQUcsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUM7WUFDOUIsS0FBSyxDQUFDO1FBQ1IsS0FBSyxZQUFLLENBQUM7UUFDWCxLQUFLLFdBQUksQ0FBQztRQUNWLEtBQUssV0FBSTtZQUNQLHFCQUFxQjtZQUNyQixLQUFLLENBQUM7SUFDVixDQUFDO0lBRUQsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFFcEMsSUFBSSxNQUFNLEdB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QyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDdEQsQ0FBQztBQW5CRCx3QkFtQkM7QUFFRCx5QkFBeUIsVUFBNkc7SUFDcEksRUFBRSxDQUFDLENBQUMscUJBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsRUFBRSxDQUFDLENBQUMsaUNBQXNCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLElBQU0sTUFBTSxHQUFHLG1CQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLENBQUMsQ0FBQyxLQUFLLEVBQVAsQ0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNySCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBZSxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLFNBQVMsQ0FBQztBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtpc0FycmF5fSBmcm9tICd2ZWdhLXV0aWwnO1xuaW1wb3J0IHtDaGFubmVsLCBDT0xPUiwgTm9uUG9zaXRpb25TY2FsZUNoYW5uZWwsIE9QQUNJVFksIFNIQVBFfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7RmllbGREZWYsIEZpZWxkRGVmV2l0aENvbmRpdGlvbiwgaGFzQ29uZGl0aW9uYWxWYWx1ZURlZiwgaXNUaW1lRmllbGREZWYsIGlzVmFsdWVEZWYsIE1hcmtQcm9wRmllbGREZWYsIFZhbHVlRGVmV2l0aENvbmRpdGlvbn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0IHtBUkVBLCBCQVIsIENJUkNMRSwgRklMTF9TVFJPS0VfQ09ORklHLCBMSU5FLCBQT0lOVCwgU1FVQVJFLCBURVhULCBUSUNLfSBmcm9tICcuLi8uLi9tYXJrJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge2tleXMsIHdpdGhvdXR9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtMZWdlbmRUeXBlfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge2FwcGx5TWFya0NvbmZpZywgdGltZUZvcm1hdEV4cHJlc3Npb259IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQgKiBhcyBtaXhpbnMgZnJvbSAnLi4vbWFyay9taXhpbnMnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuXG5leHBvcnQgZnVuY3Rpb24gc3ltYm9scyhmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgc3ltYm9sc1NwZWM6IGFueSwgbW9kZWw6IFVuaXRNb2RlbCwgY2hhbm5lbDogQ2hhbm5lbCwgdHlwZTogTGVnZW5kVHlwZSkge1xuICBpZiAodHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBsZXQgc3ltYm9sczphbnkgPSB7fTtcbiAgY29uc3QgbWFyayA9IG1vZGVsLm1hcmsoKTtcblxuICBzd2l0Y2ggKG1hcmspIHtcbiAgICBjYXNlIEJBUjpcbiAgICBjYXNlIFRJQ0s6XG4gICAgY2FzZSBURVhUOlxuICAgICAgc3ltYm9scy5zaGFwZSA9IHt2YWx1ZTogJ3NxdWFyZSd9O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBDSVJDTEU6XG4gICAgY2FzZSBTUVVBUkU6XG4gICAgICBzeW1ib2xzLnNoYXBlID0ge3ZhbHVlOiBtYXJrfTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgUE9JTlQ6XG4gICAgY2FzZSBMSU5FOlxuICAgIGNhc2UgQVJFQTpcbiAgICAgIC8vIHVzZSBkZWZhdWx0IGNpcmNsZVxuICAgICAgYnJlYWs7XG4gIH1cblxuICBjb25zdCBmaWxsZWQgPSBtb2RlbC5tYXJrRGVmLmZpbGxlZDtcblxuICBsZXQgY29uZmlnID0gY2hhbm5lbCA9PT0gQ09MT1IgP1xuICAgICAgLyogRm9yIGNvbG9yJ3MgbGVnZW5kLCBkbyBub3Qgc2V0IGZpbGwgKHdoZW4gZmlsbGVkKSBvciBzdHJva2UgKHdoZW4gdW5maWxsZWQpIHByb3BlcnR5IGZyb20gY29uZmlnIGJlY2F1c2UgdGhlIGxlZ2VuZCdzIGBmaWxsYCBvciBgc3Ryb2tlYCBzY2FsZSBzaG91bGQgaGF2ZSBwcmVjZWRlbmNlICovXG4gICAgICB3aXRob3V0KEZJTExfU1RST0tFX0NPTkZJRywgWyBmaWxsZWQgPyAnZmlsbCcgOiAnc3Ryb2tlJywgJ3N0cm9rZURhc2gnLCAnc3Ryb2tlRGFzaE9mZnNldCddKSA6XG4gICAgICAvKiBGb3Igb3RoZXIgbGVnZW5kLCBubyBuZWVkIHRvIG9taXQuICovXG4gICAgICBGSUxMX1NUUk9LRV9DT05GSUc7XG5cbiAgY29uZmlnID0gd2l0aG91dChjb25maWcsIFsnc3Ryb2tlRGFzaCcsICdzdHJva2VEYXNoT2Zmc2V0J10pO1xuXG4gIGFwcGx5TWFya0NvbmZpZyhzeW1ib2xzLCBtb2RlbCwgY29uZmlnKTtcblxuICBpZiAoY2hhbm5lbCAhPT0gQ09MT1IpIHtcbiAgICBjb25zdCBjb2xvck1peGlucyA9IG1peGlucy5jb2xvcihtb2RlbCk7XG5cbiAgICAvLyBJZiB0aGVyZSBhcmUgZmllbGQgZm9yIGZpbGwgb3Igc3Ryb2tlLCByZW1vdmUgdGhlbSBhcyB3ZSBhbHJlYWR5IGFwcGx5IGNoYW5uZWxzLlxuICAgIGlmIChjb2xvck1peGlucy5maWxsICYmIChjb2xvck1peGlucy5maWxsWydmaWVsZCddIHx8IGNvbG9yTWl4aW5zLmZpbGxbJ3ZhbHVlJ10gPT09ICd0cmFuc3BhcmVudCcpKSB7XG4gICAgICBkZWxldGUgY29sb3JNaXhpbnMuZmlsbDtcbiAgICB9XG4gICAgaWYgKGNvbG9yTWl4aW5zLnN0cm9rZSAmJiAoY29sb3JNaXhpbnMuc3Ryb2tlWydmaWVsZCddIHx8IGNvbG9yTWl4aW5zLnN0cm9rZVsndmFsdWUnXSA9PT0gJ3RyYW5zcGFyZW50JykpIHtcbiAgICAgIGRlbGV0ZSBjb2xvck1peGlucy5zdHJva2U7XG4gICAgfVxuICAgIHN5bWJvbHMgPSB7Li4uc3ltYm9scywgLi4uY29sb3JNaXhpbnN9O1xuICB9XG5cbiAgaWYgKGNoYW5uZWwgIT09IFNIQVBFKSB7XG4gICAgY29uc3Qgc2hhcGVEZWYgPSBtb2RlbC5lbmNvZGluZy5zaGFwZTtcbiAgICBpZiAoaXNWYWx1ZURlZihzaGFwZURlZikpIHtcbiAgICAgIHN5bWJvbHMuc2hhcGUgPSB7dmFsdWU6IHNoYXBlRGVmLnZhbHVlfTtcbiAgICB9XG4gIH1cblxuICBpZiAoY2hhbm5lbCAhPT0gT1BBQ0lUWSkge1xuICAgIGNvbnN0IG9wYWNpdHkgPSBnZXRPcGFjaXR5VmFsdWUobW9kZWwuZW5jb2Rpbmcub3BhY2l0eSkgfHwgbW9kZWwubWFya0RlZi5vcGFjaXR5O1xuICAgIGlmIChvcGFjaXR5KSB7IC8vIG9ubHkgYXBwbHkgb3BhY2l0eSBpZiBpdCBpcyBuZWl0aGVyIHplcm8gb3IgdW5kZWZpbmVkXG4gICAgICBzeW1ib2xzLm9wYWNpdHkgPSB7dmFsdWU6IG9wYWNpdHl9O1xuICAgIH1cbiAgfVxuXG4gIHN5bWJvbHMgPSB7Li4uc3ltYm9scywgLi4uc3ltYm9sc1NwZWN9O1xuXG4gIHJldHVybiBrZXlzKHN5bWJvbHMpLmxlbmd0aCA+IDAgPyBzeW1ib2xzIDogdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ3JhZGllbnQoZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIGdyYWRpZW50U3BlYzogYW55LCBtb2RlbDogVW5pdE1vZGVsLCBjaGFubmVsOiBDaGFubmVsLCB0eXBlOiBMZWdlbmRUeXBlKSB7XG4gIGxldCBncmFkaWVudDphbnkgPSB7fTtcblxuICBpZiAodHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuICAgIGNvbnN0IG9wYWNpdHkgPSBnZXRPcGFjaXR5VmFsdWUobW9kZWwuZW5jb2Rpbmcub3BhY2l0eSkgfHwgbW9kZWwubWFya0RlZi5vcGFjaXR5O1xuICAgIGlmIChvcGFjaXR5KSB7IC8vIG9ubHkgYXBwbHkgb3BhY2l0eSBpZiBpdCBpcyBuZWl0aGVyIHplcm8gb3IgdW5kZWZpbmVkXG4gICAgICBncmFkaWVudC5vcGFjaXR5ID0ge3ZhbHVlOiBvcGFjaXR5fTtcbiAgICB9XG4gIH1cblxuICBncmFkaWVudCA9IHsuLi5ncmFkaWVudCwgLi4uZ3JhZGllbnRTcGVjfTtcbiAgcmV0dXJuIGtleXMoZ3JhZGllbnQpLmxlbmd0aCA+IDAgPyBncmFkaWVudCA6IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxhYmVscyhmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgbGFiZWxzU3BlYzogYW55LCBtb2RlbDogVW5pdE1vZGVsLCBjaGFubmVsOiBOb25Qb3NpdGlvblNjYWxlQ2hhbm5lbCwgdHlwZTogTGVnZW5kVHlwZSkge1xuICBjb25zdCBsZWdlbmQgPSBtb2RlbC5sZWdlbmQoY2hhbm5lbCk7XG4gIGNvbnN0IGNvbmZpZyA9IG1vZGVsLmNvbmZpZztcblxuICBsZXQgbGFiZWxzOiBhbnkgPSB7fTtcblxuICBpZiAoaXNUaW1lRmllbGREZWYoZmllbGREZWYpKSB7XG4gICAgY29uc3QgaXNVVENTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpLmdldCgndHlwZScpID09PSBTY2FsZVR5cGUuVVRDO1xuICAgIGxhYmVsc1NwZWMgPSB7XG4gICAgICB0ZXh0OiB7XG4gICAgICAgIHNpZ25hbDogdGltZUZvcm1hdEV4cHJlc3Npb24oJ2RhdHVtLnZhbHVlJywgZmllbGREZWYudGltZVVuaXQsIGxlZ2VuZC5mb3JtYXQsIGNvbmZpZy5sZWdlbmQuc2hvcnRUaW1lTGFiZWxzLCBjb25maWcudGltZUZvcm1hdCwgaXNVVENTY2FsZSlcbiAgICAgIH0sXG4gICAgICAuLi5sYWJlbHNTcGVjLFxuICAgIH07XG4gIH1cblxuICBsYWJlbHMgPSB7Li4ubGFiZWxzLCAuLi5sYWJlbHNTcGVjfTtcblxuICByZXR1cm4ga2V5cyhsYWJlbHMpLmxlbmd0aCA+IDAgPyBsYWJlbHMgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGdldE9wYWNpdHlWYWx1ZShvcGFjaXR5RGVmOiBGaWVsZERlZldpdGhDb25kaXRpb248TWFya1Byb3BGaWVsZERlZjxzdHJpbmc+PiB8IFZhbHVlRGVmV2l0aENvbmRpdGlvbjxNYXJrUHJvcEZpZWxkRGVmPHN0cmluZz4+KTogbnVtYmVyIHtcbiAgaWYgKGlzVmFsdWVEZWYob3BhY2l0eURlZikpIHtcbiAgICBpZiAoaGFzQ29uZGl0aW9uYWxWYWx1ZURlZihvcGFjaXR5RGVmKSkge1xuICAgICAgY29uc3QgdmFsdWVzID0gaXNBcnJheShvcGFjaXR5RGVmLmNvbmRpdGlvbikgPyBvcGFjaXR5RGVmLmNvbmRpdGlvbi5tYXAoYyA9PiBjLnZhbHVlKSA6IFtvcGFjaXR5RGVmLmNvbmRpdGlvbi52YWx1ZV07XG4gICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkobnVsbCwgW29wYWNpdHlEZWYudmFsdWVdLmNvbmNhdCh2YWx1ZXMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG9wYWNpdHlEZWYudmFsdWUgYXMgbnVtYmVyO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIl19 \ 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..0eae154bf2 --- /dev/null +++ b/build/src/compile/legend/parse.js @@ -0,0 +1,178 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var legend_1 = require("../../legend"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var model_1 = require("../model"); +var resolve_1 = require("../resolve"); +var split_1 = require("../split"); +var split_2 = require("../split"); +var component_1 = require("./component"); +var encode = require("./encode"); +var properties = require("./properties"); +function parseLegend(model) { + if (model_1.isUnitModel(model)) { + model.component.legends = parseUnitLegend(model); + } + else { + model.component.legends = parseNonUnitLegend(model); + } +} +exports.parseLegend = parseLegend; +function parseUnitLegend(model) { + return [channel_1.COLOR, channel_1.SIZE, channel_1.SHAPE, channel_1.OPACITY].reduce(function (legendComponent, channel) { + if (model.legend(channel)) { + legendComponent[channel] = parseLegendForChannel(model, channel); + } + return legendComponent; + }, {}); +} +function getLegendDefWithScale(model, channel) { + // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels + switch (channel) { + case channel_1.COLOR: + var scale = model.scaleName(channel_1.COLOR); + return model.markDef.filled ? { fill: scale } : { stroke: scale }; + case channel_1.SIZE: + return { size: model.scaleName(channel_1.SIZE) }; + case channel_1.SHAPE: + return { shape: model.scaleName(channel_1.SHAPE) }; + case channel_1.OPACITY: + return { opacity: model.scaleName(channel_1.OPACITY) }; + } + return null; +} +function parseLegendForChannel(model, channel) { + var fieldDef = model.fieldDef(channel); + var legend = model.legend(channel); + var legendCmpt = new component_1.LegendComponent({}, getLegendDefWithScale(model, channel)); + legend_1.LEGEND_PROPERTIES.forEach(function (property) { + var value = getProperty(property, legend, channel, model); + if (value !== undefined) { + var explicit = property === 'values' ? + !!legend.values : // specified legend.values is already respected, but may get transformed. + 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 value = encode[part] ? + // TODO: replace legendCmpt with type is sufficient + encode[part](fieldDef, legendEncoding[part], model, channel, legendCmpt.get('type')) : // apply rule + legendEncoding[part]; // no rule -- just default values + if (value !== undefined && util_1.keys(value).length > 0) { + e[part] = { update: value }; + } + return e; + }, {}); + if (util_1.keys(legendEncode).length > 0) { + legendCmpt.set('encode', legendEncode, !!legend.encoding); + } + return legendCmpt; +} +exports.parseLegendForChannel = parseLegendForChannel; +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 common_1.numberFormat(fieldDef, specifiedLegend.format, model.config); + case 'title': + return common_1.getSpecifiedOrDefaultValue(specifiedLegend.title, fielddef_1.title(fieldDef, model.config)); + case 'values': + return properties.values(specifiedLegend); + case 'type': + return common_1.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); + util_1.keys(child.component.legends).forEach(function (channel) { + resolve.legend[channel] = resolve_1.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); + } + util_1.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 = split_2.mergeValuesWithExplicit(mergedLegend.getWithExplicit(prop), childLegend.getWithExplicit(prop), prop, 'legend', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return common_1.titleMerger(v1, v2); + case 'type': + // There are only two types. If we have different types, then prefer symbol over gradient. + typeMerged = true; + return split_1.makeImplicit('symbol'); + } + return split_2.defaultTieBreaker(v1, v2, prop, 'legend'); + }); + mergedLegend.setWithExplicit(prop, mergedValueWithExplicit); + }; + // Otherwise, let's merge + for (var _i = 0, VG_LEGEND_PROPERTIES_1 = legend_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) { + util_1.deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']); + } + if (((mergedLegend.explicit || {}).encode || {}).gradient) { + util_1.deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']); + } + } + return mergedLegend; +} +exports.mergeLegendComponent = mergeLegendComponent; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9sZWdlbmQvcGFyc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBNEY7QUFDNUYsMkNBQXNEO0FBQ3RELHVDQUE2RTtBQUM3RSxtQ0FBc0Q7QUFFdEQsb0NBQWdGO0FBQ2hGLGtDQUE0QztBQUM1QyxzQ0FBNkM7QUFDN0Msa0NBQWdEO0FBQ2hELGtDQUFvRTtBQUVwRSx5Q0FBa0U7QUFDbEUsaUNBQW1DO0FBQ25DLHlDQUEyQztBQUczQyxxQkFBNEIsS0FBWTtJQUN0QyxFQUFFLENBQUMsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUFDLElBQUksQ0FBQyxDQUFDO1FBQ04sS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEQsQ0FBQztBQUNILENBQUM7QUFORCxrQ0FNQztBQUVELHlCQUF5QixLQUFnQjtJQUN2QyxNQUFNLENBQUMsQ0FBQyxlQUFLLEVBQUUsY0FBSSxFQUFFLGVBQUssRUFBRSxpQkFBTyxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQVMsZUFBZSxFQUFFLE9BQU87UUFDM0UsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsZUFBZSxDQUFDLE9BQU8sQ0FBQyxHQUFHLHFCQUFxQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNuRSxDQUFDO1FBQ0QsTUFBTSxDQUFDLGVBQWUsQ0FBQztJQUN6QixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDVCxDQUFDO0FBRUQsK0JBQStCLEtBQWdCLEVBQUUsT0FBZ0I7SUFD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SUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ3pELDJCQUFvQixDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBQ0QsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDMUQsMkJBQW9CLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7SUFDSCxDQUFDO0lBR0QsTUFBTSxDQUFDLFlBQVksQ0FBQztBQUN0QixDQUFDO0FBL0NELG9EQStDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbm5lbCwgQ09MT1IsIE5vblBvc2l0aW9uU2NhbGVDaGFubmVsLCBPUEFDSVRZLCBTSEFQRSwgU0laRX0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge3RpdGxlIGFzIGZpZWxkRGVmVGl0bGV9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCB7TGVnZW5kLCBMRUdFTkRfUFJPUEVSVElFUywgVkdfTEVHRU5EX1BST1BFUlRJRVN9IGZyb20gJy4uLy4uL2xlZ2VuZCc7XG5pbXBvcnQge2RlbGV0ZU5lc3RlZFByb3BlcnR5LCBrZXlzfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7VmdMZWdlbmQsIFZnTGVnZW5kRW5jb2RlfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge2dldFNwZWNpZmllZE9yRGVmYXVsdFZhbHVlLCBudW1iZXJGb3JtYXQsIHRpdGxlTWVyZ2VyfSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHtpc1VuaXRNb2RlbCwgTW9kZWx9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7cGFyc2VHdWlkZVJlc29sdmV9IGZyb20gJy4uL3Jlc29sdmUnO1xuaW1wb3J0IHtFeHBsaWNpdCwgbWFrZUltcGxpY2l0fSBmcm9tICcuLi9zcGxpdCc7XG5pbXBvcnQge2RlZmF1bHRUaWVCcmVha2VyLCBtZXJnZVZhbHVlc1dpdGhFeHBsaWNpdH0gZnJvbSAnLi4vc3BsaXQnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IHtMZWdlbmRDb21wb25lbnQsIExlZ2VuZENvbXBvbmVudEluZGV4fSBmcm9tICcuL2NvbXBvbmVudCc7XG5pbXBvcnQgKiBhcyBlbmNvZGUgZnJvbSAnLi9lbmNvZGUnO1xuaW1wb3J0ICogYXMgcHJvcGVydGllcyBmcm9tICcuL3Byb3BlcnRpZXMnO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxlZ2VuZChtb2RlbDogTW9kZWwpIHtcbiAgaWYgKGlzVW5pdE1vZGVsKG1vZGVsKSkge1xuICAgIG1vZGVsLmNvbXBvbmVudC5sZWdlbmRzID0gcGFyc2VVbml0TGVnZW5kKG1vZGVsKTtcbiAgfSBlbHNlIHtcbiAgICBtb2RlbC5jb21wb25lbnQubGVnZW5kcyA9IHBhcnNlTm9uVW5pdExlZ2VuZChtb2RlbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VVbml0TGVnZW5kKG1vZGVsOiBVbml0TW9kZWwpOiBMZWdlbmRDb21wb25lbnRJbmRleCB7XG4gIHJldHVybiBbQ09MT1IsIFNJWkUsIFNIQVBFLCBPUEFDSVRZXS5yZWR1Y2UoZnVuY3Rpb24obGVnZW5kQ29tcG9uZW50LCBjaGFubmVsKSB7XG4gICAgaWYgKG1vZGVsLmxlZ2VuZChjaGFubmVsKSkge1xuICAgICAgbGVnZW5kQ29tcG9uZW50W2NoYW5uZWxdID0gcGFyc2VMZWdlbmRGb3JDaGFubmVsKG1vZGVsLCBjaGFubmVsKTtcbiAgICB9XG4gICAgcmV0dXJuIGxlZ2VuZENvbXBvbmVudDtcbiAgfSwge30pO1xufVxuXG5mdW5jdGlvbiBnZXRMZWdlbmREZWZXaXRoU2NhbGUobW9kZWw6IFVuaXRNb2RlbCwgY2hhbm5lbDogQ2hhbm5lbCk6IFZnTGVnZW5kIHtcbiAgLy8gRm9yIGJpbm5lZCBmaWVsZCB3aXRoIGNvbnRpbnVvdXMgc2NhbGUsIHVzZSBhIHNwZWNpYWwgc2NhbGUgc28gd2UgY2FuIG92ZXJycmlkZSB0aGUgbWFyayBwcm9wcyBhbmQgbGFiZWxzXG4gIHN3aXRjaCAoY2hhbm5lbCkge1xuICAgIGNhc2UgQ09MT1I6XG4gICAgICBjb25zdCBzY2FsZSA9IG1vZGVsLnNjYWxlTmFtZShDT0xPUik7XG4gICAgICByZXR1cm4gbW9kZWwubWFya0RlZi5maWxsZWQgPyB7ZmlsbDogc2NhbGV9IDoge3N0cm9rZTogc2NhbGV9O1xuICAgIGNhc2UgU0laRTpcbiAgICAgIHJldHVybiB7c2l6ZTogbW9kZWwuc2NhbGVOYW1lKFNJWkUpfTtcbiAgICBjYXNlIFNIQVBFOlxuICAgICAgcmV0dXJuIHtzaGFwZTogbW9kZWwuc2NhbGVOYW1lKFNIQVBFKX07XG4gICAgY2FzZSBPUEFDSVRZOlxuICAgICAgcmV0dXJuIHtvcGFjaXR5OiBtb2RlbC5zY2FsZU5hbWUoT1BBQ0lUWSl9O1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VMZWdlbmRGb3JDaGFubmVsKG1vZGVsOiBVbml0TW9kZWwsIGNoYW5uZWw6IE5vblBvc2l0aW9uU2NhbGVDaGFubmVsKTogTGVnZW5kQ29tcG9uZW50IHtcbiAgY29uc3QgZmllbGREZWYgPSBtb2RlbC5maWVsZERlZihjaGFubmVsKTtcbiAgY29uc3QgbGVnZW5kID0gbW9kZWwubGVnZW5kKGNoYW5uZWwpO1xuXG4gIGNvbnN0IGxlZ2VuZENtcHQgPSBuZXcgTGVnZW5kQ29tcG9uZW50KHt9LCBnZXRMZWdlbmREZWZXaXRoU2NhbGUobW9kZWwsIGNoYW5uZWwpKTtcblxuICBMRUdFTkRfUFJPUEVSVElFUy5mb3JFYWNoKGZ1bmN0aW9uKHByb3BlcnR5KSB7XG4gICAgY29uc3QgdmFsdWUgPSBnZXRQcm9wZXJ0eShwcm9wZXJ0eSwgbGVnZW5kLCBjaGFubmVsLCBtb2RlbCk7XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGV4cGxpY2l0ID0gcHJvcGVydHkgPT09ICd2YWx1ZXMnID9cbiAgICAgICAgISFsZWdlbmQudmFsdWVzIDogIC8vIHNwZWNpZmllZCBsZWdlbmQudmFsdWVzIGlzIGFscmVhZHkgcmVzcGVjdGVkLCBidXQgbWF5IGdldCB0cmFuc2Zvcm1lZC5cbiAgICAgICAgdmFsdWUgPT09IGxlZ2VuZFtwcm9wZXJ0eV07XG4gICAgICBpZiAoZXhwbGljaXQgfHwgbW9kZWwuY29uZmlnLmxlZ2VuZFtwcm9wZXJ0eV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsZWdlbmRDbXB0LnNldChwcm9wZXJ0eSwgdmFsdWUsIGV4cGxpY2l0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIDIpIEFkZCBtYXJrIHByb3BlcnR5IGRlZmluaXRpb24gZ3JvdXBzXG4gIGNvbnN0IGxlZ2VuZEVuY29kaW5nID0gbGVnZW5kLmVuY29kaW5nIHx8IHt9O1xuICBjb25zdCBsZWdlbmRFbmNvZGUgPSBbJ2xhYmVscycsICdsZWdlbmQnLCAndGl0bGUnLCAnc3ltYm9scycsICdncmFkaWVudCddLnJlZHVjZSgoZTogVmdMZWdlbmRFbmNvZGUsIHBhcnQpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGVuY29kZVtwYXJ0XSA/XG4gICAgICAvLyBUT0RPOiByZXBsYWNlIGxlZ2VuZENtcHQgd2l0aCB0eXBlIGlzIHN1ZmZpY2llbnRcbiAgICAgIGVuY29kZVtwYXJ0XShmaWVsZERlZiwgbGVnZW5kRW5jb2RpbmdbcGFydF0sIG1vZGVsLCBjaGFubmVsLCBsZWdlbmRDbXB0LmdldCgndHlwZScpKSA6IC8vIGFwcGx5IHJ1bGVcbiAgICAgIGxlZ2VuZEVuY29kaW5nW3BhcnRdOyAvLyBubyBydWxlIC0tIGp1c3QgZGVmYXVsdCB2YWx1ZXNcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiBrZXlzKHZhbHVlKS5sZW5ndGggPiAwKSB7XG4gICAgICBlW3BhcnRdID0ge3VwZGF0ZTogdmFsdWV9O1xuICAgIH1cbiAgICByZXR1cm4gZTtcbiAgfSwge30gYXMgVmdMZWdlbmRFbmNvZGUpO1xuXG4gIGlmIChrZXlzKGxlZ2VuZEVuY29kZSkubGVuZ3RoID4gMCkge1xuICAgIGxlZ2VuZENtcHQuc2V0KCdlbmNvZGUnLCBsZWdlbmRFbmNvZGUsICEhbGVnZW5kLmVuY29kaW5nKTtcbiAgfVxuXG4gIHJldHVybiBsZWdlbmRDbXB0O1xufVxuXG5mdW5jdGlvbiBnZXRQcm9wZXJ0eShwcm9wZXJ0eToga2V5b2YgKExlZ2VuZCB8IFZnTGVnZW5kKSwgc3BlY2lmaWVkTGVnZW5kOiBMZWdlbmQsIGNoYW5uZWw6IE5vblBvc2l0aW9uU2NhbGVDaGFubmVsLCBtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IGZpZWxkRGVmID0gbW9kZWwuZmllbGREZWYoY2hhbm5lbCk7XG5cbiAgc3dpdGNoIChwcm9wZXJ0eSkge1xuICAgIGNhc2UgJ2Zvcm1hdCc6XG4gICAgICAvLyBXZSBkb24ndCBpbmNsdWRlIHRlbXBvcmFsIGZpZWxkIGhlcmUgYXMgd2UgYXBwbHkgZm9ybWF0IGluIGVuY29kZSBibG9ja1xuICAgICAgcmV0dXJuIG51bWJlckZvcm1hdChmaWVsZERlZiwgc3BlY2lmaWVkTGVnZW5kLmZvcm1hdCwgbW9kZWwuY29uZmlnKTtcbiAgICBjYXNlICd0aXRsZSc6XG4gICAgICByZXR1cm4gZ2V0U3BlY2lmaWVkT3JEZWZhdWx0VmFsdWUoc3BlY2lmaWVkTGVnZW5kLnRpdGxlLCBmaWVsZERlZlRpdGxlKGZpZWxkRGVmLCBtb2RlbC5jb25maWcpKTtcbiAgICBjYXNlICd2YWx1ZXMnOlxuICAgICAgcmV0dXJuIHByb3BlcnRpZXMudmFsdWVzKHNwZWNpZmllZExlZ2VuZCk7XG4gICAgY2FzZSAndHlwZSc6XG4gICAgICByZXR1cm4gZ2V0U3BlY2lmaWVkT3JEZWZhdWx0VmFsdWUoc3BlY2lmaWVkTGVnZW5kLnR5cGUsIHByb3BlcnRpZXMudHlwZShmaWVsZERlZi50eXBlLCBjaGFubmVsLCBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKS5nZXQoJ3R5cGUnKSkpO1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCByZXR1cm4gc3BlY2lmaWVkIHByb3BlcnR5LlxuICByZXR1cm4gc3BlY2lmaWVkTGVnZW5kW3Byb3BlcnR5XTtcbn1cblxuZnVuY3Rpb24gcGFyc2VOb25Vbml0TGVnZW5kKG1vZGVsOiBNb2RlbCkge1xuICBjb25zdCB7bGVnZW5kcywgcmVzb2x2ZX0gPSBtb2RlbC5jb21wb25lbnQ7XG5cbiAgZm9yIChjb25zdCBjaGlsZCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgIHBhcnNlTGVnZW5kKGNoaWxkKTtcblxuICAgIGtleXMoY2hpbGQuY29tcG9uZW50LmxlZ2VuZHMpLmZvckVhY2goKGNoYW5uZWw6IE5vblBvc2l0aW9uU2NhbGVDaGFubmVsKSA9PiB7XG4gICAgICByZXNvbHZlLmxlZ2VuZFtjaGFubmVsXSA9IHBhcnNlR3VpZGVSZXNvbHZlKG1vZGVsLmNvbXBvbmVudC5yZXNvbHZlLCBjaGFubmVsKTtcblxuICAgICAgaWYgKHJlc29sdmUubGVnZW5kW2NoYW5uZWxdID09PSAnc2hhcmVkJykge1xuICAgICAgICAvLyBJZiB0aGUgcmVzb2x2ZSBzYXlzIHNoYXJlZCAoYW5kIGhhcyBub3QgYmVlbiBvdmVycmlkZGVuKVxuICAgICAgICAvLyBXZSB3aWxsIHRyeSB0byBtZXJnZSBhbmQgc2VlIGlmIHRoZXJlIGlzIGEgY29uZmxpY3RcblxuICAgICAgICBsZWdlbmRzW2NoYW5uZWxdID0gbWVyZ2VMZWdlbmRDb21wb25lbnQobGVnZW5kc1tjaGFubmVsXSwgY2hpbGQuY29tcG9uZW50LmxlZ2VuZHNbY2hhbm5lbF0pO1xuXG4gICAgICAgIGlmICghbGVnZW5kc1tjaGFubmVsXSkge1xuICAgICAgICAgIC8vIElmIG1lcmdlIHJldHVybnMgbm90aGluZywgdGhlcmUgaXMgYSBjb25mbGljdCBzbyB3ZSBjYW5ub3QgbWFrZSB0aGUgbGVnZW5kIHNoYXJlZC5cbiAgICAgICAgICAvLyBUaHVzLCBtYXJrIGxlZ2VuZCBhcyBpbmRlcGVuZGVudCBhbmQgcmVtb3ZlIHRoZSBsZWdlbmQgY29tcG9uZW50LlxuICAgICAgICAgIHJlc29sdmUubGVnZW5kW2NoYW5uZWxdID0gJ2luZGVwZW5kZW50JztcbiAgICAgICAgICBkZWxldGUgbGVnZW5kc1tjaGFubmVsXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAga2V5cyhsZWdlbmRzKS5mb3JFYWNoKChjaGFubmVsOiBOb25Qb3NpdGlvblNjYWxlQ2hhbm5lbCkgPT4ge1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgbW9kZWwuY2hpbGRyZW4pIHtcbiAgICAgIGlmICghY2hpbGQuY29tcG9uZW50LmxlZ2VuZHNbY2hhbm5lbF0pIHtcbiAgICAgICAgLy8gc2tpcCBpZiB0aGUgY2hpbGQgZG9lcyBub3QgaGF2ZSBhIHBhcnRpY3VsYXIgbGVnZW5kXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzb2x2ZS5sZWdlbmRbY2hhbm5lbF0gPT09ICdzaGFyZWQnKSB7XG4gICAgICAgIC8vIEFmdGVyIG1lcmdpbmcgc2hhcmVkIGxlZ2VuZCwgbWFrZSBzdXJlIHRvIHJlbW92ZSBsZWdlbmQgZnJvbSBjaGlsZFxuICAgICAgICBkZWxldGUgY2hpbGQuY29tcG9uZW50LmxlZ2VuZHNbY2hhbm5lbF07XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGxlZ2VuZHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUxlZ2VuZENvbXBvbmVudChtZXJnZWRMZWdlbmQ6IExlZ2VuZENvbXBvbmVudCwgY2hpbGRMZWdlbmQ6IExlZ2VuZENvbXBvbmVudCkge1xuICBpZiAoIW1lcmdlZExlZ2VuZCkge1xuICAgIHJldHVybiBjaGlsZExlZ2VuZC5jbG9uZSgpO1xuICB9XG4gIGNvbnN0IG1lcmdlZE9yaWVudCA9IG1lcmdlZExlZ2VuZC5nZXRXaXRoRXhwbGljaXQoJ29yaWVudCcpO1xuICBjb25zdCBjaGlsZE9yaWVudCA9IGNoaWxkTGVnZW5kLmdldFdpdGhFeHBsaWNpdCgnb3JpZW50Jyk7XG5cblxuICBpZiAobWVyZ2VkT3JpZW50LmV4cGxpY2l0ICYmIGNoaWxkT3JpZW50LmV4cGxpY2l0ICYmIG1lcmdlZE9yaWVudC52YWx1ZSAhPT0gY2hpbGRPcmllbnQudmFsdWUpIHtcbiAgICAvLyBUT0RPOiB0aHJvdyB3YXJuaW5nIGlmIHJlc29sdmUgaXMgZXhwbGljaXQgKFdlIGRvbid0IGhhdmUgaW5mbyBhYm91dCBleHBsaWNpdC9pbXBsaWNpdCByZXNvbHZlIHlldC4pXG4gICAgLy8gQ2Fubm90IG1lcmdlIGR1ZSB0byBpbmNvbnNpc3RlbnQgb3JpZW50XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgdHlwZU1lcmdlZCA9IGZhbHNlO1xuICAvLyBPdGhlcndpc2UsIGxldCdzIG1lcmdlXG4gIGZvciAoY29uc3QgcHJvcCBvZiBWR19MRUdFTkRfUFJPUEVSVElFUykge1xuICAgIGNvbnN0IG1lcmdlZFZhbHVlV2l0aEV4cGxpY2l0ID0gbWVyZ2VWYWx1ZXNXaXRoRXhwbGljaXQ8VmdMZWdlbmQsIGFueT4oXG4gICAgICBtZXJnZWRMZWdlbmQuZ2V0V2l0aEV4cGxpY2l0KHByb3ApLFxuICAgICAgY2hpbGRMZWdlbmQuZ2V0V2l0aEV4cGxpY2l0KHByb3ApLFxuICAgICAgcHJvcCwgJ2xlZ2VuZCcsXG5cbiAgICAgIC8vIFRpZSBicmVha2VyIGZ1bmN0aW9uXG4gICAgICAodjE6IEV4cGxpY2l0PGFueT4sIHYyOiBFeHBsaWNpdDxhbnk+KTogYW55ID0+IHtcbiAgICAgICAgc3dpdGNoIChwcm9wKSB7XG4gICAgICAgICAgY2FzZSAndGl0bGUnOlxuICAgICAgICAgICAgcmV0dXJuIHRpdGxlTWVyZ2VyKHYxLCB2Mik7XG4gICAgICAgICAgY2FzZSAndHlwZSc6XG4gICAgICAgICAgICAvLyBUaGVyZSBhcmUgb25seSB0d28gdHlwZXMuIElmIHdlIGhhdmUgZGlmZmVyZW50IHR5cGVzLCB0aGVuIHByZWZlciBzeW1ib2wgb3ZlciBncmFkaWVudC5cbiAgICAgICAgICAgIHR5cGVNZXJnZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIG1ha2VJbXBsaWNpdCgnc3ltYm9sJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlZmF1bHRUaWVCcmVha2VyPFZnTGVnZW5kLCBhbnk+KHYxLCB2MiwgcHJvcCwgJ2xlZ2VuZCcpO1xuICAgICAgfVxuICAgICk7XG4gICAgbWVyZ2VkTGVnZW5kLnNldFdpdGhFeHBsaWNpdChwcm9wLCBtZXJnZWRWYWx1ZVdpdGhFeHBsaWNpdCk7XG4gIH1cbiAgaWYgKHR5cGVNZXJnZWQpIHtcbiAgICBpZigoKG1lcmdlZExlZ2VuZC5pbXBsaWNpdCB8fCB7fSkuZW5jb2RlIHx8IHt9KS5ncmFkaWVudCkge1xuICAgICAgZGVsZXRlTmVzdGVkUHJvcGVydHkobWVyZ2VkTGVnZW5kLmltcGxpY2l0LCBbJ2VuY29kZScsICdncmFkaWVudCddKTtcbiAgICB9XG4gICAgaWYgKCgobWVyZ2VkTGVnZW5kLmV4cGxpY2l0IHx8IHt9KS5lbmNvZGUgfHwge30pLmdyYWRpZW50KSB7XG4gICAgICBkZWxldGVOZXN0ZWRQcm9wZXJ0eShtZXJnZWRMZWdlbmQuZXhwbGljaXQsIFsnZW5jb2RlJywgJ2dyYWRpZW50J10pO1xuICAgIH1cbiAgfVxuXG5cbiAgcmV0dXJuIG1lcmdlZExlZ2VuZDtcbn1cblxuIl19 \ 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..25bd055a2b --- /dev/null +++ b/build/src/compile/legend/properties.d.ts @@ -0,0 +1,9 @@ +import { Channel } from '../../channel'; +import { DateTime } from '../../datetime'; +import { Legend } from '../../legend'; +import { ScaleType } from '../../scale'; +import { Type } from '../../type'; +export declare function values(legend: Legend): string[] | number[] | DateTime[] | { + signal: string; +}[]; +export declare function type(type: 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..23557e25f8 --- /dev/null +++ b/build/src/compile/legend/properties.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +function values(legend) { + var vals = legend.values; + if (vals && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return { signal: datetime_1.dateTimeExpr(dt, true) }; + }); + } + return vals; +} +exports.values = values; +function type(type, channel, scaleType) { + if (channel === channel_1.COLOR && ((type === 'quantitative' && !scale_1.isBinScale(scaleType)) || + (type === 'temporal' && util_1.contains(['time', 'utc'], scaleType)))) { + return 'gradient'; + } + return undefined; +} +exports.type = type; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2xlZ2VuZC9wcm9wZXJ0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEseUNBQTZDO0FBQzdDLDJDQUFrRTtBQUVsRSxxQ0FBa0Q7QUFFbEQsbUNBQW9DO0FBRXBDLGdCQUF1QixNQUFjO0lBQ25DLElBQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDM0IsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLHFCQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sQ0FBRSxJQUFtQixDQUFDLEdBQUcsQ0FBQyxVQUFDLEVBQUU7WUFDakMscURBQXFEO1lBQ3JELE1BQU0sQ0FBQyxFQUFDLE1BQU0sRUFBRSx1QkFBWSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBVEQsd0JBU0M7QUFFRCxjQUFxQixJQUFVLEVBQUUsT0FBZ0IsRUFBRSxTQUFvQjtJQUNyRSxFQUFFLENBQUMsQ0FDQyxPQUFPLEtBQUssZUFBSyxJQUFJLENBQ25CLENBQUMsSUFBSSxLQUFLLGNBQWMsSUFBSSxDQUFDLGtCQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkQsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLGVBQVEsQ0FBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUU1RSxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUNELE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQVZELG9CQVVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFubmVsLCBDT0xPUn0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge0RhdGVUaW1lLCBkYXRlVGltZUV4cHIsIGlzRGF0ZVRpbWV9IGZyb20gJy4uLy4uL2RhdGV0aW1lJztcbmltcG9ydCB7TGVnZW5kfSBmcm9tICcuLi8uLi9sZWdlbmQnO1xuaW1wb3J0IHtpc0JpblNjYWxlLCBTY2FsZVR5cGV9IGZyb20gJy4uLy4uL3NjYWxlJztcbmltcG9ydCB7VHlwZX0gZnJvbSAnLi4vLi4vdHlwZSc7XG5pbXBvcnQge2NvbnRhaW5zfSBmcm9tICcuLi8uLi91dGlsJztcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbHVlcyhsZWdlbmQ6IExlZ2VuZCkge1xuICBjb25zdCB2YWxzID0gbGVnZW5kLnZhbHVlcztcbiAgaWYgKHZhbHMgJiYgaXNEYXRlVGltZSh2YWxzWzBdKSkge1xuICAgIHJldHVybiAodmFscyBhcyBEYXRlVGltZVtdKS5tYXAoKGR0KSA9PiB7XG4gICAgICAvLyBub3JtYWxpemUgPSB0cnVlIGFzIGVuZCB1c2VyIHdvbid0IHB1dCAwID0gSmFudWFyeVxuICAgICAgcmV0dXJuIHtzaWduYWw6IGRhdGVUaW1lRXhwcihkdCwgdHJ1ZSl9O1xuICAgIH0pO1xuICB9XG4gIHJldHVybiB2YWxzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHlwZSh0eXBlOiBUeXBlLCBjaGFubmVsOiBDaGFubmVsLCBzY2FsZVR5cGU6IFNjYWxlVHlwZSk6ICdncmFkaWVudCcge1xuICBpZiAoXG4gICAgICBjaGFubmVsID09PSBDT0xPUiAmJiAoXG4gICAgICAgICh0eXBlID09PSAncXVhbnRpdGF0aXZlJyAmJiAhaXNCaW5TY2FsZShzY2FsZVR5cGUpKSB8fFxuICAgICAgICAodHlwZSA9PT0gJ3RlbXBvcmFsJyAmJiBjb250YWluczxTY2FsZVR5cGU+KFsndGltZScsICd1dGMnXSwgc2NhbGVUeXBlKSlcbiAgICAgIClcbiAgICApIHtcbiAgICByZXR1cm4gJ2dyYWRpZW50JztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIl19 \ 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..a5297ef7df --- /dev/null +++ b/build/src/compile/mark/area.js @@ -0,0 +1,18 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mixins = require("./mixins"); +exports.area = { + vgMark: 'area', + encodeEntry: function (model) { + return __assign({}, mixins.markDefProperties(model.markDef), mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin'), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model)); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJlYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvYXJlYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsaUNBQW1DO0FBR3RCLFFBQUEsSUFBSSxHQUFpQjtJQUNoQyxNQUFNLEVBQUUsTUFBTTtJQUNkLFdBQVcsRUFBRSxVQUFDLEtBQWdCO1FBQzVCLE1BQU0sY0FDRCxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUN2QyxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsRUFDN0MsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEVBRXpDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxFQUM3QixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDdkM7SUFDSixDQUFDO0NBQ0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7TWFya0NvbXBpbGVyfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0ICogYXMgbWl4aW5zIGZyb20gJy4vbWl4aW5zJztcblxuXG5leHBvcnQgY29uc3QgYXJlYTogTWFya0NvbXBpbGVyID0ge1xuICB2Z01hcms6ICdhcmVhJyxcbiAgZW5jb2RlRW50cnk6IChtb2RlbDogVW5pdE1vZGVsKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1peGlucy5tYXJrRGVmUHJvcGVydGllcyhtb2RlbC5tYXJrRGVmKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd4JywgbW9kZWwsICd6ZXJvT3JNaW4nKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd5JywgbW9kZWwsICd6ZXJvT3JNaW4nKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uMihtb2RlbCwgJ3plcm9Pck1pbicpLFxuXG4gICAgICAuLi5taXhpbnMuY29sb3IobW9kZWwpLFxuICAgICAgLi4ubWl4aW5zLnRleHQobW9kZWwsICd0b29sdGlwJyksXG4gICAgICAuLi5taXhpbnMubm9uUG9zaXRpb24oJ29wYWNpdHknLCBtb2RlbCksXG4gICAgfTtcbiAgfVxufTtcbiJdfQ== \ 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..df9943aec3 --- /dev/null +++ b/build/src/compile/mark/bar.js @@ -0,0 +1,102 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.bar = { + vgMark: 'rect', + encodeEntry: function (model) { + var stack = model.stack; + return __assign({}, mixins.markDefProperties(model.markDef, true), x(model, stack), y(model, stack), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model)); + } +}; +function x(model, stack) { + var config = model.config, width = model.width; + var orient = model.markDef.orient; + var sizeDef = model.encoding.size; + var xDef = model.encoding.x; + var xScaleName = model.scaleName(channel_1.X); + var xScale = model.getScaleComponent(channel_1.X); + // x, x2, and width -- we must specify two of these in all conditions + if (orient === 'horizontal') { + return __assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(xDef)) { + var xScaleType = xScale.get('type'); + if (xDef.bin && !sizeDef && !scale_1.hasDiscreteDomain(xScaleType)) { + return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), config.bar.binSpacing, xScale.get('reverse')); + } + else { + if (xScaleType === scale_1.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, __assign({}, ref.mid(width)), defaultSizeRef(xScaleName, xScale, config)); + } +} +function y(model, stack) { + var config = model.config, encoding = model.encoding, height = model.height; + var orient = model.markDef.orient; + var sizeDef = encoding.size; + var yDef = encoding.y; + var yScaleName = model.scaleName(channel_1.Y); + var yScale = model.getScaleComponent(channel_1.Y); + // y, y2 & height -- we must specify two of these in all conditions + if (orient === 'vertical') { + return __assign({}, mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(yDef)) { + var yScaleType = yScale.get('type'); + if (yDef.bin && !sizeDef && !scale_1.hasDiscreteDomain(yScaleType)) { + return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), config.bar.binSpacing, yScale.get('reverse')); + } + else if (yScaleType === scale_1.ScaleType.BAND) { + return mixins.bandPosition(yDef, 'y', model); + } + } + return mixins.centeredBandPosition('y', model, ref.mid(height), defaultSizeRef(yScaleName, yScale, config)); + } +} +function defaultSizeRef(scaleName, scale, config) { + if (config.bar.discreteBandSize) { + return { value: config.bar.discreteBandSize }; + } + if (scale) { + var scaleType = scale.get('type'); + if (scaleType === scale_1.ScaleType.POINT) { + var scaleRange = scale.get('range'); + if (vega_schema_1.isVgRangeStep(scaleRange) && vega_util_1.isNumber(scaleRange.step)) { + return { value: scaleRange.step - 1 }; + } + log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL); + } + else if (scaleType === scale_1.ScaleType.BAND) { + return ref.band(scaleName); + } + else { + return { value: config.bar.continuousBandSize }; + } + } + if (config.scale.rangeStep && config.scale.rangeStep !== null) { + return { value: config.scale.rangeStep - 1 }; + } + return { value: 20 }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9iYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLHVDQUFtQztBQUNuQyx5Q0FBbUM7QUFFbkMsMkNBQTBDO0FBQzFDLCtCQUFpQztBQUNqQyxxQ0FBeUQ7QUFHekQsaURBQStEO0FBSS9ELGlDQUFtQztBQUNuQyxnQ0FBa0M7QUFHckIsUUFBQSxHQUFHLEdBQWlCO0lBQy9CLE1BQU0sRUFBRSxNQUFNO0lBQ2QsV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDNUIsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMxQixNQUFNLGNBQ0QsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQzdDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQ2YsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsRUFDN0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3ZDO0lBQ0osQ0FBQztDQUNGLENBQUM7QUFFRixXQUFXLEtBQWdCLEVBQUUsS0FBc0I7SUFDMUMsSUFBQSxxQkFBTSxFQUFFLG1CQUFLLENBQVU7SUFDOUIsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDcEMsSUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFFcEMsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUIsSUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFDLENBQUMsQ0FBQztJQUN0QyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsV0FBQyxDQUFDLENBQUM7SUFDMUMscUVBQXFFO0lBQ3JFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sY0FDRCxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUM1QztJQUNKLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLElBQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLHlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQzFCLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUM5RSxDQUFDO1lBQ0osQ0FBQztZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNOLEVBQUUsQ0FBQyxDQUFDLFVBQVUsS0FBSyxpQkFBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ2xDLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQy9DLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUNELHFFQUFxRTtRQUVyRSxNQUFNLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxLQUFLLGVBQ3ZDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQ2xCLGNBQWMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUMzQyxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUM7QUFFRCxXQUFXLEtBQWdCLEVBQUUsS0FBc0I7SUFDMUMsSUFBQSxxQkFBTSxFQUFFLHlCQUFRLEVBQUUscUJBQU0sQ0FBVTtJQUN6QyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUNwQyxJQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO0lBRTlCLElBQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDeEIsSUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFDLENBQUMsQ0FBQztJQUN0QyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsV0FBQyxDQUFDLENBQUM7SUFDMUMsbUVBQW1FO0lBQ25FLEVBQUUsQ0FBQyxDQUFDLE1BQU0sS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQzFCLE1BQU0sY0FDRCxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUM1QztJQUNKLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLElBQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLHlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQzFCLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUM5RSxDQUFDO1lBQ0osQ0FBQztZQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxVQUFVLEtBQUssaUJBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxNQUFNLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9DLENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQzVELGNBQWMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUMzQyxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUM7QUFFRCx3QkFBd0IsU0FBaUIsRUFBRSxLQUFxQixFQUFFLE1BQWM7SUFDOUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7UUFDaEMsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNWLElBQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsRUFBRSxDQUFDLENBQUMsU0FBUyxLQUFLLGlCQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNsQyxJQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RDLEVBQUUsQ0FBQyxDQUFDLDJCQUFhLENBQUMsVUFBVSxDQUFDLElBQUksb0JBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMzRCxNQUFNLENBQUMsRUFBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUMsQ0FBQztZQUN0QyxDQUFDO1lBQ0QsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLEtBQUssaUJBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLE1BQU0sQ0FBQyxFQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFDLENBQUM7UUFDaEQsQ0FBQztJQUNILENBQUM7SUFDRCxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzlELE1BQU0sQ0FBQyxFQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUMsQ0FBQztJQUM3QyxDQUFDO0lBQ0QsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFDO0FBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzTnVtYmVyfSBmcm9tICd2ZWdhLXV0aWwnO1xuaW1wb3J0IHtYLCBZfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHtpc0ZpZWxkRGVmfSBmcm9tICcuLi8uLi9maWVsZGRlZic7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vbG9nJztcbmltcG9ydCB7aGFzRGlzY3JldGVEb21haW4sIFNjYWxlVHlwZX0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtTdGFja1Byb3BlcnRpZXN9IGZyb20gJy4uLy4uL3N0YWNrJztcbmltcG9ydCB7VmdWYWx1ZVJlZn0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtpc1ZnUmFuZ2VTdGVwLCBWZ0VuY29kZUVudHJ5fSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge1NjYWxlQ29tcG9uZW50fSBmcm9tICcuLi9zY2FsZS9jb21wb25lbnQnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IHtNYXJrQ29tcGlsZXJ9IGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBtaXhpbnMgZnJvbSAnLi9taXhpbnMnO1xuaW1wb3J0ICogYXMgcmVmIGZyb20gJy4vdmFsdWVyZWYnO1xuXG5cbmV4cG9ydCBjb25zdCBiYXI6IE1hcmtDb21waWxlciA9IHtcbiAgdmdNYXJrOiAncmVjdCcsXG4gIGVuY29kZUVudHJ5OiAobW9kZWw6IFVuaXRNb2RlbCkgPT4ge1xuICAgIGNvbnN0IHN0YWNrID0gbW9kZWwuc3RhY2s7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1peGlucy5tYXJrRGVmUHJvcGVydGllcyhtb2RlbC5tYXJrRGVmLCB0cnVlKSxcbiAgICAgIC4uLngobW9kZWwsIHN0YWNrKSxcbiAgICAgIC4uLnkobW9kZWwsIHN0YWNrKSxcbiAgICAgIC4uLm1peGlucy5jb2xvcihtb2RlbCksXG4gICAgICAuLi5taXhpbnMudGV4dChtb2RlbCwgJ3Rvb2x0aXAnKSxcbiAgICAgIC4uLm1peGlucy5ub25Qb3NpdGlvbignb3BhY2l0eScsIG1vZGVsKVxuICAgIH07XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHgobW9kZWw6IFVuaXRNb2RlbCwgc3RhY2s6IFN0YWNrUHJvcGVydGllcyk6IFZnRW5jb2RlRW50cnkge1xuICBjb25zdCB7Y29uZmlnLCB3aWR0aH0gPSBtb2RlbDtcbiAgY29uc3Qgb3JpZW50ID0gbW9kZWwubWFya0RlZi5vcmllbnQ7XG4gIGNvbnN0IHNpemVEZWYgPSBtb2RlbC5lbmNvZGluZy5zaXplO1xuXG4gIGNvbnN0IHhEZWYgPSBtb2RlbC5lbmNvZGluZy54O1xuICBjb25zdCB4U2NhbGVOYW1lID0gbW9kZWwuc2NhbGVOYW1lKFgpO1xuICBjb25zdCB4U2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChYKTtcbiAgLy8geCwgeDIsIGFuZCB3aWR0aCAtLSB3ZSBtdXN0IHNwZWNpZnkgdHdvIG9mIHRoZXNlIGluIGFsbCBjb25kaXRpb25zXG4gIGlmIChvcmllbnQgPT09ICdob3Jpem9udGFsJykge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbigneCcsIG1vZGVsLCAnemVyb09yTWluJyksXG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbjIobW9kZWwsICd6ZXJvT3JNaW4nKSxcbiAgICB9O1xuICB9IGVsc2UgeyAvLyB2ZXJ0aWNhbFxuICAgIGlmIChpc0ZpZWxkRGVmKHhEZWYpKSB7XG4gICAgICBjb25zdCB4U2NhbGVUeXBlID0geFNjYWxlLmdldCgndHlwZScpO1xuICAgICAgaWYgKHhEZWYuYmluICYmICFzaXplRGVmICYmICFoYXNEaXNjcmV0ZURvbWFpbih4U2NhbGVUeXBlKSkge1xuICAgICAgICByZXR1cm4gbWl4aW5zLmJpbm5lZFBvc2l0aW9uKFxuICAgICAgICAgIHhEZWYsICd4JywgbW9kZWwuc2NhbGVOYW1lKCd4JyksIGNvbmZpZy5iYXIuYmluU3BhY2luZywgeFNjYWxlLmdldCgncmV2ZXJzZScpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoeFNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLkJBTkQpIHtcbiAgICAgICAgICByZXR1cm4gbWl4aW5zLmJhbmRQb3NpdGlvbih4RGVmLCAneCcsIG1vZGVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBzaXplZCBiaW4sIG5vcm1hbCBwb2ludC1vcmRpbmFsIGF4aXMsIHF1YW50aXRhdGl2ZSB4LWF4aXMsIG9yIG5vIHhcblxuICAgIHJldHVybiBtaXhpbnMuY2VudGVyZWRCYW5kUG9zaXRpb24oJ3gnLCBtb2RlbCxcbiAgICAgIHsuLi5yZWYubWlkKHdpZHRoKX0sXG4gICAgICBkZWZhdWx0U2l6ZVJlZih4U2NhbGVOYW1lLCB4U2NhbGUsIGNvbmZpZylcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHkobW9kZWw6IFVuaXRNb2RlbCwgc3RhY2s6IFN0YWNrUHJvcGVydGllcykge1xuICBjb25zdCB7Y29uZmlnLCBlbmNvZGluZywgaGVpZ2h0fSA9IG1vZGVsO1xuICBjb25zdCBvcmllbnQgPSBtb2RlbC5tYXJrRGVmLm9yaWVudDtcbiAgY29uc3Qgc2l6ZURlZiA9IGVuY29kaW5nLnNpemU7XG5cbiAgY29uc3QgeURlZiA9IGVuY29kaW5nLnk7XG4gIGNvbnN0IHlTY2FsZU5hbWUgPSBtb2RlbC5zY2FsZU5hbWUoWSk7XG4gIGNvbnN0IHlTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KFkpO1xuICAvLyB5LCB5MiAmIGhlaWdodCAtLSB3ZSBtdXN0IHNwZWNpZnkgdHdvIG9mIHRoZXNlIGluIGFsbCBjb25kaXRpb25zXG4gIGlmIChvcmllbnQgPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ubWl4aW5zLnBvaW50UG9zaXRpb24oJ3knLCBtb2RlbCwgJ3plcm9Pck1pbicpLFxuICAgICAgLi4ubWl4aW5zLnBvaW50UG9zaXRpb24yKG1vZGVsLCAnemVyb09yTWluJyksXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoaXNGaWVsZERlZih5RGVmKSkge1xuICAgICAgY29uc3QgeVNjYWxlVHlwZSA9IHlTY2FsZS5nZXQoJ3R5cGUnKTtcbiAgICAgIGlmICh5RGVmLmJpbiAmJiAhc2l6ZURlZiAmJiAhaGFzRGlzY3JldGVEb21haW4oeVNjYWxlVHlwZSkpIHtcbiAgICAgICAgcmV0dXJuIG1peGlucy5iaW5uZWRQb3NpdGlvbihcbiAgICAgICAgICB5RGVmLCAneScsIG1vZGVsLnNjYWxlTmFtZSgneScpLCBjb25maWcuYmFyLmJpblNwYWNpbmcsIHlTY2FsZS5nZXQoJ3JldmVyc2UnKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICh5U2NhbGVUeXBlID09PSBTY2FsZVR5cGUuQkFORCkge1xuICAgICAgICByZXR1cm4gbWl4aW5zLmJhbmRQb3NpdGlvbih5RGVmLCAneScsIG1vZGVsKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1peGlucy5jZW50ZXJlZEJhbmRQb3NpdGlvbigneScsIG1vZGVsLCByZWYubWlkKGhlaWdodCksXG4gICAgICBkZWZhdWx0U2l6ZVJlZih5U2NhbGVOYW1lLCB5U2NhbGUsIGNvbmZpZylcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRTaXplUmVmKHNjYWxlTmFtZTogc3RyaW5nLCBzY2FsZTogU2NhbGVDb21wb25lbnQsIGNvbmZpZzogQ29uZmlnKTogVmdWYWx1ZVJlZiB7XG4gIGlmIChjb25maWcuYmFyLmRpc2NyZXRlQmFuZFNpemUpIHtcbiAgICByZXR1cm4ge3ZhbHVlOiBjb25maWcuYmFyLmRpc2NyZXRlQmFuZFNpemV9O1xuICB9XG5cbiAgaWYgKHNjYWxlKSB7XG4gICAgY29uc3Qgc2NhbGVUeXBlID0gc2NhbGUuZ2V0KCd0eXBlJyk7XG4gICAgaWYgKHNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLlBPSU5UKSB7XG4gICAgICBjb25zdCBzY2FsZVJhbmdlID0gc2NhbGUuZ2V0KCdyYW5nZScpO1xuICAgICAgaWYgKGlzVmdSYW5nZVN0ZXAoc2NhbGVSYW5nZSkgJiYgaXNOdW1iZXIoc2NhbGVSYW5nZS5zdGVwKSkge1xuICAgICAgICByZXR1cm4ge3ZhbHVlOiBzY2FsZVJhbmdlLnN0ZXAgLSAxfTtcbiAgICAgIH1cbiAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLkJBUl9XSVRIX1BPSU5UX1NDQUxFX0FORF9SQU5HRVNURVBfTlVMTCk7XG4gICAgfSBlbHNlIGlmIChzY2FsZVR5cGUgPT09IFNjYWxlVHlwZS5CQU5EKSB7XG4gICAgICByZXR1cm4gcmVmLmJhbmQoc2NhbGVOYW1lKTtcbiAgICB9IGVsc2UgeyAvLyBub24tb3JkaW5hbCBzY2FsZVxuICAgICAgcmV0dXJuIHt2YWx1ZTogY29uZmlnLmJhci5jb250aW51b3VzQmFuZFNpemV9O1xuICAgIH1cbiAgfVxuICBpZiAoY29uZmlnLnNjYWxlLnJhbmdlU3RlcCAmJiBjb25maWcuc2NhbGUucmFuZ2VTdGVwICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHt2YWx1ZTogY29uZmlnLnNjYWxlLnJhbmdlU3RlcCAtIDF9O1xuICB9XG4gIHJldHVybiB7dmFsdWU6IDIwfTtcbn1cblxuIl19 \ 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..d24c0a8574 --- /dev/null +++ b/build/src/compile/mark/base.d.ts @@ -0,0 +1,12 @@ +import { VgEncodeEntry } 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'; + encodeEntry: (model: UnitModel) => VgEncodeEntry; +} diff --git a/build/src/compile/mark/base.js b/build/src/compile/mark/base.js new file mode 100644 index 0000000000..1ab037491f --- /dev/null +++ b/build/src/compile/mark/base.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtWZ0VuY29kZUVudHJ5fSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vdW5pdCc7XG5cbi8qKlxuICogQWJzdHJhY3QgaW50ZXJmYWNlIGZvciBjb21waWxpbmcgYSBWZWdhLUxpdGUgcHJpbWl0aXZlIG1hcmsgdHlwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNYXJrQ29tcGlsZXIge1xuICAvKipcbiAgICogVW5kZXJseWluZyB2ZWdhIE1hcmsgdHlwZSBmb3IgdGhlIFZlZ2EtTGl0ZSBtYXJrLlxuICAgKi9cbiAgdmdNYXJrOiAnYXJlYScgfCAnbGluZScgfCAnc3ltYm9sJyB8ICdyZWN0JyB8ICdydWxlJyB8ICd0ZXh0JztcblxuICBlbmNvZGVFbnRyeTogKG1vZGVsOiBVbml0TW9kZWwpID0+IFZnRW5jb2RlRW50cnk7XG59XG4iXX0= \ 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..298a57869c --- /dev/null +++ b/build/src/compile/mark/init.js @@ -0,0 +1,131 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var mark_1 = require("../../mark"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function normalizeMarkDef(mark, encoding, config) { + var markDef = mark_1.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 || common_1.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 || common_1.getMarkConfig('opacity', markDef, config); + if (specifiedOpacity === undefined) { + markDef.opacity = defaultOpacity(markDef.type, encoding); + } + var specifiedFilled = markDef.filled; + if (specifiedFilled === undefined) { + markDef.filled = filled(markDef, config); + } + return markDef; +} +exports.normalizeMarkDef = normalizeMarkDef; +function defaultOpacity(mark, encoding) { + if (util_1.contains([mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE], mark)) { + // point-based marks + if (!encoding_1.isAggregate(encoding)) { + return 0.7; + } + } + return undefined; +} +function filled(markDef, config) { + var filledConfig = common_1.getMarkConfig('filled', markDef, config); + var mark = markDef.type; + return filledConfig !== undefined ? filledConfig : mark !== mark_1.POINT && mark !== mark_1.LINE && mark !== mark_1.RULE; +} +function orient(mark, encoding, specifiedOrient) { + switch (mark) { + case mark_1.POINT: + case mark_1.CIRCLE: + case mark_1.SQUARE: + case mark_1.TEXT: + case mark_1.RECT: + // orient is meaningless for these marks. + return undefined; + } + var yIsRange = encoding.y2; + var xIsRange = encoding.x2; + switch (mark) { + case mark_1.RULE: + case mark_1.BAR: + case mark_1.AREA: + // 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 === mark_1.RULE) { + if (encoding.x && !encoding.y) { + return 'vertical'; + } + else if (encoding.y && !encoding.x) { + return 'horizontal'; + } + } + /* tslint:disable */ + case mark_1.LINE: // intentional fall through + case mark_1.TICK:// Tick is opposite to bar, line, area and never have ranged mark. + /* tslint:enable */ + var xIsContinuous = fielddef_1.isFieldDef(encoding.x) && fielddef_1.isContinuous(encoding.x); + var yIsContinuous = fielddef_1.isFieldDef(encoding.y) && fielddef_1.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 === type_1.TEMPORAL; + var yIsTemporal = yDef.type === type_1.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; + } + if (!(mark === mark_1.LINE && encoding.order)) { + // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots. + log.warn(log.message.unclearOrientContinuous(mark)); + } + return 'vertical'; + } + else { + // For Discrete x Discrete case, return undefined. + log.warn(log.message.unclearOrientDiscreteOrEmpty(mark)); + return undefined; + } + } + return 'vertical'; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsMkNBQXFEO0FBQ3JELDJDQUFrRTtBQUNsRSwrQkFBaUM7QUFDakMsbUNBQW9IO0FBQ3BILG1DQUFvQztBQUNwQyxtQ0FBb0M7QUFDcEMsb0NBQXdDO0FBSXhDLDBCQUFpQyxJQUFvQixFQUFFLFFBQTBCLEVBQUUsTUFBYztJQUMvRixJQUFNLE9BQU8sR0FBWSxnQkFBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDO0lBRXBFLDZGQUE2RjtJQUM3RixJQUFNLGVBQWUsR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLHNCQUFhLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNuRixPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUNqRSxFQUFFLENBQUMsQ0FBQyxlQUFlLEtBQUssU0FBUyxJQUFJLGVBQWUsS0FBSyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN4RSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCx5REFBeUQ7SUFDekQsSUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLHNCQUFhLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN0RixFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ25DLE9B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QUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLDRCQUE0QixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3pELE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDbkIsQ0FBQztJQUNMLENBQUM7SUFDRCxNQUFNLENBQUMsVUFBVSxDQUFDO0FBQ3BCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHtFbmNvZGluZywgaXNBZ2dyZWdhdGV9IGZyb20gJy4uLy4uL2VuY29kaW5nJztcbmltcG9ydCB7RmllbGREZWYsIGlzQ29udGludW91cywgaXNGaWVsZERlZn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge0FSRUEsIEJBUiwgQ0lSQ0xFLCBpc01hcmtEZWYsIExJTkUsIE1hcmssIE1hcmtEZWYsIFBPSU5ULCBSRUNULCBSVUxFLCBTUVVBUkUsIFRFWFQsIFRJQ0t9IGZyb20gJy4uLy4uL21hcmsnO1xuaW1wb3J0IHtURU1QT1JBTH0gZnJvbSAnLi4vLi4vdHlwZSc7XG5pbXBvcnQge2NvbnRhaW5zfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7Z2V0TWFya0NvbmZpZ30gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7T3JpZW50fSBmcm9tICcuLy4uLy4uL3ZlZ2Euc2NoZW1hJztcblxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplTWFya0RlZihtYXJrOiBNYXJrIHwgTWFya0RlZiwgZW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4sIGNvbmZpZzogQ29uZmlnKSB7XG4gIGNvbnN0IG1hcmtEZWY6IE1hcmtEZWYgPSBpc01hcmtEZWYobWFyaykgPyB7Li4ubWFya30gOiB7dHlwZTogbWFya307XG5cbiAgLy8gc2V0IG9yaWVudCwgd2hpY2ggY2FuIGJlIG92ZXJyaWRkZW4gYnkgcnVsZXMgYXMgc29tZXRpbWVzIHRoZSBzcGVjaWZpZWQgb3JpZW50IGlzIGludmFsaWQuXG4gIGNvbnN0IHNwZWNpZmllZE9yaWVudCA9IG1hcmtEZWYub3JpZW50IHx8IGdldE1hcmtDb25maWcoJ29yaWVudCcsIG1hcmtEZWYsIGNvbmZpZyk7XG4gIG1hcmtEZWYub3JpZW50ID0gb3JpZW50KG1hcmtEZWYudHlwZSwgZW5jb2RpbmcsIHNwZWNpZmllZE9yaWVudCk7XG4gIGlmIChzcGVjaWZpZWRPcmllbnQgIT09IHVuZGVmaW5lZCAmJiBzcGVjaWZpZWRPcmllbnQgIT09IG1hcmtEZWYub3JpZW50KSB7XG4gICAgbG9nLndhcm4obG9nLm1lc3NhZ2Uub3JpZW50T3ZlcnJpZGRlbihtYXJrRGVmLm9yaWVudCxzcGVjaWZpZWRPcmllbnQpKTtcbiAgfVxuXG4gIC8vIHNldCBvcGFjaXR5IGFuZCBmaWxsZWQgaWYgbm90IHNwZWNpZmllZCBpbiBtYXJrIGNvbmZpZ1xuICBjb25zdCBzcGVjaWZpZWRPcGFjaXR5ID0gbWFya0RlZi5vcGFjaXR5IHx8IGdldE1hcmtDb25maWcoJ29wYWNpdHknLCBtYXJrRGVmLCBjb25maWcpO1xuICBpZiAoc3BlY2lmaWVkT3BhY2l0eSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbWFya0RlZi5vcGFjaXR5ID0gZGVmYXVsdE9wYWNpdHkobWFya0RlZi50eXBlLCBlbmNvZGluZyk7XG4gIH1cblxuICBjb25zdCBzcGVjaWZpZWRGaWxsZWQgPSBtYXJrRGVmLmZpbGxlZDtcbiAgaWYgKHNwZWNpZmllZEZpbGxlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbWFya0RlZi5maWxsZWQgPSBmaWxsZWQobWFya0RlZiwgY29uZmlnKTtcbiAgfVxuICByZXR1cm4gbWFya0RlZjtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdE9wYWNpdHkobWFyazogTWFyaywgZW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4pIHtcbiAgaWYgKGNvbnRhaW5zKFtQT0lOVCwgVElDSywgQ0lSQ0xFLCBTUVVBUkVdLCBtYXJrKSkge1xuICAgIC8vIHBvaW50LWJhc2VkIG1hcmtzXG4gICAgaWYgKCFpc0FnZ3JlZ2F0ZShlbmNvZGluZykpIHtcbiAgICAgIHJldHVybiAwLjc7XG4gICAgfVxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGZpbGxlZChtYXJrRGVmOiBNYXJrRGVmLCBjb25maWc6IENvbmZpZykge1xuICBjb25zdCBmaWxsZWRDb25maWcgPSBnZXRNYXJrQ29uZmlnKCdmaWxsZWQnLCBtYXJrRGVmLCBjb25maWcpO1xuICBjb25zdCBtYXJrID0gbWFya0RlZi50eXBlO1xuICByZXR1cm4gZmlsbGVkQ29uZmlnICE9PSB1bmRlZmluZWQgPyBmaWxsZWRDb25maWcgOiBtYXJrICE9PSBQT0lOVCAmJiBtYXJrICE9PSBMSU5FICYmIG1hcmsgIT09IFJVTEU7XG59XG5cbmZ1bmN0aW9uIG9yaWVudChtYXJrOiBNYXJrLCBlbmNvZGluZzogRW5jb2Rpbmc8c3RyaW5nPiwgc3BlY2lmaWVkT3JpZW50OiBPcmllbnQpOiBPcmllbnQge1xuICBzd2l0Y2ggKG1hcmspIHtcbiAgICBjYXNlIFBPSU5UOlxuICAgIGNhc2UgQ0lSQ0xFOlxuICAgIGNhc2UgU1FVQVJFOlxuICAgIGNhc2UgVEVYVDpcbiAgICBjYXNlIFJFQ1Q6XG4gICAgICAvLyBvcmllbnQgaXMgbWVhbmluZ2xlc3MgZm9yIHRoZXNlIG1hcmtzLlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHlJc1JhbmdlID0gZW5jb2RpbmcueTI7XG4gIGNvbnN0IHhJc1JhbmdlID0gZW5jb2RpbmcueDI7XG5cbiAgc3dpdGNoIChtYXJrKSB7XG4gICAgY2FzZSBSVUxFOlxuICAgIGNhc2UgQkFSOlxuICAgIGNhc2UgQVJFQTpcbiAgICAgIC8vIElmIHRoZXJlIGFyZSByYW5nZSBmb3IgYm90aCB4IGFuZCB5LCB5ICh2ZXJ0aWNhbCkgaGFzIGhpZ2hlciBwcmVjZWRlbmNlLlxuICAgICAgaWYgKHlJc1JhbmdlKSB7XG4gICAgICAgIHJldHVybiAndmVydGljYWwnO1xuICAgICAgfSBlbHNlIGlmICh4SXNSYW5nZSkge1xuICAgICAgICByZXR1cm4gJ2hvcml6b250YWwnO1xuICAgICAgfSBlbHNlIGlmIChtYXJrID09PSBSVUxFKSB7XG4gICAgICAgIGlmIChlbmNvZGluZy54ICYmICFlbmNvZGluZy55KSB7XG4gICAgICAgICAgcmV0dXJuICd2ZXJ0aWNhbCc7XG4gICAgICAgIH0gZWxzZSBpZiAoZW5jb2RpbmcueSAmJiAhZW5jb2RpbmcueCkge1xuICAgICAgICAgIHJldHVybiAnaG9yaXpvbnRhbCc7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLyogdHNsaW50OmRpc2FibGUgKi9cbiAgICBjYXNlIExJTkU6IC8vIGludGVudGlvbmFsIGZhbGwgdGhyb3VnaFxuICAgIGNhc2UgVElDSzogLy8gVGljayBpcyBvcHBvc2l0ZSB0byBiYXIsIGxpbmUsIGFyZWEgYW5kIG5ldmVyIGhhdmUgcmFuZ2VkIG1hcmsuXG5cbiAgICAgIC8qIHRzbGludDplbmFibGUgKi9cbiAgICAgIGNvbnN0IHhJc0NvbnRpbnVvdXMgPSBpc0ZpZWxkRGVmKGVuY29kaW5nLngpICYmIGlzQ29udGludW91cyhlbmNvZGluZy54KTtcbiAgICAgIGNvbnN0IHlJc0NvbnRpbnVvdXMgPSBpc0ZpZWxkRGVmKGVuY29kaW5nLnkpICYmIGlzQ29udGludW91cyhlbmNvZGluZy55KTtcbiAgICAgIGlmICh4SXNDb250aW51b3VzICYmICF5SXNDb250aW51b3VzKSB7XG4gICAgICAgIHJldHVybiBtYXJrICE9PSAndGljaycgPyAnaG9yaXpvbnRhbCcgOiAndmVydGljYWwnO1xuICAgICAgfSBlbHNlIGlmICgheElzQ29udGludW91cyAmJiB5SXNDb250aW51b3VzKSB7XG4gICAgICAgIHJldHVybiBtYXJrICE9PSAndGljaycgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xuICAgICAgfSBlbHNlIGlmICh4SXNDb250aW51b3VzICYmIHlJc0NvbnRpbnVvdXMpIHtcbiAgICAgICAgY29uc3QgeERlZiA9IGVuY29kaW5nLnggYXMgRmllbGREZWY8c3RyaW5nPjsgLy8gd2UgY2FuIGNhc3QgaGVyZSBzaW5jZSB0aGV5IGFyZSBzdXJlbHkgZmllbGREZWZcbiAgICAgICAgY29uc3QgeURlZiA9IGVuY29kaW5nLnkgYXMgRmllbGREZWY8c3RyaW5nPjtcblxuICAgICAgICBjb25zdCB4SXNUZW1wb3JhbCA9IHhEZWYudHlwZSA9PT0gVEVNUE9SQUw7XG4gICAgICAgIGNvbnN0IHlJc1RlbXBvcmFsID0geURlZi50eXBlID09PSBURU1QT1JBTDtcblxuICAgICAgICAvLyB0ZW1wb3JhbCB3aXRob3V0IHRpbWVVbml0IGlzIGNvbnNpZGVyZWQgY29udGludW91cywgYnV0IGJldHRlciBzZXJ2ZXMgYXMgZGltZW5zaW9uXG4gICAgICAgIGlmICh4SXNUZW1wb3JhbCAmJiAheUlzVGVtcG9yYWwpIHtcbiAgICAgICAgICByZXR1cm4gbWFyayAhPT0gJ3RpY2snID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcbiAgICAgICAgfSBlbHNlIGlmICgheElzVGVtcG9yYWwgJiYgeUlzVGVtcG9yYWwpIHtcbiAgICAgICAgICByZXR1cm4gbWFyayAhPT0gJ3RpY2snID8gJ2hvcml6b250YWwnIDogJ3ZlcnRpY2FsJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgheERlZi5hZ2dyZWdhdGUgJiYgeURlZi5hZ2dyZWdhdGUpIHtcbiAgICAgICAgICByZXR1cm4gbWFyayAhPT0gJ3RpY2snID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcbiAgICAgICAgfSBlbHNlIGlmICh4RGVmLmFnZ3JlZ2F0ZSAmJiAheURlZi5hZ2dyZWdhdGUpIHtcbiAgICAgICAgICByZXR1cm4gbWFyayAhPT0gJ3RpY2snID8gJ2hvcml6b250YWwnIDogJ3ZlcnRpY2FsJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcGVjaWZpZWRPcmllbnQpIHtcbiAgICAgICAgICAvLyBXaGVuIGFtYmlndW91cywgdXNlIHVzZXIgc3BlY2lmaWVkIG9uZS5cbiAgICAgICAgICByZXR1cm4gc3BlY2lmaWVkT3JpZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEobWFyayA9PT0gTElORSAmJiBlbmNvZGluZy5vcmRlcikpIHtcbiAgICAgICAgICAvLyBFeGNlcHQgZm9yIGNvbm5lY3RlZCBzY2F0dGVycGxvdCwgd2Ugc2hvdWxkIGxvZyB3YXJuaW5nIGZvciB1bmNsZWFyIG9yaWVudGF0aW9uIG9mIFF4USBwbG90cy5cbiAgICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS51bmNsZWFyT3JpZW50Q29udGludW91cyhtYXJrKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICd2ZXJ0aWNhbCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGb3IgRGlzY3JldGUgeCBEaXNjcmV0ZSBjYXNlLCByZXR1cm4gdW5kZWZpbmVkLlxuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS51bmNsZWFyT3JpZW50RGlzY3JldGVPckVtcHR5KG1hcmspKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgfVxuICByZXR1cm4gJ3ZlcnRpY2FsJztcbn1cblxuIl19 \ 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..1a1b8215a5 --- /dev/null +++ b/build/src/compile/mark/line.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const line: MarkCompiler; diff --git a/build/src/compile/mark/line.js b/build/src/compile/mark/line.js new file mode 100644 index 0000000000..97eb5ada7a --- /dev/null +++ b/build/src/compile/mark/line.js @@ -0,0 +1,22 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.line = { + vgMark: 'line', + encodeEntry: function (model) { + var width = model.width, height = model.height; + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's line size is strokeWidth + })); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvbGluZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsaUNBQW1DO0FBQ25DLGdDQUFrQztBQUdyQixRQUFBLElBQUksR0FBaUI7SUFDaEMsTUFBTSxFQUFFLE1BQU07SUFDZCxXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUNyQixJQUFBLG1CQUFLLEVBQUUscUJBQU0sQ0FBVTtRQUU5QixNQUFNLGNBQ0QsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQ2hELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ2pELE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxFQUM3QixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDcEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFO1lBQ25DLFNBQVMsRUFBRSxhQUFhLENBQUUsZ0NBQWdDO1NBQzNELENBQUMsRUFDRjtJQUNKLENBQUM7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IHtNYXJrQ29tcGlsZXJ9IGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBtaXhpbnMgZnJvbSAnLi9taXhpbnMnO1xuaW1wb3J0ICogYXMgcmVmIGZyb20gJy4vdmFsdWVyZWYnO1xuXG5cbmV4cG9ydCBjb25zdCBsaW5lOiBNYXJrQ29tcGlsZXIgPSB7XG4gIHZnTWFyazogJ2xpbmUnLFxuICBlbmNvZGVFbnRyeTogKG1vZGVsOiBVbml0TW9kZWwpID0+IHtcbiAgICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSBtb2RlbDtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5taXhpbnMubWFya0RlZlByb3BlcnRpZXMobW9kZWwubWFya0RlZiwgdHJ1ZSksXG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbigneCcsIG1vZGVsLCByZWYubWlkKHdpZHRoKSksXG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbigneScsIG1vZGVsLCByZWYubWlkKGhlaWdodCkpLFxuICAgICAgLi4ubWl4aW5zLmNvbG9yKG1vZGVsKSxcbiAgICAgIC4uLm1peGlucy50ZXh0KG1vZGVsLCAndG9vbHRpcCcpLFxuICAgICAgLi4ubWl4aW5zLm5vblBvc2l0aW9uKCdvcGFjaXR5JywgbW9kZWwpLFxuICAgICAgLi4ubWl4aW5zLm5vblBvc2l0aW9uKCdzaXplJywgbW9kZWwsIHtcbiAgICAgICAgdmdDaGFubmVsOiAnc3Ryb2tlV2lkdGgnICAvLyBWTCdzIGxpbmUgc2l6ZSBpcyBzdHJva2VXaWR0aFxuICAgICAgfSlcbiAgICB9O1xuICB9XG59O1xuIl19 \ 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..24cccea44c --- /dev/null +++ b/build/src/compile/mark/mark.d.ts @@ -0,0 +1,18 @@ +import { Encoding } from '../../encoding'; +import { UnitModel } from '../unit'; +export declare function parseMarkGroup(model: UnitModel): any[]; +export declare function getPathSort(model: UnitModel): { + field: string; + order?: "ascending" | "descending"; +} | { + field: string[]; + order?: ("ascending" | "descending")[]; +} | { + field: string; + order: string; +}; +/** + * Returns list of path grouping fields + * that the model's spec contains. + */ +export declare function pathGroupingFields(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..d564cc5c66 --- /dev/null +++ b/build/src/compile/mark/mark.js @@ -0,0 +1,180 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var data_1 = require("../../data"); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var mark_1 = require("../../mark"); +var sort_1 = require("../../sort"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var area_1 = require("./area"); +var bar_1 = require("./bar"); +var line_1 = require("./line"); +var point_1 = require("./point"); +var rect_1 = require("./rect"); +var rule_1 = require("./rule"); +var text_1 = require("./text"); +var tick_1 = require("./tick"); +var markCompiler = { + area: area_1.area, + bar: bar_1.bar, + line: line_1.line, + point: point_1.point, + text: text_1.text, + tick: tick_1.tick, + rect: rect_1.rect, + rule: rule_1.rule, + circle: point_1.circle, + square: point_1.square +}; +function parseMarkGroup(model) { + if (util_1.contains([mark_1.LINE, mark_1.AREA], model.mark())) { + return parsePathMark(model); + } + else { + return parseNonPathMark(model); + } +} +exports.parseMarkGroup = parseMarkGroup; +var FACETED_PATH_PREFIX = 'faceted_path_'; +function parsePathMark(model) { + var mark = model.mark(); + var details = pathGroupingFields(model.encoding); + var clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model); + var style = common_1.getStyles(model.markDef); + var sort = getPathSort(model); + var pathMarks = [ + __assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (clip ? { clip: true } : {}), (style ? { style: style } : {}), (sort ? { sort: sort } : {}), { + // If has subfacet for line/area group, need to use faceted data from below. + // FIXME: support sorting path order (in connected scatterplot) + from: { data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + model.requestDataName(data_1.MAIN) }, encode: { update: markCompiler[mark].encodeEntry(model) } }) + ]; + if (details.length > 0) { + // 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(data_1.MAIN), + data: model.requestDataName(data_1.MAIN), + groupby: details, + } + }, + encode: { + update: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } } + } + }, + marks: pathMarks + }]; + } + else { + return pathMarks; + } +} +function getPathSort(model) { + if (model.mark() === 'line' && model.channelHasField('order')) { + // For only line, sort by the order field if it is specified. + return common_1.sortParams(model.encoding.order, { expr: 'datum' }); + } + else { + // For both line and area, we sort values based on dimension by default + var dimensionChannel = model.markDef.orient === 'horizontal' ? 'y' : 'x'; + var s = model.sort(dimensionChannel); + var sortField = sort_1.isSortField(s) ? + fielddef_1.field({ + // FIXME: this op might not already exist? + // FIXME: what if dimensionChannel (x or y) contains custom domain? + aggregate: encoding_1.isAggregate(model.encoding) ? s.op : undefined, + field: s.field + }, { expr: 'datum' }) : + model.field(dimensionChannel, { + // For stack with imputation, we only have bin_mid + binSuffix: model.stack && model.stack.impute ? 'mid' : undefined, + expr: 'datum' + }); + return sortField ? + { + field: sortField, + order: 'descending' + } : + undefined; + } +} +exports.getPathSort = getPathSort; +function parseNonPathMark(model) { + var mark = model.mark(); + var style = common_1.getStyles(model.markDef); + var clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model); + var marks = []; // TODO: vgMarks + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + marks.push(__assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (clip ? { clip: true } : {}), (style ? { style: style } : {}), { from: { data: model.requestDataName(data_1.MAIN) }, encode: { update: markCompiler[mark].encodeEntry(model) } })); + return marks; +} +/** + * Returns list of path grouping fields + * that the model's spec contains. + */ +function pathGroupingFields(encoding) { + return util_1.keys(encoding).reduce(function (details, channel) { + switch (channel) { + // x, y, x2, y2, order, tooltip, href, cursor should not cause lines to group + case 'x': + case 'y': + case 'order': + case 'tooltip': + case 'x2': + case 'y2': + // TODO: case 'href', 'cursor': + // text, shape, shouldn't be a part of line/area + case 'text': + case 'shape': + return details; + case 'detail': + var channelDef = encoding[channel]; + if (channelDef) { + (vega_util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + if (!fieldDef.aggregate) { + details.push(fielddef_1.field(fieldDef, {})); + } + }); + } + return details; + case 'color': + case 'size': + case 'opacity': + // TODO strokeDashOffset: + var fieldDef = fielddef_1.getFieldDef(encoding[channel]); + if (fieldDef && !fieldDef.aggregate) { + details.push(fielddef_1.field(fieldDef, {})); + } + return details; + default: + throw new Error("Bug: Channel " + channel + " unimplemented for line mark"); + } + }, []); +} +exports.pathGroupingFields = pathGroupingFields; +/** + * 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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvbWFyay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsdUNBQWtDO0FBQ2xDLG1DQUFnQztBQUNoQywyQ0FBcUQ7QUFDckQsMkNBQWtEO0FBQ2xELG1DQUFzQztBQUN0QyxtQ0FBdUM7QUFDdkMsbUNBQTBDO0FBQzFDLG9DQUFnRDtBQUVoRCwrQkFBNEI7QUFDNUIsNkJBQTBCO0FBRTFCLCtCQUE0QjtBQUM1QixpQ0FBOEM7QUFDOUMsK0JBQTRCO0FBQzVCLCtCQUE0QjtBQUM1QiwrQkFBNEI7QUFDNUIsK0JBQTRCO0FBRzVCLElBQU0sWUFBWSxHQUFtQztJQUNuRCxJQUFJLEVBQUUsV0FBSTtJQUNWLEdBQUcsRUFBRSxTQUFHO0lBQ1IsSUFBSSxFQUFFLFdBQUk7SUFDVixLQUFLLEVBQUUsYUFBSztJQUNaLElBQUksRUFBRSxXQUFJO0lBQ1YsSUFBSSxFQUFFLFdBQUk7SUFDVixJQUFJLEVBQUUsV0FBSTtJQUNWLElBQUksRUFBRSxXQUFJO0lBQ1YsTUFBTSxFQUFFLGNBQU07SUFDZCxNQUFNLEVBQUUsY0FBTTtDQUNmLENBQUM7QUFHRix3QkFBK0IsS0FBZ0I7SUFDN0MsRUFBRSxDQUFDLENBQUMsZUFBUSxDQUFDLENBQUMsV0FBSSxFQUFFLFdBQUksQ0FBQyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0FBQ0gsQ0FBQztBQU5ELHdDQU1DO0FBRUQsSUFBTSxtQkFBbUIsR0FBRyxlQUFlLENBQUM7QUFFNUMsdUJBQXVCLEtBQWdCO0lBQ3JDLElBQU0sSUFB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LGtCQUFnQixPQUFPLGlDQUE4QixDQUFDLENBQUM7UUFDM0UsQ0FBQztJQUNILENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNULENBQUM7QUF4Q0QsZ0RBd0NDO0FBRUQ7Ozs7R0FJRztBQUNILG1CQUFtQixLQUFnQjtJQUNqQyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFDdkQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aXNBcnJheX0gZnJvbSAndmVnYS11dGlsJztcbmltcG9ydCB7TUFJTn0gZnJvbSAnLi4vLi4vZGF0YSc7XG5pbXBvcnQge0VuY29kaW5nLCBpc0FnZ3JlZ2F0ZX0gZnJvbSAnLi4vLi4vZW5jb2RpbmcnO1xuaW1wb3J0IHtmaWVsZCwgZ2V0RmllbGREZWZ9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCB7QVJFQSwgTElORX0gZnJvbSAnLi4vLi4vbWFyayc7XG5pbXBvcnQge2lzU29ydEZpZWxkfSBmcm9tICcuLi8uLi9zb3J0JztcbmltcG9ydCB7Y29udGFpbnMsIGtleXN9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtnZXRTdHlsZXMsIHNvcnRQYXJhbXN9IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vdW5pdCc7XG5pbXBvcnQge2FyZWF9IGZyb20gJy4vYXJlYSc7XG5pbXBvcnQge2Jhcn0gZnJvbSAnLi9iYXInO1xuaW1wb3J0IHtNYXJrQ29tcGlsZXJ9IGZyb20gJy4vYmFzZSc7XG5pbXBvcnQge2xpbmV9IGZyb20gJy4vbGluZSc7XG5pbXBvcnQge2NpcmNsZSwgcG9pbnQsIHNxdWFyZX0gZnJvbSAnLi9wb2ludCc7XG5pbXBvcnQge3JlY3R9IGZyb20gJy4vcmVjdCc7XG5pbXBvcnQge3J1bGV9IGZyb20gJy4vcnVsZSc7XG5pbXBvcnQge3RleHR9IGZyb20gJy4vdGV4dCc7XG5pbXBvcnQge3RpY2t9IGZyb20gJy4vdGljayc7XG5cblxuY29uc3QgbWFya0NvbXBpbGVyOiB7W3R5cGU6IHN0cmluZ106IE1hcmtDb21waWxlcn0gPSB7XG4gIGFyZWE6IGFyZWEsXG4gIGJhcjogYmFyLFxuICBsaW5lOiBsaW5lLFxuICBwb2ludDogcG9pbnQsXG4gIHRleHQ6IHRleHQsXG4gIHRpY2s6IHRpY2ssXG4gIHJlY3Q6IHJlY3QsXG4gIHJ1bGU6IHJ1bGUsXG4gIGNpcmNsZTogY2lyY2xlLFxuICBzcXVhcmU6IHNxdWFyZVxufTtcblxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VNYXJrR3JvdXAobW9kZWw6IFVuaXRNb2RlbCk6IGFueVtdIHtcbiAgaWYgKGNvbnRhaW5zKFtMSU5FLCBBUkVBXSwgbW9kZWwubWFyaygpKSkge1xuICAgIHJldHVybiBwYXJzZVBhdGhNYXJrKG1vZGVsKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcGFyc2VOb25QYXRoTWFyayhtb2RlbCk7XG4gIH1cbn1cblxuY29uc3QgRkFDRVRFRF9QQVRIX1BSRUZJWCA9ICdmYWNldGVkX3BhdGhfJztcblxuZnVuY3Rpb24gcGFyc2VQYXRoTWFyayhtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IG1hcmsgPSBtb2RlbC5tYXJrKCk7XG4gIGNvbnN0IGRldGFpbHMgPSBwYXRoR3JvdXBpbmdGaWVsZHMobW9kZWwuZW5jb2RpbmcpO1xuXG4gIGNvbnN0IGNsaXAgPSBtb2RlbC5tYXJrRGVmLmNsaXAgIT09IHVuZGVmaW5lZCA/ICEhbW9kZWwubWFya0RlZi5jbGlwIDogc2NhbGVDbGlwKG1vZGVsKTtcbiAgY29uc3Qgc3R5bGUgPSBnZXRTdHlsZXMobW9kZWwubWFya0RlZik7XG4gIGNvbnN0IHNvcnQgPSBnZXRQYXRoU29ydChtb2RlbCk7XG5cbiAgY29uc3QgcGF0aE1hcmtzOiBhbnkgPSBbXG4gICAge1xuICAgICAgbmFtZTogbW9kZWwuZ2V0TmFtZSgnbWFya3MnKSxcbiAgICAgIHR5cGU6IG1hcmtDb21waWxlclttYXJrXS52Z01hcmssXG4gICAgICAuLi4oY2xpcCA/IHtjbGlwOiB0cnVlfSA6IHt9KSxcbiAgICAgIC4uLihzdHlsZT8ge3N0eWxlfSA6IHt9KSxcbiAgICAgIC4uLihzb3J0PyB7c29ydH0gOiB7fSksXG4gICAgICAvLyBJZiBoYXMgc3ViZmFjZXQgZm9yIGxpbmUvYXJlYSBncm91cCwgbmVlZCB0byB1c2UgZmFjZXRlZCBkYXRhIGZyb20gYmVsb3cuXG4gICAgICAvLyBGSVhNRTogc3VwcG9ydCBzb3J0aW5nIHBhdGggb3JkZXIgKGluIGNvbm5lY3RlZCBzY2F0dGVycGxvdClcbiAgICAgIGZyb206IHtkYXRhOiAoZGV0YWlscy5sZW5ndGggPiAwID8gRkFDRVRFRF9QQVRIX1BSRUZJWCA6ICcnKSArIG1vZGVsLnJlcXVlc3REYXRhTmFtZShNQUlOKX0sXG4gICAgICBlbmNvZGU6IHt1cGRhdGU6IG1hcmtDb21waWxlclttYXJrXS5lbmNvZGVFbnRyeShtb2RlbCl9XG4gICAgfVxuICBdO1xuXG4gIGlmIChkZXRhaWxzLmxlbmd0aCA+IDApIHsgLy8gaGF2ZSBsZXZlbCBvZiBkZXRhaWxzIC0gbmVlZCB0byBmYWNldCBsaW5lIGludG8gc3ViZ3JvdXBzXG4gICAgLy8gVE9ETzogZm9yIG5vbi1zdGFja2VkIHBsb3QsIG1hcCBvcmRlciB0byB6aW5kZXguIChNYXliZSByZW5hbWUgb3JkZXIgZm9yIGxheWVyIHRvIHppbmRleD8pXG5cbiAgICByZXR1cm4gW3tcbiAgICAgIG5hbWU6IG1vZGVsLmdldE5hbWUoJ3BhdGhncm91cCcpLFxuICAgICAgdHlwZTogJ2dyb3VwJyxcbiAgICAgIGZyb206IHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICBuYW1lOiBGQUNFVEVEX1BBVEhfUFJFRklYICsgbW9kZWwucmVxdWVzdERhdGFOYW1lKE1BSU4pLFxuICAgICAgICAgIGRhdGE6IG1vZGVsLnJlcXVlc3REYXRhTmFtZShNQUlOKSxcbiAgICAgICAgICBncm91cGJ5OiBkZXRhaWxzLFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZW5jb2RlOiB7XG4gICAgICAgIHVwZGF0ZToge1xuICAgICAgICAgIHdpZHRoOiB7ZmllbGQ6IHtncm91cDogJ3dpZHRoJ319LFxuICAgICAgICAgIGhlaWdodDoge2ZpZWxkOiB7Z3JvdXA6ICdoZWlnaHQnfX1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIG1hcmtzOiBwYXRoTWFya3NcbiAgICB9XTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcGF0aE1hcmtzO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXRoU29ydChtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGlmIChtb2RlbC5tYXJrKCkgPT09ICdsaW5lJyAmJiBtb2RlbC5jaGFubmVsSGFzRmllbGQoJ29yZGVyJykpIHtcbiAgICAvLyBGb3Igb25seSBsaW5lLCBzb3J0IGJ5IHRoZSBvcmRlciBmaWVsZCBpZiBpdCBpcyBzcGVjaWZpZWQuXG4gICAgcmV0dXJuIHNvcnRQYXJhbXMobW9kZWwuZW5jb2Rpbmcub3JkZXIsIHtleHByOiAnZGF0dW0nfSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gRm9yIGJvdGggbGluZSBhbmQgYXJlYSwgd2Ugc29ydCB2YWx1ZXMgYmFzZWQgb24gZGltZW5zaW9uIGJ5IGRlZmF1bHRcbiAgICBjb25zdCBkaW1lbnNpb25DaGFubmVsOiAneCcgfCAneScgPSBtb2RlbC5tYXJrRGVmLm9yaWVudCA9PT0gJ2hvcml6b250YWwnID8gJ3knIDogJ3gnO1xuICAgIGNvbnN0IHMgPSBtb2RlbC5zb3J0KGRpbWVuc2lvbkNoYW5uZWwpO1xuICAgIGNvbnN0IHNvcnRGaWVsZCA9IGlzU29ydEZpZWxkKHMpID9cbiAgICAgIGZpZWxkKHtcbiAgICAgICAgLy8gRklYTUU6IHRoaXMgb3AgbWlnaHQgbm90IGFscmVhZHkgZXhpc3Q/XG4gICAgICAgIC8vIEZJWE1FOiB3aGF0IGlmIGRpbWVuc2lvbkNoYW5uZWwgKHggb3IgeSkgY29udGFpbnMgY3VzdG9tIGRvbWFpbj9cbiAgICAgICAgYWdncmVnYXRlOiBpc0FnZ3JlZ2F0ZShtb2RlbC5lbmNvZGluZykgPyBzLm9wIDogdW5kZWZpbmVkLFxuICAgICAgICBmaWVsZDogcy5maWVsZFxuICAgICAgfSwge2V4cHI6ICdkYXR1bSd9KSA6XG4gICAgICBtb2RlbC5maWVsZChkaW1lbnNpb25DaGFubmVsLCB7XG4gICAgICAgIC8vIEZvciBzdGFjayB3aXRoIGltcHV0YXRpb24sIHdlIG9ubHkgaGF2ZSBiaW5fbWlkXG4gICAgICAgIGJpblN1ZmZpeDogbW9kZWwuc3RhY2sgJiYgbW9kZWwuc3RhY2suaW1wdXRlID8gJ21pZCcgOiB1bmRlZmluZWQsXG4gICAgICAgIGV4cHI6ICdkYXR1bSdcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHNvcnRGaWVsZCA/XG4gICAgICB7XG4gICAgICAgIGZpZWxkOiBzb3J0RmllbGQsXG4gICAgICAgIG9yZGVyOiAnZGVzY2VuZGluZydcbiAgICAgIH0gOlxuICAgICAgdW5kZWZpbmVkO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlTm9uUGF0aE1hcmsobW9kZWw6IFVuaXRNb2RlbCkge1xuICBjb25zdCBtYXJrID0gbW9kZWwubWFyaygpO1xuXG4gIGNvbnN0IHN0eWxlID0gZ2V0U3R5bGVzKG1vZGVsLm1hcmtEZWYpO1xuICBjb25zdCBjbGlwID0gbW9kZWwubWFya0RlZi5jbGlwICE9PSB1bmRlZmluZWQgPyAhIW1vZGVsLm1hcmtEZWYuY2xpcCA6IHNjYWxlQ2xpcChtb2RlbCk7XG5cbiAgY29uc3QgbWFya3M6IGFueVtdID0gW107IC8vIFRPRE86IHZnTWFya3NcblxuICAvLyBUT0RPOiBmb3Igbm9uLXN0YWNrZWQgcGxvdCwgbWFwIG9yZGVyIHRvIHppbmRleC4gKE1heWJlIHJlbmFtZSBvcmRlciBmb3IgbGF5ZXIgdG8gemluZGV4PylcblxuICBtYXJrcy5wdXNoKHtcbiAgICBuYW1lOiBtb2RlbC5nZXROYW1lKCdtYXJrcycpLFxuICAgIHR5cGU6IG1hcmtDb21waWxlclttYXJrXS52Z01hcmssXG4gICAgLi4uKGNsaXAgPyB7Y2xpcDogdHJ1ZX0gOiB7fSksXG4gICAgLi4uKHN0eWxlPyB7c3R5bGV9IDoge30pLFxuICAgIGZyb206IHtkYXRhOiBtb2RlbC5yZXF1ZXN0RGF0YU5hbWUoTUFJTil9LFxuICAgIGVuY29kZToge3VwZGF0ZTogbWFya0NvbXBpbGVyW21hcmtdLmVuY29kZUVudHJ5KG1vZGVsKX1cbiAgfSk7XG5cbiAgcmV0dXJuIG1hcmtzO1xufVxuXG4vKipcbiAqIFJldHVybnMgbGlzdCBvZiBwYXRoIGdyb3VwaW5nIGZpZWxkc1xuICogdGhhdCB0aGUgbW9kZWwncyBzcGVjIGNvbnRhaW5zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0aEdyb3VwaW5nRmllbGRzKGVuY29kaW5nOiBFbmNvZGluZzxzdHJpbmc+KTogc3RyaW5nW10ge1xuICByZXR1cm4ga2V5cyhlbmNvZGluZykucmVkdWNlKChkZXRhaWxzLCBjaGFubmVsKSA9PiB7XG4gICAgc3dpdGNoIChjaGFubmVsKSB7XG4gICAgICAvLyB4LCB5LCB4MiwgeTIsIG9yZGVyLCB0b29sdGlwLCBocmVmLCBjdXJzb3Igc2hvdWxkIG5vdCBjYXVzZSBsaW5lcyB0byBncm91cFxuICAgICAgY2FzZSAneCc6XG4gICAgICBjYXNlICd5JzpcbiAgICAgIGNhc2UgJ29yZGVyJzpcbiAgICAgIGNhc2UgJ3Rvb2x0aXAnOlxuICAgICAgY2FzZSAneDInOlxuICAgICAgY2FzZSAneTInOlxuICAgICAgLy8gVE9ETzogY2FzZSAnaHJlZicsICdjdXJzb3InOlxuXG4gICAgICAvLyB0ZXh0LCBzaGFwZSwgc2hvdWxkbid0IGJlIGEgcGFydCBvZiBsaW5lL2FyZWFcbiAgICAgIGNhc2UgJ3RleHQnOlxuICAgICAgY2FzZSAnc2hhcGUnOlxuICAgICAgICByZXR1cm4gZGV0YWlscztcblxuICAgICAgY2FzZSAnZGV0YWlsJzpcbiAgICAgICAgY29uc3QgY2hhbm5lbERlZiA9IGVuY29kaW5nW2NoYW5uZWxdO1xuICAgICAgICBpZiAoY2hhbm5lbERlZikge1xuICAgICAgICAgIChpc0FycmF5KGNoYW5uZWxEZWYpID8gY2hhbm5lbERlZiA6IFtjaGFubmVsRGVmXSkuZm9yRWFjaCgoZmllbGREZWYpID0+IHtcbiAgICAgICAgICAgIGlmICghZmllbGREZWYuYWdncmVnYXRlKSB7XG4gICAgICAgICAgICAgIGRldGFpbHMucHVzaChmaWVsZChmaWVsZERlZiwge30pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGV0YWlscztcbiAgICAgIGNhc2UgJ2NvbG9yJzpcbiAgICAgIGNhc2UgJ3NpemUnOlxuICAgICAgY2FzZSAnb3BhY2l0eSc6XG4gICAgICAvLyBUT0RPIHN0cm9rZURhc2hPZmZzZXQ6XG4gICAgICAgIGNvbnN0IGZpZWxkRGVmID0gZ2V0RmllbGREZWY8c3RyaW5nPihlbmNvZGluZ1tjaGFubmVsXSk7XG4gICAgICAgIGlmIChmaWVsZERlZiAmJiAhZmllbGREZWYuYWdncmVnYXRlKSB7XG4gICAgICAgICAgZGV0YWlscy5wdXNoKGZpZWxkKGZpZWxkRGVmLCB7fSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZXRhaWxzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBCdWc6IENoYW5uZWwgJHtjaGFubmVsfSB1bmltcGxlbWVudGVkIGZvciBsaW5lIG1hcmtgKTtcbiAgICB9XG4gIH0sIFtdKTtcbn1cblxuLyoqXG4gKiBJZiBzY2FsZXMgYXJlIGJvdW5kIHRvIGludGVydmFsIHNlbGVjdGlvbnMsIHdlIHdhbnQgdG8gYXV0b21hdGljYWxseSBjbGlwXG4gKiBtYXJrcyB0byBhY2NvdW50IGZvciBwYW5uaW5nL3pvb21pbmcgaW50ZXJhY3Rpb25zLiBXZSBpZGVudGlmeSBib3VuZCBzY2FsZXNcbiAqIGJ5IHRoZSBkb21haW5SYXcgcHJvcGVydHksIHdoaWNoIGdldHMgYWRkZWQgZHVyaW5nIHNjYWxlIHBhcnNpbmcuXG4gKi9cbmZ1bmN0aW9uIHNjYWxlQ2xpcChtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IHhTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd4Jyk7XG4gIGNvbnN0IHlTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd5Jyk7XG4gIHJldHVybiAoeFNjYWxlICYmIHhTY2FsZS5nZXQoJ2RvbWFpblJhdycpKSB8fFxuICAgICh5U2NhbGUgJiYgeVNjYWxlLmdldCgnZG9tYWluUmF3JykpID8gdHJ1ZSA6IGZhbHNlO1xufVxuIl19 \ 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..a5968e97c6 --- /dev/null +++ b/build/src/compile/mark/mixins.d.ts @@ -0,0 +1,305 @@ +import { NONPOSITION_SCALE_CHANNELS } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { MarkDef } from '../../mark'; +import { VgEncodeEntry, VgValueRef } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function color(model: UnitModel): VgEncodeEntry; +export declare function markDefProperties(mark: MarkDef, ignoreOrient?: boolean): {}; +export declare function valueIfDefined(prop: string, value: string | number | boolean): 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; +export declare function text(model: UnitModel, channel?: 'text' | 'tooltip'): 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; + })[]; + x?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + opacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + size?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + shape?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + interpolate?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + stroke?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeWidth?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDash?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDashOffset?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fill?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fillOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + orient?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tension?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + align?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + angle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + baseline?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dx?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dy?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + radius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + limit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + theta?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontSize?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontStyle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontWeight?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + xc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + width?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + yc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + height?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cursor?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + clip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + innerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + outerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + startAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + endAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + url?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + ellipsis?: 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; + })[]; + x?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + opacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + size?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + shape?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + interpolate?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + stroke?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeWidth?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDash?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDashOffset?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fill?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fillOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + orient?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tension?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + align?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + angle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + baseline?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dx?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dy?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + radius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + limit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + theta?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontSize?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontStyle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontWeight?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + xc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + width?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + yc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + height?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cursor?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + clip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + innerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + outerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + startAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + endAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + url?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + ellipsis?: VgValueRef | (VgValueRef & { + test?: string; + })[]; +}; +export declare function binnedPosition(fieldDef: FieldDef, channel: 'x' | 'y', scaleName: string, spacing: number, reverse: boolean): { + x2: VgValueRef; + x: VgValueRef; +} | { + y2: VgValueRef; + y: VgValueRef; +}; +/** + * 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]: 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]: VgValueRef; +}; diff --git a/build/src/compile/mark/mixins.js b/build/src/compile/mark/mixins.js new file mode 100644 index 0000000000..2c9f00c4db --- /dev/null +++ b/build/src/compile/mark/mixins.js @@ -0,0 +1,181 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var util = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var common_1 = require("../common"); +var selection_1 = require("../selection/selection"); +var ref = require("./valueref"); +function color(model) { + var config = model.config; + var filled = model.markDef.filled; + var vgChannel = filled ? 'fill' : 'stroke'; + var e = nonPosition('color', model, { + vgChannel: vgChannel, + // Mark definition has higher predecence than config; + // fill/stroke has higher precedence than color. + defaultValue: model.markDef[vgChannel] || + model.markDef.color || + common_1.getMarkConfig(vgChannel, model.markDef, config) || + common_1.getMarkConfig('color', model.markDef, config) + }); + // If there is no fill, always fill symbols + // with transparent fills https://github.com/vega/vega-lite/issues/1316 + if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) { + e.fill = { value: 'transparent' }; + } + return e; +} +exports.color = color; +function markDefProperties(mark, ignoreOrient) { + return vega_schema_1.VG_MARK_CONFIGS.reduce(function (m, prop) { + if (mark[prop] && (!ignoreOrient || prop !== 'orient')) { + m[prop] = { value: mark[prop] }; + } + return m; + }, {}); +} +exports.markDefProperties = markDefProperties; +function valueIfDefined(prop, value) { + if (value !== undefined) { + return _a = {}, _a[prop] = { value: value }, _a; + } + return undefined; + var _a; +} +exports.valueIfDefined = valueIfDefined; +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +function nonPosition(channel, model, opt) { + // TODO: refactor how we refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + 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); + }); +} +exports.nonPosition = nonPosition; +/** + * 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 condition = channelDef && channelDef.condition; + var valueRef = refFn(channelDef); + if (condition) { + var conditions = vega_util_1.isArray(condition) ? condition : [condition]; + var vgConditions = conditions.map(function (c) { + var conditionValueRef = refFn(c); + return __assign({ test: selection_1.predicate(model, c.selection) }, conditionValueRef); + }); + return _a = {}, + _a[vgChannel] = vgConditions.concat((valueRef !== undefined ? [valueRef] : [])), + _a; + } + else { + return valueRef !== undefined ? (_b = {}, _b[vgChannel] = valueRef, _b) : {}; + } + var _a, _b; +} +function text(model, channel) { + if (channel === void 0) { channel = 'text'; } + var channelDef = model.encoding[channel]; + return wrapCondition(model, channelDef, channel, function (cDef) { return ref.text(cDef, model.config); }); +} +exports.text = text; +function bandPosition(fieldDef, channel, model) { + var scaleName = model.scaleName(channel); + var sizeChannel = channel === 'x' ? 'width' : 'height'; + if (model.encoding.size) { + 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 (fielddef_1.getFieldDef(model.encoding.size)) { + log.warn(log.message.cannotUseSizeFieldWithBandSize(channel)); + // TODO: apply size to band and set scale range to some values between 0-1. + // return { + // ...centeredBandPositionMixins, + // ...bandSize('size', model, {vgChannel: sizeChannel}) + // }; + } + else if (fielddef_1.isValueDef(model.encoding.size)) { + return __assign({}, centeredBandPositionMixins, nonPosition('size', model, { vgChannel: sizeChannel })); + } + } + else { + log.warn(log.message.cannotApplySizeToNonOrientedMark(model.markDef.type)); + } + } + return _b = {}, + _b[channel] = ref.fieldRef(fieldDef, scaleName, { binSuffix: 'range' }), + _b[sizeChannel] = ref.band(scaleName), + _b; + var _a, _b; +} +exports.bandPosition = bandPosition; +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 })); +} +exports.centeredBandPosition = centeredBandPosition; +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) + }; + } +} +exports.binnedPosition = binnedPosition; +/** + * 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 encoding = model.encoding, stack = model.stack; + var valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.getScaleComponent(channel), stack, defaultRef); + return _a = {}, + _a[vgChannel || channel] = valueRef, + _a; + var _a; +} +exports.pointPosition = pointPosition; +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +function pointPosition2(model, defaultRef, channel) { + var encoding = model.encoding, markDef = model.markDef, stack = model.stack; + channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2'); + var baseChannel = channel === 'x2' ? 'x' : 'y'; + var valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.getScaleComponent(baseChannel), stack, defaultRef); + return _a = {}, _a[channel] = valueRef, _a; + var _a; +} +exports.pointPosition2 = pointPosition2; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWl4aW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9taXhpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLHVDQUFrQztBQUVsQywyQ0FBNkU7QUFDN0UsK0JBQWlDO0FBRWpDLGlDQUFtQztBQUNuQyxpREFBNkU7QUFDN0Usb0NBQXdDO0FBQ3hDLG9EQUFpRDtBQUVqRCxnQ0FBa0M7QUFHbEMsZUFBc0IsS0FBZ0I7SUFDcEMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUM1QixJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUNwQyxJQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0lBQzdDLElBQU0sQ0FBQyxHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFO1FBQ3BDLFNBQVMsV0FBQTtRQUNULHFEQUFxRDtRQUNyRCxnREFBZ0Q7UUFDaEQsWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1lBQ3BDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSztZQUNuQixzQkFBYSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQztZQUMvQyxzQkFBYSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQztLQUNoRCxDQUFDLENBQUM7SUFFSCwyQ0FBMkM7SUFDM0MsdUVBQXVFO0lBQ3ZFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FB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QUMsRUFBRSxLQUFLLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzFLLE1BQU0sVUFBRSxHQUFDLE9BQU8sSUFBRyxRQUFRLEtBQUU7O0FBQy9CLENBQUM7QUFQRCx3Q0FPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aXNBcnJheX0gZnJvbSAndmVnYS11dGlsJztcbmltcG9ydCB7Tk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFN9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtDaGFubmVsRGVmLCBGaWVsZERlZiwgZ2V0RmllbGREZWYsIGlzVmFsdWVEZWZ9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi9sb2cnO1xuaW1wb3J0IHtNYXJrRGVmfSBmcm9tICcuLi8uLi9tYXJrJztcbmltcG9ydCAqIGFzIHV0aWwgZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZHX01BUktfQ09ORklHUywgVmdFbmNvZGVFbnRyeSwgVmdWYWx1ZVJlZn0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtnZXRNYXJrQ29uZmlnfSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHtwcmVkaWNhdGV9IGZyb20gJy4uL3NlbGVjdGlvbi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0ICogYXMgcmVmIGZyb20gJy4vdmFsdWVyZWYnO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvcihtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IGNvbmZpZyA9IG1vZGVsLmNvbmZpZztcbiAgY29uc3QgZmlsbGVkID0gbW9kZWwubWFya0RlZi5maWxsZWQ7XG4gIGNvbnN0IHZnQ2hhbm5lbCA9IGZpbGxlZCA/ICdmaWxsJyA6ICdzdHJva2UnO1xuICBjb25zdCBlID0gbm9uUG9zaXRpb24oJ2NvbG9yJywgbW9kZWwsIHtcbiAgICB2Z0NoYW5uZWwsXG4gICAgLy8gTWFyayBkZWZpbml0aW9uIGhhcyBoaWdoZXIgcHJlZGVjZW5jZSB0aGFuIGNvbmZpZztcbiAgICAvLyBmaWxsL3N0cm9rZSBoYXMgaGlnaGVyIHByZWNlZGVuY2UgdGhhbiBjb2xvci5cbiAgICBkZWZhdWx0VmFsdWU6IG1vZGVsLm1hcmtEZWZbdmdDaGFubmVsXSB8fFxuICAgICAgbW9kZWwubWFya0RlZi5jb2xvciB8fFxuICAgICAgZ2V0TWFya0NvbmZpZyh2Z0NoYW5uZWwsIG1vZGVsLm1hcmtEZWYsIGNvbmZpZykgfHxcbiAgICAgIGdldE1hcmtDb25maWcoJ2NvbG9yJywgbW9kZWwubWFya0RlZiwgY29uZmlnKVxuICB9KTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyBmaWxsLCBhbHdheXMgZmlsbCBzeW1ib2xzXG4gIC8vIHdpdGggdHJhbnNwYXJlbnQgZmlsbHMgaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8xMzE2XG4gIGlmICghZS5maWxsICYmIHV0aWwuY29udGFpbnMoWydiYXInLCAncG9pbnQnLCAnY2lyY2xlJywgJ3NxdWFyZSddLCBtb2RlbC5tYXJrKCkpKSB7XG4gICAgZS5maWxsID0ge3ZhbHVlOiAndHJhbnNwYXJlbnQnfTtcbiAgfVxuICByZXR1cm4gZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1hcmtEZWZQcm9wZXJ0aWVzKG1hcms6IE1hcmtEZWYsIGlnbm9yZU9yaWVudD86IGJvb2xlYW4pIHtcbiAgcmV0dXJuIFZHX01BUktfQ09ORklHUy5yZWR1Y2UoKG0sIHByb3ApID0+IHtcbiAgICBpZiAobWFya1twcm9wXSAmJiAoIWlnbm9yZU9yaWVudCB8fCBwcm9wICE9PSAnb3JpZW50JykpIHtcbiAgICAgIG1bcHJvcF0gPSB7dmFsdWU6IG1hcmtbcHJvcF19O1xuICAgIH1cbiAgICByZXR1cm4gbTtcbiAgfSwge30pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVJZkRlZmluZWQocHJvcDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbik6IFZnRW5jb2RlRW50cnkge1xuICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7W3Byb3BdOiB7dmFsdWU6IHZhbHVlfX07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gbWl4aW5zIGZvciBub24tcG9zaXRpb25hbCBjaGFubmVscyB3aXRoIHNjYWxlcy4gIChUZXh0IGRvZXNuJ3QgaGF2ZSBzY2FsZS4pXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub25Qb3NpdGlvbihjaGFubmVsOiB0eXBlb2YgTk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFNbMF0sIG1vZGVsOiBVbml0TW9kZWwsIG9wdDoge2RlZmF1bHRWYWx1ZT86IG51bWJlciB8IHN0cmluZyB8IGJvb2xlYW4sIHZnQ2hhbm5lbD86IHN0cmluZywgZGVmYXVsdFJlZj86IFZnVmFsdWVSZWZ9ID0ge30pOiBWZ0VuY29kZUVudHJ5IHtcbiAgLy8gVE9ETzogcmVmYWN0b3IgaG93IHdlIHJlZmVyIHRvIHNjYWxlIGFzIGRpc2N1c3NlZCBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvcHVsbC8xNjEzXG5cbiAgY29uc3Qge2RlZmF1bHRWYWx1ZSwgdmdDaGFubmVsfSA9IG9wdDtcbiAgY29uc3QgZGVmYXVsdFJlZiA9IG9wdC5kZWZhdWx0UmVmIHx8IChkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCA/IHt2YWx1ZTogZGVmYXVsdFZhbHVlfSA6IHVuZGVmaW5lZCk7XG5cbiAgY29uc3QgY2hhbm5lbERlZiA9IG1vZGVsLmVuY29kaW5nW2NoYW5uZWxdO1xuXG4gIHJldHVybiB3cmFwQ29uZGl0aW9uKG1vZGVsLCBjaGFubmVsRGVmLCB2Z0NoYW5uZWwgfHwgY2hhbm5lbCwgKGNEZWYpID0+IHtcbiAgICByZXR1cm4gcmVmLm1pZFBvaW50KFxuICAgICAgY2hhbm5lbCwgY0RlZiwgbW9kZWwuc2NhbGVOYW1lKGNoYW5uZWwpLFxuICAgICAgbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoY2hhbm5lbCksXG4gICAgICBudWxsLCAvLyBObyBuZWVkIHRvIHByb3ZpZGUgc3RhY2sgZm9yIG5vbi1wb3NpdGlvbiBhcyBpdCBkb2VzIG5vdCBhZmZlY3QgbWlkIHBvaW50XG4gICAgICBkZWZhdWx0UmVmXG4gICAgKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgbWl4aW4gdGhhdCBpbmNsdWRlIGEgVmVnYSBwcm9kdWN0aW9uIHJ1bGUgZm9yIGEgVmVnYS1MaXRlIGNvbmRpdGlvbmFsIGNoYW5uZWwgZGVmaW5pdGlvbi5cbiAqIG9yIGEgc2ltcGxlIG1peGluIGlmIGNoYW5uZWwgZGVmIGhhcyBubyBjb25kaXRpb24uXG4gKi9cbmZ1bmN0aW9uIHdyYXBDb25kaXRpb24oXG4gICAgbW9kZWw6IFVuaXRNb2RlbCwgY2hhbm5lbERlZjogQ2hhbm5lbERlZjxzdHJpbmc+LCB2Z0NoYW5uZWw6IHN0cmluZyxcbiAgICByZWZGbjogKGNEZWY6IENoYW5uZWxEZWY8c3RyaW5nPikgPT4gVmdWYWx1ZVJlZlxuICApOiBWZ0VuY29kZUVudHJ5IHtcbiAgY29uc3QgY29uZGl0aW9uID0gY2hhbm5lbERlZiAmJiBjaGFubmVsRGVmLmNvbmRpdGlvbjtcbiAgY29uc3QgdmFsdWVSZWYgPSByZWZGbihjaGFubmVsRGVmKTtcbiAgaWYgKGNvbmRpdGlvbikge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSBpc0FycmF5KGNvbmRpdGlvbikgPyBjb25kaXRpb24gOiBbY29uZGl0aW9uXTtcbiAgICBjb25zdCB2Z0NvbmRpdGlvbnMgPSBjb25kaXRpb25zLm1hcCgoYykgPT4ge1xuICAgICAgY29uc3QgY29uZGl0aW9uVmFsdWVSZWYgPSByZWZGbihjKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRlc3Q6IHByZWRpY2F0ZShtb2RlbCwgYy5zZWxlY3Rpb24pLFxuICAgICAgICAuLi5jb25kaXRpb25WYWx1ZVJlZlxuICAgICAgfTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgW3ZnQ2hhbm5lbF06IFtcbiAgICAgICAgLi4udmdDb25kaXRpb25zLFxuICAgICAgICAuLi4odmFsdWVSZWYgIT09IHVuZGVmaW5lZCA/IFt2YWx1ZVJlZl0gOiBbXSlcbiAgICAgIF1cbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB2YWx1ZVJlZiAhPT0gdW5kZWZpbmVkID8ge1t2Z0NoYW5uZWxdOiB2YWx1ZVJlZn0gOiB7fTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdGV4dChtb2RlbDogVW5pdE1vZGVsLCBjaGFubmVsOiAndGV4dCcgfCAndG9vbHRpcCcgPSAndGV4dCcpIHtcbiAgY29uc3QgY2hhbm5lbERlZiA9IG1vZGVsLmVuY29kaW5nW2NoYW5uZWxdO1xuICByZXR1cm4gd3JhcENvbmRpdGlvbihtb2RlbCwgY2hhbm5lbERlZiwgY2hhbm5lbCwgKGNEZWYpID0+IHJlZi50ZXh0KGNEZWYsIG1vZGVsLmNvbmZpZykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYmFuZFBvc2l0aW9uKGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBjaGFubmVsOiAneCd8J3knLCBtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IHNjYWxlTmFtZSA9IG1vZGVsLnNjYWxlTmFtZShjaGFubmVsKTtcbiAgY29uc3Qgc2l6ZUNoYW5uZWwgPSBjaGFubmVsID09PSAneCcgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG5cbiAgaWYgKG1vZGVsLmVuY29kaW5nLnNpemUpIHtcbiAgICBjb25zdCBvcmllbnQgPSBtb2RlbC5tYXJrRGVmLm9yaWVudDtcbiAgICBpZiAob3JpZW50KSB7XG4gICAgICBjb25zdCBjZW50ZXJlZEJhbmRQb3NpdGlvbk1peGlucyA9IHtcbiAgICAgICAgLy8gVXNlIHhjL3ljIGFuZCBwbGFjZSB0aGUgbWFyayBhdCB0aGUgbWlkZGxlIG9mIHRoZSBiYW5kXG4gICAgICAgIC8vIFRoaXMgd2F5IHdlIG5ldmVyIGhhdmUgdG8gZGVhbCB3aXRoIHNpemUncyBjb25kaXRpb24gZm9yIHgveSBwb3NpdGlvbi5cbiAgICAgICAgW2NoYW5uZWwrJ2MnXTogcmVmLmZpZWxkUmVmKGZpZWxkRGVmLCBzY2FsZU5hbWUsIHt9LCB7YmFuZDogMC41fSlcbiAgICAgIH07XG5cbiAgICAgIGlmIChnZXRGaWVsZERlZihtb2RlbC5lbmNvZGluZy5zaXplKSkge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5jYW5ub3RVc2VTaXplRmllbGRXaXRoQmFuZFNpemUoY2hhbm5lbCkpO1xuICAgICAgICAvLyBUT0RPOiBhcHBseSBzaXplIHRvIGJhbmQgYW5kIHNldCBzY2FsZSByYW5nZSB0byBzb21lIHZhbHVlcyBiZXR3ZWVuIDAtMS5cbiAgICAgICAgLy8gcmV0dXJuIHtcbiAgICAgICAgLy8gICAuLi5jZW50ZXJlZEJhbmRQb3NpdGlvbk1peGlucyxcbiAgICAgICAgLy8gICAuLi5iYW5kU2l6ZSgnc2l6ZScsIG1vZGVsLCB7dmdDaGFubmVsOiBzaXplQ2hhbm5lbH0pXG4gICAgICAgIC8vIH07XG4gICAgICB9IGVsc2UgaWYgKGlzVmFsdWVEZWYobW9kZWwuZW5jb2Rpbmcuc2l6ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5jZW50ZXJlZEJhbmRQb3NpdGlvbk1peGlucyxcbiAgICAgICAgICAuLi5ub25Qb3NpdGlvbignc2l6ZScsIG1vZGVsLCB7dmdDaGFubmVsOiBzaXplQ2hhbm5lbH0pXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmNhbm5vdEFwcGx5U2l6ZVRvTm9uT3JpZW50ZWRNYXJrKG1vZGVsLm1hcmtEZWYudHlwZSkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIFtjaGFubmVsXTogcmVmLmZpZWxkUmVmKGZpZWxkRGVmLCBzY2FsZU5hbWUsIHtiaW5TdWZmaXg6ICdyYW5nZSd9KSxcbiAgICBbc2l6ZUNoYW5uZWxdOiByZWYuYmFuZChzY2FsZU5hbWUpXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjZW50ZXJlZEJhbmRQb3NpdGlvbihjaGFubmVsOiAneCcgfCAneScsIG1vZGVsOiBVbml0TW9kZWwsIGRlZmF1bHRQb3NSZWY6IFZnVmFsdWVSZWYsIGRlZmF1bHRTaXplUmVmOiBWZ1ZhbHVlUmVmKSB7XG4gIGNvbnN0IGNlbnRlckNoYW5uZWw6ICd4YycgfCAneWMnID0gY2hhbm5lbCA9PT0gJ3gnID8gJ3hjJyA6ICd5Yyc7XG4gIGNvbnN0IHNpemVDaGFubmVsID0gY2hhbm5lbCA9PT0gJ3gnID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICByZXR1cm4ge1xuICAgIC4uLnBvaW50UG9zaXRpb24oY2hhbm5lbCwgbW9kZWwsIGRlZmF1bHRQb3NSZWYsIGNlbnRlckNoYW5uZWwpLFxuICAgIC4uLm5vblBvc2l0aW9uKCdzaXplJywgbW9kZWwsIHtkZWZhdWx0UmVmOiBkZWZhdWx0U2l6ZVJlZiwgdmdDaGFubmVsOiBzaXplQ2hhbm5lbH0pXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBiaW5uZWRQb3NpdGlvbihmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgY2hhbm5lbDogJ3gnfCd5Jywgc2NhbGVOYW1lOiBzdHJpbmcsIHNwYWNpbmc6IG51bWJlciwgcmV2ZXJzZTogYm9vbGVhbikge1xuICBpZiAoY2hhbm5lbCA9PT0gJ3gnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHgyOiByZWYuYmluKGZpZWxkRGVmLCBzY2FsZU5hbWUsICdzdGFydCcsIHJldmVyc2UgPyAwIDogc3BhY2luZyksXG4gICAgICB4OiByZWYuYmluKGZpZWxkRGVmLCBzY2FsZU5hbWUsICdlbmQnLCByZXZlcnNlID8gc3BhY2luZyA6IDApXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgeTI6IHJlZi5iaW4oZmllbGREZWYsIHNjYWxlTmFtZSwgJ3N0YXJ0JywgcmV2ZXJzZSA/IHNwYWNpbmcgOiAwKSxcbiAgICAgIHk6IHJlZi5iaW4oZmllbGREZWYsIHNjYWxlTmFtZSwgJ2VuZCcsIHJldmVyc2UgPyAwIDogc3BhY2luZylcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIG1peGlucyBmb3IgcG9pbnQgKG5vbi1iYW5kKSBwb3NpdGlvbiBjaGFubmVscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50UG9zaXRpb24oY2hhbm5lbDogJ3gnfCd5JywgbW9kZWw6IFVuaXRNb2RlbCwgZGVmYXVsdFJlZjogVmdWYWx1ZVJlZiB8ICd6ZXJvT3JNaW4nIHwgJ3plcm9Pck1heCcsIHZnQ2hhbm5lbD86ICd4J3wneSd8J3hjJ3wneWMnKSB7XG4gIC8vIFRPRE86IHJlZmFjdG9yIGhvdyByZWZlciB0byBzY2FsZSBhcyBkaXNjdXNzZWQgaW4gaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL3B1bGwvMTYxM1xuXG4gIGNvbnN0IHtlbmNvZGluZywgc3RhY2t9ID0gbW9kZWw7XG4gIGNvbnN0IHZhbHVlUmVmID0gcmVmLnN0YWNrYWJsZShjaGFubmVsLCBlbmNvZGluZ1tjaGFubmVsXSwgbW9kZWwuc2NhbGVOYW1lKGNoYW5uZWwpLCBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKSwgc3RhY2ssIGRlZmF1bHRSZWYpO1xuXG4gIHJldHVybiB7XG4gICAgW3ZnQ2hhbm5lbCB8fCBjaGFubmVsXTogdmFsdWVSZWZcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gbWl4aW5zIGZvciB4MiwgeTIuXG4gKiBJZiBjaGFubmVsIGlzIG5vdCBzcGVjaWZpZWQsIHJldHVybiBvbmUgY2hhbm5lbCBiYXNlZCBvbiBvcmllbnRhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50UG9zaXRpb24yKG1vZGVsOiBVbml0TW9kZWwsIGRlZmF1bHRSZWY6ICd6ZXJvT3JNaW4nIHwgJ3plcm9Pck1heCcsIGNoYW5uZWw/OiAneDInIHwgJ3kyJykge1xuICBjb25zdCB7ZW5jb2RpbmcsIG1hcmtEZWYsIHN0YWNrfSA9IG1vZGVsO1xuICBjaGFubmVsID0gY2hhbm5lbCB8fCAobWFya0RlZi5vcmllbnQgPT09ICdob3Jpem9udGFsJyA/ICd4MicgOiAneTInKTtcbiAgY29uc3QgYmFzZUNoYW5uZWwgPSBjaGFubmVsID09PSAneDInID8gJ3gnIDogJ3knO1xuXG4gIGNvbnN0IHZhbHVlUmVmID0gcmVmLnN0YWNrYWJsZTIoY2hhbm5lbCwgZW5jb2RpbmdbYmFzZUNoYW5uZWxdLCBlbmNvZGluZ1tjaGFubmVsXSwgbW9kZWwuc2NhbGVOYW1lKGJhc2VDaGFubmVsKSwgbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoYmFzZUNoYW5uZWwpLCBzdGFjaywgZGVmYXVsdFJlZik7XG4gIHJldHVybiB7W2NoYW5uZWxdOiB2YWx1ZVJlZn07XG59XG4iXX0= \ 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..d272a91001 --- /dev/null +++ b/build/src/compile/mark/point.js @@ -0,0 +1,43 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("../common"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +function encodeEntry(model, fixedShape) { + var config = model.config, width = model.width, height = model.height; + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('size', model), shapeMixins(model, config, fixedShape), mixins.nonPosition('opacity', model)); +} +function shapeMixins(model, config, fixedShape) { + if (fixedShape) { + return { shape: { value: fixedShape } }; + } + return mixins.nonPosition('shape', model, { defaultValue: common_1.getMarkConfig('shape', model.markDef, config) }); +} +exports.shapeMixins = shapeMixins; +exports.point = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model); + } +}; +exports.circle = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'circle'); + } +}; +exports.square = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'square'); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL3BvaW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFFQSxvQ0FBd0M7QUFHeEMsaUNBQW1DO0FBQ25DLGdDQUFrQztBQUdsQyxxQkFBcUIsS0FBZ0IsRUFBRSxVQUFnQztJQUM5RCxJQUFBLHFCQUFNLEVBQUUsbUJBQUssRUFBRSxxQkFBTSxDQUFVO0lBRXRDLE1BQU0sY0FDRCxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFDN0MsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFDaEQsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFFakQsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFDbkIsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUNqQyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFDdEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3ZDO0FBQ0osQ0FBQztBQUVELHFCQUE0QixLQUFnQixFQUFFLE1BQWMsRUFBRSxVQUFnQztJQUM1RixFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2YsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFVBQVUsRUFBQyxFQUFDLENBQUM7SUFDdEMsQ0FBQztJQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBQyxZQUFZLEVBQUUsc0JBQWEsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQVcsRUFBQyxDQUFDLENBQUM7QUFDckgsQ0FBQztBQUxELGtDQUtDO0FBRVksUUFBQSxLQUFLLEdBQWlCO0lBQ2pDLE1BQU0sRUFBRSxRQUFRO0lBQ2hCLFdBQVcsRUFBRSxVQUFDLEtBQWdCO1FBQzVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUIsQ0FBQztDQUNGLENBQUM7QUFFVyxRQUFBLE1BQU0sR0FBaUI7SUFDbEMsTUFBTSxFQUFFLFFBQVE7SUFDaEIsV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDNUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdEMsQ0FBQztDQUNGLENBQUM7QUFFVyxRQUFBLE1BQU0sR0FBaUI7SUFDbEMsTUFBTSxFQUFFLFFBQVE7SUFDaEIsV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDNUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdEMsQ0FBQztDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vLi4vY29uZmlnJztcbmltcG9ydCB7VmdFbmNvZGVFbnRyeX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtnZXRNYXJrQ29uZmlnfSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IHtNYXJrQ29tcGlsZXJ9IGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBtaXhpbnMgZnJvbSAnLi9taXhpbnMnO1xuaW1wb3J0ICogYXMgcmVmIGZyb20gJy4vdmFsdWVyZWYnO1xuXG5cbmZ1bmN0aW9uIGVuY29kZUVudHJ5KG1vZGVsOiBVbml0TW9kZWwsIGZpeGVkU2hhcGU/OiAnY2lyY2xlJyB8ICdzcXVhcmUnKSB7XG4gIGNvbnN0IHtjb25maWcsIHdpZHRoLCBoZWlnaHR9ID0gbW9kZWw7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5taXhpbnMubWFya0RlZlByb3BlcnRpZXMobW9kZWwubWFya0RlZiwgdHJ1ZSksXG4gICAgLi4ubWl4aW5zLnBvaW50UG9zaXRpb24oJ3gnLCBtb2RlbCwgcmVmLm1pZCh3aWR0aCkpLFxuICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd5JywgbW9kZWwsIHJlZi5taWQoaGVpZ2h0KSksXG5cbiAgICAuLi5taXhpbnMuY29sb3IobW9kZWwpLFxuICAgIC4uLm1peGlucy50ZXh0KG1vZGVsLCAndG9vbHRpcCcpLFxuICAgIC4uLm1peGlucy5ub25Qb3NpdGlvbignc2l6ZScsIG1vZGVsKSxcbiAgICAuLi5zaGFwZU1peGlucyhtb2RlbCwgY29uZmlnLCBmaXhlZFNoYXBlKSxcbiAgICAuLi5taXhpbnMubm9uUG9zaXRpb24oJ29wYWNpdHknLCBtb2RlbCksXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaGFwZU1peGlucyhtb2RlbDogVW5pdE1vZGVsLCBjb25maWc6IENvbmZpZywgZml4ZWRTaGFwZT86ICdjaXJjbGUnIHwgJ3NxdWFyZScpOiBWZ0VuY29kZUVudHJ5IHtcbiAgaWYgKGZpeGVkU2hhcGUpIHtcbiAgICByZXR1cm4ge3NoYXBlOiB7dmFsdWU6IGZpeGVkU2hhcGV9fTtcbiAgfVxuICByZXR1cm4gbWl4aW5zLm5vblBvc2l0aW9uKCdzaGFwZScsIG1vZGVsLCB7ZGVmYXVsdFZhbHVlOiBnZXRNYXJrQ29uZmlnKCdzaGFwZScsIG1vZGVsLm1hcmtEZWYsIGNvbmZpZykgYXMgc3RyaW5nfSk7XG59XG5cbmV4cG9ydCBjb25zdCBwb2ludDogTWFya0NvbXBpbGVyID0ge1xuICB2Z01hcms6ICdzeW1ib2wnLFxuICBlbmNvZGVFbnRyeTogKG1vZGVsOiBVbml0TW9kZWwpID0+IHtcbiAgICByZXR1cm4gZW5jb2RlRW50cnkobW9kZWwpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY2lyY2xlOiBNYXJrQ29tcGlsZXIgPSB7XG4gIHZnTWFyazogJ3N5bWJvbCcsXG4gIGVuY29kZUVudHJ5OiAobW9kZWw6IFVuaXRNb2RlbCkgPT4ge1xuICAgIHJldHVybiBlbmNvZGVFbnRyeShtb2RlbCwgJ2NpcmNsZScpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc3F1YXJlOiBNYXJrQ29tcGlsZXIgPSB7XG4gIHZnTWFyazogJ3N5bWJvbCcsXG4gIGVuY29kZUVudHJ5OiAobW9kZWw6IFVuaXRNb2RlbCkgPT4ge1xuICAgIHJldHVybiBlbmNvZGVFbnRyeShtb2RlbCwgJ3NxdWFyZScpO1xuICB9XG59O1xuIl19 \ 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..58a147b1bb --- /dev/null +++ b/build/src/compile/mark/rect.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const rect: MarkCompiler; diff --git a/build/src/compile/mark/rect.js b/build/src/compile/mark/rect.js new file mode 100644 index 0000000000..4c9d61cc1f --- /dev/null +++ b/build/src/compile/mark/rect.js @@ -0,0 +1,67 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var mark_1 = require("../../mark"); +var scale_1 = require("../../scale"); +var mixins = require("./mixins"); +exports.rect = { + vgMark: 'rect', + encodeEntry: function (model) { + return __assign({}, mixins.markDefProperties(model.markDef, true), x(model), y(model), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model)); + } +}; +function x(model) { + var xDef = model.encoding.x; + var x2Def = model.encoding.x2; + var xScale = model.getScaleComponent(channel_1.X); + var xScaleType = xScale ? xScale.get('type') : undefined; + if (fielddef_1.isFieldDef(xDef) && xDef.bin && !x2Def) { + return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse')); + } + else if (fielddef_1.isFieldDef(xDef) && xScale && scale_1.hasDiscreteDomain(xScaleType)) { + /* istanbul ignore else */ + if (xScaleType === scale_1.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(mark_1.RECT, xScaleType)); + } + } + else { + return __assign({}, mixins.pointPosition('x', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'x2')); + } +} +function y(model) { + var yDef = model.encoding.y; + var y2Def = model.encoding.y2; + var yScale = model.getScaleComponent(channel_1.Y); + var yScaleType = yScale ? yScale.get('type') : undefined; + if (fielddef_1.isFieldDef(yDef) && yDef.bin && !y2Def) { + return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse')); + } + else if (fielddef_1.isFieldDef(yDef) && yScale && scale_1.hasDiscreteDomain(yScaleType)) { + /* istanbul ignore else */ + if (yScaleType === scale_1.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(mark_1.RECT, yScaleType)); + } + } + else { + return __assign({}, mixins.pointPosition('y', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'y2')); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvcmVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEseUNBQW1DO0FBQ25DLDJDQUEwQztBQUMxQywrQkFBaUM7QUFDakMsbUNBQWdDO0FBQ2hDLHFDQUF5RDtBQUd6RCxpQ0FBbUM7QUFHdEIsUUFBQSxJQUFJLEdBQWlCO0lBQ2hDLE1BQU0sRUFBRSxNQUFNO0lBQ2QsV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDNUIsTUFBTSxjQUNELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUM3QyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQ1IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUNSLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxFQUM3QixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDdkM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLFdBQVcsS0FBZ0I7SUFDekIsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUIsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7SUFDaEMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFdBQUMsQ0FBQyxDQUFDO0lBQzFDLElBQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBRTNELEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FB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LENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtYLCBZfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7aXNGaWVsZERlZn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge1JFQ1R9IGZyb20gJy4uLy4uL21hcmsnO1xuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbiwgU2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vdW5pdCc7XG5pbXBvcnQge01hcmtDb21waWxlcn0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCAqIGFzIG1peGlucyBmcm9tICcuL21peGlucyc7XG5cblxuZXhwb3J0IGNvbnN0IHJlY3Q6IE1hcmtDb21waWxlciA9IHtcbiAgdmdNYXJrOiAncmVjdCcsXG4gIGVuY29kZUVudHJ5OiAobW9kZWw6IFVuaXRNb2RlbCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5taXhpbnMubWFya0RlZlByb3BlcnRpZXMobW9kZWwubWFya0RlZiwgdHJ1ZSksXG4gICAgICAuLi54KG1vZGVsKSxcbiAgICAgIC4uLnkobW9kZWwpLFxuICAgICAgLi4ubWl4aW5zLmNvbG9yKG1vZGVsKSxcbiAgICAgIC4uLm1peGlucy50ZXh0KG1vZGVsLCAndG9vbHRpcCcpLFxuICAgICAgLi4ubWl4aW5zLm5vblBvc2l0aW9uKCdvcGFjaXR5JywgbW9kZWwpLFxuICAgIH07XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHgobW9kZWw6IFVuaXRNb2RlbCkge1xuICBjb25zdCB4RGVmID0gbW9kZWwuZW5jb2RpbmcueDtcbiAgY29uc3QgeDJEZWYgPSBtb2RlbC5lbmNvZGluZy54MjtcbiAgY29uc3QgeFNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoWCk7XG4gIGNvbnN0IHhTY2FsZVR5cGUgPSB4U2NhbGUgPyB4U2NhbGUuZ2V0KCd0eXBlJykgOiB1bmRlZmluZWQ7XG5cbiAgaWYgKGlzRmllbGREZWYoeERlZikgJiYgeERlZi5iaW4gJiYgIXgyRGVmKSB7XG4gICAgcmV0dXJuIG1peGlucy5iaW5uZWRQb3NpdGlvbih4RGVmLCAneCcsIG1vZGVsLnNjYWxlTmFtZSgneCcpLCAwLCB4U2NhbGUuZ2V0KCdyZXZlcnNlJykpO1xuICB9IGVsc2UgaWYgKGlzRmllbGREZWYoeERlZikgJiYgeFNjYWxlICYmIGhhc0Rpc2NyZXRlRG9tYWluKHhTY2FsZVR5cGUpKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoeFNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLkJBTkQpIHtcbiAgICAgIHJldHVybiBtaXhpbnMuYmFuZFBvc2l0aW9uKHhEZWYsICd4JywgbW9kZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSBkb24ndCBzdXBwb3J0IHJlY3QgbWFyayB3aXRoIHBvaW50L29yZGluYWwgc2NhbGVcbiAgICAgIHRocm93IG5ldyBFcnJvcihsb2cubWVzc2FnZS5zY2FsZVR5cGVOb3RXb3JrV2l0aE1hcmsoUkVDVCwgeFNjYWxlVHlwZSkpO1xuICAgIH1cbiAgfSBlbHNlIHsgLy8gY29udGludW91cyBzY2FsZSBvciBubyBzY2FsZVxuICAgIHJldHVybiB7XG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbigneCcsIG1vZGVsLCAnemVyb09yTWF4JyksXG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbjIobW9kZWwsICd6ZXJvT3JNaW4nLCAneDInKVxuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24geShtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IHlEZWYgPSBtb2RlbC5lbmNvZGluZy55O1xuICBjb25zdCB5MkRlZiA9IG1vZGVsLmVuY29kaW5nLnkyO1xuICBjb25zdCB5U2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChZKTtcbiAgY29uc3QgeVNjYWxlVHlwZSA9IHlTY2FsZSA/IHlTY2FsZS5nZXQoJ3R5cGUnKSA6IHVuZGVmaW5lZDtcblxuICBpZiAoaXNGaWVsZERlZih5RGVmKSAmJiB5RGVmLmJpbiAmJiAheTJEZWYpIHtcbiAgICByZXR1cm4gbWl4aW5zLmJpbm5lZFBvc2l0aW9uKHlEZWYsICd5JywgbW9kZWwuc2NhbGVOYW1lKCd5JyksIDAsIHlTY2FsZS5nZXQoJ3JldmVyc2UnKSk7XG4gIH0gZWxzZSBpZiAoaXNGaWVsZERlZih5RGVmKSAmJiB5U2NhbGUgJiYgaGFzRGlzY3JldGVEb21haW4oeVNjYWxlVHlwZSkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh5U2NhbGVUeXBlID09PSBTY2FsZVR5cGUuQkFORCkge1xuICAgICAgcmV0dXJuIG1peGlucy5iYW5kUG9zaXRpb24oeURlZiwgJ3knLCBtb2RlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgcmVjdCBtYXJrIHdpdGggcG9pbnQvb3JkaW5hbCBzY2FsZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGxvZy5tZXNzYWdlLnNjYWxlVHlwZU5vdFdvcmtXaXRoTWFyayhSRUNULCB5U2NhbGVUeXBlKSk7XG4gICAgfVxuICB9IGVsc2UgeyAvLyBjb250aW51b3VzIHNjYWxlIG9yIG5vIHNjYWxlXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd5JywgbW9kZWwsICd6ZXJvT3JNYXgnKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uMihtb2RlbCwgJ3plcm9Pck1pbicsICd5MicpXG4gICAgfTtcbiAgfVxufVxuIl19 \ 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..3fed35484b --- /dev/null +++ b/build/src/compile/mark/rule.js @@ -0,0 +1,27 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.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) { + // if we have neither x or y, show nothing + return {}; + } + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)), mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)), mixins.pointPosition2(model, 'zeroOrMax'), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's rule size is strokeWidth + })); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsaUNBQW1DO0FBQ25DLGdDQUFrQztBQUdyQixRQUFBLElBQUksR0FBaUI7SUFDaEMsTUFBTSxFQUFFLE1BQU07SUFDZCxXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUNyQixJQUFBLHNCQUFlLEVBQUUsdUJBQU8sRUFBRSxtQkFBSyxFQUFFLHFCQUFNLENBQVU7UUFDeEQsSUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUU5QixFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLDBDQUEwQztZQUMxQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELE1BQU0sY0FDRCxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFDN0MsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUN4RixNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3ZGLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUV6QyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsRUFDN0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3BDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtZQUNuQyxTQUFTLEVBQUUsYUFBYSxDQUFFLGdDQUFnQztTQUMzRCxDQUFDLEVBQ0Y7SUFDSixDQUFDO0NBQ0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7TWFya0NvbXBpbGVyfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0ICogYXMgbWl4aW5zIGZyb20gJy4vbWl4aW5zJztcbmltcG9ydCAqIGFzIHJlZiBmcm9tICcuL3ZhbHVlcmVmJztcblxuXG5leHBvcnQgY29uc3QgcnVsZTogTWFya0NvbXBpbGVyID0ge1xuICB2Z01hcms6ICdydWxlJyxcbiAgZW5jb2RlRW50cnk6IChtb2RlbDogVW5pdE1vZGVsKSA9PiB7XG4gICAgY29uc3Qge2NvbmZpZzogX2NvbmZpZywgbWFya0RlZiwgd2lkdGgsIGhlaWdodH0gPSBtb2RlbDtcbiAgICBjb25zdCBvcmllbnQgPSBtYXJrRGVmLm9yaWVudDtcblxuICAgIGlmICghbW9kZWwuZW5jb2RpbmcueCAmJiAhbW9kZWwuZW5jb2RpbmcueSkge1xuICAgICAgLy8gaWYgd2UgaGF2ZSBuZWl0aGVyIHggb3IgeSwgc2hvdyBub3RoaW5nXG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1peGlucy5tYXJrRGVmUHJvcGVydGllcyhtb2RlbC5tYXJrRGVmLCB0cnVlKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd4JywgbW9kZWwsIG9yaWVudCA9PT0gJ2hvcml6b250YWwnID8gJ3plcm9Pck1pbicgOiByZWYubWlkKHdpZHRoKSksXG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbigneScsIG1vZGVsLCBvcmllbnQgPT09ICd2ZXJ0aWNhbCcgPyAnemVyb09yTWluJyA6IHJlZi5taWQoaGVpZ2h0KSksXG4gICAgICAuLi5taXhpbnMucG9pbnRQb3NpdGlvbjIobW9kZWwsICd6ZXJvT3JNYXgnKSxcblxuICAgICAgLi4ubWl4aW5zLmNvbG9yKG1vZGVsKSxcbiAgICAgIC4uLm1peGlucy50ZXh0KG1vZGVsLCAndG9vbHRpcCcpLFxuICAgICAgLi4ubWl4aW5zLm5vblBvc2l0aW9uKCdvcGFjaXR5JywgbW9kZWwpLFxuICAgICAgLi4ubWl4aW5zLm5vblBvc2l0aW9uKCdzaXplJywgbW9kZWwsIHtcbiAgICAgICAgdmdDaGFubmVsOiAnc3Ryb2tlV2lkdGgnICAvLyBWTCdzIHJ1bGUgc2l6ZSBpcyBzdHJva2VXaWR0aFxuICAgICAgfSlcbiAgICB9O1xuICB9XG59O1xuIl19 \ 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..bcdc944880 --- /dev/null +++ b/build/src/compile/mark/text.js @@ -0,0 +1,43 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var common_1 = require("../common"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.text = { + vgMark: 'text', + encodeEntry: function (model) { + var config = model.config, encoding = model.encoding, height = model.height; + var textDef = encoding.text; + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, xDefault(config, textDef)), mixins.pointPosition('y', model, ref.mid(height)), mixins.text(model), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'fontSize' // VL's text size is fontSize + }), mixins.valueIfDefined('align', align(model.markDef, encoding, config))); + } +}; +function xDefault(config, textDef) { + if (fielddef_1.isFieldDef(textDef) && textDef.type === type_1.QUANTITATIVE) { + return { field: { group: 'width' }, offset: -5 }; + } + // TODO: allow this to fit (Be consistent with ref.midX()) + return { value: config.scale.textXRangeStep / 2 }; +} +function align(markDef, encoding, config) { + var align = markDef.align || common_1.getMarkConfig('align', markDef, config); + if (align === undefined) { + return encoding_1.channelHasField(encoding, channel_1.X) ? 'center' : 'right'; + } + // If there is a config, Vega-parser will process this already. + return undefined; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvdGV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEseUNBQWdDO0FBRWhDLDJDQUF5RDtBQUN6RCwyQ0FBc0Q7QUFFdEQsbUNBQXdDO0FBRXhDLG9DQUF3QztBQUd4QyxpQ0FBbUM7QUFDbkMsZ0NBQWtDO0FBR3JCLFFBQUEsSUFBSSxHQUFpQjtJQUNoQyxNQUFNLEVBQUUsTUFBTTtJQUVkLFdBQVcsRUFBRSxVQUFDLEtBQWdCO1FBQ3JCLElBQUEscUJBQU0sRUFBRSx5QkFBUSxFQUFFLHFCQUFNLENBQVU7UUFDekMsSUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUU5QixNQUFNLGNBQ0QsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQzNELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQ2xCLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxFQUM3QixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDcEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFO1lBQ25DLFNBQVMsRUFBRSxVQUFVLENBQUUsNkJBQTZCO1NBQ3JELENBQUMsRUFDQyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFDekU7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLGtCQUFrQixNQUFjLEVBQUUsT0FBMkI7SUFDM0QsRUFBRSxDQUFDLENBQUMscUJBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLG1CQUFZLENBQUMsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sQ0FBQyxFQUFDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQztJQUMvQyxDQUFDO0lBQ0QsMERBQTBEO0lBQzFELE1BQU0sQ0FBQyxFQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsR0FBRyxDQUFDLEVBQUMsQ0FBQztBQUNsRCxDQUFDO0FBRUQsZUFBZSxPQUFnQixFQUFFLFFBQTBCLEVBQUUsTUFBYztJQUN6RSxJQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLHNCQUFhLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN2RSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsMEJBQWUsQ0FBQyxRQUFRLEVBQUUsV0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQzNELENBQUM7SUFDRCwrREFBK0Q7SUFDL0QsTUFBTSxDQUFDLFNBQVMsQ0FBQztBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtYfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHtjaGFubmVsSGFzRmllbGQsIEVuY29kaW5nfSBmcm9tICcuLi8uLi9lbmNvZGluZyc7XG5pbXBvcnQge0NoYW5uZWxEZWYsIGlzRmllbGREZWZ9IGZyb20gJy4uLy4uL2ZpZWxkZGVmJztcbmltcG9ydCB7TWFya0RlZn0gZnJvbSAnLi4vLi4vbWFyayc7XG5pbXBvcnQge1FVQU5USVRBVElWRX0gZnJvbSAnLi4vLi4vdHlwZSc7XG5pbXBvcnQge1ZnVmFsdWVSZWZ9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7Z2V0TWFya0NvbmZpZ30gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7TWFya0NvbXBpbGVyfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0ICogYXMgbWl4aW5zIGZyb20gJy4vbWl4aW5zJztcbmltcG9ydCAqIGFzIHJlZiBmcm9tICcuL3ZhbHVlcmVmJztcblxuXG5leHBvcnQgY29uc3QgdGV4dDogTWFya0NvbXBpbGVyID0ge1xuICB2Z01hcms6ICd0ZXh0JyxcblxuICBlbmNvZGVFbnRyeTogKG1vZGVsOiBVbml0TW9kZWwpID0+IHtcbiAgICBjb25zdCB7Y29uZmlnLCBlbmNvZGluZywgaGVpZ2h0fSA9IG1vZGVsO1xuICAgIGNvbnN0IHRleHREZWYgPSBlbmNvZGluZy50ZXh0O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1peGlucy5tYXJrRGVmUHJvcGVydGllcyhtb2RlbC5tYXJrRGVmLCB0cnVlKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd4JywgbW9kZWwsIHhEZWZhdWx0KGNvbmZpZywgdGV4dERlZikpLFxuICAgICAgLi4ubWl4aW5zLnBvaW50UG9zaXRpb24oJ3knLCBtb2RlbCwgcmVmLm1pZChoZWlnaHQpKSxcbiAgICAgIC4uLm1peGlucy50ZXh0KG1vZGVsKSxcbiAgICAgIC4uLm1peGlucy5jb2xvcihtb2RlbCksXG4gICAgICAuLi5taXhpbnMudGV4dChtb2RlbCwgJ3Rvb2x0aXAnKSxcbiAgICAgIC4uLm1peGlucy5ub25Qb3NpdGlvbignb3BhY2l0eScsIG1vZGVsKSxcbiAgICAgIC4uLm1peGlucy5ub25Qb3NpdGlvbignc2l6ZScsIG1vZGVsLCB7XG4gICAgICAgIHZnQ2hhbm5lbDogJ2ZvbnRTaXplJyAgLy8gVkwncyB0ZXh0IHNpemUgaXMgZm9udFNpemVcbiAgICAgIH0pLFxuICAgICAgLi4ubWl4aW5zLnZhbHVlSWZEZWZpbmVkKCdhbGlnbicsIGFsaWduKG1vZGVsLm1hcmtEZWYsIGVuY29kaW5nLCBjb25maWcpKVxuICAgIH07XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHhEZWZhdWx0KGNvbmZpZzogQ29uZmlnLCB0ZXh0RGVmOiBDaGFubmVsRGVmPHN0cmluZz4pOiBWZ1ZhbHVlUmVmIHtcbiAgaWYgKGlzRmllbGREZWYodGV4dERlZikgJiYgdGV4dERlZi50eXBlID09PSBRVUFOVElUQVRJVkUpIHtcbiAgICByZXR1cm4ge2ZpZWxkOiB7Z3JvdXA6ICd3aWR0aCd9LCBvZmZzZXQ6IC01fTtcbiAgfVxuICAvLyBUT0RPOiBhbGxvdyB0aGlzIHRvIGZpdCAoQmUgY29uc2lzdGVudCB3aXRoIHJlZi5taWRYKCkpXG4gIHJldHVybiB7dmFsdWU6IGNvbmZpZy5zY2FsZS50ZXh0WFJhbmdlU3RlcCAvIDJ9O1xufVxuXG5mdW5jdGlvbiBhbGlnbihtYXJrRGVmOiBNYXJrRGVmLCBlbmNvZGluZzogRW5jb2Rpbmc8c3RyaW5nPiwgY29uZmlnOiBDb25maWcpIHtcbiAgY29uc3QgYWxpZ24gPSBtYXJrRGVmLmFsaWduIHx8IGdldE1hcmtDb25maWcoJ2FsaWduJywgbWFya0RlZiwgY29uZmlnKTtcbiAgaWYgKGFsaWduID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY2hhbm5lbEhhc0ZpZWxkKGVuY29kaW5nLCBYKSA/ICdjZW50ZXInIDogJ3JpZ2h0JztcbiAgfVxuICAvLyBJZiB0aGVyZSBpcyBhIGNvbmZpZywgVmVnYS1wYXJzZXIgd2lsbCBwcm9jZXNzIHRoaXMgYWxyZWFkeS5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiJdfQ== \ 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..7071bc6df9 --- /dev/null +++ b/build/src/compile/mark/tick.js @@ -0,0 +1,47 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_schema_1 = require("../../vega.schema"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.tick = { + vgMark: 'rect', + encodeEntry: function (model) { + 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({}, mixins.markDefProperties(model.markDef, true), 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: config.tick.thickness }, _a), mixins.color(model), mixins.nonPosition('opacity', model)); + var _a; + } +}; +function defaultSize(model) { + var config = model.config; + var orient = model.markDef.orient; + var scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y'); + if (config.tick.bandSize !== undefined) { + return config.tick.bandSize; + } + else { + var scaleRange = scale ? scale.get('range') : undefined; + var rangeStep = scaleRange && vega_schema_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGljay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvdGljay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsaURBQWdEO0FBR2hELGlDQUFtQztBQUNuQyxnQ0FBa0M7QUFHckIsUUFBQSxJQUFJLEdBQWlCO0lBQ2hDLE1BQU0sRUFBRSxNQUFNO0lBRWQsV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDckIsSUFBQSxxQkFBTSxFQUFFLHVCQUFPLEVBQUUsbUJBQUssRUFBRSxxQkFBTSxDQUFVO1FBQy9DLElBQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFFOUIsSUFBTSxhQUFhLEdBQUcsTUFBTSxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDbkUsSUFBTSxrQkFBa0IsR0FBRyxNQUFNLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUV4RSxNQUFNLGNBQ0QsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUN0RCxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsRUFHdkQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFO1lBQ25DLFlBQVksRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDO1lBQ2hDLFNBQVMsRUFBRSxhQUFhO1NBQ3pCLENBQUMsZUFDRCxrQkFBa0IsSUFBRyxFQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxPQUVqRCxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUNuQixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDdkM7O0lBQ0osQ0FBQztDQUNGLENBQUM7QUFFRixxQkFBcUIsS0FBZ0I7SUFDNUIsSUFBQSxxQkFBTSxDQUFVO0lBQ3ZCLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBQ3BDLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTNFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDdkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQzlCLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLElBQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzFELElBQU0sU0FBUyxHQUFHLFVBQVUsSUFBSSwyQkFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDekQsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ3pCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sU0FBUyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDbEMsNkJBQTZCO1lBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztRQUNwRSxDQUFDO1FBQ0QsTUFBTSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUM7SUFDekIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzVmdSYW5nZVN0ZXB9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7TWFya0NvbXBpbGVyfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0ICogYXMgbWl4aW5zIGZyb20gJy4vbWl4aW5zJztcbmltcG9ydCAqIGFzIHJlZiBmcm9tICcuL3ZhbHVlcmVmJztcblxuXG5leHBvcnQgY29uc3QgdGljazogTWFya0NvbXBpbGVyID0ge1xuICB2Z01hcms6ICdyZWN0JyxcblxuICBlbmNvZGVFbnRyeTogKG1vZGVsOiBVbml0TW9kZWwpID0+IHtcbiAgICBjb25zdCB7Y29uZmlnLCBtYXJrRGVmLCB3aWR0aCwgaGVpZ2h0fSA9IG1vZGVsO1xuICAgIGNvbnN0IG9yaWVudCA9IG1hcmtEZWYub3JpZW50O1xuXG4gICAgY29uc3QgdmdTaXplQ2hhbm5lbCA9IG9yaWVudCA9PT0gJ2hvcml6b250YWwnID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICAgIGNvbnN0IHZnVGhpY2tuZXNzQ2hhbm5lbCA9IG9yaWVudCA9PT0gJ2hvcml6b250YWwnID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1peGlucy5tYXJrRGVmUHJvcGVydGllcyhtb2RlbC5tYXJrRGVmLCB0cnVlKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd4JywgbW9kZWwsIHJlZi5taWQod2lkdGgpLCAneGMnKSxcbiAgICAgIC4uLm1peGlucy5wb2ludFBvc2l0aW9uKCd5JywgbW9kZWwsIHJlZi5taWQoaGVpZ2h0KSwgJ3ljJyksXG5cbiAgICAgIC8vIHNpemUgLyB0aGlja25lc3MgPT4gd2lkdGggLyBoZWlnaHRcbiAgICAgIC4uLm1peGlucy5ub25Qb3NpdGlvbignc2l6ZScsIG1vZGVsLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogZGVmYXVsdFNpemUobW9kZWwpLFxuICAgICAgICB2Z0NoYW5uZWw6IHZnU2l6ZUNoYW5uZWxcbiAgICAgIH0pLFxuICAgICAgW3ZnVGhpY2tuZXNzQ2hhbm5lbF06IHt2YWx1ZTogY29uZmlnLnRpY2sudGhpY2tuZXNzfSxcblxuICAgICAgLi4ubWl4aW5zLmNvbG9yKG1vZGVsKSxcbiAgICAgIC4uLm1peGlucy5ub25Qb3NpdGlvbignb3BhY2l0eScsIG1vZGVsKSxcbiAgICB9O1xuICB9XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2l6ZShtb2RlbDogVW5pdE1vZGVsKTogbnVtYmVyIHtcbiAgY29uc3Qge2NvbmZpZ30gPSBtb2RlbDtcbiAgY29uc3Qgb3JpZW50ID0gbW9kZWwubWFya0RlZi5vcmllbnQ7XG4gIGNvbnN0IHNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQob3JpZW50ID09PSAnaG9yaXpvbnRhbCcgPyAneCcgOiAneScpO1xuXG4gIGlmIChjb25maWcudGljay5iYW5kU2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGNvbmZpZy50aWNrLmJhbmRTaXplO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHNjYWxlUmFuZ2UgPSBzY2FsZSA/IHNjYWxlLmdldCgncmFuZ2UnKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCByYW5nZVN0ZXAgPSBzY2FsZVJhbmdlICYmIGlzVmdSYW5nZVN0ZXAoc2NhbGVSYW5nZSkgP1xuICAgICAgc2NhbGVSYW5nZS5zdGVwIDpcbiAgICAgIGNvbmZpZy5zY2FsZS5yYW5nZVN0ZXA7XG4gICAgaWYgKHR5cGVvZiByYW5nZVN0ZXAgIT09ICdudW1iZXInKSB7XG4gICAgICAvLyBGSVhNRSBjb25zb2xpZGF0ZSB0aGlzIGxvZ1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGdW5jdGlvbiBkb2VzIG5vdCBoYW5kbGUgbm9uLW51bWVyaWMgcmFuZ2VTdGVwJyk7XG4gICAgfVxuICAgIHJldHVybiByYW5nZVN0ZXAgLyAxLjU7XG4gIH1cbn1cbiJdfQ== \ 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..5c2ee511a9 --- /dev/null +++ b/build/src/compile/mark/valueref.d.ts @@ -0,0 +1,32 @@ +/** + * Utility files for producing Vega ValueRef for marks + */ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { ChannelDef, ChannelDefWithCondition, FieldDef, FieldRefOption, TextFieldDef } from '../../fielddef'; +import { StackProperties } from '../../stack'; +import { VgSignalRef, VgValueRef } from '../../vega.schema'; +import { ScaleComponent } from '../scale/component'; +/** + * @return Vega ValueRef for stackable x or y + */ +export declare function stackable(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): VgValueRef; +/** + * @return Vega ValueRef for stackable x2 or y2 + */ +export declare function stackable2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): VgValueRef; +/** + * 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 band(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 | 'zeroOrMin' | 'zeroOrMax'): VgValueRef; +export declare function text(textDef: ChannelDefWithCondition>, config: Config): VgValueRef; +export declare function mid(sizeRef: VgSignalRef): VgValueRef; diff --git a/build/src/compile/mark/valueref.js b/build/src/compile/mark/valueref.js new file mode 100644 index 0000000000..ee3a3bfff1 --- /dev/null +++ b/build/src/compile/mark/valueref.js @@ -0,0 +1,228 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Utility files for producing Vega ValueRef for marks + */ +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var common_1 = require("../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 stackable x or y + */ +function stackable(channel, channelDef, scaleName, scale, stack, defaultRef) { + if (fielddef_1.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); +} +exports.stackable = stackable; +/** + * @return Vega ValueRef for stackable x2 or y2 + */ +function stackable2(channel, aFieldDef, a2fieldDef, scaleName, scale, stack, defaultRef) { + if (fielddef_1.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); +} +exports.stackable2 = stackable2; +/** + * Value Ref for binned fields + */ +function bin(fieldDef, scaleName, side, offset) { + var binSuffix = side === 'start' ? undefined : 'end'; + return fieldRef(fieldDef, scaleName, { binSuffix: binSuffix }, offset ? { offset: offset } : {}); +} +exports.bin = bin; +function fieldRef(fieldDef, scaleName, opt, mixins) { + var ref = { + scale: scaleName, + field: fielddef_1.field(fieldDef, opt), + }; + if (mixins) { + return __assign({}, ref, mixins); + } + return ref; +} +exports.fieldRef = fieldRef; +function band(scaleName, band) { + if (band === void 0) { band = true; } + return { + scale: scaleName, + band: band + }; +} +exports.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 + "\", " + fielddef_1.field(fieldDef, { expr: 'datum' }) + ")") + + " + " + + ("scale(\"" + scaleName + "\", " + fielddef_1.field(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 (fielddef_1.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 (util_1.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, common_1.binRequiresRange(channelDef, channel) ? { binSuffix: 'range' } : {}); + } + var scaleType = scale.get('type'); + if (scale_1.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' }); + } + else { + return fieldRef(channelDef, scaleName, {}); // no need for bin suffix + } + } + else if (fielddef_1.isValueDef(channelDef)) { + return { value: channelDef.value }; + } + else { + return undefined; + } + } + if (defaultRef === 'zeroOrMin') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMinX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMinY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + else if (defaultRef === 'zeroOrMax') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMaxX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMaxY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + return defaultRef; +} +exports.midPoint = midPoint; +function text(textDef, config) { + // text + if (textDef) { + if (fielddef_1.isFieldDef(textDef)) { + return common_1.formatSignalRef(textDef, textDef.format, 'datum', config); + } + else if (fielddef_1.isValueDef(textDef)) { + return { value: textDef.value }; + } + } + return undefined; +} +exports.text = text; +function mid(sizeRef) { + return __assign({}, sizeRef, { mult: 0.5 }); +} +exports.mid = mid; +function zeroOrMinX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the x-axis + return { value: 0 }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + return { field: { group: 'width' } }; +} +function zeroOrMinY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { field: { group: 'height' } }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { value: 0 }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsdWVyZWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL3ZhbHVlcmVmLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7R0FFRztBQUNILHlDQUFvRDtBQUVwRCwyQ0FTd0I7QUFDeEIscUNBQXlEO0FBRXpELG1DQUFvQztBQUVwQyxvQ0FBNEQ7QUFJNUQscUZBQXFGO0FBQ3JGLHdFQUF3RTtBQUV4RTs7R0FFRztBQUNILG1CQUEwQixPQUFrQixFQUFFLFVBQThCLEVBQUUsU0FBaUIsRUFBRSxLQUFxQixFQUNsSCxLQUFzQixFQUFFLFVBQWtEO0lBQzVFLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUN0RSw0RUFBNEU7UUFDNUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUNELE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM1RSxDQUFDO0FBUEQsOEJBT0M7QUFFRDs7R0FFRztBQUNILG9CQUEyQixPQUFvQixFQUFFLFNBQTZCLEVBQUUsVUFBOEIsRUFBRSxTQUFpQixFQUFFLEtBQXFCLEVBQ3BKLEtBQXNCLEVBQUUsVUFBa0Q7SUFDNUUsRUFBRSxDQUFDLENBQUMscUJBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLO1FBQzlCLHVEQUF1RDtRQUN2RCxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDakQsQ0FBQyxDQUFDLENBQUM7UUFDTCxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQzVFLENBQUM7QUFURCxnQ0FTQztBQUVEOztHQUVHO0FBQ0gsYUFBb0IsUUFBMEIsRUFBRSxTQUFpQixFQUFFLElBQXFCLEVBQUUsTUFBZTtJQUN2RyxJQUFNLFNBQVMsR0FBRyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN2RCxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsRUFBQyxTQUFTLFdBQUEsRUFBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBQyxNQUFNLFFBQUEsRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM1RSxDQUFDO0FBSEQsa0JBR0M7QUFFRCxrQkFDSSxRQUEwQixFQUFFLFNBQWlCLEVBQUUsR0FBbUIsRUFDbEUsTUFBOEQ7SUFFaEUsSUFBTSxHQUFHLEdBQWU7UUFDdEIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsS0FBSyxFQUFFLGdCQUFLLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQztLQUM1QixDQUFDO0lBQ0YsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNYLE1BQU0sY0FDRCxHQUFHLEVBQ0gsTUFBTSxFQUNUO0lBQ0osQ0FBQztJQUNELE1BQU0sQ0FBQyxHQUFHLENBQUM7QUFDYixDQUFDO0FBZkQsNEJBZUM7QUFFRCxjQUFxQixTQUFpQixFQUFFLElBQTJCO0lBQTNCLHFCQUFBLEVBQUEsV0FBMkI7SUFDakUsTUFBTSxDQUFDO1FBQ0wsS0FBSyxFQUFFLFNBQVM7UUFDaEIsSUFBSSxFQUFFLElBQUk7S0FDWCxDQUFDO0FBQ0osQ0FBQztBQUxELG9CQUtDO0FBRUQ7O0dBRUc7QUFDSCxzQkFBc0IsUUFBMEIsRUFBRSxTQUFpQjtJQUNqRSxNQUFNLENBQUM7UUFDTCxNQUFNLEVBQUUsR0FBRzthQUNULGFBQVUsU0FBUyxZQUFNLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLE1BQUcsQ0FBQTtZQUM1RCxLQUFLO2FBQ0wsYUFBVSxTQUFTLFlBQU0sZ0JBQUssQ0FBQyxRQUFRLEVBQUUsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUMsQ0FBQyxNQUFHLENBQUE7WUFDaEYsS0FBSztLQUNOLENBQUM7QUFDSixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxrQkFBeUIsT0FBZ0IsRUFBRSxVQUE4QixFQUFFLFNBQWlCLEVBQUUsS0FBcUIsRUFBRSxLQUFzQixFQUN6SSxVQUFrRDtJQUNsRCxzQkFBc0I7SUFFdEIsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNmLDBCQUEwQjtRQUUxQixFQUFFLENBQUMsQ0FBQyxxQkFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzQixFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDbkIsa0dBQWtHO2dCQUNsRyw0R0FBNEc7Z0JBQzVHLEVBQUUsQ0FBQyxDQUFDLGVBQVEsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsSUFBSSxVQUFVLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7b0JBQ3hFLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzt3QkFDMUIsbURBQW1EO3dCQUNuRCxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztvQkFDN0QsQ0FBQztvQkFDRCx3RUFBd0U7b0JBQ3hFLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUM3QyxDQUFDO2dCQUNELE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSx5QkFBZ0IsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM1RyxDQUFDO1lBRUQsSUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwQyxFQUFFLENBQUMsQ0FBQyx5QkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDO29CQUN6QixpRUFBaUU7b0JBQ2pFLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFDO2dCQUM1RSxDQUFDO2dCQUNELE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDO1lBQy9ELENBQUM7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyx5QkFBeUI7WUFDdkUsQ0FBQztRQUNILENBQUM7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMscUJBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMsU0FBUyxDQUFDO1FBQ25CLENBQUM7SUFDSCxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDL0IsMEJBQTBCO1FBQzFCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sS0FBSyxXQUFDLElBQUksT0FBTyxLQUFLLFlBQUUsQ0FBQyxDQUFDLENBQUM7WUFDcEMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLEtBQUssV0FBQyxJQUFJLE9BQU8sS0FBSyxZQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXVCLE9BQU8sdUJBQW9CLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztRQUN2RyxDQUFDO0lBQ0gsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxVQUFVLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN0QywwQkFBMEI7UUFDMUIsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLFdBQUMsSUFBSSxPQUFPLEtBQUssWUFBRSxDQUFDLENBQUMsQ0FBQztZQUNwQyxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sS0FBSyxXQUFDLElBQUksT0FBTyxLQUFLLFlBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0MsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBdUIsT0FBTyx1QkFBb0IsQ0FBQyxDQUFDLENBQUMsZ0NBQWdDO1FBQ3ZHLENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLFVBQVUsQ0FBQztBQUNwQixDQUFDO0FBM0RELDRCQTJEQztBQUVELGNBQXFCLE9BQXNELEVBQUUsTUFBYztJQUN6RixPQUFPO0lBQ1AsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNaLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyx3QkFBZSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNuRSxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxFQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxFQUFDLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFDRCxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFWRCxvQkFVQztBQUVELGFBQW9CLE9BQW9CO0lBQ3RDLE1BQU0sY0FBSyxPQUFPLElBQUUsSUFBSSxFQUFFLEdBQUcsSUFBRTtBQUNqQyxDQUFDO0FBRkQsa0JBRUM7QUFFRCxvQkFBb0IsU0FBaUIsRUFBRSxLQUFxQjtJQUMxRCxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2QsNkNBQTZDO1FBQzdDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBUSxDQUFDLENBQUMsaUJBQVMsQ0FBQyxHQUFHLEVBQUUsaUJBQVMsQ0FBQyxJQUFJLEVBQUUsaUJBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlFLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztZQUU5QixNQUFNLENBQUM7Z0JBQ0wsS0FBSyxFQUFFLFNBQVM7Z0JBQ2hCLEtBQUssRUFBRSxDQUFDO2FBQ1QsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsNkJBQTZCO0lBQzdCLE1BQU0sQ0FBQyxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUMsQ0FBQztBQUNwQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxvQkFBb0IsU0FBaUIsRUFBRSxLQUFxQjtJQUMxRCxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2QsNkNBQTZDO1FBQzdDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBUSxDQUFDLENBQUMsaUJBQVMsQ0FBQyxHQUFHLEVBQUUsaUJBQVMsQ0FBQyxJQUFJLEVBQUUsaUJBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlFLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztZQUU5QixNQUFNLENBQUM7Z0JBQ0wsS0FBSyxFQUFFLFNBQVM7Z0JBQ2hCLEtBQUssRUFBRSxDQUFDO2FBQ1QsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQyxFQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVELG9CQUFvQixTQUFpQixFQUFFLEtBQXFCO0lBQzFELEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDZCw2Q0FBNkM7UUFDN0MsRUFBRSxDQUFDLENBQUMsQ0FBQyxlQUFRLENBQUMsQ0FBQyxpQkFBUyxDQUFDLEdBQUcsRUFBRSxpQkFBUyxDQUFDLElBQUksRUFBRSxpQkFBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDOUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBRTlCLE1BQU0sQ0FBQztnQkFDTCxLQUFLLEVBQUUsU0FBUztnQkFDaEIsS0FBSyxFQUFFLENBQUM7YUFDVCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFDRCw2QkFBNkI7SUFDN0IsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQyxFQUFDLENBQUM7QUFDcEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsb0JBQW9CLFNBQWlCLEVBQUUsS0FBcUI7SUFDMUQsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNkLDZDQUE2QztRQUM3QyxFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQVEsQ0FBQyxDQUFDLGlCQUFTLENBQUMsR0FBRyxFQUFFLGlCQUFTLENBQUMsSUFBSSxFQUFFLGlCQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM5RSxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFFOUIsTUFBTSxDQUFDO2dCQUNMLEtBQUssRUFBRSxTQUFTO2dCQUNoQixLQUFLLEVBQUUsQ0FBQzthQUNULENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUNELDZCQUE2QjtJQUM3QixNQUFNLENBQUMsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUM7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbGl0eSBmaWxlcyBmb3IgcHJvZHVjaW5nIFZlZ2EgVmFsdWVSZWYgZm9yIG1hcmtzXG4gKi9cbmltcG9ydCB7Q2hhbm5lbCwgWCwgWDIsIFksIFkyfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHtcbiAgQ2hhbm5lbERlZixcbiAgQ2hhbm5lbERlZldpdGhDb25kaXRpb24sXG4gIGZpZWxkLFxuICBGaWVsZERlZixcbiAgRmllbGRSZWZPcHRpb24sXG4gIGlzRmllbGREZWYsXG4gIGlzVmFsdWVEZWYsXG4gIFRleHRGaWVsZERlZixcbn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbiwgU2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge1N0YWNrUHJvcGVydGllc30gZnJvbSAnLi4vLi4vc3RhY2snO1xuaW1wb3J0IHtjb250YWluc30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnU2lnbmFsUmVmLCBWZ1ZhbHVlUmVmfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge2JpblJlcXVpcmVzUmFuZ2UsIGZvcm1hdFNpZ25hbFJlZn0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7U2NhbGVDb21wb25lbnR9IGZyb20gJy4uL3NjYWxlL2NvbXBvbmVudCc7XG5cblxuLy8gVE9ETzogd2UgbmVlZCB0byBmaW5kIGEgd2F5IHRvIHJlZmFjdG9yIHRoZXNlIHNvIHRoYXQgc2NhbGVOYW1lIGlzIGEgcGFydCBvZiBzY2FsZVxuLy8gYnV0IHRoYXQncyBjb21wbGljYXRlZC4gIEZvciBub3csIHRoaXMgaXMgYSBodWdlIHN0ZXAgbW92aW5nIGZvcndhcmQuXG5cbi8qKlxuICogQHJldHVybiBWZWdhIFZhbHVlUmVmIGZvciBzdGFja2FibGUgeCBvciB5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFja2FibGUoY2hhbm5lbDogJ3gnIHwgJ3knLCBjaGFubmVsRGVmOiBDaGFubmVsRGVmPHN0cmluZz4sIHNjYWxlTmFtZTogc3RyaW5nLCBzY2FsZTogU2NhbGVDb21wb25lbnQsXG4gICAgc3RhY2s6IFN0YWNrUHJvcGVydGllcywgZGVmYXVsdFJlZjogVmdWYWx1ZVJlZiB8ICd6ZXJvT3JNaW4nIHwgJ3plcm9Pck1heCcpOiBWZ1ZhbHVlUmVmIHtcbiAgaWYgKGlzRmllbGREZWYoY2hhbm5lbERlZikgJiYgc3RhY2sgJiYgY2hhbm5lbCA9PT0gc3RhY2suZmllbGRDaGFubmVsKSB7XG4gICAgLy8geCBvciB5IHVzZSBzdGFja19lbmQgc28gdGhhdCBzdGFja2VkIGxpbmUncyBwb2ludCBtYXJrIHVzZSBzdGFja19lbmQgdG9vLlxuICAgIHJldHVybiBmaWVsZFJlZihjaGFubmVsRGVmLCBzY2FsZU5hbWUsIHtzdWZmaXg6ICdlbmQnfSk7XG4gIH1cbiAgcmV0dXJuIG1pZFBvaW50KGNoYW5uZWwsIGNoYW5uZWxEZWYsIHNjYWxlTmFtZSwgc2NhbGUsIHN0YWNrLCBkZWZhdWx0UmVmKTtcbn1cblxuLyoqXG4gKiBAcmV0dXJuIFZlZ2EgVmFsdWVSZWYgZm9yIHN0YWNrYWJsZSB4MiBvciB5MlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhY2thYmxlMihjaGFubmVsOiAneDInIHwgJ3kyJywgYUZpZWxkRGVmOiBDaGFubmVsRGVmPHN0cmluZz4sIGEyZmllbGREZWY6IENoYW5uZWxEZWY8c3RyaW5nPiwgc2NhbGVOYW1lOiBzdHJpbmcsIHNjYWxlOiBTY2FsZUNvbXBvbmVudCxcbiAgICBzdGFjazogU3RhY2tQcm9wZXJ0aWVzLCBkZWZhdWx0UmVmOiBWZ1ZhbHVlUmVmIHwgJ3plcm9Pck1pbicgfCAnemVyb09yTWF4Jyk6IFZnVmFsdWVSZWYge1xuICBpZiAoaXNGaWVsZERlZihhRmllbGREZWYpICYmIHN0YWNrICYmXG4gICAgICAvLyBJZiBmaWVsZENoYW5uZWwgaXMgWCBhbmQgY2hhbm5lbCBpcyBYMiAob3IgWSBhbmQgWTIpXG4gICAgICBjaGFubmVsLmNoYXJBdCgwKSA9PT0gc3RhY2suZmllbGRDaGFubmVsLmNoYXJBdCgwKVxuICAgICAgKSB7XG4gICAgcmV0dXJuIGZpZWxkUmVmKGFGaWVsZERlZiwgc2NhbGVOYW1lLCB7c3VmZml4OiAnc3RhcnQnfSk7XG4gIH1cbiAgcmV0dXJuIG1pZFBvaW50KGNoYW5uZWwsIGEyZmllbGREZWYsIHNjYWxlTmFtZSwgc2NhbGUsIHN0YWNrLCBkZWZhdWx0UmVmKTtcbn1cblxuLyoqXG4gKiBWYWx1ZSBSZWYgZm9yIGJpbm5lZCBmaWVsZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbihmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgc2NhbGVOYW1lOiBzdHJpbmcsIHNpZGU6ICdzdGFydCcgfCAnZW5kJywgb2Zmc2V0PzogbnVtYmVyKSB7XG4gIGNvbnN0IGJpblN1ZmZpeCA9IHNpZGUgPT09ICdzdGFydCcgPyB1bmRlZmluZWQgOiAnZW5kJztcbiAgcmV0dXJuIGZpZWxkUmVmKGZpZWxkRGVmLCBzY2FsZU5hbWUsIHtiaW5TdWZmaXh9LCBvZmZzZXQgPyB7b2Zmc2V0fSA6IHt9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpZWxkUmVmKFxuICAgIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBzY2FsZU5hbWU6IHN0cmluZywgb3B0OiBGaWVsZFJlZk9wdGlvbixcbiAgICBtaXhpbnM/OiB7b2Zmc2V0PzogbnVtYmVyIHwgVmdWYWx1ZVJlZiwgYmFuZD86IG51bWJlcnxib29sZWFufVxuICApOiBWZ1ZhbHVlUmVmIHtcbiAgY29uc3QgcmVmOiBWZ1ZhbHVlUmVmID0ge1xuICAgIHNjYWxlOiBzY2FsZU5hbWUsXG4gICAgZmllbGQ6IGZpZWxkKGZpZWxkRGVmLCBvcHQpLFxuICB9O1xuICBpZiAobWl4aW5zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJlZixcbiAgICAgIC4uLm1peGluc1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIHJlZjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJhbmQoc2NhbGVOYW1lOiBzdHJpbmcsIGJhbmQ6IG51bWJlcnxib29sZWFuID0gdHJ1ZSk6IFZnVmFsdWVSZWYge1xuICByZXR1cm4ge1xuICAgIHNjYWxlOiBzY2FsZU5hbWUsXG4gICAgYmFuZDogYmFuZFxuICB9O1xufVxuXG4vKipcbiAqIFNpZ25hbCB0aGF0IHJldHVybnMgdGhlIG1pZGRsZSBvZiBhIGJpbi4gU2hvdWxkIG9ubHkgYmUgdXNlZCB3aXRoIHggYW5kIHkuXG4gKi9cbmZ1bmN0aW9uIGJpbk1pZFNpZ25hbChmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgc2NhbGVOYW1lOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHtcbiAgICBzaWduYWw6IGAoYCArXG4gICAgICBgc2NhbGUoXCIke3NjYWxlTmFtZX1cIiwgJHtmaWVsZChmaWVsZERlZiwge2V4cHI6ICdkYXR1bSd9KX0pYCArXG4gICAgICBgICsgYCArXG4gICAgICBgc2NhbGUoXCIke3NjYWxlTmFtZX1cIiwgJHtmaWVsZChmaWVsZERlZiwge2JpblN1ZmZpeDogJ2VuZCcsIGV4cHI6ICdkYXR1bSd9KX0pYCtcbiAgICBgKS8yYFxuICB9O1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHtWZ1ZhbHVlUmVmfSBWYWx1ZSBSZWYgZm9yIHhjIC8geWMgb3IgbWlkIHBvaW50IGZvciBvdGhlciBjaGFubmVscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1pZFBvaW50KGNoYW5uZWw6IENoYW5uZWwsIGNoYW5uZWxEZWY6IENoYW5uZWxEZWY8c3RyaW5nPiwgc2NhbGVOYW1lOiBzdHJpbmcsIHNjYWxlOiBTY2FsZUNvbXBvbmVudCwgc3RhY2s6IFN0YWNrUHJvcGVydGllcyxcbiAgZGVmYXVsdFJlZjogVmdWYWx1ZVJlZiB8ICd6ZXJvT3JNaW4nIHwgJ3plcm9Pck1heCcsKTogVmdWYWx1ZVJlZiB7XG4gIC8vIFRPRE86IGRhdHVtIHN1cHBvcnRcblxuICBpZiAoY2hhbm5lbERlZikge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG5cbiAgICBpZiAoaXNGaWVsZERlZihjaGFubmVsRGVmKSkge1xuICAgICAgaWYgKGNoYW5uZWxEZWYuYmluKSB7XG4gICAgICAgIC8vIFVzZSBtaWRkbGUgb25seSBmb3IgeCBhbiB5IHRvIHBsYWNlIG1hcmtzIGluIHRoZSBjZW50ZXIgYmV0d2VlbiBzdGFydCBhbmQgZW5kIG9mIHRoZSBiaW4gcmFuZ2UuXG4gICAgICAgIC8vIFdlIGRvIG5vdCB1c2UgdGhlIG1pZCBwb2ludCBmb3Igb3RoZXIgY2hhbm5lbHMgKGUuZy4gc2l6ZSkgc28gdGhhdCBwcm9wZXJ0aWVzIG9mIGxlZ2VuZHMgYW5kIG1hcmtzIG1hdGNoLlxuICAgICAgICBpZiAoY29udGFpbnMoWyd4JywgJ3knXSwgY2hhbm5lbCkgJiYgY2hhbm5lbERlZi50eXBlID09PSAncXVhbnRpdGF0aXZlJykge1xuICAgICAgICAgIGlmIChzdGFjayAmJiBzdGFjay5pbXB1dGUpIHtcbiAgICAgICAgICAgIC8vIEZvciBzdGFjaywgd2UgY29tcHV0ZWQgYmluX21pZCBzbyB3ZSBjYW4gaW1wdXRlLlxuICAgICAgICAgICAgcmV0dXJuIGZpZWxkUmVmKGNoYW5uZWxEZWYsIHNjYWxlTmFtZSwge2JpblN1ZmZpeDogJ21pZCd9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gRm9yIG5vbi1zdGFjaywgd2UgY2FuIGp1c3QgY2FsY3VsYXRlIGJpbiBtaWQgb24gdGhlIGZseSB1c2luZyBzaWduYWwuXG4gICAgICAgICAgcmV0dXJuIGJpbk1pZFNpZ25hbChjaGFubmVsRGVmLCBzY2FsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWVsZFJlZihjaGFubmVsRGVmLCBzY2FsZU5hbWUsIGJpblJlcXVpcmVzUmFuZ2UoY2hhbm5lbERlZiwgY2hhbm5lbCkgPyB7YmluU3VmZml4OiAncmFuZ2UnfSA6IHt9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2NhbGVUeXBlID0gc2NhbGUuZ2V0KCd0eXBlJyk7XG4gICAgICBpZiAoaGFzRGlzY3JldGVEb21haW4oc2NhbGVUeXBlKSkge1xuICAgICAgICBpZiAoc2NhbGVUeXBlID09PSAnYmFuZCcpIHtcbiAgICAgICAgICAvLyBGb3IgYmFuZCwgdG8gZ2V0IG1pZCBwb2ludCwgbmVlZCB0byBvZmZzZXQgYnkgaGFsZiBvZiB0aGUgYmFuZFxuICAgICAgICAgIHJldHVybiBmaWVsZFJlZihjaGFubmVsRGVmLCBzY2FsZU5hbWUsIHtiaW5TdWZmaXg6ICdyYW5nZSd9LCB7YmFuZDogMC41fSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpZWxkUmVmKGNoYW5uZWxEZWYsIHNjYWxlTmFtZSwge2JpblN1ZmZpeDogJ3JhbmdlJ30pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkUmVmKGNoYW5uZWxEZWYsIHNjYWxlTmFtZSwge30pOyAvLyBubyBuZWVkIGZvciBiaW4gc3VmZml4XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1ZhbHVlRGVmKGNoYW5uZWxEZWYpKSB7XG4gICAgICByZXR1cm4ge3ZhbHVlOiBjaGFubmVsRGVmLnZhbHVlfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBpZiAoZGVmYXVsdFJlZiA9PT0gJ3plcm9Pck1pbicpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChjaGFubmVsID09PSBYIHx8IGNoYW5uZWwgPT09IFgyKSB7XG4gICAgICByZXR1cm4gemVyb09yTWluWChzY2FsZU5hbWUsIHNjYWxlKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWwgPT09IFkgfHwgY2hhbm5lbCA9PT0gWTIpIHtcbiAgICAgIHJldHVybiB6ZXJvT3JNaW5ZKHNjYWxlTmFtZSwgc2NhbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGNoYW5uZWwgJHtjaGFubmVsfSBmb3IgYmFzZSBmdW5jdGlvbmApOyAvLyBGSVhNRSBhZGQgdGhpcyB0byBsb2cubWVzc2FnZVxuICAgIH1cbiAgfSBlbHNlIGlmIChkZWZhdWx0UmVmID09PSAnemVyb09yTWF4Jykge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKGNoYW5uZWwgPT09IFggfHwgY2hhbm5lbCA9PT0gWDIpIHtcbiAgICAgIHJldHVybiB6ZXJvT3JNYXhYKHNjYWxlTmFtZSwgc2NhbGUpO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbCA9PT0gWSB8fCBjaGFubmVsID09PSBZMikge1xuICAgICAgcmV0dXJuIHplcm9Pck1heFkoc2NhbGVOYW1lLCBzY2FsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgY2hhbm5lbCAke2NoYW5uZWx9IGZvciBiYXNlIGZ1bmN0aW9uYCk7IC8vIEZJWE1FIGFkZCB0aGlzIHRvIGxvZy5tZXNzYWdlXG4gICAgfVxuICB9XG4gIHJldHVybiBkZWZhdWx0UmVmO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGV4dCh0ZXh0RGVmOiBDaGFubmVsRGVmV2l0aENvbmRpdGlvbjxUZXh0RmllbGREZWY8c3RyaW5nPj4sIGNvbmZpZzogQ29uZmlnKTogVmdWYWx1ZVJlZiB7XG4gIC8vIHRleHRcbiAgaWYgKHRleHREZWYpIHtcbiAgICBpZiAoaXNGaWVsZERlZih0ZXh0RGVmKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFNpZ25hbFJlZih0ZXh0RGVmLCB0ZXh0RGVmLmZvcm1hdCwgJ2RhdHVtJywgY29uZmlnKTtcbiAgICB9IGVsc2UgaWYgKGlzVmFsdWVEZWYodGV4dERlZikpIHtcbiAgICAgIHJldHVybiB7dmFsdWU6IHRleHREZWYudmFsdWV9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWlkKHNpemVSZWY6IFZnU2lnbmFsUmVmKTogVmdWYWx1ZVJlZiB7XG4gIHJldHVybiB7Li4uc2l6ZVJlZiwgbXVsdDogMC41fTtcbn1cblxuZnVuY3Rpb24gemVyb09yTWluWChzY2FsZU5hbWU6IHN0cmluZywgc2NhbGU6IFNjYWxlQ29tcG9uZW50KTogVmdWYWx1ZVJlZiB7XG4gIGlmIChzY2FsZU5hbWUpIHtcbiAgICAvLyBMb2cgLyBUaW1lIC8gVVRDIHNjYWxlIGRvIG5vdCBzdXBwb3J0IHplcm9cbiAgICBpZiAoIWNvbnRhaW5zKFtTY2FsZVR5cGUuTE9HLCBTY2FsZVR5cGUuVElNRSwgU2NhbGVUeXBlLlVUQ10sIHNjYWxlLmdldCgndHlwZScpKSAmJlxuICAgICAgc2NhbGUuZ2V0KCd6ZXJvJykgIT09IGZhbHNlKSB7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNjYWxlOiBzY2FsZU5hbWUsXG4gICAgICAgIHZhbHVlOiAwXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICAvLyBQdXQgdGhlIG1hcmsgb24gdGhlIHgtYXhpc1xuICByZXR1cm4ge3ZhbHVlOiAwfTtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB7VmdWYWx1ZVJlZn0gYmFzZSB2YWx1ZSBpZiBzY2FsZSBleGlzdHMgYW5kIHJldHVybiBtYXggdmFsdWUgaWYgc2NhbGUgZG9lcyBub3QgZXhpc3RcbiAqL1xuZnVuY3Rpb24gemVyb09yTWF4WChzY2FsZU5hbWU6IHN0cmluZywgc2NhbGU6IFNjYWxlQ29tcG9uZW50KTogVmdWYWx1ZVJlZiB7XG4gIGlmIChzY2FsZU5hbWUpIHtcbiAgICAvLyBMb2cgLyBUaW1lIC8gVVRDIHNjYWxlIGRvIG5vdCBzdXBwb3J0IHplcm9cbiAgICBpZiAoIWNvbnRhaW5zKFtTY2FsZVR5cGUuTE9HLCBTY2FsZVR5cGUuVElNRSwgU2NhbGVUeXBlLlVUQ10sIHNjYWxlLmdldCgndHlwZScpKSAmJlxuICAgICAgc2NhbGUuZ2V0KCd6ZXJvJykgIT09IGZhbHNlKSB7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNjYWxlOiBzY2FsZU5hbWUsXG4gICAgICAgIHZhbHVlOiAwXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICByZXR1cm4ge2ZpZWxkOiB7Z3JvdXA6ICd3aWR0aCd9fTtcbn1cblxuZnVuY3Rpb24gemVyb09yTWluWShzY2FsZU5hbWU6IHN0cmluZywgc2NhbGU6IFNjYWxlQ29tcG9uZW50KTogVmdWYWx1ZVJlZiB7XG4gIGlmIChzY2FsZU5hbWUpIHtcbiAgICAvLyBMb2cgLyBUaW1lIC8gVVRDIHNjYWxlIGRvIG5vdCBzdXBwb3J0IHplcm9cbiAgICBpZiAoIWNvbnRhaW5zKFtTY2FsZVR5cGUuTE9HLCBTY2FsZVR5cGUuVElNRSwgU2NhbGVUeXBlLlVUQ10sIHNjYWxlLmdldCgndHlwZScpKSAmJlxuICAgICAgc2NhbGUuZ2V0KCd6ZXJvJykgIT09IGZhbHNlKSB7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNjYWxlOiBzY2FsZU5hbWUsXG4gICAgICAgIHZhbHVlOiAwXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICAvLyBQdXQgdGhlIG1hcmsgb24gdGhlIHktYXhpc1xuICByZXR1cm4ge2ZpZWxkOiB7Z3JvdXA6ICdoZWlnaHQnfX07XG59XG5cbi8qKlxuICogQHJldHVybnMge1ZnVmFsdWVSZWZ9IGJhc2UgdmFsdWUgaWYgc2NhbGUgZXhpc3RzIGFuZCByZXR1cm4gbWF4IHZhbHVlIGlmIHNjYWxlIGRvZXMgbm90IGV4aXN0XG4gKi9cbmZ1bmN0aW9uIHplcm9Pck1heFkoc2NhbGVOYW1lOiBzdHJpbmcsIHNjYWxlOiBTY2FsZUNvbXBvbmVudCk6IFZnVmFsdWVSZWYge1xuICBpZiAoc2NhbGVOYW1lKSB7XG4gICAgLy8gTG9nIC8gVGltZSAvIFVUQyBzY2FsZSBkbyBub3Qgc3VwcG9ydCB6ZXJvXG4gICAgaWYgKCFjb250YWlucyhbU2NhbGVUeXBlLkxPRywgU2NhbGVUeXBlLlRJTUUsIFNjYWxlVHlwZS5VVENdLCBzY2FsZS5nZXQoJ3R5cGUnKSkgJiZcbiAgICAgIHNjYWxlLmdldCgnemVybycpICE9PSBmYWxzZSkge1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzY2FsZTogc2NhbGVOYW1lLFxuICAgICAgICB2YWx1ZTogMFxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgLy8gUHV0IHRoZSBtYXJrIG9uIHRoZSB5LWF4aXNcbiAgcmV0dXJuIHt2YWx1ZTogMH07XG59XG4iXX0= \ 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..63d4c34a38 --- /dev/null +++ b/build/src/compile/model.d.ts @@ -0,0 +1,154 @@ +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 { Transform } from '../transform'; +import { Dict } from '../util'; +import { VgAxis, VgData, VgEncodeEntry, VgLayout, VgLegend, VgMarkGroup, VgSignal, VgSignalRef, VgTitle } from '../vega.schema'; +import { AxisComponentIndex } from './axis/component'; +import { ConcatModel } from './concat'; +import { DataComponent } from './data/index'; +import { FacetModel } from './facet'; +import { LayerModel } from './layer'; +import { LayoutHeaderComponent } from './layout/header'; +import { LayoutSizeComponent, LayoutSizeIndex } from './layoutsize/component'; +import { LegendComponentIndex } from './legend/component'; +import { RepeatModel } from './repeat'; +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; + 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 { + readonly abstract type: 'unit' | 'facet' | 'layer' | 'concat' | 'repeat'; + readonly parent: Model; + readonly name: string; + readonly title: TitleParams; + readonly description: string; + readonly data: Data; + readonly transforms: Transform[]; + /** Name map for scales, which can be renamed by a model's parent. */ + protected scaleNameMap: NameMapInterface; + /** Name map for size, which can be renamed by a model's parent. */ + protected layoutSizeNameMap: NameMapInterface; + readonly config: Config; + readonly component: Component; + readonly abstract children: Model[]; + constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, resolve: Resolve); + readonly width: VgSignalRef; + readonly height: VgSignalRef; + protected initSize(size: LayoutSizeIndex): void; + parse(): void; + abstract parseData(): void; + abstract parseSelection(): void; + parseScale(): 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; + abstract assembleLayout(): VgLayout; + abstract assembleLayoutSignals(): VgSignal[]; + assembleHeaderMarks(): VgMarkGroup[]; + abstract assembleMarks(): VgMarkGroup[]; + assembleAxes(): VgAxis[]; + assembleLegends(): VgLegend[]; + 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; + /** + * @return scale name for a given channel after the scale has been parsed and named. + */ + scaleName(originalScaleName: Channel | string, 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(varName: 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 */ + field(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..7b5b1209d2 --- /dev/null +++ b/build/src/compile/model.js @@ -0,0 +1,448 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../channel"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var log = require("../log"); +var scale_1 = require("../scale"); +var title_1 = require("../title"); +var transform_1 = require("../transform"); +var util_1 = require("../util"); +var vega_schema_1 = require("../vega.schema"); +var assemble_1 = require("./axis/assemble"); +var header_1 = require("./layout/header"); +var assemble_2 = require("./layoutsize/assemble"); +var assemble_3 = require("./legend/assemble"); +var parse_1 = require("./legend/parse"); +var assemble_4 = require("./scale/assemble"); +var domain_1 = require("./scale/domain"); +var parse_2 = require("./scale/parse"); +var split_1 = require("./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; +}()); +exports.NameMap = 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'; +} +exports.isUnitModel = isUnitModel; +function isFacetModel(model) { + return model && model.type === 'facet'; +} +exports.isFacetModel = isFacetModel; +function isRepeatModel(model) { + return model && model.type === 'repeat'; +} +exports.isRepeatModel = isRepeatModel; +function isConcatModel(model) { + return model && model.type === 'concat'; +} +exports.isConcatModel = isConcatModel; +function isLayerModel(model) { + return model && model.type === 'layer'; +} +exports.isLayerModel = isLayerModel; +var Model = /** @class */ (function () { + function Model(spec, parent, parentGivenName, config, 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; + // If name is not provided, always use parent's givenName to avoid name conflicts. + this.name = spec.name || parentGivenName; + this.title = vega_util_1.isString(spec.title) ? { text: spec.title } : spec.title; + // Shared name maps + this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap(); + this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap(); + this.data = spec.data; + this.description = spec.description; + this.transforms = transform_1.normalizeTransform(spec.transform || []); + this.component = { + data: { + sources: parent ? parent.component.data.sources : {}, + outputNodes: parent ? parent.component.data.outputNodes : {}, + outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {}, + ancestorParse: parent ? __assign({}, parent.component.data.ancestorParse) : {} + }, + layoutSize: new split_1.Split(), + layoutHeaders: { row: {}, column: {} }, + mark: null, + resolve: __assign({ scale: {}, axis: {}, legend: {} }, (resolve || {})), + selection: null, + scales: 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.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections. + 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 () { + parse_2.parseScale(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 () { + parse_1.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.assembleHeaderMarks = function () { + var layoutHeaders = this.component.layoutHeaders; + var headerMarks = []; + for (var _i = 0, HEADER_CHANNELS_1 = header_1.HEADER_CHANNELS; _i < HEADER_CHANNELS_1.length; _i++) { + var channel = HEADER_CHANNELS_1[_i]; + if (layoutHeaders[channel].title) { + headerMarks.push(header_1.getTitleGroup(this, channel)); + } + } + for (var _a = 0, HEADER_CHANNELS_2 = header_1.HEADER_CHANNELS; _a < HEADER_CHANNELS_2.length; _a++) { + var channel = HEADER_CHANNELS_2[_a]; + var layoutHeader = layoutHeaders[channel]; + for (var _b = 0, HEADER_TYPES_1 = header_1.HEADER_TYPES; _b < HEADER_TYPES_1.length; _b++) { + var headerType = HEADER_TYPES_1[_b]; + if (layoutHeader[headerType]) { + for (var _c = 0, _d = layoutHeader[headerType]; _c < _d.length; _c++) { + var header = _d[_c]; + var headerGroup = header_1.getHeaderGroup(this, channel, headerType, layoutHeader, header); + if (headerGroup) { + headerMarks.push(headerGroup); + } + } + } + } + } + return headerMarks; + }; + Model.prototype.assembleAxes = function () { + return assemble_1.assembleAxes(this.component.axes); + }; + Model.prototype.assembleLegends = function () { + return assemble_3.assembleLegends(this); + }; + Model.prototype.assembleTitle = function () { + var title = __assign({}, title_1.extractTitleConfig(this.config.title).nonMark, this.title); + if (title.text) { + if (!util_1.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 util_1.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)) ? assemble_4.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 util_1.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) { + var type = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var scaleName = scaleComponent.get('name'); + var domain = domain_1.assembleDomain(this, channel); + var fieldName = domain_1.getFieldFromDomain(domain); + if (fieldName) { + var fieldRef = fielddef_1.field({ aggregate: 'distinct', field: fieldName }, { expr: 'datum' }); + return { + signal: assemble_2.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); + }; + /** + * @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 + (channel_1.isChannel(originalScaleName) && channel_1.isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) || + // in the scale name map (the the scale get merged by its parent) + this.scaleNameMap.has(this.getName(originalScaleName))) { + return this.scaleNameMap.get(this.getName(originalScaleName)); + } + 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 (varName, origName) { + var sel = this.component.selection[varName]; + if (!sel && this.parent) { + sel = this.parent.getSelectionComponent(varName, origName); + } + if (!sel) { + throw new Error(log.message.selectionNotFound(origName)); + } + return sel; + }; + return Model; +}()); +exports.Model = 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.field = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (!fieldDef) { + return undefined; + } + return fielddef_1.field(fieldDef, opt); + }; + ModelWithField.prototype.reduceFieldDef = function (f, init, t) { + return encoding_1.reduce(this.getMapping(), function (acc, cd, c) { + var fieldDef = fielddef_1.getFieldDef(cd); + if (fieldDef) { + return f(acc, fieldDef, c); + } + return acc; + }, init, t); + }; + ModelWithField.prototype.forEachFieldDef = function (f, t) { + encoding_1.forEach(this.getMapping(), function (cd, c) { + var fieldDef = fielddef_1.getFieldDef(cd); + if (fieldDef) { + f(fieldDef, c); + } + }, t); + }; + return ModelWithField; +}(Model)); +exports.ModelWithField = ModelWithField; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUFtQztBQUVuQyxzQ0FBOEY7QUFHOUYsd0NBQTRDO0FBQzVDLHdDQUFxRjtBQUNyRiw0QkFBOEI7QUFFOUIsa0NBQTJDO0FBRTNDLGtDQUF5RDtBQUN6RCwwQ0FBMkQ7QUFDM0QsZ0NBQXNEO0FBQ3RELDhDQVd3QjtBQUN4Qiw0Q0FBNkM7QUFNN0MsMENBQW9IO0FBQ3BILGtEQUErQztBQUUvQyw4Q0FBa0Q7QUFFbEQsd0NBQTJDO0FBRTNDLDZDQUFnRDtBQUVoRCx5Q0FBa0U7QUFDbEUsdUNBQXlDO0FBRXpDLGlDQUE4QjtBQXdDOUI7SUFHRTtRQUNFLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFTSx3QkFBTSxHQUFiLFVBQWMsT0FBZSxFQUFFLE9BQWU7UUFDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxPQUFPLENBQUM7SUFDbEMsQ0FBQztJQUdNLHFCQUFHLEdBQVYsVUFBVyxJQUFZO1FBQ3JCLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLFNBQVMsQ0FBQztJQUMxQyxDQUFDO0lBRU0scUJBQUcsR0FBVixVQUFXLElBQVk7UUFDckIscUVBQXFFO1FBQ3JFLDZFQUE2RTtRQUM3RSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN6RCxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFDSCxjQUFDO0FBQUQsQ0FBQyxB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ZXNDb250ZW50IjpbImltcG9ydCB7aXNTdHJpbmd9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5cbmltcG9ydCB7Q2hhbm5lbCwgaXNDaGFubmVsLCBpc1NjYWxlQ2hhbm5lbCwgU2NhbGVDaGFubmVsLCBTaW5nbGVEZWZDaGFubmVsfSBmcm9tICcuLi9jaGFubmVsJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHtEYXRhLCBEYXRhU291cmNlVHlwZX0gZnJvbSAnLi4vZGF0YSc7XG5pbXBvcnQge2ZvckVhY2gsIHJlZHVjZX0gZnJvbSAnLi4vZW5jb2RpbmcnO1xuaW1wb3J0IHtDaGFubmVsRGVmLCBmaWVsZCwgRmllbGREZWYsIEZpZWxkUmVmT3B0aW9uLCBnZXRGaWVsZERlZn0gZnJvbSAnLi4vZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL2xvZyc7XG5pbXBvcnQge1Jlc29sdmV9IGZyb20gJy4uL3Jlc29sdmUnO1xuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbn0gZnJvbSAnLi4vc2NhbGUnO1xuaW1wb3J0IHtCYXNlU3BlY30gZnJvbSAnLi4vc3BlYyc7XG5pbXBvcnQge2V4dHJhY3RUaXRsZUNvbmZpZywgVGl0bGVQYXJhbXN9IGZyb20gJy4uL3RpdGxlJztcbmltcG9ydCB7bm9ybWFsaXplVHJhbnNmb3JtLCBUcmFuc2Zvcm19IGZyb20gJy4uL3RyYW5zZm9ybSc7XG5pbXBvcnQge2NvbnRhaW5zLCBEaWN0LCBrZXlzLCB2YXJOYW1lfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7XG4gIGlzVmdSYW5nZVN0ZXAsXG4gIFZnQXhpcyxcbiAgVmdEYXRhLFxuICBWZ0VuY29kZUVudHJ5LFxuICBWZ0xheW91dCxcbiAgVmdMZWdlbmQsXG4gIFZnTWFya0dyb3VwLFxuICBWZ1NpZ25hbCxcbiAgVmdTaWduYWxSZWYsXG4gIFZnVGl0bGUsXG59IGZyb20gJy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7YXNzZW1ibGVBeGVzfSBmcm9tICcuL2F4aXMvYXNzZW1ibGUnO1xuaW1wb3J0IHtBeGlzQ29tcG9uZW50SW5kZXh9IGZyb20gJy4vYXhpcy9jb21wb25lbnQnO1xuaW1wb3J0IHtDb25jYXRNb2RlbH0gZnJvbSAnLi9jb25jYXQnO1xuaW1wb3J0IHtEYXRhQ29tcG9uZW50fSBmcm9tICcuL2RhdGEvaW5kZXgnO1xuaW1wb3J0IHtGYWNldE1vZGVsfSBmcm9tICcuL2ZhY2V0JztcbmltcG9ydCB7TGF5ZXJNb2RlbH0gZnJvbSAnLi9sYXllcic7XG5pbXBvcnQge2dldEhlYWRlckdyb3VwLCBnZXRUaXRsZUdyb3VwLCBIRUFERVJfQ0hBTk5FTFMsIEhFQURFUl9UWVBFUywgTGF5b3V0SGVhZGVyQ29tcG9uZW50fSBmcm9tICcuL2xheW91dC9oZWFkZXInO1xuaW1wb3J0IHtzaXplRXhwcn0gZnJvbSAnLi9sYXlvdXRzaXplL2Fzc2VtYmxlJztcbmltcG9ydCB7TGF5b3V0U2l6ZUNvbXBvbmVudCwgTGF5b3V0U2l6ZUluZGV4fSBmcm9tICcuL2xheW91dHNpemUvY29tcG9uZW50JztcbmltcG9ydCB7YXNzZW1ibGVMZWdlbmRzfSBmcm9tICcuL2xlZ2VuZC9hc3NlbWJsZSc7XG5pbXBvcnQge0xlZ2VuZENvbXBvbmVudEluZGV4fSBmcm9tICcuL2xlZ2VuZC9jb21wb25lbnQnO1xuaW1wb3J0IHtwYXJzZUxlZ2VuZH0gZnJvbSAnLi9sZWdlbmQvcGFyc2UnO1xuaW1wb3J0IHtSZXBlYXRNb2RlbH0gZnJvbSAnLi9yZXBlYXQnO1xuaW1wb3J0IHthc3NlbWJsZVNjYWxlc30gZnJvbSAnLi9zY2FsZS9hc3NlbWJsZSc7XG5pbXBvcnQge1NjYWxlQ29tcG9uZW50LCBTY2FsZUNvbXBvbmVudEluZGV4fSBmcm9tICcuL3NjYWxlL2NvbXBvbmVudCc7XG5pbXBvcnQge2Fzc2VtYmxlRG9tYWluLCBnZXRGaWVsZEZyb21Eb21haW59IGZyb20gJy4vc2NhbGUvZG9tYWluJztcbmltcG9ydCB7cGFyc2VTY2FsZX0gZnJvbSAnLi9zY2FsZS9wYXJzZSc7XG5pbXBvcnQge1NlbGVjdGlvbkNvbXBvbmVudH0gZnJvbSAnLi9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCB7U3BsaXR9IGZyb20gJy4vc3BsaXQnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4vdW5pdCc7XG5cblxuLyoqXG4gKiBDb21wb3NhYmxlIENvbXBvbmVudHMgdGhhdCBhcmUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgb2YgdGhlIHBhcnNpbmcgcGhhc2Ugb2YgdGhlXG4gKiBjb21waWxhdGlvbnMuICBUaGUgY29tcG9uZW50cyByZXByZXNlbnRzIHBhcnRzIG9mIHRoZSBzcGVjaWZpY2F0aW9uIGluIGEgZm9ybSB0aGF0XG4gKiBjYW4gYmUgZWFzaWx5IG1lcmdlZCAoZHVyaW5nIHBhcnNpbmcgZm9yIGNvbXBvc2l0ZSBzcGVjcykuXG4gKiBJbiBhZGRpdGlvbiwgdGhlc2UgY29tcG9uZW50cyBhcmUgZWFzaWx5IHRyYW5zZm9ybWVkIGludG8gVmVnYSBzcGVjaWZpY2F0aW9uc1xuICogZHVyaW5nIHRoZSBcImFzc2VtYmxlXCIgcGhhc2UsIHdoaWNoIGlzIHRoZSBsYXN0IHBoYXNlIG9mIHRoZSBjb21waWxhdGlvbiBzdGVwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudCB7XG4gIGRhdGE6IERhdGFDb21wb25lbnQ7XG5cbiAgbGF5b3V0U2l6ZTogTGF5b3V0U2l6ZUNvbXBvbmVudDtcblxuICBsYXlvdXRIZWFkZXJzOiB7XG4gICAgcm93PzogTGF5b3V0SGVhZGVyQ29tcG9uZW50LFxuICAgIGNvbHVtbj86IExheW91dEhlYWRlckNvbXBvbmVudFxuICB9O1xuXG4gIG1hcms6IFZnTWFya0dyb3VwW107XG4gIHNjYWxlczogU2NhbGVDb21wb25lbnRJbmRleDtcbiAgc2VsZWN0aW9uOiBEaWN0PFNlbGVjdGlvbkNvbXBvbmVudD47XG5cbiAgLyoqIERpY3Rpb25hcnkgbWFwcGluZyBjaGFubmVsIHRvIFZnQXhpcyBkZWZpbml0aW9uICovXG4gIGF4ZXM6IEF4aXNDb21wb25lbnRJbmRleDtcblxuICAvKiogRGljdGlvbmFyeSBtYXBwaW5nIGNoYW5uZWwgdG8gVmdMZWdlbmQgZGVmaW5pdGlvbiAqL1xuICBsZWdlbmRzOiBMZWdlbmRDb21wb25lbnRJbmRleDtcblxuICByZXNvbHZlOiBSZXNvbHZlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5hbWVNYXBJbnRlcmZhY2Uge1xuICByZW5hbWUob2xkbmFtZTogc3RyaW5nLCBuZXdOYW1lOiBzdHJpbmcpOiB2b2lkO1xuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbjtcbiAgZ2V0KG5hbWU6IHN0cmluZyk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIE5hbWVNYXAgaW1wbGVtZW50cyBOYW1lTWFwSW50ZXJmYWNlIHtcbiAgcHJpdmF0ZSBuYW1lTWFwOiBEaWN0PHN0cmluZz47XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5uYW1lTWFwID0ge307XG4gIH1cblxuICBwdWJsaWMgcmVuYW1lKG9sZE5hbWU6IHN0cmluZywgbmV3TmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5uYW1lTWFwW29sZE5hbWVdID0gbmV3TmFtZTtcbiAgfVxuXG5cbiAgcHVibGljIGhhcyhuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uYW1lTWFwW25hbWVdICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0KG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8gSWYgdGhlIG5hbWUgYXBwZWFycyBpbiB0aGUgX25hbWVNYXAsIHdlIG5lZWQgdG8gcmVhZCBpdHMgbmV3IG5hbWUuXG4gICAgLy8gV2UgaGF2ZSB0byBsb29wIG92ZXIgdGhlIGRpY3QganVzdCBpbiBjYXNlIHRoZSBuZXcgbmFtZSBhbHNvIGdldHMgcmVuYW1lZC5cbiAgICB3aGlsZSAodGhpcy5uYW1lTWFwW25hbWVdICYmIG5hbWUgIT09IHRoaXMubmFtZU1hcFtuYW1lXSkge1xuICAgICAgbmFtZSA9IHRoaXMubmFtZU1hcFtuYW1lXTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmFtZTtcbiAgfVxufVxuXG4vKlxuICBXZSB1c2UgdHlwZSBndWFyZHMgaW5zdGVhZCBvZiBgaW5zdGFuY2VvZmAgYXMgYGluc3RhbmNlb2ZgIG1ha2VzXG4gIGRpZmZlcmVudCBwYXJ0cyBvZiB0aGUgY29tcGlsZXIgZGVwZW5kIG9uIHRoZSBhY3R1YWwgaW1wbGVtZW50YXRpb24gb2ZcbiAgdGhlIG1vZGVsIGNsYXNzZXMsIHdoaWNoIGluIHR1cm4gZGVwZW5kIG9uIGRpZmZlcmVudCBwYXJ0cyBvZiB0aGUgY29tcGlsZXIuXG4gIFRodXMsIGBpbnN0YW5jZW9mYCBsZWFkcyB0byBjaXJjdWxhciBkZXBlbmRlbmN5IHByb2JsZW1zLlxuXG4gIE9uIHRoZSBvdGhlciBoYW5kLCB0eXBlIGd1YXJkcyBvbmx5IG1ha2UgZGlmZmVyZW50IHBhcnRzIG9mIHRoZSBjb21waWxlclxuICBkZXBlbmQgb24gdGhlIHR5cGUgb2YgdGhlIG1vZGVsIGNsYXNzZXMsIGJ1dCBub3QgdGhlIGFjdHVhbCBpbXBsZW1lbnRhdGlvbi5cbiovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1VuaXRNb2RlbChtb2RlbDogTW9kZWwpOiBtb2RlbCBpcyBVbml0TW9kZWwge1xuICByZXR1cm4gbW9kZWwgJiYgbW9kZWwudHlwZSA9PT0gJ3VuaXQnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNGYWNldE1vZGVsKG1vZGVsOiBNb2RlbCk6IG1vZGVsIGlzIEZhY2V0TW9kZWwge1xuICByZXR1cm4gbW9kZWwgJiYgbW9kZWwudHlwZSA9PT0gJ2ZhY2V0Jztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUmVwZWF0TW9kZWwobW9kZWw6IE1vZGVsKTogbW9kZWwgaXMgUmVwZWF0TW9kZWwge1xuICByZXR1cm4gbW9kZWwgJiYgbW9kZWwudHlwZSA9PT0gJ3JlcGVhdCc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbmNhdE1vZGVsKG1vZGVsOiBNb2RlbCk6IG1vZGVsIGlzIENvbmNhdE1vZGVsIHtcbiAgcmV0dXJuIG1vZGVsICYmIG1vZGVsLnR5cGUgPT09ICdjb25jYXQnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNMYXllck1vZGVsKG1vZGVsOiBNb2RlbCk6IG1vZGVsIGlzIExheWVyTW9kZWwge1xuICByZXR1cm4gbW9kZWwgJiYgbW9kZWwudHlwZSA9PT0gJ2xheWVyJztcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE1vZGVsIHtcblxuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgdHlwZTogJ3VuaXQnIHwgJ2ZhY2V0JyB8ICdsYXllcicgfCAnY29uY2F0JyB8ICdyZXBlYXQnO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFyZW50OiBNb2RlbDtcbiAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IFRpdGxlUGFyYW1zO1xuICBwdWJsaWMgcmVhZG9ubHkgZGVzY3JpcHRpb246IHN0cmluZztcblxuICBwdWJsaWMgcmVhZG9ubHkgZGF0YTogRGF0YTtcbiAgcHVibGljIHJlYWRvbmx5IHRyYW5zZm9ybXM6IFRyYW5zZm9ybVtdO1xuXG4gIC8qKiBOYW1lIG1hcCBmb3Igc2NhbGVzLCB3aGljaCBjYW4gYmUgcmVuYW1lZCBieSBhIG1vZGVsJ3MgcGFyZW50LiAqL1xuICBwcm90ZWN0ZWQgc2NhbGVOYW1lTWFwOiBOYW1lTWFwSW50ZXJmYWNlO1xuXG4gIC8qKiBOYW1lIG1hcCBmb3Igc2l6ZSwgd2hpY2ggY2FuIGJlIHJlbmFtZWQgYnkgYSBtb2RlbCdzIHBhcmVudC4gKi9cbiAgcHJvdGVjdGVkIGxheW91dFNpemVOYW1lTWFwOiBOYW1lTWFwSW50ZXJmYWNlO1xuXG5cbiAgcHVibGljIHJlYWRvbmx5IGNvbmZpZzogQ29uZmlnO1xuXG4gIHB1YmxpYyByZWFkb25seSBjb21wb25lbnQ6IENvbXBvbmVudDtcblxuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgY2hpbGRyZW46IE1vZGVsW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihzcGVjOiBCYXNlU3BlYywgcGFyZW50OiBNb2RlbCwgcGFyZW50R2l2ZW5OYW1lOiBzdHJpbmcsIGNvbmZpZzogQ29uZmlnLCByZXNvbHZlOiBSZXNvbHZlKSB7XG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG5cbiAgICAvLyBJZiBuYW1lIGlzIG5vdCBwcm92aWRlZCwgYWx3YXlzIHVzZSBwYXJlbnQncyBnaXZlbk5hbWUgdG8gYXZvaWQgbmFtZSBjb25mbGljdHMuXG4gICAgdGhpcy5uYW1lID0gc3BlYy5uYW1lIHx8IHBhcmVudEdpdmVuTmFtZTtcbiAgICB0aGlzLnRpdGxlID0gaXNTdHJpbmcoc3BlYy50aXRsZSkgPyB7dGV4dDogc3BlYy50aXRsZX0gOiBzcGVjLnRpdGxlO1xuXG4gICAgLy8gU2hhcmVkIG5hbWUgbWFwc1xuICAgIHRoaXMuc2NhbGVOYW1lTWFwID0gcGFyZW50ID8gcGFyZW50LnNjYWxlTmFtZU1hcCA6IG5ldyBOYW1lTWFwKCk7XG4gICAgdGhpcy5sYXlvdXRTaXplTmFtZU1hcCA9IHBhcmVudCA/IHBhcmVudC5sYXlvdXRTaXplTmFtZU1hcCA6IG5ldyBOYW1lTWFwKCk7XG5cbiAgICB0aGlzLmRhdGEgPSBzcGVjLmRhdGE7XG5cbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gc3BlYy5kZXNjcmlwdGlvbjtcbiAgICB0aGlzLnRyYW5zZm9ybXMgPSBub3JtYWxpemVUcmFuc2Zvcm0oc3BlYy50cmFuc2Zvcm0gfHwgW10pO1xuXG4gICAgdGhpcy5jb21wb25lbnQgPSB7XG4gICAgICBkYXRhOiB7XG4gICAgICAgIHNvdXJjZXM6IHBhcmVudCA/IHBhcmVudC5jb21wb25lbnQuZGF0YS5zb3VyY2VzIDoge30sXG4gICAgICAgIG91dHB1dE5vZGVzOiBwYXJlbnQgPyBwYXJlbnQuY29tcG9uZW50LmRhdGEub3V0cHV0Tm9kZXMgOiB7fSxcbiAgICAgICAgb3V0cHV0Tm9kZVJlZkNvdW50czogcGFyZW50ID8gcGFyZW50LmNvbXBvbmVudC5kYXRhLm91dHB1dE5vZGVSZWZDb3VudHMgOiB7fSxcbiAgICAgICAgYW5jZXN0b3JQYXJzZTogcGFyZW50ID8gey4uLnBhcmVudC5jb21wb25lbnQuZGF0YS5hbmNlc3RvclBhcnNlfSA6IHt9XG4gICAgICB9LFxuICAgICAgbGF5b3V0U2l6ZTogbmV3IFNwbGl0PExheW91dFNpemVJbmRleD4oKSxcbiAgICAgIGxheW91dEhlYWRlcnM6e3Jvdzoge30sIGNvbHVtbjoge319LFxuICAgICAgbWFyazogbnVsbCxcbiAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgc2NhbGU6IHt9LCBheGlzOiB7fSwgbGVnZW5kOiB7fSxcbiAgICAgICAgLi4uKHJlc29sdmUgfHwge30pXG4gICAgICB9LFxuICAgICAgc2VsZWN0aW9uOiBudWxsLFxuICAgICAgc2NhbGVzOiBudWxsLFxuICAgICAgYXhlczoge30sXG4gICAgICBsZWdlbmRzOiB7fSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGdldCB3aWR0aCgpOiBWZ1NpZ25hbFJlZiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U2l6ZVNpZ25hbFJlZignd2lkdGgnKTtcbiAgfVxuXG5cbiAgcHVibGljIGdldCBoZWlnaHQoKTogVmdTaWduYWxSZWYge1xuICAgIHJldHVybiB0aGlzLmdldFNpemVTaWduYWxSZWYoJ2hlaWdodCcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGluaXRTaXplKHNpemU6IExheW91dFNpemVJbmRleCkge1xuICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHNpemU7XG4gICAgaWYgKHdpZHRoKSB7XG4gICAgICB0aGlzLmNvbXBvbmVudC5sYXlvdXRTaXplLnNldCgnd2lkdGgnLCB3aWR0aCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgaWYgKGhlaWdodCkge1xuICAgICAgdGhpcy5jb21wb25lbnQubGF5b3V0U2l6ZS5zZXQoJ2hlaWdodCcsIGhlaWdodCwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBhcnNlKCkge1xuICAgIHRoaXMucGFyc2VTY2FsZSgpO1xuXG4gICAgdGhpcy5wYXJzZUxheW91dFNpemUoKTsgLy8gZGVwZW5kcyBvbiBzY2FsZVxuICAgIHRoaXMucmVuYW1lVG9wTGV2ZWxMYXlvdXRTaXplKCk7XG5cbiAgICB0aGlzLnBhcnNlU2VsZWN0aW9uKCk7XG4gICAgdGhpcy5wYXJzZURhdGEoKTsgLy8gKHBhdGhvcmRlcikgZGVwZW5kcyBvbiBtYXJrRGVmOyBzZWxlY3Rpb24gZmlsdGVycyBkZXBlbmQgb24gcGFyc2VkIHNlbGVjdGlvbnMuXG4gICAgdGhpcy5wYXJzZUF4aXNBbmRIZWFkZXIoKTsgLy8gZGVwZW5kcyBvbiBzY2FsZSBhbmQgbGF5b3V0IHNpemVcbiAgICB0aGlzLnBhcnNlTGVnZW5kKCk7IC8vIGRlcGVuZHMgb24gc2NhbGUsIG1hcmtEZWZcbiAgICB0aGlzLnBhcnNlTWFya0dyb3VwKCk7IC8vIGRlcGVuZHMgb24gZGF0YSBuYW1lLCBzY2FsZSwgbGF5b3V0IHNpemUsIGF4aXNHcm91cCwgYW5kIGNoaWxkcmVuJ3Mgc2NhbGUsIGF4aXMsIGxlZ2VuZCBhbmQgbWFyay5cbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBwYXJzZURhdGEoKTogdm9pZDtcblxuICBwdWJsaWMgYWJzdHJhY3QgcGFyc2VTZWxlY3Rpb24oKTogdm9pZDtcblxuXG4gIHB1YmxpYyBwYXJzZVNjYWxlKCkge1xuICAgIHBhcnNlU2NhbGUodGhpcyk7XG4gIH1cblxuICBwdWJsaWMgYWJzdHJhY3QgcGFyc2VMYXlvdXRTaXplKCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlbmFtZSB0b3AtbGV2ZWwgc3BlYydzIHNpemUgdG8gYmUganVzdCB3aWR0aCAvIGhlaWdodCwgaWdub3JpbmcgbW9kZWwgbmFtZS5cbiAgICogVGhpcyBlc3NlbnRpYWxseSBtZXJnZXMgdGhlIHRvcC1sZXZlbCBzcGVjJ3Mgd2lkdGgvaGVpZ2h0IHNpZ25hbHMgd2l0aCB0aGUgd2lkdGgvaGVpZ2h0IHNpZ25hbHNcbiAgICogdG8gaGVscCB1cyByZWR1Y2UgcmVkdW5kYW50IHNpZ25hbHMgZGVjbGFyYXRpb24uXG4gICAqL1xuICBwcml2YXRlIHJlbmFtZVRvcExldmVsTGF5b3V0U2l6ZSgpIHtcbiAgICBpZiAodGhpcy5nZXROYW1lKCd3aWR0aCcpICE9PSAnd2lkdGgnKSB7XG4gICAgICB0aGlzLnJlbmFtZUxheW91dFNpemUodGhpcy5nZXROYW1lKCd3aWR0aCcpLCAnd2lkdGgnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZ2V0TmFtZSgnaGVpZ2h0JykgIT09ICdoZWlnaHQnKSB7XG4gICAgICB0aGlzLnJlbmFtZUxheW91dFNpemUodGhpcy5nZXROYW1lKCdoZWlnaHQnKSwgJ2hlaWdodCcpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBwYXJzZU1hcmtHcm91cCgpOiB2b2lkO1xuXG4gIHB1YmxpYyBhYnN0cmFjdCBwYXJzZUF4aXNBbmRIZWFkZXIoKTogdm9pZDtcblxuICBwdWJsaWMgcGFyc2VMZWdlbmQoKSB7XG4gICAgcGFyc2VMZWdlbmQodGhpcyk7XG4gIH1cblxuICBwdWJsaWMgYWJzdHJhY3QgYXNzZW1ibGVTZWxlY3Rpb25Ub3BMZXZlbFNpZ25hbHMoc2lnbmFsczogYW55W10pOiBhbnlbXTtcbiAgcHVibGljIGFic3RyYWN0IGFzc2VtYmxlU2VsZWN0aW9uU2lnbmFscygpOiBhbnlbXTtcblxuICBwdWJsaWMgYWJzdHJhY3QgYXNzZW1ibGVTZWxlY3Rpb25EYXRhKGRhdGE6IFZnRGF0YVtdKTogVmdEYXRhW107XG5cbiAgcHVibGljIGFzc2VtYmxlR3JvdXBTdHlsZSgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnR5cGUgPT09ICd1bml0JyB8fCB0aGlzLnR5cGUgPT09ICdsYXllcicpIHtcbiAgICAgIHJldHVybiAnY2VsbCc7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVMYXlvdXRTaXplKCk6IFZnRW5jb2RlRW50cnkge1xuICAgIGlmICh0aGlzLnR5cGUgPT09ICd1bml0JyB8fCB0aGlzLnR5cGUgPT09ICdsYXllcicpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoOiB0aGlzLmdldFNpemVTaWduYWxSZWYoJ3dpZHRoJyksXG4gICAgICAgIGhlaWdodDogdGhpcy5nZXRTaXplU2lnbmFsUmVmKCdoZWlnaHQnKVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBhc3NlbWJsZUxheW91dCgpOiBWZ0xheW91dDtcblxuICBwdWJsaWMgYWJzdHJhY3QgYXNzZW1ibGVMYXlvdXRTaWduYWxzKCk6IFZnU2lnbmFsW107XG5cbiAgcHVibGljIGFzc2VtYmxlSGVhZGVyTWFya3MoKTogVmdNYXJrR3JvdXBbXSB7XG4gICAgY29uc3Qge2xheW91dEhlYWRlcnN9ID0gdGhpcy5jb21wb25lbnQ7XG4gICAgY29uc3QgaGVhZGVyTWFya3MgPSBbXTtcblxuICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBIRUFERVJfQ0hBTk5FTFMpIHtcbiAgICAgIGlmIChsYXlvdXRIZWFkZXJzW2NoYW5uZWxdLnRpdGxlKSB7XG4gICAgICAgIGhlYWRlck1hcmtzLnB1c2goZ2V0VGl0bGVHcm91cCh0aGlzLCBjaGFubmVsKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjaGFubmVsIG9mIEhFQURFUl9DSEFOTkVMUykge1xuICAgICAgY29uc3QgbGF5b3V0SGVhZGVyID0gbGF5b3V0SGVhZGVyc1tjaGFubmVsXTtcbiAgICAgIGZvciAoY29uc3QgaGVhZGVyVHlwZSBvZiBIRUFERVJfVFlQRVMpIHtcbiAgICAgICAgaWYgKGxheW91dEhlYWRlcltoZWFkZXJUeXBlXSkge1xuICAgICAgICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIGxheW91dEhlYWRlcltoZWFkZXJUeXBlXSkge1xuICAgICAgICAgICAgY29uc3QgaGVhZGVyR3JvdXAgPSBnZXRIZWFkZXJHcm91cCh0aGlzLCBjaGFubmVsLCBoZWFkZXJUeXBlLCBsYXlvdXRIZWFkZXIsIGhlYWRlcik7XG4gICAgICAgICAgICBpZiAoaGVhZGVyR3JvdXApIHtcbiAgICAgICAgICAgICAgaGVhZGVyTWFya3MucHVzaChoZWFkZXJHcm91cCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoZWFkZXJNYXJrcztcbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBhc3NlbWJsZU1hcmtzKCk6IFZnTWFya0dyb3VwW107IC8vIFRPRE86IFZnTWFya0dyb3VwW11cblxuICBwdWJsaWMgYXNzZW1ibGVBeGVzKCk6IFZnQXhpc1tdIHtcbiAgICByZXR1cm4gYXNzZW1ibGVBeGVzKHRoaXMuY29tcG9uZW50LmF4ZXMpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTGVnZW5kcygpOiBWZ0xlZ2VuZFtdIHtcbiAgICByZXR1cm4gYXNzZW1ibGVMZWdlbmRzKHRoaXMpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlVGl0bGUoKTogVmdUaXRsZSB7XG4gICAgY29uc3QgdGl0bGU6IFZnVGl0bGUgPSB7XG4gICAgICAuLi5leHRyYWN0VGl0bGVDb25maWcodGhpcy5jb25maWcudGl0bGUpLm5vbk1hcmssXG4gICAgICAuLi50aGlzLnRpdGxlXG4gICAgfTtcblxuICAgIGlmICh0aXRsZS50ZXh0KSB7XG4gICAgICBpZiAoIWNvbnRhaW5zKFsndW5pdCcsICdsYXllciddLCB0aGlzLnR5cGUpKSB7XG4gICAgICAgIC8vIEFzIGRlc2NyaWJlZCBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzI4NzU6XG4gICAgICAgIC8vIER1ZSB0byB2ZWdhL3ZlZ2EjOTYwIChjb21tZW50KSwgd2Ugb25seSBzdXBwb3J0IHRpdGxlJ3MgYW5jaG9yIGZvciB1bml0IGFuZCBsYXllcmVkIHNwZWMgZm9yIG5vdy5cblxuICAgICAgICBpZiAodGl0bGUuYW5jaG9yICYmIHRpdGxlLmFuY2hvciAhPT0gJ3N0YXJ0Jykge1xuICAgICAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmNhbm5vdFNldFRpdGxlQW5jaG9yKHRoaXMudHlwZSkpO1xuICAgICAgICB9XG4gICAgICAgIHRpdGxlLmFuY2hvciA9ICdzdGFydCc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBrZXlzKHRpdGxlKS5sZW5ndGggPiAwID8gdGl0bGUgOiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQXNzZW1ibGUgdGhlIG1hcmsgZ3JvdXAgZm9yIHRoaXMgbW9kZWwuICBXZSBhY2NlcHQgb3B0aW9uYWwgYHNpZ25hbHNgIHNvIHRoYXQgd2UgY2FuIGluY2x1ZGUgY29uY2F0IHRvcC1sZXZlbCBzaWduYWxzIHdpdGggdGhlIHRvcC1sZXZlbCBtb2RlbCdzIGxvY2FsIHNpZ25hbHMuXG4gICAqL1xuICBwdWJsaWMgYXNzZW1ibGVHcm91cChzaWduYWxzOiBWZ1NpZ25hbFtdID0gW10pIHtcbiAgICBjb25zdCBncm91cDogVmdNYXJrR3JvdXAgPSB7fTtcblxuICAgIHNpZ25hbHMgPSBzaWduYWxzLmNvbmNhdCh0aGlzLmFzc2VtYmxlU2VsZWN0aW9uU2lnbmFscygpKTtcblxuICAgIGlmIChzaWduYWxzLmxlbmd0aCA+IDApIHtcbiAgICAgIGdyb3VwLnNpZ25hbHMgPSBzaWduYWxzO1xuICAgIH1cblxuICAgIGNvbnN0IGxheW91dCA9IHRoaXMuYXNzZW1ibGVMYXlvdXQoKTtcbiAgICBpZiAobGF5b3V0KSB7XG4gICAgICBncm91cC5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgfVxuXG4gICAgZ3JvdXAubWFya3MgPSBbXS5jb25jYXQoXG4gICAgICB0aGlzLmFzc2VtYmxlSGVhZGVyTWFya3MoKSxcbiAgICAgIHRoaXMuYXNzZW1ibGVNYXJrcygpXG4gICAgKTtcblxuICAgIC8vIE9ubHkgaW5jbHVkZSBzY2FsZXMgaWYgdGhpcyBzcGVjIGlzIHRvcC1sZXZlbCBvciBpZiBwYXJlbnQgaXMgZmFjZXQuXG4gICAgLy8gKE90aGVyd2lzZSwgaXQgd2lsbCBiZSBtZXJnZWQgd2l0aCB1cHBlci1sZXZlbCdzIHNjb3BlLilcbiAgICBjb25zdCBzY2FsZXMgPSAoIXRoaXMucGFyZW50IHx8IGlzRmFjZXRNb2RlbCh0aGlzLnBhcmVudCkpID8gYXNzZW1ibGVTY2FsZXModGhpcykgOiBbXTtcbiAgICBpZiAoc2NhbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGdyb3VwLnNjYWxlcyA9IHNjYWxlcztcbiAgICB9XG5cbiAgICBjb25zdCBheGVzID0gdGhpcy5hc3NlbWJsZUF4ZXMoKTtcbiAgICBpZiAoYXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICBncm91cC5heGVzID0gYXhlcztcbiAgICB9XG5cbiAgICBjb25zdCBsZWdlbmRzID0gdGhpcy5hc3NlbWJsZUxlZ2VuZHMoKTtcbiAgICBpZiAobGVnZW5kcy5sZW5ndGggPiAwKSB7XG4gICAgICBncm91cC5sZWdlbmRzID0gbGVnZW5kcztcbiAgICB9XG5cbiAgICByZXR1cm4gZ3JvdXA7XG4gIH1cblxuICBwdWJsaWMgaGFzRGVzY2VuZGFudFdpdGhGaWVsZE9uQ2hhbm5lbChjaGFubmVsOiBDaGFubmVsKSB7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiB0aGlzLmNoaWxkcmVuKSB7XG4gICAgICBpZiAoaXNVbml0TW9kZWwoY2hpbGQpKSB7XG4gICAgICAgIGlmIChjaGlsZC5jaGFubmVsSGFzRmllbGQoY2hhbm5lbCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNoaWxkLmhhc0Rlc2NlbmRhbnRXaXRoRmllbGRPbkNoYW5uZWwoY2hhbm5lbCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgZ2V0TmFtZSh0ZXh0OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdmFyTmFtZSgodGhpcy5uYW1lID8gdGhpcy5uYW1lICsgJ18nIDogJycpICsgdGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWVzdCBhIGRhdGEgc291cmNlIG5hbWUgZm9yIHRoZSBnaXZlbiBkYXRhIHNvdXJjZSB0eXBlIGFuZCBtYXJrIHRoYXQgZGF0YSBzb3VyY2UgYXMgcmVxdWlyZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgaW4gcGFyc2UsIHNvIHRoYXQgYWxsIHVzZWQgZGF0YSBzb3VyY2UgY2FuIGJlIGNvcnJlY3RseSBpbnN0YW50aWF0ZWQgaW4gYXNzZW1ibGVEYXRhKCkuXG4gICAqL1xuICBwdWJsaWMgcmVxdWVzdERhdGFOYW1lKG5hbWU6IERhdGFTb3VyY2VUeXBlKSB7XG4gICAgY29uc3QgZnVsbE5hbWUgPSB0aGlzLmdldE5hbWUobmFtZSk7XG5cbiAgICAvLyBJbmNyZWFzZSByZWYgY291bnQuIFRoaXMgaXMgY3JpdGljYWwgYmVjYXVzZSBvdGhlcndpc2Ugd2Ugd29uJ3QgY3JlYXRlIGEgZGF0YSBzb3VyY2UuXG4gICAgLy8gV2UgYWxzbyBpbmNyZWFzZSB0aGUgcmVmIGNvdW50cyBvbiBPdXRwdXROb2RlLmdldFNvdXJjZSgpIGNhbGxzLlxuICAgIGNvbnN0IHJlZkNvdW50cyA9IHRoaXMuY29tcG9uZW50LmRhdGEub3V0cHV0Tm9kZVJlZkNvdW50cztcbiAgICByZWZDb3VudHNbZnVsbE5hbWVdID0gKHJlZkNvdW50c1tmdWxsTmFtZV0gfHwgMCkgKyAxO1xuXG4gICAgcmV0dXJuIGZ1bGxOYW1lO1xuICB9XG5cbiAgcHVibGljIGdldFNpemVTaWduYWxSZWYoc2l6ZVR5cGU6ICd3aWR0aCcgfCAnaGVpZ2h0Jyk6IFZnU2lnbmFsUmVmIHtcbiAgICBpZiAoaXNGYWNldE1vZGVsKHRoaXMucGFyZW50KSkge1xuICAgICAgY29uc3QgY2hhbm5lbCA9IHNpemVUeXBlID09PSAnd2lkdGgnID8gJ3gnIDogJ3knO1xuICAgICAgY29uc3Qgc2NhbGVDb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudC5zY2FsZXNbY2hhbm5lbF07XG5cbiAgICAgIGlmIChzY2FsZUNvbXBvbmVudCAmJiAhc2NhbGVDb21wb25lbnQubWVyZ2VkKSB7IC8vIGluZGVwZW5kZW50IHNjYWxlXG4gICAgICAgIGNvbnN0IHR5cGUgPSBzY2FsZUNvbXBvbmVudC5nZXQoJ3R5cGUnKTtcbiAgICAgICAgY29uc3QgcmFuZ2UgPSBzY2FsZUNvbXBvbmVudC5nZXQoJ3JhbmdlJyk7XG5cbiAgICAgICAgaWYgKGhhc0Rpc2NyZXRlRG9tYWluKHR5cGUpICYmIGlzVmdSYW5nZVN0ZXAocmFuZ2UpKSB7XG4gICAgICAgICAgY29uc3Qgc2NhbGVOYW1lID0gc2NhbGVDb21wb25lbnQuZ2V0KCduYW1lJyk7XG4gICAgICAgICAgY29uc3QgZG9tYWluID0gYXNzZW1ibGVEb21haW4odGhpcywgY2hhbm5lbCk7XG4gICAgICAgICAgY29uc3QgZmllbGROYW1lID0gZ2V0RmllbGRGcm9tRG9tYWluKGRvbWFpbik7XG4gICAgICAgICAgaWYgKGZpZWxkTmFtZSkge1xuICAgICAgICAgICAgY29uc3QgZmllbGRSZWYgPSBmaWVsZCh7YWdncmVnYXRlOiAnZGlzdGluY3QnLCBmaWVsZDogZmllbGROYW1lfSwge2V4cHI6ICdkYXR1bSd9KTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHNpZ25hbDogc2l6ZUV4cHIoc2NhbGVOYW1lLCBzY2FsZUNvbXBvbmVudCwgZmllbGRSZWYpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2cud2FybignVW5rbm93biBmaWVsZCBmb3IgJHtjaGFubmVsfS4gIENhbm5vdCBjYWxjdWxhdGUgdmlldyBzaXplLicpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc2lnbmFsOiB0aGlzLmxheW91dFNpemVOYW1lTWFwLmdldCh0aGlzLmdldE5hbWUoc2l6ZVR5cGUpKVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTG9va3VwIHRoZSBuYW1lIG9mIHRoZSBkYXRhc291cmNlIGZvciBhbiBvdXRwdXQgbm9kZS4gWW91IHByb2JhYmx5IHdhbnQgdG8gY2FsbCB0aGlzIGluIGFzc2VtYmxlLlxuICAgKi9cbiAgcHVibGljIGxvb2t1cERhdGFTb3VyY2UobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuY29tcG9uZW50LmRhdGEub3V0cHV0Tm9kZXNbbmFtZV07XG5cbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIC8vIE5hbWUgbm90IGZvdW5kIGluIG1hcCBzbyBsZXQncyBqdXN0IHJldHVybiB3aGF0IHdlIGdvdC5cbiAgICAgIC8vIFRoaXMgY2FuIGhhcHBlbiBpZiB3ZSBhbHJlYWR5IGhhdmUgdGhlIGNvcnJlY3QgbmFtZS5cbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cblxuICAgIHJldHVybiBub2RlLmdldFNvdXJjZSgpO1xuICB9XG5cbiAgcHVibGljIGdldFNpemVOYW1lKG9sZFNpemVOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICByZXR1cm4gdGhpcy5sYXlvdXRTaXplTmFtZU1hcC5nZXQob2xkU2l6ZU5hbWUpO1xuICB9XG5cbiAgcHVibGljIHJlbmFtZUxheW91dFNpemUob2xkTmFtZTogc3RyaW5nLCBuZXdOYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLmxheW91dFNpemVOYW1lTWFwLnJlbmFtZShvbGROYW1lLCBuZXdOYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyByZW5hbWVTY2FsZShvbGROYW1lOiBzdHJpbmcsIG5ld05hbWU6IHN0cmluZykge1xuICAgIHRoaXMuc2NhbGVOYW1lTWFwLnJlbmFtZShvbGROYW1lLCBuZXdOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHNjYWxlIG5hbWUgZm9yIGEgZ2l2ZW4gY2hhbm5lbCBhZnRlciB0aGUgc2NhbGUgaGFzIGJlZW4gcGFyc2VkIGFuZCBuYW1lZC5cbiAgICovXG4gIHB1YmxpYyBzY2FsZU5hbWUob3JpZ2luYWxTY2FsZU5hbWU6IENoYW5uZWwgfCBzdHJpbmcsIHBhcnNlPzogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgaWYgKHBhcnNlKSB7XG4gICAgICAvLyBEdXJpbmcgdGhlIHBhcnNlIHBoYXNlIGFsd2F5cyByZXR1cm4gYSB2YWx1ZVxuICAgICAgLy8gTm8gbmVlZCB0byByZWZlciB0byByZW5hbWUgbWFwIGJlY2F1c2UgYSBzY2FsZSBjYW4ndCBiZSByZW5hbWVkXG4gICAgICAvLyBiZWZvcmUgaXQgaGFzIHRoZSBvcmlnaW5hbCBuYW1lLlxuICAgICAgcmV0dXJuIHRoaXMuZ2V0TmFtZShvcmlnaW5hbFNjYWxlTmFtZSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUgaXMgYSBzY2FsZSBmb3IgdGhlIGNoYW5uZWwsIGl0IHNob3VsZCBlaXRoZXJcbiAgICAvLyBiZSBpbiB0aGUgc2NhbGUgY29tcG9uZW50IG9yIGV4aXN0IGluIHRoZSBuYW1lIG1hcFxuICAgIGlmIChcbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBzY2FsZSBmb3IgdGhlIGNoYW5uZWwsIHRoZXJlIHNob3VsZCBiZSBhIGxvY2FsIHNjYWxlIGNvbXBvbmVudCBmb3IgaXRcbiAgICAgICAgKGlzQ2hhbm5lbChvcmlnaW5hbFNjYWxlTmFtZSkgJiYgaXNTY2FsZUNoYW5uZWwob3JpZ2luYWxTY2FsZU5hbWUpICYmIHRoaXMuY29tcG9uZW50LnNjYWxlc1tvcmlnaW5hbFNjYWxlTmFtZV0pIHx8XG4gICAgICAgIC8vIGluIHRoZSBzY2FsZSBuYW1lIG1hcCAodGhlIHRoZSBzY2FsZSBnZXQgbWVyZ2VkIGJ5IGl0cyBwYXJlbnQpXG4gICAgICAgIHRoaXMuc2NhbGVOYW1lTWFwLmhhcyh0aGlzLmdldE5hbWUob3JpZ2luYWxTY2FsZU5hbWUpKVxuICAgICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5zY2FsZU5hbWVNYXAuZ2V0KHRoaXMuZ2V0TmFtZShvcmlnaW5hbFNjYWxlTmFtZSkpO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcnJlY3RzIHRoZSBkYXRhIHJlZmVyZW5jZXMgaW4gbWFya3MgYWZ0ZXIgYXNzZW1ibGUuXG4gICAqL1xuICBwdWJsaWMgY29ycmVjdERhdGFOYW1lcyA9IChtYXJrOiBWZ01hcmtHcm91cCkgPT4ge1xuICAgIC8vIFRPRE86IG1ha2UgdGhpcyBjb3JyZWN0XG5cbiAgICAvLyBmb3Igbm9ybWFsIGRhdGEgcmVmZXJlbmNlc1xuICAgIGlmIChtYXJrLmZyb20gJiYgbWFyay5mcm9tLmRhdGEpIHtcbiAgICAgIG1hcmsuZnJvbS5kYXRhID0gdGhpcy5sb29rdXBEYXRhU291cmNlKG1hcmsuZnJvbS5kYXRhKTtcbiAgICB9XG5cbiAgICAvLyBmb3IgYWNjZXNzIHRvIGZhY2V0IGRhdGFcbiAgICBpZiAobWFyay5mcm9tICYmIG1hcmsuZnJvbS5mYWNldCAmJiBtYXJrLmZyb20uZmFjZXQuZGF0YSkge1xuICAgICAgbWFyay5mcm9tLmZhY2V0LmRhdGEgPSB0aGlzLmxvb2t1cERhdGFTb3VyY2UobWFyay5mcm9tLmZhY2V0LmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlIGEgbW9kZWwncyBoaWVyYXJjaHkgdG8gZ2V0IHRoZSBzY2FsZSBjb21wb25lbnQgZm9yIGEgcGFydGljdWxhciBjaGFubmVsLlxuICAgKi9cbiAgcHVibGljIGdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCk6IFNjYWxlQ29tcG9uZW50IHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogVGhpcyBpcyB3YXJuaW5nIGZvciBkZWJ1Z2dpbmcgdGVzdCAqL1xuICAgIGlmICghdGhpcy5jb21wb25lbnQuc2NhbGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dldFNjYWxlQ29tcG9uZW50IGNhbm5vdCBiZSBjYWxsZWQgYmVmb3JlIHBhcnNlU2NhbGUoKS4gIE1ha2Ugc3VyZSB5b3UgaGF2ZSBjYWxsZWQgcGFyc2VTY2FsZSBvciB1c2UgcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoKS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2NhbFNjYWxlQ29tcG9uZW50ID0gdGhpcy5jb21wb25lbnQuc2NhbGVzW2NoYW5uZWxdO1xuICAgIGlmIChsb2NhbFNjYWxlQ29tcG9uZW50ICYmICFsb2NhbFNjYWxlQ29tcG9uZW50Lm1lcmdlZCkge1xuICAgICAgcmV0dXJuIGxvY2FsU2NhbGVDb21wb25lbnQ7XG4gICAgfVxuICAgIHJldHVybiAodGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKSA6IHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2UgYSBtb2RlbCdzIGhpZXJhcmNoeSB0byBnZXQgYSBwYXJ0aWN1bGFyIHNlbGVjdGlvbiBjb21wb25lbnQuXG4gICAqL1xuICBwdWJsaWMgZ2V0U2VsZWN0aW9uQ29tcG9uZW50KHZhck5hbWU6IHN0cmluZywgb3JpZ05hbWU6IHN0cmluZyk6IFNlbGVjdGlvbkNvbXBvbmVudCB7XG4gICAgbGV0IHNlbCA9IHRoaXMuY29tcG9uZW50LnNlbGVjdGlvblt2YXJOYW1lXTtcbiAgICBpZiAoIXNlbCAmJiB0aGlzLnBhcmVudCkge1xuICAgICAgc2VsID0gdGhpcy5wYXJlbnQuZ2V0U2VsZWN0aW9uQ29tcG9uZW50KHZhck5hbWUsIG9yaWdOYW1lKTtcbiAgICB9XG4gICAgaWYgKCFzZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihsb2cubWVzc2FnZS5zZWxlY3Rpb25Ob3RGb3VuZChvcmlnTmFtZSkpO1xuICAgIH1cbiAgICByZXR1cm4gc2VsO1xuICB9XG59XG5cbi8qKiBBYnN0cmFjdCBjbGFzcyBmb3IgVW5pdE1vZGVsIGFuZCBGYWNldE1vZGVsLiAgQm90aCBvZiB3aGljaCBjYW4gY29udGFpbiBmaWVsZERlZnMgYXMgYSBwYXJ0IG9mIGl0cyBvd24gc3BlY2lmaWNhdGlvbi4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBNb2RlbFdpdGhGaWVsZCBleHRlbmRzIE1vZGVsIHtcbiAgcHVibGljIGFic3RyYWN0IGZpZWxkRGVmKGNoYW5uZWw6IFNpbmdsZURlZkNoYW5uZWwpOiBGaWVsZERlZjxzdHJpbmc+O1xuXG4gIC8qKiBHZXQgXCJmaWVsZFwiIHJlZmVyZW5jZSBmb3IgdmVnYSAqL1xuICBwdWJsaWMgZmllbGQoY2hhbm5lbDogU2luZ2xlRGVmQ2hhbm5lbCwgb3B0OiBGaWVsZFJlZk9wdGlvbiA9IHt9KSB7XG4gICAgY29uc3QgZmllbGREZWYgPSB0aGlzLmZpZWxkRGVmKGNoYW5uZWwpO1xuXG4gICAgaWYgKCFmaWVsZERlZikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZmllbGQoZmllbGREZWYsIG9wdCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0TWFwcGluZygpOiB7W2tleSBpbiBDaGFubmVsXT86IGFueX07XG5cbiAgcHVibGljIHJlZHVjZUZpZWxkRGVmPFQsIFU+KGY6IChhY2M6IFUsIGZkOiBGaWVsZERlZjxzdHJpbmc+LCBjOiBDaGFubmVsKSA9PiBVLCBpbml0OiBULCB0PzogYW55KSB7XG4gICAgcmV0dXJuIHJlZHVjZSh0aGlzLmdldE1hcHBpbmcoKSwgKGFjYzpVICwgY2Q6IENoYW5uZWxEZWY8c3RyaW5nPiwgYzogQ2hhbm5lbCkgPT4ge1xuICAgICAgY29uc3QgZmllbGREZWYgPSBnZXRGaWVsZERlZihjZCk7XG4gICAgICBpZiAoZmllbGREZWYpIHtcbiAgICAgICAgcmV0dXJuIGYoYWNjLCBmaWVsZERlZiwgYyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIGluaXQsIHQpO1xuICB9XG5cbiAgcHVibGljIGZvckVhY2hGaWVsZERlZihmOiAoZmQ6IEZpZWxkRGVmPHN0cmluZz4sIGM6IENoYW5uZWwpID0+IHZvaWQsIHQ/OiBhbnkpIHtcbiAgICBmb3JFYWNoKHRoaXMuZ2V0TWFwcGluZygpLCAoY2Q6IENoYW5uZWxEZWY8c3RyaW5nPiwgYzogQ2hhbm5lbCkgPT4ge1xuICAgICAgY29uc3QgZmllbGREZWYgPSBnZXRGaWVsZERlZihjZCk7XG4gICAgICBpZiAoZmllbGREZWYpIHtcbiAgICAgICAgZihmaWVsZERlZiwgYyk7XG4gICAgICB9XG4gICAgfSwgdCk7XG4gIH1cbiAgcHVibGljIGFic3RyYWN0IGNoYW5uZWxIYXNGaWVsZChjaGFubmVsOiBDaGFubmVsKTogYm9vbGVhbjtcbn1cbiJdfQ== \ 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..f844e03458 --- /dev/null +++ b/build/src/compile/repeat.d.ts @@ -0,0 +1,16 @@ +import { Config } from '../config'; +import { Repeat } from '../repeat'; +import { RepeatSpec } 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: RepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config); + private _initChildren(spec, repeat, repeater, config); + parseLayoutSize(): void; + assembleLayout(): VgLayout; +} diff --git a/build/src/compile/repeat.js b/build/src/compile/repeat.js new file mode 100644 index 0000000000..d3f4ba819d --- /dev/null +++ b/build/src/compile/repeat.js @@ -0,0 +1,64 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var baseconcat_1 = require("./baseconcat"); +var buildmodel_1 = require("./buildmodel"); +var parse_1 = require("./layoutsize/parse"); +var RepeatModel = /** @class */ (function (_super) { + __extends(RepeatModel, _super); + function RepeatModel(spec, parent, parentGivenName, repeatValues, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, 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_1.buildModel(spec.spec, this, this.getName('child' + name_1), undefined, childRepeat, config, false)); + } + } + return children; + }; + RepeatModel.prototype.parseLayoutSize = function () { + parse_1.parseRepeatLayoutSize(this); + }; + RepeatModel.prototype.assembleLayout = function () { + // TODO: allow customization + return { + padding: { row: 10, column: 10 }, + offset: 10, + columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1, + bounds: 'full', + align: 'all' + }; + }; + return RepeatModel; +}(baseconcat_1.BaseConcatModel)); +exports.RepeatModel = RepeatModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwZWF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGUvcmVwZWF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUVBLDRCQUE4QjtBQUk5QiwyQ0FBNkM7QUFDN0MsMkNBQXdDO0FBQ3hDLDRDQUF5RDtBQUl6RDtJQUFpQywrQkFBZTtJQU05QyxxQkFBWSxJQUFnQixFQUFFLE1BQWEsRUFBRSxlQUF1QixFQUFFLFlBQTJCLEVBQUUsTUFBYztRQUFqSCxZQUNFLGtCQUFNLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBUTNEO1FBZGUsVUFBSSxHQUFhLFFBQVEsQ0FBQztRQVF4QyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hILEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxLQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDMUIsS0FBSSxDQUFDLFFBQVEsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQzs7SUFDOUUsQ0FBQztJQUVPLG1DQUFhLEdBQXJCLFVBQXNCLElBQWdCLEVBQUUsTUFBYyxFQUFFLFFBQXVCLEVBQUUsTUFBYztRQUM3RixJQUFNLFFBQVEsR0FBWSxFQUFFLENBQUM7UUFDN0IsSUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0QsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFcEUsZ0JBQWdCO1FBQ2hCLEdBQUcsQ0FBQyxDQUFtQixVQUFHLEVBQUgsV0FBRyxFQUFILGlCQUFHLEVBQUgsSUFBRztZQUFyQixJQUFNLFFBQVEsWUFBQTtZQUNqQixHQUFHLENBQUMsQ0FBc0IsVUFBTSxFQUFOLGlCQUFNLEVBQU4sb0JBQU0sRUFBTixJQUFNO2dCQUEzQixJQUFNLFdBQVcsZUFBQTtnQkFDcEIsSUFBTSxNQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFFdkYsSUFBTSxXQUFXLEdBQUc7b0JBQ2xCLEdBQUcsRUFBRSxRQUFRO29CQUNiLE1BQU0sRUFBRSxXQUFXO2lCQUNwQixDQUFDO2dCQUVGLFFBQVEsQ0FBQyxJQUFJLENBQUMsdUJBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sR0FBRyxNQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQ2pIO1NBQ0Y7UUFFRCxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFTSxxQ0FBZSxHQUF0QjtRQUNFLDZCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFTSxvQ0FBYyxHQUFyQjtRQUNFLDRCQUE0QjtRQUM1QixNQUFNLENBQUM7WUFDTCxPQUFPLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUM7WUFDOUIsTUFBTSxFQUFFLEVBQUU7WUFDVixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFFLE1BQU0sRUFBRSxNQUFNO1lBQ2QsS0FBSyxFQUFFLEtBQUs7U0FDYixDQUFDO0lBQ0osQ0FBQztJQUNILGtCQUFDO0FBQUQsQ0FBQyxBQXJERCxDQUFpQyw0QkFBZSxHQXFEL0M7QUFyRFksa0NBQVciLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL2xvZyc7XG5pbXBvcnQge1JlcGVhdH0gZnJvbSAnLi4vcmVwZWF0JztcbmltcG9ydCB7UmVwZWF0U3BlY30gZnJvbSAnLi4vc3BlYyc7XG5pbXBvcnQge1ZnTGF5b3V0fSBmcm9tICcuLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge0Jhc2VDb25jYXRNb2RlbH0gZnJvbSAnLi9iYXNlY29uY2F0JztcbmltcG9ydCB7YnVpbGRNb2RlbH0gZnJvbSAnLi9idWlsZG1vZGVsJztcbmltcG9ydCB7cGFyc2VSZXBlYXRMYXlvdXRTaXplfSBmcm9tICcuL2xheW91dHNpemUvcGFyc2UnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQge1JlcGVhdGVyVmFsdWV9IGZyb20gJy4vcmVwZWF0ZXInO1xuXG5leHBvcnQgY2xhc3MgUmVwZWF0TW9kZWwgZXh0ZW5kcyBCYXNlQ29uY2F0TW9kZWwge1xuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogJ3JlcGVhdCcgPSAncmVwZWF0JztcbiAgcHVibGljIHJlYWRvbmx5IHJlcGVhdDogUmVwZWF0O1xuXG4gIHB1YmxpYyByZWFkb25seSBjaGlsZHJlbjogTW9kZWxbXTtcblxuICBjb25zdHJ1Y3RvcihzcGVjOiBSZXBlYXRTcGVjLCBwYXJlbnQ6IE1vZGVsLCBwYXJlbnRHaXZlbk5hbWU6IHN0cmluZywgcmVwZWF0VmFsdWVzOiBSZXBlYXRlclZhbHVlLCBjb25maWc6IENvbmZpZykge1xuICAgIHN1cGVyKHNwZWMsIHBhcmVudCwgcGFyZW50R2l2ZW5OYW1lLCBjb25maWcsIHNwZWMucmVzb2x2ZSk7XG5cbiAgICBpZiAoc3BlYy5yZXNvbHZlICYmIHNwZWMucmVzb2x2ZS5heGlzICYmIChzcGVjLnJlc29sdmUuYXhpcy54ID09PSAnc2hhcmVkJyB8fCBzcGVjLnJlc29sdmUuYXhpcy55ID09PSAnc2hhcmVkJykpIHtcbiAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLlJFUEVBVF9DQU5OT1RfU0hBUkVfQVhJUyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXBlYXQgPSBzcGVjLnJlcGVhdDtcbiAgICB0aGlzLmNoaWxkcmVuID0gdGhpcy5faW5pdENoaWxkcmVuKHNwZWMsIHRoaXMucmVwZWF0LCByZXBlYXRWYWx1ZXMsIGNvbmZpZyk7XG4gIH1cblxuICBwcml2YXRlIF9pbml0Q2hpbGRyZW4oc3BlYzogUmVwZWF0U3BlYywgcmVwZWF0OiBSZXBlYXQsIHJlcGVhdGVyOiBSZXBlYXRlclZhbHVlLCBjb25maWc6IENvbmZpZyk6IE1vZGVsW10ge1xuICAgIGNvbnN0IGNoaWxkcmVuOiBNb2RlbFtdID0gW107XG4gICAgY29uc3Qgcm93ID0gcmVwZWF0LnJvdyB8fCBbcmVwZWF0ZXIgPyByZXBlYXRlci5yb3cgOiBudWxsXTtcbiAgICBjb25zdCBjb2x1bW4gPSByZXBlYXQuY29sdW1uIHx8IFtyZXBlYXRlciA/IHJlcGVhdGVyLmNvbHVtbiA6IG51bGxdO1xuXG4gICAgLy8gY3Jvc3MgcHJvZHVjdFxuICAgIGZvciAoY29uc3Qgcm93RmllbGQgb2Ygcm93KSB7XG4gICAgICBmb3IgKGNvbnN0IGNvbHVtbkZpZWxkIG9mIGNvbHVtbikge1xuICAgICAgICBjb25zdCBuYW1lID0gKHJvd0ZpZWxkID8gJ18nICsgcm93RmllbGQgOiAnJykgKyAoY29sdW1uRmllbGQgPyAnXycgKyBjb2x1bW5GaWVsZCA6ICcnKTtcblxuICAgICAgICBjb25zdCBjaGlsZFJlcGVhdCA9IHtcbiAgICAgICAgICByb3c6IHJvd0ZpZWxkLFxuICAgICAgICAgIGNvbHVtbjogY29sdW1uRmllbGRcbiAgICAgICAgfTtcblxuICAgICAgICBjaGlsZHJlbi5wdXNoKGJ1aWxkTW9kZWwoc3BlYy5zcGVjLCB0aGlzLCB0aGlzLmdldE5hbWUoJ2NoaWxkJyArIG5hbWUpLCB1bmRlZmluZWQsIGNoaWxkUmVwZWF0LCBjb25maWcsIGZhbHNlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNoaWxkcmVuO1xuICB9XG5cbiAgcHVibGljIHBhcnNlTGF5b3V0U2l6ZSgpIHtcbiAgICBwYXJzZVJlcGVhdExheW91dFNpemUodGhpcyk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVMYXlvdXQoKTogVmdMYXlvdXQge1xuICAgIC8vIFRPRE86IGFsbG93IGN1c3RvbWl6YXRpb25cbiAgICByZXR1cm4ge1xuICAgICAgcGFkZGluZzoge3JvdzogMTAsIGNvbHVtbjogMTB9LFxuICAgICAgb2Zmc2V0OiAxMCxcbiAgICAgIGNvbHVtbnM6IHRoaXMucmVwZWF0ICYmIHRoaXMucmVwZWF0LmNvbHVtbiA/IHRoaXMucmVwZWF0LmNvbHVtbi5sZW5ndGggOiAxLFxuICAgICAgYm91bmRzOiAnZnVsbCcsXG4gICAgICBhbGlnbjogJ2FsbCdcbiAgICB9O1xuICB9XG59XG4iXX0= \ 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..00ad56abc7 --- /dev/null +++ b/build/src/compile/repeater.js @@ -0,0 +1,108 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../fielddef"); +var log = require("../log"); +var sort_1 = require("../sort"); +var util_1 = require("../util"); +function replaceRepeaterInFacet(facet, repeater) { + return replaceRepeater(facet, repeater); +} +exports.replaceRepeaterInFacet = replaceRepeaterInFacet; +function replaceRepeaterInEncoding(encoding, repeater) { + return replaceRepeater(encoding, repeater); +} +exports.replaceRepeaterInEncoding = replaceRepeaterInEncoding; +/** + * Replaces repeated value and returns if the repeated value is valid. + */ +function replaceRepeat(o, repeater) { + if (fielddef_1.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 { + 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 && sort_1.isSortField(fieldDef.sort)) { + var sort = replaceRepeat(fieldDef.sort, repeater); + fieldDef = __assign({}, fieldDef, (sort ? { sort: sort } : {})); + } + return fieldDef; +} +function replaceRepeaterInChannelDef(channelDef, repeater) { + if (fielddef_1.isFieldDef(channelDef)) { + var fd = replaceRepeaterInFieldDef(channelDef, repeater); + if (fd) { + return fd; + } + else if (fielddef_1.isConditionalDef(channelDef)) { + return { condition: channelDef.condition }; + } + } + else { + if (fielddef_1.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 (util_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwZWF0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9yZXBlYXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsd0NBQXlIO0FBRXpILDRCQUE4QjtBQUM5QixnQ0FBb0M7QUFDcEMsZ0NBQWdDO0FBT2hDLGdDQUF1QyxLQUEwQixFQUFFLFFBQXVCO0lBQ3hGLE1BQU0sQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBeUIsQ0FBQztBQUNsRSxDQUFDO0FBRkQsd0RBRUM7QUFFRCxtQ0FBMEMsUUFBeUIsRUFBRSxRQUF1QjtJQUMxRixNQUFNLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQXFCLENBQUM7QUFDakUsQ0FBQztBQUZELDhEQUVDO0FBRUQ7O0dBRUc7QUFDSCx1QkFBa0QsQ0FBSSxFQUFFLFFBQXVCO0lBQzdFLEVBQUUsQ0FBQyxDQUFDLHNCQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQy9CLHNDQUFzQztZQUN0QyxNQUFNLGNBQUssQ0FBUSxJQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBRTtRQUN4RCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzFELE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDbkIsQ0FBQztJQUNILENBQUM7SUFDRCxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsbUNBQW1D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LEdBQUcsMkJBQTJCLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUM3RCxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNQLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQ3BCLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RW5jb2Rpbmd9IGZyb20gJy4uL2VuY29kaW5nJztcbmltcG9ydCB7RmFjZXRNYXBwaW5nfSBmcm9tICcuLi9mYWNldCc7XG5pbXBvcnQge0ZpZWxkLCBGaWVsZERlZiwgaGFzQ29uZGl0aW9uYWxGaWVsZERlZiwgaXNDb25kaXRpb25hbERlZiwgaXNGaWVsZERlZiwgaXNSZXBlYXRSZWYsIFZhbHVlRGVmfSBmcm9tICcuLi9maWVsZGRlZic7XG5pbXBvcnQge0NoYW5uZWxEZWYsIFNjYWxlRmllbGREZWZ9IGZyb20gJy4uL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi9sb2cnO1xuaW1wb3J0IHtpc1NvcnRGaWVsZH0gZnJvbSAnLi4vc29ydCc7XG5pbXBvcnQge2lzQXJyYXl9IGZyb20gJy4uL3V0aWwnO1xuXG5leHBvcnQgdHlwZSBSZXBlYXRlclZhbHVlID0ge1xuICByb3c/OiBzdHJpbmcsXG4gIGNvbHVtbj86IHN0cmluZ1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VSZXBlYXRlckluRmFjZXQoZmFjZXQ6IEZhY2V0TWFwcGluZzxGaWVsZD4sIHJlcGVhdGVyOiBSZXBlYXRlclZhbHVlKTogRmFjZXRNYXBwaW5nPHN0cmluZz4ge1xuICByZXR1cm4gcmVwbGFjZVJlcGVhdGVyKGZhY2V0LCByZXBlYXRlcikgYXMgRmFjZXRNYXBwaW5nPHN0cmluZz47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlUmVwZWF0ZXJJbkVuY29kaW5nKGVuY29kaW5nOiBFbmNvZGluZzxGaWVsZD4sIHJlcGVhdGVyOiBSZXBlYXRlclZhbHVlKTogRW5jb2Rpbmc8c3RyaW5nPiB7XG4gIHJldHVybiByZXBsYWNlUmVwZWF0ZXIoZW5jb2RpbmcsIHJlcGVhdGVyKSBhcyBFbmNvZGluZzxzdHJpbmc+O1xufVxuXG4vKipcbiAqIFJlcGxhY2VzIHJlcGVhdGVkIHZhbHVlIGFuZCByZXR1cm5zIGlmIHRoZSByZXBlYXRlZCB2YWx1ZSBpcyB2YWxpZC5cbiAqL1xuZnVuY3Rpb24gcmVwbGFjZVJlcGVhdDxUIGV4dGVuZHMge2ZpZWxkPzogRmllbGR9PihvOiBULCByZXBlYXRlcjogUmVwZWF0ZXJWYWx1ZSk6IFQge1xuICBpZiAoaXNSZXBlYXRSZWYoby5maWVsZCkpIHtcbiAgICBpZiAoby5maWVsZC5yZXBlYXQgaW4gcmVwZWF0ZXIpIHtcbiAgICAgIC8vIGFueSBuZWVkZWQgdG8gY2FsbSBkb3duIHRzIGNvbXBpbGVyXG4gICAgICByZXR1cm4gey4uLm8gYXMgYW55LCBmaWVsZDogcmVwZWF0ZXJbby5maWVsZC5yZXBlYXRdfTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2Uubm9TdWNoUmVwZWF0ZWRWYWx1ZShvLmZpZWxkLnJlcGVhdCkpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG87XG59XG5cbi8qKlxuICogUmVwbGFjZSByZXBlYXRlciB2YWx1ZXMgaW4gYSBmaWVsZCBkZWYgd2l0aCB0aGUgY29uY3JldGUgZmllbGQgbmFtZS5cbiAqL1xuZnVuY3Rpb24gcmVwbGFjZVJlcGVhdGVySW5GaWVsZERlZihmaWVsZERlZjogU2NhbGVGaWVsZERlZjxGaWVsZD4sIHJlcGVhdGVyOiBSZXBlYXRlclZhbHVlKTogU2NhbGVGaWVsZERlZjxzdHJpbmc+IHtcbiAgZmllbGREZWYgPSByZXBsYWNlUmVwZWF0KGZpZWxkRGVmLCByZXBlYXRlcik7XG5cbiAgaWYgKGZpZWxkRGVmID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyB0aGUgZmllbGQgZGVmIHNob3VsZCBiZSBpZ25vcmVkXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChmaWVsZERlZi5zb3J0ICYmIGlzU29ydEZpZWxkKGZpZWxkRGVmLnNvcnQpKSB7XG4gICAgY29uc3Qgc29ydCA9IHJlcGxhY2VSZXBlYXQoZmllbGREZWYuc29ydCwgcmVwZWF0ZXIpO1xuICAgIGZpZWxkRGVmID0ge1xuICAgICAgLi4uZmllbGREZWYsXG4gICAgICAuLi4oc29ydCA/IHtzb3J0fSA6IHt9KVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gZmllbGREZWYgYXMgU2NhbGVGaWVsZERlZjxzdHJpbmc+O1xufVxuXG5mdW5jdGlvbiByZXBsYWNlUmVwZWF0ZXJJbkNoYW5uZWxEZWYoY2hhbm5lbERlZjogQ2hhbm5lbERlZjxGaWVsZD4sIHJlcGVhdGVyOiBSZXBlYXRlclZhbHVlKTogQ2hhbm5lbERlZjxzdHJpbmc+IHtcbiAgaWYgKGlzRmllbGREZWYoY2hhbm5lbERlZikpIHtcbiAgICBjb25zdCBmZCA9IHJlcGxhY2VSZXBlYXRlckluRmllbGREZWYoY2hhbm5lbERlZiwgcmVwZWF0ZXIpO1xuICAgIGlmIChmZCkge1xuICAgICAgcmV0dXJuIGZkO1xuICAgIH0gZWxzZSBpZiAoaXNDb25kaXRpb25hbERlZihjaGFubmVsRGVmKSkge1xuICAgICAgcmV0dXJuIHtjb25kaXRpb246IGNoYW5uZWxEZWYuY29uZGl0aW9ufTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGhhc0NvbmRpdGlvbmFsRmllbGREZWYoY2hhbm5lbERlZikpIHtcbiAgICAgIGNvbnN0IGZkID0gcmVwbGFjZVJlcGVhdGVySW5GaWVsZERlZihjaGFubmVsRGVmLmNvbmRpdGlvbiwgcmVwZWF0ZXIpO1xuICAgICAgaWYgKGZkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uY2hhbm5lbERlZixcbiAgICAgICAgICBjb25kaXRpb246IGZkXG4gICAgICAgIH0gYXMgQ2hhbm5lbERlZjxzdHJpbmc+O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qge2NvbmRpdGlvbiwgLi4uY2hhbm5lbERlZldpdGhvdXRDb25kaXRpb259ID0gY2hhbm5lbERlZjtcbiAgICAgICAgcmV0dXJuIGNoYW5uZWxEZWZXaXRob3V0Q29uZGl0aW9uIGFzIENoYW5uZWxEZWY8c3RyaW5nPjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNoYW5uZWxEZWYgYXMgVmFsdWVEZWY7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxudHlwZSBFbmNvZGluZ09yRmFjZXQ8Rj4gPSBFbmNvZGluZzxGPiB8IEZhY2V0TWFwcGluZzxGPjtcblxuZnVuY3Rpb24gcmVwbGFjZVJlcGVhdGVyKG1hcHBpbmc6IEVuY29kaW5nT3JGYWNldDxGaWVsZD4sIHJlcGVhdGVyOiBSZXBlYXRlclZhbHVlKTogRW5jb2RpbmdPckZhY2V0PHN0cmluZz4ge1xuICBjb25zdCBvdXQ6IEVuY29kaW5nT3JGYWNldDxzdHJpbmc+ID0ge307XG4gIGZvciAoY29uc3QgY2hhbm5lbCBpbiBtYXBwaW5nKSB7XG4gICAgaWYgKG1hcHBpbmcuaGFzT3duUHJvcGVydHkoY2hhbm5lbCkpIHtcbiAgICAgIGNvbnN0IGNoYW5uZWxEZWY6IENoYW5uZWxEZWY8RmllbGQ+IHwgQ2hhbm5lbERlZjxGaWVsZD5bXSA9IG1hcHBpbmdbY2hhbm5lbF07XG5cbiAgICAgIGlmIChpc0FycmF5KGNoYW5uZWxEZWYpKSB7XG4gICAgICAgIC8vIGFycmF5IGNhbm5vdCBoYXZlIGNvbmRpdGlvblxuICAgICAgICBvdXRbY2hhbm5lbF0gPSBjaGFubmVsRGVmLm1hcChjZCA9PiByZXBsYWNlUmVwZWF0ZXJJbkNoYW5uZWxEZWYoY2QsIHJlcGVhdGVyKSlcbiAgICAgICAgICAuZmlsdGVyKGNkID0+IGNkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNkID0gcmVwbGFjZVJlcGVhdGVySW5DaGFubmVsRGVmKGNoYW5uZWxEZWYsIHJlcGVhdGVyKTtcbiAgICAgICAgaWYgKGNkKSB7XG4gICAgICAgICAgb3V0W2NoYW5uZWxdID0gY2Q7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ== \ 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..bbb9c08110 --- /dev/null +++ b/build/src/compile/resolve.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var log = require("../log"); +var util_1 = require("../util"); +var model_1 = require("./model"); +function defaultScaleResolve(channel, model) { + if (model_1.isLayerModel(model) || model_1.isFacetModel(model)) { + return 'shared'; + } + else if (model_1.isConcatModel(model) || model_1.isRepeatModel(model)) { + return util_1.contains(channel_1.POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared'; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('invalid model type for resolve'); +} +exports.defaultScaleResolve = defaultScaleResolve; +function parseGuideResolve(resolve, channel) { + var channelScaleResolve = resolve.scale[channel]; + var guide = util_1.contains(channel_1.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'; +} +exports.parseGuideResolve = parseGuideResolve; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL3Jlc29sdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzQ0FBaUU7QUFDakUsNEJBQThCO0FBRTlCLGdDQUFpQztBQUNqQyxpQ0FBd0Y7QUFFeEYsNkJBQW9DLE9BQXFCLEVBQUUsS0FBWTtJQUNyRSxFQUFFLENBQUMsQ0FBQyxvQkFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLG9CQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxxQkFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLHFCQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sQ0FBQyxlQUFRLENBQUMsaUNBQXVCLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0lBQy9FLENBQUM7SUFDRCxvREFBb0Q7SUFDcEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3BELENBQUM7QUFSRCxrREFRQztBQUVELDJCQUFrQyxPQUFnQixFQUFFLE9BQXFCO0lBQ3ZFLElBQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxJQUFNLEtBQUssR0FBRyxlQUFRLENBQUMsaUNBQXVCLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0lBRTdFLEVBQUUsQ0FBQyxDQUFDLG1CQUFtQixLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDMUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDekMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLHFDQUFxQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUNELE1BQU0sQ0FBQyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVELE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksUUFBUSxDQUFDO0FBQzdDLENBQUM7QUFaRCw4Q0FZQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7UE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMsIFNjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vY2hhbm5lbCc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vbG9nJztcbmltcG9ydCB7UmVzb2x2ZSwgUmVzb2x2ZU1vZGV9IGZyb20gJy4uL3Jlc29sdmUnO1xuaW1wb3J0IHtjb250YWluc30gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQge2lzQ29uY2F0TW9kZWwsIGlzRmFjZXRNb2RlbCwgaXNMYXllck1vZGVsLCBpc1JlcGVhdE1vZGVsLCBNb2RlbH0gZnJvbSAnLi9tb2RlbCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0U2NhbGVSZXNvbHZlKGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCwgbW9kZWw6IE1vZGVsKTogUmVzb2x2ZU1vZGUge1xuICBpZiAoaXNMYXllck1vZGVsKG1vZGVsKSB8fCBpc0ZhY2V0TW9kZWwobW9kZWwpKSB7XG4gICAgcmV0dXJuICdzaGFyZWQnO1xuICB9IGVsc2UgaWYgKGlzQ29uY2F0TW9kZWwobW9kZWwpIHx8IGlzUmVwZWF0TW9kZWwobW9kZWwpKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5zKFBPU0lUSU9OX1NDQUxFX0NIQU5ORUxTLCBjaGFubmVsKSA/ICdpbmRlcGVuZGVudCcgOiAnc2hhcmVkJztcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogc2hvdWxkIG5ldmVyIHJlYWNoIGhlcmUuICovXG4gIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBtb2RlbCB0eXBlIGZvciByZXNvbHZlJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUd1aWRlUmVzb2x2ZShyZXNvbHZlOiBSZXNvbHZlLCBjaGFubmVsOiBTY2FsZUNoYW5uZWwpOiBSZXNvbHZlTW9kZSB7XG4gIGNvbnN0IGNoYW5uZWxTY2FsZVJlc29sdmUgPSByZXNvbHZlLnNjYWxlW2NoYW5uZWxdO1xuICBjb25zdCBndWlkZSA9IGNvbnRhaW5zKFBPU0lUSU9OX1NDQUxFX0NIQU5ORUxTLCBjaGFubmVsKSA/ICdheGlzJyA6ICdsZWdlbmQnO1xuXG4gIGlmIChjaGFubmVsU2NhbGVSZXNvbHZlID09PSAnaW5kZXBlbmRlbnQnKSB7XG4gICAgaWYgKHJlc29sdmVbZ3VpZGVdW2NoYW5uZWxdID09PSAnc2hhcmVkJykge1xuICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuaW5kZXBlbmRlbnRTY2FsZU1lYW5zSW5kZXBlbmRlbnRHdWlkZShjaGFubmVsKSk7XG4gICAgfVxuICAgIHJldHVybiAnaW5kZXBlbmRlbnQnO1xuICB9XG5cbiAgcmV0dXJuIHJlc29sdmVbZ3VpZGVdW2NoYW5uZWxdIHx8ICdzaGFyZWQnO1xufVxuIl19 \ 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..e68c36a4c6 --- /dev/null +++ b/build/src/compile/scale/assemble.js @@ -0,0 +1,90 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var util_1 = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var model_1 = require("../model"); +var selection_1 = require("../selection/selection"); +var domain_1 = require("./domain"); +function assembleScales(model) { + if (model_1.isLayerModel(model) || model_1.isConcatModel(model) || model_1.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); + } +} +exports.assembleScales = assembleScales; +function assembleScalesForModel(model) { + return util_1.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 && selection_1.isRawSelectionDomain(domainRaw)) { + domainRaw = selection_1.selectionScaleDomain(model, domainRaw); + } + scales.push(__assign({ name: name, + type: type, domain: domain_1.assembleDomain(model, channel) }, (domainRaw ? { domainRaw: domainRaw } : {}), { range: range }, otherScaleProps)); + return scales; + }, []); +} +exports.assembleScalesForModel = assembleScalesForModel; +function assembleScaleRange(scaleRange, scaleName, model, channel) { + // add signals to x/y range + if (channel === 'x' || channel === 'y') { + if (vega_schema_1.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 (vega_util_1.isArray(scaleRange) && scaleRange.length === 2) { + var r0 = scaleRange[0]; + var r1 = scaleRange[1]; + if (r0 === 0 && vega_schema_1.isVgSignalRef(r1)) { + // Replace width signal just in case it is renamed. + return [0, { signal: model.getSizeName(r1.signal) }]; + } + else if (vega_schema_1.isVgSignalRef(r0) && r1 === 0) { + // Replace height signal just in case it is renamed. + return [{ signal: model.getSizeName(r0.signal) }, 0]; + } + } + } + return scaleRange; +} +exports.assembleScaleRange = assembleScaleRange; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9hc3NlbWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdUNBQWtDO0FBRWxDLG1DQUFnQztBQUNoQyxpREFBaUY7QUFDakYsa0NBQTJFO0FBQzNFLG9EQUFrRjtBQUNsRixtQ0FBd0M7QUFFeEMsd0JBQStCLEtBQVk7SUFDekMsRUFBRSxDQUFDLENBQUMsb0JBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxxQkFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLHFCQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLDhEQUE4RDtRQUM5RCxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBQyxNQUFNLEVBQUUsS0FBSztZQUN6QyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM5QyxDQUFDLEVBQUUsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTix1RUFBdUU7UUFDdkUsK0JBQStCO1FBQy9CLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxDQUFDO0FBQ0gsQ0FBQztBQVhELHdDQVdDO0FBRUQsZ0NBQXVDLEtBQVk7SUFDL0MsTUFBTSxDQUFDLFdBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFDLE1BQWlCLEVBQUUsT0FBcUI7UUFDbEYsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkQsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDMUIsd0JBQXdCO1lBQ3hCLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELElBQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV2QywwREFBMEQ7UUFDckQsSUFBQSwyQkFBUyxFQUFFLG1CQUFLLENBQVU7UUFDeEIsSUFBQSxpQkFBSSxFQUFFLGlCQUFJLEVBQUUsb0JBQWEsRUFBRSxnQkFBUyxFQUFFLHVFQUFrQixDQUFVO1FBRXpFLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztRQUV4RCx1RUFBdUU7UUFDdkUsa0VBQWtFO1FBQ2xFLDREQUE0RDtRQUM1RCxrRUFBa0U7UUFDbEUsRUFBRSxDQUFDLENBQUMsU0FBUyxJQUFJLGdDQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRCxTQUFTLEdBQUcsZ0NBQW9CLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFHRCxNQUFNLENBQUMsSUFBSSxZQUNULElBQUksTUFBQTtZQUNKLElBQUksTUFBQSxFQUNKLE1BQU0sRUFBRSx1QkFBYyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsSUFDbkMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUMsU0FBUyxXQUFBLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQ2pDLEtBQUssRUFBRSxLQUFLLElBQ1QsZUFBZSxFQUNsQixDQUFDO1FBRUgsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNoQixDQUFDLEVBQUUsRUFBZSxDQUFDLENBQUM7QUFDeEIsQ0FBQztBQXBDRCx3REFvQ0M7QUFFRCw0QkFBbUMsVUFBbUIsRUFBRSxTQUFpQixFQUFFLEtBQVksRUFBRSxPQUFnQjtJQUN2RywyQkFBMkI7SUFDM0IsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLEdBQUcsSUFBSSxPQUFPLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2QyxFQUFFLENBQUMsQ0FBQywyQkFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QixnR0FBZ0c7WUFDaEcsTUFBTSxDQUFDO2dCQUNMLElBQUksRUFBRSxFQUFDLE1BQU0sRUFBRSxTQUFTLEdBQUcsT0FBTyxFQUFDO2FBQ3BDLENBQUM7UUFDSixDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLG1CQUFPLENBQUMsVUFBVSxDQUFDLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFELElBQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6QixJQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsSUFBSSwyQkFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEMsbURBQW1EO2dCQUNuRCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQ3JELENBQUM7WUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsMkJBQWEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDekMsb0RBQW9EO2dCQUNwRCxNQUFNLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQXJCRCxnREFxQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzQXJyYXl9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5pbXBvcnQge0NoYW5uZWwsIFNjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge2tleXN9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtpc1ZnUmFuZ2VTdGVwLCBpc1ZnU2lnbmFsUmVmLCBWZ1JhbmdlLCBWZ1NjYWxlfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge2lzQ29uY2F0TW9kZWwsIGlzTGF5ZXJNb2RlbCwgaXNSZXBlYXRNb2RlbCwgTW9kZWx9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7aXNSYXdTZWxlY3Rpb25Eb21haW4sIHNlbGVjdGlvblNjYWxlRG9tYWlufSBmcm9tICcuLi9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCB7YXNzZW1ibGVEb21haW59IGZyb20gJy4vZG9tYWluJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlU2NhbGVzKG1vZGVsOiBNb2RlbCk6IFZnU2NhbGVbXSB7XG4gIGlmIChpc0xheWVyTW9kZWwobW9kZWwpIHx8IGlzQ29uY2F0TW9kZWwobW9kZWwpIHx8IGlzUmVwZWF0TW9kZWwobW9kZWwpKSB7XG4gICAgLy8gRm9yIGNvbmNhdCAvIGxheWVyIC8gcmVwZWF0LCBpbmNsdWRlIHNjYWxlcyBvZiBjaGlsZHJlbiB0b29cbiAgICByZXR1cm4gbW9kZWwuY2hpbGRyZW4ucmVkdWNlKChzY2FsZXMsIGNoaWxkKSA9PiB7XG4gICAgICByZXR1cm4gc2NhbGVzLmNvbmNhdChhc3NlbWJsZVNjYWxlcyhjaGlsZCkpO1xuICAgIH0sIGFzc2VtYmxlU2NhbGVzRm9yTW9kZWwobW9kZWwpKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGb3IgZmFjZXQsIGNoaWxkIHNjYWxlcyB3b3VsZCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHBhcmVudCdzIHNjb3BlLlxuICAgIC8vIEZvciB1bml0LCB0aGVyZSBpcyBubyBjaGlsZC5cbiAgICByZXR1cm4gYXNzZW1ibGVTY2FsZXNGb3JNb2RlbChtb2RlbCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlU2NhbGVzRm9yTW9kZWwobW9kZWw6IE1vZGVsKTogVmdTY2FsZVtdIHtcbiAgICByZXR1cm4ga2V5cyhtb2RlbC5jb21wb25lbnQuc2NhbGVzKS5yZWR1Y2UoKHNjYWxlczogVmdTY2FsZVtdLCBjaGFubmVsOiBTY2FsZUNoYW5uZWwpID0+IHtcbiAgICAgIGNvbnN0IHNjYWxlQ29tcG9uZW50ID0gbW9kZWwuY29tcG9uZW50LnNjYWxlc1tjaGFubmVsXTtcbiAgICAgIGlmIChzY2FsZUNvbXBvbmVudC5tZXJnZWQpIHtcbiAgICAgICAgLy8gU2tpcHBlZCBtZXJnZWQgc2NhbGVzXG4gICAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNjYWxlID0gc2NhbGVDb21wb25lbnQuY29tYmluZSgpO1xuXG4gICAgICAvLyBuZWVkIHRvIHNlcGFyYXRlIGNvbnN0IGFuZCBub24gY29uc3Qgb2JqZWN0IGRlc3RydWN0aW9uXG4gICAgICBsZXQge2RvbWFpblJhdywgcmFuZ2V9ID0gc2NhbGU7XG4gICAgICBjb25zdCB7bmFtZSwgdHlwZSwgZG9tYWluUmF3OiBfZCwgcmFuZ2U6IF9yLCAuLi5vdGhlclNjYWxlUHJvcHN9ID0gc2NhbGU7XG5cbiAgICAgIHJhbmdlID0gYXNzZW1ibGVTY2FsZVJhbmdlKHJhbmdlLCBuYW1lLCBtb2RlbCwgY2hhbm5lbCk7XG5cbiAgICAgIC8vIEFzIHNjYWxlIHBhcnNpbmcgb2NjdXJzIGJlZm9yZSBzZWxlY3Rpb24gcGFyc2luZywgYSB0ZW1wb3Jhcnkgc2lnbmFsXG4gICAgICAvLyBpcyB1c2VkIGZvciBkb21haW5SYXcuIEhlcmUsIHdlIGRldGVjdCBpZiB0aGlzIHRlbXBvcmFyeSBzaWduYWxcbiAgICAgIC8vIGlzIHNldCwgYW5kIHJlcGxhY2UgaXQgd2l0aCB0aGUgY29ycmVjdCBkb21haW5SYXcgc2lnbmFsLlxuICAgICAgLy8gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBpc1Jhd1NlbGVjdGlvbkRvbWFpbiBpbiBzZWxlY3Rpb24udHMuXG4gICAgICBpZiAoZG9tYWluUmF3ICYmIGlzUmF3U2VsZWN0aW9uRG9tYWluKGRvbWFpblJhdykpIHtcbiAgICAgICAgZG9tYWluUmF3ID0gc2VsZWN0aW9uU2NhbGVEb21haW4obW9kZWwsIGRvbWFpblJhdyk7XG4gICAgICB9XG5cblxuICAgICAgc2NhbGVzLnB1c2goe1xuICAgICAgICBuYW1lLFxuICAgICAgICB0eXBlLFxuICAgICAgICBkb21haW46IGFzc2VtYmxlRG9tYWluKG1vZGVsLCBjaGFubmVsKSxcbiAgICAgICAgLi4uKGRvbWFpblJhdyA/IHtkb21haW5SYXd9IDoge30pLFxuICAgICAgICByYW5nZTogcmFuZ2UsXG4gICAgICAgIC4uLm90aGVyU2NhbGVQcm9wc1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgfSwgW10gYXMgVmdTY2FsZVtdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlU2NhbGVSYW5nZShzY2FsZVJhbmdlOiBWZ1JhbmdlLCBzY2FsZU5hbWU6IHN0cmluZywgbW9kZWw6IE1vZGVsLCBjaGFubmVsOiBDaGFubmVsKSB7XG4gIC8vIGFkZCBzaWduYWxzIHRvIHgveSByYW5nZVxuICBpZiAoY2hhbm5lbCA9PT0gJ3gnIHx8IGNoYW5uZWwgPT09ICd5Jykge1xuICAgIGlmIChpc1ZnUmFuZ2VTdGVwKHNjYWxlUmFuZ2UpKSB7XG4gICAgICAvLyBGb3IgeC95IHJhbmdlIHN0ZXAsIHVzZSBhIHNpZ25hbCBjcmVhdGVkIGluIGxheW91dCBhc3NlbWJsZSBpbnN0ZWFkIG9mIGEgY29uc3RhbnQgcmFuZ2Ugc3RlcC5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN0ZXA6IHtzaWduYWw6IHNjYWxlTmFtZSArICdfc3RlcCd9XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShzY2FsZVJhbmdlKSAmJiBzY2FsZVJhbmdlLmxlbmd0aCA9PT0gMikge1xuICAgICAgY29uc3QgcjAgPSBzY2FsZVJhbmdlWzBdO1xuICAgICAgY29uc3QgcjEgPSBzY2FsZVJhbmdlWzFdO1xuICAgICAgaWYgKHIwID09PSAwICYmIGlzVmdTaWduYWxSZWYocjEpKSB7XG4gICAgICAgIC8vIFJlcGxhY2Ugd2lkdGggc2lnbmFsIGp1c3QgaW4gY2FzZSBpdCBpcyByZW5hbWVkLlxuICAgICAgICByZXR1cm4gWzAsIHtzaWduYWw6IG1vZGVsLmdldFNpemVOYW1lKHIxLnNpZ25hbCl9XTtcbiAgICAgIH0gZWxzZSBpZiAoaXNWZ1NpZ25hbFJlZihyMCkgJiYgcjEgPT09IDApIHtcbiAgICAgICAgLy8gUmVwbGFjZSBoZWlnaHQgc2lnbmFsIGp1c3QgaW4gY2FzZSBpdCBpcyByZW5hbWVkLlxuICAgICAgICByZXR1cm4gW3tzaWduYWw6IG1vZGVsLmdldFNpemVOYW1lKHIwLnNpZ25hbCl9LCAwXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNjYWxlUmFuZ2U7XG59XG4iXX0= \ 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..2cfa227c4a --- /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 = Partial>; +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..052395354a --- /dev/null +++ b/build/src/compile/scale/component.js @@ -0,0 +1,28 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var split_1 = require("../split"); +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_1.Split)); +exports.ScaleComponent = ScaleComponent; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUlBLGtDQUF5QztBQVN6QztJQUFvQyxrQ0FBMEI7SUFLNUQsd0JBQVksSUFBWSxFQUFFLGdCQUFxQztRQUEvRCxZQUNFLGtCQUNFLEVBQUUsRUFBTSwrQkFBK0I7UUFDdkMsRUFBQyxJQUFJLE1BQUEsRUFBQyxDQUFFLG9DQUFvQztTQUM3QyxTQUVGO1FBVk0sWUFBTSxHQUFHLEtBQUssQ0FBQztRQUVmLGFBQU8sR0FBdUIsRUFBRSxDQUFDO1FBT3RDLEtBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUM7O0lBQ2pELENBQUM7SUFDSCxxQkFBQztBQUFELENBQUMsQUFaRCxDQUFvQyxhQUFLLEdBWXhDO0FBWlksd0NBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1NjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge1NjYWxlLCBTY2FsZVR5cGV9IGZyb20gJy4uLy4uL3NjYWxlJztcbmltcG9ydCB7T21pdH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnTm9uVW5pb25Eb21haW4sIFZnU2NhbGV9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7RXhwbGljaXQsIFNwbGl0fSBmcm9tICcuLi9zcGxpdCc7XG5cbi8qKlxuICogQWxsIFZnRG9tYWluIHByb3BlcnR5IGV4Y2VwdCBkb21haW4uXG4gKiAoV2UgZXhjbHVkZSBkb21haW4gYXMgd2UgaGF2ZSBhIHNwZWNpYWwgXCJkb21haW5zXCIgYXJyYXkgdGhhdCBhbGxvdyB1cyBtZXJnZSB0aGVtIGFsbCBhdCBvbmNlIGluIGFzc2VtYmxlLilcbiAqL1xuLy8gVE9ETzogYWxzbyBleGNsdWRlIGRvbWFpblJhdyBhbmQgcHJvcGVydHkgaW1wbGVtZW50IHRoZSByaWdodCBzY2FsZUNvbXBvbmVudCBmb3Igc2VsZWN0aW9uIGRvbWFpblxuZXhwb3J0IHR5cGUgU2NhbGVDb21wb25lbnRQcm9wcyA9IFBhcnRpYWw8T21pdDxWZ1NjYWxlLCAnZG9tYWluJz4+O1xuXG5leHBvcnQgY2xhc3MgU2NhbGVDb21wb25lbnQgZXh0ZW5kcyBTcGxpdDxTY2FsZUNvbXBvbmVudFByb3BzPiB7XG4gIHB1YmxpYyBtZXJnZWQgPSBmYWxzZTtcblxuICBwdWJsaWMgZG9tYWluczogVmdOb25VbmlvbkRvbWFpbltdID0gW107XG5cbiAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCB0eXBlV2l0aEV4cGxpY2l0OiBFeHBsaWNpdDxTY2FsZVR5cGU+KSB7XG4gICAgc3VwZXIoXG4gICAgICB7fSwgICAgIC8vIG5vIGluaXRpYWwgZXhwbGljaXQgcHJvcGVydHlcbiAgICAgIHtuYW1lfSAgLy8gbmFtZSBhcyBpbml0aWFsIGltcGxpY2l0IHByb3BlcnR5XG4gICAgKTtcbiAgICB0aGlzLnNldFdpdGhFeHBsaWNpdCgndHlwZScsIHR5cGVXaXRoRXhwbGljaXQpO1xuICB9XG59XG5cbi8vIFVzaW5nIE1hcHBlZCBUeXBlIHRvIGRlY2xhcmUgdHlwZSAoaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svYWR2YW5jZWQtdHlwZXMuaHRtbCNtYXBwZWQtdHlwZXMpXG5leHBvcnQgdHlwZSBTY2FsZUNvbXBvbmVudEluZGV4ID0ge1tQIGluIFNjYWxlQ2hhbm5lbF0/OiBTY2FsZUNvbXBvbmVudH07XG5cbmV4cG9ydCB0eXBlIFNjYWxlSW5kZXggPSB7W1AgaW4gU2NhbGVDaGFubmVsXT86IFNjYWxlfTtcbiJdfQ== \ 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..60c963d69e --- /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 { SortField } 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 | SortField; +/** + * 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..c573f6818c --- /dev/null +++ b/build/src/compile/scale/domain.js @@ -0,0 +1,420 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var aggregate_1 = require("../../aggregate"); +var bin_1 = require("../../bin"); +var channel_1 = require("../../channel"); +var data_1 = require("../../data"); +var datetime_1 = require("../../datetime"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var sort_1 = require("../../sort"); +var util = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var vega_schema_2 = require("../../vega.schema"); +var common_1 = require("../common"); +var optimize_1 = require("../data/optimize"); +var model_1 = require("../model"); +var selection_1 = require("../selection/selection"); +function parseScaleDomain(model) { + if (model_1.isUnitModel(model)) { + parseUnitScaleDomain(model); + } + else { + parseNonUnitScaleDomain(model); + } +} +exports.parseScaleDomain = parseScaleDomain; +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 (scale_1.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_1.SELECTION_DOMAIN + JSON.stringify(specifiedDomain) + }, true); + } + }); +} +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) { + // FIXME: Arvind -- Please revise logic for merging selectionDomain / domainRaw + var domains; + 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); + } + } + } + if (model_1.isFacetModel(model)) { + domains.forEach(function (domain) { + // Replace the scale domain with data output from a cloned subtree after the facet. + if (vega_schema_1.isDataRefDomain(domain)) { + // use data from cloned subtree (which is the same as data but with a prefix added once) + domain.data = optimize_1.FACET_SCALE_PREFIX + domain.data.replace(optimize_1.FACET_SCALE_PREFIX, ''); + } + }); + } + localScaleComponents[channel].domains = domains; + }); +} +/** + * 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; +} +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); +} +exports.parseDomainForChannel = parseDomainForChannel; +function parseSingleChannelDomain(scaleType, domain, model, channel) { + var fieldDef = model.fieldDef(channel); + if (domain && domain !== 'unaggregated' && !scale_1.isSelectionDomain(domain)) { + if (fieldDef.bin) { + log.warn(log.message.conflictedDomain(channel)); + } + else { + if (datetime_1.isDateTime(domain[0])) { + return domain.map(function (dt) { + return { signal: "{data: " + datetime_1.dateTimeExpr(dt, true) + "}" }; + }); + } + return [domain]; + } + } + var stack = model.stack; + if (stack && channel === stack.fieldChannel) { + if (stack.offset === 'normalize') { + return [[0, 1]]; + } + var data = model.requestDataName(data_1.MAIN); + return [{ + data: data, + field: model.field(channel, { suffix: 'start' }) + }, { + data: data, + field: model.field(channel, { suffix: 'end' }) + }]; + } + var sort = channel_1.isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined; + if (domain === 'unaggregated') { + var data = model.requestDataName(data_1.MAIN); + return [{ + data: data, + field: model.field(channel, { aggregate: 'min' }) + }, { + data: data, + field: model.field(channel, { aggregate: 'max' }) + }]; + } + else if (fieldDef.bin) { + if (scale_1.isBinScale(scaleType)) { + var signal = model.getName(bin_1.binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return [{ signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }]; + } + if (scale_1.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(data_1.MAIN) : model.requestDataName(data_1.RAW), + // Use range if we added it and the scale does not support computing a range as a signal. + field: model.field(channel, common_1.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 || !sort_1.isSortField(sort) ? { + field: model.field(channel, {}), + op: 'min' // min or max doesn't matter since we sort by the start of the bin range + } : sort + }]; + } + else { + if (channel === 'x' || channel === 'y') { + // X/Y position have to include start and end for non-ordinal scale + var data = model.requestDataName(data_1.MAIN); + return [{ + data: data, + field: model.field(channel, {}) + }, { + data: data, + field: model.field(channel, { binSuffix: 'end' }) + }]; + } + else { + // TODO: use bin_mid + return [{ + data: model.requestDataName(data_1.MAIN), + field: model.field(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(data_1.MAIN) : model.requestDataName(data_1.RAW), + field: model.field(channel), + sort: sort + }]; + } + else { + return [{ + data: model.requestDataName(data_1.MAIN), + field: model.field(channel) + }]; + } +} +function domainSort(model, channel, scaleType) { + if (!scale_1.hasDiscreteDomain(scaleType)) { + return undefined; + } + var sort = model.sort(channel); + // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale) + if (sort_1.isSortField(sort)) { + return sort; + } + if (sort === 'descending') { + return { + op: 'min', + field: model.field(channel), + order: 'descending' + }; + } + if (util.contains(['ascending', undefined /* default =ascending*/], sort)) { + return true; + } + // sort == null + return undefined; +} +exports.domainSort = domainSort; +/** + * 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: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef) + }; + } + if (!aggregate_1.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 }; +} +exports.canUseUnaggregatedDomain = canUseUnaggregatedDomain; +/** + * Converts an array of domains to a single Vega scale domain. + */ +function mergeDomains(domains) { + var uniqueDomains = util.unique(domains.map(function (domain) { + // ignore sort property when computing the unique domains + if (vega_schema_1.isDataRefDomain(domain)) { + var _s = domain.sort, domainWithoutSort = __rest(domain, ["sort"]); + return domainWithoutSort; + } + return domain; + }), util.hash); + var sorts = util.unique(domains.map(function (d) { + if (vega_schema_1.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 (vega_schema_1.isDataRefDomain(domain) && sorts.length > 0) { + var sort_2 = sorts[0]; + if (sorts.length > 1) { + log.warn(log.message.MORE_THAN_ONE_SORT); + sort_2 = true; + } + return __assign({}, domain, { sort: sort_2 }); + } + 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 (vega_schema_1.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 } : {})); +} +exports.mergeDomains = mergeDomains; +/** + * Return a field if a scale single field. + * Return `undefined` otherwise. + * + */ +function getFieldFromDomain(domain) { + if (vega_schema_1.isDataRefDomain(domain) && util.isString(domain.field)) { + return domain.field; + } + else if (vega_schema_2.isDataRefUnionedDomain(domain)) { + var field = void 0; + for (var _i = 0, _a = domain.fields; _i < _a.length; _i++) { + var nonUnionDomain = _a[_i]; + if (vega_schema_1.isDataRefDomain(nonUnionDomain) && util.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 (vega_schema_2.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 util.isString(field) ? field : undefined; + } + return undefined; +} +exports.getFieldFromDomain = getFieldFromDomain; +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 (vega_schema_1.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); +} +exports.assembleDomain = assembleDomain; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvZG9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2Q0FBdUQ7QUFDdkQsaUNBQXNDO0FBQ3RDLHlDQUEyRDtBQUMzRCxtQ0FBcUM7QUFDckMsMkNBQWtFO0FBRWxFLCtCQUFpQztBQUNqQyxxQ0FBNkc7QUFDN0csbUNBQWtEO0FBQ2xELGlDQUFtQztBQUNuQyxpREFRMkI7QUFDM0IsaURBQWdGO0FBQ2hGLG9DQUEyQztBQUMzQyw2Q0FBb0Q7QUFDcEQsa0NBQTBEO0FBQzFELG9EQUF3RDtBQUt4RCwwQkFBaUMsS0FBWTtJQUMzQyxFQUFFLENBQUMsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTix1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0FBQ0gsQ0FBQztBQU5ELDRDQU1DO0FBRUQsOEJBQThCLEtBQWdCO0lBQzVDLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUM7SUFDckMsSUFBTSxvQkFBb0IsR0FBd0IsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFFekUsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLE9BQXFCO1FBQzVELElBQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2QyxJQUFNLGVBQWUsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUUzRSxJQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENB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QztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQXhCRCxnREF3QkM7QUFFRCx3QkFBK0IsS0FBWSxFQUFFLE9BQXFCO0lBQ2hFLElBQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZELElBQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQUEsTUFBTTtRQUMvQywwRUFBMEU7UUFDMUUsd0VBQXdFO1FBQ3hFLDhCQUE4QjtRQUU5QixFQUFFLENBQUMsQ0FBQyw2QkFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1QixNQUFNLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUNELE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxzRUFBc0U7SUFDdEUsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBZkQsd0NBZUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1NIQVJFRF9ET01BSU5fT1BfSU5ERVh9IGZyb20gJy4uLy4uL2FnZ3JlZ2F0ZSc7XG5pbXBvcnQge2JpblRvU3RyaW5nfSBmcm9tICcuLi8uLi9iaW4nO1xuaW1wb3J0IHtpc1NjYWxlQ2hhbm5lbCwgU2NhbGVDaGFubmVsfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7TUFJTiwgUkFXfSBmcm9tICcuLi8uLi9kYXRhJztcbmltcG9ydCB7RGF0ZVRpbWUsIGRhdGVUaW1lRXhwciwgaXNEYXRlVGltZX0gZnJvbSAnLi4vLi4vZGF0ZXRpbWUnO1xuaW1wb3J0IHtGaWVsZERlZn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge0RvbWFpbiwgaGFzRGlzY3JldGVEb21haW4sIGlzQmluU2NhbGUsIGlzU2VsZWN0aW9uRG9tYWluLCBTY2FsZUNvbmZpZywgU2NhbGVUeXBlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge2lzU29ydEZpZWxkLCBTb3J0RmllbGR9IGZyb20gJy4uLy4uL3NvcnQnO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7XG4gIGlzRGF0YVJlZkRvbWFpbixcbiAgVmdEYXRhUmVmLFxuICBWZ0RvbWFpbixcbiAgVmdGaWVsZFJlZlVuaW9uRG9tYWluLFxuICBWZ05vblVuaW9uRG9tYWluLFxuICBWZ1NvcnRGaWVsZCxcbiAgVmdVbmlvblNvcnRGaWVsZFxufSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge2lzRGF0YVJlZlVuaW9uZWREb21haW4sIGlzRmllbGRSZWZVbmlvbkRvbWFpbn0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtiaW5SZXF1aXJlc1JhbmdlfSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHtGQUNFVF9TQ0FMRV9QUkVGSVh9IGZyb20gJy4uL2RhdGEvb3B0aW1pemUnO1xuaW1wb3J0IHtpc0ZhY2V0TW9kZWwsIGlzVW5pdE1vZGVsLCBNb2RlbH0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtTRUxFQ1RJT05fRE9NQUlOfSBmcm9tICcuLi9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7U2NhbGVDb21wb25lbnRJbmRleH0gZnJvbSAnLi9jb21wb25lbnQnO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNjYWxlRG9tYWluKG1vZGVsOiBNb2RlbCkge1xuICBpZiAoaXNVbml0TW9kZWwobW9kZWwpKSB7XG4gICAgcGFyc2VVbml0U2NhbGVEb21haW4obW9kZWwpO1xuICB9IGVsc2Uge1xuICAgIHBhcnNlTm9uVW5pdFNjYWxlRG9tYWluKG1vZGVsKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVVuaXRTY2FsZURvbWFpbihtb2RlbDogVW5pdE1vZGVsKSB7XG4gIGNvbnN0IHNjYWxlcyA9IG1vZGVsLnNwZWNpZmllZFNjYWxlcztcbiAgY29uc3QgbG9jYWxTY2FsZUNvbXBvbmVudHM6IFNjYWxlQ29tcG9uZW50SW5kZXggPSBtb2RlbC5jb21wb25lbnQuc2NhbGVzO1xuXG4gIHV0aWwua2V5cyhsb2NhbFNjYWxlQ29tcG9uZW50cykuZm9yRWFjaCgoY2hhbm5lbDogU2NhbGVDaGFubmVsKSA9PiB7XG4gICAgY29uc3Qgc3BlY2lmaWVkU2NhbGUgPSBzY2FsZXNbY2hhbm5lbF07XG4gICAgY29uc3Qgc3BlY2lmaWVkRG9tYWluID0gc3BlY2lmaWVkU2NhbGUgPyBzcGVjaWZpZWRTY2FsZS5kb21haW4gOiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBkb21haW5zID0gcGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCBjaGFubmVsKTtcbiAgICBjb25zdCBsb2NhbFNjYWxlQ21wdCA9IGxvY2FsU2NhbGVDb21wb25lbnRzW2NoYW5uZWxdO1xuICAgIGxvY2FsU2NhbGVDbXB0LmRvbWFpbnMgPSBkb21haW5zO1xuXG4gICAgaWYgKGlzU2VsZWN0aW9uRG9tYWluKHNwZWNpZmllZERvbWFpbikpIHtcbiAgICAgIC8vIEFzIHNjYWxlIHBhcnNpbmcgb2NjdXJzIGJlZm9yZSBzZWxlY3Rpb24gcGFyc2luZywgd2UgdXNlIGEgdGVtcG9yYXJ5XG4gICAgICAvLyBzaWduYWwgaGVyZSBhbmQgYXBwZW5kIHRoZSBzY2FsZS5kb21haW4gZGVmaW5pdGlvbi4gVGhpcyBpcyByZXBsYWNlZFxuICAgICAgLy8gd2l0aCB0aGUgY29ycmVjdCBkb21haW5SYXcgc2lnbmFsIGR1cmluZyBzY2FsZSBhc3NlbWJseS5cbiAgICAgIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgaXNSYXdTZWxlY3Rpb25Eb21haW4gaW4gc2VsZWN0aW9uLnRzLlxuXG4gICAgICAvLyBGSVhNRTogcmVwbGFjZSB0aGlzIHdpdGggYSBzcGVjaWFsIHByb3BlcnR5IGluIHRoZSBzY2FsZUNvbXBvbmVudFxuICAgICAgbG9jYWxTY2FsZUNtcHQuc2V0KCdkb21haW5SYXcnLCB7XG4gICAgICAgIHNpZ25hbDogU0VMRUNUSU9OX0RPTUFJTiArIEpTT04uc3RyaW5naWZ5KHNwZWNpZmllZERvbWFpbilcbiAgICAgIH0sIHRydWUpO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlTm9uVW5pdFNjYWxlRG9tYWluKG1vZGVsOiBNb2RlbCkge1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIG1vZGVsLmNoaWxkcmVuKSB7XG4gICAgcGFyc2VTY2FsZURvbWFpbihjaGlsZCk7XG4gIH1cblxuICBjb25zdCBsb2NhbFNjYWxlQ29tcG9uZW50czogU2NhbGVDb21wb25lbnRJbmRleCA9IG1vZGVsLmNvbXBvbmVudC5zY2FsZXM7XG5cbiAgdXRpbC5rZXlzKGxvY2FsU2NhbGVDb21wb25lbnRzKS5mb3JFYWNoKChjaGFubmVsOiBTY2FsZUNoYW5uZWwpID0+IHtcbiAgICAvLyBGSVhNRTogQXJ2aW5kIC0tIFBsZWFzZSByZXZpc2UgbG9naWMgZm9yIG1lcmdpbmcgc2VsZWN0aW9uRG9tYWluIC8gZG9tYWluUmF3XG5cbiAgICBsZXQgZG9tYWluczogVmdOb25VbmlvbkRvbWFpbltdO1xuXG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgICAgY29uc3QgY2hpbGRDb21wb25lbnQgPSBjaGlsZC5jb21wb25lbnQuc2NhbGVzW2NoYW5uZWxdO1xuICAgICAgaWYgKGNoaWxkQ29tcG9uZW50KSB7XG4gICAgICAgIGlmIChkb21haW5zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBkb21haW5zID0gY2hpbGRDb21wb25lbnQuZG9tYWlucztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkb21haW5zID0gZG9tYWlucy5jb25jYXQoY2hpbGRDb21wb25lbnQuZG9tYWlucyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNGYWNldE1vZGVsKG1vZGVsKSkge1xuICAgICAgZG9tYWlucy5mb3JFYWNoKChkb21haW4pID0+IHtcbiAgICAgICAgLy8gUmVwbGFjZSB0aGUgc2NhbGUgZG9tYWluIHdpdGggZGF0YSBvdXRwdXQgZnJvbSBhIGNsb25lZCBzdWJ0cmVlIGFmdGVyIHRoZSBmYWNldC5cbiAgICAgICAgaWYgKGlzRGF0YVJlZkRvbWFpbihkb21haW4pKSB7XG4gICAgICAgICAgLy8gdXNlIGRhdGEgZnJvbSBjbG9uZWQgc3VidHJlZSAod2hpY2ggaXMgdGhlIHNhbWUgYXMgZGF0YSBidXQgd2l0aCBhIHByZWZpeCBhZGRlZCBvbmNlKVxuICAgICAgICAgIGRvbWFpbi5kYXRhID0gRkFDRVRfU0NBTEVfUFJFRklYICsgZG9tYWluLmRhdGEucmVwbGFjZShGQUNFVF9TQ0FMRV9QUkVGSVgsICcnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbG9jYWxTY2FsZUNvbXBvbmVudHNbY2hhbm5lbF0uZG9tYWlucyA9IGRvbWFpbnM7XG4gIH0pO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlIHVuYWdncmVnYXRlZCBkb21haW4gaWYgaXQgaXMgbm90IGFwcGxpY2FibGVcbiAqIEFkZCB1bmFnZ3JlZ2F0ZWQgZG9tYWluIGlmIGRvbWFpbiBpcyBub3Qgc3BlY2lmaWVkIGFuZCBjb25maWcuc2NhbGUudXNlVW5hZ2dyZWdhdGVkRG9tYWluIGlzIHRydWUuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVVuYWdncmVnYXRlZERvbWFpbihkb21haW46IERvbWFpbiwgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIHNjYWxlVHlwZTogU2NhbGVUeXBlLCBzY2FsZUNvbmZpZzogU2NhbGVDb25maWcpIHtcbiAgaWYgKGRvbWFpbiA9PT0gJ3VuYWdncmVnYXRlZCcpIHtcbiAgICBjb25zdCB7dmFsaWQsIHJlYXNvbn0gPSBjYW5Vc2VVbmFnZ3JlZ2F0ZWREb21haW4oZmllbGREZWYsIHNjYWxlVHlwZSk7XG4gICAgaWYoIXZhbGlkKSB7XG4gICAgICBsb2cud2FybihyZWFzb24pO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZG9tYWluID09PSB1bmRlZmluZWQgJiYgc2NhbGVDb25maWcudXNlVW5hZ2dyZWdhdGVkRG9tYWluKSB7XG4gICAgLy8gQXBwbHkgY29uZmlnIGlmIGRvbWFpbiBpcyBub3Qgc3BlY2lmaWVkLlxuICAgIGNvbnN0IHt2YWxpZH0gPSBjYW5Vc2VVbmFnZ3JlZ2F0ZWREb21haW4oZmllbGREZWYsIHNjYWxlVHlwZSk7XG4gICAgaWYgKHZhbGlkKSB7XG4gICAgICByZXR1cm4gJ3VuYWdncmVnYXRlZCc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRvbWFpbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbDogVW5pdE1vZGVsLCBjaGFubmVsOiBTY2FsZUNoYW5uZWwpOiBWZ05vblVuaW9uRG9tYWluW10ge1xuICBjb25zdCBzY2FsZVR5cGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKS5nZXQoJ3R5cGUnKTtcblxuICBjb25zdCBkb21haW4gPSBub3JtYWxpemVVbmFnZ3JlZ2F0ZWREb21haW4obW9kZWwuc2NhbGVEb21haW4oY2hhbm5lbCksIG1vZGVsLmZpZWxkRGVmKGNoYW5uZWwpLCBzY2FsZVR5cGUsIG1vZGVsLmNvbmZpZy5zY2FsZSk7XG4gIGlmIChkb21haW4gIT09IG1vZGVsLnNjYWxlRG9tYWluKGNoYW5uZWwpKSB7XG4gICAgbW9kZWwuc3BlY2lmaWVkU2NhbGVzW2NoYW5uZWxdID0ge1xuICAgICAgLi4ubW9kZWwuc3BlY2lmaWVkU2NhbGVzW2NoYW5uZWxdLFxuICAgICAgZG9tYWluXG4gICAgfTtcbiAgfVxuXG4gIC8vIElmIGNoYW5uZWwgaXMgZWl0aGVyIFggb3IgWSB0aGVuIHVuaW9uIHRoZW0gd2l0aCBYMiAmIFkyIGlmIHRoZXkgZXhpc3RcbiAgaWYgKGNoYW5uZWwgPT09ICd4JyAmJiBtb2RlbC5jaGFubmVsSGFzRmllbGQoJ3gyJykpIHtcbiAgICBpZiAobW9kZWwuY2hhbm5lbEhhc0ZpZWxkKCd4JykpIHtcbiAgICAgIHJldHVybiBwYXJzZVNpbmdsZUNoYW5uZWxEb21haW4oc2NhbGVUeXBlLCBkb21haW4sIG1vZGVsLCAneCcpLmNvbmNhdChwYXJzZVNpbmdsZUNoYW5uZWxEb21haW4oc2NhbGVUeXBlLCBkb21haW4sIG1vZGVsLCAneDInKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYXJzZVNpbmdsZUNoYW5uZWxEb21haW4oc2NhbGVUeXBlLCBkb21haW4sIG1vZGVsLCAneDInKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoY2hhbm5lbCA9PT0gJ3knICYmIG1vZGVsLmNoYW5uZWxIYXNGaWVsZCgneTInKSkge1xuICAgIGlmIChtb2RlbC5jaGFubmVsSGFzRmllbGQoJ3knKSkge1xuICAgICAgcmV0dXJuIHBhcnNlU2luZ2xlQ2hhbm5lbERvbWFpbihzY2FsZVR5cGUsIGRvbWFpbiwgbW9kZWwsICd5JykuY29uY2F0KHBhcnNlU2luZ2xlQ2hhbm5lbERvbWFpbihzY2FsZVR5cGUsIGRvbWFpbiwgbW9kZWwsICd5MicpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHBhcnNlU2luZ2xlQ2hhbm5lbERvbWFpbihzY2FsZVR5cGUsIGRvbWFpbiwgbW9kZWwsICd5MicpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcGFyc2VTaW5nbGVDaGFubmVsRG9tYWluKHNjYWxlVHlwZSwgZG9tYWluLCBtb2RlbCwgY2hhbm5lbCk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU2luZ2xlQ2hhbm5lbERvbWFpbihzY2FsZVR5cGU6IFNjYWxlVHlwZSwgZG9tYWluOiBEb21haW4sIG1vZGVsOiBVbml0TW9kZWwsIGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCB8ICd4MicgfCAneTInKTogVmdOb25VbmlvbkRvbWFpbltdIHtcbiAgY29uc3QgZmllbGREZWYgPSBtb2RlbC5maWVsZERlZihjaGFubmVsKTtcblxuICBpZiAoZG9tYWluICYmIGRvbWFpbiAhPT0gJ3VuYWdncmVnYXRlZCcgJiYgIWlzU2VsZWN0aW9uRG9tYWluKGRvbWFpbikpIHsgLy8gZXhwbGljaXQgdmFsdWVcbiAgICBpZiAoZmllbGREZWYuYmluKSB7XG4gICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5jb25mbGljdGVkRG9tYWluKGNoYW5uZWwpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzRGF0ZVRpbWUoZG9tYWluWzBdKSkge1xuICAgICAgICByZXR1cm4gKGRvbWFpbiBhcyBEYXRlVGltZVtdKS5tYXAoKGR0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHtzaWduYWw6IGB7ZGF0YTogJHtkYXRlVGltZUV4cHIoZHQsIHRydWUpfX1gfTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW2RvbWFpbl07XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc3RhY2sgPSBtb2RlbC5zdGFjaztcbiAgaWYgKHN0YWNrICYmIGNoYW5uZWwgPT09IHN0YWNrLmZpZWxkQ2hhbm5lbCkge1xuICAgIGlmKHN0YWNrLm9mZnNldCA9PT0gJ25vcm1hbGl6ZScpIHtcbiAgICAgIHJldHVybiBbWzAsIDFdXTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gbW9kZWwucmVxdWVzdERhdGFOYW1lKE1BSU4pO1xuICAgIHJldHVybiBbe1xuICAgICAgZGF0YSxcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChjaGFubmVsLCB7c3VmZml4OiAnc3RhcnQnfSlcbiAgICB9LCB7XG4gICAgICBkYXRhLFxuICAgICAgZmllbGQ6IG1vZGVsLmZpZWxkKGNoYW5uZWwsIHtzdWZmaXg6ICdlbmQnfSlcbiAgICB9XTtcbiAgfVxuXG4gIGNvbnN0IHNvcnQgPSBpc1NjYWxlQ2hhbm5lbChjaGFubmVsKSA/IGRvbWFpblNvcnQobW9kZWwsIGNoYW5uZWwsIHNjYWxlVHlwZSkgOiB1bmRlZmluZWQ7XG5cbiAgaWYgKGRvbWFpbiA9PT0gJ3VuYWdncmVnYXRlZCcpIHtcbiAgICBjb25zdCBkYXRhID0gbW9kZWwucmVxdWVzdERhdGFOYW1lKE1BSU4pO1xuICAgIHJldHVybiBbe1xuICAgICAgZGF0YSxcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChjaGFubmVsLCB7YWdncmVnYXRlOiAnbWluJ30pXG4gICAgfSwge1xuICAgICAgZGF0YSxcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChjaGFubmVsLCB7YWdncmVnYXRlOiAnbWF4J30pXG4gICAgfV07XG4gIH0gZWxzZSBpZiAoZmllbGREZWYuYmluKSB7IC8vIGJpblxuICAgIGlmIChpc0JpblNjYWxlKHNjYWxlVHlwZSkpIHtcbiAgICAgIGNvbnN0IHNpZ25hbCA9IG1vZGVsLmdldE5hbWUoYCR7YmluVG9TdHJpbmcoZmllbGREZWYuYmluKX1fJHtmaWVsZERlZi5maWVsZH1fYmluc2ApO1xuICAgICAgcmV0dXJuIFt7c2lnbmFsOiBgc2VxdWVuY2UoJHtzaWduYWx9LnN0YXJ0LCAke3NpZ25hbH0uc3RvcCArICR7c2lnbmFsfS5zdGVwLCAke3NpZ25hbH0uc3RlcClgfV07XG4gICAgfVxuXG4gICAgaWYgKGhhc0Rpc2NyZXRlRG9tYWluKHNjYWxlVHlwZSkpIHtcbiAgICAgIC8vIG9yZGluYWwgYmluIHNjYWxlIHRha2VzIGRvbWFpbiBmcm9tIGJpbl9yYW5nZSwgb3JkZXJlZCBieSBiaW4gc3RhcnRcbiAgICAgIC8vIFRoaXMgaXMgdXNlZnVsIGZvciBib3RoIGF4aXMtYmFzZWQgc2NhbGUgKHgveSkgYW5kIGxlZ2VuZC1iYXNlZCBzY2FsZSAob3RoZXIgY2hhbm5lbHMpLlxuICAgICAgcmV0dXJuIFt7XG4gICAgICAgIC8vIElmIHNvcnQgYnkgYWdncmVnYXRpb24gb2YgYSBzcGVjaWZpZWQgc29ydCBmaWVsZCwgd2UgbmVlZCB0byB1c2UgUkFXIHRhYmxlLFxuICAgICAgICAvLyBzbyB3ZSBjYW4gYWdncmVnYXRlIHZhbHVlcyBmb3IgdGhlIHNjYWxlIGluZGVwZW5kZW50bHkgZnJvbSB0aGUgbWFpbiBhZ2dyZWdhdGlvbi5cbiAgICAgICAgZGF0YTogdXRpbC5pc0Jvb2xlYW4oc29ydCkgPyBtb2RlbC5yZXF1ZXN0RGF0YU5hbWUoTUFJTikgOiBtb2RlbC5yZXF1ZXN0RGF0YU5hbWUoUkFXKSxcbiAgICAgICAgLy8gVXNlIHJhbmdlIGlmIHdlIGFkZGVkIGl0IGFuZCB0aGUgc2NhbGUgZG9lcyBub3Qgc3VwcG9ydCBjb21wdXRpbmcgYSByYW5nZSBhcyBhIHNpZ25hbC5cbiAgICAgICAgZmllbGQ6IG1vZGVsLmZpZWxkKGNoYW5uZWwsIGJpblJlcXVpcmVzUmFuZ2UoZmllbGREZWYsIGNoYW5uZWwpID8ge2JpblN1ZmZpeDogJ3JhbmdlJ30gOiB7fSksXG4gICAgICAgIC8vIHdlIGhhdmUgdG8gdXNlIGEgc29ydCBvYmplY3QgaWYgc29ydCA9IHRydWUgdG8gbWFrZSB0aGUgc29ydCBjb3JyZWN0IGJ5IGJpbiBzdGFydFxuICAgICAgICBzb3J0OiBzb3J0ID09PSB0cnVlIHx8ICFpc1NvcnRGaWVsZChzb3J0KSA/IHtcbiAgICAgICAgICBmaWVsZDogbW9kZWwuZmllbGQoY2hhbm5lbCwge30pLFxuICAgICAgICAgIG9wOiAnbWluJyAvLyBtaW4gb3IgbWF4IGRvZXNuJ3QgbWF0dGVyIHNpbmNlIHdlIHNvcnQgYnkgdGhlIHN0YXJ0IG9mIHRoZSBiaW4gcmFuZ2VcbiAgICAgICAgfSA6IHNvcnRcbiAgICAgIH1dO1xuICAgIH0gZWxzZSB7IC8vIGNvbnRpbnVvdXMgc2NhbGVzXG4gICAgICBpZiAoY2hhbm5lbCA9PT0gJ3gnIHx8IGNoYW5uZWwgPT09ICd5Jykge1xuICAgICAgICAvLyBYL1kgcG9zaXRpb24gaGF2ZSB0byBpbmNsdWRlIHN0YXJ0IGFuZCBlbmQgZm9yIG5vbi1vcmRpbmFsIHNjYWxlXG4gICAgICAgIGNvbnN0IGRhdGEgPSBtb2RlbC5yZXF1ZXN0RGF0YU5hbWUoTUFJTik7XG4gICAgICAgIHJldHVybiBbe1xuICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgZmllbGQ6IG1vZGVsLmZpZWxkKGNoYW5uZWwsIHt9KVxuICAgICAgICB9LCB7XG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBmaWVsZDogbW9kZWwuZmllbGQoY2hhbm5lbCwge2JpblN1ZmZpeDogJ2VuZCd9KVxuICAgICAgICB9XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IHVzZSBiaW5fbWlkXG4gICAgICAgIHJldHVybiBbe1xuICAgICAgICAgIGRhdGE6IG1vZGVsLnJlcXVlc3REYXRhTmFtZShNQUlOKSxcbiAgICAgICAgICBmaWVsZDogbW9kZWwuZmllbGQoY2hhbm5lbCwge30pXG4gICAgICAgIH1dO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChzb3J0KSB7XG4gICAgcmV0dXJuIFt7XG4gICAgICAvLyBJZiBzb3J0IGJ5IGFnZ3JlZ2F0aW9uIG9mIGEgc3BlY2lmaWVkIHNvcnQgZmllbGQsIHdlIG5lZWQgdG8gdXNlIFJBVyB0YWJsZSxcbiAgICAgIC8vIHNvIHdlIGNhbiBhZ2dyZWdhdGUgdmFsdWVzIGZvciB0aGUgc2NhbGUgaW5kZXBlbmRlbnRseSBmcm9tIHRoZSBtYWluIGFnZ3JlZ2F0aW9uLlxuICAgICAgZGF0YTogdXRpbC5pc0Jvb2xlYW4oc29ydCkgPyBtb2RlbC5yZXF1ZXN0RGF0YU5hbWUoTUFJTikgOiBtb2RlbC5yZXF1ZXN0RGF0YU5hbWUoUkFXKSxcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChjaGFubmVsKSxcbiAgICAgIHNvcnQ6IHNvcnRcbiAgICB9XTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW3tcbiAgICAgIGRhdGE6IG1vZGVsLnJlcXVlc3REYXRhTmFtZShNQUlOKSxcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChjaGFubmVsKVxuICAgIH1dO1xuICB9XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGRvbWFpblNvcnQobW9kZWw6IFVuaXRNb2RlbCwgY2hhbm5lbDogU2NhbGVDaGFubmVsLCBzY2FsZVR5cGU6IFNjYWxlVHlwZSk6IHRydWUgfCBTb3J0RmllbGQ8c3RyaW5nPiB7XG4gIGlmICghaGFzRGlzY3JldGVEb21haW4oc2NhbGVUeXBlKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBzb3J0ID0gbW9kZWwuc29ydChjaGFubmVsKTtcblxuICAvLyBTb3J0ZWQgYmFzZWQgb24gYW4gYWdncmVnYXRlIGNhbGN1bGF0aW9uIG92ZXIgYSBzcGVjaWZpZWQgc29ydCBmaWVsZCAob25seSBmb3Igb3JkaW5hbCBzY2FsZSlcbiAgaWYgKGlzU29ydEZpZWxkKHNvcnQpKSB7XG4gICAgcmV0dXJuIHNvcnQ7XG4gIH1cblxuICBpZiAoc29ydCA9PT0gJ2Rlc2NlbmRpbmcnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wOiAnbWluJyxcbiAgICAgIGZpZWxkOiBtb2RlbC5maWVsZChjaGFubmVsKSxcbiAgICAgIG9yZGVyOiAnZGVzY2VuZGluZydcbiAgICB9O1xuICB9XG5cbiAgaWYgKHV0aWwuY29udGFpbnMoWydhc2NlbmRpbmcnLCB1bmRlZmluZWQgLyogZGVmYXVsdCA9YXNjZW5kaW5nKi9dLCBzb3J0KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gc29ydCA9PSBudWxsXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cblxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHNjYWxlIGNhbiB1c2UgdW5hZ2dyZWdhdGVkIGRvbWFpbi5cbiAqIEByZXR1cm4ge0Jvb2xlYW59IFJldHVybnMgdHJ1ZSBpZiBhbGwgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRvbnMgYXBwbGllczpcbiAqIDEuIGBzY2FsZS5kb21haW5gIGlzIGB1bmFnZ3JlZ2F0ZWRgXG4gKiAyLiBBZ2dyZWdhdGlvbiBmdW5jdGlvbiBpcyBub3QgYGNvdW50YCBvciBgc3VtYFxuICogMy4gVGhlIHNjYWxlIGlzIHF1YW50aXRhdGl2ZSBvciB0aW1lIHNjYWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FuVXNlVW5hZ2dyZWdhdGVkRG9tYWluKGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBzY2FsZVR5cGU6IFNjYWxlVHlwZSk6IHt2YWxpZDogYm9vbGVhbiwgcmVhc29uPzogc3RyaW5nfSB7XG4gIGlmICghZmllbGREZWYuYWdncmVnYXRlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIHJlYXNvbjogbG9nLm1lc3NhZ2UudW5hZ2dyZWdhdGVEb21haW5IYXNOb0VmZmVjdEZvclJhd0ZpZWxkKGZpZWxkRGVmKVxuICAgIH07XG4gIH1cblxuICBpZiAoIVNIQVJFRF9ET01BSU5fT1BfSU5ERVhbZmllbGREZWYuYWdncmVnYXRlXSkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICByZWFzb246IGxvZy5tZXNzYWdlLnVuYWdncmVnYXRlRG9tYWluV2l0aE5vblNoYXJlZERvbWFpbk9wKGZpZWxkRGVmLmFnZ3JlZ2F0ZSlcbiAgICB9O1xuICB9XG5cbiAgaWYgKGZpZWxkRGVmLnR5cGUgPT09ICdxdWFudGl0YXRpdmUnKSB7XG4gICAgaWYgKHNjYWxlVHlwZSA9PT0gJ2xvZycpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgcmVhc29uOiBsb2cubWVzc2FnZS51bmFnZ3JlZ2F0ZWREb21haW5XaXRoTG9nU2NhbGUoZmllbGREZWYpXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7dmFsaWQ6IHRydWV9O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGFuIGFycmF5IG9mIGRvbWFpbnMgdG8gYSBzaW5nbGUgVmVnYSBzY2FsZSBkb21haW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURvbWFpbnMoZG9tYWluczogVmdOb25VbmlvbkRvbWFpbltdKTogVmdEb21haW4ge1xuICBjb25zdCB1bmlxdWVEb21haW5zID0gdXRpbC51bmlxdWUoZG9tYWlucy5tYXAoZG9tYWluID0+IHtcbiAgICAvLyBpZ25vcmUgc29ydCBwcm9wZXJ0eSB3aGVuIGNvbXB1dGluZyB0aGUgdW5pcXVlIGRvbWFpbnNcbiAgICBpZiAoaXNEYXRhUmVmRG9tYWluKGRvbWFpbikpIHtcbiAgICAgIGNvbnN0IHtzb3J0OiBfcywgLi4uZG9tYWluV2l0aG91dFNvcnR9ID0gZG9tYWluO1xuICAgICAgcmV0dXJuIGRvbWFpbldpdGhvdXRTb3J0O1xuICAgIH1cbiAgICByZXR1cm4gZG9tYWluO1xuICB9KSwgdXRpbC5oYXNoKTtcblxuICBjb25zdCBzb3J0czogVmdTb3J0RmllbGRbXSA9IHV0aWwudW5pcXVlKGRvbWFpbnMubWFwKGQgPT4ge1xuICAgIGlmIChpc0RhdGFSZWZEb21haW4oZCkpIHtcbiAgICAgIGNvbnN0IHMgPSBkLnNvcnQ7XG4gICAgICBpZiAocyAhPT0gdW5kZWZpbmVkICYmICF1dGlsLmlzQm9vbGVhbihzKSkge1xuICAgICAgICBpZiAocy5vcCA9PT0gJ2NvdW50Jykge1xuICAgICAgICAgIC8vIGxldCdzIG1ha2Ugc3VyZSB0aGF0IGlmIG9wIGlzIGNvdW50LCB3ZSBkb24ndCB1c2UgYSBmaWVsZFxuICAgICAgICAgIGRlbGV0ZSBzLmZpZWxkO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzLm9yZGVyID09PSAnYXNjZW5kaW5nJykge1xuICAgICAgICAgIC8vIGRyb3Agb3JkZXI6IGFzY2VuZGluZyBhcyBpdCBpcyB0aGUgZGVmYXVsdFxuICAgICAgICAgIGRlbGV0ZSBzLm9yZGVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcztcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSkuZmlsdGVyKHMgPT4gcyAhPT0gdW5kZWZpbmVkKSwgdXRpbC5oYXNoKTtcblxuICBpZiAodW5pcXVlRG9tYWlucy5sZW5ndGggPT09IDEpIHtcbiAgICBjb25zdCBkb21haW4gPSBkb21haW5zWzBdO1xuICAgIGlmIChpc0RhdGFSZWZEb21haW4oZG9tYWluKSAmJiBzb3J0cy5sZW5ndGggPiAwKSB7XG4gICAgICBsZXQgc29ydCA9IHNvcnRzWzBdO1xuICAgICAgaWYgKHNvcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuTU9SRV9USEFOX09ORV9TT1JUKTtcbiAgICAgICAgc29ydCA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5kb21haW4sXG4gICAgICAgIHNvcnRcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBkb21haW47XG4gIH1cblxuICAvLyBvbmx5IGtlZXAgc2ltcGxlIHNvcnQgcHJvcGVydGllcyB0aGF0IHdvcmsgd2l0aCB1bmlvbmVkIGRvbWFpbnNcbiAgY29uc3Qgc2ltcGxlU29ydHMgPSB1dGlsLnVuaXF1ZShzb3J0cy5tYXAocyA9PiB7XG4gICAgaWYgKHMgPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBzO1xuICAgIH1cbiAgICBpZiAocy5vcCA9PT0gJ2NvdW50Jykge1xuICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmRvbWFpblNvcnREcm9wcGVkKHMpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSksIHV0aWwuaGFzaCkgYXMgVmdVbmlvblNvcnRGaWVsZFtdO1xuXG4gIGxldCBzb3J0OiBWZ1VuaW9uU29ydEZpZWxkID0gdW5kZWZpbmVkO1xuXG4gIGlmIChzaW1wbGVTb3J0cy5sZW5ndGggPT09IDEpIHtcbiAgICBzb3J0ID0gc2ltcGxlU29ydHNbMF07XG4gIH0gZWxzZSBpZiAoc2ltcGxlU29ydHMubGVuZ3RoID4gMSkge1xuICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLk1PUkVfVEhBTl9PTkVfU09SVCk7XG4gICAgc29ydCA9IHRydWU7XG4gIH1cblxuICBjb25zdCBhbGxEYXRhID0gdXRpbC51bmlxdWUoZG9tYWlucy5tYXAoZCA9PiB7XG4gICAgaWYgKGlzRGF0YVJlZkRvbWFpbihkKSkge1xuICAgICAgcmV0dXJuIGQuZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0pLCB4ID0+IHgpO1xuXG4gIGlmIChhbGxEYXRhLmxlbmd0aCA9PT0gMSAmJiBhbGxEYXRhWzBdICE9PSBudWxsKSB7XG4gICAgLy8gY3JlYXRlIGEgdW5pb24gZG9tYWluIG9mIGRpZmZlcmVudCBmaWVsZHMgd2l0aCBhIHNpbmdsZSBkYXRhIHNvdXJjZVxuICAgIGNvbnN0IGRvbWFpbjogVmdGaWVsZFJlZlVuaW9uRG9tYWluID0ge1xuICAgICAgZGF0YTogYWxsRGF0YVswXSxcbiAgICAgIGZpZWxkczogdW5pcXVlRG9tYWlucy5tYXAoZCA9PiAoZCBhcyBWZ0RhdGFSZWYpLmZpZWxkKSxcbiAgICAgIC4uLihzb3J0ID8ge3NvcnR9IDoge30pXG4gICAgfTtcblxuICAgIHJldHVybiBkb21haW47XG4gIH1cblxuICByZXR1cm4ge2ZpZWxkczogdW5pcXVlRG9tYWlucywgLi4uKHNvcnQgPyB7c29ydH0gOiB7fSl9O1xufVxuXG4vKipcbiAqIFJldHVybiBhIGZpZWxkIGlmIGEgc2NhbGUgc2luZ2xlIGZpZWxkLlxuICogUmV0dXJuIGB1bmRlZmluZWRgIG90aGVyd2lzZS5cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGaWVsZEZyb21Eb21haW4oZG9tYWluOiBWZ0RvbWFpbik6IHN0cmluZyB7XG4gIGlmIChpc0RhdGFSZWZEb21haW4oZG9tYWluKSAmJiB1dGlsLmlzU3RyaW5nKGRvbWFpbi5maWVsZCkpIHtcbiAgICByZXR1cm4gZG9tYWluLmZpZWxkO1xuICB9IGVsc2UgaWYgKGlzRGF0YVJlZlVuaW9uZWREb21haW4oZG9tYWluKSkge1xuICAgIGxldCBmaWVsZDtcbiAgICBmb3IgKGNvbnN0IG5vblVuaW9uRG9tYWluIG9mIGRvbWFpbi5maWVsZHMpIHtcbiAgICAgIGlmIChpc0RhdGFSZWZEb21haW4obm9uVW5pb25Eb21haW4pICYmIHV0aWwuaXNTdHJpbmcobm9uVW5pb25Eb21haW4uZmllbGQpKSB7XG4gICAgICAgIGlmICghZmllbGQpIHtcbiAgICAgICAgICBmaWVsZCA9IG5vblVuaW9uRG9tYWluLmZpZWxkO1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkICE9PSBub25VbmlvbkRvbWFpbi5maWVsZCkge1xuICAgICAgICAgIGxvZy53YXJuKCdEZXRlY3RlZCBmYWNldGVkIGluZGVwZW5kZW50IHNjYWxlcyB0aGF0IHVuaW9uIGRvbWFpbiBvZiBtdWx0aXBsZSBmaWVsZHMgZnJvbSBkaWZmZXJlbnQgZGF0YSBzb3VyY2VzLiAgV2Ugd2lsbCB1c2UgdGhlIGZpcnN0IGZpZWxkLiAgVGhlIHJlc3VsdCB2aWV3IHNpemUgbWF5IGJlIGluY29ycmVjdC4nKTtcbiAgICAgICAgICByZXR1cm4gZmllbGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgbG9nLndhcm4oJ0RldGVjdGVkIGZhY2V0ZWQgaW5kZXBlbmRlbnQgc2NhbGVzIHRoYXQgdW5pb24gZG9tYWluIG9mIGlkZW50aWNhbCBmaWVsZHMgZnJvbSBkaWZmZXJlbnQgc291cmNlIGRldGVjdGVkLiAgV2Ugd2lsbCBhc3N1bWUgdGhhdCB0aGlzIGlzIHRoZSBzYW1lIGZpZWxkIGZyb20gYSBkaWZmZXJlbnQgZm9yayBvZiB0aGUgc2FtZSBkYXRhIHNvdXJjZS4gIEhvd2V2ZXIsIGlmIHRoaXMgaXMgbm90IGNhc2UsIHRoZSByZXN1bHQgdmlldyBzaXplIG1heWJlIGluY29ycmVjdC4nKTtcbiAgICByZXR1cm4gZmllbGQ7XG4gIH0gZWxzZSBpZiAoaXNGaWVsZFJlZlVuaW9uRG9tYWluKGRvbWFpbikpIHtcbiAgICBsb2cud2FybignRGV0ZWN0ZWQgZmFjZXRlZCBpbmRlcGVuZGVudCBzY2FsZXMgdGhhdCB1bmlvbiBkb21haW4gb2YgbXVsdGlwbGUgZmllbGRzIGZyb20gdGhlIHNhbWUgZGF0YSBzb3VyY2UuICBXZSB3aWxsIHVzZSB0aGUgZmlyc3QgZmllbGQuICBUaGUgcmVzdWx0IHZpZXcgc2l6ZSBtYXkgYmUgaW5jb3JyZWN0LicpO1xuICAgIGNvbnN0IGZpZWxkID0gZG9tYWluLmZpZWxkc1swXTtcbiAgICByZXR1cm4gdXRpbC5pc1N0cmluZyhmaWVsZCkgPyBmaWVsZCA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlbWJsZURvbWFpbihtb2RlbDogTW9kZWwsIGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCkge1xuICBjb25zdCBzY2FsZUNvbXBvbmVudCA9IG1vZGVsLmNvbXBvbmVudC5zY2FsZXNbY2hhbm5lbF07XG4gIGNvbnN0IGRvbWFpbnMgPSBzY2FsZUNvbXBvbmVudC5kb21haW5zLm1hcChkb21haW4gPT4ge1xuICAgIC8vIENvcnJlY3QgcmVmZXJlbmNlcyB0byBkYXRhIGFzIHRoZSBvcmlnaW5hbCBkb21haW4ncyBkYXRhIHdhcyBkZXRlcm1pbmVkXG4gICAgLy8gaW4gcGFyc2VTY2FsZSwgd2hpY2ggaGFwcGVucyBiZWZvcmUgcGFyc2VEYXRhLiBUaHVzIHRoZSBvcmlnaW5hbCBkYXRhXG4gICAgLy8gcmVmZXJlbmNlIGNhbiBiZSBpbmNvcnJlY3QuXG5cbiAgICBpZiAoaXNEYXRhUmVmRG9tYWluKGRvbWFpbikpIHtcbiAgICAgIGRvbWFpbi5kYXRhID0gbW9kZWwubG9va3VwRGF0YVNvdXJjZShkb21haW4uZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiBkb21haW47XG4gIH0pO1xuXG4gIC8vIGRvbWFpbnMgaXMgYW4gYXJyYXkgdGhhdCBoYXMgdG8gYmUgbWVyZ2VkIGludG8gYSBzaW5nbGUgdmVnYSBkb21haW5cbiAgcmV0dXJuIG1lcmdlRG9tYWlucyhkb21haW5zKTtcbn1cbiJdfQ== \ 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..3a619d9835 --- /dev/null +++ b/build/src/compile/scale/parse.js @@ -0,0 +1,122 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var resolve_1 = require("../resolve"); +var split_1 = require("../split"); +var component_1 = require("./component"); +var domain_1 = require("./domain"); +var properties_1 = require("./properties"); +var range_1 = require("./range"); +var type_1 = require("./type"); +function parseScale(model) { + parseScaleCore(model); + domain_1.parseScaleDomain(model); + for (var _i = 0, NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1 = scale_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]; + properties_1.parseScaleProperty(model, prop); + } + // range depends on zero + range_1.parseScaleRange(model); +} +exports.parseScale = parseScale; +function parseScaleCore(model) { + if (model_1.isUnitModel(model)) { + model.component.scales = parseUnitScaleCore(model); + } + else { + model.component.scales = parseNonUnitScaleCore(model); + } +} +exports.parseScaleCore = parseScaleCore; +/** + * Parse scales for all channels of a model. + */ +function parseUnitScaleCore(model) { + var encoding = model.encoding, config = model.config; + var mark = model.mark(); + return channel_1.SCALE_CHANNELS.reduce(function (scaleComponents, channel) { + var fieldDef; + var specifiedScale = {}; + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale || {}; + } + else if (fielddef_1.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 = fielddef_1.getFieldDef(encoding.x2); + } + else if (channel === 'y') { + fieldDef = fielddef_1.getFieldDef(encoding.y2); + } + if (fieldDef) { + var specifiedScaleType = specifiedScale.type; + var sType = type_1.scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale); + scaleComponents[channel] = new component_1.ScaleComponent(model.scaleName(channel + '', true), { value: sType, explicit: specifiedScaleType === sType }); + } + return scaleComponents; + }, {}); +} +var scaleTypeTieBreaker = split_1.tieBreakByComparing(function (st1, st2) { return (scale_1.scaleTypePrecedence(st1) - scale_1.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! + util_1.keys(child.component.scales).forEach(function (channel) { + // if resolve is undefined, set default first + resolve.scale[channel] = resolve.scale[channel] || resolve_1.defaultScaleResolve(channel, model); + if (resolve.scale[channel] === 'shared') { + var scaleType_1 = scaleTypeWithExplicitIndex[channel]; + var childScaleType = child.component.scales[channel].getWithExplicit('type'); + if (scaleType_1) { + if (scale_1.scaleCompatible(scaleType_1.value, childScaleType.value)) { + // merge scale component if type are compatible + scaleTypeWithExplicitIndex[channel] = split_1.mergeValuesWithExplicit(scaleType_1, 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 + util_1.keys(scaleTypeWithExplicitIndex).forEach(function (channel) { + // Create new merged scale component + var name = model.scaleName(channel, true); + var typeWithExplicit = scaleTypeWithExplicitIndex[channel]; + scaleComponents[channel] = new component_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9wYXJzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUEyRDtBQUMzRCwyQ0FBeUY7QUFDekYscUNBTXFCO0FBQ3JCLG1DQUFnQztBQUVoQyxrQ0FBNEM7QUFDNUMsc0NBQStDO0FBQy9DLGtDQUFnRjtBQUVoRix5Q0FBZ0U7QUFDaEUsbUNBQTBDO0FBQzFDLDJDQUFnRDtBQUNoRCxpQ0FBd0M7QUFDeEMsK0JBQWlDO0FBRWpDLG9CQUEyQixLQUFZO0lBQ3JDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0Qix5QkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QixHQUFHLENBQUMsQ0FBZSxVQUEyQyxFQUEzQyxnREFBQSxtREFBMkMsRUFBM0MseURBQTJDLEVBQTNDLElBQTJDO1FBQXpELElBQU0sSUFBSSxvREFBQTtRQUNiLCtCQUFrQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztLQUNqQztJQUNELHdCQUF3QjtJQUN4Qix1QkFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFSRCxnQ0FRQztBQUVELHdCQUErQixLQUFZO0lBQ3pDLEVBQUUsQ0FBQyxDQUFDLG1CQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3hELENBQUM7QUFDSCxDQUFDO0FBTkQsd0NBTUM7QUFFRDs7R0FFRztBQUNILDRCQUE0QixLQUFnQjtJQUNuQyxJQUFBLHlCQUFRLEVBQUUscUJBQU0sQ0FBVTtJQUNqQyxJ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QyxVQUFDLE9BQXFCO1FBQzdELG9DQUFvQztRQUNwQyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM1QyxJQUFNLGdCQUFnQixHQUFHLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdELGVBQWUsQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLDBCQUFjLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFdEUsNENBQTRDO1FBQzVDLEdBQUcsQ0FBQyxDQUFnQixVQUFjLEVBQWQsS0FBQSxLQUFLLENBQUMsUUFBUSxFQUFkLGNBQWMsRUFBZCxJQUFjO1lBQTdCLElBQU0sS0FBSyxTQUFBO1lBQ2QsSUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbkQsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDZixLQUFLLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2hELFVBQVUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQzNCLENBQUM7U0FDRjtJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLGVBQWUsQ0FBQztBQUN6QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTQ0FMRV9DSEFOTkVMUywgU2NhbGVDaGFubmVsfSBmcm9tICcuLi8uLi9jaGFubmVsJztcbmltcG9ydCB7RmllbGREZWYsIGdldEZpZWxkRGVmLCBoYXNDb25kaXRpb25hbEZpZWxkRGVmLCBpc0ZpZWxkRGVmfSBmcm9tICcuLi8uLi9maWVsZGRlZic7XG5pbXBvcnQge1xuICBOT05fVFlQRV9ET01BSU5fUkFOR0VfVkVHQV9TQ0FMRV9QUk9QRVJUSUVTLFxuICBTY2FsZSxcbiAgc2NhbGVDb21wYXRpYmxlLFxuICBTY2FsZVR5cGUsXG4gIHNjYWxlVHlwZVByZWNlZGVuY2UsXG59IGZyb20gJy4uLy4uL3NjYWxlJztcbmltcG9ydCB7a2V5c30gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnU2NhbGV9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7aXNVbml0TW9kZWwsIE1vZGVsfSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge2RlZmF1bHRTY2FsZVJlc29sdmV9IGZyb20gJy4uL3Jlc29sdmUnO1xuaW1wb3J0IHtFeHBsaWNpdCwgbWVyZ2VWYWx1ZXNXaXRoRXhwbGljaXQsIHRpZUJyZWFrQnlDb21wYXJpbmd9IGZyb20gJy4uL3NwbGl0JztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi91bml0JztcbmltcG9ydCB7U2NhbGVDb21wb25lbnQsIFNjYWxlQ29tcG9uZW50SW5kZXh9IGZyb20gJy4vY29tcG9uZW50JztcbmltcG9ydCB7cGFyc2VTY2FsZURvbWFpbn0gZnJvbSAnLi9kb21haW4nO1xuaW1wb3J0IHtwYXJzZVNjYWxlUHJvcGVydHl9IGZyb20gJy4vcHJvcGVydGllcyc7XG5pbXBvcnQge3BhcnNlU2NhbGVSYW5nZX0gZnJvbSAnLi9yYW5nZSc7XG5pbXBvcnQge3NjYWxlVHlwZX0gZnJvbSAnLi90eXBlJztcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU2NhbGUobW9kZWw6IE1vZGVsKSB7XG4gIHBhcnNlU2NhbGVDb3JlKG1vZGVsKTtcbiAgcGFyc2VTY2FsZURvbWFpbihtb2RlbCk7XG4gIGZvciAoY29uc3QgcHJvcCBvZiBOT05fVFlQRV9ET01BSU5fUkFOR0VfVkVHQV9TQ0FMRV9QUk9QRVJUSUVTKSB7XG4gICAgcGFyc2VTY2FsZVByb3BlcnR5KG1vZGVsLCBwcm9wKTtcbiAgfVxuICAvLyByYW5nZSBkZXBlbmRzIG9uIHplcm9cbiAgcGFyc2VTY2FsZVJhbmdlKG1vZGVsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU2NhbGVDb3JlKG1vZGVsOiBNb2RlbCkge1xuICBpZiAoaXNVbml0TW9kZWwobW9kZWwpKSB7XG4gICAgbW9kZWwuY29tcG9uZW50LnNjYWxlcyA9IHBhcnNlVW5pdFNjYWxlQ29yZShtb2RlbCk7XG4gIH0gZWxzZSB7XG4gICAgbW9kZWwuY29tcG9uZW50LnNjYWxlcyA9IHBhcnNlTm9uVW5pdFNjYWxlQ29yZShtb2RlbCk7XG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZSBzY2FsZXMgZm9yIGFsbCBjaGFubmVscyBvZiBhIG1vZGVsLlxuICovXG5mdW5jdGlvbiBwYXJzZVVuaXRTY2FsZUNvcmUobW9kZWw6IFVuaXRNb2RlbCk6IFNjYWxlQ29tcG9uZW50SW5kZXgge1xuICBjb25zdCB7ZW5jb2RpbmcsIGNvbmZpZ30gPSBtb2RlbDtcbiAgY29uc3QgbWFyayA9IG1vZGVsLm1hcmsoKTtcblxuICByZXR1cm4gU0NBTEVfQ0hBTk5FTFMucmVkdWNlKChzY2FsZUNvbXBvbmVudHM6IFNjYWxlQ29tcG9uZW50SW5kZXgsIGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCkgPT4ge1xuICAgIGxldCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPjtcbiAgICBsZXQgc3BlY2lmaWVkU2NhbGU6IFNjYWxlID0ge307XG5cbiAgICBjb25zdCBjaGFubmVsRGVmID0gZW5jb2RpbmdbY2hhbm5lbF07XG5cbiAgICBpZiAoaXNGaWVsZERlZihjaGFubmVsRGVmKSkge1xuICAgICAgZmllbGREZWYgPSBjaGFubmVsRGVmO1xuICAgICAgc3BlY2lmaWVkU2NhbGUgPSBjaGFubmVsRGVmLnNjYWxlIHx8IHt9O1xuICAgIH0gZWxzZSBpZiAoaGFzQ29uZGl0aW9uYWxGaWVsZERlZihjaGFubmVsRGVmKSkge1xuICAgICAgZmllbGREZWYgPSBjaGFubmVsRGVmLmNvbmRpdGlvbjtcbiAgICAgIHNwZWNpZmllZFNjYWxlID0gY2hhbm5lbERlZi5jb25kaXRpb25bJ3NjYWxlJ10gfHwge307IC8vIFdlIHVzZSBbJ3NjYWxlJ10gc2luY2Ugd2Uga25vdyB0aGF0IGNoYW5uZWwgaGVyZSBoYXMgc2NhbGUgZm9yIHN1cmVcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWwgPT09ICd4Jykge1xuICAgICAgZmllbGREZWYgPSBnZXRGaWVsZERlZihlbmNvZGluZy54Mik7XG4gICAgfSBlbHNlIGlmIChjaGFubmVsID09PSAneScpIHtcbiAgICAgIGZpZWxkRGVmID0gZ2V0RmllbGREZWYoZW5jb2RpbmcueTIpO1xuICAgIH1cblxuICAgIGlmIChmaWVsZERlZikge1xuICAgICAgY29uc3Qgc3BlY2lmaWVkU2NhbGVUeXBlID0gc3BlY2lmaWVkU2NhbGUudHlwZTtcbiAgICAgIGNvbnN0IHNUeXBlID0gc2NhbGVUeXBlKHNwZWNpZmllZFNjYWxlLnR5cGUsIGNoYW5uZWwsIGZpZWxkRGVmLCBtYXJrLCBjb25maWcuc2NhbGUpO1xuICAgICAgc2NhbGVDb21wb25lbnRzW2NoYW5uZWxdID0gbmV3IFNjYWxlQ29tcG9uZW50KFxuICAgICAgICBtb2RlbC5zY2FsZU5hbWUoY2hhbm5lbCArICcnLCB0cnVlKSxcbiAgICAgICAge3ZhbHVlOiBzVHlwZSwgZXhwbGljaXQ6IHNwZWNpZmllZFNjYWxlVHlwZSA9PT0gc1R5cGV9XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2NhbGVDb21wb25lbnRzO1xuICB9LCB7fSk7XG59XG5cbmNvbnN0IHNjYWxlVHlwZVRpZUJyZWFrZXIgPSB0aWVCcmVha0J5Q29tcGFyaW5nKFxuICAoc3QxOiBTY2FsZVR5cGUsIHN0MjogU2NhbGVUeXBlKSA9PiAoc2NhbGVUeXBlUHJlY2VkZW5jZShzdDEpIC0gc2NhbGVUeXBlUHJlY2VkZW5jZShzdDIpKVxuKTtcblxuXG5mdW5jdGlvbiBwYXJzZU5vblVuaXRTY2FsZUNvcmUobW9kZWw6IE1vZGVsKSB7XG4gIGNvbnN0IHNjYWxlQ29tcG9uZW50czogU2NhbGVDb21wb25lbnRJbmRleCA9IG1vZGVsLmNvbXBvbmVudC5zY2FsZXMgPSB7fTtcblxuICBjb25zdCBzY2FsZVR5cGVXaXRoRXhwbGljaXRJbmRleDoge1xuICAgIC8vIFVzaW5nIE1hcHBlZCBUeXBlIHRvIGRlY2xhcmUgdHlwZSAoaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svYWR2YW5jZWQtdHlwZXMuaHRtbCNtYXBwZWQtdHlwZXMpXG4gICAgW2sgaW4gU2NhbGVDaGFubmVsXT86IEV4cGxpY2l0PFNjYWxlVHlwZT5cbiAgfSA9IHt9O1xuICBjb25zdCByZXNvbHZlID0gbW9kZWwuY29tcG9uZW50LnJlc29sdmU7XG5cbiAgLy8gUGFyc2UgZWFjaCBjaGlsZCBzY2FsZSBhbmQgZGV0ZXJtaW5lIGlmIGEgcGFydGljdWxhciBjaGFubmVsIGNhbiBiZSBtZXJnZWQuXG4gIGZvciAoY29uc3QgY2hpbGQgb2YgbW9kZWwuY2hpbGRyZW4pIHtcbiAgICBwYXJzZVNjYWxlQ29yZShjaGlsZCk7XG5cbiAgICAvLyBJbnN0ZWFkIG9mIGFsd2F5cyBtZXJnaW5nIHJpZ2h0IGF3YXkgLS0gY2hlY2sgaWYgaXQgaXMgY29tcGF0aWJsZSB0byBtZXJnZSBmaXJzdCFcbiAgICBrZXlzKGNoaWxkLmNvbXBvbmVudC5zY2FsZXMpLmZvckVhY2goKGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCkgPT4ge1xuICAgICAgLy8gaWYgcmVzb2x2ZSBpcyB1bmRlZmluZWQsIHNldCBkZWZhdWx0IGZpcnN0XG4gICAgICByZXNvbHZlLnNjYWxlW2NoYW5uZWxdID0gcmVzb2x2ZS5zY2FsZVtjaGFubmVsXSB8fCBkZWZhdWx0U2NhbGVSZXNvbHZlKGNoYW5uZWwsIG1vZGVsKTtcblxuICAgICAgaWYgKHJlc29sdmUuc2NhbGVbY2hhbm5lbF0gPT09ICdzaGFyZWQnKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlVHlwZSA9IHNjYWxlVHlwZVdpdGhFeHBsaWNpdEluZGV4W2NoYW5uZWxdO1xuICAgICAgICBjb25zdCBjaGlsZFNjYWxlVHlwZSA9IGNoaWxkLmNvbXBvbmVudC5zY2FsZXNbY2hhbm5lbF0uZ2V0V2l0aEV4cGxpY2l0KCd0eXBlJyk7XG5cbiAgICAgICAgaWYgKHNjYWxlVHlwZSkge1xuICAgICAgICAgIGlmIChzY2FsZUNvbXBhdGlibGUoc2NhbGVUeXBlLnZhbHVlLCBjaGlsZFNjYWxlVHlwZS52YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIG1lcmdlIHNjYWxlIGNvbXBvbmVudCBpZiB0eXBlIGFyZSBjb21wYXRpYmxlXG4gICAgICAgICAgICBzY2FsZVR5cGVXaXRoRXhwbGljaXRJbmRleFtjaGFubmVsXSA9IG1lcmdlVmFsdWVzV2l0aEV4cGxpY2l0PFZnU2NhbGUsIFNjYWxlVHlwZT4oXG4gICAgICAgICAgICAgIHNjYWxlVHlwZSwgY2hpbGRTY2FsZVR5cGUsICd0eXBlJywgJ3NjYWxlJywgc2NhbGVUeXBlVGllQnJlYWtlclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB1cGRhdGUgY29uZmxpY3RpbmcgY2hhbm5lbCB0byBiZSBpbmRlcGVuZGVudFxuICAgICAgICAgICAgcmVzb2x2ZS5zY2FsZVtjaGFubmVsXSA9ICdpbmRlcGVuZGVudCc7XG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSB0aGUgaW5kZXggc28gdGhleSBkb24ndCBnZXQgbWVyZ2VkXG4gICAgICAgICAgICBkZWxldGUgc2NhbGVUeXBlV2l0aEV4cGxpY2l0SW5kZXhbY2hhbm5lbF07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNjYWxlVHlwZVdpdGhFeHBsaWNpdEluZGV4W2NoYW5uZWxdID0gY2hpbGRTY2FsZVR5cGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIE1lcmdlIGVhY2ggY2hhbm5lbCBsaXN0ZWQgaW4gdGhlIGluZGV4XG4gIGtleXMoc2NhbGVUeXBlV2l0aEV4cGxpY2l0SW5kZXgpLmZvckVhY2goKGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCkgPT4ge1xuICAgIC8vIENyZWF0ZSBuZXcgbWVyZ2VkIHNjYWxlIGNvbXBvbmVudFxuICAgIGNvbnN0IG5hbWUgPSBtb2RlbC5zY2FsZU5hbWUoY2hhbm5lbCwgdHJ1ZSk7XG4gICAgY29uc3QgdHlwZVdpdGhFeHBsaWNpdCA9IHNjYWxlVHlwZVdpdGhFeHBsaWNpdEluZGV4W2NoYW5uZWxdO1xuICAgIHNjYWxlQ29tcG9uZW50c1tjaGFubmVsXSA9IG5ldyBTY2FsZUNvbXBvbmVudChuYW1lLCB0eXBlV2l0aEV4cGxpY2l0KTtcblxuICAgIC8vIHJlbmFtZSBlYWNoIGNoaWxkIGFuZCBtYXJrIHRoZW0gYXMgbWVyZ2VkXG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgICAgY29uc3QgY2hpbGRTY2FsZSA9IGNoaWxkLmNvbXBvbmVudC5zY2FsZXNbY2hhbm5lbF07XG4gICAgICBpZiAoY2hpbGRTY2FsZSkge1xuICAgICAgICBjaGlsZC5yZW5hbWVTY2FsZShjaGlsZFNjYWxlLmdldCgnbmFtZScpLCBuYW1lKTtcbiAgICAgICAgY2hpbGRTY2FsZS5tZXJnZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHNjYWxlQ29tcG9uZW50cztcbn1cbiJdfQ== \ 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..3258c73009 --- /dev/null +++ b/build/src/compile/scale/properties.d.ts @@ -0,0 +1,17 @@ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { FieldDef } from '../../fielddef'; +import { BarConfig, MarkDef } from '../../mark'; +import { Domain, NiceTime, Scale, ScaleConfig, ScaleType } from '../../scale'; +import { SortField, SortOrder } 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: FieldDef, sort: SortOrder | SortField, 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(padding: number, channel: Channel, scaleConfig: ScaleConfig): number; +export declare function paddingOuter(padding: number, channel: Channel, scaleType: ScaleType, paddingInner: number, scaleConfig: ScaleConfig): number; +export declare function reverse(scaleType: ScaleType, sort: SortOrder | SortField): boolean; +export declare function zero(channel: Channel, fieldDef: FieldDef, specifiedScale: Domain): boolean; diff --git a/build/src/compile/scale/properties.js b/build/src/compile/scale/properties.js new file mode 100644 index 0000000000..cd8b44a891 --- /dev/null +++ b/build/src/compile/scale/properties.js @@ -0,0 +1,204 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var util = require("../../util"); +var model_1 = require("../model"); +var split_1 = require("../split"); +var range_1 = require("./range"); +function parseScaleProperty(model, property) { + if (model_1.isUnitModel(model)) { + parseUnitScaleProperty(model, property); + } + else { + parseNonUnitScaleProperty(model, property); + } +} +exports.parseScaleProperty = parseScaleProperty; +function parseUnitScaleProperty(model, property) { + var localScaleComponents = model.component.scales; + util_1.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 sort = model.sort(channel); + var config = model.config; + var specifiedValue = specifiedScale[property]; + var sType = mergedScaleCmpt.get('type'); + var supportedByScaleType = scale_1.scaleTypeSupportProperty(sType, property); + var channelIncompatability = scale_1.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) { + 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, sort, 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, sort, 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, sort); + case 'zero': + return zero(channel, fieldDef, specifiedDomain); + } + // Otherwise, use scale config + return scaleConfig[property]; +} +exports.getDefaultValue = getDefaultValue; +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') { + range_1.parseScaleRange(child); + } + else { + parseScaleProperty(child, property); + } + } + util_1.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 = split_1.mergeValuesWithExplicit(valueWithExplicit, childValueWithExplicit, property, 'scale', split_1.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; + } + return 0; + })); + } + } + localScaleComponents[channel].setWithExplicit(property, valueWithExplicit); + }); +} +exports.parseNonUnitScaleProperty = parseNonUnitScaleProperty; +function nice(scaleType, channel, fieldDef) { + if (fieldDef.bin || util.contains([scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scaleType)) { + return undefined; + } + return util.contains([channel_1.X, channel_1.Y], channel); // return true for quantitative X/Y unless binned +} +exports.nice = nice; +function padding(channel, scaleType, scaleConfig, fieldDef, markDef, barConfig) { + if (util.contains([channel_1.X, channel_1.Y], channel)) { + if (scale_1.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 === scale_1.ScaleType.POINT) { + return scaleConfig.pointPadding; + } + } + return undefined; +} +exports.padding = padding; +function paddingInner(padding, channel, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingInner. + return undefined; + } + if (util.contains([channel_1.X, channel_1.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; +} +exports.paddingInner = paddingInner; +function paddingOuter(padding, channel, scaleType, paddingInner, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingOuter. + return undefined; + } + if (util.contains([channel_1.X, channel_1.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 === scale_1.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 paddingInner / 2; + } + } + return undefined; +} +exports.paddingOuter = paddingOuter; +function reverse(scaleType, sort) { + if (scale_1.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; +} +exports.reverse = reverse; +function zero(channel, fieldDef, specifiedScale) { + // By default, 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 if no custom domain is provided. + // (For binning, we should not include zero by default because binning are calculated without zero. + // Similar, if users explicitly provide a domain range, we should not augment zero as that will be unexpected.) + var hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated'; + if (!hasCustomDomain && !fieldDef.bin && util.contains([channel_1.X, channel_1.Y], channel)) { + return true; + } + return false; +} +exports.zero = zero; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NjYWxlL3Byb3BlcnRpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBMEQ7QUFHMUQsK0JBQWlDO0FBRWpDLHFDQUEwTDtBQUUxTCxtQ0FBZ0M7QUFDaEMsaUNBQW1DO0FBRW5DLGtDQUE0QztBQUM1QyxrQ0FBZ0Y7QUFHaEYsaUNBQXdDO0FBRXhDLDRCQUFtQyxLQUFZLEVBQUUsUUFBNkM7SUFDNUYsRUFBRSxDQUFDLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsc0JBQXNCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLHlCQUF5QixDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM3QyxDQUFDO0FBQ0gsQ0FBQztBQU5ELGdEQU1DO0FBRUQsZ0NBQWdDLEtBQWdCLEVBQUUsUUFBNkM7SUFDN0YsSUFBTSxvQkFBb0IsR0FBd0IsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFFekUsV0FBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsT0FBcUI7UUFDdkQsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0RCxJQUFNLGNBQWMsR0FBRyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRCxJQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDekQsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLElBQU0sTUFBTSxH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LDJCQUFtQixDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzVELG1FQUFtRTtRQUNuRSx1REFBdUQ7UUFDdkQsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFQRCwwQkFPQztBQUVELGNBQXFCLE9BQWdCLEVBQUUsUUFBMEIsRUFBRSxjQUFzQjtJQUN2Rix3REFBd0Q7SUFFeEQsd0NBQXdDO0lBQ3hDLDRFQUE0RTtJQUM1RSx5QkFBeUI7SUFDekIsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLE1BQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDM0QsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxrRkFBa0Y7SUFDbEYsbUdBQW1HO0lBQ25HLCtHQUErRztJQUMvRyxJQUFNLGVBQWUsR0FBRyxDQUFDLENBQUMsY0FBYyxJQUFJLGNBQWMsS0FBSyxjQUFjLENBQUM7SUFDOUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxlQUFlLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxXQUFDLEVBQUUsV0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFsQkQsb0JBa0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFubmVsLCBTY2FsZUNoYW5uZWwsIFgsIFl9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQge0ZpZWxkRGVmfSBmcm9tICcuLi8uLi9maWVsZGRlZic7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vbG9nJztcbmltcG9ydCB7QmFyQ29uZmlnLCBNYXJrRGVmfSBmcm9tICcuLi8uLi9tYXJrJztcbmltcG9ydCB7Y2hhbm5lbFNjYWxlUHJvcGVydHlJbmNvbXBhdGFiaWxpdHksIERvbWFpbiwgaGFzQ29udGludW91c0RvbWFpbiwgaXNDb250aW51b3VzVG9Db250aW51b3VzLCBOaWNlVGltZSwgU2NhbGUsIFNjYWxlQ29uZmlnLCBTY2FsZVR5cGUsIHNjYWxlVHlwZVN1cHBvcnRQcm9wZXJ0eX0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtTb3J0RmllbGQsIFNvcnRPcmRlcn0gZnJvbSAnLi4vLi4vc29ydCc7XG5pbXBvcnQge2tleXN9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7VmdTY2FsZX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtpc1VuaXRNb2RlbCwgTW9kZWx9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7RXhwbGljaXQsIG1lcmdlVmFsdWVzV2l0aEV4cGxpY2l0LCB0aWVCcmVha0J5Q29tcGFyaW5nfSBmcm9tICcuLi9zcGxpdCc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vdW5pdCc7XG5pbXBvcnQge1NjYWxlQ29tcG9uZW50LCBTY2FsZUNvbXBvbmVudEluZGV4LCBTY2FsZUNvbXBvbmVudFByb3BzfSBmcm9tICcuL2NvbXBvbmVudCc7XG5pbXBvcnQge3BhcnNlU2NhbGVSYW5nZX0gZnJvbSAnLi9yYW5nZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNjYWxlUHJvcGVydHkobW9kZWw6IE1vZGVsLCBwcm9wZXJ0eToga2V5b2YgKFNjYWxlIHwgU2NhbGVDb21wb25lbnRQcm9wcykpIHtcbiAgaWYgKGlzVW5pdE1vZGVsKG1vZGVsKSkge1xuICAgIHBhcnNlVW5pdFNjYWxlUHJvcGVydHkobW9kZWwsIHByb3BlcnR5KTtcbiAgfSBlbHNlIHtcbiAgICBwYXJzZU5vblVuaXRTY2FsZVByb3BlcnR5KG1vZGVsLCBwcm9wZXJ0eSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VVbml0U2NhbGVQcm9wZXJ0eShtb2RlbDogVW5pdE1vZGVsLCBwcm9wZXJ0eToga2V5b2YgKFNjYWxlIHwgU2NhbGVDb21wb25lbnRQcm9wcykpIHtcbiAgY29uc3QgbG9jYWxTY2FsZUNvbXBvbmVudHM6IFNjYWxlQ29tcG9uZW50SW5kZXggPSBtb2RlbC5jb21wb25lbnQuc2NhbGVzO1xuXG4gIGtleXMobG9jYWxTY2FsZUNvbXBvbmVudHMpLmZvckVhY2goKGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCkgPT4ge1xuICAgIGNvbnN0IHNwZWNpZmllZFNjYWxlID0gbW9kZWwuc3BlY2lmaWVkU2NhbGVzW2NoYW5uZWxdO1xuICAgIGNvbnN0IGxvY2FsU2NhbGVDbXB0ID0gbG9jYWxTY2FsZUNvbXBvbmVudHNbY2hhbm5lbF07XG4gICAgY29uc3QgbWVyZ2VkU2NhbGVDbXB0ID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoY2hhbm5lbCk7XG4gICAgY29uc3QgZmllbGREZWYgPSBtb2RlbC5maWVsZERlZihjaGFubmVsKTtcbiAgICBjb25zdCBzb3J0ID0gbW9kZWwuc29ydChjaGFubmVsKTtcbiAgICBjb25zdCBjb25maWcgPSBtb2RlbC5jb25maWc7XG5cbiAgICBjb25zdCBzcGVjaWZpZWRWYWx1ZSA9IHNwZWNpZmllZFNjYWxlW3Byb3BlcnR5XTtcbiAgICBjb25zdCBzVHlwZSA9IG1lcmdlZFNjYWxlQ21wdC5nZXQoJ3R5cGUnKTtcblxuICAgIGNvbnN0IHN1cHBvcnRlZEJ5U2NhbGVUeXBlID0gc2NhbGVUeXBlU3VwcG9ydFByb3BlcnR5KHNUeXBlLCBwcm9wZXJ0eSk7XG4gICAgY29uc3QgY2hhbm5lbEluY29tcGF0YWJpbGl0eSA9IGNoYW5uZWxTY2FsZVByb3BlcnR5SW5jb21wYXRhYmlsaXR5KGNoYW5uZWwsIHByb3BlcnR5KTtcblxuICAgIGlmIChzcGVjaWZpZWRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBhIHNwZWNpZmllZCB2YWx1ZSwgY2hlY2sgaWYgaXQgaXMgY29tcGF0aWJsZSB3aXRoIHNjYWxlIHR5cGUgYW5kIGNoYW5uZWxcbiAgICAgIGlmICghc3VwcG9ydGVkQnlTY2FsZVR5cGUpIHtcbiAgICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2Uuc2NhbGVQcm9wZXJ0eU5vdFdvcmtXaXRoU2NhbGVUeXBlKHNUeXBlLCBwcm9wZXJ0eSwgY2hhbm5lbCkpO1xuICAgICAgfSBlbHNlIGlmIChjaGFubmVsSW5jb21wYXRhYmlsaXR5KSB7IC8vIGNoYW5uZWxcbiAgICAgICAgbG9nLndhcm4oY2hhbm5lbEluY29tcGF0YWJpbGl0eSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzdXBwb3J0ZWRCeVNjYWxlVHlwZSAmJiBjaGFubmVsSW5jb21wYXRhYmlsaXR5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChzcGVjaWZpZWRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGNvcHlLZXlGcm9tT2JqZWN0IGVuc3VyZSB0eXBlIHNhZmV0eVxuICAgICAgICBsb2NhbFNjYWxlQ21wdC5jb3B5S2V5RnJvbU9iamVjdChwcm9wZXJ0eSwgc3BlY2lmaWVkU2NhbGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBnZXREZWZhdWx0VmFsdWUoXG4gICAgICAgICAgcHJvcGVydHksIGNoYW5uZWwsIGZpZWxkRGVmLCBzb3J0LFxuICAgICAgICAgIG1lcmdlZFNjYWxlQ21wdC5nZXQoJ3R5cGUnKSxcbiAgICAgICAgICBtZXJnZWRTY2FsZUNtcHQuZ2V0KCdwYWRkaW5nJyksXG4gICAgICAgICAgbWVyZ2VkU2NhbGVDbXB0LmdldCgncGFkZGluZ0lubmVyJyksXG4gICAgICAgICAgc3BlY2lmaWVkU2NhbGUuZG9tYWluLFxuICAgICAgICAgIG1vZGVsLm1hcmtEZWYsIGNvbmZpZ1xuICAgICAgICApO1xuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxvY2FsU2NhbGVDbXB0LnNldChwcm9wZXJ0eSwgdmFsdWUsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbi8vIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gVm95YWdlci5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0VmFsdWUoXG4gIHByb3BlcnR5OiBrZXlvZiBTY2FsZSwgY2hhbm5lbDogQ2hhbm5lbCwgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIHNvcnQ6IFNvcnRPcmRlciB8IFNvcnRGaWVsZDxzdHJpbmc+LFxuICBzY2FsZVR5cGU6IFNjYWxlVHlwZSwgc2NhbGVQYWRkaW5nOiBudW1iZXIsIHNjYWxlUGFkZGluZ0lubmVyOiBudW1iZXIsXG4gIHNwZWNpZmllZERvbWFpbjogU2NhbGVbJ2RvbWFpbiddLCBtYXJrRGVmOiBNYXJrRGVmLCBjb25maWc6IENvbmZpZykge1xuICBjb25zdCBzY2FsZUNvbmZpZyA9IGNvbmZpZy5zY2FsZTtcblxuICAvLyBJZiB3ZSBoYXZlIGRlZmF1bHQgcnVsZS1iYXNlLCBkZXRlcm1pbmUgZGVmYXVsdCB2YWx1ZSBmaXJzdFxuICBzd2l0Y2ggKHByb3BlcnR5KSB7XG4gICAgY2FzZSAnbmljZSc6XG4gICAgICByZXR1cm4gbmljZShzY2FsZVR5cGUsIGNoYW5uZWwsIGZpZWxkRGVmKTtcbiAgICBjYXNlICdwYWRkaW5nJzpcbiAgICAgIHJldHVybiBwYWRkaW5nKGNoYW5uZWwsIHNjYWxlVHlwZSwgc2NhbGVDb25maWcsIGZpZWxkRGVmLCBtYXJrRGVmLCBjb25maWcuYmFyKTtcbiAgICBjYXNlICdwYWRkaW5nSW5uZXInOlxuICAgICAgcmV0dXJuIHBhZGRpbmdJbm5lcihzY2FsZVBhZGRpbmcsIGNoYW5uZWwsIHNjYWxlQ29uZmlnKTtcbiAgICBjYXNlICdwYWRkaW5nT3V0ZXInOlxuICAgICAgcmV0dXJuIHBhZGRpbmdPdXRlcihzY2FsZVBhZGRpbmcsIGNoYW5uZWwsIHNjYWxlVHlwZSwgc2NhbGVQYWRkaW5nSW5uZXIsIHNjYWxlQ29uZmlnKTtcbiAgICBjYXNlICdyZXZlcnNlJzpcbiAgICAgIHJldHVybiByZXZlcnNlKHNjYWxlVHlwZSwgc29ydCk7XG4gICAgY2FzZSAnemVybyc6XG4gICAgICByZXR1cm4gemVybyhjaGFubmVsLCBmaWVsZERlZiwgc3BlY2lmaWVkRG9tYWluKTtcbiAgfVxuICAvLyBPdGhlcndpc2UsIHVzZSBzY2FsZSBjb25maWdcbiAgcmV0dXJuIHNjYWxlQ29uZmlnW3Byb3BlcnR5XTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTm9uVW5pdFNjYWxlUHJvcGVydHkobW9kZWw6IE1vZGVsLCBwcm9wZXJ0eToga2V5b2YgKFNjYWxlIHwgU2NhbGVDb21wb25lbnRQcm9wcykpIHtcbiAgY29uc3QgbG9jYWxTY2FsZUNvbXBvbmVudHM6IFNjYWxlQ29tcG9uZW50SW5kZXggPSBtb2RlbC5jb21wb25lbnQuc2NhbGVzO1xuXG4gIGZvciAoY29uc3QgY2hpbGQgb2YgbW9kZWwuY2hpbGRyZW4pIHtcbiAgICBpZiAocHJvcGVydHkgPT09ICdyYW5nZScpIHtcbiAgICAgIHBhcnNlU2NhbGVSYW5nZShjaGlsZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcnNlU2NhbGVQcm9wZXJ0eShjaGlsZCwgcHJvcGVydHkpO1xuICAgIH1cbiAgfVxuXG4gIGtleXMobG9jYWxTY2FsZUNvbXBvbmVudHMpLmZvckVhY2goKGNoYW5uZWw6IFNjYWxlQ2hhbm5lbCkgPT4ge1xuICAgIGxldCB2YWx1ZVdpdGhFeHBsaWNpdDogRXhwbGljaXQ8YW55PjtcblxuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgbW9kZWwuY2hpbGRyZW4pIHtcbiAgICAgIGNvbnN0IGNoaWxkQ29tcG9uZW50ID0gY2hpbGQuY29tcG9uZW50LnNjYWxlc1tjaGFubmVsXTtcbiAgICAgIGlmIChjaGlsZENvbXBvbmVudCkge1xuICAgICAgICBjb25zdCBjaGlsZFZhbHVlV2l0aEV4cGxpY2l0ID0gY2hpbGRDb21wb25lbnQuZ2V0V2l0aEV4cGxpY2l0KHByb3BlcnR5KTtcbiAgICAgICAgdmFsdWVXaXRoRXhwbGljaXQgPSBtZXJnZVZhbHVlc1dpdGhFeHBsaWNpdDxWZ1NjYWxlLCBhbnk+KFxuICAgICAgICAgIHZhbHVlV2l0aEV4cGxpY2l0LCBjaGlsZFZhbHVlV2l0aEV4cGxpY2l0LFxuICAgICAgICAgIHByb3BlcnR5LFxuICAgICAgICAgICdzY2FsZScsXG4gICAgICAgICAgdGllQnJlYWtCeUNvbXBhcmluZzxWZ1NjYWxlLCBhbnk+KCh2MSwgdjIpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgY2FzZSAncmFuZ2UnOlxuICAgICAgICAgICAgICAgIC8vIEZvciByYW5nZSBzdGVwLCBwcmVmZXIgbGFyZ2VyIHN0ZXBcbiAgICAgICAgICAgICAgICBpZiAodjEuc3RlcCAmJiB2Mi5zdGVwKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdjEuc3RlcCAtIHYyLnN0ZXA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAvLyBUT0RPOiBwcmVjZWRlbmNlIHJ1bGUgZm9yIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGxvY2FsU2NhbGVDb21wb25lbnRzW2NoYW5uZWxdLnNldFdpdGhFeHBsaWNpdChwcm9wZXJ0eSwgdmFsdWVXaXRoRXhwbGljaXQpO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5pY2Uoc2NhbGVUeXBlOiBTY2FsZVR5cGUsIGNoYW5uZWw6IENoYW5uZWwsIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+KTogYm9vbGVhbiB8IE5pY2VUaW1lIHtcbiAgaWYgKGZpZWxkRGVmLmJpbiB8fCB1dGlsLmNvbnRhaW5zKFtTY2FsZVR5cGUuVElNRSwgU2NhbGVUeXBlLlVUQ10sIHNjYWxlVHlwZSkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiB1dGlsLmNvbnRhaW5zKFtYLCBZXSwgY2hhbm5lbCk7IC8vIHJldHVybiB0cnVlIGZvciBxdWFudGl0YXRpdmUgWC9ZIHVubGVzcyBiaW5uZWRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhZGRpbmcoY2hhbm5lbDogQ2hhbm5lbCwgc2NhbGVUeXBlOiBTY2FsZVR5cGUsIHNjYWxlQ29uZmlnOiBTY2FsZUNvbmZpZywgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIG1hcmtEZWY6IE1hcmtEZWYsIGJhckNvbmZpZzogQmFyQ29uZmlnKSB7XG4gIGlmICh1dGlsLmNvbnRhaW5zKFtYLCBZXSwgY2hhbm5lbCkpIHtcbiAgICBpZiAoaXNDb250aW51b3VzVG9Db250aW51b3VzKHNjYWxlVHlwZSkpIHtcbiAgICAgIGlmIChzY2FsZUNvbmZpZy5jb250aW51b3VzUGFkZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBzY2FsZUNvbmZpZy5jb250aW51b3VzUGFkZGluZztcbiAgICAgIH1cblxuICAgICAgY29uc3Qge3R5cGUsIG9yaWVudH0gPSBtYXJrRGVmO1xuICAgICAgaWYgKHR5cGUgPT09ICdiYXInICYmICFmaWVsZERlZi5iaW4pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChvcmllbnQgPT09ICd2ZXJ0aWNhbCcgJiYgY2hhbm5lbCA9PT0gJ3gnKSB8fFxuICAgICAgICAgIChvcmllbnQgPT09ICdob3Jpem9udGFsJyAmJiBjaGFubmVsID09PSAneScpXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBiYXJDb25maWcuY29udGludW91c0JhbmRTaXplO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLlBPSU5UKSB7XG4gICAgICByZXR1cm4gc2NhbGVDb25maWcucG9pbnRQYWRkaW5nO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFkZGluZ0lubmVyKHBhZGRpbmc6IG51bWJlciwgY2hhbm5lbDogQ2hhbm5lbCwgc2NhbGVDb25maWc6IFNjYWxlQ29uZmlnKSB7XG4gIGlmIChwYWRkaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBJZiB1c2VyIGhhcyBhbHJlYWR5IG1hbnVhbGx5IHNwZWNpZmllZCBcInBhZGRpbmdcIiwgbm8gbmVlZCB0byBhZGQgZGVmYXVsdCBwYWRkaW5nSW5uZXIuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICh1dGlsLmNvbnRhaW5zKFtYLCBZXSwgY2hhbm5lbCkpIHtcbiAgICAvLyBQYWRkaW5nIGlzIG9ubHkgc2V0IGZvciBYIGFuZCBZIGJ5IGRlZmF1bHQuXG4gICAgLy8gQmFzaWNhbGx5IGl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byBhZGQgcGFkZGluZyBmb3IgY29sb3IgYW5kIHNpemUuXG5cbiAgICAvLyBwYWRkaW5nT3V0ZXIgd291bGQgb25seSBiZSBjYWxsZWQgaWYgaXQncyBhIGJhbmQgc2NhbGUsIGp1c3QgcmV0dXJuIHRoZSBkZWZhdWx0IGZvciBiYW5kU2NhbGUuXG4gICAgcmV0dXJuIHNjYWxlQ29uZmlnLmJhbmRQYWRkaW5nSW5uZXI7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhZGRpbmdPdXRlcihwYWRkaW5nOiBudW1iZXIsIGNoYW5uZWw6IENoYW5uZWwsIHNjYWxlVHlwZTogU2NhbGVUeXBlLCBwYWRkaW5nSW5uZXI6IG51bWJlciwgc2NhbGVDb25maWc6IFNjYWxlQ29uZmlnKSB7XG4gIGlmIChwYWRkaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBJZiB1c2VyIGhhcyBhbHJlYWR5IG1hbnVhbGx5IHNwZWNpZmllZCBcInBhZGRpbmdcIiwgbm8gbmVlZCB0byBhZGQgZGVmYXVsdCBwYWRkaW5nT3V0ZXIuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICh1dGlsLmNvbnRhaW5zKFtYLCBZXSwgY2hhbm5lbCkpIHtcbiAgICAvLyBQYWRkaW5nIGlzIG9ubHkgc2V0IGZvciBYIGFuZCBZIGJ5IGRlZmF1bHQuXG4gICAgLy8gQmFzaWNhbGx5IGl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byBhZGQgcGFkZGluZyBmb3IgY29sb3IgYW5kIHNpemUuXG4gICAgaWYgKHNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLkJBTkQpIHtcbiAgICAgIGlmIChzY2FsZUNvbmZpZy5iYW5kUGFkZGluZ091dGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHNjYWxlQ29uZmlnLmJhbmRQYWRkaW5nT3V0ZXI7XG4gICAgICB9XG4gICAgICAvKiBCeSBkZWZhdWx0LCBwYWRkaW5nT3V0ZXIgaXMgcGFkZGluZ0lubmVyIC8gMi4gVGhlIHJlYXNvbiBpcyB0aGF0XG4gICAgICAgICAgc2l6ZSAod2lkdGgvaGVpZ2h0KSA9IHN0ZXAgKiAoY2FyZGluYWxpdHkgLSBwYWRkaW5nSW5uZXIgKyAyICogcGFkZGluZ091dGVyKS5cbiAgICAgICAgICBhbmQgd2Ugd2FudCB0aGUgd2lkdGgvaGVpZ2h0IHRvIGJlIGludGVnZXIgYnkgZGVmYXVsdC5cbiAgICAgICAgICBOb3RlIHRoYXQgc3RlcCAoYnkgZGVmYXVsdCkgYW5kIGNhcmRpbmFsaXR5IGFyZSBpbnRlZ2Vycy4pICovXG4gICAgICByZXR1cm4gcGFkZGluZ0lubmVyIC8gMjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJldmVyc2Uoc2NhbGVUeXBlOiBTY2FsZVR5cGUsIHNvcnQ6IFNvcnRPcmRlciB8IFNvcnRGaWVsZDxzdHJpbmc+KSB7XG4gIGlmIChoYXNDb250aW51b3VzRG9tYWluKHNjYWxlVHlwZSkgJiYgc29ydCA9PT0gJ2Rlc2NlbmRpbmcnKSB7XG4gICAgLy8gRm9yIGNvbnRpbnVvdXMgZG9tYWluIHNjYWxlcywgVmVnYSBkb2VzIG5vdCBzdXBwb3J0IGRvbWFpbiBzb3J0LlxuICAgIC8vIFRodXMsIHdlIHJldmVyc2UgcmFuZ2UgaW5zdGVhZCBpZiBzb3J0IGlzIGRlc2NlbmRpbmdcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gemVybyhjaGFubmVsOiBDaGFubmVsLCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgc3BlY2lmaWVkU2NhbGU6IERvbWFpbikge1xuICAvLyBCeSBkZWZhdWx0LCByZXR1cm4gdHJ1ZSBvbmx5IGZvciB0aGUgZm9sbG93aW5nIGNhc2VzOlxuXG4gIC8vIDEpIHVzaW5nIHF1YW50aXRhdGl2ZSBmaWVsZCB3aXRoIHNpemVcbiAgLy8gV2hpbGUgdGhpcyBjYW4gYmUgZWl0aGVyIHJhdGlvIG9yIGludGVydmFsIGZpZWxkcywgb3VyIGFzc3VtcHRpb24gaXMgdGhhdFxuICAvLyByYXRpbyBhcmUgbW9yZSBjb21tb24uXG4gIGlmIChjaGFubmVsID09PSAnc2l6ZScgJiYgZmllbGREZWYudHlwZSA9PT0gJ3F1YW50aXRhdGl2ZScpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIDIpIG5vbi1iaW5uZWQsIHF1YW50aXRhdGl2ZSB4LXNjYWxlIG9yIHktc2NhbGUgaWYgbm8gY3VzdG9tIGRvbWFpbiBpcyBwcm92aWRlZC5cbiAgLy8gKEZvciBiaW5uaW5nLCB3ZSBzaG91bGQgbm90IGluY2x1ZGUgemVybyBieSBkZWZhdWx0IGJlY2F1c2UgYmlubmluZyBhcmUgY2FsY3VsYXRlZCB3aXRob3V0IHplcm8uXG4gIC8vIFNpbWlsYXIsIGlmIHVzZXJzIGV4cGxpY2l0bHkgcHJvdmlkZSBhIGRvbWFpbiByYW5nZSwgd2Ugc2hvdWxkIG5vdCBhdWdtZW50IHplcm8gYXMgdGhhdCB3aWxsIGJlIHVuZXhwZWN0ZWQuKVxuICBjb25zdCBoYXNDdXN0b21Eb21haW4gPSAhIXNwZWNpZmllZFNjYWxlICYmIHNwZWNpZmllZFNjYWxlICE9PSAndW5hZ2dyZWdhdGVkJztcbiAgaWYgKCFoYXNDdXN0b21Eb21haW4gJiYgIWZpZWxkRGVmLmJpbiAmJiB1dGlsLmNvbnRhaW5zKFtYLCBZXSwgY2hhbm5lbCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG4iXX0= \ 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..cc797a59c3 --- /dev/null +++ b/build/src/compile/scale/range.js @@ -0,0 +1,231 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var scale_2 = require("../../scale"); +var util = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var model_1 = require("../model"); +var split_1 = require("../split"); +var properties_1 = require("./properties"); +exports.RANGE_PROPERTIES = ['range', 'rangeStep', 'scheme']; +function parseScaleRange(model) { + if (model_1.isUnitModel(model)) { + parseUnitScaleRange(model); + } + else { + properties_1.parseNonUnitScaleProperty(model, 'range'); + } +} +exports.parseScaleRange = parseScaleRange; +function parseUnitScaleRange(model) { + var localScaleComponents = model.component.scales; + // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first! + channel_1.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 && vega_schema_1.isVgRangeStep(xRange) && vega_util_1.isNumber(xRange.step)) { + xyRangeSteps.push(xRange.step); + } + var yScale = model.getScaleComponent('y'); + var yRange = yScale && yScale.get('range'); + if (yRange && vega_schema_1.isVgRangeStep(yRange) && vega_util_1.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, 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 = exports.RANGE_PROPERTIES; _i < RANGE_PROPERTIES_1.length; _i++) { + var property = RANGE_PROPERTIES_1[_i]; + if (specifiedScale[property] !== undefined) { + var supportedByScaleType = scale_1.scaleTypeSupportProperty(scaleType, property); + var channelIncompatability = scale_1.channelScalePropertyIncompatability(channel, property); + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel)); + } + else if (channelIncompatability) { + log.warn(channelIncompatability); + } + else { + switch (property) { + case 'range': + return split_1.makeExplicit(specifiedScale[property]); + case 'scheme': + return split_1.makeExplicit(parseScheme(specifiedScale[property])); + case 'rangeStep': + var rangeStep = specifiedScale[property]; + if (rangeStep !== null) { + if (!sizeSpecified) { + return split_1.makeExplicit({ step: rangeStep }); + } + else { + // If top-level size is specified, we ignore specified rangeStep. + log.warn(log.message.rangeStepDropped(channel)); + } + } + } + } + } + } + return split_1.makeImplicit(defaultRange(channel, scaleType, type, config, zero, mark, sizeSignal, xyRangeSteps, noRangeStep)); +} +exports.parseRangeForChannel = parseRangeForChannel; +function parseScheme(scheme) { + if (scale_1.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, mark, sizeSignal, xyRangeSteps, noRangeStep) { + switch (channel) { + case channel_1.X: + case channel_1.Y: + if (util.contains(['point', 'band'], scaleType) && !noRangeStep) { + if (channel === channel_1.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 === channel_1.Y && scale_2.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 channel_1.SIZE: + // TODO: support custom rangeMin, rangeMax + var rangeMin = sizeRangeMin(mark, zero, config); + var rangeMax = sizeRangeMax(mark, xyRangeSteps, config); + return [rangeMin, rangeMax]; + case channel_1.SHAPE: + return 'symbol'; + case channel_1.COLOR: + if (scaleType === 'ordinal') { + // Only nominal data uses ordinal scale by default + return type === 'nominal' ? 'category' : 'ordinal'; + } + return mark === 'rect' ? 'heatmap' : 'ramp'; + case channel_1.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); +} +exports.defaultRange = defaultRange; +function sizeRangeMin(mark, zero, config) { + if (zero) { + return 0; + } + switch (mark) { + case 'bar': + case 'tick': + return config.scale.minBandSize; + case 'line': + 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; + // TODO(#1168): make max size scale based on rangeStep / overall plot size + switch (mark) { + case 'bar': + case 'tick': + if (config.scale.maxBandSize !== undefined) { + return config.scale.maxBandSize; + } + return minXYRangeStep(xyRangeSteps, config.scale) - 1; + case 'line': + 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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9yYW5nZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHVDQUFtQztBQUVuQyx5Q0FBdUc7QUFFdkcsK0JBQWlDO0FBRWpDLHFDQVNxQjtBQUNyQixxQ0FBZ0Q7QUFFaEQsaUNBQW1DO0FBQ25DLGlEQUFtRTtBQUNuRSxrQ0FBNEM7QUFDNUMsa0NBQThEO0FBRzlELDJDQUF1RDtBQUsxQyxRQUFBLGdCQUFnQixHQUFvQixDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFHbEYseUJBQWdDLEtBQVk7SUFDMUMsRUFBRSxDQUFDLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUFDLElBQUksQ0FBQyxDQUFDO1FBQ04sc0NBQXlCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLENBQUM7QUFDSCxDQUFDO0FBTkQsMENBTUM7QUFFRCw2QkFBNkIsS0FBZ0I7SUFDM0MsSUFBTSxvQkFBb0IsR0FBd0IsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFFekUsZ0ZBQWdGO0lBQ2hGLHdCQUFjLENBQUMsT0FBTyxDQUFDLFVBQUMsT0FBcUI7UUFDM0MsSUFBTSxjQUFjLEdBQUcsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckQsRUFBRSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLE1BQU0sQ0FBQztRQUNULENBQUM7UUFDRCxJQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFHekQsSUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0RCxJQUFNLFFB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QUMsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUMxQixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQztJQUMvQixDQUFDO0lBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLDZDQUE2QztBQUMxRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtpc051bWJlcn0gZnJvbSAndmVnYS11dGlsJztcblxuaW1wb3J0IHtDaGFubmVsLCBDT0xPUiwgT1BBQ0lUWSwgU0NBTEVfQ0hBTk5FTFMsIFNjYWxlQ2hhbm5lbCwgU0hBUEUsIFNJWkUsIFgsIFl9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vbG9nJztcbmltcG9ydCB7TWFya30gZnJvbSAnLi4vLi4vbWFyayc7XG5pbXBvcnQge1xuICBjaGFubmVsU2NhbGVQcm9wZXJ0eUluY29tcGF0YWJpbGl0eSxcbiAgaXNFeHRlbmRlZFNjaGVtZSxcbiAgUmFuZ2UsXG4gIFNjYWxlLFxuICBTY2FsZUNvbmZpZyxcbiAgU2NhbGVUeXBlLFxuICBzY2FsZVR5cGVTdXBwb3J0UHJvcGVydHksXG4gIFNjaGVtZSxcbn0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtoYXNDb250aW51b3VzRG9tYWlufSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge1R5cGV9IGZyb20gJy4uLy4uL3R5cGUnO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7aXNWZ1JhbmdlU3RlcCwgVmdSYW5nZSwgVmdTY2hlbWV9IGZyb20gJy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7aXNVbml0TW9kZWwsIE1vZGVsfSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge0V4cGxpY2l0LCBtYWtlRXhwbGljaXQsIG1ha2VJbXBsaWNpdH0gZnJvbSAnLi4vc3BsaXQnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IHtTY2FsZUNvbXBvbmVudEluZGV4fSBmcm9tICcuL2NvbXBvbmVudCc7XG5pbXBvcnQge3BhcnNlTm9uVW5pdFNjYWxlUHJvcGVydHl9IGZyb20gJy4vcHJvcGVydGllcyc7XG5cblxuZXhwb3J0IHR5cGUgUmFuZ2VNaXhpbnMgPSB7cmFuZ2U6IFJhbmdlfSB8IHtyYW5nZVN0ZXA6IG51bWJlcn0gfCB7c2NoZW1lOiBTY2hlbWV9O1xuXG5leHBvcnQgY29uc3QgUkFOR0VfUFJPUEVSVElFUzogKGtleW9mIFNjYWxlKVtdID0gWydyYW5nZScsICdyYW5nZVN0ZXAnLCAnc2NoZW1lJ107XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU2NhbGVSYW5nZShtb2RlbDogTW9kZWwpIHtcbiAgaWYgKGlzVW5pdE1vZGVsKG1vZGVsKSkge1xuICAgIHBhcnNlVW5pdFNjYWxlUmFuZ2UobW9kZWwpO1xuICB9IGVsc2Uge1xuICAgIHBhcnNlTm9uVW5pdFNjYWxlUHJvcGVydHkobW9kZWwsICdyYW5nZScpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlVW5pdFNjYWxlUmFuZ2UobW9kZWw6IFVuaXRNb2RlbCkge1xuICBjb25zdCBsb2NhbFNjYWxlQ29tcG9uZW50czogU2NhbGVDb21wb25lbnRJbmRleCA9IG1vZGVsLmNvbXBvbmVudC5zY2FsZXM7XG5cbiAgLy8gdXNlIFNDQUxFX0NIQU5ORUxTIGluc3RlYWQgb2Ygc2NhbGVzW2NoYW5uZWxdIHRvIGVuc3VyZSB0aGF0IHgsIHkgY29tZSBmaXJzdCFcbiAgU0NBTEVfQ0hBTk5FTFMuZm9yRWFjaCgoY2hhbm5lbDogU2NhbGVDaGFubmVsKSA9PiB7XG4gICAgY29uc3QgbG9jYWxTY2FsZUNtcHQgPSBsb2NhbFNjYWxlQ29tcG9uZW50c1tjaGFubmVsXTtcbiAgICBpZiAoIWxvY2FsU2NhbGVDbXB0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1lcmdlZFNjYWxlQ21wdCA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpO1xuXG5cbiAgICBjb25zdCBzcGVjaWZpZWRTY2FsZSA9IG1vZGVsLnNwZWNpZmllZFNjYWxlc1tjaGFubmVsXTtcbiAgICBjb25zdCBmaWVsZERlZiA9IG1vZGVsLmZpZWxkRGVmKGNoYW5uZWwpO1xuXG4gICAgLy8gUmVhZCBpZiB0aGVyZSBpcyBhIHNwZWNpZmllZCB3aWR0aC9oZWlnaHRcbiAgICBjb25zdCBzaXplVHlwZSA9IGNoYW5uZWwgPT09ICd4JyA/ICd3aWR0aCcgOiBjaGFubmVsID09PSAneScgPyAnaGVpZ2h0JyA6IHVuZGVmaW5lZDtcbiAgICBsZXQgc2l6ZVNwZWNpZmllZCA9IHNpemVUeXBlID8gISFtb2RlbC5jb21wb25lbnQubGF5b3V0U2l6ZS5nZXQoc2l6ZVR5cGUpIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3Qgc2NhbGVUeXBlID0gbWVyZ2VkU2NhbGVDbXB0LmdldCgndHlwZScpO1xuXG4gICAgLy8gaWYgYXV0b3NpemUgaXMgZml0LCBzaXplIGNhbm5vdCBiZSBkYXRhIGRyaXZlblxuICAgIGNvbnN0IHJhbmdlU3RlcCA9IHV0aWwuY29udGFpbnMoWydwb2ludCcsICdiYW5kJ10sIHNjYWxlVHlwZSkgfHwgISFzcGVjaWZpZWRTY2FsZS5yYW5nZVN0ZXA7XG4gICAgaWYgKHNpemVUeXBlICYmIG1vZGVsLmZpdCAmJiAhc2l6ZVNwZWNpZmllZCAmJiByYW5nZVN0ZXApIHtcbiAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLkNBTk5PVF9GSVhfUkFOR0VfU1RFUF9XSVRIX0ZJVCk7XG4gICAgICBzaXplU3BlY2lmaWVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCB4eVJhbmdlU3RlcHMgPSBnZXRYWVJhbmdlU3RlcChtb2RlbCk7XG5cbiAgICBjb25zdCByYW5nZVdpdGhFeHBsaWNpdCA9IHBhcnNlUmFuZ2VGb3JDaGFubmVsKFxuICAgICAgY2hhbm5lbCwgc2NhbGVUeXBlLCBmaWVsZERlZi50eXBlLCBzcGVjaWZpZWRTY2FsZSwgbW9kZWwuY29uZmlnLFxuICAgICAgbG9jYWxTY2FsZUNtcHQuZ2V0KCd6ZXJvJyksIG1vZGVsLm1hcmsoKSwgc2l6ZVNwZWNpZmllZCwgbW9kZWwuZ2V0TmFtZShzaXplVHlwZSksIHh5UmFuZ2VTdGVwc1xuICAgICk7XG5cbiAgICBsb2NhbFNjYWxlQ21wdC5zZXRXaXRoRXhwbGljaXQoJ3JhbmdlJywgcmFuZ2VXaXRoRXhwbGljaXQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0WFlSYW5nZVN0ZXAobW9kZWw6IFVuaXRNb2RlbCkge1xuICBjb25zdCB4eVJhbmdlU3RlcHM6IG51bWJlcltdID0gW107XG5cbiAgY29uc3QgeFNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoJ3gnKTtcbiAgY29uc3QgeFJhbmdlID0geFNjYWxlICYmIHhTY2FsZS5nZXQoJ3JhbmdlJyk7XG4gIGlmICh4UmFuZ2UgJiYgaXNWZ1JhbmdlU3RlcCh4UmFuZ2UpICYmIGlzTnVtYmVyKHhSYW5nZS5zdGVwKSkge1xuICAgIHh5UmFuZ2VTdGVwcy5wdXNoKHhSYW5nZS5zdGVwKTtcbiAgfVxuXG4gIGNvbnN0IHlTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd5Jyk7XG4gIGNvbnN0IHlSYW5nZSA9IHlTY2FsZSAmJiB5U2NhbGUuZ2V0KCdyYW5nZScpO1xuICBpZiAoeVJhbmdlICYmIGlzVmdSYW5nZVN0ZXAoeVJhbmdlKSAmJiBpc051bWJlcih5UmFuZ2Uuc3RlcCkpIHtcbiAgICB4eVJhbmdlU3RlcHMucHVzaCh5UmFuZ2Uuc3RlcCk7XG4gIH1cblxuICByZXR1cm4geHlSYW5nZVN0ZXBzO1xufVxuXG4vKipcbiAqIFJldHVybiBtaXhpbnMgdGhhdCBpbmNsdWRlcyBvbmUgb2YgdGhlIHJhbmdlIHByb3BlcnRpZXMgKHJhbmdlLCByYW5nZVN0ZXAsIHNjaGVtZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJhbmdlRm9yQ2hhbm5lbChcbiAgICBjaGFubmVsOiBDaGFubmVsLCBzY2FsZVR5cGU6IFNjYWxlVHlwZSwgdHlwZTogVHlwZSwgc3BlY2lmaWVkU2NhbGU6IFNjYWxlLCBjb25maWc6IENvbmZpZyxcbiAgICB6ZXJvOiBib29sZWFuLCBtYXJrOiBNYXJrLCBzaXplU3BlY2lmaWVkOiBib29sZWFuLCBzaXplU2lnbmFsOiBzdHJpbmcsIHh5UmFuZ2VTdGVwczogbnVtYmVyW11cbiAgKTogRXhwbGljaXQ8VmdSYW5nZT4ge1xuXG4gIGNvbnN0IG5vUmFuZ2VTdGVwID0gc2l6ZVNwZWNpZmllZCB8fCBzcGVjaWZpZWRTY2FsZS5yYW5nZVN0ZXAgPT09IG51bGw7XG5cbiAgLy8gQ2hlY2sgaWYgYW55IG9mIHRoZSByYW5nZSBwcm9wZXJ0aWVzIGlzIHNwZWNpZmllZC5cbiAgLy8gSWYgc28sIGNoZWNrIGlmIGl0IGlzIGNvbXBhdGlibGUgYW5kIG1ha2Ugc3VyZSB0aGF0IHdlIG9ubHkgb3V0cHV0IG9uZSBvZiB0aGUgcHJvcGVydGllc1xuICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIFJBTkdFX1BST1BFUlRJRVMpIHtcbiAgICBpZiAoc3BlY2lmaWVkU2NhbGVbcHJvcGVydHldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHN1cHBvcnRlZEJ5U2NhbGVUeXBlID0gc2NhbGVUeXBlU3VwcG9ydFByb3BlcnR5KHNjYWxlVHlwZSwgcHJvcGVydHkpO1xuICAgICAgY29uc3QgY2hhbm5lbEluY29tcGF0YWJpbGl0eSA9IGNoYW5uZWxTY2FsZVByb3BlcnR5SW5jb21wYXRhYmlsaXR5KGNoYW5uZWwsIHByb3BlcnR5KTtcbiAgICAgIGlmICghc3VwcG9ydGVkQnlTY2FsZVR5cGUpIHtcbiAgICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2Uuc2NhbGVQcm9wZXJ0eU5vdFdvcmtXaXRoU2NhbGVUeXBlKHNjYWxlVHlwZSwgcHJvcGVydHksIGNoYW5uZWwpKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbEluY29tcGF0YWJpbGl0eSkgeyAvLyBjaGFubmVsXG4gICAgICAgIGxvZy53YXJuKGNoYW5uZWxJbmNvbXBhdGFiaWxpdHkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpdGNoIChwcm9wZXJ0eSkge1xuICAgICAgICAgIGNhc2UgJ3JhbmdlJzpcbiAgICAgICAgICAgIHJldHVybiBtYWtlRXhwbGljaXQoc3BlY2lmaWVkU2NhbGVbcHJvcGVydHldKTtcbiAgICAgICAgICBjYXNlICdzY2hlbWUnOlxuICAgICAgICAgICAgcmV0dXJuIG1ha2VFeHBsaWNpdChwYXJzZVNjaGVtZShzcGVjaWZpZWRTY2FsZVtwcm9wZXJ0eV0pKTtcbiAgICAgICAgICBjYXNlICdyYW5nZVN0ZXAnOlxuICAgICAgICAgICAgY29uc3QgcmFuZ2VTdGVwID0gc3BlY2lmaWVkU2NhbGVbcHJvcGVydHldO1xuICAgICAgICAgICAgaWYgKHJhbmdlU3RlcCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBpZiAoIXNpemVTcGVjaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZUV4cGxpY2l0KHtzdGVwOiByYW5nZVN0ZXB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0b3AtbGV2ZWwgc2l6ZSBpcyBzcGVjaWZpZWQsIHdlIGlnbm9yZSBzcGVjaWZpZWQgcmFuZ2VTdGVwLlxuICAgICAgICAgICAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLnJhbmdlU3RlcERyb3BwZWQoY2hhbm5lbCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1ha2VJbXBsaWNpdChcbiAgICBkZWZhdWx0UmFuZ2UoXG4gICAgICBjaGFubmVsLCBzY2FsZVR5cGUsIHR5cGUsIGNvbmZpZyxcbiAgICAgIHplcm8sIG1hcmssIHNpemVTaWduYWwsIHh5UmFuZ2VTdGVwcywgbm9SYW5nZVN0ZXBcbiAgICApXG4gICk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU2NoZW1lKHNjaGVtZTogU2NoZW1lKSB7XG4gIGlmIChpc0V4dGVuZGVkU2NoZW1lKHNjaGVtZSkpIHtcbiAgICBjb25zdCByOiBWZ1NjaGVtZSA9IHtzY2hlbWU6IHNjaGVtZS5uYW1lfTtcbiAgICBpZiAoc2NoZW1lLmNvdW50KSB7XG4gICAgICByLmNvdW50ID0gc2NoZW1lLmNvdW50O1xuICAgIH1cbiAgICBpZiAoc2NoZW1lLmV4dGVudCkge1xuICAgICAgci5leHRlbnQgPSBzY2hlbWUuZXh0ZW50O1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICByZXR1cm4ge3NjaGVtZTogc2NoZW1lfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRSYW5nZShcbiAgY2hhbm5lbDogQ2hhbm5lbCwgc2NhbGVUeXBlOiBTY2FsZVR5cGUsIHR5cGU6IFR5cGUsIGNvbmZpZzogQ29uZmlnLCB6ZXJvOiBib29sZWFuLCBtYXJrOiBNYXJrLFxuICBzaXplU2lnbmFsOiBzdHJpbmcsIHh5UmFuZ2VTdGVwczogbnVtYmVyW10sIG5vUmFuZ2VTdGVwOiBib29sZWFuXG4pOiBWZ1JhbmdlIHtcbiAgc3dpdGNoIChjaGFubmVsKSB7XG4gICAgY2FzZSBYOlxuICAgIGNhc2UgWTpcbiAgICAgIGlmICh1dGlsLmNvbnRhaW5zKFsncG9pbnQnLCAnYmFuZCddLCBzY2FsZVR5cGUpICYmICFub1JhbmdlU3RlcCkge1xuICAgICAgICBpZiAoY2hhbm5lbCA9PT0gWCAmJiBtYXJrID09PSAndGV4dCcpIHtcbiAgICAgICAgICBpZiAoY29uZmlnLnNjYWxlLnRleHRYUmFuZ2VTdGVwKSB7XG4gICAgICAgICAgICByZXR1cm4ge3N0ZXA6IGNvbmZpZy5zY2FsZS50ZXh0WFJhbmdlU3RlcH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjb25maWcuc2NhbGUucmFuZ2VTdGVwKSB7XG4gICAgICAgICAgICByZXR1cm4ge3N0ZXA6IGNvbmZpZy5zY2FsZS5yYW5nZVN0ZXB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJZiByYW5nZSBzdGVwIGlzIG51bGwsIHVzZSB6ZXJvIHRvIHdpZHRoIG9yIGhlaWdodC5cbiAgICAgIC8vIE5vdGUgdGhhdCB0aGVzZSByYW5nZSBzaWduYWxzIGFyZSB0ZW1wb3JhcnlcbiAgICAgIC8vIGFzIHRoZXkgY2FuIGJlIG1lcmdlZCBhbmQgcmVuYW1lZC5cbiAgICAgIC8vIChXZSBkbyBub3QgaGF2ZSB0aGUgcmlnaHQgc2l6ZSBzaWduYWwgaGVyZSBzaW5jZSBwYXJzZUxheW91dFNpemUoKSBoYXBwZW5zIGFmdGVyIHBhcnNlU2NhbGUoKS4pXG4gICAgICAvLyBXZSB3aWxsIGxhdGVyIHJlcGxhY2UgdGhlc2UgdGVtcG9yYXJ5IG5hbWVzIHdpdGhcbiAgICAgIC8vIHRoZSBmaW5hbCBuYW1lIGluIGFzc2VtYmxlU2NhbGVSYW5nZSgpXG5cbiAgICAgIGlmIChjaGFubmVsID09PSBZICYmIGhhc0NvbnRpbnVvdXNEb21haW4oc2NhbGVUeXBlKSkge1xuICAgICAgICAvLyBGb3IgeSBjb250aW51b3VzIHNjYWxlLCB3ZSBoYXZlIHRvIHN0YXJ0IGZyb20gdGhlIGhlaWdodCBhcyB0aGUgYm90dG9tIHBhcnQgaGFzIHRoZSBtYXggdmFsdWUuXG4gICAgICAgIHJldHVybiBbe3NpZ25hbDogc2l6ZVNpZ25hbH0sIDBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFswLCB7c2lnbmFsOiBzaXplU2lnbmFsfV07XG4gICAgICB9XG4gICAgY2FzZSBTSVpFOlxuICAgICAgLy8gVE9ETzogc3VwcG9ydCBjdXN0b20gcmFuZ2VNaW4sIHJhbmdlTWF4XG4gICAgICBjb25zdCByYW5nZU1pbiA9IHNpemVSYW5nZU1pbihtYXJrLCB6ZXJvLCBjb25maWcpO1xuICAgICAgY29uc3QgcmFuZ2VNYXggPSBzaXplUmFuZ2VNYXgobWFyaywgeHlSYW5nZVN0ZXBzLCBjb25maWcpO1xuICAgICAgcmV0dXJuIFtyYW5nZU1pbiwgcmFuZ2VNYXhdO1xuICAgIGNhc2UgU0hBUEU6XG4gICAgICByZXR1cm4gJ3N5bWJvbCc7XG4gICAgY2FzZSBDT0xPUjpcbiAgICAgIGlmIChzY2FsZVR5cGUgPT09ICdvcmRpbmFsJykge1xuICAgICAgICAvLyBPbmx5IG5vbWluYWwgZGF0YSB1c2VzIG9yZGluYWwgc2NhbGUgYnkgZGVmYXVsdFxuICAgICAgICByZXR1cm4gdHlwZSA9PT0gJ25vbWluYWwnID8gJ2NhdGVnb3J5JyA6ICdvcmRpbmFsJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYXJrID09PSAncmVjdCcgPyAnaGVhdG1hcCcgOiAncmFtcCc7XG4gICAgY2FzZSBPUEFDSVRZOlxuICAgICAgLy8gVE9ETzogc3VwcG9ydCBjdXN0b20gcmFuZ2VNaW4sIHJhbmdlTWF4XG4gICAgICByZXR1cm4gW2NvbmZpZy5zY2FsZS5taW5PcGFjaXR5LCBjb25maWcuc2NhbGUubWF4T3BhY2l0eV07XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IHNob3VsZCBuZXZlciByZWFjaCBoZXJlICovXG4gIHRocm93IG5ldyBFcnJvcihgU2NhbGUgcmFuZ2UgdW5kZWZpbmVkIGZvciBjaGFubmVsICR7Y2hhbm5lbH1gKTtcbn1cblxuZnVuY3Rpb24gc2l6ZVJhbmdlTWluKG1hcms6IE1hcmssIHplcm86IGJvb2xlYW4sIGNvbmZpZzogQ29uZmlnKSB7XG4gIGlmICh6ZXJvKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgc3dpdGNoIChtYXJrKSB7XG4gICAgY2FzZSAnYmFyJzpcbiAgICBjYXNlICd0aWNrJzpcbiAgICAgIHJldHVybiBjb25maWcuc2NhbGUubWluQmFuZFNpemU7XG4gICAgY2FzZSAnbGluZSc6XG4gICAgY2FzZSAncnVsZSc6XG4gICAgICByZXR1cm4gY29uZmlnLnNjYWxlLm1pblN0cm9rZVdpZHRoO1xuICAgIGNhc2UgJ3RleHQnOlxuICAgICAgcmV0dXJuIGNvbmZpZy5zY2FsZS5taW5Gb250U2l6ZTtcbiAgICBjYXNlICdwb2ludCc6XG4gICAgY2FzZSAnc3F1YXJlJzpcbiAgICBjYXNlICdjaXJjbGUnOlxuICAgICAgcmV0dXJuIGNvbmZpZy5zY2FsZS5taW5TaXplO1xuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBzaG91bGQgbmV2ZXIgcmVhY2ggaGVyZSAqL1xuICAvLyBzaXplUmFuZ2VNaW4gbm90IGltcGxlbWVudGVkIGZvciB0aGUgbWFya1xuICB0aHJvdyBuZXcgRXJyb3IobG9nLm1lc3NhZ2UuaW5jb21wYXRpYmxlQ2hhbm5lbCgnc2l6ZScsIG1hcmspKTtcbn1cblxuZnVuY3Rpb24gc2l6ZVJhbmdlTWF4KG1hcms6IE1hcmssIHh5UmFuZ2VTdGVwczogbnVtYmVyW10sIGNvbmZpZzogQ29uZmlnKSB7XG4gIGNvbnN0IHNjYWxlQ29uZmlnID0gY29uZmlnLnNjYWxlO1xuICAvLyBUT0RPKCMxMTY4KTogbWFrZSBtYXggc2l6ZSBzY2FsZSBiYXNlZCBvbiByYW5nZVN0ZXAgLyBvdmVyYWxsIHBsb3Qgc2l6ZVxuICBzd2l0Y2ggKG1hcmspIHtcbiAgICBjYXNlICdiYXInOlxuICAgIGNhc2UgJ3RpY2snOlxuICAgICAgaWYgKGNvbmZpZy5zY2FsZS5tYXhCYW5kU2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBjb25maWcuc2NhbGUubWF4QmFuZFNpemU7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWluWFlSYW5nZVN0ZXAoeHlSYW5nZVN0ZXBzLCBjb25maWcuc2NhbGUpIC0gMTtcbiAgICBjYXNlICdsaW5lJzpcbiAgICBjYXNlICdydWxlJzpcbiAgICAgIHJldHVybiBjb25maWcuc2NhbGUubWF4U3Ryb2tlV2lkdGg7XG4gICAgY2FzZSAndGV4dCc6XG4gICAgICByZXR1cm4gY29uZmlnLnNjYWxlLm1heEZvbnRTaXplO1xuICAgIGNhc2UgJ3BvaW50JzpcbiAgICBjYXNlICdzcXVhcmUnOlxuICAgIGNhc2UgJ2NpcmNsZSc6XG4gICAgICBpZiAoY29uZmlnLnNjYWxlLm1heFNpemUpIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5zY2FsZS5tYXhTaXplO1xuICAgICAgfVxuXG4gICAgICAvLyBGSVhNRSB0aGlzIGNhc2UgdG90YWxseSBzaG91bGQgYmUgcmVmYWN0b3JlZFxuICAgICAgY29uc3QgcG9pbnRTdGVwID0gbWluWFlSYW5nZVN0ZXAoeHlSYW5nZVN0ZXBzLCBzY2FsZUNvbmZpZyk7XG4gICAgICByZXR1cm4gKHBvaW50U3RlcCAtIDIpICogKHBvaW50U3RlcCAtIDIpO1xuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBzaG91bGQgbmV2ZXIgcmVhY2ggaGVyZSAqL1xuICAvLyBzaXplUmFuZ2VNYXggbm90IGltcGxlbWVudGVkIGZvciB0aGUgbWFya1xuICB0aHJvdyBuZXcgRXJyb3IobG9nLm1lc3NhZ2UuaW5jb21wYXRpYmxlQ2hhbm5lbCgnc2l6ZScsIG1hcmspKTtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSYW5nZSBzdGVwIG9mIHggb3IgeSBvciBtaW5pbXVtIGJldHdlZW4gdGhlIHR3byBpZiBib3RoIGFyZSBvcmRpbmFsIHNjYWxlLlxuICovXG5mdW5jdGlvbiBtaW5YWVJhbmdlU3RlcCh4eVJhbmdlU3RlcHM6IG51bWJlcltdLCBzY2FsZUNvbmZpZzogU2NhbGVDb25maWcpOiBudW1iZXIge1xuICBpZiAoeHlSYW5nZVN0ZXBzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gTWF0aC5taW4uYXBwbHkobnVsbCwgeHlSYW5nZVN0ZXBzKTtcbiAgfVxuICBpZiAoc2NhbGVDb25maWcucmFuZ2VTdGVwKSB7XG4gICAgcmV0dXJuIHNjYWxlQ29uZmlnLnJhbmdlU3RlcDtcbiAgfVxuICByZXR1cm4gMjE7IC8vIEZJWE1FOiByZS1ldmFsdWF0ZSB0aGUgZGVmYXVsdCB2YWx1ZSBoZXJlLlxufVxuIl19 \ 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..d03b5f19e1 --- /dev/null +++ b/build/src/compile/scale/type.d.ts @@ -0,0 +1,11 @@ +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; +export declare function fieldDefMatchScaleType(specifiedType: ScaleType, fieldDef: FieldDef): boolean; diff --git a/build/src/compile/scale/type.js b/build/src/compile/scale/type.js new file mode 100644 index 0000000000..b8487f7dff --- /dev/null +++ b/build/src/compile/scale/type.js @@ -0,0 +1,113 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var scale_2 = require("../../scale"); +var type_1 = require("../../type"); +var util = require("../../util"); +var util_1 = require("../../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. +function scaleType(specifiedType, channel, fieldDef, mark, scaleConfig) { + var defaultScaleType = defaultType(channel, fieldDef, mark, scaleConfig); + if (!channel_1.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 (!scale_1.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 (!fieldDefMatchScaleType(specifiedType, fieldDef)) { + log.warn(log.message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType)); + return defaultScaleType; + } + return specifiedType; + } + return defaultScaleType; +} +exports.scaleType = scaleType; +/** + * Determine appropriate default scale type. + */ +// NOTE: Voyager uses this method. +function defaultType(channel, fieldDef, mark, scaleConfig) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + if (channel === 'color' || channel_1.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 (mark === 'rect') { + // The rect mark should fit into a band. + 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 (channel === 'color') { + return 'sequential'; + } + else if (channel_1.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 (channel === 'color') { + 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 (channel_1.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'; + } + /* istanbul ignore next: should never reach this */ + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +function fieldDefMatchScaleType(specifiedType, fieldDef) { + var type = fieldDef.type; + if (util_1.contains([type_1.Type.ORDINAL, type_1.Type.NOMINAL], type)) { + return specifiedType === undefined || scale_2.hasDiscreteDomain(specifiedType); + } + else if (type === type_1.Type.TEMPORAL) { + return util_1.contains([scale_1.ScaleType.TIME, scale_1.ScaleType.UTC, scale_1.ScaleType.SEQUENTIAL, undefined], specifiedType); + } + else if (type === type_1.Type.QUANTITATIVE) { + if (fieldDef.bin) { + return util_1.contains([scale_1.ScaleType.BIN_LINEAR, scale_1.ScaleType.BIN_ORDINAL, scale_1.ScaleType.LINEAR], specifiedType); + } + return util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.POW, scale_1.ScaleType.SQRT, scale_1.ScaleType.QUANTILE, scale_1.ScaleType.QUANTIZE, scale_1.ScaleType.LINEAR, scale_1.ScaleType.SEQUENTIAL, undefined], specifiedType); + } + return true; +} +exports.fieldDefMatchScaleType = fieldDefMatchScaleType; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NjYWxlL3R5cGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBaUU7QUFFakUsK0JBQWlDO0FBRWpDLHFDQUE0RTtBQUM1RSxxQ0FBOEM7QUFDOUMsbUNBQWdDO0FBQ2hDLGlDQUFtQztBQUNuQyxtQ0FBb0M7QUFLcEM7OztHQUdHO0FBQ0gsb0NBQW9DO0FBQ3BDLG1CQUNFLGFBQXdCLEVBQUUsT0FBZ0IsRUFBRSxRQUEwQixFQUN0RSxJQUFVLEVBQUUsV0FBd0I7SUFHcEMsSUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFFM0UsRUFBRSxDQUFDLENBQUMsQ0FBQyx3QkFBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3Qix1Q0FBdUM7UUFDdkMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxFQUFFLENBQUMsQ0FBQyxhQUFhLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNoQyx1RUFBdUU7UUFDdkUsRUFBRSxDQUFDLENBQUMsQ0FBQywrQkFBdUIsQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JELEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxPQUFPLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUM1RixNQUFNLENBQUMsZ0JBQWdCLENBQUM7UUFDMUIsQ0FBQztRQUVELHlFQUF5RTtRQUN6RSxFQUFFLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckQsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLDRCQUE0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RUFBRSxpQkFBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ2xHLENBQUM7UUFDRCxNQUFNLENBQUMsZUFBUSxDQUFDLENBQUMsaUJBQVMsQ0FBQyxHQUFHLEVBQUUsaUJBQVMsQ0FBQyxHQUFHLEVBQUUsaUJBQVMsQ0FBQyxJQUFJLEVBQUUsaUJBQVMsQ0FBQyxRQUFRLEVBQUUsaUJBQVMsQ0FBQyxRQUFRLEVBQUUsaUJBQVMsQ0FBQyxNQUFNLEVBQUUsaUJBQVMsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDNUssQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBZEQsd0RBY0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NoYW5uZWwsIGlzU2NhbGVDaGFubmVsLCByYW5nZVR5cGV9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtGaWVsZERlZn0gZnJvbSAnLi4vLi4vZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge01hcmt9IGZyb20gJy4uLy4uL21hcmsnO1xuaW1wb3J0IHtjaGFubmVsU3VwcG9ydFNjYWxlVHlwZSwgU2NhbGVDb25maWcsIFNjYWxlVHlwZX0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtoYXNEaXNjcmV0ZURvbWFpbn0gZnJvbSAnLi4vLi4vc2NhbGUnO1xuaW1wb3J0IHtUeXBlfSBmcm9tICcuLi8uLi90eXBlJztcbmltcG9ydCAqIGFzIHV0aWwgZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge2NvbnRhaW5zfSBmcm9tICcuLi8uLi91dGlsJztcblxuXG5leHBvcnQgdHlwZSBSYW5nZVR5cGUgPSAnY29udGludW91cycgfCAnZGlzY3JldGUnIHwgJ2ZsZXhpYmxlJyB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSBzcGVjaWZpZWQgc2NhbGUgdHlwZSBhbmQgaWYgaXQgaXMgYXBwcm9wcmlhdGUsXG4gKiBvciBkZXRlcm1pbmUgZGVmYXVsdCB0eXBlIGlmIHR5cGUgaXMgdW5zcGVjaWZpZWQgb3IgaW5hcHByb3ByaWF0ZS5cbiAqL1xuLy8gTk9URTogQ29tcGFzc1FMIHVzZXMgdGhpcyBtZXRob2QuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVUeXBlKFxuICBzcGVjaWZpZWRUeXBlOiBTY2FsZVR5cGUsIGNoYW5uZWw6IENoYW5uZWwsIGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LFxuICBtYXJrOiBNYXJrLCBzY2FsZUNvbmZpZzogU2NhbGVDb25maWdcbik6IFNjYWxlVHlwZSB7XG5cbiAgY29uc3QgZGVmYXVsdFNjYWxlVHlwZSA9IGRlZmF1bHRUeXBlKGNoYW5uZWwsIGZpZWxkRGVmLCBtYXJrLCBzY2FsZUNvbmZpZyk7XG5cbiAgaWYgKCFpc1NjYWxlQ2hhbm5lbChjaGFubmVsKSkge1xuICAgIC8vIFRoZXJlIGlzIG5vIHNjYWxlIGZvciB0aGVzZSBjaGFubmVsc1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChzcGVjaWZpZWRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBDaGVjayBpZiBleHBsaWNpdGx5IHNwZWNpZmllZCBzY2FsZSB0eXBlIGlzIHN1cHBvcnRlZCBieSB0aGUgY2hhbm5lbFxuICAgIGlmICghY2hhbm5lbFN1cHBvcnRTY2FsZVR5cGUoY2hhbm5lbCwgc3BlY2lmaWVkVHlwZSkpIHtcbiAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLnNjYWxlVHlwZU5vdFdvcmtXaXRoQ2hhbm5lbChjaGFubmVsLCBzcGVjaWZpZWRUeXBlLCBkZWZhdWx0U2NhbGVUeXBlKSk7XG4gICAgICByZXR1cm4gZGVmYXVsdFNjYWxlVHlwZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBleHBsaWNpdGx5IHNwZWNpZmllZCBzY2FsZSB0eXBlIGlzIHN1cHBvcnRlZCBieSB0aGUgZGF0YSB0eXBlXG4gICAgaWYgKCFmaWVsZERlZk1hdGNoU2NhbGVUeXBlKHNwZWNpZmllZFR5cGUsIGZpZWxkRGVmKSkge1xuICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2Uuc2NhbGVUeXBlTm90V29ya1dpdGhGaWVsZERlZihzcGVjaWZpZWRUeXBlLCBkZWZhdWx0U2NhbGVUeXBlKSk7XG4gICAgICByZXR1cm4gZGVmYXVsdFNjYWxlVHlwZTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3BlY2lmaWVkVHlwZTtcbiAgfVxuXG4gIHJldHVybiBkZWZhdWx0U2NhbGVUeXBlO1xufVxuXG4vKipcbiAqIERldGVybWluZSBhcHByb3ByaWF0ZSBkZWZhdWx0IHNjYWxlIHR5cGUuXG4gKi9cbi8vIE5PVEU6IFZveWFnZXIgdXNlcyB0aGlzIG1ldGhvZC5cbmZ1bmN0aW9uIGRlZmF1bHRUeXBlKFxuICBjaGFubmVsOiBDaGFubmVsLCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgbWFyazogTWFyaywgc2NhbGVDb25maWc6IFNjYWxlQ29uZmlnXG4pOiBTY2FsZVR5cGUge1xuICBzd2l0Y2ggKGZpZWxkRGVmLnR5cGUpIHtcbiAgICBjYXNlICdub21pbmFsJzpcbiAgICBjYXNlICdvcmRpbmFsJzpcbiAgICAgIGlmIChjaGFubmVsID09PSAnY29sb3InIHx8IHJhbmdlVHlwZShjaGFubmVsKSA9PT0gJ2Rpc2NyZXRlJykge1xuICAgICAgICBpZiAoY2hhbm5lbCA9PT0gJ3NoYXBlJyAmJiBmaWVsZERlZi50eXBlID09PSAnb3JkaW5hbCcpIHtcbiAgICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5kaXNjcmV0ZUNoYW5uZWxDYW5ub3RFbmNvZGUoY2hhbm5lbCwgJ29yZGluYWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICdvcmRpbmFsJztcbiAgICAgIH1cblxuICAgICAgaWYgKHV0aWwuY29udGFpbnMoWyd4JywgJ3knXSwgY2hhbm5lbCkpIHtcbiAgICAgICAgaWYgKG1hcmsgPT09ICdyZWN0Jykge1xuICAgICAgICAgIC8vIFRoZSByZWN0IG1hcmsgc2hvdWxkIGZpdCBpbnRvIGEgYmFuZC5cbiAgICAgICAgICByZXR1cm4gJ2JhbmQnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXJrID09PSAnYmFyJykge1xuICAgICAgICAgIHJldHVybiAnYmFuZCc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIE90aGVyd2lzZSwgdXNlIG9yZGluYWwgcG9pbnQgc2NhbGUgc28gd2UgY2FuIGVhc2lseSBnZXQgY2VudGVyIHBvc2l0aW9ucyBvZiB0aGUgbWFya3MuXG4gICAgICByZXR1cm4gJ3BvaW50JztcblxuICAgIGNhc2UgJ3RlbXBvcmFsJzpcbiAgICAgIGlmIChjaGFubmVsID09PSAnY29sb3InKSB7XG4gICAgICAgIHJldHVybiAnc2VxdWVudGlhbCc7XG4gICAgICB9IGVsc2UgaWYgKHJhbmdlVHlwZShjaGFubmVsKSA9PT0gJ2Rpc2NyZXRlJykge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5kaXNjcmV0ZUNoYW5uZWxDYW5ub3RFbmNvZGUoY2hhbm5lbCwgJ3RlbXBvcmFsJykpO1xuICAgICAgICAvLyBUT0RPOiBjb25zaWRlciB1c2luZyBxdWFudGl6ZSAoZXF1aXZhbGVudCB0byBiaW5uaW5nKSBvbmNlIHdlIGhhdmUgaXRcbiAgICAgICAgcmV0dXJuICdvcmRpbmFsJztcbiAgICAgIH1cbiAgICAgIHJldHVybiAndGltZSc7XG5cbiAgICBjYXNlICdxdWFudGl0YXRpdmUnOlxuICAgICAgaWYgKGNoYW5uZWwgPT09ICdjb2xvcicpIHtcbiAgICAgICAgaWYgKGZpZWxkRGVmLmJpbikge1xuICAgICAgICAgIHJldHVybiAnYmluLW9yZGluYWwnO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzZSBgc2VxdWVudGlhbGAgYXMgdGhlIGRlZmF1bHQgY29sb3Igc2NhbGUgZm9yIGNvbnRpbnVvdXMgZGF0YVxuICAgICAgICAvLyBzaW5jZSBpdCBzdXBwb3J0cyBib3RoIGFycmF5IHJhbmdlIGFuZCBzY2hlbWUgcmFuZ2UuXG4gICAgICAgIHJldHVybiAnc2VxdWVudGlhbCc7XG4gICAgICB9IGVsc2UgaWYgKHJhbmdlVHlwZShjaGFubmVsKSA9PT0gJ2Rpc2NyZXRlJykge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5kaXNjcmV0ZUNoYW5uZWxDYW5ub3RFbmNvZGUoY2hhbm5lbCwgJ3F1YW50aXRhdGl2ZScpKTtcbiAgICAgICAgLy8gVE9ETzogY29uc2lkZXIgdXNpbmcgcXVhbnRpemUgKGVxdWl2YWxlbnQgdG8gYmlubmluZykgb25jZSB3ZSBoYXZlIGl0XG4gICAgICAgIHJldHVybiAnb3JkaW5hbCc7XG4gICAgICB9XG5cbiAgICAgIC8vIHggYW5kIHkgdXNlIGEgbGluZWFyIHNjYWxlIGJlY2F1c2Ugc2VsZWN0aW9ucyBkb24ndCB3b3JrIHdpdGggYmluIHNjYWxlcy5cbiAgICAgIC8vIEJpbm5lZCBzY2FsZXMgYXBwbHkgZGlzY3JldGl6YXRpb24gYnV0IHBhbi96b29tIGFwcGx5IHRyYW5zZm9ybWF0aW9ucyB0byBhIFttaW4sIG1heF0gZXh0ZW50IGRvbWFpbi5cbiAgICAgIGlmIChmaWVsZERlZi5iaW4gJiYgY2hhbm5lbCAhPT0gJ3gnICYmIGNoYW5uZWwgIT09ICd5Jykge1xuICAgICAgICByZXR1cm4gJ2Jpbi1saW5lYXInO1xuICAgICAgfVxuICAgICAgcmV0dXJuICdsaW5lYXInO1xuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IHNob3VsZCBuZXZlciByZWFjaCB0aGlzICovXG4gIHRocm93IG5ldyBFcnJvcihsb2cubWVzc2FnZS5pbnZhbGlkRmllbGRUeXBlKGZpZWxkRGVmLnR5cGUpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpZWxkRGVmTWF0Y2hTY2FsZVR5cGUoc3BlY2lmaWVkVHlwZTogU2NhbGVUeXBlLCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPik6Ym9vbGVhbiB7XG4gIGNvbnN0IHR5cGU6IFR5cGUgPSBmaWVsZERlZi50eXBlO1xuICBpZiAoY29udGFpbnMoW1R5cGUuT1JESU5BTCwgVHlwZS5OT01JTkFMXSwgdHlwZSkpIHtcbiAgICByZXR1cm4gc3BlY2lmaWVkVHlwZSA9PT0gdW5kZWZpbmVkIHx8IGhhc0Rpc2NyZXRlRG9tYWluKHNwZWNpZmllZFR5cGUpO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09IFR5cGUuVEVNUE9SQUwpIHtcbiAgICByZXR1cm4gY29udGFpbnMoW1NjYWxlVHlwZS5USU1FLCBTY2FsZVR5cGUuVVRDLCBTY2FsZVR5cGUuU0VRVUVOVElBTCwgdW5kZWZpbmVkXSwgc3BlY2lmaWVkVHlwZSk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gVHlwZS5RVUFOVElUQVRJVkUpIHtcbiAgICBpZiAoZmllbGREZWYuYmluKSB7XG4gICAgICByZXR1cm4gY29udGFpbnMoW1NjYWxlVHlwZS5CSU5fTElORUFSLCBTY2FsZVR5cGUuQklOX09SRElOQUwsIFNjYWxlVHlwZS5MSU5FQVJdLCBzcGVjaWZpZWRUeXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRhaW5zKFtTY2FsZVR5cGUuTE9HLCBTY2FsZVR5cGUuUE9XLCBTY2FsZVR5cGUuU1FSVCwgU2NhbGVUeXBlLlFVQU5USUxFLCBTY2FsZVR5cGUuUVVBTlRJWkUsIFNjYWxlVHlwZS5MSU5FQVIsIFNjYWxlVHlwZS5TRVFVRU5USUFMLCB1bmRlZmluZWRdLCBzcGVjaWZpZWRUeXBlKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuIl19 \ 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..043e45de5d --- /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 { interval as default }; diff --git a/build/src/compile/selection/interval.js b/build/src/compile/selection/interval.js new file mode 100644 index 0000000000..8c0c7702cc --- /dev/null +++ b/build/src/compile/selection/interval.js @@ -0,0 +1,193 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log_1 = require("../../log"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var selection_1 = require("./selection"); +var scales_1 = require("./transforms/scales"); +exports.BRUSH = '_brush'; +exports.SCALE_TRIGGER = '_scale_trigger'; +var interval = { + predicate: 'vlInterval', + scaleDomain: 'vlIntervalDomain', + signals: function (model, selCmpt) { + var name = selCmpt.name; + var hasScales = scales_1.default.has(selCmpt); + var signals = []; + var intervals = []; + var tupleTriggers = []; + var scaleTriggers = []; + if (selCmpt.translate && !hasScales) { + var filterExpr_1 = "!event.item || event.item.mark.name !== " + util_1.stringValue(name + exports.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 !== channel_1.X && channel !== channel_1.Y) { + log_1.warn('Interval selections only support x and y encoding channels.'); + return; + } + var cs = channelSignals(model, selCmpt, channel); + var dname = selection_1.channelSignalName(selCmpt, channel, 'data'); + var vname = selection_1.channelSignalName(selCmpt, channel, 'visual'); + var scaleStr = util_1.stringValue(model.scaleName(channel)); + var scaleType = model.getScaleComponent(channel).get('type'); + var toNum = scale_1.hasContinuousDomain(scaleType) ? '+' : ''; + signals.push.apply(signals, cs); + tupleTriggers.push(dname); + intervals.push("{encoding: " + util_1.stringValue(channel) + ", " + + ("field: " + util_1.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 + exports.SCALE_TRIGGER, + update: scaleTriggers.map(function (t) { return t.expr; }).join(' && ') + + (" ? " + (name + exports.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 + selection_1.TUPLE, + on: [{ + events: tupleTriggers.map(function (t) { return ({ signal: t }); }), + update: tupleTriggers.join(' && ') + + (" ? {unit: " + selection_1.unitName(model) + ", intervals: [" + intervals.join(', ') + "]} : null") + }] + }); + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + selection_1.TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + selection_1.unitName(model) + "}"); + }, + marks: function (model, selCmpt, marks) { + var name = selCmpt.name; + var _a = selection_1.positionalProjections(selCmpt), xi = _a.xi, yi = _a.yi; + var store = "data(" + util_1.stringValue(selCmpt.name + selection_1.STORE) + ")"; + // Do not add a brush if we're binding to scales. + if (scales_1.default.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 = util_1.keys(update); _i < _b.length; _i++) { + var key = _b[_i]; + update[key] = [__assign({ test: store + ".length && " + store + "[0].unit === " + selection_1.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 = __rest(_c, ["fill", "fillOpacity"]); + var vgStroke = util_1.keys(stroke).reduce(function (def, k) { + def[k] = { value: stroke[k] }; + return def; + }, {}); + return [{ + name: name + exports.BRUSH + '_bg', + type: 'rect', + clip: true, + encode: { + enter: { + fill: { value: fill }, + fillOpacity: { value: fillOpacity } + }, + update: update + } + }].concat(marks, { + name: name + exports.BRUSH, + type: 'rect', + clip: true, + encode: { + enter: __assign({ fill: { value: 'transparent' } }, vgStroke), + update: update + } + }); + } +}; +exports.default = interval; +/** + * Returns the visual and data signals for an interval selection. + */ +function channelSignals(model, selCmpt, channel) { + var vname = selection_1.channelSignalName(selCmpt, channel, 'visual'); + var dname = selection_1.channelSignalName(selCmpt, channel, 'data'); + var hasScales = scales_1.default.has(selCmpt); + var scaleName = model.scaleName(channel); + var scaleStr = util_1.stringValue(scaleName); + var scale = model.getScaleComponent(channel); + var scaleType = scale ? scale.get('type') : undefined; + var size = model.getSizeSignalRef(channel === channel_1.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 + exports.SCALE_TRIGGER }, + update: scale_1.hasContinuousDomain(scaleType) && !scale_1.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) { + log_1.warn(evt + " is not an ordered event stream for interval selections"); + return on; + } + return cb(on, evt); + }, []); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJ2YWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vaW50ZXJ2YWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlDQUFtQztBQUNuQyxpQ0FBK0I7QUFDL0IscUNBQTREO0FBQzVELG1DQUE2QztBQUc3Qyx5Q0FRcUI7QUFDckIsOENBQXlDO0FBRTVCLFFBQUEsS0FBSyxHQUFHLFFBQVEsQ0FBQztBQUNqQixRQUFBLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQztBQUU5QyxJQUFNLFFBQVEsR0FBcUI7SUFDakMsU0FBUyxFQUFFLFlBQVk7SUFDdkIsV0FBVyxFQUFFLGtCQUFrQjtJQUUvQixPQUFPLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTztRQUM5QixJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQzFCLElBQU0sU0FBUyxHQUFHLGdCQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLElBQU0sT0FBTyxHQUFVLEVBQUUsQ0FBQztRQUMxQixJQUFNLFNBQVMsR0FBVSxFQUFFLENBQUM7UUFDNUIsSUFBTSxhQUFhLEdBQWEsRUFBRSxDQUFDO1FBQ25DLElBQU0sYUFBYSxHQUFVLEVBQUUsQ0FBQztRQUVoQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNwQyxJQUFNLFlBQVUsR0FBRyw2Q0FBMkMsa0JBQVcsQ0FBQyxJQUFJLEdBQUcsYUFBSyxDQUFHLENBQUM7WUFDMUYsTUFBTSxDQUFDLE9BQU8sRUFBRSxVQUFTLENBQVEsRUFBRSxHQUFrQjtnQkFDbkQsSUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFD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b3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1gsIFl9IGZyb20gJy4uLy4uL2NoYW5uZWwnO1xuaW1wb3J0IHt3YXJufSBmcm9tICcuLi8uLi9sb2cnO1xuaW1wb3J0IHtoYXNDb250aW51b3VzRG9tYWluLCBpc0JpblNjYWxlfSBmcm9tICcuLi8uLi9zY2FsZSc7XG5pbXBvcnQge2tleXMsIHN0cmluZ1ZhbHVlfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7VmdFdmVudFN0cmVhbX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IHtcbiAgY2hhbm5lbFNpZ25hbE5hbWUsXG4gIHBvc2l0aW9uYWxQcm9qZWN0aW9ucyxcbiAgU2VsZWN0aW9uQ29tcGlsZXIsXG4gIFNlbGVjdGlvbkNvbXBvbmVudCxcbiAgU1RPUkUsXG4gIFRVUExFLFxuICB1bml0TmFtZSxcbn0gZnJvbSAnLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHNjYWxlcyBmcm9tICcuL3RyYW5zZm9ybXMvc2NhbGVzJztcblxuZXhwb3J0IGNvbnN0IEJSVVNIID0gJ19icnVzaCc7XG5leHBvcnQgY29uc3QgU0NBTEVfVFJJR0dFUiA9ICdfc2NhbGVfdHJpZ2dlcic7XG5cbmNvbnN0IGludGVydmFsOlNlbGVjdGlvbkNvbXBpbGVyID0ge1xuICBwcmVkaWNhdGU6ICd2bEludGVydmFsJyxcbiAgc2NhbGVEb21haW46ICd2bEludGVydmFsRG9tYWluJyxcblxuICBzaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCkge1xuICAgIGNvbnN0IG5hbWUgPSBzZWxDbXB0Lm5hbWU7XG4gICAgY29uc3QgaGFzU2NhbGVzID0gc2NhbGVzLmhhcyhzZWxDbXB0KTtcbiAgICBjb25zdCBzaWduYWxzOiBhbnlbXSA9IFtdO1xuICAgIGNvbnN0IGludGVydmFsczogYW55W10gPSBbXTtcbiAgICBjb25zdCB0dXBsZVRyaWdnZXJzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHNjYWxlVHJpZ2dlcnM6IGFueVtdID0gW107XG5cbiAgICBpZiAoc2VsQ21wdC50cmFuc2xhdGUgJiYgIWhhc1NjYWxlcykge1xuICAgICAgY29uc3QgZmlsdGVyRXhwciA9IGAhZXZlbnQuaXRlbSB8fCBldmVudC5pdGVtLm1hcmsubmFtZSAhPT0gJHtzdHJpbmdWYWx1ZShuYW1lICsgQlJVU0gpfWA7XG4gICAgICBldmVudHMoc2VsQ21wdCwgZnVuY3Rpb24oXzogYW55W10sIGV2dDogVmdFdmVudFN0cmVhbSkge1xuICAgICAgICBjb25zdCBmaWx0ZXJzID0gZXZ0LmJldHdlZW5bMF0uZmlsdGVyIHx8IChldnQuYmV0d2VlblswXS5maWx0ZXIgPSBbXSk7XG4gICAgICAgIGlmIChmaWx0ZXJzLmluZGV4T2YoZmlsdGVyRXhwcikgPCAwKSB7XG4gICAgICAgICAgZmlsdGVycy5wdXNoKGZpbHRlckV4cHIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBzZWxDbXB0LnByb2plY3QuZm9yRWFjaChmdW5jdGlvbihwKSB7XG4gICAgICBjb25zdCBjaGFubmVsID0gcC5jaGFubmVsO1xuICAgICAgaWYgKGNoYW5uZWwgIT09IFggJiYgY2hhbm5lbCAhPT0gWSkge1xuICAgICAgICB3YXJuKCdJbnRlcnZhbCBzZWxlY3Rpb25zIG9ubHkgc3VwcG9ydCB4IGFuZCB5IGVuY29kaW5nIGNoYW5uZWxzLicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNzID0gY2hhbm5lbFNpZ25hbHMobW9kZWwsIHNlbENtcHQsIGNoYW5uZWwpO1xuICAgICAgY29uc3QgZG5hbWUgPSBjaGFubmVsU2lnbmFsTmFtZShzZWxDbXB0LCBjaGFubmVsLCAnZGF0YScpO1xuICAgICAgY29uc3Qgdm5hbWUgPSBjaGFubmVsU2lnbmFsTmFtZShzZWxDbXB0LCBjaGFubmVsLCAndmlzdWFsJyk7XG4gICAgICBjb25zdCBzY2FsZVN0ciA9IHN0cmluZ1ZhbHVlKG1vZGVsLnNjYWxlTmFtZShjaGFubmVsKSk7XG4gICAgICBjb25zdCBzY2FsZVR5cGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKS5nZXQoJ3R5cGUnKTtcbiAgICAgIGNvbnN0IHRvTnVtID0gaGFzQ29udGludW91c0RvbWFpbihzY2FsZVR5cGUpID8gJysnIDogJyc7XG5cbiAgICAgIHNpZ25hbHMucHVzaC5hcHBseShzaWduYWxzLCBjcyk7XG4gICAgICB0dXBsZVRyaWdnZXJzLnB1c2goZG5hbWUpO1xuICAgICAgaW50ZXJ2YWxzLnB1c2goYHtlbmNvZGluZzogJHtzdHJpbmdWYWx1ZShjaGFubmVsKX0sIGAgK1xuICAgICAgICBgZmllbGQ6ICR7c3RyaW5nVmFsdWUocC5maWVsZCl9LCBleHRlbnQ6ICR7ZG5hbWV9fWApO1xuXG4gICAgICBzY2FsZVRyaWdnZXJzLnB1c2goe1xuICAgICAgICBzY2FsZU5hbWU6IG1vZGVsLnNjYWxlTmFtZShjaGFubmVsKSxcbiAgICAgICAgZXhwcjogYCghaXNBcnJheSgke2RuYW1lfSkgfHwgYCArXG4gICAgICAgICAgYCgke3RvTnVtfWludmVydCgke3NjYWxlU3RyfSwgJHt2bmFtZX0pWzBdID09PSAke3RvTnVtfSR7ZG5hbWV9WzBdICYmIGAgK1xuICAgICAgICAgICAgYCR7dG9OdW19aW52ZXJ0KCR7c2NhbGVTdHJ9LCAke3ZuYW1lfSlbMV0gPT09ICR7dG9OdW19JHtkbmFtZX1bMV0pKWBcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gUHJveHkgc2NhbGUgcmVhY3Rpb25zIHRvIGVuc3VyZSB0aGF0IGFuIGluZmluaXRlIGxvb3AgZG9lc24ndCBvY2N1clxuICAgIC8vIHdoZW4gYW4gaW50ZXJ2YWwgc2VsZWN0aW9uIGZpbHRlciB0b3VjaGVzIHRoZSBzY2FsZS5cbiAgICBpZiAoIWhhc1NjYWxlcykge1xuICAgICAgc2lnbmFscy5wdXNoKHtcbiAgICAgICAgbmFtZTogbmFtZSArIFNDQUxFX1RSSUdHRVIsXG4gICAgICAgIHVwZGF0ZTogc2NhbGVUcmlnZ2Vycy5tYXAoKHQpID0+IHQuZXhwcikuam9pbignICYmICcpICtcbiAgICAgICAgICBgID8gJHtuYW1lICsgU0NBTEVfVFJJR0dFUn0gOiB7fWBcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIE9ubHkgYWRkIGFuIGludGVydmFsIHRvIHRoZSBzdG9yZSBpZiBpdCBoYXMgdmFsaWQgZGF0YSBleHRlbnRzLiBEYXRhIGV4dGVudHNcbiAgICAvLyBhcmUgc2V0IHRvIG51bGwgaWYgcGl4ZWwgZXh0ZW50cyBhcmUgZXF1YWwgdG8gYWNjb3VudCBmb3IgaW50ZXJ2YWxzIG92ZXJcbiAgICAvLyBvcmRpbmFsL25vbWluYWwgZG9tYWlucyB3aGljaCwgd2hlbiBpbnZlcnRlZCwgd2lsbCBzdGlsbCBwcm9kdWNlIGEgdmFsaWQgZGF0dW0uXG4gICAgcmV0dXJuIHNpZ25hbHMuY29uY2F0KHtcbiAgICAgIG5hbWU6IG5hbWUgKyBUVVBMRSxcbiAgICAgIG9uOiBbe1xuICAgICAgICBldmVudHM6IHR1cGxlVHJpZ2dlcnMubWFwKCh0KSA9PiAoe3NpZ25hbDogdH0pKSxcbiAgICAgICAgdXBkYXRlOiB0dXBsZVRyaWdnZXJzLmpvaW4oJyAmJiAnKSArXG4gICAgICAgICAgYCA/IHt1bml0OiAke3VuaXROYW1lKG1vZGVsKX0sIGludGVydmFsczogWyR7aW50ZXJ2YWxzLmpvaW4oJywgJyl9XX0gOiBudWxsYFxuICAgICAgfV1cbiAgICB9KTtcbiAgfSxcblxuICBtb2RpZnlFeHByOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCkge1xuICAgIGNvbnN0IHRwbCA9IHNlbENtcHQubmFtZSArIFRVUExFO1xuICAgIHJldHVybiB0cGwgKyAnLCAnICtcbiAgICAgIChzZWxDbXB0LnJlc29sdmUgPT09ICdnbG9iYWwnID8gJ3RydWUnIDogYHt1bml0OiAke3VuaXROYW1lKG1vZGVsKX19YCk7XG4gIH0sXG5cbiAgbWFya3M6IGZ1bmN0aW9uKG1vZGVsLCBzZWxDbXB0LCBtYXJrcykge1xuICAgIGNvbnN0IG5hbWUgPSBzZWxDbXB0Lm5hbWU7XG4gICAgY29uc3Qge3hpLCB5aX0gPSBwb3NpdGlvbmFsUHJvamVjdGlvbnMoc2VsQ21wdCk7XG4gICAgY29uc3Qgc3RvcmUgPSBgZGF0YSgke3N0cmluZ1ZhbHVlKHNlbENtcHQubmFtZSArIFNUT1JFKX0pYDtcblxuICAgIC8vIERvIG5vdCBhZGQgYSBicnVzaCBpZiB3ZSdyZSBiaW5kaW5nIHRvIHNjYWxlcy5cbiAgICBpZiAoc2NhbGVzLmhhcyhzZWxDbXB0KSkge1xuICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cblxuICAgIGNvbnN0IHVwZGF0ZTogYW55ID0ge1xuICAgICAgeDogeGkgIT09IG51bGwgPyB7c2lnbmFsOiBgJHtuYW1lfV94WzBdYH0gOiB7dmFsdWU6IDB9LFxuICAgICAgeTogeWkgIT09IG51bGwgPyB7c2lnbmFsOiBgJHtuYW1lfV95WzBdYH0gOiB7dmFsdWU6IDB9LFxuICAgICAgeDI6IHhpICE9PSBudWxsID8ge3NpZ25hbDogYCR7bmFtZX1feFsxXWB9IDoge2ZpZWxkOiB7Z3JvdXA6ICd3aWR0aCd9fSxcbiAgICAgIHkyOiB5aSAhPT0gbnVsbCA/IHtzaWduYWw6IGAke25hbWV9X3lbMV1gfSA6IHtmaWVsZDoge2dyb3VwOiAnaGVpZ2h0J319XG4gICAgfTtcblxuICAgIC8vIElmIHRoZSBzZWxlY3Rpb24gaXMgcmVzb2x2ZWQgdG8gZ2xvYmFsLCBvbmx5IGEgc2luZ2xlIGludGVydmFsIGlzIGluXG4gICAgLy8gdGhlIHN0b3JlLiBXcmFwIGJydXNoIG1hcmsncyBlbmNvZGluZ3Mgd2l0aCBhIHByb2R1Y3Rpb24gcnVsZSB0byB0ZXN0XG4gICAgLy8gdGhpcyBiYXNlZCBvbiB0aGUgYHVuaXRgIHByb3BlcnR5LiBIaWRlIHRoZSBicnVzaCBtYXJrIGlmIGl0IGNvcnJlc3BvbmRzXG4gICAgLy8gdG8gYSB1bml0IGRpZmZlcmVudCBmcm9tIHRoZSBvbmUgaW4gdGhlIHN0b3JlLlxuICAgIGlmIChzZWxDbXB0LnJlc29sdmUgPT09ICdnbG9iYWwnKSB7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKHVwZGF0ZSkpIHtcbiAgICAgICAgdXBkYXRlW2tleV0gPSBbe1xuICAgICAgICAgIHRlc3Q6IGAke3N0b3JlfS5sZW5ndGggJiYgJHtzdG9yZX1bMF0udW5pdCA9PT0gJHt1bml0TmFtZShtb2RlbCl9YCxcbiAgICAgICAgICAuLi51cGRhdGVba2V5XVxuICAgICAgICB9LCB7dmFsdWU6IDB9XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUd28gYnJ1c2ggbWFya3MgZW5zdXJlIHRoYXQgZmlsbCBjb2xvcnMgYW5kIG90aGVyIGFlc3RoZXRpYyBjaG9pY2VzIGRvXG4gICAgLy8gbm90IGludGVyZWZlcmUgd2l0aCB0aGUgY29yZSBtYXJrcywgYnV0IHRoYXQgdGhlIGJydXNoZWQgcmVnaW9uIGNhbiBzdGlsbFxuICAgIC8vIGJlIGludGVyYWN0ZWQgd2l0aCAoZS5nLiwgZHJhZ2dpbmcgaXQgYXJvdW5kKS5cbiAgICBjb25zdCB7ZmlsbCwgZmlsbE9wYWNpdHksIC4uLnN0cm9rZX0gPSBzZWxDbXB0Lm1hcms7XG4gICAgY29uc3QgdmdTdHJva2UgPSBrZXlzKHN0cm9rZSkucmVkdWNlKChkZWYsIGspID0+IHtcbiAgICAgIGRlZltrXSA9IHt2YWx1ZTogc3Ryb2tlW2tdfTtcbiAgICAgIHJldHVybiBkZWY7XG4gICAgfSwge30pO1xuXG4gICAgcmV0dXJuIFt7XG4gICAgICBuYW1lOiBuYW1lICsgQlJVU0ggKyAnX2JnJyxcbiAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgIGNsaXA6IHRydWUsXG4gICAgICBlbmNvZGU6IHtcbiAgICAgICAgZW50ZXI6IHtcbiAgICAgICAgICBmaWxsOiB7dmFsdWU6IGZpbGx9LFxuICAgICAgICAgIGZpbGxPcGFjaXR5OiB7dmFsdWU6IGZpbGxPcGFjaXR5fVxuICAgICAgICB9LFxuICAgICAgICB1cGRhdGU6IHVwZGF0ZVxuICAgICAgfVxuICAgIH0gYXMgYW55XS5jb25jYXQobWFya3MsIHtcbiAgICAgIG5hbWU6IG5hbWUgKyBCUlVTSCxcbiAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgIGNsaXA6IHRydWUsXG4gICAgICBlbmNvZGU6IHtcbiAgICAgICAgZW50ZXI6IHtcbiAgICAgICAgICBmaWxsOiB7dmFsdWU6ICd0cmFuc3BhcmVudCd9LFxuICAgICAgICAgIC4uLnZnU3Ryb2tlXG4gICAgICAgIH0sXG4gICAgICAgIHVwZGF0ZTogdXBkYXRlXG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5leHBvcnQge2ludGVydmFsIGFzIGRlZmF1bHR9O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHZpc3VhbCBhbmQgZGF0YSBzaWduYWxzIGZvciBhbiBpbnRlcnZhbCBzZWxlY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNoYW5uZWxTaWduYWxzKG1vZGVsOiBVbml0TW9kZWwsIHNlbENtcHQ6IFNlbGVjdGlvbkNvbXBvbmVudCwgY2hhbm5lbDogJ3gnfCd5Jyk6IGFueSB7XG4gIGNvbnN0IHZuYW1lID0gY2hhbm5lbFNpZ25hbE5hbWUoc2VsQ21wdCwgY2hhbm5lbCwgJ3Zpc3VhbCcpO1xuICBjb25zdCBkbmFtZSA9IGNoYW5uZWxTaWduYWxOYW1lKHNlbENtcHQsIGNoYW5uZWwsICdkYXRhJyk7XG4gIGNvbnN0IGhhc1NjYWxlcyA9IHNjYWxlcy5oYXMoc2VsQ21wdCk7XG4gIGNvbnN0IHNjYWxlTmFtZSA9IG1vZGVsLnNjYWxlTmFtZShjaGFubmVsKTtcbiAgY29uc3Qgc2NhbGVTdHIgPSBzdHJpbmdWYWx1ZShzY2FsZU5hbWUpO1xuICBjb25zdCBzY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpO1xuICBjb25zdCBzY2FsZVR5cGUgPSBzY2FsZSA/IHNjYWxlLmdldCgndHlwZScpIDogdW5kZWZpbmVkO1xuICBjb25zdCBzaXplID0gbW9kZWwuZ2V0U2l6ZVNpZ25hbFJlZihjaGFubmVsID09PSBYID8gJ3dpZHRoJyA6ICdoZWlnaHQnKS5zaWduYWw7XG4gIGNvbnN0IGNvb3JkID0gYCR7Y2hhbm5lbH0odW5pdClgO1xuXG4gIGNvbnN0IG9uID0gZXZlbnRzKHNlbENtcHQsIGZ1bmN0aW9uKGRlZjogYW55W10sIGV2dDogVmdFdmVudFN0cmVhbSkge1xuICAgIHJldHVybiBkZWYuY29uY2F0KFxuICAgICAge2V2ZW50czogZXZ0LmJldHdlZW5bMF0sIHVwZGF0ZTogYFske2Nvb3JkfSwgJHtjb29yZH1dYH0sICAgICAgICAgICAvLyBCcnVzaCBTdGFydFxuICAgICAge2V2ZW50czogZXZ0LCB1cGRhdGU6IGBbJHt2bmFtZX1bMF0sIGNsYW1wKCR7Y29vcmR9LCAwLCAke3NpemV9KV1gfSAvLyBCcnVzaCBFbmRcbiAgICApO1xuICB9KTtcblxuICAvLyBSZWFjdCB0byBwYW4vem9vbXMgb2YgY29udGludW91cyBzY2FsZXMuIE5vbi1jb250aW51b3VzIHNjYWxlc1xuICAvLyAoYmluLWxpbmVhciwgYmFuZCwgcG9pbnQpIGNhbm5vdCBiZSBwYW4vem9vbWVkIGFuZCBhbnkgb3RoZXIgY2hhbmdlc1xuICAvLyB0byB0aGVpciBkb21haW5zIChlLmcuLCBmaWx0ZXJpbmcpIHNob3VsZCBjbGVhciB0aGUgYnJ1c2hlcy5cbiAgb24ucHVzaCh7XG4gICAgZXZlbnRzOiB7c2lnbmFsOiBzZWxDbXB0Lm5hbWUgKyBTQ0FMRV9UUklHR0VSfSxcbiAgICB1cGRhdGU6IGhhc0NvbnRpbnVvdXNEb21haW4oc2NhbGVUeXBlKSAmJiAhaXNCaW5TY2FsZShzY2FsZVR5cGUpID9cbiAgICAgIGBbc2NhbGUoJHtzY2FsZVN0cn0sICR7ZG5hbWV9WzBdKSwgc2NhbGUoJHtzY2FsZVN0cn0sICR7ZG5hbWV9WzFdKV1gIDogYFswLCAwXWBcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc1NjYWxlcyA/IFt7bmFtZTogZG5hbWUsIG9uOiBbXX1dIDogW3tcbiAgICBuYW1lOiB2bmFtZSwgdmFsdWU6IFtdLCBvbjogb25cbiAgfSwge1xuICAgIG5hbWU6IGRuYW1lLFxuICAgIG9uOiBbe2V2ZW50czoge3NpZ25hbDogdm5hbWV9LCB1cGRhdGU6IGAke3ZuYW1lfVswXSA9PT0gJHt2bmFtZX1bMV0gPyBudWxsIDogaW52ZXJ0KCR7c2NhbGVTdHJ9LCAke3ZuYW1lfSlgfV1cbiAgfV07XG59XG5cbmZ1bmN0aW9uIGV2ZW50cyhzZWxDbXB0OiBTZWxlY3Rpb25Db21wb25lbnQsIGNiOiBGdW5jdGlvbikge1xuICByZXR1cm4gc2VsQ21wdC5ldmVudHMucmVkdWNlKGZ1bmN0aW9uKG9uOiBhbnlbXSwgZXZ0OiBWZ0V2ZW50U3RyZWFtKSB7XG4gICAgaWYgKCFldnQuYmV0d2Vlbikge1xuICAgICAgd2FybihgJHtldnR9IGlzIG5vdCBhbiBvcmRlcmVkIGV2ZW50IHN0cmVhbSBmb3IgaW50ZXJ2YWwgc2VsZWN0aW9uc2ApO1xuICAgICAgcmV0dXJuIG9uO1xuICAgIH1cbiAgICByZXR1cm4gY2Iob24sIGV2dCk7XG4gIH0sIFtdKTtcbn1cbiJdfQ== \ 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..47971478a2 --- /dev/null +++ b/build/src/compile/selection/multi.d.ts @@ -0,0 +1,3 @@ +import { SelectionCompiler } from './selection'; +declare const multi: SelectionCompiler; +export { multi as default }; diff --git a/build/src/compile/selection/multi.js b/build/src/compile/selection/multi.js new file mode 100644 index 0000000000..001e04f61b --- /dev/null +++ b/build/src/compile/selection/multi.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var selection_1 = require("./selection"); +var nearest_1 = require("./transforms/nearest"); +var multi = { + predicate: 'vlMulti', + scaleDomain: 'vlMultiDomain', + signals: function (model, selCmpt) { + var proj = selCmpt.project; + var datum = nearest_1.default.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + var bins = []; + var encodings = proj.map(function (p) { return util_1.stringValue(p.channel); }).filter(function (e) { return e; }).join(', '); + var fields = proj.map(function (p) { return util_1.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), + "[" + datum + util_1.accessPath(model.field(channel, {})) + ", " + + ("" + datum + util_1.accessPath(model.field(channel, { binSuffix: 'end' })) + "]")) : + "" + datum + util_1.accessPath(p.field); + }).join(', '); + // Only add a discrete selection to the store if a datum is present _and_ + // the interaction isn't occuring 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 + selection_1.TUPLE, + value: {}, + on: [{ + events: selCmpt.events, + update: "datum && item().mark.marktype !== 'group' ? " + + ("{unit: " + selection_1.unitName(model) + ", encodings: [" + encodings + "], ") + + ("fields: [" + fields + "], values: [" + values + "]") + + (bins.length ? ', ' + bins.map(function (b) { return util_1.stringValue('bin_' + b) + ": 1"; }).join(', ') : '') + + '} : null', + force: true + }] + }]; + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + selection_1.TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'null' : "{unit: " + selection_1.unitName(model) + "}"); + } +}; +exports.default = multi; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vbXVsdGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxtQ0FBbUQ7QUFDbkQseUNBQStEO0FBQy9ELGdEQUEyQztBQUczQyxJQUFNLEtBQUssR0FBcUI7SUFDOUIsU0FBUyxFQUFFLFNBQVM7SUFDcEIsV0FBVyxFQUFFLGVBQWU7SUFFNUIsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU87UUFDOUIsSUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztRQUM3QixJQUFNLEtBQUssR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLDBDQUEwQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDdkQsSUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFDO1FBQzFCLElBQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxrQkFBVyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBdEIsQ0FBc0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsRUFBRCxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEYsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLGtCQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFwQixDQUFvQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hFLElBQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFDO1lBQ3hCLElBQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDMUIsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QyxnRkFBZ0Y7WUFDaEYsTUFBTSxDQUFDLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQ3JELE1BQUksS0FBSyxHQUFHLGlCQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBSTtxQkFDaEQsS0FBRyxLQUFLLEdBQUcsaUJBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDLE1BQUcsQ0FBQSxDQUFDLENBQUMsQ0FBQztnQkFDekUsS0FBRyxLQUFLLEdBQUcsaUJBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFHLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWQseUVBQXlFO1FBQ3pFLHNFQUFzRTtRQUN0RSxzRUFBc0U7UUFDdEUsMEVBQTBFO1FBQzFFLHFFQUFxRTtRQUNyRSxzRUFBc0U7UUFDdEUsbUNBQW1DO1FBQ25DLE1BQU0sQ0FBQyxDQUFDO2dCQUNOLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxHQUFHLGlCQUFLO2dCQUMxQixLQUFLLEVBQUUsRUFBRTtnQkFDVCxFQUFFLEVBQUUsQ0FBQzt3QkFDSCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07d0JBQ3RCLE1BQU0sRUFBRSw4Q0FBOEM7NkJBQ3BELFlBQVUsb0JBQVEsQ0FBQyxLQUFLLENBQUMsc0JBQWlCLFNBQVMsUUFBSyxDQUFBOzZCQUN4RCxjQUFZLE1BQU0sb0JBQWUsTUFBTSxNQUFHLENBQUE7NEJBQzFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFDLElBQUssT0FBRyxrQkFBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsUUFBSyxFQUEvQixDQUErQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ3ZGLFVBQVU7d0JBQ1osS0FBSyxFQUFFLElBQUk7cUJBQ1osQ0FBQzthQUNILENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxVQUFVLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTztRQUNqQyxJQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsSUFBSSxHQUFHLGlCQUFLLENBQUM7UUFDakMsTUFBTSxDQUFDLEdBQUcsR0FBRyxJQUFJO1lBQ2YsQ0FBQyxPQUFPLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFVLG9CQUFRLENBQUMsS0FBSyxDQUFDLE1BQUcsQ0FBQyxDQUFDO0lBQzNFLENBQUM7Q0FDRixDQUFDO0FBRWUsd0JBQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2FjY2Vzc1BhdGgsIHN0cmluZ1ZhbHVlfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7U2VsZWN0aW9uQ29tcGlsZXIsIFRVUExFLCB1bml0TmFtZX0gZnJvbSAnLi9zZWxlY3Rpb24nO1xuaW1wb3J0IG5lYXJlc3QgZnJvbSAnLi90cmFuc2Zvcm1zL25lYXJlc3QnO1xuXG5cbmNvbnN0IG11bHRpOlNlbGVjdGlvbkNvbXBpbGVyID0ge1xuICBwcmVkaWNhdGU6ICd2bE11bHRpJyxcbiAgc2NhbGVEb21haW46ICd2bE11bHRpRG9tYWluJyxcblxuICBzaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCkge1xuICAgIGNvbnN0IHByb2ogPSBzZWxDbXB0LnByb2plY3Q7XG4gICAgY29uc3QgZGF0dW0gPSBuZWFyZXN0LmhhcyhzZWxDbXB0KSA/XG4gICAgICAnKGl0ZW0oKS5pc1Zvcm9ub2kgPyBkYXR1bS5kYXR1bSA6IGRhdHVtKScgOiAnZGF0dW0nO1xuICAgIGNvbnN0IGJpbnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgZW5jb2RpbmdzID0gcHJvai5tYXAoKHApID0+IHN0cmluZ1ZhbHVlKHAuY2hhbm5lbCkpLmZpbHRlcigoZSkgPT4gZSkuam9pbignLCAnKTtcbiAgICBjb25zdCBmaWVsZHMgPSBwcm9qLm1hcCgocCkgPT4gc3RyaW5nVmFsdWUocC5maWVsZCkpLmpvaW4oJywgJyk7XG4gICAgY29uc3QgdmFsdWVzID0gcHJvai5tYXAoKHApID0+IHtcbiAgICAgIGNvbnN0IGNoYW5uZWwgPSBwLmNoYW5uZWw7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IG1vZGVsLmZpZWxkRGVmKGNoYW5uZWwpO1xuICAgICAgLy8gQmlubmVkIGZpZWxkcyBzaG91bGQgY2FwdHVyZSBleHRlbnRzLCBmb3IgYSByYW5nZSB0ZXN0IGFnYWluc3QgdGhlIHJhdyBmaWVsZC5cbiAgICAgIHJldHVybiAoZmllbGREZWYgJiYgZmllbGREZWYuYmluKSA/IChiaW5zLnB1c2gocC5maWVsZCksXG4gICAgICAgIGBbJHtkYXR1bX0ke2FjY2Vzc1BhdGgobW9kZWwuZmllbGQoY2hhbm5lbCwge30pKX0sIGAgK1xuICAgICAgICAgICAgYCR7ZGF0dW19JHthY2Nlc3NQYXRoKG1vZGVsLmZpZWxkKGNoYW5uZWwsIHtiaW5TdWZmaXg6ICdlbmQnfSkpfV1gKSA6XG4gICAgICAgIGAke2RhdHVtfSR7YWNjZXNzUGF0aChwLmZpZWxkKX1gO1xuICAgIH0pLmpvaW4oJywgJyk7XG5cbiAgICAvLyBPbmx5IGFkZCBhIGRpc2NyZXRlIHNlbGVjdGlvbiB0byB0aGUgc3RvcmUgaWYgYSBkYXR1bSBpcyBwcmVzZW50IF9hbmRfXG4gICAgLy8gdGhlIGludGVyYWN0aW9uIGlzbid0IG9jY3VyaW5nIG9uIGEgZ3JvdXAgbWFyay4gVGhpcyBndWFyZHMgYWdhaW5zdFxuICAgIC8vIHBvbGx1dGluZyBpbnRlcmFjdGl2ZSBzdGF0ZSB3aXRoIGludmFsaWQgdmFsdWVzIGluIGZhY2V0ZWQgZGlzcGxheXNcbiAgICAvLyBhcyB0aGUgZ3JvdXAgbWFya3MgYXJlIGFsc28gZGF0YS1kcml2ZW4uIFdlIGZvcmNlIHRoZSB1cGRhdGUgdG8gYWNjb3VudFxuICAgIC8vIGZvciBjb25zdGFudCBudWxsIHN0YXRlcyBidXQgdmFyeWluZyB0b2dnbGVzIChlLmcuLCBzaGlmdC1jbGljayBpblxuICAgIC8vIHdoaXRlc3BhY2UgZm9sbG93ZWQgYnkgYSBjbGljayBpbiB3aGl0ZXNwYWNlOyB0aGUgc3RvcmUgc2hvdWxkIG9ubHlcbiAgICAvLyBiZSBjbGVhcmVkIG9uIHRoZSBzZWNvbmQgY2xpY2spLlxuICAgIHJldHVybiBbe1xuICAgICAgbmFtZTogc2VsQ21wdC5uYW1lICsgVFVQTEUsXG4gICAgICB2YWx1ZToge30sXG4gICAgICBvbjogW3tcbiAgICAgICAgZXZlbnRzOiBzZWxDbXB0LmV2ZW50cyxcbiAgICAgICAgdXBkYXRlOiBgZGF0dW0gJiYgaXRlbSgpLm1hcmsubWFya3R5cGUgIT09ICdncm91cCcgPyBgICtcbiAgICAgICAgICBge3VuaXQ6ICR7dW5pdE5hbWUobW9kZWwpfSwgZW5jb2RpbmdzOiBbJHtlbmNvZGluZ3N9XSwgYCArXG4gICAgICAgICAgYGZpZWxkczogWyR7ZmllbGRzfV0sIHZhbHVlczogWyR7dmFsdWVzfV1gICtcbiAgICAgICAgICAoYmlucy5sZW5ndGggPyAnLCAnICsgYmlucy5tYXAoKGIpID0+IGAke3N0cmluZ1ZhbHVlKCdiaW5fJyArIGIpfTogMWApLmpvaW4oJywgJykgOiAnJykgK1xuICAgICAgICAgICd9IDogbnVsbCcsXG4gICAgICAgIGZvcmNlOiB0cnVlXG4gICAgICB9XVxuICAgIH1dO1xuICB9LFxuXG4gIG1vZGlmeUV4cHI6IGZ1bmN0aW9uKG1vZGVsLCBzZWxDbXB0KSB7XG4gICAgY29uc3QgdHBsID0gc2VsQ21wdC5uYW1lICsgVFVQTEU7XG4gICAgcmV0dXJuIHRwbCArICcsICcgK1xuICAgICAgKHNlbENtcHQucmVzb2x2ZSA9PT0gJ2dsb2JhbCcgPyAnbnVsbCcgOiBge3VuaXQ6ICR7dW5pdE5hbWUobW9kZWwpfX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IHttdWx0aSBhcyBkZWZhdWx0fTtcbiJdfQ== \ 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..576aeadc44 --- /dev/null +++ b/build/src/compile/selection/selection.d.ts @@ -0,0 +1,64 @@ +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; + 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 predicate(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'): string; +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..a0d76af733 --- /dev/null +++ b/build/src/compile/selection/selection.js @@ -0,0 +1,293 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_event_selector_1 = require("vega-event-selector"); +var channel_1 = require("../../channel"); +var log_1 = require("../../log"); +var selection_1 = require("../../selection"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var interval_1 = require("./interval"); +var multi_1 = require("./multi"); +var single_1 = require("./single"); +var transforms_1 = require("./transforms/transforms"); +exports.STORE = '_store'; +exports.TUPLE = '_tuple'; +exports.MODIFY = '_modify'; +exports.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 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] = __assign({}, cfg[key], selDef[key]); + } + if (selDef[key] === undefined || selDef[key] === true) { + selDef[key] = cfg[key] || selDef[key]; + } + } + name_1 = util_1.varName(name_1); + var selCmpt = selCmpts[name_1] = __assign({}, selDef, { name: name_1, events: util_1.isString(selDef.on) ? vega_event_selector_1.selector(selDef.on, 'scope') : selDef.on }); + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.parse) { + txCompiler.parse(model, selDef, selCmpt); + } + }); + }; + for (var name_1 in selDefs) { + _loop_1(name_1); + } + return selCmpts; +} +exports.parseUnitSelection = parseUnitSelection; +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)); + transforms_1.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 + exports.MODIFY, + on: [{ + events: { signal: name + exports.TUPLE }, + update: "modify(" + util_1.stringValue(selCmpt.name + exports.STORE) + ", " + modifyExpr + ")" + }] + }); + }); + var facetModel = getFacetModel(model); + if (signals.length && facetModel) { + var name_2 = util_1.stringValue(facetModel.getName('cell')); + signals.unshift({ + name: 'facet', + value: {}, + on: [{ + events: vega_event_selector_1.selector('mousemove', 'scope'), + update: "isTuple(facet) ? facet : group(" + name_2 + ").datum" + }] + }); + } + return signals; +} +exports.assembleUnitSelectionSignals = assembleUnitSelectionSignals; +function assembleTopLevelSignals(model, signals) { + var needsUnit = false; + forEachSelection(model, function (selCmpt, selCompiler) { + if (selCompiler.topLevelSignals) { + signals = selCompiler.topLevelSignals(model, selCmpt, signals); + } + transforms_1.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; +} +exports.assembleTopLevelSignals = assembleTopLevelSignals; +function assembleUnitSelectionData(model, data) { + forEachSelection(model, function (selCmpt) { + var contains = data.filter(function (d) { return d.name === selCmpt.name + exports.STORE; }); + if (!contains.length) { + data.push({ name: selCmpt.name + exports.STORE }); + } + }); + return data; +} +exports.assembleUnitSelectionData = assembleUnitSelectionData; +function assembleUnitSelectionMarks(model, marks) { + forEachSelection(model, function (selCmpt, selCompiler) { + marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks; + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.marks) { + marks = txCompiler.marks(model, selCmpt, marks); + } + }); + }); + return marks; +} +exports.assembleUnitSelectionMarks = assembleUnitSelectionMarks; +function assembleLayerSelectionMarks(model, marks) { + model.children.forEach(function (child) { + if (model_1.isUnitModel(child)) { + marks = assembleUnitSelectionMarks(child, marks); + } + }); + return marks; +} +exports.assembleLayerSelectionMarks = assembleLayerSelectionMarks; +function predicate(model, selections, dfnode) { + var stores = []; + function expr(name) { + var vname = util_1.varName(name); + var selCmpt = model.getSelectionComponent(vname, name); + var store = util_1.stringValue(vname + exports.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' ? ')' : ", " + util_1.stringValue(selCmpt.resolve) + ")"); + } + var predicateStr = util_1.logicalExpr(selections, expr); + return (stores.length + ? '!(' + stores.map(function (s) { return "length(data(" + s + "))"; }).join(' || ') + ') || ' + : '') + ("(" + predicateStr + ")"); +} +exports.predicate = predicate; +// 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(exports.SELECTION_DOMAIN) >= 0; +} +exports.isRawSelectionDomain = isRawSelectionDomain; +function selectionScaleDomain(model, domainRaw) { + var selDomain = JSON.parse(domainRaw.signal.replace(exports.SELECTION_DOMAIN, '')); + var name = util_1.varName(selDomain.selection); + var selCmpt = model.component.selection && model.component.selection[name]; + if (selCmpt) { + log_1.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) { + log_1.warn('A "field" or "encoding" must be specified when using a selection as a scale domain. ' + + ("Using \"field\": " + util_1.stringValue(selDomain.field) + ".")); + } + } + return { + signal: compiler(selCmpt.type).scaleDomain + + ("(" + util_1.stringValue(name + exports.STORE) + ", " + util_1.stringValue(selDomain.encoding || null) + ", ") + + util_1.stringValue(selDomain.field || null) + + (selCmpt.resolve === 'global' ? ')' : ", " + util_1.stringValue(selCmpt.resolve) + ")") + }; + } + return { signal: 'null' }; +} +exports.selectionScaleDomain = selectionScaleDomain; +// 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_1.default; + case 'multi': + return multi_1.default; + case 'interval': + return interval_1.default; + } + return null; +} +function getFacetModel(model) { + var parent = model.parent; + while (parent) { + if (model_1.isFacetModel(parent)) { + break; + } + parent = parent.parent; + } + return parent; +} +function unitName(model) { + var name = util_1.stringValue(model.name); + var facet = getFacetModel(model); + if (facet) { + name += (facet.facet.row ? " + '_' + facet" + util_1.accessPath(facet.field('row')) : '') + + (facet.facet.column ? " + '_' + facet" + util_1.accessPath(facet.field('column')) : ''); + } + return name; +} +exports.unitName = unitName; +function requiresSelectionId(model) { + var identifier = false; + forEachSelection(model, function (selCmpt) { + identifier = identifier || selCmpt.project.some(function (proj) { return proj.field === selection_1.SELECTION_ID; }); + }); + return identifier; +} +exports.requiresSelectionId = requiresSelectionId; +function channelSignalName(selCmpt, channel, range) { + return util_1.varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel])); +} +exports.channelSignalName = channelSignalName; +function positionalProjections(selCmpt) { + var x = null; + var xi = null; + var y = null; + var yi = null; + selCmpt.project.forEach(function (p, i) { + if (p.channel === channel_1.X) { + x = p; + xi = i; + } + else if (p.channel === channel_1.Y) { + y = p; + yi = i; + } + }); + return { x: x, xi: xi, y: y, yi: yi }; +} +exports.positionalProjections = positionalProjections; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsMkRBQThEO0FBQzlELHlDQUEwRDtBQUMxRCxpQ0FBK0I7QUFFL0IsNkNBQTRHO0FBQzVHLG1DQUF5RjtBQU16RixrQ0FBMEQ7QUFFMUQsdUNBQTBDO0FBQzFDLGlDQUFvQztBQUVwQyxtQ0FBc0M7QUFDdEMsc0RBQXlEO0FBRzVDLFFBQUEsS0FBSyxHQUFHLFFBQVEsQ0FBQztBQUNqQixRQUFBLEtBQUssR0FBRyxRQUFRLENBQUM7QUFDakIsUUFBQSxNQUFNLEdBQUcsU0FBUyxDQUFDO0FBQ25CLFFBQUEsZ0JBQWdCLEdBQUcsb0JBQW9CLENBQUM7QUFxQ3JELDRCQUFtQyxLQUFnQixFQUFFLE9BQTJCO0lBQzlFLElBQU0sUUFBUSxHQUE2QixFQUFFLENBQUM7SUFDOUMsSUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7NEJBRXRDLE1BQUk7UUFDWCxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDOztRQUVwQyxDQUFDO1FBRUQsSUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQUksQ0FBQyxDQUFDO1FBQzdCLElBQU0sR0FBRyxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekMsc0VBQXNFO1FBQ3RFLG1FQUFtRTtRQUNuRSx1RUFBdUU7UUFDdkUsc0NBQXNDO1FBQ3RDLEdBQUcsQ0FBQyxDQUFDLElBQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDdEIsc0VBQXNFO1lBQ3RFLHVFQUF1RTtZQUN2RSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxXQUFXLElBQUksTUFBTSxDQUFD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Q0FBQyxVQUFDLENBQUMsRUFBRSxDQUFDO1FBQzNCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssV0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ04sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNULENBQUM7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxXQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNCLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDTixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ1QsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLEVBQUMsQ0FBQyxHQUFBLEVBQUUsRUFBRSxJQUFBLEVBQUUsQ0FBQyxHQUFBLEVBQUUsRUFBRSxJQUFBLEVBQUMsQ0FBQztBQUN4QixDQUFDO0FBaEJELHNEQWdCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7c2VsZWN0b3IgYXMgcGFyc2VTZWxlY3Rvcn0gZnJvbSAndmVnYS1ldmVudC1zZWxlY3Rvcic7XG5pbXBvcnQge0NoYW5uZWwsIFNjYWxlQ2hhbm5lbCwgWCwgWX0gZnJvbSAnLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge3dhcm59IGZyb20gJy4uLy4uL2xvZyc7XG5pbXBvcnQge0xvZ2ljYWxPcGVyYW5kfSBmcm9tICcuLi8uLi9sb2dpY2FsJztcbmltcG9ydCB7QnJ1c2hDb25maWcsIFNFTEVDVElPTl9JRCwgU2VsZWN0aW9uRGVmLCBTZWxlY3Rpb25SZXNvbHV0aW9uLCBTZWxlY3Rpb25UeXBlfSBmcm9tICcuLi8uLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHthY2Nlc3NQYXRoLCBEaWN0LCBpc1N0cmluZywgbG9naWNhbEV4cHIsIHN0cmluZ1ZhbHVlLCB2YXJOYW1lfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7VmdCaW5kaW5nLCBWZ0RhdGEsIFZnRXZlbnRTdHJlYW0sIFZnU2lnbmFsUmVmfSBmcm9tICcuLi8uLi92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge0RhdGFGbG93Tm9kZX0gZnJvbSAnLi4vZGF0YS9kYXRhZmxvdyc7XG5pbXBvcnQge1RpbWVVbml0Tm9kZX0gZnJvbSAnLi4vZGF0YS90aW1ldW5pdCc7XG5pbXBvcnQge0ZhY2V0TW9kZWx9IGZyb20gJy4uL2ZhY2V0JztcbmltcG9ydCB7TGF5ZXJNb2RlbH0gZnJvbSAnLi4vbGF5ZXInO1xuaW1wb3J0IHtpc0ZhY2V0TW9kZWwsIGlzVW5pdE1vZGVsLCBNb2RlbH0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3VuaXQnO1xuaW1wb3J0IGludGVydmFsQ29tcGlsZXIgZnJvbSAnLi9pbnRlcnZhbCc7XG5pbXBvcnQgbXVsdGlDb21waWxlciBmcm9tICcuL211bHRpJztcbmltcG9ydCB7U2VsZWN0aW9uQ29tcG9uZW50fSBmcm9tICcuL3NlbGVjdGlvbic7XG5pbXBvcnQgc2luZ2xlQ29tcGlsZXIgZnJvbSAnLi9zaW5nbGUnO1xuaW1wb3J0IHtmb3JFYWNoVHJhbnNmb3JtfSBmcm9tICcuL3RyYW5zZm9ybXMvdHJhbnNmb3Jtcyc7XG5cblxuZXhwb3J0IGNvbnN0IFNUT1JFID0gJ19zdG9yZSc7XG5leHBvcnQgY29uc3QgVFVQTEUgPSAnX3R1cGxlJztcbmV4cG9ydCBjb25zdCBNT0RJRlkgPSAnX21vZGlmeSc7XG5leHBvcnQgY29uc3QgU0VMRUNUSU9OX0RPTUFJTiA9ICdfc2VsZWN0aW9uX2RvbWFpbl8nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdGlvbkNvbXBvbmVudCB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogU2VsZWN0aW9uVHlwZTtcbiAgZXZlbnRzOiBWZ0V2ZW50U3RyZWFtO1xuICAvLyBwcmVkaWNhdGU/OiBzdHJpbmc7XG4gIGJpbmQ/OiAnc2NhbGVzJyB8IFZnQmluZGluZyB8IHtba2V5OiBzdHJpbmddOiBWZ0JpbmRpbmd9O1xuICByZXNvbHZlOiBTZWxlY3Rpb25SZXNvbHV0aW9uO1xuICBlbXB0eTogJ2FsbCcgfCAnbm9uZSc7XG4gIG1hcms/OiBCcnVzaENvbmZpZztcblxuICAvLyBUcmFuc2Zvcm1zXG4gIHByb2plY3Q/OiBQcm9qZWN0Q29tcG9uZW50W107XG4gIGZpZWxkcz86IGFueTtcbiAgdGltZVVuaXQ/OiBUaW1lVW5pdE5vZGU7XG4gIHNjYWxlcz86IENoYW5uZWxbXTtcbiAgdG9nZ2xlPzogYW55O1xuICB0cmFuc2xhdGU/OiBhbnk7XG4gIHpvb20/OiBhbnk7XG4gIG5lYXJlc3Q/OiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvamVjdENvbXBvbmVudCB7XG4gIGZpZWxkPzogc3RyaW5nO1xuICBjaGFubmVsPzogU2NhbGVDaGFubmVsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdGlvbkNvbXBpbGVyIHtcbiAgc2lnbmFsczogKG1vZGVsOiBVbml0TW9kZWwsIHNlbENtcHQ6IFNlbGVjdGlvbkNvbXBvbmVudCkgPT4gYW55W107XG4gIHRvcExldmVsU2lnbmFscz86IChtb2RlbDogTW9kZWwsIHNlbENtcHQ6IFNlbGVjdGlvbkNvbXBvbmVudCwgc2lnbmFsczogYW55W10pID0+IGFueVtdO1xuICBtb2RpZnlFeHByOiAobW9kZWw6IFVuaXRNb2RlbCwgc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50KSA9PiBzdHJpbmc7XG4gIG1hcmtzPzogKG1vZGVsOiBVbml0TW9kZWwsIHNlbENtcHQ6U2VsZWN0aW9uQ29tcG9uZW50LCBtYXJrczogYW55W10pID0+IGFueVtdO1xuICBwcmVkaWNhdGU6IHN0cmluZzsgIC8vIFZlZ2EgZXhwciBzdHJpbmcgdG8gZGV0ZXJtaW5lIGluY2x1c2lvbiBpbiBzZWxlY3Rpb24uXG4gIHNjYWxlRG9tYWluOiBzdHJpbmc7ICAvLyBWZWdhIGV4cHIgc3RyaW5nIHRvIG1hdGVyaWFsaXplIGEgc2NhbGUgZG9tYWluLlxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VVbml0U2VsZWN0aW9uKG1vZGVsOiBVbml0TW9kZWwsIHNlbERlZnM6IERpY3Q8U2VsZWN0aW9uRGVmPikge1xuICBjb25zdCBzZWxDbXB0czogRGljdDxTZWxlY3Rpb25Db21wb25lbnQ+ID0ge307XG4gIGNvbnN0IHNlbGVjdGlvbkNvbmZpZyA9IG1vZGVsLmNvbmZpZy5zZWxlY3Rpb247XG5cbiAgZm9yIChsZXQgbmFtZSBpbiBzZWxEZWZzKSB7XG4gICAgaWYgKCFzZWxEZWZzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxEZWYgPSBzZWxEZWZzW25hbWVdO1xuICAgIGNvbnN0IGNmZyA9IHNlbGVjdGlvbkNvbmZpZ1tzZWxEZWYudHlwZV07XG5cbiAgICAvLyBTZXQgZGVmYXVsdCB2YWx1ZXMgZnJvbSBjb25maWcgaWYgYSBwcm9wZXJ0eSBoYXNuJ3QgYmVlbiBzcGVjaWZpZWQsXG4gICAgLy8gb3IgaWYgaXQgaXMgdHJ1ZS4gRS5nLiwgXCJ0cmFuc2xhdGVcIjogdHJ1ZSBzaG91bGQgdXNlIHRoZSBkZWZhdWx0XG4gICAgLy8gZXZlbnQgaGFuZGxlcnMgZm9yIHRyYW5zbGF0ZS4gSG93ZXZlciwgdHJ1ZSBtYXkgYmUgYSB2YWxpZCB2YWx1ZSBmb3JcbiAgICAvLyBhIHByb3BlcnR5IChlLmcuLCBcIm5lYXJlc3RcIjogdHJ1ZSkuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gY2ZnKSB7XG4gICAgICAvLyBBIHNlbGVjdGlvbiBzaG91bGQgY29udGFpbiBlaXRoZXIgYGVuY29kaW5nc2Agb3IgYGZpZWxkc2AsIG9ubHkgdXNlXG4gICAgICAvLyBkZWZhdWx0IHZhbHVlcyBmb3IgdGhlc2UgdHdvIHZhbHVlcyBpZiBuZWl0aGVyIG9mIHRoZW0gaXMgc3BlY2lmaWVkLlxuICAgICAgaWYgKChrZXkgPT09ICdlbmNvZGluZ3MnICYmIHNlbERlZi5maWVsZHMpIHx8IChrZXkgPT09ICdmaWVsZHMnICYmIHNlbERlZi5lbmNvZGluZ3MpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ID09PSAnbWFyaycpIHtcbiAgICAgICAgc2VsRGVmW2tleV0gPSB7Li4uY2ZnW2tleV0sIC4uLnNlbERlZltrZXldfTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNlbERlZltrZXldID09PSB1bmRlZmluZWQgfHwgc2VsRGVmW2tleV0gPT09IHRydWUpIHtcbiAgICAgICAgc2VsRGVmW2tleV0gPSBjZmdba2V5XSB8fCBzZWxEZWZba2V5XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBuYW1lID0gdmFyTmFtZShuYW1lKTtcbiAgICBjb25zdCBzZWxDbXB0ID0gc2VsQ21wdHNbbmFtZV0gPSB7XG4gICAgICAuLi5zZWxEZWYsXG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgZXZlbnRzOiBpc1N0cmluZyhzZWxEZWYub24pID8gcGFyc2VTZWxlY3RvcihzZWxEZWYub24sICdzY29wZScpIDogc2VsRGVmLm9uLFxuICAgIH0gYXMgU2VsZWN0aW9uQ29tcG9uZW50O1xuXG4gICAgZm9yRWFjaFRyYW5zZm9ybShzZWxDbXB0LCB0eENvbXBpbGVyID0+IHtcbiAgICAgIGlmICh0eENvbXBpbGVyLnBhcnNlKSB7XG4gICAgICAgIHR4Q29tcGlsZXIucGFyc2UobW9kZWwsIHNlbERlZiwgc2VsQ21wdCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc2VsQ21wdHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlbWJsZVVuaXRTZWxlY3Rpb25TaWduYWxzKG1vZGVsOiBVbml0TW9kZWwsIHNpZ25hbHM6IGFueVtdKSB7XG4gIGZvckVhY2hTZWxlY3Rpb24obW9kZWwsIChzZWxDbXB0LCBzZWxDb21waWxlcikgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSBzZWxDbXB0Lm5hbWU7XG4gICAgbGV0IG1vZGlmeUV4cHIgPSBzZWxDb21waWxlci5tb2RpZnlFeHByKG1vZGVsLCBzZWxDbXB0KTtcblxuICAgIHNpZ25hbHMucHVzaC5hcHBseShzaWduYWxzLCBzZWxDb21waWxlci5zaWduYWxzKG1vZGVsLCBzZWxDbXB0KSk7XG5cbiAgICBmb3JFYWNoVHJhbnNmb3JtKHNlbENtcHQsIHR4Q29tcGlsZXIgPT4ge1xuICAgICAgaWYgKHR4Q29tcGlsZXIuc2lnbmFscykge1xuICAgICAgICBzaWduYWxzID0gdHhDb21waWxlci5zaWduYWxzKG1vZGVsLCBzZWxDbXB0LCBzaWduYWxzKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eENvbXBpbGVyLm1vZGlmeUV4cHIpIHtcbiAgICAgICAgbW9kaWZ5RXhwciA9IHR4Q29tcGlsZXIubW9kaWZ5RXhwcihtb2RlbCwgc2VsQ21wdCwgbW9kaWZ5RXhwcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBzaWduYWxzLnB1c2goe1xuICAgICAgbmFtZTogbmFtZSArIE1PRElGWSxcbiAgICAgIG9uOiBbe1xuICAgICAgICBldmVudHM6IHtzaWduYWw6IG5hbWUgKyBUVVBMRX0sXG4gICAgICAgIHVwZGF0ZTogYG1vZGlmeSgke3N0cmluZ1ZhbHVlKHNlbENtcHQubmFtZSArIFNUT1JFKX0sICR7bW9kaWZ5RXhwcn0pYFxuICAgICAgfV1cbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3QgZmFjZXRNb2RlbCA9IGdldEZhY2V0TW9kZWwobW9kZWwpO1xuICBpZiAoc2lnbmFscy5sZW5ndGggJiYgZmFjZXRNb2RlbCkge1xuICAgIGNvbnN0IG5hbWUgPSBzdHJpbmdWYWx1ZShmYWNldE1vZGVsLmdldE5hbWUoJ2NlbGwnKSk7XG4gICAgc2lnbmFscy51bnNoaWZ0KHtcbiAgICAgIG5hbWU6ICdmYWNldCcsXG4gICAgICB2YWx1ZToge30sXG4gICAgICBvbjogW3tcbiAgICAgICAgZXZlbnRzOiBwYXJzZVNlbGVjdG9yKCdtb3VzZW1vdmUnLCAnc2NvcGUnKSxcbiAgICAgICAgdXBkYXRlOiBgaXNUdXBsZShmYWNldCkgPyBmYWNldCA6IGdyb3VwKCR7bmFtZX0pLmRhdHVtYFxuICAgICAgfV1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBzaWduYWxzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZW1ibGVUb3BMZXZlbFNpZ25hbHMobW9kZWw6IFVuaXRNb2RlbCwgc2lnbmFsczogYW55W10pIHtcbiAgbGV0IG5lZWRzVW5pdCA9IGZhbHNlO1xuICBmb3JFYWNoU2VsZWN0aW9uKG1vZGVsLCAoc2VsQ21wdCwgc2VsQ29tcGlsZXIpID0+IHtcbiAgICBpZiAoc2VsQ29tcGlsZXIudG9wTGV2ZWxTaWduYWxzKSB7XG4gICAgICBzaWduYWxzID0gc2VsQ29tcGlsZXIudG9wTGV2ZWxTaWduYWxzKG1vZGVsLCBzZWxDbXB0LCBzaWduYWxzKTtcbiAgICB9XG5cbiAgICBmb3JFYWNoVHJhbnNmb3JtKHNlbENtcHQsIHR4Q29tcGlsZXIgPT4ge1xuICAgICAgaWYgKHR4Q29tcGlsZXIudG9wTGV2ZWxTaWduYWxzKSB7XG4gICAgICAgIHNpZ25hbHMgPSB0eENvbXBpbGVyLnRvcExldmVsU2lnbmFscyhtb2RlbCwgc2VsQ21wdCwgc2lnbmFscyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBuZWVkc1VuaXQgPSB0cnVlO1xuICB9KTtcblxuICBpZiAobmVlZHNVbml0KSB7XG4gICAgY29uc3QgaGFzVW5pdCA9IHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICd1bml0Jyk7XG4gICAgaWYgKCEoaGFzVW5pdC5sZW5ndGgpKSB7XG4gICAgICBzaWduYWxzLnVuc2hpZnQoe1xuICAgICAgICBuYW1lOiAndW5pdCcsXG4gICAgICAgIHZhbHVlOiB7fSxcbiAgICAgICAgb246IFt7ZXZlbnRzOiAnbW91c2Vtb3ZlJywgdXBkYXRlOiAnaXNUdXBsZShncm91cCgpKSA/IGdyb3VwKCkgOiB1bml0J31dXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc2lnbmFscztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlVW5pdFNlbGVjdGlvbkRhdGEobW9kZWw6IFVuaXRNb2RlbCwgZGF0YTogVmdEYXRhW10pOiBWZ0RhdGFbXSB7XG4gIGZvckVhY2hTZWxlY3Rpb24obW9kZWwsIHNlbENtcHQgPT4ge1xuICAgIGNvbnN0IGNvbnRhaW5zID0gZGF0YS5maWx0ZXIoKGQpID0+IGQubmFtZSA9PT0gc2VsQ21wdC5uYW1lICsgU1RPUkUpO1xuICAgIGlmICghY29udGFpbnMubGVuZ3RoKSB7XG4gICAgICBkYXRhLnB1c2goe25hbWU6IHNlbENtcHQubmFtZSArIFNUT1JFfSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlVW5pdFNlbGVjdGlvbk1hcmtzKG1vZGVsOiBVbml0TW9kZWwsIG1hcmtzOiBhbnlbXSk6IGFueVtdIHtcbiAgZm9yRWFjaFNlbGVjdGlvbihtb2RlbCwgKHNlbENtcHQsIHNlbENvbXBpbGVyKSA9PiB7XG4gICAgbWFya3MgPSBzZWxDb21waWxlci5tYXJrcyA/IHNlbENvbXBpbGVyLm1hcmtzKG1vZGVsLCBzZWxDbXB0LCBtYXJrcykgOiBtYXJrcztcbiAgICBmb3JFYWNoVHJhbnNmb3JtKHNlbENtcHQsICh0eENvbXBpbGVyKSA9PiB7XG4gICAgICBpZiAodHhDb21waWxlci5tYXJrcykge1xuICAgICAgICBtYXJrcyA9IHR4Q29tcGlsZXIubWFya3MobW9kZWwsIHNlbENtcHQsIG1hcmtzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIG1hcmtzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZW1ibGVMYXllclNlbGVjdGlvbk1hcmtzKG1vZGVsOiBMYXllck1vZGVsLCBtYXJrczogYW55W10pOiBhbnlbXSB7XG4gIG1vZGVsLmNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4ge1xuICAgIGlmIChpc1VuaXRNb2RlbChjaGlsZCkpIHtcbiAgICAgIG1hcmtzID0gYXNzZW1ibGVVbml0U2VsZWN0aW9uTWFya3MoY2hpbGQsIG1hcmtzKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBtYXJrcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByZWRpY2F0ZShtb2RlbDogTW9kZWwsIHNlbGVjdGlvbnM6IExvZ2ljYWxPcGVyYW5kPHN0cmluZz4sIGRmbm9kZT86IERhdGFGbG93Tm9kZSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0b3Jlczogc3RyaW5nW10gPSBbXTtcbiAgZnVuY3Rpb24gZXhwcihuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZuYW1lID0gdmFyTmFtZShuYW1lKTtcbiAgICBjb25zdCBzZWxDbXB0ID0gbW9kZWwuZ2V0U2VsZWN0aW9uQ29tcG9uZW50KHZuYW1lLCBuYW1lKTtcbiAgICBjb25zdCBzdG9yZSA9IHN0cmluZ1ZhbHVlKHZuYW1lICsgU1RPUkUpO1xuXG4gICAgaWYgKHNlbENtcHQudGltZVVuaXQpIHtcbiAgICAgIGNvbnN0IGNoaWxkID0gZGZub2RlIHx8IG1vZGVsLmNvbXBvbmVudC5kYXRhLnJhdztcbiAgICAgIGNvbnN0IHR1bm9kZSA9IHNlbENtcHQudGltZVVuaXQuY2xvbmUoKTtcbiAgICAgIGlmIChjaGlsZC5wYXJlbnQpIHtcbiAgICAgICAgdHVub2RlLmluc2VydEFzUGFyZW50T2YoY2hpbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gdHVub2RlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZWxDbXB0LmVtcHR5ICE9PSAnbm9uZScpIHtcbiAgICAgIHN0b3Jlcy5wdXNoKHN0b3JlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcGlsZXIoc2VsQ21wdC50eXBlKS5wcmVkaWNhdGUgKyBgKCR7c3RvcmV9LCBkYXR1bWAgK1xuICAgICAgKHNlbENtcHQucmVzb2x2ZSA9PT0gJ2dsb2JhbCcgPyAnKScgOiBgLCAke3N0cmluZ1ZhbHVlKHNlbENtcHQucmVzb2x2ZSl9KWApO1xuICB9XG5cbiAgY29uc3QgcHJlZGljYXRlU3RyID0gbG9naWNhbEV4cHIoc2VsZWN0aW9ucywgZXhwcik7XG4gIHJldHVybiAoc3RvcmVzLmxlbmd0aFxuICAgID8gJyEoJyArIHN0b3Jlcy5tYXAoKHMpID0+IGBsZW5ndGgoZGF0YSgke3N9KSlgKS5qb2luKCcgfHwgJykgKyAnKSB8fCAnXG4gICAgOiAnJ1xuICApICsgYCgke3ByZWRpY2F0ZVN0cn0pYDtcbn1cblxuLy8gU2VsZWN0aW9ucyBhcmUgcGFyc2VkIF9hZnRlcl8gc2NhbGVzLiBJZiBhIHNjYWxlIGRvbWFpbiBpcyBzZXQgdG9cbi8vIHVzZSBhIHNlbGVjdGlvbiwgdGhlIFNFTEVDVElPTl9ET01BSU4gY29uc3RhbnQgaXMgdXNlZCBhcyB0aGVcbi8vIGRvbWFpblJhdy5zaWduYWwgZHVyaW5nIHNjYWxlLnBhcnNlIGFuZCB0aGVuIHJlcGxhY2VkIHdpdGggdGhlIG5lY2Vzc2FyeVxuLy8gc2VsZWN0aW9uIGV4cHJlc3Npb24gZnVuY3Rpb24gZHVyaW5nIHNjYWxlLmFzc2VtYmxlLiBUbyBub3QgcG9sbHV0ZSB0aGVcbi8vIHR5cGUgc2lnbmF0dXJlcyB0byBhY2NvdW50IGZvciB0aGlzIHNldHVwLCB0aGUgc2VsZWN0aW9uIGRvbWFpbiBkZWZpbml0aW9uXG4vLyBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nIGFuZCBhcHBlbmRlZCB0byBTRUxFQ1RJT05fRE9NQUlOLlxuZXhwb3J0IGZ1bmN0aW9uIGlzUmF3U2VsZWN0aW9uRG9tYWluKGRvbWFpblJhdzogVmdTaWduYWxSZWYpIHtcbiAgcmV0dXJuIGRvbWFpblJhdy5zaWduYWwuaW5kZXhPZihTRUxFQ1RJT05fRE9NQUlOKSA+PSAwO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdGlvblNjYWxlRG9tYWluKG1vZGVsOiBNb2RlbCwgZG9tYWluUmF3OiBWZ1NpZ25hbFJlZik6IFZnU2lnbmFsUmVmIHtcbiAgY29uc3Qgc2VsRG9tYWluID0gSlNPTi5wYXJzZShkb21haW5SYXcuc2lnbmFsLnJlcGxhY2UoU0VMRUNUSU9OX0RPTUFJTiwgJycpKTtcbiAgY29uc3QgbmFtZSA9IHZhck5hbWUoc2VsRG9tYWluLnNlbGVjdGlvbik7XG5cbiAgbGV0IHNlbENtcHQgPSBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uICYmIG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb25bbmFtZV07XG4gIGlmIChzZWxDbXB0KSB7XG4gICAgd2FybignVXNlIFwiYmluZFwiOiBcInNjYWxlc1wiIHRvIHNldHVwIGEgYmluZGluZyBmb3Igc2NhbGVzIGFuZCBzZWxlY3Rpb25zIHdpdGhpbiB0aGUgc2FtZSB2aWV3LicpO1xuICB9IGVsc2Uge1xuICAgIHNlbENtcHQgPSBtb2RlbC5nZXRTZWxlY3Rpb25Db21wb25lbnQobmFtZSwgc2VsRG9tYWluLnNlbGVjdGlvbik7XG4gICAgaWYgKCFzZWxEb21haW4uZW5jb2RpbmcgJiYgIXNlbERvbWFpbi5maWVsZCkge1xuICAgICAgc2VsRG9tYWluLmZpZWxkID0gc2VsQ21wdC5wcm9qZWN0WzBdLmZpZWxkO1xuICAgICAgaWYgKHNlbENtcHQucHJvamVjdC5sZW5ndGggPiAxKSB7XG4gICAgICAgIHdhcm4oJ0EgXCJmaWVsZFwiIG9yIFwiZW5jb2RpbmdcIiBtdXN0IGJlIHNwZWNpZmllZCB3aGVuIHVzaW5nIGEgc2VsZWN0aW9uIGFzIGEgc2NhbGUgZG9tYWluLiAnICtcbiAgICAgICAgYFVzaW5nIFwiZmllbGRcIjogJHtzdHJpbmdWYWx1ZShzZWxEb21haW4uZmllbGQpfS5gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHNpZ25hbDogY29tcGlsZXIoc2VsQ21wdC50eXBlKS5zY2FsZURvbWFpbiArXG4gICAgICAgIGAoJHtzdHJpbmdWYWx1ZShuYW1lICsgU1RPUkUpfSwgJHtzdHJpbmdWYWx1ZShzZWxEb21haW4uZW5jb2RpbmcgfHwgbnVsbCl9LCBgICtcbiAgICAgICAgICBzdHJpbmdWYWx1ZShzZWxEb21haW4uZmllbGQgfHwgbnVsbCkgK1xuICAgICAgICAgIChzZWxDbXB0LnJlc29sdmUgPT09ICdnbG9iYWwnID8gJyknIDogYCwgJHtzdHJpbmdWYWx1ZShzZWxDbXB0LnJlc29sdmUpfSlgKVxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge3NpZ25hbDogJ251bGwnfTtcbn1cblxuLy8gVXRpbGl0eSBmdW5jdGlvbnNcblxuZnVuY3Rpb24gZm9yRWFjaFNlbGVjdGlvbihtb2RlbDogTW9kZWwsIGNiOiAoc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50LCBzZWxDb21waWxlcjogU2VsZWN0aW9uQ29tcGlsZXIpID0+IHZvaWQpIHtcbiAgY29uc3Qgc2VsZWN0aW9ucyA9IG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb247XG4gIGZvciAoY29uc3QgbmFtZSBpbiBzZWxlY3Rpb25zKSB7XG4gICAgaWYgKHNlbGVjdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgIGNvbnN0IHNlbCA9IHNlbGVjdGlvbnNbbmFtZV07XG4gICAgICBjYihzZWwsIGNvbXBpbGVyKHNlbC50eXBlKSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVyKHR5cGU6IFNlbGVjdGlvblR5cGUpOiBTZWxlY3Rpb25Db21waWxlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3NpbmdsZSc6XG4gICAgICByZXR1cm4gc2luZ2xlQ29tcGlsZXI7XG4gICAgY2FzZSAnbXVsdGknOlxuICAgICAgcmV0dXJuIG11bHRpQ29tcGlsZXI7XG4gICAgY2FzZSAnaW50ZXJ2YWwnOlxuICAgICAgcmV0dXJuIGludGVydmFsQ29tcGlsZXI7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldEZhY2V0TW9kZWwobW9kZWw6IE1vZGVsKTogRmFjZXRNb2RlbCB7XG4gIGxldCBwYXJlbnQgPSBtb2RlbC5wYXJlbnQ7XG4gIHdoaWxlIChwYXJlbnQpIHtcbiAgICBpZiAoaXNGYWNldE1vZGVsKHBhcmVudCkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICB9XG5cbiAgcmV0dXJuIHBhcmVudCBhcyBGYWNldE1vZGVsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pdE5hbWUobW9kZWw6IE1vZGVsKSB7XG4gIGxldCBuYW1lID0gc3RyaW5nVmFsdWUobW9kZWwubmFtZSk7XG4gIGNvbnN0IGZhY2V0ID0gZ2V0RmFjZXRNb2RlbChtb2RlbCk7XG4gIGlmIChmYWNldCkge1xuICAgIG5hbWUgKz0gKGZhY2V0LmZhY2V0LnJvdyA/IGAgKyAnXycgKyBmYWNldCR7YWNjZXNzUGF0aChmYWNldC5maWVsZCgncm93JykpfWAgOiAnJylcbiAgICAgICsgKGZhY2V0LmZhY2V0LmNvbHVtbiA/IGAgKyAnXycgKyBmYWNldCR7YWNjZXNzUGF0aChmYWNldC5maWVsZCgnY29sdW1uJykpfWAgOiAnJyk7XG4gIH1cbiAgcmV0dXJuIG5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlc1NlbGVjdGlvbklkKG1vZGVsOiBNb2RlbCkge1xuICBsZXQgaWRlbnRpZmllciA9IGZhbHNlO1xuICBmb3JFYWNoU2VsZWN0aW9uKG1vZGVsLCAoc2VsQ21wdCkgPT4ge1xuICAgIGlkZW50aWZpZXIgPSBpZGVudGlmaWVyIHx8IHNlbENtcHQucHJvamVjdC5zb21lKChwcm9qKSA9PiBwcm9qLmZpZWxkID09PSBTRUxFQ1RJT05fSUQpO1xuICB9KTtcbiAgcmV0dXJuIGlkZW50aWZpZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGFubmVsU2lnbmFsTmFtZShzZWxDbXB0OiBTZWxlY3Rpb25Db21wb25lbnQsIGNoYW5uZWw6IENoYW5uZWwsIHJhbmdlOiAndmlzdWFsJyB8ICdkYXRhJykge1xuICByZXR1cm4gdmFyTmFtZShzZWxDbXB0Lm5hbWUgKyAnXycgKyAocmFuZ2UgPT09ICd2aXN1YWwnID8gY2hhbm5lbCA6IHNlbENtcHQuZmllbGRzW2NoYW5uZWxdKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwb3NpdGlvbmFsUHJvamVjdGlvbnMoc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50KSB7XG4gIGxldCB4OlByb2plY3RDb21wb25lbnQgPSBudWxsO1xuICBsZXQgeGk6bnVtYmVyID0gbnVsbDtcbiAgbGV0IHk6UHJvamVjdENvbXBvbmVudCA9IG51bGw7XG4gIGxldCB5aTogbnVtYmVyID0gbnVsbDtcblxuICBzZWxDbXB0LnByb2plY3QuZm9yRWFjaCgocCwgaSkgPT4ge1xuICAgIGlmIChwLmNoYW5uZWwgPT09IFgpIHtcbiAgICAgIHggPSBwO1xuICAgICAgeGkgPSBpO1xuICAgIH0gZWxzZSBpZiAocC5jaGFubmVsID09PSBZKSB7XG4gICAgICB5ID0gcDtcbiAgICAgIHlpID0gaTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4ge3gsIHhpLCB5LCB5aX07XG59XG4iXX0= \ 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..8a1db8583c --- /dev/null +++ b/build/src/compile/selection/single.d.ts @@ -0,0 +1,3 @@ +import { SelectionCompiler } from './selection'; +declare const single: SelectionCompiler; +export { single as default }; diff --git a/build/src/compile/selection/single.js b/build/src/compile/selection/single.js new file mode 100644 index 0000000000..cf390f542b --- /dev/null +++ b/build/src/compile/selection/single.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var multi_1 = require("./multi"); +var selection_1 = require("./selection"); +var single = { + predicate: 'vlSingle', + scaleDomain: 'vlSingleDomain', + signals: multi_1.default.signals, + topLevelSignals: function (model, selCmpt, signals) { + var hasSignal = signals.filter(function (s) { return s.name === selCmpt.name; }); + var data = "data(" + util_1.stringValue(selCmpt.name + selection_1.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 + selection_1.TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + selection_1.unitName(model) + "}"); + } +}; +exports.default = single; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NpbmdsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQUF1QztBQUN2QyxpQ0FBNEI7QUFDNUIseUNBQXNFO0FBR3RFLElBQU0sTUFBTSxHQUFxQjtJQUMvQixTQUFTLEVBQUUsVUFBVTtJQUNyQixXQUFXLEVBQUUsZ0JBQWdCO0lBRTdCLE9BQU8sRUFBRSxlQUFLLENBQUMsT0FBTztJQUV0QixlQUFlLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU87UUFDL0MsSUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLElBQUksRUFBdkIsQ0FBdUIsQ0FBQyxDQUFDO1FBQ2pFLElBQU0sSUFBSSxHQUFHLFVBQVEsa0JBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLGlCQUFLLENBQUMsTUFBRyxDQUFDO1FBQzFELElBQU0sTUFBTSxHQUFNLElBQUksZUFBWSxDQUFDO1FBQ25DLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDakQsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQ2xCLE1BQU0sRUFBSyxJQUFJLGlCQUFjO2dCQUMzQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFDLENBQUMsRUFBRSxDQUFDLElBQUssT0FBRyxDQUFDLENBQUMsS0FBSyxVQUFLLE1BQU0sU0FBSSxDQUFDLE1BQUcsRUFBN0IsQ0FBNkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHO1NBQ2hGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxVQUFVLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTztRQUNqQyxJQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsSUFBSSxHQUFHLGlCQUFLLENBQUM7UUFDakMsTUFBTSxDQUFDLEdBQUcsR0FBRyxJQUFJO1lBQ2YsQ0FBQyxPQUFPLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFVLG9CQUFRLENBQUMsS0FBSyxDQUFDLE1BQUcsQ0FBQyxDQUFDO0lBQzNFLENBQUM7Q0FDRixDQUFDO0FBRWdCLHlCQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtzdHJpbmdWYWx1ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgbXVsdGkgZnJvbSAnLi9tdWx0aSc7XG5pbXBvcnQge1NlbGVjdGlvbkNvbXBpbGVyLCBTVE9SRSwgVFVQTEUsIHVuaXROYW1lfSBmcm9tICcuL3NlbGVjdGlvbic7XG5cblxuY29uc3Qgc2luZ2xlOlNlbGVjdGlvbkNvbXBpbGVyID0ge1xuICBwcmVkaWNhdGU6ICd2bFNpbmdsZScsXG4gIHNjYWxlRG9tYWluOiAndmxTaW5nbGVEb21haW4nLFxuXG4gIHNpZ25hbHM6IG11bHRpLnNpZ25hbHMsXG5cbiAgdG9wTGV2ZWxTaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCwgc2lnbmFscykge1xuICAgIGNvbnN0IGhhc1NpZ25hbCA9IHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09IHNlbENtcHQubmFtZSk7XG4gICAgY29uc3QgZGF0YSA9IGBkYXRhKCR7c3RyaW5nVmFsdWUoc2VsQ21wdC5uYW1lICsgU1RPUkUpfSlgO1xuICAgIGNvbnN0IHZhbHVlcyA9IGAke2RhdGF9WzBdLnZhbHVlc2A7XG4gICAgcmV0dXJuIGhhc1NpZ25hbC5sZW5ndGggPyBzaWduYWxzIDogc2lnbmFscy5jb25jYXQoe1xuICAgICAgbmFtZTogc2VsQ21wdC5uYW1lLFxuICAgICAgdXBkYXRlOiBgJHtkYXRhfS5sZW5ndGggJiYge2AgK1xuICAgICAgICBzZWxDbXB0LnByb2plY3QubWFwKChwLCBpKSA9PiBgJHtwLmZpZWxkfTogJHt2YWx1ZXN9WyR7aX1dYCkuam9pbignLCAnKSArICd9J1xuICAgIH0pO1xuICB9LFxuXG4gIG1vZGlmeUV4cHI6IGZ1bmN0aW9uKG1vZGVsLCBzZWxDbXB0KSB7XG4gICAgY29uc3QgdHBsID0gc2VsQ21wdC5uYW1lICsgVFVQTEU7XG4gICAgcmV0dXJuIHRwbCArICcsICcgK1xuICAgICAgKHNlbENtcHQucmVzb2x2ZSA9PT0gJ2dsb2JhbCcgPyAndHJ1ZScgOiBge3VuaXQ6ICR7dW5pdE5hbWUobW9kZWwpfX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IHtzaW5nbGUgYXMgZGVmYXVsdH07XG4iXX0= \ 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..a86baa2131 --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const inputBindings: TransformCompiler; +export { inputBindings as default }; diff --git a/build/src/compile/selection/transforms/inputs.js b/build/src/compile/selection/transforms/inputs.js new file mode 100644 index 0000000000..5e2cbeb9c5 --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../../util"); +var selection_1 = require("../selection"); +var nearest_1 = require("./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_1.default.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + proj.forEach(function (p) { + var sgname = util_1.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' ? " + datum + util_1.accessPath(p.field) + " : 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 + selection_1.TUPLE; })[0]; + var fields = proj.map(function (p) { return util_1.stringValue(p.field); }).join(', '); + var values = proj.map(function (p) { return util_1.varName(name + "_" + p.field); }); + signal.update = values.join(' && ') + " ? {fields: [" + fields + "], values: [" + values.join(', ') + "]} : null"; + delete signal.value; + delete signal.on; + return signals; + } +}; +exports.default = inputBindings; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvaW5wdXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsc0NBQStEO0FBQy9ELDBDQUFtQztBQUNuQyxxQ0FBZ0M7QUFJaEMsSUFBTSxhQUFhLEdBQXFCO0lBQ3RDLEdBQUcsRUFBRSxVQUFTLE9BQU87UUFDbkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxPQUFPLEtBQUssUUFBUTtZQUM5RCxPQUFPLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDO0lBQzlDLENBQUM7SUFFRCxlQUFlLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU87UUFDL0MsSUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQzdCLElBQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDMUIsSUFBTSxLQUFLLEdBQUcsaUJBQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNsQywwQ0FBMEMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBRXZELElBQUksQ0FBQyxPQUFPLENBQUMsVUFBUyxDQUFDO1lBQ3JCLElBQU0sTUFBTSxHQUFHLGNBQU8sQ0FBSSxJQUFJLFNBQUksQ0FBQyxDQUFDLEtBQU8sQ0FBQyxDQUFDO1lBQzdDLElBQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBakIsQ0FBaUIsQ0FBQyxDQUFDO1lBQzNELEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLE9BQU8sQ0FBQyxPQUFPLENBQUM7b0JBQ2QsSUFBSSxFQUFFLE1BQU07b0JBQ1osS0FBSyxFQUFFLEVBQUU7b0JBQ1QsRUFBRSxFQUFFLENBQUM7NEJBQ0gsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNOzRCQUN0QixNQUFNLEVBQUUsaURBQStDLEtBQUssR0FBRyxpQkFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsWUFBUzt5QkFDNUYsQ0FBQztvQkFDRixJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUk7aUJBQy9DLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELE9BQU8sRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTztRQUN2QyxJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQzFCLElBQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDN0IsSUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHLGlCQUFLLEVBQXZCLENBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRSxJQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsa0JBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQXBCLENBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEUsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLGNBQU8sQ0FBSSxJQUFJLFNBQUksQ0FBQyxDQUFDLEtBQU8sQ0FBQyxFQUE3QixDQUE2QixDQUFDLENBQUM7UUFFOUQsTUFBTSxDQUFDLE1BQU0sR0FBTSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBZ0IsTUFBTSxvQkFBZSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFXLENBQUM7UUFDeEcsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ3BCLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUVqQixNQUFNLENBQUMsT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FDRixDQUFDO0FBRXVCLGdDQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthY2Nlc3NQYXRoLCBzdHJpbmdWYWx1ZSwgdmFyTmFtZX0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1RVUExFfSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuaW1wb3J0IG5lYXJlc3QgZnJvbSAnLi9uZWFyZXN0JztcbmltcG9ydCB7VHJhbnNmb3JtQ29tcGlsZXJ9IGZyb20gJy4vdHJhbnNmb3Jtcyc7XG5cblxuY29uc3QgaW5wdXRCaW5kaW5nczpUcmFuc2Zvcm1Db21waWxlciA9IHtcbiAgaGFzOiBmdW5jdGlvbihzZWxDbXB0KSB7XG4gICAgcmV0dXJuIHNlbENtcHQudHlwZSA9PT0gJ3NpbmdsZScgJiYgc2VsQ21wdC5yZXNvbHZlID09PSAnZ2xvYmFsJyAmJlxuICAgICAgc2VsQ21wdC5iaW5kICYmIHNlbENtcHQuYmluZCAhPT0gJ3NjYWxlcyc7XG4gIH0sXG5cbiAgdG9wTGV2ZWxTaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCwgc2lnbmFscykge1xuICAgIGNvbnN0IG5hbWUgPSBzZWxDbXB0Lm5hbWU7XG4gICAgY29uc3QgcHJvaiA9IHNlbENtcHQucHJvamVjdDtcbiAgICBjb25zdCBiaW5kID0gc2VsQ21wdC5iaW5kO1xuICAgIGNvbnN0IGRhdHVtID0gbmVhcmVzdC5oYXMoc2VsQ21wdCkgP1xuICAgICAgJyhpdGVtKCkuaXNWb3Jvbm9pID8gZGF0dW0uZGF0dW0gOiBkYXR1bSknIDogJ2RhdHVtJztcblxuICAgIHByb2ouZm9yRWFjaChmdW5jdGlvbihwKSB7XG4gICAgICBjb25zdCBzZ25hbWUgPSB2YXJOYW1lKGAke25hbWV9XyR7cC5maWVsZH1gKTtcbiAgICAgIGNvbnN0IGhhc1NpZ25hbCA9IHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09IHNnbmFtZSk7XG4gICAgICBpZiAoIWhhc1NpZ25hbC5sZW5ndGgpIHtcbiAgICAgICAgc2lnbmFscy51bnNoaWZ0KHtcbiAgICAgICAgICBuYW1lOiBzZ25hbWUsXG4gICAgICAgICAgdmFsdWU6ICcnLFxuICAgICAgICAgIG9uOiBbe1xuICAgICAgICAgICAgZXZlbnRzOiBzZWxDbXB0LmV2ZW50cyxcbiAgICAgICAgICAgIHVwZGF0ZTogYGRhdHVtICYmIGl0ZW0oKS5tYXJrLm1hcmt0eXBlICE9PSAnZ3JvdXAnID8gJHtkYXR1bX0ke2FjY2Vzc1BhdGgocC5maWVsZCl9IDogbnVsbGBcbiAgICAgICAgICB9XSxcbiAgICAgICAgICBiaW5kOiBiaW5kW3AuZmllbGRdIHx8IGJpbmRbcC5jaGFubmVsXSB8fCBiaW5kXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ25hbHM7XG4gIH0sXG5cbiAgc2lnbmFsczogZnVuY3Rpb24obW9kZWwsIHNlbENtcHQsIHNpZ25hbHMpIHtcbiAgICBjb25zdCBuYW1lID0gc2VsQ21wdC5uYW1lO1xuICAgIGNvbnN0IHByb2ogPSBzZWxDbXB0LnByb2plY3Q7XG4gICAgY29uc3Qgc2lnbmFsID0gc2lnbmFscy5maWx0ZXIoKHMpID0+IHMubmFtZSA9PT0gbmFtZSArIFRVUExFKVswXTtcbiAgICBjb25zdCBmaWVsZHMgPSBwcm9qLm1hcCgocCkgPT4gc3RyaW5nVmFsdWUocC5maWVsZCkpLmpvaW4oJywgJyk7XG4gICAgY29uc3QgdmFsdWVzID0gcHJvai5tYXAoKHApID0+IHZhck5hbWUoYCR7bmFtZX1fJHtwLmZpZWxkfWApKTtcblxuICAgIHNpZ25hbC51cGRhdGUgPSBgJHt2YWx1ZXMuam9pbignICYmICcpfSA/IHtmaWVsZHM6IFske2ZpZWxkc31dLCB2YWx1ZXM6IFske3ZhbHVlcy5qb2luKCcsICcpfV19IDogbnVsbGA7XG4gICAgZGVsZXRlIHNpZ25hbC52YWx1ZTtcbiAgICBkZWxldGUgc2lnbmFsLm9uO1xuXG4gICAgcmV0dXJuIHNpZ25hbHM7XG4gIH1cbn07XG5cbmV4cG9ydCB7aW5wdXRCaW5kaW5ncyBhcyBkZWZhdWx0fTtcbiJdfQ== \ 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..3fc5fb0148 --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const nearest: TransformCompiler; +export { nearest as default }; diff --git a/build/src/compile/selection/transforms/nearest.js b/build/src/compile/selection/transforms/nearest.js new file mode 100644 index 0000000000..da3f1dd748 --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../log"); +var selection_1 = require("../selection"); +var VORONOI = 'voronoi'; +var nearest = { + has: function (selCmpt) { + return selCmpt.type !== 'interval' && selCmpt.nearest; + }, + marks: function (model, selCmpt, marks) { + var _a = selection_1.positionalProjections(selCmpt), x = _a.x, y = _a.y; + var markType = model.mark(); + if (markType === 'line' || markType === 'area') { + 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: (x || (!x && !y)) ? 'datum.x' : { expr: '0' }, + y: (y || (!x && !y)) ? 'datum.y' : { expr: '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; + } +}; +exports.default = nearest; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVhcmVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL25lYXJlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxrQ0FBb0M7QUFDcEMsMENBQW1EO0FBR25ELElBQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQztBQUUxQixJQUFNLE9BQU8sR0FBcUI7SUFDaEMsR0FBRyxFQUFFLFVBQVMsT0FBTztRQUNuQixNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQztJQUN4RCxDQUFDO0lBRUQsS0FBSyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLO1FBQzdCLElBQUEsK0NBQXVDLEVBQXRDLFFBQUMsRUFBRSxRQUFDLENBQW1DO1FBQzlDLElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5QixFQUFFLENBQUMsQ0FBQyxRQUFRLEtBQUssTUFBTSxJQUFJLFFBQVEsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQy9DLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsSUFBTSxPQUFPLEdBQUc7WUFDZCxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDNUIsSUFBSSxFQUFFLE1BQU07WUFDWixJQUFJLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBQztZQUNwQyxNQUFNLEVBQUU7Z0JBQ04sS0FBSyxFQUFFO29CQUNMLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxhQUFhLEVBQUM7b0JBQzVCLFdBQVcsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUM7b0JBQzFCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxhQUFhLEVBQUM7b0JBQzlCLFNBQVMsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUM7aUJBQ3pCO2FBQ0Y7WUFDRCxTQUFTLEVBQUUsQ0FBQztvQkFDVixJQUFJLEVBQUUsU0FBUztvQkFDZixDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsR0FBRyxFQUFDO29CQUM5QyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsR0FBRyxFQUFDO29CQUM5QyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUMxRSxDQUFDO1NBQ0gsQ0FBQztRQUVGLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNuQixLQUFLLENBQUMsT0FBTyxDQUFDLFVBQUMsSUFBSSxFQUFFLENBQUM7WUFDcEIsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7WUFDN0IsRUFBRSxDQUFDLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzFDLEtBQUssR0FBRyxDQUFDLENBQUM7WUFDWixDQUFDO1lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEMsTUFBTSxHQUFHLElBQUksQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDWixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFFRCxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUNGLENBQUM7QUFFaUIsMEJBQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vbG9nJztcbmltcG9ydCB7cG9zaXRpb25hbFByb2plY3Rpb25zfSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtUcmFuc2Zvcm1Db21waWxlcn0gZnJvbSAnLi90cmFuc2Zvcm1zJztcblxuY29uc3QgVk9ST05PSSA9ICd2b3Jvbm9pJztcblxuY29uc3QgbmVhcmVzdDpUcmFuc2Zvcm1Db21waWxlciA9IHtcbiAgaGFzOiBmdW5jdGlvbihzZWxDbXB0KSB7XG4gICAgcmV0dXJuIHNlbENtcHQudHlwZSAhPT0gJ2ludGVydmFsJyAmJiBzZWxDbXB0Lm5lYXJlc3Q7XG4gIH0sXG5cbiAgbWFya3M6IGZ1bmN0aW9uKG1vZGVsLCBzZWxDbXB0LCBtYXJrcykge1xuICAgIGNvbnN0IHt4LCB5fSA9IHBvc2l0aW9uYWxQcm9qZWN0aW9ucyhzZWxDbXB0KTtcbiAgICBjb25zdCBtYXJrVHlwZSA9IG1vZGVsLm1hcmsoKTtcbiAgICBpZiAobWFya1R5cGUgPT09ICdsaW5lJyB8fCBtYXJrVHlwZSA9PT0gJ2FyZWEnKSB7XG4gICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5uZWFyZXN0Tm90U3VwcG9ydEZvckNvbnRpbnVvdXMobWFya1R5cGUpKTtcbiAgICAgIHJldHVybiBtYXJrcztcbiAgICB9XG5cbiAgICBjb25zdCBjZWxsRGVmID0ge1xuICAgICAgbmFtZTogbW9kZWwuZ2V0TmFtZShWT1JPTk9JKSxcbiAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgIGZyb206IHtkYXRhOiBtb2RlbC5nZXROYW1lKCdtYXJrcycpfSxcbiAgICAgIGVuY29kZToge1xuICAgICAgICBlbnRlcjoge1xuICAgICAgICAgIGZpbGw6IHt2YWx1ZTogJ3RyYW5zcGFyZW50J30sXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IHt2YWx1ZTogMC4zNX0sXG4gICAgICAgICAgc3Ryb2tlOiB7dmFsdWU6ICd0cmFuc3BhcmVudCd9LFxuICAgICAgICAgIGlzVm9yb25vaToge3ZhbHVlOiB0cnVlfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdHJhbnNmb3JtOiBbe1xuICAgICAgICB0eXBlOiAndm9yb25vaScsXG4gICAgICAgIHg6ICh4IHx8ICgheCAmJiAheSkpID8gJ2RhdHVtLngnIDoge2V4cHI6ICcwJ30sXG4gICAgICAgIHk6ICh5IHx8ICgheCAmJiAheSkpID8gJ2RhdHVtLnknIDoge2V4cHI6ICcwJ30sXG4gICAgICAgIHNpemU6IFttb2RlbC5nZXRTaXplU2lnbmFsUmVmKCd3aWR0aCcpLCBtb2RlbC5nZXRTaXplU2lnbmFsUmVmKCdoZWlnaHQnKV1cbiAgICAgIH1dXG4gICAgfTtcblxuICAgIGxldCBpbmRleCA9IDA7XG4gICAgbGV0IGV4aXN0cyA9IGZhbHNlO1xuICAgIG1hcmtzLmZvckVhY2goKG1hcmssIGkpID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBtYXJrLm5hbWUgfHwgJyc7XG4gICAgICBpZiAobmFtZSA9PT0gbW9kZWwuY29tcG9uZW50Lm1hcmtbMF0ubmFtZSkge1xuICAgICAgICBpbmRleCA9IGk7XG4gICAgICB9IGVsc2UgaWYgKG5hbWUuaW5kZXhPZihWT1JPTk9JKSA+PSAwKSB7XG4gICAgICAgIGV4aXN0cyA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoIWV4aXN0cykge1xuICAgICAgbWFya3Muc3BsaWNlKGluZGV4ICsgMSwgMCwgY2VsbERlZik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcmtzO1xuICB9XG59O1xuXG5leHBvcnQge25lYXJlc3QgYXMgZGVmYXVsdH07XG4iXX0= \ 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..bc267cb167 --- /dev/null +++ b/build/src/compile/selection/transforms/project.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const project: TransformCompiler; +export { project as default }; diff --git a/build/src/compile/selection/transforms/project.js b/build/src/compile/selection/transforms/project.js new file mode 100644 index 0000000000..832ab812a5 --- /dev/null +++ b/build/src/compile/selection/transforms/project.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../log"); +var util_1 = require("../../../util"); +var timeunit_1 = require("../../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.field(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 (util_1.keys(timeUnits).length) { + selCmpt.timeUnit = new timeunit_1.TimeUnitNode(timeUnits); + } + } +}; +exports.default = project; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL3Byb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQSxrQ0FBb0M7QUFFcEMsc0NBQW1DO0FBQ25DLGdEQUFvRTtBQUlwRSxJQUFNLE9BQU8sR0FBc0I7SUFDakMsR0FBRyxFQUFFLFVBQVMsTUFBeUM7UUFDckQsSUFBTSxHQUFHLEdBQUcsTUFBc0IsQ0FBQztRQUNuQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksR0FBRyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUM7SUFDakUsQ0FBQztJQUVELEtBQUssRUFBRSxVQUFTLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTztRQUNwQyxJQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBTSxTQUFTLEdBQXVDLEVBQUUsQ0FBQztRQUV6RCwwREFBMEQ7UUFDMUQsQ0FBQyxNQUFNLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLEVBQXRCLENBQXNCLENBQUMsQ0FBQztRQUVqRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsT0FBeUI7WUFDekQsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUNiLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO29CQUN0QixJQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNyQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsT0FBTyxDQUFDO29CQUU1Qiw2REFBNkQ7b0JBQzdELDJEQUEyRDtvQkFDM0QsNkRBQTZEO29CQUM3RCxpQ0FBaUM7b0JBQ2pDLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRzt3QkFDbkIsRUFBRSxFQUFFLE9BQU87d0JBQ1gsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO3dCQUNyQixRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVE7cUJBQzVCLENBQUM7Z0JBQ0osQ0FBQztnQkFBQyxJQUFJLENBQUMsQ0FBQztvQkFDTixRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQztnQkFDckMsQ0FBQztZQUNILENBQUM7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsa0NBQWtDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNwRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM3RCxHQUFHLENBQUMsQ0FBQyxJQUFNLEtBQUssSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzdCLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUM1RCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsT0FBTyxFQUFULENBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBM0IsQ0FBMkIsQ0FBQyxDQUFDO1FBRWhGLEVBQUUsQ0FBQyxDQUFDLFdBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sQ0FBQyxRQUFRLEdBQUcsSUFBSSx1QkFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELENBQUM7SUFDSCxDQUFDO0NBQ0YsQ0FBQztBQUVpQiwwQkFBTyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7U2luZ2xlRGVmQ2hhbm5lbH0gZnJvbSAnLi4vLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vbG9nJztcbmltcG9ydCB7U2VsZWN0aW9uRGVmfSBmcm9tICcuLi8uLi8uLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtrZXlzfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7VGltZVVuaXRDb21wb25lbnQsIFRpbWVVbml0Tm9kZX0gZnJvbSAnLi4vLi4vZGF0YS90aW1ldW5pdCc7XG5pbXBvcnQge1NlbGVjdGlvbkNvbXBvbmVudH0gZnJvbSAnLi4vc2VsZWN0aW9uJztcbmltcG9ydCB7VHJhbnNmb3JtQ29tcGlsZXJ9IGZyb20gJy4vdHJhbnNmb3Jtcyc7XG5cbmNvbnN0IHByb2plY3Q6IFRyYW5zZm9ybUNvbXBpbGVyID0ge1xuICBoYXM6IGZ1bmN0aW9uKHNlbERlZjogU2VsZWN0aW9uQ29tcG9uZW50IHwgU2VsZWN0aW9uRGVmKSB7XG4gICAgY29uc3QgZGVmID0gc2VsRGVmIGFzIFNlbGVjdGlvbkRlZjtcbiAgICByZXR1cm4gZGVmLmZpZWxkcyAhPT0gdW5kZWZpbmVkIHx8IGRlZi5lbmNvZGluZ3MgIT09IHVuZGVmaW5lZDtcbiAgfSxcblxuICBwYXJzZTogZnVuY3Rpb24obW9kZWwsIHNlbERlZiwgc2VsQ21wdCkge1xuICAgIGNvbnN0IGNoYW5uZWxzID0ge307XG4gICAgY29uc3QgdGltZVVuaXRzOiB7W2tleTogc3RyaW5nXTogVGltZVVuaXRDb21wb25lbnR9ID0ge307XG5cbiAgICAvLyBUT0RPOiBmaW5kIGEgcG9zc2libGUgY2hhbm5lbCBtYXBwaW5nIGZvciB0aGVzZSBmaWVsZHMuXG4gICAgKHNlbERlZi5maWVsZHMgfHwgW10pLmZvckVhY2goKGZpZWxkKSA9PiBjaGFubmVsc1tmaWVsZF0gPSBudWxsKTtcblxuICAgIChzZWxEZWYuZW5jb2RpbmdzIHx8IFtdKS5mb3JFYWNoKChjaGFubmVsOiBTaW5nbGVEZWZDaGFubmVsKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IG1vZGVsLmZpZWxkRGVmKGNoYW5uZWwpO1xuICAgICAgaWYgKGZpZWxkRGVmKSB7XG4gICAgICAgIGlmIChmaWVsZERlZi50aW1lVW5pdCkge1xuICAgICAgICAgIGNvbnN0IHR1RmllbGQgPSBtb2RlbC5maWVsZChjaGFubmVsKTtcbiAgICAgICAgICBjaGFubmVsc1t0dUZpZWxkXSA9IGNoYW5uZWw7XG5cbiAgICAgICAgICAvLyBDb25zdHJ1Y3QgVGltZVVuaXRDb21wb25lbnRzIHdoaWNoIHdpbGwgYmUgY29tYmluZWQgaW50byBhXG4gICAgICAgICAgLy8gVGltZVVuaXROb2RlLiBUaGlzIG5vZGUgbWF5IG5lZWQgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGVcbiAgICAgICAgICAvLyBkYXRhZmxvdyBpZiB0aGUgc2VsZWN0aW9uIGlzIHVzZWQgYWNyb3NzIHZpZXdzIHRoYXQgZG8gbm90XG4gICAgICAgICAgLy8gaGF2ZSB0aGVzZSB0aW1lIHVuaXRzIGRlZmluZWQuXG4gICAgICAgICAgdGltZVVuaXRzW3R1RmllbGRdID0ge1xuICAgICAgICAgICAgYXM6IHR1RmllbGQsXG4gICAgICAgICAgICBmaWVsZDogZmllbGREZWYuZmllbGQsXG4gICAgICAgICAgICB0aW1lVW5pdDogZmllbGREZWYudGltZVVuaXRcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNoYW5uZWxzW2ZpZWxkRGVmLmZpZWxkXSA9IGNoYW5uZWw7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmNhbm5vdFByb2plY3RPbkNoYW5uZWxXaXRob3V0RmllbGQoY2hhbm5lbCkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvamVjdGlvbiA9IHNlbENtcHQucHJvamVjdCB8fCAoc2VsQ21wdC5wcm9qZWN0ID0gW10pO1xuICAgIGZvciAoY29uc3QgZmllbGQgaW4gY2hhbm5lbHMpIHtcbiAgICAgIGlmIChjaGFubmVscy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpIHtcbiAgICAgICAgcHJvamVjdGlvbi5wdXNoKHtmaWVsZDogZmllbGQsIGNoYW5uZWw6IGNoYW5uZWxzW2ZpZWxkXX0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZpZWxkcyA9IHNlbENtcHQuZmllbGRzIHx8IChzZWxDbXB0LmZpZWxkcyA9IHt9KTtcbiAgICBwcm9qZWN0aW9uLmZpbHRlcigocCkgPT4gcC5jaGFubmVsKS5mb3JFYWNoKChwKSA9PiBmaWVsZHNbcC5jaGFubmVsXSA9IHAuZmllbGQpO1xuXG4gICAgaWYgKGtleXModGltZVVuaXRzKS5sZW5ndGgpIHtcbiAgICAgIHNlbENtcHQudGltZVVuaXQgPSBuZXcgVGltZVVuaXROb2RlKHRpbWVVbml0cyk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQge3Byb2plY3QgYXMgZGVmYXVsdH07XG4iXX0= \ 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..55a8d0dd13 --- /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 { scaleBindings as default }; +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..97fdb4fdb3 --- /dev/null +++ b/build/src/compile/selection/transforms/scales.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../log"); +var scale_1 = require("../../../scale"); +var util_1 = require("../../../util"); +var selection_1 = require("../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 || !scale_1.hasContinuousDomain(scaleType) || scale_1.isBinScale(scaleType)) { + log.warn(log.message.SCALE_BINDINGS_CONTINUOUS); + return; + } + scale.set('domainRaw', { signal: selection_1.channelSignalName(selCmpt, channel, 'data') }, true); + bound.push(channel); + }); + }, + 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 === selection_1.channelSignalName(selCmpt, channel, 'data'); }).length); + }); + return signals.concat(channels.map(function (channel) { + return { name: selection_1.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 === selection_1.channelSignalName(selCmpt, channel, 'data'); })[0]; + signal.push = 'outer'; + delete signal.value; + delete signal.update; + }); + } + return signals; + } +}; +exports.default = scaleBindings; +function domain(model, channel) { + var scale = util_1.stringValue(model.scaleName(channel)); + return "domain(" + scale + ")"; +} +exports.domain = domain; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvc2NhbGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esa0NBQW9DO0FBQ3BDLHdDQUErRDtBQUMvRCxzQ0FBMEM7QUFFMUMsMENBQStDO0FBSS9DLElBQU0sYUFBYSxHQUFxQjtJQUN0QyxHQUFHLEVBQUUsVUFBUyxPQUFPO1FBQ25CLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxPQUFPLENBQUMsT0FBTyxLQUFLLFFBQVE7WUFDaEUsT0FBTyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztJQUM5QyxDQUFDO0lBRUQsS0FBSyxFQUFFLFVBQVMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPO1FBQ3BDLElBQU0sS0FBSyxHQUFjLE9BQU8sQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBRTdDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVMsQ0FBQztZQUNoQyxJQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzFCLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxJQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUV4RCxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLDJCQUFtQixDQUFDLFNBQVMsQ0FBQyxJQUFJLGtCQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2RSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMseUJBQXlCLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDO1lBQ1QsQ0FBQztZQUVELEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLEVBQUMsTUFBTSxFQUFFLDZCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNwRixLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWUsRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTztRQUMvQyxzRUFBc0U7UUFDdEUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNsQixNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxJQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFDLE9BQU87WUFDN0MsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxDQUFDLElBQUksS0FBSyw2QkFBaUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxFQUF0RCxDQUFzRCxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0YsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQUMsT0FBTztZQUN6QyxNQUFNLENBQUMsRUFBQyxJQUFJLEVBQUUsNkJBQWlCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsRUFBQyxDQUFDO1FBQzdELENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ3ZDLGlGQUFpRjtRQUNqRixFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNqQixPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFBLE9BQU87Z0JBQzVCLElBQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQSxDQUFDLElBQUksT0FBQSxDQUFDLENBQUMsSUFBSSxLQUFLLDZCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQXRELENBQXNELENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFOUYsTUFBTSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7Z0JBQ3RCLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQztnQkFDcEIsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQ3ZCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE1BQU0sQ0FBQyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUNGLENBQUM7QUFFdUIsZ0NBQU87QUFFaEMsZ0JBQXVCLEtBQWdCLEVBQUUsT0FBZ0I7SUFDdkQsSUFBTSxLQUFLLEdBQUcsa0JBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDcEQsTUFBTSxDQUFDLFlBQVUsS0FBSyxNQUFHLENBQUM7QUFDNUIsQ0FBQztBQUhELHdCQUdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFubmVsfSBmcm9tICcuLi8uLi8uLi9jaGFubmVsJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi8uLi9sb2cnO1xuaW1wb3J0IHtoYXNDb250aW51b3VzRG9tYWluLCBpc0JpblNjYWxlfSBmcm9tICcuLi8uLi8uLi9zY2FsZSc7XG5pbXBvcnQge3N0cmluZ1ZhbHVlfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi8uLi91bml0JztcbmltcG9ydCB7Y2hhbm5lbFNpZ25hbE5hbWV9IGZyb20gJy4uL3NlbGVjdGlvbic7XG5pbXBvcnQge1RyYW5zZm9ybUNvbXBpbGVyfSBmcm9tICcuL3RyYW5zZm9ybXMnO1xuXG5cbmNvbnN0IHNjYWxlQmluZGluZ3M6VHJhbnNmb3JtQ29tcGlsZXIgPSB7XG4gIGhhczogZnVuY3Rpb24oc2VsQ21wdCkge1xuICAgIHJldHVybiBzZWxDbXB0LnR5cGUgPT09ICdpbnRlcnZhbCcgJiYgc2VsQ21wdC5yZXNvbHZlID09PSAnZ2xvYmFsJyAmJlxuICAgICAgc2VsQ21wdC5iaW5kICYmIHNlbENtcHQuYmluZCA9PT0gJ3NjYWxlcyc7XG4gIH0sXG5cbiAgcGFyc2U6IGZ1bmN0aW9uKG1vZGVsLCBzZWxEZWYsIHNlbENtcHQpIHtcbiAgICBjb25zdCBib3VuZDogQ2hhbm5lbFtdID0gc2VsQ21wdC5zY2FsZXMgPSBbXTtcblxuICAgIHNlbENtcHQucHJvamVjdC5mb3JFYWNoKGZ1bmN0aW9uKHApIHtcbiAgICAgIGNvbnN0IGNoYW5uZWwgPSBwLmNoYW5uZWw7XG4gICAgICBjb25zdCBzY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KGNoYW5uZWwpO1xuICAgICAgY29uc3Qgc2NhbGVUeXBlID0gc2NhbGUgPyBzY2FsZS5nZXQoJ3R5cGUnKSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKCFzY2FsZSB8fCAhaGFzQ29udGludW91c0RvbWFpbihzY2FsZVR5cGUpIHx8IGlzQmluU2NhbGUoc2NhbGVUeXBlKSkge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5TQ0FMRV9CSU5ESU5HU19DT05USU5VT1VTKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzY2FsZS5zZXQoJ2RvbWFpblJhdycsIHtzaWduYWw6IGNoYW5uZWxTaWduYWxOYW1lKHNlbENtcHQsIGNoYW5uZWwsICdkYXRhJyl9LCB0cnVlKTtcbiAgICAgIGJvdW5kLnB1c2goY2hhbm5lbCk7XG4gICAgfSk7XG4gIH0sXG5cbiAgdG9wTGV2ZWxTaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCwgc2lnbmFscykge1xuICAgIC8vIFRvcC1sZXZlbCBzaWduYWxzIGFyZSBvbmx5IG5lZWRlZCB3aGVuIGNvb3JkaW5hdGluZyBjb21wb3NlZCB2aWV3cy5cbiAgICBpZiAoIW1vZGVsLnBhcmVudCkge1xuICAgICAgcmV0dXJuIHNpZ25hbHM7XG4gICAgfVxuXG4gICAgY29uc3QgY2hhbm5lbHMgPSBzZWxDbXB0LnNjYWxlcy5maWx0ZXIoKGNoYW5uZWwpID0+IHtcbiAgICAgIHJldHVybiAhKHNpZ25hbHMuZmlsdGVyKHMgPT4gcy5uYW1lID09PSBjaGFubmVsU2lnbmFsTmFtZShzZWxDbXB0LCBjaGFubmVsLCAnZGF0YScpKS5sZW5ndGgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ25hbHMuY29uY2F0KGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuICAgICAgcmV0dXJuIHtuYW1lOiBjaGFubmVsU2lnbmFsTmFtZShzZWxDbXB0LCBjaGFubmVsLCAnZGF0YScpfTtcbiAgICB9KSk7XG4gIH0sXG5cbiAgc2lnbmFsczogZnVuY3Rpb24obW9kZWwsIHNlbENtcHQsIHNpZ25hbHMpIHtcbiAgICAvLyBOZXN0ZWQgc2lnbmFscyBuZWVkIG9ubHkgcHVzaCB0byB0b3AtbGV2ZWwgc2lnbmFscyB3aGVuIHdpdGhpbiBjb21wb3NlZCB2aWV3cy5cbiAgICBpZiAobW9kZWwucGFyZW50KSB7XG4gICAgICBzZWxDbXB0LnNjYWxlcy5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgICBjb25zdCBzaWduYWwgPSBzaWduYWxzLmZpbHRlcihzID0+IHMubmFtZSA9PT0gY2hhbm5lbFNpZ25hbE5hbWUoc2VsQ21wdCwgY2hhbm5lbCwgJ2RhdGEnKSlbMF07XG5cbiAgICAgICAgc2lnbmFsLnB1c2ggPSAnb3V0ZXInO1xuICAgICAgICBkZWxldGUgc2lnbmFsLnZhbHVlO1xuICAgICAgICBkZWxldGUgc2lnbmFsLnVwZGF0ZTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBzaWduYWxzO1xuICB9XG59O1xuXG5leHBvcnQge3NjYWxlQmluZGluZ3MgYXMgZGVmYXVsdH07XG5cbmV4cG9ydCBmdW5jdGlvbiBkb21haW4obW9kZWw6IFVuaXRNb2RlbCwgY2hhbm5lbDogQ2hhbm5lbCkge1xuICBjb25zdCBzY2FsZSA9IHN0cmluZ1ZhbHVlKG1vZGVsLnNjYWxlTmFtZShjaGFubmVsKSk7XG4gIHJldHVybiBgZG9tYWluKCR7c2NhbGV9KWA7XG59XG4iXX0= \ 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..22c443e915 --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const toggle: TransformCompiler; +export { toggle as default }; diff --git a/build/src/compile/selection/transforms/toggle.js b/build/src/compile/selection/transforms/toggle.js new file mode 100644 index 0000000000..c5bdf5b9be --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("../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 + selection_1.TUPLE; + var signal = selCmpt.name + TOGGLE; + return signal + " ? null : " + tpl + ", " + + (selCmpt.resolve === 'global' ? + signal + " ? null : true, " : + signal + " ? null : {unit: " + selection_1.unitName(model) + "}, ") + + (signal + " ? " + tpl + " : null"); + } +}; +exports.default = toggle; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvdG9nZ2xlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsMENBQTZDO0FBSTdDLElBQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQztBQUV6QixJQUFNLE1BQU0sR0FBcUI7SUFDL0IsR0FBRyxFQUFFLFVBQVMsT0FBTztRQUNuQixNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUNwRCxDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ3ZDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQ3BCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxHQUFHLE1BQU07WUFDM0IsS0FBSyxFQUFFLEtBQUs7WUFDWixFQUFFLEVBQUUsQ0FBQyxFQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFDLENBQUM7U0FDdkQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFVBQVUsRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSTtRQUN2QyxJQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsSUFBSSxHQUFHLGlCQUFLLENBQUM7UUFDakMsSUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7UUFFckMsTUFBTSxDQUFJLE1BQU0sa0JBQWEsR0FBRyxPQUFJO1lBQ2xDLENBQUMsT0FBTyxDQUFDLE9BQU8sS0FBSyxRQUFRLENBQUMsQ0FBQztnQkFDMUIsTUFBTSxxQkFBa0IsQ0FBQyxDQUFDO2dCQUMxQixNQUFNLHlCQUFvQixvQkFBUSxDQUFDLEtBQUssQ0FBQyxRQUFLLENBQUM7YUFDakQsTUFBTSxXQUFNLEdBQUcsWUFBUyxDQUFBLENBQUM7SUFDaEMsQ0FBQztDQUNGLENBQUM7QUFFZ0IseUJBQU8iLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7VFVQTEUsIHVuaXROYW1lfSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtUcmFuc2Zvcm1Db21waWxlcn0gZnJvbSAnLi90cmFuc2Zvcm1zJztcblxuXG5jb25zdCBUT0dHTEUgPSAnX3RvZ2dsZSc7XG5cbmNvbnN0IHRvZ2dsZTpUcmFuc2Zvcm1Db21waWxlciA9IHtcbiAgaGFzOiBmdW5jdGlvbihzZWxDbXB0KSB7XG4gICAgcmV0dXJuIHNlbENtcHQudHlwZSA9PT0gJ211bHRpJyAmJiBzZWxDbXB0LnRvZ2dsZTtcbiAgfSxcblxuICBzaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCwgc2lnbmFscykge1xuICAgIHJldHVybiBzaWduYWxzLmNvbmNhdCh7XG4gICAgICBuYW1lOiBzZWxDbXB0Lm5hbWUgKyBUT0dHTEUsXG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICBvbjogW3tldmVudHM6IHNlbENtcHQuZXZlbnRzLCB1cGRhdGU6IHNlbENtcHQudG9nZ2xlfV1cbiAgICB9KTtcbiAgfSxcblxuICBtb2RpZnlFeHByOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCwgZXhwcikge1xuICAgIGNvbnN0IHRwbCA9IHNlbENtcHQubmFtZSArIFRVUExFO1xuICAgIGNvbnN0IHNpZ25hbCA9IHNlbENtcHQubmFtZSArIFRPR0dMRTtcblxuICAgIHJldHVybiBgJHtzaWduYWx9ID8gbnVsbCA6ICR7dHBsfSwgYCArXG4gICAgICAoc2VsQ21wdC5yZXNvbHZlID09PSAnZ2xvYmFsJyA/XG4gICAgICAgIGAke3NpZ25hbH0gPyBudWxsIDogdHJ1ZSwgYCA6XG4gICAgICAgIGAke3NpZ25hbH0gPyBudWxsIDoge3VuaXQ6ICR7dW5pdE5hbWUobW9kZWwpfX0sIGApICtcbiAgICAgIGAke3NpZ25hbH0gPyAke3RwbH0gOiBudWxsYDtcbiAgfVxufTtcblxuZXhwb3J0IHt0b2dnbGUgYXMgZGVmYXVsdH07XG4iXX0= \ 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..836411f0ce --- /dev/null +++ b/build/src/compile/selection/transforms/transforms.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var inputs_1 = require("./inputs"); +var nearest_1 = require("./nearest"); +var project_1 = require("./project"); +var scales_1 = require("./scales"); +var toggle_1 = require("./toggle"); +var translate_1 = require("./translate"); +var zoom_1 = require("./zoom"); +var compilers = { project: project_1.default, toggle: toggle_1.default, scales: scales_1.default, + translate: translate_1.default, zoom: zoom_1.default, inputs: inputs_1.default, nearest: nearest_1.default }; +function forEachTransform(selCmpt, cb) { + for (var t in compilers) { + if (compilers[t].has(selCmpt)) { + cb(compilers[t]); + } + } +} +exports.forEachTransform = forEachTransform; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3Jtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL3RyYW5zZm9ybXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFpQkEsbUNBQThCO0FBQzlCLHFDQUFnQztBQUNoQyxxQ0FBZ0M7QUFDaEMsbUNBQThCO0FBQzlCLG1DQUE4QjtBQUM5Qix5Q0FBb0M7QUFDcEMsK0JBQTBCO0FBQzFCLElBQU0sU0FBUyxHQUE0QixFQUFDLE9BQU8sbUJBQUEsRUFBRSxNQUFNLGtCQUFBLEVBQUUsTUFBTSxrQkFBQTtJQUNqRSxTQUFTLHFCQUFBLEVBQUUsSUFBSSxnQkFBQSxFQUFFLE1BQU0sa0JBQUEsRUFBRSxPQUFPLG1CQUFBLEVBQUMsQ0FBQztBQUVwQywwQkFBaUMsT0FBMkIsRUFBRSxFQUFtQztJQUMvRixHQUFHLENBQUMsQ0FBQyxJQUFNLENBQUMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQzFCLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFORCw0Q0FNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7U2VsZWN0aW9uRGVmfSBmcm9tICcuLi8uLi8uLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtEaWN0fSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7VmdTaWduYWx9IGZyb20gJy4uLy4uLy4uL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7TW9kZWx9IGZyb20gJy4uLy4uL21vZGVsJztcbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi8uLi91bml0JztcbmltcG9ydCB7U2VsZWN0aW9uQ29tcG9uZW50fSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNmb3JtQ29tcGlsZXIge1xuICBoYXM6IChzZWxDbXB0OiBTZWxlY3Rpb25Db21wb25lbnQgfCBTZWxlY3Rpb25EZWYpID0+IGJvb2xlYW47XG4gIHBhcnNlPzogKG1vZGVsOiBVbml0TW9kZWwsIGRlZjogU2VsZWN0aW9uRGVmLCBzZWxDbXB0OiBTZWxlY3Rpb25Db21wb25lbnQpID0+IHZvaWQ7XG4gIHNpZ25hbHM/OiAobW9kZWw6IFVuaXRNb2RlbCwgc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50LCBzaWduYWxzOiBWZ1NpZ25hbFtdKSA9PiBWZ1NpZ25hbFtdO1xuICB0b3BMZXZlbFNpZ25hbHM/OiAobW9kZWw6IE1vZGVsLCBzZWxDbXB0OiBTZWxlY3Rpb25Db21wb25lbnQsIHNpZ25hbHM6IFZnU2lnbmFsW10pID0+IFZnU2lnbmFsW107XG4gIG1vZGlmeUV4cHI/OiAobW9kZWw6IFVuaXRNb2RlbCwgc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50LCBleHByOiBzdHJpbmcpID0+IHN0cmluZztcbiAgbWFya3M/OiAobW9kZWw6IFVuaXRNb2RlbCwgc2VsQ21wdDpTZWxlY3Rpb25Db21wb25lbnQsIG1hcmtzOiBhbnlbXSkgPT4gYW55W107XG59XG5cbmltcG9ydCBpbnB1dHMgZnJvbSAnLi9pbnB1dHMnO1xuaW1wb3J0IG5lYXJlc3QgZnJvbSAnLi9uZWFyZXN0JztcbmltcG9ydCBwcm9qZWN0IGZyb20gJy4vcHJvamVjdCc7XG5pbXBvcnQgc2NhbGVzIGZyb20gJy4vc2NhbGVzJztcbmltcG9ydCB0b2dnbGUgZnJvbSAnLi90b2dnbGUnO1xuaW1wb3J0IHRyYW5zbGF0ZSBmcm9tICcuL3RyYW5zbGF0ZSc7XG5pbXBvcnQgem9vbSBmcm9tICcuL3pvb20nO1xuY29uc3QgY29tcGlsZXJzOiBEaWN0PFRyYW5zZm9ybUNvbXBpbGVyPiA9IHtwcm9qZWN0LCB0b2dnbGUsIHNjYWxlcyxcbiAgdHJhbnNsYXRlLCB6b29tLCBpbnB1dHMsIG5lYXJlc3R9O1xuXG5leHBvcnQgZnVuY3Rpb24gZm9yRWFjaFRyYW5zZm9ybShzZWxDbXB0OiBTZWxlY3Rpb25Db21wb25lbnQsIGNiOiAodHg6IFRyYW5zZm9ybUNvbXBpbGVyKSA9PiB2b2lkKSB7XG4gIGZvciAoY29uc3QgdCBpbiBjb21waWxlcnMpIHtcbiAgICBpZiAoY29tcGlsZXJzW3RdLmhhcyhzZWxDbXB0KSkge1xuICAgICAgY2IoY29tcGlsZXJzW3RdKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ== \ 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..fffa908ace --- /dev/null +++ b/build/src/compile/selection/transforms/translate.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const translate: TransformCompiler; +export { translate as default }; diff --git a/build/src/compile/selection/transforms/translate.js b/build/src/compile/selection/transforms/translate.js new file mode 100644 index 0000000000..3d4f779d98 --- /dev/null +++ b/build/src/compile/selection/transforms/translate.js @@ -0,0 +1,76 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_event_selector_1 = require("vega-event-selector"); +var channel_1 = require("../../../channel"); +var interval_1 = require("../interval"); +var selection_1 = require("../selection"); +var scales_1 = require("./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 = scales_1.default.has(selCmpt); + var anchor = name + ANCHOR; + var _a = selection_1.positionalProjections(selCmpt), x = _a.x, y = _a.y; + var events = vega_event_selector_1.selector(selCmpt.translate, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.between[0].markname = name + interval_1.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 ? scales_1.domain(model, channel_1.X) : + "slice(" + selection_1.channelSignalName(selCmpt, 'x', 'visual') + ")") : '') + + (y !== null ? ', extent_y: ' + (hasScales ? scales_1.domain(model, channel_1.Y) : + "slice(" + selection_1.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, channel_1.X, 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, channel_1.Y, 'height', signals); + } + return signals; + } +}; +exports.default = translate; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scales_1.default.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === selection_1.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 === channel_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvdHJhbnNsYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsMkRBQThEO0FBQzlELDRDQUFvRDtBQUVwRCx3Q0FBb0Q7QUFDcEQsMENBQTBGO0FBRTFGLG1DQUEyRDtBQUkzRCxJQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQztBQUNuQyxJQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBQztBQUVqQyxJQUFNLFNBQVMsR0FBcUI7SUFDbEMsR0FBRyxFQUFFLFVBQVMsT0FBTztRQUNuQixNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ3ZDLElBQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDMUIsSUFBTSxTQUFTLEdBQUcsZ0JBQWMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUMsSUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLE1BQU0sQ0FBQztRQUN2QixJQUFBLCtDQUF1QyxFQUF0QyxRQUFDLEVBQUUsUUFBQyxDQUFtQztRQUM5QyxJQUFJLE1BQU0sR0FBRyw4QkFBYSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFdkQsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ2YsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksR0FBRyxnQkFBYyxFQUFFLENBQUMsQ0FBQyxFQUFsRCxDQUFrRCxDQUFD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QUFJLEdBQUcsU0FBUyxJQUFJLE9BQU8sS0FBSyxXQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsc0NBQXNDO0lBQzFGLElBQU0sTUFBTSxHQUFNLE1BQU0sZ0JBQVcsT0FBUyxDQUFDO0lBQzdDLElBQU0sTUFBTSxHQUFHLEtBQUcsSUFBSSxHQUFHLEtBQUssU0FBSSxPQUFPLFFBQUssR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBRyxNQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVEsTUFBTSxNQUFHLENBQUMsQ0FBQztJQUMvRixJQUFNLEtBQUssR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEMsU0FBUyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDaEMsU0FBUyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7SUFDL0MsSUFBTSxNQUFNLEdBQU0sS0FBSyxTQUFJLE1BQU0sVUFBSyxNQUFRO1FBQzVDLENBQUMsU0FBUyxJQUFJLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQUssU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBRXhGLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQ2IsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQztRQUN2QixNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLGdCQUFjLE1BQU0sYUFBUSxNQUFNLE1BQUc7S0FDbkUsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7c2VsZWN0b3IgYXMgcGFyc2VTZWxlY3Rvcn0gZnJvbSAndmVnYS1ldmVudC1zZWxlY3Rvcic7XG5pbXBvcnQge1NjYWxlQ2hhbm5lbCwgWCwgWX0gZnJvbSAnLi4vLi4vLi4vY2hhbm5lbCc7XG5pbXBvcnQge1ZnRXZlbnRIYW5kbGVyLCBWZ1NpZ25hbH0gZnJvbSAnLi4vLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtCUlVTSCBhcyBJTlRFUlZBTF9CUlVTSH0gZnJvbSAnLi4vaW50ZXJ2YWwnO1xuaW1wb3J0IHtjaGFubmVsU2lnbmFsTmFtZSwgcG9zaXRpb25hbFByb2plY3Rpb25zLCBTZWxlY3Rpb25Db21wb25lbnR9IGZyb20gJy4uL3NlbGVjdGlvbic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi8uLi8uLi91bml0JztcbmltcG9ydCB7ZGVmYXVsdCBhcyBzY2FsZXNDb21waWxlciwgZG9tYWlufSBmcm9tICcuL3NjYWxlcyc7XG5pbXBvcnQge1RyYW5zZm9ybUNvbXBpbGVyfSBmcm9tICcuL3RyYW5zZm9ybXMnO1xuXG5cbmNvbnN0IEFOQ0hPUiA9ICdfdHJhbnNsYXRlX2FuY2hvcic7XG5jb25zdCBERUxUQSA9ICdfdHJhbnNsYXRlX2RlbHRhJztcblxuY29uc3QgdHJhbnNsYXRlOlRyYW5zZm9ybUNvbXBpbGVyID0ge1xuICBoYXM6IGZ1bmN0aW9uKHNlbENtcHQpIHtcbiAgICByZXR1cm4gc2VsQ21wdC50eXBlID09PSAnaW50ZXJ2YWwnICYmIHNlbENtcHQudHJhbnNsYXRlO1xuICB9LFxuXG4gIHNpZ25hbHM6IGZ1bmN0aW9uKG1vZGVsLCBzZWxDbXB0LCBzaWduYWxzKSB7XG4gICAgY29uc3QgbmFtZSA9IHNlbENtcHQubmFtZTtcbiAgICBjb25zdCBoYXNTY2FsZXMgPSBzY2FsZXNDb21waWxlci5oYXMoc2VsQ21wdCk7XG4gICAgY29uc3QgYW5jaG9yID0gbmFtZSArIEFOQ0hPUjtcbiAgICBjb25zdCB7eCwgeX0gPSBwb3NpdGlvbmFsUHJvamVjdGlvbnMoc2VsQ21wdCk7XG4gICAgbGV0IGV2ZW50cyA9IHBhcnNlU2VsZWN0b3Ioc2VsQ21wdC50cmFuc2xhdGUsICdzY29wZScpO1xuXG4gICAgaWYgKCFoYXNTY2FsZXMpIHtcbiAgICAgIGV2ZW50cyA9IGV2ZW50cy5tYXAoKGUpID0+IChlLmJldHdlZW5bMF0ubWFya25hbWUgPSBuYW1lICsgSU5URVJWQUxfQlJVU0gsIGUpKTtcbiAgICB9XG5cbiAgICBzaWduYWxzLnB1c2goe1xuICAgICAgbmFtZTogYW5jaG9yLFxuICAgICAgdmFsdWU6IHt9LFxuICAgICAgb246IFt7XG4gICAgICAgIGV2ZW50czogZXZlbnRzLm1hcCgoZSkgPT4gZS5iZXR3ZWVuWzBdKSxcbiAgICAgICAgdXBkYXRlOiAne3g6IHgodW5pdCksIHk6IHkodW5pdCknICtcbiAgICAgICAgICAoeCAhPT0gbnVsbCA/ICcsIGV4dGVudF94OiAnICsgKGhhc1NjYWxlcyA/IGRvbWFpbihtb2RlbCwgWCkgOlxuICAgICAgICAgICAgICBgc2xpY2UoJHtjaGFubmVsU2lnbmFsTmFtZShzZWxDbXB0LCAneCcsICd2aXN1YWwnKX0pYCkgOiAnJykgK1xuXG4gICAgICAgICAgKHkgIT09IG51bGwgPyAnLCBleHRlbnRfeTogJyArIChoYXNTY2FsZXMgPyBkb21haW4obW9kZWwsIFkpIDpcbiAgICAgICAgICAgICAgYHNsaWNlKCR7Y2hhbm5lbFNpZ25hbE5hbWUoc2VsQ21wdCwgJ3knLCAndmlzdWFsJyl9KWApIDogJycpICsgJ30nXG4gICAgICB9XVxuICAgIH0sIHtcbiAgICAgIG5hbWU6IG5hbWUgKyBERUxUQSxcbiAgICAgIHZhbHVlOiB7fSxcbiAgICAgIG9uOiBbe1xuICAgICAgICBldmVudHM6IGV2ZW50cyxcbiAgICAgICAgdXBkYXRlOiBge3g6ICR7YW5jaG9yfS54IC0geCh1bml0KSwgeTogJHthbmNob3J9LnkgLSB5KHVuaXQpfWBcbiAgICAgIH1dXG4gICAgfSk7XG5cbiAgICBpZiAoeCAhPT0gbnVsbCkge1xuICAgICAgb25EZWx0YShtb2RlbCwgc2VsQ21wdCwgWCwgJ3dpZHRoJywgc2lnbmFscyk7XG4gICAgfVxuXG4gICAgaWYgKHkgIT09IG51bGwpIHtcbiAgICAgIG9uRGVsdGEobW9kZWwsIHNlbENtcHQsIFksICdoZWlnaHQnLCBzaWduYWxzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2lnbmFscztcbiAgfVxufTtcblxuZXhwb3J0IHt0cmFuc2xhdGUgYXMgZGVmYXVsdH07XG5cbmZ1bmN0aW9uIG9uRGVsdGEobW9kZWw6IFVuaXRNb2RlbCwgc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50LCBjaGFubmVsOiBTY2FsZUNoYW5uZWwsIHNpemU6ICd3aWR0aCcgfCAnaGVpZ2h0Jywgc2lnbmFsczogVmdTaWduYWxbXSkge1xuICBjb25zdCBuYW1lID0gc2VsQ21wdC5uYW1lO1xuICBjb25zdCBoYXNTY2FsZXMgPSBzY2FsZXNDb21waWxlci5oYXMoc2VsQ21wdCk7XG4gIGNvbnN0IHNpZ25hbCA9IHNpZ25hbHMuZmlsdGVyKHMgPT4ge1xuICAgIHJldHVybiBzLm5hbWUgPT09IGNoYW5uZWxTaWduYWxOYW1lKHNlbENtcHQsIGNoYW5uZWwsIGhhc1NjYWxlcyA/ICdkYXRhJyA6ICd2aXN1YWwnKTtcbiAgfSlbMF07XG4gIGNvbnN0IGFuY2hvciA9IG5hbWUgKyBBTkNIT1I7XG4gIGNvbnN0IGRlbHRhID0gbmFtZSArIERFTFRBO1xuICBjb25zdCBzaXplU2cgPSBtb2RlbC5nZXRTaXplU2lnbmFsUmVmKHNpemUpLnNpZ25hbDtcbiAgY29uc3Qgc2NhbGVDbXB0ID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoY2hhbm5lbCk7XG4gIGNvbnN0IHNjYWxlVHlwZSA9IHNjYWxlQ21wdC5nZXQoJ3R5cGUnKTtcbiAgY29uc3Qgc2lnbiA9IGhhc1NjYWxlcyAmJiBjaGFubmVsID09PSBYID8gJy0nIDogJyc7IC8vIEludmVydCBkZWx0YSB3aGVuIHBhbm5pbmcgeC1zY2FsZXMuXG4gIGNvbnN0IGV4dGVudCA9IGAke2FuY2hvcn0uZXh0ZW50XyR7Y2hhbm5lbH1gO1xuICBjb25zdCBvZmZzZXQgPSBgJHtzaWdufSR7ZGVsdGF9LiR7Y2hhbm5lbH0gLyBgICsgKGhhc1NjYWxlcyA/IGAke3NpemVTZ31gIDogYHNwYW4oJHtleHRlbnR9KWApO1xuICBjb25zdCBwYW5GbiA9ICFoYXNTY2FsZXMgPyAncGFuTGluZWFyJyA6XG4gICAgc2NhbGVUeXBlID09PSAnbG9nJyA/ICdwYW5Mb2cnIDpcbiAgICBzY2FsZVR5cGUgPT09ICdwb3cnID8gJ3BhblBvdycgOiAncGFuTGluZWFyJztcbiAgY29uc3QgdXBkYXRlID0gYCR7cGFuRm59KCR7ZXh0ZW50fSwgJHtvZmZzZXR9YCArXG4gICAgKGhhc1NjYWxlcyAmJiBzY2FsZVR5cGUgPT09ICdwb3cnID8gYCwgJHtzY2FsZUNtcHQuZ2V0KCdleHBvbmVudCcpIHx8IDF9YCA6ICcnKSArICcpJztcblxuICBzaWduYWwub24ucHVzaCh7XG4gICAgZXZlbnRzOiB7c2lnbmFsOiBkZWx0YX0sXG4gICAgdXBkYXRlOiBoYXNTY2FsZXMgPyB1cGRhdGUgOiBgY2xhbXBSYW5nZSgke3VwZGF0ZX0sIDAsICR7c2l6ZVNnfSlgXG4gIH0pO1xufVxuIl19 \ 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..a3ff88c3af --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const zoom: TransformCompiler; +export { zoom as default }; diff --git a/build/src/compile/selection/transforms/zoom.js b/build/src/compile/selection/transforms/zoom.js new file mode 100644 index 0000000000..9251e5e842 --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.js @@ -0,0 +1,76 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_event_selector_1 = require("vega-event-selector"); +var channel_1 = require("../../../channel"); +var util_1 = require("../../../util"); +var interval_1 = require("../interval"); +var selection_1 = require("../selection"); +var scales_1 = require("./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 = scales_1.default.has(selCmpt); + var delta = name + DELTA; + var _a = selection_1.positionalProjections(selCmpt), x = _a.x, y = _a.y; + var sx = util_1.stringValue(model.scaleName(channel_1.X)); + var sy = util_1.stringValue(model.scaleName(channel_1.Y)); + var events = vega_event_selector_1.selector(selCmpt.zoom, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.markname = name + interval_1.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; + } +}; +exports.default = zoom; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scales_1.default.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === selection_1.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 ? scales_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL3pvb20udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyREFBOEQ7QUFDOUQsNENBQW9EO0FBQ3BELHNDQUEwQztBQUUxQyx3Q0FBb0Q7QUFDcEQsMENBQTBGO0FBRTFGLG1DQUEyRDtBQUkzRCxJQUFNLE1BQU0sR0FBRyxjQUFjLENBQUM7QUFDOUIsSUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDO0FBRTVCLElBQU0sSUFBSSxHQUFxQjtJQUM3QixHQUFHLEVBQUUsVUFBUyxPQUFPO1FBQ25CLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQ3JELENBQUM7SUFFRCxPQUFPLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU87UUFDdkMsSUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFNLFNBQVMsR0FBRyxnQkFBYyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QyxJQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUEsK0NBQXVDLEVBQXRDLFFBQUMsRUFBRSxRQUFDLENBQW1DO1FBQzlDLElBQU0sRUFBRSxHQUFHLGtCQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLElBQU0sRUFBRSxHQUFHLGtCQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLElBQUksTUFBTSxHQUFHLDhCQUFhLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVsRCxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDZixNQUFN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LEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3hDLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2pDLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO0lBQ2pELElBQU0sTUFBTSxHQUFNLE1BQU0sU0FBSSxJQUFJLFVBQUssTUFBTSxVQUFLLEtBQU87UUFDckQsQ0FBQyxTQUFTLElBQUksU0FBUyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBSyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7SUFFeEYsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFDYixNQUFNLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDO1FBQ3ZCLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsZ0JBQWMsTUFBTSxhQUFRLE1BQU0sTUFBRztLQUNuRSxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtzZWxlY3RvciBhcyBwYXJzZVNlbGVjdG9yfSBmcm9tICd2ZWdhLWV2ZW50LXNlbGVjdG9yJztcbmltcG9ydCB7U2NhbGVDaGFubmVsLCBYLCBZfSBmcm9tICcuLi8uLi8uLi9jaGFubmVsJztcbmltcG9ydCB7c3RyaW5nVmFsdWV9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtWZ1NpZ25hbH0gZnJvbSAnLi4vLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtCUlVTSCBhcyBJTlRFUlZBTF9CUlVTSH0gZnJvbSAnLi4vaW50ZXJ2YWwnO1xuaW1wb3J0IHtjaGFubmVsU2lnbmFsTmFtZSwgcG9zaXRpb25hbFByb2plY3Rpb25zLCBTZWxlY3Rpb25Db21wb25lbnR9IGZyb20gJy4uL3NlbGVjdGlvbic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi8uLi8uLi91bml0JztcbmltcG9ydCB7ZGVmYXVsdCBhcyBzY2FsZXNDb21waWxlciwgZG9tYWlufSBmcm9tICcuL3NjYWxlcyc7XG5pbXBvcnQge1RyYW5zZm9ybUNvbXBpbGVyfSBmcm9tICcuL3RyYW5zZm9ybXMnO1xuXG5cbmNvbnN0IEFOQ0hPUiA9ICdfem9vbV9hbmNob3InO1xuY29uc3QgREVMVEEgPSAnX3pvb21fZGVsdGEnO1xuXG5jb25zdCB6b29tOlRyYW5zZm9ybUNvbXBpbGVyID0ge1xuICBoYXM6IGZ1bmN0aW9uKHNlbENtcHQpIHtcbiAgICByZXR1cm4gc2VsQ21wdC50eXBlID09PSAnaW50ZXJ2YWwnICYmIHNlbENtcHQuem9vbTtcbiAgfSxcblxuICBzaWduYWxzOiBmdW5jdGlvbihtb2RlbCwgc2VsQ21wdCwgc2lnbmFscykge1xuICAgIGNvbnN0IG5hbWUgPSBzZWxDbXB0Lm5hbWU7XG4gICAgY29uc3QgaGFzU2NhbGVzID0gc2NhbGVzQ29tcGlsZXIuaGFzKHNlbENtcHQpO1xuICAgIGNvbnN0IGRlbHRhID0gbmFtZSArIERFTFRBO1xuICAgIGNvbnN0IHt4LCB5fSA9IHBvc2l0aW9uYWxQcm9qZWN0aW9ucyhzZWxDbXB0KTtcbiAgICBjb25zdCBzeCA9IHN0cmluZ1ZhbHVlKG1vZGVsLnNjYWxlTmFtZShYKSk7XG4gICAgY29uc3Qgc3kgPSBzdHJpbmdWYWx1ZShtb2RlbC5zY2FsZU5hbWUoWSkpO1xuICAgIGxldCBldmVudHMgPSBwYXJzZVNlbGVjdG9yKHNlbENtcHQuem9vbSwgJ3Njb3BlJyk7XG5cbiAgICBpZiAoIWhhc1NjYWxlcykge1xuICAgICAgZXZlbnRzID0gZXZlbnRzLm1hcCgoZSkgPT4gKGUubWFya25hbWUgPSBuYW1lICsgSU5URVJWQUxfQlJVU0gsIGUpKTtcbiAgICB9XG5cbiAgICBzaWduYWxzLnB1c2goe1xuICAgICAgbmFtZTogbmFtZSArIEFOQ0hPUixcbiAgICAgIG9uOiBbe1xuICAgICAgICBldmVudHM6IGV2ZW50cyxcbiAgICAgICAgdXBkYXRlOiAhaGFzU2NhbGVzID8gYHt4OiB4KHVuaXQpLCB5OiB5KHVuaXQpfWAgOlxuICAgICAgICAgICd7JyArIFtcbiAgICAgICAgICAgIChzeCA/IGB4OiBpbnZlcnQoJHtzeH0sIHgodW5pdCkpYCA6ICcnKSxcbiAgICAgICAgICAgIChzeSA/IGB5OiBpbnZlcnQoJHtzeX0sIHkodW5pdCkpYCA6ICcnKVxuICAgICAgICAgIF0uZmlsdGVyKChleHByKSA9PiAhIWV4cHIpLmpvaW4oJywgJykgKyAnfSdcbiAgICAgIH1dXG4gICAgfSwge1xuICAgICAgbmFtZTogZGVsdGEsXG4gICAgICBvbjogW3tcbiAgICAgICAgZXZlbnRzOiBldmVudHMsXG4gICAgICAgIGZvcmNlOiB0cnVlLFxuICAgICAgICB1cGRhdGU6ICdwb3coMS4wMDEsIGV2ZW50LmRlbHRhWSAqIHBvdygxNiwgZXZlbnQuZGVsdGFNb2RlKSknXG4gICAgICB9XVxuICAgIH0pO1xuXG4gICAgaWYgKHggIT09IG51bGwpIHtcbiAgICAgIG9uRGVsdGEobW9kZWwsIHNlbENtcHQsICd4JywgJ3dpZHRoJywgc2lnbmFscyk7XG4gICAgfVxuXG4gICAgaWYgKHkgIT09IG51bGwpIHtcbiAgICAgIG9uRGVsdGEobW9kZWwsIHNlbENtcHQsICd5JywgJ2hlaWdodCcsIHNpZ25hbHMpO1xuICAgIH1cblxuICAgIHJldHVybiBzaWduYWxzO1xuICB9XG59O1xuXG5leHBvcnQge3pvb20gYXMgZGVmYXVsdH07XG5cbmZ1bmN0aW9uIG9uRGVsdGEobW9kZWw6IFVuaXRNb2RlbCwgc2VsQ21wdDogU2VsZWN0aW9uQ29tcG9uZW50LCBjaGFubmVsOiBTY2FsZUNoYW5uZWwsIHNpemU6ICd3aWR0aCcgfCAnaGVpZ2h0Jywgc2lnbmFsczogVmdTaWduYWxbXSkge1xuICBjb25zdCBuYW1lID0gc2VsQ21wdC5uYW1lO1xuICBjb25zdCBoYXNTY2FsZXMgPSBzY2FsZXNDb21waWxlci5oYXMoc2VsQ21wdCk7XG4gIGNvbnN0IHNpZ25hbCA9IHNpZ25hbHMuZmlsdGVyKHMgPT4ge1xuICAgIHJldHVybiBzLm5hbWUgPT09IGNoYW5uZWxTaWduYWxOYW1lKHNlbENtcHQsIGNoYW5uZWwsIGhhc1NjYWxlcyA/ICdkYXRhJyA6ICd2aXN1YWwnKTtcbiAgfSlbMF07XG4gIGNvbnN0IHNpemVTZyA9IG1vZGVsLmdldFNpemVTaWduYWxSZWYoc2l6ZSkuc2lnbmFsO1xuICBjb25zdCBzY2FsZUNtcHQgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudChjaGFubmVsKTtcbiAgY29uc3Qgc2NhbGVUeXBlID0gc2NhbGVDbXB0LmdldCgndHlwZScpO1xuICBjb25zdCBiYXNlID0gaGFzU2NhbGVzID8gZG9tYWluKG1vZGVsLCBjaGFubmVsKSA6IHNpZ25hbC5uYW1lO1xuICBjb25zdCBkZWx0YSA9IG5hbWUgKyBERUxUQTtcbiAgY29uc3QgYW5jaG9yID0gYCR7bmFtZX0ke0FOQ0hPUn0uJHtjaGFubmVsfWA7XG4gIGNvbnN0IHpvb21GbiA9ICFoYXNTY2FsZXMgPyAnem9vbUxpbmVhcicgOlxuICAgIHNjYWxlVHlwZSA9PT0gJ2xvZycgPyAnem9vbUxvZycgOlxuICAgIHNjYWxlVHlwZSA9PT0gJ3BvdycgPyAnem9vbVBvdycgOiAnem9vbUxpbmVhcic7XG4gIGNvbnN0IHVwZGF0ZSA9IGAke3pvb21Gbn0oJHtiYXNlfSwgJHthbmNob3J9LCAke2RlbHRhfWAgK1xuICAgIChoYXNTY2FsZXMgJiYgc2NhbGVUeXBlID09PSAncG93JyA/IGAsICR7c2NhbGVDbXB0LmdldCgnZXhwb25lbnQnKSB8fCAxfWAgOiAnJykgKyAnKSc7XG5cbiAgc2lnbmFsLm9uLnB1c2goe1xuICAgIGV2ZW50czoge3NpZ25hbDogZGVsdGF9LFxuICAgIHVwZGF0ZTogaGFzU2NhbGVzID8gdXBkYXRlIDogYGNsYW1wUmFuZ2UoJHt1cGRhdGV9LCAwLCAke3NpemVTZ30pYFxuICB9KTtcbn1cbiJdfQ== \ 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..ec47a47218 --- /dev/null +++ b/build/src/compile/split.d.ts @@ -0,0 +1,28 @@ +/** + * 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: T; + readonly implicit: T; + constructor(explicit?: T, implicit?: T); + clone(): Split; + combine(): T; + 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: K, s: Split): void; + copyKeyFromObject(key: K, s: S): 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) => Explicit; +export declare function defaultTieBreaker(v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string): 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..6e3c21316a --- /dev/null +++ b/build/src/compile/split.js @@ -0,0 +1,131 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var util_1 = require("../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(util_1.duplicate(this.explicit), util_1.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); + } + }; + return Split; +}()); +exports.Split = Split; +function makeExplicit(value) { + return { + explicit: true, + value: value + }; +} +exports.makeExplicit = makeExplicit; +function makeImplicit(value) { + return { + explicit: false, + value: value + }; +} +exports.makeImplicit = makeImplicit; +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); + }; +} +exports.tieBreakByComparing = tieBreakByComparing; +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; +} +exports.defaultTieBreaker = defaultTieBreaker; +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 (v1.value === v2.value) { + return v1; + } + else { + return tieBreaker(v1, v2, property, propertyOf); + } +} +exports.mergeValuesWithExplicit = mergeValuesWithExplicit; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9zcGxpdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQ0EsNEJBQThCO0FBQzlCLGdDQUFrQztBQUVsQzs7Ozs7R0FLRztBQUNIO0lBQ0UsZUFBNEIsUUFBcUIsRUFBa0IsUUFBcUI7UUFBNUQseUJBQUEsRUFBQSxXQUFjLEVBQU87UUFBa0IseUJBQUEsRUFBQSxXQUFjLEVBQU87UUFBNUQsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQUFrQixhQUFRLEdBQVIsUUFBUSxDQUFhO0lBQUcsQ0FBQztJQUVyRixxQkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGdCQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGdCQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVNLHVCQUFPLEdBQWQ7UUFDRSx5QkFBeUI7UUFDekIsdUZBQXVGO1FBQ3ZGLE1BQU0sY0FDRCxJQUFJLENBQUMsUUFBZSxFQUNwQixJQUFJLENBQUMsUUFBZSxFQUN2QjtJQUNKLENBQUM7SUFFTSxtQkFBRyxHQUFWLFVBQThCLEdBQU07UUFDbEMsaUNBQWlDO1FBQ2pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRU0sK0JBQWUsR0FBdEIsVUFBMEMsR0FBTTtRQUM5QyxpQ0FBaUM7UUFDakMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxFQUFDLFFB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QVEsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDWixDQUFDO0lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxRQUFRLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUN2QyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDWixDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ2xELENBQUM7QUFDSCxDQUFDO0FBcEJELDBEQW9CQyIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL2xvZyc7XG5pbXBvcnQge2R1cGxpY2F0ZX0gZnJvbSAnLi4vdXRpbCc7XG5cbi8qKlxuICogR2VuZXJpYyBjbGFzcyBmb3Igc3RvcmluZyBwcm9wZXJ0aWVzIHRoYXQgYXJlIGV4cGxpY2l0bHkgc3BlY2lmaWVkXG4gKiBhbmQgaW1wbGljaXRseSBkZXRlcm1pbmVkIGJ5IHRoZSBjb21waWxlci5cbiAqIFRoaXMgaXMgaW1wb3J0YW50IGZvciBzY2FsZS9heGlzL2xlZ2VuZCBtZXJnaW5nIGFzXG4gKiB3ZSB3YW50IHRvIHByaW9yaXRpemUgcHJvcGVydGllcyB0aGF0IHVzZXJzIGV4cGxpY2l0bHkgc3BlY2lmaWVkLlxuICovXG5leHBvcnQgY2xhc3MgU3BsaXQ8VCBleHRlbmRzIG9iamVjdD4ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgZXhwbGljaXQ6IFQgPSB7fSBhcyBULCBwdWJsaWMgcmVhZG9ubHkgaW1wbGljaXQ6IFQgPSB7fSBhcyBUKSB7fVxuXG4gIHB1YmxpYyBjbG9uZSgpIHtcbiAgICByZXR1cm4gbmV3IFNwbGl0KGR1cGxpY2F0ZSh0aGlzLmV4cGxpY2l0KSwgZHVwbGljYXRlKHRoaXMuaW1wbGljaXQpKTtcbiAgfVxuXG4gIHB1YmxpYyBjb21iaW5lKCk6IFQge1xuICAgIC8vIEZJWE1FIHJlbW92ZSBcImFzIGFueVwiLlxuICAgIC8vIEFkZCBcImFzIGFueVwiIHRvIGF2b2lkIGFuIGVycm9yIFwiU3ByZWFkIHR5cGVzIG1heSBvbmx5IGJlIGNyZWF0ZWQgZnJvbSBvYmplY3QgdHlwZXNcIi5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5leHBsaWNpdCBhcyBhbnksIC8vIEV4cGxpY2l0IHByb3BlcnRpZXMgY29tZXMgZmlyc3RcbiAgICAgIC4uLnRoaXMuaW1wbGljaXQgYXMgYW55XG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQ8SyBleHRlbmRzIGtleW9mIFQ+KGtleTogSyk6IFRbS10ge1xuICAgIC8vIEV4cGxpY2l0IGhhcyBoaWdoZXIgcHJlY2VkZW5jZVxuICAgIHJldHVybiB0aGlzLmV4cGxpY2l0W2tleV0gIT09IHVuZGVmaW5lZCA/IHRoaXMuZXhwbGljaXRba2V5XSA6IHRoaXMuaW1wbGljaXRba2V5XTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRXaXRoRXhwbGljaXQ8SyBleHRlbmRzIGtleW9mIFQ+KGtleTogSyk6IEV4cGxpY2l0PFRbS10+IHtcbiAgICAvLyBFeHBsaWNpdCBoYXMgaGlnaGVyIHByZWNlZGVuY2VcbiAgICBpZiAodGhpcy5leHBsaWNpdFtrZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB7ZXhwbGljaXQ6IHRydWUsIHZhbHVlOiB0aGlzLmV4cGxpY2l0W2tleV19O1xuICAgIH0gZWxzZSBpZiAodGhpcy5pbXBsaWNpdFtrZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB7ZXhwbGljaXQ6IGZhbHNlLCB2YWx1ZTogdGhpcy5pbXBsaWNpdFtrZXldfTtcbiAgICB9XG4gICAgcmV0dXJuIHtleHBsaWNpdDogZmFsc2UsIHZhbHVlOiB1bmRlZmluZWR9O1xuICB9XG5cbiAgcHVibGljIHNldFdpdGhFeHBsaWNpdDxLIGV4dGVuZHMga2V5b2YgVD4oa2V5OiBLLCB2YWx1ZTogRXhwbGljaXQ8VFtLXT4pIHtcbiAgICBpZiAodmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXQoa2V5LCB2YWx1ZS52YWx1ZSwgdmFsdWUuZXhwbGljaXQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXQ8SyBleHRlbmRzIGtleW9mIFQ+KGtleTogSywgdmFsdWU6IFRbS10sIGV4cGxpY2l0OiBib29sZWFuKSB7XG4gICAgZGVsZXRlIHRoaXNbZXhwbGljaXQgPyAnaW1wbGljaXQnIDogJ2V4cGxpY2l0J11ba2V5XTtcbiAgICB0aGlzW2V4cGxpY2l0ID8gJ2V4cGxpY2l0JyA6ICdpbXBsaWNpdCddW2tleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBjb3B5S2V5RnJvbVNwbGl0PFMgZXh0ZW5kcyBvYmplY3QsIEsgZXh0ZW5kcyBrZXlvZiAoVHxTKT4oa2V5OiBLLCBzOiBTcGxpdDxTPikge1xuICAgIC8vIEV4cGxpY2l0IGhhcyBoaWdoZXIgcHJlY2VkZW5jZVxuICAgIGlmIChzLmV4cGxpY2l0W2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXQoa2V5LCBzLmV4cGxpY2l0W2tleV0sIHRydWUpO1xuICAgIH0gZWxzZSBpZiAocy5pbXBsaWNpdFtrZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2V0KGtleSwgcy5pbXBsaWNpdFtrZXldLCBmYWxzZSk7XG4gICAgfVxuICB9XG4gIHB1YmxpYyBjb3B5S2V5RnJvbU9iamVjdDxTLCBLIGV4dGVuZHMga2V5b2YgKFR8Uyk+KGtleTogSywgczogUykge1xuICAgIC8vIEV4cGxpY2l0IGhhcyBoaWdoZXIgcHJlY2VkZW5jZVxuICAgIGlmIChzW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXQoa2V5LCBzW2tleV0sIHRydWUpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxpY2l0PFQ+IHtcbiAgZXhwbGljaXQ6IGJvb2xlYW47XG4gIHZhbHVlOiBUO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlRXhwbGljaXQ8VD4odmFsdWU6IFQpOiBFeHBsaWNpdDxUPiB7XG4gIHJldHVybiB7XG4gICAgZXhwbGljaXQ6IHRydWUsXG4gICAgdmFsdWVcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VJbXBsaWNpdDxUPih2YWx1ZTogVCk6IEV4cGxpY2l0PFQ+IHtcbiAgcmV0dXJuIHtcbiAgICBleHBsaWNpdDogZmFsc2UsXG4gICAgdmFsdWVcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRpZUJyZWFrQnlDb21wYXJpbmc8UywgVD4oY29tcGFyZTogKHYxOiBULCB2MjogVCkgPT4gbnVtYmVyKSB7XG4gIHJldHVybiAodjE6IEV4cGxpY2l0PFQ+LCB2MjogRXhwbGljaXQ8VD4sIHByb3BlcnR5OiBrZXlvZiBTIHwgbmV2ZXIsIHByb3BlcnR5T2Y6IHN0cmluZyk6IEV4cGxpY2l0PFQ+ID0+IHtcbiAgICBjb25zdCBkaWZmID0gY29tcGFyZSh2MS52YWx1ZSwgdjIudmFsdWUpO1xuICAgIGlmIChkaWZmID4gMCkge1xuICAgICAgcmV0dXJuIHYxO1xuICAgIH0gZWxzZSBpZiAoZGlmZiA8IDApIHtcbiAgICAgIHJldHVybiB2MjtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmF1bHRUaWVCcmVha2VyPFMsIFQ+KHYxLCB2MiwgcHJvcGVydHksIHByb3BlcnR5T2YpO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFRpZUJyZWFrZXI8UywgVD4odjE6IEV4cGxpY2l0PFQ+LCB2MjogRXhwbGljaXQ8VD4sIHByb3BlcnR5OiBrZXlvZiBTLCBwcm9wZXJ0eU9mOiBzdHJpbmcpIHtcbiAgaWYgKHYxLmV4cGxpY2l0ICYmIHYyLmV4cGxpY2l0KSB7XG4gICAgbG9nLndhcm4obG9nLm1lc3NhZ2UubWVyZ2VDb25mbGljdGluZ1Byb3BlcnR5KHByb3BlcnR5LCBwcm9wZXJ0eU9mLCB2MS52YWx1ZSwgdjIudmFsdWUpKTtcbiAgfVxuICAvLyBJZiBlcXVhbCBzY29yZSwgcHJlZmVyIHYxLlxuICByZXR1cm4gdjE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZVZhbHVlc1dpdGhFeHBsaWNpdDxTLCBUPihcbiAgICB2MTogRXhwbGljaXQ8VD4sIHYyOiBFeHBsaWNpdDxUPixcbiAgICBwcm9wZXJ0eToga2V5b2YgUyxcbiAgICBwcm9wZXJ0eU9mOiAnc2NhbGUnIHwgJ2F4aXMnIHwgJ2xlZ2VuZCcgfCAnJyxcbiAgICB0aWVCcmVha2VyOiAodjE6IEV4cGxpY2l0PFQ+LCB2MjogRXhwbGljaXQ8VD4sIHByb3BlcnR5OiBrZXlvZiBTLCBwcm9wZXJ0eU9mOiBzdHJpbmcpID0+IEV4cGxpY2l0PFQ+ID0gZGVmYXVsdFRpZUJyZWFrZXJcbiAgKSB7XG4gIGlmICh2MSA9PT0gdW5kZWZpbmVkIHx8IHYxLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBGb3IgZmlyc3QgcnVuXG4gICAgcmV0dXJuIHYyO1xuICB9XG5cbiAgaWYgKHYxLmV4cGxpY2l0ICYmICF2Mi5leHBsaWNpdCkge1xuICAgIHJldHVybiB2MTtcbiAgfSBlbHNlIGlmICh2Mi5leHBsaWNpdCAmJiAhdjEuZXhwbGljaXQpIHtcbiAgICByZXR1cm4gdjI7XG4gIH0gZWxzZSBpZiAodjEudmFsdWUgPT09IHYyLnZhbHVlKSB7XG4gICAgcmV0dXJuIHYxO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aWVCcmVha2VyKHYxLCB2MiwgcHJvcGVydHksIHByb3BlcnR5T2YpO1xuICB9XG59XG4iXX0= \ 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..17ef4eab6e --- /dev/null +++ b/build/src/compile/unit.d.ts @@ -0,0 +1,64 @@ +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 { Domain } from '../scale'; +import { SelectionDef } from '../selection'; +import { SortField, SortOrder } from '../sort'; +import { LayoutSizeMixins, UnitSpec } 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; + readonly selection: Dict; + children: Model[]; + constructor(spec: UnitSpec, parent: Model, parentGivenName: string, parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean); + /** + * Return specified Vega-lite scale domain for a particular channel + * @param channel + */ + scaleDomain(channel: ScaleChannel): Domain; + sort(channel: Channel): SortField | SortOrder; + axis(channel: Channel): Axis; + legend(channel: Channel): Legend; + private initScales(mark, encoding); + private initAxes(encoding); + private initLegend(encoding); + 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; + 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..b71f92c674 --- /dev/null +++ b/build/src/compile/unit.js @@ -0,0 +1,215 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var vlEncoding = require("../encoding"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var mark_1 = require("../mark"); +var stack_1 = require("../stack"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var parse_2 = require("./data/parse"); +var assemble_1 = require("./layoutsize/assemble"); +var parse_3 = require("./layoutsize/parse"); +var init_1 = require("./mark/init"); +var mark_2 = require("./mark/mark"); +var model_1 = require("./model"); +var repeater_1 = require("./repeater"); +var selection_1 = require("./selection/selection"); +/** + * 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, undefined) || this; + _this.fit = fit; + _this.type = 'unit'; + _this.specifiedScales = {}; + _this.specifiedAxes = {}; + _this.specifiedLegends = {}; + _this.selection = {}; + _this.children = []; + _this.initSize(__assign({}, parentGivenSize, (spec.width ? { width: spec.width } : {}), (spec.height ? { height: spec.height } : {}))); + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = _this.encoding = encoding_1.normalizeEncoding(repeater_1.replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark); + _this.markDef = init_1.normalizeMarkDef(spec.mark, encoding, config); + // calculate stack properties + _this.stack = stack_1.stack(mark, encoding, _this.config.stack); + _this.specifiedScales = _this.initScales(mark, encoding); + _this.specifiedAxes = _this.initAxes(encoding); + _this.specifiedLegends = _this.initLegend(encoding); + // Selections will be initialized upon parse. + _this.selection = spec.selection; + return _this; + } + /** + * 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.sort = function (channel) { + return (this.getMapping()[channel] || {}).sort; + }; + 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 channel_1.SCALE_CHANNELS.reduce(function (scales, channel) { + var fieldDef; + var specifiedScale; + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale; + } + else if (fielddef_1.hasConditionalFieldDef(channelDef)) { + fieldDef = channelDef.condition; + specifiedScale = channelDef.condition['scale']; + } + else if (channel === 'x') { + fieldDef = fielddef_1.getFieldDef(encoding.x2); + } + else if (channel === 'y') { + fieldDef = fielddef_1.getFieldDef(encoding.y2); + } + if (fieldDef) { + scales[channel] = specifiedScale || {}; + } + return scales; + }, {}); + }; + UnitModel.prototype.initAxes = function (encoding) { + return [channel_1.X, channel_1.Y].reduce(function (_axis, channel) { + // Position Axis + // TODO: handle ConditionFieldDef + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef) || + (channel === channel_1.X && fielddef_1.isFieldDef(encoding.x2)) || + (channel === channel_1.Y && fielddef_1.isFieldDef(encoding.y2))) { + var axisSpec = fielddef_1.isFieldDef(channelDef) ? channelDef.axis : null; + // We no longer support false in the schema, but we keep false here for backward compatability. + if (axisSpec !== null && axisSpec !== false) { + _axis[channel] = __assign({}, axisSpec); + } + } + return _axis; + }, {}); + }; + UnitModel.prototype.initLegend = function (encoding) { + return channel_1.NONPOSITION_SCALE_CHANNELS.reduce(function (_legend, channel) { + var channelDef = encoding[channel]; + if (channelDef) { + var legend = fielddef_1.isFieldDef(channelDef) ? channelDef.legend : + (fielddef_1.hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null; + if (legend !== null && legend !== false) { + _legend[channel] = __assign({}, legend); + } + } + return _legend; + }, {}); + }; + UnitModel.prototype.parseData = function () { + this.component.data = parse_2.parseData(this); + }; + UnitModel.prototype.parseLayoutSize = function () { + parse_3.parseUnitLayoutSize(this); + }; + UnitModel.prototype.parseSelection = function () { + this.component.selection = selection_1.parseUnitSelection(this, this.selection); + }; + UnitModel.prototype.parseMarkGroup = function () { + this.component.mark = mark_2.parseMarkGroup(this); + }; + UnitModel.prototype.parseAxisAndHeader = function () { + this.component.axes = parse_1.parseUnitAxis(this); + }; + UnitModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return selection_1.assembleTopLevelSignals(this, signals); + }; + UnitModel.prototype.assembleSelectionSignals = function () { + return selection_1.assembleUnitSelectionSignals(this, []); + }; + UnitModel.prototype.assembleSelectionData = function (data) { + return selection_1.assembleUnitSelectionData(this, data); + }; + UnitModel.prototype.assembleLayout = function () { + return null; + }; + UnitModel.prototype.assembleLayoutSignals = function () { + return assemble_1.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 || !model_1.isLayerModel(this.parent)) { + marks = selection_1.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 = util_1.duplicate(this.encoding); + var spec; + spec = { + mark: this.markDef, + encoding: encoding + }; + if (!excludeConfig) { + spec.config = util_1.duplicate(this.config); + } + if (!excludeData) { + spec.data = util_1.duplicate(this.data); + } + // remove defaults + return spec; + }; + UnitModel.prototype.mark = function () { + return this.markDef.type; + }; + UnitModel.prototype.channelHasField = function (channel) { + return vlEncoding.channelHasField(this.encoding, channel); + }; + UnitModel.prototype.fieldDef = function (channel) { + var channelDef = this.encoding[channel]; + return fielddef_1.getFieldDef(channelDef); + }; + return UnitModel; +}(model_1.ModelWithField)); +exports.UnitModel = UnitModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL3VuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSxzQ0FBcUg7QUFFckgsd0NBQTBDO0FBQzFDLHdDQUF3RDtBQUN4RCx3Q0FBa0c7QUFFbEcsZ0NBQWlEO0FBS2pELGtDQUFnRDtBQUNoRCxnQ0FBd0M7QUFHeEMsc0NBQTJDO0FBQzNDLHNDQUF1QztBQUN2QyxrREFBNEQ7QUFDNUQsNENBQXVEO0FBRXZELG9DQUE2QztBQUM3QyxvQ0FBMkM7QUFDM0MsaUNBQTREO0FBQzVELHVDQUFvRTtBQUVwRSxtREFNK0I7QUFHL0I7O0dBRUc7QUFDSDtJQUErQiw2QkFBYztJQWdCM0MsbUJBQVksSUFBYyxFQUFFLE1BQWEsRUFBRSxlQUF1QixFQUNoRSxlQUFzQyxFQUFFLFFBQXVCLEVBQUUsTUFBYyxFQUFTLEdBQVk7UUFBcEcsZ0NBQUEsRUFBQSxvQkFBc0M7UUFEeEMsWUFHRSxrQkFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLFNBcUJ4RDtRQXZCeUYsU0FBRyxHQUFILEdBQUcsQ0FBUztRQWhCdEYsVUFBSSxHQUFXLE1BQU0sQ0FBQztRQUl0QixxQkFBZSxHQUFlLEVBQUUsQ0FBQztRQUl2QyxtQkFBYSxHQUFjLEVBQUUsQ0FBQztRQUU5QixzQkFBZ0IsR0FBZ0IsRUFBRSxDQUFDO1FBRTdCLGVBQVMsR0FBdUIsRUFBRSxDQUFDO1FBQzVDLGNBQVEsR0FBWSxFQUFFLENBQUM7UUFNNUIsS0FBSSxDQUFDLFFBQVEsY0FDUixlQUFlLEVBQ2YsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUN2QyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMs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QUFnQjtRQUNyQyxNQUFNLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFTSw0QkFBUSxHQUFmLFVBQWdCLE9BQXlCO1FBQ3ZDLElBQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUF1QixDQUFDO1FBQ2hFLE1BQU0sQ0FBQyxzQkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFDSCxnQkFBQztBQUFELENBQUMsQUFqT0QsQ0FBK0Isc0JBQWMsR0FpTzVDO0FBak9ZLDhCQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBeGlzfSBmcm9tICcuLi9heGlzJztcbmltcG9ydCB7Q2hhbm5lbCwgTk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMsIFNDQUxFX0NIQU5ORUxTLCBTY2FsZUNoYW5uZWwsIFNpbmdsZURlZkNoYW5uZWwsIFgsIFl9IGZyb20gJy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgKiBhcyB2bEVuY29kaW5nIGZyb20gJy4uL2VuY29kaW5nJztcbmltcG9ydCB7RW5jb2RpbmcsIG5vcm1hbGl6ZUVuY29kaW5nfSBmcm9tICcuLi9lbmNvZGluZyc7XG5pbXBvcnQge0NoYW5uZWxEZWYsIEZpZWxkRGVmLCBnZXRGaWVsZERlZiwgaGFzQ29uZGl0aW9uYWxGaWVsZERlZiwgaXNGaWVsZERlZn0gZnJvbSAnLi4vZmllbGRkZWYnO1xuaW1wb3J0IHtMZWdlbmR9IGZyb20gJy4uL2xlZ2VuZCc7XG5pbXBvcnQge2lzTWFya0RlZiwgTWFyaywgTWFya0RlZn0gZnJvbSAnLi4vbWFyayc7XG5pbXBvcnQge0RvbWFpbiwgU2NhbGV9IGZyb20gJy4uL3NjYWxlJztcbmltcG9ydCB7U2VsZWN0aW9uRGVmfSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtTb3J0RmllbGQsIFNvcnRPcmRlcn0gZnJvbSAnLi4vc29ydCc7XG5pbXBvcnQge0xheW91dFNpemVNaXhpbnMsIFVuaXRTcGVjfSBmcm9tICcuLi9zcGVjJztcbmltcG9ydCB7c3RhY2ssIFN0YWNrUHJvcGVydGllc30gZnJvbSAnLi4vc3RhY2snO1xuaW1wb3J0IHtEaWN0LCBkdXBsaWNhdGV9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHtWZ0RhdGEsIFZnRW5jb2RlRW50cnksIFZnTGF5b3V0LCBWZ1NpZ25hbH0gZnJvbSAnLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtBeGlzSW5kZXh9IGZyb20gJy4vYXhpcy9jb21wb25lbnQnO1xuaW1wb3J0IHtwYXJzZVVuaXRBeGlzfSBmcm9tICcuL2F4aXMvcGFyc2UnO1xuaW1wb3J0IHtwYXJzZURhdGF9IGZyb20gJy4vZGF0YS9wYXJzZSc7XG5pbXBvcnQge2Fzc2VtYmxlTGF5b3V0U2lnbmFsc30gZnJvbSAnLi9sYXlvdXRzaXplL2Fzc2VtYmxlJztcbmltcG9ydCB7cGFyc2VVbml0TGF5b3V0U2l6ZX0gZnJvbSAnLi9sYXlvdXRzaXplL3BhcnNlJztcbmltcG9ydCB7TGVnZW5kSW5kZXh9IGZyb20gJy4vbGVnZW5kL2NvbXBvbmVudCc7XG5pbXBvcnQge25vcm1hbGl6ZU1hcmtEZWZ9IGZyb20gJy4vbWFyay9pbml0JztcbmltcG9ydCB7cGFyc2VNYXJrR3JvdXB9IGZyb20gJy4vbWFyay9tYXJrJztcbmltcG9ydCB7aXNMYXllck1vZGVsLCBNb2RlbCwgTW9kZWxXaXRoRmllbGR9IGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0IHtSZXBlYXRlclZhbHVlLCByZXBsYWNlUmVwZWF0ZXJJbkVuY29kaW5nfSBmcm9tICcuL3JlcGVhdGVyJztcbmltcG9ydCB7U2NhbGVJbmRleH0gZnJvbSAnLi9zY2FsZS9jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgYXNzZW1ibGVUb3BMZXZlbFNpZ25hbHMsXG4gIGFzc2VtYmxlVW5pdFNlbGVjdGlvbkRhdGEsXG4gIGFzc2VtYmxlVW5pdFNlbGVjdGlvbk1hcmtzLFxuICBhc3NlbWJsZVVuaXRTZWxlY3Rpb25TaWduYWxzLFxuICBwYXJzZVVuaXRTZWxlY3Rpb24sXG59IGZyb20gJy4vc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5cblxuLyoqXG4gKiBJbnRlcm5hbCBtb2RlbCBvZiBWZWdhLUxpdGUgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIGNvbXBpbGVyLlxuICovXG5leHBvcnQgY2xhc3MgVW5pdE1vZGVsIGV4dGVuZHMgTW9kZWxXaXRoRmllbGQge1xuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogJ3VuaXQnID0gJ3VuaXQnO1xuICBwdWJsaWMgcmVhZG9ubHkgbWFya0RlZjogTWFya0RlZjtcbiAgcHVibGljIHJlYWRvbmx5IGVuY29kaW5nOiBFbmNvZGluZzxzdHJpbmc+O1xuXG4gIHB1YmxpYyByZWFkb25seSBzcGVjaWZpZWRTY2FsZXM6IFNjYWxlSW5kZXggPSB7fTtcblxuICBwdWJsaWMgcmVhZG9ubHkgc3RhY2s6IFN0YWNrUHJvcGVydGllcztcblxuICBwcm90ZWN0ZWQgc3BlY2lmaWVkQXhlczogQXhpc0luZGV4ID0ge307XG5cbiAgcHJvdGVjdGVkIHNwZWNpZmllZExlZ2VuZHM6IExlZ2VuZEluZGV4ID0ge307XG5cbiAgcHVibGljIHJlYWRvbmx5IHNlbGVjdGlvbjogRGljdDxTZWxlY3Rpb25EZWY+ID0ge307XG4gIHB1YmxpYyBjaGlsZHJlbjogTW9kZWxbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHNwZWM6IFVuaXRTcGVjLCBwYXJlbnQ6IE1vZGVsLCBwYXJlbnRHaXZlbk5hbWU6IHN0cmluZyxcbiAgICBwYXJlbnRHaXZlblNpemU6IExheW91dFNpemVNaXhpbnMgPSB7fSwgcmVwZWF0ZXI6IFJlcGVhdGVyVmFsdWUsIGNvbmZpZzogQ29uZmlnLCBwdWJsaWMgZml0OiBib29sZWFuKSB7XG5cbiAgICBzdXBlcihzcGVjLCBwYXJlbnQsIHBhcmVudEdpdmVuTmFtZSwgY29uZmlnLCB1bmRlZmluZWQpO1xuICAgIHRoaXMuaW5pdFNpemUoe1xuICAgICAgLi4ucGFyZW50R2l2ZW5TaXplLFxuICAgICAgLi4uKHNwZWMud2lkdGggPyB7d2lkdGg6IHNwZWMud2lkdGh9IDoge30pLFxuICAgICAgLi4uKHNwZWMuaGVpZ2h0ID8ge2hlaWdodDogc3BlYy5oZWlnaHR9IDoge30pXG4gICAgfSk7XG4gICAgY29uc3QgbWFyayA9IGlzTWFya0RlZihzcGVjLm1hcmspID8gc3BlYy5tYXJrLnR5cGUgOiBzcGVjLm1hcms7XG5cbiAgICBjb25zdCBlbmNvZGluZyA9IHRoaXMuZW5jb2RpbmcgPSBub3JtYWxpemVFbmNvZGluZyhyZXBsYWNlUmVwZWF0ZXJJbkVuY29kaW5nKHNwZWMuZW5jb2RpbmcgfHwge30sIHJlcGVhdGVyKSwgbWFyayk7XG5cbiAgICB0aGlzLm1hcmtEZWYgPSBub3JtYWxpemVNYXJrRGVmKHNwZWMubWFyaywgZW5jb2RpbmcsIGNvbmZpZyk7XG5cbiAgICAvLyBjYWxjdWxhdGUgc3RhY2sgcHJvcGVydGllc1xuICAgIHRoaXMuc3RhY2sgPSBzdGFjayhtYXJrLCBlbmNvZGluZywgdGhpcy5jb25maWcuc3RhY2spO1xuICAgIHRoaXMuc3BlY2lmaWVkU2NhbGVzID0gdGhpcy5pbml0U2NhbGVzKG1hcmssIGVuY29kaW5nKTtcblxuICAgIHRoaXMuc3BlY2lmaWVkQXhlcyA9IHRoaXMuaW5pdEF4ZXMoZW5jb2RpbmcpO1xuICAgIHRoaXMuc3BlY2lmaWVkTGVnZW5kcyA9IHRoaXMuaW5pdExlZ2VuZChlbmNvZGluZyk7XG5cbiAgICAvLyBTZWxlY3Rpb25zIHdpbGwgYmUgaW5pdGlhbGl6ZWQgdXBvbiBwYXJzZS5cbiAgICB0aGlzLnNlbGVjdGlvbiA9IHNwZWMuc2VsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBzcGVjaWZpZWQgVmVnYS1saXRlIHNjYWxlIGRvbWFpbiBmb3IgYSBwYXJ0aWN1bGFyIGNoYW5uZWxcbiAgICogQHBhcmFtIGNoYW5uZWxcbiAgICovXG4gIHB1YmxpYyBzY2FsZURvbWFpbihjaGFubmVsOiBTY2FsZUNoYW5uZWwpOiBEb21haW4ge1xuICAgIGNvbnN0IHNjYWxlID0gdGhpcy5zcGVjaWZpZWRTY2FsZXNbY2hhbm5lbF07XG4gICAgcmV0dXJuIHNjYWxlID8gc2NhbGUuZG9tYWluIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIHNvcnQoY2hhbm5lbDogQ2hhbm5lbCk6IFNvcnRGaWVsZDxzdHJpbmc+IHwgU29ydE9yZGVyIHtcbiAgICByZXR1cm4gKHRoaXMuZ2V0TWFwcGluZygpW2NoYW5uZWxdIHx8IHt9KS5zb3J0O1xuICB9XG5cbiAgcHVibGljIGF4aXMoY2hhbm5lbDogQ2hhbm5lbCk6IEF4aXMge1xuICAgIHJldHVybiB0aGlzLnNwZWNpZmllZEF4ZXNbY2hhbm5lbF07XG4gIH1cblxuICBwdWJsaWMgbGVnZW5kKGNoYW5uZWw6IENoYW5uZWwpOiBMZWdlbmQge1xuICAgIHJldHVybiB0aGlzLnNwZWNpZmllZExlZ2VuZHNbY2hhbm5lbF07XG4gIH1cblxuICBwcml2YXRlIGluaXRTY2FsZXMobWFyazogTWFyaywgZW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4pOiBTY2FsZUluZGV4IHtcbiAgICByZXR1cm4gU0NBTEVfQ0hBTk5FTFMucmVkdWNlKChzY2FsZXMsIGNoYW5uZWwpID0+IHtcbiAgICAgIGxldCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPjtcbiAgICAgIGxldCBzcGVjaWZpZWRTY2FsZTogU2NhbGU7XG5cbiAgICAgIGNvbnN0IGNoYW5uZWxEZWYgPSBlbmNvZGluZ1tjaGFubmVsXTtcblxuICAgICAgaWYgKGlzRmllbGREZWYoY2hhbm5lbERlZikpIHtcbiAgICAgICAgZmllbGREZWYgPSBjaGFubmVsRGVmO1xuICAgICAgICBzcGVjaWZpZWRTY2FsZSA9IGNoYW5uZWxEZWYuc2NhbGU7XG4gICAgICB9IGVsc2UgaWYgKGhhc0NvbmRpdGlvbmFsRmllbGREZWYoY2hhbm5lbERlZikpIHtcbiAgICAgICAgZmllbGREZWYgPSBjaGFubmVsRGVmLmNvbmRpdGlvbjtcbiAgICAgICAgc3BlY2lmaWVkU2NhbGUgPSBjaGFubmVsRGVmLmNvbmRpdGlvblsnc2NhbGUnXTtcbiAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbCA9PT0gJ3gnKSB7XG4gICAgICAgIGZpZWxkRGVmID0gZ2V0RmllbGREZWYoZW5jb2RpbmcueDIpO1xuICAgICAgfSBlbHNlIGlmIChjaGFubmVsID09PSAneScpIHtcbiAgICAgICAgZmllbGREZWYgPSBnZXRGaWVsZERlZihlbmNvZGluZy55Mik7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWVsZERlZikge1xuICAgICAgICBzY2FsZXNbY2hhbm5lbF0gPSBzcGVjaWZpZWRTY2FsZSB8fCB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgfSwge30gYXMgU2NhbGVJbmRleCk7XG4gIH1cblxuICBwcml2YXRlIGluaXRBeGVzKGVuY29kaW5nOiBFbmNvZGluZzxzdHJpbmc+KTogQXhpc0luZGV4IHtcbiAgICByZXR1cm4gW1gsIFldLnJlZHVjZShmdW5jdGlvbihfYXhpcywgY2hhbm5lbCkge1xuICAgICAgLy8gUG9zaXRpb24gQXhpc1xuXG4gICAgICAvLyBUT0RPOiBoYW5kbGUgQ29uZGl0aW9uRmllbGREZWZcbiAgICAgIGNvbnN0IGNoYW5uZWxEZWYgPSBlbmNvZGluZ1tjaGFubmVsXTtcbiAgICAgIGlmIChpc0ZpZWxkRGVmKGNoYW5uZWxEZWYpIHx8XG4gICAgICAgICAgKGNoYW5uZWwgPT09IFggJiYgaXNGaWVsZERlZihlbmNvZGluZy54MikpIHx8XG4gICAgICAgICAgKGNoYW5uZWwgPT09IFkgJiYgaXNGaWVsZERlZihlbmNvZGluZy55MikpKSB7XG5cbiAgICAgICAgY29uc3QgYXhpc1NwZWMgPSBpc0ZpZWxkRGVmKGNoYW5uZWxEZWYpID8gY2hhbm5lbERlZi5heGlzIDogbnVsbDtcblxuICAgICAgICAvLyBXZSBubyBsb25nZXIgc3VwcG9ydCBmYWxzZSBpbiB0aGUgc2NoZW1hLCBidXQgd2Uga2VlcCBmYWxzZSBoZXJlIGZvciBiYWNrd2FyZCBjb21wYXRhYmlsaXR5LlxuICAgICAgICBpZiAoYXhpc1NwZWMgIT09IG51bGwgJiYgYXhpc1NwZWMgIT09IGZhbHNlKSB7XG4gICAgICAgICAgX2F4aXNbY2hhbm5lbF0gPSB7XG4gICAgICAgICAgICAuLi5heGlzU3BlY1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBfYXhpcztcbiAgICB9LCB7fSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRMZWdlbmQoZW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4pOiBMZWdlbmRJbmRleCB7XG4gICAgcmV0dXJuIE5PTlBPU0lUSU9OX1NDQUxFX0NIQU5ORUxTLnJlZHVjZShmdW5jdGlvbihfbGVnZW5kLCBjaGFubmVsKSB7XG4gICAgICBjb25zdCBjaGFubmVsRGVmID0gZW5jb2RpbmdbY2hhbm5lbF07XG4gICAgICBpZiAoY2hhbm5lbERlZikge1xuICAgICAgICBjb25zdCBsZWdlbmQgPSBpc0ZpZWxkRGVmKGNoYW5uZWxEZWYpID8gY2hhbm5lbERlZi5sZWdlbmQgOlxuICAgICAgICAgIChoYXNDb25kaXRpb25hbEZpZWxkRGVmKGNoYW5uZWxEZWYpKSA/IGNoYW5uZWxEZWYuY29uZGl0aW9uWydsZWdlbmQnXSA6IG51bGw7XG5cbiAgICAgICAgaWYgKGxlZ2VuZCAhPT0gbnVsbCAmJiBsZWdlbmQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgX2xlZ2VuZFtjaGFubmVsXSA9IHsuLi5sZWdlbmR9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBfbGVnZW5kO1xuICAgIH0sIHt9KTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZURhdGEoKSB7XG4gICAgdGhpcy5jb21wb25lbnQuZGF0YSA9IHBhcnNlRGF0YSh0aGlzKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZUxheW91dFNpemUoKSB7XG4gICAgcGFyc2VVbml0TGF5b3V0U2l6ZSh0aGlzKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZVNlbGVjdGlvbigpIHtcbiAgICB0aGlzLmNvbXBvbmVudC5zZWxlY3Rpb24gPSBwYXJzZVVuaXRTZWxlY3Rpb24odGhpcywgdGhpcy5zZWxlY3Rpb24pO1xuICB9XG5cbiAgcHVibGljIHBhcnNlTWFya0dyb3VwKCkge1xuICAgIHRoaXMuY29tcG9uZW50Lm1hcmsgPSBwYXJzZU1hcmtHcm91cCh0aGlzKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXJzZUF4aXNBbmRIZWFkZXIoKSB7XG4gICAgdGhpcy5jb21wb25lbnQuYXhlcyA9IHBhcnNlVW5pdEF4aXModGhpcyk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVTZWxlY3Rpb25Ub3BMZXZlbFNpZ25hbHMoc2lnbmFsczogYW55W10pOiBWZ1NpZ25hbFtdIHtcbiAgICByZXR1cm4gYXNzZW1ibGVUb3BMZXZlbFNpZ25hbHModGhpcywgc2lnbmFscyk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVTZWxlY3Rpb25TaWduYWxzKCk6IFZnU2lnbmFsW10ge1xuICAgIHJldHVybiBhc3NlbWJsZVVuaXRTZWxlY3Rpb25TaWduYWxzKHRoaXMsIFtdKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NlbWJsZVNlbGVjdGlvbkRhdGEoZGF0YTogVmdEYXRhW10pOiBWZ0RhdGFbXSB7XG4gICAgcmV0dXJuIGFzc2VtYmxlVW5pdFNlbGVjdGlvbkRhdGEodGhpcywgZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVMYXlvdXQoKTogVmdMYXlvdXQge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTGF5b3V0U2lnbmFscygpOiBWZ1NpZ25hbFtdIHtcbiAgICByZXR1cm4gYXNzZW1ibGVMYXlvdXRTaWduYWxzKHRoaXMpO1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlTWFya3MoKSB7XG4gICAgbGV0IG1hcmtzID0gdGhpcy5jb21wb25lbnQubWFyayB8fCBbXTtcblxuICAgIC8vIElmIHRoaXMgdW5pdCBpcyBwYXJ0IG9mIGEgbGF5ZXIsIHNlbGVjdGlvbnMgc2hvdWxkIGF1Z21lbnRcbiAgICAvLyBhbGwgaW4gY29uY2VydCByYXRoZXIgdGhhbiBlYWNoIHVuaXQgaW5kaXZpZHVhbGx5LiBUaGlzXG4gICAgLy8gZW5zdXJlcyBjb3JyZWN0IGludGVybGVhdmluZyBvZiBjbGlwcGluZyBhbmQgYnJ1c2hlZCBtYXJrcy5cbiAgICBpZiAoIXRoaXMucGFyZW50IHx8ICFpc0xheWVyTW9kZWwodGhpcy5wYXJlbnQpKSB7XG4gICAgICBtYXJrcyA9IGFzc2VtYmxlVW5pdFNlbGVjdGlvbk1hcmtzKHRoaXMsIG1hcmtzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWFya3MubWFwKHRoaXMuY29ycmVjdERhdGFOYW1lcyk7XG4gIH1cblxuICBwdWJsaWMgYXNzZW1ibGVMYXlvdXRTaXplKCk6IFZnRW5jb2RlRW50cnkge1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogdGhpcy5nZXRTaXplU2lnbmFsUmVmKCd3aWR0aCcpLFxuICAgICAgaGVpZ2h0OiB0aGlzLmdldFNpemVTaWduYWxSZWYoJ2hlaWdodCcpXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRNYXBwaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmVuY29kaW5nO1xuICB9XG5cbiAgcHVibGljIHRvU3BlYyhleGNsdWRlQ29uZmlnPzogYW55LCBleGNsdWRlRGF0YT86IGFueSkge1xuICAgIGNvbnN0IGVuY29kaW5nID0gZHVwbGljYXRlKHRoaXMuZW5jb2RpbmcpO1xuICAgIGxldCBzcGVjOiBhbnk7XG5cbiAgICBzcGVjID0ge1xuICAgICAgbWFyazogdGhpcy5tYXJrRGVmLFxuICAgICAgZW5jb2Rpbmc6IGVuY29kaW5nXG4gICAgfTtcblxuICAgIGlmICghZXhjbHVkZUNvbmZpZykge1xuICAgICAgc3BlYy5jb25maWcgPSBkdXBsaWNhdGUodGhpcy5jb25maWcpO1xuICAgIH1cblxuICAgIGlmICghZXhjbHVkZURhdGEpIHtcbiAgICAgIHNwZWMuZGF0YSA9IGR1cGxpY2F0ZSh0aGlzLmRhdGEpO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBkZWZhdWx0c1xuICAgIHJldHVybiBzcGVjO1xuICB9XG5cbiAgcHVibGljIG1hcmsoKTogTWFyayB7XG4gICAgcmV0dXJuIHRoaXMubWFya0RlZi50eXBlO1xuICB9XG5cbiAgcHVibGljIGNoYW5uZWxIYXNGaWVsZChjaGFubmVsOiBDaGFubmVsKSB7XG4gICAgcmV0dXJuIHZsRW5jb2RpbmcuY2hhbm5lbEhhc0ZpZWxkKHRoaXMuZW5jb2RpbmcsIGNoYW5uZWwpO1xuICB9XG5cbiAgcHVibGljIGZpZWxkRGVmKGNoYW5uZWw6IFNpbmdsZURlZkNoYW5uZWwpOiBGaWVsZERlZjxzdHJpbmc+IHtcbiAgICBjb25zdCBjaGFubmVsRGVmID0gdGhpcy5lbmNvZGluZ1tjaGFubmVsXSBhcyBDaGFubmVsRGVmPHN0cmluZz47XG4gICAgcmV0dXJuIGdldEZpZWxkRGVmKGNoYW5uZWxEZWYpO1xuICB9XG59XG4iXX0= \ 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..ce23291b55 --- /dev/null +++ b/build/src/compositemark/boxplot.d.ts @@ -0,0 +1,52 @@ +import { Config } from '../config'; +import { Encoding } from './../encoding'; +import { MarkConfig } from './../mark'; +import { GenericUnitSpec, LayerSpec } 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](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. + * - `"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. + * __Default value:__ `"min-max"`. + */ + 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; +} +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): LayerSpec; diff --git a/build/src/compositemark/boxplot.js b/build/src/compositemark/boxplot.js new file mode 100644 index 0000000000..ef99510ba2 --- /dev/null +++ b/build/src/compositemark/boxplot.js @@ -0,0 +1,277 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var encoding_1 = require("../encoding"); +var encoding_2 = require("./../encoding"); +var fielddef_1 = require("./../fielddef"); +var log = require("./../log"); +var common_1 = require("./common"); +exports.BOXPLOT = 'box-plot'; +function isBoxPlotDef(mark) { + return !!mark['type']; +} +exports.isBoxPlotDef = isBoxPlotDef; +exports.BOXPLOT_STYLES = ['boxWhisker', 'box', 'boxMid']; +exports.VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX = { + box: ['size', 'color'], + boxWhisker: ['color'], + boxMid: ['color'] +}; +var supportedChannels = ['x', 'y', 'color', 'detail', 'opacity', 'size']; +function filterUnsupportedChannels(spec) { + return __assign({}, spec, { encoding: encoding_1.reduce(spec.encoding, function (newEncoding, fieldDef, channel) { + if (supportedChannels.indexOf(channel) > -1) { + newEncoding[channel] = fieldDef; + } + else { + log.warn(log.message.incompatibleChannel(channel, exports.BOXPLOT)); + } + return newEncoding; + }, {}) }); +} +exports.filterUnsupportedChannels = filterUnsupportedChannels; +function normalizeBoxPlot(spec, config) { + spec = filterUnsupportedChannels(spec); + // TODO: use selection + var mark = spec.mark, encoding = spec.encoding, selection = spec.selection, outerSpec = __rest(spec, ["mark", "encoding", "selection"]); + var kIQRScalar = undefined; + if (isBoxPlotDef(mark)) { + if (mark.extent) { + if (vega_util_1.isNumber(mark.extent)) { + kIQRScalar = mark.extent; + } + } + } + var orient = boxOrient(spec); + var _a = boxParams(spec, orient, kIQRScalar), transform = _a.transform, continuousAxisChannelDef = _a.continuousAxisChannelDef, continuousAxis = _a.continuousAxis, encodingWithoutContinuousAxis = _a.encodingWithoutContinuousAxis; + var color = encodingWithoutContinuousAxis.color, 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 } : common_1.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((_b = {}, _b[continuousAxis] = __assign({ field: 'lower_whisker_' + continuousAxisChannelDef.field, type: continuousAxisChannelDef.type }, continuousAxisScaleAndAxis), _b[continuousAxis + '2'] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _b), encodingWithoutSizeColorAndContinuousAxis, common_1.getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + encoding: __assign((_c = {}, _c[continuousAxis] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c[continuousAxis + '2'] = { + field: 'upper_whisker_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c), encodingWithoutSizeColorAndContinuousAxis, common_1.getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, + __assign({}, (selection ? { selection: selection } : {}), { mark: { + type: 'bar', + style: 'box' + }, encoding: __assign((_d = {}, _d[continuousAxis] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _d[continuousAxis + '2'] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _d), encodingWithoutContinuousAxis, (encodingWithoutContinuousAxis.color ? {} : common_1.getMarkSpecificConfigMixins(config.box, 'color')), sizeMixins) }), + { + mark: { + type: 'tick', + style: 'boxMid' + }, + encoding: __assign((_e = {}, _e[continuousAxis] = { + field: 'mid_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _e), encodingWithoutSizeColorAndContinuousAxis, common_1.getMarkSpecificConfigMixins(config.boxMid, 'color'), sizeMixins) + } + ] }); + var _b, _c, _d, _e; +} +exports.normalizeBoxPlot = normalizeBoxPlot; +function boxOrient(spec) { + var mark = spec.mark, encoding = spec.encoding, _outerSpec = __rest(spec, ["mark", "encoding"]); + if (fielddef_1.isFieldDef(encoding.x) && fielddef_1.isContinuous(encoding.x)) { + // x is continuous + if (fielddef_1.isFieldDef(encoding.y) && fielddef_1.isContinuous(encoding.y)) { + // both x and y are continuous + if (encoding.x.aggregate === undefined && encoding.y.aggregate === exports.BOXPLOT) { + return 'vertical'; + } + else if (encoding.y.aggregate === undefined && encoding.x.aggregate === exports.BOXPLOT) { + return 'horizontal'; + } + else if (encoding.x.aggregate === exports.BOXPLOT && encoding.y.aggregate === exports.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 (fielddef_1.isFieldDef(encoding.y) && fielddef_1.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, _outerSpec = __rest(spec, ["mark", "encoding"]); + var continuousAxisChannelDef; + var continuousAxis; + if (orient === 'vertical') { + continuousAxis = 'y'; + continuousAxisChannelDef = encoding.y; // Safe to cast because if y is not continous fielddef, the orient would not be vertical. + } + else { + continuousAxis = 'x'; + continuousAxisChannelDef = encoding.x; // Safe to cast because if x is not continous fielddef, the orient would not be horizontal. + } + if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) { + var aggregate = continuousAxisChannelDef.aggregate, continuousAxisWithoutAggregate = __rest(continuousAxisChannelDef, ["aggregate"]); + if (aggregate !== exports.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 = {}; + encoding_2.forEach(encoding, function (channelDef, channel) { + if (channel === continuousAxis) { + // Skip continuous axis as we already handle it separately + return; + } + if (fielddef_1.isFieldDef(channelDef)) { + if (channelDef.aggregate && channelDef.aggregate !== exports.BOXPLOT) { + aggregate.push({ + op: channelDef.aggregate, + field: channelDef.field, + as: fielddef_1.field(channelDef) + }); + } + else if (channelDef.aggregate === undefined) { + var transformedField = fielddef_1.field(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_2 = channelDef.field; + timeUnits.push({ timeUnit: timeUnit, field: field_2, as: transformedField }); + } + groupby.push(transformedField); + } + // now the field should refer to post-transformed field instead + encodingWithoutContinuousAxis[channel] = { + field: fielddef_1.field(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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm94cGxvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb3NpdGVtYXJrL2JveHBsb3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUFtQztBQUduQyx3Q0FBbUM7QUFFbkMsMENBQWdEO0FBQ2hELDBDQUFpRztBQUNqRyw4QkFBZ0M7QUFJaEMsbUNBQXFEO0FBR3hDLFFBQUEsT0FBTyxHQUFlLFVBQVUsQ0FBQztBQTBCOUMsc0JBQTZCLElBQTBCO0lBQ3JELE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3hCLENBQUM7QUFGRCxvQ0FFQztBQUVZLFFBQUEsY0FBYyxHQUFtQixDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7QUF5QmpFLFFBQUEscUNBQXFDLEdBRTlDO0lBQ0YsR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQztJQUN0QixVQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUM7SUFDckIsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDO0NBQ2xCLENBQUM7QUFFRixJQUFNLGlCQUFpQixHQUFjLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN0RixtQ0FBMEMsSUFBNkQ7SUFDckcsTUFBTSxjQUNELElBQUksSUFDUCxRQUFRLEVBQUUsaUJBQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxPQUFPO1lBQzdELEVBQUUsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUM7WUFDbEMsQ0FBQztZQUFDLElBQUksQ0FB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S0FBSyxTQUFBLEVBQUUsRUFBRSxFQUFFLGdCQUFnQixFQUFDLENBQUMsQ0FBQztnQkFDMUQsQ0FBQztnQkFFRCxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDakMsQ0FBQztZQUNELCtEQUErRDtZQUMvRCw2QkFBNkIsQ0FBQyxPQUFPLENBQUMsR0FBRztnQkFDdkMsS0FBSyxFQUFFLGdCQUFLLENBQUMsVUFBVSxDQUFDO2dCQUN4QixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7YUFDdEIsQ0FBQztRQUNKLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLDJCQUEyQjtZQUMzQiw2QkFBNkIsQ0FBQyxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDO1FBQ0wsU0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQ2xCLElBQUksRUFDSixTQUFTLEVBQ1QsQ0FBQyxFQUFDLFNBQVMsV0FBQSxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUMsRUFDdEIsdUJBQXVCLENBQ3hCO1FBQ0Qsd0JBQXdCLDBCQUFBO1FBQ3hCLGNBQWMsZ0JBQUE7UUFDZCw2QkFBNkIsK0JBQUE7S0FDOUIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2lzTnVtYmVyfSBmcm9tICd2ZWdhLXV0aWwnO1xuaW1wb3J0IHtDaGFubmVsfSBmcm9tICcuLi9jaGFubmVsJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHtyZWR1Y2V9IGZyb20gJy4uL2VuY29kaW5nJztcbmltcG9ydCB7QWdncmVnYXRlZEZpZWxkRGVmLCBCaW5UcmFuc2Zvcm0sIENhbGN1bGF0ZVRyYW5zZm9ybSwgVGltZVVuaXRUcmFuc2Zvcm19IGZyb20gJy4uL3RyYW5zZm9ybSc7XG5pbXBvcnQge0VuY29kaW5nLCBmb3JFYWNofSBmcm9tICcuLy4uL2VuY29kaW5nJztcbmltcG9ydCB7ZmllbGQsIEZpZWxkLCBGaWVsZERlZiwgaXNDb250aW51b3VzLCBpc0ZpZWxkRGVmLCBQb3NpdGlvbkZpZWxkRGVmfSBmcm9tICcuLy4uL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLy4uL2xvZyc7XG5pbXBvcnQge01hcmtDb25maWd9IGZyb20gJy4vLi4vbWFyayc7XG5pbXBvcnQge0dlbmVyaWNVbml0U3BlYywgTGF5ZXJTcGVjfSBmcm9tICcuLy4uL3NwZWMnO1xuaW1wb3J0IHtPcmllbnR9IGZyb20gJy4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtnZXRNYXJrU3BlY2lmaWNDb25maWdNaXhpbnN9IGZyb20gJy4vY29tbW9uJztcblxuXG5leHBvcnQgY29uc3QgQk9YUExPVDogJ2JveC1wbG90JyA9ICdib3gtcGxvdCc7XG5leHBvcnQgdHlwZSBCT1hQTE9UID0gdHlwZW9mIEJPWFBMT1Q7XG5leHBvcnQgdHlwZSBCb3hQbG90U3R5bGUgPSAnYm94V2hpc2tlcicgfCAnYm94JyB8ICdib3hNaWQnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQm94UGxvdERlZiB7XG4gIC8qKlxuICAgKiBUeXBlIG9mIHRoZSBtYXJrLiAgRm9yIGJveCBwbG90cywgdGhpcyBzaG91bGQgYWx3YXlzIGJlIGBcImJveC1wbG90XCJgLlxuICAgKiBbYm94cGxvdF0oY29tcG9zaXRlbWFyay5odG1sI2JveHBsb3QpXG4gICAqL1xuICB0eXBlOiBCT1hQTE9UO1xuXG4gIC8qKlxuICAgKiBPcmllbnRhdGlvbiBvZiB0aGUgYm94IHBsb3QuICBUaGlzIGlzIG5vcm1hbGx5IGF1dG9tYXRpY2FsbHkgZGV0ZXJtaW5lZCwgYnV0IGNhbiBiZSBzcGVjaWZpZWQgd2hlbiB0aGUgb3JpZW50YXRpb24gaXMgYW1iaWd1b3VzIGFuZCBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBkZXRlcm1pbmVkLlxuICAgKi9cbiAgb3JpZW50PzogT3JpZW50O1xuXG4gIC8qKlxuICAgKiBFeHRlbnQgaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hlcmUgdGhlIHdoaXNrZXJzIGV4dGVuZCB0by4gVGhlIG9wdGlvbnMgYXJlXG4gICAqIC0gYFwibWluLW1heFwiOiBtaW4gYW5kIG1heCBhcmUgdGhlIGxvd2VyIGFuZCB1cHBlciB3aGlza2VycyByZXNwZWN0aXZlbHkuXG4gICAqIC0gYFwibnVtYmVyXCI6IEEgc2NhbGFyIChpbnRlZ2VyIG9yIGZsb2F0aW5nIHBvaW50IG51bWJlcikgdGhhdCB3aWxsIGJlIG11bHRpcGxpZWQgYnkgdGhlIElRUiBhbmQgdGhlIHByb2R1Y3Qgd2lsbCBiZSBhZGRlZCB0byB0aGUgdGhpcmQgcXVhcnRpbGUgdG8gZ2V0IHRoZSB1cHBlciB3aGlza2VyIGFuZCBzdWJ0cmFjdGVkIGZyb20gdGhlIGZpcnN0IHF1YXJ0aWxlIHRvIGdldCB0aGUgbG93ZXIgd2hpc2tlci5cbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGBcIm1pbi1tYXhcImAuXG4gICAqL1xuICBleHRlbnQ/OiAnbWluLW1heCcgfCBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0JveFBsb3REZWYobWFyazogQk9YUExPVCB8IEJveFBsb3REZWYpOiBtYXJrIGlzIEJveFBsb3REZWYge1xuICByZXR1cm4gISFtYXJrWyd0eXBlJ107XG59XG5cbmV4cG9ydCBjb25zdCBCT1hQTE9UX1NUWUxFUzogQm94UGxvdFN0eWxlW10gPSBbJ2JveFdoaXNrZXInLCAnYm94JywgJ2JveE1pZCddO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJveFBsb3RDb25maWcgZXh0ZW5kcyBNYXJrQ29uZmlnIHtcbiAgLyoqIFNpemUgb2YgdGhlIGJveCBhbmQgbWlkIHRpY2sgb2YgYSBib3ggcGxvdCAqL1xuICBzaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJveFBsb3RDb25maWdNaXhpbnMge1xuICAvKipcbiAgICogQm94IENvbmZpZ1xuICAgKiBAaGlkZVxuICAgKi9cbiAgYm94PzogQm94UGxvdENvbmZpZztcblxuICAvKipcbiAgICogQGhpZGVcbiAgICovXG4gIGJveFdoaXNrZXI/OiBNYXJrQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBAaGlkZVxuICAgKi9cbiAgYm94TWlkPzogTWFya0NvbmZpZztcbn1cblxuZXhwb3J0IGNvbnN0IFZMX09OTFlfQk9YUExPVF9DT05GSUdfUFJPUEVSVFlfSU5ERVg6IHtcbiAgW2sgaW4ga2V5b2YgQm94UGxvdENvbmZpZ01peGluc10/OiAoa2V5b2YgQm94UGxvdENvbmZpZ01peGluc1trXSlbXVxufSA9IHtcbiAgYm94OiBbJ3NpemUnLCAnY29sb3InXSxcbiAgYm94V2hpc2tlcjogWydjb2xvciddLFxuICBib3hNaWQ6IFsnY29sb3InXVxufTtcblxuY29uc3Qgc3VwcG9ydGVkQ2hhbm5lbHM6IENoYW5uZWxbXSA9IFsneCcsICd5JywgJ2NvbG9yJywgJ2RldGFpbCcsICdvcGFjaXR5JywgJ3NpemUnXTtcbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJVbnN1cHBvcnRlZENoYW5uZWxzKHNwZWM6IEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxzdHJpbmc+LCBCT1hQTE9UIHwgQm94UGxvdERlZj4pOiBHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8c3RyaW5nPiwgQk9YUExPVCB8IEJveFBsb3REZWY+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zcGVjLFxuICAgIGVuY29kaW5nOiByZWR1Y2Uoc3BlYy5lbmNvZGluZywgKG5ld0VuY29kaW5nLCBmaWVsZERlZiwgY2hhbm5lbCkgPT4ge1xuICAgICAgaWYgKHN1cHBvcnRlZENoYW5uZWxzLmluZGV4T2YoY2hhbm5lbCkgPiAtMSkge1xuICAgICAgICBuZXdFbmNvZGluZ1tjaGFubmVsXSA9IGZpZWxkRGVmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuaW5jb21wYXRpYmxlQ2hhbm5lbChjaGFubmVsLCBCT1hQTE9UKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3RW5jb2Rpbmc7XG4gICAgfSwge30pLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQm94UGxvdChzcGVjOiBHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8c3RyaW5nPiwgQk9YUExPVCB8IEJveFBsb3REZWY+LCBjb25maWc6IENvbmZpZyk6IExheWVyU3BlYyB7XG4gIHNwZWMgPSBmaWx0ZXJVbnN1cHBvcnRlZENoYW5uZWxzKHNwZWMpO1xuICAvLyBUT0RPOiB1c2Ugc2VsZWN0aW9uXG4gIGNvbnN0IHttYXJrLCBlbmNvZGluZywgc2VsZWN0aW9uLCAuLi5vdXRlclNwZWN9ID0gc3BlYztcblxuICBsZXQga0lRUlNjYWxhcjogbnVtYmVyID0gdW5kZWZpbmVkO1xuICBpZiAoaXNCb3hQbG90RGVmKG1hcmspKSB7XG4gICAgaWYgKG1hcmsuZXh0ZW50KSB7XG4gICAgICBpZihpc051bWJlcihtYXJrLmV4dGVudCkpIHtcbiAgICAgICAga0lRUlNjYWxhciA9IG1hcmsuZXh0ZW50O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG9yaWVudDogT3JpZW50ID0gYm94T3JpZW50KHNwZWMpO1xuICBjb25zdCB7dHJhbnNmb3JtLCBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYsIGNvbnRpbnVvdXNBeGlzLCBlbmNvZGluZ1dpdGhvdXRDb250aW51b3VzQXhpc30gPSBib3hQYXJhbXMoc3BlYywgb3JpZW50LCBrSVFSU2NhbGFyKTtcblxuICBjb25zdCB7Y29sb3IsIHNpemUsIC4uLmVuY29kaW5nV2l0aG91dFNpemVDb2xvckFuZENvbnRpbnVvdXNBeGlzfSA9IGVuY29kaW5nV2l0aG91dENvbnRpbnVvdXNBeGlzO1xuXG4gIC8vIFNpemUgZW5jb2Rpbmcgb3IgdGhlIGRlZmF1bHQgY29uZmlnLmJveC5zaXplIGlzIGFwcGxpZWQgdG8gYm94IGFuZCBib3hNaWRcbiAgY29uc3Qgc2l6ZU1peGlucyA9IHNpemUgPyB7c2l6ZX0gOiBnZXRNYXJrU3BlY2lmaWNDb25maWdNaXhpbnMoY29uZmlnLmJveCwgJ3NpemUnKTtcblxuICBjb25zdCBjb250aW51b3VzQXhpc1NjYWxlQW5kQXhpcyA9IHt9O1xuICBpZiAoY29udGludW91c0F4aXNDaGFubmVsRGVmLnNjYWxlKSB7XG4gICAgY29udGludW91c0F4aXNTY2FsZUFuZEF4aXNbJ3NjYWxlJ10gPSBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuc2NhbGU7XG4gIH1cbiAgaWYgKGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5heGlzKSB7XG4gICAgY29udGludW91c0F4aXNTY2FsZUFuZEF4aXNbJ2F4aXMnXSA9IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5heGlzO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vdXRlclNwZWMsXG4gICAgdHJhbnNmb3JtLFxuICAgIGxheWVyOiBbXG4gICAgICB7IC8vIGxvd2VyIHdoaXNrZXJcbiAgICAgICAgbWFyazoge1xuICAgICAgICAgIHR5cGU6ICdydWxlJyxcbiAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgIH0sXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgW2NvbnRpbnVvdXNBeGlzXToge1xuICAgICAgICAgICAgZmllbGQ6ICdsb3dlcl93aGlza2VyXycgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGQsXG4gICAgICAgICAgICB0eXBlOiBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYudHlwZSxcbiAgICAgICAgICAgIC4uLmNvbnRpbnVvdXNBeGlzU2NhbGVBbmRBeGlzXG4gICAgICAgICAgfSxcbiAgICAgICAgICBbY29udGludW91c0F4aXMgKyAnMiddOiB7XG4gICAgICAgICAgICBmaWVsZDogJ2xvd2VyX2JveF8nICsgY29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkLFxuICAgICAgICAgICAgdHlwZTogY29udGludW91c0F4aXNDaGFubmVsRGVmLnR5cGVcbiAgICAgICAgICB9LFxuICAgICAgICAgIC4uLmVuY29kaW5nV2l0aG91dFNpemVDb2xvckFuZENvbnRpbnVvdXNBeGlzLFxuICAgICAgICAgIC4uLmdldE1hcmtTcGVjaWZpY0NvbmZpZ01peGlucyhjb25maWcuYm94V2hpc2tlciwgJ2NvbG9yJylcbiAgICAgICAgfVxuICAgICAgfSwgeyAvLyB1cHBlciB3aGlza2VyXG4gICAgICAgIG1hcms6IHtcbiAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgc3R5bGU6ICdib3hXaGlza2VyJ1xuICAgICAgICB9LFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFtjb250aW51b3VzQXhpc106IHtcbiAgICAgICAgICAgIGZpZWxkOiAndXBwZXJfYm94XycgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGQsXG4gICAgICAgICAgICB0eXBlOiBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYudHlwZVxuICAgICAgICAgIH0sXG4gICAgICAgICAgW2NvbnRpbnVvdXNBeGlzICsgJzInXToge1xuICAgICAgICAgICAgZmllbGQ6ICd1cHBlcl93aGlza2VyXycgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGQsXG4gICAgICAgICAgICB0eXBlOiBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYudHlwZVxuICAgICAgICAgIH0sXG4gICAgICAgICAgLi4uZW5jb2RpbmdXaXRob3V0U2l6ZUNvbG9yQW5kQ29udGludW91c0F4aXMsXG4gICAgICAgICAgLi4uZ2V0TWFya1NwZWNpZmljQ29uZmlnTWl4aW5zKGNvbmZpZy5ib3hXaGlza2VyLCAnY29sb3InKVxuICAgICAgICB9XG4gICAgICB9LCB7IC8vIGJveCAocTEgdG8gcTMpXG4gICAgICAgIC4uLihzZWxlY3Rpb24gPyB7c2VsZWN0aW9ufSA6IHt9KSxcbiAgICAgICAgbWFyazoge1xuICAgICAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgICAgIHN0eWxlOiAnYm94J1xuICAgICAgICB9LFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFtjb250aW51b3VzQXhpc106IHtcbiAgICAgICAgICAgIGZpZWxkOiAnbG93ZXJfYm94XycgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGQsXG4gICAgICAgICAgICB0eXBlOiBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYudHlwZVxuICAgICAgICAgIH0sXG4gICAgICAgICAgW2NvbnRpbnVvdXNBeGlzICsgJzInXToge1xuICAgICAgICAgICAgZmllbGQ6ICd1cHBlcl9ib3hfJyArIGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZCxcbiAgICAgICAgICAgIHR5cGU6IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi50eXBlXG4gICAgICAgICAgfSxcbiAgICAgICAgICAuLi5lbmNvZGluZ1dpdGhvdXRDb250aW51b3VzQXhpcyxcbiAgICAgICAgICAuLi4oZW5jb2RpbmdXaXRob3V0Q29udGludW91c0F4aXMuY29sb3IgPyB7fSA6IGdldE1hcmtTcGVjaWZpY0NvbmZpZ01peGlucyhjb25maWcuYm94LCAnY29sb3InKSksXG4gICAgICAgICAgLi4uc2l6ZU1peGlucyxcbiAgICAgICAgfVxuICAgICAgfSwgeyAvLyBtaWQgdGlja1xuICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgdHlwZTogJ3RpY2snLFxuICAgICAgICAgIHN0eWxlOiAnYm94TWlkJ1xuICAgICAgICB9LFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFtjb250aW51b3VzQXhpc106IHtcbiAgICAgICAgICAgIGZpZWxkOiAnbWlkX2JveF8nICsgY29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkLFxuICAgICAgICAgICAgdHlwZTogY29udGludW91c0F4aXNDaGFubmVsRGVmLnR5cGVcbiAgICAgICAgICB9LFxuICAgICAgICAgIC4uLmVuY29kaW5nV2l0aG91dFNpemVDb2xvckFuZENvbnRpbnVvdXNBeGlzLFxuICAgICAgICAgIC4uLmdldE1hcmtTcGVjaWZpY0NvbmZpZ01peGlucyhjb25maWcuYm94TWlkLCAnY29sb3InKSxcbiAgICAgICAgICAuLi5zaXplTWl4aW5zLFxuICAgICAgICB9XG4gICAgICB9XG4gICAgXVxuICB9O1xufVxuXG5mdW5jdGlvbiBib3hPcmllbnQoc3BlYzogR2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPEZpZWxkPiwgQk9YUExPVCB8IEJveFBsb3REZWY+KTogT3JpZW50IHtcbiAgY29uc3Qge21hcms6IG1hcmssIGVuY29kaW5nOiBlbmNvZGluZywgLi4uX291dGVyU3BlY30gPSBzcGVjO1xuXG4gIGlmIChpc0ZpZWxkRGVmKGVuY29kaW5nLngpICYmIGlzQ29udGludW91cyhlbmNvZGluZy54KSkge1xuICAgIC8vIHggaXMgY29udGludW91c1xuICAgIGlmIChpc0ZpZWxkRGVmKGVuY29kaW5nLnkpICYmIGlzQ29udGludW91cyhlbmNvZGluZy55KSkge1xuICAgICAgLy8gYm90aCB4IGFuZCB5IGFyZSBjb250aW51b3VzXG4gICAgICBpZiAoZW5jb2RpbmcueC5hZ2dyZWdhdGUgPT09IHVuZGVmaW5lZCAmJiBlbmNvZGluZy55LmFnZ3JlZ2F0ZSA9PT0gQk9YUExPVCkge1xuICAgICAgICByZXR1cm4gJ3ZlcnRpY2FsJztcbiAgICAgIH0gZWxzZSBpZiAoZW5jb2RpbmcueS5hZ2dyZWdhdGUgPT09IHVuZGVmaW5lZCAmJiBlbmNvZGluZy54LmFnZ3JlZ2F0ZSA9PT0gQk9YUExPVCkge1xuICAgICAgICByZXR1cm4gJ2hvcml6b250YWwnO1xuICAgICAgfSBlbHNlIGlmIChlbmNvZGluZy54LmFnZ3JlZ2F0ZSA9PT0gQk9YUExPVCAmJiBlbmNvZGluZy55LmFnZ3JlZ2F0ZSA9PT0gQk9YUExPVCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JvdGggeCBhbmQgeSBjYW5ub3QgaGF2ZSBhZ2dyZWdhdGUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc0JveFBsb3REZWYobWFyaykgJiYgbWFyay5vcmllbnQpIHtcbiAgICAgICAgICByZXR1cm4gbWFyay5vcmllbnQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkZWZhdWx0IG9yaWVudGF0aW9uID0gdmVydGljYWxcbiAgICAgICAgcmV0dXJuICd2ZXJ0aWNhbCc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8geCBpcyBjb250aW51b3VzIGJ1dCB5IGlzIG5vdFxuICAgIHJldHVybiAnaG9yaXpvbnRhbCc7XG4gIH0gZWxzZSBpZiAoaXNGaWVsZERlZihlbmNvZGluZy55KSAmJiBpc0NvbnRpbnVvdXMoZW5jb2RpbmcueSkpIHtcbiAgICAvLyB5IGlzIGNvbnRpbnVvdXMgYnV0IHggaXMgbm90XG4gICAgcmV0dXJuICd2ZXJ0aWNhbCc7XG4gIH0gZWxzZSB7XG4gICAgLy8gTmVpdGhlciB4IG5vciB5IGlzIGNvbnRpbnVvdXMuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdOZWVkIGEgdmFsaWQgY29udGludW91cyBheGlzIGZvciBib3hwbG90cycpO1xuICB9XG59XG5cblxuZnVuY3Rpb24gYm94Q29udGlub3VzQXhpcyhzcGVjOiBHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8c3RyaW5nPiwgQk9YUExPVCB8IEJveFBsb3REZWY+LCBvcmllbnQ6IE9yaWVudCkge1xuICBjb25zdCB7bWFyazogbWFyaywgZW5jb2Rpbmc6IGVuY29kaW5nLCAuLi5fb3V0ZXJTcGVjfSA9IHNwZWM7XG5cbiAgbGV0IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZjogUG9zaXRpb25GaWVsZERlZjxzdHJpbmc+O1xuICBsZXQgY29udGludW91c0F4aXM6ICd4JyB8ICd5JztcblxuICBpZiAob3JpZW50ID09PSAndmVydGljYWwnKSB7XG4gICAgY29udGludW91c0F4aXMgPSAneSc7XG4gICAgY29udGludW91c0F4aXNDaGFubmVsRGVmID0gZW5jb2RpbmcueSBhcyBGaWVsZERlZjxzdHJpbmc+OyAvLyBTYWZlIHRvIGNhc3QgYmVjYXVzZSBpZiB5IGlzIG5vdCBjb250aW5vdXMgZmllbGRkZWYsIHRoZSBvcmllbnQgd291bGQgbm90IGJlIHZlcnRpY2FsLlxuICB9IGVsc2Uge1xuICAgIGNvbnRpbnVvdXNBeGlzID0gJ3gnO1xuICAgIGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZiA9IGVuY29kaW5nLnggYXMgRmllbGREZWY8c3RyaW5nPjsgLy8gU2FmZSB0byBjYXN0IGJlY2F1c2UgaWYgeCBpcyBub3QgY29udGlub3VzIGZpZWxkZGVmLCB0aGUgb3JpZW50IHdvdWxkIG5vdCBiZSBob3Jpem9udGFsLlxuICB9XG5cbiAgaWYgKGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZiAmJiBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuYWdncmVnYXRlKSB7XG4gICAgY29uc3Qge2FnZ3JlZ2F0ZSwgLi4uY29udGludW91c0F4aXNXaXRob3V0QWdncmVnYXRlfSA9IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZjtcbiAgICBpZiAoYWdncmVnYXRlICE9PSBCT1hQTE9UKSB7XG4gICAgICBsb2cud2FybihgQ29udGludW91cyBheGlzIHNob3VsZCBub3QgaGF2ZSBjdXN0b21pemVkIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uICR7YWdncmVnYXRlfWApO1xuICAgIH1cbiAgICBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYgPSBjb250aW51b3VzQXhpc1dpdGhvdXRBZ2dyZWdhdGU7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZixcbiAgICBjb250aW51b3VzQXhpc1xuICB9O1xufVxuXG5mdW5jdGlvbiBib3hQYXJhbXMoc3BlYzogR2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPHN0cmluZz4sIEJPWFBMT1QgfCBCb3hQbG90RGVmPiwgb3JpZW50OiBPcmllbnQsIGtJUVJTY2FsYXI6ICdtaW4tbWF4JyB8IG51bWJlcikge1xuXG4gIGNvbnN0IHtjb250aW51b3VzQXhpc0NoYW5uZWxEZWYsIGNvbnRpbnVvdXNBeGlzfSA9IGJveENvbnRpbm91c0F4aXMoc3BlYywgb3JpZW50KTtcbiAgY29uc3QgZW5jb2RpbmcgPSBzcGVjLmVuY29kaW5nO1xuXG4gIGNvbnN0IGlzTWluTWF4ID0ga0lRUlNjYWxhciA9PT0gdW5kZWZpbmVkO1xuICBjb25zdCBhZ2dyZWdhdGU6IEFnZ3JlZ2F0ZWRGaWVsZERlZltdID0gW1xuICAgIHtcbiAgICAgIG9wOiAncTEnLFxuICAgICAgZmllbGQ6IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZCxcbiAgICAgIGFzOiAnbG93ZXJfYm94XycgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGRcbiAgICB9LFxuICAgIHtcbiAgICAgIG9wOiAncTMnLFxuICAgICAgZmllbGQ6IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZCxcbiAgICAgIGFzOiAndXBwZXJfYm94XycgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGRcbiAgICB9LFxuICAgIHtcbiAgICAgIG9wOiAnbWVkaWFuJyxcbiAgICAgIGZpZWxkOiBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGQsXG4gICAgICBhczogJ21pZF9ib3hfJyArIGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZFxuICAgIH1cbiAgXTtcbiAgbGV0IHBvc3RBZ2dyZWdhdGVDYWxjdWxhdGVzOiBDYWxjdWxhdGVUcmFuc2Zvcm1bXSA9IFtdO1xuXG4gIGFnZ3JlZ2F0ZS5wdXNoKHtcbiAgICBvcDogJ21pbicsXG4gICAgZmllbGQ6IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZCxcbiAgICBhczogKGlzTWluTWF4ID8gJ2xvd2VyX3doaXNrZXJfJyA6ICdtaW5fJykgKyBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGRcbiAgfSk7XG4gIGFnZ3JlZ2F0ZS5wdXNoKHtcbiAgICBvcDogJ21heCcsXG4gICAgZmllbGQ6IGNvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZCxcbiAgICBhczogIChpc01pbk1heCA/ICd1cHBlcl93aGlza2VyXycgOiAnbWF4XycpICsgY29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkXG4gIH0pO1xuXG4gIGlmICghaXNNaW5NYXgpIHtcbiAgICBwb3N0QWdncmVnYXRlQ2FsY3VsYXRlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgY2FsY3VsYXRlOiBgZGF0dW0udXBwZXJfYm94XyR7Y29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkfSAtIGRhdHVtLmxvd2VyX2JveF8ke2NvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZH1gLFxuICAgICAgICBhczogJ2lxcl8nICsgY29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBjYWxjdWxhdGU6IGBtaW4oZGF0dW0udXBwZXJfYm94XyR7Y29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkfSArIGRhdHVtLmlxcl8ke2NvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZH0gKiAke2tJUVJTY2FsYXJ9LCBkYXR1bS5tYXhfJHtjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGR9KWAsXG4gICAgICAgIGFzOiAndXBwZXJfd2hpc2tlcl8nICsgY29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBjYWxjdWxhdGU6IGBtYXgoZGF0dW0ubG93ZXJfYm94XyR7Y29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkfSAtIGRhdHVtLmlxcl8ke2NvbnRpbnVvdXNBeGlzQ2hhbm5lbERlZi5maWVsZH0gKiAke2tJUVJTY2FsYXJ9LCBkYXR1bS5taW5fJHtjb250aW51b3VzQXhpc0NoYW5uZWxEZWYuZmllbGR9KWAsXG4gICAgICAgIGFzOiAnbG93ZXJfd2hpc2tlcl8nICsgY29udGludW91c0F4aXNDaGFubmVsRGVmLmZpZWxkXG4gICAgICB9XG4gICAgXTtcbiAgfVxuXG4gIGNvbnN0IGdyb3VwYnk6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IGJpbnM6IEJpblRyYW5zZm9ybVtdID0gW107XG4gIGNvbnN0IHRpbWVVbml0czogVGltZVVuaXRUcmFuc2Zvcm1bXSA9IFtdO1xuXG4gIGNvbnN0IGVuY29kaW5nV2l0aG91dENvbnRpbnVvdXNBeGlzOiBFbmNvZGluZzxzdHJpbmc+ID0ge307XG4gIGZvckVhY2goZW5jb2RpbmcsIChjaGFubmVsRGVmLCBjaGFubmVsKSA9PiB7XG4gICAgaWYgKGNoYW5uZWwgPT09IGNvbnRpbnVvdXNBeGlzKSB7XG4gICAgICAvLyBTa2lwIGNvbnRpbnVvdXMgYXhpcyBhcyB3ZSBhbHJlYWR5IGhhbmRsZSBpdCBzZXBhcmF0ZWx5XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpc0ZpZWxkRGVmKGNoYW5uZWxEZWYpKSB7XG4gICAgICBpZiAoY2hhbm5lbERlZi5hZ2dyZWdhdGUgJiYgY2hhbm5lbERlZi5hZ2dyZWdhdGUgIT09IEJPWFBMT1QpIHtcbiAgICAgICAgYWdncmVnYXRlLnB1c2goe1xuICAgICAgICAgIG9wOiBjaGFubmVsRGVmLmFnZ3JlZ2F0ZSxcbiAgICAgICAgICBmaWVsZDogY2hhbm5lbERlZi5maWVsZCxcbiAgICAgICAgICBhczogZmllbGQoY2hhbm5lbERlZilcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGNoYW5uZWxEZWYuYWdncmVnYXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRGaWVsZCA9IGZpZWxkKGNoYW5uZWxEZWYpO1xuXG4gICAgICAgIC8vIEFkZCBiaW4gb3IgdGltZVVuaXQgdHJhbnNmb3JtIGlmIGFwcGxpY2FibGVcbiAgICAgICAgY29uc3QgYmluID0gY2hhbm5lbERlZi5iaW47XG4gICAgICAgIGlmIChiaW4pIHtcbiAgICAgICAgICBjb25zdCB7ZmllbGR9ID0gY2hhbm5lbERlZjtcbiAgICAgICAgICBiaW5zLnB1c2goe2JpbiwgZmllbGQsIGFzOiB0cmFuc2Zvcm1lZEZpZWxkfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbERlZi50aW1lVW5pdCkge1xuICAgICAgICAgIGNvbnN0IHt0aW1lVW5pdCwgZmllbGR9ID0gY2hhbm5lbERlZjtcbiAgICAgICAgICB0aW1lVW5pdHMucHVzaCh7dGltZVVuaXQsIGZpZWxkLCBhczogdHJhbnNmb3JtZWRGaWVsZH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3JvdXBieS5wdXNoKHRyYW5zZm9ybWVkRmllbGQpO1xuICAgICAgfVxuICAgICAgLy8gbm93IHRoZSBmaWVsZCBzaG91bGQgcmVmZXIgdG8gcG9zdC10cmFuc2Zvcm1lZCBmaWVsZCBpbnN0ZWFkXG4gICAgICBlbmNvZGluZ1dpdGhvdXRDb250aW51b3VzQXhpc1tjaGFubmVsXSA9IHtcbiAgICAgICAgZmllbGQ6IGZpZWxkKGNoYW5uZWxEZWYpLFxuICAgICAgICB0eXBlOiBjaGFubmVsRGVmLnR5cGVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciB2YWx1ZSBkZWYsIGp1c3QgY29weVxuICAgICAgZW5jb2RpbmdXaXRob3V0Q29udGludW91c0F4aXNbY2hhbm5lbF0gPSBlbmNvZGluZ1tjaGFubmVsXTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgdHJhbnNmb3JtOiBbXS5jb25jYXQoXG4gICAgICBiaW5zLFxuICAgICAgdGltZVVuaXRzLFxuICAgICAgW3thZ2dyZWdhdGUsIGdyb3VwYnl9XSxcbiAgICAgIHBvc3RBZ2dyZWdhdGVDYWxjdWxhdGVzXG4gICAgKSxcbiAgICBjb250aW51b3VzQXhpc0NoYW5uZWxEZWYsXG4gICAgY29udGludW91c0F4aXMsXG4gICAgZW5jb2RpbmdXaXRob3V0Q29udGludW91c0F4aXNcbiAgfTtcbn1cbiJdfQ== \ 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..8031a1bc59 --- /dev/null +++ b/build/src/compositemark/common.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function getMarkSpecificConfigMixins(markSpecificConfig, channel) { + var value = markSpecificConfig[channel]; + return value !== undefined ? (_a = {}, _a[channel] = { value: value }, _a) : {}; + var _a; +} +exports.getMarkSpecificConfigMixins = getMarkSpecificConfigMixins; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvc2l0ZW1hcmsvY29tbW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBR0EscUNBQTRDLGtCQUE4QixFQUFFLE9BQTJCO0lBQ3JHLElBQU0sS0FBSyxHQUFHLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsV0FBRSxHQUFDLE9BQU8sSUFBRyxFQUFDLEtBQUssT0FBQSxFQUFDLE1BQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7QUFDekQsQ0FBQztBQUhELGtFQUdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOb25Qb3NpdGlvbkNoYW5uZWx9IGZyb20gJy4uL2NoYW5uZWwnO1xuaW1wb3J0IHtNYXJrQ29uZmlnfSBmcm9tICcuLi9tYXJrJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcmtTcGVjaWZpY0NvbmZpZ01peGlucyhtYXJrU3BlY2lmaWNDb25maWc6IE1hcmtDb25maWcsIGNoYW5uZWw6IE5vblBvc2l0aW9uQ2hhbm5lbCkge1xuICBjb25zdCB2YWx1ZSA9IG1hcmtTcGVjaWZpY0NvbmZpZ1tjaGFubmVsXTtcbiAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgPyB7W2NoYW5uZWxdOiB7dmFsdWV9fSA6IHt9O1xufVxuIl19 \ 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..90c18ab37f --- /dev/null +++ b/build/src/compositemark/errorbar.d.ts @@ -0,0 +1,6 @@ +import { Field } from '../fielddef'; +import { Encoding } from './../encoding'; +import { GenericUnitSpec, LayerSpec } from './../spec'; +export declare const ERRORBAR: 'error-bar'; +export declare type ERRORBAR = typeof ERRORBAR; +export declare function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): LayerSpec; diff --git a/build/src/compositemark/errorbar.js b/build/src/compositemark/errorbar.js new file mode 100644 index 0000000000..c0d33b4ead --- /dev/null +++ b/build/src/compositemark/errorbar.js @@ -0,0 +1,44 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ERRORBAR = 'error-bar'; +function normalizeErrorBar(spec) { + // TODO: use selection + var _m = spec.mark, _sel = spec.selection, encoding = spec.encoding, outerSpec = __rest(spec, ["mark", "selection", "encoding"]); + var _s = encoding.size, encodingWithoutSize = __rest(encoding, ["size"]); + var _x2 = encoding.x2, _y2 = encoding.y2, encodingWithoutX2Y2 = __rest(encoding, ["x2", "y2"]); + var _x = encodingWithoutX2Y2.x, _y = encodingWithoutX2Y2.y, 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) + } + ] }); +} +exports.normalizeErrorBar = normalizeErrorBar; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JiYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcG9zaXRlbWFyay9lcnJvcmJhci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBS2EsUUFBQSxRQUFRLEdBQWdCLFdBQVcsQ0FBQztBQUdqRCwyQkFBa0MsSUFBZ0Q7SUFDaEYsc0JBQXNCO0lBQ2YsSUFBQSxjQUFRLEVBQUUscUJBQWUsRUFBRSx3QkFBUSxFQUFFLDJEQUFZLENBQVM7SUFDMUQsSUFBQSxrQkFBUSxFQUFFLGdEQUFzQixDQUFhO0lBQzdDLElBQUEsaUJBQU8sRUFBRSxpQkFBTyxFQUFFLG9EQUFzQixDQUFhO0lBQ3JELElBQUEsMEJBQUssRUFBRSwwQkFBSyxFQUFFLGtFQUEyQixDQUF3QjtJQUV4RSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVELE1BQU0sY0FDRCxTQUFTLElBQ1osS0FBSyxFQUFFO1lBQ0w7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osUUFBUSxFQUFFLG1CQUFtQjthQUM5QixFQUFDO2dCQUNBLElBQUksRUFBRSxNQUFNO2dCQUNaLFFBQVEsRUFBRSxtQkFBbUI7YUFDOUIsRUFBRTtnQkFDRCxJQUFJLEVBQUUsTUFBTTtnQkFDWixRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFlBQ3JCLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBRSxFQUNkLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxJQUNWLHdCQUF3QixFQUMzQixDQUFDLFlBQ0QsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQ2IsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFFLElBQ1gsd0JBQXdCLENBQzVCO2FBQ0Y7U0FDRixJQUNEO0FBQ0osQ0FBQztBQWxDRCw4Q0FrQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0ZpZWxkfSBmcm9tICcuLi9maWVsZGRlZic7XG5pbXBvcnQge0VuY29kaW5nfSBmcm9tICcuLy4uL2VuY29kaW5nJztcbmltcG9ydCB7R2VuZXJpY1VuaXRTcGVjLCBMYXllclNwZWN9IGZyb20gJy4vLi4vc3BlYyc7XG5cblxuZXhwb3J0IGNvbnN0IEVSUk9SQkFSOiAnZXJyb3ItYmFyJyA9ICdlcnJvci1iYXInO1xuZXhwb3J0IHR5cGUgRVJST1JCQVIgPSB0eXBlb2YgRVJST1JCQVI7XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVFcnJvckJhcihzcGVjOiBHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8RmllbGQ+LCBFUlJPUkJBUj4pOiBMYXllclNwZWMge1xuICAvLyBUT0RPOiB1c2Ugc2VsZWN0aW9uXG4gIGNvbnN0IHttYXJrOiBfbSwgc2VsZWN0aW9uOiBfc2VsLCBlbmNvZGluZywgLi4ub3V0ZXJTcGVjfSA9IHNwZWM7XG4gIGNvbnN0IHtzaXplOiBfcywgLi4uZW5jb2RpbmdXaXRob3V0U2l6ZX0gPSBlbmNvZGluZztcbiAgY29uc3Qge3gyOiBfeDIsIHkyOiBfeTIsIC4uLmVuY29kaW5nV2l0aG91dFgyWTJ9ID0gZW5jb2Rpbmc7XG4gIGNvbnN0IHt4OiBfeCwgeTogX3ksIC4uLmVuY29kaW5nV2l0aG91dFhfWDJfWV9ZMn0gPSBlbmNvZGluZ1dpdGhvdXRYMlkyO1xuXG4gIGlmICghZW5jb2RpbmcueDIgJiYgIWVuY29kaW5nLnkyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdOZWl0aGVyIHgyIG9yIHkyIHByb3ZpZGVkJyk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLm91dGVyU3BlYyxcbiAgICBsYXllcjogW1xuICAgICAge1xuICAgICAgICBtYXJrOiAncnVsZScsXG4gICAgICAgIGVuY29kaW5nOiBlbmNvZGluZ1dpdGhvdXRTaXplXG4gICAgICB9LHsgLy8gTG93ZXIgdGlja1xuICAgICAgICBtYXJrOiAndGljaycsXG4gICAgICAgIGVuY29kaW5nOiBlbmNvZGluZ1dpdGhvdXRYMlkyXG4gICAgICB9LCB7IC8vIFVwcGVyIHRpY2tcbiAgICAgICAgbWFyazogJ3RpY2snLFxuICAgICAgICBlbmNvZGluZzogZW5jb2RpbmcueDIgPyB7XG4gICAgICAgICAgeDogZW5jb2RpbmcueDIsXG4gICAgICAgICAgeTogZW5jb2RpbmcueSxcbiAgICAgICAgICAuLi5lbmNvZGluZ1dpdGhvdXRYX1gyX1lfWTJcbiAgICAgICAgfSA6IHtcbiAgICAgICAgICB4OiBlbmNvZGluZy54LFxuICAgICAgICAgIHk6IGVuY29kaW5nLnkyLFxuICAgICAgICAgIC4uLmVuY29kaW5nV2l0aG91dFhfWDJfWV9ZMlxuICAgICAgICB9XG4gICAgICB9XG4gICAgXVxuICB9O1xufVxuIl19 \ 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..085b6d6370 --- /dev/null +++ b/build/src/compositemark/index.d.ts @@ -0,0 +1,25 @@ +import { Config } from './../config'; +import { AnyMark } from './../mark'; +import { GenericUnitSpec, LayerSpec } from './../spec'; +import { BOXPLOT, BoxPlotConfigMixins, BoxPlotDef } from './boxplot'; +import { ERRORBAR } from './errorbar'; +export { BoxPlotConfig } from './boxplot'; +export declare type UnitNormalizer = (spec: GenericUnitSpec, config: Config) => LayerSpec; +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: ("box" | "boxWhisker" | "boxMid")[]; +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?: ("font" | "text" | "color" | "opacity" | "size" | "shape" | "interpolate" | "stroke" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "fill" | "fillOpacity" | "filled" | "orient" | "tension" | "align" | "angle" | "baseline" | "dx" | "dy" | "radius" | "limit" | "theta" | "fontSize" | "fontStyle" | "fontWeight")[]; + boxWhisker?: ("font" | "text" | "color" | "opacity" | "size" | "shape" | "interpolate" | "stroke" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "fill" | "fillOpacity" | "filled" | "orient" | "tension" | "align" | "angle" | "baseline" | "dx" | "dy" | "radius" | "limit" | "theta" | "fontSize" | "fontStyle" | "fontWeight")[]; + boxMid?: ("font" | "text" | "color" | "opacity" | "size" | "shape" | "interpolate" | "stroke" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "fill" | "fillOpacity" | "filled" | "orient" | "tension" | "align" | "angle" | "baseline" | "dx" | "dy" | "radius" | "limit" | "theta" | "fontSize" | "fontStyle" | "fontWeight")[]; +}; +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +export declare function normalize(spec: GenericUnitSpec, config: Config): LayerSpec; diff --git a/build/src/compositemark/index.js b/build/src/compositemark/index.js new file mode 100644 index 0000000000..420b6b0b3e --- /dev/null +++ b/build/src/compositemark/index.js @@ -0,0 +1,44 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mark_1 = require("./../mark"); +var boxplot_1 = require("./boxplot"); +var errorbar_1 = require("./errorbar"); +/** + * Registry index for all composite mark's normalizer + */ +var normalizerRegistry = {}; +function add(mark, normalizer) { + normalizerRegistry[mark] = normalizer; +} +exports.add = add; +function remove(mark) { + delete normalizerRegistry[mark]; +} +exports.remove = remove; +exports.COMPOSITE_MARK_STYLES = boxplot_1.BOXPLOT_STYLES; +exports.VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = __assign({}, boxplot_1.VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX); +add(boxplot_1.BOXPLOT, boxplot_1.normalizeBoxPlot); +add(errorbar_1.ERRORBAR, errorbar_1.normalizeErrorBar); +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +function normalize( + // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels. + spec, config) { + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var normalizer = normalizerRegistry[mark]; + if (normalizer) { + return normalizer(spec, config); + } + throw new Error("Unregistered composite mark " + mark); +} +exports.normalize = normalize; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcG9zaXRlbWFyay9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQ0Esa0NBQTZDO0FBRTdDLHFDQUE0STtBQUM1SSx1Q0FBdUQ7QUFNdkQ7O0dBRUc7QUFDSCxJQUFNLGtCQUFrQixHQUFxQyxFQUFFLENBQUM7QUFFaEUsYUFBb0IsSUFBWSxFQUFFLFVBQTBCO0lBQzFELGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQztBQUN4QyxDQUFDO0FBRkQsa0JBRUM7QUFFRCxnQkFBdUIsSUFBWTtJQUNqQyxPQUFPLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xDLENBQUM7QUFGRCx3QkFFQztBQVFZLFFBQUEscUJBQXFCLEdBQUcsd0JBQWMsQ0FBQztBQUt2QyxRQUFBLHFEQUFxRCxnQkFDN0QsK0NBQXFDLEVBQ3hDO0FBRUYsR0FBRyxDQUFDLGlCQUFPLEVBQUUsMEJBQWdCLENBQUMsQ0FBQztBQUMvQixHQUFHLENBQUMsbUJBQVEsRUFBRSw0QkFBaUIsQ0FBQyxDQUFDO0FBRWpDOztHQUVHO0FBQ0g7SUFDSSx5SEFBeUg7SUFDekgsSUFBbUMsRUFDbkMsTUFBYztJQUdoQixJQUFNLElBQUksR0FBRyxnQkFBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDL0QsSUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNmLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUErQixJQUFNLENBQUMsQ0FBQztBQUN6RCxDQUFDO0FBYkQsOEJBYUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbmZpZ30gZnJvbSAnLi8uLi9jb25maWcnO1xuaW1wb3J0IHtBbnlNYXJrLCBpc01hcmtEZWZ9IGZyb20gJy4vLi4vbWFyayc7XG5pbXBvcnQge0dlbmVyaWNVbml0U3BlYywgTGF5ZXJTcGVjfSBmcm9tICcuLy4uL3NwZWMnO1xuaW1wb3J0IHtCT1hQTE9ULCBCT1hQTE9UX1NUWUxFUywgQm94UGxvdENvbmZpZ01peGlucywgQm94UGxvdERlZiwgbm9ybWFsaXplQm94UGxvdCwgVkxfT05MWV9CT1hQTE9UX0NPTkZJR19QUk9QRVJUWV9JTkRFWH0gZnJvbSAnLi9ib3hwbG90JztcbmltcG9ydCB7RVJST1JCQVIsIG5vcm1hbGl6ZUVycm9yQmFyfSBmcm9tICcuL2Vycm9yYmFyJztcblxuXG5leHBvcnQge0JveFBsb3RDb25maWd9IGZyb20gJy4vYm94cGxvdCc7XG5leHBvcnQgdHlwZSBVbml0Tm9ybWFsaXplciA9IChzcGVjOiBHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+LCBjb25maWc6IENvbmZpZyk9PiBMYXllclNwZWM7XG5cbi8qKlxuICogUmVnaXN0cnkgaW5kZXggZm9yIGFsbCBjb21wb3NpdGUgbWFyaydzIG5vcm1hbGl6ZXJcbiAqL1xuY29uc3Qgbm9ybWFsaXplclJlZ2lzdHJ5OiB7W21hcms6IHN0cmluZ106IFVuaXROb3JtYWxpemVyfSA9IHt9O1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG1hcms6IHN0cmluZywgbm9ybWFsaXplcjogVW5pdE5vcm1hbGl6ZXIpIHtcbiAgbm9ybWFsaXplclJlZ2lzdHJ5W21hcmtdID0gbm9ybWFsaXplcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZShtYXJrOiBzdHJpbmcpIHtcbiAgZGVsZXRlIG5vcm1hbGl6ZXJSZWdpc3RyeVttYXJrXTtcbn1cblxuZXhwb3J0IHR5cGUgQ29tcG9zaXRlTWFyayA9IEJPWFBMT1QgfCBFUlJPUkJBUjtcblxuZXhwb3J0IHR5cGUgQ29tcG9zaXRlTWFya0RlZiA9IEJveFBsb3REZWY7XG5cbmV4cG9ydCB0eXBlIENvbXBvc2l0ZUFnZ3JlZ2F0ZSA9IEJPWFBMT1Q7XG5cbmV4cG9ydCBjb25zdCBDT01QT1NJVEVfTUFSS19TVFlMRVMgPSBCT1hQTE9UX1NUWUxFUztcbmV4cG9ydCB0eXBlIENvbXBvc2l0ZU1hcmtTdHlsZSA9IHR5cGVvZiBDT01QT1NJVEVfTUFSS19TVFlMRVNbMF07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9zaXRlTWFya0NvbmZpZ01peGlucyBleHRlbmRzIEJveFBsb3RDb25maWdNaXhpbnMge31cblxuZXhwb3J0IGNvbnN0IFZMX09OTFlfQ09NUE9TSVRFX01BUktfU1BFQ0lGSUNfQ09ORklHX1BST1BFUlRZX0lOREVYID0ge1xuICAuLi5WTF9PTkxZX0JPWFBMT1RfQ09ORklHX1BST1BFUlRZX0lOREVYXG59O1xuXG5hZGQoQk9YUExPVCwgbm9ybWFsaXplQm94UGxvdCk7XG5hZGQoRVJST1JCQVIsIG5vcm1hbGl6ZUVycm9yQmFyKTtcblxuLyoqXG4gKiBUcmFuc2Zvcm0gYSB1bml0IHNwZWMgd2l0aCBjb21wb3NpdGUgbWFyayBpbnRvIGEgbm9ybWFsIGxheWVyIHNwZWMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUoXG4gICAgLy8gVGhpcyBHZW5lcmljVW5pdFNwZWMgaGFzIGFueSBhcyBFbmNvZGluZyBiZWNhdXNlIHVuaXQgc3BlY3Mgd2l0aCBjb21wb3NpdGUgbWFyayBjYW4gaGF2ZSBhZGRpdGlvbmFsIGVuY29kaW5nIGNoYW5uZWxzLlxuICAgIHNwZWM6IEdlbmVyaWNVbml0U3BlYzxhbnksIEFueU1hcms+LFxuICAgIGNvbmZpZzogQ29uZmlnXG4gICk6IExheWVyU3BlYyB7XG5cbiAgY29uc3QgbWFyayA9IGlzTWFya0RlZihzcGVjLm1hcmspID8gc3BlYy5tYXJrLnR5cGUgOiBzcGVjLm1hcms7XG4gIGNvbnN0IG5vcm1hbGl6ZXIgPSBub3JtYWxpemVyUmVnaXN0cnlbbWFya107XG4gIGlmIChub3JtYWxpemVyKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZXIoc3BlYywgY29uZmlnKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5yZWdpc3RlcmVkIGNvbXBvc2l0ZSBtYXJrICR7bWFya31gKTtcbn1cbiJdfQ== \ 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..67d53a831e --- /dev/null +++ b/build/src/config.d.ts @@ -0,0 +1,191 @@ +import { AxisConfigMixins } from './axis'; +import { CompositeMarkConfigMixins } from './compositemark/index'; +import { LegendConfig } from './legend'; +import { MarkConfigMixins } from './mark'; +import { ScaleConfig } from './scale'; +import { SelectionConfig } from './selection'; +import { StackOffset } from './stack'; +import { TopLevelProperties } from './toplevelprops'; +import { 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; +} +export declare const defaultViewConfig: ViewConfig; +export declare type RangeConfigValue = (number | string)[] | VgScheme | { + step: number; +}; +export interface RangeConfig { + /** + * 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[]; + [name: string]: RangeConfigValue; +} +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 are filtered. + * - 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:__ `'%b %d, %Y'`. + * + */ + timeFormat?: string; + /** Default properties for [single view plots](spec.html#single). */ + view?: ViewConfig; + /** + * Scale configuration determines default properties for all [scales](scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](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 declare type AreaOverlay = 'line' | 'linepoint' | 'none'; +export interface OverlayConfig { + /** + * Whether to overlay line with point. + */ + line?: boolean; + /** + * Type of overlay for area mark (line or linepoint) + */ + area?: AreaOverlay; +} +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](scale.html#config). + */ + range?: RangeConfig; + /** + * Legend configuration, which determines default properties for all [legends](legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](legend.html#config). + */ + legend?: LegendConfig; + /** + * Title configuration, which determines default properties for all [titles](title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](title.html#config). + */ + title?: VgTitleConfig; + /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](mark.html#mark-def). The keys represent styles names; the value are valid [mark configuration objects](mark.html#config). */ + style?: StyleConfigIndex; + /** + * @hide + */ + overlay?: OverlayConfig; +} +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..ba142f0a23 --- /dev/null +++ b/build/src/config.js @@ -0,0 +1,140 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var compositemark_1 = require("./compositemark"); +var index_1 = require("./compositemark/index"); +var guide_1 = require("./guide"); +var legend_1 = require("./legend"); +var mark_1 = require("./mark"); +var mark = require("./mark"); +var scale_1 = require("./scale"); +var selection_1 = require("./selection"); +var title_1 = require("./title"); +var util_1 = require("./util"); +exports.defaultViewConfig = { + width: 200, + height: 200 +}; +exports.defaultConfig = { + padding: 5, + timeFormat: '%b %d, %Y', + countTitle: 'Number of Records', + invalidValues: 'filter', + view: exports.defaultViewConfig, + mark: mark.defaultMarkConfig, + area: {}, + bar: mark.defaultBarConfig, + circle: {}, + line: {}, + point: {}, + rect: {}, + rule: { color: 'black' }, + square: {}, + text: { color: 'black' }, + tick: mark.defaultTickConfig, + box: { size: 14 }, + boxWhisker: {}, + boxMid: { color: 'white' }, + scale: scale_1.defaultScaleConfig, + axis: {}, + axisX: {}, + axisY: { minExtent: 30 }, + axisLeft: {}, + axisRight: {}, + axisTop: {}, + axisBottom: {}, + axisBand: {}, + legend: legend_1.defaultLegendConfig, + selection: selection_1.defaultConfig, + style: {}, + title: {}, +}; +function initConfig(config) { + return util_1.mergeDeep(util_1.duplicate(exports.defaultConfig), config); +} +exports.initConfig = initConfig; +var MARK_STYLES = ['view'].concat(mark_1.PRIMITIVE_MARKS, compositemark_1.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'] }, mark_1.VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX, index_1.VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX); +function stripAndRedirectConfig(config) { + config = util_1.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 = guide_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 = guide_1.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 = mark_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 mark_2 = MARK_STYLES_1[_d]; + // Remove Vega-Lite-only mark config + for (var _e = 0, VL_ONLY_MARK_CONFIG_PROPERTIES_2 = mark_1.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[mark_2][prop]; + } + // Remove Vega-Lite only mark-specific config + var vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[mark_2]; + if (vlOnlyMarkSpecificConfigs) { + for (var _f = 0, vlOnlyMarkSpecificConfigs_1 = vlOnlyMarkSpecificConfigs; _f < vlOnlyMarkSpecificConfigs_1.length; _f++) { + var prop = vlOnlyMarkSpecificConfigs_1[_f]; + delete config[mark_2][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, mark_2); + } + // 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 (util_1.isObject(config[prop]) && util_1.keys(config[prop]).length === 0) { + delete config[prop]; + } + } + return util_1.keys(config).length > 0 ? config : undefined; +} +exports.stripAndRedirectConfig = stripAndRedirectConfig; +function redirectConfig(config, prop, toProp) { + var propConfig = prop === 'title' ? title_1.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 (util_1.keys(style).length > 0) { + config.style[toProp || prop] = style; + } + delete config[prop]; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQ0EsaURBQXNEO0FBQ3RELCtDQUEySTtBQUMzSSxpQ0FBNkM7QUFDN0MsbUNBQTJEO0FBQzNELCtCQUE0STtBQUM1SSw2QkFBK0I7QUFDL0IsaUNBQXdEO0FBQ3hELHlDQUFxRjtBQUVyRixpQ0FBMkM7QUFFM0MsK0JBQTREO0FBb0YvQyxRQUFBLGlCQUFpQixHQUFlO0lBQzNDLEtBQUssRUFBRSxHQUFHO0lBQ1YsTUFBTSxFQUFFLEdBQUc7Q0FDWixDQUFDO0FBeUlXLFFBQUEsYUFBYSxHQUFXO0lBQ25DLE9BQU8sRUFBRSxDQUFDO0lBQ1YsVUFBVSxFQUFFLFdBQVc7SUFDdkIsVUFBVSxFQUFFLG1CQUFtQjtJQUUvQixhQUFhLEVBQUUsUUFBUTtJQUV2QixJQUFJLEVBQUUseUJBQWlCO0lBRXZCLElBQUksRUFBRSxJQUFJLENBQUMsaUJBQWlCO0lBQzVCLElBQUksRUFBRSxFQUFFO0lBQ1IsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7SUFDMUIsTUFBTSxFQUFFLEVBQUU7SUFDVixJQUFJLEVBQUUsRUFBRTtJQUNSLEtBQUssRUFBRSxFQUFFO0lBQ1QsSUFBSSxFQUFFLEVBQUU7SUFDUixJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFDO0lBQ3RCLE1BQU0sRUFBRSxFQUFFO0lBQ1YsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQztJQUN0QixJQUFJLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjtJQUU1QixHQUFHLEVBQUUsRUFBQyxJQUFJLEVBQUUsRUFBRSxFQUFDO0lBQ2YsVUFBVSxFQUFFLEVBQUU7SUFDZCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFDO0lBRXhCLEtBQUssRUFBRSwwQkFBa0I7SUFDekIsSUFBSSxFQUFFLEVBQUU7SUFDUixL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QUksQ0FBQyxDQUFDO0lBRXpHLEVBQUUsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxpQ0FBaUM7SUFDcEQsQ0FBQztJQUVELElBQU0sS0FBSyxnQkFDTixVQUFVLEVBQ1YsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FDdEIsQ0FBQztJQUNGLGdEQUFnRDtJQUNoRCxFQUFFLENBQUMsQ0FBQyxXQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3ZDLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBeGlzQ29uZmlnTWl4aW5zfSBmcm9tICcuL2F4aXMnO1xuaW1wb3J0IHtDT01QT1NJVEVfTUFSS19TVFlMRVN9IGZyb20gJy4vY29tcG9zaXRlbWFyayc7XG5pbXBvcnQge0NvbXBvc2l0ZU1hcmtDb25maWdNaXhpbnMsIENvbXBvc2l0ZU1hcmtTdHlsZSwgVkxfT05MWV9DT01QT1NJVEVfTUFSS19TUEVDSUZJQ19DT05GSUdfUFJPUEVSVFlfSU5ERVh9IGZyb20gJy4vY29tcG9zaXRlbWFyay9pbmRleCc7XG5pbXBvcnQge1ZMX09OTFlfR1VJREVfQ09ORklHfSBmcm9tICcuL2d1aWRlJztcbmltcG9ydCB7ZGVmYXVsdExlZ2VuZENvbmZpZywgTGVnZW5kQ29uZmlnfSBmcm9tICcuL2xlZ2VuZCc7XG5pbXBvcnQge01hcmssIE1hcmtDb25maWdNaXhpbnMsIFBSSU1JVElWRV9NQVJLUywgVkxfT05MWV9NQVJLX0NPTkZJR19QUk9QRVJUSUVTLCBWTF9PTkxZX01BUktfU1BFQ0lGSUNfQ09ORklHX1BST1BFUlRZX0lOREVYfSBmcm9tICcuL21hcmsnO1xuaW1wb3J0ICogYXMgbWFyayBmcm9tICcuL21hcmsnO1xuaW1wb3J0IHtkZWZhdWx0U2NhbGVDb25maWcsIFNjYWxlQ29uZmlnfSBmcm9tICcuL3NjYWxlJztcbmltcG9ydCB7ZGVmYXVsdENvbmZpZyBhcyBkZWZhdWx0U2VsZWN0aW9uQ29uZmlnLCBTZWxlY3Rpb25Db25maWd9IGZyb20gJy4vc2VsZWN0aW9uJztcbmltcG9ydCB7U3RhY2tPZmZzZXR9IGZyb20gJy4vc3RhY2snO1xuaW1wb3J0IHtleHRyYWN0VGl0bGVDb25maWd9IGZyb20gJy4vdGl0bGUnO1xuaW1wb3J0IHtUb3BMZXZlbFByb3BlcnRpZXN9IGZyb20gJy4vdG9wbGV2ZWxwcm9wcyc7XG5pbXBvcnQge2R1cGxpY2F0ZSwgaXNPYmplY3QsIGtleXMsIG1lcmdlRGVlcH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7VmdNYXJrQ29uZmlnLCBWZ1NjaGVtZSwgVmdUaXRsZUNvbmZpZ30gZnJvbSAnLi92ZWdhLnNjaGVtYSc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBWaWV3Q29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IHdpZHRoIG9mIHRoZSBzaW5nbGUgcGxvdCBvciBlYWNoIHBsb3QgaW4gYSB0cmVsbGlzIHBsb3Qgd2hlbiB0aGUgdmlzdWFsaXphdGlvbiBoYXMgYSBjb250aW51b3VzIChub24tb3JkaW5hbCkgeC1zY2FsZSBvciBvcmRpbmFsIHgtc2NhbGUgd2l0aCBgcmFuZ2VTdGVwYCA9IGBudWxsYC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAyMDBgXG4gICAqXG4gICAqL1xuICB3aWR0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGRlZmF1bHQgaGVpZ2h0IG9mIHRoZSBzaW5nbGUgcGxvdCBvciBlYWNoIHBsb3QgaW4gYSB0cmVsbGlzIHBsb3Qgd2hlbiB0aGUgdmlzdWFsaXphdGlvbiBoYXMgYSBjb250aW51b3VzIChub24tb3JkaW5hbCkgeS1zY2FsZSB3aXRoIGByYW5nZVN0ZXBgID0gYG51bGxgLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDIwMGBcbiAgICpcbiAgICovXG4gIGhlaWdodD86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgdmlldyBzaG91bGQgYmUgY2xpcHBlZC5cbiAgICovXG4gIGNsaXA/OiBib29sZWFuO1xuXG4gIC8vIEZJTExfU1RST0tFX0NPTkZJR1xuICAvKipcbiAgICogVGhlIGZpbGwgY29sb3IuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAobm9uZSlcbiAgICpcbiAgICovXG4gIGZpbGw/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBmaWxsIG9wYWNpdHkgKHZhbHVlIGJldHdlZW4gWzAsMV0pLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gKG5vbmUpXG4gICAqXG4gICAqL1xuICBmaWxsT3BhY2l0eT86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHN0cm9rZSBjb2xvci5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIChub25lKVxuICAgKlxuICAgKi9cbiAgc3Ryb2tlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgc3Ryb2tlIG9wYWNpdHkgKHZhbHVlIGJldHdlZW4gWzAsMV0pLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gKG5vbmUpXG4gICAqXG4gICAqL1xuICBzdHJva2VPcGFjaXR5PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgc3Ryb2tlIHdpZHRoLCBpbiBwaXhlbHMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAobm9uZSlcbiAgICpcbiAgICovXG4gIHN0cm9rZVdpZHRoPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBhbHRlcm5hdGluZyBzdHJva2UsIHNwYWNlIGxlbmd0aHMgZm9yIGNyZWF0aW5nIGRhc2hlZCBvciBkb3R0ZWQgbGluZXMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAobm9uZSlcbiAgICpcbiAgICovXG4gIHN0cm9rZURhc2g/OiBudW1iZXJbXTtcblxuICAvKipcbiAgICogVGhlIG9mZnNldCAoaW4gcGl4ZWxzKSBpbnRvIHdoaWNoIHRvIGJlZ2luIGRyYXdpbmcgd2l0aCB0aGUgc3Ryb2tlIGRhc2ggYXJyYXkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAobm9uZSlcbiAgICpcbiAgICovXG4gIHN0cm9rZURhc2hPZmZzZXQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0Vmlld0NvbmZpZzogVmlld0NvbmZpZyA9IHtcbiAgd2lkdGg6IDIwMCxcbiAgaGVpZ2h0OiAyMDBcbn07XG5cbmV4cG9ydCB0eXBlIFJhbmdlQ29uZmlnVmFsdWUgPSAobnVtYmVyfHN0cmluZylbXSB8IFZnU2NoZW1lIHwge3N0ZXA6IG51bWJlcn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmFuZ2VDb25maWcge1xuICAvKipcbiAgICogRGVmYXVsdCByYW5nZSBmb3IgX25vbWluYWxfIChjYXRlZ29yaWNhbCkgZmllbGRzLlxuICAgKi9cbiAgY2F0ZWdvcnk/OiBzdHJpbmdbXSB8IFZnU2NoZW1lO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IHJhbmdlIGZvciBkaXZlcmdpbmcgX3F1YW50aXRhdGl2ZV8gZmllbGRzLlxuICAgKi9cbiAgZGl2ZXJnaW5nPzogc3RyaW5nW10gfCBWZ1NjaGVtZTtcblxuICAvKipcbiAgICogRGVmYXVsdCByYW5nZSBmb3IgX3F1YW50aXRhdGl2ZV8gaGVhdG1hcHMuXG4gICAqL1xuICBoZWF0bWFwPzogc3RyaW5nW10gfCBWZ1NjaGVtZTtcblxuICAvKipcbiAgICogRGVmYXVsdCByYW5nZSBmb3IgX29yZGluYWxfIGZpZWxkcy5cbiAgICovXG4gIG9yZGluYWw/OiBzdHJpbmdbXSB8IFZnU2NoZW1lO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IHJhbmdlIGZvciBfcXVhbnRpdGF0aXZlXyBhbmQgX3RlbXBvcmFsXyBmaWVsZHMuXG4gICAqL1xuICByYW1wPzogc3RyaW5nW10gfCBWZ1NjaGVtZTtcblxuICAvKipcbiAgICogRGVmYXVsdCByYW5nZSBwYWxldHRlIGZvciB0aGUgYHNoYXBlYCBjaGFubmVsLlxuICAgKi9cbiAgc3ltYm9sPzogc3RyaW5nW107XG5cbiAgW25hbWU6IHN0cmluZ106IFJhbmdlQ29uZmlnVmFsdWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVkxPbmx5Q29uZmlnIHtcbiAgLyoqXG4gICAqIERlZmF1bHQgYXhpcyBhbmQgbGVnZW5kIHRpdGxlIGZvciBjb3VudCBmaWVsZHMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgJ051bWJlciBvZiBSZWNvcmRzJ2AuXG4gICAqXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqL1xuICBjb3VudFRpdGxlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGhvdyBWZWdhLUxpdGUgc2hvdWxkIGhhbmRsZSBpbnZhbGlkIHZhbHVlcyAoYG51bGxgIGFuZCBgTmFOYCkuXG4gICAqIC0gSWYgc2V0IHRvIGBcImZpbHRlclwiYCAoZGVmYXVsdCksIGFsbCBkYXRhIGl0ZW1zIHdpdGggbnVsbCB2YWx1ZXMgYXJlIGZpbHRlcmVkLlxuICAgKiAtIElmIGBudWxsYCwgYWxsIGRhdGEgaXRlbXMgYXJlIGluY2x1ZGVkLiBJbiB0aGlzIGNhc2UsIGludmFsaWQgdmFsdWVzIHdpbGwgYmUgaW50ZXJwcmV0ZWQgYXMgemVyb2VzLlxuICAgKi9cbiAgaW52YWxpZFZhbHVlcz86ICdmaWx0ZXInIHwgbnVsbDtcblxuICAvKipcbiAgICogRGVmaW5lcyBob3cgVmVnYS1MaXRlIGdlbmVyYXRlcyB0aXRsZSBmb3IgZmllbGRzLiAgVGhlcmUgYXJlIHRocmVlIHBvc3NpYmxlIHN0eWxlczpcbiAgICogLSBgXCJ2ZXJiYWxcImAgKERlZmF1bHQpIC0gZGlzcGxheXMgZnVuY3Rpb24gaW4gYSB2ZXJiYWwgc3R5bGUgKGUuZy4sIFwiU3VtIG9mIGZpZWxkXCIsIFwiWWVhci1tb250aCBvZiBkYXRlXCIsIFwiZmllbGQgKGJpbm5lZClcIikuXG4gICAqIC0gYFwiZnVuY3Rpb25cImAgLSBkaXNwbGF5cyBmdW5jdGlvbiB1c2luZyBwYXJlbnRoZXNlcyBhbmQgY2FwaXRhbGl6ZWQgdGV4dHMgKGUuZy4sIFwiU1VNKGZpZWxkKVwiLCBcIllFQVJNT05USChkYXRlKVwiLCBcIkJJTihmaWVsZClcIikuXG4gICAqIC0gYFwicGxhaW5cImAgLSBkaXNwbGF5cyBvbmx5IHRoZSBmaWVsZCBuYW1lIHdpdGhvdXQgZnVuY3Rpb25zIChlLmcuLCBcImZpZWxkXCIsIFwiZGF0ZVwiLCBcImZpZWxkXCIpLlxuICAgKi9cbiAgZmllbGRUaXRsZT86ICd2ZXJiYWwnIHwgJ2Z1bmN0aW9uYWwnIHwgJ3BsYWluJztcblxuICAvKipcbiAgICogRDMgTnVtYmVyIGZvcm1hdCBmb3IgYXhpcyBsYWJlbHMgYW5kIHRleHQgdGFibGVzLiBGb3IgZXhhbXBsZSBcInNcIiBmb3IgU0kgdW5pdHMuIFVzZSBbRDMncyBudW1iZXIgZm9ybWF0IHBhdHRlcm5dKGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1mb3JtYXQjbG9jYWxlX2Zvcm1hdCkuXG4gICAqL1xuICBudW1iZXJGb3JtYXQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgZGF0ZXRpbWUgZm9ybWF0IGZvciBheGlzIGFuZCBsZWdlbmQgbGFiZWxzLiBUaGUgZm9ybWF0IGNhbiBiZSBzZXQgZGlyZWN0bHkgb24gZWFjaCBheGlzIGFuZCBsZWdlbmQuIFVzZSBbRDMncyB0aW1lIGZvcm1hdCBwYXR0ZXJuXShodHRwczovL2dpdGh1Yi5jb20vZDMvZDMtdGltZS1mb3JtYXQjbG9jYWxlX2Zvcm1hdCkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgJyViICVkLCAlWSdgLlxuICAgKlxuICAgKi9cbiAgdGltZUZvcm1hdD86IHN0cmluZztcblxuXG4gIC8qKiBEZWZhdWx0IHByb3BlcnRpZXMgZm9yIFtzaW5nbGUgdmlldyBwbG90c10oc3BlYy5odG1sI3NpbmdsZSkuICovXG4gIHZpZXc/OiBWaWV3Q29uZmlnO1xuXG4gIC8qKlxuICAgKiBTY2FsZSBjb25maWd1cmF0aW9uIGRldGVybWluZXMgZGVmYXVsdCBwcm9wZXJ0aWVzIGZvciBhbGwgW3NjYWxlc10oc2NhbGUuaHRtbCkuIEZvciBhIGZ1bGwgbGlzdCBvZiBzY2FsZSBjb25maWd1cmF0aW9uIG9wdGlvbnMsIHBsZWFzZSBzZWUgdGhlIFtjb3JyZXNwb25kaW5nIHNlY3Rpb24gb2YgdGhlIHNjYWxlIGRvY3VtZW50YXRpb25dKHNjYWxlLmh0bWwjY29uZmlnKS5cbiAgICovXG4gIHNjYWxlPzogU2NhbGVDb25maWc7XG5cbiAgLyoqIEFuIG9iamVjdCBoYXNoIGZvciBkZWZpbmluZyBkZWZhdWx0IHByb3BlcnRpZXMgZm9yIGVhY2ggdHlwZSBvZiBzZWxlY3Rpb25zLiAqL1xuICBzZWxlY3Rpb24/OiBTZWxlY3Rpb25Db25maWc7XG5cbiAgLyoqIERlZmF1bHQgc3RhY2sgb2Zmc2V0IGZvciBzdGFja2FibGUgbWFyay4gKi9cbiAgc3RhY2s/OiBTdGFja09mZnNldDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdHlsZUNvbmZpZ0luZGV4IHtcbiAgW3N0eWxlOiBzdHJpbmddOiBWZ01hcmtDb25maWc7XG59XG5cbmV4cG9ydCB0eXBlIEFyZWFPdmVybGF5ID0gJ2xpbmUnIHwgJ2xpbmVwb2ludCcgfCAnbm9uZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheUNvbmZpZyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIG92ZXJsYXkgbGluZSB3aXRoIHBvaW50LlxuICAgKi9cbiAgbGluZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFR5cGUgb2Ygb3ZlcmxheSBmb3IgYXJlYSBtYXJrIChsaW5lIG9yIGxpbmVwb2ludClcbiAgICovXG4gIGFyZWE/OiBBcmVhT3ZlcmxheTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25maWcgZXh0ZW5kcyBUb3BMZXZlbFByb3BlcnRpZXMsIFZMT25seUNvbmZpZywgTWFya0NvbmZpZ01peGlucywgQ29tcG9zaXRlTWFya0NvbmZpZ01peGlucywgQXhpc0NvbmZpZ01peGlucyB7XG5cbiAgLyoqXG4gICAqIEFuIG9iamVjdCBoYXNoIHRoYXQgZGVmaW5lcyBkZWZhdWx0IHJhbmdlIGFycmF5cyBvciBzY2hlbWVzIGZvciB1c2luZyB3aXRoIHNjYWxlcy5cbiAgICogRm9yIGEgZnVsbCBsaXN0IG9mIHNjYWxlIHJhbmdlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucywgcGxlYXNlIHNlZSB0aGUgW2NvcnJlc3BvbmRpbmcgc2VjdGlvbiBvZiB0aGUgc2NhbGUgZG9jdW1lbnRhdGlvbl0oc2NhbGUuaHRtbCNjb25maWcpLlxuICAgKi9cbiAgcmFuZ2U/OiBSYW5nZUNvbmZpZztcblxuICAvKipcbiAgICogTGVnZW5kIGNvbmZpZ3VyYXRpb24sIHdoaWNoIGRldGVybWluZXMgZGVmYXVsdCBwcm9wZXJ0aWVzIGZvciBhbGwgW2xlZ2VuZHNdKGxlZ2VuZC5odG1sKS4gRm9yIGEgZnVsbCBsaXN0IG9mIGxlZ2VuZCBjb25maWd1cmF0aW9uIG9wdGlvbnMsIHBsZWFzZSBzZWUgdGhlIFtjb3JyZXNwb25kaW5nIHNlY3Rpb24gb2YgaW4gdGhlIGxlZ2VuZCBkb2N1bWVudGF0aW9uXShsZWdlbmQuaHRtbCNjb25maWcpLlxuICAgKi9cbiAgbGVnZW5kPzogTGVnZW5kQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBUaXRsZSBjb25maWd1cmF0aW9uLCB3aGljaCBkZXRlcm1pbmVzIGRlZmF1bHQgcHJvcGVydGllcyBmb3IgYWxsIFt0aXRsZXNdKHRpdGxlLmh0bWwpLiBGb3IgYSBmdWxsIGxpc3Qgb2YgdGl0bGUgY29uZmlndXJhdGlvbiBvcHRpb25zLCBwbGVhc2Ugc2VlIHRoZSBbY29ycmVzcG9uZGluZyBzZWN0aW9uIG9mIHRoZSB0aXRsZSBkb2N1bWVudGF0aW9uXSh0aXRsZS5odG1sI2NvbmZpZykuXG4gICAqL1xuICB0aXRsZT86IFZnVGl0bGVDb25maWc7XG5cbiAgLyoqIEFuIG9iamVjdCBoYXNoIHRoYXQgZGVmaW5lcyBrZXktdmFsdWUgbWFwcGluZ3MgdG8gZGV0ZXJtaW5lIGRlZmF1bHQgcHJvcGVydGllcyBmb3IgbWFya3Mgd2l0aCBhIGdpdmVuIFtzdHlsZV0obWFyay5odG1sI21hcmstZGVmKS4gIFRoZSBrZXlzIHJlcHJlc2VudCBzdHlsZXMgbmFtZXM7IHRoZSB2YWx1ZSBhcmUgdmFsaWQgW21hcmsgY29uZmlndXJhdGlvbiBvYmplY3RzXShtYXJrLmh0bWwjY29uZmlnKS4gICovXG4gIHN0eWxlPzogU3R5bGVDb25maWdJbmRleDtcblxuICAvKipcbiAgICogQGhpZGVcbiAgICovXG4gIG92ZXJsYXk/OiBPdmVybGF5Q29uZmlnO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdENvbmZpZzogQ29uZmlnID0ge1xuICBwYWRkaW5nOiA1LFxuICB0aW1lRm9ybWF0OiAnJWIgJWQsICVZJyxcbiAgY291bnRUaXRsZTogJ051bWJlciBvZiBSZWNvcmRzJyxcblxuICBpbnZhbGlkVmFsdWVzOiAnZmlsdGVyJyxcblxuICB2aWV3OiBkZWZhdWx0Vmlld0NvbmZpZyxcblxuICBtYXJrOiBtYXJrLmRlZmF1bHRNYXJrQ29uZmlnLFxuICBhcmVhOiB7fSxcbiAgYmFyOiBtYXJrLmRlZmF1bHRCYXJDb25maWcsXG4gIGNpcmNsZToge30sXG4gIGxpbmU6IHt9LFxuICBwb2ludDoge30sXG4gIHJlY3Q6IHt9LFxuICBydWxlOiB7Y29sb3I6ICdibGFjayd9LCAvLyBOZWVkIHRoaXMgdG8gb3ZlcnJpZGUgZGVmYXVsdCBjb2xvciBpbiBtYXJrIGNvbmZpZ1xuICBzcXVhcmU6IHt9LFxuICB0ZXh0OiB7Y29sb3I6ICdibGFjayd9LCAvLyBOZWVkIHRoaXMgdG8gb3ZlcnJpZGUgZGVmYXVsdCBjb2xvciBpbiBtYXJrIGNvbmZpZ1xuICB0aWNrOiBtYXJrLmRlZmF1bHRUaWNrQ29uZmlnLFxuXG4gIGJveDoge3NpemU6IDE0fSxcbiAgYm94V2hpc2tlcjoge30sXG4gIGJveE1pZDoge2NvbG9yOiAnd2hpdGUnfSxcblxuICBzY2FsZTogZGVmYXVsdFNjYWxlQ29uZmlnLFxuICBheGlzOiB7fSxcbiAgYXhpc1g6IHt9LFxuICBheGlzWToge21pbkV4dGVudDogMzB9LFxuICBheGlzTGVmdDoge30sXG4gIGF4aXNSaWdodDoge30sXG4gIGF4aXNUb3A6IHt9LFxuICBheGlzQm90dG9tOiB7fSxcbiAgYXhpc0JhbmQ6IHt9LFxuICBsZWdlbmQ6IGRlZmF1bHRMZWdlbmRDb25maWcsXG5cbiAgc2VsZWN0aW9uOiBkZWZhdWx0U2VsZWN0aW9uQ29uZmlnLFxuICBzdHlsZToge30sXG5cbiAgdGl0bGU6IHt9LFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRDb25maWcoY29uZmlnOiBDb25maWcpIHtcbiAgcmV0dXJuIG1lcmdlRGVlcChkdXBsaWNhdGUoZGVmYXVsdENvbmZpZyksIGNvbmZpZyk7XG59XG5cbmNvbnN0IE1BUktfU1RZTEVTID0gWyd2aWV3J10uY29uY2F0KFBSSU1JVElWRV9NQVJLUywgQ09NUE9TSVRFX01BUktfU1RZTEVTKSBhcyAoJ3ZpZXcnIHwgTWFyayB8IENvbXBvc2l0ZU1hcmtTdHlsZSlbXTtcblxuXG5jb25zdCBWTF9PTkxZX0NPTkZJR19QUk9QRVJUSUVTOiAoa2V5b2YgQ29uZmlnKVtdID0gW1xuICAncGFkZGluZycsICdudW1iZXJGb3JtYXQnLCAndGltZUZvcm1hdCcsICdjb3VudFRpdGxlJyxcbiAgJ3N0YWNrJywgJ3NjYWxlJywgJ3NlbGVjdGlvbicsICdpbnZhbGlkVmFsdWVzJyxcbiAgJ292ZXJsYXknIGFzIGtleW9mIENvbmZpZyAvLyBGSVhNRTogUmVkZXNpZ24gYW5kIHVuaGlkZSB0aGlzXG5dO1xuXG5jb25zdCBWTF9PTkxZX0FMTF9NQVJLX1NQRUNJRklDX0NPTkZJR19QUk9QRVJUWV9JTkRFWCA9IHtcbiAgdmlldzogWyd3aWR0aCcsICdoZWlnaHQnXSxcbiAgLi4uVkxfT05MWV9NQVJLX1NQRUNJRklDX0NPTkZJR19QUk9QRVJUWV9JTkRFWCxcbiAgLi4uVkxfT05MWV9DT01QT1NJVEVfTUFSS19TUEVDSUZJQ19DT05GSUdfUFJPUEVSVFlfSU5ERVhcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJpcEFuZFJlZGlyZWN0Q29uZmlnKGNvbmZpZzogQ29uZmlnKSB7XG4gIGNvbmZpZyA9IGR1cGxpY2F0ZShjb25maWcpO1xuXG4gIGZvciAoY29uc3QgcHJvcCBvZiBWTF9PTkxZX0NPTkZJR19QUk9QRVJUSUVTKSB7XG4gICAgZGVsZXRlIGNvbmZpZ1twcm9wXTtcbiAgfVxuXG4gIC8vIFJlbW92ZSBWZWdhLUxpdGUgb25seSBheGlzL2xlZ2VuZCBjb25maWdcbiAgaWYgKGNvbmZpZy5heGlzKSB7XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIFZMX09OTFlfR1VJREVfQ09ORklHKSB7XG4gICAgICBkZWxldGUgY29uZmlnLmF4aXNbcHJvcF07XG4gICAgfVxuICB9XG4gIGlmIChjb25maWcubGVnZW5kKSB7XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIFZMX09OTFlfR1VJREVfQ09ORklHKSB7XG4gICAgICBkZWxldGUgY29uZmlnLmxlZ2VuZFtwcm9wXTtcbiAgICB9XG4gIH1cblxuICAvLyBSZW1vdmUgVmVnYS1MaXRlIG9ubHkgZ2VuZXJpYyBtYXJrIGNvbmZpZ1xuICBpZiAoY29uZmlnLm1hcmspIHtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgVkxfT05MWV9NQVJLX0NPTkZJR19QUk9QRVJUSUVTKSB7XG4gICAgICBkZWxldGUgY29uZmlnLm1hcmtbcHJvcF07XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCBtYXJrIG9mIE1BUktfU1RZTEVTKSB7XG4gICAgLy8gUmVtb3ZlIFZlZ2EtTGl0ZS1vbmx5IG1hcmsgY29uZmlnXG4gICAgZm9yIChjb25zdCBwcm9wIG9mIFZMX09OTFlfTUFSS19DT05GSUdfUFJPUEVSVElFUykge1xuICAgICAgZGVsZXRlIGNvbmZpZ1ttYXJrXVtwcm9wXTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgVmVnYS1MaXRlIG9ubHkgbWFyay1zcGVjaWZpYyBjb25maWdcbiAgICBjb25zdCB2bE9ubHlNYXJrU3BlY2lmaWNDb25maWdzID0gVkxfT05MWV9BTExfTUFSS19TUEVDSUZJQ19DT05GSUdfUFJPUEVSVFlfSU5ERVhbbWFya107XG4gICAgaWYgKHZsT25seU1hcmtTcGVjaWZpY0NvbmZpZ3MpIHtcbiAgICAgIGZvciAoY29uc3QgcHJvcCBvZiB2bE9ubHlNYXJrU3BlY2lmaWNDb25maWdzKSB7XG4gICAgICAgIGRlbGV0ZSBjb25maWdbbWFya11bcHJvcF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmVkaXJlY3QgbWFyayBjb25maWcgdG8gY29uZmlnLnN0eWxlIHNvIHRoYXQgbWFyayBjb25maWcgb25seSBhZmZlY3QgaXRzIG93biBtYXJrIHR5cGVcbiAgICAvLyB3aXRob3V0IGFmZmVjdGluZyBvdGhlciBtYXJrcyB0aGF0IHNoYXJlIHRoZSBzYW1lIHVuZGVybHlpbmcgVmVnYSBtYXJrcy5cbiAgICAvLyBGb3IgZXhhbXBsZSwgY29uZmlnLnJlY3Qgc2hvdWxkIG5vdCBhZmZlY3QgYmFyIG1hcmtzLlxuICAgIHJlZGlyZWN0Q29uZmlnKGNvbmZpZywgbWFyayk7XG4gIH1cblxuICAvLyBSZWRpcmVjdCBjb25maWcudGl0bGUgLS0gc28gdGhhdCB0aXRsZSBjb25maWcgZG8gbm90XG4gIC8vIGFmZmVjdCBoZWFkZXIgbGFiZWxzLCB3aGljaCBhbHNvIHVzZXMgYHRpdGxlYCBkaXJlY3RpdmUgdG8gaW1wbGVtZW50LlxuICByZWRpcmVjdENvbmZpZyhjb25maWcsICd0aXRsZScsICdncm91cC10aXRsZScpO1xuXG4gIC8vIFJlbW92ZSBlbXB0eSBjb25maWcgb2JqZWN0c1xuICBmb3IgKGNvbnN0IHByb3AgaW4gY29uZmlnKSB7XG4gICAgaWYgKGlzT2JqZWN0KGNvbmZpZ1twcm9wXSkgJiYga2V5cyhjb25maWdbcHJvcF0pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZGVsZXRlIGNvbmZpZ1twcm9wXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ga2V5cyhjb25maWcpLmxlbmd0aCA+IDAgPyBjb25maWcgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHJlZGlyZWN0Q29uZmlnKGNvbmZpZzogQ29uZmlnLCBwcm9wOiBNYXJrIHwgQ29tcG9zaXRlTWFya1N0eWxlIHwgJ3RpdGxlJyB8ICd2aWV3JywgdG9Qcm9wPzogc3RyaW5nKSB7XG4gIGNvbnN0IHByb3BDb25maWc6IFZnTWFya0NvbmZpZyA9IHByb3AgPT09ICd0aXRsZScgPyBleHRyYWN0VGl0bGVDb25maWcoY29uZmlnLnRpdGxlKS5tYXJrIDogY29uZmlnW3Byb3BdO1xuXG4gIGlmIChwcm9wID09PSAndmlldycpIHtcbiAgICB0b1Byb3AgPSAnY2VsbCc7IC8vIFZpZXcncyBkZWZhdWx0IHN0eWxlIGlzIFwiY2VsbFwiXG4gIH1cblxuICBjb25zdCBzdHlsZTogVmdNYXJrQ29uZmlnID0ge1xuICAgIC4uLnByb3BDb25maWcsXG4gICAgLi4uY29uZmlnLnN0eWxlW3Byb3BdXG4gIH07XG4gIC8vIHNldCBjb25maWcuc3R5bGUgaWYgaXQgaXMgbm90IGFuIGVtcHR5IG9iamVjdFxuICBpZiAoa2V5cyhzdHlsZSkubGVuZ3RoID4gMCkge1xuICAgIGNvbmZpZy5zdHlsZVt0b1Byb3AgfHwgcHJvcF0gPSBzdHlsZTtcbiAgfVxuICBkZWxldGUgY29uZmlnW3Byb3BdO1xufVxuIl19 \ 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..9c247ec3a3 --- /dev/null +++ b/build/src/data.d.ts @@ -0,0 +1,97 @@ +import { VgData } from './vega.schema'; +export interface DataFormatBase { + /** + * If set to auto (the default), perform automatic type inference to determine the desired data types. + * 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"` or `"date"`). + * 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](timeunit.html#utc) + */ + parse?: 'auto' | object; +} +export interface CsvDataFormat extends DataFormatBase { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`. + * 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 JsonDataFormat extends DataFormatBase { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`. + * 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"`. + * 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 | JsonDataFormat | TopoDataFormat; +export declare type DataFormatType = 'json' | 'csv' | 'tsv' | 'topojson'; +export declare type Data = UrlData | InlineData | NamedData; +export interface UrlData { + /** + * An object that specifies the format for parsing the data file. + */ + format?: DataFormat; + /** + * 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 { + /** + * An object that specifies the format for parsing the data values. + */ + format?: DataFormat; + /** + * The full data set, included inline. 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. Strings are parsed according to the specified format type. + */ + values: number[] | string[] | boolean[] | object[] | string | object; +} +export interface NamedData { + /** + * An object that specifies the format for parsing the data. + */ + format?: DataFormat; + /** + * 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..4eb0fc5bd6 --- /dev/null +++ b/build/src/data.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isUrlData(data) { + return !!data['url']; +} +exports.isUrlData = isUrlData; +function isInlineData(data) { + return !!data['values']; +} +exports.isInlineData = isInlineData; +function isNamedData(data) { + return !!data['name']; +} +exports.isNamedData = isNamedData; +exports.MAIN = 'main'; +exports.RAW = 'raw'; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMEdBLG1CQUEwQixJQUFxQztJQUM3RCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN2QixDQUFDO0FBRkQsOEJBRUM7QUFFRCxzQkFBNkIsSUFBcUM7SUFDaEUsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUZELG9DQUVDO0FBRUQscUJBQTRCLElBQW1CO0lBQzdDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3hCLENBQUM7QUFGRCxrQ0FFQztBQUlZLFFBQUEsSUFBSSxHQUFXLE1BQU0sQ0FBQztBQUN0QixRQUFBLEdBQUcsR0FBVSxLQUFLLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1ZnRGF0YX0gZnJvbSAnLi92ZWdhLnNjaGVtYSc7XG4vKlxuICogQ29uc3RhbnRzIGFuZCB1dGlsaXRpZXMgZm9yIGRhdGEuXG4gKi9cblxuZXhwb3J0IGludGVyZmFjZSBEYXRhRm9ybWF0QmFzZSB7XG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gYXV0byAodGhlIGRlZmF1bHQpLCBwZXJmb3JtIGF1dG9tYXRpYyB0eXBlIGluZmVyZW5jZSB0byBkZXRlcm1pbmUgdGhlIGRlc2lyZWQgZGF0YSB0eXBlcy5cbiAgICogQWx0ZXJuYXRpdmVseSwgYSBwYXJzaW5nIGRpcmVjdGl2ZSBvYmplY3QgY2FuIGJlIHByb3ZpZGVkIGZvciBleHBsaWNpdCBkYXRhIHR5cGVzLiBFYWNoIHByb3BlcnR5IG9mIHRoZSBvYmplY3QgY29ycmVzcG9uZHMgdG8gYSBmaWVsZCBuYW1lLCBhbmQgdGhlIHZhbHVlIHRvIHRoZSBkZXNpcmVkIGRhdGEgdHlwZSAob25lIG9mIGBcIm51bWJlclwiYCwgYFwiYm9vbGVhblwiYCBvciBgXCJkYXRlXCJgKS5cbiAgICogRm9yIGV4YW1wbGUsIGBcInBhcnNlXCI6IHtcIm1vZGlmaWVkX29uXCI6IFwiZGF0ZVwifWAgcGFyc2VzIHRoZSBgbW9kaWZpZWRfb25gIGZpZWxkIGluIGVhY2ggaW5wdXQgcmVjb3JkIGEgRGF0ZSB2YWx1ZS5cbiAgICpcbiAgICogRm9yIGBcImRhdGVcImAsIHdlIHBhcnNlIGRhdGEgYmFzZWQgdXNpbmcgSmF2YXNjcmlwdCdzIFtgRGF0ZS5wYXJzZSgpYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRGF0ZS9wYXJzZSkuXG4gICAqIEZvciBTcGVjaWZpYyBkYXRlIGZvcm1hdHMgY2FuIGJlIHByb3ZpZGVkIChlLmcuLCBge2ZvbzogJ2RhdGU6XCIlbSVkJVlcIid9YCksIHVzaW5nIHRoZSBbZDMtdGltZS1mb3JtYXQgc3ludGF4XShodHRwczovL2dpdGh1Yi5jb20vZDMvZDMtdGltZS1mb3JtYXQjbG9jYWxlX2Zvcm1hdCkuIFVUQyBkYXRlIGZvcm1hdCBwYXJzaW5nIGlzIHN1cHBvcnRlZCBzaW1pbGFybHkgKGUuZy4sIGB7Zm9vOiAndXRjOlwiJW0lZCVZXCInfWApLiBTZWUgbW9yZSBhYm91dCBbVVRDIHRpbWVdKHRpbWV1bml0Lmh0bWwjdXRjKVxuICAgKi9cbiAgcGFyc2U/OiAnYXV0bycgfCBvYmplY3Q7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3N2RGF0YUZvcm1hdCBleHRlbmRzIERhdGFGb3JtYXRCYXNlIHtcbiAgLyoqXG4gICAqIFR5cGUgb2YgaW5wdXQgZGF0YTogYFwianNvblwiYCwgYFwiY3N2XCJgLCBgXCJ0c3ZcImAuXG4gICAqIFRoZSBkZWZhdWx0IGZvcm1hdCB0eXBlIGlzIGRldGVybWluZWQgYnkgdGhlIGV4dGVuc2lvbiBvZiB0aGUgZmlsZSBVUkwuXG4gICAqIElmIG5vIGV4dGVuc2lvbiBpcyBkZXRlY3RlZCwgYFwianNvblwiYCB3aWxsIGJlIHVzZWQgYnkgZGVmYXVsdC5cbiAgICovXG4gIHR5cGU/OiAnY3N2JyB8ICd0c3YnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEpzb25EYXRhRm9ybWF0IGV4dGVuZHMgRGF0YUZvcm1hdEJhc2Uge1xuICAvKipcbiAgICogVHlwZSBvZiBpbnB1dCBkYXRhOiBgXCJqc29uXCJgLCBgXCJjc3ZcImAsIGBcInRzdlwiYC5cbiAgICogVGhlIGRlZmF1bHQgZm9ybWF0IHR5cGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUgZXh0ZW5zaW9uIG9mIHRoZSBmaWxlIFVSTC5cbiAgICogSWYgbm8gZXh0ZW5zaW9uIGlzIGRldGVjdGVkLCBgXCJqc29uXCJgIHdpbGwgYmUgdXNlZCBieSBkZWZhdWx0LlxuICAgKi9cbiAgdHlwZT86ICdqc29uJztcbiAgLyoqXG4gICAqIFRoZSBKU09OIHByb3BlcnR5IGNvbnRhaW5pbmcgdGhlIGRlc2lyZWQgZGF0YS5cbiAgICogVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIHVzZWQgd2hlbiB0aGUgbG9hZGVkIEpTT04gZmlsZSBtYXkgaGF2ZSBzdXJyb3VuZGluZyBzdHJ1Y3R1cmUgb3IgbWV0YS1kYXRhLlxuICAgKiBGb3IgZXhhbXBsZSBgXCJwcm9wZXJ0eVwiOiBcInZhbHVlcy5mZWF0dXJlc1wiYCBpcyBlcXVpdmFsZW50IHRvIHJldHJpZXZpbmcgYGpzb24udmFsdWVzLmZlYXR1cmVzYFxuICAgKiBmcm9tIHRoZSBsb2FkZWQgSlNPTiBvYmplY3QuXG4gICAqL1xuICBwcm9wZXJ0eT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUb3BvRGF0YUZvcm1hdCBleHRlbmRzIERhdGFGb3JtYXRCYXNlIHtcbiAgLyoqXG4gICAqIFR5cGUgb2YgaW5wdXQgZGF0YTogYFwianNvblwiYCwgYFwiY3N2XCJgLCBgXCJ0c3ZcImAuXG4gICAqIFRoZSBkZWZhdWx0IGZvcm1hdCB0eXBlIGlzIGRldGVybWluZWQgYnkgdGhlIGV4dGVuc2lvbiBvZiB0aGUgZmlsZSBVUkwuXG4gICAqIElmIG5vIGV4dGVuc2lvbiBpcyBkZXRlY3RlZCwgYFwianNvblwiYCB3aWxsIGJlIHVzZWQgYnkgZGVmYXVsdC5cbiAgICovXG4gIHR5cGU/OiAndG9wb2pzb24nO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIFRvcG9KU09OIG9iamVjdCBzZXQgdG8gY29udmVydCB0byBhIEdlb0pTT04gZmVhdHVyZSBjb2xsZWN0aW9uLlxuICAgKiBGb3IgZXhhbXBsZSwgaW4gYSBtYXAgb2YgdGhlIHdvcmxkLCB0aGVyZSBtYXkgYmUgYW4gb2JqZWN0IHNldCBuYW1lZCBgXCJjb3VudHJpZXNcImAuXG4gICAqIFVzaW5nIHRoZSBmZWF0dXJlIHByb3BlcnR5LCB3ZSBjYW4gZXh0cmFjdCB0aGlzIHNldCBhbmQgZ2VuZXJhdGUgYSBHZW9KU09OIGZlYXR1cmUgb2JqZWN0IGZvciBlYWNoIGNvdW50cnkuXG4gICAqL1xuICBmZWF0dXJlPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIFRvcG9KU09OIG9iamVjdCBzZXQgdG8gY29udmVydCB0byBtZXNoLlxuICAgKiBTaW1pbGFyIHRvIHRoZSBgZmVhdHVyZWAgb3B0aW9uLCBgbWVzaGAgZXh0cmFjdHMgYSBuYW1lZCBUb3BvSlNPTiBvYmplY3Qgc2V0LlxuICAgKiAgVW5saWtlIHRoZSBgZmVhdHVyZWAgb3B0aW9uLCB0aGUgY29ycmVzcG9uZGluZyBnZW8gZGF0YSBpcyByZXR1cm5lZCBhcyBhIHNpbmdsZSwgdW5pZmllZCBtZXNoIGluc3RhbmNlLCBub3QgYXMgaW5kaXZpZHVhbCBHZW9KU09OIGZlYXR1cmVzLlxuICAgKiBFeHRyYWN0aW5nIGEgbWVzaCBpcyB1c2VmdWwgZm9yIG1vcmUgZWZmaWNpZW50bHkgZHJhd2luZyBib3JkZXJzIG9yIG90aGVyIGdlb2dyYXBoaWMgZWxlbWVudHMgdGhhdCB5b3UgZG8gbm90IG5lZWQgdG8gYXNzb2NpYXRlIHdpdGggc3BlY2lmaWMgcmVnaW9ucyBzdWNoIGFzIGluZGl2aWR1YWwgY291bnRyaWVzLCBzdGF0ZXMgb3IgY291bnRpZXMuXG4gICAqL1xuICBtZXNoPzogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBEYXRhRm9ybWF0ID0gQ3N2RGF0YUZvcm1hdCB8IEpzb25EYXRhRm9ybWF0IHwgVG9wb0RhdGFGb3JtYXQ7XG5cbmV4cG9ydCB0eXBlIERhdGFGb3JtYXRUeXBlID0gJ2pzb24nIHwgJ2NzdicgfCAndHN2JyB8ICd0b3BvanNvbic7XG5cbmV4cG9ydCB0eXBlIERhdGEgPSBVcmxEYXRhIHwgSW5saW5lRGF0YSB8IE5hbWVkRGF0YTtcblxuZXhwb3J0IGludGVyZmFjZSBVcmxEYXRhIHtcbiAgLyoqXG4gICAqIEFuIG9iamVjdCB0aGF0IHNwZWNpZmllcyB0aGUgZm9ybWF0IGZvciBwYXJzaW5nIHRoZSBkYXRhIGZpbGUuXG4gICAqL1xuICBmb3JtYXQ/OiBEYXRhRm9ybWF0O1xuXG4gIC8qKlxuICAgKiBBbiBVUkwgZnJvbSB3aGljaCB0byBsb2FkIHRoZSBkYXRhIHNldC4gVXNlIHRoZSBgZm9ybWF0LnR5cGVgIHByb3BlcnR5XG4gICAqIHRvIGVuc3VyZSB0aGUgbG9hZGVkIGRhdGEgaXMgY29ycmVjdGx5IHBhcnNlZC5cbiAgICovXG4gIHVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElubGluZURhdGEge1xuICAvKipcbiAgICogQW4gb2JqZWN0IHRoYXQgc3BlY2lmaWVzIHRoZSBmb3JtYXQgZm9yIHBhcnNpbmcgdGhlIGRhdGEgdmFsdWVzLlxuICAgKi9cbiAgZm9ybWF0PzogRGF0YUZvcm1hdDtcbiAgLyoqXG4gICAqIFRoZSBmdWxsIGRhdGEgc2V0LCBpbmNsdWRlZCBpbmxpbmUuIFRoaXMgY2FuIGJlIGFuIGFycmF5IG9mIG9iamVjdHMgb3IgcHJpbWl0aXZlIHZhbHVlcyBvciBhIHN0cmluZy5cbiAgICogQXJyYXlzIG9mIHByaW1pdGl2ZSB2YWx1ZXMgYXJlIGluZ2VzdGVkIGFzIG9iamVjdHMgd2l0aCBhIGBkYXRhYCBwcm9wZXJ0eS4gU3RyaW5ncyBhcmUgcGFyc2VkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGZvcm1hdCB0eXBlLlxuICAgKi9cbiAgdmFsdWVzOiBudW1iZXJbXSB8IHN0cmluZ1tdIHwgYm9vbGVhbltdIHwgb2JqZWN0W10gfCBzdHJpbmcgfCBvYmplY3Q7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmFtZWREYXRhIHtcbiAgLyoqXG4gICAqIEFuIG9iamVjdCB0aGF0IHNwZWNpZmllcyB0aGUgZm9ybWF0IGZvciBwYXJzaW5nIHRoZSBkYXRhLlxuICAgKi9cbiAgZm9ybWF0PzogRGF0YUZvcm1hdDtcbiAgLyoqXG4gICAqIFByb3ZpZGUgYSBwbGFjZWhvbGRlciBuYW1lIGFuZCBiaW5kIGRhdGEgYXQgcnVudGltZS5cbiAgICovXG4gIG5hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVXJsRGF0YShkYXRhOiBQYXJ0aWFsPERhdGE+IHwgUGFydGlhbDxWZ0RhdGE+KTogZGF0YSBpcyBVcmxEYXRhIHtcbiAgcmV0dXJuICEhZGF0YVsndXJsJ107XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0lubGluZURhdGEoZGF0YTogUGFydGlhbDxEYXRhPiB8IFBhcnRpYWw8VmdEYXRhPik6IGRhdGEgaXMgSW5saW5lRGF0YSB7XG4gIHJldHVybiAhIWRhdGFbJ3ZhbHVlcyddO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNOYW1lZERhdGEoZGF0YTogUGFydGlhbDxEYXRhPik6IGRhdGEgaXMgTmFtZWREYXRhIHtcbiAgcmV0dXJuICEhZGF0YVsnbmFtZSddO1xufVxuXG5leHBvcnQgdHlwZSBEYXRhU291cmNlVHlwZSA9ICdyYXcnIHwgJ21haW4nIHwgJ3JvdycgfCAnY29sdW1uJyB8ICdsb29rdXAnO1xuXG5leHBvcnQgY29uc3QgTUFJTjogJ21haW4nID0gJ21haW4nO1xuZXhwb3J0IGNvbnN0IFJBVzogJ3JhdycgPSAncmF3JztcbiJdfQ== \ 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..90eba60b6d --- /dev/null +++ b/build/src/datetime.js @@ -0,0 +1,140 @@ +"use strict"; +// DateTime definition object +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("./log"); +var util_1 = require("./util"); +/* + * 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); +} +exports.isDateTime = isDateTime; +exports.MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; +exports.SHORT_MONTHS = exports.MONTHS.map(function (m) { return m.substr(0, 3); }); +exports.DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; +exports.SHORT_DAYS = exports.DAYS.map(function (d) { return d.substr(0, 3); }); +function normalizeQuarter(q) { + if (util_1.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 (util_1.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 = exports.MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + var shortM = lowerM.substr(0, 3); + var shortMonthIndex = exports.SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(log.message.invalidTimeUnit('month', m)); + } +} +function normalizeDay(d) { + if (util_1.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 = exports.DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + var shortD = lowerD.substr(0, 3); + var shortDayIndex = exports.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. + */ +function dateTimeExpr(d, normalize) { + if (normalize === void 0) { normalize = false; } + var units = []; + if (normalize && d.day !== undefined) { + if (util_1.keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = util_1.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(', ') + ")"; + } +} +exports.dateTimeExpr = dateTimeExpr; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0ZXRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDZCQUE2Qjs7QUFFN0IsMkJBQTZCO0FBQzdCLCtCQUFpRDtBQUdqRDs7R0FFRztBQUNILElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQztBQThHekIsb0JBQTJCLENBQU07SUFDL0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUc7UUFDeEUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBSEQsZ0NBR0M7QUFFWSxRQUFBLE1BQU0sR0FBRyxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDcEksUUFBQSxZQUFZLEdBQUcsY0FBTSxDQUFDLEdBQUcsQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFkLENBQWMsQ0FBQyxDQUFDO0FBRWpELFFBQUEsSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxRQUFR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QyxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3BELEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyx5QkFBeUI7SUFDMUMsQ0FBQztJQUVELGlFQUFpRTtJQUNqRSwrQkFBK0I7SUFDL0IsR0FBRyxDQUFDLENBQW1CLFVBQStDLEVBQS9DLE1BQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsY0FBYyxDQUFDLEVBQS9DLGNBQStDLEVBQS9DLElBQStDO1FBQWpFLElBQU0sUUFBUSxTQUFBO1FBQ2pCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQzlCLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDMUIsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQixDQUFDO0tBQ0Y7SUFFRCxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNWLE1BQU0sQ0FBQyxTQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQUcsQ0FBQztJQUNwQyxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixNQUFNLENBQUMsY0FBWSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFHLENBQUM7SUFDekMsQ0FBQztBQUNILENBQUM7QUF4REQsb0NBd0RDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gRGF0ZVRpbWUgZGVmaW5pdGlvbiBvYmplY3RcblxuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4vbG9nJztcbmltcG9ydCB7ZHVwbGljYXRlLCBpc051bWJlciwga2V5c30gZnJvbSAnLi91dGlsJztcblxuXG4vKlxuICogQSBkZXNpZ25hdGVkIHllYXIgdGhhdCBzdGFydHMgb24gU3VuZGF5LlxuICovXG5jb25zdCBTVU5EQVlfWUVBUiA9IDIwMDY7XG5cbi8qKlxuICogQG1pbmltdW0gMVxuICogQG1heGltdW0gMTJcbiAqIEBUSlMtdHlwZSBpbnRlZ2VyXG4gKi9cbmV4cG9ydCB0eXBlIE1vbnRoID0gbnVtYmVyO1xuXG4vKipcbiAqIEBtaW5pbXVtIDFcbiAqIEBtYXhpbXVtIDdcbiAqL1xuZXhwb3J0IHR5cGUgRGF5ID0gbnVtYmVyO1xuXG4vKipcbiAqIE9iamVjdCBmb3IgZGVmaW5pbmcgZGF0ZXRpbWUgaW4gVmVnYS1MaXRlIEZpbHRlci5cbiAqIElmIGJvdGggbW9udGggYW5kIHF1YXJ0ZXIgYXJlIHByb3ZpZGVkLCBtb250aCBoYXMgaGlnaGVyIHByZWNlZGVuY2UuXG4gKiBgZGF5YCBjYW5ub3QgYmUgY29tYmluZWQgd2l0aCBvdGhlciBkYXRlLlxuICogV2UgYWNjZXB0IHN0cmluZyBmb3IgbW9udGggYW5kIGRheSBuYW1lcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRlVGltZSB7XG4gIC8qKlxuICAgKiBJbnRlZ2VyIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgeWVhci5cbiAgICogQFRKUy10eXBlIGludGVnZXJcbiAgICovXG4gIHllYXI/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEludGVnZXIgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBxdWFydGVyIG9mIHRoZSB5ZWFyIChmcm9tIDEtNCkuXG4gICAqIEBtaW5pbXVtIDFcbiAgICogQG1heGltdW0gNFxuICAgKiBAVEpTLXR5cGUgaW50ZWdlclxuICAgKi9cbiAgcXVhcnRlcj86IG51bWJlcjtcblxuICAvKiogT25lIG9mOiAoMSkgaW50ZWdlciB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIG1vbnRoIGZyb20gYDFgLWAxMmAuIGAxYCByZXByZXNlbnRzIEphbnVhcnk7ICAoMikgY2FzZS1pbnNlbnNpdGl2ZSBtb250aCBuYW1lIChlLmcuLCBgXCJKYW51YXJ5XCJgKTsgICgzKSBjYXNlLWluc2Vuc2l0aXZlLCAzLWNoYXJhY3RlciBzaG9ydCBtb250aCBuYW1lIChlLmcuLCBgXCJKYW5cImApLiAqL1xuICBtb250aD86IE1vbnRoIHwgc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbnRlZ2VyIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgZGF0ZSBmcm9tIDEtMzEuXG4gICAqIEBtaW5pbXVtIDFcbiAgICogQG1heGltdW0gMzFcbiAgICogQFRKUy10eXBlIGludGVnZXJcbiAgICovXG4gIGRhdGU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFZhbHVlIHJlcHJlc2VudGluZyB0aGUgZGF5IG9mIGEgd2Vlay4gIFRoaXMgY2FuIGJlIG9uZSBvZjogKDEpIGludGVnZXIgdmFsdWUgLS0gYDFgIHJlcHJlc2VudHMgTW9uZGF5OyAoMikgY2FzZS1pbnNlbnNpdGl2ZSBkYXkgbmFtZSAoZS5nLiwgYFwiTW9uZGF5XCJgKTsgICgzKSBjYXNlLWluc2Vuc2l0aXZlLCAzLWNoYXJhY3RlciBzaG9ydCBkYXkgbmFtZSAoZS5nLiwgYFwiTW9uXCJgKS4gICA8YnIvPiAqKldhcm5pbmc6KiogQSBEYXRlVGltZSBkZWZpbml0aW9uIG9iamVjdCB3aXRoIGBkYXlgKiogc2hvdWxkIG5vdCBiZSBjb21iaW5lZCB3aXRoIGB5ZWFyYCwgYHF1YXJ0ZXJgLCBgbW9udGhgLCBvciBgZGF0ZWAuXG4gICAqL1xuICBkYXk/OiBEYXkgfCBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEludGVnZXIgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBob3VyIG9mIGEgZGF5IGZyb20gMC0yMy5cbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSAyM1xuICAgKiBAVEpTLXR5cGUgaW50ZWdlclxuICAgKi9cbiAgaG91cnM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEludGVnZXIgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBtaW51dGUgc2VnbWVudCBvZiB0aW1lIGZyb20gMC01OS5cbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSA1OVxuICAgKiBAVEpTLXR5cGUgaW50ZWdlclxuICAgKi9cbiAgbWludXRlcz86IG51bWJlcjtcblxuICAvKipcbiAgICogSW50ZWdlciB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIHNlY29uZCBzZWdtZW50ICgwLTU5KSBvZiBhIHRpbWUgdmFsdWVcbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSA1OVxuICAgKiBAVEpTLXR5cGUgaW50ZWdlclxuICAgKi9cbiAgc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogSW50ZWdlciB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIG1pbGxpc2Vjb25kIHNlZ21lbnQgb2YgdGltZS5cbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSA5OTlcbiAgICogQFRKUy10eXBlIGludGVnZXJcbiAgICovXG4gIG1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogQSBib29sZWFuIGZsYWcgaW5kaWNhdGluZyBpZiBkYXRlIHRpbWUgaXMgaW4gdXRjIHRpbWUuIElmIGZhbHNlLCB0aGUgZGF0ZSB0aW1lIGlzIGluIGxvY2FsIHRpbWVcbiAgICovXG4gIHV0Yz86IGJvb2xlYW47XG59XG5cblxuLyoqXG4gKiBJbnRlcm5hbCBPYmplY3QgZm9yIGRlZmluaW5nIGRhdGV0aW1lIGV4cHJlc3Npb25zLlxuICogVGhpcyBpcyBhbiBleHByZXNzaW9uIHZlcnNpb24gb2YgRGF0ZVRpbWUuXG4gKiBJZiBib3RoIG1vbnRoIGFuZCBxdWFydGVyIGFyZSBwcm92aWRlZCwgbW9udGggaGFzIGhpZ2hlciBwcmVjZWRlbmNlLlxuICogYGRheWAgY2Fubm90IGJlIGNvbWJpbmVkIHdpdGggb3RoZXIgZGF0ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRlVGltZUV4cHIge1xuICB5ZWFyPzogc3RyaW5nO1xuICBxdWFydGVyPzogc3RyaW5nO1xuICBtb250aD86IHN0cmluZztcbiAgZGF0ZT86IHN0cmluZztcbiAgZGF5Pzogc3RyaW5nO1xuICBob3Vycz86IHN0cmluZztcbiAgbWludXRlcz86IHN0cmluZztcbiAgc2Vjb25kcz86IHN0cmluZztcbiAgbWlsbGlzZWNvbmRzPzogc3RyaW5nO1xuICB1dGM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRlVGltZShvOiBhbnkpOiBvIGlzIERhdGVUaW1lIHtcbiAgcmV0dXJuICEhbyAmJiAoISFvLnllYXIgfHwgISFvLnF1YXJ0ZXIgfHwgISFvLm1vbnRoIHx8ICEhby5kYXRlIHx8ICEhby5kYXkgfHxcbiAgICAhIW8uaG91cnMgfHwgISFvLm1pbnV0ZXMgfHwgISFvLnNlY29uZHMgfHwgISFvLm1pbGxpc2Vjb25kcyk7XG59XG5cbmV4cG9ydCBjb25zdCBNT05USFMgPSBbJ2phbnVhcnknLCAnZmVicnVhcnknLCAnbWFyY2gnLCAnYXByaWwnLCAnbWF5JywgJ2p1bmUnLCAnanVseScsICdhdWd1c3QnLCAnc2VwdGVtYmVyJywgJ29jdG9iZXInLCAnbm92ZW1iZXInLCAnZGVjZW1iZXInXTtcbmV4cG9ydCBjb25zdCBTSE9SVF9NT05USFMgPSBNT05USFMubWFwKChtKSA9PiBtLnN1YnN0cigwLCAzKSk7XG5cbmV4cG9ydCBjb25zdCBEQVlTID0gWydzdW5kYXknLCAnbW9uZGF5JywgJ3R1ZXNkYXknLCAnd2VkbmVzZGF5JywgJ3RodXJzZGF5JywgJ2ZyaWRheScsICdzYXR1cmRheSddO1xuZXhwb3J0IGNvbnN0IFNIT1JUX0RBWVMgPSBEQVlTLm1hcCgoZCkgPT4gZC5zdWJzdHIoMCwzKSk7XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVF1YXJ0ZXIocTogbnVtYmVyIHwgc3RyaW5nKSB7XG4gIGlmIChpc051bWJlcihxKSkge1xuICAgIGlmIChxID4gNCkge1xuICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuaW52YWxpZFRpbWVVbml0KCdxdWFydGVyJywgcSkpO1xuICAgIH1cbiAgICAvLyBXZSBhY2NlcHQgMS1iYXNlZCBxdWFydGVyLCBzbyBuZWVkIHRvIHJlYWRqdXN0IHRvIDAtYmFzZWQgcXVhcnRlclxuICAgIHJldHVybiAocSAtIDEpICsgJyc7XG4gIH0gZWxzZSB7XG4gICAgLy8gSW52YWxpZCBxdWFydGVyXG4gICAgdGhyb3cgbmV3IEVycm9yKGxvZy5tZXNzYWdlLmludmFsaWRUaW1lVW5pdCgncXVhcnRlcicsIHEpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVNb250aChtOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgaWYgKGlzTnVtYmVyKG0pKSB7XG4gICAgLy8gV2UgYWNjZXB0IDEtYmFzZWQgbW9udGgsIHNvIG5lZWQgdG8gcmVhZGp1c3QgdG8gMC1iYXNlZCBtb250aFxuICAgIHJldHVybiAobSAtIDEpICsgJyc7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgbG93ZXJNID0gbS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IG1vbnRoSW5kZXggPSBNT05USFMuaW5kZXhPZihsb3dlck0pO1xuICAgIGlmIChtb250aEluZGV4ICE9PSAtMSkge1xuICAgICAgcmV0dXJuIG1vbnRoSW5kZXggKyAnJzsgLy8gMCBmb3IgamFudWFyeSwgLi4uXG4gICAgfVxuICAgIGNvbnN0IHNob3J0TSA9IGxvd2VyTS5zdWJzdHIoMCwgMyk7XG4gICAgY29uc3Qgc2hvcnRNb250aEluZGV4ID0gU0hPUlRfTU9OVEhTLmluZGV4T2Yoc2hvcnRNKTtcbiAgICBpZiAoc2hvcnRNb250aEluZGV4ICE9PSAtMSkge1xuICAgICAgcmV0dXJuIHNob3J0TW9udGhJbmRleCArICcnO1xuICAgIH1cbiAgICAvLyBJbnZhbGlkIG1vbnRoXG4gICAgdGhyb3cgbmV3IEVycm9yKGxvZy5tZXNzYWdlLmludmFsaWRUaW1lVW5pdCgnbW9udGgnLCBtKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplRGF5KGQ6IHN0cmluZyB8IG51bWJlcikge1xuICBpZiAoaXNOdW1iZXIoZCkpIHtcbiAgICAvLyBtb2Qgc28gdGhhdCB0aGlzIGNhbiBiZSBib3RoIDAtYmFzZWQgd2hlcmUgMCA9IHN1bmRheVxuICAgIC8vIGFuZCAxLWJhc2VkIHdoZXJlIDc9c3VuZGF5XG4gICAgcmV0dXJuIChkICUgNykgKyAnJztcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBsb3dlckQgPSBkLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgZGF5SW5kZXggPSBEQVlTLmluZGV4T2YobG93ZXJEKTtcbiAgICBpZiAoZGF5SW5kZXggIT09IC0xKSB7XG4gICAgICByZXR1cm4gZGF5SW5kZXggKyAnJzsgLy8gMCBmb3IgamFudWFyeSwgLi4uXG4gICAgfVxuICAgIGNvbnN0IHNob3J0RCA9IGxvd2VyRC5zdWJzdHIoMCwgMyk7XG4gICAgY29uc3Qgc2hvcnREYXlJbmRleCA9IFNIT1JUX0RBWVMuaW5kZXhPZihzaG9ydEQpO1xuICAgIGlmIChzaG9ydERheUluZGV4ICE9PSAtMSkge1xuICAgICAgcmV0dXJuIHNob3J0RGF5SW5kZXggKyAnJztcbiAgICB9XG4gICAgLy8gSW52YWxpZCBkYXlcbiAgICB0aHJvdyBuZXcgRXJyb3IobG9nLm1lc3NhZ2UuaW52YWxpZFRpbWVVbml0KCdkYXknLCBkKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gVmVnYSBFeHByZXNzaW9uIGZvciBhIHBhcnRpY3VsYXIgZGF0ZSB0aW1lLlxuICogQHBhcmFtIGRcbiAqIEBwYXJhbSBub3JtYWxpemUgd2hldGhlciB0byBub3JtYWxpemUgcXVhcnRlciwgbW9udGgsIGRheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGVUaW1lRXhwcihkOiBEYXRlVGltZSB8IERhdGVUaW1lRXhwciwgbm9ybWFsaXplID0gZmFsc2UpIHtcbiAgY29uc3QgdW5pdHM6IChzdHJpbmcgfCBudW1iZXIpW10gPSBbXTtcblxuICBpZiAobm9ybWFsaXplICYmIGQuZGF5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoa2V5cyhkKS5sZW5ndGggPiAxKSB7XG4gICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5kcm9wcGVkRGF5KGQpKTtcbiAgICAgIGQgPSBkdXBsaWNhdGUoZCk7XG4gICAgICBkZWxldGUgZC5kYXk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGQueWVhciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdW5pdHMucHVzaChkLnllYXIpO1xuICB9IGVsc2UgaWYgKGQuZGF5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBTZXQgeWVhciB0byAyMDA2IGZvciB3b3JraW5nIHdpdGggZGF5IHNpbmNlIEphbnVhcnkgMSAyMDA2IGlzIGEgU3VuZGF5XG4gICAgdW5pdHMucHVzaChTVU5EQVlfWUVBUik7XG4gIH0gZWxzZSB7XG4gICAgdW5pdHMucHVzaCgwKTtcbiAgfVxuXG4gIGlmIChkLm1vbnRoICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBtb250aCA9IG5vcm1hbGl6ZSA/IG5vcm1hbGl6ZU1vbnRoKGQubW9udGgpIDogZC5tb250aDtcbiAgICB1bml0cy5wdXNoKG1vbnRoKTtcbiAgfSBlbHNlIGlmIChkLnF1YXJ0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IHF1YXJ0ZXIgPSBub3JtYWxpemUgPyBub3JtYWxpemVRdWFydGVyKGQucXVhcnRlcikgOiBkLnF1YXJ0ZXI7XG4gICAgdW5pdHMucHVzaChxdWFydGVyICsgJyozJyk7XG4gIH0gZWxzZSB7XG4gICAgdW5pdHMucHVzaCgwKTsgLy8gbW9udGhzIHN0YXJ0IGF0IHplcm8gaW4gSlNcbiAgfVxuXG4gIGlmIChkLmRhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHVuaXRzLnB1c2goZC5kYXRlKTtcbiAgfSBlbHNlIGlmIChkLmRheSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gSEFDSzogRGF5IG9ubHkgd29ya3MgYXMgYSBzdGFuZGFsb25lIHVuaXRcbiAgICAvLyBUaGlzIGlzIG9ubHkgY29ycmVjdCBiZWNhdXNlIHdlIGFsd2F5cyBzZXQgeWVhciB0byAyMDA2IGZvciBkYXlcbiAgICBjb25zdCBkYXkgPSBub3JtYWxpemUgPyBub3JtYWxpemVEYXkoZC5kYXkpIDogZC5kYXk7XG4gICAgdW5pdHMucHVzaChkYXkgKyAnKzEnKTtcbiAgfSBlbHNlIHtcbiAgICB1bml0cy5wdXNoKDEpOyAvLyBEYXRlIHN0YXJ0cyBhdCAxIGluIEpTXG4gIH1cblxuICAvLyBOb3RlOiBjYW4ndCB1c2UgVGltZVVuaXQgZW51bSBoZXJlIGFzIGltcG9ydGluZyBpdCB3aWxsIGNyZWF0ZVxuICAvLyBjaXJjdWxhciBkZXBlbmRlbmN5IHByb2JsZW0hXG4gIGZvciAoY29uc3QgdGltZVVuaXQgb2YgWydob3VycycsICdtaW51dGVzJywgJ3NlY29uZHMnLCAnbWlsbGlzZWNvbmRzJ10pIHtcbiAgICBpZiAoZFt0aW1lVW5pdF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdW5pdHMucHVzaChkW3RpbWVVbml0XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXRzLnB1c2goMCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGQudXRjKSB7XG4gICAgcmV0dXJuIGB1dGMoJHt1bml0cy5qb2luKCcsICcpfSlgO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBgZGF0ZXRpbWUoJHt1bml0cy5qb2luKCcsICcpfSlgO1xuICB9XG59XG4iXX0= \ 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..65d4c24752 --- /dev/null +++ b/build/src/encoding.d.ts @@ -0,0 +1,83 @@ +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; + /** + * Color of the marks – either fill or stroke color based on mark type. + * By default, `color` represents fill color for `"area"`, `"bar"`, `"tick"`, + * `"text"`, `"circle"`, and `"square"` / stroke color for `"line"` and `"point"`. + * + * __Default value:__ If undefined, the default color depends on [mark config](config.html#mark)'s `color` property. + * + * _Note:_ See the scale documentation for more information about customizing [color scheme](scale.html#scheme). + */ + color?: 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](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 currently unsupported for `"line"`, `"area"`, and `"rect"`. + */ + size?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * The symbol's shape (only for `point` marks). The supported values are + * `"circle"` (default), `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, + * or `"triangle-down"`, or else a custom SVG path string. + * __Default value:__ If undefined, the default shape depends on [mark config](config.html#point-config)'s `shape` property. + */ + shape?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Additional levels of detail for grouping data in aggregate views and + * in line and area marks without mapping data to a specific visual channel. + */ + detail?: FieldDef | FieldDef[]; + /** + * Text of the `text` mark. + */ + text?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * The tooltip text to show upon mouse hover. + */ + tooltip?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Stack order for stacked marks or order of data points in line marks for connected scatter plots. + * + * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping. + */ + order?: OrderFieldDef | OrderFieldDef[]; +} +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..7d2f26c4a2 --- /dev/null +++ b/build/src/encoding.js @@ -0,0 +1,139 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var fielddef_1 = require("./fielddef"); +var log = require("./log"); +var util_1 = require("./util"); +function channelHasField(encoding, channel) { + var channelDef = encoding && encoding[channel]; + if (channelDef) { + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.field; }); + } + else { + return fielddef_1.isFieldDef(channelDef) || fielddef_1.hasConditionalFieldDef(channelDef); + } + } + return false; +} +exports.channelHasField = channelHasField; +function isAggregate(encoding) { + return util_1.some(channel_1.CHANNELS, function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.aggregate; }); + } + else { + var fieldDef = fielddef_1.getFieldDef(channelDef); + return fieldDef && !!fieldDef.aggregate; + } + } + return false; + }); +} +exports.isAggregate = isAggregate; +function normalizeEncoding(encoding, mark) { + return util_1.keys(encoding).reduce(function (normalizedEncoding, channel) { + if (!channel_1.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 = fielddef_1.getFieldDef(encoding[channel]); + if (fieldDef && fieldDef.aggregate) { + log.warn(log.message.incompatibleChannel(channel, mark, 'when the field is aggregated.')); + return normalizedEncoding; + } + } + if (channel === 'detail' || channel === 'order') { + var channelDef = encoding[channel]; + if (channelDef) { + // Array of fieldDefs for detail channel (or production rule) + normalizedEncoding[channel] = (util_1.isArray(channelDef) ? channelDef : [channelDef]) + .reduce(function (fieldDefs, fieldDef) { + if (!fielddef_1.isFieldDef(fieldDef)) { + log.warn(log.message.emptyFieldDef(fieldDef, channel)); + } + else { + fieldDefs.push(fielddef_1.normalizeFieldDef(fieldDef, channel)); + } + return fieldDefs; + }, []); + } + } + else { + // FIXME: remove this casting. (I don't know why Typescript doesn't infer this correctly here.) + var channelDef = encoding[channel]; + if (!fielddef_1.isFieldDef(channelDef) && !fielddef_1.isValueDef(channelDef) && !fielddef_1.isConditionalDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + return normalizedEncoding; + } + normalizedEncoding[channel] = fielddef_1.normalize(channelDef, channel); + } + return normalizedEncoding; + }, {}); +} +exports.normalizeEncoding = normalizeEncoding; +function isRanged(encoding) { + return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2)); +} +exports.isRanged = isRanged; +function fieldDefs(encoding) { + var arr = []; + channel_1.CHANNELS.forEach(function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (def) { + if (fielddef_1.isFieldDef(def)) { + arr.push(def); + } + else if (fielddef_1.hasConditionalFieldDef(def)) { + arr.push(def.condition); + } + }); + } + }); + return arr; +} +exports.fieldDefs = fieldDefs; +function forEach(mapping, f, thisArg) { + if (!mapping) { + return; + } + var _loop_1 = function (channel) { + if (util_1.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 = util_1.keys(mapping); _i < _a.length; _i++) { + var channel = _a[_i]; + _loop_1(channel); + } +} +exports.forEach = forEach; +function reduce(mapping, f, init, thisArg) { + if (!mapping) { + return init; + } + return util_1.keys(mapping).reduce(function (r, channel) { + var map = mapping[channel]; + if (util_1.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); +} +exports.reduce = reduce; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZW5jb2RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQSxxQ0FBeUQ7QUFFekQsdUNBa0JvQjtBQUNwQiwyQkFBNkI7QUFFN0IsK0JBQTJDO0FBc0YzQyx5QkFBZ0MsUUFBa0MsRUFBRSxPQUFnQjtJQUNsRixJQUFNLFVBQVUsR0FBRyxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pELEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDZixFQUFFLENBQUMsQ0FBQyxjQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxXQUFJLENBQUMsVUFBVSxFQUFFLFVBQUMsUUFBUSxJQUFLLE9BQUEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQWhCLENBQWdCLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMscUJBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxpQ0FBc0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDO0FBVkQsMENBVUM7QUFHRCxxQkFBNEIsUUFBa0M7SUFDNUQsTUFBTSxDQUFDLFdBQUksQ0FBQyxrQkFBUSxFQUFFLFVBQUMsT0FBTztRQUM1QixFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QyxJQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsRUFBRSxDQUFDLENBQUMsY0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsTUFBTSxDQUFDLFdBQUksQ0FBQyxVQUFVLEVBQUUsVUFBQyxRQUFRLElBQUss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LE9BQWE7SUFDeEIsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2IsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxNQUFNLENBQUMsV0FBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsRUFBRSxPQUFPO1FBQ3JDLElBQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QixFQUFFLENBQUMsQ0FBQyxjQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFVBQUMsRUFBSyxFQUFFLFVBQThCO2dCQUN0RCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsRCxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDUixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxQyxDQUFDO0lBQ0gsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQWpCRCx3QkFpQkMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7Q2hhbm5lbCwgQ0hBTk5FTFMsIHN1cHBvcnRNYXJrfSBmcm9tICcuL2NoYW5uZWwnO1xuaW1wb3J0IHtGYWNldE1hcHBpbmd9IGZyb20gJy4vZmFjZXQnO1xuaW1wb3J0IHtcbiAgQ2hhbm5lbERlZixcbiAgRmllbGQsXG4gIEZpZWxkRGVmLFxuICBGaWVsZERlZldpdGhDb25kaXRpb24sXG4gIGdldEZpZWxkRGVmLFxuICBoYXNDb25kaXRpb25hbEZpZWxkRGVmLFxuICBpc0NvbmRpdGlvbmFsRGVmLFxuICBpc0ZpZWxkRGVmLFxuICBpc1ZhbHVlRGVmLFxuICBNYXJrUHJvcEZpZWxkRGVmLFxuICBub3JtYWxpemUsXG4gIG5vcm1hbGl6ZUZpZWxkRGVmLFxuICBPcmRlckZpZWxkRGVmLFxuICBQb3NpdGlvbkZpZWxkRGVmLFxuICBUZXh0RmllbGREZWYsXG4gIFZhbHVlRGVmLFxuICBWYWx1ZURlZldpdGhDb25kaXRpb25cbn0gZnJvbSAnLi9maWVsZGRlZic7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi9sb2cnO1xuaW1wb3J0IHtNYXJrfSBmcm9tICcuL21hcmsnO1xuaW1wb3J0IHtpc0FycmF5LCBrZXlzLCBzb21lfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVuY29kaW5nPEY+IHtcbiAgLyoqXG4gICAqIFggY29vcmRpbmF0ZXMgb2YgdGhlIG1hcmtzLCBvciB3aWR0aCBvZiBob3Jpem9udGFsIGBcImJhclwiYCBhbmQgYFwiYXJlYVwiYC5cbiAgICovXG4gIHg/OiBQb3NpdGlvbkZpZWxkRGVmPEY+IHwgVmFsdWVEZWY7XG5cbiAgLyoqXG4gICAqIFkgY29vcmRpbmF0ZXMgb2YgdGhlIG1hcmtzLCBvciBoZWlnaHQgb2YgdmVydGljYWwgYFwiYmFyXCJgIGFuZCBgXCJhcmVhXCJgLlxuICAgKi9cbiAgeT86IFBvc2l0aW9uRmllbGREZWY8Rj4gfCBWYWx1ZURlZjtcblxuICAvKipcbiAgICogWDIgY29vcmRpbmF0ZXMgZm9yIHJhbmdlZCAgYFwiYXJlYVwiYCwgYFwiYmFyXCJgLCBgXCJyZWN0XCJgLCBhbmQgIGBcInJ1bGVcImAuXG4gICAqL1xuICAvLyBUT0RPOiBIYW0gbmVlZCB0byBhZGQgZGVmYXVsdCBiZWhhdmlvclxuICB4Mj86IEZpZWxkRGVmPEY+IHwgVmFsdWVEZWY7XG5cbiAgLyoqXG4gICAqIFkyIGNvb3JkaW5hdGVzIGZvciByYW5nZWQgIGBcImFyZWFcImAsIGBcImJhclwiYCwgYFwicmVjdFwiYCwgYW5kICBgXCJydWxlXCJgLlxuICAgKi9cbiAgLy8gVE9ETzogSGFtIG5lZWQgdG8gYWRkIGRlZmF1bHQgYmVoYXZpb3JcbiAgeTI/OiBGaWVsZERlZjxGPiB8IFZhbHVlRGVmO1xuXG4gIC8qKlxuICAgKiBDb2xvciBvZiB0aGUgbWFya3Mg4oCTIGVpdGhlciBmaWxsIG9yIHN0cm9rZSBjb2xvciBiYXNlZCBvbiBtYXJrIHR5cGUuXG4gICAqIEJ5IGRlZmF1bHQsIGBjb2xvcmAgcmVwcmVzZW50cyBmaWxsIGNvbG9yIGZvciBgXCJhcmVhXCJgLCBgXCJiYXJcImAsIGBcInRpY2tcImAsXG4gICAqIGBcInRleHRcImAsIGBcImNpcmNsZVwiYCwgYW5kIGBcInNxdWFyZVwiYCAvIHN0cm9rZSBjb2xvciBmb3IgYFwibGluZVwiYCBhbmQgYFwicG9pbnRcImAuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBJZiB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IGNvbG9yIGRlcGVuZHMgb24gW21hcmsgY29uZmlnXShjb25maWcuaHRtbCNtYXJrKSdzIGBjb2xvcmAgcHJvcGVydHkuXG4gICAqXG4gICAqIF9Ob3RlOl8gU2VlIHRoZSBzY2FsZSBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGN1c3RvbWl6aW5nIFtjb2xvciBzY2hlbWVdKHNjYWxlLmh0bWwjc2NoZW1lKS5cbiAgICovXG4gIGNvbG9yPzogRmllbGREZWZXaXRoQ29uZGl0aW9uPE1hcmtQcm9wRmllbGREZWY8Rj4+IHwgVmFsdWVEZWZXaXRoQ29uZGl0aW9uPE1hcmtQcm9wRmllbGREZWY8Rj4+O1xuXG4gIC8qKlxuICAgKiBPcGFjaXR5IG9mIHRoZSBtYXJrcyDigJMgZWl0aGVyIGNhbiBiZSBhIHZhbHVlIG9yIGEgcmFuZ2UuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBJZiB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IG9wYWNpdHkgZGVwZW5kcyBvbiBbbWFyayBjb25maWddKGNvbmZpZy5odG1sI21hcmspJ3MgYG9wYWNpdHlgIHByb3BlcnR5LlxuICAgKi9cbiAgb3BhY2l0eT86IEZpZWxkRGVmV2l0aENvbmRpdGlvbjxNYXJrUHJvcEZpZWxkRGVmPEY+PiB8IFZhbHVlRGVmV2l0aENvbmRpdGlvbjxNYXJrUHJvcEZpZWxkRGVmPEY+PjtcblxuICAvKipcbiAgICogU2l6ZSBvZiB0aGUgbWFyay5cbiAgICogLSBGb3IgYFwicG9pbnRcImAsIGBcInNxdWFyZVwiYCBhbmQgYFwiY2lyY2xlXCJgLCDigJMgdGhlIHN5bWJvbCBzaXplLCBvciBwaXhlbCBhcmVhIG9mIHRoZSBtYXJrLlxuICAgKiAtIEZvciBgXCJiYXJcImAgYW5kIGBcInRpY2tcImAg4oCTIHRoZSBiYXIgYW5kIHRpY2sncyBzaXplLlxuICAgKiAtIEZvciBgXCJ0ZXh0XCJgIOKAkyB0aGUgdGV4dCdzIGZvbnQgc2l6ZS5cbiAgICogLSBTaXplIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBmb3IgYFwibGluZVwiYCwgYFwiYXJlYVwiYCwgYW5kIGBcInJlY3RcImAuXG4gICAqL1xuICBzaXplPzogRmllbGREZWZXaXRoQ29uZGl0aW9uPE1hcmtQcm9wRmllbGREZWY8Rj4+IHwgVmFsdWVEZWZXaXRoQ29uZGl0aW9uPE1hcmtQcm9wRmllbGREZWY8Rj4+O1xuXG4gIC8qKlxuICAgKiBUaGUgc3ltYm9sJ3Mgc2hhcGUgKG9ubHkgZm9yIGBwb2ludGAgbWFya3MpLiBUaGUgc3VwcG9ydGVkIHZhbHVlcyBhcmVcbiAgICogYFwiY2lyY2xlXCJgIChkZWZhdWx0KSwgYFwic3F1YXJlXCJgLCBgXCJjcm9zc1wiYCwgYFwiZGlhbW9uZFwiYCwgYFwidHJpYW5nbGUtdXBcImAsXG4gICAqIG9yIGBcInRyaWFuZ2xlLWRvd25cImAsIG9yIGVsc2UgYSBjdXN0b20gU1ZHIHBhdGggc3RyaW5nLlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gSWYgdW5kZWZpbmVkLCB0aGUgZGVmYXVsdCBzaGFwZSBkZXBlbmRzIG9uIFttYXJrIGNvbmZpZ10oY29uZmlnLmh0bWwjcG9pbnQtY29uZmlnKSdzIGBzaGFwZWAgcHJvcGVydHkuXG4gICAqL1xuICBzaGFwZT86IEZpZWxkRGVmV2l0aENvbmRpdGlvbjxNYXJrUHJvcEZpZWxkRGVmPEY+PiB8IFZhbHVlRGVmV2l0aENvbmRpdGlvbjxNYXJrUHJvcEZpZWxkRGVmPEY+PjsgLy8gVE9ETzogbWF5YmUgZGlzdGluZ3Vpc2ggb3JkaW5hbC1vbmx5XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgbGV2ZWxzIG9mIGRldGFpbCBmb3IgZ3JvdXBpbmcgZGF0YSBpbiBhZ2dyZWdhdGUgdmlld3MgYW5kXG4gICAqIGluIGxpbmUgYW5kIGFyZWEgbWFya3Mgd2l0aG91dCBtYXBwaW5nIGRhdGEgdG8gYSBzcGVjaWZpYyB2aXN1YWwgY2hhbm5lbC5cbiAgICovXG4gIGRldGFpbD86IEZpZWxkRGVmPEY+IHwgRmllbGREZWY8Rj5bXTtcblxuICAvKipcbiAgICogVGV4dCBvZiB0aGUgYHRleHRgIG1hcmsuXG4gICAqL1xuICB0ZXh0PzogRmllbGREZWZXaXRoQ29uZGl0aW9uPFRleHRGaWVsZERlZjxGPj4gfCBWYWx1ZURlZldpdGhDb25kaXRpb248VGV4dEZpZWxkRGVmPEY+PjtcblxuICAvKipcbiAgICogVGhlIHRvb2x0aXAgdGV4dCB0byBzaG93IHVwb24gbW91c2UgaG92ZXIuXG4gICAqL1xuICB0b29sdGlwPzogRmllbGREZWZXaXRoQ29uZGl0aW9uPFRleHRGaWVsZERlZjxGPj4gfCBWYWx1ZURlZldpdGhDb25kaXRpb248VGV4dEZpZWxkRGVmPEY+PjtcblxuICAvKipcbiAgICogU3RhY2sgb3JkZXIgZm9yIHN0YWNrZWQgbWFya3Mgb3Igb3JkZXIgb2YgZGF0YSBwb2ludHMgaW4gbGluZSBtYXJrcyBmb3IgY29ubmVjdGVkIHNjYXR0ZXIgcGxvdHMuXG4gICAqXG4gICAqIF9fTm90ZV9fOiBJbiBhZ2dyZWdhdGUgcGxvdHMsIGBvcmRlcmAgZmllbGQgc2hvdWxkIGJlIGBhZ2dyZWdhdGVgZCB0byBhdm9pZCBjcmVhdGluZyBhZGRpdGlvbmFsIGFnZ3JlZ2F0aW9uIGdyb3VwaW5nLlxuICAgKi9cbiAgb3JkZXI/OiBPcmRlckZpZWxkRGVmPEY+IHwgT3JkZXJGaWVsZERlZjxGPltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVuY29kaW5nV2l0aEZhY2V0PEY+IGV4dGVuZHMgRW5jb2Rpbmc8Rj4sIEZhY2V0TWFwcGluZzxGPiB7fVxuXG5leHBvcnQgZnVuY3Rpb24gY2hhbm5lbEhhc0ZpZWxkKGVuY29kaW5nOiBFbmNvZGluZ1dpdGhGYWNldDxGaWVsZD4sIGNoYW5uZWw6IENoYW5uZWwpOiBib29sZWFuIHtcbiAgY29uc3QgY2hhbm5lbERlZiA9IGVuY29kaW5nICYmIGVuY29kaW5nW2NoYW5uZWxdO1xuICBpZiAoY2hhbm5lbERlZikge1xuICAgIGlmIChpc0FycmF5KGNoYW5uZWxEZWYpKSB7XG4gICAgICByZXR1cm4gc29tZShjaGFubmVsRGVmLCAoZmllbGREZWYpID0+ICEhZmllbGREZWYuZmllbGQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaXNGaWVsZERlZihjaGFubmVsRGVmKSB8fCBoYXNDb25kaXRpb25hbEZpZWxkRGVmKGNoYW5uZWxEZWYpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQWdncmVnYXRlKGVuY29kaW5nOiBFbmNvZGluZ1dpdGhGYWNldDxGaWVsZD4pIHtcbiAgcmV0dXJuIHNvbWUoQ0hBTk5FTFMsIChjaGFubmVsKSA9PiB7XG4gICAgaWYgKGNoYW5uZWxIYXNGaWVsZChlbmNvZGluZywgY2hhbm5lbCkpIHtcbiAgICAgIGNvbnN0IGNoYW5uZWxEZWYgPSBlbmNvZGluZ1tjaGFubmVsXTtcbiAgICAgIGlmIChpc0FycmF5KGNoYW5uZWxEZWYpKSB7XG4gICAgICAgIHJldHVybiBzb21lKGNoYW5uZWxEZWYsIChmaWVsZERlZikgPT4gISFmaWVsZERlZi5hZ2dyZWdhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZmllbGREZWYgPSBnZXRGaWVsZERlZihjaGFubmVsRGVmKTtcbiAgICAgICAgcmV0dXJuIGZpZWxkRGVmICYmICEhZmllbGREZWYuYWdncmVnYXRlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplRW5jb2RpbmcoZW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4sIG1hcms6IE1hcmspOiBFbmNvZGluZzxzdHJpbmc+IHtcbiAgcmV0dXJuIGtleXMoZW5jb2RpbmcpLnJlZHVjZSgobm9ybWFsaXplZEVuY29kaW5nOiBFbmNvZGluZzxzdHJpbmc+LCBjaGFubmVsOiBDaGFubmVsKSA9PiB7XG4gICAgaWYgKCFzdXBwb3J0TWFyayhjaGFubmVsLCBtYXJrKSkge1xuICAgICAgLy8gRHJvcCB1bnN1cHBvcnRlZCBjaGFubmVsXG5cbiAgICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmluY29tcGF0aWJsZUNoYW5uZWwoY2hhbm5lbCwgbWFyaykpO1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRFbmNvZGluZztcbiAgICB9XG5cbiAgICAvLyBEcm9wIGxpbmUncyBzaXplIGlmIHRoZSBmaWVsZCBpcyBhZ2dyZWdhdGVkLlxuICAgIGlmIChjaGFubmVsID09PSAnc2l6ZScgJiYgbWFyayA9PT0gJ2xpbmUnKSB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IGdldEZpZWxkRGVmKGVuY29kaW5nW2NoYW5uZWxdKTtcbiAgICAgIGlmIChmaWVsZERlZiAmJiBmaWVsZERlZi5hZ2dyZWdhdGUpIHtcbiAgICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuaW5jb21wYXRpYmxlQ2hhbm5lbChjaGFubmVsLCBtYXJrLCAnd2hlbiB0aGUgZmllbGQgaXMgYWdncmVnYXRlZC4nKSk7XG4gICAgICAgIHJldHVybiBub3JtYWxpemVkRW5jb2Rpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYW5uZWwgPT09ICdkZXRhaWwnIHx8IGNoYW5uZWwgPT09ICdvcmRlcicpIHtcbiAgICAgIGNvbnN0IGNoYW5uZWxEZWYgPSBlbmNvZGluZ1tjaGFubmVsXTtcbiAgICAgIGlmIChjaGFubmVsRGVmKSB7XG4gICAgICAgIC8vIEFycmF5IG9mIGZpZWxkRGVmcyBmb3IgZGV0YWlsIGNoYW5uZWwgKG9yIHByb2R1Y3Rpb24gcnVsZSlcbiAgICAgICAgbm9ybWFsaXplZEVuY29kaW5nW2NoYW5uZWxdID0gKGlzQXJyYXkoY2hhbm5lbERlZikgPyBjaGFubmVsRGVmIDogW2NoYW5uZWxEZWZdKVxuICAgICAgICAgIC5yZWR1Y2UoKGZpZWxkRGVmczogRmllbGREZWY8c3RyaW5nPltdLCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPikgPT4ge1xuICAgICAgICAgICAgaWYgKCFpc0ZpZWxkRGVmKGZpZWxkRGVmKSkge1xuICAgICAgICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5lbXB0eUZpZWxkRGVmKGZpZWxkRGVmLCBjaGFubmVsKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBmaWVsZERlZnMucHVzaChub3JtYWxpemVGaWVsZERlZihmaWVsZERlZiwgY2hhbm5lbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZpZWxkRGVmcztcbiAgICAgICAgICB9LCBbXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZJWE1FOiByZW1vdmUgdGhpcyBjYXN0aW5nLiAgKEkgZG9uJ3Qga25vdyB3aHkgVHlwZXNjcmlwdCBkb2Vzbid0IGluZmVyIHRoaXMgY29ycmVjdGx5IGhlcmUuKVxuICAgICAgY29uc3QgY2hhbm5lbERlZiA9IGVuY29kaW5nW2NoYW5uZWxdIGFzIENoYW5uZWxEZWY8c3RyaW5nPjtcbiAgICAgIGlmICghaXNGaWVsZERlZihjaGFubmVsRGVmKSAmJiAhaXNWYWx1ZURlZihjaGFubmVsRGVmKSAmJiAhaXNDb25kaXRpb25hbERlZihjaGFubmVsRGVmKSkge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5lbXB0eUZpZWxkRGVmKGNoYW5uZWxEZWYsIGNoYW5uZWwpKTtcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRFbmNvZGluZztcbiAgICAgIH1cbiAgICAgIG5vcm1hbGl6ZWRFbmNvZGluZ1tjaGFubmVsXSA9IG5vcm1hbGl6ZShjaGFubmVsRGVmLCBjaGFubmVsKTtcbiAgICB9XG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRFbmNvZGluZztcbiAgfSwge30pO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JhbmdlZChlbmNvZGluZzogRW5jb2RpbmdXaXRoRmFjZXQ8YW55Pikge1xuICByZXR1cm4gZW5jb2RpbmcgJiYgKCghIWVuY29kaW5nLnggJiYgISFlbmNvZGluZy54MikgfHwgKCEhZW5jb2RpbmcueSAmJiAhIWVuY29kaW5nLnkyKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaWVsZERlZnMoZW5jb2Rpbmc6IEVuY29kaW5nV2l0aEZhY2V0PEZpZWxkPik6IEZpZWxkRGVmPEZpZWxkPltdIHtcbiAgY29uc3QgYXJyOiBGaWVsZERlZjxGaWVsZD5bXSA9IFtdO1xuICBDSEFOTkVMUy5mb3JFYWNoKGZ1bmN0aW9uKGNoYW5uZWwpIHtcbiAgICBpZiAoY2hhbm5lbEhhc0ZpZWxkKGVuY29kaW5nLCBjaGFubmVsKSkge1xuICAgICAgY29uc3QgY2hhbm5lbERlZiA9IGVuY29kaW5nW2NoYW5uZWxdO1xuICAgICAgKGlzQXJyYXkoY2hhbm5lbERlZikgPyBjaGFubmVsRGVmIDogW2NoYW5uZWxEZWZdKS5mb3JFYWNoKChkZWYpID0+IHtcbiAgICAgICAgaWYgKGlzRmllbGREZWYoZGVmKSkge1xuICAgICAgICAgIGFyci5wdXNoKGRlZik7XG4gICAgICAgIH0gZWxzZSBpZiAoaGFzQ29uZGl0aW9uYWxGaWVsZERlZihkZWYpKSB7XG4gICAgICAgICAgYXJyLnB1c2goZGVmLmNvbmRpdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBhcnI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JFYWNoKG1hcHBpbmc6IGFueSxcbiAgICBmOiAoZmQ6IEZpZWxkRGVmPHN0cmluZz4sIGM6IENoYW5uZWwpID0+IHZvaWQsXG4gICAgdGhpc0FyZz86IGFueSkge1xuICBpZiAoIW1hcHBpbmcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKGNvbnN0IGNoYW5uZWwgb2Yga2V5cyhtYXBwaW5nKSkge1xuICAgIGlmIChpc0FycmF5KG1hcHBpbmdbY2hhbm5lbF0pKSB7XG4gICAgICBtYXBwaW5nW2NoYW5uZWxdLmZvckVhY2goZnVuY3Rpb24oY2hhbm5lbERlZjogQ2hhbm5lbERlZjxzdHJpbmc+KSB7XG4gICAgICAgIGYuY2FsbCh0aGlzQXJnLCBjaGFubmVsRGVmLCBjaGFubmVsKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmLmNhbGwodGhpc0FyZywgbWFwcGluZ1tjaGFubmVsXSwgY2hhbm5lbCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWR1Y2U8VCwgVSBleHRlbmRzIHtbayBpbiBDaGFubmVsXT86IGFueX0+KG1hcHBpbmc6IFUsXG4gICAgZjogKGFjYzogYW55LCBmZDogRmllbGREZWY8c3RyaW5nPiwgYzogQ2hhbm5lbCkgPT4gVSxcbiAgICBpbml0OiBULCB0aGlzQXJnPzogYW55KSB7XG4gIGlmICghbWFwcGluZykge1xuICAgIHJldHVybiBpbml0O1xuICB9XG5cbiAgcmV0dXJuIGtleXMobWFwcGluZykucmVkdWNlKChyLCBjaGFubmVsKSA9PiB7XG4gICAgY29uc3QgbWFwID0gbWFwcGluZ1tjaGFubmVsXTtcbiAgICBpZiAoaXNBcnJheShtYXApKSB7XG4gICAgICByZXR1cm4gbWFwLnJlZHVjZSgocjE6IFQsIGNoYW5uZWxEZWY6IENoYW5uZWxEZWY8c3RyaW5nPikgPT4ge1xuICAgICAgICByZXR1cm4gZi5jYWxsKHRoaXNBcmcsIHIxLCBjaGFubmVsRGVmLCBjaGFubmVsKTtcbiAgICAgIH0sIHIpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZi5jYWxsKHRoaXNBcmcsIHIsIG1hcCwgY2hhbm5lbCk7XG4gICAgfVxuICB9LCBpbml0KTtcbn1cbiJdfQ== \ 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..c16e8ce6e0 --- /dev/null +++ b/build/src/facet.d.ts @@ -0,0 +1,38 @@ +import { FieldDef } from './fielddef'; +import { Guide } from './guide'; +import { SortOrder } from './sort'; +/** + * Headers of row / column channels for faceted plots. + */ +export interface Header extends Guide { + /** + * The rotation angle of the header labels. + * + * __Default value:__ `0`. + * + * @minimum -360 + * @maximum 360 + */ + labelAngle?: number; +} +export interface FacetFieldDef extends FieldDef { + /** + * An object defining properties of a facet's header. + */ + header?: Header; + /** + * Sort order for a facet field. + * This can be `"ascending"`, `"descending"`. + */ + sort?: SortOrder; +} +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..bc4373f4dc --- /dev/null +++ b/build/src/facet.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFjZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RmllbGREZWZ9IGZyb20gJy4vZmllbGRkZWYnO1xuaW1wb3J0IHtHdWlkZX0gZnJvbSAnLi9ndWlkZSc7XG5pbXBvcnQge1NvcnRPcmRlcn0gZnJvbSAnLi9zb3J0JztcblxuXG4vKipcbiAqIEhlYWRlcnMgb2Ygcm93IC8gY29sdW1uIGNoYW5uZWxzIGZvciBmYWNldGVkIHBsb3RzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhlYWRlciBleHRlbmRzIEd1aWRlIHtcbiAgLyoqXG4gICAqIFRoZSByb3RhdGlvbiBhbmdsZSBvZiB0aGUgaGVhZGVyIGxhYmVscy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAwYC5cbiAgICpcbiAgICogQG1pbmltdW0gLTM2MFxuICAgKiBAbWF4aW11bSAzNjBcbiAgICovXG4gIGxhYmVsQW5nbGU/OiBudW1iZXI7XG5cbiAgLy8gVE9ETzogbGFiZWxQYWRkaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmFjZXRGaWVsZERlZjxGPiBleHRlbmRzIEZpZWxkRGVmPEY+IHtcbiAgLyoqXG4gICAqIEFuIG9iamVjdCBkZWZpbmluZyBwcm9wZXJ0aWVzIG9mIGEgZmFjZXQncyBoZWFkZXIuXG4gICAqL1xuICBoZWFkZXI/OiBIZWFkZXI7XG5cbiAgLyoqXG4gICAqIFNvcnQgb3JkZXIgZm9yIGEgZmFjZXQgZmllbGQuXG4gICAqIFRoaXMgY2FuIGJlIGBcImFzY2VuZGluZ1wiYCwgYFwiZGVzY2VuZGluZ1wiYC5cbiAgICovXG4gIHNvcnQ/OiBTb3J0T3JkZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmFjZXRNYXBwaW5nPEY+IHtcblxuICAvKipcbiAgICogVmVydGljYWwgZmFjZXRzIGZvciB0cmVsbGlzIHBsb3RzLlxuICAgKi9cbiAgcm93PzogRmFjZXRGaWVsZERlZjxGPjtcblxuICAvKipcbiAgICogSG9yaXpvbnRhbCBmYWNldHMgZm9yIHRyZWxsaXMgcGxvdHMuXG4gICAqL1xuICBjb2x1bW4/OiBGYWNldEZpZWxkRGVmPEY+O1xufVxuIl19 \ 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..ac1168d1f6 --- /dev/null +++ b/build/src/fielddef.d.ts @@ -0,0 +1,246 @@ +import { AggregateOp } from './aggregate'; +import { Axis } from './axis'; +import { BinParams } from './bin'; +import { Channel } from './channel'; +import { CompositeAggregate } from './compositemark'; +import { Config } from './config'; +import { Legend } from './legend'; +import { LogicalOperand } from './logical'; +import { Scale } from './scale'; +import { SortField, SortOrder } from './sort'; +import { StackOffset } from './stack'; +import { TimeUnit } from './timeunit'; +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 = { + /** + * A [selection name](selection.html), or a series of [composed selections](selection.html#compose). + */ + selection: LogicalOperand; +} & T; +/** + * A FieldDef with Condition + * { + * condition: {value: ...}, + * field: ..., + * ... + * } + */ +export declare type FieldDefWithCondition> = F & { + /** + * One or more value definition(s) with a selection predicate. + * + * __Note:__ A field definition's `condition` property can only contain [value definitions](encoding.html#value-def) + * since Vega-Lite only allows at mosty one encoded field per encoding channel. + */ + condition?: Conditional | Conditional[]; +}; +/** + * 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`](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](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](type.html#cast). + * + * __Default value:__ `undefined` (None) + */ + timeUnit?: TimeUnit; + /** + * A flag for binning a `quantitative` field, or [an object defining binning parameters](bin.html#params). + * If `true`, default [binning parameters](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; +} +/** + * Definition object for a data field, its type and transformation of an encoding channel. + */ +export interface FieldDef extends FieldDefBase { + /** + * The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or `"nominal"`). + */ + type: Type; +} +export interface ScaleFieldDef extends FieldDef { + /** + * 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. + * + * __Default value:__ If undefined, default [scale properties](scale.html) are applied. + */ + scale?: Scale; + /** + * Sort order for the encoded field. + * Supported `sort` values include `"ascending"`, `"descending"` and `null` (no sorting). + * For fields with discrete domains, `sort` can also be a [sort field definition object](sort.html#sort-field). + * + * __Default value:__ `"ascending"` + */ + sort?: SortOrder | SortField | 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](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](stack.html#bar) and [area](stack.html#area) chart). + * - `"normalize"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](stack.html#normalized).
+ * -`"center"` - stacking with center baseline (for [streamgraph](stack.html#streamgraph)). + * - `null` - No-stacking. This will produce layered [bar](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](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](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 | 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; + /** Overrride which aggregate to use. Needed for unaggregated domain. */ + aggregate?: AggregateOp; +} +export declare function field(fieldDef: FieldDefBase, 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: FieldDef, config: Config) => string; +export declare function verbalTitleFormatter(fieldDef: FieldDef, config: Config): string; +export declare function functionalTitleFormatter(fieldDef: FieldDef, config: Config): string; +export declare const defaultTitleFormatter: FieldTitleFormatter; +export declare function setTitleFormatter(formatter: (fieldDef: FieldDef, config: Config) => string): void; +export declare function resetTitleFormatter(): void; +export declare function title(fieldDef: FieldDef, 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; diff --git a/build/src/fielddef.js b/build/src/fielddef.js new file mode 100644 index 0000000000..c40fe84fab --- /dev/null +++ b/build/src/fielddef.js @@ -0,0 +1,342 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Declaration and utility for variants of a field definition object +var aggregate_1 = require("./aggregate"); +var bin_1 = require("./bin"); +var channel_1 = require("./channel"); +var log = require("./log"); +var timeunit_1 = require("./timeunit"); +var type_1 = require("./type"); +var util_1 = require("./util"); +function isRepeatRef(field) { + return field && !util_1.isString(field) && 'repeat' in field; +} +exports.isRepeatRef = isRepeatRef; +function isConditionalDef(channelDef) { + return !!channelDef && !!channelDef.condition; +} +exports.isConditionalDef = isConditionalDef; +/** + * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef + */ +function hasConditionalFieldDef(channelDef) { + return !!channelDef && !!channelDef.condition && !util_1.isArray(channelDef.condition) && isFieldDef(channelDef.condition); +} +exports.hasConditionalFieldDef = hasConditionalFieldDef; +function hasConditionalValueDef(channelDef) { + return !!channelDef && !!channelDef.condition && (util_1.isArray(channelDef.condition) || isValueDef(channelDef.condition)); +} +exports.hasConditionalValueDef = hasConditionalValueDef; +function isFieldDef(channelDef) { + return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); +} +exports.isFieldDef = isFieldDef; +function isStringFieldDef(fieldDef) { + return isFieldDef(fieldDef) && util_1.isString(fieldDef.field); +} +exports.isStringFieldDef = isStringFieldDef; +function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; +} +exports.isValueDef = isValueDef; +function isScaleFieldDef(channelDef) { + return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']); +} +exports.isScaleFieldDef = isScaleFieldDef; +function field(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 (fieldDef.bin) { + fn = bin_1.binToString(fieldDef.bin); + suffix = opt.binSuffix || ''; + } + else if (fieldDef.aggregate) { + fn = String(opt.aggregate || fieldDef.aggregate); + } + else if (fieldDef.timeUnit) { + fn = String(fieldDef.timeUnit); + } + } + if (fn) { + field = fn + "_" + field; + } + } + if (suffix) { + field = field + "_" + suffix; + } + if (prefix) { + field = prefix + "_" + field; + } + if (opt.expr) { + field = "" + opt.expr + util_1.accessPath(field); + } + return field; +} +exports.field = field; +function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'temporal': + return false; + } + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +exports.isDiscrete = isDiscrete; +function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); +} +exports.isContinuous = isContinuous; +function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; +} +exports.isCount = isCount; +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 = timeunit_1.getTimeUnitParts(timeUnit).join('-'); + return field + " (" + units + ")"; + } + else if (aggregate) { + return util_1.titlecase(aggregate) + " of " + field; + } + return field; +} +exports.verbalTitleFormatter = verbalTitleFormatter; +function functionalTitleFormatter(fieldDef, config) { + var fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin'); + if (fn) { + return fn.toUpperCase() + '(' + fieldDef.field + ')'; + } + else { + return fieldDef.field; + } +} +exports.functionalTitleFormatter = functionalTitleFormatter; +exports.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 = exports.defaultTitleFormatter; +function setTitleFormatter(formatter) { + titleFormatter = formatter; +} +exports.setTitleFormatter = setTitleFormatter; +function resetTitleFormatter() { + setTitleFormatter(exports.defaultTitleFormatter); +} +exports.resetTitleFormatter = resetTitleFormatter; +function title(fieldDef, config) { + return titleFormatter(fieldDef, config); +} +exports.title = title; +function defaultType(fieldDef, channel) { + if (fieldDef.timeUnit) { + return 'temporal'; + } + if (fieldDef.bin) { + return 'quantitative'; + } + switch (channel_1.rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible':// color + return 'nominal'; + default: + return 'quantitative'; + } +} +exports.defaultType = defaultType; +/** + * 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; +} +exports.getFieldDef = getFieldDef; +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +function normalize(channelDef, channel) { + if (util_1.isString(channelDef) || util_1.isNumber(channelDef) || util_1.isBoolean(channelDef)) { + var primitiveType = util_1.isString(channelDef) ? 'string' : + util_1.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 __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; +} +exports.normalize = normalize; +function normalizeFieldDef(fieldDef, channel) { + // Drop invalid aggregate + if (fieldDef.aggregate && !aggregate_1.isAggregateOp(fieldDef.aggregate)) { + var aggregate = fieldDef.aggregate, fieldDefWithoutAggregate = __rest(fieldDef, ["aggregate"]); + log.warn(log.message.invalidAggregate(fieldDef.aggregate)); + fieldDef = fieldDefWithoutAggregate; + } + // Normalize Time Unit + if (fieldDef.timeUnit) { + fieldDef = __assign({}, fieldDef, { timeUnit: timeunit_1.normalizeTimeUnit(fieldDef.timeUnit) }); + } + // Normalize bin + if (fieldDef.bin) { + fieldDef = __assign({}, fieldDef, { bin: normalizeBin(fieldDef.bin, channel) }); + } + // Normalize Type + if (fieldDef.type) { + var fullType = type_1.getFullName(fieldDef.type); + if (fieldDef.type !== fullType) { + // convert short type to full type + fieldDef = __assign({}, fieldDef, { type: fullType }); + } + if (fieldDef.type !== 'quantitative') { + if (aggregate_1.isCountingAggregateOp(fieldDef.aggregate)) { + log.warn(log.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); + log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType)); + fieldDef = __assign({}, fieldDef, { type: newType }); + } + var _a = channelCompatibility(fieldDef, channel), compatible = _a.compatible, warning = _a.warning; + if (!compatible) { + log.warn(warning); + } + return fieldDef; +} +exports.normalizeFieldDef = normalizeFieldDef; +function normalizeBin(bin, channel) { + if (util_1.isBoolean(bin)) { + return { maxbins: bin_1.autoMaxBins(channel) }; + } + else if (!bin.maxbins && !bin.step) { + return __assign({}, bin, { maxbins: bin_1.autoMaxBins(channel) }); + } + else { + return bin; + } +} +exports.normalizeBin = normalizeBin; +var COMPATIBLE = { compatible: true }; +function channelCompatibility(fieldDef, channel) { + switch (channel) { + case 'row': + case 'column': + if (isContinuous(fieldDef) && !fieldDef.timeUnit) { + // TODO:(https://github.com/vega/vega-lite/issues/2011): + // with timeUnit it's not always strictly continuous + return { + compatible: false, + warning: log.message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'text': + case 'detail': + case 'tooltip': + return COMPATIBLE; + case 'opacity': + case 'size': + case 'x2': + case 'y2': + if (isDiscrete(fieldDef) && !fieldDef.bin) { + return { + compatible: false, + warning: "Channel " + channel + " should not be used with discrete field." + }; + } + return COMPATIBLE; + case 'shape': + if (fieldDef.type !== 'nominal') { + return { + compatible: false, + warning: 'Shape channel should be used with nominal data only' + }; + } + return COMPATIBLE; + case 'order': + if (fieldDef.type === 'nominal') { + 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); +} +exports.channelCompatibility = channelCompatibility; +function isNumberFieldDef(fieldDef) { + return fieldDef.type === 'quantitative' || !!fieldDef.bin; +} +exports.isNumberFieldDef = isNumberFieldDef; +function isTimeFieldDef(fieldDef) { + return fieldDef.type === 'temporal' || !!fieldDef.timeUnit; +} +exports.isTimeFieldDef = isTimeFieldDef; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRkZWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmllbGRkZWYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9FQUFvRTtBQUNwRSx5Q0FBOEU7QUFFOUUsNkJBQTBEO0FBQzFELHFDQUE2QztBQUk3QywyQkFBNkI7QUFLN0IsdUNBQXlFO0FBQ3pFLCtCQUF5QztBQUN6QywrQkFBcUY7QUF5RXJGLHFCQUE0QixLQUFZO0lBQ3RDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxlQUFRLENBQUMsS0FBSyxDQUFDLElBQUksUUFBUSxJQUFJLEtBQUssQ0FBQztBQUN4RCxDQUFDO0FBRkQsa0NBRUM7QUE0SUQsMEJBQW9DLFVBQXlCO0lBQzNELE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDO0FBQ2hELENBQUM7QUFGRCw0Q0FFQztBQUVEOztHQUVHO0FBQ0gsZ0NBQTBDLFVBQXlCO0lBQ2pFLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxJQUFJLENBQUMsY0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ3RILENBQUM7QUFGRCx3REFFQztBQUVELGdDQUEwQyxVQUF5QjtJQUNqRSxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsSUFBSSxDQUMvQyxjQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQ2xFLENBQUM7QUFDSixDQUFDO0FBSkQsd0RBSUM7QUFFRCxvQkFBOEIsVUFBeUI7SUFDckQsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLENB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QixPQUFPLEVBQUUsYUFBVyxPQUFPLDZDQUEwQztpQkFDdEUsQ0FBQztZQUNKLENBQUM7WUFDRCxNQUFNLENBQUMsVUFBVSxDQUFDO1FBRXBCLEtBQUssT0FBTztZQUNWLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztnQkFDaEMsTUFBTSxDQUFDO29CQUNMLFVBQVUsRUFBRSxLQUFLO29CQUNqQixPQUFPLEVBQUUscURBQXFEO2lCQUMvRCxDQUFDO1lBQ0osQ0FBQztZQUNELE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFFcEIsS0FBSyxPQUFPO1lBQ1YsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUNoQyxNQUFNLENBQUM7b0JBQ0wsVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLE9BQU8sRUFBRSxnRkFBZ0Y7aUJBQzFGLENBQUM7WUFDSixDQUFDO1lBQ0QsTUFBTSxDQUFDLFVBQVUsQ0FBQztJQUN0QixDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxtREFBbUQsR0FBRyxPQUFPLENBQUMsQ0FBQztBQUNqRixDQUFDO0FBckRELG9EQXFEQztBQUVELDBCQUFpQyxRQUF1QjtJQUN0RCxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxjQUFjLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7QUFDNUQsQ0FBQztBQUZELDRDQUVDO0FBRUQsd0JBQStCLFFBQXVCO0lBQ3BELE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztBQUM3RCxDQUFDO0FBRkQsd0NBRUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBEZWNsYXJhdGlvbiBhbmQgdXRpbGl0eSBmb3IgdmFyaWFudHMgb2YgYSBmaWVsZCBkZWZpbml0aW9uIG9iamVjdFxuaW1wb3J0IHtBZ2dyZWdhdGVPcCwgaXNBZ2dyZWdhdGVPcCwgaXNDb3VudGluZ0FnZ3JlZ2F0ZU9wfSBmcm9tICcuL2FnZ3JlZ2F0ZSc7XG5pbXBvcnQge0F4aXN9IGZyb20gJy4vYXhpcyc7XG5pbXBvcnQge2F1dG9NYXhCaW5zLCBCaW5QYXJhbXMsIGJpblRvU3RyaW5nfSBmcm9tICcuL2Jpbic7XG5pbXBvcnQge0NoYW5uZWwsIHJhbmdlVHlwZX0gZnJvbSAnLi9jaGFubmVsJztcbmltcG9ydCB7Q29tcG9zaXRlQWdncmVnYXRlfSBmcm9tICcuL2NvbXBvc2l0ZW1hcmsnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7TGVnZW5kfSBmcm9tICcuL2xlZ2VuZCc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi9sb2cnO1xuaW1wb3J0IHtMb2dpY2FsT3BlcmFuZH0gZnJvbSAnLi9sb2dpY2FsJztcbmltcG9ydCB7U2NhbGV9IGZyb20gJy4vc2NhbGUnO1xuaW1wb3J0IHtTb3J0RmllbGQsIFNvcnRPcmRlcn0gZnJvbSAnLi9zb3J0JztcbmltcG9ydCB7U3RhY2tPZmZzZXR9IGZyb20gJy4vc3RhY2snO1xuaW1wb3J0IHtnZXRUaW1lVW5pdFBhcnRzLCBub3JtYWxpemVUaW1lVW5pdCwgVGltZVVuaXR9IGZyb20gJy4vdGltZXVuaXQnO1xuaW1wb3J0IHtnZXRGdWxsTmFtZSwgVHlwZX0gZnJvbSAnLi90eXBlJztcbmltcG9ydCB7YWNjZXNzUGF0aCwgaXNBcnJheSwgaXNCb29sZWFuLCBpc051bWJlciwgaXNTdHJpbmcsIHRpdGxlY2FzZX0gZnJvbSAnLi91dGlsJztcblxuXG4vKipcbiAqIERlZmluaXRpb24gb2JqZWN0IGZvciBhIGNvbnN0YW50IHZhbHVlIG9mIGFuIGVuY29kaW5nIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmFsdWVEZWYge1xuICAvKipcbiAgICogQSBjb25zdGFudCB2YWx1ZSBpbiB2aXN1YWwgZG9tYWluIChlLmcuLCBgXCJyZWRcImAgLyBcIiMwMDk5ZmZcIiBmb3IgY29sb3IsIHZhbHVlcyBiZXR3ZWVuIGAwYCB0byBgMWAgZm9yIG9wYWNpdHkpLlxuICAgKi9cbiAgdmFsdWU6IG51bWJlciB8IHN0cmluZyB8IGJvb2xlYW47XG59XG5cbi8qKlxuICogR2VuZXJpYyB0eXBlIGZvciBjb25kaXRpb25hbCBjaGFubmVsRGVmLlxuICogRiBkZWZpbmVzIHRoZSB1bmRlcmx5aW5nIEZpZWxkRGVmIHR5cGUuXG4gKi9cbmV4cG9ydCB0eXBlIENoYW5uZWxEZWZXaXRoQ29uZGl0aW9uPEYgZXh0ZW5kcyBGaWVsZERlZjxhbnk+PiA9IEZpZWxkRGVmV2l0aENvbmRpdGlvbjxGPiB8IFZhbHVlRGVmV2l0aENvbmRpdGlvbjxGPjtcblxuXG5leHBvcnQgdHlwZSBDb25kaXRpb25hbDxUPiA9IHtcbiAgLyoqXG4gICAqIEEgW3NlbGVjdGlvbiBuYW1lXShzZWxlY3Rpb24uaHRtbCksIG9yIGEgc2VyaWVzIG9mIFtjb21wb3NlZCBzZWxlY3Rpb25zXShzZWxlY3Rpb24uaHRtbCNjb21wb3NlKS5cbiAgICovXG4gIHNlbGVjdGlvbjogTG9naWNhbE9wZXJhbmQ8c3RyaW5nPjtcbn0gJiBUO1xuXG4vKipcbiAqIEEgRmllbGREZWYgd2l0aCBDb25kaXRpb248VmFsdWVEZWY+XG4gKiB7XG4gKiAgIGNvbmRpdGlvbjoge3ZhbHVlOiAuLi59LFxuICogICBmaWVsZDogLi4uLFxuICogICAuLi5cbiAqIH1cbiAqL1xuZXhwb3J0IHR5cGUgRmllbGREZWZXaXRoQ29uZGl0aW9uPEYgZXh0ZW5kcyBGaWVsZERlZjxhbnk+PiA9IEYgJiB7XG4gIC8qKlxuICAgKiBPbmUgb3IgbW9yZSB2YWx1ZSBkZWZpbml0aW9uKHMpIHdpdGggYSBzZWxlY3Rpb24gcHJlZGljYXRlLlxuICAgKlxuICAgKiBfX05vdGU6X18gQSBmaWVsZCBkZWZpbml0aW9uJ3MgYGNvbmRpdGlvbmAgcHJvcGVydHkgY2FuIG9ubHkgY29udGFpbiBbdmFsdWUgZGVmaW5pdGlvbnNdKGVuY29kaW5nLmh0bWwjdmFsdWUtZGVmKVxuICAgKiBzaW5jZSBWZWdhLUxpdGUgb25seSBhbGxvd3MgYXQgbW9zdHkgIG9uZSBlbmNvZGVkIGZpZWxkIHBlciBlbmNvZGluZyBjaGFubmVsLlxuICAgKi9cbiAgY29uZGl0aW9uPzogQ29uZGl0aW9uYWw8VmFsdWVEZWY+IHwgQ29uZGl0aW9uYWw8VmFsdWVEZWY+W107XG59O1xuXG4vKipcbiAqIEEgVmFsdWVEZWYgd2l0aCBDb25kaXRpb248VmFsdWVEZWYgfCBGaWVsZERlZj5cbiAqIHtcbiAqICAgY29uZGl0aW9uOiB7ZmllbGQ6IC4uLn0gfCB7dmFsdWU6IC4uLn0sXG4gKiAgIHZhbHVlOiAuLi4sXG4gKiB9XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmFsdWVEZWZXaXRoQ29uZGl0aW9uPEYgZXh0ZW5kcyBGaWVsZERlZjxhbnk+PiB7XG4gIC8qKlxuICAgKiBBIGZpZWxkIGRlZmluaXRpb24gb3Igb25lIG9yIG1vcmUgdmFsdWUgZGVmaW5pdGlvbihzKSB3aXRoIGEgc2VsZWN0aW9uIHByZWRpY2F0ZS5cbiAgICovXG4gIGNvbmRpdGlvbj86IENvbmRpdGlvbmFsPEY+IHwgQ29uZGl0aW9uYWw8VmFsdWVEZWY+IHwgQ29uZGl0aW9uYWw8VmFsdWVEZWY+W107XG5cbiAgLyoqXG4gICAqIEEgY29uc3RhbnQgdmFsdWUgaW4gdmlzdWFsIGRvbWFpbi5cbiAgICovXG4gIHZhbHVlPzogbnVtYmVyIHwgc3RyaW5nIHwgYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSZWZlcmVuY2UgdG8gYSByZXBlYXRlZCB2YWx1ZS5cbiAqL1xuZXhwb3J0IHR5cGUgUmVwZWF0UmVmID0ge1xuICByZXBlYXQ6ICdyb3cnIHwgJ2NvbHVtbidcbn07XG5cbmV4cG9ydCB0eXBlIEZpZWxkID0gc3RyaW5nIHwgUmVwZWF0UmVmO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXBlYXRSZWYoZmllbGQ6IEZpZWxkKTogZmllbGQgaXMgUmVwZWF0UmVmIHtcbiAgcmV0dXJuIGZpZWxkICYmICFpc1N0cmluZyhmaWVsZCkgJiYgJ3JlcGVhdCcgaW4gZmllbGQ7XG59XG5cbi8qKiBAaGlkZSAqL1xuZXhwb3J0IHR5cGUgSGlkZGVuQ29tcG9zaXRlQWdncmVnYXRlID0gQ29tcG9zaXRlQWdncmVnYXRlO1xuXG5leHBvcnQgdHlwZSBBZ2dyZWdhdGUgPSBBZ2dyZWdhdGVPcCB8IEhpZGRlbkNvbXBvc2l0ZUFnZ3JlZ2F0ZTtcblxuZXhwb3J0IGludGVyZmFjZSBGaWVsZERlZkJhc2U8Rj4ge1xuXG4gIC8qKlxuICAgKiBfX1JlcXVpcmVkLl9fIEEgc3RyaW5nIGRlZmluaW5nIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCBmcm9tIHdoaWNoIHRvIHB1bGwgYSBkYXRhIHZhbHVlXG4gICAqIG9yIGFuIG9iamVjdCBkZWZpbmluZyBpdGVyYXRlZCB2YWx1ZXMgZnJvbSB0aGUgW2ByZXBlYXRgXShyZXBlYXQuaHRtbCkgb3BlcmF0b3IuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBEb3RzIChgLmApIGFuZCBicmFja2V0cyAoYFtgIGFuZCBgXWApIGNhbiBiZSB1c2VkIHRvIGFjY2VzcyBuZXN0ZWQgb2JqZWN0cyAoZS5nLiwgYFwiZmllbGRcIjogXCJmb28uYmFyXCJgIGFuZCBgXCJmaWVsZFwiOiBcImZvb1snYmFyJ11cImApLlxuICAgKiBJZiBmaWVsZCBuYW1lcyBjb250YWluIGRvdHMgb3IgYnJhY2tldHMgYnV0IGFyZSBub3QgbmVzdGVkLCB5b3UgY2FuIHVzZSBgXFxcXGAgdG8gZXNjYXBlIGRvdHMgYW5kIGJyYWNrZXRzIChlLmcuLCBgXCJhXFxcXC5iXCJgIGFuZCBgXCJhXFxcXFswXFxcXF1cImApLlxuICAgKiBTZWUgbW9yZSBkZXRhaWxzIGFib3V0IGVzY2FwaW5nIGluIHRoZSBbZmllbGQgZG9jdW1lbnRhdGlvbl0oZmllbGQuaHRtbCkuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBgZmllbGRgIGlzIG5vdCByZXF1aXJlZCBpZiBgYWdncmVnYXRlYCBpcyBgY291bnRgLlxuICAgKi9cbiAgZmllbGQ/OiBGO1xuXG4gIC8vIGZ1bmN0aW9uXG5cbiAgLyoqXG4gICAqIFRpbWUgdW5pdCAoZS5nLiwgYHllYXJgLCBgeWVhcm1vbnRoYCwgYG1vbnRoYCwgYGhvdXJzYCkgZm9yIGEgdGVtcG9yYWwgZmllbGQuXG4gICAqIG9yIFthIHRlbXBvcmFsIGZpZWxkIHRoYXQgZ2V0cyBjYXN0ZWQgYXMgb3JkaW5hbF0odHlwZS5odG1sI2Nhc3QpLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYHVuZGVmaW5lZGAgKE5vbmUpXG4gICAqL1xuICB0aW1lVW5pdD86IFRpbWVVbml0O1xuXG4gIC8qKlxuICAgKiBBIGZsYWcgZm9yIGJpbm5pbmcgYSBgcXVhbnRpdGF0aXZlYCBmaWVsZCwgb3IgW2FuIG9iamVjdCBkZWZpbmluZyBiaW5uaW5nIHBhcmFtZXRlcnNdKGJpbi5odG1sI3BhcmFtcykuXG4gICAqIElmIGB0cnVlYCwgZGVmYXVsdCBbYmlubmluZyBwYXJhbWV0ZXJzXShiaW4uaHRtbCkgd2lsbCBiZSBhcHBsaWVkLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYGZhbHNlYFxuICAgKi9cbiAgYmluPzogYm9vbGVhbiB8IEJpblBhcmFtcztcblxuICAvKipcbiAgICogQWdncmVnYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBmaWVsZFxuICAgKiAoZS5nLiwgYG1lYW5gLCBgc3VtYCwgYG1lZGlhbmAsIGBtaW5gLCBgbWF4YCwgYGNvdW50YCkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgdW5kZWZpbmVkYCAoTm9uZSlcbiAgICpcbiAgICovXG4gIGFnZ3JlZ2F0ZT86IEFnZ3JlZ2F0ZTtcbn1cblxuLyoqXG4gKiAgRGVmaW5pdGlvbiBvYmplY3QgZm9yIGEgZGF0YSBmaWVsZCwgaXRzIHR5cGUgYW5kIHRyYW5zZm9ybWF0aW9uIG9mIGFuIGVuY29kaW5nIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmllbGREZWY8Rj4gZXh0ZW5kcyBGaWVsZERlZkJhc2U8Rj4ge1xuICAvKipcbiAgICogVGhlIGVuY29kZWQgZmllbGQncyB0eXBlIG9mIG1lYXN1cmVtZW50IChgXCJxdWFudGl0YXRpdmVcImAsIGBcInRlbXBvcmFsXCJgLCBgXCJvcmRpbmFsXCJgLCBvciBgXCJub21pbmFsXCJgKS5cbiAgICovXG4gIC8vICogb3IgYW4gaW5pdGlhbCBjaGFyYWN0ZXIgb2YgdGhlIHR5cGUgbmFtZSAoYFwiUVwiYCwgYFwiVFwiYCwgYFwiT1wiYCwgYFwiTlwiYCkuXG4gIC8vICogVGhpcyBwcm9wZXJ0eSBpcyBjYXNlLWluc2Vuc2l0aXZlLlxuICB0eXBlOiBUeXBlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNjYWxlRmllbGREZWY8Rj4gZXh0ZW5kcyBGaWVsZERlZjxGPiB7XG4gIC8qKlxuICAgKiBBbiBvYmplY3QgZGVmaW5pbmcgcHJvcGVydGllcyBvZiB0aGUgY2hhbm5lbCdzIHNjYWxlLCB3aGljaCBpcyB0aGUgZnVuY3Rpb24gdGhhdCB0cmFuc2Zvcm1zIHZhbHVlcyBpbiB0aGUgZGF0YSBkb21haW4gKG51bWJlcnMsIGRhdGVzLCBzdHJpbmdzLCBldGMpIHRvIHZpc3VhbCB2YWx1ZXMgKHBpeGVscywgY29sb3JzLCBzaXplcykgb2YgdGhlIGVuY29kaW5nIGNoYW5uZWxzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gSWYgdW5kZWZpbmVkLCBkZWZhdWx0IFtzY2FsZSBwcm9wZXJ0aWVzXShzY2FsZS5odG1sKSBhcmUgYXBwbGllZC5cbiAgICovXG4gIHNjYWxlPzogU2NhbGU7XG5cbiAgLyoqXG4gICAqIFNvcnQgb3JkZXIgZm9yIHRoZSBlbmNvZGVkIGZpZWxkLlxuICAgKiBTdXBwb3J0ZWQgYHNvcnRgIHZhbHVlcyBpbmNsdWRlIGBcImFzY2VuZGluZ1wiYCwgYFwiZGVzY2VuZGluZ1wiYCBhbmQgYG51bGxgIChubyBzb3J0aW5nKS5cbiAgICogRm9yIGZpZWxkcyB3aXRoIGRpc2NyZXRlIGRvbWFpbnMsIGBzb3J0YCBjYW4gYWxzbyBiZSBhIFtzb3J0IGZpZWxkIGRlZmluaXRpb24gb2JqZWN0XShzb3J0Lmh0bWwjc29ydC1maWVsZCkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgXCJhc2NlbmRpbmdcImBcbiAgICovXG4gIHNvcnQ/OiBTb3J0T3JkZXIgfCBTb3J0RmllbGQ8Rj4gfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBvc2l0aW9uRmllbGREZWY8Rj4gZXh0ZW5kcyBTY2FsZUZpZWxkRGVmPEY+IHtcbiAgLyoqXG4gICAqIEFuIG9iamVjdCBkZWZpbmluZyBwcm9wZXJ0aWVzIG9mIGF4aXMncyBncmlkbGluZXMsIHRpY2tzIGFuZCBsYWJlbHMuXG4gICAqIElmIGBudWxsYCwgdGhlIGF4aXMgZm9yIHRoZSBlbmNvZGluZyBjaGFubmVsIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIElmIHVuZGVmaW5lZCwgZGVmYXVsdCBbYXhpcyBwcm9wZXJ0aWVzXShheGlzLmh0bWwpIGFyZSBhcHBsaWVkLlxuICAgKi9cbiAgYXhpcz86IEF4aXMgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBUeXBlIG9mIHN0YWNraW5nIG9mZnNldCBpZiB0aGUgZmllbGQgc2hvdWxkIGJlIHN0YWNrZWQuXG4gICAqIGBzdGFja2AgaXMgb25seSBhcHBsaWNhYmxlIGZvciBgeGAgYW5kIGB5YCBjaGFubmVscyB3aXRoIGNvbnRpbnVvdXMgZG9tYWlucy5cbiAgICogRm9yIGV4YW1wbGUsIGBzdGFja2Agb2YgYHlgIGNhbiBiZSB1c2VkIHRvIGN1c3RvbWl6ZSBzdGFja2luZyBmb3IgYSB2ZXJ0aWNhbCBiYXIgY2hhcnQuXG4gICAqXG4gICAqIGBzdGFja2AgY2FuIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczpcbiAgICogLSBgXCJ6ZXJvXCJgOiBzdGFja2luZyB3aXRoIGJhc2VsaW5lIG9mZnNldCBhdCB6ZXJvIHZhbHVlIG9mIHRoZSBzY2FsZSAoZm9yIGNyZWF0aW5nIHR5cGljYWwgc3RhY2tlZCBbYmFyXShzdGFjay5odG1sI2JhcikgYW5kIFthcmVhXShzdGFjay5odG1sI2FyZWEpIGNoYXJ0KS5cbiAgICogLSBgXCJub3JtYWxpemVcImAgLSBzdGFja2luZyB3aXRoIG5vcm1hbGl6ZWQgZG9tYWluIChmb3IgY3JlYXRpbmcgW25vcm1hbGl6ZWQgc3RhY2tlZCBiYXIgYW5kIGFyZWEgY2hhcnRzXShzdGFjay5odG1sI25vcm1hbGl6ZWQpLiA8YnIvPlxuICAgKiAtYFwiY2VudGVyXCJgIC0gc3RhY2tpbmcgd2l0aCBjZW50ZXIgYmFzZWxpbmUgKGZvciBbc3RyZWFtZ3JhcGhdKHN0YWNrLmh0bWwjc3RyZWFtZ3JhcGgpKS5cbiAgICogLSBgbnVsbGAgLSBOby1zdGFja2luZy4gVGhpcyB3aWxsIHByb2R1Y2UgbGF5ZXJlZCBbYmFyXShzdGFjay5odG1sI2xheWVyZWQtYmFyLWNoYXJ0KSBhbmQgYXJlYSBjaGFydC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB6ZXJvYCBmb3IgcGxvdHMgd2l0aCBhbGwgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSB0cnVlOlxuICAgKiAoMSkgdGhlIG1hcmsgaXMgYGJhcmAgb3IgYGFyZWFgO1xuICAgKiAoMikgdGhlIHN0YWNrZWQgbWVhc3VyZSBjaGFubmVsICh4IG9yIHkpIGhhcyBhIGxpbmVhciBzY2FsZTtcbiAgICogKDMpIEF0IGxlYXN0IG9uZSBvZiBub24tcG9zaXRpb24gY2hhbm5lbHMgbWFwcGVkIHRvIGFuIHVuYWdncmVnYXRlZCBmaWVsZCB0aGF0IGlzIGRpZmZlcmVudCBmcm9tIHggYW5kIHkuICBPdGhlcndpc2UsIGBudWxsYCBieSBkZWZhdWx0LlxuICAgKi9cbiAgc3RhY2s/OiBTdGFja09mZnNldCB8IG51bGw7XG59XG5cbi8qKlxuICogRmllbGQgZGVmaW5pdGlvbiBvZiBhIG1hcmsgcHJvcGVydHksIHdoaWNoIGNhbiBjb250YWluIGEgbGVnZW5kLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1hcmtQcm9wRmllbGREZWY8Rj4gZXh0ZW5kcyBTY2FsZUZpZWxkRGVmPEY+IHtcbiAgIC8qKlxuICAgICogQW4gb2JqZWN0IGRlZmluaW5nIHByb3BlcnRpZXMgb2YgdGhlIGxlZ2VuZC5cbiAgICAqIElmIGBudWxsYCwgdGhlIGxlZ2VuZCBmb3IgdGhlIGVuY29kaW5nIGNoYW5uZWwgd2lsbCBiZSByZW1vdmVkLlxuICAgICpcbiAgICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBJZiB1bmRlZmluZWQsIGRlZmF1bHQgW2xlZ2VuZCBwcm9wZXJ0aWVzXShsZWdlbmQuaHRtbCkgYXJlIGFwcGxpZWQuXG4gICAgKi9cbiAgbGVnZW5kPzogTGVnZW5kIHwgbnVsbDtcbn1cblxuLy8gRGV0YWlsXG5cbi8vIE9yZGVyIFBhdGggaGF2ZSBubyBzY2FsZVxuXG5leHBvcnQgaW50ZXJmYWNlIE9yZGVyRmllbGREZWY8Rj4gZXh0ZW5kcyBGaWVsZERlZjxGPiB7XG4gIC8qKlxuICAgKiBUaGUgc29ydCBvcmRlci4gT25lIG9mIGBcImFzY2VuZGluZ1wiYCAoZGVmYXVsdCkgb3IgYFwiZGVzY2VuZGluZ1wiYC5cbiAgICovXG4gIHNvcnQ/OiBTb3J0T3JkZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dEZpZWxkRGVmPEY+IGV4dGVuZHMgRmllbGREZWY8Rj4ge1xuICAvKipcbiAgICogVGhlIFtmb3JtYXR0aW5nIHBhdHRlcm5dKGZvcm1hdC5odG1sKSBmb3IgYSB0ZXh0IGZpZWxkLiBJZiBub3QgZGVmaW5lZCwgdGhpcyB3aWxsIGJlIGRldGVybWluZWQgYXV0b21hdGljYWxseS5cbiAgICovXG4gIGZvcm1hdD86IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgQ2hhbm5lbERlZjxGPiA9IENoYW5uZWxEZWZXaXRoQ29uZGl0aW9uPEZpZWxkRGVmPEY+PjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29uZGl0aW9uYWxEZWY8Rj4oY2hhbm5lbERlZjogQ2hhbm5lbERlZjxGPik6IGNoYW5uZWxEZWYgaXMgQ2hhbm5lbERlZldpdGhDb25kaXRpb248RmllbGREZWY8Rj4+IHtcbiAgcmV0dXJuICEhY2hhbm5lbERlZiAmJiAhIWNoYW5uZWxEZWYuY29uZGl0aW9uO1xufVxuXG4vKipcbiAqIFJldHVybiBpZiBhIGNoYW5uZWxEZWYgaXMgYSBDb25kaXRpb25hbFZhbHVlRGVmIHdpdGggQ29uZGl0aW9uRmllbGREZWZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc0NvbmRpdGlvbmFsRmllbGREZWY8Rj4oY2hhbm5lbERlZjogQ2hhbm5lbERlZjxGPik6IGNoYW5uZWxEZWYgaXMgKFZhbHVlRGVmICYge2NvbmRpdGlvbjogQ29uZGl0aW9uYWw8RmllbGREZWY8Rj4+fSkge1xuICByZXR1cm4gISFjaGFubmVsRGVmICYmICEhY2hhbm5lbERlZi5jb25kaXRpb24gJiYgIWlzQXJyYXkoY2hhbm5lbERlZi5jb25kaXRpb24pICYmIGlzRmllbGREZWYoY2hhbm5lbERlZi5jb25kaXRpb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzQ29uZGl0aW9uYWxWYWx1ZURlZjxGPihjaGFubmVsRGVmOiBDaGFubmVsRGVmPEY+KTogY2hhbm5lbERlZiBpcyAoVmFsdWVEZWYgJiB7Y29uZGl0aW9uOiBDb25kaXRpb25hbDxWYWx1ZURlZj4gfCBDb25kaXRpb25hbDxWYWx1ZURlZj5bXX0pIHtcbiAgcmV0dXJuICEhY2hhbm5lbERlZiAmJiAhIWNoYW5uZWxEZWYuY29uZGl0aW9uICYmIChcbiAgICBpc0FycmF5KGNoYW5uZWxEZWYuY29uZGl0aW9uKSB8fCBpc1ZhbHVlRGVmKGNoYW5uZWxEZWYuY29uZGl0aW9uKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNGaWVsZERlZjxGPihjaGFubmVsRGVmOiBDaGFubmVsRGVmPEY+KTogY2hhbm5lbERlZiBpcyBGaWVsZERlZjxGPiB8IFBvc2l0aW9uRmllbGREZWY8Rj4gfCBNYXJrUHJvcEZpZWxkRGVmPEY+IHwgT3JkZXJGaWVsZERlZjxGPiB8IFRleHRGaWVsZERlZjxGPiB7XG4gIHJldHVybiAhIWNoYW5uZWxEZWYgJiYgKCEhY2hhbm5lbERlZlsnZmllbGQnXSB8fCBjaGFubmVsRGVmWydhZ2dyZWdhdGUnXSA9PT0gJ2NvdW50Jyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZ0ZpZWxkRGVmKGZpZWxkRGVmOiBDaGFubmVsRGVmPHN0cmluZ3xSZXBlYXRSZWY+KTogZmllbGREZWYgaXMgRmllbGREZWY8c3RyaW5nPiB7XG4gIHJldHVybiBpc0ZpZWxkRGVmKGZpZWxkRGVmKSAmJiBpc1N0cmluZyhmaWVsZERlZi5maWVsZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbHVlRGVmPEY+KGNoYW5uZWxEZWY6IENoYW5uZWxEZWY8Rj4pOiBjaGFubmVsRGVmIGlzIFZhbHVlRGVmIHtcbiAgcmV0dXJuIGNoYW5uZWxEZWYgJiYgJ3ZhbHVlJyBpbiBjaGFubmVsRGVmICYmIGNoYW5uZWxEZWZbJ3ZhbHVlJ10gIT09IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2NhbGVGaWVsZERlZihjaGFubmVsRGVmOiBDaGFubmVsRGVmPGFueT4pOiBjaGFubmVsRGVmIGlzIFNjYWxlRmllbGREZWY8YW55PiB7XG4gICAgcmV0dXJuICEhY2hhbm5lbERlZiAmJiAoISFjaGFubmVsRGVmWydzY2FsZSddIHx8ICEhY2hhbm5lbERlZlsnc29ydCddKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWVsZFJlZk9wdGlvbiB7XG4gIC8qKiBleGNsdWRlIGJpbiwgYWdncmVnYXRlLCB0aW1lVW5pdCAqL1xuICBub2ZuPzogYm9vbGVhbjtcbiAgLyoqIFdyYXAgdGhlIGZpZWxkIHdpdGggZGF0dW0gb3IgcGFyZW50IChlLmcuLCBkYXR1bVsnLi4uJ10gZm9yIFZlZ2EgRXhwcmVzc2lvbiAqL1xuICBleHByPzogJ2RhdHVtJyB8ICdwYXJlbnQnO1xuICAvKiogcHJlcGVuZCBmbiB3aXRoIGN1c3RvbSBmdW5jdGlvbiBwcmVmaXggKi9cbiAgcHJlZml4Pzogc3RyaW5nO1xuICAvKiogYXBwZW5kIHN1ZmZpeCB0byB0aGUgZmllbGQgcmVmIGZvciBiaW4gKGRlZmF1bHQ9J3N0YXJ0JykgKi9cbiAgYmluU3VmZml4PzogJ2VuZCcgfCAncmFuZ2UnIHwgJ21pZCc7XG4gIC8qKiBhcHBlbmQgc3VmZml4IHRvIHRoZSBmaWVsZCByZWYgKGdlbmVyYWwpICovXG4gIHN1ZmZpeD86IHN0cmluZztcbiAgLyoqIE92ZXJycmlkZSB3aGljaCBhZ2dyZWdhdGUgdG8gdXNlLiBOZWVkZWQgZm9yIHVuYWdncmVnYXRlZCBkb21haW4uICovXG4gIGFnZ3JlZ2F0ZT86IEFnZ3JlZ2F0ZU9wO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmllbGQoZmllbGREZWY6IEZpZWxkRGVmQmFzZTxzdHJpbmc+LCBvcHQ6IEZpZWxkUmVmT3B0aW9uID0ge30pOiBzdHJpbmcge1xuICBsZXQgZmllbGQgPSBmaWVsZERlZi5maWVsZDtcbiAgY29uc3QgcHJlZml4ID0gb3B0LnByZWZpeDtcbiAgbGV0IHN1ZmZpeCA9IG9wdC5zdWZmaXg7XG5cbiAgaWYgKGlzQ291bnQoZmllbGREZWYpKSB7XG4gICAgZmllbGQgPSAnY291bnRfKic7XG4gIH0gZWxzZSB7XG4gICAgbGV0IGZuOiBzdHJpbmcgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIW9wdC5ub2ZuKSB7XG4gICAgICBpZiAoZmllbGREZWYuYmluKSB7XG4gICAgICAgIGZuID0gYmluVG9TdHJpbmcoZmllbGREZWYuYmluKTtcbiAgICAgICAgc3VmZml4ID0gb3B0LmJpblN1ZmZpeCB8fCAnJztcbiAgICAgIH0gZWxzZSBpZiAoZmllbGREZWYuYWdncmVnYXRlKSB7XG4gICAgICAgIGZuID0gU3RyaW5nKG9wdC5hZ2dyZWdhdGUgfHwgZmllbGREZWYuYWdncmVnYXRlKTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGREZWYudGltZVVuaXQpIHtcbiAgICAgICAgZm4gPSBTdHJpbmcoZmllbGREZWYudGltZVVuaXQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChmbikge1xuICAgICAgZmllbGQgPSBgJHtmbn1fJHtmaWVsZH1gO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdWZmaXgpIHtcbiAgICBmaWVsZCA9IGAke2ZpZWxkfV8ke3N1ZmZpeH1gO1xuICB9XG5cbiAgaWYgKHByZWZpeCkge1xuICAgIGZpZWxkID0gYCR7cHJlZml4fV8ke2ZpZWxkfWA7XG4gIH1cblxuICBpZiAob3B0LmV4cHIpIHtcbiAgICBmaWVsZCA9IGAke29wdC5leHByfSR7YWNjZXNzUGF0aChmaWVsZCl9YDtcbiAgfVxuXG4gIHJldHVybiBmaWVsZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGlzY3JldGUoZmllbGREZWY6IEZpZWxkRGVmPEZpZWxkPikge1xuICBzd2l0Y2ggKGZpZWxkRGVmLnR5cGUpIHtcbiAgICBjYXNlICdub21pbmFsJzpcbiAgICBjYXNlICdvcmRpbmFsJzpcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGNhc2UgJ3F1YW50aXRhdGl2ZSc6XG4gICAgICByZXR1cm4gISFmaWVsZERlZi5iaW47XG4gICAgY2FzZSAndGVtcG9yYWwnOlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihsb2cubWVzc2FnZS5pbnZhbGlkRmllbGRUeXBlKGZpZWxkRGVmLnR5cGUpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29udGludW91cyhmaWVsZERlZjogRmllbGREZWY8RmllbGQ+KSB7XG4gIHJldHVybiAhaXNEaXNjcmV0ZShmaWVsZERlZik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvdW50KGZpZWxkRGVmOiBGaWVsZERlZkJhc2U8RmllbGQ+KSB7XG4gIHJldHVybiBmaWVsZERlZi5hZ2dyZWdhdGUgPT09ICdjb3VudCc7XG59XG5cbmV4cG9ydCB0eXBlIEZpZWxkVGl0bGVGb3JtYXR0ZXIgPSAoZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIGNvbmZpZzogQ29uZmlnKSA9PiBzdHJpbmc7XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZXJiYWxUaXRsZUZvcm1hdHRlcihmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgY29uZmlnOiBDb25maWcpIHtcbiAgY29uc3Qge2ZpZWxkLCBiaW4sIHRpbWVVbml0LCBhZ2dyZWdhdGV9ID0gZmllbGREZWY7XG4gIGlmIChhZ2dyZWdhdGUgPT09ICdjb3VudCcpIHtcbiAgICByZXR1cm4gY29uZmlnLmNvdW50VGl0bGU7XG4gIH0gZWxzZSBpZiAoYmluKSB7XG4gICAgcmV0dXJuIGAke2ZpZWxkfSAoYmlubmVkKWA7XG4gIH0gZWxzZSBpZiAodGltZVVuaXQpIHtcbiAgICBjb25zdCB1bml0cyA9IGdldFRpbWVVbml0UGFydHModGltZVVuaXQpLmpvaW4oJy0nKTtcbiAgICByZXR1cm4gYCR7ZmllbGR9ICgke3VuaXRzfSlgO1xuICB9IGVsc2UgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgIHJldHVybiBgJHt0aXRsZWNhc2UoYWdncmVnYXRlKX0gb2YgJHtmaWVsZH1gO1xuICB9XG4gIHJldHVybiBmaWVsZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZ1bmN0aW9uYWxUaXRsZUZvcm1hdHRlcihmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgY29uZmlnOiBDb25maWcpIHtcbiAgY29uc3QgZm4gPSBmaWVsZERlZi5hZ2dyZWdhdGUgfHwgZmllbGREZWYudGltZVVuaXQgfHwgKGZpZWxkRGVmLmJpbiAmJiAnYmluJyk7XG4gIGlmIChmbikge1xuICAgIHJldHVybiBmbi50b1VwcGVyQ2FzZSgpICsgJygnICsgZmllbGREZWYuZmllbGQgKyAnKSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZpZWxkRGVmLmZpZWxkO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0VGl0bGVGb3JtYXR0ZXI6IEZpZWxkVGl0bGVGb3JtYXR0ZXIgPSAoZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4sIGNvbmZpZzogQ29uZmlnKSA9PiB7XG4gIHN3aXRjaCAoY29uZmlnLmZpZWxkVGl0bGUpIHtcbiAgICBjYXNlICdwbGFpbic6XG4gICAgICByZXR1cm4gZmllbGREZWYuZmllbGQ7XG4gICAgY2FzZSAnZnVuY3Rpb25hbCc6XG4gICAgICByZXR1cm4gZnVuY3Rpb25hbFRpdGxlRm9ybWF0dGVyKGZpZWxkRGVmLCBjb25maWcpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdmVyYmFsVGl0bGVGb3JtYXR0ZXIoZmllbGREZWYsIGNvbmZpZyk7XG4gIH1cbn07XG5cbmxldCB0aXRsZUZvcm1hdHRlciA9IGRlZmF1bHRUaXRsZUZvcm1hdHRlcjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFRpdGxlRm9ybWF0dGVyKGZvcm1hdHRlcjogKGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBjb25maWc6IENvbmZpZykgPT4gc3RyaW5nKSB7XG4gIHRpdGxlRm9ybWF0dGVyID0gZm9ybWF0dGVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRUaXRsZUZvcm1hdHRlcigpIHtcbiAgc2V0VGl0bGVGb3JtYXR0ZXIoZGVmYXVsdFRpdGxlRm9ybWF0dGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRpdGxlKGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+LCBjb25maWc6IENvbmZpZykge1xuICByZXR1cm4gdGl0bGVGb3JtYXR0ZXIoZmllbGREZWYsIGNvbmZpZyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0VHlwZShmaWVsZERlZjogRmllbGREZWY8RmllbGQ+LCBjaGFubmVsOiBDaGFubmVsKTogVHlwZSB7XG4gIGlmIChmaWVsZERlZi50aW1lVW5pdCkge1xuICAgIHJldHVybiAndGVtcG9yYWwnO1xuICB9XG4gIGlmIChmaWVsZERlZi5iaW4pIHtcbiAgICByZXR1cm4gJ3F1YW50aXRhdGl2ZSc7XG4gIH1cbiAgc3dpdGNoIChyYW5nZVR5cGUoY2hhbm5lbCkpIHtcbiAgICBjYXNlICdjb250aW51b3VzJzpcbiAgICAgIHJldHVybiAncXVhbnRpdGF0aXZlJztcbiAgICBjYXNlICdkaXNjcmV0ZSc6XG4gICAgICByZXR1cm4gJ25vbWluYWwnO1xuICAgIGNhc2UgJ2ZsZXhpYmxlJzogLy8gY29sb3JcbiAgICAgIHJldHVybiAnbm9taW5hbCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAncXVhbnRpdGF0aXZlJztcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpZWxkRGVmIC0tIGVpdGhlciBmcm9tIHRoZSBvdXRlciBjaGFubmVsRGVmIG9yIGZyb20gdGhlIGNvbmRpdGlvbiBvZiBjaGFubmVsRGVmLlxuICogQHBhcmFtIGNoYW5uZWxEZWZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpZWxkRGVmPEY+KGNoYW5uZWxEZWY6IENoYW5uZWxEZWY8Rj4pOiBGaWVsZERlZjxGPiB7XG4gIGlmIChpc0ZpZWxkRGVmKGNoYW5uZWxEZWYpKSB7XG4gICAgcmV0dXJuIGNoYW5uZWxEZWY7XG4gIH0gZWxzZSBpZiAoaGFzQ29uZGl0aW9uYWxGaWVsZERlZihjaGFubmVsRGVmKSkge1xuICAgIHJldHVybiBjaGFubmVsRGVmLmNvbmRpdGlvbjtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENvbnZlcnQgdHlwZSB0byBmdWxsLCBsb3dlcmNhc2UgdHlwZSwgb3IgYXVnbWVudCB0aGUgZmllbGREZWYgd2l0aCBhIGRlZmF1bHQgdHlwZSBpZiBtaXNzaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKGNoYW5uZWxEZWY6IENoYW5uZWxEZWY8c3RyaW5nPiwgY2hhbm5lbDogQ2hhbm5lbCk6IENoYW5uZWxEZWY8YW55PiB7XG4gIGlmIChpc1N0cmluZyhjaGFubmVsRGVmKSB8fCBpc051bWJlcihjaGFubmVsRGVmKSB8fCBpc0Jvb2xlYW4oY2hhbm5lbERlZikpIHtcbiAgICBjb25zdCBwcmltaXRpdmVUeXBlID0gaXNTdHJpbmcoY2hhbm5lbERlZikgPyAnc3RyaW5nJyA6XG4gICAgICBpc051bWJlcihjaGFubmVsRGVmKSA/ICdudW1iZXInIDogJ2Jvb2xlYW4nO1xuICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLnByaW1pdGl2ZUNoYW5uZWxEZWYoY2hhbm5lbCwgcHJpbWl0aXZlVHlwZSwgY2hhbm5lbERlZikpO1xuICAgIHJldHVybiB7dmFsdWU6IGNoYW5uZWxEZWZ9O1xuICB9XG5cbiAgLy8gSWYgYSBmaWVsZERlZiBjb250YWlucyBhIGZpZWxkLCB3ZSBuZWVkIHR5cGUuXG4gIGlmIChpc0ZpZWxkRGVmKGNoYW5uZWxEZWYpKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUZpZWxkRGVmKGNoYW5uZWxEZWYsIGNoYW5uZWwpO1xuICB9IGVsc2UgaWYgKGhhc0NvbmRpdGlvbmFsRmllbGREZWYoY2hhbm5lbERlZikpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uY2hhbm5lbERlZixcbiAgICAgIC8vIE5lZWQgdG8gY2FzdCBhcyBub3JtYWxpemVGaWVsZERlZiBub3JtYWxseSByZXR1cm4gRmllbGREZWYsIGJ1dCBoZXJlIHdlIGtub3cgdGhhdCBpdCBpcyBkZWZpbml0ZWx5IENvbmRpdGlvbjxGaWVsZERlZj5cbiAgICAgIGNvbmRpdGlvbjogbm9ybWFsaXplRmllbGREZWYoY2hhbm5lbERlZi5jb25kaXRpb24sIGNoYW5uZWwpIGFzIENvbmRpdGlvbmFsPEZpZWxkRGVmPHN0cmluZz4+XG4gICAgfTtcbiAgfVxuICByZXR1cm4gY2hhbm5lbERlZjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVGaWVsZERlZihmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgY2hhbm5lbDogQ2hhbm5lbCkge1xuICAvLyBEcm9wIGludmFsaWQgYWdncmVnYXRlXG4gIGlmIChmaWVsZERlZi5hZ2dyZWdhdGUgJiYgIWlzQWdncmVnYXRlT3AoZmllbGREZWYuYWdncmVnYXRlKSkge1xuICAgIGNvbnN0IHthZ2dyZWdhdGUsIC4uLmZpZWxkRGVmV2l0aG91dEFnZ3JlZ2F0ZX0gPSBmaWVsZERlZjtcbiAgICBsb2cud2Fybihsb2cubWVzc2FnZS5pbnZhbGlkQWdncmVnYXRlKGZpZWxkRGVmLmFnZ3JlZ2F0ZSkpO1xuICAgIGZpZWxkRGVmID0gZmllbGREZWZXaXRob3V0QWdncmVnYXRlO1xuICB9XG5cbiAgLy8gTm9ybWFsaXplIFRpbWUgVW5pdFxuICBpZiAoZmllbGREZWYudGltZVVuaXQpIHtcbiAgICBmaWVsZERlZiA9IHtcbiAgICAgIC4uLmZpZWxkRGVmLFxuICAgICAgdGltZVVuaXQ6IG5vcm1hbGl6ZVRpbWVVbml0KGZpZWxkRGVmLnRpbWVVbml0KVxuICAgIH07XG4gIH1cblxuICAvLyBOb3JtYWxpemUgYmluXG4gIGlmIChmaWVsZERlZi5iaW4pIHtcbiAgICBmaWVsZERlZiA9IHtcbiAgICAgIC4uLmZpZWxkRGVmLFxuICAgICAgYmluOiBub3JtYWxpemVCaW4oZmllbGREZWYuYmluLCBjaGFubmVsKVxuICAgIH07XG4gIH1cblxuICAvLyBOb3JtYWxpemUgVHlwZVxuICBpZiAoZmllbGREZWYudHlwZSkge1xuICAgIGNvbnN0IGZ1bGxUeXBlID0gZ2V0RnVsbE5hbWUoZmllbGREZWYudHlwZSk7XG4gICAgaWYgKGZpZWxkRGVmLnR5cGUgIT09IGZ1bGxUeXBlKSB7XG4gICAgICAvLyBjb252ZXJ0IHNob3J0IHR5cGUgdG8gZnVsbCB0eXBlXG4gICAgICBmaWVsZERlZiA9IHtcbiAgICAgICAgLi4uZmllbGREZWYsXG4gICAgICAgIHR5cGU6IGZ1bGxUeXBlXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoZmllbGREZWYudHlwZSAhPT0gJ3F1YW50aXRhdGl2ZScpIHtcbiAgICAgIGlmIChpc0NvdW50aW5nQWdncmVnYXRlT3AoZmllbGREZWYuYWdncmVnYXRlKSkge1xuICAgICAgICBsb2cud2Fybihsb2cubWVzc2FnZS5pbnZhbGlkRmllbGRUeXBlRm9yQ291bnRBZ2dyZWdhdGUoZmllbGREZWYudHlwZSwgZmllbGREZWYuYWdncmVnYXRlKSk7XG4gICAgICAgIGZpZWxkRGVmID0ge1xuICAgICAgICAgIC4uLmZpZWxkRGVmLFxuICAgICAgICAgIHR5cGU6ICdxdWFudGl0YXRpdmUnXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElmIHR5cGUgaXMgZW1wdHkgLyBpbnZhbGlkLCB0aGVuIGF1Z21lbnQgd2l0aCBkZWZhdWx0IHR5cGVcbiAgICBjb25zdCBuZXdUeXBlID0gZGVmYXVsdFR5cGUoZmllbGREZWYsIGNoYW5uZWwpO1xuICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmVtcHR5T3JJbnZhbGlkRmllbGRUeXBlKGZpZWxkRGVmLnR5cGUsIGNoYW5uZWwsIG5ld1R5cGUpKTtcbiAgICBmaWVsZERlZiA9IHtcbiAgICAgICAgLi4uZmllbGREZWYsXG4gICAgICB0eXBlOiBuZXdUeXBlXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHtjb21wYXRpYmxlLCB3YXJuaW5nfSA9IGNoYW5uZWxDb21wYXRpYmlsaXR5KGZpZWxkRGVmLCBjaGFubmVsKTtcbiAgaWYgKCFjb21wYXRpYmxlKSB7XG4gICAgbG9nLndhcm4od2FybmluZyk7XG4gIH1cbiAgcmV0dXJuIGZpZWxkRGVmO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQmluKGJpbjogQmluUGFyYW1zfGJvb2xlYW4sIGNoYW5uZWw6IENoYW5uZWwpIHtcbiAgaWYgKGlzQm9vbGVhbihiaW4pKSB7XG4gICAgcmV0dXJuIHttYXhiaW5zOiBhdXRvTWF4QmlucyhjaGFubmVsKX07XG4gIH0gZWxzZSBpZiAoIWJpbi5tYXhiaW5zICYmICFiaW4uc3RlcCkge1xuICAgIHJldHVybiB7Li4uYmluLCBtYXhiaW5zOiBhdXRvTWF4QmlucyhjaGFubmVsKX07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJpbjtcbiAgfVxufVxuXG5jb25zdCBDT01QQVRJQkxFID0ge2NvbXBhdGlibGU6IHRydWV9O1xuZXhwb3J0IGZ1bmN0aW9uIGNoYW5uZWxDb21wYXRpYmlsaXR5KGZpZWxkRGVmOiBGaWVsZERlZjxGaWVsZD4sIGNoYW5uZWw6IENoYW5uZWwpOiB7Y29tcGF0aWJsZTogYm9vbGVhbjsgd2FybmluZz86IHN0cmluZzt9IHtcbiAgc3dpdGNoIChjaGFubmVsKSB7XG4gICAgY2FzZSAncm93JzpcbiAgICBjYXNlICdjb2x1bW4nOlxuICAgICAgaWYgKGlzQ29udGludW91cyhmaWVsZERlZikgJiYgIWZpZWxkRGVmLnRpbWVVbml0KSB7XG4gICAgICAgIC8vIFRPRE86KGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EtbGl0ZS9pc3N1ZXMvMjAxMSk6XG4gICAgICAgIC8vIHdpdGggdGltZVVuaXQgaXQncyBub3QgYWx3YXlzIHN0cmljdGx5IGNvbnRpbnVvdXNcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb21wYXRpYmxlOiBmYWxzZSxcbiAgICAgICAgICB3YXJuaW5nOiBsb2cubWVzc2FnZS5mYWNldENoYW5uZWxTaG91bGRCZURpc2NyZXRlKGNoYW5uZWwpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gQ09NUEFUSUJMRTtcblxuICAgIGNhc2UgJ3gnOlxuICAgIGNhc2UgJ3knOlxuICAgIGNhc2UgJ2NvbG9yJzpcbiAgICBjYXNlICd0ZXh0JzpcbiAgICBjYXNlICdkZXRhaWwnOlxuICAgIGNhc2UgJ3Rvb2x0aXAnOlxuICAgICAgcmV0dXJuIENPTVBBVElCTEU7XG5cbiAgICBjYXNlICdvcGFjaXR5JzpcbiAgICBjYXNlICdzaXplJzpcbiAgICBjYXNlICd4Mic6XG4gICAgY2FzZSAneTInOlxuICAgICAgaWYgKGlzRGlzY3JldGUoZmllbGREZWYpICYmICFmaWVsZERlZi5iaW4pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb21wYXRpYmxlOiBmYWxzZSxcbiAgICAgICAgICB3YXJuaW5nOiBgQ2hhbm5lbCAke2NoYW5uZWx9IHNob3VsZCBub3QgYmUgdXNlZCB3aXRoIGRpc2NyZXRlIGZpZWxkLmBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBDT01QQVRJQkxFO1xuXG4gICAgY2FzZSAnc2hhcGUnOlxuICAgICAgaWYgKGZpZWxkRGVmLnR5cGUgIT09ICdub21pbmFsJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbXBhdGlibGU6IGZhbHNlLFxuICAgICAgICAgIHdhcm5pbmc6ICdTaGFwZSBjaGFubmVsIHNob3VsZCBiZSB1c2VkIHdpdGggbm9taW5hbCBkYXRhIG9ubHknXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gQ09NUEFUSUJMRTtcblxuICAgIGNhc2UgJ29yZGVyJzpcbiAgICAgIGlmIChmaWVsZERlZi50eXBlID09PSAnbm9taW5hbCcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb21wYXRpYmxlOiBmYWxzZSxcbiAgICAgICAgICB3YXJuaW5nOiBgQ2hhbm5lbCBvcmRlciBpcyBpbmFwcHJvcHJpYXRlIGZvciBub21pbmFsIGZpZWxkLCB3aGljaCBoYXMgbm8gaW5oZXJlbnQgb3JkZXIuYFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIENPTVBBVElCTEU7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdjaGFubmVsQ29tcGF0YWJpbGl0eSBub3QgaW1wbGVtZW50ZWQgZm9yIGNoYW5uZWwgJyArIGNoYW5uZWwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXJGaWVsZERlZihmaWVsZERlZjogRmllbGREZWY8YW55Pikge1xuICByZXR1cm4gZmllbGREZWYudHlwZSA9PT0gJ3F1YW50aXRhdGl2ZScgfHwgISFmaWVsZERlZi5iaW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RpbWVGaWVsZERlZihmaWVsZERlZjogRmllbGREZWY8YW55Pikge1xuICByZXR1cm4gZmllbGREZWYudHlwZSA9PT0gJ3RlbXBvcmFsJyB8fCAhIWZpZWxkRGVmLnRpbWVVbml0O1xufVxuIl19 \ No newline at end of file diff --git a/build/src/filter.d.ts b/build/src/filter.d.ts new file mode 100644 index 0000000000..bdaf0792c5 --- /dev/null +++ b/build/src/filter.d.ts @@ -0,0 +1,70 @@ +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 Filter = EqualFilter | RangeFilter | OneOfFilter | SelectionFilter | string; +export declare type FieldFilter = EqualFilter | RangeFilter | OneOfFilter; +export interface SelectionFilter { + /** + * Filter using a selection name. + */ + selection: LogicalOperand; +} +export declare function isSelectionFilter(filter: LogicalOperand): filter is SelectionFilter; +export interface EqualFilter { + /** + * Time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered. + */ + field: string; + /** + * The value that the field should be equal to. + */ + equal: string | number | boolean | DateTime; +} +export declare function isEqualFilter(filter: any): filter is EqualFilter; +export interface RangeFilter { + /** + * time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered + */ + field: string; + /** + * 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)[]; +} +export declare function isRangeFilter(filter: any): filter is RangeFilter; +export interface OneOfFilter { + /** + * time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered + */ + field: string; + /** + * 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 isOneOfFilter(filter: any): filter is OneOfFilter; +export declare function isFieldFilter(filter: Filter): filter is OneOfFilter | EqualFilter | RangeFilter; +/** + * Converts a filter into an expression. + */ +export declare function expression(model: Model, filterOp: LogicalOperand, node?: DataFlowNode): string; +export declare function fieldFilterExpression(filter: FieldFilter, useInRange?: boolean): string; +export declare function normalizeFilter(f: Filter): Filter; diff --git a/build/src/filter.js b/build/src/filter.js new file mode 100644 index 0000000000..38f6266770 --- /dev/null +++ b/build/src/filter.js @@ -0,0 +1,124 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./compile/selection/selection"); +var datetime_1 = require("./datetime"); +var fielddef_1 = require("./fielddef"); +var timeunit_1 = require("./timeunit"); +var util_1 = require("./util"); +function isSelectionFilter(filter) { + return filter && filter['selection']; +} +exports.isSelectionFilter = isSelectionFilter; +function isEqualFilter(filter) { + return filter && !!filter.field && filter.equal !== undefined; +} +exports.isEqualFilter = isEqualFilter; +function isRangeFilter(filter) { + if (filter && filter.field) { + if (util_1.isArray(filter.range) && filter.range.length === 2) { + return true; + } + } + return false; +} +exports.isRangeFilter = isRangeFilter; +function isOneOfFilter(filter) { + return filter && !!filter.field && (util_1.isArray(filter.oneOf) || + util_1.isArray(filter.in) // backward compatibility + ); +} +exports.isOneOfFilter = isOneOfFilter; +function isFieldFilter(filter) { + return isOneOfFilter(filter) || isEqualFilter(filter) || isRangeFilter(filter); +} +exports.isFieldFilter = isFieldFilter; +/** + * Converts a filter into an expression. + */ +// model is only used for selection filters. +function expression(model, filterOp, node) { + return util_1.logicalExpr(filterOp, function (filter) { + if (util_1.isString(filter)) { + return filter; + } + else if (isSelectionFilter(filter)) { + return selection_1.predicate(model, filter.selection, node); + } + else { + return fieldFilterExpression(filter); + } + }); +} +exports.expression = expression; +// This method is used by Voyager. Do not change its behavior without changing Voyager. +function fieldFilterExpression(filter, useInRange) { + if (useInRange === void 0) { useInRange = true; } + var fieldExpr = filter.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(' + timeunit_1.fieldExpr(filter.timeUnit, filter.field) + ')') : + fielddef_1.field(filter, { expr: 'datum' }); + if (isEqualFilter(filter)) { + return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit); + } + else if (isOneOfFilter(filter)) { + // "oneOf" was formerly "in" -- so we need to add backward compatibility + var oneOf = filter.oneOf || filter['in']; + return 'indexof([' + + oneOf.map(function (v) { return valueExpr(v, filter.timeUnit); }).join(',') + + '], ' + fieldExpr + ') !== -1'; + } + else if (isRangeFilter(filter)) { + var lower = filter.range[0]; + var upper = filter.range[1]; + if (lower !== null && upper !== null && useInRange) { + return 'inrange(' + fieldExpr + ', [' + + valueExpr(lower, filter.timeUnit) + ', ' + + valueExpr(upper, filter.timeUnit) + '])'; + } + var exprs = []; + if (lower !== null) { + exprs.push(fieldExpr + " >= " + valueExpr(lower, filter.timeUnit)); + } + if (upper !== null) { + exprs.push(fieldExpr + " <= " + valueExpr(upper, filter.timeUnit)); + } + return exprs.length > 0 ? exprs.join(' && ') : 'true'; + } + /* istanbul ignore next: it should never reach here */ + throw new Error("Invalid field filter: " + JSON.stringify(filter)); +} +exports.fieldFilterExpression = fieldFilterExpression; +function valueExpr(v, timeUnit) { + if (datetime_1.isDateTime(v)) { + var expr = datetime_1.dateTimeExpr(v, true); + return 'time(' + expr + ')'; + } + if (timeunit_1.isLocalSingleTimeUnit(timeUnit)) { + var datetime = {}; + datetime[timeUnit] = v; + var expr = datetime_1.dateTimeExpr(datetime, true); + return 'time(' + expr + ')'; + } + else if (timeunit_1.isUtcSingleTimeUnit(timeUnit)) { + return valueExpr(v, timeunit_1.getLocalTimeUnit(timeUnit)); + } + return JSON.stringify(v); +} +function normalizeFilter(f) { + if (isFieldFilter(f) && f.timeUnit) { + return __assign({}, f, { timeUnit: timeunit_1.normalizeTimeUnit(f.timeUnit) }); + } + return f; +} +exports.normalizeFilter = normalizeFilter; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ZpbHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsMkRBQXdEO0FBQ3hELHVDQUE4RDtBQUM5RCx1Q0FBaUM7QUFFakMsdUNBQXFKO0FBQ3JKLCtCQUFzRDtBQWtCdEQsMkJBQWtDLE1BQThCO0lBQzlELE1BQU0sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3ZDLENBQUM7QUFGRCw4Q0FFQztBQXNCRCx1QkFBOEIsTUFBVztJQUN2QyxNQUFNLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUcsU0FBUyxDQUFDO0FBQzlELENBQUM7QUFGRCxzQ0FFQztBQXlCRCx1QkFBOEIsTUFBVztJQUN2QyxFQUFFLENBQUMsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDM0IsRUFBRSxDQUFDLENBQUMsY0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDO0FBUEQsc0NBT0M7QUF1QkQsdUJBQThCLE1BQVc7SUFDdkMsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUNqQyxjQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNyQixjQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLHlCQUF5QjtLQUM3QyxDQUFDO0FBQ0osQ0FBQztBQUxELHNDQUtDO0FBRUQsdUJBQThCLE1BQWM7SUFDMUMsTUFBTSxDQUFDLGFB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Ryx1QkFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxQyxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxHQUFHLENBQUM7SUFDOUIsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyw4QkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsMkJBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVELHlCQUFnQyxDQUFTO0lBQ3ZDLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLGNBQ0QsQ0FBQyxJQUNKLFFBQVEsRUFBRSw0QkFBaUIsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQ3ZDO0lBQ0osQ0FBQztJQUNELE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDWCxDQUFDO0FBUkQsMENBUUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RhdGFGbG93Tm9kZX0gZnJvbSAnLi9jb21waWxlL2RhdGEvZGF0YWZsb3cnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi9jb21waWxlL21vZGVsJztcbmltcG9ydCB7cHJlZGljYXRlfSBmcm9tICcuL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge0RhdGVUaW1lLCBkYXRlVGltZUV4cHIsIGlzRGF0ZVRpbWV9IGZyb20gJy4vZGF0ZXRpbWUnO1xuaW1wb3J0IHtmaWVsZH0gZnJvbSAnLi9maWVsZGRlZic7XG5pbXBvcnQge0xvZ2ljYWxPcGVyYW5kfSBmcm9tICcuL2xvZ2ljYWwnO1xuaW1wb3J0IHtmaWVsZEV4cHIgYXMgdGltZVVuaXRGaWVsZEV4cHIsIGdldExvY2FsVGltZVVuaXQsIGlzTG9jYWxTaW5nbGVUaW1lVW5pdCwgaXNVdGNTaW5nbGVUaW1lVW5pdCwgbm9ybWFsaXplVGltZVVuaXQsIFRpbWVVbml0fSBmcm9tICcuL3RpbWV1bml0JztcbmltcG9ydCB7aXNBcnJheSwgaXNTdHJpbmcsIGxvZ2ljYWxFeHByfSBmcm9tICcuL3V0aWwnO1xuXG5cbmV4cG9ydCB0eXBlIEZpbHRlciA9XG4gIC8vIEZpZWxkRmlsdGVyIChidXQgd2UgZG9uJ3QgdHlwZSBGaWVsZEZpbHRlciBoZXJlIHNvIHRoZSBzY2hlbWEgaGFzIG5vIG5lc3RpbmdcbiAgLy8gYW5kIHRodXMgdGhlIGRvY3VtZW50YXRpb24gc2hvd3MgYWxsIG9mIHRoZSB0eXBlcyBjbGVhcmx5KVxuICBFcXVhbEZpbHRlciB8IFJhbmdlRmlsdGVyIHwgT25lT2ZGaWx0ZXIgfFxuICBTZWxlY3Rpb25GaWx0ZXIgfCBzdHJpbmc7XG5cbmV4cG9ydCB0eXBlIEZpZWxkRmlsdGVyID0gRXF1YWxGaWx0ZXIgfCBSYW5nZUZpbHRlciB8IE9uZU9mRmlsdGVyO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdGlvbkZpbHRlciB7XG4gIC8qKlxuICAgKiBGaWx0ZXIgdXNpbmcgYSBzZWxlY3Rpb24gbmFtZS5cbiAgICovXG4gIHNlbGVjdGlvbjogTG9naWNhbE9wZXJhbmQ8c3RyaW5nPjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2VsZWN0aW9uRmlsdGVyKGZpbHRlcjogTG9naWNhbE9wZXJhbmQ8RmlsdGVyPik6IGZpbHRlciBpcyBTZWxlY3Rpb25GaWx0ZXIge1xuICByZXR1cm4gZmlsdGVyICYmIGZpbHRlclsnc2VsZWN0aW9uJ107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXF1YWxGaWx0ZXIge1xuICAvLyBUT0RPOiBzdXBwb3J0IGFnZ3JlZ2F0ZVxuXG4gIC8qKlxuICAgKiBUaW1lIHVuaXQgZm9yIHRoZSBmaWVsZCB0byBiZSBmaWx0ZXJlZC5cbiAgICovXG4gIHRpbWVVbml0PzogVGltZVVuaXQ7XG5cbiAgLyoqXG4gICAqIEZpZWxkIHRvIGJlIGZpbHRlcmVkLlxuICAgKi9cbiAgZmllbGQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHZhbHVlIHRoYXQgdGhlIGZpZWxkIHNob3VsZCBiZSBlcXVhbCB0by5cbiAgICovXG4gIGVxdWFsOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgRGF0ZVRpbWU7XG5cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRXF1YWxGaWx0ZXIoZmlsdGVyOiBhbnkpOiBmaWx0ZXIgaXMgRXF1YWxGaWx0ZXIge1xuICByZXR1cm4gZmlsdGVyICYmICEhZmlsdGVyLmZpZWxkICYmIGZpbHRlci5lcXVhbCE9PXVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSYW5nZUZpbHRlciB7XG4gIC8vIFRPRE86IHN1cHBvcnQgYWdncmVnYXRlXG5cbiAgLyoqXG4gICAqIHRpbWUgdW5pdCBmb3IgdGhlIGZpZWxkIHRvIGJlIGZpbHRlcmVkLlxuICAgKi9cbiAgdGltZVVuaXQ/OiBUaW1lVW5pdDtcblxuICAvKipcbiAgICogRmllbGQgdG8gYmUgZmlsdGVyZWRcbiAgICovXG4gIGZpZWxkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGluY2x1c2l2ZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlc1xuICAgKiBmb3IgYSBmaWVsZCB2YWx1ZSBvZiBhIGRhdGEgaXRlbSB0byBiZSBpbmNsdWRlZCBpbiB0aGUgZmlsdGVyZWQgZGF0YS5cbiAgICogQG1heEl0ZW1zIDJcbiAgICogQG1pbkl0ZW1zIDJcbiAgICovXG4gIHJhbmdlOiAobnVtYmVyfERhdGVUaW1lKVtdO1xuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JhbmdlRmlsdGVyKGZpbHRlcjogYW55KTogZmlsdGVyIGlzIFJhbmdlRmlsdGVyIHtcbiAgaWYgKGZpbHRlciAmJiBmaWx0ZXIuZmllbGQpIHtcbiAgICBpZiAoaXNBcnJheShmaWx0ZXIucmFuZ2UpICYmIGZpbHRlci5yYW5nZS5sZW5ndGggPT09IDIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT25lT2ZGaWx0ZXIge1xuICAvLyBUT0RPOiBzdXBwb3J0IGFnZ3JlZ2F0ZVxuXG4gIC8qKlxuICAgKiB0aW1lIHVuaXQgZm9yIHRoZSBmaWVsZCB0byBiZSBmaWx0ZXJlZC5cbiAgICovXG4gIHRpbWVVbml0PzogVGltZVVuaXQ7XG5cbiAgLyoqXG4gICAqIEZpZWxkIHRvIGJlIGZpbHRlcmVkXG4gICAqL1xuICBmaWVsZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHNldCBvZiB2YWx1ZXMgdGhhdCB0aGUgYGZpZWxkYCdzIHZhbHVlIHNob3VsZCBiZSBhIG1lbWJlciBvZixcbiAgICogZm9yIGEgZGF0YSBpdGVtIGluY2x1ZGVkIGluIHRoZSBmaWx0ZXJlZCBkYXRhLlxuICAgKi9cbiAgb25lT2Y6IHN0cmluZ1tdIHwgbnVtYmVyW10gfCBib29sZWFuW10gfCBEYXRlVGltZVtdO1xuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc09uZU9mRmlsdGVyKGZpbHRlcjogYW55KTogZmlsdGVyIGlzIE9uZU9mRmlsdGVyIHtcbiAgcmV0dXJuIGZpbHRlciAmJiAhIWZpbHRlci5maWVsZCAmJiAoXG4gICAgaXNBcnJheShmaWx0ZXIub25lT2YpIHx8XG4gICAgaXNBcnJheShmaWx0ZXIuaW4pIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRmllbGRGaWx0ZXIoZmlsdGVyOiBGaWx0ZXIpOiBmaWx0ZXIgaXMgT25lT2ZGaWx0ZXIgfCBFcXVhbEZpbHRlciB8IFJhbmdlRmlsdGVyIHtcbiAgcmV0dXJuIGlzT25lT2ZGaWx0ZXIoZmlsdGVyKSB8fCBpc0VxdWFsRmlsdGVyKGZpbHRlcikgfHwgaXNSYW5nZUZpbHRlcihmaWx0ZXIpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgZmlsdGVyIGludG8gYW4gZXhwcmVzc2lvbi5cbiAqL1xuLy8gbW9kZWwgaXMgb25seSB1c2VkIGZvciBzZWxlY3Rpb24gZmlsdGVycy5cbmV4cG9ydCBmdW5jdGlvbiBleHByZXNzaW9uKG1vZGVsOiBNb2RlbCwgZmlsdGVyT3A6IExvZ2ljYWxPcGVyYW5kPEZpbHRlcj4sIG5vZGU/OiBEYXRhRmxvd05vZGUpOiBzdHJpbmcge1xuICByZXR1cm4gbG9naWNhbEV4cHIoZmlsdGVyT3AsIChmaWx0ZXI6IEZpbHRlcikgPT4ge1xuICAgIGlmIChpc1N0cmluZyhmaWx0ZXIpKSB7XG4gICAgICByZXR1cm4gZmlsdGVyO1xuICAgIH0gZWxzZSBpZiAoaXNTZWxlY3Rpb25GaWx0ZXIoZmlsdGVyKSkge1xuICAgICAgcmV0dXJuIHByZWRpY2F0ZShtb2RlbCwgZmlsdGVyLnNlbGVjdGlvbiwgbm9kZSk7XG4gICAgfSBlbHNlIHsgLy8gRmlsdGVyIE9iamVjdFxuICAgICAgcmV0dXJuIGZpZWxkRmlsdGVyRXhwcmVzc2lvbihmaWx0ZXIpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIFRoaXMgbWV0aG9kIGlzIHVzZWQgYnkgVm95YWdlci4gIERvIG5vdCBjaGFuZ2UgaXRzIGJlaGF2aW9yIHdpdGhvdXQgY2hhbmdpbmcgVm95YWdlci5cbmV4cG9ydCBmdW5jdGlvbiBmaWVsZEZpbHRlckV4cHJlc3Npb24oZmlsdGVyOiBGaWVsZEZpbHRlciwgdXNlSW5SYW5nZT10cnVlKSB7XG4gIGNvbnN0IGZpZWxkRXhwciA9IGZpbHRlci50aW1lVW5pdCA/XG4gICAgLy8gRm9yIHRpbWVVbml0LCBjYXN0IGludG8gaW50ZWdlciB3aXRoIHRpbWUoKSBzbyB3ZSBjYW4gdXNlID09PSwgaW5yYW5nZSwgaW5kZXhPZiB0byBjb21wYXJlIHZhbHVlcyBkaXJlY3RseS5cbiAgICAgIC8vIFRPRE86IFdlIGNhbGN1bGF0ZSB0aW1lVW5pdCBvbiB0aGUgZmx5IGhlcmUuIENvbnNpZGVyIGlmIHdlIHdvdWxkIGxpa2UgdG8gY29uc29saWRhdGUgdGhpcyB3aXRoIHRpbWVVbml0IHBpcGVsaW5lXG4gICAgICAvLyBUT0RPOiBzdXBwb3J0IHV0Y1xuICAgICgndGltZSgnICsgdGltZVVuaXRGaWVsZEV4cHIoZmlsdGVyLnRpbWVVbml0LCBmaWx0ZXIuZmllbGQpICsgJyknKSA6XG4gICAgZmllbGQoZmlsdGVyLCB7ZXhwcjogJ2RhdHVtJ30pO1xuXG4gIGlmIChpc0VxdWFsRmlsdGVyKGZpbHRlcikpIHtcbiAgICByZXR1cm4gZmllbGRFeHByICsgJz09PScgKyB2YWx1ZUV4cHIoZmlsdGVyLmVxdWFsLCBmaWx0ZXIudGltZVVuaXQpO1xuICB9IGVsc2UgaWYgKGlzT25lT2ZGaWx0ZXIoZmlsdGVyKSkge1xuICAgIC8vIFwib25lT2ZcIiB3YXMgZm9ybWVybHkgXCJpblwiIC0tIHNvIHdlIG5lZWQgdG8gYWRkIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbiAgICBjb25zdCBvbmVPZjogT25lT2ZGaWx0ZXJbXSA9IGZpbHRlci5vbmVPZiB8fCBmaWx0ZXJbJ2luJ107XG4gICAgcmV0dXJuICdpbmRleG9mKFsnICtcbiAgICAgIG9uZU9mLm1hcCgodikgPT4gdmFsdWVFeHByKHYsIGZpbHRlci50aW1lVW5pdCkpLmpvaW4oJywnKSArXG4gICAgICAnXSwgJyArIGZpZWxkRXhwciArICcpICE9PSAtMSc7XG4gIH0gZWxzZSBpZiAoaXNSYW5nZUZpbHRlcihmaWx0ZXIpKSB7XG4gICAgY29uc3QgbG93ZXIgPSBmaWx0ZXIucmFuZ2VbMF07XG4gICAgY29uc3QgdXBwZXIgPSBmaWx0ZXIucmFuZ2VbMV07XG5cbiAgICBpZiAobG93ZXIgIT09IG51bGwgJiYgdXBwZXIgIT09IG51bGwgJiYgdXNlSW5SYW5nZSkge1xuICAgICAgcmV0dXJuICdpbnJhbmdlKCcgKyBmaWVsZEV4cHIgKyAnLCBbJyArXG4gICAgICAgIHZhbHVlRXhwcihsb3dlciwgZmlsdGVyLnRpbWVVbml0KSArICcsICcgK1xuICAgICAgICB2YWx1ZUV4cHIodXBwZXIsIGZpbHRlci50aW1lVW5pdCkgKyAnXSknO1xuICAgIH1cblxuICAgIGNvbnN0IGV4cHJzID0gW107XG4gICAgaWYgKGxvd2VyICE9PSBudWxsKSB7XG4gICAgICBleHBycy5wdXNoKGAke2ZpZWxkRXhwcn0gPj0gJHt2YWx1ZUV4cHIobG93ZXIsIGZpbHRlci50aW1lVW5pdCl9YCk7XG4gICAgfVxuICAgIGlmICh1cHBlciAhPT0gbnVsbCkge1xuICAgICAgZXhwcnMucHVzaChgJHtmaWVsZEV4cHJ9IDw9ICR7dmFsdWVFeHByKHVwcGVyLCBmaWx0ZXIudGltZVVuaXQpfWApO1xuICAgIH1cblxuICAgIHJldHVybiBleHBycy5sZW5ndGggPiAwID8gZXhwcnMuam9pbignICYmICcpIDogJ3RydWUnO1xuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGl0IHNob3VsZCBuZXZlciByZWFjaCBoZXJlICovXG4gIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBmaWVsZCBmaWx0ZXI6ICR7SlNPTi5zdHJpbmdpZnkoZmlsdGVyKX1gKTtcbn1cblxuZnVuY3Rpb24gdmFsdWVFeHByKHY6IGFueSwgdGltZVVuaXQ6IFRpbWVVbml0KTogc3RyaW5nIHtcbiAgaWYgKGlzRGF0ZVRpbWUodikpIHtcbiAgICBjb25zdCBleHByID0gZGF0ZVRpbWVFeHByKHYsIHRydWUpO1xuICAgIHJldHVybiAndGltZSgnICsgZXhwciArICcpJztcbiAgfVxuICBpZiAoaXNMb2NhbFNpbmdsZVRpbWVVbml0KHRpbWVVbml0KSkge1xuICAgIGNvbnN0IGRhdGV0aW1lOiBEYXRlVGltZSA9IHt9O1xuICAgIGRhdGV0aW1lW3RpbWVVbml0XSA9IHY7XG4gICAgY29uc3QgZXhwciA9IGRhdGVUaW1lRXhwcihkYXRldGltZSwgdHJ1ZSk7XG4gICAgcmV0dXJuICd0aW1lKCcgKyBleHByICsgJyknO1xuICB9IGVsc2UgaWYgKGlzVXRjU2luZ2xlVGltZVVuaXQodGltZVVuaXQpKSB7XG4gICAgcmV0dXJuIHZhbHVlRXhwcih2LCBnZXRMb2NhbFRpbWVVbml0KHRpbWVVbml0KSk7XG4gIH1cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplRmlsdGVyKGY6IEZpbHRlcik6IEZpbHRlciB7XG4gIGlmIChpc0ZpZWxkRmlsdGVyKGYpICYmIGYudGltZVVuaXQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZixcbiAgICAgIHRpbWVVbml0OiBub3JtYWxpemVUaW1lVW5pdChmLnRpbWVVbml0KVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIGY7XG59XG4iXX0= \ 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..024b3cade6 --- /dev/null +++ b/build/src/guide.d.ts @@ -0,0 +1,32 @@ +import { ValueDef } from './fielddef'; +import { VgEncodeChannel } from './vega.schema'; +export interface Guide { + /** + * 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](format.html) for more information. + * + * __Default value:__ derived from [numberFormat](config.html#format) config for quantitative fields and from [timeFormat](config.html#format) config for temporal fields. + */ + format?: string; + /** + * 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 a part of the title (e.g., `"Sum of Profit"`). If the field is binned or has a time unit applied, the applied function will be denoted in parentheses (e.g., `"Profit (binned)"`, `"Transaction Date (year-month)"`). Otherwise, the title is simply the field name. + * + * __Note__: You can customize the default field title format by providing the [`fieldTitle` property in the [config](config.html) or [`fieldTitle` function via the `compile` function's options](compile.html#field-title). + */ + title?: string | null; +} +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; +}; +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..3dcc61d678 --- /dev/null +++ b/build/src/guide.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.VL_ONLY_GUIDE_CONFIG = ['shortTimeLabels']; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VpZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZ3VpZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFzQ2EsUUFBQSxvQkFBb0IsR0FBZ0MsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtWYWx1ZURlZn0gZnJvbSAnLi9maWVsZGRlZic7XG5pbXBvcnQge1ZnRW5jb2RlQ2hhbm5lbH0gZnJvbSAnLi92ZWdhLnNjaGVtYSc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBHdWlkZSB7XG4gIC8qKlxuICAgKiBUaGUgZm9ybWF0dGluZyBwYXR0ZXJuIGZvciBsYWJlbHMuIFRoaXMgaXMgRDMncyBbbnVtYmVyIGZvcm1hdCBwYXR0ZXJuXShodHRwczovL2dpdGh1Yi5jb20vZDMvZDMtZm9ybWF0I2xvY2FsZV9mb3JtYXQpIGZvciBxdWFudGl0YXRpdmUgZmllbGRzIGFuZCBEMydzIFt0aW1lIGZvcm1hdCBwYXR0ZXJuXShodHRwczovL2dpdGh1Yi5jb20vZDMvZDMtdGltZS1mb3JtYXQjbG9jYWxlX2Zvcm1hdCkgZm9yIHRpbWUgZmllbGQuXG4gICAqXG4gICAqIFNlZSB0aGUgW2Zvcm1hdCBkb2N1bWVudGF0aW9uXShmb3JtYXQuaHRtbCkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAgZGVyaXZlZCBmcm9tIFtudW1iZXJGb3JtYXRdKGNvbmZpZy5odG1sI2Zvcm1hdCkgY29uZmlnIGZvciBxdWFudGl0YXRpdmUgZmllbGRzIGFuZCBmcm9tIFt0aW1lRm9ybWF0XShjb25maWcuaHRtbCNmb3JtYXQpIGNvbmZpZyBmb3IgdGVtcG9yYWwgZmllbGRzLlxuICAgKi9cbiAgZm9ybWF0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHRpdGxlIGZvciB0aGUgZmllbGQuIElmIGBudWxsYCwgdGhlIHRpdGxlIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fICBkZXJpdmVkIGZyb20gdGhlIGZpZWxkJ3MgbmFtZSBhbmQgdHJhbnNmb3JtYXRpb24gZnVuY3Rpb24gKGBhZ2dyZWdhdGVgLCBgYmluYCBhbmQgYHRpbWVVbml0YCkuICBJZiB0aGUgZmllbGQgaGFzIGFuIGFnZ3JlZ2F0ZSBmdW5jdGlvbiwgdGhlIGZ1bmN0aW9uIGlzIGRpc3BsYXllZCBhcyBhIHBhcnQgb2YgdGhlIHRpdGxlIChlLmcuLCBgXCJTdW0gb2YgUHJvZml0XCJgKS4gSWYgdGhlIGZpZWxkIGlzIGJpbm5lZCBvciBoYXMgYSB0aW1lIHVuaXQgYXBwbGllZCwgdGhlIGFwcGxpZWQgZnVuY3Rpb24gd2lsbCBiZSBkZW5vdGVkIGluIHBhcmVudGhlc2VzIChlLmcuLCBgXCJQcm9maXQgKGJpbm5lZClcImAsIGBcIlRyYW5zYWN0aW9uIERhdGUgKHllYXItbW9udGgpXCJgKS4gIE90aGVyd2lzZSwgdGhlIHRpdGxlIGlzIHNpbXBseSB0aGUgZmllbGQgbmFtZS5cbiAgICpcbiAgICogX19Ob3RlX186IFlvdSBjYW4gY3VzdG9taXplIHRoZSBkZWZhdWx0IGZpZWxkIHRpdGxlIGZvcm1hdCBieSBwcm92aWRpbmcgdGhlIFtgZmllbGRUaXRsZWAgcHJvcGVydHkgaW4gdGhlIFtjb25maWddKGNvbmZpZy5odG1sKSBvciBbYGZpZWxkVGl0bGVgIGZ1bmN0aW9uIHZpYSB0aGUgYGNvbXBpbGVgIGZ1bmN0aW9uJ3Mgb3B0aW9uc10oY29tcGlsZS5odG1sI2ZpZWxkLXRpdGxlKS5cbiAgICovXG4gIHRpdGxlPzogc3RyaW5nIHwgbnVsbDtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVmxPbmx5R3VpZGVDb25maWcge1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG1vbnRoIG5hbWVzIGFuZCB3ZWVrZGF5IG5hbWVzIHNob3VsZCBiZSBhYmJyZXZpYXRlZC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fICBgZmFsc2VgXG4gICAqL1xuICBzaG9ydFRpbWVMYWJlbHM/OiBib29sZWFuO1xufVxuXG5cbmV4cG9ydCB0eXBlIEd1aWRlRW5jb2RpbmdFbnRyeSA9IHtcbiAgW2sgaW4gVmdFbmNvZGVDaGFubmVsXT86IFZhbHVlRGVmO1xufTtcblxuZXhwb3J0IGNvbnN0IFZMX09OTFlfR1VJREVfQ09ORklHOiAoa2V5b2YgVmxPbmx5R3VpZGVDb25maWcpW10gPSBbJ3Nob3J0VGltZUxhYmVscyddO1xuIl19 \ 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..ef15285ba8 --- /dev/null +++ b/build/src/index.d.ts @@ -0,0 +1,24 @@ +export import axis = require('./axis'); +export import aggregate = require('./aggregate'); +export import bin = require('./bin'); +export import channel = require('./channel'); +export import compositeMark = require('./compositemark'); +export { compile } from './compile/compile'; +export import config = require('./config'); +export import data = require('./data'); +export import datetime = require('./datetime'); +export import encoding = require('./encoding'); +export import facet = require('./facet'); +export import fieldDef = require('./fielddef'); +export import legend = require('./legend'); +export import mark = require('./mark'); +export import scale = require('./scale'); +export import sort = require('./sort'); +export import spec = require('./spec'); +export import stack = require('./stack'); +export import timeUnit = require('./timeunit'); +export import transform = require('./transform'); +export import type = require('./type'); +export import util = require('./util'); +export import validate = require('./validate'); +export declare const version: string; diff --git a/build/src/index.js b/build/src/index.js new file mode 100644 index 0000000000..ddb4b90ee2 --- /dev/null +++ b/build/src/index.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.axis = require("./axis"); +exports.aggregate = require("./aggregate"); +exports.bin = require("./bin"); +exports.channel = require("./channel"); +exports.compositeMark = require("./compositemark"); +var compile_1 = require("./compile/compile"); +exports.compile = compile_1.compile; +exports.config = require("./config"); +exports.data = require("./data"); +exports.datetime = require("./datetime"); +exports.encoding = require("./encoding"); +exports.facet = require("./facet"); +exports.fieldDef = require("./fielddef"); +exports.legend = require("./legend"); +exports.mark = require("./mark"); +exports.scale = require("./scale"); +exports.sort = require("./sort"); +exports.spec = require("./spec"); +exports.stack = require("./stack"); +exports.timeUnit = require("./timeunit"); +exports.transform = require("./transform"); +exports.type = require("./type"); +exports.util = require("./util"); +exports.validate = require("./validate"); +exports.version = require('../package.json').version; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBdUM7QUFDdkMsMkNBQWlEO0FBQ2pELCtCQUFxQztBQUNyQyx1Q0FBNkM7QUFDN0MsbURBQXlEO0FBQ3pELDZDQUEwQztBQUFsQyw0QkFBQSxPQUFPLENBQUE7QUFDZixxQ0FBMkM7QUFDM0MsaUNBQXVDO0FBQ3ZDLHlDQUErQztBQUMvQyx5Q0FBK0M7QUFDL0MsbUNBQXlDO0FBQ3pDLHlDQUErQztBQUMvQyxxQ0FBMkM7QUFDM0MsaUNBQXVDO0FBQ3ZDLG1DQUF5QztBQUN6QyxpQ0FBdUM7QUFDdkMsaUNBQXVDO0FBQ3ZDLG1DQUF5QztBQUN6Qyx5Q0FBK0M7QUFDL0MsMkNBQWlEO0FBQ2pELGlDQUF1QztBQUN2QyxpQ0FBdUM7QUFDdkMseUNBQStDO0FBRWxDLFFBQUEsT0FBTyxHQUFXLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbXBvcnQgYXhpcyA9IHJlcXVpcmUoJy4vYXhpcycpO1xuZXhwb3J0IGltcG9ydCBhZ2dyZWdhdGUgPSByZXF1aXJlKCcuL2FnZ3JlZ2F0ZScpO1xuZXhwb3J0IGltcG9ydCBiaW4gPSByZXF1aXJlKCcuL2JpbicpO1xuZXhwb3J0IGltcG9ydCBjaGFubmVsID0gcmVxdWlyZSgnLi9jaGFubmVsJyk7XG5leHBvcnQgaW1wb3J0IGNvbXBvc2l0ZU1hcmsgPSByZXF1aXJlKCcuL2NvbXBvc2l0ZW1hcmsnKTtcbmV4cG9ydCB7Y29tcGlsZX0gZnJvbSAnLi9jb21waWxlL2NvbXBpbGUnO1xuZXhwb3J0IGltcG9ydCBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpO1xuZXhwb3J0IGltcG9ydCBkYXRhID0gcmVxdWlyZSgnLi9kYXRhJyk7XG5leHBvcnQgaW1wb3J0IGRhdGV0aW1lID0gcmVxdWlyZSgnLi9kYXRldGltZScpO1xuZXhwb3J0IGltcG9ydCBlbmNvZGluZyA9IHJlcXVpcmUoJy4vZW5jb2RpbmcnKTtcbmV4cG9ydCBpbXBvcnQgZmFjZXQgPSByZXF1aXJlKCcuL2ZhY2V0Jyk7XG5leHBvcnQgaW1wb3J0IGZpZWxkRGVmID0gcmVxdWlyZSgnLi9maWVsZGRlZicpO1xuZXhwb3J0IGltcG9ydCBsZWdlbmQgPSByZXF1aXJlKCcuL2xlZ2VuZCcpO1xuZXhwb3J0IGltcG9ydCBtYXJrID0gcmVxdWlyZSgnLi9tYXJrJyk7XG5leHBvcnQgaW1wb3J0IHNjYWxlID0gcmVxdWlyZSgnLi9zY2FsZScpO1xuZXhwb3J0IGltcG9ydCBzb3J0ID0gcmVxdWlyZSgnLi9zb3J0Jyk7XG5leHBvcnQgaW1wb3J0IHNwZWMgPSByZXF1aXJlKCcuL3NwZWMnKTtcbmV4cG9ydCBpbXBvcnQgc3RhY2sgPSByZXF1aXJlKCcuL3N0YWNrJyk7XG5leHBvcnQgaW1wb3J0IHRpbWVVbml0ID0gcmVxdWlyZSgnLi90aW1ldW5pdCcpO1xuZXhwb3J0IGltcG9ydCB0cmFuc2Zvcm0gPSByZXF1aXJlKCcuL3RyYW5zZm9ybScpO1xuZXhwb3J0IGltcG9ydCB0eXBlID0gcmVxdWlyZSgnLi90eXBlJyk7XG5leHBvcnQgaW1wb3J0IHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbmV4cG9ydCBpbXBvcnQgdmFsaWRhdGUgPSByZXF1aXJlKCcuL3ZhbGlkYXRlJyk7XG5cbmV4cG9ydCBjb25zdCB2ZXJzaW9uOiBzdHJpbmcgPSByZXF1aXJlKCcuLi9wYWNrYWdlLmpzb24nKS52ZXJzaW9uO1xuIl19 \ 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..bbdee0e6bc --- /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[] | 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" | "values" | "type" | "padding" | "orient" | "entryPadding" | "format" | "offset" | "tickCount" | "zindex")[]; +export declare const VG_LEGEND_PROPERTIES: ("title" | "values" | "opacity" | "size" | "shape" | "type" | "padding" | "stroke" | "fill" | "orient" | "entryPadding" | "format" | "offset" | "tickCount" | "zindex" | "encode")[]; diff --git a/build/src/legend.js b/build/src/legend.js new file mode 100644 index 0000000000..756cbd7f51 --- /dev/null +++ b/build/src/legend.js @@ -0,0 +1,32 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +exports.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 }); +exports.LEGEND_PROPERTIES = util_1.flagKeys(COMMON_LEGEND_PROPERTY_INDEX); +exports.VG_LEGEND_PROPERTIES = util_1.flagKeys(VG_LEGEND_PROPERTY_INDEX); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVnZW5kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xlZ2VuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsK0JBQXNDO0FBd0V6QixRQUFBLG1CQUFtQixHQUFpQixFQUFFLENBQUM7QUFFcEQsSUFBTSw0QkFBNEIsR0FBb0M7SUFDcEUsWUFBWSxFQUFFLENBQUM7SUFDZixNQUFNLEVBQUUsQ0FBQztJQUNULE1BQU0sRUFBRSxDQUFDO0lBQ1QsTUFBTSxFQUFFLENBQUM7SUFDVCxPQUFPLEVBQUUsQ0FBQztJQUNWLFNBQVMsRUFBRSxDQUFDO0lBQ1osS0FBSyxFQUFFLENBQUM7SUFDUixJQUFJLEVBQUUsQ0FBQztJQUNQLE1BQU0sRUFBRSxDQUFDO0lBQ1QsTUFBTSxFQUFFLENBQUM7Q0FDVixDQUFDO0FBRUYsSUFBTSx3QkFBd0IsZ0JBQ3pCLDRCQUE0QjtJQUMvQixpQkFBaUI7SUFDakIsT0FBTyxFQUFFLENBQUMsRUFDVixLQUFLLEVBQUUsQ0FBQyxFQUNSLE1BQU0sRUFBRSxDQUFDLEVBQ1QsSUFBSSxFQUFFLENBQUMsRUFDUCxJQUFJLEVBQUUsQ0FBQztJQUNQLFNBQVM7SUFDVCxNQUFNLEVBQUUsQ0FBQyxHQUNWLENBQUM7QUFFVyxRQUFBLGlCQUFpQixHQUFHLGVBQVEsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0FBRTNELFFBQUEsb0JBQW9CLEdBQUcsZUFBUSxDQUFDLHdCQUF3QixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RhdGVUaW1lfSBmcm9tICcuL2RhdGV0aW1lJztcbmltcG9ydCB7R3VpZGUsIEd1aWRlRW5jb2RpbmdFbnRyeSwgVmxPbmx5R3VpZGVDb25maWd9IGZyb20gJy4vZ3VpZGUnO1xuaW1wb3J0IHtGbGFnLCBmbGFnS2V5c30gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7VmdMZWdlbmQsIFZnTGVnZW5kQmFzZSwgVmdMZWdlbmRDb25maWd9IGZyb20gJy4vdmVnYS5zY2hlbWEnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgTGVnZW5kQ29uZmlnIGV4dGVuZHMgVmdMZWdlbmRDb25maWcsIFZsT25seUd1aWRlQ29uZmlnIHt9XG5cbi8qKlxuICogUHJvcGVydGllcyBvZiBhIGxlZ2VuZCBvciBib29sZWFuIGZsYWcgZm9yIGRldGVybWluaW5nIHdoZXRoZXIgdG8gc2hvdyBpdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMZWdlbmQgZXh0ZW5kcyBWZ0xlZ2VuZEJhc2UsIEd1aWRlIHtcbiAgLyoqXG4gICAqIE1hcmsgZGVmaW5pdGlvbnMgZm9yIGN1c3RvbSBsZWdlbmQgZW5jb2RpbmcuXG4gICAqXG4gICAqIEBoaWRlXG4gICAqL1xuICBlbmNvZGluZz86IExlZ2VuZEVuY29kaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVzaXJlZCBudW1iZXIgb2YgdGljayB2YWx1ZXMgZm9yIHF1YW50aXRhdGl2ZSBsZWdlbmRzLlxuICAgKi9cbiAgdGlja0NvdW50PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBFeHBsaWNpdGx5IHNldCB0aGUgdmlzaWJsZSBsZWdlbmQgdmFsdWVzLlxuICAgKi9cbiAgdmFsdWVzPzogbnVtYmVyW10gfCBzdHJpbmdbXSB8IERhdGVUaW1lW107XG5cbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIHRoZSBsZWdlbmQuIFVzZSBgXCJzeW1ib2xcImAgdG8gY3JlYXRlIGEgZGlzY3JldGUgbGVnZW5kIGFuZCBgXCJncmFkaWVudFwiYCBmb3IgYSBjb250aW51b3VzIGNvbG9yIGdyYWRpZW50LlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYFwiZ3JhZGllbnRcImAgZm9yIG5vbi1iaW5uZWQgcXVhbnRpdGF0aXZlIGZpZWxkcyBhbmQgdGVtcG9yYWwgZmllbGRzOyBgXCJzeW1ib2xcImAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgdHlwZT86ICdzeW1ib2wnIHwgJ2dyYWRpZW50JztcblxuICAvKipcbiAgICogQSBub24tcG9zaXRpdmUgaW50ZWdlciBpbmRpY2F0aW5nIHotaW5kZXggb2YgdGhlIGxlZ2VuZC5cbiAgICogSWYgemluZGV4IGlzIDAsIGxlZ2VuZCBzaG91bGQgYmUgZHJhd24gYmVoaW5kIGFsbCBjaGFydCBlbGVtZW50cy5cbiAgICogVG8gcHV0IHRoZW0gaW4gZnJvbnQsIHVzZSB6aW5kZXggPSAxLlxuICAgKiBAVEpTLXR5cGUgaW50ZWdlclxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICB6aW5kZXg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIExlZ2VuZEVuY29kaW5nID0ge1xuICAvKipcbiAgICogQ3VzdG9tIGVuY29kaW5nIGZvciB0aGUgbGVnZW5kIGNvbnRhaW5lci5cbiAgICogVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBjcmVhdGluZyBsZWdlbmQgd2l0aCBjdXN0b20geCwgeSBwb3NpdGlvbi5cbiAgICovXG4gIGxlZ2VuZD86IEd1aWRlRW5jb2RpbmdFbnRyeTtcblxuICAvKipcbiAgICogQ3VzdG9tIGVuY29kaW5nIGZvciB0aGUgbGVnZW5kIHRpdGxlIHRleHQgbWFyay5cbiAgICovXG4gIHRpdGxlPzogR3VpZGVFbmNvZGluZ0VudHJ5O1xuXG4gIC8qKlxuICAgKiBDdXN0b20gZW5jb2RpbmcgZm9yIGxlZ2VuZCBsYWJlbCB0ZXh0IG1hcmtzLlxuICAgKi9cbiAgbGFiZWxzPzogR3VpZGVFbmNvZGluZ0VudHJ5O1xuXG4gIC8qKlxuICAgKiBDdXN0b20gZW5jb2RpbmcgZm9yIGxlZ2VuZCBzeW1ib2wgbWFya3MuXG4gICAqL1xuICBzeW1ib2xzPzogR3VpZGVFbmNvZGluZ0VudHJ5O1xuXG4gIC8qKlxuICAgKiBDdXN0b20gZW5jb2RpbmcgZm9yIGxlZ2VuZCBncmFkaWVudCBmaWxsZWQgcmVjdCBtYXJrcy5cbiAgICovXG4gIGdyYWRpZW50PzogR3VpZGVFbmNvZGluZ0VudHJ5O1xufTtcblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRMZWdlbmRDb25maWc6IExlZ2VuZENvbmZpZyA9IHt9O1xuXG5jb25zdCBDT01NT05fTEVHRU5EX1BST1BFUlRZX0lOREVYOiBGbGFnPGtleW9mIChWZ0xlZ2VuZCB8IExlZ2VuZCk+ID0ge1xuICBlbnRyeVBhZGRpbmc6IDEsXG4gIGZvcm1hdDogMSxcbiAgb2Zmc2V0OiAxLFxuICBvcmllbnQ6IDEsXG4gIHBhZGRpbmc6IDEsXG4gIHRpY2tDb3VudDogMSxcbiAgdGl0bGU6IDEsXG4gIHR5cGU6IDEsXG4gIHZhbHVlczogMSxcbiAgemluZGV4OiAxXG59O1xuXG5jb25zdCBWR19MRUdFTkRfUFJPUEVSVFlfSU5ERVg6IEZsYWc8a2V5b2YgVmdMZWdlbmQ+ID0ge1xuICAuLi5DT01NT05fTEVHRU5EX1BST1BFUlRZX0lOREVYLFxuICAvLyBjaGFubmVsIHNjYWxlc1xuICBvcGFjaXR5OiAxLFxuICBzaGFwZTogMSxcbiAgc3Ryb2tlOiAxLFxuICBmaWxsOiAxLFxuICBzaXplOiAxLFxuICAvLyBlbmNvZGVcbiAgZW5jb2RlOiAxXG59O1xuXG5leHBvcnQgY29uc3QgTEVHRU5EX1BST1BFUlRJRVMgPSBmbGFnS2V5cyhDT01NT05fTEVHRU5EX1BST1BFUlRZX0lOREVYKTtcblxuZXhwb3J0IGNvbnN0IFZHX0xFR0VORF9QUk9QRVJUSUVTID0gZmxhZ0tleXMoVkdfTEVHRU5EX1BST1BFUlRZX0lOREVYKTtcbiJdfQ== \ 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..831bc30d0c --- /dev/null +++ b/build/src/log.d.ts @@ -0,0 +1,96 @@ +/** + * Vega-Lite's singleton logger utility. + */ +import { LoggerInterface } from 'vega-util'; +import { AggregateOp } from './aggregate'; +import { Channel } from './channel'; +import { CompositeMark } from './compositemark'; +import { DateTime, DateTimeExpr } from './datetime'; +import { FieldDef } from './fielddef'; +import { Mark } from './mark'; +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(logger: 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 the data from the secondary source."; + function primitiveChannelDef(channel: Channel, type: 'string' | 'number' | 'boolean', value: string | number | boolean): string; + function invalidFieldType(type: Type): 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 emptyFieldDef(fieldDef: FieldDef, channel: Channel): string; + function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: 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 unclearOrientContinuous(mark: Mark): string; + function unclearOrientDiscreteOrEmpty(mark: Mark): 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 cannotUseSizeFieldWithBandSize(positionChannel: 'x' | 'y'): 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, propertyOf: string, v1: T, v2: T): string; + function independentScaleMeansIndependentGuide(channel: Channel): string; + function conflictedDomain(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..cf6d78b34f --- /dev/null +++ b/build/src/log.js @@ -0,0 +1,298 @@ +"use strict"; +/** + * Vega-Lite's singleton logger utility. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +/** + * Main (default) Vega Logger instance for Vega-Lite + */ +var main = vega_util_1.logger(vega_util_1.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]; + } + (_a = this.warns).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.infos).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.debug = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.debugs).push.apply(_a, args); + return this; + var _a; + }; + return LocalLogger; +}()); +exports.LocalLogger = LocalLogger; +function wrap(f) { + return function () { + var logger = current = new LocalLogger(); + f(logger); + reset(); + }; +} +exports.wrap = wrap; +/** + * Set the singleton logger to be a custom logger + */ +function set(logger) { + current = logger; + return current; +} +exports.set = set; +/** + * Reset the main logger to use the default Vega Logger + */ +function reset() { + current = main; + return current; +} +exports.reset = reset; +function warn() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.warn.apply(current, arguments); +} +exports.warn = warn; +function info() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.info.apply(current, arguments); +} +exports.info = info; +function debug() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.debug.apply(current, arguments); +} +exports.debug = debug; +/** + * 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) { + 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: " + JSON.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 the data from the secondary source.'; + // ENCODING & FACET + function primitiveChannelDef(channel, type, value) { + return "Channel " + channel + " is a " + type + ". Converted to {value: " + value + "}."; + } + message.primitiveChannelDef = primitiveChannelDef; + function invalidFieldType(type) { + return "Invalid field type \"" + type + "\""; + } + message.invalidFieldType = invalidFieldType; + 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 emptyFieldDef(fieldDef, channel) { + return "Dropping " + JSON.stringify(fieldDef) + " from channel \"" + channel + "\" since it does not contain data field or value."; + } + message.emptyFieldDef = emptyFieldDef; + function incompatibleChannel(channel, markOrFacet, when) { + return channel + " dropped as it is incompatible with \"" + markOrFacet + "\"" + (when ? " when " + when : '') + "."; + } + message.incompatibleChannel = incompatibleChannel; + 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 unclearOrientContinuous(mark) { + return "Cannot clearly determine orientation for \"" + mark + "\" since both x and y channel encode continous fields. In this case, we use vertical by default"; + } + message.unclearOrientContinuous = unclearOrientContinuous; + function unclearOrientDiscreteOrEmpty(mark) { + return "Cannot clearly determine orientation for \"" + mark + "\" since both x and y channel encode discrete or empty fields."; + } + message.unclearOrientDiscreteOrEmpty = unclearOrientDiscreteOrEmpty; + 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 (" + JSON.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 (" + JSON.stringify(fieldDef) + ")."; + } + message.unaggregatedDomainWithLogScale = unaggregatedDomainWithLogScale; + function cannotUseSizeFieldWithBandSize(positionChannel) { + return "Using size field when " + positionChannel + "-channel has a band scale is not supported."; + } + message.cannotUseSizeFieldWithBandSize = cannotUseSizeFieldWithBandSize; + 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 + " property \"" + property + "\" (\"" + v1 + "\" and \"" + v2 + "\"). Using \"" + 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 conflictedDomain(channel) { + return "Cannot set " + channel + "-scale's \"domain\" as it is binned. Please use \"bin\"'s \"extent\" instead."; + } + message.conflictedDomain = conflictedDomain; + function domainSortDropped(sort) { + return "Dropping sort property \"" + JSON.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 + ": \"" + 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 " + JSON.stringify(d) + " as day cannot be combined with other units."; + } + message.droppedDay = droppedDay; +})(message = exports.message || (exports.message = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0dBRUc7O0FBRUgsdUNBQXdEO0FBY3hEOztHQUVHO0FBQ0gsSUFBTSxJQUFJLEdBQUcsa0JBQU0sQ0FBQyxnQkFBSSxDQUFDLENBQUM7QUFDMUIsSUFBSSxPQUFPLEdBQW9CLElBQUksQ0FBQztBQUVwQzs7R0FFRztBQUNIO0lBQUE7UUFDUyxVQUFLLEdBQVUsRUFBRSxDQUFDO1FBQ2xCLFVBQUssR0FBVSxFQUFFLENBQUM7UUFDbEIsV0FBTSxHQUFVLEVBQUUsQ0FBQztJQW9CNUIsQ0FBQztJQWxCUSwyQkFBSyxHQUFaO1FBQ0UsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTSwwQkFBSSxHQUFYO1FBQVksY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDeEIsQ0FBQSxLQUFBLElBQUksQ0FBQyxLQUFLLENBQUEsQ0FBQyxJQUFJLFdBQUksSUFBSSxFQUFFO1FBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUM7O0lBQ2QsQ0FBQztJQUVNLDBCQUFJLEdBQVg7UUFBWSxjQUFjO2FBQWQsVUFBYyxFQUFkLHFCQUFjLEVBQWQsSUFBYztZQUFkLHlCQUFjOztRQUN4QixDQUFBLEtBQUEsSUFBSSxDQUFDLEtBQUssQ0FBQSxDQUFDLElBQUksV0FBSSxJQUFJLEVBQUU7UUFDekIsTUFBTSxDQUFDLElBQUksQ0FBQzs7SUFDZCxDQUFDO0lBRU0sMkJBQUssR0FBWjtRQUFhLGNBQWM7YUFBZCxVQUFjLEVBQWQscUJBQWMsRUFBZCxJQUFjO1lBQWQseUJBQWM7O1FBQ3pCLENBQUEsS0FBQSxJQUFJLENBQUMsTUFBTSxDQUFBLENBQUMsSUFBSSxXQUFJLElBQUksRUFBRTtRQUMxQixNQUFNLENBQUMsSUFBSSxDQUFDOztJQUNkLENBQUM7SUFDSCxrQkFBQztBQUFELENBQUMs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RUQsbUNBQTBDLFNBQW9CO1FBQzVELE1BQU0sQ0FBQyxvQ0FBa0MsU0FBUyxNQUFHLENBQUM7SUFDeEQsQ0FBQztJQUZlLGlDQUF5Qiw0QkFFeEMsQ0FBQTtJQUVELG9DQUEyQyxTQUFpQjtRQUMxRCxNQUFNLENBQUMsZ0ZBQTZFLFNBQVMsUUFBSSxDQUFDO0lBQ3BHLENBQUM7SUFGZSxrQ0FBMEIsNkJBRXpDLENBQUE7SUFFRCxXQUFXO0lBQ1gseUJBQWdDLFFBQWdCLEVBQUUsS0FBc0I7UUFDdEUsTUFBTSxDQUFDLGFBQVcsUUFBUSxZQUFNLEtBQUssT0FBRyxDQUFDO0lBQzNDLENBQUM7SUFGZSx1QkFBZSxrQkFFOUIsQ0FBQTtJQUVELDZCQUFvQyxZQUFvQjtRQUN0RCxNQUFNLENBQUMsaUJBQWMsWUFBWSxzREFDL0IsWUFBWSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQUcsQ0FBQztJQUMzQyxDQUFDO0lBSGUsMkJBQW1CLHNCQUdsQyxDQUFBO0lBRUQsb0JBQTJCLENBQTBCO1FBQ25ELE1BQU0sQ0FBQyxnQ0FBOEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsaURBQThDLENBQUM7SUFDdkcsQ0FBQztJQUZlLGtCQUFVLGFBRXpCLENBQUE7QUFDSCxDQUFDLEVBN01nQixPQUFPLEdBQVAsZUFBTyxLQUFQLGVBQU8sUUE2TXZCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBWZWdhLUxpdGUncyBzaW5nbGV0b24gbG9nZ2VyIHV0aWxpdHkuXG4gKi9cblxuaW1wb3J0IHtsb2dnZXIsIExvZ2dlckludGVyZmFjZSwgV2Fybn0gZnJvbSAndmVnYS11dGlsJztcbmltcG9ydCB7QWdncmVnYXRlT3B9IGZyb20gJy4vYWdncmVnYXRlJztcbmltcG9ydCB7Q2hhbm5lbH0gZnJvbSAnLi9jaGFubmVsJztcbmltcG9ydCB7Q29tcG9zaXRlTWFya30gZnJvbSAnLi9jb21wb3NpdGVtYXJrJztcbmltcG9ydCB7RGF0ZVRpbWUsIERhdGVUaW1lRXhwcn0gZnJvbSAnLi9kYXRldGltZSc7XG5pbXBvcnQge0ZpZWxkRGVmfSBmcm9tICcuL2ZpZWxkZGVmJztcbmltcG9ydCB7TWFya30gZnJvbSAnLi9tYXJrJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuL3NjYWxlJztcbmltcG9ydCB7VHlwZX0gZnJvbSAnLi90eXBlJztcbmltcG9ydCB7VmdTb3J0RmllbGR9IGZyb20gJy4vdmVnYS5zY2hlbWEnO1xuXG5cbmV4cG9ydCB7TG9nZ2VySW50ZXJmYWNlfSBmcm9tICd2ZWdhLXV0aWwnO1xuXG4vKipcbiAqIE1haW4gKGRlZmF1bHQpIFZlZ2EgTG9nZ2VyIGluc3RhbmNlIGZvciBWZWdhLUxpdGVcbiAqL1xuY29uc3QgbWFpbiA9IGxvZ2dlcihXYXJuKTtcbmxldCBjdXJyZW50OiBMb2dnZXJJbnRlcmZhY2UgPSBtYWluO1xuXG4vKipcbiAqIExvZ2dlciB0b29sIGZvciBjaGVja2luZyBpZiB0aGUgY29kZSB0aHJvd3MgY29ycmVjdCB3YXJuaW5nXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NhbExvZ2dlciBpbXBsZW1lbnRzIExvZ2dlckludGVyZmFjZSB7XG4gIHB1YmxpYyB3YXJuczogYW55W10gPSBbXTtcbiAgcHVibGljIGluZm9zOiBhbnlbXSA9IFtdO1xuICBwdWJsaWMgZGVidWdzOiBhbnlbXSA9IFtdO1xuXG4gIHB1YmxpYyBsZXZlbCgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyB3YXJuKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgdGhpcy53YXJucy5wdXNoKC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGluZm8oLi4uYXJnczogYW55W10pIHtcbiAgICB0aGlzLmluZm9zLnB1c2goLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgZGVidWcoLi4uYXJnczogYW55W10pIHtcbiAgICB0aGlzLmRlYnVncy5wdXNoKC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwKGY6IChsb2dnZXI6IExvY2FsTG9nZ2VyKSA9PiB2b2lkKSB7XG4gIHJldHVybiAoKSA9PiB7XG4gICAgY29uc3QgbG9nZ2VyID0gY3VycmVudCA9IG5ldyBMb2NhbExvZ2dlcigpO1xuICAgIGYobG9nZ2VyKTtcbiAgICByZXNldCgpO1xuICB9O1xufVxuXG4vKipcbiAqIFNldCB0aGUgc2luZ2xldG9uIGxvZ2dlciB0byBiZSBhIGN1c3RvbSBsb2dnZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldChsb2dnZXI6IExvZ2dlckludGVyZmFjZSkge1xuICBjdXJyZW50ID0gbG9nZ2VyO1xuICByZXR1cm4gY3VycmVudDtcbn1cblxuLyoqXG4gKiBSZXNldCB0aGUgbWFpbiBsb2dnZXIgdG8gdXNlIHRoZSBkZWZhdWx0IFZlZ2EgTG9nZ2VyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldCgpIHtcbiAgY3VycmVudCA9IG1haW47XG4gIHJldHVybiBjdXJyZW50O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2FybiguLi5fOiBhbnlbXSkge1xuICBjdXJyZW50Lndhcm4uYXBwbHkoY3VycmVudCwgYXJndW1lbnRzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluZm8oLi4uXzogYW55W10pIHtcbiAgY3VycmVudC5pbmZvLmFwcGx5KGN1cnJlbnQsIGFyZ3VtZW50cyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWJ1ZyguLi5fOiBhbnlbXSkge1xuICBjdXJyZW50LmRlYnVnLmFwcGx5KGN1cnJlbnQsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogQ29sbGVjdGlvbiBvZiBhbGwgVmVnYS1MaXRlIEVycm9yIE1lc3NhZ2VzXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2UgbWVzc2FnZSB7XG4gIGV4cG9ydCBjb25zdCBJTlZBTElEX1NQRUMgPSAnSW52YWxpZCBzcGVjJztcblxuICAvLyBGSVRcbiAgZXhwb3J0IGNvbnN0IEZJVF9OT05fU0lOR0xFID0gJ0F1dG9zaXplIFwiZml0XCIgb25seSB3b3JrcyBmb3Igc2luZ2xlIHZpZXdzIGFuZCBsYXllcmVkIHZpZXdzLic7XG5cbiAgZXhwb3J0IGNvbnN0IENBTk5PVF9GSVhfUkFOR0VfU1RFUF9XSVRIX0ZJVCA9ICdDYW5ub3QgdXNlIGEgZml4ZWQgdmFsdWUgb2YgXCJyYW5nZVN0ZXBcIiB3aGVuIFwiYXV0b3NpemVcIiBpcyBcImZpdFwiLic7XG5cbiAgLy8gU0VMRUNUSU9OXG4gIGV4cG9ydCBmdW5jdGlvbiBjYW5ub3RQcm9qZWN0T25DaGFubmVsV2l0aG91dEZpZWxkKGNoYW5uZWw6IENoYW5uZWwpIHtcbiAgICByZXR1cm4gYENhbm5vdCBwcm9qZWN0IGEgc2VsZWN0aW9uIG9uIGVuY29kaW5nIGNoYW5uZWwgXCIke2NoYW5uZWx9XCIsIHdoaWNoIGhhcyBubyBmaWVsZC5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIG5lYXJlc3ROb3RTdXBwb3J0Rm9yQ29udGludW91cyhtYXJrOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYFRoZSBcIm5lYXJlc3RcIiB0cmFuc2Zvcm0gaXMgbm90IHN1cHBvcnRlZCBmb3IgJHttYXJrfSBtYXJrcy5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdGlvbk5vdEZvdW5kKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiBgQ2Fubm90IGZpbmQgYSBzZWxlY3Rpb24gbmFtZWQgXCIke25hbWV9XCJgO1xuICB9XG5cbiAgZXhwb3J0IGNvbnN0IFNDQUxFX0JJTkRJTkdTX0NPTlRJTlVPVVMgPSAnU2NhbGUgYmluZGluZ3MgYXJlIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBmb3Igc2NhbGVzIHdpdGggdW5iaW5uZWQsIGNvbnRpbnVvdXMgZG9tYWlucy4nO1xuXG4gIC8vIFJFUEVBVFxuICBleHBvcnQgZnVuY3Rpb24gbm9TdWNoUmVwZWF0ZWRWYWx1ZShmaWVsZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBVbmtub3duIHJlcGVhdGVkIHZhbHVlIFwiJHtmaWVsZH1cIi5gO1xuICB9XG5cbiAgLy8gQ09OQ0FUXG4gIGV4cG9ydCBjb25zdCBDT05DQVRfQ0FOTk9UX1NIQVJFX0FYSVMgPSAnQXhlcyBjYW5ub3QgYmUgc2hhcmVkIGluIGNvbmNhdGVuYXRlZCB2aWV3cy4nO1xuXG4gIC8vIFJFUEVBVFxuICBleHBvcnQgY29uc3QgUkVQRUFUX0NBTk5PVF9TSEFSRV9BWElTID0gJ0F4ZXMgY2Fubm90IGJlIHNoYXJlZCBpbiByZXBlYXRlZCB2aWV3cy4nO1xuXG4gIC8vIFRJVExFXG4gIGV4cG9ydCBmdW5jdGlvbiBjYW5ub3RTZXRUaXRsZUFuY2hvcih0eXBlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYENhbm5vdCBzZXQgdGl0bGUgXCJhbmNob3JcIiBmb3IgYSAke3R5cGV9IHNwZWNgO1xuICB9XG5cbiAgLy8gREFUQVxuICBleHBvcnQgZnVuY3Rpb24gdW5yZWNvZ25pemVkUGFyc2UocDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBVbnJlY29nbml6ZWQgcGFyc2UgXCIke3B9XCIuYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBkaWZmZXJlbnRQYXJzZShmaWVsZDogc3RyaW5nLCBsb2NhbDogc3RyaW5nLCBhbmNlc3Rvcjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBBbiBhbmNlc3RvciBwYXJzZWQgZmllbGQgXCIke2ZpZWxkfVwiIGFzICR7YW5jZXN0b3J9IGJ1dCBhIGNoaWxkIHdhbnRzIHRvIHBhcnNlIHRoZSBmaWVsZCBhcyAke2xvY2FsfS5gO1xuICB9XG5cbiAgLy8gVFJBTlNGT1JNU1xuICBleHBvcnQgZnVuY3Rpb24gaW52YWxpZFRyYW5zZm9ybUlnbm9yZWQodHJhbnNmb3JtOiBhbnkpIHtcbiAgICByZXR1cm4gYElnbm9yaW5nIGFuIGludmFsaWQgdHJhbnNmb3JtOiAke0pTT04uc3RyaW5naWZ5KHRyYW5zZm9ybSl9LmA7XG4gIH1cblxuICBleHBvcnQgY29uc3QgTk9fRklFTERTX05FRURTX0FTID0gJ0lmIFwiZnJvbS5maWVsZHNcIiBpcyBub3Qgc3BlY2lmaWVkLCBcImFzXCIgaGFzIHRvIGJlIGEgc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHRoZSBrZXkgdG8gYmUgdXNlZCBmb3IgdGhlIHRoZSBkYXRhIGZyb20gdGhlIHNlY29uZGFyeSBzb3VyY2UuJztcblxuICAvLyBFTkNPRElORyAmIEZBQ0VUXG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHByaW1pdGl2ZUNoYW5uZWxEZWYoY2hhbm5lbDogQ2hhbm5lbCwgdHlwZTogJ3N0cmluZycgfCAnbnVtYmVyJyB8ICdib29sZWFuJywgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gYENoYW5uZWwgJHtjaGFubmVsfSBpcyBhICR7dHlwZX0uIENvbnZlcnRlZCB0byB7dmFsdWU6ICR7dmFsdWV9fS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGludmFsaWRGaWVsZFR5cGUodHlwZTogVHlwZSkge1xuICAgIHJldHVybiBgSW52YWxpZCBmaWVsZCB0eXBlIFwiJHt0eXBlfVwiYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBpbnZhbGlkRmllbGRUeXBlRm9yQ291bnRBZ2dyZWdhdGUodHlwZTogVHlwZSwgYWdncmVnYXRlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYEludmFsaWQgZmllbGQgdHlwZSBcIiR7dHlwZX1cIiBmb3IgYWdncmVnYXRlOiBcIiR7YWdncmVnYXRlfVwiLCB1c2luZyBcInF1YW50aXRhdGl2ZVwiIGluc3RlYWQuYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBpbnZhbGlkQWdncmVnYXRlKGFnZ3JlZ2F0ZTogQWdncmVnYXRlT3AgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gYEludmFsaWQgYWdncmVnYXRpb24gb3BlcmF0b3IgXCIke2FnZ3JlZ2F0ZX1cImA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gZW1wdHlPckludmFsaWRGaWVsZFR5cGUodHlwZTogVHlwZSB8IHN0cmluZywgY2hhbm5lbDogQ2hhbm5lbCwgbmV3VHlwZTogVHlwZSkge1xuICAgIHJldHVybiBgSW52YWxpZCBmaWVsZCB0eXBlIFwiJHt0eXBlfVwiIGZvciBjaGFubmVsIFwiJHtjaGFubmVsfVwiLCB1c2luZyBcIiR7bmV3VHlwZX1cIiBpbnN0ZWFkLmA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gZW1wdHlGaWVsZERlZihmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiwgY2hhbm5lbDogQ2hhbm5lbCkge1xuICAgIHJldHVybiBgRHJvcHBpbmcgJHtKU09OLnN0cmluZ2lmeShmaWVsZERlZil9IGZyb20gY2hhbm5lbCBcIiR7Y2hhbm5lbH1cIiBzaW5jZSBpdCBkb2VzIG5vdCBjb250YWluIGRhdGEgZmllbGQgb3IgdmFsdWUuYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBpbmNvbXBhdGlibGVDaGFubmVsKGNoYW5uZWw6IENoYW5uZWwsIG1hcmtPckZhY2V0OiBNYXJrIHwgJ2ZhY2V0JyB8IENvbXBvc2l0ZU1hcmssIHdoZW4/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYCR7Y2hhbm5lbH0gZHJvcHBlZCBhcyBpdCBpcyBpbmNvbXBhdGlibGUgd2l0aCBcIiR7bWFya09yRmFjZXR9XCIke3doZW4gPyBgIHdoZW4gJHt3aGVufWAgOiAnJ30uYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBmYWNldENoYW5uZWxTaG91bGRCZURpc2NyZXRlKGNoYW5uZWw6IHN0cmluZykge1xuICAgIHJldHVybiBgJHtjaGFubmVsfSBlbmNvZGluZyBzaG91bGQgYmUgZGlzY3JldGUgKG9yZGluYWwgLyBub21pbmFsIC8gYmlubmVkKS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGRpc2NyZXRlQ2hhbm5lbENhbm5vdEVuY29kZShjaGFubmVsOiBDaGFubmVsLCB0eXBlOiBUeXBlKSB7XG4gICAgcmV0dXJuIGBVc2luZyBkaXNjcmV0ZSBjaGFubmVsIFwiJHtjaGFubmVsfVwiIHRvIGVuY29kZSBcIiR7dHlwZX1cIiBmaWVsZCBjYW4gYmUgbWlzbGVhZGluZyBhcyBpdCBkb2VzIG5vdCBlbmNvZGUgJHt0eXBlID09PSAnb3JkaW5hbCcgPyAnb3JkZXInIDogJ21hZ25pdHVkZSd9LmA7XG4gIH1cblxuICAvLyBNYXJrXG4gIGV4cG9ydCBjb25zdCBCQVJfV0lUSF9QT0lOVF9TQ0FMRV9BTkRfUkFOR0VTVEVQX05VTEwgPSAnQmFyIG1hcmsgc2hvdWxkIG5vdCBiZSB1c2VkIHdpdGggcG9pbnQgc2NhbGUgd2hlbiByYW5nZVN0ZXAgaXMgbnVsbC4gUGxlYXNlIHVzZSBiYW5kIHNjYWxlIGluc3RlYWQuJztcblxuICBleHBvcnQgZnVuY3Rpb24gdW5jbGVhck9yaWVudENvbnRpbnVvdXMobWFyazogTWFyaykge1xuICAgIHJldHVybiBgQ2Fubm90IGNsZWFybHkgZGV0ZXJtaW5lIG9yaWVudGF0aW9uIGZvciBcIiR7bWFya31cIiBzaW5jZSBib3RoIHggYW5kIHkgY2hhbm5lbCBlbmNvZGUgY29udGlub3VzIGZpZWxkcy4gSW4gdGhpcyBjYXNlLCB3ZSB1c2UgdmVydGljYWwgYnkgZGVmYXVsdGA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gdW5jbGVhck9yaWVudERpc2NyZXRlT3JFbXB0eShtYXJrOiBNYXJrKSB7XG4gICAgcmV0dXJuIGBDYW5ub3QgY2xlYXJseSBkZXRlcm1pbmUgb3JpZW50YXRpb24gZm9yIFwiJHttYXJrfVwiIHNpbmNlIGJvdGggeCBhbmQgeSBjaGFubmVsIGVuY29kZSBkaXNjcmV0ZSBvciBlbXB0eSBmaWVsZHMuYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBvcmllbnRPdmVycmlkZGVuKG9yaWdpbmFsOiBzdHJpbmcsIGFjdHVhbDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBTcGVjaWZpZWQgb3JpZW50IFwiJHtvcmlnaW5hbH1cIiBvdmVycmlkZGVuIHdpdGggXCIke2FjdHVhbH1cImA7XG4gIH1cblxuICAvLyBTQ0FMRVxuICBleHBvcnQgY29uc3QgQ0FOTk9UX1VOSU9OX0NVU1RPTV9ET01BSU5fV0lUSF9GSUVMRF9ET01BSU4gPSAnY3VzdG9tIGRvbWFpbiBzY2FsZSBjYW5ub3QgYmUgdW5pb25lZCB3aXRoIGRlZmF1bHQgZmllbGQtYmFzZWQgZG9tYWluJztcblxuICBleHBvcnQgZnVuY3Rpb24gY2Fubm90VXNlU2NhbGVQcm9wZXJ0eVdpdGhOb25Db2xvcihwcm9wOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYENhbm5vdCB1c2UgdGhlIHNjYWxlIHByb3BlcnR5IFwiJHtwcm9wfVwiIHdpdGggbm9uLWNvbG9yIGNoYW5uZWwuYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiB1bmFnZ3JlZ2F0ZURvbWFpbkhhc05vRWZmZWN0Rm9yUmF3RmllbGQoZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4pIHtcbiAgICByZXR1cm4gYFVzaW5nIHVuYWdncmVnYXRlZCBkb21haW4gd2l0aCByYXcgZmllbGQgaGFzIG5vIGVmZmVjdCAoJHtKU09OLnN0cmluZ2lmeShmaWVsZERlZil9KS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHVuYWdncmVnYXRlRG9tYWluV2l0aE5vblNoYXJlZERvbWFpbk9wKGFnZ3JlZ2F0ZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBVbmFnZ3JlZ2F0ZWQgZG9tYWluIG5vdCBhcHBsaWNhYmxlIGZvciBcIiR7YWdncmVnYXRlfVwiIHNpbmNlIGl0IHByb2R1Y2VzIHZhbHVlcyBvdXRzaWRlIHRoZSBvcmlnaW4gZG9tYWluIG9mIHRoZSBzb3VyY2UgZGF0YS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHVuYWdncmVnYXRlZERvbWFpbldpdGhMb2dTY2FsZShmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPikge1xuICAgIHJldHVybiBgVW5hZ2dyZWdhdGVkIGRvbWFpbiBpcyBjdXJyZW50bHkgdW5zdXBwb3J0ZWQgZm9yIGxvZyBzY2FsZSAoJHtKU09OLnN0cmluZ2lmeShmaWVsZERlZil9KS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGNhbm5vdFVzZVNpemVGaWVsZFdpdGhCYW5kU2l6ZShwb3NpdGlvbkNoYW5uZWw6ICd4J3wneScpIHtcbiAgICByZXR1cm4gYFVzaW5nIHNpemUgZmllbGQgd2hlbiAke3Bvc2l0aW9uQ2hhbm5lbH0tY2hhbm5lbCBoYXMgYSBiYW5kIHNjYWxlIGlzIG5vdCBzdXBwb3J0ZWQuYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBjYW5ub3RBcHBseVNpemVUb05vbk9yaWVudGVkTWFyayhtYXJrOiBNYXJrKSB7XG4gICAgcmV0dXJuIGBDYW5ub3QgYXBwbHkgc2l6ZSB0byBub24tb3JpZW50ZWQgbWFyayBcIiR7bWFya31cIi5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHJhbmdlU3RlcERyb3BwZWQoY2hhbm5lbDogQ2hhbm5lbCkge1xuICAgIHJldHVybiBgcmFuZ2VTdGVwIGZvciBcIiR7Y2hhbm5lbH1cIiBpcyBkcm9wcGVkIGFzIHRvcC1sZXZlbCAke1xuICAgICAgY2hhbm5lbCA9PT0gJ3gnID8gJ3dpZHRoJyA6ICdoZWlnaHQnfSBpcyBwcm92aWRlZC5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHNjYWxlVHlwZU5vdFdvcmtXaXRoQ2hhbm5lbChjaGFubmVsOiBDaGFubmVsLCBzY2FsZVR5cGU6IFNjYWxlVHlwZSwgZGVmYXVsdFNjYWxlVHlwZTogU2NhbGVUeXBlKSB7XG4gICAgcmV0dXJuIGBDaGFubmVsIFwiJHtjaGFubmVsfVwiIGRvZXMgbm90IHdvcmsgd2l0aCBcIiR7c2NhbGVUeXBlfVwiIHNjYWxlLiBXZSBhcmUgdXNpbmcgXCIke2RlZmF1bHRTY2FsZVR5cGV9XCIgc2NhbGUgaW5zdGVhZC5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHNjYWxlVHlwZU5vdFdvcmtXaXRoRmllbGREZWYoc2NhbGVUeXBlOiBTY2FsZVR5cGUsIGRlZmF1bHRTY2FsZVR5cGU6IFNjYWxlVHlwZSkge1xuICAgIHJldHVybiBgRmllbGREZWYgZG9lcyBub3Qgd29yayB3aXRoIFwiJHtzY2FsZVR5cGV9XCIgc2NhbGUuIFdlIGFyZSB1c2luZyBcIiR7ZGVmYXVsdFNjYWxlVHlwZX1cIiBzY2FsZSBpbnN0ZWFkLmA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gc2NhbGVQcm9wZXJ0eU5vdFdvcmtXaXRoU2NhbGVUeXBlKHNjYWxlVHlwZTogU2NhbGVUeXBlLCBwcm9wTmFtZTogc3RyaW5nLCBjaGFubmVsOiBDaGFubmVsKSB7XG4gICAgcmV0dXJuIGAke2NoYW5uZWx9LXNjYWxlJ3MgXCIke3Byb3BOYW1lfVwiIGlzIGRyb3BwZWQgYXMgaXQgZG9lcyBub3Qgd29yayB3aXRoICR7c2NhbGVUeXBlfSBzY2FsZS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHNjYWxlVHlwZU5vdFdvcmtXaXRoTWFyayhtYXJrOiBNYXJrLCBzY2FsZVR5cGU6IFNjYWxlVHlwZSkge1xuICAgIHJldHVybiBgU2NhbGUgdHlwZSBcIiR7c2NhbGVUeXBlfVwiIGRvZXMgbm90IHdvcmsgd2l0aCBtYXJrIFwiJHttYXJrfVwiLmA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gbWVyZ2VDb25mbGljdGluZ1Byb3BlcnR5PFQ+KHByb3BlcnR5OiBzdHJpbmcsIHByb3BlcnR5T2Y6IHN0cmluZywgdjE6IFQsIHYyOiBUKSB7XG4gICAgcmV0dXJuIGBDb25mbGljdGluZyAke3Byb3BlcnR5T2Z9IHByb3BlcnR5IFwiJHtwcm9wZXJ0eX1cIiAoXCIke3YxfVwiIGFuZCBcIiR7djJ9XCIpLiAgVXNpbmcgXCIke3YxfVwiLmA7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gaW5kZXBlbmRlbnRTY2FsZU1lYW5zSW5kZXBlbmRlbnRHdWlkZShjaGFubmVsOiBDaGFubmVsKSB7XG4gICAgcmV0dXJuIGBTZXR0aW5nIHRoZSBzY2FsZSB0byBiZSBpbmRlcGVuZGVudCBmb3IgXCIke2NoYW5uZWx9XCIgbWVhbnMgd2UgYWxzbyBoYXZlIHRvIHNldCB0aGUgZ3VpZGUgKGF4aXMgb3IgbGVnZW5kKSB0byBiZSBpbmRlcGVuZGVudC5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGNvbmZsaWN0ZWREb21haW4oY2hhbm5lbDogQ2hhbm5lbCkge1xuICAgIHJldHVybiBgQ2Fubm90IHNldCAke2NoYW5uZWx9LXNjYWxlJ3MgXCJkb21haW5cIiBhcyBpdCBpcyBiaW5uZWQuIFBsZWFzZSB1c2UgXCJiaW5cIidzIFwiZXh0ZW50XCIgaW5zdGVhZC5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGRvbWFpblNvcnREcm9wcGVkKHNvcnQ6IFZnU29ydEZpZWxkKSB7XG4gICAgcmV0dXJuIGBEcm9wcGluZyBzb3J0IHByb3BlcnR5IFwiJHtKU09OLnN0cmluZ2lmeShzb3J0KX1cIiBhcyB1bmlvbmVkIGRvbWFpbnMgb25seSBzdXBwb3J0IGJvb2xlYW4gb3Igb3AgJ2NvdW50Jy5gO1xuICB9XG5cbiAgZXhwb3J0IGNvbnN0IFVOQUJMRV9UT19NRVJHRV9ET01BSU5TID0gJ1VuYWJsZSB0byBtZXJnZSBkb21haW5zJztcblxuICBleHBvcnQgY29uc3QgTU9SRV9USEFOX09ORV9TT1JUID0gJ0RvbWFpbnMgdGhhdCBzaG91bGQgYmUgdW5pb25lZCBoYXMgY29uZmxpY3Rpbmcgc29ydCBwcm9wZXJ0aWVzLiBTb3J0IHdpbGwgYmUgc2V0IHRvIHRydWUuJztcblxuICAvLyBBWElTXG4gIGV4cG9ydCBjb25zdCBJTlZBTElEX0NIQU5ORUxfRk9SX0FYSVMgPSAnSW52YWxpZCBjaGFubmVsIGZvciBheGlzLic7XG5cbiAgLy8gU1RBQ0tcbiAgZXhwb3J0IGZ1bmN0aW9uIGNhbm5vdFN0YWNrUmFuZ2VkTWFyayhjaGFubmVsOiBDaGFubmVsKSB7XG4gICAgcmV0dXJuIGBDYW5ub3Qgc3RhY2sgXCIke2NoYW5uZWx9XCIgaWYgdGhlcmUgaXMgYWxyZWFkeSBcIiR7Y2hhbm5lbH0yXCJgO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGNhbm5vdFN0YWNrTm9uTGluZWFyU2NhbGUoc2NhbGVUeXBlOiBTY2FsZVR5cGUpIHtcbiAgICByZXR1cm4gYENhbm5vdCBzdGFjayBub24tbGluZWFyIHNjYWxlICgke3NjYWxlVHlwZX0pYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBzdGFja05vblN1bW1hdGl2ZUFnZ3JlZ2F0ZShhZ2dyZWdhdGU6IHN0cmluZykge1xuICAgIHJldHVybiBgU3RhY2tpbmcgaXMgYXBwbGllZCBldmVuIHRob3VnaCB0aGUgYWdncmVnYXRlIGZ1bmN0aW9uIGlzIG5vbi1zdW1tYXRpdmUgKFwiJHthZ2dyZWdhdGV9XCIpYDtcbiAgfVxuXG4gIC8vIFRJTUVVTklUXG4gIGV4cG9ydCBmdW5jdGlvbiBpbnZhbGlkVGltZVVuaXQodW5pdE5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IG51bWJlcikge1xuICAgIHJldHVybiBgSW52YWxpZCAke3VuaXROYW1lfTogXCIke3ZhbHVlfVwiYDtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBkYXlSZXBsYWNlZFdpdGhEYXRlKGZ1bGxUaW1lVW5pdDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBUaW1lIHVuaXQgXCIke2Z1bGxUaW1lVW5pdH1cIiBpcyBub3Qgc3VwcG9ydGVkLiBXZSBhcmUgcmVwbGFjaW5nIGl0IHdpdGggJHtcbiAgICAgIGZ1bGxUaW1lVW5pdC5yZXBsYWNlKCdkYXknLCAnZGF0ZScpfS5gO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIGRyb3BwZWREYXkoZDogRGF0ZVRpbWUgfCBEYXRlVGltZUV4cHIpIHtcbiAgICByZXR1cm4gYERyb3BwaW5nIGRheSBmcm9tIGRhdGV0aW1lICR7SlNPTi5zdHJpbmdpZnkoZCl9IGFzIGRheSBjYW5ub3QgYmUgY29tYmluZWQgd2l0aCBvdGhlciB1bml0cy5gO1xuICB9XG59XG5cbiJdfQ== \ 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..91e6c767d0 --- /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 forEachLeave(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..715b6e85b3 --- /dev/null +++ b/build/src/logical.js @@ -0,0 +1,51 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isLogicalOr(op) { + return !!op.or; +} +exports.isLogicalOr = isLogicalOr; +function isLogicalAnd(op) { + return !!op.and; +} +exports.isLogicalAnd = isLogicalAnd; +function isLogicalNot(op) { + return !!op.not; +} +exports.isLogicalNot = isLogicalNot; +function forEachLeave(op, fn) { + if (isLogicalNot(op)) { + forEachLeave(op.not, fn); + } + else if (isLogicalAnd(op)) { + for (var _i = 0, _a = op.and; _i < _a.length; _i++) { + var subop = _a[_i]; + forEachLeave(subop, fn); + } + } + else if (isLogicalOr(op)) { + for (var _b = 0, _c = op.or; _b < _c.length; _b++) { + var subop = _c[_b]; + forEachLeave(subop, fn); + } + } + else { + fn(op); + } +} +exports.forEachLeave = forEachLeave; +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); + } +} +exports.normalizeLogicalOperand = normalizeLogicalOperand; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9naWNhbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sb2dpY2FsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBY0EscUJBQTRCLEVBQXVCO0lBQ2pELE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUNqQixDQUFDO0FBRkQsa0NBRUM7QUFFRCxzQkFBNkIsRUFBdUI7SUFDbEQsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDO0FBQ2xCLENBQUM7QUFGRCxvQ0FFQztBQUVELHNCQUE2QixFQUF1QjtJQUNsRCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUM7QUFDbEIsQ0FBQztBQUZELG9DQUVDO0FBRUQsc0JBQWdDLEVBQXFCLEVBQUUsRUFBbUI7SUFDeEUsRUFBRSxDQUFDLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixZQUFZLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsR0FBRyxDQUFDLENBQWdCLFVBQU0sRUFBTixLQUFBLEVBQUUsQ0FBQyxHQUFHLEVBQU4sY0FBTSxFQUFOLElBQU07WUFBckIsSUFBTSxLQUFLLFNBQUE7WUFDZCxZQUFZLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ3pCO0lBQ0gsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLEdBQUcsQ0FBQyxDQUFnQixVQUFLLEVBQUwsS0FBQSxFQUFFLENBQUMsRUFBRSxFQUFMLGNBQUssRUFBTCxJQUFLO1lBQXBCLElBQU0sS0FBSyxTQUFBO1lBQ2QsWUFBWSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztTQUN6QjtJQUNILENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNULENBQUM7QUFDSCxDQUFDO0FBZEQsb0NBY0M7QUFFRCxpQ0FBMkMsRUFBcUIsRUFBRSxVQUF1QjtJQUN2RixFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyxFQUFDLEdBQUcsRUFBRSx1QkFBdUIsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFDLENBQUM7SUFDNUQsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxFQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLHVCQUF1QixDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsRUFBdEMsQ0FBc0MsQ0FBQyxFQUFDLENBQUM7SUFDeEUsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxFQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLHVCQUF1QixDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsRUFBdEMsQ0FBc0MsQ0FBQyxFQUFDLENBQUM7SUFDdEUsQ0FBQztJQUFDLElBQUksQ0FBQyxDQUFDO1FBQ04sTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4QixDQUFDO0FBQ0gsQ0FBQztBQVZELDBEQVVDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgTG9naWNhbE9wZXJhbmQ8VD4gPSBMb2dpY2FsTm90PFQ+IHwgTG9naWNhbEFuZDxUPiB8IExvZ2ljYWxPcjxUPiB8IFQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9naWNhbE9yPFQ+IHtcbiAgb3I6IExvZ2ljYWxPcGVyYW5kPFQ+W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9naWNhbEFuZDxUPiB7XG4gIGFuZDogTG9naWNhbE9wZXJhbmQ8VD5bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2dpY2FsTm90PFQ+IHtcbiAgbm90OiBMb2dpY2FsT3BlcmFuZDxUPjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTG9naWNhbE9yKG9wOiBMb2dpY2FsT3BlcmFuZDxhbnk+KTogb3AgaXMgTG9naWNhbE9yPGFueT4ge1xuICByZXR1cm4gISFvcC5vcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTG9naWNhbEFuZChvcDogTG9naWNhbE9wZXJhbmQ8YW55Pik6IG9wIGlzIExvZ2ljYWxBbmQ8YW55PiB7XG4gIHJldHVybiAhIW9wLmFuZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTG9naWNhbE5vdChvcDogTG9naWNhbE9wZXJhbmQ8YW55Pik6IG9wIGlzIExvZ2ljYWxOb3Q8YW55PiB7XG4gIHJldHVybiAhIW9wLm5vdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvckVhY2hMZWF2ZTxUPihvcDogTG9naWNhbE9wZXJhbmQ8VD4sIGZuOiAob3A6IFQpID0+IHZvaWQpIHtcbiAgaWYgKGlzTG9naWNhbE5vdChvcCkpIHtcbiAgICBmb3JFYWNoTGVhdmUob3Aubm90LCBmbik7XG4gIH0gZWxzZSBpZiAoaXNMb2dpY2FsQW5kKG9wKSkge1xuICAgIGZvciAoY29uc3Qgc3Vib3Agb2Ygb3AuYW5kKSB7XG4gICAgICBmb3JFYWNoTGVhdmUoc3Vib3AsIGZuKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNMb2dpY2FsT3Iob3ApKSB7XG4gICAgZm9yIChjb25zdCBzdWJvcCBvZiBvcC5vcikge1xuICAgICAgZm9yRWFjaExlYXZlKHN1Ym9wLCBmbik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZuKG9wKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplTG9naWNhbE9wZXJhbmQ8VD4ob3A6IExvZ2ljYWxPcGVyYW5kPFQ+LCBub3JtYWxpemVyOiAobzogVCkgPT4gVCk6IExvZ2ljYWxPcGVyYW5kPFQ+IHtcbiAgaWYgKGlzTG9naWNhbE5vdChvcCkpIHtcbiAgICByZXR1cm4ge25vdDogbm9ybWFsaXplTG9naWNhbE9wZXJhbmQob3Aubm90LCBub3JtYWxpemVyKX07XG4gIH0gZWxzZSBpZiAoaXNMb2dpY2FsQW5kKG9wKSkge1xuICAgIHJldHVybiB7YW5kOiBvcC5hbmQubWFwKG8gPT4gbm9ybWFsaXplTG9naWNhbE9wZXJhbmQobywgbm9ybWFsaXplcikpfTtcbiAgfSBlbHNlIGlmIChpc0xvZ2ljYWxPcihvcCkpIHtcbiAgICByZXR1cm4ge29yOiBvcC5vci5tYXAobyA9PiBub3JtYWxpemVMb2dpY2FsT3BlcmFuZChvLCBub3JtYWxpemVyKSl9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBub3JtYWxpemVyKG9wKTtcbiAgfVxufVxuIl19 \ 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..e6aadc00bd --- /dev/null +++ b/build/src/mark.d.ts @@ -0,0 +1,157 @@ +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 CIRCLE: 'circle'; + const SQUARE: 'square'; +} +/** + * All types of primitive marks. + */ +export declare type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE; +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 RECT: "rect"; +export declare const RULE: "rule"; +export declare const CIRCLE: "circle"; +export declare const SQUARE: "square"; +export declare function isMark(m: string): m is Mark; +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](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](mark.html#style-config). + */ + color?: string; +} +export interface MarkDef extends MarkConfig { + /** + * The mark type. + * One of `"bar"`, `"circle"`, `"square"`, `"tick"`, `"line"`, + * `"area"`, `"point"`, `"rule"`, and `"text"`. + */ + type: Mark; + /** + * + * 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](mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](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; +} +/** @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?: MarkConfig; + /** Bar-Specific Config */ + bar?: BarConfig; + /** Circle-Specific Config */ + circle?: MarkConfig; + /** Line-Specific Config */ + line?: MarkConfig; + /** 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; +} +export interface BarConfig extends MarkConfig { + /** + * Offset between bar 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; + /** + * 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 const defaultBarConfig: BarConfig; +export interface TextConfig extends MarkConfig { + /** + * Whether month names and weekday names should be abbreviated. + */ + shortTimeLabels?: boolean; +} +export interface TickConfig extends MarkConfig { + /** + * The width of the ticks. + * + * __Default value:__ 2/3 of rangeStep. + * @minimum 0 + */ + bandSize?: number; + /** + * Thickness of the tick mark. + * + * __Default value:__ `1` + * + * @minimum 0 + */ + thickness?: number; +} +export declare const defaultTickConfig: TickConfig; diff --git a/build/src/mark.js b/build/src/mark.js new file mode 100644 index 0000000000..438e7f5b01 --- /dev/null +++ b/build/src/mark.js @@ -0,0 +1,75 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +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.CIRCLE = 'circle'; + Mark.SQUARE = 'square'; +})(Mark = exports.Mark || (exports.Mark = {})); +exports.AREA = Mark.AREA; +exports.BAR = Mark.BAR; +exports.LINE = Mark.LINE; +exports.POINT = Mark.POINT; +exports.TEXT = Mark.TEXT; +exports.TICK = Mark.TICK; +exports.RECT = Mark.RECT; +exports.RULE = Mark.RULE; +exports.CIRCLE = Mark.CIRCLE; +exports.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, + rect: 1, + rule: 1, + circle: 1, + square: 1 +}; +function isMark(m) { + return !!MARK_INDEX[m]; +} +exports.isMark = isMark; +exports.PRIMITIVE_MARKS = util_1.flagKeys(MARK_INDEX); +function isMarkDef(mark) { + return mark['type']; +} +exports.isMarkDef = isMarkDef; +var PRIMITIVE_MARK_INDEX = util_1.toSet(exports.PRIMITIVE_MARKS); +function isPrimitiveMark(mark) { + var markType = isMarkDef(mark) ? mark.type : mark; + return markType in PRIMITIVE_MARK_INDEX; +} +exports.isPrimitiveMark = isPrimitiveMark; +exports.STROKE_CONFIG = ['stroke', 'strokeWidth', + 'strokeDash', 'strokeDashOffset', 'strokeOpacity']; +exports.FILL_CONFIG = ['fill', 'fillOpacity']; +exports.FILL_STROKE_CONFIG = [].concat(exports.STROKE_CONFIG, exports.FILL_CONFIG); +exports.VL_ONLY_MARK_CONFIG_PROPERTIES = ['filled', 'color']; +exports.VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = { + bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'], + text: ['shortTimeLabels'], + tick: ['bandSize', 'thickness'] +}; +exports.defaultMarkConfig = { + color: '#4c78a8', +}; +exports.defaultBarConfig = { + binSpacing: 1, + continuousBandSize: 5 +}; +exports.defaultTickConfig = { + thickness: 1 +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYXJrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsK0JBQXVDO0FBR3ZDLElBQWlCLElBQUksQ0FXcEI7QUFYRCxXQUFpQixJQUFJO0lBQ04sU0FBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixRQUFHLEdBQVUsS0FBSyxDQUFDO0lBQ25CLFNBQUksR0FBVyxNQUFNLENBQUM7SUFDdEIsVUFBSyxHQUFZLE9BQU8sQ0FBQztJQUN6QixTQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLFNBQUksR0FBVyxNQUFNLENBQUM7SUFDdEIsU0FBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixTQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLFdBQU0sR0FBYSxRQUFRLENBQUM7SUFDNUIsV0FBTSxHQUFhLFFBQVEsQ0FBQztBQUMzQyxDQUFDLEVBWGdCLElBQUksR0FBSixZQUFJLEtBQUosWUFBSSxRQVdwQjtBQVFZLFFBQUEsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDakIsUUFBQSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNmLFFBQUEsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDakIsUUFBQSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztBQUNuQixRQUFBLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ2pCLFFBQUEsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDakIsUUFBQSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUNqQixRQUFBLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBRWpCLFFBQUEsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDckIsUUFBQSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUVsQywwRkFBMEY7QUFDMUYsSUFBTSxVQUFVLEdBQXFCO0lBQ25DLElBQUksRUFBRSxDQUFDO0lBQ1AsR0FBRyxFQUFFLENBQUM7SUFDTixJQUFJLEVBQUUsQ0FBQztJQUNQLEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBSSxFQUFFLENBQUM7SUFDUCxJQUFJLEVBQUUsQ0FBQztJQUNQLElBQUksRUFBRSxDQUFDO0lBQ1AsSUFBSSxFQUFFLENBQUM7SUFDUCxNQUFNLEVBQUUsQ0FBQztJQUNULE1BQU0sRUFBRSxDQUFDO0NBQ1YsQ0FBQztBQUVGLGdCQUF1QixDQUFTO0lBQzlCLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFGRCx3QkFFQztBQUVZLFFBQUEsZUFBZSxHQUFHLGVBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQTBEcEQsbUJBQTBCLElBQWE7SUFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN0QixDQUFDO0FBRkQsOEJBRUM7QUFFRCxJQUFNLG9CQUFvQixHQUFHLFlBQUssQ0FBQyx1QkFBZSxDQUFDLENBQUM7QUFFcEQseUJBQWdDLElBQXVEO0lBQ3JGLElBQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3BELE1BQU0sQ0FBQyxRQUFRLElBQUksb0JBQW9CLENBQUM7QUFDMUMsQ0FBQztBQUhELDBDQUdDO0FBRVksUUFBQSxhQUFhLEdBQUcsQ0FBQyxRQUFRLEVBQUUsYUFBYTtJQUNuRCxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFFeEMsUUFBQSxXQUFXLEdBQUcsQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFFdEMsUUFBQSxrQkFBa0IsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLHFCQUFhLEVBQUUsbUJBQVcsQ0FBQyxDQUFDO0FBRTNELFFBQUEsOEJBQThCLEdBQXlCLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBRTNFLFFBQUEsMkNBQTJDLEdBRXBEO0lBQ0YsR0FBRyxFQUFFLENBQUMsWUFBWSxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixDQUFDO0lBQzdELElBQUksRUFBRSxDQUFDLGlCQUFpQixDQUFDO0lBQ3pCLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUM7Q0FDaEMsQ0FBQztBQUlXLFFBQUEsaUJBQWlCLEdBQWU7SUFDM0MsS0FBSyxFQUFFLFNBQVM7Q0FDakIsQ0FBQztBQWdFVyxRQUFBLGdCQUFnQixHQUFjO0lBQ3pDLFVBQVUsRUFBRSxDQUFDO0lBQ2Isa0JBQWtCLEVBQUUsQ0FBQztDQUN0QixDQUFDO0FBNEJXLFFBQUEsaUJBQWlCLEdBQWU7SUFDM0MsU0FBUyxFQUFFLENBQUM7Q0FDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb21wb3NpdGVNYXJrLCBDb21wb3NpdGVNYXJrRGVmfSBmcm9tICcuL2NvbXBvc2l0ZW1hcmsvaW5kZXgnO1xuaW1wb3J0IHtmbGFnS2V5cywgdG9TZXR9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQge1ZnTWFya0NvbmZpZ30gZnJvbSAnLi92ZWdhLnNjaGVtYSc7XG5cbmV4cG9ydCBuYW1lc3BhY2UgTWFyayB7XG4gIGV4cG9ydCBjb25zdCBBUkVBOiAnYXJlYScgPSAnYXJlYSc7XG4gIGV4cG9ydCBjb25zdCBCQVI6ICdiYXInID0gJ2Jhcic7XG4gIGV4cG9ydCBjb25zdCBMSU5FOiAnbGluZScgPSAnbGluZSc7XG4gIGV4cG9ydCBjb25zdCBQT0lOVDogJ3BvaW50JyA9ICdwb2ludCc7XG4gIGV4cG9ydCBjb25zdCBSRUNUOiAncmVjdCcgPSAncmVjdCc7XG4gIGV4cG9ydCBjb25zdCBSVUxFOiAncnVsZScgPSAncnVsZSc7XG4gIGV4cG9ydCBjb25zdCBURVhUOiAndGV4dCcgPSAndGV4dCc7XG4gIGV4cG9ydCBjb25zdCBUSUNLOiAndGljaycgPSAndGljayc7XG4gIGV4cG9ydCBjb25zdCBDSVJDTEU6ICdjaXJjbGUnID0gJ2NpcmNsZSc7XG4gIGV4cG9ydCBjb25zdCBTUVVBUkU6ICdzcXVhcmUnID0gJ3NxdWFyZSc7XG59XG5cbi8qKlxuICogQWxsIHR5cGVzIG9mIHByaW1pdGl2ZSBtYXJrcy5cbiAqL1xuZXhwb3J0IHR5cGUgTWFyayA9IHR5cGVvZiBNYXJrLkFSRUEgfCB0eXBlb2YgTWFyay5CQVIgfCB0eXBlb2YgTWFyay5MSU5FIHwgdHlwZW9mIE1hcmsuUE9JTlQgfCB0eXBlb2YgTWFyay5URVhUIHwgdHlwZW9mIE1hcmsuVElDSyB8IHR5cGVvZiBNYXJrLlJFQ1QgfCB0eXBlb2YgTWFyay5SVUxFIHwgdHlwZW9mIE1hcmsuQ0lSQ0xFIHwgdHlwZW9mIE1hcmsuU1FVQVJFO1xuXG5cbmV4cG9ydCBjb25zdCBBUkVBID0gTWFyay5BUkVBO1xuZXhwb3J0IGNvbnN0IEJBUiA9IE1hcmsuQkFSO1xuZXhwb3J0IGNvbnN0IExJTkUgPSBNYXJrLkxJTkU7XG5leHBvcnQgY29uc3QgUE9JTlQgPSBNYXJrLlBPSU5UO1xuZXhwb3J0IGNvbnN0IFRFWFQgPSBNYXJrLlRFWFQ7XG5leHBvcnQgY29uc3QgVElDSyA9IE1hcmsuVElDSztcbmV4cG9ydCBjb25zdCBSRUNUID0gTWFyay5SRUNUO1xuZXhwb3J0IGNvbnN0IFJVTEUgPSBNYXJrLlJVTEU7XG5cbmV4cG9ydCBjb25zdCBDSVJDTEUgPSBNYXJrLkNJUkNMRTtcbmV4cG9ydCBjb25zdCBTUVVBUkUgPSBNYXJrLlNRVUFSRTtcblxuLy8gVXNpbmcgbWFwcGVkIHR5cGUgdG8gZGVjbGFyZSBpbmRleCwgZW5zdXJpbmcgd2UgYWx3YXlzIGhhdmUgYWxsIG1hcmtzIHdoZW4gd2UgYWRkIG1vcmUuXG5jb25zdCBNQVJLX0lOREVYOiB7W00gaW4gTWFya106IDF9ID0ge1xuICBhcmVhOiAxLFxuICBiYXI6IDEsXG4gIGxpbmU6IDEsXG4gIHBvaW50OiAxLFxuICB0ZXh0OiAxLFxuICB0aWNrOiAxLFxuICByZWN0OiAxLFxuICBydWxlOiAxLFxuICBjaXJjbGU6IDEsXG4gIHNxdWFyZTogMVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFyayhtOiBzdHJpbmcpOiBtIGlzIE1hcmsge1xuICByZXR1cm4gISFNQVJLX0lOREVYW21dO1xufVxuXG5leHBvcnQgY29uc3QgUFJJTUlUSVZFX01BUktTID0gZmxhZ0tleXMoTUFSS19JTkRFWCk7XG5cblxuZXhwb3J0IGludGVyZmFjZSBNYXJrQ29uZmlnIGV4dGVuZHMgVmdNYXJrQ29uZmlnIHtcbiAgLy8gLS0tLS0tLS0tLSBDb2xvciAtLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBtYXJrJ3MgY29sb3Igc2hvdWxkIGJlIHVzZWQgYXMgZmlsbCBjb2xvciBpbnN0ZWFkIG9mIHN0cm9rZSBjb2xvci5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB0cnVlYCBmb3IgYWxsIG1hcmtzIGV4Y2VwdCBgcG9pbnRgIGFuZCBgZmFsc2VgIGZvciBgcG9pbnRgLlxuICAgKlxuICAgKiBfX0FwcGxpY2FibGUgZm9yOl9fIGBiYXJgLCBgcG9pbnRgLCBgY2lyY2xlYCwgYHNxdWFyZWAsIGFuZCBgYXJlYWAgbWFya3MuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBUaGlzIHByb3BlcnR5IGNhbm5vdCBiZSB1c2VkIGluIGEgW3N0eWxlIGNvbmZpZ10obWFyay5odG1sI3N0eWxlLWNvbmZpZykuXG4gICAqXG4gICAqL1xuICBmaWxsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IGNvbG9yLiAgTm90ZSB0aGF0IGBmaWxsYCBhbmQgYHN0cm9rZWAgaGF2ZSBoaWdoZXIgcHJlY2VkZW5jZSB0aGFuIGBjb2xvcmAgYW5kIHdpbGwgb3ZlcnJpZGUgYGNvbG9yYC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIDxzcGFuIHN0eWxlPVwiY29sb3I6ICM0NjgyYjQ7XCI+JiM5NjMyOzwvc3Bhbj4gYFwiIzQ2ODJiNFwiYFxuICAgKlxuICAgKiBfX05vdGU6X18gVGhpcyBwcm9wZXJ0eSBjYW5ub3QgYmUgdXNlZCBpbiBhIFtzdHlsZSBjb25maWddKG1hcmsuaHRtbCNzdHlsZS1jb25maWcpLlxuICAgKi9cbiAgY29sb3I/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWFya0RlZiBleHRlbmRzIE1hcmtDb25maWcge1xuICAvKipcbiAgICogVGhlIG1hcmsgdHlwZS5cbiAgICogT25lIG9mIGBcImJhclwiYCwgYFwiY2lyY2xlXCJgLCBgXCJzcXVhcmVcImAsIGBcInRpY2tcImAsIGBcImxpbmVcImAsXG4gICAqIGBcImFyZWFcImAsIGBcInBvaW50XCJgLCBgXCJydWxlXCJgLCBhbmQgYFwidGV4dFwiYC5cbiAgICovXG4gIHR5cGU6IE1hcms7XG5cbiAgLyoqXG4gICAqXG4gICAqIEEgc3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3MgaW5kaWNhdGluZyB0aGUgbmFtZSBvZiBjdXN0b20gc3R5bGVzIHRvIGFwcGx5IHRvIHRoZSBtYXJrLiBBIHN0eWxlIGlzIGEgbmFtZWQgY29sbGVjdGlvbiBvZiBtYXJrIHByb3BlcnR5IGRlZmF1bHRzIGRlZmluZWQgd2l0aGluIHRoZSBbc3R5bGUgY29uZmlndXJhdGlvbl0obWFyay5odG1sI3N0eWxlLWNvbmZpZykuIElmIHN0eWxlIGlzIGFuIGFycmF5LCBsYXRlciBzdHlsZXMgd2lsbCBvdmVycmlkZSBlYXJsaWVyIHN0eWxlcy4gQW55IFttYXJrIHByb3BlcnRpZXNdKGVuY29kaW5nLmh0bWwjbWFyay1wcm9wKSBleHBsaWNpdGx5IGRlZmluZWQgd2l0aGluIHRoZSBgZW5jb2RpbmdgIHdpbGwgb3ZlcnJpZGUgYSBzdHlsZSBkZWZhdWx0LlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gVGhlIG1hcmsncyBuYW1lLiAgRm9yIGV4YW1wbGUsIGEgYmFyIG1hcmsgd2lsbCBoYXZlIHN0eWxlIGBcImJhclwiYCBieSBkZWZhdWx0LlxuICAgKiBfX05vdGU6X18gQW55IHNwZWNpZmllZCBzdHlsZSB3aWxsIGF1Z21lbnQgdGhlIGRlZmF1bHQgc3R5bGUuIEZvciBleGFtcGxlLCBhIGJhciBtYXJrIHdpdGggYFwic3R5bGVcIjogXCJmb29cImAgd2lsbCByZWNlaXZlIGZyb20gYGNvbmZpZy5zdHlsZS5iYXJgIGFuZCBgY29uZmlnLnN0eWxlLmZvb2AgKHRoZSBzcGVjaWZpZWQgc3R5bGUgYFwiZm9vXCJgIGhhcyBoaWdoZXIgcHJlY2VkZW5jZSkuXG4gICAqL1xuICBzdHlsZT86IHN0cmluZyB8IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGEgbWFyayBiZSBjbGlwcGVkIHRvIHRoZSBlbmNsb3NpbmcgZ3JvdXDigJlzIHdpZHRoIGFuZCBoZWlnaHQuXG4gICAqL1xuICBjbGlwPzogYm9vbGVhbjtcbn1cblxuLyoqIEBoaWRlICovXG5leHBvcnQgdHlwZSBIaWRkZW5Db21wb3NpdGUgPSBDb21wb3NpdGVNYXJrIHwgQ29tcG9zaXRlTWFya0RlZjtcblxuZXhwb3J0IHR5cGUgQW55TWFyayA9XG4gIEhpZGRlbkNvbXBvc2l0ZSB8XG4gIE1hcmsgfFxuICBNYXJrRGVmO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNNYXJrRGVmKG1hcms6IEFueU1hcmspOiBtYXJrIGlzIChNYXJrRGVmIHwgQ29tcG9zaXRlTWFya0RlZikge1xuICByZXR1cm4gbWFya1sndHlwZSddO1xufVxuXG5jb25zdCBQUklNSVRJVkVfTUFSS19JTkRFWCA9IHRvU2V0KFBSSU1JVElWRV9NQVJLUyk7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ByaW1pdGl2ZU1hcmsobWFyazogQ29tcG9zaXRlTWFyayB8IENvbXBvc2l0ZU1hcmtEZWYgfCBNYXJrIHwgTWFya0RlZik6IG1hcmsgaXMgTWFyayB7XG4gIGNvbnN0IG1hcmtUeXBlID0gaXNNYXJrRGVmKG1hcmspID8gbWFyay50eXBlIDogbWFyaztcbiAgcmV0dXJuIG1hcmtUeXBlIGluIFBSSU1JVElWRV9NQVJLX0lOREVYO1xufVxuXG5leHBvcnQgY29uc3QgU1RST0tFX0NPTkZJRyA9IFsnc3Ryb2tlJywgJ3N0cm9rZVdpZHRoJyxcbiAgJ3N0cm9rZURhc2gnLCAnc3Ryb2tlRGFzaE9mZnNldCcsICdzdHJva2VPcGFjaXR5J107XG5cbmV4cG9ydCBjb25zdCBGSUxMX0NPTkZJRyA9IFsnZmlsbCcsICdmaWxsT3BhY2l0eSddO1xuXG5leHBvcnQgY29uc3QgRklMTF9TVFJPS0VfQ09ORklHID0gW10uY29uY2F0KFNUUk9LRV9DT05GSUcsIEZJTExfQ09ORklHKTtcblxuZXhwb3J0IGNvbnN0IFZMX09OTFlfTUFSS19DT05GSUdfUFJPUEVSVElFUzogKGtleW9mIE1hcmtDb25maWcpW10gPSBbJ2ZpbGxlZCcsICdjb2xvciddO1xuXG5leHBvcnQgY29uc3QgVkxfT05MWV9NQVJLX1NQRUNJRklDX0NPTkZJR19QUk9QRVJUWV9JTkRFWDoge1xuICBbayBpbiAodHlwZW9mIFBSSU1JVElWRV9NQVJLU1swXSldPzogKGtleW9mIE1hcmtDb25maWdNaXhpbnNba10pW11cbn0gPSB7XG4gIGJhcjogWydiaW5TcGFjaW5nJywgJ2NvbnRpbnVvdXNCYW5kU2l6ZScsICdkaXNjcmV0ZUJhbmRTaXplJ10sXG4gIHRleHQ6IFsnc2hvcnRUaW1lTGFiZWxzJ10sXG4gIHRpY2s6IFsnYmFuZFNpemUnLCAndGhpY2tuZXNzJ11cbn07XG5cblxuXG5leHBvcnQgY29uc3QgZGVmYXVsdE1hcmtDb25maWc6IE1hcmtDb25maWcgPSB7XG4gIGNvbG9yOiAnIzRjNzhhOCcsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE1hcmtDb25maWdNaXhpbnMge1xuICAvKiogTWFyayBDb25maWcgKi9cbiAgbWFyaz86IE1hcmtDb25maWc7XG5cbiAgLy8gTUFSSy1TUEVDSUZJQyBDT05GSUdTXG4gIC8qKiBBcmVhLVNwZWNpZmljIENvbmZpZyAqL1xuICBhcmVhPzogTWFya0NvbmZpZztcblxuICAvKiogQmFyLVNwZWNpZmljIENvbmZpZyAqL1xuICBiYXI/OiBCYXJDb25maWc7XG5cbiAgLyoqIENpcmNsZS1TcGVjaWZpYyBDb25maWcgKi9cbiAgY2lyY2xlPzogTWFya0NvbmZpZztcblxuICAvKiogTGluZS1TcGVjaWZpYyBDb25maWcgKi9cbiAgbGluZT86IE1hcmtDb25maWc7XG5cbiAgLyoqIFBvaW50LVNwZWNpZmljIENvbmZpZyAqL1xuICBwb2ludD86IE1hcmtDb25maWc7XG5cbiAgLyoqIFJlY3QtU3BlY2lmaWMgQ29uZmlnICovXG4gIHJlY3Q/OiBNYXJrQ29uZmlnO1xuXG4gIC8qKiBSdWxlLVNwZWNpZmljIENvbmZpZyAqL1xuICBydWxlPzogTWFya0NvbmZpZztcblxuICAvKiogU3F1YXJlLVNwZWNpZmljIENvbmZpZyAqL1xuICBzcXVhcmU/OiBNYXJrQ29uZmlnO1xuXG4gIC8qKiBUZXh0LVNwZWNpZmljIENvbmZpZyAqL1xuICB0ZXh0PzogVGV4dENvbmZpZztcblxuICAvKiogVGljay1TcGVjaWZpYyBDb25maWcgKi9cbiAgdGljaz86IFRpY2tDb25maWc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFyQ29uZmlnIGV4dGVuZHMgTWFya0NvbmZpZyB7XG4gIC8qKlxuICAgKiBPZmZzZXQgYmV0d2VlbiBiYXIgZm9yIGJpbm5lZCBmaWVsZC4gIElkZWFsIHZhbHVlIGZvciB0aGlzIGlzIGVpdGhlciAwIChQcmVmZXJyZWQgYnkgc3RhdGlzdGljaWFucykgb3IgMSAoVmVnYS1MaXRlIERlZmF1bHQsIEQzIGV4YW1wbGUgc3R5bGUpLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDFgXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGJpblNwYWNpbmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBzaXplIG9mIHRoZSBiYXJzIG9uIGNvbnRpbnVvdXMgc2NhbGVzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDVgXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGNvbnRpbnVvdXNCYW5kU2l6ZT86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHNpemUgb2YgdGhlIGJhcnMuICBJZiB1bnNwZWNpZmllZCwgdGhlIGRlZmF1bHQgc2l6ZSBpcyAgYGJhbmRTaXplLTFgLFxuICAgKiB3aGljaCBwcm92aWRlcyAxIHBpeGVsIG9mZnNldCBiZXR3ZWVuIGJhcnMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGRpc2NyZXRlQmFuZFNpemU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0QmFyQ29uZmlnOiBCYXJDb25maWcgPSB7XG4gIGJpblNwYWNpbmc6IDEsXG4gIGNvbnRpbnVvdXNCYW5kU2l6ZTogNVxufTtcblxuZXhwb3J0IGludGVyZmFjZSBUZXh0Q29uZmlnIGV4dGVuZHMgTWFya0NvbmZpZyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIG1vbnRoIG5hbWVzIGFuZCB3ZWVrZGF5IG5hbWVzIHNob3VsZCBiZSBhYmJyZXZpYXRlZC5cbiAgICovXG4gIHNob3J0VGltZUxhYmVscz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja0NvbmZpZyBleHRlbmRzIE1hcmtDb25maWcge1xuICAvKipcbiAgICogVGhlIHdpZHRoIG9mIHRoZSB0aWNrcy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fICAyLzMgb2YgcmFuZ2VTdGVwLlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBiYW5kU2l6ZT86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhpY2tuZXNzIG9mIHRoZSB0aWNrIG1hcmsuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAgYDFgXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIHRoaWNrbmVzcz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRUaWNrQ29uZmlnOiBUaWNrQ29uZmlnID0ge1xuICB0aGlja25lc3M6IDFcbn07XG4iXX0= \ 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..71fe9da293 --- /dev/null +++ b/build/src/repeat.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwZWF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlcGVhdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBSZXBlYXQge1xuXG4gIC8qKlxuICAgKiBWZXJ0aWNhbCByZXBlYXRlZCB2aWV3cy5cbiAgICovXG4gIHJvdz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBIb3Jpem9udGFsIHJlcGVhdGVkIHZpZXdzLlxuICAgKi9cbiAgY29sdW1uPzogc3RyaW5nW107XG59XG4iXX0= \ 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..aa58dffb19 --- /dev/null +++ b/build/src/resolve.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZXNvbHZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge05vblBvc2l0aW9uU2NhbGVDaGFubmVsLCBQb3NpdGlvblNjYWxlQ2hhbm5lbCwgU2NhbGVDaGFubmVsfSBmcm9tICcuL2NoYW5uZWwnO1xuXG5cbmV4cG9ydCB0eXBlIFJlc29sdmVNb2RlID0gJ2luZGVwZW5kZW50JyB8ICdzaGFyZWQnO1xuXG4vKipcbiAqIERlZmluZXMgaG93IHNjYWxlcywgYXhlcywgYW5kIGxlZ2VuZHMgZnJvbSBkaWZmZXJlbnQgc3BlY3Mgc2hvdWxkIGJlIGNvbWJpbmVkLiBSZXNvbHZlIGlzIGEgbWFwcGluZyBmcm9tIGBzY2FsZWAsIGBheGlzYCwgYW5kIGBsZWdlbmRgIHRvIGEgbWFwcGluZyBmcm9tIGNoYW5uZWxzIHRvIHJlc29sdXRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmUge1xuICBzY2FsZT86IFNjYWxlUmVzb2x2ZU1hcDtcblxuICBheGlzPzogQXhpc1Jlc29sdmVNYXA7XG5cbiAgbGVnZW5kPzogTGVnZW5kUmVzb2x2ZU1hcDtcbn1cblxuZXhwb3J0IHR5cGUgU2NhbGVSZXNvbHZlTWFwID0ge1xuICBbQyBpbiBTY2FsZUNoYW5uZWxdPzogUmVzb2x2ZU1vZGVcbn07XG5cbmV4cG9ydCB0eXBlIEF4aXNSZXNvbHZlTWFwID0ge1xuICBbQyBpbiBQb3NpdGlvblNjYWxlQ2hhbm5lbF0/OiBSZXNvbHZlTW9kZVxufTtcblxuZXhwb3J0IHR5cGUgTGVnZW5kUmVzb2x2ZU1hcCA9IHtcbiAgW0MgaW4gTm9uUG9zaXRpb25TY2FsZUNoYW5uZWxdPzogUmVzb2x2ZU1vZGVcbn07XG4iXX0= \ 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..bcc03fa823 --- /dev/null +++ b/build/src/scale.d.ts @@ -0,0 +1,412 @@ +import { Channel } from './channel'; +import { DateTime } from './datetime'; +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.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 strokeWidth (or rule/line's size) scale with zero=false. + * + * __Default value:__ `1` + * + * @minimum 0 + */ + minStrokeWidth?: number; + /** + * Default max strokeWidth for strokeWidth (or rule/line's size) scale. + * + * __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 scheme, 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](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](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**](scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`"linear"`](scale.html#linear), [`"pow"`](scale.html#pow), [`"sqrt"`](scale.html#sqrt), [`"log"`](scale.html#log), [`"time"`](scale.html#time), [`"utc"`](scale.html#utc), [`"sequential"`](scale.html#sequential)). + * + * 2) [**Discrete Scales**](scale.html#discrete) -- mapping discrete domains to discrete ([`"ordinal"`](scale.html#ordinal)) or continuous ([`"band"`](scale.html#band) and [`"point"`](scale.html#point)) output ranges. + * + * 3) [**Discretizing Scales**](scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`"bin-linear"`](scale.html#bin-linear) and [`"bin-ordinal"`](scale.html#bin-ordinal)). + * + * __Default value:__ please see the [scale type table](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](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](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](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](scale.html#range-config) (e.g., example, `"symbol"`, or `"diverging"`). + * + * - For [continuous scales](scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](scale.html#piecewise). + * + * - For [discrete](scale.html#discrete) and [discretizing](scale.html#discretizing) scales, an array of desired output values. + * + * __Notes:__ + * + * 1) For [sequential](scale.html#sequential), [ordinal](scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](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](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](scale.html#band) and [point](scale.html#point) scales. + * + * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](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](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](scale.html#scheme) name (e.g., `"category10"` or `"viridis"`) or a [scheme parameter object](scale.html#scheme-params). + * + * Discrete color schemes may be used with [discrete](scale.html#discrete) or [discretizing](scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](scales.html#sequential) scales. + * + * For the full list of supported scheme, 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](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](scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value. + * + * For _[point](scale.html#point)_ scales, alias for `paddingOuter`. + * + * __Default value:__ For _continuous_ scales, derived from the [scale config](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](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](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](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?: Interpolate | InterpolateParams; +} +export declare type Interpolate = 'rgb' | 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long'; +export interface InterpolateParams { + type: 'rgb' | 'cubehelix' | 'cubehelix-long'; + gamma?: number; +} +export declare const SCALE_PROPERTIES: ("base" | "nice" | "domain" | "type" | "range" | "clamp" | "exponent" | "interpolate" | "padding" | "paddingInner" | "paddingOuter" | "reverse" | "round" | "zero" | "rangeStep" | "scheme")[]; +export declare const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES: ("base" | "nice" | "clamp" | "exponent" | "interpolate" | "padding" | "paddingInner" | "paddingOuter" | "reverse" | "round" | "zero")[]; +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 channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean; diff --git a/build/src/scale.js b/build/src/scale.js new file mode 100644 index 0000000000..769957ef5b --- /dev/null +++ b/build/src/scale.js @@ -0,0 +1,259 @@ +"use strict"; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var log = require("./log"); +var util_1 = require("./util"); +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 = exports.ScaleType || (exports.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' +}; +exports.SCALE_TYPES = util_1.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'); +} +exports.scaleCompatible = scaleCompatible; +/** + * Index for scale predecence -- 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]; +} +exports.scaleTypePrecedence = scaleTypePrecedence; +exports.CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc']; +var CONTINUOUS_TO_CONTINUOUS_INDEX = util_1.toSet(exports.CONTINUOUS_TO_CONTINUOUS_SCALES); +exports.CONTINUOUS_DOMAIN_SCALES = exports.CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]); +var CONTINUOUS_DOMAIN_INDEX = util_1.toSet(exports.CONTINUOUS_DOMAIN_SCALES); +exports.DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; +var DISCRETE_DOMAIN_INDEX = util_1.toSet(exports.DISCRETE_DOMAIN_SCALES); +var BIN_SCALES_INDEX = util_1.toSet(['bin-linear', 'bin-ordinal']); +exports.TIME_SCALE_TYPES = ['time', 'utc']; +function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; +} +exports.hasDiscreteDomain = hasDiscreteDomain; +function isBinScale(type) { + return type in BIN_SCALES_INDEX; +} +exports.isBinScale = isBinScale; +function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; +} +exports.hasContinuousDomain = hasContinuousDomain; +function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; +} +exports.isContinuousToContinuous = isContinuousToContinuous; +exports.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']; +} +exports.isExtendedScheme = isExtendedScheme; +function isSelectionDomain(domain) { + return domain && domain['selection']; +} +exports.isSelectionDomain = isSelectionDomain; +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 +}; +exports.SCALE_PROPERTIES = util_1.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 = __rest(SCALE_PROPERTY_INDEX, ["type", "domain", "range", "rangeStep", "scheme"]); +exports.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = util_1.flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX); +function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'reverse': + case 'range': + return true; + case 'scheme': + return util_1.contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType); + case 'interpolate': + // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal? + return util_1.contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType); + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'padding': + return isContinuousToContinuous(scaleType) || util_1.contains(['point', 'band'], scaleType); + case 'paddingOuter': + case 'rangeStep': + return util_1.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) && !util_1.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 + "."); +} +exports.scaleTypeSupportProperty = scaleTypeSupportProperty; +/** + * Returns undefined if the input channel supports the input scale property name + */ +function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'interpolate': + case 'scheme': + if (channel !== 'color') { + 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 + "\"."); +} +exports.channelScalePropertyIncompatability = channelScalePropertyIncompatability; +function channelSupportScaleType(channel, scaleType) { + switch (channel) { + case channel_1.Channel.X: + case channel_1.Channel.Y: + case channel_1.Channel.SIZE: // TODO: size and opacity can support ordinal with more modification + case channel_1.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) || util_1.contains(['band', 'point'], scaleType); + case channel_1.Channel.COLOR: + return scaleType !== 'band'; // band does not make sense with color + case channel_1.Channel.SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; +} +exports.channelSupportScaleType = channelSupportScaleType; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NhbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBa0M7QUFHbEMsMkJBQTZCO0FBQzdCLCtCQUE2RDtBQUU3RCxJQUFpQixTQUFTLENBc0J6QjtBQXRCRCxXQUFpQixTQUFTO0lBQ3hCLDRCQUE0QjtJQUNmLGdCQUFNLEdBQWEsUUFBUSxDQUFDO0lBQzVCLG9CQUFVLEdBQWlCLFlBQVksQ0FBQztJQUN4QyxhQUFHLEdBQVUsS0FBSyxDQUFDO0lBQ25CLGFBQUcsR0FBVSxLQUFLLENBQUM7SUFDbkIsY0FBSSxHQUFXLE1BQU0sQ0FBQztJQUNuQyxvQkFBb0I7SUFDUCxjQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLGFBQUcsR0FBVSxLQUFLLENBQUM7SUFDaEMsYUFBYTtJQUNBLG9CQUFVLEdBQWlCLFlBQVksQ0FBQztJQUVyRCxnQ0FBZ0M7SUFDbkIsa0JBQVEsR0FBZSxVQUFVLENBQUM7SUFDbEMsa0JBQVEsR0FBZSxVQUFVLENBQUM7SUFDbEMsbUJBQVMsR0FBZ0IsV0FBVyxDQUFDO0lBRXJDLGlCQUFPLEdBQWMsU0FBUyxDQUFDO0lBQy9CLHFCQUFXLEdBQWtCLGFBQWEsQ0FBQztJQUMzQyxlQUFLLEdBQVksT0FBTyxDQUFDO0lBQ3pCLGNBQUksR0FBVyxNQUFNLENBQUM7QUFDckMsQ0FBQyxFQXRCZ0IsU0FBUyxHQUFULGlCQUFTLEtBQVQsaUJBQVMsUUFzQnpCO0FBVUQ7OztHQUdHO0FBQ0gsSUFBTSxvQkFBb0IsR0FHdEI7SUFDRixNQUFNLEVBQUUsU0FBUztJQUNqQixHQUFHLEVBQUUsU0FBUztJQUNkLEdBQUcsRUFBRSxTQUFTO0lBQ2QsSUFBSSxFQUFFLFNBQVM7SUFDZixZQUFZLEVBQUUsWUFBWTtJQUMxQixJQUFJLEVBQUUsTUFBTTtJQUNaLEdBQUcsRUFBRSxNQUFNO0lBQ1gsVUFBVSxFQUFFLFlBQVk7SUFDeEIsT0FB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ZW50IjpbImltcG9ydCB7Q2hhbm5lbH0gZnJvbSAnLi9jaGFubmVsJztcbmltcG9ydCB7U2NhbGVDb21wb25lbnRQcm9wc30gZnJvbSAnLi9jb21waWxlL3NjYWxlL2NvbXBvbmVudCc7XG5pbXBvcnQge0RhdGVUaW1lfSBmcm9tICcuL2RhdGV0aW1lJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQge2NvbnRhaW5zLCBGbGFnLCBmbGFnS2V5cywga2V5cywgdG9TZXR9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBuYW1lc3BhY2UgU2NhbGVUeXBlIHtcbiAgLy8gQ29udGludW91cyAtIFF1YW50aXRhdGl2ZVxuICBleHBvcnQgY29uc3QgTElORUFSOiAnbGluZWFyJyA9ICdsaW5lYXInO1xuICBleHBvcnQgY29uc3QgQklOX0xJTkVBUjogJ2Jpbi1saW5lYXInID0gJ2Jpbi1saW5lYXInO1xuICBleHBvcnQgY29uc3QgTE9HOiAnbG9nJyA9ICdsb2cnO1xuICBleHBvcnQgY29uc3QgUE9XOiAncG93JyA9ICdwb3cnO1xuICBleHBvcnQgY29uc3QgU1FSVDogJ3NxcnQnID0gJ3NxcnQnO1xuICAvLyBDb250aW51b3VzIC0gVGltZVxuICBleHBvcnQgY29uc3QgVElNRTogJ3RpbWUnID0gJ3RpbWUnO1xuICBleHBvcnQgY29uc3QgVVRDOiAndXRjJyA9ICd1dGMnO1xuICAvLyBzZXF1ZW50aWFsXG4gIGV4cG9ydCBjb25zdCBTRVFVRU5USUFMOiAnc2VxdWVudGlhbCcgPSAnc2VxdWVudGlhbCc7XG5cbiAgLy8gUXVhbnRpbGUsIFF1YW50aXplLCB0aHJlc2hvbGRcbiAgZXhwb3J0IGNvbnN0IFFVQU5USUxFOiAncXVhbnRpbGUnID0gJ3F1YW50aWxlJztcbiAgZXhwb3J0IGNvbnN0IFFVQU5USVpFOiAncXVhbnRpemUnID0gJ3F1YW50aXplJztcbiAgZXhwb3J0IGNvbnN0IFRIUkVTSE9MRDogJ3RocmVzaG9sZCcgPSAndGhyZXNob2xkJztcblxuICBleHBvcnQgY29uc3QgT1JESU5BTDogJ29yZGluYWwnID0gJ29yZGluYWwnO1xuICBleHBvcnQgY29uc3QgQklOX09SRElOQUw6ICdiaW4tb3JkaW5hbCcgPSAnYmluLW9yZGluYWwnO1xuICBleHBvcnQgY29uc3QgUE9JTlQ6ICdwb2ludCcgPSAncG9pbnQnO1xuICBleHBvcnQgY29uc3QgQkFORDogJ2JhbmQnID0gJ2JhbmQnO1xufVxuXG5leHBvcnQgdHlwZSBTY2FsZVR5cGUgPSB0eXBlb2YgU2NhbGVUeXBlLkxJTkVBUiB8IHR5cGVvZiBTY2FsZVR5cGUuQklOX0xJTkVBUiB8XG4gIHR5cGVvZiBTY2FsZVR5cGUuTE9HIHwgdHlwZW9mIFNjYWxlVHlwZS5QT1cgfCB0eXBlb2YgU2NhbGVUeXBlLlNRUlQgfFxuICB0eXBlb2YgU2NhbGVUeXBlLlRJTUUgfCB0eXBlb2YgU2NhbGVUeXBlLlVUQyB8XG4gIC8vIFRPRE86IGFkZCAncXVhbnRpemUnLCAncXVhbnRpbGUnLCAndGhyZXNob2xkJyBiYWNrIHdoZW4gd2UgcmVhbGx5IHN1cHBvcnQgdGhlbVxuICB0eXBlb2YgU2NhbGVUeXBlLlNFUVVFTlRJQUwgfCAvLyB0eXBlb2YgU2NhbGVUeXBlLlFVQU5USUxFIHwgdHlwZW9mIFNjYWxlVHlwZS5RVUFOVElaRSB8IHR5cGVvZiBTY2FsZVR5cGUuVEhSRVNIT0xEIHxcbiAgdHlwZW9mIFNjYWxlVHlwZS5PUkRJTkFMIHwgdHlwZW9mIFNjYWxlVHlwZS5CSU5fT1JESU5BTCB8IHR5cGVvZiBTY2FsZVR5cGUuUE9JTlQgfCB0eXBlb2YgU2NhbGVUeXBlLkJBTkQ7XG5cblxuLyoqXG4gKiBJbmRleCBmb3Igc2NhbGUgY2F0ZWdvcmllcyAtLSBvbmx5IHNjYWxlIG9mIHRoZSBzYW1lIGNhdGVnb3JpZXMgY2FuIGJlIG1lcmdlZCB0b2dldGhlci5cbiAqIEN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgdHJ5aW5nIHRvIGJlIGNvbnNlcnZhdGl2ZSBhbmQgYXZvaWQgbWVyZ2luZyBzY2FsZSB0eXBlIHRoYXQgbWlnaHQgbm90IHdvcmsgdG9nZXRoZXJcbiAqL1xuY29uc3QgU0NBTEVfQ0FURUdPUllfSU5ERVg6IHtcbiAgLy8gVXNpbmcgTWFwcGVkIFR5cGUgdG8gZGVjbGFyZSB0eXBlIChodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay9hZHZhbmNlZC10eXBlcy5odG1sI21hcHBlZC10eXBlcylcbiAgW2sgaW4gU2NhbGVUeXBlXTogU2NhbGVUeXBlIHwgJ251bWVyaWMnIHwgJ29yZGluYWwtcG9zaXRpb24nXG59ID0ge1xuICBsaW5lYXI6ICdudW1lcmljJyxcbiAgbG9nOiAnbnVtZXJpYycsXG4gIHBvdzogJ251bWVyaWMnLFxuICBzcXJ0OiAnbnVtZXJpYycsXG4gICdiaW4tbGluZWFyJzogJ2Jpbi1saW5lYXInLCAvLyBUT0RPOiBzaG91bGQgYmluLWxpbmVhciBzdXBwb3J0IG1lcmdpbmcgd2l0aCBvdGhlclxuICB0aW1lOiAndGltZScsXG4gIHV0YzogJ3RpbWUnLFxuICBzZXF1ZW50aWFsOiAnc2VxdWVudGlhbCcsXG4gIG9yZGluYWw6ICdvcmRpbmFsJyxcbiAgJ2Jpbi1vcmRpbmFsJzogJ2Jpbi1vcmRpbmFsJywgLy8gVE9ETzogc2hvdWxkIGJpbi1vcmRpbmFsIHN1cHBvcnQgbWVyZ2luZyB3aXRoIG90aGVyXG4gIHBvaW50OiAnb3JkaW5hbC1wb3NpdGlvbicsXG4gIGJhbmQ6ICdvcmRpbmFsLXBvc2l0aW9uJ1xufTtcblxuZXhwb3J0IGNvbnN0IFNDQUxFX1RZUEVTID0ga2V5cyhTQ0FMRV9DQVRFR09SWV9JTkRFWCkgYXMgU2NhbGVUeXBlW107XG5cbi8qKlxuICogV2hldGhlciB0aGUgdHdvIGdpdmVuIHNjYWxlIHR5cGVzIGNhbiBiZSBtZXJnZWQgdG9nZXRoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZUNvbXBhdGlibGUoc2NhbGVUeXBlMTogU2NhbGVUeXBlLCBzY2FsZVR5cGUyOiBTY2FsZVR5cGUpIHtcbiAgY29uc3Qgc2NhbGVDYXRlZ29yeTEgPSBTQ0FMRV9DQVRFR09SWV9JTkRFWFtzY2FsZVR5cGUxXTtcbiAgY29uc3Qgc2NhbGVDYXRlZ29yeTIgPSBTQ0FMRV9DQVRFR09SWV9JTkRFWFtzY2FsZVR5cGUyXTtcbiAgcmV0dXJuIHNjYWxlQ2F0ZWdvcnkxID09PSBzY2FsZUNhdGVnb3J5MiB8fFxuICAgIChzY2FsZUNhdGVnb3J5MSA9PT0gJ29yZGluYWwtcG9zaXRpb24nICYmIHNjYWxlQ2F0ZWdvcnkyID09PSAndGltZScpIHx8XG4gICAgKHNjYWxlQ2F0ZWdvcnkyID09PSAnb3JkaW5hbC1wb3NpdGlvbicgJiYgc2NhbGVDYXRlZ29yeTEgPT09ICd0aW1lJyk7XG59XG5cbi8qKlxuICogSW5kZXggZm9yIHNjYWxlIHByZWRlY2VuY2UgLS0gaGlnaCBzY29yZSA9IGhpZ2hlciBwcmlvcml0eSBmb3IgbWVyZ2luZy5cbiAqL1xuY29uc3QgU0NBTEVfUFJFQ0VERU5DRV9JTkRFWDoge1xuICAvLyBVc2luZyBNYXBwZWQgVHlwZSB0byBkZWNsYXJlIHR5cGUgKGh0dHBzOi8vd3d3LnR5cGVzY3JpcHRsYW5nLm9yZy9kb2NzL2hhbmRib29rL2FkdmFuY2VkLXR5cGVzLmh0bWwjbWFwcGVkLXR5cGVzKVxuICBbayBpbiBTY2FsZVR5cGVdOiBudW1iZXJcbn0gPSB7XG4gIC8vIG51bWVyaWNcbiAgbGluZWFyOiAwLFxuICBsb2c6IDEsXG4gIHBvdzogMSxcbiAgc3FydDogMSxcbiAgLy8gdGltZVxuICB0aW1lOiAwLFxuICB1dGM6IDAsXG4gIC8vIG9yZGluYWwtcG9zaXRpb24gLS0gdGhlc2UgaGF2ZSBoaWdoZXIgcHJlY2VkZW5jZSB0aGFuIGNvbnRpbnVvdXMgc2NhbGVzIGFzIHRoZXkgc3VwcG9ydCBtb3JlIHR5cGVzIG9mIGRhdGFcbiAgcG9pbnQ6IDEwLFxuICBiYW5kOiAxMSwgLy8gYmFuZCBoYXMgaGlnaGVyIHByZWNlZGVuY2UgYXMgaXQgaXMgYmV0dGVyIGZvciBpbnRlcmFjdGlvblxuICAvLyBub24gZ3JvdXBlZCB0eXBlc1xuICAnYmluLWxpbmVhcic6IDAsXG4gIHNlcXVlbnRpYWw6IDAsXG4gIG9yZGluYWw6IDAsXG4gICdiaW4tb3JkaW5hbCc6IDAsXG59O1xuXG4vKipcbiAqIFJldHVybiBzY2FsZSBjYXRlZ29yaWVzIC0tIG9ubHkgc2NhbGUgb2YgdGhlIHNhbWUgY2F0ZWdvcmllcyBjYW4gYmUgbWVyZ2VkIHRvZ2V0aGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVUeXBlUHJlY2VkZW5jZShzY2FsZVR5cGU6IFNjYWxlVHlwZSk6IG51bWJlciB7XG4gIHJldHVybiBTQ0FMRV9QUkVDRURFTkNFX0lOREVYW3NjYWxlVHlwZV07XG59XG5cbmV4cG9ydCBjb25zdCBDT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfU0NBTEVTOiBTY2FsZVR5cGVbXSA9IFsnbGluZWFyJywgJ2Jpbi1saW5lYXInLCAnbG9nJywgJ3BvdycsICdzcXJ0JywgJ3RpbWUnLCAndXRjJ107XG5jb25zdCBDT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfSU5ERVggPSB0b1NldChDT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfU0NBTEVTKTtcblxuZXhwb3J0IGNvbnN0IENPTlRJTlVPVVNfRE9NQUlOX1NDQUxFUzogU2NhbGVUeXBlW10gPSBDT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfU0NBTEVTLmNvbmNhdChbJ3NlcXVlbnRpYWwnIC8qIFRPRE8gYWRkICdxdWFudGlsZScsICdxdWFudGl6ZScsICd0aHJlc2hvbGQnKi9dKTtcbmNvbnN0IENPTlRJTlVPVVNfRE9NQUlOX0lOREVYID0gdG9TZXQoQ09OVElOVU9VU19ET01BSU5fU0NBTEVTKTtcblxuZXhwb3J0IGNvbnN0IERJU0NSRVRFX0RPTUFJTl9TQ0FMRVM6IFNjYWxlVHlwZVtdID0gWydvcmRpbmFsJywgJ2Jpbi1vcmRpbmFsJywgJ3BvaW50JywgJ2JhbmQnXTtcbmNvbnN0IERJU0NSRVRFX0RPTUFJTl9JTkRFWCA9IHRvU2V0KERJU0NSRVRFX0RPTUFJTl9TQ0FMRVMpO1xuXG5jb25zdCBCSU5fU0NBTEVTX0lOREVYID0gdG9TZXQoWydiaW4tbGluZWFyJywgJ2Jpbi1vcmRpbmFsJ10pO1xuXG5leHBvcnQgY29uc3QgVElNRV9TQ0FMRV9UWVBFUzogU2NhbGVUeXBlW10gPSBbJ3RpbWUnLCAndXRjJ107XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNEaXNjcmV0ZURvbWFpbih0eXBlOiBTY2FsZVR5cGUpOiB0eXBlIGlzICdvcmRpbmFsJyB8ICdiaW4tb3JkaW5hbCcgfCAncG9pbnQnIHwgJ2JhbmQnIHtcbiAgcmV0dXJuIHR5cGUgaW4gRElTQ1JFVEVfRE9NQUlOX0lOREVYO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNCaW5TY2FsZSh0eXBlOiBTY2FsZVR5cGUpOiB0eXBlIGlzICdiaW4tbGluZWFyJyB8ICdiaW4tb3JkaW5hbCcge1xuICByZXR1cm4gdHlwZSBpbiBCSU5fU0NBTEVTX0lOREVYO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzQ29udGludW91c0RvbWFpbih0eXBlOiBTY2FsZVR5cGUpOlxuICB0eXBlIGlzICdsaW5lYXInIHwgJ2xvZycgfCAncG93JyB8ICdzcXJ0JyB8ICd0aW1lJyB8ICd1dGMnfFxuICAgICAgICAgICdzZXF1ZW50aWFsJyAvKiBUT0RPIGFkZCB8ICdxdWFudGlsZScgfCAncXVhbnRpemUnIHwgJ3RocmVzaG9sZCcgKi8ge1xuICByZXR1cm4gdHlwZSBpbiBDT05USU5VT1VTX0RPTUFJTl9JTkRFWDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29udGludW91c1RvQ29udGludW91cyh0eXBlOiBTY2FsZVR5cGUpOiB0eXBlIGlzICdsaW5lYXInIHwgJ2Jpbi1saW5lYXInIHwgJ2xvZycgfCAncG93JyB8ICdzcXJ0JyB8ICd0aW1lJyB8ICd1dGMnIHtcbiAgcmV0dXJuIHR5cGUgaW4gQ09OVElOVU9VU19UT19DT05USU5VT1VTX0lOREVYO1xufVxuXG5leHBvcnQgdHlwZSBOaWNlVGltZSA9ICdzZWNvbmQnIHwgJ21pbnV0ZScgfCAnaG91cicgfCAnZGF5JyB8ICd3ZWVrJyB8ICdtb250aCcgfCAneWVhcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2NhbGVDb25maWcge1xuICAvKipcbiAgICogSWYgdHJ1ZSwgcm91bmRzIG51bWVyaWMgb3V0cHV0IHZhbHVlcyB0byBpbnRlZ2Vycy5cbiAgICogVGhpcyBjYW4gYmUgaGVscGZ1bCBmb3Igc25hcHBpbmcgdG8gdGhlIHBpeGVsIGdyaWQuXG4gICAqIChPbmx5IGF2YWlsYWJsZSBmb3IgYHhgLCBgeWAsIGFuZCBgc2l6ZWAgc2NhbGVzLilcbiAgICovXG4gIHJvdW5kPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSWYgdHJ1ZSwgdmFsdWVzIHRoYXQgZXhjZWVkIHRoZSBkYXRhIGRvbWFpbiBhcmUgY2xhbXBlZCB0byBlaXRoZXIgdGhlIG1pbmltdW0gb3IgbWF4aW11bSByYW5nZSB2YWx1ZVxuICAgKi9cbiAgY2xhbXA/OiBib29sZWFuO1xuICAvKipcbiAgICogIERlZmF1bHQgcmFuZ2Ugc3RlcCBmb3IgYHhgIGJhbmQgYW5kIHBvaW50IHNjYWxlcyBvZiB0ZXh0IG1hcmtzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDkwYFxuICAgKlxuICAgKiAgQG1pbmltdW0gMFxuICAgKi9cbiAgdGV4dFhSYW5nZVN0ZXA/OiBudW1iZXI7IC8vIEZJWE1FOiBjb25zaWRlciBpZiB3ZSB3aWxsIHJlbmFtZSB0aGlzIFwidGFibGVDb2x1bW5XaWR0aFwiXG5cbiAgLyoqXG4gICAqIERlZmF1bHQgcmFuZ2Ugc3RlcCBmb3IgYmFuZCBhbmQgcG9pbnQgc2NhbGVzIG9mICgxKSB0aGUgYHlgIGNoYW5uZWxcbiAgICogYW5kICgyKSB0aGUgYHhgIGNoYW5uZWwgd2hlbiB0aGUgbWFyayBpcyBub3QgYHRleHRgLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDIxYFxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICByYW5nZVN0ZXA/OiBudW1iZXIgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IGlubmVyIHBhZGRpbmcgZm9yIGB4YCBhbmQgYHlgIGJhbmQtb3JkaW5hbCBzY2FsZXMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMC4xYFxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIGJhbmRQYWRkaW5nSW5uZXI/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgb3V0ZXIgcGFkZGluZyBmb3IgYHhgIGFuZCBgeWAgYmFuZC1vcmRpbmFsIHNjYWxlcy5cbiAgICogSWYgbm90IHNwZWNpZmllZCwgYnkgZGVmYXVsdCwgYmFuZCBzY2FsZSdzIHBhZGRpbmdPdXRlciBpcyBwYWRkaW5nSW5uZXIvMi5cbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSAxXG4gICAqL1xuICBiYW5kUGFkZGluZ091dGVyPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IHBhZGRpbmcgZm9yIGNvbnRpbnVvdXMgc2NhbGVzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQ6X18gYDVgIGZvciBjb250aW51b3VzIHgtc2NhbGUgb2YgYSB2ZXJ0aWNhbCBiYXIgYW5kIGNvbnRpbnVvdXMgeS1zY2FsZSBvZiBhIGhvcml6b250YWwgYmFyLjsgYDBgIG90aGVyd2lzZS5cbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgY29udGludW91c1BhZGRpbmc/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgb3V0ZXIgcGFkZGluZyBmb3IgYHhgIGFuZCBgeWAgcG9pbnQtb3JkaW5hbCBzY2FsZXMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMC41YFxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIHBvaW50UGFkZGluZz86IG51bWJlcjtcblxuICAvKipcbiAgICogVXNlIHRoZSBzb3VyY2UgZGF0YSByYW5nZSBiZWZvcmUgYWdncmVnYXRpb24gYXMgc2NhbGUgZG9tYWluIGluc3RlYWQgb2YgYWdncmVnYXRlZCBkYXRhIGZvciBhZ2dyZWdhdGUgYXhpcy5cbiAgICpcbiAgICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIHNldHRpbmcgYGRvbWFpbmAgdG8gYFwidW5hZ2dyZWdhdGVcImAgZm9yIGFnZ3JlZ2F0ZWQgX3F1YW50aXRhdGl2ZV8gZmllbGRzIGJ5IGRlZmF1bHQuXG4gICAqXG4gICAqIFRoaXMgcHJvcGVydHkgb25seSB3b3JrcyB3aXRoIGFnZ3JlZ2F0ZSBmdW5jdGlvbnMgdGhhdCBwcm9kdWNlIHZhbHVlcyB3aXRoaW4gdGhlIHJhdyBkYXRhIGRvbWFpbiAoYFwibWVhblwiYCwgYFwiYXZlcmFnZVwiYCwgYFwibWVkaWFuXCJgLCBgXCJxMVwiYCwgYFwicTNcImAsIGBcIm1pblwiYCwgYFwibWF4XCJgKS4gRm9yIG90aGVyIGFnZ3JlZ2F0aW9ucyB0aGF0IHByb2R1Y2UgdmFsdWVzIG91dHNpZGUgb2YgdGhlIHJhdyBkYXRhIGRvbWFpbiAoZS5nLiBgXCJjb3VudFwiYCwgYFwic3VtXCJgKSwgdGhpcyBwcm9wZXJ0eSBpcyBpZ25vcmVkLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYGZhbHNlYFxuICAgKi9cbiAgdXNlVW5hZ2dyZWdhdGVkRG9tYWluPzogYm9vbGVhbjtcblxuICAvLyBuaWNlIHNob3VsZCBkZXBlbmRzIG9uIHR5cGUgKHF1YW50aXRhdGl2ZSBvciB0ZW1wb3JhbCksIHNvXG4gIC8vIGxldCdzIG5vdCBtYWtlIGEgY29uZmlnLlxuXG4gIC8vIENvbmZpZ3MgZm9yIFJhbmdlXG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IG1heCB2YWx1ZSBmb3IgbWFwcGluZyBxdWFudGl0YXRpdmUgZmllbGRzIHRvIGJhcidzIHNpemUvYmFuZFNpemUuXG4gICAqXG4gICAqIElmIHVuZGVmaW5lZCAoZGVmYXVsdCksIHdlIHdpbGwgdXNlIHRoZSBzY2FsZSdzIGByYW5nZVN0ZXBgIC0gMS5cbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgbWF4QmFuZFNpemU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IG1pbiB2YWx1ZSBmb3IgbWFwcGluZyBxdWFudGl0YXRpdmUgZmllbGRzIHRvIGJhciBhbmQgdGljaydzIHNpemUvYmFuZFNpemUgc2NhbGUgd2l0aCB6ZXJvPWZhbHNlLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDJgXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIG1pbkJhbmRTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBtYXggdmFsdWUgZm9yIG1hcHBpbmcgcXVhbnRpdGF0aXZlIGZpZWxkcyB0byB0ZXh0J3Mgc2l6ZS9mb250U2l6ZS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGA0MGBcbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgbWF4Rm9udFNpemU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IG1pbiB2YWx1ZSBmb3IgbWFwcGluZyBxdWFudGl0YXRpdmUgZmllbGRzIHRvIHRpY2sncyBzaXplL2ZvbnRTaXplIHNjYWxlIHdpdGggemVybz1mYWxzZVxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDhgXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIG1pbkZvbnRTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IG1pbmltdW0gb3BhY2l0eSBmb3IgbWFwcGluZyBhIGZpZWxkIHRvIG9wYWNpdHkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMC4zYFxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIG1pbk9wYWNpdHk/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgbWF4IG9wYWNpdHkgZm9yIG1hcHBpbmcgYSBmaWVsZCB0byBvcGFjaXR5LlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDAuOGBcbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSAxXG4gICAqL1xuICBtYXhPcGFjaXR5PzogbnVtYmVyO1xuXG5cbiAgLyoqXG4gICAqIERlZmF1bHQgbWluaW11bSB2YWx1ZSBmb3IgcG9pbnQgc2l6ZSBzY2FsZSB3aXRoIHplcm89ZmFsc2UuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgOWBcbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgbWluU2l6ZT86IG51bWJlcjtcblxuICAvKipcbiAgICogRGVmYXVsdCBtYXggdmFsdWUgZm9yIHBvaW50IHNpemUgc2NhbGUuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIG1heFNpemU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgbWluaW11bSBzdHJva2VXaWR0aCBmb3Igc3Ryb2tlV2lkdGggKG9yIHJ1bGUvbGluZSdzIHNpemUpIHNjYWxlIHdpdGggemVybz1mYWxzZS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAxYFxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBtaW5TdHJva2VXaWR0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogRGVmYXVsdCBtYXggc3Ryb2tlV2lkdGggZm9yIHN0cm9rZVdpZHRoICAob3IgcnVsZS9saW5lJ3Mgc2l6ZSkgc2NhbGUuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgNGBcbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgbWF4U3Ryb2tlV2lkdGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0U2NhbGVDb25maWcgPSB7XG4gIHRleHRYUmFuZ2VTdGVwOiA5MCxcbiAgcmFuZ2VTdGVwOiAyMSxcbiAgcG9pbnRQYWRkaW5nOiAwLjUsXG4gIGJhbmRQYWRkaW5nSW5uZXI6IDAuMSxcbiAgZmFjZXRTcGFjaW5nOiAxNixcblxuICBtaW5CYW5kU2l6ZTogMixcblxuICBtaW5Gb250U2l6ZTogOCxcbiAgbWF4Rm9udFNpemU6IDQwLFxuXG4gIG1pbk9wYWNpdHk6IDAuMyxcbiAgbWF4T3BhY2l0eTogMC44LFxuXG4gIC8vIEZJWE1FOiByZXZpc2UgaWYgdGhlc2UgKmNhbiogYmVjb21lIHJhdGlvcyBvZiByYW5nZVN0ZXBcbiAgbWluU2l6ZTogOSwgLy8gUG9pbnQgc2l6ZSBpcyBhcmVhLiBGb3Igc3F1YXJlIHBvaW50LCA5ID0gMyBwaXhlbCBeIDIsIG5vdCB0b28gc21hbGwhXG5cbiAgbWluU3Ryb2tlV2lkdGg6IDEsXG4gIG1heFN0cm9rZVdpZHRoOiA0XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFNjaGVtZVBhcmFtcyB7XG4gIC8qKlxuICAgKiBBIGNvbG9yIHNjaGVtZSBuYW1lIGZvciBzZXF1ZW50aWFsL29yZGluYWwgc2NhbGVzIChlLmcuLCBgXCJjYXRlZ29yeTEwXCJgIG9yIGBcInZpcmlkaXNcImApLlxuICAgKlxuICAgKiBGb3IgdGhlIGZ1bGwgbGlzdCBvZiBzdXBwb3J0ZWQgc2NoZW1lLCBwbGVhc2UgcmVmZXIgdG8gdGhlIFtWZWdhIFNjaGVtZV0oaHR0cHM6Ly92ZWdhLmdpdGh1Yi5pby92ZWdhL2RvY3Mvc2NoZW1lcy8jcmVmZXJlbmNlKSByZWZlcmVuY2UuXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEZvciBzZXF1ZW50aWFsIGFuZCBkaXZlcmdpbmcgc2NoZW1lcyBvbmx5LCBkZXRlcm1pbmVzIHRoZSBleHRlbnQgb2YgdGhlIGNvbG9yIHJhbmdlIHRvIHVzZS4gRm9yIGV4YW1wbGUgYFswLjIsIDFdYCB3aWxsIHJlc2NhbGUgdGhlIGNvbG9yIHNjaGVtZSBzdWNoIHRoYXQgY29sb3IgdmFsdWVzIGluIHRoZSByYW5nZSBfWzAsIDAuMilfIGFyZSBleGNsdWRlZCBmcm9tIHRoZSBzY2hlbWUuXG4gICAqL1xuICBleHRlbnQ/OiBudW1iZXJbXTtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBjb2xvcnMgdG8gdXNlIGluIHRoZSBzY2hlbWUuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3Igc2NhbGUgdHlwZXMgc3VjaCBhcyBgXCJxdWFudGl6ZVwiYCwgd2hpY2ggdXNlIHRoZSBsZW5ndGggb2YgdGhlIHNjYWxlIHJhbmdlIHRvIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGRpc2NyZXRlIGJpbnMgZm9yIHRoZSBzY2FsZSBkb21haW4uXG4gICAqXG4gICAqIEBoaWRlXG4gICAqL1xuICBjb3VudD86IG51bWJlcjtcbn1cblxuZXhwb3J0IHR5cGUgU2VsZWN0aW9uRG9tYWluID0ge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgYSBzZWxlY3Rpb24uXG4gICAqL1xuICBzZWxlY3Rpb246IHN0cmluZyxcbiAgLyoqXG4gICAqIFRoZSBmaWVsZCBuYW1lIHRvIGV4dHJhY3Qgc2VsZWN0ZWQgdmFsdWVzIGZvciwgd2hlbiBhIHNlbGVjdGlvbiBpcyBbcHJvamVjdGVkXShwcm9qZWN0Lmh0bWwpXG4gICAqIG92ZXIgbXVsdGlwbGUgZmllbGRzIG9yIGVuY29kaW5ncy5cbiAgICovXG4gIGZpZWxkPzogc3RyaW5nXG59IHwge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgYSBzZWxlY3Rpb24uXG4gICAqL1xuICBzZWxlY3Rpb246IHN0cmluZyxcbiAgLyoqXG4gICAqIFRoZSBlbmNvZGluZyBjaGFubmVsIHRvIGV4dHJhY3Qgc2VsZWN0ZWQgdmFsdWVzIGZvciwgd2hlbiBhIHNlbGVjdGlvbiBpcyBbcHJvamVjdGVkXShwcm9qZWN0Lmh0bWwpXG4gICAqIG92ZXIgbXVsdGlwbGUgZmllbGRzIG9yIGVuY29kaW5ncy5cbiAgICovXG4gIGVuY29kaW5nPzogc3RyaW5nXG59O1xuXG5leHBvcnQgdHlwZSBEb21haW4gPSBudW1iZXJbXSB8IHN0cmluZ1tdIHwgYm9vbGVhbltdIHwgRGF0ZVRpbWVbXSB8ICd1bmFnZ3JlZ2F0ZWQnIHwgU2VsZWN0aW9uRG9tYWluO1xuZXhwb3J0IHR5cGUgU2NoZW1lID0gc3RyaW5nIHwgU2NoZW1lUGFyYW1zO1xuXG5leHBvcnQgdHlwZSBSYW5nZSA9IG51bWJlcltdIHwgc3RyaW5nW10gfCBzdHJpbmc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0V4dGVuZGVkU2NoZW1lKHNjaGVtZTogc3RyaW5nIHwgU2NoZW1lUGFyYW1zKTogc2NoZW1lIGlzIFNjaGVtZVBhcmFtcyB7XG4gIHJldHVybiBzY2hlbWUgJiYgISFzY2hlbWVbJ25hbWUnXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2VsZWN0aW9uRG9tYWluKGRvbWFpbjogRG9tYWluKTogZG9tYWluIGlzIFNlbGVjdGlvbkRvbWFpbiB7XG4gIHJldHVybiBkb21haW4gJiYgZG9tYWluWydzZWxlY3Rpb24nXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTY2FsZSB7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiBzY2FsZS4gIFZlZ2EtTGl0ZSBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGNhdGVnb3JpZXMgb2Ygc2NhbGUgdHlwZXM6XG4gICAqXG4gICAqIDEpIFsqKkNvbnRpbnVvdXMgU2NhbGVzKipdKHNjYWxlLmh0bWwjY29udGludW91cykgLS0gbWFwcGluZyBjb250aW51b3VzIGRvbWFpbnMgdG8gY29udGludW91cyBvdXRwdXQgcmFuZ2VzIChbYFwibGluZWFyXCJgXShzY2FsZS5odG1sI2xpbmVhciksIFtgXCJwb3dcImBdKHNjYWxlLmh0bWwjcG93KSwgW2BcInNxcnRcImBdKHNjYWxlLmh0bWwjc3FydCksIFtgXCJsb2dcImBdKHNjYWxlLmh0bWwjbG9nKSwgW2BcInRpbWVcImBdKHNjYWxlLmh0bWwjdGltZSksIFtgXCJ1dGNcImBdKHNjYWxlLmh0bWwjdXRjKSwgW2BcInNlcXVlbnRpYWxcImBdKHNjYWxlLmh0bWwjc2VxdWVudGlhbCkpLlxuICAgKlxuICAgKiAyKSBbKipEaXNjcmV0ZSBTY2FsZXMqKl0oc2NhbGUuaHRtbCNkaXNjcmV0ZSkgLS0gbWFwcGluZyBkaXNjcmV0ZSBkb21haW5zIHRvIGRpc2NyZXRlIChbYFwib3JkaW5hbFwiYF0oc2NhbGUuaHRtbCNvcmRpbmFsKSkgb3IgY29udGludW91cyAoW2BcImJhbmRcImBdKHNjYWxlLmh0bWwjYmFuZCkgYW5kIFtgXCJwb2ludFwiYF0oc2NhbGUuaHRtbCNwb2ludCkpIG91dHB1dCByYW5nZXMuXG4gICAqXG4gICAqIDMpIFsqKkRpc2NyZXRpemluZyBTY2FsZXMqKl0oc2NhbGUuaHRtbCNkaXNjcmV0aXppbmcpIC0tIG1hcHBpbmcgY29udGludW91cyBkb21haW5zIHRvIGRpc2NyZXRlIG91dHB1dCByYW5nZXMgKFtgXCJiaW4tbGluZWFyXCJgXShzY2FsZS5odG1sI2Jpbi1saW5lYXIpIGFuZCBbYFwiYmluLW9yZGluYWxcImBdKHNjYWxlLmh0bWwjYmluLW9yZGluYWwpKS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIHBsZWFzZSBzZWUgdGhlIFtzY2FsZSB0eXBlIHRhYmxlXShzY2FsZS5odG1sI3R5cGUpLlxuICAgKi9cbiAgdHlwZT86IFNjYWxlVHlwZTtcblxuICAvKipcbiAgICogQ3VzdG9taXplZCBkb21haW4gdmFsdWVzLlxuICAgKlxuICAgKiBGb3IgX3F1YW50aXRhdGl2ZV8gZmllbGRzLCBgZG9tYWluYCBjYW4gdGFrZSB0aGUgZm9ybSBvZiBhIHR3by1lbGVtZW50IGFycmF5IHdpdGggbWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMuICBbUGllY2V3aXNlIHNjYWxlc10oc2NhbGUuaHRtbCNwaWVjZXdpc2UpIGNhbiBiZSBjcmVhdGVkIGJ5IHByb3ZpZGluZyBhIGBkb21haW5gIHdpdGggbW9yZSB0aGFuIHR3byBlbnRyaWVzLlxuICAgKiBJZiB0aGUgaW5wdXQgZmllbGQgaXMgYWdncmVnYXRlZCwgYGRvbWFpbmAgY2FuIGFsc28gYmUgYSBzdHJpbmcgdmFsdWUgYFwidW5hZ2dyZWdhdGVkXCJgLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGRvbWFpbiBzaG91bGQgaW5jbHVkZSB0aGUgcmF3IGRhdGEgdmFsdWVzIHByaW9yIHRvIHRoZSBhZ2dyZWdhdGlvbi5cbiAgICpcbiAgICogRm9yIF90ZW1wb3JhbF8gZmllbGRzLCBgZG9tYWluYCBjYW4gYmUgYSB0d28tZWxlbWVudCBhcnJheSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcywgaW4gdGhlIGZvcm0gb2YgZWl0aGVyIHRpbWVzdGFtcHMgb3IgdGhlIFtEYXRlVGltZSBkZWZpbml0aW9uIG9iamVjdHNdKHR5cGVzLmh0bWwjZGF0ZXRpbWUpLlxuICAgKlxuICAgKiBGb3IgX29yZGluYWxfIGFuZCBfbm9taW5hbF8gZmllbGRzLCBgZG9tYWluYCBjYW4gYmUgYW4gYXJyYXkgdGhhdCBsaXN0cyB2YWxpZCBpbnB1dCB2YWx1ZXMuXG4gICAqXG4gICAqIFRoZSBgc2VsZWN0aW9uYCBwcm9wZXJ0eSBjYW4gYmUgdXNlZCB0byBbaW50ZXJhY3RpdmVseSBkZXRlcm1pbmVdKHNlbGVjdGlvbi5odG1sI3NjYWxlLWRvbWFpbnMpIHRoZSBzY2FsZSBkb21haW4uXG4gICAqL1xuICBkb21haW4/OiBudW1iZXJbXSB8IHN0cmluZ1tdIHwgYm9vbGVhbltdIHwgRGF0ZVRpbWVbXSB8ICd1bmFnZ3JlZ2F0ZWQnIHwgU2VsZWN0aW9uRG9tYWluO1xuXG5cbiAgLy8gSGlkZSBiZWNhdXNlIHdlIG1pZ2h0IG5vdCByZWFsbHkgbmVlZCB0aGlzLlxuICAvKipcbiAgICogSWYgdHJ1ZSwgcmV2ZXJzZXMgdGhlIG9yZGVyIG9mIHRoZSBzY2FsZSByYW5nZS5cbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGBmYWxzZWAuXG4gICAqXG4gICAqIEBoaWRlXG4gICAqL1xuICByZXZlcnNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHJhbmdlIG9mIHRoZSBzY2FsZS4gT25lIG9mOlxuICAgKlxuICAgKiAtIEEgc3RyaW5nIGluZGljYXRpbmcgYSBbcHJlLWRlZmluZWQgbmFtZWQgc2NhbGUgcmFuZ2VdKHNjYWxlLmh0bWwjcmFuZ2UtY29uZmlnKSAoZS5nLiwgZXhhbXBsZSwgYFwic3ltYm9sXCJgLCBvciBgXCJkaXZlcmdpbmdcImApLlxuICAgKlxuICAgKiAtIEZvciBbY29udGludW91cyBzY2FsZXNdKHNjYWxlLmh0bWwjY29udGludW91cyksIHR3by1lbGVtZW50IGFycmF5IGluZGljYXRpbmcgIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWVzLCBvciBhbiBhcnJheSB3aXRoIG1vcmUgdGhhbiB0d28gZW50cmllcyBmb3Igc3BlY2lmeWluZyBhIFtwaWVjZXdpc2Ugc2NhbGVdKHNjYWxlLmh0bWwjcGllY2V3aXNlKS5cbiAgICpcbiAgICogLSBGb3IgW2Rpc2NyZXRlXShzY2FsZS5odG1sI2Rpc2NyZXRlKSBhbmQgW2Rpc2NyZXRpemluZ10oc2NhbGUuaHRtbCNkaXNjcmV0aXppbmcpIHNjYWxlcywgYW4gYXJyYXkgb2YgZGVzaXJlZCBvdXRwdXQgdmFsdWVzLlxuICAgKlxuICAgKiBfX05vdGVzOl9fXG4gICAqXG4gICAqIDEpIEZvciBbc2VxdWVudGlhbF0oc2NhbGUuaHRtbCNzZXF1ZW50aWFsKSwgW29yZGluYWxdKHNjYWxlLmh0bWwjb3JkaW5hbCksIGFuZCBkaXNjcmV0aXppbmcgY29sb3Igc2NhbGVzLCB5b3UgY2FuIGFsc28gc3BlY2lmeSBhIGNvbG9yIFtgc2NoZW1lYF0oc2NhbGUuaHRtbCNzY2hlbWUpIGluc3RlYWQgb2YgYHJhbmdlYC5cbiAgICpcbiAgICogMikgQW55IGRpcmVjdGx5IHNwZWNpZmllZCBgcmFuZ2VgIGZvciBgeGAgYW5kIGB5YCBjaGFubmVscyB3aWxsIGJlIGlnbm9yZWQuIFJhbmdlIGNhbiBiZSBjdXN0b21pemVkIHZpYSB0aGUgdmlldydzIGNvcnJlc3BvbmRpbmcgW3NpemVdKHNpemUuaHRtbCkgKGB3aWR0aGAgYW5kIGBoZWlnaHRgKSBvciB2aWEgW3JhbmdlIHN0ZXBzIGFuZCBwYWRkaW5ncyBwcm9wZXJ0aWVzXSgjcmFuZ2Utc3RlcCkgZm9yIFtiYW5kXSgjYmFuZCkgYW5kIFtwb2ludF0oI3BvaW50KSBzY2FsZXMuXG4gICAqL1xuICByYW5nZT86IG51bWJlcltdIHwgc3RyaW5nW10gfCBzdHJpbmc7XG5cbiAgLy8gb3JkaW5hbFxuICAvKipcbiAgICogVGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHN0YXJ0cyBvZiBhZGphY2VudCBiYW5kcyBvciBwb2ludHMgaW4gW2JhbmRdKHNjYWxlLmh0bWwjYmFuZCkgYW5kIFtwb2ludF0oc2NhbGUuaHRtbCNwb2ludCkgc2NhbGVzLlxuICAgKlxuICAgKiBJZiBgcmFuZ2VTdGVwYCBpcyBgbnVsbGAgb3IgaWYgdGhlIHZpZXcgY29udGFpbnMgdGhlIHNjYWxlJ3MgY29ycmVzcG9uZGluZyBbc2l6ZV0oc2l6ZS5odG1sKSAoYHdpZHRoYCBmb3IgYHhgIHNjYWxlcyBhbmQgYGhlaWdodGAgZm9yIGB5YCBzY2FsZXMpLCBgcmFuZ2VTdGVwYCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZGV0ZXJtaW5lZCB0byBmaXQgdGhlIHNpemUgb2YgdGhlIHZpZXcuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAgZGVyaXZlZCB0aGUgW3NjYWxlIGNvbmZpZ10oY29uZmlnLmh0bWwjc2NhbGUtY29uZmlnKSdzIGB0ZXh0WFJhbmdlU3RlcGAgKGA5MGAgYnkgZGVmYXVsdCkgZm9yIHgtc2NhbGVzIG9mIGB0ZXh0YCBtYXJrcyBhbmQgYHJhbmdlU3RlcGAgKGAyMWAgYnkgZGVmYXVsdCkgZm9yIHgtc2NhbGVzIG9mIG90aGVyIG1hcmtzIGFuZCB5LXNjYWxlcy5cbiAgICpcbiAgICogX19XYXJuaW5nX186IElmIGByYW5nZVN0ZXBgIGlzIGBudWxsYCBhbmQgdGhlIGNhcmRpbmFsaXR5IG9mIHRoZSBzY2FsZSdzIGRvbWFpbiBpcyBoaWdoZXIgdGhhbiBgd2lkdGhgIG9yIGBoZWlnaHRgLCB0aGUgcmFuZ2VTdGVwIG1pZ2h0IGJlY29tZSBsZXNzIHRoYW4gb25lIHBpeGVsIGFuZCB0aGUgbWFyayBtaWdodCBub3QgYXBwZWFyIGNvcnJlY3RseS5cbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgcmFuZ2VTdGVwPzogbnVtYmVyIHwgbnVsbDtcblxuICAvKipcbiAgICogQSBzdHJpbmcgaW5kaWNhdGluZyBhIGNvbG9yIFtzY2hlbWVdKHNjYWxlLmh0bWwjc2NoZW1lKSBuYW1lIChlLmcuLCBgXCJjYXRlZ29yeTEwXCJgIG9yIGBcInZpcmlkaXNcImApIG9yIGEgW3NjaGVtZSBwYXJhbWV0ZXIgb2JqZWN0XShzY2FsZS5odG1sI3NjaGVtZS1wYXJhbXMpLlxuICAgKlxuICAgKiBEaXNjcmV0ZSBjb2xvciBzY2hlbWVzIG1heSBiZSB1c2VkIHdpdGggW2Rpc2NyZXRlXShzY2FsZS5odG1sI2Rpc2NyZXRlKSBvciBbZGlzY3JldGl6aW5nXShzY2FsZS5odG1sI2Rpc2NyZXRpemluZykgc2NhbGVzLiBDb250aW51b3VzIGNvbG9yIHNjaGVtZXMgYXJlIGludGVuZGVkIGZvciB1c2Ugd2l0aCBbc2VxdWVudGlhbF0oc2NhbGVzLmh0bWwjc2VxdWVudGlhbCkgc2NhbGVzLlxuICAgKlxuICAgKiBGb3IgdGhlIGZ1bGwgbGlzdCBvZiBzdXBwb3J0ZWQgc2NoZW1lLCBwbGVhc2UgcmVmZXIgdG8gdGhlIFtWZWdhIFNjaGVtZV0oaHR0cHM6Ly92ZWdhLmdpdGh1Yi5pby92ZWdhL2RvY3Mvc2NoZW1lcy8jcmVmZXJlbmNlKSByZWZlcmVuY2UuXG4gICAqL1xuICBzY2hlbWU/OiBzdHJpbmcgfCBTY2hlbWVQYXJhbXM7XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgcm91bmRzIG51bWVyaWMgb3V0cHV0IHZhbHVlcyB0byBpbnRlZ2Vycy4gVGhpcyBjYW4gYmUgaGVscGZ1bCBmb3Igc25hcHBpbmcgdG8gdGhlIHBpeGVsIGdyaWQuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgZmFsc2VgLlxuICAgKi9cbiAgcm91bmQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBGb3IgX1tjb250aW51b3VzXShzY2FsZS5odG1sI2NvbnRpbnVvdXMpXyBzY2FsZXMsIGV4cGFuZHMgdGhlIHNjYWxlIGRvbWFpbiB0byBhY2NvbW1vZGF0ZSB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBwaXhlbHMgb24gZWFjaCBvZiB0aGUgc2NhbGUgcmFuZ2UuIFRoZSBzY2FsZSByYW5nZSBtdXN0IHJlcHJlc2VudCBwaXhlbHMgZm9yIHRoaXMgcGFyYW1ldGVyIHRvIGZ1bmN0aW9uIGFzIGludGVuZGVkLiBQYWRkaW5nIGFkanVzdG1lbnQgaXMgcGVyZm9ybWVkwqBwcmlvcsKgdG8gYWxsIG90aGVyIGFkanVzdG1lbnRzLCBpbmNsdWRpbmcgdGhlIGVmZmVjdHMgb2YgdGhlwqB6ZXJvLMKgbmljZSzCoGRvbWFpbk1pbiwgYW5kwqBkb21haW5NYXjCoHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEZvciBfW2JhbmRdKHNjYWxlLmh0bWwjYmFuZClfIHNjYWxlcywgc2hvcnRjdXQgZm9yIHNldHRpbmcgYHBhZGRpbmdJbm5lcmAgYW5kIGBwYWRkaW5nT3V0ZXJgIHRvIHRoZSBzYW1lIHZhbHVlLlxuICAgKlxuICAgKiBGb3IgX1twb2ludF0oc2NhbGUuaHRtbCNwb2ludClfIHNjYWxlcywgYWxpYXMgZm9yIGBwYWRkaW5nT3V0ZXJgLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gRm9yIF9jb250aW51b3VzXyBzY2FsZXMsIGRlcml2ZWQgZnJvbSB0aGUgW3NjYWxlIGNvbmZpZ10oc2NhbGUuaHRtbCNjb25maWcpJ3MgYGNvbnRpbnVvdXNQYWRkaW5nYC5cbiAgICogRm9yIF9iYW5kIGFuZCBwb2ludF8gc2NhbGVzLCBzZWUgYHBhZGRpbmdJbm5lcmAgYW5kIGBwYWRkaW5nT3V0ZXJgLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBwYWRkaW5nPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5uZXIgcGFkZGluZyAoc3BhY2luZykgd2l0aGluIGVhY2ggYmFuZCBzdGVwIG9mIGJhbmQgc2NhbGVzLCBhcyBhIGZyYWN0aW9uIG9mIHRoZSBzdGVwIHNpemUuIFRoaXMgdmFsdWUgbXVzdCBsaWUgaW4gdGhlIHJhbmdlIFswLDFdLlxuICAgKlxuICAgKiBGb3IgcG9pbnQgc2NhbGUsIHRoaXMgcHJvcGVydHkgaXMgaW52YWxpZCBhcyBwb2ludCBzY2FsZXMgZG8gbm90IGhhdmUgaW50ZXJuYWwgYmFuZCB3aWR0aHMgKG9ubHkgc3RlcCBzaXplcyBiZXR3ZWVuIGJhbmRzKS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGRlcml2ZWQgZnJvbSB0aGUgW3NjYWxlIGNvbmZpZ10oc2NhbGUuaHRtbCNjb25maWcpJ3MgYGJhbmRQYWRkaW5nSW5uZXJgLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIHBhZGRpbmdJbm5lcj86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG91dGVyIHBhZGRpbmcgKHNwYWNpbmcpIGF0IHRoZSBlbmRzIG9mIHRoZSByYW5nZSBvZiBiYW5kIGFuZCBwb2ludCBzY2FsZXMsXG4gICAqIGFzIGEgZnJhY3Rpb24gb2YgdGhlIHN0ZXAgc2l6ZS4gVGhpcyB2YWx1ZSBtdXN0IGxpZSBpbiB0aGUgcmFuZ2UgWzAsMV0uXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBkZXJpdmVkIGZyb20gdGhlIFtzY2FsZSBjb25maWddKHNjYWxlLmh0bWwjY29uZmlnKSdzIGBiYW5kUGFkZGluZ091dGVyYCBmb3IgYmFuZCBzY2FsZXMgYW5kIGBwb2ludFBhZGRpbmdgIGZvciBwb2ludCBzY2FsZXMuXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICogQG1heGltdW0gMVxuICAgKi9cbiAgcGFkZGluZ091dGVyPzogbnVtYmVyO1xuXG4gIC8vIHR5cGljYWxcbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgdmFsdWVzIHRoYXQgZXhjZWVkIHRoZSBkYXRhIGRvbWFpbiBhcmUgY2xhbXBlZCB0byBlaXRoZXIgdGhlIG1pbmltdW0gb3IgbWF4aW11bSByYW5nZSB2YWx1ZVxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gZGVyaXZlZCBmcm9tIHRoZSBbc2NhbGUgY29uZmlnXShjb25maWcuaHRtbCNzY2FsZS1jb25maWcpJ3MgYGNsYW1wYCAoYHRydWVgIGJ5IGRlZmF1bHQpLlxuICAgKi9cbiAgY2xhbXA/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBFeHRlbmRpbmcgdGhlIGRvbWFpbiBzbyB0aGF0IGl0IHN0YXJ0cyBhbmQgZW5kcyBvbiBuaWNlIHJvdW5kIHZhbHVlcy4gVGhpcyBtZXRob2QgdHlwaWNhbGx5IG1vZGlmaWVzIHRoZSBzY2FsZeKAmXMgZG9tYWluLCBhbmQgbWF5IG9ubHkgZXh0ZW5kIHRoZSBib3VuZHMgdG8gdGhlIG5lYXJlc3Qgcm91bmQgdmFsdWUuIE5pY2luZyBpcyB1c2VmdWwgaWYgdGhlIGRvbWFpbiBpcyBjb21wdXRlZCBmcm9tIGRhdGEgYW5kIG1heSBiZSBpcnJlZ3VsYXIuIEZvciBleGFtcGxlLCBmb3IgYSBkb21haW4gb2YgX1swLjIwMTQ3OeKApiwgMC45OTY2NznigKZdXywgYSBuaWNlIGRvbWFpbiBtaWdodCBiZSBfWzAuMiwgMS4wXV8uXG4gICAqXG4gICAqIEZvciBxdWFudGl0YXRpdmUgc2NhbGVzIHN1Y2ggYXMgbGluZWFyLCBgbmljZWAgY2FuIGJlIGVpdGhlciBhIGJvb2xlYW4gZmxhZyBvciBhIG51bWJlci4gSWYgYG5pY2VgIGlzIGEgbnVtYmVyLCBpdCB3aWxsIHJlcHJlc2VudCBhIGRlc2lyZWQgdGljayBjb3VudC4gVGhpcyBhbGxvd3MgZ3JlYXRlciBjb250cm9sIG92ZXIgdGhlIHN0ZXAgc2l6ZSB1c2VkIHRvIGV4dGVuZCB0aGUgYm91bmRzLCBndWFyYW50ZWVpbmcgdGhhdCB0aGUgcmV0dXJuZWQgdGlja3Mgd2lsbCBleGFjdGx5IGNvdmVyIHRoZSBkb21haW4uXG4gICAqXG4gICAqIEZvciB0ZW1wb3JhbCBmaWVsZHMgd2l0aCB0aW1lIGFuZCB1dGMgc2NhbGVzLCB0aGUgYG5pY2VgIHZhbHVlIGNhbiBiZSBhIHN0cmluZyBpbmRpY2F0aW5nIHRoZSBkZXNpcmVkIHRpbWUgaW50ZXJ2YWwuIExlZ2FsIHZhbHVlcyBhcmUgYFwibWlsbGlzZWNvbmRcImAsIGBcInNlY29uZFwiYCwgYFwibWludXRlXCJgLCBgXCJob3VyXCJgLCBgXCJkYXlcImAsIGBcIndlZWtcImAsIGBcIm1vbnRoXCJgLCBhbmQgYFwieWVhclwiYC4gQWx0ZXJuYXRpdmVseSwgYHRpbWVgIGFuZCBgdXRjYCBzY2FsZXMgY2FuIGFjY2VwdCBhbiBvYmplY3QtdmFsdWVkIGludGVydmFsIHNwZWNpZmllciBvZiB0aGUgZm9ybSBge1wiaW50ZXJ2YWxcIjogXCJtb250aFwiLCBcInN0ZXBcIjogM31gLCB3aGljaCBpbmNsdWRlcyBhIGRlc2lyZWQgbnVtYmVyIG9mIGludGVydmFsIHN0ZXBzLiBIZXJlLCB0aGUgZG9tYWluIHdvdWxkIHNuYXAgdG8gcXVhcnRlciAoSmFuLCBBcHIsIEp1bCwgT2N0KSBib3VuZGFyaWVzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYHRydWVgIGZvciB1bmJpbm5lZCBfcXVhbnRpdGF0aXZlXyBmaWVsZHM7IGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKlxuICAgKi9cbiAgbmljZT86IGJvb2xlYW4gfCBudW1iZXIgfCBOaWNlVGltZSB8IHtpbnRlcnZhbDogc3RyaW5nLCBzdGVwOiBudW1iZXJ9O1xuXG4gIC8qKlxuICAgKiBUaGUgbG9nYXJpdGhtIGJhc2Ugb2YgdGhlIGBsb2dgIHNjYWxlIChkZWZhdWx0IGAxMGApLlxuICAgKi9cbiAgYmFzZT86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGV4cG9uZW50IG9mIHRoZSBgcG93YCBzY2FsZS5cbiAgICovXG4gIGV4cG9uZW50PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIGVuc3VyZXMgdGhhdCBhIHplcm8gYmFzZWxpbmUgdmFsdWUgaXMgaW5jbHVkZWQgaW4gdGhlIHNjYWxlIGRvbWFpbi5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB0cnVlYCBmb3IgeCBhbmQgeSBjaGFubmVscyBpZiB0aGUgcXVhbnRpdGF0aXZlIGZpZWxkIGlzIG5vdCBiaW5uZWQgYW5kIG5vIGN1c3RvbSBgZG9tYWluYCBpcyBwcm92aWRlZDsgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBMb2csIHRpbWUsIGFuZCB1dGMgc2NhbGVzIGRvIG5vdCBzdXBwb3J0IGB6ZXJvYC5cbiAgICovXG4gIHplcm8/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgaW50ZXJwb2xhdGlvbiBtZXRob2QgZm9yIHJhbmdlIHZhbHVlcy4gQnkgZGVmYXVsdCwgYSBnZW5lcmFsIGludGVycG9sYXRvciBmb3IgbnVtYmVycywgZGF0ZXMsIHN0cmluZ3MgYW5kIGNvbG9ycyAoaW4gUkdCIHNwYWNlKSBpcyB1c2VkLiBGb3IgY29sb3IgcmFuZ2VzLCB0aGlzIHByb3BlcnR5IGFsbG93cyBpbnRlcnBvbGF0aW9uIGluIGFsdGVybmF0aXZlIGNvbG9yIHNwYWNlcy4gTGVnYWwgdmFsdWVzIGluY2x1ZGUgYHJnYmAsIGBoc2xgLCBgaHNsLWxvbmdgLCBgbGFiYCwgYGhjbGAsIGBoY2wtbG9uZ2AsIGBjdWJlaGVsaXhgIGFuZCBgY3ViZWhlbGl4LWxvbmdgICgnLWxvbmcnIHZhcmlhbnRzIHVzZSBsb25nZXIgcGF0aHMgaW4gcG9sYXIgY29vcmRpbmF0ZSBzcGFjZXMpLiBJZiBvYmplY3QtdmFsdWVkLCB0aGlzIHByb3BlcnR5IGFjY2VwdHMgYW4gb2JqZWN0IHdpdGggYSBzdHJpbmctdmFsdWVkIF90eXBlXyBwcm9wZXJ0eSBhbmQgYW4gb3B0aW9uYWwgbnVtZXJpYyBfZ2FtbWFfIHByb3BlcnR5IGFwcGxpY2FibGUgdG8gcmdiIGFuZCBjdWJlaGVsaXggaW50ZXJwb2xhdG9ycy4gRm9yIG1vcmUsIHNlZSB0aGUgW2QzLWludGVycG9sYXRlIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1pbnRlcnBvbGF0ZSkuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBTZXF1ZW50aWFsIHNjYWxlcyBkbyBub3Qgc3VwcG9ydCBgaW50ZXJwb2xhdGVgIGFzIHRoZXkgaGF2ZSBhIGZpeGVkIGludGVycG9sYXRvci4gIFNpbmNlIFZlZ2EtTGl0ZSB1c2VzIHNlcXVlbnRpYWwgc2NhbGVzIGZvciBxdWFudGl0YXRpdmUgZmllbGRzIGJ5IGRlZmF1bHQsIHlvdSBoYXZlIHRvIHNldCB0aGUgc2NhbGUgYHR5cGVgIHRvIG90aGVyIHF1YW50aXRhdGl2ZSBzY2FsZSB0eXBlIHN1Y2ggYXMgYFwibGluZWFyXCJgIHRvIGN1c3RvbWl6ZSBgaW50ZXJwb2xhdGVgLlxuICAgKi9cbiAgaW50ZXJwb2xhdGU/OiBJbnRlcnBvbGF0ZSB8IEludGVycG9sYXRlUGFyYW1zO1xufVxuXG5leHBvcnQgdHlwZSBJbnRlcnBvbGF0ZSA9ICdyZ2InfCAnbGFiJyB8ICdoY2wnIHwgJ2hzbCcgfCAnaHNsLWxvbmcnIHwgJ2hjbC1sb25nJyB8ICdjdWJlaGVsaXgnIHwgJ2N1YmVoZWxpeC1sb25nJztcblxuZXhwb3J0IGludGVyZmFjZSBJbnRlcnBvbGF0ZVBhcmFtcyB7XG4gIHR5cGU6ICdyZ2InIHwgJ2N1YmVoZWxpeCcgfCAnY3ViZWhlbGl4LWxvbmcnO1xuICBnYW1tYT86IG51bWJlcjtcbn1cblxuY29uc3QgU0NBTEVfUFJPUEVSVFlfSU5ERVg6IEZsYWc8a2V5b2YgU2NhbGU+ID0ge1xuICB0eXBlOiAxLFxuICBkb21haW46IDEsXG4gIHJhbmdlOiAxLFxuICByYW5nZVN0ZXA6IDEsXG4gIHNjaGVtZTogMSxcbiAgLy8gT3RoZXIgcHJvcGVydGllc1xuICByZXZlcnNlOiAxLFxuICByb3VuZDogMSxcbiAgLy8gcXVhbnRpdGF0aXZlIC8gdGltZVxuICBjbGFtcDogMSxcbiAgbmljZTogMSxcbiAgLy8gcXVhbnRpdGF0aXZlXG4gIGJhc2U6IDEsXG4gIGV4cG9uZW50OiAxLFxuICBpbnRlcnBvbGF0ZTogMSxcbiAgemVybzogMSwgLy8gemVybyBkZXBlbmRzIG9uIGRvbWFpblxuICAvLyBiYW5kL3BvaW50XG4gIHBhZGRpbmc6IDEsXG4gIHBhZGRpbmdJbm5lcjogMSxcbiAgcGFkZGluZ091dGVyOiAxXG59O1xuXG5leHBvcnQgY29uc3QgU0NBTEVfUFJPUEVSVElFUyA9IGZsYWdLZXlzKFNDQUxFX1BST1BFUlRZX0lOREVYKTtcblxuY29uc3Qge3R5cGUsIGRvbWFpbiwgcmFuZ2UsIHJhbmdlU3RlcCwgc2NoZW1lLCAuLi5OT05fVFlQRV9ET01BSU5fUkFOR0VfVkVHQV9TQ0FMRV9QUk9QRVJUWV9JTkRFWH0gPSBTQ0FMRV9QUk9QRVJUWV9JTkRFWDtcblxuZXhwb3J0IGNvbnN0IE5PTl9UWVBFX0RPTUFJTl9SQU5HRV9WRUdBX1NDQUxFX1BST1BFUlRJRVMgPSBmbGFnS2V5cyhOT05fVFlQRV9ET01BSU5fUkFOR0VfVkVHQV9TQ0FMRV9QUk9QRVJUWV9JTkRFWCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZVR5cGVTdXBwb3J0UHJvcGVydHkoc2NhbGVUeXBlOiBTY2FsZVR5cGUsIHByb3BOYW1lOiBrZXlvZiBTY2FsZSkge1xuICBzd2l0Y2ggKHByb3BOYW1lKSB7XG4gICAgY2FzZSAndHlwZSc6XG4gICAgY2FzZSAnZG9tYWluJzpcbiAgICBjYXNlICdyZXZlcnNlJzpcbiAgICBjYXNlICdyYW5nZSc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBjYXNlICdzY2hlbWUnOlxuICAgICAgcmV0dXJuIGNvbnRhaW5zKFsnc2VxdWVudGlhbCcsICdvcmRpbmFsJywgJ2Jpbi1vcmRpbmFsJywgJ3F1YW50aWxlJywgJ3F1YW50aXplJ10sIHNjYWxlVHlwZSk7XG4gICAgY2FzZSAnaW50ZXJwb2xhdGUnOlxuICAgICAgLy8gRklYTUUoaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yOTAyKSBob3cgYWJvdXQgb3JkaW5hbD9cbiAgICAgIHJldHVybiBjb250YWlucyhbJ2xpbmVhcicsICdiaW4tbGluZWFyJywgJ3BvdycsICdsb2cnLCAnc3FydCcsICd1dGMnLCAndGltZSddLCBzY2FsZVR5cGUpO1xuICAgIGNhc2UgJ3JvdW5kJzpcbiAgICAgIHJldHVybiBpc0NvbnRpbnVvdXNUb0NvbnRpbnVvdXMoc2NhbGVUeXBlKSB8fCBzY2FsZVR5cGUgPT09ICdiYW5kJyB8fCBzY2FsZVR5cGUgPT09ICdwb2ludCc7XG4gICAgY2FzZSAncGFkZGluZyc6XG4gICAgICByZXR1cm4gaXNDb250aW51b3VzVG9Db250aW51b3VzKHNjYWxlVHlwZSkgfHwgY29udGFpbnMoWydwb2ludCcsICdiYW5kJ10sIHNjYWxlVHlwZSk7XG4gICAgY2FzZSAncGFkZGluZ091dGVyJzpcbiAgICBjYXNlICdyYW5nZVN0ZXAnOlxuICAgICAgcmV0dXJuIGNvbnRhaW5zKFsncG9pbnQnLCAnYmFuZCddLCBzY2FsZVR5cGUpO1xuICAgIGNhc2UgJ3BhZGRpbmdJbm5lcic6XG4gICAgICByZXR1cm4gc2NhbGVUeXBlID09PSAnYmFuZCc7XG4gICAgY2FzZSAnY2xhbXAnOlxuICAgICAgcmV0dXJuIGlzQ29udGludW91c1RvQ29udGludW91cyhzY2FsZVR5cGUpIHx8IHNjYWxlVHlwZSA9PT0gJ3NlcXVlbnRpYWwnO1xuICAgIGNhc2UgJ25pY2UnOlxuICAgICAgcmV0dXJuIGlzQ29udGludW91c1RvQ29udGludW91cyhzY2FsZVR5cGUpIHx8IHNjYWxlVHlwZSA9PT0gJ3NlcXVlbnRpYWwnIHx8IHNjYWxlVHlwZSBhcyBhbnkgPT09ICdxdWFudGl6ZSc7XG4gICAgY2FzZSAnZXhwb25lbnQnOlxuICAgICAgcmV0dXJuIHNjYWxlVHlwZSA9PT0gJ3Bvdyc7XG4gICAgY2FzZSAnYmFzZSc6XG4gICAgICByZXR1cm4gc2NhbGVUeXBlID09PSAnbG9nJztcbiAgICBjYXNlICd6ZXJvJzpcbiAgICAgIHJldHVybiBoYXNDb250aW51b3VzRG9tYWluKHNjYWxlVHlwZSkgJiYgIWNvbnRhaW5zKFtcbiAgICAgICAgJ2xvZycsICAvLyBsb2cgc2NhbGUgY2Fubm90IGhhdmUgemVybyB2YWx1ZVxuICAgICAgICAndGltZScsICd1dGMnLCAvLyB6ZXJvIGlzIG5vdCBtZWFuaW5nZnVsIGZvciB0aW1lXG4gICAgICAgICdiaW4tbGluZWFyJywgLy8gYmlubmluZyBzaG91bGQgbm90IGF1dG9tYXRpY2FsbHkgYWRkIHplcm9cbiAgICAgICAgJ3RocmVzaG9sZCcsIC8vIHRocmVzaG9sZCByZXF1aXJlcyBjdXN0b20gZG9tYWluIHNvIHplcm8gZG9lcyBub3QgbWF0dGVyXG4gICAgICAgICdxdWFudGlsZScgLy8gcXVhbnRpbGUgZGVwZW5kcyBvbiBkaXN0cmlidXRpb24gc28gemVybyBkb2VzIG5vdCBtYXR0ZXJcbiAgICAgIF0sIHNjYWxlVHlwZSk7XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IHNob3VsZCBuZXZlciByZWFjaCBoZXJlKi9cbiAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNjYWxlIHByb3BlcnR5ICR7cHJvcE5hbWV9LmApO1xufVxuXG4vKipcbiAqIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZSBpbnB1dCBjaGFubmVsIHN1cHBvcnRzIHRoZSBpbnB1dCBzY2FsZSBwcm9wZXJ0eSBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFubmVsU2NhbGVQcm9wZXJ0eUluY29tcGF0YWJpbGl0eShjaGFubmVsOiBDaGFubmVsLCBwcm9wTmFtZToga2V5b2YgU2NhbGUpOiBzdHJpbmcge1xuICBzd2l0Y2ggKHByb3BOYW1lKSB7XG4gICAgY2FzZSAnaW50ZXJwb2xhdGUnOlxuICAgIGNhc2UgJ3NjaGVtZSc6XG4gICAgICBpZiAoY2hhbm5lbCAhPT0gJ2NvbG9yJykge1xuICAgICAgICByZXR1cm4gbG9nLm1lc3NhZ2UuY2Fubm90VXNlU2NhbGVQcm9wZXJ0eVdpdGhOb25Db2xvcihjaGFubmVsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY2FzZSAndHlwZSc6XG4gICAgY2FzZSAnZG9tYWluJzpcbiAgICBjYXNlICdyYW5nZSc6XG4gICAgY2FzZSAnYmFzZSc6XG4gICAgY2FzZSAnZXhwb25lbnQnOlxuICAgIGNhc2UgJ25pY2UnOlxuICAgIGNhc2UgJ3BhZGRpbmcnOlxuICAgIGNhc2UgJ3BhZGRpbmdJbm5lcic6XG4gICAgY2FzZSAncGFkZGluZ091dGVyJzpcbiAgICBjYXNlICdyYW5nZVN0ZXAnOlxuICAgIGNhc2UgJ3JldmVyc2UnOlxuICAgIGNhc2UgJ3JvdW5kJzpcbiAgICBjYXNlICdjbGFtcCc6XG4gICAgY2FzZSAnemVybyc6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkOyAvLyBHT09EIVxuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpdCBzaG91bGQgbmV2ZXIgcmVhY2ggaGVyZSAqL1xuICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc2NhbGUgcHJvcGVydHkgXCIke3Byb3BOYW1lfVwiLmApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hhbm5lbFN1cHBvcnRTY2FsZVR5cGUoY2hhbm5lbDogQ2hhbm5lbCwgc2NhbGVUeXBlOiBTY2FsZVR5cGUpOiBib29sZWFuIHtcbiAgc3dpdGNoIChjaGFubmVsKSB7XG4gICAgY2FzZSBDaGFubmVsLlg6XG4gICAgY2FzZSBDaGFubmVsLlk6XG4gICAgY2FzZSBDaGFubmVsLlNJWkU6IC8vIFRPRE86IHNpemUgYW5kIG9wYWNpdHkgY2FuIHN1cHBvcnQgb3JkaW5hbCB3aXRoIG1vcmUgbW9kaWZpY2F0aW9uXG4gICAgY2FzZSBDaGFubmVsLk9QQUNJVFk6XG4gICAgICAvLyBBbHRob3VnaCBpdCBnZW5lcmFsbHkgZG9lc24ndCBtYWtlIHNlbnNlIHRvIHVzZSBiYW5kIHdpdGggc2l6ZSBhbmQgb3BhY2l0eSxcbiAgICAgIC8vIGl0IGNhbiBhbHNvIHdvcmsgc2luY2Ugd2UgdXNlIGJhbmQ6IDAuNSB0byBnZXQgbWlkcG9pbnQuXG4gICAgICByZXR1cm4gaXNDb250aW51b3VzVG9Db250aW51b3VzKHNjYWxlVHlwZSkgfHwgY29udGFpbnMoWydiYW5kJywgJ3BvaW50J10sIHNjYWxlVHlwZSk7XG4gICAgY2FzZSBDaGFubmVsLkNPTE9SOlxuICAgICAgcmV0dXJuIHNjYWxlVHlwZSAhPT0gJ2JhbmQnOyAgICAvLyBiYW5kIGRvZXMgbm90IG1ha2Ugc2Vuc2Ugd2l0aCBjb2xvclxuICAgIGNhc2UgQ2hhbm5lbC5TSEFQRTpcbiAgICAgIHJldHVybiBzY2FsZVR5cGUgPT09ICdvcmRpbmFsJzsgLy8gc2hhcGUgPSBsb29rdXAgb25seVxuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpdCBzaG91bGQgbmV2ZXIgcmVhY2ggaGVyZSAqL1xuICByZXR1cm4gZmFsc2U7XG59XG4iXX0= \ 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..7f9ebbf5de --- /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](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](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](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](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`](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`](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`](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..17b01cf868 --- /dev/null +++ b/build/src/selection.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SELECTION_ID = '_vgsid_'; +exports.defaultConfig = { + single: { + on: 'click', + fields: [exports.SELECTION_ID], + resolve: 'global', + empty: 'all' + }, + multi: { + on: 'click', + fields: [exports.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUdhLFFBQUEsWUFBWSxHQUFHLFNBQVMsQ0FBQztBQTJNekIsUUFBQSxhQUFhLEdBQW1CO0lBQzNDLE1BQU0sRUFBRTtRQUNOLEVBQUUsRUFBRSxPQUFPO1FBQ1gsTUFBTSxFQUFFLENBQUMsb0JBQVksQ0FBQztRQUN0QixPQUFPLEVBQUUsUUFBUTtRQUNqQixLQUFLLEVBQUUsS0FBSztLQUNiO0lBQ0QsS0FBSyxFQUFFO1FBQ0wsRUFBRSxFQUFFLE9BQU87UUFDWCxNQUFNLEVBQUUsQ0FBQyxvQkFBWSxDQUFDO1FBQ3RCLE1BQU0sRUFBRSxnQkFBZ0I7UUFDeEIsT0FBTyxFQUFFLFFBQVE7UUFDakIsS0FBSyxFQUFFLEtBQUs7S0FDYjtJQUNELFFBQVEsRUFBRTtRQUNSLEVBQUUsRUFBRSxpREFBaUQ7UUFDckQsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztRQUNyQixTQUFTLEVBQUUsaURBQWlEO1FBQzVELElBQUksRUFBRSxRQUFRO1FBQ2QsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUM7UUFDekQsT0FBTyxFQUFFLFFBQVE7S0FDbEI7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTaW5nbGVEZWZDaGFubmVsfSBmcm9tICcuL2NoYW5uZWwnO1xuaW1wb3J0IHtWZ0JpbmRpbmcsIFZnRXZlbnRTdHJlYW19IGZyb20gJy4vdmVnYS5zY2hlbWEnO1xuXG5leHBvcnQgY29uc3QgU0VMRUNUSU9OX0lEID0gJ192Z3NpZF8nO1xuZXhwb3J0IHR5cGUgU2VsZWN0aW9uVHlwZSA9ICdzaW5nbGUnIHwgJ211bHRpJyB8ICdpbnRlcnZhbCc7XG5leHBvcnQgdHlwZSBTZWxlY3Rpb25SZXNvbHV0aW9uID0gJ2dsb2JhbCcgfCAndW5pb24nIHwgJ2ludGVyc2VjdCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZVNlbGVjdGlvbkRlZiB7XG4gIC8qKlxuICAgKiBBIFtWZWdhIGV2ZW50IHN0cmVhbV0oaHR0cHM6Ly92ZWdhLmdpdGh1Yi5pby92ZWdhL2RvY3MvZXZlbnQtc3RyZWFtcy8pIChvYmplY3Qgb3Igc2VsZWN0b3IpIHRoYXQgdHJpZ2dlcnMgdGhlIHNlbGVjdGlvbi5cbiAgICogRm9yIGludGVydmFsIHNlbGVjdGlvbnMsIHRoZSBldmVudCBzdHJlYW0gbXVzdCBzcGVjaWZ5IGEgW3N0YXJ0IGFuZCBlbmRdKGh0dHBzOi8vdmVnYS5naXRodWIuaW8vdmVnYS9kb2NzL2V2ZW50LXN0cmVhbXMvI2JldHdlZW4tZmlsdGVycykuXG4gICAqL1xuICBvbj86IFZnRXZlbnRTdHJlYW07XG4gIC8qKlxuICAgKiBXaXRoIGxheWVyZWQgYW5kIG11bHRpLXZpZXcgZGlzcGxheXMsIGEgc3RyYXRlZ3kgdGhhdCBkZXRlcm1pbmVzIGhvd1xuICAgKiBzZWxlY3Rpb25zJyBkYXRhIHF1ZXJpZXMgYXJlIHJlc29sdmVkIHdoZW4gYXBwbGllZCBpbiBhIGZpbHRlciB0cmFuc2Zvcm0sXG4gICAqIGNvbmRpdGlvbmFsIGVuY29kaW5nIHJ1bGUsIG9yIHNjYWxlIGRvbWFpbi5cbiAgICpcbiAgICovXG4gIHJlc29sdmU/OiBTZWxlY3Rpb25SZXNvbHV0aW9uO1xuXG4gIC8vIFRPRE8oaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yNTk2KS5cbiAgLy8gcHJlZGljYXRlPzogc3RyaW5nO1xuICAvLyBkb21haW4/OiBTZWxlY3Rpb25Eb21haW47XG5cbiAgLy8gVHJhbnNmb3Jtc1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBlbmNvZGluZyBjaGFubmVscy4gVGhlIGNvcnJlc3BvbmRpbmcgZGF0YSBmaWVsZCB2YWx1ZXNcbiAgICogbXVzdCBtYXRjaCBmb3IgYSBkYXRhIHR1cGxlIHRvIGZhbGwgd2l0aGluIHRoZSBzZWxlY3Rpb24uXG4gICAqL1xuICBlbmNvZGluZ3M/OiBTaW5nbGVEZWZDaGFubmVsW107XG5cbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGZpZWxkIG5hbWVzIHdob3NlIHZhbHVlcyBtdXN0IG1hdGNoIGZvciBhIGRhdGEgdHVwbGUgdG9cbiAgICogZmFsbCB3aXRoaW4gdGhlIHNlbGVjdGlvbi5cbiAgICovXG4gIGZpZWxkcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBCeSBkZWZhdWx0LCBhbGwgZGF0YSB2YWx1ZXMgYXJlIGNvbnNpZGVyZWQgdG8gbGllIHdpdGhpbiBhbiBlbXB0eSBzZWxlY3Rpb24uXG4gICAqIFdoZW4gc2V0IHRvIGBub25lYCwgZW1wdHkgc2VsZWN0aW9ucyBjb250YWluIG5vIGRhdGEgdmFsdWVzLlxuICAgKi9cbiAgZW1wdHk/OiAnYWxsJyB8ICdub25lJztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaW5nbGVTZWxlY3Rpb25Db25maWcgZXh0ZW5kcyBCYXNlU2VsZWN0aW9uRGVmIHtcbiAgLyoqXG4gICAqIEVzdGFibGlzaCBhIHR3by13YXkgYmluZGluZyBiZXR3ZWVuIGEgc2luZ2xlIHNlbGVjdGlvbiBhbmQgaW5wdXQgZWxlbWVudHNcbiAgICogKGFsc28ga25vd24gYXMgZHluYW1pYyBxdWVyeSB3aWRnZXRzKS4gQSBiaW5kaW5nIHRha2VzIHRoZSBmb3JtIG9mXG4gICAqIFZlZ2EncyBbaW5wdXQgZWxlbWVudCBiaW5kaW5nIGRlZmluaXRpb25dKGh0dHBzOi8vdmVnYS5naXRodWIuaW8vdmVnYS9kb2NzL3NpZ25hbHMvI2JpbmQpXG4gICAqIG9yIGNhbiBiZSBhIG1hcHBpbmcgYmV0d2VlbiBwcm9qZWN0ZWQgZmllbGQvZW5jb2RpbmdzIGFuZCBiaW5kaW5nIGRlZmluaXRpb25zLlxuICAgKlxuICAgKiBTZWUgdGhlIFtiaW5kIHRyYW5zZm9ybV0oYmluZC5odG1sKSBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgYmluZD86IFZnQmluZGluZyB8IHtba2V5OiBzdHJpbmddOiBWZ0JpbmRpbmd9O1xuXG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIGFuIGludmlzaWJsZSB2b3Jvbm9pIGRpYWdyYW0gaXMgY29tcHV0ZWQgdG8gYWNjZWxlcmF0ZSBkaXNjcmV0ZVxuICAgKiBzZWxlY3Rpb24uIFRoZSBkYXRhIHZhbHVlIF9uZWFyZXN0XyB0aGUgbW91c2UgY3Vyc29yIGlzIGFkZGVkIHRvIHRoZSBzZWxlY3Rpb24uXG4gICAqXG4gICAqIFNlZSB0aGUgW25lYXJlc3QgdHJhbnNmb3JtXShuZWFyZXN0Lmh0bWwpIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBuZWFyZXN0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNdWx0aVNlbGVjdGlvbkNvbmZpZyBleHRlbmRzIEJhc2VTZWxlY3Rpb25EZWYge1xuICAvKipcbiAgICogQ29udHJvbHMgd2hldGhlciBkYXRhIHZhbHVlcyBzaG91bGQgYmUgdG9nZ2xlZCBvciBvbmx5IGV2ZXIgaW5zZXJ0ZWQgaW50b1xuICAgKiBtdWx0aSBzZWxlY3Rpb25zLiBDYW4gYmUgYHRydWVgLCBgZmFsc2VgIChmb3IgaW5zZXJ0aW9uIG9ubHkpLCBvciBhXG4gICAqIFtWZWdhIGV4cHJlc3Npb25dKGh0dHBzOi8vdmVnYS5naXRodWIuaW8vdmVnYS9kb2NzL2V4cHJlc3Npb25zLykuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgdHJ1ZWAsIHdoaWNoIGNvcnJlc3BvbmRzIHRvIGBldmVudC5zaGlmdEtleWAgKGkuZS4sXG4gICAqIGRhdGEgdmFsdWVzIGFyZSB0b2dnbGVkIHdoZW4gYSB1c2VyIGludGVyYWN0cyB3aXRoIHRoZSBzaGlmdC1rZXkgcHJlc3NlZCkuXG4gICAqXG4gICAqIFNlZSB0aGUgW3RvZ2dsZSB0cmFuc2Zvcm1dKHRvZ2dsZS5odG1sKSBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgdG9nZ2xlPzogc3RyaW5nIHwgYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hlbiB0cnVlLCBhbiBpbnZpc2libGUgdm9yb25vaSBkaWFncmFtIGlzIGNvbXB1dGVkIHRvIGFjY2VsZXJhdGUgZGlzY3JldGVcbiAgICogc2VsZWN0aW9uLiBUaGUgZGF0YSB2YWx1ZSBfbmVhcmVzdF8gdGhlIG1vdXNlIGN1cnNvciBpcyBhZGRlZCB0byB0aGUgc2VsZWN0aW9uLlxuICAgKlxuICAgKiBTZWUgdGhlIFtuZWFyZXN0IHRyYW5zZm9ybV0obmVhcmVzdC5odG1sKSBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgbmVhcmVzdD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJ1c2hDb25maWcge1xuICAvKipcbiAgICogVGhlIGZpbGwgY29sb3Igb2YgdGhlIGludGVydmFsIG1hcmsuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgIzMzMzMzM2BcbiAgICpcbiAgICovXG4gIGZpbGw/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZmlsbCBvcGFjaXR5IG9mIHRoZSBpbnRlcnZhbCBtYXJrIChhIHZhbHVlIGJldHdlZW4gMCBhbmQgMSkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMC4xMjVgXG4gICAqL1xuICBmaWxsT3BhY2l0eT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBzdHJva2UgY29sb3Igb2YgdGhlIGludGVydmFsIG1hcmsuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgI2ZmZmZmZmBcbiAgICovXG4gIHN0cm9rZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBzdHJva2Ugb3BhY2l0eSBvZiB0aGUgaW50ZXJ2YWwgbWFyayAoYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEpLlxuICAgKi9cbiAgc3Ryb2tlT3BhY2l0eT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBzdHJva2Ugd2lkdGggb2YgdGhlIGludGVydmFsIG1hcmsuXG4gICAqL1xuICBzdHJva2VXaWR0aD86IG51bWJlcjtcbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGFsdGVybmF0aW5nIHN0cm9rZSBhbmQgc3BhY2UgbGVuZ3RocyxcbiAgICogZm9yIGNyZWF0aW5nIGRhc2hlZCBvciBkb3R0ZWQgbGluZXMuXG4gICAqL1xuICBzdHJva2VEYXNoPzogbnVtYmVyW107XG4gIC8qKlxuICAgKiBUaGUgb2Zmc2V0IChpbiBwaXhlbHMpIHdpdGggd2hpY2ggdG8gYmVnaW4gZHJhd2luZyB0aGUgc3Ryb2tlIGRhc2ggYXJyYXkuXG4gICAqL1xuICBzdHJva2VEYXNoT2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEludGVydmFsU2VsZWN0aW9uQ29uZmlnIGV4dGVuZHMgQmFzZVNlbGVjdGlvbkRlZiB7XG4gIC8qKlxuICAgKiBXaGVuIHRydXRoeSwgYWxsb3dzIGEgdXNlciB0byBpbnRlcmFjdGl2ZWx5IG1vdmUgYW4gaW50ZXJ2YWwgc2VsZWN0aW9uXG4gICAqIGJhY2stYW5kLWZvcnRoLiBDYW4gYmUgYHRydWVgLCBgZmFsc2VgICh0byBkaXNhYmxlIHBhbm5pbmcpLCBvciBhXG4gICAqIFtWZWdhIGV2ZW50IHN0cmVhbSBkZWZpbml0aW9uXShodHRwczovL3ZlZ2EuZ2l0aHViLmlvL3ZlZ2EvZG9jcy9ldmVudC1zdHJlYW1zLylcbiAgICogd2hpY2ggbXVzdCBpbmNsdWRlIGEgc3RhcnQgYW5kIGVuZCBldmVudCB0byB0cmlnZ2VyIGNvbnRpbnVvdXMgcGFubmluZy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB0cnVlYCwgd2hpY2ggY29ycmVzcG9uZHMgdG9cbiAgICogYFttb3VzZWRvd24sIHdpbmRvdzptb3VzZXVwXSA+IHdpbmRvdzptb3VzZW1vdmUhYCB3aGljaCBjb3JyZXNwb25kcyB0b1xuICAgKiBjbGlja3MgYW5kIGRyYWdnaW5nIHdpdGhpbiBhbiBpbnRlcnZhbCBzZWxlY3Rpb24gdG8gcmVwb3NpdGlvbiBpdC5cbiAgICovXG4gIHRyYW5zbGF0ZT86IHN0cmluZyB8IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZW4gdHJ1dGh5LCBhbGxvd3MgYSB1c2VyIHRvIGludGVyYWN0aXZlbHkgcmVzaXplIGFuIGludGVydmFsIHNlbGVjdGlvbi5cbiAgICogQ2FuIGJlIGB0cnVlYCwgYGZhbHNlYCAodG8gZGlzYWJsZSB6b29taW5nKSwgb3IgYSBbVmVnYSBldmVudCBzdHJlYW1cbiAgICogZGVmaW5pdGlvbl0oaHR0cHM6Ly92ZWdhLmdpdGh1Yi5pby92ZWdhL2RvY3MvZXZlbnQtc3RyZWFtcy8pLiBDdXJyZW50bHksXG4gICAqIG9ubHkgYHdoZWVsYCBldmVudHMgYXJlIHN1cHBvcnRlZC5cbiAgICpcbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB0cnVlYCwgd2hpY2ggY29ycmVzcG9uZHMgdG8gYHdoZWVsIWAuXG4gICAqL1xuICB6b29tPzogc3RyaW5nIHwgYm9vbGVhbjtcblxuICAvKipcbiAgICogRXN0YWJsaXNoZXMgYSB0d28td2F5IGJpbmRpbmcgYmV0d2VlbiB0aGUgaW50ZXJ2YWwgc2VsZWN0aW9uIGFuZCB0aGUgc2NhbGVzXG4gICAqIHVzZWQgd2l0aGluIHRoZSBzYW1lIHZpZXcuIFRoaXMgYWxsb3dzIGEgdXNlciB0byBpbnRlcmFjdGl2ZWx5IHBhbiBhbmRcbiAgICogem9vbSB0aGUgdmlldy5cbiAgICovXG4gIGJpbmQ/OiAnc2NhbGVzJztcblxuICAvKipcbiAgICogQW4gaW50ZXJ2YWwgc2VsZWN0aW9uIGFsc28gYWRkcyBhIHJlY3RhbmdsZSBtYXJrIHRvIGRlcGljdCB0aGVcbiAgICogZXh0ZW50cyBvZiB0aGUgaW50ZXJ2YWwuIFRoZSBgbWFya2AgcHJvcGVydHkgY2FuIGJlIHVzZWQgdG8gY3VzdG9taXplIHRoZVxuICAgKiBhcHBlYXJhbmNlIG9mIHRoZSBtYXJrLlxuICAgKi9cbiAgbWFyaz86IEJydXNoQ29uZmlnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNpbmdsZVNlbGVjdGlvbiBleHRlbmRzIFNpbmdsZVNlbGVjdGlvbkNvbmZpZyB7XG4gIHR5cGU6ICdzaW5nbGUnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE11bHRpU2VsZWN0aW9uIGV4dGVuZHMgTXVsdGlTZWxlY3Rpb25Db25maWcge1xuICB0eXBlOiAnbXVsdGknO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEludGVydmFsU2VsZWN0aW9uIGV4dGVuZHMgSW50ZXJ2YWxTZWxlY3Rpb25Db25maWcge1xuICB0eXBlOiAnaW50ZXJ2YWwnO1xufVxuXG5leHBvcnQgdHlwZSBTZWxlY3Rpb25EZWYgPSBTaW5nbGVTZWxlY3Rpb24gfCBNdWx0aVNlbGVjdGlvbiB8IEludGVydmFsU2VsZWN0aW9uO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdGlvbkNvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBkZWZpbml0aW9uIGZvciBhIFtgc2luZ2xlYF0oc2VsZWN0aW9uLmh0bWwjdHlwZSkgc2VsZWN0aW9uLiBBbGwgcHJvcGVydGllcyBhbmQgdHJhbnNmb3JtYXRpb25zXG4gICAqICBmb3IgYSBzaW5nbGUgc2VsZWN0aW9uIGRlZmluaXRpb24gKGV4Y2VwdCBgdHlwZWApIG1heSBiZSBzcGVjaWZpZWQgaGVyZS5cbiAgICpcbiAgICogRm9yIGluc3RhbmNlLCBzZXR0aW5nIGBzaW5nbGVgIHRvIGB7XCJvblwiOiBcImRibGNsaWNrXCJ9YCBwb3B1bGF0ZXMgc2luZ2xlIHNlbGVjdGlvbnMgb24gZG91YmxlLWNsaWNrIGJ5IGRlZmF1bHQuXG4gICAqL1xuICBzaW5nbGU/OiBTaW5nbGVTZWxlY3Rpb25Db25maWc7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBkZWZpbml0aW9uIGZvciBhIFtgbXVsdGlgXShzZWxlY3Rpb24uaHRtbCN0eXBlKSBzZWxlY3Rpb24uIEFsbCBwcm9wZXJ0aWVzIGFuZCB0cmFuc2Zvcm1hdGlvbnNcbiAgICogZm9yIGEgbXVsdGkgc2VsZWN0aW9uIGRlZmluaXRpb24gKGV4Y2VwdCBgdHlwZWApIG1heSBiZSBzcGVjaWZpZWQgaGVyZS5cbiAgICpcbiAgICogRm9yIGluc3RhbmNlLCBzZXR0aW5nIGBtdWx0aWAgdG8gYHtcInRvZ2dsZVwiOiBcImV2ZW50LmFsdEtleVwifWAgYWRkcyBhZGRpdGlvbmFsIHZhbHVlcyB0b1xuICAgKiBtdWx0aSBzZWxlY3Rpb25zIHdoZW4gY2xpY2tpbmcgd2l0aCB0aGUgYWx0LWtleSBwcmVzc2VkIGJ5IGRlZmF1bHQuXG4gICAqL1xuICBtdWx0aT86IE11bHRpU2VsZWN0aW9uQ29uZmlnO1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgZGVmaW5pdGlvbiBmb3IgYW4gW2BpbnRlcnZhbGBdKHNlbGVjdGlvbi5odG1sI3R5cGUpIHNlbGVjdGlvbi4gQWxsIHByb3BlcnRpZXMgYW5kIHRyYW5zZm9ybWF0aW9uc1xuICAgKiBmb3IgYW4gaW50ZXJ2YWwgc2VsZWN0aW9uIGRlZmluaXRpb24gKGV4Y2VwdCBgdHlwZWApIG1heSBiZSBzcGVjaWZpZWQgaGVyZS5cbiAgICpcbiAgICogRm9yIGluc3RhbmNlLCBzZXR0aW5nIGBpbnRlcnZhbGAgdG8gYHtcInRyYW5zbGF0ZVwiOiBmYWxzZX1gIGRpc2FibGVzIHRoZSBhYmlsaXR5IHRvIG1vdmVcbiAgICogaW50ZXJ2YWwgc2VsZWN0aW9ucyBieSBkZWZhdWx0LlxuICAgKi9cbiAgaW50ZXJ2YWw/OiBJbnRlcnZhbFNlbGVjdGlvbkNvbmZpZztcbn1cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRDb25maWc6U2VsZWN0aW9uQ29uZmlnID0ge1xuICBzaW5nbGU6IHtcbiAgICBvbjogJ2NsaWNrJyxcbiAgICBmaWVsZHM6IFtTRUxFQ1RJT05fSURdLFxuICAgIHJlc29sdmU6ICdnbG9iYWwnLFxuICAgIGVtcHR5OiAnYWxsJ1xuICB9LFxuICBtdWx0aToge1xuICAgIG9uOiAnY2xpY2snLFxuICAgIGZpZWxkczogW1NFTEVDVElPTl9JRF0sXG4gICAgdG9nZ2xlOiAnZXZlbnQuc2hpZnRLZXknLFxuICAgIHJlc29sdmU6ICdnbG9iYWwnLFxuICAgIGVtcHR5OiAnYWxsJ1xuICB9LFxuICBpbnRlcnZhbDoge1xuICAgIG9uOiAnW21vdXNlZG93biwgd2luZG93Om1vdXNldXBdID4gd2luZG93Om1vdXNlbW92ZSEnLFxuICAgIGVuY29kaW5nczogWyd4JywgJ3knXSxcbiAgICB0cmFuc2xhdGU6ICdbbW91c2Vkb3duLCB3aW5kb3c6bW91c2V1cF0gPiB3aW5kb3c6bW91c2Vtb3ZlIScsXG4gICAgem9vbTogJ3doZWVsIScsXG4gICAgbWFyazoge2ZpbGw6ICcjMzMzJywgZmlsbE9wYWNpdHk6IDAuMTI1LCBzdHJva2U6ICd3aGl0ZSd9LFxuICAgIHJlc29sdmU6ICdnbG9iYWwnXG4gIH1cbn07XG4iXX0= \ 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..e928296e72 --- /dev/null +++ b/build/src/sort.d.ts @@ -0,0 +1,23 @@ +import { AggregateOp } from './aggregate'; +export declare type SortOrder = 'ascending' | 'descending' | null; +export interface SortField { + /** + * The data [field](field.html) to sort by. + * + * __Default value:__ If unspecified, defaults to the field specified in the outer data reference. + */ + field?: F; + /** + * An [aggregate operation](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](aggregate.html#ops). + */ + op: AggregateOp; + /** + * The sort order. One of `"ascending"` (default) or `"descending"`. + */ + order?: SortOrder; +} +export declare function isSortField(sort: SortOrder | SortField): sort is SortField; diff --git a/build/src/sort.js b/build/src/sort.js new file mode 100644 index 0000000000..408cf73311 --- /dev/null +++ b/build/src/sort.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isSortField(sort) { + return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op']; +} +exports.isSortField = isSortField; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkJBLHFCQUErQixJQUE4QjtJQUMzRCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxPQUFPLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUZELGtDQUVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBZ2dyZWdhdGVPcH0gZnJvbSAnLi9hZ2dyZWdhdGUnO1xuXG5cbmV4cG9ydCB0eXBlIFNvcnRPcmRlciA9ICdhc2NlbmRpbmcnIHwgJ2Rlc2NlbmRpbmcnIHwgbnVsbDtcblxuZXhwb3J0IGludGVyZmFjZSBTb3J0RmllbGQ8Rj4ge1xuICAvKipcbiAgICogVGhlIGRhdGEgW2ZpZWxkXShmaWVsZC5odG1sKSB0byBzb3J0IGJ5LlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gSWYgdW5zcGVjaWZpZWQsIGRlZmF1bHRzIHRvIHRoZSBmaWVsZCBzcGVjaWZpZWQgaW4gdGhlIG91dGVyIGRhdGEgcmVmZXJlbmNlLlxuICAgKi9cbiAgZmllbGQ/OiBGO1xuICAvKipcbiAgICogQW4gW2FnZ3JlZ2F0ZSBvcGVyYXRpb25dKGFnZ3JlZ2F0ZS5odG1sI29wcykgdG8gcGVyZm9ybSBvbiB0aGUgZmllbGQgcHJpb3IgdG8gc29ydGluZyAoZS5nLiwgYFwiY291bnRcImAsIGBcIm1lYW5cImAgYW5kIGBcIm1lZGlhblwiYCkuXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgcmVxdWlyZWQgaW4gY2FzZXMgd2hlcmUgdGhlIHNvcnQgZmllbGQgYW5kIHRoZSBkYXRhIHJlZmVyZW5jZSBmaWVsZCBkbyBub3QgbWF0Y2guXG4gICAqIFRoZSBpbnB1dCBkYXRhIG9iamVjdHMgd2lsbCBiZSBhZ2dyZWdhdGVkLCBncm91cGVkIGJ5IHRoZSBlbmNvZGVkIGRhdGEgZmllbGQuXG4gICAqXG4gICAqIEZvciBhIGZ1bGwgbGlzdCBvZiBvcGVyYXRpb25zLCBwbGVhc2Ugc2VlIHRoZSBkb2N1bWVudGF0aW9uIGZvciBbYWdncmVnYXRlXShhZ2dyZWdhdGUuaHRtbCNvcHMpLlxuICAgKi9cbiAgb3A6IEFnZ3JlZ2F0ZU9wO1xuXG4gIC8qKlxuICAgKiBUaGUgc29ydCBvcmRlci4gT25lIG9mIGBcImFzY2VuZGluZ1wiYCAoZGVmYXVsdCkgb3IgYFwiZGVzY2VuZGluZ1wiYC5cbiAgICovXG4gIG9yZGVyPzogU29ydE9yZGVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTb3J0RmllbGQ8Rj4oc29ydDogU29ydE9yZGVyIHwgU29ydEZpZWxkPEY+KTogc29ydCBpcyBTb3J0RmllbGQ8Rj4ge1xuICByZXR1cm4gISFzb3J0ICYmIChzb3J0WydvcCddID09PSAnY291bnQnIHx8ICEhc29ydFsnZmllbGQnXSkgJiYgISFzb3J0WydvcCddO1xufVxuIl19 \ 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..f373682c6c --- /dev/null +++ b/build/src/spec.d.ts @@ -0,0 +1,177 @@ +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 { Repeat } from './repeat'; +import { Resolve } from './resolve'; +import { SelectionDef } from './selection'; +import { TitleParams } from './title'; +import { 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 interface BaseSpec { + /** + * 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 interface LayoutSizeMixins { + /** + * The width of a visualization. + * + * __Default value:__ This will be determined by the following rules: + * + * - If a view's [`autosize`](size.html#autosize) type is `"fit"` or its x-channel has a [continuous scale](scale.html#continuous), the width will be the value of [`config.view.width`](spec.html#config). + * - For x-axis with a band or point scale: if [`rangeStep`](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](scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](spec.html#config). + * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](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](encoding.html#facet), this represents the width of a single view. + * + * __See also:__ The documentation for [width and height](size.html) contains more examples. + */ + width?: number; + /** + * The height of a visualization. + * + * __Default value:__ + * - If a view's [`autosize`](size.html#autosize) type is `"fit"` or its y-channel has a [continuous scale](scale.html#continuous), the height will be the value of [`config.view.height`](spec.html#config). + * - For y-axis with a band or point scale: if [`rangeStep`](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](scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](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](encoding.html#facet), this represents the height of a single view. + * + * __See also:__ The documentation for [width and height](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"`, and `"text"`) or a [mark definition object](mark.html#mark-def). + */ + mark: M; + /** + * A key-value mapping between encoding channels and definition of fields. + */ + encoding: E; + /** + * A key-value mapping between selection names and definitions. + */ + selection?: { + [name: string]: SelectionDef; + }; +} +export declare type UnitSpec = 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; +} +export declare type LayerSpec = GenericLayerSpec; +export interface GenericFacetSpec> extends BaseSpec { + /** + * 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: GenericLayerSpec | U; + /** + * Scale, axis, and legend resolutions for facets. + */ + resolve?: Resolve; +} +export declare type FacetSpec = GenericFacetSpec; +export interface GenericRepeatSpec> extends BaseSpec { + /** + * 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 RepeatSpec = GenericRepeatSpec; +export interface GenericVConcatSpec> extends BaseSpec { + /** + * 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> extends BaseSpec { + /** + * 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 ConcatSpec = GenericVConcatSpec | GenericHConcatSpec; +export declare type GenericSpec> = U | GenericLayerSpec | GenericFacetSpec | GenericRepeatSpec | GenericVConcatSpec | GenericHConcatSpec; +export declare type Spec = GenericSpec; +export declare type TopLevelExtendedSpec = TopLevel | TopLevel> | TopLevel> | TopLevel> | TopLevel> | TopLevel>; +export declare function isFacetSpec(spec: GenericSpec>): spec is GenericFacetSpec>; +export declare function isUnitSpec(spec: GenericSpec>): spec is FacetedCompositeUnitSpec | UnitSpec; +export declare function isLayerSpec(spec: GenericSpec>): spec is GenericLayerSpec>; +export declare function isRepeatSpec(spec: GenericSpec>): spec is GenericRepeatSpec>; +export declare function isConcatSpec(spec: GenericSpec>): spec is GenericVConcatSpec> | GenericHConcatSpec>; +export declare function isVConcatSpec(spec: GenericSpec>): spec is GenericVConcatSpec>; +export declare function isHConcatSpec(spec: GenericSpec>): spec is GenericHConcatSpec>; +/** + * Decompose extended unit specs into composition of pure unit specs. + */ +export declare function normalize(spec: TopLevelExtendedSpec, config: Config): Spec; +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..1c58f5e997 --- /dev/null +++ b/build/src/spec.js @@ -0,0 +1,247 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var compositeMark = require("./compositemark"); +var encoding_1 = require("./encoding"); +var vlEncoding = require("./encoding"); +var log = require("./log"); +var mark_1 = require("./mark"); +var stack_1 = require("./stack"); +var util_1 = require("./util"); +/* Custom type guards */ +function isFacetSpec(spec) { + return spec['facet'] !== undefined; +} +exports.isFacetSpec = isFacetSpec; +function isUnitSpec(spec) { + return !!spec['mark']; +} +exports.isUnitSpec = isUnitSpec; +function isLayerSpec(spec) { + return spec['layer'] !== undefined; +} +exports.isLayerSpec = isLayerSpec; +function isRepeatSpec(spec) { + return spec['repeat'] !== undefined; +} +exports.isRepeatSpec = isRepeatSpec; +function isConcatSpec(spec) { + return isVConcatSpec(spec) || isHConcatSpec(spec); +} +exports.isConcatSpec = isConcatSpec; +function isVConcatSpec(spec) { + return spec['vconcat'] !== undefined; +} +exports.isVConcatSpec = isVConcatSpec; +function isHConcatSpec(spec) { + return spec['hconcat'] !== undefined; +} +exports.isHConcatSpec = isHConcatSpec; +/** + * 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(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 = encoding_1.channelHasField(spec.encoding, channel_1.ROW); + var hasColumn = encoding_1.channelHasField(spec.encoding, channel_1.COLUMN); + if (hasRow || hasColumn) { + return normalizeFacetedUnit(spec, config); + } + return normalizeNonFacetUnit(spec, config); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.normalize = normalize; +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(subspec, config) }); +} +function normalizeLayer(spec, config) { + var layer = spec.layer, rest = __rest(spec, ["layer"]); + return __assign({}, rest, { layer: layer.map(function (subspec) { return isLayerSpec(subspec) ? normalizeLayer(subspec, config) : normalizeNonFacetUnit(subspec, config); }) }); +} +function normalizeRepeat(spec, config) { + var subspec = spec.spec, rest = __rest(spec, ["spec"]); + return __assign({}, rest, { spec: normalize(subspec, config) }); +} +function normalizeVConcat(spec, config) { + var vconcat = spec.vconcat, rest = __rest(spec, ["vconcat"]); + return __assign({}, rest, { vconcat: vconcat.map(function (subspec) { return normalize(subspec, config); }) }); +} +function normalizeHConcat(spec, config) { + var hconcat = spec.hconcat, rest = __rest(spec, ["hconcat"]); + return __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 = __rest(_a, ["row", "column"]); + // Mark and encoding should be moved into the inner spec + var mark = spec.mark, width = spec.width, height = spec.height, selection = spec.selection, _ = spec.encoding, outerSpec = __rest(spec, ["mark", "width", "height", "selection", "encoding"]); + return __assign({}, outerSpec, { facet: __assign({}, (row ? { row: row } : {}), (column ? { column: column } : {})), spec: normalizeNonFacetUnit(__assign({ mark: mark }, (width ? { width: width } : {}), (height ? { height: height } : {}), { encoding: encoding }, (selection ? { selection: selection } : {})), config) }); +} +function isNonFacetUnitSpecWithPrimitiveMark(spec) { + return mark_1.isPrimitiveMark(spec.mark); +} +function normalizeNonFacetUnit(spec, config) { + if (isNonFacetUnitSpecWithPrimitiveMark(spec)) { + // TODO: thoroughly test + if (encoding_1.isRanged(spec.encoding)) { + return normalizeRangedUnit(spec); + } + var overlayConfig = config && config.overlay; + var overlayWithLine = overlayConfig && spec.mark === mark_1.AREA && + util_1.contains(['linepoint', 'line'], overlayConfig.area); + var overlayWithPoint = overlayConfig && ((overlayConfig.line && spec.mark === mark_1.LINE) || + (overlayConfig.area === 'linepoint' && spec.mark === mark_1.AREA)); + // TODO: consider moving this to become another case of compositeMark + if (overlayWithPoint || overlayWithLine) { + return normalizeOverlay(spec, overlayWithPoint, overlayWithLine, config); + } + return spec; // Nothing to normalize + } + else { + return compositeMark.normalize(spec, config); + } +} +function normalizeRangedUnit(spec) { + var hasX = encoding_1.channelHasField(spec.encoding, channel_1.X); + var hasY = encoding_1.channelHasField(spec.encoding, channel_1.Y); + var hasX2 = encoding_1.channelHasField(spec.encoding, channel_1.X2); + var hasY2 = encoding_1.channelHasField(spec.encoding, channel_1.Y2); + if ((hasX2 && !hasX) || (hasY2 && !hasY)) { + var normalizedSpec = util_1.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; +} +// FIXME(#1804): re-design this +function normalizeOverlay(spec, overlayWithPoint, overlayWithLine, config) { + var mark = spec.mark, selection = spec.selection, encoding = spec.encoding, outerSpec = __rest(spec, ["mark", "selection", "encoding"]); + var layer = [{ mark: mark, encoding: encoding }]; + // Need to copy stack config to overlayed layer + var stackProps = stack_1.stack(mark, 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 (overlayWithLine) { + layer.push(__assign({ mark: { + type: 'line', + style: 'lineOverlay' + } }, (selection ? { selection: selection } : {}), { encoding: overlayEncoding })); + } + if (overlayWithPoint) { + layer.push(__assign({ mark: { + type: 'point', + filled: true, + style: 'pointOverlay' + } }, (selection ? { selection: selection } : {}), { encoding: overlayEncoding })); + } + return __assign({}, outerSpec, { layer: layer }); + var _a; +} +// TODO: add vl.spec.validate & move stuff from vl.validate to here +/* Accumulate non-duplicate fieldDefs in a dictionary */ +function accumulate(dict, fieldDefs) { + fieldDefs.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 = util_1.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 { + accumulate(dict, vlEncoding.fieldDefs(spec.encoding)); + } + return dict; +} +/* Returns all non-duplicate fieldDefs in a spec in a flat array */ +function fieldDefs(spec) { + return util_1.vals(fieldDefIndex(spec)); +} +exports.fieldDefs = fieldDefs; +function isStacked(spec, config) { + config = config || spec.config; + if (mark_1.isPrimitiveMark(spec.mark)) { + return stack_1.stack(spec.mark, spec.encoding, config ? config.stack : undefined) !== null; + } + return false; +} +exports.isStacked = isStacked; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBb0Q7QUFDcEQsK0NBQWlEO0FBR2pELHVDQUFrRjtBQUNsRix1Q0FBeUM7QUFHekMsMkJBQTZCO0FBQzdCLCtCQUEyRTtBQUkzRSxpQ0FBOEI7QUFJOUIsK0JBQTZEO0FBOEw3RCx3QkFBd0I7QUFHeEIscUJBQTRCLElBQTRDO0lBQ3RFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssU0FBUyxDQUFDO0FBQ3JDLENBQUM7QUFGRCxrQ0FFQztBQUVELG9CQUEyQixJQUE0QztJQUNyRSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN4QixDQUFDO0FBRkQsZ0NBRUM7QUFFRCxxQkFBNEIsSUFBNEM7SUFDdEUsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDckMsQ0FBQztBQUZELGtDQUVDO0FBRUQsc0JBQTZCLElBQTRDO0lBQ3ZFLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssU0FBUyxDQUFDO0FBQ3RDLENBQUM7QUFGRCxvQ0FFQztBQUVELHNCQUE2QixJQUE0QztJQUN2RSxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNwRCxDQUFDO0FBRkQsb0NBRUM7QUFFRCx1QkFBOEIsSUFBNEM7SUFDeEUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDdkMsQ0FBQztBQUZELHNDQUVDO0FBRUQsdUJBQThCLElBQTRDO0lBQ3hFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssU0FBUyxDQUFDO0FBQ3ZDLENBQUM7QUFGRCxzQ0FFQztBQUVEOztHQUVH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QUksQ0FBQyxPQUFPLENBQUM7UUFDcEUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxVQUFBLEtBQUssSUFBSSxPQUFBLGFBQWEsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQTFCLENBQTBCLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixVQUFVLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsbUVBQW1FO0FBQ25FLG1CQUEwQixJQUE0QztJQUNwRSxNQUFNLENBQUMsV0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFGRCw4QkFFQztBQUVELG1CQUEwQixJQUF3QyxFQUFFLE1BQWU7SUFDakYsTUFBTSxHQUFHLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQy9CLEVBQUUsQ0FBQyxDQUFDLHNCQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixNQUFNLENBQUMsYUFBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQ2xDLEtBQUssSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQVJELDhCQVFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDT0xVTU4sIFJPVywgWCwgWDIsIFksIFkyfSBmcm9tICcuL2NoYW5uZWwnO1xuaW1wb3J0ICogYXMgY29tcG9zaXRlTWFyayBmcm9tICcuL2NvbXBvc2l0ZW1hcmsnO1xuaW1wb3J0IHtDb25maWcsIE92ZXJsYXlDb25maWd9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7RGF0YX0gZnJvbSAnLi9kYXRhJztcbmltcG9ydCB7Y2hhbm5lbEhhc0ZpZWxkLCBFbmNvZGluZywgRW5jb2RpbmdXaXRoRmFjZXQsIGlzUmFuZ2VkfSBmcm9tICcuL2VuY29kaW5nJztcbmltcG9ydCAqIGFzIHZsRW5jb2RpbmcgZnJvbSAnLi9lbmNvZGluZyc7XG5pbXBvcnQge0ZhY2V0TWFwcGluZ30gZnJvbSAnLi9mYWNldCc7XG5pbXBvcnQge0ZpZWxkLCBGaWVsZERlZiwgUmVwZWF0UmVmfSBmcm9tICcuL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQge0FueU1hcmssIEFSRUEsIGlzUHJpbWl0aXZlTWFyaywgTElORSwgTWFyaywgTWFya0RlZn0gZnJvbSAnLi9tYXJrJztcbmltcG9ydCB7UmVwZWF0fSBmcm9tICcuL3JlcGVhdCc7XG5pbXBvcnQge1Jlc29sdmV9IGZyb20gJy4vcmVzb2x2ZSc7XG5pbXBvcnQge1NlbGVjdGlvbkRlZn0gZnJvbSAnLi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtzdGFja30gZnJvbSAnLi9zdGFjayc7XG5pbXBvcnQge1RpdGxlUGFyYW1zfSBmcm9tICcuL3RpdGxlJztcbmltcG9ydCB7VG9wTGV2ZWxQcm9wZXJ0aWVzfSBmcm9tICcuL3RvcGxldmVscHJvcHMnO1xuaW1wb3J0IHtUcmFuc2Zvcm19IGZyb20gJy4vdHJhbnNmb3JtJztcbmltcG9ydCB7Y29udGFpbnMsIERpY3QsIGR1cGxpY2F0ZSwgaGFzaCwgdmFsc30gZnJvbSAnLi91dGlsJztcblxuXG5leHBvcnQgdHlwZSBUb3BMZXZlbDxTIGV4dGVuZHMgQmFzZVNwZWM+ID0gUyAmIFRvcExldmVsUHJvcGVydGllcyAmIHtcbiAgLyoqXG4gICAqIFVSTCB0byBbSlNPTiBzY2hlbWFdKGh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvKSBmb3IgYSBWZWdhLUxpdGUgc3BlY2lmaWNhdGlvbi4gVW5sZXNzIHlvdSBoYXZlIGEgcmVhc29uIHRvIGNoYW5nZSB0aGlzLCB1c2UgYGh0dHBzOi8vdmVnYS5naXRodWIuaW8vc2NoZW1hL3ZlZ2EtbGl0ZS92Mi5qc29uYC4gU2V0dGluZyB0aGUgYCRzY2hlbWFgIHByb3BlcnR5IGFsbG93cyBhdXRvbWF0aWMgdmFsaWRhdGlvbiBhbmQgYXV0b2NvbXBsZXRlIGluIGVkaXRvcnMgdGhhdCBzdXBwb3J0IEpTT04gc2NoZW1hLlxuICAgKiBAZm9ybWF0IHVyaVxuICAgKi9cbiAgJHNjaGVtYT86IHN0cmluZztcblxuICAvKipcbiAgICogVmVnYS1MaXRlIGNvbmZpZ3VyYXRpb24gb2JqZWN0LiAgVGhpcyBwcm9wZXJ0eSBjYW4gb25seSBiZSBkZWZpbmVkIGF0IHRoZSB0b3AtbGV2ZWwgb2YgYSBzcGVjaWZpY2F0aW9uLlxuICAgKi9cbiAgY29uZmlnPzogQ29uZmlnO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBCYXNlU3BlYyB7XG4gIC8qKlxuICAgKiBUaXRsZSBmb3IgdGhlIHBsb3QuXG4gICAqL1xuICB0aXRsZT86IHN0cmluZyB8IFRpdGxlUGFyYW1zO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSB2aXN1YWxpemF0aW9uIGZvciBsYXRlciByZWZlcmVuY2UuXG4gICAqL1xuICBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZXNjcmlwdGlvbiBvZiB0aGlzIG1hcmsgZm9yIGNvbW1lbnRpbmcgcHVycG9zZS5cbiAgICovXG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBbiBvYmplY3QgZGVzY3JpYmluZyB0aGUgZGF0YSBzb3VyY2VcbiAgICovXG4gIGRhdGE/OiBEYXRhO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBkYXRhIHRyYW5zZm9ybWF0aW9ucyBzdWNoIGFzIGZpbHRlciBhbmQgbmV3IGZpZWxkIGNhbGN1bGF0aW9uLlxuICAgKi9cbiAgdHJhbnNmb3JtPzogVHJhbnNmb3JtW107XG59XG5cbi8vIFRPRE8oaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yNTAzKTogTWFrZSB0aGlzIGdlbmVyaWMgc28gd2UgY2FuIHN1cHBvcnQgc29tZSBmb3JtIG9mIHRvcC1kb3duIHNpemluZy5cbmV4cG9ydCBpbnRlcmZhY2UgTGF5b3V0U2l6ZU1peGlucyB7XG4gIC8qKlxuICAgKiBUaGUgd2lkdGggb2YgYSB2aXN1YWxpemF0aW9uLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gVGhpcyB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIGZvbGxvd2luZyBydWxlczpcbiAgICpcbiAgICogLSBJZiBhIHZpZXcncyBbYGF1dG9zaXplYF0oc2l6ZS5odG1sI2F1dG9zaXplKSB0eXBlIGlzIGBcImZpdFwiYCBvciBpdHMgeC1jaGFubmVsIGhhcyBhIFtjb250aW51b3VzIHNjYWxlXShzY2FsZS5odG1sI2NvbnRpbnVvdXMpLCB0aGUgd2lkdGggd2lsbCBiZSB0aGUgdmFsdWUgb2YgW2Bjb25maWcudmlldy53aWR0aGBdKHNwZWMuaHRtbCNjb25maWcpLlxuICAgKiAtIEZvciB4LWF4aXMgd2l0aCBhIGJhbmQgb3IgcG9pbnQgc2NhbGU6IGlmIFtgcmFuZ2VTdGVwYF0oc2NhbGUuaHRtbCNiYW5kKSBpcyBhIG51bWVyaWMgdmFsdWUgb3IgdW5zcGVjaWZpZWQsIHRoZSB3aWR0aCBpcyBbZGV0ZXJtaW5lZCBieSB0aGUgcmFuZ2Ugc3RlcCwgcGFkZGluZ3MsIGFuZCB0aGUgY2FyZGluYWxpdHkgb2YgdGhlIGZpZWxkIG1hcHBlZCB0byB4LWNoYW5uZWxdKHNjYWxlLmh0bWwjYmFuZCkuICAgT3RoZXJ3aXNlLCBpZiB0aGUgYHJhbmdlU3RlcGAgaXMgYG51bGxgLCB0aGUgd2lkdGggd2lsbCBiZSB0aGUgdmFsdWUgb2YgW2Bjb25maWcudmlldy53aWR0aGBdKHNwZWMuaHRtbCNjb25maWcpLlxuICAgKiAtIElmIG5vIGZpZWxkIGlzIG1hcHBlZCB0byBgeGAgY2hhbm5lbCwgdGhlIGB3aWR0aGAgd2lsbCBiZSB0aGUgdmFsdWUgb2YgW2Bjb25maWcuc2NhbGUudGV4dFhSYW5nZVN0ZXBgXShzaXplLmh0bWwjZGVmYXVsdC13aWR0aC1hbmQtaGVpZ2h0KSBmb3IgYHRleHRgIG1hcmsgYW5kIHRoZSB2YWx1ZSBvZiBgcmFuZ2VTdGVwYCBmb3Igb3RoZXIgbWFya3MuXG4gICAqXG4gICAqIF9fTm90ZTpfXyBGb3IgcGxvdHMgd2l0aCBbYHJvd2AgYW5kIGBjb2x1bW5gIGNoYW5uZWxzXShlbmNvZGluZy5odG1sI2ZhY2V0KSwgdGhpcyByZXByZXNlbnRzIHRoZSB3aWR0aCBvZiBhIHNpbmdsZSB2aWV3LlxuICAgKlxuICAgKiBfX1NlZSBhbHNvOl9fIFRoZSBkb2N1bWVudGF0aW9uIGZvciBbd2lkdGggYW5kIGhlaWdodF0oc2l6ZS5odG1sKSBjb250YWlucyBtb3JlIGV4YW1wbGVzLlxuICAgKi9cbiAgd2lkdGg/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBoZWlnaHQgb2YgYSB2aXN1YWxpemF0aW9uLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X19cbiAgICogLSBJZiBhIHZpZXcncyBbYGF1dG9zaXplYF0oc2l6ZS5odG1sI2F1dG9zaXplKSB0eXBlIGlzIGBcImZpdFwiYCBvciBpdHMgeS1jaGFubmVsIGhhcyBhIFtjb250aW51b3VzIHNjYWxlXShzY2FsZS5odG1sI2NvbnRpbnVvdXMpLCB0aGUgaGVpZ2h0IHdpbGwgYmUgdGhlIHZhbHVlIG9mIFtgY29uZmlnLnZpZXcuaGVpZ2h0YF0oc3BlYy5odG1sI2NvbmZpZykuXG4gICAqIC0gRm9yIHktYXhpcyB3aXRoIGEgYmFuZCBvciBwb2ludCBzY2FsZTogaWYgW2ByYW5nZVN0ZXBgXShzY2FsZS5odG1sI2JhbmQpIGlzIGEgbnVtZXJpYyB2YWx1ZSBvciB1bnNwZWNpZmllZCwgdGhlIGhlaWdodCBpcyBbZGV0ZXJtaW5lZCBieSB0aGUgcmFuZ2Ugc3RlcCwgcGFkZGluZ3MsIGFuZCB0aGUgY2FyZGluYWxpdHkgb2YgdGhlIGZpZWxkIG1hcHBlZCB0byB5LWNoYW5uZWxdKHNjYWxlLmh0bWwjYmFuZCkuIE90aGVyd2lzZSwgaWYgdGhlIGByYW5nZVN0ZXBgIGlzIGBudWxsYCwgdGhlIGhlaWdodCB3aWxsIGJlIHRoZSB2YWx1ZSBvZiBbYGNvbmZpZy52aWV3LmhlaWdodGBdKHNwZWMuaHRtbCNjb25maWcpLlxuICAgKiAtIElmIG5vIGZpZWxkIGlzIG1hcHBlZCB0byBgeWAgY2hhbm5lbCwgdGhlIGBoZWlnaHRgIHdpbGwgYmUgdGhlIHZhbHVlIG9mIGByYW5nZVN0ZXBgLlxuICAgKlxuICAgKiBfX05vdGVfXzogRm9yIHBsb3RzIHdpdGggW2Byb3dgIGFuZCBgY29sdW1uYCBjaGFubmVsc10oZW5jb2RpbmcuaHRtbCNmYWNldCksIHRoaXMgcmVwcmVzZW50cyB0aGUgaGVpZ2h0IG9mIGEgc2luZ2xlIHZpZXcuXG4gICAqXG4gICAqIF9fU2VlIGFsc286X18gVGhlIGRvY3VtZW50YXRpb24gZm9yIFt3aWR0aCBhbmQgaGVpZ2h0XShzaXplLmh0bWwpIGNvbnRhaW5zIG1vcmUgZXhhbXBsZXMuXG4gICAqL1xuICBoZWlnaHQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VuZXJpY1VuaXRTcGVjPEUgZXh0ZW5kcyBFbmNvZGluZzxhbnk+LCBNPiBleHRlbmRzIEJhc2VTcGVjLCBMYXlvdXRTaXplTWl4aW5zIHtcblxuICAvKipcbiAgICogQSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgbWFyayB0eXBlIChvbmUgb2YgYFwiYmFyXCJgLCBgXCJjaXJjbGVcImAsIGBcInNxdWFyZVwiYCwgYFwidGlja1wiYCwgYFwibGluZVwiYCxcbiAgICogYFwiYXJlYVwiYCwgYFwicG9pbnRcImAsIGBcInJ1bGVcImAsIGFuZCBgXCJ0ZXh0XCJgKSBvciBhIFttYXJrIGRlZmluaXRpb24gb2JqZWN0XShtYXJrLmh0bWwjbWFyay1kZWYpLlxuICAgKi9cbiAgbWFyazogTTtcblxuICAvKipcbiAgICogQSBrZXktdmFsdWUgbWFwcGluZyBiZXR3ZWVuIGVuY29kaW5nIGNoYW5uZWxzIGFuZCBkZWZpbml0aW9uIG9mIGZpZWxkcy5cbiAgICovXG4gIGVuY29kaW5nOiBFO1xuXG4gIC8qKlxuICAgKiBBIGtleS12YWx1ZSBtYXBwaW5nIGJldHdlZW4gc2VsZWN0aW9uIG5hbWVzIGFuZCBkZWZpbml0aW9ucy5cbiAgICovXG4gIHNlbGVjdGlvbj86IHtbbmFtZTogc3RyaW5nXTogU2VsZWN0aW9uRGVmfTtcbn1cblxuZXhwb3J0IHR5cGUgVW5pdFNwZWMgPSBHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8c3RyaW5nIHwgUmVwZWF0UmVmPiwgTWFyayB8IE1hcmtEZWY+O1xuXG4vKipcbiAqIFVuaXQgc3BlYyB0aGF0IGNhbiBoYXZlIGEgY29tcG9zaXRlIG1hcmsuXG4gKi9cbmV4cG9ydCB0eXBlIENvbXBvc2l0ZVVuaXRTcGVjID0gR2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPHN0cmluZyB8IFJlcGVhdFJlZj4sIEFueU1hcms+O1xuXG4vKipcbiAqIFVuaXQgc3BlYyB0aGF0IGNhbiBoYXZlIGEgY29tcG9zaXRlIG1hcmsgYW5kIHJvdyBvciBjb2x1bW4gY2hhbm5lbHMuXG4gKi9cbmV4cG9ydCB0eXBlIEZhY2V0ZWRDb21wb3NpdGVVbml0U3BlYyA9IEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZ1dpdGhGYWNldDxzdHJpbmcgfCBSZXBlYXRSZWY+LCBBbnlNYXJrPjtcblxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmljTGF5ZXJTcGVjPFUgZXh0ZW5kcyBHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+PiBleHRlbmRzIEJhc2VTcGVjLCBMYXlvdXRTaXplTWl4aW5zIHtcbiAgLyoqXG4gICAqIExheWVyIG9yIHNpbmdsZSB2aWV3IHNwZWNpZmljYXRpb25zIHRvIGJlIGxheWVyZWQuXG4gICAqXG4gICAqIF9fTm90ZV9fOiBTcGVjaWZpY2F0aW9ucyBpbnNpZGUgYGxheWVyYCBjYW5ub3QgdXNlIGByb3dgIGFuZCBgY29sdW1uYCBjaGFubmVscyBhcyBsYXllcmluZyBmYWNldCBzcGVjaWZpY2F0aW9ucyBpcyBub3QgYWxsb3dlZC5cbiAgICovXG4gIGxheWVyOiAoR2VuZXJpY0xheWVyU3BlYzxVPiB8IFUpW107XG5cbiAgLyoqXG4gICAqIFNjYWxlLCBheGlzLCBhbmQgbGVnZW5kIHJlc29sdXRpb25zIGZvciBsYXllcnMuXG4gICAqL1xuICByZXNvbHZlPzogUmVzb2x2ZTtcbn1cblxuZXhwb3J0IHR5cGUgTGF5ZXJTcGVjID0gR2VuZXJpY0xheWVyU3BlYzxVbml0U3BlYz47XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VuZXJpY0ZhY2V0U3BlYzxVIGV4dGVuZHMgR2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4gZXh0ZW5kcyBCYXNlU3BlYyB7XG4gIC8qKlxuICAgKiBBbiBvYmplY3QgdGhhdCBkZXNjcmliZXMgbWFwcGluZ3MgYmV0d2VlbiBgcm93YCBhbmQgYGNvbHVtbmAgY2hhbm5lbHMgYW5kIHRoZWlyIGZpZWxkIGRlZmluaXRpb25zLlxuICAgKi9cbiAgZmFjZXQ6IEZhY2V0TWFwcGluZzxzdHJpbmcgfCBSZXBlYXRSZWY+O1xuXG4gIC8qKlxuICAgKiBBIHNwZWNpZmljYXRpb24gb2YgdGhlIHZpZXcgdGhhdCBnZXRzIGZhY2V0ZWQuXG4gICAqL1xuICBzcGVjOiBHZW5lcmljTGF5ZXJTcGVjPFU+IHwgVTtcbiAgLy8gVE9ETzogcmVwbGFjZSB0aGlzIHdpdGggR2VuZXJpY1NwZWM8VT4gb25jZSB3ZSBzdXBwb3J0IGFsbCBjYXNlcztcblxuICAvKipcbiAgICogU2NhbGUsIGF4aXMsIGFuZCBsZWdlbmQgcmVzb2x1dGlvbnMgZm9yIGZhY2V0cy5cbiAgICovXG4gIHJlc29sdmU/OiBSZXNvbHZlO1xufVxuXG5leHBvcnQgdHlwZSBGYWNldFNwZWMgPSBHZW5lcmljRmFjZXRTcGVjPFVuaXRTcGVjPjtcblxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmljUmVwZWF0U3BlYzxVIGV4dGVuZHMgR2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4gZXh0ZW5kcyBCYXNlU3BlYyB7XG4gIC8qKlxuICAgKiBBbiBvYmplY3QgdGhhdCBkZXNjcmliZXMgd2hhdCBmaWVsZHMgc2hvdWxkIGJlIHJlcGVhdGVkIGludG8gdmlld3MgdGhhdCBhcmUgbGFpZCBvdXQgYXMgYSBgcm93YCBvciBgY29sdW1uYC5cbiAgICovXG4gIHJlcGVhdDogUmVwZWF0O1xuXG4gIHNwZWM6IEdlbmVyaWNTcGVjPFU+O1xuXG4gIC8qKlxuICAgKiBTY2FsZSBhbmQgbGVnZW5kIHJlc29sdXRpb25zIGZvciByZXBlYXRlZCBjaGFydHMuXG4gICAqL1xuICByZXNvbHZlPzogUmVzb2x2ZTtcbn1cblxuZXhwb3J0IHR5cGUgUmVwZWF0U3BlYyA9IEdlbmVyaWNSZXBlYXRTcGVjPFVuaXRTcGVjPjtcblxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmljVkNvbmNhdFNwZWM8VSBleHRlbmRzIEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+IGV4dGVuZHMgQmFzZVNwZWMge1xuICAvKipcbiAgICogQSBsaXN0IG9mIHZpZXdzIHRoYXQgc2hvdWxkIGJlIGNvbmNhdGVuYXRlZCBhbmQgcHV0IGludG8gYSBjb2x1bW4uXG4gICAqL1xuICB2Y29uY2F0OiAoR2VuZXJpY1NwZWM8VT4pW107XG5cbiAgLyoqXG4gICAqIFNjYWxlLCBheGlzLCBhbmQgbGVnZW5kIHJlc29sdXRpb25zIGZvciB2ZXJ0aWNhbGx5IGNvbmNhdGVuYXRlZCBjaGFydHMuXG4gICAqL1xuICByZXNvbHZlPzogUmVzb2x2ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmljSENvbmNhdFNwZWM8VSBleHRlbmRzIEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+IGV4dGVuZHMgQmFzZVNwZWMge1xuICAvKipcbiAgICogQSBsaXN0IG9mIHZpZXdzIHRoYXQgc2hvdWxkIGJlIGNvbmNhdGVuYXRlZCBhbmQgcHV0IGludG8gYSByb3cuXG4gICAqL1xuICBoY29uY2F0OiAoR2VuZXJpY1NwZWM8VT4pW107XG5cbiAgLyoqXG4gICAqIFNjYWxlLCBheGlzLCBhbmQgbGVnZW5kIHJlc29sdXRpb25zIGZvciBob3Jpem9udGFsbHkgY29uY2F0ZW5hdGVkIGNoYXJ0cy5cbiAgICovXG4gIHJlc29sdmU/OiBSZXNvbHZlO1xufVxuXG5leHBvcnQgdHlwZSBDb25jYXRTcGVjID0gR2VuZXJpY1ZDb25jYXRTcGVjPFVuaXRTcGVjPiB8IEdlbmVyaWNIQ29uY2F0U3BlYzxVbml0U3BlYz47XG5cbmV4cG9ydCB0eXBlIEdlbmVyaWNTcGVjPFUgZXh0ZW5kcyBHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+PiA9IFUgfCBHZW5lcmljTGF5ZXJTcGVjPFU+IHwgR2VuZXJpY0ZhY2V0U3BlYzxVPiB8IEdlbmVyaWNSZXBlYXRTcGVjPFU+IHwgR2VuZXJpY1ZDb25jYXRTcGVjPFU+IHwgR2VuZXJpY0hDb25jYXRTcGVjPFU+O1xuXG5leHBvcnQgdHlwZSBTcGVjID0gR2VuZXJpY1NwZWM8VW5pdFNwZWM+O1xuXG5leHBvcnQgdHlwZSBUb3BMZXZlbEV4dGVuZGVkU3BlYyA9IFRvcExldmVsPEZhY2V0ZWRDb21wb3NpdGVVbml0U3BlYz4gfCBUb3BMZXZlbDxHZW5lcmljTGF5ZXJTcGVjPENvbXBvc2l0ZVVuaXRTcGVjPj4gfCBUb3BMZXZlbDxHZW5lcmljRmFjZXRTcGVjPENvbXBvc2l0ZVVuaXRTcGVjPj4gfCBUb3BMZXZlbDxHZW5lcmljUmVwZWF0U3BlYzxDb21wb3NpdGVVbml0U3BlYz4+IHwgVG9wTGV2ZWw8R2VuZXJpY1ZDb25jYXRTcGVjPENvbXBvc2l0ZVVuaXRTcGVjPj4gfCBUb3BMZXZlbDxHZW5lcmljSENvbmNhdFNwZWM8Q29tcG9zaXRlVW5pdFNwZWM+PjtcblxuLyogQ3VzdG9tIHR5cGUgZ3VhcmRzICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRmFjZXRTcGVjKHNwZWM6IEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+KTogc3BlYyBpcyBHZW5lcmljRmFjZXRTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+IHtcbiAgcmV0dXJuIHNwZWNbJ2ZhY2V0J10gIT09IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVW5pdFNwZWMoc3BlYzogR2VuZXJpY1NwZWM8R2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4pOiBzcGVjIGlzIEZhY2V0ZWRDb21wb3NpdGVVbml0U3BlYyB8IFVuaXRTcGVjIHtcbiAgcmV0dXJuICEhc3BlY1snbWFyayddO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNMYXllclNwZWMoc3BlYzogR2VuZXJpY1NwZWM8R2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4pOiBzcGVjIGlzIEdlbmVyaWNMYXllclNwZWM8R2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4ge1xuICByZXR1cm4gc3BlY1snbGF5ZXInXSAhPT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXBlYXRTcGVjKHNwZWM6IEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+KTogc3BlYyBpcyBHZW5lcmljUmVwZWF0U3BlYzxHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+PiB7XG4gIHJldHVybiBzcGVjWydyZXBlYXQnXSAhPT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNDb25jYXRTcGVjKHNwZWM6IEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+KTogc3BlYyBpcyBHZW5lcmljVkNvbmNhdFNwZWM8R2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4gfCBHZW5lcmljSENvbmNhdFNwZWM8R2VuZXJpY1VuaXRTcGVjPGFueSwgYW55Pj4ge1xuICByZXR1cm4gaXNWQ29uY2F0U3BlYyhzcGVjKSB8fCBpc0hDb25jYXRTcGVjKHNwZWMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWQ29uY2F0U3BlYyhzcGVjOiBHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+Pik6IHNwZWMgaXMgR2VuZXJpY1ZDb25jYXRTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+IHtcbiAgcmV0dXJuIHNwZWNbJ3Zjb25jYXQnXSAhPT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNIQ29uY2F0U3BlYyhzcGVjOiBHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+Pik6IHNwZWMgaXMgR2VuZXJpY0hDb25jYXRTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+IHtcbiAgcmV0dXJuIHNwZWNbJ2hjb25jYXQnXSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIERlY29tcG9zZSBleHRlbmRlZCB1bml0IHNwZWNzIGludG8gY29tcG9zaXRpb24gb2YgcHVyZSB1bml0IHNwZWNzLlxuICovXG4vLyBUT0RPOiBjb25zaWRlciBtb3ZpbmcgdGhpcyB0byBhbm90aGVyIGZpbGUuICBNYXliZSB2bC5zcGVjLm5vcm1hbGl6ZSBvciB2bC5ub3JtYWxpemVcbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUoc3BlYzogVG9wTGV2ZWxFeHRlbmRlZFNwZWMsIGNvbmZpZzogQ29uZmlnKTogU3BlYyB7XG4gIGlmIChpc0ZhY2V0U3BlYyhzcGVjKSkge1xuICAgIHJldHVybiBub3JtYWxpemVGYWNldChzcGVjLCBjb25maWcpO1xuICB9XG4gIGlmIChpc0xheWVyU3BlYyhzcGVjKSkge1xuICAgIHJldHVybiBub3JtYWxpemVMYXllcihzcGVjLCBjb25maWcpO1xuICB9XG4gIGlmIChpc1JlcGVhdFNwZWMoc3BlYykpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplUmVwZWF0KHNwZWMsIGNvbmZpZyk7XG4gIH1cbiAgaWYgKGlzVkNvbmNhdFNwZWMoc3BlYykpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplVkNvbmNhdChzcGVjLCBjb25maWcpO1xuICB9XG4gIGlmIChpc0hDb25jYXRTcGVjKHNwZWMpKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUhDb25jYXQoc3BlYywgY29uZmlnKTtcbiAgfVxuICBpZiAoaXNVbml0U3BlYyhzcGVjKSkge1xuICAgIGNvbnN0IGhhc1JvdyA9IGNoYW5uZWxIYXNGaWVsZChzcGVjLmVuY29kaW5nLCBST1cpO1xuICAgIGNvbnN0IGhhc0NvbHVtbiA9IGNoYW5uZWxIYXNGaWVsZChzcGVjLmVuY29kaW5nLCBDT0xVTU4pO1xuXG4gICAgaWYgKGhhc1JvdyB8fCBoYXNDb2x1bW4pIHtcbiAgICAgIHJldHVybiBub3JtYWxpemVGYWNldGVkVW5pdChzcGVjLCBjb25maWcpO1xuICAgIH1cbiAgICByZXR1cm4gbm9ybWFsaXplTm9uRmFjZXRVbml0KHNwZWMsIGNvbmZpZyk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGxvZy5tZXNzYWdlLklOVkFMSURfU1BFQyk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUZhY2V0KHNwZWM6IEdlbmVyaWNGYWNldFNwZWM8Q29tcG9zaXRlVW5pdFNwZWM+LCBjb25maWc6IENvbmZpZyk6IEZhY2V0U3BlYyB7XG4gIGNvbnN0IHtzcGVjOiBzdWJzcGVjLCAuLi5yZXN0fSA9IHNwZWM7XG4gIHJldHVybiB7XG4gICAgLi4ucmVzdCxcbiAgICAvLyBUT0RPOiByZW1vdmUgXCJhbnlcIiBvbmNlIHdlIHN1cHBvcnQgYWxsIGZhY2V0IGxpc3RlZCBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzI3NjBcbiAgICBzcGVjOiBub3JtYWxpemUoc3Vic3BlYywgY29uZmlnKSBhcyBhbnlcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplTGF5ZXIoc3BlYzogR2VuZXJpY0xheWVyU3BlYzxDb21wb3NpdGVVbml0U3BlYz4sIGNvbmZpZzogQ29uZmlnKTogTGF5ZXJTcGVjIHtcbiAgY29uc3Qge2xheWVyOiBsYXllciwgLi4ucmVzdH0gPSBzcGVjO1xuICByZXR1cm4ge1xuICAgIC4uLnJlc3QsXG4gICAgbGF5ZXI6IGxheWVyLm1hcCgoc3Vic3BlYykgPT4gaXNMYXllclNwZWMoc3Vic3BlYykgPyBub3JtYWxpemVMYXllcihzdWJzcGVjLCBjb25maWcpIDogbm9ybWFsaXplTm9uRmFjZXRVbml0KHN1YnNwZWMsIGNvbmZpZykpXG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJlcGVhdChzcGVjOiBHZW5lcmljUmVwZWF0U3BlYzxDb21wb3NpdGVVbml0U3BlYz4sIGNvbmZpZzogQ29uZmlnKTogUmVwZWF0U3BlYyB7XG4gIGNvbnN0IHtzcGVjOiBzdWJzcGVjLCAuLi5yZXN0fSA9IHNwZWM7XG4gIHJldHVybiB7XG4gICAgLi4ucmVzdCxcbiAgICBzcGVjOiBub3JtYWxpemUoc3Vic3BlYywgY29uZmlnKVxuICB9O1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVWQ29uY2F0KHNwZWM6IEdlbmVyaWNWQ29uY2F0U3BlYzxDb21wb3NpdGVVbml0U3BlYz4sIGNvbmZpZzogQ29uZmlnKTogQ29uY2F0U3BlYyB7XG4gIGNvbnN0IHt2Y29uY2F0OiB2Y29uY2F0LCAuLi5yZXN0fSA9IHNwZWM7XG4gIHJldHVybiB7XG4gICAgLi4ucmVzdCxcbiAgICB2Y29uY2F0OiB2Y29uY2F0Lm1hcCgoc3Vic3BlYykgPT4gbm9ybWFsaXplKHN1YnNwZWMsIGNvbmZpZykpXG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUhDb25jYXQoc3BlYzogR2VuZXJpY0hDb25jYXRTcGVjPENvbXBvc2l0ZVVuaXRTcGVjPiwgY29uZmlnOiBDb25maWcpOiBDb25jYXRTcGVjIHtcbiAgY29uc3Qge2hjb25jYXQ6IGhjb25jYXQsIC4uLnJlc3R9ID0gc3BlYztcbiAgcmV0dXJuIHtcbiAgICAuLi5yZXN0LFxuICAgIGhjb25jYXQ6IGhjb25jYXQubWFwKChzdWJzcGVjKSA9PiBub3JtYWxpemUoc3Vic3BlYywgY29uZmlnKSlcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplRmFjZXRlZFVuaXQoc3BlYzogRmFjZXRlZENvbXBvc2l0ZVVuaXRTcGVjLCBjb25maWc6IENvbmZpZyk6IEZhY2V0U3BlYyB7XG4gIC8vIE5ldyBlbmNvZGluZyBpbiB0aGUgaW5zaWRlIHNwZWMgc2hvdWxkIG5vdCBjb250YWluIHJvdyAvIGNvbHVtblxuICAvLyBhcyByb3cvY29sdW1uIHNob3VsZCBiZSBtb3ZlZCB0byBmYWNldFxuICBjb25zdCB7cm93OiByb3csIGNvbHVtbjogY29sdW1uLCAuLi5lbmNvZGluZ30gPSBzcGVjLmVuY29kaW5nO1xuXG4gIC8vIE1hcmsgYW5kIGVuY29kaW5nIHNob3VsZCBiZSBtb3ZlZCBpbnRvIHRoZSBpbm5lciBzcGVjXG4gIGNvbnN0IHttYXJrLCB3aWR0aCwgaGVpZ2h0LCBzZWxlY3Rpb24sIGVuY29kaW5nOiBfLCAuLi5vdXRlclNwZWN9ID0gc3BlYztcblxuICByZXR1cm4ge1xuICAgIC4uLm91dGVyU3BlYyxcbiAgICBmYWNldDoge1xuICAgICAgLi4uKHJvdyA/IHtyb3d9IDoge30pLFxuICAgICAgLi4uKGNvbHVtbiA/IHtjb2x1bW59OiB7fSksXG4gICAgfSxcbiAgICBzcGVjOiBub3JtYWxpemVOb25GYWNldFVuaXQoe1xuICAgICAgbWFyayxcbiAgICAgIC4uLih3aWR0aCA/IHt3aWR0aH0gOiB7fSksXG4gICAgICAuLi4oaGVpZ2h0ID8ge2hlaWdodH0gOiB7fSksXG4gICAgICBlbmNvZGluZyxcbiAgICAgIC4uLihzZWxlY3Rpb24gPyB7c2VsZWN0aW9ufSA6IHt9KVxuICAgIH0sIGNvbmZpZylcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNOb25GYWNldFVuaXRTcGVjV2l0aFByaW1pdGl2ZU1hcmsoc3BlYzogR2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPEZpZWxkPiwgQW55TWFyaz4pOlxuICBzcGVjIGlzIEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIE1hcms+IHtcbiAgICByZXR1cm4gaXNQcmltaXRpdmVNYXJrKHNwZWMubWFyayk7XG59XG5cblxuZnVuY3Rpb24gbm9ybWFsaXplTm9uRmFjZXRVbml0KHNwZWM6IEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIEFueU1hcms+LCBjb25maWc6IENvbmZpZykge1xuICBpZiAoaXNOb25GYWNldFVuaXRTcGVjV2l0aFByaW1pdGl2ZU1hcmsoc3BlYykpIHtcbiAgICAvLyBUT0RPOiB0aG9yb3VnaGx5IHRlc3RcbiAgICBpZiAoaXNSYW5nZWQoc3BlYy5lbmNvZGluZykpIHtcbiAgICAgIHJldHVybiBub3JtYWxpemVSYW5nZWRVbml0KHNwZWMpO1xuICAgIH1cblxuICAgIGNvbnN0IG92ZXJsYXlDb25maWc6IE92ZXJsYXlDb25maWcgPSBjb25maWcgJiYgY29uZmlnLm92ZXJsYXk7XG4gICAgY29uc3Qgb3ZlcmxheVdpdGhMaW5lID0gb3ZlcmxheUNvbmZpZyAmJiBzcGVjLm1hcmsgPT09IEFSRUEgJiZcbiAgICAgIGNvbnRhaW5zKFsnbGluZXBvaW50JywgJ2xpbmUnXSwgb3ZlcmxheUNvbmZpZy5hcmVhKTtcbiAgICBjb25zdCBvdmVybGF5V2l0aFBvaW50ID0gb3ZlcmxheUNvbmZpZyAmJiAoXG4gICAgICAob3ZlcmxheUNvbmZpZy5saW5lICYmIHNwZWMubWFyayA9PT0gTElORSkgfHxcbiAgICAgIChvdmVybGF5Q29uZmlnLmFyZWEgPT09ICdsaW5lcG9pbnQnICYmIHNwZWMubWFyayA9PT0gQVJFQSlcbiAgICApO1xuICAgIC8vIFRPRE86IGNvbnNpZGVyIG1vdmluZyB0aGlzIHRvIGJlY29tZSBhbm90aGVyIGNhc2Ugb2YgY29tcG9zaXRlTWFya1xuICAgIGlmIChvdmVybGF5V2l0aFBvaW50IHx8IG92ZXJsYXlXaXRoTGluZSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZU92ZXJsYXkoc3BlYywgb3ZlcmxheVdpdGhQb2ludCwgb3ZlcmxheVdpdGhMaW5lLCBjb25maWcpO1xuICAgIH1cblxuICAgIHJldHVybiBzcGVjOyAvLyBOb3RoaW5nIHRvIG5vcm1hbGl6ZVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb21wb3NpdGVNYXJrLm5vcm1hbGl6ZShzcGVjLCBjb25maWcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJhbmdlZFVuaXQoc3BlYzogVW5pdFNwZWMpIHtcbiAgY29uc3QgaGFzWCA9IGNoYW5uZWxIYXNGaWVsZChzcGVjLmVuY29kaW5nLCBYKTtcbiAgY29uc3QgaGFzWSA9IGNoYW5uZWxIYXNGaWVsZChzcGVjLmVuY29kaW5nLCBZKTtcbiAgY29uc3QgaGFzWDIgPSBjaGFubmVsSGFzRmllbGQoc3BlYy5lbmNvZGluZywgWDIpO1xuICBjb25zdCBoYXNZMiA9IGNoYW5uZWxIYXNGaWVsZChzcGVjLmVuY29kaW5nLCBZMik7XG4gIGlmICgoaGFzWDIgJiYgIWhhc1gpIHx8IChoYXNZMiAmJiAhaGFzWSkpIHtcbiAgICBjb25zdCBub3JtYWxpemVkU3BlYyA9IGR1cGxpY2F0ZShzcGVjKTtcbiAgICBpZiAoaGFzWDIgJiYgIWhhc1gpIHtcbiAgICAgIG5vcm1hbGl6ZWRTcGVjLmVuY29kaW5nLnggPSBub3JtYWxpemVkU3BlYy5lbmNvZGluZy54MjtcbiAgICAgIGRlbGV0ZSBub3JtYWxpemVkU3BlYy5lbmNvZGluZy54MjtcbiAgICB9XG4gICAgaWYgKGhhc1kyICYmICFoYXNZKSB7XG4gICAgICBub3JtYWxpemVkU3BlYy5lbmNvZGluZy55ID0gbm9ybWFsaXplZFNwZWMuZW5jb2RpbmcueTI7XG4gICAgICBkZWxldGUgbm9ybWFsaXplZFNwZWMuZW5jb2RpbmcueTI7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRTcGVjO1xuICB9XG4gIHJldHVybiBzcGVjO1xufVxuXG5cbi8vIEZJWE1FKCMxODA0KTogcmUtZGVzaWduIHRoaXNcbmZ1bmN0aW9uIG5vcm1hbGl6ZU92ZXJsYXkoc3BlYzogVW5pdFNwZWMsIG92ZXJsYXlXaXRoUG9pbnQ6IGJvb2xlYW4sIG92ZXJsYXlXaXRoTGluZTogYm9vbGVhbiwgY29uZmlnOiBDb25maWcpOiBMYXllclNwZWMge1xuICBjb25zdCB7bWFyaywgc2VsZWN0aW9uLCBlbmNvZGluZywgLi4ub3V0ZXJTcGVjfSA9IHNwZWM7XG4gIGNvbnN0IGxheWVyID0gW3ttYXJrLCBlbmNvZGluZ31dO1xuXG4gIC8vIE5lZWQgdG8gY29weSBzdGFjayBjb25maWcgdG8gb3ZlcmxheWVkIGxheWVyXG4gIGNvbnN0IHN0YWNrUHJvcHMgPSBzdGFjayhtYXJrLCBlbmNvZGluZywgY29uZmlnID8gY29uZmlnLnN0YWNrIDogdW5kZWZpbmVkKTtcblxuICBsZXQgb3ZlcmxheUVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIGlmIChzdGFja1Byb3BzKSB7XG4gICAgY29uc3Qge2ZpZWxkQ2hhbm5lbDogc3RhY2tGaWVsZENoYW5uZWwsIG9mZnNldH0gPSBzdGFja1Byb3BzO1xuICAgIG92ZXJsYXlFbmNvZGluZyA9IHtcbiAgICAgIC4uLmVuY29kaW5nLFxuICAgICAgW3N0YWNrRmllbGRDaGFubmVsXToge1xuICAgICAgICAuLi5lbmNvZGluZ1tzdGFja0ZpZWxkQ2hhbm5lbF0sXG4gICAgICAgIC4uLihvZmZzZXQgPyB7c3RhY2s6IG9mZnNldH0gOiB7fSlcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgaWYgKG92ZXJsYXlXaXRoTGluZSkge1xuICAgIGxheWVyLnB1c2goe1xuICAgICAgbWFyazoge1xuICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgIHN0eWxlOiAnbGluZU92ZXJsYXknXG4gICAgICB9LFxuICAgICAgLi4uKHNlbGVjdGlvbiA/IHtzZWxlY3Rpb259IDoge30pLFxuICAgICAgZW5jb2Rpbmc6IG92ZXJsYXlFbmNvZGluZ1xuICAgIH0pO1xuICB9XG4gIGlmIChvdmVybGF5V2l0aFBvaW50KSB7XG4gICAgbGF5ZXIucHVzaCh7XG4gICAgICBtYXJrOiB7XG4gICAgICAgIHR5cGU6ICdwb2ludCcsXG4gICAgICAgIGZpbGxlZDogdHJ1ZSxcbiAgICAgICAgc3R5bGU6ICdwb2ludE92ZXJsYXknXG4gICAgICB9LFxuICAgICAgLi4uKHNlbGVjdGlvbiA/IHtzZWxlY3Rpb259IDoge30pLFxuICAgICAgZW5jb2Rpbmc6IG92ZXJsYXlFbmNvZGluZ1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vdXRlclNwZWMsXG4gICAgbGF5ZXJcbiAgfTtcbn1cblxuLy8gVE9ETzogYWRkIHZsLnNwZWMudmFsaWRhdGUgJiBtb3ZlIHN0dWZmIGZyb20gdmwudmFsaWRhdGUgdG8gaGVyZVxuXG4vKiBBY2N1bXVsYXRlIG5vbi1kdXBsaWNhdGUgZmllbGREZWZzIGluIGEgZGljdGlvbmFyeSAqL1xuZnVuY3Rpb24gYWNjdW11bGF0ZShkaWN0OiBhbnksIGZpZWxkRGVmczogRmllbGREZWY8RmllbGQ+W10pOiBhbnkge1xuICBmaWVsZERlZnMuZm9yRWFjaChmdW5jdGlvbihmaWVsZERlZikge1xuICAgIC8vIENvbnNpZGVyIG9ubHkgcHVyZSBmaWVsZERlZiBwcm9wZXJ0aWVzIChpZ25vcmluZyBzY2FsZSwgYXhpcywgbGVnZW5kKVxuICAgIGNvbnN0IHB1cmVGaWVsZERlZiA9IFsnZmllbGQnLCAndHlwZScsICd2YWx1ZScsICd0aW1lVW5pdCcsICdiaW4nLCAnYWdncmVnYXRlJ10ucmVkdWNlKChmLCBrZXkpID0+IHtcbiAgICAgIGlmIChmaWVsZERlZltrZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZltrZXldID0gZmllbGREZWZba2V5XTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmO1xuICAgIH0sIHt9KTtcbiAgICBjb25zdCBrZXkgPSBoYXNoKHB1cmVGaWVsZERlZik7XG4gICAgZGljdFtrZXldID0gZGljdFtrZXldIHx8IGZpZWxkRGVmO1xuICB9KTtcbiAgcmV0dXJuIGRpY3Q7XG59XG5cbi8qIFJlY3Vyc2l2ZWx5IGdldCBmaWVsZERlZnMgZnJvbSBhIHNwZWMsIHJldHVybnMgYSBkaWN0aW9uYXJ5IG9mIGZpZWxkRGVmcyAqL1xuZnVuY3Rpb24gZmllbGREZWZJbmRleDxUPihzcGVjOiBHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8YW55LCBhbnk+PiwgZGljdDogRGljdDxGaWVsZERlZjxUPj4gPSB7fSk6IERpY3Q8RmllbGREZWY8VD4+IHtcbiAgLy8gRklYTUUoaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yMjA3KTogU3VwcG9ydCBmaWVsZERlZkluZGV4IGZvciByZXBlYXRcbiAgaWYgKGlzTGF5ZXJTcGVjKHNwZWMpKSB7XG4gICAgc3BlYy5sYXllci5mb3JFYWNoKGxheWVyID0+IHtcbiAgICAgIGlmIChpc1VuaXRTcGVjKGxheWVyKSkge1xuICAgICAgICBhY2N1bXVsYXRlKGRpY3QsIHZsRW5jb2RpbmcuZmllbGREZWZzKGxheWVyLmVuY29kaW5nKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmaWVsZERlZkluZGV4KGxheWVyLCBkaWN0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmIChpc0ZhY2V0U3BlYyhzcGVjKSkge1xuICAgIGFjY3VtdWxhdGUoZGljdCwgdmxFbmNvZGluZy5maWVsZERlZnMoc3BlYy5mYWNldCkpO1xuICAgIGZpZWxkRGVmSW5kZXgoc3BlYy5zcGVjLCBkaWN0KTtcbiAgfSBlbHNlIGlmIChpc1JlcGVhdFNwZWMoc3BlYykpIHtcbiAgICBmaWVsZERlZkluZGV4KHNwZWMuc3BlYywgZGljdCk7XG4gIH0gZWxzZSBpZiAoaXNDb25jYXRTcGVjKHNwZWMpKSB7XG4gICAgY29uc3QgY2hpbGRTcGVjID0gaXNWQ29uY2F0U3BlYyhzcGVjKSA/IHNwZWMudmNvbmNhdCA6IHNwZWMuaGNvbmNhdDtcbiAgICBjaGlsZFNwZWMuZm9yRWFjaChjaGlsZCA9PiBmaWVsZERlZkluZGV4KGNoaWxkLCBkaWN0KSk7XG4gIH0gZWxzZSB7IC8vIFVuaXQgU3BlY1xuICAgIGFjY3VtdWxhdGUoZGljdCwgdmxFbmNvZGluZy5maWVsZERlZnMoc3BlYy5lbmNvZGluZykpO1xuICB9XG4gIHJldHVybiBkaWN0O1xufVxuXG4vKiBSZXR1cm5zIGFsbCBub24tZHVwbGljYXRlIGZpZWxkRGVmcyBpbiBhIHNwZWMgaW4gYSBmbGF0IGFycmF5ICovXG5leHBvcnQgZnVuY3Rpb24gZmllbGREZWZzKHNwZWM6IEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxhbnksIGFueT4+KTogRmllbGREZWY8YW55PltdIHtcbiAgcmV0dXJuIHZhbHMoZmllbGREZWZJbmRleChzcGVjKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0YWNrZWQoc3BlYzogVG9wTGV2ZWw8RmFjZXRlZENvbXBvc2l0ZVVuaXRTcGVjPiwgY29uZmlnPzogQ29uZmlnKTogYm9vbGVhbiB7XG4gIGNvbmZpZyA9IGNvbmZpZyB8fCBzcGVjLmNvbmZpZztcbiAgaWYgKGlzUHJpbWl0aXZlTWFyayhzcGVjLm1hcmspKSB7XG4gICAgcmV0dXJuIHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZyxcbiAgICAgICAgICAgIGNvbmZpZyA/IGNvbmZpZy5zdGFjayA6IHVuZGVmaW5lZFxuICAgICAgICAgICkgIT09IG51bGw7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuIl19 \ 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..81261953e5 --- /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(stack: string): stack 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: ("area" | "circle" | "line" | "text" | "square" | "point" | "bar" | "rule" | "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..5fef1766d5 --- /dev/null +++ b/build/src/stack.js @@ -0,0 +1,133 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var aggregate_1 = require("./aggregate"); +var channel_1 = require("./channel"); +var encoding_1 = require("./encoding"); +var fielddef_1 = require("./fielddef"); +var log = require("./log"); +var mark_1 = require("./mark"); +var scale_1 = require("./scale"); +var util_1 = require("./util"); +var STACK_OFFSET_INDEX = { + zero: 1, + center: 1, + normalize: 1 +}; +function isStackOffset(stack) { + return !!STACK_OFFSET_INDEX[stack]; +} +exports.isStackOffset = isStackOffset; +exports.STACKABLE_MARKS = [mark_1.BAR, mark_1.AREA, mark_1.RULE, mark_1.POINT, mark_1.CIRCLE, mark_1.SQUARE, mark_1.LINE, mark_1.TEXT, mark_1.TICK]; +exports.STACK_BY_DEFAULT_MARKS = [mark_1.BAR, mark_1.AREA]; +function potentialStackedChannel(encoding) { + var xDef = encoding.x; + var yDef = encoding.y; + if (fielddef_1.isFieldDef(xDef) && fielddef_1.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 (fielddef_1.isFieldDef(xDef) && xDef.type === 'quantitative') { + return 'x'; + } + else if (fielddef_1.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 = mark_1.isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!util_1.contains(exports.STACKABLE_MARKS, mark)) { + return null; + } + var fieldChannel = potentialStackedChannel(encoding); + if (!fieldChannel) { + return null; + } + var stackedFieldDef = encoding[fieldChannel]; + var stackedField = fielddef_1.isStringFieldDef(stackedFieldDef) ? fielddef_1.field(stackedFieldDef, {}) : undefined; + var dimensionChannel = fieldChannel === 'x' ? 'y' : 'x'; + var dimensionDef = encoding[dimensionChannel]; + var dimensionField = fielddef_1.isStringFieldDef(dimensionDef) ? fielddef_1.field(dimensionDef, {}) : undefined; + // Should have grouping level of detail that is different from the dimension field + var stackBy = channel_1.NONPOSITION_CHANNELS.reduce(function (sc, channel) { + if (encoding_1.channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (cDef) { + var fieldDef = fielddef_1.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 = fielddef_1.isStringFieldDef(fieldDef) ? fielddef_1.field(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 (util_1.contains(exports.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; + } + // If stacked, check scale type if it is linear + if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== scale_1.ScaleType.LINEAR) { + log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type)); + return null; + } + // Check if it is a ranged mark + if (encoding_1.channelHasField(encoding, fieldChannel === channel_1.X ? channel_1.X2 : channel_1.Y2)) { + log.warn(log.message.cannotStackRangedMark(fieldChannel)); + return null; + } + // Warn if stacking summative aggregate + if (stackedFieldDef.aggregate && !util_1.contains(aggregate_1.SUM_OPS, stackedFieldDef.aggregate)) { + log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate)); + } + return { + groupbyChannel: dimensionDef ? dimensionChannel : undefined, + fieldChannel: fieldChannel, + impute: util_1.contains(['area', 'line'], mark), + stackBy: stackBy, + offset: offset + }; +} +exports.stack = stack; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBb0M7QUFDcEMscUNBQThFO0FBQzlFLHVDQUFxRDtBQUNyRCx1Q0FBK0c7QUFDL0csMkJBQTZCO0FBQzdCLCtCQUEwRztBQUMxRyxpQ0FBa0M7QUFDbEMsK0JBQStDO0FBSy9DLElBQU0sa0JBQWtCLEdBQXNCO0lBQzVDLElBQUksRUFBRSxDQUFDO0lBQ1AsTUFBTSxFQUFFLENBQUM7SUFDVCxTQUFTLEVBQUUsQ0FBQztDQUNiLENBQUM7QUFFRix1QkFBOEIsS0FBYTtJQUN6QyxNQUFNLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFGRCxzQ0FFQztBQTBCWSxRQUFBLGVBQWUsR0FBRyxDQUFDLFVBQUcsRUFBRSxXQUFJLEVBQUUsV0FBSSxFQUFFLFlBQUssRUFBRSxhQUFNLEVBQUUsYUFBTSxFQUFFLFdBQUksRUFBRSxXQUFJLEVBQUUsV0FBSSxDQUFDLENBQUM7QUFDN0UsUUFBQSxzQkFBc0IsR0FBRyxDQUFDLFVBQUcsRUFBRSxXQUFJLENBQUMsQ0FBQztBQUdsRCxpQ0FBaUMsUUFBeUI7SUFDeEQsSUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUN4QixJQUFNLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBRXhCLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsSUFBSSxDQUFDLElBQUkscUJBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxjQUFjLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxjQUFjLENBQUMsQ0FBQyxDQUFDO1lBQ2pFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNm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QyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzFELE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLEVBQUUsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxTQUFTLElBQUksQ0FBQyxlQUFRLENBQUMsbUJBQU8sRUFBRSxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9FLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRUQsTUFBTSxDQUFDO1FBQ0wsY0FBYyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDM0QsWUFBWSxjQUFBO1FBQ1osTUFBTSxFQUFFLGVBQVEsQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUM7UUFDeEMsT0FBTyxTQUFBO1FBQ1AsTUFBTSxRQUFBO0tBQ1AsQ0FBQztBQUNKLENBQUM7QUF2RkQsc0JBdUZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTVU1fT1BTfSBmcm9tICcuL2FnZ3JlZ2F0ZSc7XG5pbXBvcnQge05PTlBPU0lUSU9OX0NIQU5ORUxTLCBOb25Qb3NpdGlvbkNoYW5uZWwsIFgsIFgyLCBZMn0gZnJvbSAnLi9jaGFubmVsJztcbmltcG9ydCB7Y2hhbm5lbEhhc0ZpZWxkLCBFbmNvZGluZ30gZnJvbSAnLi9lbmNvZGluZyc7XG5pbXBvcnQge0ZpZWxkLCBmaWVsZCwgRmllbGREZWYsIGdldEZpZWxkRGVmLCBpc0ZpZWxkRGVmLCBpc1N0cmluZ0ZpZWxkRGVmLCBQb3NpdGlvbkZpZWxkRGVmfSBmcm9tICcuL2ZpZWxkZGVmJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQge0FSRUEsIEJBUiwgQ0lSQ0xFLCBpc01hcmtEZWYsIExJTkUsIE1hcmssIE1hcmtEZWYsIFBPSU5ULCBSVUxFLCBTUVVBUkUsIFRFWFQsIFRJQ0t9IGZyb20gJy4vbWFyayc7XG5pbXBvcnQge1NjYWxlVHlwZX0gZnJvbSAnLi9zY2FsZSc7XG5pbXBvcnQge2NvbnRhaW5zLCBGbGFnLCBpc0FycmF5fSBmcm9tICcuL3V0aWwnO1xuXG5cbmV4cG9ydCB0eXBlIFN0YWNrT2Zmc2V0ID0gJ3plcm8nIHwgJ2NlbnRlcicgfCAnbm9ybWFsaXplJztcblxuY29uc3QgU1RBQ0tfT0ZGU0VUX0lOREVYOiBGbGFnPFN0YWNrT2Zmc2V0PiA9IHtcbiAgemVybzogMSxcbiAgY2VudGVyOiAxLFxuICBub3JtYWxpemU6IDFcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0YWNrT2Zmc2V0KHN0YWNrOiBzdHJpbmcpOiBzdGFjayBpcyBTdGFja09mZnNldCB7XG4gIHJldHVybiAhIVNUQUNLX09GRlNFVF9JTkRFWFtzdGFja107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tQcm9wZXJ0aWVzIHtcbiAgLyoqIERpbWVuc2lvbiBheGlzIG9mIHRoZSBzdGFjay4gKi9cbiAgZ3JvdXBieUNoYW5uZWw6ICd4JyB8ICd5JztcblxuICAvKiogTWVhc3VyZSBheGlzIG9mIHRoZSBzdGFjay4gKi9cbiAgZmllbGRDaGFubmVsOiAneCcgfCAneSc7XG5cbiAgLyoqIFN0YWNrLWJ5IGZpZWxkcyBlLmcuLCBjb2xvciwgZGV0YWlsICovXG4gIHN0YWNrQnk6IHtcbiAgICBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPixcbiAgICBjaGFubmVsOiBOb25Qb3NpdGlvbkNoYW5uZWxcbiAgfVtdO1xuXG4gIC8qKlxuICAgKiBTZWUgYFwic3RhY2tcImAgcHJvcGVydHkgb2YgUG9zaXRpb24gRmllbGQgRGVmLlxuICAgKi9cbiAgb2Zmc2V0OiBTdGFja09mZnNldDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHN0YWNrIHdpbGwgcHJvZHVjZSBpbXB1dGUgdHJhbnNmb3JtXG4gICAqL1xuICBpbXB1dGU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBTVEFDS0FCTEVfTUFSS1MgPSBbQkFSLCBBUkVBLCBSVUxFLCBQT0lOVCwgQ0lSQ0xFLCBTUVVBUkUsIExJTkUsIFRFWFQsIFRJQ0tdO1xuZXhwb3J0IGNvbnN0IFNUQUNLX0JZX0RFRkFVTFRfTUFSS1MgPSBbQkFSLCBBUkVBXTtcblxuXG5mdW5jdGlvbiBwb3RlbnRpYWxTdGFja2VkQ2hhbm5lbChlbmNvZGluZzogRW5jb2Rpbmc8RmllbGQ+KTogJ3gnIHwgJ3knIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgeERlZiA9IGVuY29kaW5nLng7XG4gIGNvbnN0IHlEZWYgPSBlbmNvZGluZy55O1xuXG4gIGlmIChpc0ZpZWxkRGVmKHhEZWYpICYmIGlzRmllbGREZWYoeURlZikpIHtcbiAgICBpZiAoeERlZi50eXBlID09PSAncXVhbnRpdGF0aXZlJyAmJiB5RGVmLnR5cGUgPT09ICdxdWFudGl0YXRpdmUnKSB7XG4gICAgICBpZiAoeERlZi5zdGFjaykge1xuICAgICAgICByZXR1cm4gJ3gnO1xuICAgICAgfSBlbHNlIGlmICh5RGVmLnN0YWNrKSB7XG4gICAgICAgIHJldHVybiAneSc7XG4gICAgICB9XG4gICAgICAvLyBpZiB0aGVyZSBpcyBubyBleHBsaWNpdCBzdGFja2luZywgb25seSBhcHBseSBzdGFjayBpZiB0aGVyZSBpcyBvbmx5IG9uZSBhZ2dyZWdhdGUgZm9yIHggb3IgeVxuICAgICAgaWYgKCghIXhEZWYuYWdncmVnYXRlKSAhPT0gKCEheURlZi5hZ2dyZWdhdGUpKSB7XG4gICAgICAgIHJldHVybiB4RGVmLmFnZ3JlZ2F0ZSA/ICd4JyA6ICd5JztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHhEZWYudHlwZSA9PT0gJ3F1YW50aXRhdGl2ZScpIHtcbiAgICAgIHJldHVybiAneCc7XG4gICAgfSBlbHNlIGlmICh5RGVmLnR5cGUgPT09ICdxdWFudGl0YXRpdmUnKSB7XG4gICAgICByZXR1cm4gJ3knO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0ZpZWxkRGVmKHhEZWYpICYmIHhEZWYudHlwZSA9PT0gJ3F1YW50aXRhdGl2ZScpIHtcbiAgICByZXR1cm4gJ3gnO1xuICB9IGVsc2UgaWYgKGlzRmllbGREZWYoeURlZikgJiYgeURlZi50eXBlID09PSAncXVhbnRpdGF0aXZlJykge1xuICAgIHJldHVybiAneSc7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLy8gTm90ZTogQ29tcGFzc1FMIHVzZXMgdGhpcyBtZXRob2QgYW5kIG9ubHkgcGFzcyBpbiByZXF1aXJlZCBwcm9wZXJ0aWVzIG9mIGVhY2ggYXJndW1lbnQgb2JqZWN0LlxuLy8gSWYgcmVxdWlyZWQgcHJvcGVydGllcyBjaGFuZ2UsIG1ha2Ugc3VyZSB0byB1cGRhdGUgQ29tcGFzc1FMLlxuZXhwb3J0IGZ1bmN0aW9uIHN0YWNrKG06IE1hcmsgfCBNYXJrRGVmLCBlbmNvZGluZzogRW5jb2Rpbmc8RmllbGQ+LCBzdGFja0NvbmZpZzogU3RhY2tPZmZzZXQpOiBTdGFja1Byb3BlcnRpZXMge1xuICBjb25zdCBtYXJrID0gaXNNYXJrRGVmKG0pID8gbS50eXBlIDogbTtcbiAgLy8gU2hvdWxkIGhhdmUgc3RhY2thYmxlIG1hcmtcbiAgaWYgKCFjb250YWlucyhTVEFDS0FCTEVfTUFSS1MsIG1hcmspKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBmaWVsZENoYW5uZWwgPSBwb3RlbnRpYWxTdGFja2VkQ2hhbm5lbChlbmNvZGluZyk7XG4gIGlmICghZmllbGRDaGFubmVsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBzdGFja2VkRmllbGREZWYgPSBlbmNvZGluZ1tmaWVsZENoYW5uZWxdIGFzIFBvc2l0aW9uRmllbGREZWY8c3RyaW5nPjtcbiAgY29uc3Qgc3RhY2tlZEZpZWxkID0gaXNTdHJpbmdGaWVsZERlZihzdGFja2VkRmllbGREZWYpID8gZmllbGQoc3RhY2tlZEZpZWxkRGVmLCB7fSkgOiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgZGltZW5zaW9uQ2hhbm5lbCA9IGZpZWxkQ2hhbm5lbCA9PT0gJ3gnID8gJ3knIDogJ3gnO1xuICBjb25zdCBkaW1lbnNpb25EZWYgPSBlbmNvZGluZ1tkaW1lbnNpb25DaGFubmVsXTtcbiAgY29uc3QgZGltZW5zaW9uRmllbGQgPSBpc1N0cmluZ0ZpZWxkRGVmKGRpbWVuc2lvbkRlZikgPyBmaWVsZChkaW1lbnNpb25EZWYsIHt9KSA6IHVuZGVmaW5lZDtcblxuICAvLyBTaG91bGQgaGF2ZSBncm91cGluZyBsZXZlbCBvZiBkZXRhaWwgdGhhdCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgZGltZW5zaW9uIGZpZWxkXG4gIGNvbnN0IHN0YWNrQnkgPSBOT05QT1NJVElPTl9DSEFOTkVMUy5yZWR1Y2UoKHNjLCBjaGFubmVsKSA9PiB7XG4gICAgaWYgKGNoYW5uZWxIYXNGaWVsZChlbmNvZGluZywgY2hhbm5lbCkpIHtcbiAgICAgIGNvbnN0IGNoYW5uZWxEZWYgPSBlbmNvZGluZ1tjaGFubmVsXTtcbiAgICAgIChpc0FycmF5KGNoYW5uZWxEZWYpID8gY2hhbm5lbERlZiA6IFtjaGFubmVsRGVmXSkuZm9yRWFjaCgoY0RlZikgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZERlZiA9IGdldEZpZWxkRGVmKGNEZWYpO1xuICAgICAgICBpZiAoZmllbGREZWYuYWdncmVnYXRlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgY2hhbm5lbCdzIGZpZWxkIGlzIGlkZW50aWNhbCB0byB4L3kncyBmaWVsZCBvciBpZiB0aGUgY2hhbm5lbCBpcyBhIHJlcGVhdFxuICAgICAgICBjb25zdCBmID0gaXNTdHJpbmdGaWVsZERlZihmaWVsZERlZikgPyBmaWVsZChmaWVsZERlZiwge30pIDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgLy8gaWYgZmllbGRkZWYgaXMgYSByZXBlYXQsIGp1c3QgaW5jbHVkZSBpdCBpbiB0aGUgc3RhY2sgYnlcbiAgICAgICAgICAhZiB8fFxuICAgICAgICAgIC8vIG90aGVyd2lzZSwgdGhlIGZpZWxkIG11c3QgYmUgZGlmZmVyZW50IGZyb20geCBhbmQgeSBmaWVsZHMuXG4gICAgICAgICAgKGYgIT09IGRpbWVuc2lvbkZpZWxkICYmIGYgIT09IHN0YWNrZWRGaWVsZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgc2MucHVzaCh7Y2hhbm5lbCwgZmllbGREZWZ9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBzYztcbiAgfSwgW10pO1xuXG4gIGlmIChzdGFja0J5Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQXV0b21hdGljYWxseSBkZXRlcm1pbmUgb2Zmc2V0XG4gIGxldCBvZmZzZXQ6IFN0YWNrT2Zmc2V0ID0gdW5kZWZpbmVkO1xuICBpZiAoc3RhY2tlZEZpZWxkRGVmLnN0YWNrICE9PSB1bmRlZmluZWQpIHtcbiAgICBvZmZzZXQgPSBzdGFja2VkRmllbGREZWYuc3RhY2s7XG4gIH0gZWxzZSBpZiAoY29udGFpbnMoU1RBQ0tfQllfREVGQVVMVF9NQVJLUywgbWFyaykpIHtcbiAgICAvLyBCYXIgYW5kIEFyZWEgd2l0aCBzdW0gb3BzIGFyZSBhdXRvbWF0aWNhbGx5IHN0YWNrZWQgYnkgZGVmYXVsdFxuICAgIG9mZnNldCA9IHN0YWNrQ29uZmlnID09PSB1bmRlZmluZWQgPyAnemVybycgOiBzdGFja0NvbmZpZztcbiAgfSBlbHNlIHtcbiAgICBvZmZzZXQgPSBzdGFja0NvbmZpZztcbiAgfVxuXG4gIGlmICghb2Zmc2V0IHx8ICFpc1N0YWNrT2Zmc2V0KG9mZnNldCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIElmIHN0YWNrZWQsIGNoZWNrIHNjYWxlIHR5cGUgaWYgaXQgaXMgbGluZWFyXG4gIGlmIChzdGFja2VkRmllbGREZWYuc2NhbGUgJiYgc3RhY2tlZEZpZWxkRGVmLnNjYWxlLnR5cGUgJiYgc3RhY2tlZEZpZWxkRGVmLnNjYWxlLnR5cGUgIT09IFNjYWxlVHlwZS5MSU5FQVIpIHtcbiAgICBsb2cud2Fybihsb2cubWVzc2FnZS5jYW5ub3RTdGFja05vbkxpbmVhclNjYWxlKHN0YWNrZWRGaWVsZERlZi5zY2FsZS50eXBlKSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBDaGVjayBpZiBpdCBpcyBhIHJhbmdlZCBtYXJrXG4gIGlmIChjaGFubmVsSGFzRmllbGQoZW5jb2RpbmcsIGZpZWxkQ2hhbm5lbCA9PT0gWCA/IFgyIDogWTIpKSB7XG4gICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuY2Fubm90U3RhY2tSYW5nZWRNYXJrKGZpZWxkQ2hhbm5lbCkpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gV2FybiBpZiBzdGFja2luZyBzdW1tYXRpdmUgYWdncmVnYXRlXG4gIGlmIChzdGFja2VkRmllbGREZWYuYWdncmVnYXRlICYmICFjb250YWlucyhTVU1fT1BTLCBzdGFja2VkRmllbGREZWYuYWdncmVnYXRlKSkge1xuICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLnN0YWNrTm9uU3VtbWF0aXZlQWdncmVnYXRlKHN0YWNrZWRGaWVsZERlZi5hZ2dyZWdhdGUpKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZ3JvdXBieUNoYW5uZWw6IGRpbWVuc2lvbkRlZiA/IGRpbWVuc2lvbkNoYW5uZWwgOiB1bmRlZmluZWQsXG4gICAgZmllbGRDaGFubmVsLFxuICAgIGltcHV0ZTogY29udGFpbnMoWydhcmVhJywgJ2xpbmUnXSwgbWFyayksXG4gICAgc3RhY2tCeSxcbiAgICBvZmZzZXRcbiAgfTtcbn1cbiJdfQ== \ 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..9522214dcd --- /dev/null +++ b/build/src/timeunit.js @@ -0,0 +1,307 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("./datetime"); +var log = require("./log"); +var util_1 = require("./util"); +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 = exports.TimeUnit || (exports.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 +}; +exports.TIMEUNIT_PARTS = util_1.flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX); +function isLocalSingleTimeUnit(timeUnit) { + return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit]; +} +exports.isLocalSingleTimeUnit = isLocalSingleTimeUnit; +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]; +} +exports.isUtcSingleTimeUnit = isUtcSingleTimeUnit; +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]; +} +exports.isUTCTimeUnit = isUTCTimeUnit; +function getLocalTimeUnit(t) { + return t.substr(3); +} +exports.getLocalTimeUnit = getLocalTimeUnit; +var TIMEUNIT_INDEX = __assign({}, LOCAL_SINGLE_TIMEUNIT_INDEX, UTC_SINGLE_TIMEUNIT_INDEX, LOCAL_MULTI_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); +exports.TIMEUNITS = util_1.flagKeys(TIMEUNIT_INDEX); +function isTimeUnit(t) { + return !!TIMEUNIT_INDEX[t]; +} +exports.isTimeUnit = isTimeUnit; +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 = exports.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; +} +exports.convert = convert; +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 exports.TIMEUNIT_PARTS.reduce(function (parts, part) { + if (containsTimeUnit(timeUnit, part)) { + return parts.concat(part); + } + return parts; + }, []); +} +exports.getTimeUnitParts = getTimeUnitParts; +/** 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 + ); +} +exports.containsTimeUnit = containsTimeUnit; +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +function fieldExpr(fullTimeUnit, field) { + var fieldRef = "datum" + util_1.accessPath(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 = exports.TIMEUNIT_PARTS.reduce(function (dateExpr, tu) { + if (containsTimeUnit(fullTimeUnit, tu)) { + dateExpr[tu] = func(tu); + } + return dateExpr; + }, {}); + return datetime_1.dateTimeExpr(d); +} +exports.fieldExpr = fieldExpr; +/** + * 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; +} +exports.formatExpression = formatExpression; +function normalizeTimeUnit(timeUnit) { + if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) { + log.warn(log.message.dayReplacedWithDate(timeUnit)); + return timeUnit.replace('day', 'date'); + } + return timeUnit; +} +exports.normalizeTimeUnit = normalizeTimeUnit; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGltZXVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLHVDQUFzRDtBQUN0RCwyQkFBNkI7QUFDN0IsK0JBQWtEO0FBRWxELElBQWlCLFFBQVEsQ0FpRHhCO0FBakRELFdBQWlCLFFBQVE7SUFDVixhQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLGNBQUssR0FBWSxPQUFPLENBQUM7SUFDekIsWUFBRyxHQUFVLEtBQUssQ0FBQztJQUNuQixhQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLGNBQUssR0FBWSxPQUFPLENBQUM7SUFDekIsZ0JBQU8sR0FBYyxTQUFTLENBQUM7SUFDL0IsZ0JBQU8sR0FBYyxTQUFTLENBQUM7SUFDL0IscUJBQVksR0FBbUIsY0FBYyxDQUFDO0lBQzlDLGtCQUFTLEdBQWdCLFdBQVcsQ0FBQztJQUNyQyxzQkFBYSxHQUFvQixlQUFlLENBQUM7SUFDakQsMkJBQWtCLEdBQXlCLG9CQUFvQixDQUFDO0lBQ2hFLGtDQUF5QixHQUFnQywyQkFBMkIsQ0FBQztJQUNyRix5Q0FBZ0MsR0FBdUMsa0NBQWtDLENBQUM7SUFFdkgscUZBQXFGO0lBQ3hFLGtCQUFTLEdBQWdCLFdBQVcsQ0FBQztJQUNyQyxxQkFBWSxHQUFtQixjQUFjLENBQUM7SUFDOUMsNEJBQW1CLEdBQTBCLHFCQUFxQixDQUFDO0lBQ25FLHVCQUFjLEdBQXFCLGdCQUFnQixDQUFDO0lBQ3BELDRCQUFtQixHQUEwQixxQkFBcUIsQ0FBQztJQUNuRSxnQkFBTyxHQUFjLFNBQVMsQ0FBQztJQUMvQixvQkFBVyxHQUFrQixhQUFhLENBQUM7SUFDM0MscUJBQVksR0FBbUIsY0FBYyxDQUFDO0lBQzlDLHlCQUFnQixHQUF1QixrQkFBa0IsQ0FBQztJQUMxRCxnQkFBTyxHQUFjLFNBQVMsQ0FBQztJQUMvQixpQkFBUSxHQUFlLFVBQVUsQ0FBQztJQUNsQyxlQUFNLEdBQWEsUUFBUSxDQUFDO0lBQzVCLGdCQUFPLEdBQWMsU0FBUyxDQUFDO0lBQy9CLGlCQUFRLEdBQWUsVUFBVSxDQUFDO0lBQ2xDLG1CQUFVLEdBQWlCLFlBQVksQ0FBQztJQUN4QyxtQkFBVSxHQUFpQixZQUFZLENBQUM7SUFDeEMsd0JBQWUsR0FBc0IsaUJBQWlCLENBQUM7SUFDdkQscUJBQVksR0FBbUIsY0FBYyxDQUFDO0lBQzlDLHlCQUFnQixHQUF1QixrQkFBa0IsQ0FBQztJQUMxRCw4QkFBcUIsR0FBNEIsdUJBQXVCLENBQUM7SUFDekUscUNBQTRCLEdBQW1DLDhCQUE4QixDQUFDO0lBQzlGLDRDQUFtQyxHQUEwQyxxQ0FBcUMsQ0FBQztJQUVoSSxxRkFBcUY7SUFDeEUscUJBQVksR0FBbUIsY0FBYyxDQUFDO0lBQzlDLHdCQUFlLEdBQXNCLGlCQUFpQixDQUFDO0lBQ3ZELCtCQUFzQixHQUE2Qix3QkFBd0IsQ0FBQztJQUM1RSwwQkFBaUIsR0FBd0IsbUJBQW1CLENBQUM7SUFDN0QsK0JBQXNCLEdBQTZCLHdCQUF3QixDQUFDO0lBQzVFLG1CQUFVLEdBQWlCLFlBQVksQ0FBQztJQUN4Qyx1QkFBYyxHQUFxQixnQkFBZ0IsQ0FBQztJQUNwRCx3QkFBZSxHQUFzQixpQkFBaUIsQ0FBQztJQUN2RCw0QkFBbUIsR0FBMEIscUJBQXFCLENBQUM7QUFDbEYsQ0FBQyxFQWpEZ0IsUUFBUSxHQUFSLGdCQUFRLEtBQVIsZ0JBQVEsUUFpRHhCO0FBYUQsd0VBQXdFO0FBQ3hFLElBQU0sMkJBQTJCLEdBQThCO0lBQzdELElBQUksRUFBRSxDQUFDO0lBQ1AsT0FBTyxFQUFFLENBQUM7SUFDVixLQUFLLEVBQUUsQ0FBQztJQUNSLEdBQUcsRUFBRSxDQUFDO0lBQ04sSUFBSSxFQUFFLENBQUM7SUFDUCxLQUFLLEVBQUUsQ0FBQztJQUNSLE9BQU8sRUFBRSxDQUFDO0lBQ1YsT0FBTyxFQUFFLENBQUM7SUFDVixZQUFZLEVBQUUsQ0FBQztDQUNoQixDQUFDO0FBRVcsUUFBQSxjQUFjLEdBQUcsZUFBUSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUFFcEUsK0JBQXNDLFFBQWdCO0lBQ3BELE1BQU0sQ0FBQyxDQUFDLENBQUMsMkJBQTJCLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakQsQ0FBQztBQUZELHNEQUVDO0FBYUQsSUFBTSx5QkFBeUIsR0FBNEI7SUFDekQsT0FBTyxFQUFFLENBQUM7SUFDVixVQUFVLEVBQUUsQ0FBQztJQUNiLFFBQVEsRUFBRSxDQUFDO0lBQ1gsTUFBTSxFQUFFLENBQUM7SUFDVCxPQUFPLEVBQUUsQ0FBQztJQUNWLFFBQVEsRUFBRSxDQUFDO0lBQ1gsVUFBVSxFQUFFLENBQUM7SUFDYixVQUFVLEVBQUUsQ0FBQztJQUNiLGVBQWUsRUFBRSxDQUFDO0NBQ25CLENBQUM7QUFFRiw2QkFBb0MsUUFBZ0I7SUFDbEQsTUFBTSxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMvQyxDQUFDO0FBRkQsa0RBRUM7QUFjRCxJQUFNLDBCQUEwQixHQUE2QjtJQUMzRCxXQUFXLEVBQUUsQ0FBQztJQUNkLGdCQUFnQixFQUFFLENBQUM7SUFFbkIsU0FBUyxFQUFFLENBQUM7SUFDWixhQUFhLEVBQUUsQ0FBQztJQUNoQixrQkFBa0IsRUFBRSxDQUFDO0lBQ3JCLHlCQUF5QixFQUFFLENBQUM7SUFDNUIsZ0NBQWdDLEVBQUUsQ0FBQztJQUVuQyxZQUFZLEVBQUUsQ0FBQztJQUVmLFNBQVMsRUFBRSxDQUFDO0lBRVosWUFBWSxFQUFFLENBQUM7SUFDZixtQkFBbUIsRUFBRSxDQUFDO0lBRXRCLGNBQWMsRUFBRSxDQUFDO0lBRWpCLG1CQUFtQixFQUFFLENBQUM7Q0FDdkIsQ0FBQztBQVdGLElBQU0sd0JBQXdCLEdBQTJCO0lBQ3ZELGNBQWMsRUFBRSxDQUFDO0lBQ2pCLG1CQUFtQixFQUFFLENBQUM7SUFFdEIsWUFBWSxFQUFFLENBQUM7SUFDZixnQkFBZ0IsRUFBRSxDQUFDO0lBQ25CLHFCQUFxQixFQUFFLENBQUM7SUFDeEIsNEJBQTRCLEVBQUUsQ0FBQztJQUMvQixtQ0FBbUMsRUFBRSxDQUFDO0lBRXRDLGVBQWUsRUFBRSxDQUFDO0lBRWxCLFlBQVksRUFBRSxDQUFDO0lBRWYsZUFBZSxFQUFFLENBQUM7SUFDbEIsc0JBQXNCLEVBQUUsQ0FBQztJQUV6QixpQkFBaUIsRUFBRSxDQUFDO0lBRXBCLHNCQUFzQixFQUFFLENBQUM7Q0FDMUIsQ0FBQztBQVFGLElBQU0sa0JBQWtCLGdCQUNuQix5QkFBeUIsRUFDekIsd0JBQXdCLENBQzVCLENBQUM7QUFFRix1QkFBOEIsQ0FBUztJQUNyQyxNQUFNLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFGRCxzQ0FFQztBQUVELDBCQUFpQyxDQUFjO0lBQzdDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBa0IsQ0FBQztBQUN0QyxDQUFDO0FBRkQsNENBRUM7QUFJRCxJQUFNLGNBQWMsZ0JBQ2YsMkJBQTJCLEVBQzNCLHlCQUF5QixFQUN6QiwwQkFBMEIsRUFDMUIsd0JBQXdCLENBQzVCLENBQUM7QUFFVyxRQUFBLFNBQVMsR0FBRyxlQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFbEQsb0JBQTJCLENBQVM7SUFDbEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0IsQ0FBQztBQUZELGdDQUVDO0FBSUQsSUFBTSxlQUFlLEdBQWdEO0lBQ25FLElBQUksRUFBRSxhQUFhO0lBQ25CLEtBQUssRUFBRSxVQUFVO0lBQ2pCLElBQUksRUFBRSxTQUFTO0lBQ2YsS0FBSyxFQUFFLFVBQVU7SUFDakIsT0FBTyxFQUFFLFlBQVk7SUFDckIsT0FBTyxFQUFFLFlBQVk7SUFDckIsWUFBWSxFQUFFLGlCQUFpQjtJQUMvQiwrQ0FBK0M7SUFDL0MsT0FBTyxFQUFFLElBQUk7SUFDYixHQUFHLEVBQUUsSUFBSTtDQUNWLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsaUJBQXdCLElBQWMsRUFBRSxJQUFVO0lBQ2hELElBQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxJQUFNLE1BQU0sR0FBUyxLQUFLLENBQUMsQ0FBQztRQUMxQiwwQkFBMEI7UUFDMUIsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUIsR0FBRyxDQUFDLENBQXVCLFVBQWMsRUFBZCxtQkFBQSxzQkFBYyxFQUFkLDRCQUFjLEVBQWQsSUFBYztRQUFwQyxJQUFNLFlBQVksdUJBQUE7UUFDdkIsRUFBRSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6QyxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUNyQixLQUFLLFFBQVEsQ0FBQyxHQUFHO29CQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztnQkFDcEUsS0FBSyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ2hCLElBQUEsZ0NBQTRELEVBQTNELGtDQUFhLEVBQUUsa0NBQWEsQ0FBZ0M7b0JBQ25FLDZGQUE2RjtvQkFDN0YsTUFBTSxDQUFDLGVBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBYSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNuRSxLQUFLLENBQUM7Z0JBQ1IsQ0FBQztnQkFDRDtvQkFDUSxJQUFBLHFDQUFpRSxFQUFoRSxnQ0FBYSxFQUFFLGdDQUFhLENBQXFDO29CQUN4RSxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqRCxDQUFDO1FBQ0gsQ0FBQztLQUNGO0lBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBeEJELDBCQXdCQztBQUVELHFCQUFxQixVQUEwQixFQUFFLEtBQWM7SUFDN0QsSUFBTSxnQkFBZ0IsR0FBRyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDckQsSUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQztJQUN2RixJQUFNLGFBQWEsR0FBRyxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hGLE1BQU0sQ0FBQyxFQUFDLGFBQWEsZUFBQSxFQUFFLGFBQWEsZUFBQSxFQUFDLENBQUM7QUFDeEMsQ0FBQztBQUVELDBCQUFpQyxRQUFrQjtJQUNqRCxNQUFNLENBQUMsc0JBQWMsQ0FBQyxNQUFNLENBQUMsVUFBQyxLQUFLLEVBQUUsSUFBSTtRQUN2QyxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ2YsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ1QsQ0FBQztBQVBELDRDQU9DO0FBRUQsMkVBQTJFO0FBQzNFLDBCQUFpQyxZQUFzQixFQUFFLFFBQWtCO0lBQ3pFLElBQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDN0MsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDZixDQUNFLFFBQVEsS0FBSyxRQUFRLENBQUMsT0FBTztZQUM3QixLQUFLLEtBQUssQ0FBQztZQUNYLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyx1QkFBdUI7U0FDN0QsQ0FBQztBQUNOLENBQUM7QUFSRCw0Q0FRQztBQUVEOztHQUVHO0FBQ0gsbUJBQTBCLFlBQXNCLEVBQUUsS0FBYTtJQUM3RCxJQUFNLFFBQVEsR0FBRyxVQUFRLGlCQUFVLENBQUMsS0FBSyxDQUFHLENBQUM7SUFFN0MsSUFBTSxHQUFHLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNyRCxjQUFjLFFBQWtCO1FBQzlCLEVBQUUsQ0FBQyxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNsQyxtQ0FBbUM7WUFDbkMsTUFBTSxDQUFDLE1BQUksR0FBRyxnQkFBVyxRQUFRLFNBQU0sQ0FBQztRQUMxQyxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMsS0FBRyxHQUFHLEdBQUcsUUFBUSxTQUFJLFFBQVEsTUFBRyxDQUFDO1FBQzFDLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBTSxDQUFDLEdBQUcsc0JBQWMsQ0FBQyxNQUFNLENBQUMsVUFBQyxRQUFzQixFQUFFLEVBQVk7UUFDbkUsRUFBRSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QyxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFDRCxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQ2xCLENBQUMsRUFBRSxFQUF1QyxDQUFDLENBQUM7SUFFNUMsTUFBTSxDQUFDLHVCQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekIsQ0FBQztBQXJCRCw4QkFxQkM7QUFFRDs7R0FFRztBQUNILDBCQUFpQyxRQUFrQixFQUFFLEtBQWEsRUFBRSxlQUF3QixFQUFFLFVBQW1CO0lBQy9HLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNkLE1BQU0sQ0FBQyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELElBQU0sY0FBYyxHQUFhLEVBQUUsQ0FBQztJQUNwQyxJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUM7SUFDcEIsSUFBTSxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUUxRCxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCwyQ0FBMkM7UUFDMUMsVUFBVSxHQUFHLG1CQUFpQixLQUFLLE1BQUcsQ0FBQztJQUN6QyxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0Msa0NBQWtDO1FBQ2xDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsY0FBYyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyRCxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsNkJBQTZCO0lBQ2pGLENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ1osY0FBYyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELElBQU0sY0FBYyxHQUFhLEVBQUUsQ0FBQztJQUVwQyxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFDRCxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRCxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFDRCxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRCxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFDRCxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RCxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFNLGtCQUFrQixHQUFhLEVBQUUsQ0FBQztJQUN4QyxFQUFFLENBQUMsQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBQ0QsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlCLGtCQUFrQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELEVBQUUsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDZixpREFBaUQ7WUFDakQsVUFBVSxJQUFJLFdBQVcsQ0FBQztRQUM1QixDQUFDO1FBRUQsc0NBQXNDO1FBQ3RDLHFGQUFxRjtRQUNyRiwrRUFBK0U7UUFDL0UsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUNmLFVBQVUsSUFBSSxlQUFhLEtBQUssV0FBTSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQUksQ0FBQztRQUN6RSxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixVQUFVLElBQUksZ0JBQWMsS0FBSyxXQUFNLGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBSSxDQUFDO1FBQzFFLENBQUM7SUFDSCxDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLE1BQU0sQ0FBQyxVQUFVLElBQUksU0FBUyxDQUFDO0FBQ2pDLENBQUM7QUF0RUQsNENBc0VDO0FBRUQsMkJBQWtDLFFBQWtCO0lBQ2xELEVBQUUsQ0FBQyxDQUFDLFFBQVEsS0FBSyxLQUFLLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQWEsQ0FBQztJQUNyRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBTkQsOENBTUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RhdGVUaW1lRXhwciwgZGF0ZVRpbWVFeHByfSBmcm9tICcuL2RhdGV0aW1lJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQge2FjY2Vzc1BhdGgsIEZsYWcsIGZsYWdLZXlzfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgbmFtZXNwYWNlIFRpbWVVbml0IHtcbiAgZXhwb3J0IGNvbnN0IFlFQVI6ICd5ZWFyJyA9ICd5ZWFyJztcbiAgZXhwb3J0IGNvbnN0IE1PTlRIOiAnbW9udGgnID0gJ21vbnRoJztcbiAgZXhwb3J0IGNvbnN0IERBWTogJ2RheScgPSAnZGF5JztcbiAgZXhwb3J0IGNvbnN0IERBVEU6ICdkYXRlJyA9ICdkYXRlJztcbiAgZXhwb3J0IGNvbnN0IEhPVVJTOiAnaG91cnMnID0gJ2hvdXJzJztcbiAgZXhwb3J0IGNvbnN0IE1JTlVURVM6ICdtaW51dGVzJyA9ICdtaW51dGVzJztcbiAgZXhwb3J0IGNvbnN0IFNFQ09ORFM6ICdzZWNvbmRzJyA9ICdzZWNvbmRzJztcbiAgZXhwb3J0IGNvbnN0IE1JTExJU0VDT05EUzogJ21pbGxpc2Vjb25kcycgPSAnbWlsbGlzZWNvbmRzJztcbiAgZXhwb3J0IGNvbnN0IFlFQVJNT05USDogJ3llYXJtb250aCcgPSAneWVhcm1vbnRoJztcbiAgZXhwb3J0IGNvbnN0IFlFQVJNT05USERBVEU6ICd5ZWFybW9udGhkYXRlJyA9ICd5ZWFybW9udGhkYXRlJztcbiAgZXhwb3J0IGNvbnN0IFlFQVJNT05USERBVEVIT1VSUzogJ3llYXJtb250aGRhdGVob3VycycgPSAneWVhcm1vbnRoZGF0ZWhvdXJzJztcbiAgZXhwb3J0IGNvbnN0IFlFQVJNT05USERBVEVIT1VSU01JTlVURVM6ICd5ZWFybW9udGhkYXRlaG91cnNtaW51dGVzJyA9ICd5ZWFybW9udGhkYXRlaG91cnNtaW51dGVzJztcbiAgZXhwb3J0IGNvbnN0IFlFQVJNT05USERBVEVIT1VSU01JTlVURVNTRUNPTkRTOiAneWVhcm1vbnRoZGF0ZWhvdXJzbWludXRlc3NlY29uZHMnID0gJ3llYXJtb250aGRhdGVob3Vyc21pbnV0ZXNzZWNvbmRzJztcblxuICAvLyBNT05USERBVEUgYWx3YXlzIGluY2x1ZGUgMjkgRmVicnVhcnkgc2luY2Ugd2UgdXNlIHllYXIgMHRoICh3aGljaCBpcyBhIGxlYXAgeWVhcik7XG4gIGV4cG9ydCBjb25zdCBNT05USERBVEU6ICdtb250aGRhdGUnID0gJ21vbnRoZGF0ZSc7XG4gIGV4cG9ydCBjb25zdCBIT1VSU01JTlVURVM6ICdob3Vyc21pbnV0ZXMnID0gJ2hvdXJzbWludXRlcyc7XG4gIGV4cG9ydCBjb25zdCBIT1VSU01JTlVURVNTRUNPTkRTOiAnaG91cnNtaW51dGVzc2Vjb25kcycgPSAnaG91cnNtaW51dGVzc2Vjb25kcyc7XG4gIGV4cG9ydCBjb25zdCBNSU5VVEVTU0VDT05EUzogJ21pbnV0ZXNzZWNvbmRzJyA9ICdtaW51dGVzc2Vjb25kcyc7XG4gIGV4cG9ydCBjb25zdCBTRUNPTkRTTUlMTElTRUNPTkRTOiAnc2Vjb25kc21pbGxpc2Vjb25kcycgPSAnc2Vjb25kc21pbGxpc2Vjb25kcyc7XG4gIGV4cG9ydCBjb25zdCBRVUFSVEVSOiAncXVhcnRlcicgPSAncXVhcnRlcic7XG4gIGV4cG9ydCBjb25zdCBZRUFSUVVBUlRFUjogJ3llYXJxdWFydGVyJyA9ICd5ZWFycXVhcnRlcic7XG4gIGV4cG9ydCBjb25zdCBRVUFSVEVSTU9OVEg6ICdxdWFydGVybW9udGgnID0gJ3F1YXJ0ZXJtb250aCc7XG4gIGV4cG9ydCBjb25zdCBZRUFSUVVBUlRFUk1PTlRIOiAneWVhcnF1YXJ0ZXJtb250aCcgPSAneWVhcnF1YXJ0ZXJtb250aCc7XG4gIGV4cG9ydCBjb25zdCBVVENZRUFSOiAndXRjeWVhcicgPSAndXRjeWVhcic7XG4gIGV4cG9ydCBjb25zdCBVVENNT05USDogJ3V0Y21vbnRoJyA9ICd1dGNtb250aCc7XG4gIGV4cG9ydCBjb25zdCBVVENEQVk6ICd1dGNkYXknID0gJ3V0Y2RheSc7XG4gIGV4cG9ydCBjb25zdCBVVENEQVRFOiAndXRjZGF0ZScgPSAndXRjZGF0ZSc7XG4gIGV4cG9ydCBjb25zdCBVVENIT1VSUzogJ3V0Y2hvdXJzJyA9ICd1dGNob3Vycyc7XG4gIGV4cG9ydCBjb25zdCBVVENNSU5VVEVTOiAndXRjbWludXRlcycgPSAndXRjbWludXRlcyc7XG4gIGV4cG9ydCBjb25zdCBVVENTRUNPTkRTOiAndXRjc2Vjb25kcycgPSAndXRjc2Vjb25kcyc7XG4gIGV4cG9ydCBjb25zdCBVVENNSUxMSVNFQ09ORFM6ICd1dGNtaWxsaXNlY29uZHMnID0gJ3V0Y21pbGxpc2Vjb25kcyc7XG4gIGV4cG9ydCBjb25zdCBVVENZRUFSTU9OVEg6ICd1dGN5ZWFybW9udGgnID0gJ3V0Y3llYXJtb250aCc7XG4gIGV4cG9ydCBjb25zdCBVVENZRUFSTU9OVEhEQVRFOiAndXRjeWVhcm1vbnRoZGF0ZScgPSAndXRjeWVhcm1vbnRoZGF0ZSc7XG4gIGV4cG9ydCBjb25zdCBVVENZRUFSTU9OVEhEQVRFSE9VUlM6ICd1dGN5ZWFybW9udGhkYXRlaG91cnMnID0gJ3V0Y3llYXJtb250aGRhdGVob3Vycyc7XG4gIGV4cG9ydCBjb25zdCBVVENZRUFSTU9OVEhEQVRFSE9VUlNNSU5VVEVTOiAndXRjeWVhcm1vbnRoZGF0ZWhvdXJzbWludXRlcycgPSAndXRjeWVhcm1vbnRoZGF0ZWhvdXJzbWludXRlcyc7XG4gIGV4cG9ydCBjb25zdCBVVENZRUFSTU9OVEhEQVRFSE9VUlNNSU5VVEVTU0VDT05EUzogJ3V0Y3llYXJtb250aGRhdGVob3Vyc21pbnV0ZXNzZWNvbmRzJyA9ICd1dGN5ZWFybW9udGhkYXRlaG91cnNtaW51dGVzc2Vjb25kcyc7XG5cbiAgLy8gTU9OVEhEQVRFIGFsd2F5cyBpbmNsdWRlIDI5IEZlYnJ1YXJ5IHNpbmNlIHdlIHVzZSB5ZWFyIDB0aCAod2hpY2ggaXMgYSBsZWFwIHllYXIpO1xuICBleHBvcnQgY29uc3QgVVRDTU9OVEhEQVRFOiAndXRjbW9udGhkYXRlJyA9ICd1dGNtb250aGRhdGUnO1xuICBleHBvcnQgY29uc3QgVVRDSE9VUlNNSU5VVEVTOiAndXRjaG91cnNtaW51dGVzJyA9ICd1dGNob3Vyc21pbnV0ZXMnO1xuICBleHBvcnQgY29uc3QgVVRDSE9VUlNNSU5VVEVTU0VDT05EUzogJ3V0Y2hvdXJzbWludXRlc3NlY29uZHMnID0gJ3V0Y2hvdXJzbWludXRlc3NlY29uZHMnO1xuICBleHBvcnQgY29uc3QgVVRDTUlOVVRFU1NFQ09ORFM6ICd1dGNtaW51dGVzc2Vjb25kcycgPSAndXRjbWludXRlc3NlY29uZHMnO1xuICBleHBvcnQgY29uc3QgVVRDU0VDT05EU01JTExJU0VDT05EUzogJ3V0Y3NlY29uZHNtaWxsaXNlY29uZHMnID0gJ3V0Y3NlY29uZHNtaWxsaXNlY29uZHMnO1xuICBleHBvcnQgY29uc3QgVVRDUVVBUlRFUjogJ3V0Y3F1YXJ0ZXInID0gJ3V0Y3F1YXJ0ZXInO1xuICBleHBvcnQgY29uc3QgVVRDWUVBUlFVQVJURVI6ICd1dGN5ZWFycXVhcnRlcicgPSAndXRjeWVhcnF1YXJ0ZXInO1xuICBleHBvcnQgY29uc3QgVVRDUVVBUlRFUk1PTlRIOiAndXRjcXVhcnRlcm1vbnRoJyA9ICd1dGNxdWFydGVybW9udGgnO1xuICBleHBvcnQgY29uc3QgVVRDWUVBUlFVQVJURVJNT05USDogJ3V0Y3llYXJxdWFydGVybW9udGgnID0gJ3V0Y3llYXJxdWFydGVybW9udGgnO1xufVxuXG5leHBvcnQgdHlwZSBMb2NhbFNpbmdsZVRpbWVVbml0ID1cbiAgdHlwZW9mIFRpbWVVbml0LllFQVIgfFxuICB0eXBlb2YgVGltZVVuaXQuUVVBUlRFUiB8XG4gIHR5cGVvZiBUaW1lVW5pdC5NT05USCB8XG4gIHR5cGVvZiBUaW1lVW5pdC5EQVkgfFxuICB0eXBlb2YgVGltZVVuaXQuREFURSB8XG4gIHR5cGVvZiBUaW1lVW5pdC5IT1VSUyB8XG4gIHR5cGVvZiBUaW1lVW5pdC5NSU5VVEVTIHxcbiAgdHlwZW9mIFRpbWVVbml0LlNFQ09ORFMgfFxuICB0eXBlb2YgVGltZVVuaXQuTUlMTElTRUNPTkRTO1xuXG4vKiogVGltZSBVbml0IHRoYXQgb25seSBjb3JyZXNwb25kcyB0byBvbmx5IG9uZSBwYXJ0IG9mIERhdGUgb2JqZWN0cy4gKi9cbmNvbnN0IExPQ0FMX1NJTkdMRV9USU1FVU5JVF9JTkRFWDogRmxhZzxMb2NhbFNpbmdsZVRpbWVVbml0PiA9IHtcbiAgeWVhcjogMSxcbiAgcXVhcnRlcjogMSxcbiAgbW9udGg6IDEsXG4gIGRheTogMSxcbiAgZGF0ZTogMSxcbiAgaG91cnM6IDEsXG4gIG1pbnV0ZXM6IDEsXG4gIHNlY29uZHM6IDEsXG4gIG1pbGxpc2Vjb25kczogMVxufTtcblxuZXhwb3J0IGNvbnN0IFRJTUVVTklUX1BBUlRTID0gZmxhZ0tleXMoTE9DQUxfU0lOR0xFX1RJTUVVTklUX0lOREVYKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzTG9jYWxTaW5nbGVUaW1lVW5pdCh0aW1lVW5pdDogc3RyaW5nKTogdGltZVVuaXQgaXMgTG9jYWxTaW5nbGVUaW1lVW5pdCB7XG4gIHJldHVybiAhIUxPQ0FMX1NJTkdMRV9USU1FVU5JVF9JTkRFWFt0aW1lVW5pdF07XG59XG5cbmV4cG9ydCB0eXBlIFV0Y1NpbmdsZVRpbWVVbml0ID1cbiAgdHlwZW9mIFRpbWVVbml0LlVUQ1lFQVIgfFxuICB0eXBlb2YgVGltZVVuaXQuVVRDUVVBUlRFUiB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENNT05USCB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENEQVkgfFxuICB0eXBlb2YgVGltZVVuaXQuVVRDREFURSB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENIT1VSUyB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENNSU5VVEVTIHxcbiAgdHlwZW9mIFRpbWVVbml0LlVUQ1NFQ09ORFMgfFxuICB0eXBlb2YgVGltZVVuaXQuVVRDTUlMTElTRUNPTkRTO1xuXG5jb25zdCBVVENfU0lOR0xFX1RJTUVVTklUX0lOREVYOiBGbGFnPFV0Y1NpbmdsZVRpbWVVbml0PiA9IHtcbiAgdXRjeWVhcjogMSxcbiAgdXRjcXVhcnRlcjogMSxcbiAgdXRjbW9udGg6IDEsXG4gIHV0Y2RheTogMSxcbiAgdXRjZGF0ZTogMSxcbiAgdXRjaG91cnM6IDEsXG4gIHV0Y21pbnV0ZXM6IDEsXG4gIHV0Y3NlY29uZHM6IDEsXG4gIHV0Y21pbGxpc2Vjb25kczogMVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzVXRjU2luZ2xlVGltZVVuaXQodGltZVVuaXQ6IHN0cmluZyk6IHRpbWVVbml0IGlzIFV0Y1NpbmdsZVRpbWVVbml0IHtcbiAgcmV0dXJuICEhVVRDX1NJTkdMRV9USU1FVU5JVF9JTkRFWFt0aW1lVW5pdF07XG59XG5cbmV4cG9ydCB0eXBlIFNpbmdsZVRpbWVVbml0ID0gTG9jYWxTaW5nbGVUaW1lVW5pdCB8IFV0Y1NpbmdsZVRpbWVVbml0O1xuXG5leHBvcnQgdHlwZSBMb2NhbE11bHRpVGltZVVuaXQgPVxuICAvLyBMb2NhbCBUaW1lXG4gIHR5cGVvZiBUaW1lVW5pdC5ZRUFSUVVBUlRFUiB8IHR5cGVvZiBUaW1lVW5pdC5ZRUFSUVVBUlRFUk1PTlRIIHxcbiAgdHlwZW9mIFRpbWVVbml0LllFQVJNT05USCB8IHR5cGVvZiBUaW1lVW5pdC5ZRUFSTU9OVEhEQVRFIHwgdHlwZW9mIFRpbWVVbml0LllFQVJNT05USERBVEVIT1VSUyB8IHR5cGVvZiBUaW1lVW5pdC5ZRUFSTU9OVEhEQVRFSE9VUlNNSU5VVEVTfCB0eXBlb2YgVGltZVVuaXQuWUVBUk1PTlRIREFURUhPVVJTTUlOVVRFU1NFQ09ORFMgfFxuICB0eXBlb2YgVGltZVVuaXQuUVVBUlRFUk1PTlRIIHxcbiAgdHlwZW9mIFRpbWVVbml0Lk1PTlRIREFURSB8XG4gIHR5cGVvZiBUaW1lVW5pdC5IT1VSU01JTlVURVMgfCB0eXBlb2YgVGltZVVuaXQuSE9VUlNNSU5VVEVTU0VDT05EUyB8XG4gIHR5cGVvZiBUaW1lVW5pdC5NSU5VVEVTU0VDT05EUyB8XG4gIHR5cGVvZiBUaW1lVW5pdC5TRUNPTkRTTUlMTElTRUNPTkRTO1xuXG5jb25zdCBMT0NBTF9NVUxUSV9USU1FVU5JVF9JTkRFWDogRmxhZzxMb2NhbE11bHRpVGltZVVuaXQ+ID0ge1xuICB5ZWFycXVhcnRlcjogMSxcbiAgeWVhcnF1YXJ0ZXJtb250aDogMSxcblxuICB5ZWFybW9udGg6IDEsXG4gIHllYXJtb250aGRhdGU6IDEsXG4gIHllYXJtb250aGRhdGVob3VyczogMSxcbiAgeWVhcm1vbnRoZGF0ZWhvdXJzbWludXRlczogMSxcbiAgeWVhcm1vbnRoZGF0ZWhvdXJzbWludXRlc3NlY29uZHM6IDEsXG5cbiAgcXVhcnRlcm1vbnRoOiAxLFxuXG4gIG1vbnRoZGF0ZTogMSxcblxuICBob3Vyc21pbnV0ZXM6IDEsXG4gIGhvdXJzbWludXRlc3NlY29uZHM6IDEsXG5cbiAgbWludXRlc3NlY29uZHM6IDEsXG5cbiAgc2Vjb25kc21pbGxpc2Vjb25kczogMVxufTtcblxuZXhwb3J0IHR5cGUgVXRjTXVsdGlUaW1lVW5pdCA9XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENZRUFSUVVBUlRFUiB8IHR5cGVvZiBUaW1lVW5pdC5VVENZRUFSUVVBUlRFUk1PTlRIIHxcbiAgdHlwZW9mIFRpbWVVbml0LlVUQ1lFQVJNT05USCB8IHR5cGVvZiBUaW1lVW5pdC5VVENZRUFSTU9OVEhEQVRFIHwgdHlwZW9mIFRpbWVVbml0LlVUQ1lFQVJNT05USERBVEVIT1VSUyB8IHR5cGVvZiBUaW1lVW5pdC5VVENZRUFSTU9OVEhEQVRFSE9VUlNNSU5VVEVTfCB0eXBlb2YgVGltZVVuaXQuVVRDWUVBUk1PTlRIREFURUhPVVJTTUlOVVRFU1NFQ09ORFMgfFxuICB0eXBlb2YgVGltZVVuaXQuVVRDUVVBUlRFUk1PTlRIIHxcbiAgdHlwZW9mIFRpbWVVbml0LlVUQ01PTlRIREFURSB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENIT1VSU01JTlVURVMgfCB0eXBlb2YgVGltZVVuaXQuVVRDSE9VUlNNSU5VVEVTU0VDT05EUyB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENNSU5VVEVTU0VDT05EUyB8XG4gIHR5cGVvZiBUaW1lVW5pdC5VVENTRUNPTkRTTUlMTElTRUNPTkRTO1xuXG5jb25zdCBVVENfTVVMVElfVElNRVVOSVRfSU5ERVg6IEZsYWc8VXRjTXVsdGlUaW1lVW5pdD4gPSB7XG4gIHV0Y3llYXJxdWFydGVyOiAxLFxuICB1dGN5ZWFycXVhcnRlcm1vbnRoOiAxLFxuXG4gIHV0Y3llYXJtb250aDogMSxcbiAgdXRjeWVhcm1vbnRoZGF0ZTogMSxcbiAgdXRjeWVhcm1vbnRoZGF0ZWhvdXJzOiAxLFxuICB1dGN5ZWFybW9udGhkYXRlaG91cnNtaW51dGVzOiAxLFxuICB1dGN5ZWFybW9udGhkYXRlaG91cnNtaW51dGVzc2Vjb25kczogMSxcblxuICB1dGNxdWFydGVybW9udGg6IDEsXG5cbiAgdXRjbW9udGhkYXRlOiAxLFxuXG4gIHV0Y2hvdXJzbWludXRlczogMSxcbiAgdXRjaG91cnNtaW51dGVzc2Vjb25kczogMSxcblxuICB1dGNtaW51dGVzc2Vjb25kczogMSxcblxuICB1dGNzZWNvbmRzbWlsbGlzZWNvbmRzOiAxXG59O1xuXG5leHBvcnQgdHlwZSBNdWx0aVRpbWVVbml0ID0gTG9jYWxNdWx0aVRpbWVVbml0IHwgVXRjTXVsdGlUaW1lVW5pdDtcblxuXG5leHBvcnQgdHlwZSBMb2NhbFRpbWVVbml0ID0gTG9jYWxTaW5nbGVUaW1lVW5pdCB8IExvY2FsTXVsdGlUaW1lVW5pdDtcbmV4cG9ydCB0eXBlIFV0Y1RpbWVVbml0ID0gVXRjU2luZ2xlVGltZVVuaXQgfCBVdGNNdWx0aVRpbWVVbml0O1xuXG5jb25zdCBVVENfVElNRVVOSVRfSU5ERVg6IEZsYWc8VXRjVGltZVVuaXQ+ID0ge1xuICAuLi5VVENfU0lOR0xFX1RJTUVVTklUX0lOREVYLFxuICAuLi5VVENfTVVMVElfVElNRVVOSVRfSU5ERVhcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1VUQ1RpbWVVbml0KHQ6IHN0cmluZyk6IHQgaXMgVXRjVGltZVVuaXQge1xuICByZXR1cm4gISFVVENfVElNRVVOSVRfSU5ERVhbdF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2NhbFRpbWVVbml0KHQ6IFV0Y1RpbWVVbml0KTogTG9jYWxUaW1lVW5pdCB7XG4gIHJldHVybiB0LnN1YnN0cigzKSBhcyBMb2NhbFRpbWVVbml0O1xufVxuXG5leHBvcnQgdHlwZSBUaW1lVW5pdCA9IFNpbmdsZVRpbWVVbml0IHwgTXVsdGlUaW1lVW5pdDtcblxuY29uc3QgVElNRVVOSVRfSU5ERVg6IEZsYWc8VGltZVVuaXQ+ID0ge1xuICAuLi5MT0NBTF9TSU5HTEVfVElNRVVOSVRfSU5ERVgsXG4gIC4uLlVUQ19TSU5HTEVfVElNRVVOSVRfSU5ERVgsXG4gIC4uLkxPQ0FMX01VTFRJX1RJTUVVTklUX0lOREVYLFxuICAuLi5VVENfTVVMVElfVElNRVVOSVRfSU5ERVhcbn07XG5cbmV4cG9ydCBjb25zdCBUSU1FVU5JVFMgPSBmbGFnS2V5cyhUSU1FVU5JVF9JTkRFWCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RpbWVVbml0KHQ6IHN0cmluZyk6IHQgaXMgVGltZVVuaXQge1xuICByZXR1cm4gISFUSU1FVU5JVF9JTkRFWFt0XTtcbn1cblxudHlwZSBEYXRlTWV0aG9kTmFtZSA9IGtleW9mIERhdGU7XG5cbmNvbnN0IFNFVF9EQVRFX01FVEhPRDogUmVjb3JkPExvY2FsU2luZ2xlVGltZVVuaXQsIERhdGVNZXRob2ROYW1lPiA9IHtcbiAgeWVhcjogJ3NldEZ1bGxZZWFyJyxcbiAgbW9udGg6ICdzZXRNb250aCcsXG4gIGRhdGU6ICdzZXREYXRlJyxcbiAgaG91cnM6ICdzZXRIb3VycycsXG4gIG1pbnV0ZXM6ICdzZXRNaW51dGVzJyxcbiAgc2Vjb25kczogJ3NldFNlY29uZHMnLFxuICBtaWxsaXNlY29uZHM6ICdzZXRNaWxsaXNlY29uZHMnLFxuICAvLyBEYXkgYW5kIHF1YXJ0ZXIgaGF2ZSB0aGVpciBvd24gc3BlY2lhbCBjYXNlc1xuICBxdWFydGVyOiBudWxsLFxuICBkYXk6IG51bGwsXG59O1xuXG4vKipcbiAqIENvbnZlcnRzIGEgZGF0ZSB0byBvbmx5IGhhdmUgdGhlIG1lYXN1cmVtZW50cyByZWxldmFudCB0byB0aGUgc3BlY2lmaWVkIHVuaXRcbiAqIGkuZS4gKCd5ZWFybW9udGgnLCAnMjAwMC0xMi0wNCAwNzo1ODoxNCcpIC0+ICcyMDAwLTEyLTAxIDAwOjAwOjAwJ1xuICogTm90ZTogdGhlIGJhc2UgZGF0ZSBpcyBKYW4gMDEgMTkwMCAwMDowMDowMFxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydCh1bml0OiBUaW1lVW5pdCwgZGF0ZTogRGF0ZSk6IERhdGUge1xuICBjb25zdCBpc1VUQyA9IGlzVVRDVGltZVVuaXQodW5pdCk7XG4gIGNvbnN0IHJlc3VsdDogRGF0ZSA9IGlzVVRDID9cbiAgICAvLyBzdGFydCB3aXRoIHVuaWZvcm0gZGF0ZVxuICAgIG5ldyBEYXRlKERhdGUuVVRDKDAsIDAsIDEsIDAsIDAsIDAsIDApKSA6XG4gICAgbmV3IERhdGUoMCwgMCwgMSwgMCwgMCwgMCwgMCk7XG4gICAgZm9yIChjb25zdCB0aW1lVW5pdFBhcnQgb2YgVElNRVVOSVRfUEFSVFMpIHtcbiAgICBpZiAoY29udGFpbnNUaW1lVW5pdCh1bml0LCB0aW1lVW5pdFBhcnQpKSB7XG4gICAgICBzd2l0Y2ggKHRpbWVVbml0UGFydCkge1xuICAgICAgICBjYXNlIFRpbWVVbml0LkRBWTpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHRvIFRpbWVVbml0cyBjb250YWluaW5nIFxcJ2RheVxcJycpO1xuICAgICAgICBjYXNlIFRpbWVVbml0LlFVQVJURVI6IHtcbiAgICAgICAgICBjb25zdCB7Z2V0RGF0ZU1ldGhvZCwgc2V0RGF0ZU1ldGhvZH0gPSBkYXRlTWV0aG9kcygnbW9udGgnLCBpc1VUQyk7XG4gICAgICAgICAgLy8gaW5kaWNhdGUgcXVhcnRlciBieSBzZXR0aW5nIG1vbnRoIHRvIGJlIHRoZSBmaXJzdCBvZiB0aGUgcXVhcnRlciBpLmUuIG1heSAoNCkgLT4gYXByaWwgKDMpXG4gICAgICAgICAgcmVzdWx0W3NldERhdGVNZXRob2RdKChNYXRoLmZsb29yKGRhdGVbZ2V0RGF0ZU1ldGhvZF0oKSAvIDMpKSAqIDMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgY29uc3Qge2dldERhdGVNZXRob2QsIHNldERhdGVNZXRob2R9ID0gZGF0ZU1ldGhvZHModGltZVVuaXRQYXJ0LCBpc1VUQyk7XG4gICAgICAgICAgcmVzdWx0W3NldERhdGVNZXRob2RdKGRhdGVbZ2V0RGF0ZU1ldGhvZF0oKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGRhdGVNZXRob2RzKHNpbmdsZVVuaXQ6IFNpbmdsZVRpbWVVbml0LCBpc1V0YzogYm9vbGVhbikge1xuICBjb25zdCByYXdTZXREYXRlTWV0aG9kID0gU0VUX0RBVEVfTUVUSE9EW3NpbmdsZVVuaXRdO1xuICBjb25zdCBzZXREYXRlTWV0aG9kID0gaXNVdGMgPyAnc2V0VVRDJyArIHJhd1NldERhdGVNZXRob2Quc3Vic3RyKDMpIDogcmF3U2V0RGF0ZU1ldGhvZDtcbiAgY29uc3QgZ2V0RGF0ZU1ldGhvZCA9ICdnZXQnICsgKGlzVXRjID8gJ1VUQycgOiAnJykgKyByYXdTZXREYXRlTWV0aG9kLnN1YnN0cigzKTtcbiAgcmV0dXJuIHtzZXREYXRlTWV0aG9kLCBnZXREYXRlTWV0aG9kfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVVbml0UGFydHModGltZVVuaXQ6IFRpbWVVbml0KSB7XG4gIHJldHVybiBUSU1FVU5JVF9QQVJUUy5yZWR1Y2UoKHBhcnRzLCBwYXJ0KSA9PiB7XG4gICAgaWYgKGNvbnRhaW5zVGltZVVuaXQodGltZVVuaXQsIHBhcnQpKSB7XG4gICAgICByZXR1cm4gcGFydHMuY29uY2F0KHBhcnQpO1xuICAgIH1cbiAgICByZXR1cm4gcGFydHM7XG4gIH0sIFtdKTtcbn1cblxuLyoqIFJldHVybnMgdHJ1ZSBpZiBmdWxsVGltZVVuaXQgY29udGFpbnMgdGhlIHRpbWVVbml0LCBmYWxzZSBvdGhlcndpc2UuICovXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNUaW1lVW5pdChmdWxsVGltZVVuaXQ6IFRpbWVVbml0LCB0aW1lVW5pdDogVGltZVVuaXQpIHtcbiAgY29uc3QgaW5kZXggPSBmdWxsVGltZVVuaXQuaW5kZXhPZih0aW1lVW5pdCk7XG4gIHJldHVybiBpbmRleCA+IC0xICYmXG4gICAgKFxuICAgICAgdGltZVVuaXQgIT09IFRpbWVVbml0LlNFQ09ORFMgfHxcbiAgICAgIGluZGV4ID09PSAwIHx8XG4gICAgICBmdWxsVGltZVVuaXQuY2hhckF0KGluZGV4LTEpICE9PSAnaScgLy8gZXhjbHVkZSBtaWxsaXNlY29uZHNcbiAgICApO1xufVxuXG4vKipcbiAqIFJldHVybnMgVmVnYSBleHByZXNzc2lvbiBmb3IgYSBnaXZlbiB0aW1lVW5pdCBhbmQgZmllbGRSZWZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpZWxkRXhwcihmdWxsVGltZVVuaXQ6IFRpbWVVbml0LCBmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmllbGRSZWYgPSBgZGF0dW0ke2FjY2Vzc1BhdGgoZmllbGQpfWA7XG5cbiAgY29uc3QgdXRjID0gaXNVVENUaW1lVW5pdChmdWxsVGltZVVuaXQpID8gJ3V0YycgOiAnJztcbiAgZnVuY3Rpb24gZnVuYyh0aW1lVW5pdDogVGltZVVuaXQpIHtcbiAgICBpZiAodGltZVVuaXQgPT09IFRpbWVVbml0LlFVQVJURVIpIHtcbiAgICAgIC8vIHF1YXJ0ZXIgc3RhcnRpbmcgYXQgMCAoMCwzLDYsOSkuXG4gICAgICByZXR1cm4gYCgke3V0Y31xdWFydGVyKCR7ZmllbGRSZWZ9KS0xKWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgJHt1dGN9JHt0aW1lVW5pdH0oJHtmaWVsZFJlZn0pYDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBkID0gVElNRVVOSVRfUEFSVFMucmVkdWNlKChkYXRlRXhwcjogRGF0ZVRpbWVFeHByLCB0dTogVGltZVVuaXQpID0+IHtcbiAgICBpZiAoY29udGFpbnNUaW1lVW5pdChmdWxsVGltZVVuaXQsIHR1KSkge1xuICAgICAgZGF0ZUV4cHJbdHVdID0gZnVuYyh0dSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlRXhwcjtcbiAgfSwge30gYXMge1trZXkgaW4gU2luZ2xlVGltZVVuaXRdOiBzdHJpbmd9KTtcblxuICByZXR1cm4gZGF0ZVRpbWVFeHByKGQpO1xufVxuXG4vKipcbiAqIHJldHVybnMgdGhlIHNpZ25hbCBleHByZXNzaW9uIHVzZWQgZm9yIGF4aXMgbGFiZWxzIGZvciBhIHRpbWUgdW5pdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RXhwcmVzc2lvbih0aW1lVW5pdDogVGltZVVuaXQsIGZpZWxkOiBzdHJpbmcsIHNob3J0VGltZUxhYmVsczogYm9vbGVhbiwgaXNVVENTY2FsZTogYm9vbGVhbik6IHN0cmluZyB7XG4gIGlmICghdGltZVVuaXQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgZGF0ZUNvbXBvbmVudHM6IHN0cmluZ1tdID0gW107XG4gIGxldCBleHByZXNzaW9uID0gJyc7XG4gIGNvbnN0IGhhc1llYXIgPSBjb250YWluc1RpbWVVbml0KHRpbWVVbml0LCBUaW1lVW5pdC5ZRUFSKTtcblxuICBpZiAoY29udGFpbnNUaW1lVW5pdCh0aW1lVW5pdCwgVGltZVVuaXQuUVVBUlRFUikpIHtcbiAgIC8vIHNwZWNpYWwgZXhwcmVzc2lvbiBmb3IgcXVhcnRlciBhcyBwcmVmaXhcbiAgICBleHByZXNzaW9uID0gYCdRJyArIHF1YXJ0ZXIoJHtmaWVsZH0pYDtcbiAgfVxuXG4gIGlmIChjb250YWluc1RpbWVVbml0KHRpbWVVbml0LCBUaW1lVW5pdC5NT05USCkpIHtcbiAgICAvLyBCeSBkZWZhdWx0IHVzZSBzaG9ydCBtb250aCBuYW1lXG4gICAgZGF0ZUNvbXBvbmVudHMucHVzaChzaG9ydFRpbWVMYWJlbHMgIT09IGZhbHNlID8gJyViJyA6ICclQicpO1xuICB9XG5cbiAgaWYgKGNvbnRhaW5zVGltZVVuaXQodGltZVVuaXQsIFRpbWVVbml0LkRBWSkpIHtcbiAgICBkYXRlQ29tcG9uZW50cy5wdXNoKHNob3J0VGltZUxhYmVscyA/ICclYScgOiAnJUEnKTtcbiAgfSBlbHNlIGlmIChjb250YWluc1RpbWVVbml0KHRpbWVVbml0LCBUaW1lVW5pdC5EQVRFKSkge1xuICAgIGRhdGVDb21wb25lbnRzLnB1c2goJyVkJyArIChoYXNZZWFyID8gJywnIDogJycpKTsgLy8gYWRkIGNvbW1hIGlmIHRoZXJlIGlzIHllYXJcbiAgfVxuXG4gIGlmIChoYXNZZWFyKSB7XG4gICAgZGF0ZUNvbXBvbmVudHMucHVzaChzaG9ydFRpbWVMYWJlbHMgPyAnJXknIDogJyVZJyk7XG4gIH1cblxuICBjb25zdCB0aW1lQ29tcG9uZW50czogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoY29udGFpbnNUaW1lVW5pdCh0aW1lVW5pdCwgVGltZVVuaXQuSE9VUlMpKSB7XG4gICAgdGltZUNvbXBvbmVudHMucHVzaCgnJUgnKTtcbiAgfVxuICBpZiAoY29udGFpbnNUaW1lVW5pdCh0aW1lVW5pdCwgVGltZVVuaXQuTUlOVVRFUykpIHtcbiAgICB0aW1lQ29tcG9uZW50cy5wdXNoKCclTScpO1xuICB9XG4gIGlmIChjb250YWluc1RpbWVVbml0KHRpbWVVbml0LCBUaW1lVW5pdC5TRUNPTkRTKSkge1xuICAgIHRpbWVDb21wb25lbnRzLnB1c2goJyVTJyk7XG4gIH1cbiAgaWYgKGNvbnRhaW5zVGltZVVuaXQodGltZVVuaXQsIFRpbWVVbml0Lk1JTExJU0VDT05EUykpIHtcbiAgICB0aW1lQ29tcG9uZW50cy5wdXNoKCclTCcpO1xuICB9XG5cbiAgY29uc3QgZGF0ZVRpbWVDb21wb25lbnRzOiBzdHJpbmdbXSA9IFtdO1xuICBpZiAoZGF0ZUNvbXBvbmVudHMubGVuZ3RoID4gMCkge1xuICAgIGRhdGVUaW1lQ29tcG9uZW50cy5wdXNoKGRhdGVDb21wb25lbnRzLmpvaW4oJyAnKSk7XG4gIH1cbiAgaWYgKHRpbWVDb21wb25lbnRzLmxlbmd0aCA+IDApIHtcbiAgICBkYXRlVGltZUNvbXBvbmVudHMucHVzaCh0aW1lQ29tcG9uZW50cy5qb2luKCc6JykpO1xuICB9XG5cbiAgaWYgKGRhdGVUaW1lQ29tcG9uZW50cy5sZW5ndGggPiAwKSB7XG4gICAgaWYgKGV4cHJlc3Npb24pIHtcbiAgICAgIC8vIEFkZCBzcGFjZSBiZXR3ZWVuIHF1YXJ0ZXIgYW5kIG1haW4gdGltZSBmb3JtYXRcbiAgICAgIGV4cHJlc3Npb24gKz0gYCArICcgJyArIGA7XG4gICAgfVxuXG4gICAgLy8gV2Ugb25seSB1c2UgdXRjRm9ybWF0IGZvciB1dGMgc2NhbGVcbiAgICAvLyBGb3IgdXRjIHRpbWUgdW5pdHMsIHRoZSBkYXRhIGlzIGFscmVhZHkgY29udmVydGVkIGFzIGEgcGFydCBvZiB0aW1lVW5pdCB0cmFuc2Zvcm0uXG4gICAgLy8gVGh1cywgdXRjIHRpbWUgdW5pdHMgc2hvdWxkIHVzZSB0aW1lRm9ybWF0IHRvIGF2b2lkIHNoaWZ0aW5nIHRoZSB0aW1lIHR3aWNlLlxuICAgIGlmIChpc1VUQ1NjYWxlKSB7XG4gICAgICBleHByZXNzaW9uICs9IGB1dGNGb3JtYXQoJHtmaWVsZH0sICcke2RhdGVUaW1lQ29tcG9uZW50cy5qb2luKCcgJyl9JylgO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHByZXNzaW9uICs9IGB0aW1lRm9ybWF0KCR7ZmllbGR9LCAnJHtkYXRlVGltZUNvbXBvbmVudHMuam9pbignICcpfScpYDtcbiAgICB9XG4gIH1cblxuICAvLyBJZiBleHByZXNzaW9uIGlzIHN0aWxsIGFuIGVtcHR5IHN0cmluZywgcmV0dXJuIHVuZGVmaW5lZCBpbnN0ZWFkLlxuICByZXR1cm4gZXhwcmVzc2lvbiB8fCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVUaW1lVW5pdCh0aW1lVW5pdDogVGltZVVuaXQpOiBUaW1lVW5pdCB7XG4gIGlmICh0aW1lVW5pdCAhPT0gJ2RheScgJiYgdGltZVVuaXQuaW5kZXhPZignZGF5JykgPj0gMCkge1xuICAgIGxvZy53YXJuKGxvZy5tZXNzYWdlLmRheVJlcGxhY2VkV2l0aERhdGUodGltZVVuaXQpKTtcbiAgICByZXR1cm4gdGltZVVuaXQucmVwbGFjZSgnZGF5JywgJ2RhdGUnKSBhcyBUaW1lVW5pdDtcbiAgfVxuICByZXR1cm4gdGltZVVuaXQ7XG59XG4iXX0= \ 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..df66c7bace --- /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](spec.html) and [layered](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](spec.html) and [layered](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](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..e5ef360304 --- /dev/null +++ b/build/src/title.js @@ -0,0 +1,33 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +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 }; +} +exports.extractTitleConfig = extractTitleConfig; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGl0bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGl0bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXdDQSw0QkFBbUMsV0FBMEI7SUFNekQ7SUFEQSw0REFBNEQ7SUFDNUQsMkJBQU0sRUFBRSwyQkFBTSxFQUFFLDJCQUFNO0lBQ3RCLHFDQUFxQztJQUNyQyx5QkFBSztJQUNMLDRCQUE0QjtJQUM1Qiw4RUFBa0IsQ0FDSjtJQUVoQixJQUFNLElBQUksZ0JBQ0wsZUFBZSxFQUNmLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDOUIsQ0FBQztJQUVGLElBQU0sT0FBTyxnQkFDUixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUMsTUFBTSxRQUFBLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUMsTUFBTSxRQUFBLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUMsTUFBTSxRQUFBLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUMxQixDQUFDO0lBRUYsTUFBTSxDQUFDLEVBQUMsSUFBSSxNQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztBQUN6QixDQUFDO0FBekJELGdEQXlCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QW5jaG9yLCBUaXRsZU9yaWVudCwgVmdNYXJrQ29uZmlnLCBWZ1RpdGxlQ29uZmlnfSBmcm9tICcuL3ZlZ2Euc2NoZW1hJztcblxuZXhwb3J0IGludGVyZmFjZSBUaXRsZUJhc2Uge1xuICAvKipcbiAgICogVGhlIG9yaWVudGF0aW9uIG9mIHRoZSB0aXRsZSByZWxhdGl2ZSB0byB0aGUgY2hhcnQuIE9uZSBvZiBgXCJ0b3BcImAgKHRoZSBkZWZhdWx0KSwgYFwiYm90dG9tXCJgLCBgXCJsZWZ0XCJgLCBvciBgXCJyaWdodFwiYC5cbiAgICovXG4gIG9yaWVudD86IFRpdGxlT3JpZW50O1xuXG4gIC8qKlxuICAgKiBUaGUgYW5jaG9yIHBvc2l0aW9uIGZvciBwbGFjaW5nIHRoZSB0aXRsZS4gT25lIG9mIGBcInN0YXJ0XCJgLCBgXCJtaWRkbGVcImAsIG9yIGBcImVuZFwiYC4gRm9yIGV4YW1wbGUsIHdpdGggYW4gb3JpZW50YXRpb24gb2YgdG9wIHRoZXNlIGFuY2hvciBwb3NpdGlvbnMgbWFwIHRvIGEgbGVmdC0sIGNlbnRlci0sIG9yIHJpZ2h0LWFsaWduZWQgdGl0bGUuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgXCJtaWRkbGVcImAgZm9yIFtzaW5nbGVdKHNwZWMuaHRtbCkgYW5kIFtsYXllcmVkXShsYXllci5odG1sKSB2aWV3cy5cbiAgICogYFwic3RhcnRcImAgZm9yIG90aGVyIGNvbXBvc2l0ZSB2aWV3cy5cbiAgICpcbiAgICogX19Ob3RlOl9fIFtGb3Igbm93XShodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzI4NzUpLCBgYW5jaG9yYCBpcyBvbmx5IGN1c3RvbWl6YWJsZSBvbmx5IGZvciBbc2luZ2xlXShzcGVjLmh0bWwpIGFuZCBbbGF5ZXJlZF0obGF5ZXIuaHRtbCkgdmlld3MuICBGb3Igb3RoZXIgY29tcG9zaXRlIHZpZXdzLCBgYW5jaG9yYCBpcyBhbHdheXMgYFwic3RhcnRcImAuXG4gICAqL1xuICBhbmNob3I/OiBBbmNob3I7XG5cbiAgLyoqXG4gICAqIFRoZSBvcnRob2dvbmFsIG9mZnNldCBpbiBwaXhlbHMgYnkgd2hpY2ggdG8gZGlzcGxhY2UgdGhlIHRpdGxlIGZyb20gaXRzIHBvc2l0aW9uIGFsb25nIHRoZSBlZGdlIG9mIHRoZSBjaGFydC5cbiAgICovXG4gIG9mZnNldD86IG51bWJlcjtcblxuICAvKipcbiAgICogQSBbbWFyayBzdHlsZSBwcm9wZXJ0eV0oY29uZmlnLmh0bWwjc3R5bGUpIHRvIGFwcGx5IHRvIHRoZSB0aXRsZSB0ZXh0IG1hcmsuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgXCJncm91cC10aXRsZVwiYC5cbiAgICovXG4gIHN0eWxlPzogc3RyaW5nIHwgc3RyaW5nW107XG5cbiAgLy8gVE9ETzogbmFtZSwgZW5jb2RlLCBpbnRlcmFjdGl2ZSwgemluZGV4XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGl0bGVQYXJhbXMgZXh0ZW5kcyBUaXRsZUJhc2Uge1xuICAvKipcbiAgICogVGhlIHRpdGxlIHRleHQuXG4gICAqL1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0VGl0bGVDb25maWcodGl0bGVDb25maWc6IFZnVGl0bGVDb25maWcpOiB7XG4gIG1hcms6IFZnTWFya0NvbmZpZyxcbiAgbm9uTWFyazogVGl0bGVCYXNlXG59IHtcbiAgY29uc3Qge1xuICAgIC8vIFRoZXNlIGFyZSBub24tbWFyayB0aXRsZSBjb25maWcgdGhhdCBuZWVkIHRvIGJlIGhhcmRjb2RlZFxuICAgIGFuY2hvciwgb2Zmc2V0LCBvcmllbnQsXG4gICAgLy8gY29sb3IgbmVlZHMgdG8gYmUgcmVkaXJlY3QgdG8gZmlsbFxuICAgIGNvbG9yLFxuICAgIC8vIFRoZSByZXN0IGFyZSBtYXJrIGNvbmZpZy5cbiAgICAuLi50aXRsZU1hcmtDb25maWdcbiAgfSA9IHRpdGxlQ29uZmlnO1xuXG4gIGNvbnN0IG1hcms6IFZnTWFya0NvbmZpZyA9IHtcbiAgICAuLi50aXRsZU1hcmtDb25maWcsXG4gICAgLi4uY29sb3IgPyB7ZmlsbDogY29sb3J9IDoge31cbiAgfTtcblxuICBjb25zdCBub25NYXJrOiBUaXRsZUJhc2UgPSB7XG4gICAgLi4uYW5jaG9yID8ge2FuY2hvcn0gOiB7fSxcbiAgICAuLi5vZmZzZXQgPyB7b2Zmc2V0fSA6IHt9LFxuICAgIC4uLm9yaWVudCA/IHtvcmllbnR9IDoge31cbiAgfTtcblxuICByZXR1cm4ge21hcmssIG5vbk1hcmt9O1xufVxuIl19 \ 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..bb5425d41a --- /dev/null +++ b/build/src/toplevelprops.d.ts @@ -0,0 +1,55 @@ +/** + * @minimum 0 + */ +export declare type Padding = number | { + top?: number; + bottom?: number; + left?: number; + right?: number; +}; +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; +} +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"`) inteprets 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..11ca5f6323 --- /dev/null +++ b/build/src/toplevelprops.js @@ -0,0 +1,41 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("util"); +var log = require("./log"); +function _normalizeAutoSize(autosize) { + return util_1.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) { + log.warn(log.message.FIT_NON_SINGLE); + autosize.type = 'pad'; + } + } + return autosize; +} +exports.normalizeAutoSize = normalizeAutoSize; +var TOP_LEVEL_PROPERTIES = [ + 'background', 'padding' + // 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; + }, {}); +} +exports.extractTopLevelProperties = extractTopLevelProperties; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9wbGV2ZWxwcm9wcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b3BsZXZlbHByb3BzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSw2QkFBOEI7QUFDOUIsMkJBQTZCO0FBMEQ3Qiw0QkFBNEIsUUFBdUM7SUFDakUsTUFBTSxDQUFDLGVBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7QUFDaEUsQ0FBQztBQUVELDJCQUFrQyxnQkFBK0MsRUFBRSxjQUE2QyxFQUFFLGFBQTZCO0lBQTdCLDhCQUFBLEVBQUEsb0JBQTZCO0lBQzdKLElBQU0sUUFBUSxjQUNaLElBQUksRUFBRSxLQUFLLElBQ1Isa0JBQWtCLENBQUMsY0FBYyxDQUFDLEVBQ2xDLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLENBQ3hDLENBQUM7SUFFRixFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO1lBQ25CLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNyQyxRQUFRLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQWZELDhDQWVDO0FBRUQsSUFBTSxvQkFBb0IsR0FBaUM7SUFDekQsWUFBWSxFQUFFLFNBQVM7SUFDdkIsbUhBQW1IO0NBQ3BILENBQUM7QUFFRixtQ0FBd0UsQ0FBSTtJQUMxRSxNQUFNLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQzVCLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNULENBQUM7QUFQRCw4REFPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aXNTdHJpbmd9IGZyb20gJ3V0aWwnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4vbG9nJztcblxuLyoqXG4gKiBAbWluaW11bSAwXG4gKi9cbmV4cG9ydCB0eXBlIFBhZGRpbmcgPSBudW1iZXIgfCB7dG9wPzogbnVtYmVyLCBib3R0b20/OiBudW1iZXIsIGxlZnQ/OiBudW1iZXIsIHJpZ2h0PzogbnVtYmVyfTtcblxuZXhwb3J0IGludGVyZmFjZSBUb3BMZXZlbFByb3BlcnRpZXMge1xuICAvKipcbiAgICogQ1NTIGNvbG9yIHByb3BlcnR5IHRvIHVzZSBhcyB0aGUgYmFja2dyb3VuZCBvZiB2aXN1YWxpemF0aW9uLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gbm9uZSAodHJhbnNwYXJlbnQpXG4gICAqL1xuICBiYWNrZ3JvdW5kPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCB2aXN1YWxpemF0aW9uIHBhZGRpbmcsIGluIHBpeGVscywgZnJvbSB0aGUgZWRnZSBvZiB0aGUgdmlzdWFsaXphdGlvbiBjYW52YXMgdG8gdGhlIGRhdGEgcmVjdGFuZ2xlLiAgSWYgYSBudW1iZXIsIHNwZWNpZmllcyBwYWRkaW5nIGZvciBhbGwgc2lkZXMuXG4gICAqIElmIGFuIG9iamVjdCwgdGhlIHZhbHVlIHNob3VsZCBoYXZlIHRoZSBmb3JtYXQgYHtcImxlZnRcIjogNSwgXCJ0b3BcIjogNSwgXCJyaWdodFwiOiA1LCBcImJvdHRvbVwiOiA1fWAgdG8gc3BlY2lmeSBwYWRkaW5nIGZvciBlYWNoIHNpZGUgb2YgdGhlIHZpc3VhbGl6YXRpb24uXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZV9fOiBgNWBcbiAgICovXG4gIHBhZGRpbmc/OiBQYWRkaW5nO1xuXG4gIC8qKlxuICAgKiBTZXRzIGhvdyB0aGUgdmlzdWFsaXphdGlvbiBzaXplIHNob3VsZCBiZSBkZXRlcm1pbmVkLiBJZiBhIHN0cmluZywgc2hvdWxkIGJlIG9uZSBvZiBgXCJwYWRcImAsIGBcImZpdFwiYCBvciBgXCJub25lXCJgLlxuICAgKiBPYmplY3QgdmFsdWVzIGNhbiBhZGRpdGlvbmFsbHkgc3BlY2lmeSBwYXJhbWV0ZXJzIGZvciBjb250ZW50IHNpemluZyBhbmQgYXV0b21hdGljIHJlc2l6aW5nLlxuICAgKiBgXCJmaXRcImAgaXMgb25seSBzdXBwb3J0ZWQgZm9yIHNpbmdsZSBhbmQgbGF5ZXJlZCB2aWV3cyB0aGF0IGRvbid0IHVzZSBgcmFuZ2VTdGVwYC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlX186IGBwYWRgXG4gICAqL1xuICBhdXRvc2l6ZT86IEF1dG9zaXplVHlwZSB8IEF1dG9TaXplUGFyYW1zO1xufVxuXG5leHBvcnQgdHlwZSBBdXRvc2l6ZVR5cGUgPSAncGFkJyB8ICdmaXQnIHwgJ25vbmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF1dG9TaXplUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBzaXppbmcgZm9ybWF0IHR5cGUuIE9uZSBvZiBgXCJwYWRcImAsIGBcImZpdFwiYCBvciBgXCJub25lXCJgLiBTZWUgdGhlIFthdXRvc2l6ZSB0eXBlXShodHRwczovL3ZlZ2EuZ2l0aHViLmlvL3ZlZ2EtbGl0ZS9kb2NzL3NpemUuaHRtbCNhdXRvc2l6ZSkgZG9jdW1lbnRhdGlvbiBmb3IgZGVzY3JpcHRpb25zIG9mIGVhY2guXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZV9fOiBgXCJwYWRcImBcbiAgICovXG4gIHR5cGU/OiBBdXRvc2l6ZVR5cGU7XG5cbiAgLyoqXG4gICAqIEEgYm9vbGVhbiBmbGFnIGluZGljYXRpbmcgaWYgYXV0b3NpemUgbGF5b3V0IHNob3VsZCBiZSByZS1jYWxjdWxhdGVkIG9uIGV2ZXJ5IHZpZXcgdXBkYXRlLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWVfXzogYGZhbHNlYFxuICAgKi9cbiAgcmVzaXplPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBob3cgc2l6ZSBjYWxjdWxhdGlvbiBzaG91bGQgYmUgcGVyZm9ybWVkLCBvbmUgb2YgYFwiY29udGVudFwiYCBvciBgXCJwYWRkaW5nXCJgLiBUaGUgZGVmYXVsdCBzZXR0aW5nIChgXCJjb250ZW50XCJgKSBpbnRlcHJldHMgdGhlIHdpZHRoIGFuZCBoZWlnaHQgc2V0dGluZ3MgYXMgdGhlIGRhdGEgcmVjdGFuZ2xlIChwbG90dGluZykgZGltZW5zaW9ucywgdG8gd2hpY2ggcGFkZGluZyBpcyB0aGVuIGFkZGVkLiBJbiBjb250cmFzdCwgdGhlIGBcInBhZGRpbmdcImAgc2V0dGluZyBpbmNsdWRlcyB0aGUgcGFkZGluZyB3aXRoaW4gdGhlIHZpZXcgc2l6ZSBjYWxjdWxhdGlvbnMsIHN1Y2ggdGhhdCB0aGUgd2lkdGggYW5kIGhlaWdodCBzZXR0aW5ncyBpbmRpY2F0ZSB0aGUgKip0b3RhbCoqIGludGVuZGVkIHNpemUgb2YgdGhlIHZpZXcuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZV9fOiBgXCJjb250ZW50XCJgXG4gICAqL1xuICBjb250YWlucz86ICdjb250ZW50JyB8ICdwYWRkaW5nJztcbn1cblxuZnVuY3Rpb24gX25vcm1hbGl6ZUF1dG9TaXplKGF1dG9zaXplOiBBdXRvc2l6ZVR5cGUgfCBBdXRvU2l6ZVBhcmFtcykge1xuICByZXR1cm4gaXNTdHJpbmcoYXV0b3NpemUpID8ge3R5cGU6IGF1dG9zaXplfSA6IGF1dG9zaXplIHx8IHt9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQXV0b1NpemUodG9wTGV2ZWxBdXRvc2l6ZTogQXV0b3NpemVUeXBlIHwgQXV0b1NpemVQYXJhbXMsIGNvbmZpZ0F1dG9zaXplOiBBdXRvc2l6ZVR5cGUgfCBBdXRvU2l6ZVBhcmFtcywgaXNVbml0T3JMYXllcjogYm9vbGVhbiA9IHRydWUpOiBBdXRvU2l6ZVBhcmFtcyB7XG4gIGNvbnN0IGF1dG9zaXplOiBBdXRvU2l6ZVBhcmFtcyA9IHtcbiAgICB0eXBlOiAncGFkJyxcbiAgICAuLi5fbm9ybWFsaXplQXV0b1NpemUoY29uZmlnQXV0b3NpemUpLFxuICAgIC4uLl9ub3JtYWxpemVBdXRvU2l6ZSh0b3BMZXZlbEF1dG9zaXplKVxuICB9O1xuXG4gIGlmIChhdXRvc2l6ZS50eXBlID09PSAnZml0Jykge1xuICAgIGlmICghaXNVbml0T3JMYXllcikge1xuICAgICAgbG9nLndhcm4obG9nLm1lc3NhZ2UuRklUX05PTl9TSU5HTEUpO1xuICAgICAgYXV0b3NpemUudHlwZSA9ICdwYWQnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhdXRvc2l6ZTtcbn1cblxuY29uc3QgVE9QX0xFVkVMX1BST1BFUlRJRVM6IChrZXlvZiBUb3BMZXZlbFByb3BlcnRpZXMpW10gPSBbXG4gICdiYWNrZ3JvdW5kJywgJ3BhZGRpbmcnXG4gIC8vIFdlIGRvIG5vdCBpbmNsdWRlIFwiYXV0b3NpemVcIiBoZXJlIGFzIGl0IGlzIHN1cHBvcnRlZCBieSBvbmx5IHVuaXQgYW5kIGxheWVyIHNwZWNzIGFuZCB0aHVzIG5lZWQgdG8gYmUgbm9ybWFsaXplZFxuXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RUb3BMZXZlbFByb3BlcnRpZXM8VCBleHRlbmRzIFRvcExldmVsUHJvcGVydGllcz4odDogVCkge1xuICByZXR1cm4gVE9QX0xFVkVMX1BST1BFUlRJRVMucmVkdWNlKChvLCBwKSA9PiB7XG4gICAgaWYgKHQgJiYgdFtwXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvW3BdID0gdFtwXTtcbiAgICB9XG4gICAgcmV0dXJuIG87XG4gIH0sIHt9KTtcbn1cbiJdfQ== \ 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..4f2f9820e4 --- /dev/null +++ b/build/src/transform.d.ts @@ -0,0 +1,126 @@ +import { AggregateOp } from './aggregate'; +import { BinParams } from './bin'; +import { Data } from './data'; +import { Filter } from './filter'; +import { LogicalOperand } from './logical'; +import { TimeUnit } from './timeunit'; +export interface FilterTransform { + /** + * The `filter` property must be either (1) a filter object for [equal-filters](filter.html#equalfilter), + * [range-filters](filter.html#rangefilter), [one-of filters](filter.html#oneoffilter), or [selection filters](filter.html#selectionfilter); + * (2) a [Vega Expression](filter.html#expression) string, + * where `datum` can be used to refer to the current data object; or (3) an array of filters (either objects or expression strings) that must all be true for a datum to pass the filter and be included. + */ + filter: LogicalOperand; +} +export declare function isFilter(t: Transform): t is FilterTransform; +export interface CalculateTransform { + /** + * A string containing a Vega Expression. 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; +} +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. + */ + field: string; + /** + * The output field names to use for each aggregated field. + */ + as: string; +} +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 specificied, 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 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 type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform; +export declare function normalizeTransform(transform: Transform[]): (TimeUnitTransform | AggregateTransform | CalculateTransform | LookupTransform | BinTransform | { + filter: LogicalOperand; +})[]; diff --git a/build/src/transform.js b/build/src/transform.js new file mode 100644 index 0000000000..162a7c5a2a --- /dev/null +++ b/build/src/transform.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var filter_1 = require("./filter"); +var logical_1 = require("./logical"); +function isFilter(t) { + return t['filter'] !== undefined; +} +exports.isFilter = isFilter; +function isLookup(t) { + return t['lookup'] !== undefined; +} +exports.isLookup = isLookup; +function isCalculate(t) { + return t['calculate'] !== undefined; +} +exports.isCalculate = isCalculate; +function isBin(t) { + return !!t['bin']; +} +exports.isBin = isBin; +function isTimeUnit(t) { + return t['timeUnit'] !== undefined; +} +exports.isTimeUnit = isTimeUnit; +function isAggregate(t) { + return t['aggregate'] !== undefined; +} +exports.isAggregate = isAggregate; +function normalizeTransform(transform) { + return transform.map(function (t) { + if (isFilter(t)) { + return { + filter: logical_1.normalizeLogicalOperand(t.filter, filter_1.normalizeFilter) + }; + } + return t; + }); +} +exports.normalizeTransform = normalizeTransform; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyYW5zZm9ybS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUdBLG1DQUFpRDtBQUNqRCxxQ0FBa0U7QUFjbEUsa0JBQXlCLENBQVk7SUFDbkMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDbkMsQ0FBQztBQUZELDRCQUVDO0FBeUhELGtCQUF5QixDQUFZO0lBQ25DLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssU0FBUyxDQUFDO0FBQ25DLENBQUM7QUFGRCw0QkFFQztBQUVELHFCQUE0QixDQUFZO0lBQ3RDLE1BQU0sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssU0FBUyxDQUFDO0FBQ3RDLENBQUM7QUFGRCxrQ0FFQztBQUVELGVBQXNCLENBQVk7SUFDaEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEIsQ0FBQztBQUZELHNCQUVDO0FBRUQsb0JBQTJCLENBQVk7SUFDckMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDckMsQ0FBQztBQUZELGdDQUVDO0FBRUQscUJBQTRCLENBQVk7SUFDdEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDdEMsQ0FBQztBQUZELGtDQUVDO0FBSUQsNEJBQW1DLFNBQXNCO0lBQ3ZELE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQUEsQ0FBQztRQUNwQixFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hCLE1BQU0sQ0FBQztnQkFDTCxNQUFNLEVBQUUsaUNBQXVCLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSx3QkFBZSxDQUFDO2FBQzNELENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQVRELGdEQVNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBZ2dyZWdhdGVPcH0gZnJvbSAnLi9hZ2dyZWdhdGUnO1xuaW1wb3J0IHtCaW5QYXJhbXN9IGZyb20gJy4vYmluJztcbmltcG9ydCB7RGF0YX0gZnJvbSAnLi9kYXRhJztcbmltcG9ydCB7RmlsdGVyLCBub3JtYWxpemVGaWx0ZXJ9IGZyb20gJy4vZmlsdGVyJztcbmltcG9ydCB7TG9naWNhbE9wZXJhbmQsIG5vcm1hbGl6ZUxvZ2ljYWxPcGVyYW5kfSBmcm9tICcuL2xvZ2ljYWwnO1xuaW1wb3J0IHtUaW1lVW5pdH0gZnJvbSAnLi90aW1ldW5pdCc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJUcmFuc2Zvcm0ge1xuICAvKipcbiAgICogVGhlIGBmaWx0ZXJgIHByb3BlcnR5IG11c3QgYmUgZWl0aGVyICgxKSBhIGZpbHRlciBvYmplY3QgZm9yIFtlcXVhbC1maWx0ZXJzXShmaWx0ZXIuaHRtbCNlcXVhbGZpbHRlciksXG4gICAqIFtyYW5nZS1maWx0ZXJzXShmaWx0ZXIuaHRtbCNyYW5nZWZpbHRlciksIFtvbmUtb2YgZmlsdGVyc10oZmlsdGVyLmh0bWwjb25lb2ZmaWx0ZXIpLCBvciBbc2VsZWN0aW9uIGZpbHRlcnNdKGZpbHRlci5odG1sI3NlbGVjdGlvbmZpbHRlcik7XG4gICAqICgyKSBhIFtWZWdhIEV4cHJlc3Npb25dKGZpbHRlci5odG1sI2V4cHJlc3Npb24pIHN0cmluZyxcbiAgICogd2hlcmUgYGRhdHVtYCBjYW4gYmUgdXNlZCB0byByZWZlciB0byB0aGUgY3VycmVudCBkYXRhIG9iamVjdDsgb3IgKDMpIGFuIGFycmF5IG9mIGZpbHRlcnMgKGVpdGhlciBvYmplY3RzIG9yIGV4cHJlc3Npb24gc3RyaW5ncykgdGhhdCBtdXN0IGFsbCBiZSB0cnVlIGZvciBhIGRhdHVtIHRvIHBhc3MgdGhlIGZpbHRlciBhbmQgYmUgaW5jbHVkZWQuXG4gICAqL1xuICBmaWx0ZXI6IExvZ2ljYWxPcGVyYW5kPEZpbHRlcj47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZpbHRlcih0OiBUcmFuc2Zvcm0pOiB0IGlzIEZpbHRlclRyYW5zZm9ybSB7XG4gIHJldHVybiB0WydmaWx0ZXInXSAhPT0gdW5kZWZpbmVkO1xufVxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsY3VsYXRlVHJhbnNmb3JtIHtcbiAgLyoqXG4gICAqIEEgc3RyaW5nIGNvbnRhaW5pbmcgYSBWZWdhIEV4cHJlc3Npb24uIFVzZSB0aGUgdmFyaWFibGUgYGRhdHVtYCB0byByZWZlciB0byB0aGUgY3VycmVudCBkYXRhIG9iamVjdC5cbiAgICovXG4gIGNhbGN1bGF0ZTogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZpZWxkIGZvciBzdG9yaW5nIHRoZSBjb21wdXRlZCBmb3JtdWxhIHZhbHVlLlxuICAgKi9cbiAgYXM6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCaW5UcmFuc2Zvcm0ge1xuICAvKipcbiAgICogQW4gb2JqZWN0IGluZGljYXRpbmcgYmluIHByb3BlcnRpZXMsIG9yIHNpbXBseSBgdHJ1ZWAgZm9yIHVzaW5nIGRlZmF1bHQgYmluIHBhcmFtZXRlcnMuXG4gICAqL1xuICBiaW46IGJvb2xlYW4gfCBCaW5QYXJhbXM7XG5cbiAgLyoqXG4gICAqIFRoZSBkYXRhIGZpZWxkIHRvIGJpbi5cbiAgICovXG4gIGZpZWxkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgZmllbGRzIGF0IHdoaWNoIHRvIHdyaXRlIHRoZSBzdGFydCBhbmQgZW5kIGJpbiB2YWx1ZXMuXG4gICAqL1xuICBhczogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVVbml0VHJhbnNmb3JtIHtcbiAgLyoqXG4gICAqIFRoZSB0aW1lVW5pdC5cbiAgICovXG4gIHRpbWVVbml0OiBUaW1lVW5pdDtcblxuICAvKipcbiAgICogVGhlIGRhdGEgZmllbGQgdG8gYXBwbHkgdGltZSB1bml0LlxuICAgKi9cbiAgZmllbGQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG91dHB1dCBmaWVsZCB0byB3cml0ZSB0aGUgdGltZVVuaXQgdmFsdWUuXG4gICAqL1xuICBhczogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFnZ3JlZ2F0ZVRyYW5zZm9ybSB7XG4gIC8qKlxuICAgKiBBcnJheSBvZiBvYmplY3RzIHRoYXQgZGVmaW5lIGZpZWxkcyB0byBhZ2dyZWdhdGUuXG4gICAqL1xuICBhZ2dyZWdhdGU6IEFnZ3JlZ2F0ZWRGaWVsZERlZltdO1xuXG4gIC8qKlxuICAgKiBUaGUgZGF0YSBmaWVsZHMgdG8gZ3JvdXAgYnkuIElmIG5vdCBzcGVjaWZpZWQsIGEgc2luZ2xlIGdyb3VwIGNvbnRhaW5pbmcgYWxsIGRhdGEgb2JqZWN0cyB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICBncm91cGJ5Pzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWdncmVnYXRlZEZpZWxkRGVmIHtcbiAgLyoqXG4gICAqIFRoZSBhZ2dyZWdhdGlvbiBvcGVyYXRpb25zIHRvIGFwcGx5IHRvIHRoZSBmaWVsZHMsIHN1Y2ggYXMgc3VtLCBhdmVyYWdlIG9yIGNvdW50LlxuICAgKiBTZWUgdGhlIFtmdWxsIGxpc3Qgb2Ygc3VwcG9ydGVkIGFnZ3JlZ2F0aW9uIG9wZXJhdGlvbnNdKGh0dHBzOi8vdmVnYS5naXRodWIuaW8vdmVnYS1saXRlL2RvY3MvYWdncmVnYXRlLmh0bWwjb3BzKVxuICAgKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICovXG4gIG9wOiBBZ2dyZWdhdGVPcDtcblxuICAvKipcbiAgICogVGhlIGRhdGEgZmllbGQgZm9yIHdoaWNoIHRvIGNvbXB1dGUgYWdncmVnYXRlIGZ1bmN0aW9uLlxuICAgKi9cbiAgZmllbGQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG91dHB1dCBmaWVsZCBuYW1lcyB0byB1c2UgZm9yIGVhY2ggYWdncmVnYXRlZCBmaWVsZC5cbiAgICovXG4gIGFzOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9va3VwRGF0YSB7XG4gIC8qKlxuICAgKiBTZWNvbmRhcnkgZGF0YSBzb3VyY2UgdG8gbG9va3VwIGluLlxuICAgKi9cbiAgZGF0YTogRGF0YTtcbiAgLyoqXG4gICAqIEtleSBpbiBkYXRhIHRvIGxvb2t1cC5cbiAgICovXG4gIGtleTogc3RyaW5nO1xuICAvKipcbiAgICogRmllbGRzIGluIGZvcmVpZ24gZGF0YSB0byBsb29rdXAuXG4gICAqIElmIG5vdCBzcGVjaWZpY2llZCwgdGhlIGVudGlyZSBvYmplY3QgaXMgcXVlcmllZC5cbiAgICovXG4gIGZpZWxkcz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExvb2t1cFRyYW5zZm9ybSB7XG4gIC8qKlxuICAgKiBLZXkgaW4gcHJpbWFyeSBkYXRhIHNvdXJjZS5cbiAgICovXG4gIGxvb2t1cDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTZWNvbmRhcnkgZGF0YSByZWZlcmVuY2UuXG4gICAqL1xuICBmcm9tOiBMb29rdXBEYXRhO1xuXG4gIC8qKlxuICAgKiBUaGUgZmllbGQgb3IgZmllbGRzIGZvciBzdG9yaW5nIHRoZSBjb21wdXRlZCBmb3JtdWxhIHZhbHVlLlxuICAgKiBJZiBgZnJvbS5maWVsZHNgIGlzIHNwZWNpZmllZCwgdGhlIHRyYW5zZm9ybSB3aWxsIHVzZSB0aGUgc2FtZSBuYW1lcyBmb3IgYGFzYC5cbiAgICogSWYgYGZyb20uZmllbGRzYCBpcyBub3Qgc3BlY2lmaWVkLCBgYXNgIGhhcyB0byBiZSBhIHN0cmluZyBhbmQgd2UgcHV0IHRoZSB3aG9sZSBvYmplY3QgaW50byB0aGUgZGF0YSB1bmRlciB0aGUgc3BlY2lmaWVkIG5hbWUuXG4gICAqL1xuICBhcz86IHN0cmluZyB8IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSB0byB1c2UgaWYgbG9va3VwIGZhaWxzLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYG51bGxgXG4gICAqL1xuICBkZWZhdWx0Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNMb29rdXAodDogVHJhbnNmb3JtKTogdCBpcyBMb29rdXBUcmFuc2Zvcm0ge1xuICByZXR1cm4gdFsnbG9va3VwJ10gIT09IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2FsY3VsYXRlKHQ6IFRyYW5zZm9ybSk6IHQgaXMgQ2FsY3VsYXRlVHJhbnNmb3JtIHtcbiAgcmV0dXJuIHRbJ2NhbGN1bGF0ZSddICE9PSB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Jpbih0OiBUcmFuc2Zvcm0pOiB0IGlzIEJpblRyYW5zZm9ybSB7XG4gIHJldHVybiAhIXRbJ2JpbiddO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNUaW1lVW5pdCh0OiBUcmFuc2Zvcm0pOiB0IGlzIFRpbWVVbml0VHJhbnNmb3JtIHtcbiAgcmV0dXJuIHRbJ3RpbWVVbml0J10gIT09IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQWdncmVnYXRlKHQ6IFRyYW5zZm9ybSk6IHQgaXMgQWdncmVnYXRlVHJhbnNmb3JtIHtcbiAgcmV0dXJuIHRbJ2FnZ3JlZ2F0ZSddICE9PSB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCB0eXBlIFRyYW5zZm9ybSA9IEZpbHRlclRyYW5zZm9ybSB8IENhbGN1bGF0ZVRyYW5zZm9ybSB8IExvb2t1cFRyYW5zZm9ybSB8IEJpblRyYW5zZm9ybSB8IFRpbWVVbml0VHJhbnNmb3JtIHwgQWdncmVnYXRlVHJhbnNmb3JtO1xuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplVHJhbnNmb3JtKHRyYW5zZm9ybTogVHJhbnNmb3JtW10pIHtcbiAgcmV0dXJuIHRyYW5zZm9ybS5tYXAodCA9PiB7XG4gICAgaWYgKGlzRmlsdGVyKHQpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmaWx0ZXI6IG5vcm1hbGl6ZUxvZ2ljYWxPcGVyYW5kKHQuZmlsdGVyLCBub3JtYWxpemVGaWx0ZXIpXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdDtcbiAgfSk7XG59XG4iXX0= \ 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..2749a32a8d --- /dev/null +++ b/build/src/type.d.ts @@ -0,0 +1,20 @@ +/** 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'; +} +export declare type Type = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL; +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"; +/** + * 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..2418d18904 --- /dev/null +++ b/build/src/type.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** 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 = exports.Type || (exports.Type = {})); +var TYPE_INDEX = { + quantitative: 1, + ordinal: 1, + temporal: 1, + nominal: 1 +}; +function isType(t) { + return !!TYPE_INDEX[t]; +} +exports.isType = isType; +exports.QUANTITATIVE = Type.QUANTITATIVE; +exports.ORDINAL = Type.ORDINAL; +exports.TEMPORAL = Type.TEMPORAL; +exports.NOMINAL = Type.NOMINAL; +/** + * 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 exports.QUANTITATIVE: + return 'quantitative'; + case 't': + case exports.TEMPORAL: + return 'temporal'; + case 'o': + case exports.ORDINAL: + return 'ordinal'; + case 'n': + case exports.NOMINAL: + return 'nominal'; + } + } + // If we get invalid input, return undefined type. + return undefined; +} +exports.getFullName = getFullName; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsNENBQTRDO0FBQzVDLDhDQUE4QztBQUU5QyxJQUFpQixJQUFJLENBS3BCO0FBTEQsV0FBaUIsSUFBSTtJQUNOLGlCQUFZLEdBQW1CLGNBQWMsQ0FBQztJQUM5QyxZQUFPLEdBQWMsU0FBUyxDQUFDO0lBQy9CLGFBQVEsR0FBZSxVQUFVLENBQUM7SUFDbEMsWUFBTyxHQUFjLFNBQVMsQ0FBQztBQUM5QyxDQUFDLEVBTGdCLElBQUksR0FBSixZQUFJLEtBQUosWUFBSSxRQUtwQjtBQUdELElBQU0sVUFBVSxHQUFlO0lBQzdCLFlBQVksRUFBRSxDQUFDO0lBQ2YsT0FBTyxFQUFFLENBQUM7SUFDVixRQUFRLEVBQUUsQ0FBQztJQUNYLE9BQU8sRUFBRSxDQUFDO0NBQ1gsQ0FBQztBQUVGLGdCQUF1QixDQUFNO0lBQzNCLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFGRCx3QkFFQztBQUVZLFFBQUEsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7QUFDakMsUUFBQSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN2QixRQUFBLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3pCLFFBQUEsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7QUFFcEM7Ozs7R0FJRztBQUNILHFCQUE0QixJQUFpQjtJQUMzQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ1QsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMxQixNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2IsS0FBSyxHQUFHLENBQUM7WUFDVCxLQUFLLG9CQUFZO2dCQUNmLE1BQU0sQ0FBQyxjQUFjLENBQUM7WUFDeEIsS0FBSyxHQUFHLENBQUM7WUFDVCxLQUFLLGdCQUFRO2dCQUNYLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDcEIsS0FBSyxHQUFHLENBQUM7WUFDVCxLQUFLLGVBQU87Z0JBQ1YsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUNuQixLQUFLLEdBQUcsQ0FBQztZQUNULEtBQUssZUFBTztnQkFDVixNQUFNLENBQUMsU0FBUyxDQUFDO1FBQ3JCLENBQUM7SUFDSCxDQUFDO0lBQ0Qsa0RBQWtEO0lBQ2xELE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQXBCRCxrQ0FvQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0ZsYWd9IGZyb20gJy4vdXRpbCc7XG4vKiogQ29uc3RhbnRzIGFuZCB1dGlsaXRpZXMgZm9yIGRhdGEgdHlwZSAqL1xuLyoqIERhdGEgdHlwZSBiYXNlZCBvbiBsZXZlbCBvZiBtZWFzdXJlbWVudCAqL1xuXG5leHBvcnQgbmFtZXNwYWNlIFR5cGUge1xuICBleHBvcnQgY29uc3QgUVVBTlRJVEFUSVZFOiAncXVhbnRpdGF0aXZlJyA9ICdxdWFudGl0YXRpdmUnO1xuICBleHBvcnQgY29uc3QgT1JESU5BTDogJ29yZGluYWwnID0gJ29yZGluYWwnO1xuICBleHBvcnQgY29uc3QgVEVNUE9SQUw6ICd0ZW1wb3JhbCcgPSAndGVtcG9yYWwnO1xuICBleHBvcnQgY29uc3QgTk9NSU5BTDogJ25vbWluYWwnID0gJ25vbWluYWwnO1xufVxuZXhwb3J0IHR5cGUgVHlwZSA9IHR5cGVvZiBUeXBlLlFVQU5USVRBVElWRSB8IHR5cGVvZiBUeXBlLk9SRElOQUwgfCB0eXBlb2YgVHlwZS5URU1QT1JBTCB8IHR5cGVvZiBUeXBlLk5PTUlOQUw7XG5cbmNvbnN0IFRZUEVfSU5ERVg6IEZsYWc8VHlwZT4gPSB7XG4gIHF1YW50aXRhdGl2ZTogMSxcbiAgb3JkaW5hbDogMSxcbiAgdGVtcG9yYWw6IDEsXG4gIG5vbWluYWw6IDFcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1R5cGUodDogYW55KTogdCBpcyBUeXBlIHtcbiAgcmV0dXJuICEhVFlQRV9JTkRFWFt0XTtcbn1cblxuZXhwb3J0IGNvbnN0IFFVQU5USVRBVElWRSA9IFR5cGUuUVVBTlRJVEFUSVZFO1xuZXhwb3J0IGNvbnN0IE9SRElOQUwgPSBUeXBlLk9SRElOQUw7XG5leHBvcnQgY29uc3QgVEVNUE9SQUwgPSBUeXBlLlRFTVBPUkFMO1xuZXhwb3J0IGNvbnN0IE5PTUlOQUwgPSBUeXBlLk5PTUlOQUw7XG5cbi8qKlxuICogR2V0IGZ1bGwsIGxvd2VyY2FzZSB0eXBlIG5hbWUgZm9yIGEgZ2l2ZW4gdHlwZS5cbiAqIEBwYXJhbSAgdHlwZVxuICogQHJldHVybiBGdWxsIHR5cGUgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bGxOYW1lKHR5cGU6IFR5cGV8c3RyaW5nKTogVHlwZSB7XG4gIGlmICh0eXBlKSB7XG4gICAgdHlwZSA9IHR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ3EnOlxuICAgICAgY2FzZSBRVUFOVElUQVRJVkU6XG4gICAgICAgIHJldHVybiAncXVhbnRpdGF0aXZlJztcbiAgICAgIGNhc2UgJ3QnOlxuICAgICAgY2FzZSBURU1QT1JBTDpcbiAgICAgICAgcmV0dXJuICd0ZW1wb3JhbCc7XG4gICAgICBjYXNlICdvJzpcbiAgICAgIGNhc2UgT1JESU5BTDpcbiAgICAgICAgcmV0dXJuICdvcmRpbmFsJztcbiAgICAgIGNhc2UgJ24nOlxuICAgICAgY2FzZSBOT01JTkFMOlxuICAgICAgICByZXR1cm4gJ25vbWluYWwnO1xuICAgIH1cbiAgfVxuICAvLyBJZiB3ZSBnZXQgaW52YWxpZCBpbnB1dCwgcmV0dXJuIHVuZGVmaW5lZCB0eXBlLlxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIl19 \ 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..dd72f1bcbd --- /dev/null +++ b/build/src/util.d.ts @@ -0,0 +1,82 @@ +import { LogicalOperand } from './logical'; +export { isArray, isObject, isNumber, isString, truncate, toSet, stringValue, splitAccessPath } from 'vega-util'; +/** + * 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: object, props: string[]): {}; +/** + * 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: object, props: string[]): object; +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) => (keyof T)[]; +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 Diff = ({ + [P in T]: P; +} & { + [P in U]: never; +} & { + [x: string]: never; +})[T]; +export declare type Omit = { + [P in Diff]: T[P]; +}; +/** + * 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[]): void; +export declare function titlecase(s: string): string; +/** + * Converts a path to an access path. + */ +export declare function accessPath(path: string): string; diff --git a/build/src/util.js b/build/src/util.js new file mode 100644 index 0000000000..6d11eeb3ef --- /dev/null +++ b/build/src/util.js @@ -0,0 +1,284 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var vega_util_1 = require("vega-util"); +var logical_1 = require("./logical"); +var vega_util_2 = require("vega-util"); +exports.isArray = vega_util_2.isArray; +exports.isObject = vega_util_2.isObject; +exports.isNumber = vega_util_2.isNumber; +exports.isString = vega_util_2.isString; +exports.truncate = vega_util_2.truncate; +exports.toSet = vega_util_2.toSet; +exports.stringValue = vega_util_2.stringValue; +exports.splitAccessPath = vega_util_2.splitAccessPath; +/** + * 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; +} +exports.pick = 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. + */ +function omit(obj, props) { + var copy = duplicate(obj); + for (var _i = 0, props_2 = props; _i < props_2.length; _i++) { + var prop = props_2[_i]; + delete copy[prop]; + } + return copy; +} +exports.omit = omit; +function hash(a) { + if (vega_util_1.isString(a) || vega_util_1.isNumber(a) || isBoolean(a)) { + return String(a); + } + var str = stringify(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; +} +exports.hash = hash; +function contains(array, item) { + return array.indexOf(item) > -1; +} +exports.contains = contains; +/** Returns the array without the elements in item */ +function without(array, excludedItems) { + return array.filter(function (item) { return !contains(excludedItems, item); }); +} +exports.without = without; +function union(array, other) { + return array.concat(without(other, array)); +} +exports.union = union; +/** + * 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; +} +exports.some = some; +/** + * 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; +} +exports.every = every; +function flatten(arrays) { + return [].concat.apply([], arrays); +} +exports.flatten = flatten; +/** + * 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; +} +exports.mergeDeep = mergeDeep; +// 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' || vega_util_1.isArray(src[p]) || src[p] === null) { + dest[p] = src[p]; + } + else if (typeof dest[p] !== 'object' || dest[p] === null) { + dest[p] = mergeDeep(vega_util_1.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; +} +exports.unique = unique; +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +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; +} +exports.differ = differ; +function hasIntersection(a, b) { + for (var key in a) { + if (key in b) { + return true; + } + } + return false; +} +exports.hasIntersection = hasIntersection; +function isNumeric(num) { + return !isNaN(num); +} +exports.isNumeric = isNumeric; +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; +} +exports.differArray = differArray; +// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208 +exports.keys = Object.keys; +function vals(x) { + var _vals = []; + for (var k in x) { + if (x.hasOwnProperty(k)) { + _vals.push(x[k]); + } + } + return _vals; +} +exports.vals = vals; +function flagKeys(f) { + return exports.keys(f); +} +exports.flagKeys = flagKeys; +function duplicate(obj) { + return JSON.parse(JSON.stringify(obj)); +} +exports.duplicate = duplicate; +function isBoolean(b) { + return b === true || b === false; +} +exports.isBoolean = isBoolean; +/** + * 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; +} +exports.varName = varName; +function logicalExpr(op, cb) { + if (logical_1.isLogicalNot(op)) { + return '!(' + logicalExpr(op.not, cb) + ')'; + } + else if (logical_1.isLogicalAnd(op)) { + return '(' + op.and.map(function (and) { return logicalExpr(and, cb); }).join(') && (') + ')'; + } + else if (logical_1.isLogicalOr(op)) { + return '(' + op.or.map(function (or) { return logicalExpr(or, cb); }).join(') || (') + ')'; + } + else { + return cb(op); + } +} +exports.logicalExpr = logicalExpr; +/** + * Delete nested property of an object, and delete the ancestors of the property if they become empty. + */ +function deleteNestedProperty(obj, orderedProps) { + var isEmpty = true; + while (orderedProps.length > 0 && isEmpty) { + var o = obj; + for (var i = 0; i < orderedProps.length - 1; i++) { + o = o[orderedProps[i]]; + } + delete o[orderedProps.pop()]; + if (exports.keys(o).length !== 0) { + isEmpty = false; + } + } +} +exports.deleteNestedProperty = deleteNestedProperty; +function titlecase(s) { + return s.charAt(0).toUpperCase() + s.substr(1); +} +exports.titlecase = titlecase; +/** + * Converts a path to an access path. + */ +function accessPath(path) { + return "[" + vega_util_1.splitAccessPath(path).map(vega_util_1.stringValue).join('][') + "]"; +} +exports.accessPath = accessPath; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaURBQW1EO0FBQ25ELHVDQUFvRjtBQUNwRixxQ0FBa0Y7QUFHbEYsdUNBQStHO0FBQXZHLDhCQUFBLE9BQU8sQ0FBQTtBQUFFLCtCQUFBLFFBQVEsQ0FBQTtBQUFFLCtCQUFBLFFBQVEsQ0FBQTtBQUFFLCtCQUFBLFFBQVEsQ0FBQTtBQUFFLCtCQUFBLFFBQVEsQ0FBQTtBQUFFLDRCQUFBLEtBQUssQ0FBQTtBQUFFLGtDQUFBLFdBQVcsQ0FBQTtBQUFFLHNDQUFBLGVBQWUsQ0FBQTtBQUU1Rjs7Ozs7Ozs7O0dBU0c7QUFDSCxjQUFxQixHQUFXLEVBQUUsS0FBZTtJQUMvQyxJQUFNLElBQUksR0FBRyxFQUFFLENBQUM7SUFDaEIsR0FBRyxDQUFDLENBQWUsVUFBSyxFQUFMLGVBQUssRUFBTCxtQkFBSyxFQUFMLElBQUs7UUFBbkIsSUFBTSxJQUFJLGNBQUE7UUFDYixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUM7S0FDRjtJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBUkQsb0JBUUM7QUFFRDs7O0dBR0c7QUFDSCxjQUFxQixHQUFXLEVBQUUsS0FBZTtJQUMvQyxJQUFNLElBQUksR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsR0FBRyxDQUFDLENBQWUsVUFBSyxFQUFMLGVBQUssRUFBTCxtQkFBSyxFQUFMLElBQUs7UUFBbkIsSUFBTSxJQUFJLGNBQUE7UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUNuQjtJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FB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SUFDckMsTUFBTSxDQUFDLE1BQUksMkJBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsdUJBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBRyxDQUFDO0FBQ2xFLENBQUM7QUFGRCxnQ0FFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHN0cmluZ2lmeSBmcm9tICdqc29uLXN0YWJsZS1zdHJpbmdpZnknO1xuaW1wb3J0IHtpc0FycmF5LCBpc051bWJlciwgaXNTdHJpbmcsIHNwbGl0QWNjZXNzUGF0aCwgc3RyaW5nVmFsdWV9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5pbXBvcnQge2lzTG9naWNhbEFuZCwgaXNMb2dpY2FsTm90LCBpc0xvZ2ljYWxPciwgTG9naWNhbE9wZXJhbmR9IGZyb20gJy4vbG9naWNhbCc7XG5cblxuZXhwb3J0IHtpc0FycmF5LCBpc09iamVjdCwgaXNOdW1iZXIsIGlzU3RyaW5nLCB0cnVuY2F0ZSwgdG9TZXQsIHN0cmluZ1ZhbHVlLCBzcGxpdEFjY2Vzc1BhdGh9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIHBpY2tlZCBvYmplY3QgcHJvcGVydGllcy5cbiAqXG4gKiBFeGFtcGxlOiAgKGZyb20gbG9kYXNoKVxuICpcbiAqIHZhciBvYmplY3QgPSB7J2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzfTtcbiAqIHBpY2sob2JqZWN0LCBbJ2EnLCAnYyddKTtcbiAqIC8vIOKGkiB7J2EnOiAxLCAnYyc6IDN9XG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGljayhvYmo6IG9iamVjdCwgcHJvcHM6IHN0cmluZ1tdKSB7XG4gIGNvbnN0IGNvcHkgPSB7fTtcbiAgZm9yIChjb25zdCBwcm9wIG9mIHByb3BzKSB7XG4gICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSkge1xuICAgICAgY29weVtwcm9wXSA9IG9ialtwcm9wXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvcHk7XG59XG5cbi8qKlxuICogVGhlIG9wcG9zaXRlIG9mIF8ucGljazsgdGhpcyBtZXRob2QgY3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIG93blxuICogYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIG9iamVjdCB0aGF0IGFyZSBub3Qgb21pdHRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9taXQob2JqOiBvYmplY3QsIHByb3BzOiBzdHJpbmdbXSkge1xuICBjb25zdCBjb3B5ID0gZHVwbGljYXRlKG9iaik7XG4gIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcykge1xuICAgIGRlbGV0ZSBjb3B5W3Byb3BdO1xuICB9XG4gIHJldHVybiBjb3B5O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzaChhOiBhbnkpIHtcbiAgaWYgKGlzU3RyaW5nKGEpIHx8IGlzTnVtYmVyKGEpIHx8IGlzQm9vbGVhbihhKSkge1xuICAgIHJldHVybiBTdHJpbmcoYSk7XG4gIH1cblxuICBjb25zdCBzdHIgPSBzdHJpbmdpZnkoYSk7XG5cbiAgLy8gc2hvcnQgc3RyaW5ncyBjYW4gYmUgdXNlZCBhcyBoYXNoIGRpcmVjdGx5LCBsb25nZXIgc3RyaW5ncyBhcmUgaGFzaGVkIHRvIHJlZHVjZSBtZW1vcnkgdXNhZ2VcbiAgaWYgKHN0ci5sZW5ndGggPCAxMDApIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG5cbiAgLy8gZnJvbSBodHRwOi8vd2VyeGx0ZC5jb20vd3AvMjAxMC8wNS8xMy9qYXZhc2NyaXB0LWltcGxlbWVudGF0aW9uLW9mLWphdmFzLXN0cmluZy1oYXNoY29kZS1tZXRob2QvXG4gIGxldCBoID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGFyID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgaCA9ICgoaDw8NSktaCkrY2hhcjtcbiAgICBoID0gaCAmIGg7IC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuICB9XG4gIHJldHVybiBoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnM8VD4oYXJyYXk6IFRbXSwgaXRlbTogVCkge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSA+IC0xO1xufVxuXG4vKiogUmV0dXJucyB0aGUgYXJyYXkgd2l0aG91dCB0aGUgZWxlbWVudHMgaW4gaXRlbSAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhvdXQ8VD4oYXJyYXk6IFRbXSwgZXhjbHVkZWRJdGVtczogVFtdKSB7XG4gIHJldHVybiBhcnJheS5maWx0ZXIoaXRlbSA9PiAhY29udGFpbnMoZXhjbHVkZWRJdGVtcywgaXRlbSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pb248VD4oYXJyYXk6IFRbXSwgb3RoZXI6IFRbXSkge1xuICByZXR1cm4gYXJyYXkuY29uY2F0KHdpdGhvdXQob3RoZXIsIGFycmF5KSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIGFueSBpdGVtIHJldHVybnMgdHJ1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvbWU8VD4oYXJyOiBUW10sIGY6IChkOiBULCBrPzogYW55LCBpPzogYW55KSA9PiBib29sZWFuKSB7XG4gIGxldCBpID0gMDtcbiAgZm9yIChsZXQgayA9IDA7IGs8YXJyLmxlbmd0aDsgaysrKSB7XG4gICAgaWYgKGYoYXJyW2tdLCBrLCBpKyspKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgaXRlbXMgcmV0dXJuIHRydWUuXG4gKi9cbiBleHBvcnQgZnVuY3Rpb24gZXZlcnk8VD4oYXJyOiBUW10sIGY6IChkOiBULCBrPzogYW55LCBpPzogYW55KSA9PiBib29sZWFuKSB7XG4gIGxldCBpID0gMDtcbiAgZm9yIChsZXQgayA9IDA7IGs8YXJyLmxlbmd0aDsgaysrKSB7XG4gICAgaWYgKCFmKGFycltrXSwgaywgaSsrKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXlzOiBhbnlbXSkge1xuICByZXR1cm4gW10uY29uY2F0LmFwcGx5KFtdLCBhcnJheXMpO1xufVxuXG4vKipcbiAqIHJlY3Vyc2l2ZWx5IG1lcmdlcyBzcmMgaW50byBkZXN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZXA8VD4oZGVzdDogVCwgLi4uc3JjOiBQYXJ0aWFsPFQ+W10pOiBUIHtcbiAgZm9yIChjb25zdCBzIG9mIHNyYykge1xuICAgIGRlc3QgPSBkZWVwTWVyZ2VfKGRlc3QsIHMpO1xuICB9XG4gIHJldHVybiBkZXN0O1xufVxuXG4vLyByZWN1cnNpdmVseSBtZXJnZXMgc3JjIGludG8gZGVzdFxuZnVuY3Rpb24gZGVlcE1lcmdlXyhkZXN0OiBhbnksIHNyYzogYW55KSB7XG4gIGlmICh0eXBlb2Ygc3JjICE9PSAnb2JqZWN0JyB8fCBzcmMgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZGVzdDtcbiAgfVxuXG4gIGZvciAoY29uc3QgcCBpbiBzcmMpIHtcbiAgICBpZiAoIXNyYy5oYXNPd25Qcm9wZXJ0eShwKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChzcmNbcF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygc3JjW3BdICE9PSAnb2JqZWN0JyB8fCBpc0FycmF5KHNyY1twXSkgfHwgc3JjW3BdID09PSBudWxsKSB7XG4gICAgICBkZXN0W3BdID0gc3JjW3BdO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlc3RbcF0gIT09ICdvYmplY3QnIHx8IGRlc3RbcF0gPT09IG51bGwpIHtcbiAgICAgIGRlc3RbcF0gPSBtZXJnZURlZXAoaXNBcnJheShzcmNbcF0uY29uc3RydWN0b3IpID8gW10gOiB7fSwgc3JjW3BdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VEZWVwKGRlc3RbcF0sIHNyY1twXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBkZXN0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pcXVlPFQ+KHZhbHVlczogVFtdLCBmOiAoaXRlbTogVCkgPT4gc3RyaW5nIHwgbnVtYmVyKTogVFtdIHtcbiAgY29uc3QgcmVzdWx0czogYW55W10gPSBbXTtcbiAgY29uc3QgdSA9IHt9O1xuICBsZXQgdjogc3RyaW5nIHwgbnVtYmVyO1xuICBmb3IgKGNvbnN0IHZhbCBvZiB2YWx1ZXMpIHtcbiAgICB2ID0gZih2YWwpO1xuICAgIGlmICh2IGluIHUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB1W3ZdID0gMTtcbiAgICByZXN1bHRzLnB1c2godmFsKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaWN0PFQ+IHtcbiAgW2tleTogc3RyaW5nXTogVDtcbn1cblxuZXhwb3J0IHR5cGUgU3RyaW5nU2V0ID0gRGljdDxib29sZWFuPjtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBkaWN0aW9uYXJpZXMgZGlzYWdyZWUuIEFwcGxpZXMgb25seSB0byBkZWZpbmVkIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpZmZlcjxUPihkaWN0OiBEaWN0PFQ+LCBvdGhlcjogRGljdDxUPikge1xuICBmb3IgKGNvbnN0IGtleSBpbiBkaWN0KSB7XG4gICAgaWYgKGRpY3QuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgaWYgKG90aGVyW2tleV0gJiYgZGljdFtrZXldICYmIG90aGVyW2tleV0gIT09IGRpY3Rba2V5XSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzSW50ZXJzZWN0aW9uKGE6IFN0cmluZ1NldCwgYjogU3RyaW5nU2V0KSB7XG4gIGZvciAoY29uc3Qga2V5IGluIGEpIHtcbiAgICBpZiAoa2V5IGluIGIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bWVyaWMobnVtOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgcmV0dXJuICFpc05hTihudW0gYXMgYW55KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZlckFycmF5PFQ+KGFycmF5OiBUW10sIG90aGVyOiBUW10pIHtcbiAgaWYgKGFycmF5Lmxlbmd0aCAhPT0gb3RoZXIubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhcnJheS5zb3J0KCk7XG4gIG90aGVyLnNvcnQoKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG90aGVyW2ldICE9PSBhcnJheVtpXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBUaGlzIGlzIGEgc3RyaWN0ZXIgdmVyc2lvbiBvZiBPYmplY3Qua2V5cyBidXQgd2l0aCBiZXR0ZXIgdHlwZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vTWljcm9zb2Z0L1R5cGVTY3JpcHQvcHVsbC8xMjI1MyNpc3N1ZWNvbW1lbnQtMjYzMTMyMjA4XG5leHBvcnQgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzIGFzIDxUPihvOiBUKSA9PiAoa2V5b2YgVClbXTtcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbHM8VD4oeDoge1trZXk6IHN0cmluZ106IFR9KTogVFtdIHtcbiAgY29uc3QgX3ZhbHM6IFRbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGsgaW4geCkge1xuICAgIGlmICh4Lmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICBfdmFscy5wdXNoKHhba10pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gX3ZhbHM7XG59XG5cbi8vIFVzaW5nIG1hcHBlZCB0eXBlIHRvIGRlY2xhcmUgYSBjb2xsZWN0IG9mIGZsYWdzIGZvciBhIHN0cmluZyBsaXRlcmFsIHR5cGUgU1xuLy8gaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svYWR2YW5jZWQtdHlwZXMuaHRtbCNtYXBwZWQtdHlwZXNcbmV4cG9ydCB0eXBlIEZsYWc8UyBleHRlbmRzIHN0cmluZz4gPSB7XG4gIFtLIGluIFNdOiAxXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZmxhZ0tleXM8UyBleHRlbmRzIHN0cmluZz4oZjogRmxhZzxTPik6IFNbXSB7XG4gIHJldHVybiBrZXlzKGYpIGFzIFNbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGR1cGxpY2F0ZTxUPihvYmo6IFQpOiBUIHtcbiAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob2JqKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Jvb2xlYW4oYjogYW55KTogYiBpcyBib29sZWFuIHtcbiAgcmV0dXJuIGIgPT09IHRydWUgfHwgYiA9PT0gZmFsc2U7XG59XG5cbi8qKlxuICogQ29udmVydCBhIHN0cmluZyBpbnRvIGEgdmFsaWQgdmFyaWFibGUgbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFyTmFtZShzOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBSZXBsYWNlIG5vbi1hbHBoYW51bWVyaWMgY2hhcmFjdGVycyAoYW55dGhpbmcgYmVzaWRlcyBhLXpBLVowLTlfKSB3aXRoIF9cbiAgY29uc3QgYWxwaGFudW1lcmljUyA9IHMucmVwbGFjZSgvXFxXL2csICdfJyk7XG5cbiAgLy8gQWRkIF8gaWYgdGhlIHN0cmluZyBoYXMgbGVhZGluZyBudW1iZXJzLlxuICByZXR1cm4gKHMubWF0Y2goL15cXGQrLykgPyAnXycgOiAnJykgKyBhbHBoYW51bWVyaWNTO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9naWNhbEV4cHI8VD4ob3A6IExvZ2ljYWxPcGVyYW5kPFQ+LCBjYjogRnVuY3Rpb24pOiBzdHJpbmcge1xuICBpZiAoaXNMb2dpY2FsTm90KG9wKSkge1xuICAgIHJldHVybiAnISgnICsgbG9naWNhbEV4cHIob3Aubm90LCBjYikgKyAnKSc7XG4gIH0gZWxzZSBpZiAoaXNMb2dpY2FsQW5kKG9wKSkge1xuICAgIHJldHVybiAnKCcgKyBvcC5hbmQubWFwKChhbmQ6IExvZ2ljYWxPcGVyYW5kPFQ+KSA9PiBsb2dpY2FsRXhwcihhbmQsIGNiKSkuam9pbignKSAmJiAoJykgKyAnKSc7XG4gIH0gZWxzZSBpZiAoaXNMb2dpY2FsT3Iob3ApKSB7XG4gICAgcmV0dXJuICcoJyArIG9wLm9yLm1hcCgob3I6IExvZ2ljYWxPcGVyYW5kPFQ+KSA9PiBsb2dpY2FsRXhwcihvciwgY2IpKS5qb2luKCcpIHx8ICgnKSArICcpJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY2Iob3ApO1xuICB9XG59XG5cbi8vIE9taXQgZnJvbSBodHRwOi8vaWRlYXNpbnRvc29mdHdhcmUuY29tL3R5cGVzY3JpcHQtYWR2YW5jZWQtdHJpY2tzL1xuZXhwb3J0IHR5cGUgRGlmZjxUIGV4dGVuZHMgc3RyaW5nLCBVIGV4dGVuZHMgc3RyaW5nPiA9ICh7W1AgaW4gVF06IFAgfSAmIHtbUCBpbiBVXTogbmV2ZXIgfSAmIHsgW3g6IHN0cmluZ106IG5ldmVyIH0pW1RdO1xuZXhwb3J0IHR5cGUgT21pdDxULCBLIGV4dGVuZHMga2V5b2YgVD4gPSB7W1AgaW4gRGlmZjxrZXlvZiBULCBLPl06IFRbUF19O1xuXG4vKipcbiAqIERlbGV0ZSBuZXN0ZWQgcHJvcGVydHkgb2YgYW4gb2JqZWN0LCBhbmQgZGVsZXRlIHRoZSBhbmNlc3RvcnMgb2YgdGhlIHByb3BlcnR5IGlmIHRoZXkgYmVjb21lIGVtcHR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlTmVzdGVkUHJvcGVydHkob2JqOiBhbnksIG9yZGVyZWRQcm9wczogc3RyaW5nW10pIHtcbiAgbGV0IGlzRW1wdHkgPSB0cnVlO1xuICB3aGlsZSAob3JkZXJlZFByb3BzLmxlbmd0aCA+IDAgJiYgaXNFbXB0eSkge1xuICAgIGxldCBvID0gb2JqO1xuICAgIGZvciAobGV0IGk9MDsgaSA8IG9yZGVyZWRQcm9wcy5sZW5ndGgtMTsgaSsrKSB7XG4gICAgICBvID0gb1tvcmRlcmVkUHJvcHNbaV1dO1xuICAgIH1cbiAgICBkZWxldGUgb1tvcmRlcmVkUHJvcHMucG9wKCldO1xuICAgIGlmIChrZXlzKG8pLmxlbmd0aCAhPT0gMCkge1xuICAgICAgaXNFbXB0eSA9IGZhbHNlO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdGl0bGVjYXNlKHM6IHN0cmluZykge1xuICByZXR1cm4gcy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHMuc3Vic3RyKDEpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgcGF0aCB0byBhbiBhY2Nlc3MgcGF0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFjY2Vzc1BhdGgocGF0aDogc3RyaW5nKSB7XG4gIHJldHVybiBgWyR7c3BsaXRBY2Nlc3NQYXRoKHBhdGgpLm1hcChzdHJpbmdWYWx1ZSkuam9pbignXVsnKX1dYDtcbn1cbiJdfQ== \ 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..e6aef5bc42 --- /dev/null +++ b/build/src/validate.js @@ -0,0 +1,67 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var mark_1 = require("./mark"); +var mark_2 = require("./mark"); +var util_1 = require("./util"); +/** + * Required Encoding Channels for each mark type + */ +exports.DEFAULT_REQUIRED_CHANNEL_MAP = { + text: ['text'], + line: ['x', 'y'], + area: ['x', 'y'] +}; +/** + * Supported Encoding Channel for each mark type + */ +exports.DEFAULT_SUPPORTED_CHANNEL_TYPE = { + bar: util_1.toSet(['row', 'column', 'x', 'y', 'size', 'color', 'detail']), + line: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + area: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + tick: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + circle: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + square: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + point: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']), + text: util_1.toSet(['row', 'column', 'size', 'color', '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 = exports.DEFAULT_REQUIRED_CHANNEL_MAP; } + if (supportedChannelMap === void 0) { supportedChannelMap = exports.DEFAULT_SUPPORTED_CHANNEL_TYPE; } + var mark = mark_1.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) { + if (!(requiredChannels[i] in encoding)) { + return 'Missing encoding channel \"' + requiredChannels[i] + + '\" for mark \"' + mark + '\"'; + } + } + for (var channel in encoding) { + if (!supportedChannels[channel]) { + return 'Encoding channel \"' + channel + + '\" is not supported by mark type \"' + mark + '\"'; + } + } + if (mark === mark_2.BAR && !encoding.x && !encoding.y) { + return 'Missing both x and y for bar'; + } + return null; +} +exports.getEncodingMappingError = getEncodingMappingError; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBaUM7QUFDakMsK0JBQTJCO0FBRTNCLCtCQUE2QjtBQVM3Qjs7R0FFRztBQUNVLFFBQUEsNEJBQTRCLEdBQXVCO0lBQzlELElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNkLElBQUksRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7SUFDaEIsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztDQUNqQixDQUFDO0FBUUY7O0dBRUc7QUFDVSxRQUFBLDhCQUE4QixHQUF3QjtJQUNqRSxHQUFHLEVBQUUsWUFBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDbEUsSUFBSSxFQUFFLFlBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDM0QsSUFBSSxFQUFFLFlBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDM0QsSUFBSSxFQUFFLFlBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDM0QsTUFBTSxFQUFFLFlBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sRUFBRSxZQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNyRSxLQUFLLEVBQUUsWUFBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzdFLElBQUksRUFBRSxZQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxvQkFBb0I7Q0FDN0UsQ0FBQztBQUVGLHNEQUFzRDtBQUN0RCw4Q0FBOEM7QUFFOUM7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsaUNBQXdDLElBQThCLEVBQ3BFLGtCQUFxRSxFQUNyRSxtQkFBeUU7SUFEekUsbUNBQUEsRUFBQSxxQkFBeUMsb0NBQTRCO0lBQ3JFLG9DQUFBLEVBQUEsc0JBQTJDLHNDQUE4QjtJQUV6RSxJQUFNLElBQUksR0FBRyxnQkFBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDL0QsSUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUMvQixJQUFNLGdCQUFnQixHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xELElBQU0saUJBQWlCLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFcEQsR0FBRyxDQUFDLENBQUMsSUFBTSxDQUFDLElBQUksZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkMsTUFBTSxDQUFDLDZCQUE2QixHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQztnQkFDeEQsZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztJQUVELEdBQUcsQ0FBQyxDQUFDLElBQU0sT0FBTyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDL0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLHFCQUFxQixHQUFHLE9BQU87Z0JBQ3BDLHFDQUFxQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7UUFDeEQsQ0FBQztJQUNILENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssVUFBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQztJQUN4QyxDQUFDO0lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQztBQUNkLENBQUM7QUE1QkQsMERBNEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtpc01hcmtEZWZ9IGZyb20gJy4vbWFyayc7XG5pbXBvcnQge0JBUn0gZnJvbSAnLi9tYXJrJztcbmltcG9ydCB7RmFjZXRlZENvbXBvc2l0ZVVuaXRTcGVjfSBmcm9tICcuL3NwZWMnO1xuaW1wb3J0IHt0b1NldH0gZnJvbSAnLi91dGlsJztcblxuXG5cbi8vIFRPRE86IG1vdmUgdG8gdmwuc3BlYy52YWxpZGF0b3I/XG5leHBvcnQgaW50ZXJmYWNlIFJlcXVpcmVkQ2hhbm5lbE1hcCB7XG4gIFttYXJrOiBzdHJpbmddOiBBcnJheTxzdHJpbmc+O1xufVxuXG4vKipcbiAqIFJlcXVpcmVkIEVuY29kaW5nIENoYW5uZWxzIGZvciBlYWNoIG1hcmsgdHlwZVxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9SRVFVSVJFRF9DSEFOTkVMX01BUDogUmVxdWlyZWRDaGFubmVsTWFwID0ge1xuICB0ZXh0OiBbJ3RleHQnXSxcbiAgbGluZTogWyd4JywgJ3knXSxcbiAgYXJlYTogWyd4JywgJ3knXVxufTtcblxuZXhwb3J0IGludGVyZmFjZSBTdXBwb3J0ZWRDaGFubmVsTWFwIHtcbiAgW21hcms6IHN0cmluZ106IHtcbiAgICBbY2hhbm5lbDogc3RyaW5nXTogYm9vbGVhblxuICB9O1xufVxuXG4vKipcbiAqIFN1cHBvcnRlZCBFbmNvZGluZyBDaGFubmVsIGZvciBlYWNoIG1hcmsgdHlwZVxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TVVBQT1JURURfQ0hBTk5FTF9UWVBFOiBTdXBwb3J0ZWRDaGFubmVsTWFwID0ge1xuICBiYXI6IHRvU2V0KFsncm93JywgJ2NvbHVtbicsICd4JywgJ3knLCAnc2l6ZScsICdjb2xvcicsICdkZXRhaWwnXSksXG4gIGxpbmU6IHRvU2V0KFsncm93JywgJ2NvbHVtbicsICd4JywgJ3knLCAnY29sb3InLCAnZGV0YWlsJ10pLCAvLyBUT0RPOiBhZGQgc2l6ZSB3aGVuIFZlZ2Egc3VwcG9ydHNcbiAgYXJlYTogdG9TZXQoWydyb3cnLCAnY29sdW1uJywgJ3gnLCAneScsICdjb2xvcicsICdkZXRhaWwnXSksXG4gIHRpY2s6IHRvU2V0KFsncm93JywgJ2NvbHVtbicsICd4JywgJ3knLCAnY29sb3InLCAnZGV0YWlsJ10pLFxuICBjaXJjbGU6IHRvU2V0KFsncm93JywgJ2NvbHVtbicsICd4JywgJ3knLCAnY29sb3InLCAnc2l6ZScsICdkZXRhaWwnXSksXG4gIHNxdWFyZTogdG9TZXQoWydyb3cnLCAnY29sdW1uJywgJ3gnLCAneScsICdjb2xvcicsICdzaXplJywgJ2RldGFpbCddKSxcbiAgcG9pbnQ6IHRvU2V0KFsncm93JywgJ2NvbHVtbicsICd4JywgJ3knLCAnY29sb3InLCAnc2l6ZScsICdkZXRhaWwnLCAnc2hhcGUnXSksXG4gIHRleHQ6IHRvU2V0KFsncm93JywgJ2NvbHVtbicsICdzaXplJywgJ2NvbG9yJywgJ3RleHQnXSkgLy8gVE9ETygjNzI0KSByZXZpc2Vcbn07XG5cbi8vIFRPRE86IGNvbnNpZGVyIGlmIHdlIHNob3VsZCBhZGQgdmFsaWRhdGUgbWV0aG9kIGFuZFxuLy8gcmVxdWlyZXMgWlNjaGVtYSBpbiB0aGUgbWFpbiB2ZWdhLWxpdGUgcmVwb1xuXG4vKipcbiAqIEZ1cnRoZXIgY2hlY2sgaWYgZW5jb2RpbmcgbWFwcGluZyBvZiBhIHNwZWMgaXMgaW52YWxpZCBhbmRcbiAqIHJldHVybiBlcnJvciBpZiBpdCBpcyBpbnZhbGlkLlxuICpcbiAqIFRoaXMgY2hlY2tzIGlmXG4gKiAoMSkgYWxsIHRoZSByZXF1aXJlZCBlbmNvZGluZyBjaGFubmVscyBmb3IgdGhlIG1hcmsgdHlwZSBhcmUgc3BlY2lmaWVkXG4gKiAoMikgYWxsIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcgY2hhbm5lbHMgYXJlIHN1cHBvcnRlZCBieSB0aGUgbWFyayB0eXBlXG4gKiBAcGFyYW0gIHtbdHlwZV19IHNwZWMgW2Rlc2NyaXB0aW9uXVxuICogQHBhcmFtICB7UmVxdWlyZWRDaGFubmVsTWFwID0gRGVmYXVsdFJlcXVpcmVkQ2hhbm5lbE1hcH0gIHJlcXVpcmVkQ2hhbm5lbE1hcFxuICogQHBhcmFtICB7U3VwcG9ydGVkQ2hhbm5lbE1hcCA9IERlZmF1bHRTdXBwb3J0ZWRDaGFubmVsTWFwfSBzdXBwb3J0ZWRDaGFubmVsTWFwXG4gKiBAcmV0dXJuIHtTdHJpbmd9IFJldHVybiBvbmUgcmVhc29uIHdoeSB0aGUgZW5jb2RpbmcgaXMgaW52YWxpZCxcbiAqICAgICAgICAgICAgICAgICAgb3IgbnVsbCBpZiB0aGUgZW5jb2RpbmcgaXMgdmFsaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbmNvZGluZ01hcHBpbmdFcnJvcihzcGVjOiBGYWNldGVkQ29tcG9zaXRlVW5pdFNwZWMsXG4gIHJlcXVpcmVkQ2hhbm5lbE1hcDogUmVxdWlyZWRDaGFubmVsTWFwID0gREVGQVVMVF9SRVFVSVJFRF9DSEFOTkVMX01BUCxcbiAgc3VwcG9ydGVkQ2hhbm5lbE1hcDogU3VwcG9ydGVkQ2hhbm5lbE1hcCA9IERFRkFVTFRfU1VQUE9SVEVEX0NIQU5ORUxfVFlQRVxuICApIHtcbiAgY29uc3QgbWFyayA9IGlzTWFya0RlZihzcGVjLm1hcmspID8gc3BlYy5tYXJrLnR5cGUgOiBzcGVjLm1hcms7XG4gIGNvbnN0IGVuY29kaW5nID0gc3BlYy5lbmNvZGluZztcbiAgY29uc3QgcmVxdWlyZWRDaGFubmVscyA9IHJlcXVpcmVkQ2hhbm5lbE1hcFttYXJrXTtcbiAgY29uc3Qgc3VwcG9ydGVkQ2hhbm5lbHMgPSBzdXBwb3J0ZWRDaGFubmVsTWFwW21hcmtdO1xuXG4gIGZvciAoY29uc3QgaSBpbiByZXF1aXJlZENoYW5uZWxzKSB7IC8vIGFsbCByZXF1aXJlZCBjaGFubmVscyBhcmUgaW4gZW5jb2RpbmdgXG4gICAgaWYgKCEocmVxdWlyZWRDaGFubmVsc1tpXSBpbiBlbmNvZGluZykpIHtcbiAgICAgIHJldHVybiAnTWlzc2luZyBlbmNvZGluZyBjaGFubmVsIFxcXCInICsgcmVxdWlyZWRDaGFubmVsc1tpXSArXG4gICAgICAgICdcXFwiIGZvciBtYXJrIFxcXCInICsgbWFyayArICdcXFwiJztcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGNoYW5uZWwgaW4gZW5jb2RpbmcpIHsgLy8gYWxsIGNoYW5uZWxzIGluIGVuY29kaW5nIGFyZSBzdXBwb3J0ZWRcbiAgICBpZiAoIXN1cHBvcnRlZENoYW5uZWxzW2NoYW5uZWxdKSB7XG4gICAgICByZXR1cm4gJ0VuY29kaW5nIGNoYW5uZWwgXFxcIicgKyBjaGFubmVsICtcbiAgICAgICAgJ1xcXCIgaXMgbm90IHN1cHBvcnRlZCBieSBtYXJrIHR5cGUgXFxcIicgKyBtYXJrICsgJ1xcXCInO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtYXJrID09PSBCQVIgJiYgIWVuY29kaW5nLnggJiYgIWVuY29kaW5nLnkpIHtcbiAgICByZXR1cm4gJ01pc3NpbmcgYm90aCB4IGFuZCB5IGZvciBiYXInO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iXX0= \ 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..e60b448af8 --- /dev/null +++ b/build/src/vega.schema.d.ts @@ -0,0 +1,925 @@ +import { AggregateOp } from './aggregate'; +import { BaseBin } from './bin'; +import { NiceTime, ScaleType } from './scale'; +import { SortOrder } from './sort'; +import { StackOffset } from './stack'; +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 interface VgScale { + name: string; + type: ScaleType; + domain: VgDomain; + domainRaw?: VgSignalRef; + range: VgRange; + clamp?: boolean; + base?: number; + exponent?: number; + interpolate?: 'rgb' | 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long'; + nice?: boolean | NiceTime; + padding?: number; + paddingInner?: number; + paddingOuter?: number; + reverse?: boolean; + round?: boolean; + zero?: boolean; +} +export declare type VgLayoutAlign = 'none' | 'each' | 'all'; +export declare type RowCol = { + row?: T; + column?: T; +}; +export interface VgLayout { + 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 | { + row: VgLayoutAlign; + column: VgLayoutAlign; + }; +} +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' | 'strokeOpacity' | 'strokeDash' | 'strokeDashOffset' | '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'; +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; +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?: 'ascending' | 'descending'; +} | { + field: string[]; + order?: ('ascending' | 'descending')[]; +}; +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](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. (e.g., `"bold"`). + */ + titleFontWeight?: string | number; + /** + * 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. + */ + titleFontWeight?: string | number; + /** + * 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 FontWeight = 'normal' | 'bold'; +/** + * @TJS-type integer + * @minimum 100 + * @maximum 900 + */ +export declare type FontWeightNumber = number; +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 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; + /** + * 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 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, 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 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 (default 0, indicating no limit). The text value will be automatically truncated if the rendered size exceeds the limit. + */ + limit?: number; + /** + * 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 (e.g., `"bold"`). + */ + fontWeight?: FontWeight | FontWeightNumber; + /** + * Placeholder text if the `text` channel is not specified + */ + text?: string; +} +export declare const VG_MARK_CONFIGS: ("font" | "text" | "opacity" | "size" | "shape" | "interpolate" | "stroke" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "fill" | "fillOpacity" | "orient" | "tension" | "align" | "angle" | "baseline" | "dx" | "dy" | "radius" | "limit" | "theta" | "fontSize" | "fontStyle" | "fontWeight")[]; +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](spec.html) and [layered](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](spec.html) and [layered](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. + */ + fontWeight?: FontWeight | FontWeightNumber; + /** + * 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; +} diff --git a/build/src/vega.schema.js b/build/src/vega.schema.js new file mode 100644 index 0000000000..22923d0be1 --- /dev/null +++ b/build/src/vega.schema.js @@ -0,0 +1,81 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +function isVgSignalRef(o) { + return !!o['signal']; +} +exports.isVgSignalRef = isVgSignalRef; +function isVgRangeStep(range) { + return !!range['step']; +} +exports.isVgRangeStep = isVgRangeStep; +function isDataRefUnionedDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && !('data' in domain); + } + return false; +} +exports.isDataRefUnionedDomain = isDataRefUnionedDomain; +function isFieldRefUnionDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && 'data' in domain; + } + return false; +} +exports.isFieldRefUnionDomain = isFieldRefUnionDomain; +function isDataRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'field' in domain && 'data' in domain; + } + return false; +} +exports.isDataRefDomain = isDataRefDomain; +function isSignalRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'signal' in domain; + } + return false; +} +exports.isSignalRefDomain = isSignalRefDomain; +var VG_MARK_CONFIG_INDEX = { + opacity: 1, + fill: 1, + fillOpacity: 1, + stroke: 1, + strokeWidth: 1, + strokeOpacity: 1, + strokeDash: 1, + strokeDashOffset: 1, + size: 1, + shape: 1, + interpolate: 1, + tension: 1, + orient: 1, + align: 1, + baseline: 1, + text: 1, + limit: 1, + dx: 1, + dy: 1, + radius: 1, + theta: 1, + angle: 1, + font: 1, + fontSize: 1, + fontWeight: 1, + fontStyle: 1 + // commented below are vg channel that do not have mark config. + // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height' + // cursor: 1, + // clip: 1, + // dir: 1, + // ellipsis: 1, + // endAngle: 1, + // path: 1, + // innerRadius: 1, + // outerRadius: 1, + // startAngle: 1, + // url: 1, +}; +exports.VG_MARK_CONFIGS = util_1.flagKeys(VG_MARK_CONFIG_INDEX); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVnYS5zY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmVnYS5zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSwrQkFBK0M7QUFnRC9DLHVCQUE4QixDQUFNO0lBQ2xDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3ZCLENBQUM7QUFGRCxzQ0FFQztBQW1DRCx1QkFBOEIsS0FBYztJQUMxQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN6QixDQUFDO0FBRkQsc0NBRUM7QUF1REQsZ0NBQXVDLE1BQWdCO0lBQ3JELEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUxELHdEQUtDO0FBRUQsK0JBQXNDLE1BQWdCO0lBQ3BELEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sSUFBSSxNQUFNLElBQUksTUFBTSxDQUFDO0lBQ2hELENBQUM7SUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUxELHNEQUtDO0FBRUQseUJBQWdDLE1BQWdCO0lBQzlDLEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQixNQUFNLENBQUMsT0FBTyxJQUFJLE1BQU0sSUFBSSxNQUFNLElBQUksTUFBTSxDQUFDO0lBQ2hELENBQUM7SUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUxELDBDQUtDO0FBRUQsMkJBQWtDLE1BQWdCO0lBQ2hELEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQztJQUM1QixDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFMRCw4Q0FLQztBQXUzQkQsSUFBTSxvQkFBb0IsR0FBNkI7SUFDckQsT0FBTyxFQUFFLENBQUM7SUFDVixJQUFJLEVBQUUsQ0FBQztJQUNQLFdBQVcsRUFBRSxDQUFDO0lBQ2QsTUFBTSxFQUFFLENBQUM7SUFDVCxXQUFXLEVBQUUsQ0FBQztJQUNkLGFBQWEsRUFBRSxDQUFDO0lBQ2hCLFVBQVUsRUFBRSxDQUFDO0lBQ2IsZ0JBQWdCLEVBQUUsQ0FBQztJQUNuQixJQUFJLEVBQUUsQ0FBQztJQUNQLEtBQUssRUFBRSxDQUFDO0lBQ1IsV0FBVyxFQUFFLENBQUM7SUFDZCxPQUFPLEVBQUUsQ0FBQztJQUNWLE1BQU0sRUFBRSxDQUFDO0lBQ1QsS0FBSyxFQUFFLENBQUM7SUFDUixRQUFRLEVBQUUsQ0FBQztJQUNYLElBQUksRUFBRSxDQUFDO0lBQ1AsS0FBSyxFQUFFLENBQUM7SUFDUixFQUFFLEVBQUUsQ0FBQztJQUNMLEVBQUUsRUFBRSxDQUFDO0lBQ0wsTUFBTSxFQUFFLENBQUM7SUFDVCxLQUFLLEVBQUUsQ0FBQztJQUNSLEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBSSxFQUFFLENBQUM7SUFDUCxRQUFRLEVBQUUsQ0FBQztJQUNYLFVBQVUsRUFBRSxDQUFDO0lBQ2IsU0FBUyxFQUFFLENBQUM7SUFDWiwrREFBK0Q7SUFDL0QsK0NBQStDO0lBQy9DLGFBQWE7SUFDYixXQUFXO0lBQ1gsVUFBVTtJQUNWLGVBQWU7SUFDZixlQUFlO0lBQ2YsV0FBVztJQUNYLGtCQUFrQjtJQUNsQixrQkFBa0I7SUFDbEIsaUJBQWlCO0lBQ2pCLFVBQVU7Q0FDWCxDQUFDO0FBRVcsUUFBQSxlQUFlLEdBQUcsZUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FnZ3JlZ2F0ZU9wfSBmcm9tICcuL2FnZ3JlZ2F0ZSc7XG5pbXBvcnQge0Jhc2VCaW59IGZyb20gJy4vYmluJztcbmltcG9ydCB7TmljZVRpbWUsIFNjYWxlVHlwZX0gZnJvbSAnLi9zY2FsZSc7XG5pbXBvcnQge1NvcnRPcmRlcn0gZnJvbSAnLi9zb3J0JztcbmltcG9ydCB7U3RhY2tPZmZzZXR9IGZyb20gJy4vc3RhY2snO1xuaW1wb3J0IHtGbGFnLCBmbGFnS2V5cywgaXNBcnJheX0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGludGVyZmFjZSBWZ0RhdGEge1xuICBuYW1lOiBzdHJpbmc7XG4gIHNvdXJjZT86IHN0cmluZztcbiAgdmFsdWVzPzogYW55O1xuICBmb3JtYXQ/OiB7XG4gICAgdHlwZT86IHN0cmluZztcbiAgICBwYXJzZT86IHN0cmluZyB8IG9iamVjdDtcbiAgICBwcm9wZXJ0eT86IHN0cmluZztcbiAgICBmZWF0dXJlPzogc3RyaW5nO1xuICAgIG1lc2g/OiBzdHJpbmc7XG4gIH07XG4gIHVybD86IHN0cmluZztcbiAgdHJhbnNmb3JtPzogVmdUcmFuc2Zvcm1bXTtcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIFZnUGFyZW50UmVmIHtcbiAgcGFyZW50OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFZnRmllbGRSZWYgPSBzdHJpbmcgfCBWZ1BhcmVudFJlZiB8IFZnUGFyZW50UmVmW107XG5cbmV4cG9ydCB0eXBlIFZnU29ydEZpZWxkID0gdHJ1ZSB8IHtcbiAgZmllbGQ/OiBWZ0ZpZWxkUmVmLFxuICBvcDogQWdncmVnYXRlT3AsXG4gIG9yZGVyPzogU29ydE9yZGVyXG59O1xuXG4vKipcbiAqIFVuaW9uZWQgZG9tYWlucyBjYW4gb25seSBiZSBzb3J0ZWQgYnkgY291bnQgYWdncmVnYXRlLlxuICovXG5leHBvcnQgdHlwZSBWZ1VuaW9uU29ydEZpZWxkID0gdHJ1ZSB8IHtcbiAgb3A6ICdjb3VudCdcbiAgb3JkZXI/OiBTb3J0T3JkZXJcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmdEYXRhUmVmIHtcbiAgZGF0YTogc3RyaW5nO1xuICBmaWVsZDogVmdGaWVsZFJlZjtcbiAgc29ydD86IFZnU29ydEZpZWxkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZnU2lnbmFsUmVmIHtcbiAgc2lnbmFsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZnU2lnbmFsUmVmKG86IGFueSk6IG8gaXMgVmdTaWduYWxSZWYge1xuICByZXR1cm4gISFvWydzaWduYWwnXTtcbn1cblxuZXhwb3J0IHR5cGUgVmdFdmVudFN0cmVhbSA9IGFueTtcblxuLy8gVE9ETzogYWRkIHR5cGUgb2YgdmFsdWUgKE1ha2UgaXQgVmdWYWx1ZVJlZjxUPiB7dmFsdWU/OlQgLi4ufSlcbmV4cG9ydCBpbnRlcmZhY2UgVmdWYWx1ZVJlZiB7XG4gIHZhbHVlPzogbnVtYmVyIHwgc3RyaW5nIHwgYm9vbGVhbjtcbiAgZmllbGQ/OiBzdHJpbmcgfCB7XG4gICAgZGF0dW0/OiBzdHJpbmcsXG4gICAgZ3JvdXA/OiBzdHJpbmcsXG4gICAgcGFyZW50Pzogc3RyaW5nXG4gIH07XG4gIHNpZ25hbD86IHN0cmluZztcbiAgc2NhbGU/OiBzdHJpbmc7IC8vIFRPRE86IG9iamVjdFxuICBtdWx0PzogbnVtYmVyO1xuICBvZmZzZXQ/OiBudW1iZXIgfCBWZ1ZhbHVlUmVmO1xuICBiYW5kPzogYm9vbGVhbiB8IG51bWJlciB8IFZnVmFsdWVSZWY7XG59XG5cbi8vIFRPRE86IGFkZCB2ZyBwcmVmaXhcbmV4cG9ydCBpbnRlcmZhY2UgRGF0YVJlZlVuaW9uRG9tYWluIHtcbiAgZmllbGRzOiAoYW55W10gfCBWZ0RhdGFSZWYgfCBWZ1NpZ25hbFJlZilbXTtcbiAgc29ydD86IFZnVW5pb25Tb3J0RmllbGQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmdGaWVsZFJlZlVuaW9uRG9tYWluIHtcbiAgZGF0YTogc3RyaW5nO1xuICBmaWVsZHM6IFZnRmllbGRSZWZbXTtcbiAgc29ydD86IFZnVW5pb25Tb3J0RmllbGQ7XG59XG5cbmV4cG9ydCB0eXBlIFZnU2NoZW1lID0ge3NjaGVtZTogc3RyaW5nLCBleHRlbnQ/OiBudW1iZXJbXSwgY291bnQ/OiBudW1iZXJ9O1xuZXhwb3J0IHR5cGUgVmdSYW5nZSA9IHN0cmluZyB8IFZnRGF0YVJlZiB8IChudW1iZXJ8c3RyaW5nfFZnRGF0YVJlZnxWZ1NpZ25hbFJlZilbXSB8IFZnU2NoZW1lIHwgVmdSYW5nZVN0ZXA7XG5cbmV4cG9ydCB0eXBlIFZnUmFuZ2VTdGVwID0ge3N0ZXA6IG51bWJlciB8IFZnU2lnbmFsUmVmfTtcbmV4cG9ydCBmdW5jdGlvbiBpc1ZnUmFuZ2VTdGVwKHJhbmdlOiBWZ1JhbmdlKTogcmFuZ2UgaXMgVmdSYW5nZVN0ZXAge1xuICByZXR1cm4gISFyYW5nZVsnc3RlcCddO1xufVxuXG4vLyBEb21haW5zIHRoYXQgYXJlIG5vdCBhIHVuaW9uIG9mIGRvbWFpbnNcbmV4cG9ydCB0eXBlIFZnTm9uVW5pb25Eb21haW4gPSBhbnlbXSB8IFZnRGF0YVJlZiB8IFZnU2lnbmFsUmVmO1xuZXhwb3J0IHR5cGUgVmdEb21haW4gPSBWZ05vblVuaW9uRG9tYWluIHwgRGF0YVJlZlVuaW9uRG9tYWluIHwgVmdGaWVsZFJlZlVuaW9uRG9tYWluO1xuXG5leHBvcnQgdHlwZSBWZ01hcmtHcm91cCA9IGFueTtcblxuZXhwb3J0IGludGVyZmFjZSBWZ1NjYWxlIHtcbiAgbmFtZTogc3RyaW5nO1xuICB0eXBlOiBTY2FsZVR5cGU7XG4gIGRvbWFpbjogVmdEb21haW47XG4gIGRvbWFpblJhdz86IFZnU2lnbmFsUmVmO1xuICByYW5nZTogVmdSYW5nZTtcblxuICBjbGFtcD86IGJvb2xlYW47XG4gIGJhc2U/OiBudW1iZXI7XG4gIGV4cG9uZW50PzogbnVtYmVyO1xuICBpbnRlcnBvbGF0ZT86ICdyZ2InfCAnbGFiJyB8ICdoY2wnIHwgJ2hzbCcgfCAnaHNsLWxvbmcnIHwgJ2hjbC1sb25nJyB8ICdjdWJlaGVsaXgnIHwgJ2N1YmVoZWxpeC1sb25nJztcbiAgbmljZT86IGJvb2xlYW4gfCBOaWNlVGltZTtcbiAgcGFkZGluZz86IG51bWJlcjtcbiAgcGFkZGluZ0lubmVyPzogbnVtYmVyO1xuICBwYWRkaW5nT3V0ZXI/OiBudW1iZXI7XG4gIHJldmVyc2U/OiBib29sZWFuO1xuICByb3VuZD86IGJvb2xlYW47XG4gIHplcm8/OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBWZ0xheW91dEFsaWduID0gJ25vbmUnIHwgJ2VhY2gnIHwgJ2FsbCc7XG5cbmV4cG9ydCB0eXBlIFJvd0NvbDxUPiA9IHtcbiAgcm93PzogVCxcbiAgY29sdW1uPzogVFxufTtcblxuZXhwb3J0IGludGVyZmFjZSBWZ0xheW91dCB7XG4gIHBhZGRpbmc6IG51bWJlciB8IFJvd0NvbDxudW1iZXI+O1xuICBoZWFkZXJCYW5kPzogbnVtYmVyIHwgUm93Q29sPG51bWJlcj47XG4gIGZvb3RlckJhbmQ/OiBudW1iZXIgfCBSb3dDb2w8bnVtYmVyPjtcbiAgb2Zmc2V0OiBudW1iZXIgfCB7XG4gICAgcm93SGVhZGVyOiBudW1iZXIsXG4gICAgcm93Rm9vdGVyOiBudW1iZXIsXG4gICAgcm93VGl0bGU6IG51bWJlcixcbiAgICBjb2x1bW5IZWFkZXI6IG51bWJlcixcbiAgICBjb2x1bW5Gb290ZXI6IG51bWJlcixcbiAgICBjb2x1bW5UaXRsZTogbnVtYmVyXG4gIH07XG4gIGJvdW5kczogJ2Z1bGwnIHwgJ2ZsdXNoJztcbiAgY29sdW1ucz86IG51bWJlciB8IHtzaWduYWw6IHN0cmluZ307XG4gIGFsaWduPzogVmdMYXlvdXRBbGlnbiB8IHtcbiAgICByb3c6IFZnTGF5b3V0QWxpZ24sXG4gICAgY29sdW1uOiBWZ0xheW91dEFsaWduXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGFSZWZVbmlvbmVkRG9tYWluKGRvbWFpbjogVmdEb21haW4pOiBkb21haW4gaXMgRGF0YVJlZlVuaW9uRG9tYWluIHtcbiAgaWYgKCFpc0FycmF5KGRvbWFpbikpIHtcbiAgICByZXR1cm4gJ2ZpZWxkcycgaW4gZG9tYWluICYmICEoJ2RhdGEnIGluIGRvbWFpbik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNGaWVsZFJlZlVuaW9uRG9tYWluKGRvbWFpbjogVmdEb21haW4pOiBkb21haW4gaXMgVmdGaWVsZFJlZlVuaW9uRG9tYWluIHtcbiAgaWYgKCFpc0FycmF5KGRvbWFpbikpIHtcbiAgICByZXR1cm4gJ2ZpZWxkcycgaW4gZG9tYWluICYmICdkYXRhJyBpbiBkb21haW47XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRhUmVmRG9tYWluKGRvbWFpbjogVmdEb21haW4pOiBkb21haW4gaXMgVmdEYXRhUmVmIHtcbiAgaWYgKCFpc0FycmF5KGRvbWFpbikpIHtcbiAgICAgcmV0dXJuICdmaWVsZCcgaW4gZG9tYWluICYmICdkYXRhJyBpbiBkb21haW47XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTaWduYWxSZWZEb21haW4oZG9tYWluOiBWZ0RvbWFpbik6IGRvbWFpbiBpcyBWZ1NpZ25hbFJlZiB7XG4gIGlmICghaXNBcnJheShkb21haW4pKSB7XG4gICAgcmV0dXJuICdzaWduYWwnIGluIGRvbWFpbjtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmdFdmVudEhhbmRsZXIge1xuICBldmVudHM6IHN0cmluZ1tdIHwgVmdTaWduYWxSZWY7XG4gIHVwZGF0ZT86IHN0cmluZztcbiAgZW5jb2RlPzogc3RyaW5nO1xuICBmb3JjZT86IGJvb2xlYW47XG4gIGJldHdlZW4/OiBhbnlbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ1NpZ25hbCB7XG4gIG5hbWU6IHN0cmluZztcbiAgYmluZD86IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIG9uPzogVmdFdmVudEhhbmRsZXJbXTtcbiAgdXBkYXRlPzogc3RyaW5nO1xuICByZWFjdD86IGJvb2xlYW47XG4gIHZhbHVlPzogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IHt9IHwgVmdTaWduYWxSZWY7XG4gIC8vIG9ubHkgZm9yIG5lc3RlZCBzaWduYWxzXG4gIHB1c2g/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFZnRW5jb2RlQ2hhbm5lbCA9ICd4J3wneDInfCd4Yyd8J3dpZHRoJ3wneSd8J3kyJ3wneWMnfCdoZWlnaHQnfCdvcGFjaXR5J3wnZmlsbCd8J2ZpbGxPcGFjaXR5J3wnc3Ryb2tlJ3wnc3Ryb2tlV2lkdGgnfCdzdHJva2VPcGFjaXR5J3wnc3Ryb2tlRGFzaCd8J3N0cm9rZURhc2hPZmZzZXQnfCdjdXJzb3InfCdjbGlwJ3wnc2l6ZSd8J3NoYXBlJ3wncGF0aCd8J2lubmVyUmFkaXVzJ3wnb3V0ZXJSYWRpdXMnfCdzdGFydEFuZ2xlJ3wnZW5kQW5nbGUnfCdpbnRlcnBvbGF0ZSd8J3RlbnNpb24nfCdvcmllbnQnfCd1cmwnfCdhbGlnbid8J2Jhc2VsaW5lJ3wndGV4dCd8J2Rpcid8J2VsbGlwc2lzJ3wnbGltaXQnfCdkeCd8J2R5J3wncmFkaXVzJ3wndGhldGEnfCdhbmdsZSd8J2ZvbnQnfCdmb250U2l6ZSd8J2ZvbnRXZWlnaHQnfCdmb250U3R5bGUnO1xuZXhwb3J0IHR5cGUgVmdFbmNvZGVFbnRyeSA9IHtcbiAgW2sgaW4gVmdFbmNvZGVDaGFubmVsXT86IFZnVmFsdWVSZWYgfCAoVmdWYWx1ZVJlZiAmIHt0ZXN0Pzogc3RyaW5nfSlbXTtcbn07XG5cblxuLy8gVE9ETzogbWFrZSBleHBvcnQgaW50ZXJmYWNlIFZnRW5jb2RlRW50cnkge1xuLy8gICB4PzogVmdWYWx1ZVJlZjxudW1iZXI+XG4vLyAgIHk/OiBWZ1ZhbHVlUmVmPG51bWJlcj5cbi8vICAuLi5cbi8vICAgY29sb3I/OiBWZ1ZhbHVlUmVmPHN0cmluZz5cbi8vICAuLi5cbi8vIH1cblxuZXhwb3J0IHR5cGUgQXhpc09yaWVudCA9ICd0b3AnIHwgJ3JpZ2h0JyB8ICdsZWZ0JyB8ICdib3R0b20nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZnQXhpcyB7XG4gIHNjYWxlOiBzdHJpbmc7XG4gIGRvbWFpbj86IGJvb2xlYW47XG4gIGZvcm1hdD86IHN0cmluZztcbiAgZ3JpZD86IGJvb2xlYW47XG4gIGdyaWRTY2FsZT86IHN0cmluZztcblxuICBsYWJlbHM/OiBib29sZWFuO1xuXG4gIGxhYmVsQm91bmQ/OiBib29sZWFuIHwgbnVtYmVyO1xuICBsYWJlbEZsdXNoPzogYm9vbGVhbiB8IG51bWJlcjtcbiAgbGFiZWxQYWRkaW5nPzogbnVtYmVyO1xuICBsYWJlbE92ZXJsYXA/OiBib29sZWFuIHwgJ3Bhcml0eScgfCAnZ3JlZWR5JztcbiAgbWF4RXh0ZW50PzogbnVtYmVyO1xuICBtaW5FeHRlbnQ/OiBudW1iZXI7XG4gIG9mZnNldD86IG51bWJlcjtcbiAgb3JpZW50PzogQXhpc09yaWVudDtcbiAgcG9zaXRpb24/OiBudW1iZXI7XG5cbiAgdGlja3M/OiBib29sZWFuO1xuICB0aWNrQ291bnQ/OiBudW1iZXI7XG4gIHRpY2tTaXplPzogbnVtYmVyO1xuXG4gIHRpdGxlPzogc3RyaW5nO1xuICB0aXRsZVBhZGRpbmc/OiBudW1iZXI7XG5cbiAgdmFsdWVzPzogYW55W10gfCBWZ1NpZ25hbFJlZjtcbiAgemluZGV4PzogbnVtYmVyO1xuXG4gIGVuY29kZT86IFZnQXhpc0VuY29kZTtcbn1cblxuZXhwb3J0IHR5cGUgTGVnZW5kVHlwZSA9ICdzeW1ib2wnIHwgJ2dyYWRpZW50JztcblxuZXhwb3J0IGludGVyZmFjZSBWZ0xlZ2VuZCB7XG4gIGZpbGw/OiBzdHJpbmc7XG4gIHN0cm9rZT86IHN0cmluZztcbiAgc2l6ZT86IHN0cmluZztcbiAgc2hhcGU/OiBzdHJpbmc7XG4gIG9wYWNpdHk/OiBzdHJpbmc7XG5cbiAgZW50cnlQYWRkaW5nPzogbnVtYmVyO1xuICBmb3JtYXQ/OiBzdHJpbmc7XG5cbiAgb2Zmc2V0PzogbnVtYmVyO1xuICBvcmllbnQ/OiBMZWdlbmRPcmllbnQ7XG4gIHBhZGRpbmc/OiBudW1iZXI7XG5cbiAgdGlja0NvdW50PzogbnVtYmVyO1xuICB0aXRsZT86IHN0cmluZztcbiAgdHlwZT86IExlZ2VuZFR5cGU7XG4gIHZhbHVlcz86IGFueVtdIHwgVmdTaWduYWxSZWY7XG4gIHppbmRleD86IG51bWJlcjtcblxuICBlbmNvZGU/OiBWZ0xlZ2VuZEVuY29kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0JpblRyYW5zZm9ybSBleHRlbmRzIEJhc2VCaW4ge1xuICB0eXBlOiAnYmluJztcbiAgZXh0ZW50PzogbnVtYmVyW10gfCB7c2lnbmFsOiBzdHJpbmd9O1xuICBmaWVsZDogc3RyaW5nO1xuICBhczogc3RyaW5nW107XG4gIHNpZ25hbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0V4dGVudFRyYW5zZm9ybSB7XG4gIHR5cGU6ICdleHRlbnQnO1xuICBmaWVsZDogc3RyaW5nO1xuICBzaWduYWw6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0Zvcm11bGFUcmFuc2Zvcm0ge1xuICB0eXBlOiAnZm9ybXVsYSc7XG4gIGFzOiBzdHJpbmc7XG4gIGV4cHI6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0ZpbHRlclRyYW5zZm9ybSB7XG4gIHR5cGU6ICdmaWx0ZXInO1xuICBleHByOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmdBZ2dyZWdhdGVUcmFuc2Zvcm0ge1xuICB0eXBlOiAnYWdncmVnYXRlJztcbiAgZ3JvdXBieT86IFZnRmllbGRSZWZbXTtcbiAgZmllbGRzPzogVmdGaWVsZFJlZltdO1xuICBvcHM/OiBBZ2dyZWdhdGVPcFtdO1xuICBhcz86IHN0cmluZ1tdO1xuICBjcm9zcz86IGJvb2xlYW47XG4gIGRyb3A/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZnQ29sbGVjdFRyYW5zZm9ybSB7XG4gIHR5cGU6ICdjb2xsZWN0JztcbiAgc29ydDogVmdTb3J0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZnTG9va3VwVHJhbnNmb3JtIHtcbiAgdHlwZTogJ2xvb2t1cCc7XG4gIGZyb206IHN0cmluZztcbiAga2V5OiBzdHJpbmc7XG4gIGZpZWxkczogc3RyaW5nW107XG4gIHZhbHVlcz86IHN0cmluZ1tdO1xuICBhcz86IHN0cmluZ1tdO1xuICBkZWZhdWx0Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZnU3RhY2tUcmFuc2Zvcm0ge1xuICB0eXBlOiAnc3RhY2snO1xuICBvZmZzZXQ/OiBTdGFja09mZnNldDtcbiAgZ3JvdXBieTogc3RyaW5nW107XG4gIGZpZWxkOiBzdHJpbmc7XG4gIHNvcnQ6IFZnU29ydDtcbiAgYXM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZnSWRlbnRpZmllclRyYW5zZm9ybSB7XG4gIHR5cGU6ICdpZGVudGlmaWVyJztcbiAgYXM6IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgVmdUcmFuc2Zvcm0gPSBWZ0JpblRyYW5zZm9ybSB8IFZnRXh0ZW50VHJhbnNmb3JtIHwgVmdGb3JtdWxhVHJhbnNmb3JtIHwgVmdBZ2dyZWdhdGVUcmFuc2Zvcm0gfCBWZ0ZpbHRlclRyYW5zZm9ybSB8IFZnSW1wdXRlVHJhbnNmb3JtIHwgVmdTdGFja1RyYW5zZm9ybSB8IFZnQ29sbGVjdFRyYW5zZm9ybSB8IFZnTG9va3VwVHJhbnNmb3JtIHwgVmdJZGVudGlmaWVyVHJhbnNmb3JtO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZnQXhpc0VuY29kZSB7XG4gIHRpY2tzPzogVmdHdWlkZUVuY29kZTtcbiAgbGFiZWxzPzogVmdHdWlkZUVuY29kZTtcbiAgdGl0bGU/OiBWZ0d1aWRlRW5jb2RlO1xuICBncmlkPzogVmdHdWlkZUVuY29kZTtcbiAgZG9tYWluPzogVmdHdWlkZUVuY29kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0xlZ2VuZEVuY29kZSB7XG4gIHRpdGxlPzogVmdHdWlkZUVuY29kZTtcbiAgbGFiZWxzPzogVmdHdWlkZUVuY29kZTtcbiAgbGVnZW5kPzogVmdHdWlkZUVuY29kZTtcbiAgc3ltYm9scz86IFZnR3VpZGVFbmNvZGU7XG4gIGdyYWRpZW50PzogVmdHdWlkZUVuY29kZTtcbn1cblxuZXhwb3J0IHR5cGUgVmdHdWlkZUVuY29kZSA9IGFueTsgLy8gVE9ETzogcmVwbGFjZSB0aGlzIChTZWUgZ3VpZGVFbmNvZGUgaW4gVmVnYSBTY2hlbWEpXG5cbmV4cG9ydCB0eXBlIFZnU29ydCA9IHtcbiAgZmllbGQ6IHN0cmluZztcbiAgb3JkZXI/OiAnYXNjZW5kaW5nJyB8ICdkZXNjZW5kaW5nJztcbn0gfCB7XG4gIGZpZWxkOiBzdHJpbmdbXTtcbiAgb3JkZXI/OiAoJ2FzY2VuZGluZycgfCAnZGVzY2VuZGluZycpW107XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFZnSW1wdXRlVHJhbnNmb3JtIHtcbiAgdHlwZTogJ2ltcHV0ZSc7XG4gIGdyb3VwYnk/OiBzdHJpbmdbXTtcbiAgZmllbGQ6IHN0cmluZztcbiAga2V5OiBzdHJpbmc7XG4gIGtleXZhbHM/OiBzdHJpbmdbXTtcbiAgbWV0aG9kPzogJ3ZhbHVlJyB8ICdtZWRpYW4nIHwgJ21heCcgfCAnbWluJyB8ICdtZWFuJztcbiAgdmFsdWU/OiBhbnk7XG59XG5cbmV4cG9ydCB0eXBlIFZnQ2hlY2tib3hCaW5kaW5nID0ge1xuICBpbnB1dDogJ2NoZWNrYm94JztcbiAgZWxlbWVudD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIFZnUmFkaW9CaW5kaW5nID0ge1xuICBpbnB1dDogJ3JhZGlvJztcbiAgb3B0aW9uczogc3RyaW5nW107XG4gIGVsZW1lbnQ/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBWZ1NlbGVjdEJpbmRpbmcgPSB7XG4gIGlucHV0OiAnc2VsZWN0JztcbiAgb3B0aW9uczogc3RyaW5nW107XG4gIGVsZW1lbnQ/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBWZ1JhbmdlQmluZGluZyA9IHtcbiAgaW5wdXQ6ICdyYW5nZSc7XG4gIG1pbj86IG51bWJlcjtcbiAgbWF4PzogbnVtYmVyO1xuICBzdGVwPzogbnVtYmVyO1xuICBlbGVtZW50Pzogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgVmdHZW5lcmljQmluZGluZyA9IHtcbiAgaW5wdXQ6IHN0cmluZztcbiAgZWxlbWVudD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIFZnQmluZGluZyA9IFZnQ2hlY2tib3hCaW5kaW5nIHwgVmdSYWRpb0JpbmRpbmcgfFxuICBWZ1NlbGVjdEJpbmRpbmcgfCBWZ1JhbmdlQmluZGluZyB8IFZnR2VuZXJpY0JpbmRpbmc7XG5cblxuLyoqXG4gKiBCYXNlIG9iamVjdCBmb3IgVmVnYSdzIEF4aXMgYW5kIEF4aXMgQ29uZmlnLlxuICogQWxsIG9mIHRoZXNlIHByb3BlcnRpZXMgYXJlIGJvdGggcHJvcGVydGllcyBvZiBWZWdhJ3MgQXhpcyBhbmQgQXhpcyBDb25maWcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmdBeGlzQmFzZSB7XG4gIC8qKlxuICAgKiBBIGJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIGlmIHRoZSBkb21haW4gKHRoZSBheGlzIGJhc2VsaW5lKSBzaG91bGQgYmUgaW5jbHVkZWQgYXMgcGFydCBvZiB0aGUgYXhpcy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB0cnVlYFxuICAgKi9cbiAgZG9tYWluPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBib29sZWFuIGZsYWcgaW5kaWNhdGluZyBpZiBncmlkIGxpbmVzIHNob3VsZCBiZSBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBheGlzXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgdHJ1ZWAgZm9yIFtjb250aW51b3VzIHNjYWxlc10oc2NhbGUuaHRtbCNjb250aW51b3VzKSB0aGF0IGFyZSBub3QgYmlubmVkOyBvdGhlcndpc2UsIGBmYWxzZWAuXG4gICAqL1xuICBncmlkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBib29sZWFuIGZsYWcgaW5kaWNhdGluZyBpZiBsYWJlbHMgc2hvdWxkIGJlIGluY2x1ZGVkIGFzIHBhcnQgb2YgdGhlIGF4aXMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAgYHRydWVgLlxuICAgKi9cbiAgbGFiZWxzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIGlmIGxhYmVscyBzaG91bGQgYmUgaGlkZGVuIGlmIHRoZXkgZXhjZWVkIHRoZSBheGlzIHJhbmdlLiBJZsKgYGZhbHNlwqBgKHRoZSBkZWZhdWx0KSBubyBib3VuZHMgb3ZlcmxhcCBhbmFseXNpcyBpcyBwZXJmb3JtZWQuIElmwqBgdHJ1ZWAsIGxhYmVscyB3aWxsIGJlIGhpZGRlbiBpZiB0aGV5IGV4Y2VlZCB0aGUgYXhpcyByYW5nZSBieSBtb3JlIHRoYW4gMSBwaXhlbC4gSWYgdGhpcyBwcm9wZXJ0eSBpcyBhIG51bWJlciwgaXQgc3BlY2lmaWVzIHRoZSBwaXhlbCB0b2xlcmFuY2U6IHRoZSBtYXhpbXVtIGFtb3VudCBieSB3aGljaCBhIGxhYmVsIGJvdW5kaW5nIGJveCBtYXkgZXhjZWVkIHRoZSBheGlzIHJhbmdlLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYGZhbHNlYC5cbiAgICovXG4gIGxhYmVsQm91bmQ/OiBib29sZWFuIHwgbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGZpcnN0IGFuZCBsYXN0IGF4aXMgbGFiZWxzIHNob3VsZCBiZSBhbGlnbmVkIGZsdXNoIHdpdGggdGhlIHNjYWxlIHJhbmdlLiBGbHVzaCBhbGlnbm1lbnQgZm9yIGEgaG9yaXpvbnRhbCBheGlzIHdpbGwgbGVmdC1hbGlnbiB0aGUgZmlyc3QgbGFiZWwgYW5kIHJpZ2h0LWFsaWduIHRoZSBsYXN0IGxhYmVsLiBGb3IgdmVydGljYWwgYXhlcywgYm90dG9tIGFuZCB0b3AgdGV4dCBiYXNlbGluZXMgYXJlIGFwcGxpZWQgaW5zdGVhZC4gSWYgdGhpcyBwcm9wZXJ0eSBpcyBhIG51bWJlciwgaXQgYWxzbyBpbmRpY2F0ZXMgdGhlIG51bWJlciBvZiBwaXhlbHMgYnkgd2hpY2ggdG8gb2Zmc2V0IHRoZSBmaXJzdCBhbmQgbGFzdCBsYWJlbHM7IGZvciBleGFtcGxlLCBhIHZhbHVlIG9mIDIgd2lsbCBmbHVzaC1hbGlnbiB0aGUgZmlyc3QgYW5kIGxhc3QgbGFiZWxzIGFuZCBhbHNvIHB1c2ggdGhlbSAyIHBpeGVscyBvdXR3YXJkIGZyb20gdGhlIGNlbnRlciBvZiB0aGUgYXhpcy4gVGhlIGFkZGl0aW9uYWwgYWRqdXN0bWVudCBjYW4gc29tZXRpbWVzIGhlbHAgdGhlIGxhYmVscyBiZXR0ZXIgdmlzdWFsbHkgZ3JvdXAgd2l0aCBjb3JyZXNwb25kaW5nIGF4aXMgdGlja3MuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgdHJ1ZWAgZm9yIGF4aXMgb2YgYSBjb250aW51b3VzIHgtc2NhbGUuIE90aGVyd2lzZSwgYGZhbHNlYC5cbiAgICovXG4gIGxhYmVsRmx1c2g/OiBib29sZWFuIHwgbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RyYXRlZ3kgdG8gdXNlIGZvciByZXNvbHZpbmcgb3ZlcmxhcCBvZiBheGlzIGxhYmVscy4gSWYgYGZhbHNlYCAodGhlIGRlZmF1bHQpLCBubyBvdmVybGFwIHJlZHVjdGlvbiBpcyBhdHRlbXB0ZWQuIElmIHNldCB0byBgdHJ1ZWAgb3IgYFwicGFyaXR5XCJgLCBhIHN0cmF0ZWd5IG9mIHJlbW92aW5nIGV2ZXJ5IG90aGVyIGxhYmVsIGlzIHVzZWQgKHRoaXMgd29ya3Mgd2VsbCBmb3Igc3RhbmRhcmQgbGluZWFyIGF4ZXMpLiBJZiBzZXQgdG8gYFwiZ3JlZWR5XCJgLCBhIGxpbmVhciBzY2FuIG9mIHRoZSBsYWJlbHMgaXMgcGVyZm9ybWVkLCByZW1vdmluZyBhbnkgbGFiZWxzIHRoYXQgb3ZlcmxhcHMgd2l0aCB0aGUgbGFzdCB2aXNpYmxlIGxhYmVsICh0aGlzIG9mdGVuIHdvcmtzIGJldHRlciBmb3IgbG9nLXNjYWxlZCBheGVzKS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGB0cnVlYCBmb3Igbm9uLW5vbWluYWwgZmllbGRzIHdpdGggbm9uLWxvZyBzY2FsZXM7IGBcImdyZWVkeVwiYCBmb3IgbG9nIHNjYWxlczsgb3RoZXJ3aXNlIGBmYWxzZWAuXG4gICAqL1xuICBsYWJlbE92ZXJsYXA/OiBib29sZWFuIHwgJ3Bhcml0eScgfCAnZ3JlZWR5JztcblxuICAvKipcbiAgICogVGhlIHBhZGRpbmcsIGluIHBpeGVscywgYmV0d2VlbiBheGlzIGFuZCB0ZXh0IGxhYmVscy5cbiAgICovXG4gIGxhYmVsUGFkZGluZz86IG51bWJlcjtcblxuICAvKipcbiAgICogQm9vbGVhbiB2YWx1ZSB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgYXhpcyBzaG91bGQgaW5jbHVkZSB0aWNrcy5cbiAgICovXG4gIHRpY2tzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHNpemUgaW4gcGl4ZWxzIG9mIGF4aXMgdGlja3MuXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIHRpY2tTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBNYXggbGVuZ3RoIGZvciBheGlzIHRpdGxlIGlmIHRoZSB0aXRsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBmcm9tIHRoZSBmaWVsZCdzIGRlc2NyaXB0aW9uLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHRpdGxlTWF4TGVuZ3RoPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcGFkZGluZywgaW4gcGl4ZWxzLCBiZXR3ZWVuIHRpdGxlIGFuZCBheGlzLlxuICAgKi9cbiAgdGl0bGVQYWRkaW5nPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgbWluaW11bSBleHRlbnQgaW4gcGl4ZWxzIHRoYXQgYXhpcyB0aWNrcyBhbmQgbGFiZWxzIHNob3VsZCB1c2UuIFRoaXMgZGV0ZXJtaW5lcyBhIG1pbmltdW0gb2Zmc2V0IHZhbHVlIGZvciBheGlzIHRpdGxlcy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAzMGAgZm9yIHktYXhpczsgYHVuZGVmaW5lZGAgZm9yIHgtYXhpcy5cbiAgICovXG4gIG1pbkV4dGVudD86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG1heGltdW0gZXh0ZW50IGluIHBpeGVscyB0aGF0IGF4aXMgdGlja3MgYW5kIGxhYmVscyBzaG91bGQgdXNlLiBUaGlzIGRldGVybWluZXMgYSBtYXhpbXVtIG9mZnNldCB2YWx1ZSBmb3IgYXhpcyB0aXRsZXMuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgdW5kZWZpbmVkYC5cbiAgICovXG4gIG1heEV4dGVudD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0F4aXNDb25maWcgZXh0ZW5kcyBWZ0F4aXNCYXNlIHtcbiAgLyoqXG4gICAqIEFuIGludGVycG9sYXRpb24gZnJhY3Rpb24gaW5kaWNhdGluZyB3aGVyZSwgZm9yIGBiYW5kYCBzY2FsZXMsIGF4aXMgdGlja3Mgc2hvdWxkIGJlIHBvc2l0aW9uZWQuIEEgdmFsdWUgb2YgYDBgIHBsYWNlcyB0aWNrcyBhdCB0aGUgbGVmdCBlZGdlIG9mIHRoZWlyIGJhbmRzLiBBIHZhbHVlIG9mIGAwLjVgIHBsYWNlcyB0aWNrcyBpbiB0aGUgbWlkZGxlIG9mIHRoZWlyIGJhbmRzLlxuICAgKi9cbiAgYmFuZFBvc2l0aW9uPzogbnVtYmVyO1xuICAvKipcbiAgICogU3Ryb2tlIHdpZHRoIG9mIGF4aXMgZG9tYWluIGxpbmVcbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fICAobm9uZSwgdXNpbmcgVmVnYSBkZWZhdWx0KS5cbiAgICovXG4gIGRvbWFpbldpZHRoPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDb2xvciBvZiBheGlzIGRvbWFpbiBsaW5lLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gIChub25lLCB1c2luZyBWZWdhIGRlZmF1bHQpLlxuICAgKi9cbiAgZG9tYWluQ29sb3I/OiBzdHJpbmc7XG5cbiAgLy8gLS0tLS0tLS0tLSBHcmlkIC0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIENvbG9yIG9mIGdyaWRsaW5lcy5cbiAgICovXG4gIGdyaWRDb2xvcj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9mZnNldCAoaW4gcGl4ZWxzKSBpbnRvIHdoaWNoIHRvIGJlZ2luIGRyYXdpbmcgd2l0aCB0aGUgZ3JpZCBkYXNoIGFycmF5LlxuICAgKi9cbiAgZ3JpZERhc2g/OiBudW1iZXJbXTtcblxuICAvKipcbiAgICogVGhlIHN0cm9rZSBvcGFjaXR5IG9mIGdyaWQgKHZhbHVlIGJldHdlZW4gWzAsMV0pXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAoYDFgIGJ5IGRlZmF1bHQpXG4gICAqIEBtaW5pbXVtIDBcbiAgICogQG1heGltdW0gMVxuICAgKi9cbiAgZ3JpZE9wYWNpdHk/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBncmlkIHdpZHRoLCBpbiBwaXhlbHMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGdyaWRXaWR0aD86IG51bWJlcjtcblxuICAvLyAtLS0tLS0tLS0tIFRpY2tzIC0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIFRoZSBjb2xvciBvZiB0aGUgYXhpcydzIHRpY2suXG4gICAqL1xuICB0aWNrQ29sb3I/OiBzdHJpbmc7XG5cblxuICAvKipcbiAgICogVGhlIHJvdGF0aW9uIGFuZ2xlIG9mIHRoZSBheGlzIGxhYmVscy5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAtOTBgIGZvciBub21pbmFsIGFuZCBvcmRpbmFsIGZpZWxkczsgYDBgIG90aGVyd2lzZS5cbiAgICpcbiAgICogQG1pbmltdW0gLTM2MFxuICAgKiBAbWF4aW11bSAzNjBcbiAgICovXG4gIGxhYmVsQW5nbGU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBjb2xvciBvZiB0aGUgdGljayBsYWJlbCwgY2FuIGJlIGluIGhleCBjb2xvciBjb2RlIG9yIHJlZ3VsYXIgY29sb3IgbmFtZS5cbiAgICovXG4gIGxhYmVsQ29sb3I/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBmb250IG9mIHRoZSB0aWNrIGxhYmVsLlxuICAgKi9cbiAgbGFiZWxGb250Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9udCBzaXplIG9mIHRoZSBsYWJlbCwgaW4gcGl4ZWxzLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBsYWJlbEZvbnRTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIGFsbG93ZWQgcGl4ZWwgd2lkdGggb2YgYXhpcyB0aWNrIGxhYmVscy5cbiAgICovXG4gIGxhYmVsTGltaXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIGlmIHBpeGVsIHBvc2l0aW9uIHZhbHVlcyBzaG91bGQgYmUgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyLlxuICAgKi9cbiAgdGlja1JvdW5kPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHdpZHRoLCBpbiBwaXhlbHMsIG9mIHRpY2tzLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICB0aWNrV2lkdGg/OiBudW1iZXI7XG5cbiAgLy8gLS0tLS0tLS0tLSBUaXRsZSAtLS0tLS0tLS0tXG5cbiAgLyoqXG4gICAqIEhvcml6b250YWwgdGV4dCBhbGlnbm1lbnQgb2YgYXhpcyB0aXRsZXMuXG4gICAqL1xuICB0aXRsZUFsaWduPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBbmdsZSBpbiBkZWdyZWVzIG9mIGF4aXMgdGl0bGVzLlxuICAgKi9cbiAgdGl0bGVBbmdsZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFZlcnRpY2FsIHRleHQgYmFzZWxpbmUgZm9yIGF4aXMgdGl0bGVzLlxuICAgKi9cbiAgdGl0bGVCYXNlbGluZT86IHN0cmluZztcbiAgLyoqXG4gICAqIENvbG9yIG9mIHRoZSB0aXRsZSwgY2FuIGJlIGluIGhleCBjb2xvciBjb2RlIG9yIHJlZ3VsYXIgY29sb3IgbmFtZS5cbiAgICovXG4gIHRpdGxlQ29sb3I/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEZvbnQgb2YgdGhlIHRpdGxlLiAoZS5nLiwgYFwiSGVsdmV0aWNhIE5ldWVcImApLlxuICAgKi9cbiAgdGl0bGVGb250Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGb250IHNpemUgb2YgdGhlIHRpdGxlLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICB0aXRsZUZvbnRTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBGb250IHdlaWdodCBvZiB0aGUgdGl0bGUuIChlLmcuLCBgXCJib2xkXCJgKS5cbiAgICovXG4gIHRpdGxlRm9udFdlaWdodD86IHN0cmluZyB8IG51bWJlcjtcblxuICAvKipcbiAgICogTWF4aW11bSBhbGxvd2VkIHBpeGVsIHdpZHRoIG9mIGF4aXMgdGl0bGVzLlxuICAgKi9cbiAgdGl0bGVMaW1pdD86IG51bWJlcjtcblxuICAvKipcbiAgICogWC1jb29yZGluYXRlIG9mIHRoZSBheGlzIHRpdGxlIHJlbGF0aXZlIHRvIHRoZSBheGlzIGdyb3VwLlxuICAgKi9cbiAgdGl0bGVYPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBZLWNvb3JkaW5hdGUgb2YgdGhlIGF4aXMgdGl0bGUgcmVsYXRpdmUgdG8gdGhlIGF4aXMgZ3JvdXAuXG4gICAqL1xuICB0aXRsZVk/OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIExlZ2VuZE9yaWVudCA9ICdsZWZ0JyB8ICdyaWdodCcgfCAndG9wLWxlZnQnIHwgJ3RvcC1yaWdodCcgfCAnYm90dG9tLWxlZnQnIHwgJ2JvdHRvbS1yaWdodCcgfCAnbm9uZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmdMZWdlbmRCYXNlIHtcbiAgLyoqXG4gICAqIFBhZGRpbmcgKGluIHBpeGVscykgYmV0d2VlbiBsZWdlbmQgZW50cmllcyBpbiBhIHN5bWJvbCBsZWdlbmQuXG4gICAqL1xuICBlbnRyeVBhZGRpbmc/OiBudW1iZXI7XG5cblxuICAvKipcbiAgICogVGhlIG9yaWVudGF0aW9uIG9mIHRoZSBsZWdlbmQsIHdoaWNoIGRldGVybWluZXMgaG93IHRoZSBsZWdlbmQgaXMgcG9zaXRpb25lZCB3aXRoaW4gdGhlIHNjZW5lLiBPbmUgb2YgXCJsZWZ0XCIsIFwicmlnaHRcIiwgXCJ0b3AtbGVmdFwiLCBcInRvcC1yaWdodFwiLCBcImJvdHRvbS1sZWZ0XCIsIFwiYm90dG9tLXJpZ2h0XCIsIFwibm9uZVwiLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYFwicmlnaHRcImBcbiAgICovXG4gIG9yaWVudD86IExlZ2VuZE9yaWVudDtcblxuICAvKipcbiAgICogVGhlIG9mZnNldCwgaW4gcGl4ZWxzLCBieSB3aGljaCB0byBkaXNwbGFjZSB0aGUgbGVnZW5kIGZyb20gdGhlIGVkZ2Ugb2YgdGhlIGVuY2xvc2luZyBncm91cCBvciBkYXRhIHJlY3RhbmdsZS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fICBgMGBcbiAgICovXG4gIG9mZnNldD86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHBhZGRpbmcsIGluIHBpeGVscywgYmV0d2VlbiB0aGUgbGVnZW5kIGFuZCBheGlzLlxuICAgKi9cbiAgcGFkZGluZz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZ0xlZ2VuZENvbmZpZyBleHRlbmRzIFZnTGVnZW5kQmFzZSB7XG5cbiAgLyoqXG4gICAqIENvcm5lciByYWRpdXMgZm9yIHRoZSBmdWxsIGxlZ2VuZC5cbiAgICovXG4gIGNvcm5lclJhZGl1cz86IG51bWJlcjtcblxuICAvKipcbiAgICogQmFja2dyb3VuZCBmaWxsIGNvbG9yIGZvciB0aGUgZnVsbCBsZWdlbmQuXG4gICAqL1xuICBmaWxsQ29sb3I/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEJvcmRlciBzdHJva2UgY29sb3IgZm9yIHRoZSBmdWxsIGxlZ2VuZC5cbiAgICovXG4gIHN0cm9rZUNvbG9yPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBCb3JkZXIgc3Ryb2tlIGRhc2ggcGF0dGVybiBmb3IgdGhlIGZ1bGwgbGVnZW5kLlxuICAgKi9cbiAgc3Ryb2tlRGFzaD86IG51bWJlcltdO1xuXG4gIC8qKlxuICAgKiBCb3JkZXIgc3Ryb2tlIHdpZHRoIGZvciB0aGUgZnVsbCBsZWdlbmQuXG4gICAqL1xuICBzdHJva2VXaWR0aD86IG51bWJlcjtcbiAgLy8gLS0tLS0tLS0tLSBHcmFkaWVudCAtLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBUaGUgY29sb3Igb2YgdGhlIGdyYWRpZW50IHN0cm9rZSwgY2FuIGJlIGluIGhleCBjb2xvciBjb2RlIG9yIHJlZ3VsYXIgY29sb3IgbmFtZS5cbiAgICovXG4gIGdyYWRpZW50U3Ryb2tlQ29sb3I/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB3aWR0aCBvZiB0aGUgZ3JhZGllbnQgc3Ryb2tlLCBpbiBwaXhlbHMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGdyYWRpZW50U3Ryb2tlV2lkdGg/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBoZWlnaHQgb2YgdGhlIGdyYWRpZW50LCBpbiBwaXhlbHMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGdyYWRpZW50SGVpZ2h0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUZXh0IGJhc2VsaW5lIGZvciBjb2xvciByYW1wIGdyYWRpZW50IGxhYmVscy5cbiAgICovXG4gIGdyYWRpZW50TGFiZWxCYXNlbGluZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG1heGltdW0gYWxsb3dlZCBsZW5ndGggaW4gcGl4ZWxzIG9mIGNvbG9yIHJhbXAgZ3JhZGllbnQgbGFiZWxzLlxuICAgKi9cbiAgZ3JhZGllbnRMYWJlbExpbWl0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBWZXJ0aWNhbCBvZmZzZXQgaW4gcGl4ZWxzIGZvciBjb2xvciByYW1wIGdyYWRpZW50IGxhYmVscy5cbiAgICovXG4gIGdyYWRpZW50TGFiZWxPZmZzZXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB3aWR0aCBvZiB0aGUgZ3JhZGllbnQsIGluIHBpeGVscy5cbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgZ3JhZGllbnRXaWR0aD86IG51bWJlcjtcblxuICAvLyAtLS0tLS0tLS0tIExhYmVsIC0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIFRoZSBhbGlnbm1lbnQgb2YgdGhlIGxlZ2VuZCBsYWJlbCwgY2FuIGJlIGxlZnQsIG1pZGRsZSBvciByaWdodC5cbiAgICovXG4gIGxhYmVsQWxpZ24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3NpdGlvbiBvZiB0aGUgYmFzZWxpbmUgb2YgbGVnZW5kIGxhYmVsLCBjYW4gYmUgdG9wLCBtaWRkbGUgb3IgYm90dG9tLlxuICAgKi9cbiAgbGFiZWxCYXNlbGluZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNvbG9yIG9mIHRoZSBsZWdlbmQgbGFiZWwsIGNhbiBiZSBpbiBoZXggY29sb3IgY29kZSBvciByZWd1bGFyIGNvbG9yIG5hbWUuXG4gICAqL1xuICBsYWJlbENvbG9yPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9udCBvZiB0aGUgbGVnZW5kIGxhYmVsLlxuICAgKi9cbiAgbGFiZWxGb250Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9udCBzaXplIG9mIGxlZ2VuZCBsYWJlbC5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAxMGAuXG4gICAqXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGxhYmVsRm9udFNpemU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIE1heGltdW0gYWxsb3dlZCBwaXhlbCB3aWR0aCBvZiBheGlzIHRpY2sgbGFiZWxzLlxuICAgKi9cbiAgbGFiZWxMaW1pdD86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG9mZnNldCBvZiB0aGUgbGVnZW5kIGxhYmVsLlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBsYWJlbE9mZnNldD86IG51bWJlcjtcblxuICAvLyAtLS0tLS0tLS0tIFN5bWJvbHMgLS0tLS0tLS0tLVxuICAvKipcbiAgICogVGhlIGNvbG9yIG9mIHRoZSBsZWdlbmQgc3ltYm9sLFxuICAgKi9cbiAgc3ltYm9sQ29sb3I/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgc2hhcGUgdHlwZSAoc3VjaCBhcyBcImNpcmNsZVwiKSBmb3IgbGVnZW5kIHN5bWJvbHMuXG4gICAqL1xuICBzeW1ib2xUeXBlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgc2l6ZSBvZiB0aGUgbGVnZW5kIHN5bWJvbCwgaW4gcGl4ZWxzLlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBzeW1ib2xTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgd2lkdGggb2YgdGhlIHN5bWJvbCdzIHN0cm9rZS5cbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgc3ltYm9sU3Ryb2tlV2lkdGg/OiBudW1iZXI7XG5cbiAgLy8gLS0tLS0tLS0tLSBUaXRsZSAtLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBIb3Jpem9udGFsIHRleHQgYWxpZ25tZW50IGZvciBsZWdlbmQgdGl0bGVzLlxuICAgKi9cbiAgdGl0bGVBbGlnbj86IHN0cmluZztcblxuICAgLyoqXG4gICAgKiBWZXJ0aWNhbCB0ZXh0IGJhc2VsaW5lIGZvciBsZWdlbmQgdGl0bGVzLlxuICAgICovXG4gIHRpdGxlQmFzZWxpbmU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgY29sb3Igb2YgdGhlIGxlZ2VuZCB0aXRsZSwgY2FuIGJlIGluIGhleCBjb2xvciBjb2RlIG9yIHJlZ3VsYXIgY29sb3IgbmFtZS5cbiAgICovXG4gIHRpdGxlQ29sb3I/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBmb250IG9mIHRoZSBsZWdlbmQgdGl0bGUuXG4gICAqL1xuICB0aXRsZUZvbnQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBmb250IHNpemUgb2YgdGhlIGxlZ2VuZCB0aXRsZS5cbiAgICovXG4gIHRpdGxlRm9udFNpemU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBmb250IHdlaWdodCBvZiB0aGUgbGVnZW5kIHRpdGxlLlxuICAgKi9cbiAgdGl0bGVGb250V2VpZ2h0Pzogc3RyaW5nIHwgbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIGFsbG93ZWQgcGl4ZWwgd2lkdGggb2YgYXhpcyB0aXRsZXMuXG4gICAqL1xuICB0aXRsZUxpbWl0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcGFkZGluZywgaW4gcGl4ZWxzLCBiZXR3ZWVuIHRpdGxlIGFuZCBsZWdlbmQuXG4gICAqL1xuICB0aXRsZVBhZGRpbmc/OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIEZvbnRTdHlsZSA9ICdub3JtYWwnIHwgJ2l0YWxpYyc7XG5leHBvcnQgdHlwZSBGb250V2VpZ2h0ID0gJ25vcm1hbCcgfCAnYm9sZCc7XG4vKipcbiAqIEBUSlMtdHlwZSBpbnRlZ2VyXG4gKiBAbWluaW11bSAxMDBcbiAqIEBtYXhpbXVtIDkwMFxuICovXG5leHBvcnQgdHlwZSBGb250V2VpZ2h0TnVtYmVyID0gbnVtYmVyO1xuZXhwb3J0IHR5cGUgSG9yaXpvbnRhbEFsaWduID0gJ2xlZnQnIHwgJ3JpZ2h0JyB8ICdjZW50ZXInO1xuZXhwb3J0IHR5cGUgSW50ZXJwb2xhdGUgPSAnbGluZWFyJyB8ICdsaW5lYXItY2xvc2VkJyB8XG4gICdzdGVwJyB8ICdzdGVwLWJlZm9yZScgfCAnc3RlcC1hZnRlcicgfFxuICAnYmFzaXMnIHwgJ2Jhc2lzLW9wZW4nIHwgJ2Jhc2lzLWNsb3NlZCcgfFxuICAnY2FyZGluYWwnIHwgJ2NhcmRpbmFsLW9wZW4nIHwgJ2NhcmRpbmFsLWNsb3NlZCcgfFxuICAnYnVuZGxlJyB8ICdtb25vdG9uZSc7XG5leHBvcnQgdHlwZSBPcmllbnQgPSAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnO1xuZXhwb3J0IHR5cGUgVmVydGljYWxBbGlnbiA9ICd0b3AnIHwgJ21pZGRsZScgfCAnYm90dG9tJztcblxuZXhwb3J0IGludGVyZmFjZSBWZ01hcmtDb25maWcge1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IEZpbGwgQ29sb3IuICBUaGlzIGhhcyBoaWdoZXIgcHJlY2VkZW5jZSB0aGFuIGNvbmZpZy5jb2xvclxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gKE5vbmUpXG4gICAqXG4gICAqL1xuICBmaWxsPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IFN0cm9rZSBDb2xvci4gIFRoaXMgaGFzIGhpZ2hlciBwcmVjZWRlbmNlIHRoYW4gY29uZmlnLmNvbG9yXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyAoTm9uZSlcbiAgICpcbiAgICovXG4gIHN0cm9rZT86IHN0cmluZztcblxuICAvLyAtLS0tLS0tLS0tIE9wYWNpdHkgLS0tLS0tLS0tLVxuICAvKipcbiAgICogVGhlIG92ZXJhbGwgb3BhY2l0eSAodmFsdWUgYmV0d2VlbiBbMCwxXSkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMC43YCBmb3Igbm9uLWFnZ3JlZ2F0ZSBwbG90cyB3aXRoIGBwb2ludGAsIGB0aWNrYCwgYGNpcmNsZWAsIG9yIGBzcXVhcmVgIG1hcmtzIG9yIGxheWVyZWQgYGJhcmAgY2hhcnRzIGFuZCBgMWAgb3RoZXJ3aXNlLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIG9wYWNpdHk/OiBudW1iZXI7XG5cblxuICAvKipcbiAgICogVGhlIGZpbGwgb3BhY2l0eSAodmFsdWUgYmV0d2VlbiBbMCwxXSkuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgMWBcbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKiBAbWF4aW11bSAxXG4gICAqL1xuICBmaWxsT3BhY2l0eT86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHN0cm9rZSBvcGFjaXR5ICh2YWx1ZSBiZXR3ZWVuIFswLDFdKS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAxYFxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIHN0cm9rZU9wYWNpdHk/OiBudW1iZXI7XG5cbiAgLy8gLS0tLS0tLS0tLSBTdHJva2UgU3R5bGUgLS0tLS0tLS0tLVxuICAvKipcbiAgICogVGhlIHN0cm9rZSB3aWR0aCwgaW4gcGl4ZWxzLlxuICAgKlxuICAgKiBAbWluaW11bSAwXG4gICAqL1xuICBzdHJva2VXaWR0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogQW4gYXJyYXkgb2YgYWx0ZXJuYXRpbmcgc3Ryb2tlLCBzcGFjZSBsZW5ndGhzIGZvciBjcmVhdGluZyBkYXNoZWQgb3IgZG90dGVkIGxpbmVzLlxuICAgKi9cbiAgc3Ryb2tlRGFzaD86IG51bWJlcltdO1xuXG4gIC8qKlxuICAgKiBUaGUgb2Zmc2V0IChpbiBwaXhlbHMpIGludG8gd2hpY2ggdG8gYmVnaW4gZHJhd2luZyB3aXRoIHRoZSBzdHJva2UgZGFzaCBhcnJheS5cbiAgICovXG4gIHN0cm9rZURhc2hPZmZzZXQ/OiBudW1iZXI7XG5cbiAgLy8gLS0tLS0tLS0tLSBPcmllbnRhdGlvbjogQmFyLCBUaWNrLCBMaW5lLCBBcmVhIC0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIFRoZSBvcmllbnRhdGlvbiBvZiBhIG5vbi1zdGFja2VkIGJhciwgdGljaywgYXJlYSwgYW5kIGxpbmUgY2hhcnRzLlxuICAgKiBUaGUgdmFsdWUgaXMgZWl0aGVyIGhvcml6b250YWwgKGRlZmF1bHQpIG9yIHZlcnRpY2FsLlxuICAgKiAtIEZvciBiYXIsIHJ1bGUgYW5kIHRpY2ssIHRoaXMgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzaXplIG9mIHRoZSBiYXIgYW5kIHRpY2tcbiAgICogc2hvdWxkIGJlIGFwcGxpZWQgdG8geCBvciB5IGRpbWVuc2lvbi5cbiAgICogLSBGb3IgYXJlYSwgdGhpcyBwcm9wZXJ0eSBkZXRlcm1pbmVzIHRoZSBvcmllbnQgcHJvcGVydHkgb2YgdGhlIFZlZ2Egb3V0cHV0LlxuICAgKiAtIEZvciBsaW5lLCB0aGlzIHByb3BlcnR5IGRldGVybWluZXMgdGhlIHNvcnQgb3JkZXIgb2YgdGhlIHBvaW50cyBpbiB0aGUgbGluZVxuICAgKiBpZiBgY29uZmlnLnNvcnRMaW5lQnlgIGlzIG5vdCBzcGVjaWZpZWQuXG4gICAqIEZvciBzdGFja2VkIGNoYXJ0cywgdGhpcyBpcyBhbHdheXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JpZW50YXRpb24gb2YgdGhlIHN0YWNrO1xuICAgKiB0aGVyZWZvcmUgZXhwbGljaXRseSBzcGVjaWZpZWQgdmFsdWUgd2lsbCBiZSBpZ25vcmVkLlxuICAgKi9cbiAgb3JpZW50PzogT3JpZW50O1xuXG4gIC8vIC0tLS0tLS0tLS0gSW50ZXJwb2xhdGlvbjogTGluZSAvIGFyZWEgLS0tLS0tLS0tLVxuICAvKipcbiAgICogVGhlIGxpbmUgaW50ZXJwb2xhdGlvbiBtZXRob2QgdG8gdXNlIGZvciBsaW5lIGFuZCBhcmVhIG1hcmtzLiBPbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICogLSBgXCJsaW5lYXJcImA6IHBpZWNld2lzZSBsaW5lYXIgc2VnbWVudHMsIGFzIGluIGEgcG9seWxpbmUuXG4gICAqIC0gYFwibGluZWFyLWNsb3NlZFwiYDogY2xvc2UgdGhlIGxpbmVhciBzZWdtZW50cyB0byBmb3JtIGEgcG9seWdvbi5cbiAgICogLSBgXCJzdGVwXCJgOiBhbHRlcm5hdGUgYmV0d2VlbiBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCBzZWdtZW50cywgYXMgaW4gYSBzdGVwIGZ1bmN0aW9uLlxuICAgKiAtIGBcInN0ZXAtYmVmb3JlXCJgOiBhbHRlcm5hdGUgYmV0d2VlbiB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBzZWdtZW50cywgYXMgaW4gYSBzdGVwIGZ1bmN0aW9uLlxuICAgKiAtIGBcInN0ZXAtYWZ0ZXJcImA6IGFsdGVybmF0ZSBiZXR3ZWVuIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIHNlZ21lbnRzLCBhcyBpbiBhIHN0ZXAgZnVuY3Rpb24uXG4gICAqIC0gYFwiYmFzaXNcImA6IGEgQi1zcGxpbmUsIHdpdGggY29udHJvbCBwb2ludCBkdXBsaWNhdGlvbiBvbiB0aGUgZW5kcy5cbiAgICogLSBgXCJiYXNpcy1vcGVuXCJgOiBhbiBvcGVuIEItc3BsaW5lOyBtYXkgbm90IGludGVyc2VjdCB0aGUgc3RhcnQgb3IgZW5kLlxuICAgKiAtIGBcImJhc2lzLWNsb3NlZFwiYDogYSBjbG9zZWQgQi1zcGxpbmUsIGFzIGluIGEgbG9vcC5cbiAgICogLSBgXCJjYXJkaW5hbFwiYDogYSBDYXJkaW5hbCBzcGxpbmUsIHdpdGggY29udHJvbCBwb2ludCBkdXBsaWNhdGlvbiBvbiB0aGUgZW5kcy5cbiAgICogLSBgXCJjYXJkaW5hbC1vcGVuXCJgOiBhbiBvcGVuIENhcmRpbmFsIHNwbGluZTsgbWF5IG5vdCBpbnRlcnNlY3QgdGhlIHN0YXJ0IG9yIGVuZCwgYnV0IHdpbGwgaW50ZXJzZWN0IG90aGVyIGNvbnRyb2wgcG9pbnRzLlxuICAgKiAtIGBcImNhcmRpbmFsLWNsb3NlZFwiYDogYSBjbG9zZWQgQ2FyZGluYWwgc3BsaW5lLCBhcyBpbiBhIGxvb3AuXG4gICAqIC0gYFwiYnVuZGxlXCJgOiBlcXVpdmFsZW50IHRvIGJhc2lzLCBleGNlcHQgdGhlIHRlbnNpb24gcGFyYW1ldGVyIGlzIHVzZWQgdG8gc3RyYWlnaHRlbiB0aGUgc3BsaW5lLlxuICAgKiAtIGBcIm1vbm90b25lXCJgOiBjdWJpYyBpbnRlcnBvbGF0aW9uIHRoYXQgcHJlc2VydmVzIG1vbm90b25pY2l0eSBpbiB5LlxuICAgKi9cbiAgaW50ZXJwb2xhdGU/OiBJbnRlcnBvbGF0ZTtcbiAgLyoqXG4gICAqIERlcGVuZGluZyBvbiB0aGUgaW50ZXJwb2xhdGlvbiB0eXBlLCBzZXRzIHRoZSB0ZW5zaW9uIHBhcmFtZXRlciAoZm9yIGxpbmUgYW5kIGFyZWEgbWFya3MpLlxuICAgKiBAbWluaW11bSAwXG4gICAqIEBtYXhpbXVtIDFcbiAgICovXG4gIHRlbnNpb24/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IHN5bWJvbCBzaGFwZSB0byB1c2UuIE9uZSBvZjogYFwiY2lyY2xlXCJgIChkZWZhdWx0KSwgYFwic3F1YXJlXCJgLCBgXCJjcm9zc1wiYCwgYFwiZGlhbW9uZFwiYCwgYFwidHJpYW5nbGUtdXBcImAsIG9yIGBcInRyaWFuZ2xlLWRvd25cImAsIG9yIGEgY3VzdG9tIFNWRyBwYXRoLlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYFwiY2lyY2xlXCJgXG4gICAqXG4gICAqL1xuICBzaGFwZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBpeGVsIGFyZWEgZWFjaCB0aGUgcG9pbnQvY2lyY2xlL3NxdWFyZS5cbiAgICogRm9yIGV4YW1wbGU6IGluIHRoZSBjYXNlIG9mIGNpcmNsZXMsIHRoZSByYWRpdXMgaXMgZGV0ZXJtaW5lZCBpbiBwYXJ0IGJ5IHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgc2l6ZSB2YWx1ZS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGAzMGBcbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgc2l6ZT86IG51bWJlcjtcblxuICAvLyBUZXh0IC8gTGFiZWwgTWFyayBDb25maWdcblxuICAvKipcbiAgICogVGhlIGhvcml6b250YWwgYWxpZ25tZW50IG9mIHRoZSB0ZXh0LiBPbmUgb2YgYFwibGVmdFwiYCwgYFwicmlnaHRcImAsIGBcImNlbnRlclwiYC5cbiAgICovXG4gIGFsaWduPzogSG9yaXpvbnRhbEFsaWduO1xuXG4gIC8qKlxuICAgKiBUaGUgcm90YXRpb24gYW5nbGUgb2YgdGhlIHRleHQsIGluIGRlZ3JlZXMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICogQG1heGltdW0gMzYwXG4gICAqL1xuICBhbmdsZT86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHZlcnRpY2FsIGFsaWdubWVudCBvZiB0aGUgdGV4dC4gT25lIG9mIGBcInRvcFwiYCwgYFwibWlkZGxlXCJgLCBgXCJib3R0b21cImAuXG4gICAqXG4gICAqIF9fRGVmYXVsdCB2YWx1ZTpfXyBgXCJtaWRkbGVcImBcbiAgICpcbiAgICovXG4gIGJhc2VsaW5lPzogVmVydGljYWxBbGlnbjtcblxuICAvKipcbiAgICogVGhlIGhvcml6b250YWwgb2Zmc2V0LCBpbiBwaXhlbHMsIGJldHdlZW4gdGhlIHRleHQgbGFiZWwgYW5kIGl0cyBhbmNob3IgcG9pbnQuIFRoZSBvZmZzZXQgaXMgYXBwbGllZCBhZnRlciByb3RhdGlvbiBieSB0aGUgX2FuZ2xlXyBwcm9wZXJ0eS5cbiAgICovXG4gIGR4PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVydGljYWwgb2Zmc2V0LCBpbiBwaXhlbHMsIGJldHdlZW4gdGhlIHRleHQgbGFiZWwgYW5kIGl0cyBhbmNob3IgcG9pbnQuIFRoZSBvZmZzZXQgaXMgYXBwbGllZCBhZnRlciByb3RhdGlvbiBieSB0aGUgX2FuZ2xlXyBwcm9wZXJ0eS5cbiAgICovXG4gIGR5PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBQb2xhciBjb29yZGluYXRlIHJhZGlhbCBvZmZzZXQsIGluIHBpeGVscywgb2YgdGhlIHRleHQgbGFiZWwgZnJvbSB0aGUgb3JpZ2luIGRldGVybWluZWQgYnkgdGhlIGB4YCBhbmQgYHlgIHByb3BlcnRpZXMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIHJhZGl1cz86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSB0ZXh0IG1hcmsgaW4gcGl4ZWxzIChkZWZhdWx0IDAsIGluZGljYXRpbmcgbm8gbGltaXQpLiBUaGUgdGV4dCB2YWx1ZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdHJ1bmNhdGVkIGlmIHRoZSByZW5kZXJlZCBzaXplIGV4Y2VlZHMgdGhlIGxpbWl0LlxuICAgKi9cbiAgbGltaXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFBvbGFyIGNvb3JkaW5hdGUgYW5nbGUsIGluIHJhZGlhbnMsIG9mIHRoZSB0ZXh0IGxhYmVsIGZyb20gdGhlIG9yaWdpbiBkZXRlcm1pbmVkIGJ5IHRoZSBgeGAgYW5kIGB5YCBwcm9wZXJ0aWVzLiBWYWx1ZXMgZm9yIGB0aGV0YWAgZm9sbG93IHRoZSBzYW1lIGNvbnZlbnRpb24gb2YgYGFyY2AgbWFyayBgc3RhcnRBbmdsZWAgYW5kIGBlbmRBbmdsZWAgcHJvcGVydGllczogYW5nbGVzIGFyZSBtZWFzdXJlZCBpbiByYWRpYW5zLCB3aXRoIGAwYCBpbmRpY2F0aW5nIFwibm9ydGhcIi5cbiAgICovXG4gIHRoZXRhPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgdHlwZWZhY2UgdG8gc2V0IHRoZSB0ZXh0IGluIChlLmcuLCBgXCJIZWx2ZXRpY2EgTmV1ZVwiYCkuXG4gICAqL1xuICBmb250Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9udCBzaXplLCBpbiBwaXhlbHMuXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIGZvbnRTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9udCBzdHlsZSAoZS5nLiwgYFwiaXRhbGljXCJgKS5cbiAgICovXG4gIGZvbnRTdHlsZT86IEZvbnRTdHlsZTtcbiAgLyoqXG4gICAqIFRoZSBmb250IHdlaWdodCAoZS5nLiwgYFwiYm9sZFwiYCkuXG4gICAqL1xuICBmb250V2VpZ2h0PzogRm9udFdlaWdodCB8IEZvbnRXZWlnaHROdW1iZXI7XG5cbiAgLyoqXG4gICAqIFBsYWNlaG9sZGVyIHRleHQgaWYgdGhlIGB0ZXh0YCBjaGFubmVsIGlzIG5vdCBzcGVjaWZpZWRcbiAgICovXG4gIHRleHQ/OiBzdHJpbmc7XG59XG5cbmNvbnN0IFZHX01BUktfQ09ORklHX0lOREVYOiBGbGFnPGtleW9mIFZnTWFya0NvbmZpZz4gPSB7XG4gIG9wYWNpdHk6IDEsXG4gIGZpbGw6IDEsXG4gIGZpbGxPcGFjaXR5OiAxLFxuICBzdHJva2U6IDEsXG4gIHN0cm9rZVdpZHRoOiAxLFxuICBzdHJva2VPcGFjaXR5OiAxLFxuICBzdHJva2VEYXNoOiAxLFxuICBzdHJva2VEYXNoT2Zmc2V0OiAxLFxuICBzaXplOiAxLFxuICBzaGFwZTogMSxcbiAgaW50ZXJwb2xhdGU6IDEsXG4gIHRlbnNpb246IDEsXG4gIG9yaWVudDogMSxcbiAgYWxpZ246IDEsXG4gIGJhc2VsaW5lOiAxLFxuICB0ZXh0OiAxLFxuICBsaW1pdDogMSxcbiAgZHg6IDEsXG4gIGR5OiAxLFxuICByYWRpdXM6IDEsXG4gIHRoZXRhOiAxLFxuICBhbmdsZTogMSxcbiAgZm9udDogMSxcbiAgZm9udFNpemU6IDEsXG4gIGZvbnRXZWlnaHQ6IDEsXG4gIGZvbnRTdHlsZTogMVxuICAvLyBjb21tZW50ZWQgYmVsb3cgYXJlIHZnIGNoYW5uZWwgdGhhdCBkbyBub3QgaGF2ZSBtYXJrIGNvbmZpZy5cbiAgLy8gJ3gnfCd4Mid8J3hjJ3wnd2lkdGgnfCd5J3wneTInfCd5Yyd8J2hlaWdodCdcbiAgLy8gY3Vyc29yOiAxLFxuICAvLyBjbGlwOiAxLFxuICAvLyBkaXI6IDEsXG4gIC8vIGVsbGlwc2lzOiAxLFxuICAvLyBlbmRBbmdsZTogMSxcbiAgLy8gcGF0aDogMSxcbiAgLy8gaW5uZXJSYWRpdXM6IDEsXG4gIC8vIG91dGVyUmFkaXVzOiAxLFxuICAvLyBzdGFydEFuZ2xlOiAxLFxuICAvLyB1cmw6IDEsXG59O1xuXG5leHBvcnQgY29uc3QgVkdfTUFSS19DT05GSUdTID0gZmxhZ0tleXMoVkdfTUFSS19DT05GSUdfSU5ERVgpO1xuXG5leHBvcnQgdHlwZSBBbmNob3IgPSAnc3RhcnQnIHwgJ21pZGRsZScgfCAnZW5kJztcblxuZXhwb3J0IGludGVyZmFjZSBWZ1RpdGxlIHtcbiAgLyoqXG4gICAqIFRoZSB0aXRsZSB0ZXh0LlxuICAgKi9cbiAgdGV4dDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgb3JpZW50YXRpb24gb2YgdGhlIHRpdGxlIHJlbGF0aXZlIHRvIHRoZSBjaGFydC4gT25lIG9mIGBcInRvcFwiYCAodGhlIGRlZmF1bHQpLCBgXCJib3R0b21cImAsIGBcImxlZnRcImAsIG9yIGBcInJpZ2h0XCJgLlxuICAgKi9cbiAgb3JpZW50PzogVGl0bGVPcmllbnQ7XG5cbiAgLyoqXG4gICAqIFRoZSBhbmNob3IgcG9zaXRpb24gZm9yIHBsYWNpbmcgdGhlIHRpdGxlLiBPbmUgb2YgYFwic3RhcnRcImAsIGBcIm1pZGRsZVwiYCAodGhlIGRlZmF1bHQpLCBvciBgXCJlbmRcImAuIEZvciBleGFtcGxlLCB3aXRoIGFuIG9yaWVudGF0aW9uIG9mIHRvcCB0aGVzZSBhbmNob3IgcG9zaXRpb25zIG1hcCB0byBhIGxlZnQtLCBjZW50ZXItLCBvciByaWdodC1hbGlnbmVkIHRpdGxlLlxuICAgKi9cbiAgYW5jaG9yPzogQW5jaG9yO1xuXG4gIC8qKlxuICAgKiBUaGUgb3J0aG9nb25hbCBvZmZzZXQgaW4gcGl4ZWxzIGJ5IHdoaWNoIHRvIGRpc3BsYWNlIHRoZSB0aXRsZSBmcm9tIGl0cyBwb3NpdGlvbiBhbG9uZyB0aGUgZWRnZSBvZiB0aGUgY2hhcnQuXG4gICAqL1xuICBvZmZzZXQ/OiBudW1iZXI7XG5cbiAgc3R5bGU/OiBzdHJpbmcgfCBzdHJpbmdbXTtcblxuICAvLyBUT0RPOiBuYW1lLCBlbmNvZGUsIGludGVyYWN0aXZlLCB6aW5kZXhcbn1cblxuZXhwb3J0IHR5cGUgVGl0bGVPcmllbnQgPSAndG9wJyB8ICdib3R0b20nIHwgJ2xlZnQnIHwgJ3JpZ2h0JztcblxuZXhwb3J0IGludGVyZmFjZSBWZ1RpdGxlQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBhbmNob3IgcG9zaXRpb24gZm9yIHBsYWNpbmcgdGhlIHRpdGxlLiBPbmUgb2YgYFwic3RhcnRcImAsIGBcIm1pZGRsZVwiYCwgb3IgYFwiZW5kXCJgLiBGb3IgZXhhbXBsZSwgd2l0aCBhbiBvcmllbnRhdGlvbiBvZiB0b3AgdGhlc2UgYW5jaG9yIHBvc2l0aW9ucyBtYXAgdG8gYSBsZWZ0LSwgY2VudGVyLSwgb3IgcmlnaHQtYWxpZ25lZCB0aXRsZS5cbiAgICpcbiAgICogX19EZWZhdWx0IHZhbHVlOl9fIGBcIm1pZGRsZVwiYCBmb3IgW3NpbmdsZV0oc3BlYy5odG1sKSBhbmQgW2xheWVyZWRdKGxheWVyLmh0bWwpIHZpZXdzLlxuICAgKiBgXCJzdGFydFwiYCBmb3Igb3RoZXIgY29tcG9zaXRlIHZpZXdzLlxuICAgKlxuICAgKiBfX05vdGU6X18gW0ZvciBub3ddKGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EtbGl0ZS9pc3N1ZXMvMjg3NSksIGBhbmNob3JgIGlzIG9ubHkgY3VzdG9taXphYmxlIG9ubHkgZm9yIFtzaW5nbGVdKHNwZWMuaHRtbCkgYW5kIFtsYXllcmVkXShsYXllci5odG1sKSB2aWV3cy4gIEZvciBvdGhlciBjb21wb3NpdGUgdmlld3MsIGBhbmNob3JgIGlzIGFsd2F5cyBgXCJzdGFydFwiYC5cbiAgICovXG4gIGFuY2hvcj86IEFuY2hvcjtcbiAgLyoqXG4gICAqIEFuZ2xlIGluIGRlZ3JlZXMgb2YgdGl0bGUgdGV4dC5cbiAgICovXG4gIGFuZ2xlPzpcdG51bWJlcjtcbiAgLyoqXG4gICAqIFZlcnRpY2FsIHRleHQgYmFzZWxpbmUgZm9yIHRpdGxlIHRleHQuXG4gICAqL1xuICBiYXNlbGluZT86IFZlcnRpY2FsQWxpZ247XG4gIC8qKlxuICAgKiBUZXh0IGNvbG9yIGZvciB0aXRsZSB0ZXh0LlxuICAgKi9cbiAgY29sb3I/Olx0c3RyaW5nO1xuICAvKipcbiAgICogRm9udCBuYW1lIGZvciB0aXRsZSB0ZXh0LlxuICAgKi9cbiAgZm9udD86XHRzdHJpbmc7XG4gIC8qKlxuICAgKiBGb250IHNpemUgaW4gcGl4ZWxzIGZvciB0aXRsZSB0ZXh0LlxuICAgKlxuICAgKiBfX0RlZmF1bHQgdmFsdWU6X18gYDEwYC5cbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgZm9udFNpemU/Olx0bnVtYmVyO1xuICAvKipcbiAgICogRm9udCB3ZWlnaHQgZm9yIHRpdGxlIHRleHQuXG4gICAqL1xuICBmb250V2VpZ2h0PzogRm9udFdlaWdodCB8IEZvbnRXZWlnaHROdW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSBhbGxvd2VkIGxlbmd0aCBpbiBwaXhlbHMgb2YgbGVnZW5kIGxhYmVscy5cbiAgICpcbiAgICogQG1pbmltdW0gMFxuICAgKi9cbiAgbGltaXQ/Olx0bnVtYmVyO1xuICAvKipcbiAgICogT2Zmc2V0IGluIHBpeGVscyBvZiB0aGUgdGl0bGUgZnJvbSB0aGUgY2hhcnQgYm9keSBhbmQgYXhlcy5cbiAgICovXG4gIG9mZnNldD86XHRudW1iZXI7XG4gIC8qKlxuICAgKiBEZWZhdWx0IHRpdGxlIG9yaWVudGF0aW9uIChcInRvcFwiLCBcImJvdHRvbVwiLCBcImxlZnRcIiwgb3IgXCJyaWdodFwiKVxuICAgKi9cbiAgb3JpZW50PzogVGl0bGVPcmllbnQ7XG59XG4iXX0= \ No newline at end of file diff --git a/build/test-runtime/discrete.test.d.ts b/build/test-runtime/discrete.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-runtime/discrete.test.js b/build/test-runtime/discrete.test.js new file mode 100644 index 0000000000..f9f4e3516f --- /dev/null +++ b/build/test-runtime/discrete.test.js @@ -0,0 +1,74 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("./util"); +['single', 'multi'].forEach(function (type) { + describe(type + " selections at runtime in unit views", function () { + var hits = util_1.hits.discrete; + var embed = util_1.embedFn(browser); + var testRender = util_1.testRenderFn(browser, type + "/unit"); + it('should add values to the store', function () { + for (var i = 0; i < hits.qq.length; i++) { + embed(util_1.spec('unit', i, { type: type })); + var store = browser.execute(util_1.pt('qq', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.lengthOf(store[0].encodings, 0); + chai_1.assert.lengthOf(store[0].fields, 1); + chai_1.assert.lengthOf(store[0].values, 1); + testRender("click_" + i); + } + }); + it('should respect projections', function () { + var values = []; + var encodings = []; + var fields = []; + var test = function (emb) { + for (var i = 0; i < hits.qq.length; i++) { + emb(i); + var store = browser.execute(util_1.pt('qq', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.deepEqual(store[0].encodings, encodings); + chai_1.assert.deepEqual(store[0].fields, fields); + chai_1.assert.deepEqual(store[0].values, values[i]); + testRender(encodings + "_" + fields + "_" + i); + } + }; + encodings = ['x', 'color']; + fields = ['a', 'c']; + values = [[2, 1], [6, 0]]; + test(function (i) { return embed(util_1.spec('unit', i, { type: type, encodings: encodings })); }); + encodings = []; + fields = ['c', 'a', 'b']; + values = [[1, 2, 53], [0, 6, 87]]; + test(function (i) { return embed(util_1.spec('unit', i, { type: type, fields: fields })); }); + }); + it('should clear out the store', function () { + for (var i = 0; i < hits.qq_clear.length; i++) { + embed(util_1.spec('unit', i, { type: type })); + var store = browser.execute(util_1.pt('qq', i)).value; + chai_1.assert.lengthOf(store, 1); + store = browser.execute(util_1.pt('qq_clear', i)).value; + chai_1.assert.lengthOf(store, 0); + testRender("clear_" + i); + } + }); + it('should support selecting bins', function () { + var encodings = ['x', 'color', 'y']; + var fields = ['a', 'c', 'b']; + var values = [[[1, 2], 0, [40, 50]], [[8, 9], 1, [10, 20]]]; + for (var i = 0; i < hits.bins.length; i++) { + embed(util_1.spec('unit', i, { type: type, encodings: encodings }, { x: { bin: true }, y: { bin: true } })); + var store = browser.execute(util_1.pt('bins', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.sameMembers(store[0].encodings, encodings); + chai_1.assert.sameMembers(store[0].fields, fields); + chai_1.assert.sameDeepMembers(store[0].values, values[i]); + chai_1.assert.property(store[0], 'bin_a'); + chai_1.assert.property(store[0], 'bin_b'); + chai_1.assert.notProperty(store[0], 'bin_c'); + testRender("bins_" + i); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY3JldGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QtcnVudGltZS9kaXNjcmV0ZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLCtCQUEyRTtBQUUzRSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBUyxJQUFJO0lBQ3ZDLFFBQVEsQ0FBSSxJQUFJLHlDQUFzQyxFQUFFO1FBQ3RELElBQU0sSUFBSSxHQUFHLFdBQVUsQ0FBQyxRQUFRLENBQUM7UUFDakMsSUFBTSxLQUFLLEdBQUcsY0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9CLElBQU0sVUFBVSxHQUFHLG1CQUFZLENBQUMsT0FBTyxFQUFLLElBQUksVUFBTyxDQUFDLENBQUM7UUFFekQsRUFBRSxDQUFDLGdDQUFnQyxFQUFFO1lBQ25DLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDeEMsS0FBSyxDQUFDLFdBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUMsSUFBSSxNQUFBLEVBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9CLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztnQkFDakQsYUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzFCLGFBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDdkMsYUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FB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R0FBRyxFQUFFLElBQUksRUFBQyxFQUFFLENBQUMsRUFBRSxFQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztnQkFDNUUsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO2dCQUNuRCxhQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDMUIsYUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUNsRCxhQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVDLGFBQU0sQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkQsYUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ25DLGFBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUNuQyxhQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDdEMsVUFBVSxDQUFDLFVBQVEsQ0FBRyxDQUFDLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7ZW1iZWRGbiwgaGl0cyBhcyBoaXRzTWFzdGVyLCBwdCwgc3BlYywgdGVzdFJlbmRlckZufSBmcm9tICcuL3V0aWwnO1xuXG5bJ3NpbmdsZScsICdtdWx0aSddLmZvckVhY2goZnVuY3Rpb24odHlwZSkge1xuICBkZXNjcmliZShgJHt0eXBlfSBzZWxlY3Rpb25zIGF0IHJ1bnRpbWUgaW4gdW5pdCB2aWV3c2AsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IGhpdHMgPSBoaXRzTWFzdGVyLmRpc2NyZXRlO1xuICAgIGNvbnN0IGVtYmVkID0gZW1iZWRGbihicm93c2VyKTtcbiAgICBjb25zdCB0ZXN0UmVuZGVyID0gdGVzdFJlbmRlckZuKGJyb3dzZXIsIGAke3R5cGV9L3VuaXRgKTtcblxuICAgIGl0KCdzaG91bGQgYWRkIHZhbHVlcyB0byB0aGUgc3RvcmUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5xcS5sZW5ndGg7IGkrKykge1xuICAgICAgICBlbWJlZChzcGVjKCd1bml0JywgaSwge3R5cGV9KSk7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKHB0KCdxcScsIGkpKS52YWx1ZTtcbiAgICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlWzBdLmVuY29kaW5ncywgMCk7XG4gICAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZVswXS5maWVsZHMsIDEpO1xuICAgICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmVbMF0udmFsdWVzLCAxKTtcbiAgICAgICAgdGVzdFJlbmRlcihgY2xpY2tfJHtpfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXNwZWN0IHByb2plY3Rpb25zJywgZnVuY3Rpb24oKSB7XG4gICAgICBsZXQgdmFsdWVzOm51bWJlcltdW10gPSBbXTtcbiAgICAgIGxldCBlbmNvZGluZ3M6IHN0cmluZ1tdID0gW107XG4gICAgICBsZXQgZmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgdGVzdCA9IChlbWI6IEZ1bmN0aW9uKSA9PiB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5xcS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGVtYihpKTtcbiAgICAgICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShwdCgncXEnLCBpKSkudmFsdWU7XG4gICAgICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHN0b3JlWzBdLmVuY29kaW5ncywgZW5jb2RpbmdzKTtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHN0b3JlWzBdLmZpZWxkcywgZmllbGRzKTtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHN0b3JlWzBdLnZhbHVlcywgdmFsdWVzW2ldKTtcbiAgICAgICAgICB0ZXN0UmVuZGVyKGAke2VuY29kaW5nc31fJHtmaWVsZHN9XyR7aX1gKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgZW5jb2RpbmdzID0gWyd4JywgJ2NvbG9yJ107XG4gICAgICBmaWVsZHMgPSBbJ2EnLCAnYyddO1xuICAgICAgdmFsdWVzID0gW1syLCAxXSwgWzYsIDBdXTtcbiAgICAgIHRlc3QoKGk6IG51bWJlcikgPT4gZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlLCBlbmNvZGluZ3N9KSkpO1xuXG4gICAgICBlbmNvZGluZ3MgPSBbXTtcbiAgICAgIGZpZWxkcyA9IFsnYycsICdhJywgJ2InXTtcbiAgICAgIHZhbHVlcyA9IFtbMSwgMiwgNTNdLCBbMCwgNiwgODddXTtcbiAgICAgIHRlc3QoKGk6IG51bWJlcikgPT4gZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlLCBmaWVsZHN9KSkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjbGVhciBvdXQgdGhlIHN0b3JlJywgZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHMucXFfY2xlYXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlfSkpO1xuICAgICAgICBsZXQgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUocHQoJ3FxJywgaSkpLnZhbHVlO1xuICAgICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmUsIDEpO1xuXG4gICAgICAgIHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKHB0KCdxcV9jbGVhcicsIGkpKS52YWx1ZTtcbiAgICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAwKTtcbiAgICAgICAgdGVzdFJlbmRlcihgY2xlYXJfJHtpfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdXBwb3J0IHNlbGVjdGluZyBiaW5zJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBlbmNvZGluZ3MgPSBbJ3gnLCAnY29sb3InLCAneSddO1xuICAgICAgY29uc3QgZmllbGRzID0gWydhJywgJ2MnLCAnYiddO1xuICAgICAgY29uc3QgdmFsdWVzID0gW1tbMSwgMl0sIDAsIFs0MCwgNTBdXSwgW1s4LCA5XSwgMSwgWzEwLCAyMF1dXTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLmJpbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlLCBlbmNvZGluZ3N9LCB7eDoge2JpbjogdHJ1ZX0sIHk6IHtiaW46IHRydWV9fSkpO1xuICAgICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShwdCgnYmlucycsIGkpKS52YWx1ZTtcbiAgICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICAgICAgYXNzZXJ0LnNhbWVNZW1iZXJzKHN0b3JlWzBdLmVuY29kaW5ncywgZW5jb2RpbmdzKTtcbiAgICAgICAgYXNzZXJ0LnNhbWVNZW1iZXJzKHN0b3JlWzBdLmZpZWxkcywgZmllbGRzKTtcbiAgICAgICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhzdG9yZVswXS52YWx1ZXMsIHZhbHVlc1tpXSk7XG4gICAgICAgIGFzc2VydC5wcm9wZXJ0eShzdG9yZVswXSwgJ2Jpbl9hJyk7XG4gICAgICAgIGFzc2VydC5wcm9wZXJ0eShzdG9yZVswXSwgJ2Jpbl9iJyk7XG4gICAgICAgIGFzc2VydC5ub3RQcm9wZXJ0eShzdG9yZVswXSwgJ2Jpbl9jJyk7XG4gICAgICAgIHRlc3RSZW5kZXIoYGJpbnNfJHtpfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ No newline at end of file diff --git a/build/test-runtime/interval.test.d.ts b/build/test-runtime/interval.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-runtime/interval.test.js b/build/test-runtime/interval.test.js new file mode 100644 index 0000000000..5beaf7ab22 --- /dev/null +++ b/build/test-runtime/interval.test.js @@ -0,0 +1,135 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("./util"); +describe('interval selections at runtime in unit views', function () { + var type = 'interval'; + var hits = util_1.hits.interval; + var embed = util_1.embedFn(browser); + var testRender = util_1.testRenderFn(browser, type + "/unit"); + it('should add extents to the store', function () { + for (var i = 0; i < hits.drag.length; i++) { + embed(util_1.spec('unit', i, { type: type })); + var store = browser.execute(util_1.brush('drag', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.lengthOf(store[0].intervals, 2); + chai_1.assert.equal(store[0].intervals[0].encoding, 'x'); + chai_1.assert.equal(store[0].intervals[0].field, 'a'); + chai_1.assert.equal(store[0].intervals[1].encoding, 'y'); + chai_1.assert.equal(store[0].intervals[1].field, 'b'); + chai_1.assert.lengthOf(store[0].intervals[0].extent, 2); + chai_1.assert.lengthOf(store[0].intervals[1].extent, 2); + testRender("drag_" + i); + } + }); + it('should respect projections', function () { + embed(util_1.spec('unit', 0, { type: type, encodings: ['x'] })); + for (var i = 0; i < hits.drag.length; i++) { + var store = browser.execute(util_1.brush('drag', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.lengthOf(store[0].intervals, 1); + chai_1.assert.equal(store[0].intervals[0].encoding, 'x'); + chai_1.assert.equal(store[0].intervals[0].field, 'a'); + chai_1.assert.lengthOf(store[0].intervals[0].extent, 2); + testRender("x_" + i); + } + embed(util_1.spec('unit', 1, { type: type, encodings: ['y'] })); + for (var i = 0; i < hits.drag.length; i++) { + var store = browser.execute(util_1.brush('drag', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.lengthOf(store[0].intervals, 1); + chai_1.assert.equal(store[0].intervals[0].encoding, 'y'); + chai_1.assert.equal(store[0].intervals[0].field, 'b'); + chai_1.assert.lengthOf(store[0].intervals[0].extent, 2); + testRender("y_" + i); + } + }); + it('should clear out stored extents', function () { + for (var i = 0; i < hits.drag_clear.length; i++) { + embed(util_1.spec('unit', i, { type: type })); + var store = browser.execute(util_1.brush('drag', i)).value; + chai_1.assert.lengthOf(store, 1); + store = browser.execute(util_1.brush('drag_clear', i)).value; + chai_1.assert.lengthOf(store, 0); + testRender("clear_" + i); + } + }); + it('should brush over binned domains', function () { + embed(util_1.spec('unit', 1, { type: type, encodings: ['y'] }, { + x: { aggregate: 'count', field: '*', type: 'quantitative' }, + y: { bin: true }, + color: { value: 'steelblue', field: null, type: null } + })); + for (var i = 0; i < hits.bins.length; i++) { + var store_1 = browser.execute(util_1.brush('bins', i)).value; + chai_1.assert.lengthOf(store_1, 1); + chai_1.assert.lengthOf(store_1[0].intervals, 1); + // length == 2 indicates a quantitative scale was inverted. + chai_1.assert.lengthOf(store_1[0].intervals[0].extent, 2); + testRender("bins_" + i); + } + var store = browser.execute(util_1.brush('bins_clear', 0)).value; + chai_1.assert.lengthOf(store, 0); + }); + it('should brush over ordinal/nominal domains', function () { + var xextents = [[2, 3, 4], [6, 7, 8]]; + var yextents = [[48, 49, 52, 53, 54, 55, 66, 67, 68, 76, 81, 87, 91], + [16, 17, 19, 23, 24, 27, 28, 35, 39, 43, 48]]; + for (var i = 0; i < hits.drag.length; i++) { + embed(util_1.spec('unit', i, { type: type }, { x: { type: 'ordinal' }, y: { type: 'nominal' } })); + var store_2 = browser.execute(util_1.brush('drag', i)).value; + chai_1.assert.lengthOf(store_2, 1); + chai_1.assert.lengthOf(store_2[0].intervals, 2); + chai_1.assert.sameMembers(store_2[0].intervals[0].extent, xextents[i]); + chai_1.assert.sameMembers(store_2[0].intervals[1].extent, yextents[i]); + testRender("ord_" + i); + } + var store = browser.execute(util_1.brush('drag_clear', 0)).value; + chai_1.assert.lengthOf(store, 0); + }); + it('should brush over temporal domains', function () { + var values = util_1.tuples.map(function (d) { return (__assign({}, d, { a: new Date(2017, d.a) })); }); + var toNumber = '[0].intervals[0].extent.map((d) => +d)'; + embed(util_1.spec('unit', 0, { type: type, encodings: ['x'] }, { values: values, x: { type: 'temporal' } })); + var extents = [[1485969714000, 1493634384000], [1496346498000, 1504364922000]]; + for (var i = 0; i < hits.drag.length; i++) { + var store = browser.execute(util_1.brush('drag', i) + toNumber).value; + chai_1.assert.sameMembers(store, extents[i]); + testRender("temporal_" + i); + } + var cleared = browser.execute(util_1.brush('drag_clear', 0)).value; + chai_1.assert.lengthOf(cleared, 0); + embed(util_1.spec('unit', 1, { type: type, encodings: ['x'] }, { values: values, x: { type: 'temporal', timeUnit: 'day' } })); + extents = [[1136190528000, 1136361600000], [1136449728000, 1136535264000]]; + for (var i = 0; i < hits.drag.length; i++) { + var store = browser.execute(util_1.brush('drag', i) + toNumber).value; + chai_1.assert.sameMembers(store, extents[i]); + testRender("dayTimeUnit_" + i); + } + cleared = browser.execute(util_1.brush('drag_clear', 0)).value; + chai_1.assert.lengthOf(cleared, 0); + }); + it('should brush over log/pow scales', function () { + for (var i = 0; i < hits.drag.length; i++) { + embed(util_1.spec('unit', i, { type: type }, { + x: { scale: { type: 'pow', exponent: 1.5 } }, + y: { scale: { type: 'log' } } + })); + var store = browser.execute(util_1.brush('drag', i)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.lengthOf(store[0].intervals, 2); + chai_1.assert.lengthOf(store[0].intervals[0].extent, 2); + chai_1.assert.lengthOf(store[0].intervals[1].extent, 2); + testRender("logpow_" + i); + } + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJ2YWwudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QtcnVudGltZS9pbnRlcnZhbC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSw2QkFBNEI7QUFDNUIsK0JBQXNGO0FBRXRGLFFBQVEsQ0FBQyw4Q0FBOEMsRUFBRTtJQUN2RCxJQUFNLElBQUksR0FBRyxVQUFVLENBQUM7SUFDeEIsSUFBTSxJQUFJLEdBQUcsV0FBVSxDQUFDLFFBQVEsQ0FBQztJQUNqQyxJQUFNLEtBQUssR0FBRyxjQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0IsSUFBTSxVQUFVLEdBQUcsbUJBQVksQ0FBQyxPQUFPLEVBQUssSUFBSSxVQUFPLENBQUMsQ0FBQztJQUV6RCxFQUFFLENBQUMsaUNBQWlDLEVBQUU7UUFDcEMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzFDLEtBQUssQ0FBQyxXQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFDLElBQUksTUFBQSxFQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsWUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUN0RCxhQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMxQixhQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkMsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMs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TSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1lBQ3RELGFBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFCLGFBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN2QyxhQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2pELGFBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDakQsVUFBVSxDQUFDLFlBQVUsQ0FBRyxDQUFDLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2JydXNoLCBlbWJlZEZuLCBoaXRzIGFzIGhpdHNNYXN0ZXIsIHNwZWMsIHRlc3RSZW5kZXJGbiwgdHVwbGVzfSBmcm9tICcuL3V0aWwnO1xuXG5kZXNjcmliZSgnaW50ZXJ2YWwgc2VsZWN0aW9ucyBhdCBydW50aW1lIGluIHVuaXQgdmlld3MnLCBmdW5jdGlvbigpIHtcbiAgY29uc3QgdHlwZSA9ICdpbnRlcnZhbCc7XG4gIGNvbnN0IGhpdHMgPSBoaXRzTWFzdGVyLmludGVydmFsO1xuICBjb25zdCBlbWJlZCA9IGVtYmVkRm4oYnJvd3Nlcik7XG4gIGNvbnN0IHRlc3RSZW5kZXIgPSB0ZXN0UmVuZGVyRm4oYnJvd3NlciwgYCR7dHlwZX0vdW5pdGApO1xuXG4gIGl0KCdzaG91bGQgYWRkIGV4dGVudHMgdG8gdGhlIHN0b3JlJywgZnVuY3Rpb24oKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLmRyYWcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZX0pKTtcbiAgICAgIGNvbnN0IHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdkcmFnJywgaSkpLnZhbHVlO1xuICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZVswXS5pbnRlcnZhbHMsIDIpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHN0b3JlWzBdLmludGVydmFsc1swXS5lbmNvZGluZywgJ3gnKTtcbiAgICAgIGFzc2VydC5lcXVhbChzdG9yZVswXS5pbnRlcnZhbHNbMF0uZmllbGQsICdhJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3RvcmVbMF0uaW50ZXJ2YWxzWzFdLmVuY29kaW5nLCAneScpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHN0b3JlWzBdLmludGVydmFsc1sxXS5maWVsZCwgJ2InKTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZVswXS5pbnRlcnZhbHNbMF0uZXh0ZW50LCAyKTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZVswXS5pbnRlcnZhbHNbMV0uZXh0ZW50LCAyKTtcbiAgICAgIHRlc3RSZW5kZXIoYGRyYWdfJHtpfWApO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXNwZWN0IHByb2plY3Rpb25zJywgZnVuY3Rpb24oKSB7XG4gICAgZW1iZWQoc3BlYygndW5pdCcsIDAsIHt0eXBlLCBlbmNvZGluZ3M6IFsneCddfSkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5kcmFnLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZycsIGkpKS52YWx1ZTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMSk7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmVbMF0uaW50ZXJ2YWxzLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChzdG9yZVswXS5pbnRlcnZhbHNbMF0uZW5jb2RpbmcsICd4Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3RvcmVbMF0uaW50ZXJ2YWxzWzBdLmZpZWxkLCAnYScpO1xuICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlWzBdLmludGVydmFsc1swXS5leHRlbnQsIDIpO1xuICAgICAgdGVzdFJlbmRlcihgeF8ke2l9YCk7XG4gICAgfVxuXG4gICAgZW1iZWQoc3BlYygndW5pdCcsIDEsIHt0eXBlLCBlbmNvZGluZ3M6IFsneSddfSkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5kcmFnLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZycsIGkpKS52YWx1ZTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMSk7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmVbMF0uaW50ZXJ2YWxzLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChzdG9yZVswXS5pbnRlcnZhbHNbMF0uZW5jb2RpbmcsICd5Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3RvcmVbMF0uaW50ZXJ2YWxzWzBdLmZpZWxkLCAnYicpO1xuICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlWzBdLmludGVydmFsc1swXS5leHRlbnQsIDIpO1xuICAgICAgdGVzdFJlbmRlcihgeV8ke2l9YCk7XG4gICAgfVxuICB9KTtcblxuICBpdCgnc2hvdWxkIGNsZWFyIG91dCBzdG9yZWQgZXh0ZW50cycsIGZ1bmN0aW9uKCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5kcmFnX2NsZWFyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBlbWJlZChzcGVjKCd1bml0JywgaSwge3R5cGV9KSk7XG4gICAgICBsZXQgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUoYnJ1c2goJ2RyYWcnLCBpKSkudmFsdWU7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmUsIDEpO1xuXG4gICAgICBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZ19jbGVhcicsIGkpKS52YWx1ZTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMCk7XG4gICAgICB0ZXN0UmVuZGVyKGBjbGVhcl8ke2l9YCk7XG4gICAgfVxuICB9KTtcblxuICBpdCgnc2hvdWxkIGJydXNoIG92ZXIgYmlubmVkIGRvbWFpbnMnLCBmdW5jdGlvbigpIHtcbiAgICBlbWJlZChzcGVjKCd1bml0JywgMSwge3R5cGUsIGVuY29kaW5nczogWyd5J119LCB7XG4gICAgICB4OiB7YWdncmVnYXRlOiAnY291bnQnLCBmaWVsZDogJyonLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICB5OiB7YmluOiB0cnVlfSxcbiAgICAgIGNvbG9yOiB7dmFsdWU6ICdzdGVlbGJsdWUnLCBmaWVsZDogbnVsbCwgdHlwZTogbnVsbH1cbiAgICB9KSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLmJpbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdiaW5zJywgaSkpLnZhbHVlO1xuICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZVswXS5pbnRlcnZhbHMsIDEpO1xuICAgICAgLy8gbGVuZ3RoID09IDIgaW5kaWNhdGVzIGEgcXVhbnRpdGF0aXZlIHNjYWxlIHdhcyBpbnZlcnRlZC5cbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZVswXS5pbnRlcnZhbHNbMF0uZXh0ZW50LCAyKTtcbiAgICAgIHRlc3RSZW5kZXIoYGJpbnNfJHtpfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdiaW5zX2NsZWFyJywgMCkpLnZhbHVlO1xuICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYnJ1c2ggb3ZlciBvcmRpbmFsL25vbWluYWwgZG9tYWlucycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHhleHRlbnRzID0gW1syLCAzLCA0XSwgWzYsIDcsIDhdXTtcbiAgICBjb25zdCB5ZXh0ZW50cyA9IFtbNDgsIDQ5LCA1MiwgNTMsIDU0LCA1NSwgNjYsIDY3LCA2OCwgNzYsIDgxLCA4NywgOTFdLFxuICAgICAgWzE2LCAxNywgMTksIDIzLCAyNCwgMjcsIDI4LCAzNSwgMzksIDQzLCA0OF1dO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLmRyYWcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZX0sXG4gICAgICAgIHt4OiB7dHlwZTogJ29yZGluYWwnfSwgeToge3R5cGU6ICdub21pbmFsJ319KSk7XG4gICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZycsIGkpKS52YWx1ZTtcbiAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMSk7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmVbMF0uaW50ZXJ2YWxzLCAyKTtcbiAgICAgIGFzc2VydC5zYW1lTWVtYmVycyhzdG9yZVswXS5pbnRlcnZhbHNbMF0uZXh0ZW50LCB4ZXh0ZW50c1tpXSk7XG4gICAgICBhc3NlcnQuc2FtZU1lbWJlcnMoc3RvcmVbMF0uaW50ZXJ2YWxzWzFdLmV4dGVudCwgeWV4dGVudHNbaV0pO1xuICAgICAgdGVzdFJlbmRlcihgb3JkXyR7aX1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZ19jbGVhcicsIDApKS52YWx1ZTtcbiAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmUsIDApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJydXNoIG92ZXIgdGVtcG9yYWwgZG9tYWlucycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHZhbHVlcyA9IHR1cGxlcy5tYXAoKGQpID0+ICh7Li4uZCwgYTogbmV3IERhdGUoMjAxNywgZC5hKX0pKTtcbiAgICBjb25zdCB0b051bWJlciA9ICdbMF0uaW50ZXJ2YWxzWzBdLmV4dGVudC5tYXAoKGQpID0+ICtkKSc7XG5cbiAgICBlbWJlZChzcGVjKCd1bml0JywgMCwge3R5cGUsIGVuY29kaW5nczogWyd4J119LCB7dmFsdWVzLCB4OiB7dHlwZTogJ3RlbXBvcmFsJ319KSk7XG4gICAgbGV0IGV4dGVudHMgPSBbWzE0ODU5Njk3MTQwMDAsIDE0OTM2MzQzODQwMDBdLCBbMTQ5NjM0NjQ5ODAwMCwgMTUwNDM2NDkyMjAwMF1dO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5kcmFnLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZycsIGkpICsgdG9OdW1iZXIpLnZhbHVlO1xuICAgICAgYXNzZXJ0LnNhbWVNZW1iZXJzKHN0b3JlLCBleHRlbnRzW2ldKTtcbiAgICAgIHRlc3RSZW5kZXIoYHRlbXBvcmFsXyR7aX1gKTtcbiAgICB9XG5cbiAgICBsZXQgY2xlYXJlZCA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZ19jbGVhcicsIDApKS52YWx1ZTtcbiAgICBhc3NlcnQubGVuZ3RoT2YoY2xlYXJlZCwgMCk7XG5cbiAgICBlbWJlZChzcGVjKCd1bml0JywgMSwge3R5cGUsIGVuY29kaW5nczogWyd4J119LCB7dmFsdWVzLCB4OiB7dHlwZTogJ3RlbXBvcmFsJywgdGltZVVuaXQ6ICdkYXknfX0pKTtcblxuICAgIGV4dGVudHMgPSBbWzExMzYxOTA1MjgwMDAsIDExMzYzNjE2MDAwMDBdLCBbMTEzNjQ0OTcyODAwMCwgMTEzNjUzNTI2NDAwMF1dO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5kcmFnLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZycsIGkpICsgdG9OdW1iZXIpLnZhbHVlO1xuICAgICAgYXNzZXJ0LnNhbWVNZW1iZXJzKHN0b3JlLCBleHRlbnRzW2ldKTtcbiAgICAgIHRlc3RSZW5kZXIoYGRheVRpbWVVbml0XyR7aX1gKTtcbiAgICB9XG5cbiAgICBjbGVhcmVkID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdkcmFnX2NsZWFyJywgMCkpLnZhbHVlO1xuICAgIGFzc2VydC5sZW5ndGhPZihjbGVhcmVkLCAwKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBicnVzaCBvdmVyIGxvZy9wb3cgc2NhbGVzJywgZnVuY3Rpb24oKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLmRyYWcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZX0sIHtcbiAgICAgICAgeDoge3NjYWxlOiB7dHlwZTogJ3BvdycsIGV4cG9uZW50OiAxLjV9fSxcbiAgICAgICAgeToge3NjYWxlOiB7dHlwZTogJ2xvZyd9fVxuICAgICAgfSkpO1xuICAgICAgY29uc3Qgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUoYnJ1c2goJ2RyYWcnLCBpKSkudmFsdWU7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmUsIDEpO1xuICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlWzBdLmludGVydmFscywgMik7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmVbMF0uaW50ZXJ2YWxzWzBdLmV4dGVudCwgMik7XG4gICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmVbMF0uaW50ZXJ2YWxzWzFdLmV4dGVudCwgMik7XG4gICAgICB0ZXN0UmVuZGVyKGBsb2dwb3dfJHtpfWApO1xuICAgIH1cbiAgfSk7XG59KTtcbiJdfQ== \ No newline at end of file diff --git a/build/test-runtime/resolve.test.d.ts b/build/test-runtime/resolve.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-runtime/resolve.test.js b/build/test-runtime/resolve.test.js new file mode 100644 index 0000000000..fe9e93d8de --- /dev/null +++ b/build/test-runtime/resolve.test.js @@ -0,0 +1,74 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("./util"); +util_1.selectionTypes.forEach(function (type) { + var embed = util_1.embedFn(browser); + var isInterval = type === 'interval'; + var hits = isInterval ? util_1.hits.interval : util_1.hits.discrete; + var fn = isInterval ? util_1.brush : util_1.pt; + describe(type + " selections at runtime", function () { + util_1.compositeTypes.forEach(function (specType) { + var testRender = util_1.testRenderFn(browser, type + "/" + specType); + describe("in " + specType + " views", function () { + // Loop through the views, click to add a selection instance. + // Store size should stay constant, but unit names should vary. + it('should have one global selection instance', function () { + var selection = __assign({ type: type, resolve: 'global' }, (specType === 'facet' ? { encodings: ['y'] } : {})); + for (var i = 0; i < hits[specType].length; i++) { + embed(util_1.spec(specType, i, selection)); + var parent_1 = util_1.parentSelector(specType, i); + var store = browser.execute(fn(specType, i, parent_1)).value; + chai_1.assert.lengthOf(store, 1); + chai_1.assert.match(store[0].unit, util_1.unitNameRegex(specType, i)); + testRender("global_" + i); + if (i === hits[specType].length - 1) { + var cleared = browser.execute(fn(specType + "_clear", 0, parent_1)).value; + chai_1.assert.lengthOf(cleared, 0); + testRender("global_clear_" + i); + } + } + }); + util_1.resolutions.forEach(function (resolve) { + var selection = __assign({ type: type, resolve: resolve }, (specType === 'facet' ? { encodings: ['x'] } : {})); + // Loop through the views, click to add selection instance and observe + // incrementing store size. Then, loop again but click to clear and + // observe decrementing store size. Check unit names in each case. + it("should have one selection instance per " + resolve + " view", function () { + embed(util_1.spec(specType, 0, selection)); + for (var i = 0; i < hits[specType].length; i++) { + var parent_2 = util_1.parentSelector(specType, i); + var store = browser.execute(fn(specType, i, parent_2)).value; + chai_1.assert.lengthOf(store, i + 1); + chai_1.assert.match(store[i].unit, util_1.unitNameRegex(specType, i)); + testRender(resolve + "_" + i); + } + embed(util_1.spec(specType, 1, { type: type, resolve: resolve, encodings: ['x'] })); + for (var i = 0; i < hits[specType].length; i++) { + var parent_3 = util_1.parentSelector(specType, i); + browser.execute(fn(specType, i, parent_3)); + } + for (var i = hits[specType + "_clear"].length - 1; i >= 0; i--) { + var parent_4 = util_1.parentSelector(specType, i); + var store = browser.execute(fn(specType + "_clear", i, parent_4)).value; + chai_1.assert.lengthOf(store, i); + if (i > 0) { + chai_1.assert.match(store[i - 1].unit, util_1.unitNameRegex(specType, i - 1)); + } + testRender(resolve + "_clear_" + i); + } + }); + }); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC1ydW50aW1lL3Jlc29sdmUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsNkJBQTRCO0FBQzVCLCtCQVlnQjtBQUVoQixxQkFBYyxDQUFDLE9BQU8sQ0FBQyxVQUFTLElBQUk7SUFDbEMsSUFBTSxLQUFLLEdBQUcsY0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9CLElBQU0sVUFBVSxHQUFHLElBQUksS0FBSyxVQUFVLENBQUM7SUFDdkMsSUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxXQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFVLENBQUMsUUFBUSxDQUFDO0lBQ3BFLElBQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsWUFBSyxDQUFDLENBQUMsQ0FBQyxTQUFFLENBQUM7SUFFbkMsUUFBUSxDQUFJLElBQUksMkJBQXdCLEVBQUU7UUFDeEMscUJBQWMsQ0FBQyxPQUFPLENBQUMsVUFBUyxRQUFRO1lBQ3RDLElBQU0sVUFBVSxHQUFHLG1CQUFZLENBQUMsT0FBTyxFQUFLLElBQUksU0FBSSxRQUFVLENBQUMsQ0FBQztZQUNoRSxRQUFRLENBQUMsUUFBTSxRQUFRLFdBQVEsRUFBRTtnQkFDL0IsNkRBQTZEO2dCQUM3RCwrREFBK0Q7Z0JBQy9ELEVBQUUsQ0FBQywyQ0FBMkMsRUFBRTtvQkFDOUMsSUFBTSxTQUFTLGNBQUksSUFBSSxNQUFBLEVBQUUsT0FBTyxFQUFFLFFBQVEsSUFDckMsQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFDLENBQUEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBRXRELEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFB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QUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7XG4gIGJydXNoLFxuICBjb21wb3NpdGVUeXBlcyxcbiAgZW1iZWRGbixcbiAgaGl0cyBhcyBoaXRzTWFzdGVyLFxuICBwYXJlbnRTZWxlY3RvcixcbiAgcHQsXG4gIHJlc29sdXRpb25zLFxuICBzZWxlY3Rpb25UeXBlcyxcbiAgc3BlYyxcbiAgdGVzdFJlbmRlckZuLFxuICB1bml0TmFtZVJlZ2V4LFxufSBmcm9tICcuL3V0aWwnO1xuXG5zZWxlY3Rpb25UeXBlcy5mb3JFYWNoKGZ1bmN0aW9uKHR5cGUpIHtcbiAgY29uc3QgZW1iZWQgPSBlbWJlZEZuKGJyb3dzZXIpO1xuICBjb25zdCBpc0ludGVydmFsID0gdHlwZSA9PT0gJ2ludGVydmFsJztcbiAgY29uc3QgaGl0cyA9IGlzSW50ZXJ2YWwgPyBoaXRzTWFzdGVyLmludGVydmFsIDogaGl0c01hc3Rlci5kaXNjcmV0ZTtcbiAgY29uc3QgZm4gPSBpc0ludGVydmFsID8gYnJ1c2ggOiBwdDtcblxuICBkZXNjcmliZShgJHt0eXBlfSBzZWxlY3Rpb25zIGF0IHJ1bnRpbWVgLCBmdW5jdGlvbigpIHtcbiAgICBjb21wb3NpdGVUeXBlcy5mb3JFYWNoKGZ1bmN0aW9uKHNwZWNUeXBlKSB7XG4gICAgICBjb25zdCB0ZXN0UmVuZGVyID0gdGVzdFJlbmRlckZuKGJyb3dzZXIsIGAke3R5cGV9LyR7c3BlY1R5cGV9YCk7XG4gICAgICBkZXNjcmliZShgaW4gJHtzcGVjVHlwZX0gdmlld3NgLCBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gTG9vcCB0aHJvdWdoIHRoZSB2aWV3cywgY2xpY2sgdG8gYWRkIGEgc2VsZWN0aW9uIGluc3RhbmNlLlxuICAgICAgICAvLyBTdG9yZSBzaXplIHNob3VsZCBzdGF5IGNvbnN0YW50LCBidXQgdW5pdCBuYW1lcyBzaG91bGQgdmFyeS5cbiAgICAgICAgaXQoJ3Nob3VsZCBoYXZlIG9uZSBnbG9iYWwgc2VsZWN0aW9uIGluc3RhbmNlJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0ge3R5cGUsIHJlc29sdmU6ICdnbG9iYWwnLFxuICAgICAgICAgICAgLi4uKHNwZWNUeXBlID09PSAnZmFjZXQnID8ge2VuY29kaW5nczogWyd5J119OiB7fSl9O1xuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzW3NwZWNUeXBlXS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZW1iZWQoc3BlYyhzcGVjVHlwZSwgaSwgc2VsZWN0aW9uKSk7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBwYXJlbnRTZWxlY3RvcihzcGVjVHlwZSwgaSk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShmbihzcGVjVHlwZSwgaSwgcGFyZW50KSkudmFsdWU7XG4gICAgICAgICAgICBhc3NlcnQubGVuZ3RoT2Yoc3RvcmUsIDEpO1xuICAgICAgICAgICAgYXNzZXJ0Lm1hdGNoKHN0b3JlWzBdLnVuaXQsIHVuaXROYW1lUmVnZXgoc3BlY1R5cGUsIGkpKTtcbiAgICAgICAgICAgIHRlc3RSZW5kZXIoYGdsb2JhbF8ke2l9YCk7XG5cbiAgICAgICAgICAgIGlmIChpID09PSBoaXRzW3NwZWNUeXBlXS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNsZWFyZWQgPSBicm93c2VyLmV4ZWN1dGUoZm4oYCR7c3BlY1R5cGV9X2NsZWFyYCwgMCwgcGFyZW50KSkudmFsdWU7XG4gICAgICAgICAgICAgIGFzc2VydC5sZW5ndGhPZihjbGVhcmVkLCAwKTtcbiAgICAgICAgICAgICAgdGVzdFJlbmRlcihgZ2xvYmFsX2NsZWFyXyR7aX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc29sdXRpb25zLmZvckVhY2goZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHt0eXBlLCByZXNvbHZlLFxuICAgICAgICAgICAgLi4uKHNwZWNUeXBlID09PSAnZmFjZXQnID8ge2VuY29kaW5nczogWyd4J119OiB7fSl9O1xuXG4gICAgICAgICAgLy8gTG9vcCB0aHJvdWdoIHRoZSB2aWV3cywgY2xpY2sgdG8gYWRkIHNlbGVjdGlvbiBpbnN0YW5jZSBhbmQgb2JzZXJ2ZVxuICAgICAgICAgIC8vIGluY3JlbWVudGluZyBzdG9yZSBzaXplLiBUaGVuLCBsb29wIGFnYWluIGJ1dCBjbGljayB0byBjbGVhciBhbmRcbiAgICAgICAgICAvLyBvYnNlcnZlIGRlY3JlbWVudGluZyBzdG9yZSBzaXplLiBDaGVjayB1bml0IG5hbWVzIGluIGVhY2ggY2FzZS5cbiAgICAgICAgICBpdChgc2hvdWxkIGhhdmUgb25lIHNlbGVjdGlvbiBpbnN0YW5jZSBwZXIgJHtyZXNvbHZlfSB2aWV3YCwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBlbWJlZChzcGVjKHNwZWNUeXBlLCAwLCBzZWxlY3Rpb24pKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0c1tzcGVjVHlwZV0ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gcGFyZW50U2VsZWN0b3Ioc3BlY1R5cGUsIGkpO1xuICAgICAgICAgICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShmbihzcGVjVHlwZSwgaSwgcGFyZW50KSkudmFsdWU7XG4gICAgICAgICAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgaSArIDEpO1xuICAgICAgICAgICAgICBhc3NlcnQubWF0Y2goc3RvcmVbaV0udW5pdCwgdW5pdE5hbWVSZWdleChzcGVjVHlwZSwgaSkpO1xuICAgICAgICAgICAgICB0ZXN0UmVuZGVyKGAke3Jlc29sdmV9XyR7aX1gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZW1iZWQoc3BlYyhzcGVjVHlwZSwgMSwge3R5cGUsIHJlc29sdmUsIGVuY29kaW5nczogWyd4J119KSk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHNbc3BlY1R5cGVdLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudFNlbGVjdG9yKHNwZWNUeXBlLCBpKTtcbiAgICAgICAgICAgICAgYnJvd3Nlci5leGVjdXRlKGZuKHNwZWNUeXBlLCBpLCBwYXJlbnQpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGhpdHNbYCR7c3BlY1R5cGV9X2NsZWFyYF0ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gcGFyZW50U2VsZWN0b3Ioc3BlY1R5cGUsIGkpO1xuICAgICAgICAgICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZShmbihgJHtzcGVjVHlwZX1fY2xlYXJgLCBpLCBwYXJlbnQpKS52YWx1ZTtcbiAgICAgICAgICAgICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCBpKTtcbiAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0Lm1hdGNoKHN0b3JlW2kgLSAxXS51bml0LCB1bml0TmFtZVJlZ2V4KHNwZWNUeXBlLCBpIC0gMSkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRlc3RSZW5kZXIoYCR7cmVzb2x2ZX1fY2xlYXJfJHtpfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ No newline at end of file diff --git a/build/test-runtime/toggle.test.d.ts b/build/test-runtime/toggle.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-runtime/toggle.test.js b/build/test-runtime/toggle.test.js new file mode 100644 index 0000000000..95c6c61cc9 --- /dev/null +++ b/build/test-runtime/toggle.test.js @@ -0,0 +1,87 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var vega_util_1 = require("vega-util"); +var util_1 = require("./util"); +var hits = { + qq: [8, 19, 13, 21], + qq_clear: [5, 16], + bins: [4, 29, 16, 9], + bins_clear: [18, 7], + composite: [1, 3, 5, 7, 8, 9] +}; +function toggle(key, idx, shiftKey, parent) { + var fn = key.match('_clear') ? 'clear' : 'pt'; + return "return " + fn + "(" + hits[key][idx] + ", " + vega_util_1.stringValue(parent) + ", " + !!shiftKey + ")"; +} +describe('Toggle multi selections at runtime', function () { + var type = 'multi'; + var embed = util_1.embedFn(browser); + var testRender = util_1.testRenderFn(browser, 'multi/toggle'); + it('should toggle values into/out of the store', function () { + embed(util_1.spec('unit', 0, { type: type })); + browser.execute(toggle('qq', 0, false)); + browser.execute(toggle('qq', 1, true)); + var store = browser.execute(toggle('qq', 2, true)).value; + chai_1.assert.lengthOf(store, 3); + testRender('click_0'); + store = browser.execute(toggle('qq', 2, true)).value; + chai_1.assert.lengthOf(store, 2); + testRender('click_1'); + store = browser.execute(toggle('qq', 3, false)).value; + chai_1.assert.lengthOf(store, 1); + testRender('click_2'); + }); + it('should clear out the store w/o shiftKey', function () { + embed(util_1.spec('unit', 1, { type: type })); + browser.execute(toggle('qq', 0, false)); + browser.execute(toggle('qq', 1, true)); + browser.execute(toggle('qq', 2, true)); + browser.execute(toggle('qq', 3, true)); + testRender("clear_0"); + var store = browser.execute(toggle('qq_clear', 0, true)).value; + chai_1.assert.lengthOf(store, 4); + testRender("clear_1"); + store = browser.execute(toggle('qq_clear', 1, false)).value; + chai_1.assert.lengthOf(store, 0); + testRender("clear_2"); + }); + it('should toggle binned fields', function () { + embed(util_1.spec('unit', 0, { type: type, encodings: ['x', 'y'] }, { x: { bin: true }, y: { bin: true } })); + browser.execute(toggle('bins', 0, false)); + browser.execute(toggle('bins', 1, true)); + var store = browser.execute(toggle('bins', 2, true)).value; + chai_1.assert.lengthOf(store, 3); + testRender('bins_0'); + store = browser.execute(toggle('bins', 2, true)).value; + chai_1.assert.lengthOf(store, 2); + testRender('bins_1'); + store = browser.execute(toggle('bins', 3, false)).value; + chai_1.assert.lengthOf(store, 1); + testRender('bins_2'); + }); + util_1.compositeTypes.forEach(function (specType, idx) { + it("should toggle in " + specType + " views", function () { + embed(util_1.spec(specType, idx, { type: type, resolve: 'union' })); + var length = 0; + for (var i = 0; i < hits.composite.length; i++) { + var parent_1 = util_1.parentSelector(specType, i % 3); + var store = browser.execute(toggle('composite', i, true, parent_1)).value; + chai_1.assert.equal(length = store.length, i + 1); + if (i % 3 === 2) { + testRender(specType + "_" + i); + } + } + for (var i = 0; i < hits.composite.length; i++) { + var even = i % 2 === 0; + var parent_2 = util_1.parentSelector(specType, ~~(i / 2)); + var store = browser.execute(toggle('qq_clear', 0, even, parent_2)).value; + chai_1.assert.lengthOf(store, even ? length : length = length - 2, "iter: " + i); + if (!even) { + testRender(specType + "_clear_" + i); + } + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0LXJ1bnRpbWUvdG9nZ2xlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsdUNBQXNDO0FBQ3RDLCtCQUFtRjtBQUVuRixJQUFNLElBQUksR0FBRztJQUNYLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztJQUNuQixRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO0lBQ2pCLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNwQixVQUFVLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ25CLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0NBQzlCLENBQUM7QUFFRixnQkFBZ0IsR0FBVyxFQUFFLEdBQVcsRUFBRSxRQUFpQixFQUFFLE1BQWU7SUFDMUUsSUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDaEQsTUFBTSxDQUFDLFlBQVUsRUFBRSxTQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBSyx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxVQUFLLENBQUMsQ0FBQyxRQUFRLE1BQUcsQ0FBQztBQUNsRixDQUFDO0FBRUQsUUFBUSxDQUFDLG9DQUFvQyxFQUFFO0lBQzdDLElBQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQztJQUNyQixJQUFNLEtBQUssR0FBRyxjQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0IsSUFBTSxVQUFVLEdBQUcsbUJBQVksQ0FBQyxPQUFPLEVB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LE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQ3pFLGFBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLENBQUMsRUFBRSxXQUFTLENBQUcsQ0FBQyxDQUFDO2dCQUMxRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ1YsVUFBVSxDQUFJLFFBQVEsZUFBVSxDQUFHLENBQUMsQ0FBQztnQkFDdkMsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge3N0cmluZ1ZhbHVlfSBmcm9tICd2ZWdhLXV0aWwnO1xuaW1wb3J0IHtjb21wb3NpdGVUeXBlcywgZW1iZWRGbiwgcGFyZW50U2VsZWN0b3IsIHNwZWMsIHRlc3RSZW5kZXJGbn0gZnJvbSAnLi91dGlsJztcblxuY29uc3QgaGl0cyA9IHtcbiAgcXE6IFs4LCAxOSwgMTMsIDIxXSxcbiAgcXFfY2xlYXI6IFs1LCAxNl0sXG4gIGJpbnM6IFs0LCAyOSwgMTYsIDldLFxuICBiaW5zX2NsZWFyOiBbMTgsIDddLFxuICBjb21wb3NpdGU6IFsxLCAzLCA1LCA3LCA4LCA5XVxufTtcblxuZnVuY3Rpb24gdG9nZ2xlKGtleTogc3RyaW5nLCBpZHg6IG51bWJlciwgc2hpZnRLZXk6IGJvb2xlYW4sIHBhcmVudD86IHN0cmluZykge1xuICBjb25zdCBmbiA9IGtleS5tYXRjaCgnX2NsZWFyJykgPyAnY2xlYXInIDogJ3B0JztcbiAgcmV0dXJuIGByZXR1cm4gJHtmbn0oJHtoaXRzW2tleV1baWR4XX0sICR7c3RyaW5nVmFsdWUocGFyZW50KX0sICR7ISFzaGlmdEtleX0pYDtcbn1cblxuZGVzY3JpYmUoJ1RvZ2dsZSBtdWx0aSBzZWxlY3Rpb25zIGF0IHJ1bnRpbWUnLCBmdW5jdGlvbigpIHtcbiAgY29uc3QgdHlwZSA9ICdtdWx0aSc7XG4gIGNvbnN0IGVtYmVkID0gZW1iZWRGbihicm93c2VyKTtcbiAgY29uc3QgdGVzdFJlbmRlciA9IHRlc3RSZW5kZXJGbihicm93c2VyLCAnbXVsdGkvdG9nZ2xlJyk7XG5cbiAgaXQoJ3Nob3VsZCB0b2dnbGUgdmFsdWVzIGludG8vb3V0IG9mIHRoZSBzdG9yZScsIGZ1bmN0aW9uKCkge1xuICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCAwLCB7dHlwZX0pKTtcbiAgICBicm93c2VyLmV4ZWN1dGUodG9nZ2xlKCdxcScsIDAsIGZhbHNlKSk7XG4gICAgYnJvd3Nlci5leGVjdXRlKHRvZ2dsZSgncXEnLCAxLCB0cnVlKSk7XG4gICAgbGV0IHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKHRvZ2dsZSgncXEnLCAyLCB0cnVlKSkudmFsdWU7XG4gICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAzKTtcbiAgICB0ZXN0UmVuZGVyKCdjbGlja18wJyk7XG5cbiAgICBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ3FxJywgMiwgdHJ1ZSkpLnZhbHVlO1xuICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMik7XG4gICAgdGVzdFJlbmRlcignY2xpY2tfMScpO1xuXG4gICAgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUodG9nZ2xlKCdxcScsIDMsIGZhbHNlKSkudmFsdWU7XG4gICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICB0ZXN0UmVuZGVyKCdjbGlja18yJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgY2xlYXIgb3V0IHRoZSBzdG9yZSB3L28gc2hpZnRLZXknLCBmdW5jdGlvbigpIHtcbiAgICBlbWJlZChzcGVjKCd1bml0JywgMSwge3R5cGV9KSk7XG4gICAgYnJvd3Nlci5leGVjdXRlKHRvZ2dsZSgncXEnLCAwLCBmYWxzZSkpO1xuICAgIGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ3FxJywgMSwgdHJ1ZSkpO1xuICAgIGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ3FxJywgMiwgdHJ1ZSkpO1xuICAgIGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ3FxJywgMywgdHJ1ZSkpO1xuICAgIHRlc3RSZW5kZXIoYGNsZWFyXzBgKTtcblxuICAgIGxldCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ3FxX2NsZWFyJywgMCwgdHJ1ZSkpLnZhbHVlO1xuICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgNCk7XG4gICAgdGVzdFJlbmRlcihgY2xlYXJfMWApO1xuXG4gICAgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUodG9nZ2xlKCdxcV9jbGVhcicsIDEsIGZhbHNlKSkudmFsdWU7XG4gICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAwKTtcbiAgICB0ZXN0UmVuZGVyKGBjbGVhcl8yYCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdG9nZ2xlIGJpbm5lZCBmaWVsZHMnLCBmdW5jdGlvbigpIHtcbiAgICBlbWJlZChzcGVjKCd1bml0JywgMCwge3R5cGUsIGVuY29kaW5nczogWyd4JywgJ3knXX0sXG4gICAgICB7eDoge2JpbjogdHJ1ZX0sIHk6IHtiaW46IHRydWV9fSkpO1xuXG4gICAgYnJvd3Nlci5leGVjdXRlKHRvZ2dsZSgnYmlucycsIDAsIGZhbHNlKSk7XG4gICAgYnJvd3Nlci5leGVjdXRlKHRvZ2dsZSgnYmlucycsIDEsIHRydWUpKTtcbiAgICBsZXQgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUodG9nZ2xlKCdiaW5zJywgMiwgdHJ1ZSkpLnZhbHVlO1xuICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgMyk7XG4gICAgdGVzdFJlbmRlcignYmluc18wJyk7XG5cbiAgICBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ2JpbnMnLCAyLCB0cnVlKSkudmFsdWU7XG4gICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAyKTtcbiAgICB0ZXN0UmVuZGVyKCdiaW5zXzEnKTtcblxuICAgIHN0b3JlID0gYnJvd3Nlci5leGVjdXRlKHRvZ2dsZSgnYmlucycsIDMsIGZhbHNlKSkudmFsdWU7XG4gICAgYXNzZXJ0Lmxlbmd0aE9mKHN0b3JlLCAxKTtcbiAgICB0ZXN0UmVuZGVyKCdiaW5zXzInKTtcbiAgfSk7XG5cbiAgY29tcG9zaXRlVHlwZXMuZm9yRWFjaChmdW5jdGlvbihzcGVjVHlwZSwgaWR4KSB7XG4gICAgaXQoYHNob3VsZCB0b2dnbGUgaW4gJHtzcGVjVHlwZX0gdmlld3NgLCBmdW5jdGlvbigpIHtcbiAgICAgIGVtYmVkKHNwZWMoc3BlY1R5cGUsIGlkeCwge3R5cGUsIHJlc29sdmU6ICd1bmlvbid9KSk7XG4gICAgICBsZXQgbGVuZ3RoID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5jb21wb3NpdGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gcGFyZW50U2VsZWN0b3Ioc3BlY1R5cGUsIGkgJSAzKTtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBicm93c2VyLmV4ZWN1dGUodG9nZ2xlKCdjb21wb3NpdGUnLCBpLCB0cnVlLCBwYXJlbnQpKS52YWx1ZTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGxlbmd0aCA9IHN0b3JlLmxlbmd0aCwgaSArIDEpO1xuICAgICAgICBpZiAoaSAlIDMgPT09IDIpIHtcbiAgICAgICAgICB0ZXN0UmVuZGVyKGAke3NwZWNUeXBlfV8ke2l9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLmNvbXBvc2l0ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBldmVuID0gaSAlIDIgPT09IDA7XG4gICAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudFNlbGVjdG9yKHNwZWNUeXBlLCB+fihpIC8gMikpO1xuICAgICAgICBjb25zdCBzdG9yZSA9IGJyb3dzZXIuZXhlY3V0ZSh0b2dnbGUoJ3FxX2NsZWFyJywgMCwgZXZlbiwgcGFyZW50KSkudmFsdWU7XG4gICAgICAgIGFzc2VydC5sZW5ndGhPZihzdG9yZSwgZXZlbiA/IGxlbmd0aCA6IGxlbmd0aCA9IGxlbmd0aCAtIDIsIGBpdGVyOiAke2l9YCk7XG4gICAgICAgIGlmICghZXZlbikge1xuICAgICAgICAgIHRlc3RSZW5kZXIoYCR7c3BlY1R5cGV9X2NsZWFyXyR7aX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ No newline at end of file diff --git a/build/test-runtime/translate.test.d.ts b/build/test-runtime/translate.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-runtime/translate.test.js b/build/test-runtime/translate.test.js new file mode 100644 index 0000000000..65f633addc --- /dev/null +++ b/build/test-runtime/translate.test.js @@ -0,0 +1,135 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("./util"); +[util_1.bound, util_1.unbound].forEach(function (bind, idx) { + describe("Translate " + bind + " interval selections at runtime", function () { + var type = 'interval'; + var hits = util_1.hits.interval; + var embed = util_1.embedFn(browser); + var testRender = util_1.testRenderFn(browser, "interval/translate/" + bind); + var binding = bind === util_1.bound ? { bind: 'scales' } : {}; + var assertExtent = (_a = {}, + _a[util_1.unbound] = { + x: ['isAbove', 'isBelow'], + y: ['isBelow', 'isAbove'] + }, + _a[util_1.bound] = { + x: ['isBelow', 'isAbove'], + y: ['isAbove', 'isBelow'] + }, + _a); + it('should move back-and-forth', function () { + for (var i = 0; i < hits.translate.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding))); + var drag = browser.execute(util_1.brush('drag', i)).value[0]; + testRender(i + "-0"); + var translate = browser.execute(util_1.brush('translate', i, null, bind === util_1.unbound)).value[0]; + chai_1.assert[assertExtent[bind].x[i]](translate.intervals[0].extent[0], drag.intervals[0].extent[0]); + chai_1.assert[assertExtent[bind].x[i]](translate.intervals[0].extent[1], drag.intervals[0].extent[1]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[1].extent[0], drag.intervals[1].extent[0]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[1].extent[1], drag.intervals[1].extent[1]); + testRender(i + "-1"); + } + }); + it('should work with binned domains', function () { + for (var i = 0; i < hits.bins.length; i++) { + embed(util_1.spec('unit', 1, __assign({ type: type }, binding, { encodings: ['y'] }), { + x: { aggregate: 'count', field: '*', type: 'quantitative' }, + y: { bin: true }, + color: { value: 'steelblue', field: null, type: null } + })); + var drag = browser.execute(util_1.brush('bins', i)).value[0]; + testRender("bins_" + i + "-0"); + var translate = browser.execute(util_1.brush('bins_translate', i, null, bind === util_1.unbound)).value[0]; + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[0].extent[0], drag.intervals[0].extent[0]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[0].extent[1], drag.intervals[0].extent[1]); + testRender("bins_" + i + "-1"); + } + }); + it('should work with temporal domains', function () { + var values = util_1.tuples.map(function (d) { return (__assign({}, d, { a: new Date(2017, d.a) })); }); + var toNumber = '[0].intervals[0].extent.map((d) => +d)'; + for (var i = 0; i < hits.translate.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding, { encodings: ['x'] }), { values: values, x: { type: 'temporal' } })); + var drag = browser.execute(util_1.brush('drag', i) + toNumber).value; + testRender("temporal_" + i + "-0"); + var translate = browser.execute(util_1.brush('translate', i, null, bind === util_1.unbound) + toNumber).value; + chai_1.assert[assertExtent[bind].x[i]](translate[0], drag[0]); + chai_1.assert[assertExtent[bind].x[i]](translate[1], drag[1]); + testRender("temporal_" + i + "-1"); + } + }); + it('should work with log/pow scales', function () { + for (var i = 0; i < hits.translate.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding), { + x: { scale: { type: 'pow', exponent: 1.5 } }, + y: { scale: { type: 'log' } } + })); + var drag = browser.execute(util_1.brush('drag', i)).value[0]; + testRender("logpow_" + i + "-0"); + var translate = browser.execute(util_1.brush('translate', i, null, bind === util_1.unbound)).value[0]; + chai_1.assert[assertExtent[bind].x[i]](translate.intervals[0].extent[0], drag.intervals[0].extent[0]); + chai_1.assert[assertExtent[bind].x[i]](translate.intervals[0].extent[1], drag.intervals[0].extent[1]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[1].extent[0], drag.intervals[1].extent[0]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[1].extent[1], drag.intervals[1].extent[1]); + testRender("logpow_" + i + "-1"); + } + }); + if (bind === util_1.unbound) { + it('should work with ordinal/nominal domains', function () { + for (var i = 0; i < hits.translate.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding), { + x: { type: 'ordinal' }, y: { type: 'nominal' } + })); + var drag = browser.execute(util_1.brush('drag', i)).value[0]; + testRender("ord_" + i + "-0"); + var translate = browser.execute(util_1.brush('translate', i, null, true)).value[0]; + chai_1.assert[assertExtent[bind].x[i]](translate.intervals[0].extent[0], drag.intervals[0].extent[0]); + chai_1.assert[assertExtent[bind].x[i]](translate.intervals[0].extent[1], drag.intervals[0].extent[1]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[1].extent[0], drag.intervals[1].extent[0]); + chai_1.assert[assertExtent[bind].y[i]](translate.intervals[1].extent[1], drag.intervals[1].extent[1]); + testRender("ord_" + i + "-1"); + } + }); + } + else { + util_1.compositeTypes.forEach(function (specType) { + var assertExtents = { + repeat: { + x: ['isBelow', 'isBelow', 'isBelow'], + y: ['isAbove', 'isAbove', 'isAbove'] + }, + facet: { + x: ['isBelow', 'isBelow', 'isBelow'], + y: ['isBelow', 'isAbove', 'isBelow'] + } + }; + it("should work with shared scales in " + specType + " views", function () { + for (var i = 0; i < hits[specType].length; i++) { + embed(util_1.spec(specType, 0, __assign({ type: type }, binding), { resolve: { scale: { x: 'shared', y: 'shared' } } })); + var parent_1 = util_1.parentSelector(specType, i); + var xscale = browser.execute('return view._runtime.scales.x.value.domain()').value; + var yscale = browser.execute('return view._runtime.scales.y.value.domain()').value; + var drag = browser.execute(util_1.brush(specType, i, parent_1)).value[0]; + chai_1.assert[assertExtents[specType].x[i]](drag.intervals[0].extent[0], xscale[0], "iter: " + i); + chai_1.assert[assertExtents[specType].x[i]](drag.intervals[0].extent[1], xscale[1], "iter: " + i); + chai_1.assert[assertExtents[specType].y[i]](drag.intervals[1].extent[0], yscale[0], "iter: " + i); + chai_1.assert[assertExtents[specType].y[i]](drag.intervals[1].extent[1], yscale[1], "iter: " + i); + testRender(specType + "_" + i); + } + }); + }); + } + var _a; + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0LXJ1bnRpbWUvdHJhbnNsYXRlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLDZCQUE0QjtBQUM1QiwrQkFXZ0I7QUFFaEIsQ0FBQyxZQUFLLEVBQUUsY0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVMsSUFBSSxFQUFFLEdBQUc7SUFDekMsUUFBUSxDQUFDLGVBQWEsSUFBSSxvQ0FBaUMsRUFBRTtRQUMzRCxJQUFNLElBQUksR0FBRyxVQUFVLENBQUM7UUFDeEIsSUFBTSxJQUFJLEdBQUcsV0FBVSxDQUFDLFFBQVEsQ0FBQztRQUNqQyxJQUFNLEtBQUssR0FBRyxjQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0IsSUFBTSxVQUFVLEdBQUcsbUJBQVksQ0FBQyxPQUFPLEVBQUUsd0JBQXNCLElBQU0sQ0FBQyxDQUFDO1FBQ3ZFLElBQU0sT0FBTyxHQUFHLElBQUksS0FBSyxZQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFFdkQsSUFBTSxZQUFZO1lBQ2hCLEdBQUMsY0FBTyxJQUFHO2dCQUNULENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7Z0JBQ3pCLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7YUFDMUI7WUFDRCxHQUFDLFlBQUssSUFBRztnQkFDUCxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDO2dCQUN6QixDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDO2FBQzFCO2VBQ0YsQ0FBQztRQUVGLEVBQUUsQ0FBQyw0QkFBNEIsRUFBRTtZQUMvQixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMs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RUFBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBQyxFQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ2xELElBQU0sUUFBTSxHQUFHLHFCQUFjLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUMzQyxJQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLDhDQUE4QyxDQUFDLENBQUMsS0FBSyxDQUFDO3dCQUNyRixJQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLDhDQUE4QyxDQUFDLENBQUMsS0FBSyxDQUFDO3dCQUNyRixJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLFlBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLFFBQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNsRSxhQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFTLENBQUcsQ0FBQyxDQUFDO3dCQUMzRixhQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFTLENBQUcsQ0FBQyxDQUFDO3dCQUMzRixhQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFTLENBQUcsQ0FBQyxDQUFDO3dCQUMzRixhQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFTLENBQUcsQ0FBQyxDQUFDO3dCQUMzRixVQUFVLENBQUksUUFBUSxTQUFJLENBQUcsQ0FBQyxDQUFDO29CQUNqQyxDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDOztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge1xuICBib3VuZCxcbiAgYnJ1c2gsXG4gIGNvbXBvc2l0ZVR5cGVzLFxuICBlbWJlZEZuLFxuICBoaXRzIGFzIGhpdHNNYXN0ZXIsXG4gIHBhcmVudFNlbGVjdG9yLFxuICBzcGVjLFxuICB0ZXN0UmVuZGVyRm4sXG4gIHR1cGxlcyxcbiAgdW5ib3VuZCxcbn0gZnJvbSAnLi91dGlsJztcblxuW2JvdW5kLCB1bmJvdW5kXS5mb3JFYWNoKGZ1bmN0aW9uKGJpbmQsIGlkeCkge1xuICBkZXNjcmliZShgVHJhbnNsYXRlICR7YmluZH0gaW50ZXJ2YWwgc2VsZWN0aW9ucyBhdCBydW50aW1lYCwgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgdHlwZSA9ICdpbnRlcnZhbCc7XG4gICAgY29uc3QgaGl0cyA9IGhpdHNNYXN0ZXIuaW50ZXJ2YWw7XG4gICAgY29uc3QgZW1iZWQgPSBlbWJlZEZuKGJyb3dzZXIpO1xuICAgIGNvbnN0IHRlc3RSZW5kZXIgPSB0ZXN0UmVuZGVyRm4oYnJvd3NlciwgYGludGVydmFsL3RyYW5zbGF0ZS8ke2JpbmR9YCk7XG4gICAgY29uc3QgYmluZGluZyA9IGJpbmQgPT09IGJvdW5kID8ge2JpbmQ6ICdzY2FsZXMnfSA6IHt9O1xuXG4gICAgY29uc3QgYXNzZXJ0RXh0ZW50ID0ge1xuICAgICAgW3VuYm91bmRdOiB7XG4gICAgICAgIHg6IFsnaXNBYm92ZScsICdpc0JlbG93J10sXG4gICAgICAgIHk6IFsnaXNCZWxvdycsICdpc0Fib3ZlJ11cbiAgICAgIH0sXG4gICAgICBbYm91bmRdOiB7XG4gICAgICAgIHg6IFsnaXNCZWxvdycsICdpc0Fib3ZlJ10sXG4gICAgICAgIHk6IFsnaXNBYm92ZScsICdpc0JlbG93J11cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBtb3ZlIGJhY2stYW5kLWZvcnRoJywgZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHMudHJhbnNsYXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZSwgLi4uYmluZGluZ30pKTtcbiAgICAgICAgY29uc3QgZHJhZyA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgnZHJhZycsIGkpKS52YWx1ZVswXTtcbiAgICAgICAgdGVzdFJlbmRlcihgJHtpfS0wYCk7XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0ZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgndHJhbnNsYXRlJywgaSwgbnVsbCwgYmluZCA9PT0gdW5ib3VuZCkpLnZhbHVlWzBdO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnhbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzBdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnhbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzFdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMV0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMV0uZXh0ZW50WzBdLCBkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMV0uZXh0ZW50WzFdLCBkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMV0pO1xuICAgICAgICB0ZXN0UmVuZGVyKGAke2l9LTFgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgd29yayB3aXRoIGJpbm5lZCBkb21haW5zJywgZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHMuYmlucy5sZW5ndGg7IGkrKykge1xuICAgICAgICBlbWJlZChzcGVjKCd1bml0JywgMSwge3R5cGUsIC4uLmJpbmRpbmcsIGVuY29kaW5nczogWyd5J119LCB7XG4gICAgICAgICAgeDoge2FnZ3JlZ2F0ZTogJ2NvdW50JywgZmllbGQ6ICcqJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgIHk6IHtiaW46IHRydWV9LFxuICAgICAgICAgIGNvbG9yOiB7dmFsdWU6ICdzdGVlbGJsdWUnLCBmaWVsZDogbnVsbCwgdHlwZTogbnVsbH1cbiAgICAgICAgfSkpO1xuICAgICAgICBjb25zdCBkcmFnID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdiaW5zJywgaSkpLnZhbHVlWzBdO1xuICAgICAgICB0ZXN0UmVuZGVyKGBiaW5zXyR7aX0tMGApO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGUgPSBicm93c2VyLmV4ZWN1dGUoYnJ1c2goJ2JpbnNfdHJhbnNsYXRlJywgaSwgbnVsbCwgYmluZCA9PT0gdW5ib3VuZCkpLnZhbHVlWzBdO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzBdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzFdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMV0pO1xuICAgICAgICB0ZXN0UmVuZGVyKGBiaW5zXyR7aX0tMWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggdGVtcG9yYWwgZG9tYWlucycsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgdmFsdWVzID0gdHVwbGVzLm1hcCgoZCkgPT4gKHsuLi5kLCBhOiBuZXcgRGF0ZSgyMDE3LCBkLmEpfSkpO1xuICAgICAgY29uc3QgdG9OdW1iZXIgPSAnWzBdLmludGVydmFsc1swXS5leHRlbnQubWFwKChkKSA9PiArZCknO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHMudHJhbnNsYXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZSwgLi4uYmluZGluZywgZW5jb2RpbmdzOiBbJ3gnXX0sXG4gICAgICAgICAge3ZhbHVlcywgeDoge3R5cGU6ICd0ZW1wb3JhbCd9fSkpO1xuICAgICAgICBjb25zdCBkcmFnID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdkcmFnJywgaSkgKyB0b051bWJlcikudmFsdWU7XG4gICAgICAgIHRlc3RSZW5kZXIoYHRlbXBvcmFsXyR7aX0tMGApO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGUgPSBicm93c2VyLmV4ZWN1dGUoYnJ1c2goJ3RyYW5zbGF0ZScsIGksIG51bGwsIGJpbmQgPT09IHVuYm91bmQpICsgdG9OdW1iZXIpLnZhbHVlO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnhbaV1dKHRyYW5zbGF0ZVswXSwgZHJhZ1swXSk7XG4gICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRbYmluZF0ueFtpXV0odHJhbnNsYXRlWzFdLCBkcmFnWzFdKTtcbiAgICAgICAgdGVzdFJlbmRlcihgdGVtcG9yYWxfJHtpfS0xYCk7XG4gICAgICB9XG5cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgd29yayB3aXRoIGxvZy9wb3cgc2NhbGVzJywgZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHMudHJhbnNsYXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZSwgLi4uYmluZGluZ30sIHtcbiAgICAgICAgICB4OiB7c2NhbGU6IHt0eXBlOiAncG93JywgZXhwb25lbnQ6IDEuNX19LFxuICAgICAgICAgIHk6IHtzY2FsZToge3R5cGU6ICdsb2cnfX1cbiAgICAgICAgfSkpO1xuICAgICAgICBjb25zdCBkcmFnID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdkcmFnJywgaSkpLnZhbHVlWzBdO1xuICAgICAgICB0ZXN0UmVuZGVyKGBsb2dwb3dfJHtpfS0wYCk7XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0ZSA9IGJyb3dzZXIuZXhlY3V0ZShicnVzaCgndHJhbnNsYXRlJywgaSwgbnVsbCwgYmluZCA9PT0gdW5ib3VuZCkpLnZhbHVlWzBdO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnhbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzBdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnhbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzFdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMV0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMV0uZXh0ZW50WzBdLCBkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMV0uZXh0ZW50WzFdLCBkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMV0pO1xuICAgICAgICB0ZXN0UmVuZGVyKGBsb2dwb3dfJHtpfS0xYCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoYmluZCA9PT0gdW5ib3VuZCkge1xuICAgICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggb3JkaW5hbC9ub21pbmFsIGRvbWFpbnMnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLnRyYW5zbGF0ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZSwgLi4uYmluZGluZ30sIHtcbiAgICAgICAgICAgIHg6IHt0eXBlOiAnb3JkaW5hbCd9LCB5OiB7dHlwZTogJ25vbWluYWwnfVxuICAgICAgICAgIH0pKTtcbiAgICAgICAgICBjb25zdCBkcmFnID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKCdkcmFnJywgaSkpLnZhbHVlWzBdO1xuICAgICAgICAgIHRlc3RSZW5kZXIoYG9yZF8ke2l9LTBgKTtcbiAgICAgICAgICBjb25zdCB0cmFuc2xhdGUgPSBicm93c2VyLmV4ZWN1dGUoYnJ1c2goJ3RyYW5zbGF0ZScsIGksIG51bGwsIHRydWUpKS52YWx1ZVswXTtcbiAgICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnhbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMF0uZXh0ZW50WzBdLCBkcmFnLmludGVydmFsc1swXS5leHRlbnRbMF0pO1xuICAgICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRbYmluZF0ueFtpXV0odHJhbnNsYXRlLmludGVydmFsc1swXS5leHRlbnRbMV0sIGRyYWcuaW50ZXJ2YWxzWzBdLmV4dGVudFsxXSk7XG4gICAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtiaW5kXS55W2ldXSh0cmFuc2xhdGUuaW50ZXJ2YWxzWzFdLmV4dGVudFswXSwgZHJhZy5pbnRlcnZhbHNbMV0uZXh0ZW50WzBdKTtcbiAgICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2JpbmRdLnlbaV1dKHRyYW5zbGF0ZS5pbnRlcnZhbHNbMV0uZXh0ZW50WzFdLCBkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMV0pO1xuICAgICAgICAgIHRlc3RSZW5kZXIoYG9yZF8ke2l9LTFgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvc2l0ZVR5cGVzLmZvckVhY2goZnVuY3Rpb24oc3BlY1R5cGUpIHtcbiAgICAgICAgY29uc3QgYXNzZXJ0RXh0ZW50cyA9IHtcbiAgICAgICAgICByZXBlYXQ6IHtcbiAgICAgICAgICAgIHg6IFsnaXNCZWxvdycsICdpc0JlbG93JywgJ2lzQmVsb3cnXSxcbiAgICAgICAgICAgIHk6IFsnaXNBYm92ZScsICdpc0Fib3ZlJywgJ2lzQWJvdmUnXVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICAgIHg6IFsnaXNCZWxvdycsICdpc0JlbG93JywgJ2lzQmVsb3cnXSxcbiAgICAgICAgICAgIHk6IFsnaXNCZWxvdycsICdpc0Fib3ZlJywgJ2lzQmVsb3cnXVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaXQoYHNob3VsZCB3b3JrIHdpdGggc2hhcmVkIHNjYWxlcyBpbiAke3NwZWNUeXBlfSB2aWV3c2AsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0c1tzcGVjVHlwZV0ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGVtYmVkKHNwZWMoc3BlY1R5cGUsIDAsIHt0eXBlLCAuLi5iaW5kaW5nfSxcbiAgICAgICAgICAgICAge3Jlc29sdmU6IHtzY2FsZToge3g6J3NoYXJlZCcsIHk6ICdzaGFyZWQnfX19KSk7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBwYXJlbnRTZWxlY3RvcihzcGVjVHlwZSwgaSk7XG4gICAgICAgICAgICBjb25zdCB4c2NhbGUgPSBicm93c2VyLmV4ZWN1dGUoJ3JldHVybiB2aWV3Ll9ydW50aW1lLnNjYWxlcy54LnZhbHVlLmRvbWFpbigpJykudmFsdWU7XG4gICAgICAgICAgICBjb25zdCB5c2NhbGUgPSBicm93c2VyLmV4ZWN1dGUoJ3JldHVybiB2aWV3Ll9ydW50aW1lLnNjYWxlcy55LnZhbHVlLmRvbWFpbigpJykudmFsdWU7XG4gICAgICAgICAgICBjb25zdCBkcmFnID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKHNwZWNUeXBlLCBpLCBwYXJlbnQpKS52YWx1ZVswXTtcbiAgICAgICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRzW3NwZWNUeXBlXS54W2ldXShkcmFnLmludGVydmFsc1swXS5leHRlbnRbMF0sIHhzY2FsZVswXSwgYGl0ZXI6ICR7aX1gKTtcbiAgICAgICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRzW3NwZWNUeXBlXS54W2ldXShkcmFnLmludGVydmFsc1swXS5leHRlbnRbMV0sIHhzY2FsZVsxXSwgYGl0ZXI6ICR7aX1gKTtcbiAgICAgICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRzW3NwZWNUeXBlXS55W2ldXShkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMF0sIHlzY2FsZVswXSwgYGl0ZXI6ICR7aX1gKTtcbiAgICAgICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRzW3NwZWNUeXBlXS55W2ldXShkcmFnLmludGVydmFsc1sxXS5leHRlbnRbMV0sIHlzY2FsZVsxXSwgYGl0ZXI6ICR7aX1gKTtcbiAgICAgICAgICAgIHRlc3RSZW5kZXIoYCR7c3BlY1R5cGV9XyR7aX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn0pO1xuIl19 \ No newline at end of file diff --git a/build/test-runtime/util.d.ts b/build/test-runtime/util.d.ts new file mode 100644 index 0000000000..c860bbb378 --- /dev/null +++ b/build/test-runtime/util.d.ts @@ -0,0 +1,48 @@ +/// +import { SelectionResolution, SelectionType } from '../src/selection'; +import { TopLevelExtendedSpec } from '../src/spec'; +export declare const generate: string; +export declare const output = "test-runtime/resources"; +export declare type ComposeType = 'unit' | 'repeat' | 'facet'; +export declare const selectionTypes: SelectionType[]; +export declare const compositeTypes: ComposeType[]; +export declare const resolutions: SelectionResolution[]; +export declare const bound = "bound"; +export declare const unbound = "unbound"; +export declare const tuples: { + a: number; + b: number; + c: number; +}[]; +export declare const hits: { + discrete: { + qq: number[]; + qq_clear: number[]; + bins: number[]; + bins_clear: number[]; + repeat: number[]; + repeat_clear: number[]; + facet: number[]; + facet_clear: number[]; + }; + interval: { + drag: number[][]; + drag_clear: number[][]; + translate: number[][]; + bins: number[][]; + bins_clear: number[][]; + bins_translate: number[][]; + repeat: number[][]; + repeat_clear: number[][]; + facet: number[][]; + facet_clear: number[][]; + }; +}; +export declare function spec(compose: ComposeType, iter: number, sel: any, opts?: any): TopLevelExtendedSpec; +export declare function unitNameRegex(specType: ComposeType, idx: number): RegExp; +export declare function parentSelector(compositeType: ComposeType, index: number): string; +export declare function brush(key: string, idx: number, parent?: string, targetBrush?: boolean): string; +export declare function pt(key: string, idx: number, parent?: string): string; +export declare function embedFn(browser: WebdriverIO.Client): (spec: TopLevelExtendedSpec) => void; +export declare function svg(browser: WebdriverIO.Client, path: string, filename: string): any; +export declare function testRenderFn(browser: WebdriverIO.Client, path: string): (filename: string) => void; diff --git a/build/test-runtime/util.js b/build/test-runtime/util.js new file mode 100644 index 0000000000..8096cd557a --- /dev/null +++ b/build/test-runtime/util.js @@ -0,0 +1,175 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// import {assert} from 'chai'; +var fs = require("fs"); +var mkdirp_1 = require("mkdirp"); +var vega_util_1 = require("vega-util"); +exports.generate = process.env.VL_GENERATE_TESTS; +exports.output = 'test-runtime/resources'; +exports.selectionTypes = ['single', 'multi', 'interval']; +exports.compositeTypes = ['repeat', 'facet']; +exports.resolutions = ['union', 'intersect']; +exports.bound = 'bound'; +exports.unbound = 'unbound'; +exports.tuples = [ + { a: 0, b: 28, c: 0 }, { a: 0, b: 55, c: 1 }, { a: 0, b: 23, c: 2 }, + { a: 1, b: 43, c: 0 }, { a: 1, b: 91, c: 1 }, { a: 1, b: 54, c: 2 }, + { a: 2, b: 81, c: 0 }, { a: 2, b: 53, c: 1 }, { a: 2, b: 76, c: 2 }, + { a: 3, b: 19, c: 0 }, { a: 3, b: 87, c: 1 }, { a: 3, b: 12, c: 2 }, + { a: 4, b: 52, c: 0 }, { a: 4, b: 48, c: 1 }, { a: 4, b: 35, c: 2 }, + { a: 5, b: 24, c: 0 }, { a: 5, b: 49, c: 1 }, { a: 5, b: 48, c: 2 }, + { a: 6, b: 87, c: 0 }, { a: 6, b: 66, c: 1 }, { a: 6, b: 23, c: 2 }, + { a: 7, b: 17, c: 0 }, { a: 7, b: 27, c: 1 }, { a: 7, b: 39, c: 2 }, + { a: 8, b: 68, c: 0 }, { a: 8, b: 16, c: 1 }, { a: 8, b: 67, c: 2 }, + { a: 9, b: 49, c: 0 }, { a: 9, b: 15, c: 1 }, { a: 9, b: 48, 'c': 2 } +]; +var unitNames = { + repeat: ['child_d', 'child_e', 'child_f'], + facet: ['child_0', 'child_1', 'child_2'] +}; +exports.hits = { + discrete: { + qq: [8, 19], + qq_clear: [5, 16], + bins: [4, 29], + bins_clear: [18, 7], + repeat: [5, 10, 17], + repeat_clear: [13, 14, 2], + facet: [2, 6, 9], + facet_clear: [3, 4, 8] + }, + interval: { + drag: [[5, 14], [18, 26]], + drag_clear: [[5], [16]], + translate: [[6, 16], [24, 8]], + bins: [[4, 8], [2, 7]], + bins_clear: [[5], [9]], + bins_translate: [[5, 7], [1, 8]], + repeat: [[8, 29], [11, 26], [7, 21]], + repeat_clear: [[8], [11], [17]], + facet: [[1, 9], [2, 8], [4, 10]], + facet_clear: [[3], [5], [7]] + } +}; +function base(iter, sel, opts) { + if (opts === void 0) { opts = {}; } + var data = { values: opts.values || exports.tuples }; + var x = __assign({ field: 'a', type: 'quantitative' }, opts.x); + var y = __assign({ field: 'b', type: 'quantitative' }, opts.y); + var color = __assign({ field: 'c', type: 'nominal' }, opts.color); + var size = __assign({ value: 100 }, opts.size); + var selection = { sel: sel }; + var mark = 'circle'; + return iter % 2 === 0 ? { + data: data, selection: selection, mark: mark, + encoding: { + x: x, y: y, size: size, + color: { + condition: __assign({ selection: 'sel' }, color), + value: 'grey' + } + } + } : { + data: data, + layer: [{ + selection: selection, mark: mark, + encoding: { + x: x, y: y, size: size, color: color, + opacity: { value: 0.25 } + } + }, { + transform: [{ filter: { selection: 'sel' } }], + mark: mark, + encoding: { x: x, y: y, size: size, color: color } + }] + }; +} +function spec(compose, iter, sel, opts) { + if (opts === void 0) { opts = {}; } + var _a = base(iter, sel, opts), data = _a.data, spec = __rest(_a, ["data"]); + var resolve = opts.resolve; + switch (compose) { + case 'unit': + return __assign({ data: data }, spec); + case 'facet': + return { + data: data, + facet: { row: { field: 'c', type: 'nominal' } }, + spec: spec, + resolve: resolve + }; + case 'repeat': + return { + data: data, + repeat: { row: ['d', 'e', 'f'] }, + spec: spec, + resolve: resolve + }; + } + return null; +} +exports.spec = spec; +function unitNameRegex(specType, idx) { + var name = unitNames[specType][idx].replace('child_', ''); + return new RegExp("child(.*?)_" + name); +} +exports.unitNameRegex = unitNameRegex; +function parentSelector(compositeType, index) { + return compositeType === 'facet' ? "cell > g:nth-child(" + (index + 1) + ")" : + unitNames.repeat[index] + '_group'; +} +exports.parentSelector = parentSelector; +function brush(key, idx, parent, targetBrush) { + var fn = key.match('_clear') ? 'clear' : 'brush'; + return "return " + fn + "(" + exports.hits.interval[key][idx].join(', ') + ", " + vega_util_1.stringValue(parent) + ", " + !!targetBrush + ")"; +} +exports.brush = brush; +function pt(key, idx, parent) { + var fn = key.match('_clear') ? 'clear' : 'pt'; + return "return " + fn + "(" + exports.hits.discrete[key][idx] + ", " + vega_util_1.stringValue(parent) + ")"; +} +exports.pt = pt; +function embedFn(browser) { + return function (spec) { + browser.execute(function (_) { return window['embed'](_); }, spec); + }; +} +exports.embedFn = embedFn; +function svg(browser, path, filename) { + var xml = browser.executeAsync(function (done) { + window['view'].runAfter(function (view) { return view.toSVG().then(function (_) { return done(_); }); }); + }); + if (exports.generate) { + mkdirp_1.sync(path = exports.output + "/" + path); + fs.writeFileSync(path + "/" + filename + ".svg", xml.value); + } + return xml.value; +} +exports.svg = svg; +function testRenderFn(browser, path) { + return function (filename) { + // const render = + svg(browser, path, filename); + // const file = fs.readFileSync(`${output}/${path}/${filename}.svg`); + // assert.equal(render, file); + }; +} +exports.testRenderFn = testRenderFn; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QtcnVudGltZS91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsdUJBQXlCO0FBQ3pCLGlDQUFzQztBQUN0Qyx1Q0FBc0M7QUFJekIsUUFBQSxRQUFRLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQztBQUN6QyxRQUFBLE1BQU0sR0FBRyx3QkFBd0IsQ0FBQztBQUdsQyxRQUFBLGNBQWMsR0FBb0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2xFLFFBQUEsY0FBYyxHQUFrQixDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNwRCxRQUFBLFdBQVcsR0FBMEIsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFFNUQsUUFBQSxLQUFLLEdBQUcsT0FBTyxDQUFDO0FBQ2hCLFFBQUEsT0FBTyxHQUFHLFNBQVMsQ0FBQztBQUVwQixRQUFBLE1BQU0sR0FBRztJQUNwQixFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDN0QsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQzdELEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUM3RCxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDN0QsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQzdELEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUM3RCxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDN0QsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQzdELEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQztJQUM3RCxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUM7Q0FDaEUsQ0FBQztBQUVGLElBQU0sU0FBUyxHQUFHO0lBQ2hCLE1BQU0sRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FB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QUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxDQUFTLElBQUssT0FBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQVAsQ0FBTyxDQUFDLEVBQXpDLENBQXlDLENBQUMsQ0FBQztJQUNwRixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxDQUFDLGdCQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ2IsYUFBTSxDQUFDLElBQUksR0FBTSxjQUFNLFNBQUksSUFBTSxDQUFDLENBQUM7UUFDbkMsRUFBRSxDQUFDLGFBQWEsQ0FBSSxJQUFJLFNBQUksUUFBUSxTQUFNLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztBQUNuQixDQUFDO0FBWEQsa0JBV0M7QUFFRCxzQkFBNkIsT0FBaUMsRUFBRSxJQUFZO0lBQzFFLE1BQU0sQ0FBQyxVQUFTLFFBQWdCO1FBQzlCLGlCQUFpQjtRQUNmLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLHFFQUFxRTtRQUNyRSw4QkFBOEI7SUFDaEMsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQVBELG9DQU9DIiwic291cmNlc0NvbnRlbnQiOlsiLy8gaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHtzeW5jIGFzIG1rZGlycH0gZnJvbSAnbWtkaXJwJztcbmltcG9ydCB7c3RyaW5nVmFsdWV9IGZyb20gJ3ZlZ2EtdXRpbCc7XG5pbXBvcnQge1NlbGVjdGlvblJlc29sdXRpb24sIFNlbGVjdGlvblR5cGV9IGZyb20gJy4uL3NyYy9zZWxlY3Rpb24nO1xuaW1wb3J0IHtMYXllclNwZWMsIFRvcExldmVsRXh0ZW5kZWRTcGVjLCBVbml0U3BlY30gZnJvbSAnLi4vc3JjL3NwZWMnO1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGUgPSBwcm9jZXNzLmVudi5WTF9HRU5FUkFURV9URVNUUztcbmV4cG9ydCBjb25zdCBvdXRwdXQgPSAndGVzdC1ydW50aW1lL3Jlc291cmNlcyc7XG5cbmV4cG9ydCB0eXBlIENvbXBvc2VUeXBlID0gJ3VuaXQnIHwgJ3JlcGVhdCcgfCAnZmFjZXQnO1xuZXhwb3J0IGNvbnN0IHNlbGVjdGlvblR5cGVzOiBTZWxlY3Rpb25UeXBlW10gPSBbJ3NpbmdsZScsICdtdWx0aScsICdpbnRlcnZhbCddO1xuZXhwb3J0IGNvbnN0IGNvbXBvc2l0ZVR5cGVzOiBDb21wb3NlVHlwZVtdID0gWydyZXBlYXQnLCAnZmFjZXQnXTtcbmV4cG9ydCBjb25zdCByZXNvbHV0aW9uczogU2VsZWN0aW9uUmVzb2x1dGlvbltdID0gWyd1bmlvbicsICdpbnRlcnNlY3QnXTtcblxuZXhwb3J0IGNvbnN0IGJvdW5kID0gJ2JvdW5kJztcbmV4cG9ydCBjb25zdCB1bmJvdW5kID0gJ3VuYm91bmQnO1xuXG5leHBvcnQgY29uc3QgdHVwbGVzID0gW1xuICB7YTogMCwgYjogMjgsIGM6IDB9LCB7YTogMCwgYjogNTUsIGM6IDF9LCB7YTogMCwgYjogMjMsIGM6IDJ9LFxuICB7YTogMSwgYjogNDMsIGM6IDB9LCB7YTogMSwgYjogOTEsIGM6IDF9LCB7YTogMSwgYjogNTQsIGM6IDJ9LFxuICB7YTogMiwgYjogODEsIGM6IDB9LCB7YTogMiwgYjogNTMsIGM6IDF9LCB7YTogMiwgYjogNzYsIGM6IDJ9LFxuICB7YTogMywgYjogMTksIGM6IDB9LCB7YTogMywgYjogODcsIGM6IDF9LCB7YTogMywgYjogMTIsIGM6IDJ9LFxuICB7YTogNCwgYjogNTIsIGM6IDB9LCB7YTogNCwgYjogNDgsIGM6IDF9LCB7YTogNCwgYjogMzUsIGM6IDJ9LFxuICB7YTogNSwgYjogMjQsIGM6IDB9LCB7YTogNSwgYjogNDksIGM6IDF9LCB7YTogNSwgYjogNDgsIGM6IDJ9LFxuICB7YTogNiwgYjogODcsIGM6IDB9LCB7YTogNiwgYjogNjYsIGM6IDF9LCB7YTogNiwgYjogMjMsIGM6IDJ9LFxuICB7YTogNywgYjogMTcsIGM6IDB9LCB7YTogNywgYjogMjcsIGM6IDF9LCB7YTogNywgYjogMzksIGM6IDJ9LFxuICB7YTogOCwgYjogNjgsIGM6IDB9LCB7YTogOCwgYjogMTYsIGM6IDF9LCB7YTogOCwgYjogNjcsIGM6IDJ9LFxuICB7YTogOSwgYjogNDksIGM6IDB9LCB7YTogOSwgYjogMTUsIGM6IDF9LCB7YTogOSwgYjogNDgsICdjJzogMn1cbl07XG5cbmNvbnN0IHVuaXROYW1lcyA9IHtcbiAgcmVwZWF0OiBbJ2NoaWxkX2QnLCAnY2hpbGRfZScsICdjaGlsZF9mJ10sXG4gIGZhY2V0OiBbJ2NoaWxkXzAnLCAnY2hpbGRfMScsICdjaGlsZF8yJ11cbn07XG5cbmV4cG9ydCBjb25zdCBoaXRzID0ge1xuICBkaXNjcmV0ZToge1xuICAgIHFxOiBbOCwgMTldLFxuICAgIHFxX2NsZWFyOiBbNSwgMTZdLFxuXG4gICAgYmluczogWzQsIDI5XSxcbiAgICBiaW5zX2NsZWFyOiBbMTgsIDddLFxuXG4gICAgcmVwZWF0OiBbNSwgMTAsIDE3XSxcbiAgICByZXBlYXRfY2xlYXI6IFsxMywgMTQsIDJdLFxuXG4gICAgZmFjZXQ6IFsyLCA2LCA5XSxcbiAgICBmYWNldF9jbGVhcjogWzMsIDQsIDhdXG4gIH0sXG5cbiAgaW50ZXJ2YWw6IHtcbiAgICBkcmFnOiBbWzUsIDE0XSwgWzE4LCAyNl1dLFxuICAgIGRyYWdfY2xlYXI6IFtbNV0sIFsxNl1dLFxuICAgIHRyYW5zbGF0ZTogW1s2LCAxNl0sIFsyNCwgOF1dLFxuXG4gICAgYmluczogW1s0LCA4XSwgWzIsIDddXSxcbiAgICBiaW5zX2NsZWFyOiBbWzVdLCBbOV1dLFxuICAgIGJpbnNfdHJhbnNsYXRlOiBbWzUsIDddLCBbMSwgOF1dLFxuXG4gICAgcmVwZWF0OiBbWzgsIDI5XSwgWzExLCAyNl0sIFs3LCAyMV1dLFxuICAgIHJlcGVhdF9jbGVhcjogW1s4XSwgWzExXSwgWzE3XV0sXG5cbiAgICBmYWNldDogW1sxLCA5XSwgWzIsIDhdLCBbNCwgMTBdXSxcbiAgICBmYWNldF9jbGVhcjogW1szXSwgWzVdLCBbN11dXG4gIH1cbn07XG5cbmZ1bmN0aW9uIGJhc2UoaXRlcjogbnVtYmVyLCBzZWw6IGFueSwgb3B0czogYW55ID0ge30pOiBVbml0U3BlYyB8IExheWVyU3BlYyB7XG4gIGNvbnN0IGRhdGEgPSB7dmFsdWVzOiBvcHRzLnZhbHVlcyB8fCB0dXBsZXN9O1xuICBjb25zdCB4ID0ge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCAuLi5vcHRzLnh9O1xuICBjb25zdCB5ID0ge2ZpZWxkOiAnYicsdHlwZTogJ3F1YW50aXRhdGl2ZScsIC4uLm9wdHMueX07XG4gIGNvbnN0IGNvbG9yID0ge2ZpZWxkOiAnYycsIHR5cGU6ICdub21pbmFsJywgLi4ub3B0cy5jb2xvcn07XG4gIGNvbnN0IHNpemUgPSB7dmFsdWU6IDEwMCwgLi4ub3B0cy5zaXplfTtcbiAgY29uc3Qgc2VsZWN0aW9uID0ge3NlbH07XG4gIGNvbnN0IG1hcmsgPSAnY2lyY2xlJztcblxuICByZXR1cm4gaXRlciAlIDIgPT09IDAgPyB7XG4gICAgZGF0YSwgc2VsZWN0aW9uLCBtYXJrLFxuICAgIGVuY29kaW5nOiB7XG4gICAgICB4LCB5LCBzaXplLFxuICAgICAgY29sb3I6IHtcbiAgICAgICAgY29uZGl0aW9uOiB7c2VsZWN0aW9uOiAnc2VsJywgLi4uY29sb3J9LFxuICAgICAgICB2YWx1ZTogJ2dyZXknXG4gICAgICB9XG4gICAgfVxuICB9IDoge1xuICAgIGRhdGEsXG4gICAgbGF5ZXI6IFt7XG4gICAgICBzZWxlY3Rpb24sIG1hcmssXG4gICAgICBlbmNvZGluZzoge1xuICAgICAgICB4LCB5LCBzaXplLCBjb2xvcixcbiAgICAgICAgb3BhY2l0eToge3ZhbHVlOiAwLjI1fVxuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIHRyYW5zZm9ybTogW3tmaWx0ZXI6IHtzZWxlY3Rpb246ICdzZWwnfX1dLFxuICAgICAgbWFyayxcbiAgICAgIGVuY29kaW5nOiB7eCwgeSwgc2l6ZSwgY29sb3J9XG4gICAgfV1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNwZWMoY29tcG9zZTogQ29tcG9zZVR5cGUsIGl0ZXI6IG51bWJlciwgc2VsOiBhbnksIG9wdHM6IGFueSA9IHt9KTogVG9wTGV2ZWxFeHRlbmRlZFNwZWMge1xuICBjb25zdCB7ZGF0YSwgLi4uc3BlY30gPSBiYXNlKGl0ZXIsIHNlbCwgb3B0cyk7XG4gIGNvbnN0IHJlc29sdmUgPSBvcHRzLnJlc29sdmU7XG4gIHN3aXRjaCAoY29tcG9zZSkge1xuICAgIGNhc2UgJ3VuaXQnOlxuICAgICAgcmV0dXJuIHtkYXRhLCAuLi5zcGVjfTtcbiAgICBjYXNlICdmYWNldCc6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhLFxuICAgICAgICBmYWNldDoge3Jvdzoge2ZpZWxkOiAnYycsIHR5cGU6ICdub21pbmFsJ319LFxuICAgICAgICBzcGVjLFxuICAgICAgICByZXNvbHZlXG4gICAgICB9O1xuICAgIGNhc2UgJ3JlcGVhdCc6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhLFxuICAgICAgICByZXBlYXQ6IHtyb3c6IFsnZCcsICdlJywgJ2YnXX0sXG4gICAgICAgIHNwZWMsXG4gICAgICAgIHJlc29sdmVcbiAgICAgIH07XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuaXROYW1lUmVnZXgoc3BlY1R5cGU6IENvbXBvc2VUeXBlLCBpZHg6IG51bWJlcikge1xuICBjb25zdCBuYW1lID0gdW5pdE5hbWVzW3NwZWNUeXBlXVtpZHhdLnJlcGxhY2UoJ2NoaWxkXycsICcnKTtcbiAgcmV0dXJuIG5ldyBSZWdFeHAoYGNoaWxkKC4qPylfJHtuYW1lfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyZW50U2VsZWN0b3IoY29tcG9zaXRlVHlwZTogQ29tcG9zZVR5cGUsIGluZGV4OiBudW1iZXIpIHtcbiAgcmV0dXJuIGNvbXBvc2l0ZVR5cGUgPT09ICdmYWNldCcgPyBgY2VsbCA+IGc6bnRoLWNoaWxkKCR7aW5kZXggKyAxfSlgIDpcbiAgICAgdW5pdE5hbWVzLnJlcGVhdFtpbmRleF0gKyAnX2dyb3VwJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJydXNoKGtleTogc3RyaW5nLCBpZHg6IG51bWJlciwgcGFyZW50Pzogc3RyaW5nLCB0YXJnZXRCcnVzaD86IGJvb2xlYW4pIHtcbiAgY29uc3QgZm4gPSBrZXkubWF0Y2goJ19jbGVhcicpID8gJ2NsZWFyJyA6ICdicnVzaCc7XG4gIHJldHVybiBgcmV0dXJuICR7Zm59KCR7aGl0cy5pbnRlcnZhbFtrZXldW2lkeF0uam9pbignLCAnKX0sICR7c3RyaW5nVmFsdWUocGFyZW50KX0sICR7ISF0YXJnZXRCcnVzaH0pYDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHB0KGtleTogc3RyaW5nLCBpZHg6IG51bWJlciwgcGFyZW50Pzogc3RyaW5nKSB7XG4gIGNvbnN0IGZuID0ga2V5Lm1hdGNoKCdfY2xlYXInKSA/ICdjbGVhcicgOiAncHQnO1xuICByZXR1cm4gYHJldHVybiAke2ZufSgke2hpdHMuZGlzY3JldGVba2V5XVtpZHhdfSwgJHtzdHJpbmdWYWx1ZShwYXJlbnQpfSlgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW1iZWRGbihicm93c2VyOiBXZWJkcml2ZXJJTy5DbGllbnQ8dm9pZD4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHNwZWM6IFRvcExldmVsRXh0ZW5kZWRTcGVjKSB7XG4gICAgYnJvd3Nlci5leGVjdXRlKChfKSA9PiB3aW5kb3dbJ2VtYmVkJ10oXyksIHNwZWMpO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3ZnKGJyb3dzZXI6IFdlYmRyaXZlcklPLkNsaWVudDx2b2lkPiwgcGF0aDogc3RyaW5nLCBmaWxlbmFtZTogc3RyaW5nKSB7XG4gIGNvbnN0IHhtbCA9IGJyb3dzZXIuZXhlY3V0ZUFzeW5jKChkb25lKSA9PiB7XG4gICAgd2luZG93Wyd2aWV3J10ucnVuQWZ0ZXIoKHZpZXc6IGFueSkgPT4gdmlldy50b1NWRygpLnRoZW4oKF86IHN0cmluZykgPT4gZG9uZShfKSkpO1xuICB9KTtcblxuICBpZiAoZ2VuZXJhdGUpIHtcbiAgICBta2RpcnAocGF0aCA9IGAke291dHB1dH0vJHtwYXRofWApO1xuICAgIGZzLndyaXRlRmlsZVN5bmMoYCR7cGF0aH0vJHtmaWxlbmFtZX0uc3ZnYCwgeG1sLnZhbHVlKTtcbiAgfVxuXG4gIHJldHVybiB4bWwudmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0UmVuZGVyRm4oYnJvd3NlcjogV2ViZHJpdmVySU8uQ2xpZW50PHZvaWQ+LCBwYXRoOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICAvLyBjb25zdCByZW5kZXIgPVxuICAgICAgc3ZnKGJyb3dzZXIsIHBhdGgsIGZpbGVuYW1lKTtcbiAgICAvLyBjb25zdCBmaWxlID0gZnMucmVhZEZpbGVTeW5jKGAke291dHB1dH0vJHtwYXRofS8ke2ZpbGVuYW1lfS5zdmdgKTtcbiAgICAvLyBhc3NlcnQuZXF1YWwocmVuZGVyLCBmaWxlKTtcbiAgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/build/test-runtime/zoom.test.d.ts b/build/test-runtime/zoom.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-runtime/zoom.test.js b/build/test-runtime/zoom.test.js new file mode 100644 index 0000000000..8fde3e2768 --- /dev/null +++ b/build/test-runtime/zoom.test.js @@ -0,0 +1,154 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("./util"); +var hits = { + zoom: [9, 23], + bins: [8, 2] +}; +function zoom(key, idx, zoom, parent, targetBrush) { + var delta = zoom === 'out' ? 200 : -200; + return "return zoom(" + hits[key][idx] + ", " + delta + ", " + parent + ", " + targetBrush + ")"; +} +var cmp = function (a, b) { return a - b; }; +[util_1.bound, util_1.unbound].forEach(function (bind) { + describe("Zoom " + bind + " interval selections at runtime", function () { + var type = 'interval'; + var embed = util_1.embedFn(browser); + var testRender = util_1.testRenderFn(browser, "interval/zoom/" + bind); + var binding = bind === util_1.bound ? { bind: 'scales' } : {}; + var assertExtent = { + in: ['isAtLeast', 'isAtMost'], out: ['isAtMost', 'isAtLeast'] + }; + function setup(brushKey, idx, encodings, parent) { + var inOut = idx % 2 ? 'out' : 'in'; + var xold; + var yold; + if (bind === util_1.unbound) { + var drag = browser.execute(util_1.brush(brushKey, idx, parent)).value[0]; + xold = drag.intervals[0].extent.sort(cmp); + yold = encodings.indexOf('y') >= 0 ? drag.intervals[encodings.indexOf('x') + 1].extent.sort(cmp) : null; + } + else { + xold = JSON.parse(browser.execute('return JSON.stringify(view._runtime.scales.x.value.domain())').value); + yold = browser.execute('return view._runtime.scales.y.value.domain()').value; + } + return { inOut: inOut, xold: xold, yold: yold }; + } + it('should zoom in and out', function () { + for (var i = 0; i < hits.zoom.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding))); + var _a = setup('drag', i, ['x', 'y']), inOut = _a.inOut, xold = _a.xold, yold = _a.yold; + testRender(inOut + "-0"); + var zoomed = browser.execute(zoom('zoom', i, inOut, null, bind === util_1.unbound)).value[0]; + var xnew = zoomed.intervals[0].extent.sort(cmp); + var ynew = zoomed.intervals[1].extent.sort(cmp); + testRender(inOut + "-1"); + chai_1.assert[assertExtent[inOut][0]](xnew[0], xold[0]); + chai_1.assert[assertExtent[inOut][1]](xnew[1], xold[1]); + chai_1.assert[assertExtent[inOut][0]](ynew[0], yold[0]); + chai_1.assert[assertExtent[inOut][1]](ynew[1], yold[1]); + } + }); + it('should work with binned domains', function () { + for (var i = 0; i < hits.bins.length; i++) { + var encodings = ['y']; + embed(util_1.spec('unit', 1, __assign({ type: type }, binding, { encodings: encodings }), { + x: { aggregate: 'count', field: '*', type: 'quantitative' }, + y: { bin: true }, + color: { value: 'steelblue', field: null, type: null } + })); + var _a = setup('bins', i, encodings), inOut = _a.inOut, yold = _a.yold; + testRender("bins_" + inOut + "-0"); + var zoomed = browser.execute(zoom('bins', i, inOut, null, bind === util_1.unbound)).value[0]; + var ynew = zoomed.intervals[0].extent.sort(cmp); + chai_1.assert[assertExtent[inOut][0]](ynew[0], yold[0]); + chai_1.assert[assertExtent[inOut][1]](ynew[1], yold[1]); + testRender("bins_" + inOut + "-1"); + } + }); + it('should work with temporal domains', function () { + var values = util_1.tuples.map(function (d) { return (__assign({}, d, { a: new Date(2017, d.a) })); }); + var encodings = ['x']; + for (var i = 0; i < hits.zoom.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding, { encodings: encodings }), { values: values, x: { type: 'temporal' } })); + var _a = setup('drag', i, encodings), inOut = _a.inOut, xold = _a.xold; + testRender("temporal_" + inOut + "-0"); + var zoomed = browser.execute(zoom('zoom', i, inOut, null, bind === util_1.unbound)).value[0]; + var xnew = zoomed.intervals[0].extent.sort(cmp); + chai_1.assert[assertExtent[inOut][0]](+xnew[0], +(new Date(xold[0]))); + chai_1.assert[assertExtent[inOut][1]](+xnew[1], +(new Date(xold[1]))); + testRender("temporal_" + inOut + "-1"); + } + }); + it('should work with log/pow scales', function () { + for (var i = 0; i < hits.zoom.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding), { + x: { scale: { type: 'pow', exponent: 1.5 } }, + y: { scale: { type: 'log' } } + })); + var _a = setup('drag', i, ['x', 'y']), inOut = _a.inOut, xold = _a.xold, yold = _a.yold; + testRender("logpow_" + inOut + "-0"); + var zoomed = browser.execute(zoom('zoom', i, inOut, null, bind === util_1.unbound)).value[0]; + var xnew = zoomed.intervals[0].extent.sort(cmp); + var ynew = zoomed.intervals[1].extent.sort(cmp); + chai_1.assert[assertExtent[inOut][0]](xnew[0], xold[0]); + chai_1.assert[assertExtent[inOut][1]](xnew[1], xold[1]); + chai_1.assert[assertExtent[inOut][0]](ynew[0], yold[0]); + chai_1.assert[assertExtent[inOut][1]](ynew[1], yold[1]); + testRender("logpow_" + inOut + "-1"); + } + }); + if (bind === util_1.unbound) { + it('should work with ordinal/nominal domains', function () { + for (var i = 0; i < hits.zoom.length; i++) { + embed(util_1.spec('unit', i, __assign({ type: type }, binding), { + x: { type: 'ordinal' }, y: { type: 'nominal' } + })); + var _a = setup('drag', i, ['x', 'y']), inOut = _a.inOut, xold = _a.xold, yold = _a.yold; + testRender("ord_" + inOut + "-0"); + var zoomed = browser.execute(zoom('zoom', i, inOut, null, bind === util_1.unbound)).value[0]; + var xnew = zoomed.intervals[0].extent.sort(cmp); + var ynew = zoomed.intervals[1].extent.sort(cmp); + if (inOut === 'in') { + chai_1.assert.isAtMost(xnew.length, xold.length); + chai_1.assert.isAtMost(ynew.length, yold.length); + } + else { + chai_1.assert.isAtLeast(xnew.length, xold.length); + chai_1.assert.isAtLeast(ynew.length, yold.length); + } + testRender("ord_" + inOut + "-1"); + } + }); + } + else { + util_1.compositeTypes.forEach(function (specType) { + it("should work with shared scales in " + specType + " views", function () { + for (var i = 0; i < hits.bins.length; i++) { + embed(util_1.spec(specType, 0, __assign({ type: type }, binding), { resolve: { scale: { x: 'shared', y: 'shared' } } })); + var parent_1 = util_1.parentSelector(specType, i); + var _a = setup(specType, i, ['x', 'y'], parent_1), inOut = _a.inOut, xold = _a.xold, yold = _a.yold; + var zoomed = browser.execute(zoom('bins', i, inOut, null, bind === util_1.unbound)).value[0]; + var xnew = zoomed.intervals[0].extent.sort(cmp); + var ynew = zoomed.intervals[1].extent.sort(cmp); + chai_1.assert[assertExtent[inOut][0]](xnew[0], xold[0]); + chai_1.assert[assertExtent[inOut][1]](xnew[1], xold[1]); + chai_1.assert[assertExtent[inOut][0]](ynew[0], yold[0]); + chai_1.assert[assertExtent[inOut][1]](ynew[1], yold[1]); + testRender(specType + "_" + inOut); + } + }); + }); + } + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC1ydW50aW1lL3pvb20udGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsNkJBQTRCO0FBQzVCLCtCQVVnQjtBQUVoQixJQUFNLElBQUksR0FBRztJQUNYLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7SUFDYixJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0NBQ2IsQ0FBQztBQUlGLGNBQWMsR0FBVyxFQUFFLEdBQVcsRUFBRSxJQUFXLEVBQUUsTUFBZSxFQUFFLFdBQXFCO0lBQ3pGLElBQU0sS0FBSyxHQUFHLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDMUMsTUFBTSxDQUFDLGlCQUFlLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBSyxLQUFLLFVBQUssTUFBTSxVQUFLLFdBQVcsTUFBRyxDQUFDO0FBQy9FLENBQUM7QUFFRCxJQUFNLEdBQUcsR0FBRyxVQUFDLENBQVMsRUFBRSxDQUFTLElBQUssT0FBQSxDQUFDLEdBQUcsQ0FBQyxFQUFMLENBQUssQ0FBQztBQUU1QyxDQUFDLFlBQUssRUFBRSxjQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBUyxJQUFJO0lBQ3BDLFFBQVEsQ0FBQyxVQUFRLElBQUksb0NBQWlDLEVBQUU7UUFDdEQsSUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDO1FBQ3hCLElBQU0sS0FBSyxHQUFHLGNBQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQixJQUFNLFVBQVUsR0FBRyxtQkFBWSxDQUFDLE9BQU8sRUFBRSxtQkFBaUIsSUFBTSxDQUFDLENBQUM7UUFDbEUsSUFBTSxPQUFPLEdBQUcsSUFBSSxLQUFLLFlBQUssQ0FBQyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsUUFB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QUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDakQsYUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDakQsYUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDakQsVUFBVSxDQUFJLFFBQVEsU0FBSSxLQUFPLENBQUMsQ0FBQztvQkFDckMsQ0FBQztnQkFDSCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge1xuICBib3VuZCxcbiAgYnJ1c2gsXG4gIGNvbXBvc2l0ZVR5cGVzLFxuICBlbWJlZEZuLFxuICBwYXJlbnRTZWxlY3RvcixcbiAgc3BlYyxcbiAgdGVzdFJlbmRlckZuLFxuICB0dXBsZXMsXG4gIHVuYm91bmQsXG59IGZyb20gJy4vdXRpbCc7XG5cbmNvbnN0IGhpdHMgPSB7XG4gIHpvb206IFs5LCAyM10sXG4gIGJpbnM6IFs4LCAyXVxufTtcblxudHlwZSBJbk91dCA9ICdpbicgfCAnb3V0JztcblxuZnVuY3Rpb24gem9vbShrZXk6IHN0cmluZywgaWR4OiBudW1iZXIsIHpvb206IEluT3V0LCBwYXJlbnQ/OiBzdHJpbmcsIHRhcmdldEJydXNoPzogYm9vbGVhbikge1xuICBjb25zdCBkZWx0YSA9IHpvb20gPT09ICdvdXQnID8gMjAwIDogLTIwMDtcbiAgcmV0dXJuIGByZXR1cm4gem9vbSgke2hpdHNba2V5XVtpZHhdfSwgJHtkZWx0YX0sICR7cGFyZW50fSwgJHt0YXJnZXRCcnVzaH0pYDtcbn1cblxuY29uc3QgY21wID0gKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiBhIC0gYjtcblxuW2JvdW5kLCB1bmJvdW5kXS5mb3JFYWNoKGZ1bmN0aW9uKGJpbmQpIHtcbiAgZGVzY3JpYmUoYFpvb20gJHtiaW5kfSBpbnRlcnZhbCBzZWxlY3Rpb25zIGF0IHJ1bnRpbWVgLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCB0eXBlID0gJ2ludGVydmFsJztcbiAgICBjb25zdCBlbWJlZCA9IGVtYmVkRm4oYnJvd3Nlcik7XG4gICAgY29uc3QgdGVzdFJlbmRlciA9IHRlc3RSZW5kZXJGbihicm93c2VyLCBgaW50ZXJ2YWwvem9vbS8ke2JpbmR9YCk7XG4gICAgY29uc3QgYmluZGluZyA9IGJpbmQgPT09IGJvdW5kID8ge2JpbmQ6ICdzY2FsZXMnfSA6IHt9O1xuXG4gICAgY29uc3QgYXNzZXJ0RXh0ZW50ID0ge1xuICAgICAgaW46IFsnaXNBdExlYXN0JywgJ2lzQXRNb3N0J10sIG91dDogWydpc0F0TW9zdCcsICdpc0F0TGVhc3QnXVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBzZXR1cChicnVzaEtleTogc3RyaW5nLCBpZHg6IG51bWJlciwgZW5jb2RpbmdzOiBzdHJpbmdbXSwgcGFyZW50Pzogc3RyaW5nKSB7XG4gICAgICBjb25zdCBpbk91dDogSW5PdXQgPSBpZHggJSAyID8gJ291dCcgOiAnaW4nO1xuICAgICAgbGV0IHhvbGQ6IG51bWJlcltdO1xuICAgICAgbGV0IHlvbGQ6IG51bWJlcltdO1xuXG4gICAgICBpZiAoYmluZCA9PT0gdW5ib3VuZCkge1xuICAgICAgICBjb25zdCBkcmFnID0gYnJvd3Nlci5leGVjdXRlKGJydXNoKGJydXNoS2V5LCBpZHgsIHBhcmVudCkpLnZhbHVlWzBdO1xuICAgICAgICB4b2xkID0gZHJhZy5pbnRlcnZhbHNbMF0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgeW9sZCA9IGVuY29kaW5ncy5pbmRleE9mKCd5JykgPj0gMCA/IGRyYWcuaW50ZXJ2YWxzW2VuY29kaW5ncy5pbmRleE9mKCd4JykgKyAxXS5leHRlbnQuc29ydChjbXApIDogbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHhvbGQgPSBKU09OLnBhcnNlKGJyb3dzZXIuZXhlY3V0ZSgncmV0dXJuIEpTT04uc3RyaW5naWZ5KHZpZXcuX3J1bnRpbWUuc2NhbGVzLngudmFsdWUuZG9tYWluKCkpJykudmFsdWUpO1xuICAgICAgICB5b2xkID0gYnJvd3Nlci5leGVjdXRlKCdyZXR1cm4gdmlldy5fcnVudGltZS5zY2FsZXMueS52YWx1ZS5kb21haW4oKScpLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge2luT3V0LCB4b2xkLCB5b2xkfTtcbiAgICB9XG5cbiAgICBpdCgnc2hvdWxkIHpvb20gaW4gYW5kIG91dCcsIGZ1bmN0aW9uKCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLnpvb20ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlLCAuLi5iaW5kaW5nfSkpO1xuICAgICAgICBjb25zdCB7aW5PdXQsIHhvbGQsIHlvbGR9ID0gc2V0dXAoJ2RyYWcnLCBpLCBbJ3gnLCAneSddKTtcbiAgICAgICAgdGVzdFJlbmRlcihgJHtpbk91dH0tMGApO1xuXG4gICAgICAgIGNvbnN0IHpvb21lZCA9IGJyb3dzZXIuZXhlY3V0ZSh6b29tKCd6b29tJywgaSwgaW5PdXQsIG51bGwsIGJpbmQgPT09IHVuYm91bmQpKS52YWx1ZVswXTtcbiAgICAgICAgY29uc3QgeG5ldyA9IHpvb21lZC5pbnRlcnZhbHNbMF0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgY29uc3QgeW5ldyA9IHpvb21lZC5pbnRlcnZhbHNbMV0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgdGVzdFJlbmRlcihgJHtpbk91dH0tMWApO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2luT3V0XVswXV0oeG5ld1swXSwgeG9sZFswXSk7XG4gICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRbaW5PdXRdWzFdXSh4bmV3WzFdLCB4b2xkWzFdKTtcbiAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMF1dKHluZXdbMF0sIHlvbGRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2luT3V0XVsxXV0oeW5ld1sxXSwgeW9sZFsxXSk7XG5cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgd29yayB3aXRoIGJpbm5lZCBkb21haW5zJywgZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhpdHMuYmlucy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBlbmNvZGluZ3MgPSBbJ3knXTtcbiAgICAgICAgZW1iZWQoc3BlYygndW5pdCcsIDEsIHt0eXBlLCAuLi5iaW5kaW5nLCBlbmNvZGluZ3N9LCB7XG4gICAgICAgICAgeDoge2FnZ3JlZ2F0ZTogJ2NvdW50JywgZmllbGQ6ICcqJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgIHk6IHtiaW46IHRydWV9LFxuICAgICAgICAgIGNvbG9yOiB7dmFsdWU6ICdzdGVlbGJsdWUnLCBmaWVsZDogbnVsbCwgdHlwZTogbnVsbH1cbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGNvbnN0IHtpbk91dCwgeW9sZH0gPSBzZXR1cCgnYmlucycsIGksIGVuY29kaW5ncyk7XG4gICAgICAgIHRlc3RSZW5kZXIoYGJpbnNfJHtpbk91dH0tMGApO1xuXG4gICAgICAgIGNvbnN0IHpvb21lZCA9IGJyb3dzZXIuZXhlY3V0ZSh6b29tKCdiaW5zJywgaSwgaW5PdXQsIG51bGwsIGJpbmQgPT09IHVuYm91bmQpKS52YWx1ZVswXTtcbiAgICAgICAgY29uc3QgeW5ldyA9IHpvb21lZC5pbnRlcnZhbHNbMF0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMF1dKHluZXdbMF0sIHlvbGRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2luT3V0XVsxXV0oeW5ld1sxXSwgeW9sZFsxXSk7XG4gICAgICAgIHRlc3RSZW5kZXIoYGJpbnNfJHtpbk91dH0tMWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggdGVtcG9yYWwgZG9tYWlucycsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgdmFsdWVzID0gdHVwbGVzLm1hcCgoZCkgPT4gKHsuLi5kLCBhOiBuZXcgRGF0ZSgyMDE3LCBkLmEpfSkpO1xuICAgICAgY29uc3QgZW5jb2RpbmdzID0gWyd4J107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy56b29tLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVtYmVkKHNwZWMoJ3VuaXQnLCBpLCB7dHlwZSwgLi4uYmluZGluZywgZW5jb2RpbmdzfSxcbiAgICAgICAgICB7dmFsdWVzLCB4OiB7dHlwZTogJ3RlbXBvcmFsJ319KSk7XG4gICAgICAgIGNvbnN0IHtpbk91dCwgeG9sZH0gPSBzZXR1cCgnZHJhZycsIGksIGVuY29kaW5ncyk7XG4gICAgICAgIHRlc3RSZW5kZXIoYHRlbXBvcmFsXyR7aW5PdXR9LTBgKTtcblxuICAgICAgICBjb25zdCB6b29tZWQgPSBicm93c2VyLmV4ZWN1dGUoem9vbSgnem9vbScsIGksIGluT3V0LCBudWxsLCBiaW5kID09PSB1bmJvdW5kKSkudmFsdWVbMF07XG4gICAgICAgIGNvbnN0IHhuZXcgPSB6b29tZWQuaW50ZXJ2YWxzWzBdLmV4dGVudC5zb3J0KGNtcCk7XG4gICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRbaW5PdXRdWzBdXSgreG5ld1swXSwgKyhuZXcgRGF0ZSh4b2xkWzBdKSkpO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2luT3V0XVsxXV0oK3huZXdbMV0sICsobmV3IERhdGUoeG9sZFsxXSkpKTtcbiAgICAgICAgdGVzdFJlbmRlcihgdGVtcG9yYWxfJHtpbk91dH0tMWApO1xuICAgICAgfVxuXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHdvcmsgd2l0aCBsb2cvcG93IHNjYWxlcycsIGZ1bmN0aW9uKCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRzLnpvb20ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlLCAuLi5iaW5kaW5nfSwge1xuICAgICAgICAgIHg6IHtzY2FsZToge3R5cGU6ICdwb3cnLCBleHBvbmVudDogMS41fX0sXG4gICAgICAgICAgeToge3NjYWxlOiB7dHlwZTogJ2xvZyd9fVxuICAgICAgICB9KSk7XG4gICAgICAgIGNvbnN0IHtpbk91dCwgeG9sZCwgeW9sZH0gPSBzZXR1cCgnZHJhZycsIGksIFsneCcsICd5J10pO1xuICAgICAgICB0ZXN0UmVuZGVyKGBsb2dwb3dfJHtpbk91dH0tMGApO1xuXG4gICAgICAgIGNvbnN0IHpvb21lZCA9IGJyb3dzZXIuZXhlY3V0ZSh6b29tKCd6b29tJywgaSwgaW5PdXQsIG51bGwsIGJpbmQgPT09IHVuYm91bmQpKS52YWx1ZVswXTtcbiAgICAgICAgY29uc3QgeG5ldyA9IHpvb21lZC5pbnRlcnZhbHNbMF0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgY29uc3QgeW5ldyA9IHpvb21lZC5pbnRlcnZhbHNbMV0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMF1dKHhuZXdbMF0sIHhvbGRbMF0pO1xuICAgICAgICBhc3NlcnRbYXNzZXJ0RXh0ZW50W2luT3V0XVsxXV0oeG5ld1sxXSwgeG9sZFsxXSk7XG4gICAgICAgIGFzc2VydFthc3NlcnRFeHRlbnRbaW5PdXRdWzBdXSh5bmV3WzBdLCB5b2xkWzBdKTtcbiAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMV1dKHluZXdbMV0sIHlvbGRbMV0pO1xuICAgICAgICB0ZXN0UmVuZGVyKGBsb2dwb3dfJHtpbk91dH0tMWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGJpbmQgPT09IHVuYm91bmQpIHtcbiAgICAgIGl0KCdzaG91bGQgd29yayB3aXRoIG9yZGluYWwvbm9taW5hbCBkb21haW5zJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy56b29tLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgZW1iZWQoc3BlYygndW5pdCcsIGksIHt0eXBlLCAuLi5iaW5kaW5nfSwge1xuICAgICAgICAgICAgeDoge3R5cGU6ICdvcmRpbmFsJ30sIHk6IHt0eXBlOiAnbm9taW5hbCd9XG4gICAgICAgICAgfSkpO1xuICAgICAgICAgIGNvbnN0IHtpbk91dCwgeG9sZCwgeW9sZH0gPSBzZXR1cCgnZHJhZycsIGksIFsneCcsICd5J10pO1xuICAgICAgICAgIHRlc3RSZW5kZXIoYG9yZF8ke2luT3V0fS0wYCk7XG5cbiAgICAgICAgICBjb25zdCB6b29tZWQgPSBicm93c2VyLmV4ZWN1dGUoem9vbSgnem9vbScsIGksIGluT3V0LCBudWxsLCBiaW5kID09PSB1bmJvdW5kKSkudmFsdWVbMF07XG4gICAgICAgICAgY29uc3QgeG5ldyA9IHpvb21lZC5pbnRlcnZhbHNbMF0uZXh0ZW50LnNvcnQoY21wKTtcbiAgICAgICAgICBjb25zdCB5bmV3ID0gem9vbWVkLmludGVydmFsc1sxXS5leHRlbnQuc29ydChjbXApO1xuXG4gICAgICAgICAgaWYgKGluT3V0ID09PSAnaW4nKSB7XG4gICAgICAgICAgICBhc3NlcnQuaXNBdE1vc3QoeG5ldy5sZW5ndGgsIHhvbGQubGVuZ3RoKTtcbiAgICAgICAgICAgIGFzc2VydC5pc0F0TW9zdCh5bmV3Lmxlbmd0aCwgeW9sZC5sZW5ndGgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhc3NlcnQuaXNBdExlYXN0KHhuZXcubGVuZ3RoLCB4b2xkLmxlbmd0aCk7XG4gICAgICAgICAgICBhc3NlcnQuaXNBdExlYXN0KHluZXcubGVuZ3RoLCB5b2xkLmxlbmd0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGVzdFJlbmRlcihgb3JkXyR7aW5PdXR9LTFgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvc2l0ZVR5cGVzLmZvckVhY2goZnVuY3Rpb24oc3BlY1R5cGUpIHtcbiAgICAgICAgaXQoYHNob3VsZCB3b3JrIHdpdGggc2hhcmVkIHNjYWxlcyBpbiAke3NwZWNUeXBlfSB2aWV3c2AsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGl0cy5iaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBlbWJlZChzcGVjKHNwZWNUeXBlLCAwLCB7dHlwZSwgLi4uYmluZGluZ30sXG4gICAgICAgICAgICAgIHtyZXNvbHZlOiB7c2NhbGU6IHt4OiAnc2hhcmVkJywgeTogJ3NoYXJlZCd9fX0pKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudFNlbGVjdG9yKHNwZWNUeXBlLCBpKTtcbiAgICAgICAgICAgIGNvbnN0IHtpbk91dCwgeG9sZCwgeW9sZH0gPSBzZXR1cChzcGVjVHlwZSwgaSwgWyd4JywgJ3knXSwgcGFyZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHpvb21lZCA9IGJyb3dzZXIuZXhlY3V0ZSh6b29tKCdiaW5zJywgaSwgaW5PdXQsIG51bGwsIGJpbmQgPT09IHVuYm91bmQpKS52YWx1ZVswXTtcbiAgICAgICAgICAgIGNvbnN0IHhuZXcgPSB6b29tZWQuaW50ZXJ2YWxzWzBdLmV4dGVudC5zb3J0KGNtcCk7XG4gICAgICAgICAgICBjb25zdCB5bmV3ID0gem9vbWVkLmludGVydmFsc1sxXS5leHRlbnQuc29ydChjbXApO1xuICAgICAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMF1dKHhuZXdbMF0sIHhvbGRbMF0pO1xuICAgICAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMV1dKHhuZXdbMV0sIHhvbGRbMV0pO1xuICAgICAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMF1dKHluZXdbMF0sIHlvbGRbMF0pO1xuICAgICAgICAgICAgYXNzZXJ0W2Fzc2VydEV4dGVudFtpbk91dF1bMV1dKHluZXdbMV0sIHlvbGRbMV0pO1xuICAgICAgICAgICAgdGVzdFJlbmRlcihgJHtzcGVjVHlwZX1fJHtpbk91dH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/axis.test.js b/build/test/axis.test.js new file mode 100644 index 0000000000..ef884b352f --- /dev/null +++ b/build/test/axis.test.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var axis_1 = require("../src/axis"); +describe('axis', function () { + describe('VG_AXIS_PROPERTIES', function () { + it('should have scale and orient as the first two items', function () { + chai_1.assert.equal(axis_1.VG_AXIS_PROPERTIES[0], 'scale'); + chai_1.assert.equal(axis_1.VG_AXIS_PROPERTIES[1], 'orient'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpcy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC9heGlzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsb0NBQStDO0FBRS9DLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixRQUFRLENBQUMsb0JBQW9CLEVBQUU7UUFDN0IsRUFBRSxDQUFDLHFEQUFxRCxFQUFFO1lBQ3hELGFBQU0sQ0FBQyxLQUFLLENBQUMseUJBQWtCLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDN0MsYUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNoRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge1ZHX0FYSVNfUFJPUEVSVElFU30gZnJvbSAnLi4vc3JjL2F4aXMnO1xuXG5kZXNjcmliZSgnYXhpcycsICgpID0+IHtcbiAgZGVzY3JpYmUoJ1ZHX0FYSVNfUFJPUEVSVElFUycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGhhdmUgc2NhbGUgYW5kIG9yaWVudCBhcyB0aGUgZmlyc3QgdHdvIGl0ZW1zJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKFZHX0FYSVNfUFJPUEVSVElFU1swXSwgJ3NjYWxlJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoVkdfQVhJU19QUk9QRVJUSUVTWzFdLCAnb3JpZW50Jyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/bin.test.js b/build/test/bin.test.js new file mode 100644 index 0000000000..e4b948f81c --- /dev/null +++ b/build/test/bin.test.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var bin_1 = require("../src/bin"); +var channel_1 = require("../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 + [channel_1.COLOR, channel_1.OPACITY, channel_1.SHAPE, channel_1.ROW, channel_1.COLUMN].forEach(function (a) { return chai_1.assert.deepEqual(bin_1.autoMaxBins(a), 6); }); + }); +}); +describe('binToString', function () { + it('should generate the corrrect key for boolean', function () { + chai_1.assert.deepEqual(bin_1.binToString(true), 'bin'); + chai_1.assert.deepEqual(bin_1.binToString(false), 'bin'); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2Jpbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLGtDQUFvRDtBQUNwRCwwQ0FBa0U7QUFFbEUsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUN0QixFQUFFLENBQUMsZ0VBQWdFLEVBQUU7UUFDbkUsc0RBQXNEO1FBQ3RELENBQUMsZUFBSyxFQUFFLGlCQUFPLEVBQUUsZUFBSyxFQUFFLGFBQUcsRUFBRSxnQkFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsYUFBTSxDQUFDLFNBQVMsQ0FBQyxpQkFBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFuQyxDQUFtQyxDQUFDLENBQUM7SUFDM0YsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILFFBQVEsQ0FBQyxhQUFhLEVBQUU7SUFDdEIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1FBQ2xELGFBQU0sQ0FBQyxTQUFTLENBQUMsaUJBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMzQyxhQUFNLENBQUMsU0FBUyxDQUFDLGlCQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDN0MsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7YXV0b01heEJpbnMsIGJpblRvU3RyaW5nfSBmcm9tICcuLi9zcmMvYmluJztcbmltcG9ydCB7Q09MT1IsIENPTFVNTiwgT1BBQ0lUWSwgUk9XLCBTSEFQRX0gZnJvbSAnLi4vc3JjL2NoYW5uZWwnO1xuXG5kZXNjcmliZSgnYXV0b01heEJpbnMnLCAoKSA9PiB7XG4gIGl0KCdzaG91bGQgYXNzaWduIGdlbmVyYXRlIGNvcnJlY3QgZGVmYXVsdHMgZm9yIGRpZmZlcmVudCBjaGFubmVscycsICgpID0+IHtcbiAgICAvLyBOb3QgdGVzdGluZyBjYXNlIGZvciAxMCBiZWNhdXNlIGl0J3MgYWxyZWFkeSB0ZXN0ZWRcbiAgICBbQ09MT1IsIE9QQUNJVFksIFNIQVBFLCBST1csIENPTFVNTl0uZm9yRWFjaCgoYSkgPT4gYXNzZXJ0LmRlZXBFcXVhbChhdXRvTWF4QmlucyhhKSwgNikpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYmluVG9TdHJpbmcnLCAoKSA9PiB7XG4gIGl0KCdzaG91bGQgZ2VuZXJhdGUgdGhlIGNvcnJyZWN0IGtleSBmb3IgYm9vbGVhbicsICgpID0+IHtcbiAgIGFzc2VydC5kZWVwRXF1YWwoYmluVG9TdHJpbmcodHJ1ZSksICdiaW4nKTtcbiAgIGFzc2VydC5kZWVwRXF1YWwoYmluVG9TdHJpbmcoZmFsc2UpLCAnYmluJyk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/channel.test.js b/build/test/channel.test.js new file mode 100644 index 0000000000..18c95a9bb3 --- /dev/null +++ b/build/test/channel.test.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../src/channel"); +var channel_2 = require("../src/channel"); +var util_1 = require("../src/util"); +describe('channel', function () { + describe('UNIT_CHANNELS', function () { + it('should be CHANNELS without row and column', function () { + chai_1.assert.deepEqual(channel_2.UNIT_CHANNELS, util_1.without(channel_2.CHANNELS, ['row', 'column'])); + }); + }); + describe('SINGLE_DEF_CHANNELS', function () { + it('should be CHANNELS without detail and order', function () { + chai_1.assert.deepEqual(channel_1.SINGLE_DEF_CHANNELS, util_1.without(channel_2.CHANNELS, ['detail', 'order'])); + }); + }); + describe('SCALE_CHANNELS', function () { + it('should be UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT, LABEL, TOOLTIP', function () { + chai_1.assert.deepEqual(channel_2.SCALE_CHANNELS, util_1.without(channel_2.UNIT_CHANNELS, ['x2', 'y2', 'order', 'detail', 'text', 'label', 'tooltip'])); + }); + }); + describe('NONPOSITION_SCALE_CHANNELS', function () { + it('should be SCALE_CHANNELS without x, y, x2, y2', function () { + chai_1.assert.deepEqual(channel_2.NONPOSITION_SCALE_CHANNELS, util_1.without(channel_2.SCALE_CHANNELS, ['x', 'y'])); + }); + }); + describe('isScaleChannel', function () { + it('should return true for all scale channel', function () { + for (var _i = 0, SCALE_CHANNELS_1 = channel_2.SCALE_CHANNELS; _i < SCALE_CHANNELS_1.length; _i++) { + var channel = SCALE_CHANNELS_1[_i]; + chai_1.assert(channel_1.isScaleChannel(channel)); + } + }); + }); + describe('rangeType', function () { + it('should be defined for all channels (no error).', function () { + var _loop_1 = function (c) { + chai_1.assert.doesNotThrow(function () { + channel_1.rangeType(c); + }); + }; + for (var _i = 0, CHANNELS_1 = channel_2.CHANNELS; _i < CHANNELS_1.length; _i++) { + var c = CHANNELS_1[_i]; + _loop_1(c); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC9jaGFubmVsLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsMENBQThFO0FBQzlFLDBDQUFtRztBQUNuRyxvQ0FBb0M7QUFFcEMsUUFBUSxDQUFDLFNBQVMsRUFBRTtJQUNsQixRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQywyQ0FBMkMsRUFBRTtZQUM5QyxhQUFNLENBQUMsU0FBUyxDQUFDLHVCQUFhLEVBQUUsY0FBTyxDQUFDLGtCQUFRLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMscUJBQXFCLEVBQUU7UUFDOUIsRUFBRSxDQUFDLDZDQUE2QyxFQUFFO1lBQ2hELGFBQU0sQ0FBQyxTQUFTLENBQUMsNkJBQW1CLEVBQUUsY0FBTyxDQUFDLGtCQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7UUFDekIsRUFBRSxDQUFDLDZFQUE2RSxFQUFFO1lBQ2hGLGFBQU0sQ0FBQyxTQUFTLENBQUMsd0JBQWMsRUFBRSxjQUFPLENBQUMsdUJBQWEsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4SCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDRCQUE0QixFQUFFO1FBQ3JDLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRTtZQUNsRCxhQUFNLENBQUMsU0FBUyxDQUFDLG9DQUEwQixFQUFFLGNBQU8sQ0FBQyx3QkFBYyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1FBQ3pCLEVBQUUsQ0FBQywwQ0FBMEMsRUFBRTtZQUM3QyxHQUFHLENBQUMsQ0FBa0IsVUFBYyxFQUFkLG1CQUFBLHdCQUFjLEVBQWQsNEJBQWMsRUFBZCxJQUFjO2dCQUEvQixJQUFNLE9BQU8sdUJBQUE7Z0JBQ2hCLGFBQU0sQ0FBQyx3QkFBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7YUFDakM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsZ0RBQWdELEVBQUU7b0NBQ3hDLENBQUM7Z0JBQ1YsYUFBTSxDQUFDLFlBQVksQ0FBQztvQkFDbEIsbUJBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDZixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFKRCxHQUFHLENBQUMsQ0FBWSxVQUFRLEVBQVIsYUFBQSxrQkFBUSxFQUFSLHNCQUFRLEVBQVIsSUFBUTtnQkFBbkIsSUFBTSxDQUFDLGlCQUFBO3dCQUFELENBQUM7YUFJWDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7aXNTY2FsZUNoYW5uZWwsIHJhbmdlVHlwZSwgU0lOR0xFX0RFRl9DSEFOTkVMU30gZnJvbSAnLi4vc3JjL2NoYW5uZWwnO1xuaW1wb3J0IHtDSEFOTkVMUywgTk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFMsIFNDQUxFX0NIQU5ORUxTLCBVTklUX0NIQU5ORUxTfSBmcm9tICcuLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge3dpdGhvdXR9IGZyb20gJy4uL3NyYy91dGlsJztcblxuZGVzY3JpYmUoJ2NoYW5uZWwnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdVTklUX0NIQU5ORUxTJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYmUgQ0hBTk5FTFMgd2l0aG91dCByb3cgYW5kIGNvbHVtbicsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoVU5JVF9DSEFOTkVMUywgd2l0aG91dChDSEFOTkVMUywgWydyb3cnLCAnY29sdW1uJ10pKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NJTkdMRV9ERUZfQ0hBTk5FTFMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSBDSEFOTkVMUyB3aXRob3V0IGRldGFpbCBhbmQgb3JkZXInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKFNJTkdMRV9ERUZfQ0hBTk5FTFMsIHdpdGhvdXQoQ0hBTk5FTFMsIFsnZGV0YWlsJywgJ29yZGVyJ10pKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NDQUxFX0NIQU5ORUxTJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYmUgVU5JVF9DSEFOTkVMUyB3aXRob3V0IFgyLCBZMiwgT1JERVIsIERFVEFJTCwgVEVYVCwgTEFCRUwsIFRPT0xUSVAnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKFNDQUxFX0NIQU5ORUxTLCB3aXRob3V0KFVOSVRfQ0hBTk5FTFMsIFsneDInLCAneTInLCAnb3JkZXInLCAnZGV0YWlsJywgJ3RleHQnLCAnbGFiZWwnLCAndG9vbHRpcCddKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdOT05QT1NJVElPTl9TQ0FMRV9DSEFOTkVMUycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJlIFNDQUxFX0NIQU5ORUxTIHdpdGhvdXQgeCwgeSwgeDIsIHkyJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChOT05QT1NJVElPTl9TQ0FMRV9DSEFOTkVMUywgd2l0aG91dChTQ0FMRV9DSEFOTkVMUywgWyd4JywgJ3knXSkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNTY2FsZUNoYW5uZWwnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYWxsIHNjYWxlIGNoYW5uZWwnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgU0NBTEVfQ0hBTk5FTFMpIHtcbiAgICAgICAgYXNzZXJ0KGlzU2NhbGVDaGFubmVsKGNoYW5uZWwpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JhbmdlVHlwZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJlIGRlZmluZWQgZm9yIGFsbCBjaGFubmVscyAobm8gZXJyb3IpLicsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgYyBvZiBDSEFOTkVMUykge1xuICAgICAgICBhc3NlcnQuZG9lc05vdFRocm93KCgpID0+IHtcbiAgICAgICAgICByYW5nZVR5cGUoYyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/axis/encode.test.js b/build/test/compile/axis/encode.test.js new file mode 100644 index 0000000000..b6ba4f37e5 --- /dev/null +++ b/build/test/compile/axis/encode.test.js @@ -0,0 +1,73 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var encode = require("../../../src/compile/axis/encode"); +var encode_1 = require("../../../src/compile/axis/encode"); +var util_1 = require("../../util"); +describe('compile/axis', function () { + describe('encode.labels()', function () { + it('should not rotate label for temporal field by default', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "month" } + } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + chai_1.assert.isUndefined(labels.angle); + }); + it('should do not rotate label for temporal field if labelAngle is specified in axis config', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "month" } + }, + config: { axisX: { labelAngle: 90 } } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + chai_1.assert.isUndefined(labels.angle); + }); + it('should have correct text.signal for quarter timeUnits', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "quarter" } + } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + var expected = "'Q' + quarter(datum.value)"; + chai_1.assert.equal(labels.text.signal, expected); + }); + it('should have correct text.signal for yearquartermonth timeUnits', function () { + var model = util_1.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')"; + chai_1.assert.equal(labels.text.signal, expected); + }); + }); + describe('labelAlign', function () { + it('is left for bottom axis with positive angle', function () { + chai_1.assert.equal(encode_1.labelAlign(90, 'bottom'), 'left'); + chai_1.assert.equal(encode_1.labelAlign(45, 'bottom'), 'left'); + }); + it('is right for bottom axis with negative angle', function () { + chai_1.assert.equal(encode_1.labelAlign(-90, 'bottom'), 'right'); + chai_1.assert.equal(encode_1.labelAlign(-45, 'bottom'), 'right'); + }); + it('is left for top axis with positive angle', function () { + chai_1.assert.equal(encode_1.labelAlign(90, 'top'), 'right'); + chai_1.assert.equal(encode_1.labelAlign(45, 'top'), 'right'); + }); + it('is left for top axis with negative angle', function () { + chai_1.assert.equal(encode_1.labelAlign(-90, 'top'), 'left'); + chai_1.assert.equal(encode_1.labelAlign(-45, 'top'), 'left'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvYXhpcy9lbmNvZGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIseURBQTJEO0FBQzNELDJEQUE0RDtBQUM1RCxtQ0FBbUQ7QUFHbkQsUUFBUSxDQUFDLGNBQWMsRUFBRTtJQUN2QixRQUFRLENBQUMsaUJBQWlCLEVBQUU7UUFDMUIsRUFBRSxDQUFDLHVEQUF1RCxFQUFFO1lBQzFELElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO2dCQUNwQyxJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUM7aUJBQ3JEO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN2RCxhQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5RkFBeUYsRUFBRTtZQUM1RixJQUFNLEtBQUssR0FBRyw4QkFBdUIsQ0FBQztnQkFDcEMsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFDO2lCQUNyRDtnQkFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsRUFBQyxVQUFVLEVBQUUsRUFBRSxFQUFDLEVBQUM7YUFDbEMsQ0FBQyxDQUFDO1lBQ0gsSUFBTSxNQUFNLEdBQUcsTUFB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LENBQUMsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuXG5pbXBvcnQgKiBhcyBlbmNvZGUgZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvYXhpcy9lbmNvZGUnO1xuaW1wb3J0IHtsYWJlbEFsaWdufSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9heGlzL2VuY29kZSc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlfSBmcm9tICcuLi8uLi91dGlsJztcblxuXG5kZXNjcmliZSgnY29tcGlsZS9heGlzJywgKCkgPT4ge1xuICBkZXNjcmliZSgnZW5jb2RlLmxhYmVscygpJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbm90IHJvdGF0ZSBsYWJlbCBmb3IgdGVtcG9yYWwgZmllbGQgYnkgZGVmYXVsdCcsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6IFwiYVwiLCB0eXBlOiBcInRlbXBvcmFsXCIsIHRpbWVVbml0OiBcIm1vbnRoXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgbGFiZWxzID0gZW5jb2RlLmxhYmVscyhtb2RlbCwgJ3gnLCB7fSwgJ2JvdHRvbScpO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKGxhYmVscy5hbmdsZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRvIG5vdCByb3RhdGUgbGFiZWwgZm9yIHRlbXBvcmFsIGZpZWxkIGlmIGxhYmVsQW5nbGUgaXMgc3BlY2lmaWVkIGluIGF4aXMgY29uZmlnJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogXCJhXCIsIHR5cGU6IFwidGVtcG9yYWxcIiwgdGltZVVuaXQ6IFwibW9udGhcIn1cbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlnOiB7YXhpc1g6IHtsYWJlbEFuZ2xlOiA5MH19XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGxhYmVscyA9IGVuY29kZS5sYWJlbHMobW9kZWwsICd4Jywge30sICdib3R0b20nKTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChsYWJlbHMuYW5nbGUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgdGV4dC5zaWduYWwgZm9yIHF1YXJ0ZXIgdGltZVVuaXRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6IFwiYVwiLCB0eXBlOiBcInRlbXBvcmFsXCIsIHRpbWVVbml0OiBcInF1YXJ0ZXJcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBsYWJlbHMgPSBlbmNvZGUubGFiZWxzKG1vZGVsLCAneCcsIHt9LCAnYm90dG9tJyk7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IFwiJ1EnICsgcXVhcnRlcihkYXR1bS52YWx1ZSlcIjtcbiAgICAgIGFzc2VydC5lcXVhbChsYWJlbHMudGV4dC5zaWduYWwsIGV4cGVjdGVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IHRleHQuc2lnbmFsIGZvciB5ZWFycXVhcnRlcm1vbnRoIHRpbWVVbml0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJ0ZW1wb3JhbFwiLCB0aW1lVW5pdDogXCJ5ZWFycXVhcnRlcm1vbnRoXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgbGFiZWxzID0gZW5jb2RlLmxhYmVscyhtb2RlbCwgJ3gnLCB7fSwgJ2JvdHRvbScpO1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBcIidRJyArIHF1YXJ0ZXIoZGF0dW0udmFsdWUpICsgJyAnICsgdGltZUZvcm1hdChkYXR1bS52YWx1ZSwgJyViICVZJylcIjtcbiAgICAgIGFzc2VydC5lcXVhbChsYWJlbHMudGV4dC5zaWduYWwsIGV4cGVjdGVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2xhYmVsQWxpZ24nLCAoKSA9PiB7XG4gICAgaXQoJ2lzIGxlZnQgZm9yIGJvdHRvbSBheGlzIHdpdGggcG9zaXRpdmUgYW5nbGUnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwobGFiZWxBbGlnbig5MCwgJ2JvdHRvbScpLCAnbGVmdCcpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGxhYmVsQWxpZ24oNDUsICdib3R0b20nKSwgJ2xlZnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdpcyByaWdodCBmb3IgYm90dG9tIGF4aXMgd2l0aCBuZWdhdGl2ZSBhbmdsZScsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChsYWJlbEFsaWduKC05MCwgJ2JvdHRvbScpLCAncmlnaHQnKTtcbiAgICAgIGFzc2VydC5lcXVhbChsYWJlbEFsaWduKC00NSwgJ2JvdHRvbScpLCAncmlnaHQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdpcyBsZWZ0IGZvciB0b3AgYXhpcyB3aXRoIHBvc2l0aXZlIGFuZ2xlJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKGxhYmVsQWxpZ24oOTAsICd0b3AnKSwgJ3JpZ2h0Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwobGFiZWxBbGlnbig0NSwgJ3RvcCcpLCAncmlnaHQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdpcyBsZWZ0IGZvciB0b3AgYXhpcyB3aXRoIG5lZ2F0aXZlIGFuZ2xlJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKGxhYmVsQWxpZ24oLTkwLCAndG9wJyksICdsZWZ0Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwobGFiZWxBbGlnbigtNDUsICd0b3AnKSwgJ2xlZnQnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/axis/parse.test.js b/build/test/compile/axis/parse.test.js new file mode 100644 index 0000000000..b4343aa136 --- /dev/null +++ b/build/test/compile/axis/parse.test.js @@ -0,0 +1,204 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var parse_1 = require("../../../src/compile/axis/parse"); +var util_1 = require("../../util"); +describe('Axis', function () { + // TODO: move this to model.test.ts + describe('= true', function () { + it('should produce default properties for axis', function () { + var model1 = util_1.parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "data": { "url": "data/movies.json" } + }); + var model2 = util_1.parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "data": { "url": "data/movies.json" } + }); + chai_1.assert.deepEqual(model1.axis(channel_1.Y), model2.axis(channel_1.Y)); + }); + }); + describe('parseUnitAxis', function () { + it('should produce Vega grid axis objects for both main axis and for grid axis)', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: true, gridColor: "blue", gridWidth: 20 } + } + } + }); + var axisComponent = parse_1.parseUnitAxis(model); + chai_1.assert.equal(axisComponent['x'].length, 1); + chai_1.assert.equal(axisComponent['x'][0].main.implicit.grid, undefined); + chai_1.assert.equal(axisComponent['x'][0].grid.explicit.grid, true); + }); + it('should produce Vega grid axis objects for only main axis if grid is disabled)', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: false, gridColor: "blue", gridWidth: 20 } + } + } + }); + var axisComponent = parse_1.parseUnitAxis(model); + chai_1.assert.equal(axisComponent['x'].length, 1); + chai_1.assert.equal(axisComponent['x'][0].main.explicit.grid, undefined); + }); + it('should produce Vega grid axis objects for only main axis if grid is disabled via config.axisX)', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative" + } + }, + config: { axisX: { grid: false } } + }); + var axisComponent = parse_1.parseUnitAxis(model); + chai_1.assert.equal(axisComponent['x'].length, 1); + chai_1.assert.equal(axisComponent['x'][0].main.explicit.grid, undefined); + }); + it('should produce Vega grid axis objects for only main axis if grid is disabled via config.axis)', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative" + } + }, + config: { axis: { grid: false } } + }); + var axisComponent = parse_1.parseUnitAxis(model); + chai_1.assert.equal(axisComponent['x'].length, 1); + chai_1.assert.equal(axisComponent['x'][0].main.explicit.grid, undefined); + }); + }); + describe('parseLayerAxis', function () { + var globalRuleOverlay = util_1.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(); + parse_1.parseLayerAxis(globalRuleOverlay); + it('correctly merges gridScale if one layer does not have one of the axis', function () { + var axisComponents = globalRuleOverlay.component.axes; + chai_1.assert.equal(axisComponents.y.length, 1); + chai_1.assert.equal(axisComponents.y[0].grid.get('gridScale'), 'x'); + }); + it('correctly merges similar title', function () { + var axisComponents = globalRuleOverlay.component.axes; + chai_1.assert.equal(axisComponents.y[0].main.get('title'), 'Mean of a'); + }); + it('correctly combines different title', function () { + var model = util_1.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(); + parse_1.parseLayerAxis(model); + var axisComponents = model.component.axes; + chai_1.assert.equal(axisComponents.y[0].main.get('title'), 'Max of Horsepower, Min of Horsepower'); + }); + }); + describe('parseGridAxis', function () { + it('should produce a Vega grid axis object with correct type, scale and grid properties', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: true } + } + } + }); + var def = parse_1.parseGridAxis(channel_1.X, model); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.implicit.orient, 'bottom'); + chai_1.assert.equal(def.implicit.scale, 'x'); + }); + }); + describe('parseMainAxis', function () { + it('should produce a Vega axis object with correct type and scale', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "quantitative" } + } + }); + var def = parse_1.parseMainAxis(channel_1.X, model); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.implicit.orient, 'bottom'); + chai_1.assert.equal(def.implicit.scale, 'x'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9heGlzL3BhcnNlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLGdEQUEwQztBQUMxQyx5REFBNEc7QUFDNUcsbUNBQW9FO0FBRXBFLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixtQ0FBbUM7SUFDbkMsUUFBUSxDQUFDLFFBQVEsRUFBRTtRQUNqQixFQUFFLENBQUMsNENBQTRDLEVBQUU7WUFDL0MsSUFBTSxNQUFNLEdBQUcsOEJBQXVCLENBQUM7Z0JBQ3JDLE1BQU0sRUFBRSxLQUFLO2dCQUNiLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBQztpQkFDdkU7Z0JBQ0QsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDO2FBQ3BDLENBQUMsQ0FBQztZQUVILElBQU0sTUFBTSxHQUFHLDhCQUF1QixDQUFDO2dCQUNyQyxNQUFNLEVBQUUsS0FBSztnQkFDYixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUM7aUJBQ3ZFO2dCQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQzthQUNwQyxDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDSCxRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVB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Q0FBQztZQUNyQixhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzVDLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFDLCtEQUErRCxFQUFFO1lBQ2xFLElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO2dCQUNwQyxJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsQ0FBQztZQUNILElBQU0sR0FBRyxHQUFHLHFCQUFhLENBQUMsV0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BDLGFBQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUM1QyxhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge1gsIFl9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7cGFyc2VHcmlkQXhpcywgcGFyc2VMYXllckF4aXMsIHBhcnNlTWFpbkF4aXMsIHBhcnNlVW5pdEF4aXN9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2F4aXMvcGFyc2UnO1xuaW1wb3J0IHtwYXJzZUxheWVyTW9kZWwsIHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ0F4aXMnLCBmdW5jdGlvbigpIHtcbiAgLy8gVE9ETzogbW92ZSB0aGlzIHRvIG1vZGVsLnRlc3QudHNcbiAgZGVzY3JpYmUoJz0gdHJ1ZScsIGZ1bmN0aW9uKCkge1xuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBkZWZhdWx0IHByb3BlcnRpZXMgZm9yIGF4aXMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsMSA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogJ1VTX0dyb3NzJywgXCJhZ2dyZWdhdGVcIjogXCJzdW1cIn1cbiAgICAgICAgfSxcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvbW92aWVzLmpzb25cIn1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBtb2RlbDIgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdVU19Hcm9zcycsIFwiYWdncmVnYXRlXCI6IFwic3VtXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL21vdmllcy5qc29uXCJ9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwxLmF4aXMoWSksIG1vZGVsMi5heGlzKFkpKTtcbiAgICB9KTtcbiAgfSk7XG4gIGRlc2NyaWJlKCdwYXJzZVVuaXRBeGlzJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIFZlZ2EgZ3JpZCBheGlzIG9iamVjdHMgZm9yIGJvdGggbWFpbiBheGlzIGFuZCBmb3IgZ3JpZCBheGlzKScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7XG4gICAgICAgICAgICBmaWVsZDogXCJhXCIsXG4gICAgICAgICAgICB0eXBlOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgYXhpczoge2dyaWQ6IHRydWUsIGdyaWRDb2xvcjogXCJibHVlXCIsIGdyaWRXaWR0aDogMjB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGF4aXNDb21wb25lbnQgPSBwYXJzZVVuaXRBeGlzKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J10ubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J11bMF0ubWFpbi5pbXBsaWNpdC5ncmlkLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGF4aXNDb21wb25lbnRbJ3gnXVswXS5ncmlkLmV4cGxpY2l0LmdyaWQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIFZlZ2EgZ3JpZCBheGlzIG9iamVjdHMgZm9yIG9ubHkgbWFpbiBheGlzIGlmIGdyaWQgaXMgZGlzYWJsZWQpJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcImFcIixcbiAgICAgICAgICAgIHR5cGU6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICBheGlzOiB7Z3JpZDogZmFsc2UsIGdyaWRDb2xvcjogXCJibHVlXCIsIGdyaWRXaWR0aDogMjB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGF4aXNDb21wb25lbnQgPSBwYXJzZVVuaXRBeGlzKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J10ubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J11bMF0ubWFpbi5leHBsaWNpdC5ncmlkLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIFZlZ2EgZ3JpZCBheGlzIG9iamVjdHMgZm9yIG9ubHkgbWFpbiBheGlzIGlmIGdyaWQgaXMgZGlzYWJsZWQgdmlhIGNvbmZpZy5heGlzWCknLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge1xuICAgICAgICAgICAgZmllbGQ6IFwiYVwiLFxuICAgICAgICAgICAgdHlwZTogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlnOiB7YXhpc1g6IHtncmlkOiBmYWxzZX19XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGF4aXNDb21wb25lbnQgPSBwYXJzZVVuaXRBeGlzKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J10ubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J11bMF0ubWFpbi5leHBsaWNpdC5ncmlkLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgVmVnYSBncmlkIGF4aXMgb2JqZWN0cyBmb3Igb25seSBtYWluIGF4aXMgaWYgZ3JpZCBpcyBkaXNhYmxlZCB2aWEgY29uZmlnLmF4aXMpJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcImFcIixcbiAgICAgICAgICAgIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZzoge2F4aXM6IHtncmlkOiBmYWxzZX19XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGF4aXNDb21wb25lbnQgPSBwYXJzZVVuaXRBeGlzKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J10ubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50Wyd4J11bMF0ubWFpbi5leHBsaWNpdC5ncmlkLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2VMYXllckF4aXMnLCAoKSA9PiB7XG4gICAgY29uc3QgZ2xvYmFsUnVsZU92ZXJsYXkgPSBwYXJzZUxheWVyTW9kZWwoe1xuICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImFcIixcbiAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImFcIixcbiAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICBcInRpbWVVbml0XCI6IFwibW9udGhcIixcbiAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwidGVtcG9yYWxcIixcbiAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImRhdGVcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pO1xuICAgIGdsb2JhbFJ1bGVPdmVybGF5LnBhcnNlU2NhbGUoKTtcbiAgICBnbG9iYWxSdWxlT3ZlcmxheS5wYXJzZUxheW91dFNpemUoKTtcbiAgICBwYXJzZUxheWVyQXhpcyhnbG9iYWxSdWxlT3ZlcmxheSk7XG5cblxuICAgIGl0KCdjb3JyZWN0bHkgbWVyZ2VzIGdyaWRTY2FsZSBpZiBvbmUgbGF5ZXIgZG9lcyBub3QgaGF2ZSBvbmUgb2YgdGhlIGF4aXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBheGlzQ29tcG9uZW50cyA9IGdsb2JhbFJ1bGVPdmVybGF5LmNvbXBvbmVudC5heGVzO1xuICAgICAgYXNzZXJ0LmVxdWFsKGF4aXNDb21wb25lbnRzLnkubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzQ29tcG9uZW50cy55WzBdLmdyaWQuZ2V0KCdncmlkU2NhbGUnKSwgJ3gnKTtcbiAgICB9KTtcblxuICAgIGl0KCdjb3JyZWN0bHkgbWVyZ2VzIHNpbWlsYXIgdGl0bGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBheGlzQ29tcG9uZW50cyA9IGdsb2JhbFJ1bGVPdmVybGF5LmNvbXBvbmVudC5heGVzO1xuICAgICAgYXNzZXJ0LmVxdWFsKGF4aXNDb21wb25lbnRzLnlbMF0ubWFpbi5nZXQoJ3RpdGxlJyksICdNZWFuIG9mIGEnKTtcbiAgICB9KTtcblxuICAgIGl0KCdjb3JyZWN0bHkgY29tYmluZXMgZGlmZmVyZW50IHRpdGxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUxheWVyTW9kZWwoe1xuICAgICAgICBcIiRzY2hlbWFcIjogXCJodHRwczovL3ZlZ2EuZ2l0aHViLmlvL3NjaGVtYS92ZWdhLWxpdGUvdjIuanNvblwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9jYXJzLmpzb25cIn0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJDeWxpbmRlcnNcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWF4XCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwiZGFya3JlZFwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvY2Fycy5qc29uXCJ9LFxuICAgICAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkN5bGluZGVyc1wiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICAgICAgcGFyc2VMYXllckF4aXMobW9kZWwpO1xuICAgICAgY29uc3QgYXhpc0NvbXBvbmVudHMgPSBtb2RlbC5jb21wb25lbnQuYXhlcztcblxuICAgICAgYXNzZXJ0LmVxdWFsKGF4aXNDb21wb25lbnRzLnlbMF0ubWFpbi5nZXQoJ3RpdGxlJyksICdNYXggb2YgSG9yc2Vwb3dlciwgTWluIG9mIEhvcnNlcG93ZXInKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3BhcnNlR3JpZEF4aXMnLCBmdW5jdGlvbigpIHtcbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSBWZWdhIGdyaWQgYXhpcyBvYmplY3Qgd2l0aCBjb3JyZWN0IHR5cGUsIHNjYWxlIGFuZCBncmlkIHByb3BlcnRpZXMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge1xuICAgICAgICAgICAgZmllbGQ6IFwiYVwiLFxuICAgICAgICAgICAgdHlwZTogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIGF4aXM6IHtncmlkOiB0cnVlfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBkZWYgPSBwYXJzZUdyaWRBeGlzKFgsIG1vZGVsKTtcbiAgICAgIGFzc2VydC5pc09iamVjdChkZWYpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRlZi5pbXBsaWNpdC5vcmllbnQsICdib3R0b20nKTtcbiAgICAgIGFzc2VydC5lcXVhbChkZWYuaW1wbGljaXQuc2NhbGUsICd4Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXJzZU1haW5BeGlzJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGEgVmVnYSBheGlzIG9iamVjdCB3aXRoIGNvcnJlY3QgdHlwZSBhbmQgc2NhbGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBkZWYgPSBwYXJzZU1haW5BeGlzKFgsIG1vZGVsKTtcbiAgICAgIGFzc2VydC5pc09iamVjdChkZWYpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRlZi5pbXBsaWNpdC5vcmllbnQsICdib3R0b20nKTtcbiAgICAgIGFzc2VydC5lcXVhbChkZWYuaW1wbGljaXQuc2NhbGUsICd4Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/axis/properties.test.js b/build/test/compile/axis/properties.test.js new file mode 100644 index 0000000000..a556c7f38f --- /dev/null +++ b/build/test/compile/axis/properties.test.js @@ -0,0 +1,105 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var properties = require("../../../src/compile/axis/properties"); +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' }); + chai_1.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' }); + chai_1.assert.deepEqual(grid, false); + }); + it('should return false by default for a discrete scale', function () { + var grid = properties.grid('point', { field: 'a', type: 'quantitative' }); + chai_1.assert.deepEqual(grid, false); + }); + }); + describe('minMaxExtent', function () { + it('returns specified extent for a non-grid axis', function () { + chai_1.assert.equal(properties.minMaxExtent(25, false), 25); + }); + it('returns 0 for a grid axis', function () { + chai_1.assert.equal(properties.minMaxExtent(0, true), 0); + }); + }); + describe('orient()', function () { + it('should return bottom for x by default', function () { + var orient = properties.orient('x'); + chai_1.assert.deepEqual(orient, 'bottom'); + }); + it('should return left for y by default', function () { + var orient = properties.orient('y'); + chai_1.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' }); + chai_1.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' }); + chai_1.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' }); + chai_1.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); + chai_1.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); + chai_1.assert.deepEqual(tickCount, undefined); + }); + }); + describe('title()', function () { + it('should add return fieldTitle by default', function () { + var title = properties.title(3, { field: 'a', type: "quantitative" }, {}); + chai_1.assert.deepEqual(title, 'a'); + }); + it('should add return fieldTitle by default', function () { + var title = properties.title(10, { aggregate: 'sum', field: 'a', type: "quantitative" }, {}); + chai_1.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" }, {}); + chai_1.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, null); + chai_1.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, null); + chai_1.assert.deepEqual(values, [1, 2, 3, 4]); + }); + }); + describe('zindex()', function () { + it('should return undefined by default without grid defined', function () { + var zindex = properties.zindex(false); + chai_1.assert.deepEqual(zindex, 1); + }); + it('should return back by default with grid defined', function () { + var zindex = properties.zindex(true); + chai_1.assert.deepEqual(zindex, 0); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2F4aXMvcHJvcGVydGllcy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixpRUFBbUU7QUFHbkUsUUFBUSxDQUFDLGNBQWMsRUFBRTtJQUN2QixRQUFRLENBQUMsUUFBUSxFQUFFO1FBQ2pCLEVBQUUsQ0FBQyx1RUFBdUUsRUFBRTtZQUMxRSxJQUFNLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLENBQUM7WUFDM0UsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUU7WUFDcEQsSUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLENBQUM7WUFDdEYsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUU7WUFDeEQsSUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsQ0FBQyxDQUFDO1lBQzFFLGFBQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFR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QUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hDLGFBQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlEQUFpRCxFQUFFO1lBQ3BELElBQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0ICogYXMgcHJvcGVydGllcyBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9heGlzL3Byb3BlcnRpZXMnO1xuaW1wb3J0IHtUaW1lVW5pdH0gZnJvbSAnLi4vLi4vLi4vc3JjL3RpbWV1bml0JztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvYXhpcycsICgpPT4ge1xuICBkZXNjcmliZSgnZ3JpZCgpJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgYnkgZGVmYXVsdCBmb3IgY29udGludW91cyBzY2FsZSB0aGF0IGlzIG5vdCBiaW5uZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBncmlkID0gcHJvcGVydGllcy5ncmlkKCdsaW5lYXInLCB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZ3JpZCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBieSBkZWZhdWx0IGZvciBiaW5uZWQgZmllbGQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBncmlkID0gcHJvcGVydGllcy5ncmlkKCdsaW5lYXInLCB7YmluOiB0cnVlLCBmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChncmlkLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBieSBkZWZhdWx0IGZvciBhIGRpc2NyZXRlIHNjYWxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZ3JpZCA9IHByb3BlcnRpZXMuZ3JpZCgncG9pbnQnLCB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZ3JpZCwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbWluTWF4RXh0ZW50JywgKCkgPT4ge1xuICAgIGl0KCdyZXR1cm5zIHNwZWNpZmllZCBleHRlbnQgZm9yIGEgbm9uLWdyaWQgYXhpcycsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChwcm9wZXJ0aWVzLm1pbk1heEV4dGVudCgyNSwgZmFsc2UpLCAyNSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyAwIGZvciBhIGdyaWQgYXhpcycsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChwcm9wZXJ0aWVzLm1pbk1heEV4dGVudCgwLCB0cnVlKSwgMCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdvcmllbnQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBib3R0b20gZm9yIHggYnkgZGVmYXVsdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG9yaWVudCA9IHByb3BlcnRpZXMub3JpZW50KCd4Jyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKG9yaWVudCwgJ2JvdHRvbScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbGVmdCBmb3IgeSBieSBkZWZhdWx0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3JpZW50ID0gcHJvcGVydGllcy5vcmllbnQoJ3knKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwob3JpZW50LCAnbGVmdCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndGlja0NvdW50JywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdW5kZWZpbmVkIGJ5IGRlZmF1bHQgZm9yIGEgYmlubmVkIGZpZWxkJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGlja0NvdW50ID0gcHJvcGVydGllcy50aWNrQ291bnQoJ3gnLCB7YmluOiB7bWF4YmluczogMTB9LCBmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sICdsaW5lYXInLCB7c2lnbmFsIDogJ2EnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHRpY2tDb3VudCwge3NpZ25hbDogJ2NlaWwoYS8yMCknfSk7XG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IHRpbWVVbml0IG9mIFsnbW9udGgnLCAnaG91cnMnLCAnZGF5JywgJ3F1YXJ0ZXInXSBhcyBUaW1lVW5pdFtdKSB7XG4gICAgICAgIGl0KGBzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBieSBkZWZhdWx0IGZvciBhIHRlbXBvcmFsIGZpZWxkIHdpdGggdGltZVVuaXQ9JHt0aW1lVW5pdH1gLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgdGlja0NvdW50ID0gcHJvcGVydGllcy50aWNrQ291bnQoJ3gnLCB7dGltZVVuaXQsIGZpZWxkOiAnYScsIHR5cGU6ICd0ZW1wb3JhbCd9LCAnbGluZWFyJywge3NpZ25hbCA6ICdhJ30pO1xuICAgICAgICAgIGFzc2VydC5pc1VuZGVmaW5lZCh0aWNrQ291bnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzaXplLzQwIGJ5IGRlZmF1bHQgZm9yIGxpbmVhciBzY2FsZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHRpY2tDb3VudCA9IHByb3BlcnRpZXMudGlja0NvdW50KCd4Jywge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwgJ2xpbmVhcicsIHtzaWduYWwgOiAnYSd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodGlja0NvdW50LCB7c2lnbmFsOiAnY2VpbChhLzQwKSd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBieSBkZWZhdWx0IGZvciBsb2cgc2NhbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0aWNrQ291bnQgPSBwcm9wZXJ0aWVzLnRpY2tDb3VudCgneCcsIHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sICdsb2cnLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh0aWNrQ291bnQsIHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB1bmRlZmluZWQgYnkgZGVmYXVsdCBmb3IgcG9pbnQgc2NhbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0aWNrQ291bnQgPSBwcm9wZXJ0aWVzLnRpY2tDb3VudCgneCcsIHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sICdwb2ludCcsIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHRpY2tDb3VudCwgdW5kZWZpbmVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3RpdGxlKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBhZGQgcmV0dXJuIGZpZWxkVGl0bGUgYnkgZGVmYXVsdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRpdGxlID0gcHJvcGVydGllcy50aXRsZSgzLCB7ZmllbGQ6ICdhJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIn0sIHt9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodGl0bGUsICdhJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCByZXR1cm4gZmllbGRUaXRsZSBieSBkZWZhdWx0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGl0bGUgPSBwcm9wZXJ0aWVzLnRpdGxlKDEwLCB7YWdncmVnYXRlOiAnc3VtJywgZmllbGQ6ICdhJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIn0sIHt9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodGl0bGUsICdTdW0gb2YgYScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhZGQgcmV0dXJuIGZpZWxkVGl0bGUgYnkgZGVmYXVsdCBhbmQgdHJ1bmNhdGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0aXRsZSA9IHByb3BlcnRpZXMudGl0bGUoMywge2FnZ3JlZ2F0ZTogJ3N1bScsIGZpZWxkOiAnYScsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9LCB7fSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHRpdGxlLCAnU3XigKYnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZhbHVlcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IHRpbWVzdGFtcCB2YWx1ZXMgZm9yIERhdGVUaW1lcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlcyA9IHByb3BlcnRpZXMudmFsdWVzKHt2YWx1ZXM6IFt7eWVhcjogMTk3MH0sIHt5ZWFyOiAxOTgwfV19LCBudWxsLCBudWxsKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh2YWx1ZXMsIFtcbiAgICAgICAge1wic2lnbmFsXCI6IFwiZGF0ZXRpbWUoMTk3MCwgMCwgMSwgMCwgMCwgMCwgMClcIn0sXG4gICAgICAgIHtcInNpZ25hbFwiOiBcImRhdGV0aW1lKDE5ODAsIDAsIDEsIDAsIDAsIDAsIDApXCJ9XG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2ltcGx5IHJldHVybiB2YWx1ZXMgZm9yIG5vbi1EYXRlVGltZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlcyA9IHByb3BlcnRpZXMudmFsdWVzKHt2YWx1ZXM6IFsxLDIsMyw0XX0sIG51bGwsIG51bGwpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHZhbHVlcywgWzEsMiwzLDRdKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ppbmRleCgpJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBieSBkZWZhdWx0IHdpdGhvdXQgZ3JpZCBkZWZpbmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgemluZGV4ID0gcHJvcGVydGllcy56aW5kZXgoZmFsc2UpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh6aW5kZXgsIDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYmFjayBieSBkZWZhdWx0IHdpdGggZ3JpZCBkZWZpbmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgemluZGV4ID0gcHJvcGVydGllcy56aW5kZXgodHJ1ZSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHppbmRleCwgMCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/common.test.js b/build/test/compile/common.test.js new file mode 100644 index 0000000000..816eb99983 --- /dev/null +++ b/build/test/compile/common.test.js @@ -0,0 +1,63 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var common_1 = require("../../src/compile/common"); +var config_1 = require("../../src/config"); +var fielddef_1 = require("../../src/fielddef"); +var timeunit_1 = require("../../src/timeunit"); +var type_1 = require("../../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_1.TimeUnit.MONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { expr: 'datum' }), timeunit_1.TimeUnit.MONTH, undefined, true, config_1.defaultConfig.timeFormat, false); + chai_1.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_1.TimeUnit.MONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { expr: 'datum' }), timeunit_1.TimeUnit.MONTH, undefined, false, config_1.defaultConfig.timeFormat, false); + chai_1.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_1.TimeUnit.YEARMONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { expr: 'datum' }), timeunit_1.TimeUnit.MONTH, '%Y', true, config_1.defaultConfig.timeFormat, false); + chai_1.assert.equal(expression, "timeFormat(datum[\"yearmonth_a\"], '%Y')"); + }); + it('should get the right time expression for quarter', function () { + var fieldDef = { timeUnit: timeunit_1.TimeUnit.QUARTER, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { expr: 'datum' }), timeunit_1.TimeUnit.QUARTER, undefined, true, config_1.defaultConfig.timeFormat, false); + chai_1.assert.equal(expression, "'Q' + quarter(datum[\"quarter_a\"])"); + }); + it('should get the right time expression for yearquarter', function () { + var expression = common_1.timeFormatExpression('datum["data"]', timeunit_1.TimeUnit.YEARQUARTER, undefined, true, config_1.defaultConfig.timeFormat, false); + chai_1.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_1.TimeUnit.YEARMONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { expr: 'datum' }), timeunit_1.TimeUnit.MONTH, '%Y', true, config_1.defaultConfig.timeFormat, true); + chai_1.assert.equal(expression, "utcFormat(datum[\"yearmonth_a\"], '%Y')"); + }); + }); + describe('numberFormat()', function () { + it('should use number format for quantitative scale', function () { + chai_1.assert.equal(common_1.numberFormat({ field: 'a', type: type_1.QUANTITATIVE }, undefined, { numberFormat: 'd' }), 'd'); + }); + it('should support empty number format', function () { + chai_1.assert.equal(common_1.numberFormat({ field: 'a', type: type_1.QUANTITATIVE }, undefined, { numberFormat: '' }), ''); + }); + it('should use format if provided', function () { + chai_1.assert.equal(common_1.numberFormat({ field: 'a', type: type_1.QUANTITATIVE }, 'a', {}), 'a'); + }); + it('should not use number format for binned quantitative scale', function () { + chai_1.assert.equal(common_1.numberFormat({ bin: true, field: 'a', type: type_1.QUANTITATIVE }, undefined, {}), undefined); + }); + it('should not use number format for non-quantitative scale', function () { + for (var _i = 0, _a = [type_1.TEMPORAL, type_1.NOMINAL, type_1.ORDINAL]; _i < _a.length; _i++) { + var type = _a[_i]; + chai_1.assert.equal(common_1.numberFormat({ bin: true, field: 'a', type: type }, undefined, {}), undefined); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2NvbXBpbGUvY29tbW9uLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLG1EQUE0RTtBQUM1RSwyQ0FBK0M7QUFDL0MsK0NBQXlDO0FBQ3pDLCtDQUE0QztBQUM1Qyx1Q0FBd0U7QUFFeEUsUUFBUSxDQUFDLFFBQVEsRUFBRTtJQUNqQixRQUFRLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQywwRUFBMEUsRUFBRTtZQUM3RSxJQUFNLFFBQVEsR0FBRyxFQUFDLFFBQVEsRUFBRSxtQkFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxlQUFRLEVBQUMsQ0FBQztZQUN4RSxJQUFNLFVBQVUsR0FBRyw2QkFBb0IsQ0FBQyxnQkFBSyxDQUFDLFFBQVEsRUFBRSxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUMsQ0FBQyxFQUFFLG1CQUFRLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsc0JBQWEsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDNUksYUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsc0NBQW9DLENBQUMsQ0FBQztRQUNqRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyRUFBMkUsRUFBRTtZQUM5RSxJQUFNLFFBQVEsR0FBRyxFQUFDLFFBQVEsRUFBRSxtQkFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxlQUFRLEVBQUMsQ0FBQztZQUN4RSxJQUFNLFVBQVUsR0FBRyw2QkFBb0IsQ0FBQyxnQkFBSyxDQUFDLFFBQVEsRUFBRSxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUMsQ0FBQyxFQUFFLG1CQUFRLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUs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UyxFQUFFLEVBQUMsWUFBWSxFQUFFLEVBQUUsRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0JBQStCLEVBQUU7WUFDbEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBWSxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsbUJBQVksRUFBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM3RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRTtZQUMvRCxhQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFZLENBQUMsRUFBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLG1CQUFZLEVBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDcEcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseURBQXlELEVBQUU7WUFDNUQsR0FBRyxDQUFDLENBQWUsVUFBNEIsRUFBNUIsTUFBQyxlQUFRLEVBQUUsY0FBTyxFQUFFLGNBQU8sQ0FBQyxFQUE1QixjQUE0QixFQUE1QixJQUE0QjtnQkFBMUMsSUFBTSxJQUFJLFNBQUE7Z0JBQ2IsYUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBWSxDQUFDLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDM0Y7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtudW1iZXJGb3JtYXQsIHRpbWVGb3JtYXRFeHByZXNzaW9ufSBmcm9tICcuLi8uLi9zcmMvY29tcGlsZS9jb21tb24nO1xuaW1wb3J0IHtkZWZhdWx0Q29uZmlnfSBmcm9tICcuLi8uLi9zcmMvY29uZmlnJztcbmltcG9ydCB7ZmllbGR9IGZyb20gJy4uLy4uL3NyYy9maWVsZGRlZic7XG5pbXBvcnQge1RpbWVVbml0fSBmcm9tICcuLi8uLi9zcmMvdGltZXVuaXQnO1xuaW1wb3J0IHtOT01JTkFMLCBPUkRJTkFMLCBRVUFOVElUQVRJVkUsIFRFTVBPUkFMfSBmcm9tICcuLi8uLi9zcmMvdHlwZSc7XG5cbmRlc2NyaWJlKCdDb21tb24nLCBmdW5jdGlvbigpIHtcbiAgZGVzY3JpYmUoJ3RpbWVGb3JtYXQoKScsIGZ1bmN0aW9uKCkge1xuICAgIGl0KCdzaG91bGQgZ2V0IHRoZSByaWdodCB0aW1lIGV4cHJlc3Npb24gZm9yIG1vbnRoIHdpdGggc2hvcnRUaW1lTGFiZWxzPXRydWUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGZpZWxkRGVmID0ge3RpbWVVbml0OiBUaW1lVW5pdC5NT05USCwgZmllbGQ6ICdhJywgdHlwZTogVEVNUE9SQUx9O1xuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRpbWVGb3JtYXRFeHByZXNzaW9uKGZpZWxkKGZpZWxkRGVmLCB7ZXhwcjogJ2RhdHVtJ30pLCBUaW1lVW5pdC5NT05USCwgdW5kZWZpbmVkLCB0cnVlLCBkZWZhdWx0Q29uZmlnLnRpbWVGb3JtYXQsIGZhbHNlKTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uLCBgdGltZUZvcm1hdChkYXR1bVtcIm1vbnRoX2FcIl0sICclYicpYCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgcmlnaHQgdGltZSBleHByZXNzaW9uIGZvciBtb250aCB3aXRoIHNob3J0VGltZUxhYmVscz1mYWxzZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgZmllbGREZWYgPSB7dGltZVVuaXQ6IFRpbWVVbml0Lk1PTlRILCBmaWVsZDogJ2EnLCB0eXBlOiBURU1QT1JBTH07XG4gICAgICBjb25zdCBleHByZXNzaW9uID0gdGltZUZvcm1hdEV4cHJlc3Npb24oZmllbGQoZmllbGREZWYsIHtleHByOiAnZGF0dW0nfSksIFRpbWVVbml0Lk1PTlRILCB1bmRlZmluZWQsIGZhbHNlLCBkZWZhdWx0Q29uZmlnLnRpbWVGb3JtYXQsIGZhbHNlKTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uLCBgdGltZUZvcm1hdChkYXR1bVtcIm1vbnRoX2FcIl0sICclQicpYCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgcmlnaHQgdGltZSBleHByZXNzaW9uIGZvciB5ZWFybW9udGggd2l0aCBjdXN0b20gZm9ybWF0JywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IHt0aW1lVW5pdDogVGltZVVuaXQuWUVBUk1PTlRILCBmaWVsZDogJ2EnLCB0eXBlOiBURU1QT1JBTH07XG4gICAgICBjb25zdCBleHByZXNzaW9uID0gdGltZUZvcm1hdEV4cHJlc3Npb24oZmllbGQoZmllbGREZWYsIHtleHByOiAnZGF0dW0nfSksIFRpbWVVbml0Lk1PTlRILCAnJVknLCB0cnVlLCBkZWZhdWx0Q29uZmlnLnRpbWVGb3JtYXQsIGZhbHNlKTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uLCBgdGltZUZvcm1hdChkYXR1bVtcInllYXJtb250aF9hXCJdLCAnJVknKWApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgdGhlIHJpZ2h0IHRpbWUgZXhwcmVzc2lvbiBmb3IgcXVhcnRlcicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgZmllbGREZWYgPSB7dGltZVVuaXQ6IFRpbWVVbml0LlFVQVJURVIsIGZpZWxkOiAnYScsIHR5cGU6IFRFTVBPUkFMfTtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aW1lRm9ybWF0RXhwcmVzc2lvbihmaWVsZChmaWVsZERlZiwge2V4cHI6ICdkYXR1bSd9KSwgVGltZVVuaXQuUVVBUlRFUiwgdW5kZWZpbmVkLCB0cnVlLCBkZWZhdWx0Q29uZmlnLnRpbWVGb3JtYXQsIGZhbHNlKTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uLCBgJ1EnICsgcXVhcnRlcihkYXR1bVtcInF1YXJ0ZXJfYVwiXSlgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IHRoZSByaWdodCB0aW1lIGV4cHJlc3Npb24gZm9yIHllYXJxdWFydGVyJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBleHByZXNzaW9uID0gdGltZUZvcm1hdEV4cHJlc3Npb24oJ2RhdHVtW1wiZGF0YVwiXScsIFRpbWVVbml0LllFQVJRVUFSVEVSLCB1bmRlZmluZWQsIHRydWUsIGRlZmF1bHRDb25maWcudGltZUZvcm1hdCwgZmFsc2UpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHJlc3Npb24sIGAnUScgKyBxdWFydGVyKGRhdHVtW1wiZGF0YVwiXSkgKyAnICcgKyB0aW1lRm9ybWF0KGRhdHVtW1wiZGF0YVwiXSwgJyV5JylgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IHRoZSByaWdodCB0aW1lIGV4cHJlc3Npb24gZm9yIHllYXJtb250aCB3aXRoIGN1c3RvbSBmb3JtYXQgYW5kIHV0YyBzY2FsZSB0eXBlJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IHt0aW1lVW5pdDogVGltZVVuaXQuWUVBUk1PTlRILCBmaWVsZDogJ2EnLCB0eXBlOiBURU1QT1JBTH07XG4gICAgICBjb25zdCBleHByZXNzaW9uID0gdGltZUZvcm1hdEV4cHJlc3Npb24oZmllbGQoZmllbGREZWYsIHtleHByOiAnZGF0dW0nfSksIFRpbWVVbml0Lk1PTlRILCAnJVknLCB0cnVlLCBkZWZhdWx0Q29uZmlnLnRpbWVGb3JtYXQsIHRydWUpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHJlc3Npb24sIGB1dGNGb3JtYXQoZGF0dW1bXCJ5ZWFybW9udGhfYVwiXSwgJyVZJylgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ251bWJlckZvcm1hdCgpJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCB1c2UgbnVtYmVyIGZvcm1hdCBmb3IgcXVhbnRpdGF0aXZlIHNjYWxlJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZXF1YWwobnVtYmVyRm9ybWF0KHtmaWVsZDogJ2EnLCB0eXBlOiBRVUFOVElUQVRJVkV9LCB1bmRlZmluZWQsIHtudW1iZXJGb3JtYXQ6ICdkJ30pLCAnZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdXBwb3J0IGVtcHR5IG51bWJlciBmb3JtYXQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5lcXVhbChudW1iZXJGb3JtYXQoe2ZpZWxkOiAnYScsIHR5cGU6IFFVQU5USVRBVElWRX0sIHVuZGVmaW5lZCwge251bWJlckZvcm1hdDogJyd9KSwgJycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgZm9ybWF0IGlmIHByb3ZpZGVkJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZXF1YWwobnVtYmVyRm9ybWF0KHtmaWVsZDogJ2EnLCB0eXBlOiBRVUFOVElUQVRJVkV9LCAnYScsIHt9KSwgJ2EnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHVzZSBudW1iZXIgZm9ybWF0IGZvciBiaW5uZWQgcXVhbnRpdGF0aXZlIHNjYWxlJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZXF1YWwobnVtYmVyRm9ybWF0KHtiaW46IHRydWUsIGZpZWxkOiAnYScsIHR5cGU6IFFVQU5USVRBVElWRX0sIHVuZGVmaW5lZCwge30pLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgdXNlIG51bWJlciBmb3JtYXQgZm9yIG5vbi1xdWFudGl0YXRpdmUgc2NhbGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBbVEVNUE9SQUwsIE5PTUlOQUwsIE9SRElOQUxdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChudW1iZXJGb3JtYXQoe2JpbjogdHJ1ZSwgZmllbGQ6ICdhJywgdHlwZTogdHlwZX0sIHVuZGVmaW5lZCwge30pLCB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/compile.test.js b/build/test/compile/compile.test.js new file mode 100644 index 0000000000..93f83de7d7 --- /dev/null +++ b/build/test/compile/compile.test.js @@ -0,0 +1,231 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../../src/log"); +var compile_1 = require("../../src/compile/compile"); +describe('Compile', function () { + it('should throw error for invalid spec', function () { + chai_1.assert.throws(function () { + compile_1.compile({}); + }, Error, log.message.INVALID_SPEC); + }); + describe('compile', function () { + it('should return a spec with default top-level properties, size signals, data, marks, and title', function () { + var spec = compile_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "mark": "point", + "encoding": {} + }).spec; + chai_1.assert.equal(spec.padding, 5); + chai_1.assert.equal(spec.autosize, 'pad'); + chai_1.assert.equal(spec.width, 21); + chai_1.assert.equal(spec.height, 21); + chai_1.assert.deepEqual(spec.title, { text: 'test' }); + chai_1.assert.equal(spec.data.length, 1); // just source + chai_1.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_1.compile({ + "padding": 123, + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "mark": "point", + "encoding": {} + }).spec; + chai_1.assert.equal(spec.padding, 123); + chai_1.assert.equal(spec.autosize, 'pad'); + chai_1.assert.equal(spec.width, 21); + chai_1.assert.equal(spec.height, 21); + chai_1.assert.equal(spec.data.length, 1); // just source. + chai_1.assert.equal(spec.marks.length, 1); // just the root group + }); + it('should use size signal for bar chart width', function () { + var spec = compile_1.compile({ + "data": { "values": [{ "a": "A", "b": 28 }] }, + "mark": "bar", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }).spec; + chai_1.assert.deepEqual(spec.signals, [{ + name: 'x_step', + value: 21 + }, { + name: 'width', + update: "bandspace(domain('x').length, 0.1, 0.05) * x_step" + }]); + chai_1.assert.equal(spec.height, 200); + }); + it('should set resize to true if requested', function () { + var spec = compile_1.compile({ + "autosize": { + "resize": true + }, + "mark": "point", + "encoding": {} + }).spec; + chai_1.assert(spec.autosize.resize); + }); + it('should set autosize to fit and containment if requested', function () { + var spec = compile_1.compile({ + "autosize": { + "type": "fit", + "contains": "content" + }, + "mark": "point", + "encoding": {} + }).spec; + chai_1.assert.deepEqual(spec.autosize, { type: 'fit', contains: 'content' }); + }); + it('should set autosize to fit if requested', function () { + var spec = compile_1.compile({ + "autosize": "fit", + "mark": "point", + "encoding": {} + }).spec; + chai_1.assert.equal(spec.autosize, "fit"); + }); + it('warn if size is data driven and autosize is fit', log.wrap(function (localLogger) { + var spec = compile_1.compile({ + "data": { "values": [{ "a": "A", "b": 28 }] }, + "mark": "bar", + "autosize": "fit", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }).spec; + chai_1.assert.equal(localLogger.warns[0], log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT); + chai_1.assert.equal(spec.width, 200); + chai_1.assert.equal(spec.height, 200); + })); + it('warn if trying to fit composed spec', log.wrap(function (localLogger) { + var spec = compile_1.compile({ + "data": { "values": [{ "a": "A", "b": 28 }] }, + "autosize": "fit", + "vconcat": [{ + "mark": "point", + "encoding": {} + }] + }).spec; + chai_1.assert.equal(localLogger.warns[0], log.message.FIT_NON_SINGLE); + chai_1.assert.equal(spec.autosize, 'pad'); + })); + it('should return title for a layered spec.', function () { + var spec = compile_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "layer": [{ + "mark": "point", + "encoding": {} + }] + }).spec; + chai_1.assert.deepEqual(spec.title, { text: 'test' }); + }); + it('should return title (string) for a layered spec.', function () { + var spec = compile_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": "test", + "layer": [{ + "mark": "point", + "encoding": {} + }] + }).spec; + chai_1.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_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "layer": [{ + "title": { "text": "test" }, + "mark": "point", + "encoding": {} + }] + }).spec; + chai_1.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_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "hconcat": [{ + "mark": "point", + "encoding": {} + }], + "config": { "title": { "anchor": "middle" } } + }).spec; + chai_1.assert.deepEqual(spec.title, { + text: 'test', + anchor: 'start' // We only support anchor as start for concat + }); + chai_1.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_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "hconcat": [{ + "mark": "point", + "encoding": {} + }], + "config": { "title": { "offset": 5 } } + }).spec; + chai_1.assert.deepEqual(spec.title, { + text: 'test', + anchor: 'start', + offset: 5 + }); + }); + it('should not have title if there is no title.', function () { + var spec = compile_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "hconcat": [{ + "mark": "point", + "encoding": {} + }], + "config": { "title": { "offset": 5 } } + }).spec; + chai_1.assert.isUndefined(spec.title); + }); + it('should use provided config.', function () { + var spec = compile_1.compile({ + mark: "point", + encoding: {} + }, { config: { + background: "blue" + } }).spec; + chai_1.assert.equal(spec.config.background, "blue"); + }); + it('should merge spec and provided config.', function () { + var spec = compile_1.compile({ + mark: "point", + encoding: {}, + config: { + background: "red" + } + }, { config: { + background: "blue" + } }).spec; + chai_1.assert.equal(spec.config.background, "red"); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC9jb21waWxlL2NvbXBpbGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIsbUNBQXFDO0FBRXJDLHFEQUFrRDtBQUdsRCxRQUFRLENBQUMsU0FBUyxFQUFFO0lBQ2xCLEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRTtRQUN4QyxhQUFNLENBQUMsTUFBTSxDQUFDO1lBQ1osaUJBQU8sQ0FBQyxFQUFTLENBQUMsQ0FBQztRQUNyQixDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyw4RkFBOEYsRUFBRTtZQUNqRyxJQUFNLElBQUksR0FBRyxpQkFBTyxDQUFDO2dCQUNuQixNQUFNLEVBQUU7b0JBQ04sUUFBUSxFQUFFLENBQUMsRUFBQyxHQUFHLEVBQUUsR0FBRyxFQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUMsQ0FBQztpQkFDL0I7Z0JBQ0QsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLE1BQU0sRUFBQztnQkFDekIsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsVUFBVSxFQUFFLEVBQUU7YUFDZixDQUFDLENBQUMsSUFBSSxDQUFDO1lBRVIsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlCLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDN0IsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FB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QUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNULGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsSUFBTSxJQUFJLEdBQUcsaUJBQU8sQ0FBQztnQkFDbkIsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFLEVBQUU7Z0JBQ1osTUFBTSxFQUFFO29CQUNOLFVBQVUsRUFBRSxLQUFLO2lCQUNsQjthQUNGLEVBQUUsRUFBQyxNQUFNLEVBQUU7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CLEVBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNULGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcblxuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL3NyYy9sb2cnO1xuXG5pbXBvcnQge2NvbXBpbGV9IGZyb20gJy4uLy4uL3NyYy9jb21waWxlL2NvbXBpbGUnO1xuXG5cbmRlc2NyaWJlKCdDb21waWxlJywgZnVuY3Rpb24oKSB7XG4gIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgc3BlYycsICgpID0+IHtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgIGNvbXBpbGUoe30gYXMgYW55KTtcbiAgICB9LCBFcnJvciwgbG9nLm1lc3NhZ2UuSU5WQUxJRF9TUEVDKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NvbXBpbGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzcGVjIHdpdGggZGVmYXVsdCB0b3AtbGV2ZWwgcHJvcGVydGllcywgc2l6ZSBzaWduYWxzLCBkYXRhLCBtYXJrcywgYW5kIHRpdGxlJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYyA9IGNvbXBpbGUoe1xuICAgICAgICBcImRhdGFcIjoge1xuICAgICAgICAgIFwidmFsdWVzXCI6IFt7XCJhXCI6IFwiQVwiLFwiYlwiOiAyOH1dXG4gICAgICAgIH0sXG4gICAgICAgIFwidGl0bGVcIjoge1widGV4dFwiOiBcInRlc3RcIn0sXG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge31cbiAgICAgIH0pLnNwZWM7XG5cbiAgICAgIGFzc2VydC5lcXVhbChzcGVjLnBhZGRpbmcsIDUpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNwZWMuYXV0b3NpemUsICdwYWQnKTtcbiAgICAgIGFzc2VydC5lcXVhbChzcGVjLndpZHRoLCAyMSk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5oZWlnaHQsIDIxKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc3BlYy50aXRsZSwge3RleHQ6ICd0ZXN0J30pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5kYXRhLmxlbmd0aCwgMSk7IC8vIGp1c3Qgc291cmNlXG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5tYXJrcy5sZW5ndGgsIDEpOyAvLyBqdXN0IHRoZSByb290IGdyb3VwXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIHNwZWMgd2l0aCBzcGVjaWZpZWQgdG9wLWxldmVsIHByb3BlcnRpZXMsIHNpemUgc2lnbmFscywgZGF0YSBhbmQgbWFya3MnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzcGVjID0gY29tcGlsZSh7XG4gICAgICAgIFwicGFkZGluZ1wiOiAxMjMsXG4gICAgICAgIFwiZGF0YVwiOiB7XG4gICAgICAgICAgXCJ2YWx1ZXNcIjogW3tcImFcIjogXCJBXCIsXCJiXCI6IDI4fV1cbiAgICAgICAgfSxcbiAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7fVxuICAgICAgfSkuc3BlYztcblxuICAgICAgYXNzZXJ0LmVxdWFsKHNwZWMucGFkZGluZywgMTIzKTtcbiAgICAgIGFzc2VydC5lcXVhbChzcGVjLmF1dG9zaXplLCAncGFkJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy53aWR0aCwgMjEpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNwZWMuaGVpZ2h0LCAyMSk7XG5cbiAgICAgIGFzc2VydC5lcXVhbChzcGVjLmRhdGEubGVuZ3RoLCAxKTsgLy8ganVzdCBzb3VyY2UuXG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5tYXJrcy5sZW5ndGgsIDEpOyAvLyBqdXN0IHRoZSByb290IGdyb3VwXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBzaXplIHNpZ25hbCBmb3IgYmFyIGNoYXJ0IHdpZHRoJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYyA9IGNvbXBpbGUoe1xuICAgICAgICBcImRhdGFcIjoge1widmFsdWVzXCI6IFt7XCJhXCI6IFwiQVwiLFwiYlwiOiAyOH1dfSxcbiAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9XG4gICAgICB9KS5zcGVjO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNwZWMuc2lnbmFscywgW3tcbiAgICAgICAgbmFtZTogJ3hfc3RlcCcsXG4gICAgICAgIHZhbHVlOiAyMVxuICAgICAgfSwge1xuICAgICAgICBuYW1lOiAnd2lkdGgnLFxuICAgICAgICB1cGRhdGU6IGBiYW5kc3BhY2UoZG9tYWluKCd4JykubGVuZ3RoLCAwLjEsIDAuMDUpICogeF9zdGVwYFxuICAgICAgfV0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNwZWMuaGVpZ2h0LCAyMDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmVzaXplIHRvIHRydWUgaWYgcmVxdWVzdGVkJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYyA9IGNvbXBpbGUoe1xuICAgICAgICBcImF1dG9zaXplXCI6IHtcbiAgICAgICAgICBcInJlc2l6ZVwiOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge31cbiAgICAgIH0pLnNwZWM7XG5cbiAgICAgIGFzc2VydChzcGVjLmF1dG9zaXplLnJlc2l6ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCBhdXRvc2l6ZSB0byBmaXQgYW5kIGNvbnRhaW5tZW50IGlmIHJlcXVlc3RlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWMgPSBjb21waWxlKHtcbiAgICAgICAgXCJhdXRvc2l6ZVwiOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiZml0XCIsXG4gICAgICAgICAgXCJjb250YWluc1wiOiBcImNvbnRlbnRcIlxuICAgICAgICB9LFxuICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHt9XG4gICAgICB9KS5zcGVjO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNwZWMuYXV0b3NpemUsIHt0eXBlOiAnZml0JywgY29udGFpbnM6ICdjb250ZW50J30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgYXV0b3NpemUgdG8gZml0IGlmIHJlcXVlc3RlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWMgPSBjb21waWxlKHtcbiAgICAgICAgXCJhdXRvc2l6ZVwiOiBcImZpdFwiLFxuICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHt9XG4gICAgICB9KS5zcGVjO1xuXG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5hdXRvc2l6ZSwgXCJmaXRcIik7XG4gICAgfSk7XG5cbiAgICBpdCgnd2FybiBpZiBzaXplIGlzIGRhdGEgZHJpdmVuIGFuZCBhdXRvc2l6ZSBpcyBmaXQnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IHNwZWMgPSBjb21waWxlKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInZhbHVlc1wiOiBbe1wiYVwiOiBcIkFcIixcImJcIjogMjh9XX0sXG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImF1dG9zaXplXCI6IFwiZml0XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9XG4gICAgICB9KS5zcGVjO1xuICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS5DQU5OT1RfRklYX1JBTkdFX1NURVBfV0lUSF9GSVQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNwZWMud2lkdGgsIDIwMCk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5oZWlnaHQsIDIwMCk7XG4gICAgfSkpO1xuXG4gICAgaXQoJ3dhcm4gaWYgdHJ5aW5nIHRvIGZpdCBjb21wb3NlZCBzcGVjJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBzcGVjID0gY29tcGlsZSh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ2YWx1ZXNcIjogW3tcImFcIjogXCJBXCIsXCJiXCI6IDI4fV19LFxuICAgICAgICBcImF1dG9zaXplXCI6IFwiZml0XCIsXG4gICAgICAgIFwidmNvbmNhdFwiOiBbe1xuICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7fVxuICAgICAgICB9XVxuICAgICAgfSkuc3BlYztcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuRklUX05PTl9TSU5HTEUpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNwZWMuYXV0b3NpemUsICdwYWQnKTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0aXRsZSBmb3IgYSBsYXllcmVkIHNwZWMuJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYyA9IGNvbXBpbGUoe1xuICAgICAgICBcImRhdGFcIjoge1xuICAgICAgICAgIFwidmFsdWVzXCI6IFt7XCJhXCI6IFwiQVwiLFwiYlwiOiAyOH1dXG4gICAgICAgIH0sXG4gICAgICAgIFwidGl0bGVcIjoge1widGV4dFwiOiBcInRlc3RcIn0sXG4gICAgICAgIFwibGF5ZXJcIjogW3tcbiAgICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge31cbiAgICAgICAgfV1cbiAgICAgIH0pLnNwZWM7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNwZWMudGl0bGUsIHt0ZXh0OiAndGVzdCd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRpdGxlIChzdHJpbmcpIGZvciBhIGxheWVyZWQgc3BlYy4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBzcGVjID0gY29tcGlsZSh7XG4gICAgICAgIFwiZGF0YVwiOiB7XG4gICAgICAgICAgXCJ2YWx1ZXNcIjogW3tcImFcIjogXCJBXCIsXCJiXCI6IDI4fV1cbiAgICAgICAgfSxcbiAgICAgICAgXCJ0aXRsZVwiOiBcInRlc3RcIixcbiAgICAgICAgXCJsYXllclwiOiBbe1xuICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7fVxuICAgICAgICB9XVxuICAgICAgfSkuc3BlYztcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc3BlYy50aXRsZSwge3RleHQ6ICd0ZXN0J30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGl0bGUgZnJvbSBhIGNoaWxkIG9mIGEgbGF5ZXIgc3BlYyBpZiBwYXJlbnQgaGFzIG5vIHRpdGxlLicsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWMgPSBjb21waWxlKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcbiAgICAgICAgICBcInZhbHVlc1wiOiBbe1wiYVwiOiBcIkFcIixcImJcIjogMjh9XVxuICAgICAgICB9LFxuICAgICAgICBcImxheWVyXCI6IFt7XG4gICAgICAgICAgXCJ0aXRsZVwiOiB7XCJ0ZXh0XCI6IFwidGVzdFwifSxcbiAgICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge31cbiAgICAgICAgfV1cbiAgICAgIH0pLnNwZWM7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNwZWMudGl0bGUsIHt0ZXh0OiAndGVzdCd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgdGl0bGUgZm9yIGEgY29uY2F0IHNwZWMsIHRocm93IHdhcm5pbmcgaWYgYW5jaG9yIGlzIHNldCB0byBvdGhlciB2YWx1ZXMgdGhhbiBcInN0YXJ0XCIgYW5kIGF1dG9tYXRpY2FsbHkgc2V0IGFuY2hvciB0byBcInN0YXJ0XCIuJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBzcGVjID0gY29tcGlsZSh7XG4gICAgICAgIFwiZGF0YVwiOiB7XG4gICAgICAgICAgXCJ2YWx1ZXNcIjogW3tcImFcIjogXCJBXCIsXCJiXCI6IDI4fV1cbiAgICAgICAgfSxcbiAgICAgICAgXCJ0aXRsZVwiOiB7XCJ0ZXh0XCI6IFwidGVzdFwifSxcbiAgICAgICAgXCJoY29uY2F0XCI6IFt7XG4gICAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHt9XG4gICAgICAgIH1dLFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJ0aXRsZVwiOiB7XCJhbmNob3JcIjogXCJtaWRkbGVcIn19XG4gICAgICB9KS5zcGVjO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzcGVjLnRpdGxlLCB7XG4gICAgICAgIHRleHQ6ICd0ZXN0JyxcbiAgICAgICAgYW5jaG9yOiAnc3RhcnQnIC8vIFdlIG9ubHkgc3VwcG9ydCBhbmNob3IgYXMgc3RhcnQgZm9yIGNvbmNhdFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmNhbm5vdFNldFRpdGxlQW5jaG9yKCdjb25jYXQnKSk7XG4gICAgfSkpO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSB0aXRsZSBmb3IgYSBjb25jYXQgc3BlYywgYXV0b21hdGljYWxseSBzZXQgYW5jaG9yIHRvIFwic3RhcnRcIiwgYW5kIGF1Z21lbnQgdGhlIHRpdGxlIHdpdGggbm9uLW1hcmsgdGl0bGUgY29uZmlnIChlLmcuLCBvZmZzZXQpLicsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWMgPSBjb21waWxlKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcbiAgICAgICAgICBcInZhbHVlc1wiOiBbe1wiYVwiOiBcIkFcIixcImJcIjogMjh9XVxuICAgICAgICB9LFxuICAgICAgICBcInRpdGxlXCI6IHtcInRleHRcIjogXCJ0ZXN0XCJ9LFxuICAgICAgICBcImhjb25jYXRcIjogW3tcbiAgICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge31cbiAgICAgICAgfV0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcInRpdGxlXCI6IHtcIm9mZnNldFwiOiA1fX1cbiAgICAgIH0pLnNwZWM7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNwZWMudGl0bGUsIHtcbiAgICAgICAgdGV4dDogJ3Rlc3QnLFxuICAgICAgICBhbmNob3I6ICdzdGFydCcsXG4gICAgICAgIG9mZnNldDogNVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBoYXZlIHRpdGxlIGlmIHRoZXJlIGlzIG5vIHRpdGxlLicsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWMgPSBjb21waWxlKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcbiAgICAgICAgICBcInZhbHVlc1wiOiBbe1wiYVwiOiBcIkFcIixcImJcIjogMjh9XVxuICAgICAgICB9LFxuICAgICAgICBcImhjb25jYXRcIjogW3tcbiAgICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge31cbiAgICAgICAgfV0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcInRpdGxlXCI6IHtcIm9mZnNldFwiOiA1fX1cbiAgICAgIH0pLnNwZWM7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQoc3BlYy50aXRsZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBwcm92aWRlZCBjb25maWcuJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYyA9IGNvbXBpbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7fVxuICAgICAgfSwge2NvbmZpZzoge1xuICAgICAgICBiYWNrZ3JvdW5kOiBcImJsdWVcIlxuICAgICAgfX0pLnNwZWM7XG4gICAgICBhc3NlcnQuZXF1YWwoc3BlYy5jb25maWcuYmFja2dyb3VuZCwgXCJibHVlXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBtZXJnZSBzcGVjIGFuZCBwcm92aWRlZCBjb25maWcuJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYyA9IGNvbXBpbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7fSxcbiAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgYmFja2dyb3VuZDogXCJyZWRcIlxuICAgICAgICB9XG4gICAgICB9LCB7Y29uZmlnOiB7XG4gICAgICAgIGJhY2tncm91bmQ6IFwiYmx1ZVwiXG4gICAgICB9fSkuc3BlYztcbiAgICAgIGFzc2VydC5lcXVhbChzcGVjLmNvbmZpZy5iYWNrZ3JvdW5kLCBcInJlZFwiKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/concat.test.js b/build/test/compile/concat.test.js new file mode 100644 index 0000000000..02a76031e5 --- /dev/null +++ b/build/test/compile/concat.test.js @@ -0,0 +1,94 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../../src/log"); +var util_1 = require("../util"); +describe('Concat', function () { + describe('merge scale domains', function () { + it('should instantiate all children in vconcat', function () { + var model = util_1.parseConcatModel({ + vconcat: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'bar', + encoding: { + x: { field: 'b', type: 'ordinal' }, + y: { field: 'c', type: 'quantitative' } + } + }] + }); + chai_1.assert.equal(model.children.length, 2); + chai_1.assert(model.isVConcat); + }); + it('should instantiate all children in hconcat', function () { + var model = util_1.parseConcatModel({ + hconcat: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'bar', + encoding: { + x: { field: 'b', type: 'ordinal' }, + y: { field: 'c', type: 'quantitative' } + } + }] + }); + chai_1.assert.equal(model.children.length, 2); + chai_1.assert(!model.isVConcat); + }); + it('should create correct layout for vconcat', function () { + var model = util_1.parseConcatModel({ + vconcat: [{ + mark: 'point', + encoding: {} + }, { + mark: 'bar', + encoding: {} + }] + }); + chai_1.assert.deepEqual(model.assembleLayout(), { + padding: { row: 10, column: 10 }, + offset: 10, + columns: 1, + bounds: 'full', + align: 'each' + }); + }); + it('should create correct layout for hconcat', function () { + var model = util_1.parseConcatModel({ + hconcat: [{ + mark: 'point', + encoding: {} + }, { + mark: 'bar', + encoding: {} + }] + }); + chai_1.assert.deepEqual(model.assembleLayout(), { + padding: { row: 10, column: 10 }, + offset: 10, + bounds: 'full', + align: 'each' + }); + }); + }); + describe('resolve', function () { + it('cannot share axes', log.wrap(function (localLogger) { + util_1.parseConcatModel({ + hconcat: [], + resolve: { + axis: { + x: 'shared' + } + } + }); + chai_1.assert.equal(localLogger.warns[0], log.message.CONCAT_CANNOT_SHARE_AXIS); + })); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uY2F0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2NvbXBpbGUvY29uY2F0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsbUNBQXFDO0FBRXJDLGdDQUF5QztBQUV6QyxRQUFRLENBQUMsUUFBUSxFQUFFO0lBQ2pCLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtRQUM5QixFQUFFLENBQUMsNENBQTRDLEVBQUU7WUFDL0MsSUFBTSxLQUFLLEdBQUcsdUJBQWdCLENBQUM7Z0JBQzdCLE9BQU8sRUFBRSxDQUFDO3dCQUNSLElBQUksRUFBRSxPQUFPO3dCQUNiLFFBQVEsRUFBRTs0QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7eUJBQ2pDO3FCQUNGLEVBQUM7d0JBQ0EsSUFBSSxFQUFFLEtBQUs7d0JBQ1gsUUFBUSxFQUFFOzRCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzs0QkFDaEMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO3lCQUN0QztxQkFDRixDQUFDO2FBQ0gsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN2QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1lBQy9DLElBQU0sS0FBSyxHQUFHLHVCQUFnQixDQUFDO2dCQUM3QixPQUFPLEVBQUUsQ0FBQzt3QkFDUixJQUFJLEVBQUUsT0FBTzt3QkFDYixRQUFRLEVBQUU7NEJBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO3lCQUNqQztxQkFDRixFQUFDO3dCQUNBLElBQUksRUFBRSxLQUFLO3dCQUNYLFFBQVEsRUFBRTs0QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7NEJBQ2hDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQzt5QkFDdEM7cUJBQ0YsQ0FBQzthQUNILENBQUMsQ0FBQztZQUVILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkMsYUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFO1lBQzdDLElBQU0sS0FBSyxHQUFHLHVCQUFnQixDQUFDO2dCQUM3QixPQUFPLEVBQUUsQ0FBQzt3QkFDUixJQUFJLEVBQUUsT0FBTzt3QkFDYixRQUFRLEVBQUUsRUFDVDtxQkFDRixFQUFDO3dCQUNBLElBQUksRUFBRSxLQUFLO3dCQUNYLFFBQVEsRUFBRSxFQUNUO3FCQUNGLENBQUM7YUFDSCxDQUFDLENBQUM7WUFFSCxhQUFNLENBQUMsU0FBUyxDQUFXLEtBQUssQ0FBQyxjQUFjLEVBQUUsRUFBRTtnQkFDakQsT0FBTyxFQUFFLEVBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFDO2dCQUM5QixNQUFNLEVBQUUsRUFBRTtnQkFDVixPQUFPLEVBQUUsQ0FBQztnQkFDVixNQUFNLEVBQUUsTUFBTTtnQkFDZCxLQUFLLEVBQUUsTUFBTTthQUNkLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFO1lBQzdDLElBQU0sS0FBSyxHQUFHLHVCQUFnQixDQUFDO2dCQUM3QixPQUFPLEVBQUUsQ0FBQzt3QkFDUixJQUFJLEVBQUUsT0FBTzt3QkFDYixRQUFRLEVBQUUsRUFDVDtxQkFDRixFQUFDO3dCQUNBLElBQUksRUFBRSxLQUFLO3dCQUNYLFFBQVEsRUFBRSxFQUNUO3FCQUNGLENBQUM7YUFDSCxDQUFDLENBQUM7WUFFSCxhQUFNLENBQUMsU0FBUyxDQUFXLEtBQUssQ0FBQyxjQUFjLEVBQUUsRUFBRTtnQkFDakQsT0FBTyxFQUFFLEVBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFDO2dCQUM5QixNQUFNLEVBQUUsRUFBRTtnQkFDVixNQUFNLEVBQUUsTUFBTTtnQkFDZCxLQUFLLEVBQUUsTUFBTTthQUNkLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztZQUMzQyx1QkFBZ0IsQ0FBQztnQkFDZixPQUFPLEVBQUUsRUFBRTtnQkFDWCxPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFO3dCQUNKLENBQUMsRUFBRSxRQUFRO3FCQUNaO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUMzRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi9zcmMvbG9nJztcbmltcG9ydCB7VmdMYXlvdXR9IGZyb20gJy4uLy4uL3NyYy92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3BhcnNlQ29uY2F0TW9kZWx9IGZyb20gJy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnQ29uY2F0JywgKCkgPT4ge1xuICBkZXNjcmliZSgnbWVyZ2Ugc2NhbGUgZG9tYWlucycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGluc3RhbnRpYXRlIGFsbCBjaGlsZHJlbiBpbiB2Y29uY2F0JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUNvbmNhdE1vZGVsKHtcbiAgICAgICAgdmNvbmNhdDogW3tcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICAgIH1cbiAgICAgICAgfSx7XG4gICAgICAgICAgbWFyazogJ2JhcicsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAnb3JkaW5hbCd9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiAnYycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfV1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuY2hpbGRyZW4ubGVuZ3RoLCAyKTtcbiAgICAgIGFzc2VydChtb2RlbC5pc1ZDb25jYXQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbnN0YW50aWF0ZSBhbGwgY2hpbGRyZW4gaW4gaGNvbmNhdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VDb25jYXRNb2RlbCh7XG4gICAgICAgIGhjb25jYXQ6IFt7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgICB9XG4gICAgICAgIH0se1xuICAgICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdiJywgdHlwZTogJ29yZGluYWwnfSxcbiAgICAgICAgICAgIHk6IHtmaWVsZDogJ2MnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICB9XG4gICAgICAgIH1dXG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLmNoaWxkcmVuLmxlbmd0aCwgMik7XG4gICAgICBhc3NlcnQoIW1vZGVsLmlzVkNvbmNhdCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBjb3JyZWN0IGxheW91dCBmb3IgdmNvbmNhdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VDb25jYXRNb2RlbCh7XG4gICAgICAgIHZjb25jYXQ6IFt7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIH1cbiAgICAgICAgfSx7XG4gICAgICAgICAgbWFyazogJ2JhcicsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB9XG4gICAgICAgIH1dXG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0xheW91dD4obW9kZWwuYXNzZW1ibGVMYXlvdXQoKSwge1xuICAgICAgICBwYWRkaW5nOiB7cm93OiAxMCwgY29sdW1uOiAxMH0sXG4gICAgICAgIG9mZnNldDogMTAsXG4gICAgICAgIGNvbHVtbnM6IDEsXG4gICAgICAgIGJvdW5kczogJ2Z1bGwnLFxuICAgICAgICBhbGlnbjogJ2VhY2gnXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGNvcnJlY3QgbGF5b3V0IGZvciBoY29uY2F0JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUNvbmNhdE1vZGVsKHtcbiAgICAgICAgaGNvbmNhdDogW3tcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgfVxuICAgICAgICB9LHtcbiAgICAgICAgICBtYXJrOiAnYmFyJyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIH1cbiAgICAgICAgfV1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPFZnTGF5b3V0Pihtb2RlbC5hc3NlbWJsZUxheW91dCgpLCB7XG4gICAgICAgIHBhZGRpbmc6IHtyb3c6IDEwLCBjb2x1bW46IDEwfSxcbiAgICAgICAgb2Zmc2V0OiAxMCxcbiAgICAgICAgYm91bmRzOiAnZnVsbCcsXG4gICAgICAgIGFsaWduOiAnZWFjaCdcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVzb2x2ZScsICgpID0+IHtcbiAgICBpdCgnY2Fubm90IHNoYXJlIGF4ZXMnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIHBhcnNlQ29uY2F0TW9kZWwoe1xuICAgICAgICBoY29uY2F0OiBbXSxcbiAgICAgICAgcmVzb2x2ZToge1xuICAgICAgICAgIGF4aXM6IHtcbiAgICAgICAgICAgIHg6ICdzaGFyZWQnXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuQ09OQ0FUX0NBTk5PVF9TSEFSRV9BWElTKTtcbiAgICB9KSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/data/aggregate.test.js b/build/test/compile/data/aggregate.test.js new file mode 100644 index 0000000000..2555257392 --- /dev/null +++ b/build/test/compile/data/aggregate.test.js @@ -0,0 +1,171 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var aggregate_1 = require("../../../src/compile/data/aggregate"); +var util_1 = require("../../util"); +describe('compile/data/summary', function () { + describe('clone', function () { + it('should have correct type', function () { + var agg = new aggregate_1.AggregateNode({}, {}); + chai_1.assert(agg instanceof aggregate_1.AggregateNode); + var clone = agg.clone(); + chai_1.assert(clone instanceof aggregate_1.AggregateNode); + }); + it('should have make a deep copy', function () { + var agg = new aggregate_1.AggregateNode({ foo: true }, {}); + var clone = agg.clone(); + clone.addDimensions(['bar']); + chai_1.assert.deepEqual(clone.dependentFields(), { 'foo': true, 'bar': true }); + chai_1.assert.deepEqual(agg.dependentFields(), { 'foo': true }); + }); + }); + describe('parseUnit', function () { + it('should produce the correct summary component for sum(Acceleration) and count(*)', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'y': { + 'aggregate': 'sum', + 'field': 'Acceleration', + 'type': "quantitative" + }, + 'x': { + 'field': 'Origin', + 'type': "ordinal" + }, + color: { field: '*', type: "quantitative", aggregate: 'count' } + } + }); + var agg = aggregate_1.AggregateNode.makeFromEncoding(model); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative" }, + 'detail': [ + { 'field': 'Origin', 'type': "ordinal" }, + { 'field': 'Cylinders', 'type': "quantitative" } + ] + } + }); + var agg = aggregate_1.AggregateNode.makeFromEncoding(model); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative" }, + color: { + condition: { selection: 'a', field: 'Origin', 'type': "ordinal" }, + value: 'red' + } + } + }); + var agg = aggregate_1.AggregateNode.makeFromEncoding(model); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative", scale: { domain: 'unaggregated' } }, + } + }); + var agg = aggregate_1.AggregateNode.makeFromEncoding(model); + chai_1.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 = util_1.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 = aggregate_1.AggregateNode.makeFromEncoding(model); + chai_1.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 = aggregate_1.AggregateNode.makeFromTransform(t); + chai_1.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 = aggregate_1.AggregateNode.makeFromTransform(t); + chai_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9hZ2dyZWdhdGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIsaUVBQWtFO0FBSWxFLG1DQUEwQztBQUUxQyxRQUFRLENBQUMsc0JBQXNCLEVBQUU7SUFDL0IsUUFBUSxDQUFDLE9BQU8sRUFBRTtRQUNoQixFQUFFLENBQUMsMEJBQTBCLEVBQUU7WUFDN0IsSUFBTSxHQUFHLEdBQUcsSUFBSSx5QkFBYSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QyxhQUFNLENBQUMsR0FBRyxZQUFZLHlCQUFhLENBQUMsQ0FBQztZQUNyQyxJQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDMUIsYUFBTSxDQUFDLEtBQUssWUFBWSx5QkFBYSxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOEJBQThCLEVBQUU7WUFDakMsSUFBTSxHQUFHLEdBQUcsSUFBSSx5QkFBYSxDQUFDLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQy9DLElBQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQixLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUM3QixhQUFNLENBQUMsU0FBUyxDQUFZLEtBQUssQ0FBQyxlQUFlLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7WUFDakYsYUFBTSxDQUFDLFNBQVMsQ0FBWSxHQUFHLENBQUMsZUFBZSxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQztRQUNwRSxDQUFDLENB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RUFBRSxDQUFDLGNBQWMsRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDO2dCQUN4RCxFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQzthQUNsRSxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuXG5pbXBvcnQge0FnZ3JlZ2F0ZU5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvYWdncmVnYXRlJztcbmltcG9ydCB7QWdncmVnYXRlVHJhbnNmb3JtfSBmcm9tICcuLi8uLi8uLi9zcmMvdHJhbnNmb3JtJztcbmltcG9ydCB7U3RyaW5nU2V0fSBmcm9tICcuLi8uLi8uLi9zcmMvdXRpbCc7XG5pbXBvcnQge1ZnQWdncmVnYXRlVHJhbnNmb3JtfSBmcm9tICcuLi8uLi8uLi9zcmMvdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdjb21waWxlL2RhdGEvc3VtbWFyeScsIGZ1bmN0aW9uICgpIHtcbiAgZGVzY3JpYmUoJ2Nsb25lJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgdHlwZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgYWdnID0gbmV3IEFnZ3JlZ2F0ZU5vZGUoe30sIHt9KTtcbiAgICAgIGFzc2VydChhZ2cgaW5zdGFuY2VvZiBBZ2dyZWdhdGVOb2RlKTtcbiAgICAgIGNvbnN0IGNsb25lID0gYWdnLmNsb25lKCk7XG4gICAgICBhc3NlcnQoY2xvbmUgaW5zdGFuY2VvZiBBZ2dyZWdhdGVOb2RlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBtYWtlIGEgZGVlcCBjb3B5JywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBhZ2cgPSBuZXcgQWdncmVnYXRlTm9kZSh7Zm9vOiB0cnVlfSwge30pO1xuICAgICAgY29uc3QgY2xvbmUgPSBhZ2cuY2xvbmUoKTtcbiAgICAgIGNsb25lLmFkZERpbWVuc2lvbnMoWydiYXInXSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPFN0cmluZ1NldD4oY2xvbmUuZGVwZW5kZW50RmllbGRzKCksIHsnZm9vJzogdHJ1ZSwgJ2Jhcic6IHRydWV9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8U3RyaW5nU2V0PihhZ2cuZGVwZW5kZW50RmllbGRzKCksIHsnZm9vJzogdHJ1ZX0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2VVbml0JywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIHRoZSBjb3JyZWN0IHN1bW1hcnkgY29tcG9uZW50IGZvciBzdW0oQWNjZWxlcmF0aW9uKSBhbmQgY291bnQoKiknICwgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAneSc6IHtcbiAgICAgICAgICAgICdhZ2dyZWdhdGUnOiAnc3VtJyxcbiAgICAgICAgICAgICdmaWVsZCc6ICdBY2NlbGVyYXRpb24nLFxuICAgICAgICAgICAgJ3R5cGUnOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICAneCc6IHtcbiAgICAgICAgICAgICdmaWVsZCc6ICdPcmlnaW4nLFxuICAgICAgICAgICAgJ3R5cGUnOiBcIm9yZGluYWxcIlxuICAgICAgICAgIH0sXG4gICAgICAgICAgY29sb3I6IHtmaWVsZDogJyonLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwiLCBhZ2dyZWdhdGU6ICdjb3VudCd9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhZ2cgPSBBZ2dyZWdhdGVOb2RlLm1ha2VGcm9tRW5jb2RpbmcobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybT4oYWdnLmFzc2VtYmxlKCksIHtcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIGdyb3VwYnk6IFsnT3JpZ2luJ10sXG4gICAgICAgIG9wczogWydzdW0nLCAnY291bnQnXSxcbiAgICAgICAgZmllbGRzOiBbJ0FjY2VsZXJhdGlvbicsICcqJ10sXG4gICAgICAgIGFzOiBbXG4gICAgICAgICAgXCJzdW1fQWNjZWxlcmF0aW9uXCIsXG4gICAgICAgICAgXCJjb3VudF8qXCJcbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgdGhlIGNvcnJlY3Qgc3VtbWFyeSBjb21wb25lbnQgZm9yIGFnZ3JlZ2F0ZWQgcGxvdCB3aXRoIGRldGFpbCBhcnJheXMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgJ3gnOiB7J2FnZ3JlZ2F0ZSc6ICdtZWFuJywgJ2ZpZWxkJzogJ0Rpc3BsYWNlbWVudCcsICd0eXBlJzogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgJ2RldGFpbCc6IFtcbiAgICAgICAgICAgIHsnZmllbGQnOiAnT3JpZ2luJywgJ3R5cGUnOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICB7J2ZpZWxkJzogJ0N5bGluZGVycycsICd0eXBlJzogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhZ2cgPSBBZ2dyZWdhdGVOb2RlLm1ha2VGcm9tRW5jb2RpbmcobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybT4oYWdnLmFzc2VtYmxlKCksIHtcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIGdyb3VwYnk6IFsnT3JpZ2luJywgJ0N5bGluZGVycyddLFxuICAgICAgICBvcHM6IFsnbWVhbiddLFxuICAgICAgICBmaWVsZHM6IFsnRGlzcGxhY2VtZW50J10sXG4gICAgICAgIGFzOiBbJ21lYW5fRGlzcGxhY2VtZW50J11cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIGNvbmRpdGlvbmFsIGZpZWxkIGluIHRoZSBzdW1tYXJ5IGNvbXBvbmVudCcsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAneCc6IHsnYWdncmVnYXRlJzogJ21lYW4nLCAnZmllbGQnOiAnRGlzcGxhY2VtZW50JywgJ3R5cGUnOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBjb2xvcjoge1xuICAgICAgICAgICAgY29uZGl0aW9uOiB7c2VsZWN0aW9uOiAnYScsIGZpZWxkOiAnT3JpZ2luJywgJ3R5cGUnOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICB2YWx1ZTogJ3JlZCdcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhZ2cgPSBBZ2dyZWdhdGVOb2RlLm1ha2VGcm9tRW5jb2RpbmcobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybT4oYWdnLmFzc2VtYmxlKCksIHtcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIGdyb3VwYnk6IFsnT3JpZ2luJ10sXG4gICAgICAgIG9wczogWydtZWFuJ10sXG4gICAgICAgIGZpZWxkczogWydEaXNwbGFjZW1lbnQnXSxcbiAgICAgICAgYXM6IFsnbWVhbl9EaXNwbGFjZW1lbnQnXVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBtaW4gYW5kIG1heCBpZiBuZWVkZWQgZm9yIHVuYWdncmVnYXRlZCBzY2FsZSBkb21haW4nLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgJ3gnOiB7J2FnZ3JlZ2F0ZSc6ICdtZWFuJywgJ2ZpZWxkJzogJ0Rpc3BsYWNlbWVudCcsICd0eXBlJzogXCJxdWFudGl0YXRpdmVcIiwgc2NhbGU6IHtkb21haW46ICd1bmFnZ3JlZ2F0ZWQnfX0sXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhZ2cgPSBBZ2dyZWdhdGVOb2RlLm1ha2VGcm9tRW5jb2RpbmcobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybT4oYWdnLmFzc2VtYmxlKCksIHtcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIGdyb3VwYnk6IFtdLFxuICAgICAgICBvcHM6IFsnbWVhbicsICdtaW4nLCAnbWF4J10sXG4gICAgICAgIGZpZWxkczogWydEaXNwbGFjZW1lbnQnLCAnRGlzcGxhY2VtZW50JywgJ0Rpc3BsYWNlbWVudCddLFxuICAgICAgICBhczogW1xuICAgICAgICAgIFwibWVhbl9EaXNwbGFjZW1lbnRcIixcbiAgICAgICAgICBcIm1pbl9EaXNwbGFjZW1lbnRcIixcbiAgICAgICAgICBcIm1heF9EaXNwbGFjZW1lbnRcIlxuICAgICAgICBdXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWRkIGNvcnJlY3QgZGltZW5zaW9ucyB3aGVuIGJpbm5pbmcnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgJ3gnOiB7J2Jpbic6IHRydWUsICdmaWVsZCc6ICdEaXNwbGFjZW1lbnQnLCAndHlwZSc6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICd5JzogeydiaW4nOiB0cnVlLCAnZmllbGQnOiAnQWNjZWxlcmF0aW9uJywgJ3R5cGUnOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgJ2NvbG9yJzogeydhZ2dyZWdhdGUnOiAnY291bnQnLCAndHlwZSc6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhZ2cgPSBBZ2dyZWdhdGVOb2RlLm1ha2VGcm9tRW5jb2RpbmcobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybT4oYWdnLmFzc2VtYmxlKCksIHtcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIGdyb3VwYnk6IFtcbiAgICAgICAgICAnYmluX21heGJpbnNfMTBfRGlzcGxhY2VtZW50JyxcbiAgICAgICAgICAnYmluX21heGJpbnNfMTBfRGlzcGxhY2VtZW50X2VuZCcsXG4gICAgICAgICAgJ2Jpbl9tYXhiaW5zXzEwX0FjY2VsZXJhdGlvbicsXG4gICAgICAgICAgJ2Jpbl9tYXhiaW5zXzEwX0FjY2VsZXJhdGlvbl9lbmQnLFxuICAgICAgICAgICdiaW5fbWF4Ymluc18xMF9BY2NlbGVyYXRpb25fcmFuZ2UnXG4gICAgICAgIF0sXG4gICAgICAgIG9wczogWydjb3VudCddLFxuICAgICAgICBmaWVsZHM6IFsnKiddLFxuICAgICAgICBhczogWydjb3VudF8qJ11cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIHRoZSBjb3JyZWN0IHN1bW1hcnkgY29tcG9uZW50IGZyb20gdHJhbnNmb3JtIGFycmF5JywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB0OiBBZ2dyZWdhdGVUcmFuc2Zvcm0gPSB7XG4gICAgICAgIGFnZ3JlZ2F0ZTogW1xuICAgICAgICAgIHtvcDogJ21lYW4nLCBmaWVsZDogJ0Rpc3BsYWNlbWVudCcsIGFzOiAnRGlzcGxhY2VtZW50X21lYW4nfSxcbiAgICAgICAgICB7b3A6ICdzdW0nLCBmaWVsZDogJ0FjY2VsZXJhdGlvbicsIGFzOiAnQWNjZWxlcmF0aW9uX3N1bSd9XG4gICAgICAgIF0sXG4gICAgICAgIGdyb3VwYnk6IFsnRGlzcGxhY2VtZW50X21lYW4nLCAnQWNjZWxlcmF0aW9uX3N1bSddfTtcblxuICAgICAgY29uc3QgYWdnID0gQWdncmVnYXRlTm9kZS5tYWtlRnJvbVRyYW5zZm9ybSh0KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VmdBZ2dyZWdhdGVUcmFuc2Zvcm0+KGFnZy5hc3NlbWJsZSgpLCB7XG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICBncm91cGJ5OiBbJ0Rpc3BsYWNlbWVudF9tZWFuJywgJ0FjY2VsZXJhdGlvbl9zdW0nXSxcbiAgICAgICAgb3BzOiBbJ21lYW4nLCAnc3VtJ10sXG4gICAgICAgIGZpZWxkczogWydEaXNwbGFjZW1lbnQnLCAnQWNjZWxlcmF0aW9uJ10sXG4gICAgICAgIGFzOiBbJ0Rpc3BsYWNlbWVudF9tZWFuJywgJ0FjY2VsZXJhdGlvbl9zdW0nXVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgdGhlIGNvcnJlY3Qgc3VtbWFyeSBjb21wb25lbnQgZnJvbSB0cmFuc2Zvcm0gYXJyYXkgd2l0aCBkaWZmZXJlbnQgYWdncmVncmF0aW9ucyBmb3IgdGhlIHNhbWUgZmllbGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IHQ6IEFnZ3JlZ2F0ZVRyYW5zZm9ybSA9IHthZ2dyZWdhdGU6IFtcbiAgICAgICAge29wOiAnbWVhbicsIGZpZWxkOiAnRGlzcGxhY2VtZW50JywgYXM6ICdEaXNwbGFjZW1lbnRfbWVhbid9LFxuICAgICAgICB7b3A6ICdtYXgnLCBmaWVsZDogJ0Rpc3BsYWNlbWVudCcsIGFzOiAnRGlzcGxhY2VtZW50X21heCd9LFxuICAgICAgICB7b3A6ICdzdW0nLCBmaWVsZDogJ0FjY2VsZXJhdGlvbicsIGFzOiAnQWNjZWxlcmF0aW9uX3N1bSd9XSxcbiAgICAgICAgZ3JvdXBieTogWydEaXNwbGFjZW1lbnRfbWVhbicsICdBY2NlbGVyYXRpb25fc3VtJ119O1xuXG4gICAgICBjb25zdCBhZ2cgPSBBZ2dyZWdhdGVOb2RlLm1ha2VGcm9tVHJhbnNmb3JtKHQpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0FnZ3JlZ2F0ZVRyYW5zZm9ybT4oYWdnLmFzc2VtYmxlKCksIHtcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIGdyb3VwYnk6IFsnRGlzcGxhY2VtZW50X21lYW4nLCAnQWNjZWxlcmF0aW9uX3N1bSddLFxuICAgICAgICBvcHM6IFsnbWVhbicsICdtYXgnLCAnc3VtJ10sXG4gICAgICAgIGZpZWxkczogWydEaXNwbGFjZW1lbnQnLCAnRGlzcGxhY2VtZW50JywgJ0FjY2VsZXJhdGlvbiddLFxuICAgICAgICBhczogWydEaXNwbGFjZW1lbnRfbWVhbicsICdEaXNwbGFjZW1lbnRfbWF4JywgJ0FjY2VsZXJhdGlvbl9zdW0nXVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/data/assemble.test.js b/build/test/compile/data/assemble.test.js new file mode 100644 index 0000000000..342617d790 --- /dev/null +++ b/build/test/compile/data/assemble.test.js @@ -0,0 +1,62 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var aggregate_1 = require("../../../src/compile/data/aggregate"); +var assemble_1 = require("../../../src/compile/data/assemble"); +var dataflow_1 = require("../../../src/compile/data/dataflow"); +var source_1 = require("../../../src/compile/data/source"); +describe('compile/data/assemble', function () { + describe('assembleData', function () { + it('should assemble named data source', function () { + var src = new source_1.SourceNode({ name: 'foo' }); + var outputNodeRefCounts = {}; + var main = new dataflow_1.OutputNode('mainOut', 'main', outputNodeRefCounts); + main.parent = src; + chai_1.assert.equal(main.getSource(), 'mainOut'); + var data = assemble_1.assembleRootData({ + sources: { named: src }, + outputNodes: { out: main }, + outputNodeRefCounts: outputNodeRefCounts, + ancestorParse: {} + }); + chai_1.assert.equal(data.length, 1); + chai_1.assert.equal(data[0].name, "foo"); + }); + it('should assemble raw and main output', function () { + var src = new source_1.SourceNode({ url: 'foo.csv' }); + var outputNodeRefCounts = {}; + var raw = new dataflow_1.OutputNode('rawOut', 'raw', outputNodeRefCounts); + raw.parent = src; + var agg = new aggregate_1.AggregateNode({ a: true }, { b: { count: 'count_*' } }); + agg.parent = raw; + var main = new dataflow_1.OutputNode('mainOut', 'main', outputNodeRefCounts); + main.parent = agg; + chai_1.assert.equal(raw.getSource(), 'rawOut'); + chai_1.assert.equal(main.getSource(), 'mainOut'); + var data = assemble_1.assembleRootData({ + sources: { named: src }, + outputNodes: { out: main }, + outputNodeRefCounts: outputNodeRefCounts, + ancestorParse: {} + }); + chai_1.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_*'] + }] + } + ]); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL2Fzc2VtYmxlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLGlFQUFrRTtBQUNsRSwrREFBb0U7QUFDcEUsK0RBQThEO0FBQzlELDJEQUE0RDtBQUc1RCxRQUFRLENBQUMsdUJBQXVCLEVBQUU7SUFDaEMsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMsbUNBQW1DLEVBQUU7WUFDdEMsSUFBTSxHQUFHLEdBQUcsSUFBSSxtQkFBVSxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7WUFDMUMsSUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7WUFDL0IsSUFBTSxJQUFJLEdBQUcsSUFBSSxxQkFBVSxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUNwRSxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztZQUVsQixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUUxQyxJQUFNLElBQUksR0FBRywyQkFBZ0IsQ0FBQztnQkFDNUIsT0FBTyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztnQkFDckIsV0FBVyxFQUFFLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBQztnQkFDeEIsbUJBQW1CLHFCQUFBO2dCQUNuQixhQUFhLEVBQUUsRUFBRTthQUNsQixDQUFDLENBQUM7WUFFSCxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDN0IsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFDQUFxQyxFQUFFO1lBQ3hDLElBQU0sR0FBRyxHQUFHLElBQUksbUJBQVUsQ0FBQyxFQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFDO1lBQzdDLElBQU0sbUJBQW1CLEdBQUcsRUFBRSxDQUFDO1lBQy9CLElBQU0sR0FBRyxHQUFHLElBQUkscUJBQVUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7WUFDakUsR0FBRyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUM7WUFDakIsSUFBTSxHQUFHLEdBQUcsSUFBSSx5QkFBYSxDQUFDLEVBQUMsQ0FBQyxFQUFFLElBQUksRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQyxFQUFDLENBQUMsQ0FBQztZQUNsRSxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztZQUNqQixJQUFNLElBQUksR0FBRyxJQUFJLHFCQUFVLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDO1lBRWxCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3hDLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBRTFDLElBQU0sSUFBSSxHQUFHLDJCQUFnQixDQUFDO2dCQUM1QixPQUFPLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDO2dCQUNyQixXQUFXLEVBQUUsRUFBQyxHQUFHLEVBQUUsSUFBSSxFQUFDO2dCQUN4QixtQkFBbUIscUJBQUE7Z0JBQ25CLGFBQWEsRUFBRSxFQUFFO2FBQ2xCLENBQUMsQ0FBQztZQUVILGFBQU0sQ0FBQyxTQUFTLENBQVcsSUFBSSxFQUFFLENBQUM7b0JBQ2hDLElBQUksRUFBRSxVQUFVO29CQUNoQixHQUFHLEVBQUUsU0FBUztvQkFDZCxNQUFNLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDO2lCQUN0QixFQUFFO29CQUNELElBQUksRUFBRSxRQUFRO29CQUNkLE1BQU0sRUFBRSxVQUFVO29CQUNsQixTQUFTLEVBQUUsQ0FBQzs0QkFDVixJQUFJLEVBQUUsV0FBVzs0QkFDakIsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDOzRCQUNkLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDZCxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUM7NEJBQ2IsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDO3lCQUNoQixDQUFDO2lCQUFDO2FBQ0osQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7QWdncmVnYXRlTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9hZ2dyZWdhdGUnO1xuaW1wb3J0IHthc3NlbWJsZVJvb3REYXRhfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2Fzc2VtYmxlJztcbmltcG9ydCB7T3V0cHV0Tm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9kYXRhZmxvdyc7XG5pbXBvcnQge1NvdXJjZU5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvc291cmNlJztcbmltcG9ydCB7VmdEYXRhfSBmcm9tICcuLi8uLi8uLi9zcmMvdmVnYS5zY2hlbWEnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9kYXRhL2Fzc2VtYmxlJywgKCkgPT4ge1xuICBkZXNjcmliZSgnYXNzZW1ibGVEYXRhJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYXNzZW1ibGUgbmFtZWQgZGF0YSBzb3VyY2UnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzcmMgPSBuZXcgU291cmNlTm9kZSh7bmFtZTogJ2Zvbyd9KTtcbiAgICAgIGNvbnN0IG91dHB1dE5vZGVSZWZDb3VudHMgPSB7fTtcbiAgICAgIGNvbnN0IG1haW4gPSBuZXcgT3V0cHV0Tm9kZSgnbWFpbk91dCcsICdtYWluJywgb3V0cHV0Tm9kZVJlZkNvdW50cyk7XG4gICAgICBtYWluLnBhcmVudCA9IHNyYztcblxuICAgICAgYXNzZXJ0LmVxdWFsKG1haW4uZ2V0U291cmNlKCksICdtYWluT3V0Jyk7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhc3NlbWJsZVJvb3REYXRhKHtcbiAgICAgICAgc291cmNlczoge25hbWVkOiBzcmN9LFxuICAgICAgICBvdXRwdXROb2Rlczoge291dDogbWFpbn0sXG4gICAgICAgIG91dHB1dE5vZGVSZWZDb3VudHMsXG4gICAgICAgIGFuY2VzdG9yUGFyc2U6IHt9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGEubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRhWzBdLm5hbWUsIFwiZm9vXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhc3NlbWJsZSByYXcgYW5kIG1haW4gb3V0cHV0JywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3JjID0gbmV3IFNvdXJjZU5vZGUoe3VybDogJ2Zvby5jc3YnfSk7XG4gICAgICBjb25zdCBvdXRwdXROb2RlUmVmQ291bnRzID0ge307XG4gICAgICBjb25zdCByYXcgPSBuZXcgT3V0cHV0Tm9kZSgncmF3T3V0JywgJ3JhdycsIG91dHB1dE5vZGVSZWZDb3VudHMpO1xuICAgICAgcmF3LnBhcmVudCA9IHNyYztcbiAgICAgIGNvbnN0IGFnZyA9IG5ldyBBZ2dyZWdhdGVOb2RlKHthOiB0cnVlfSwge2I6IHtjb3VudDogJ2NvdW50XyonfX0pO1xuICAgICAgYWdnLnBhcmVudCA9IHJhdztcbiAgICAgIGNvbnN0IG1haW4gPSBuZXcgT3V0cHV0Tm9kZSgnbWFpbk91dCcsICdtYWluJywgb3V0cHV0Tm9kZVJlZkNvdW50cyk7XG4gICAgICBtYWluLnBhcmVudCA9IGFnZztcblxuICAgICAgYXNzZXJ0LmVxdWFsKHJhdy5nZXRTb3VyY2UoKSwgJ3Jhd091dCcpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1haW4uZ2V0U291cmNlKCksICdtYWluT3V0Jyk7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhc3NlbWJsZVJvb3REYXRhKHtcbiAgICAgICAgc291cmNlczoge25hbWVkOiBzcmN9LFxuICAgICAgICBvdXRwdXROb2Rlczoge291dDogbWFpbn0sXG4gICAgICAgIG91dHB1dE5vZGVSZWZDb3VudHMsXG4gICAgICAgIGFuY2VzdG9yUGFyc2U6IHt9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0RhdGFbXT4oZGF0YSwgW3tcbiAgICAgICAgbmFtZTogJ3NvdXJjZV8wJyxcbiAgICAgICAgdXJsOiAnZm9vLmNzdicsXG4gICAgICAgIGZvcm1hdDoge3R5cGU6ICdjc3YnfVxuICAgICAgfSwge1xuICAgICAgICBuYW1lOiAnZGF0YV8wJyxcbiAgICAgICAgc291cmNlOiAnc291cmNlXzAnLFxuICAgICAgICB0cmFuc2Zvcm06IFt7XG4gICAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgICAgZ3JvdXBieTogWydhJ10sXG4gICAgICAgICAgb3BzOiBbJ2NvdW50J10sXG4gICAgICAgICAgZmllbGRzOiBbJ2InXSxcbiAgICAgICAgICBhczogWydjb3VudF8qJ11cbiAgICAgICAgfV19XG4gICAgICBdKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/data/bin.test.js b/build/test/compile/data/bin.test.js new file mode 100644 index 0000000000..34aef2e846 --- /dev/null +++ b/build/test/compile/data/bin.test.js @@ -0,0 +1,161 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var bin_1 = require("../../../src/compile/data/bin"); +var util_1 = require("../../util"); +function assembleFromEncoding(model) { + return bin_1.BinNode.makeBinFromEncoding(model).assemble(); +} +function assembleFromTransform(model, t) { + return bin_1.BinNode.makeFromTransform(t, { model: model }).assemble(); +} +describe('compile/data/bin', function () { + it('should add bin transform and correctly apply bin with custom extent', function () { + var model = util_1.parseUnitModelWithScale({ + mark: 'point', + encoding: { + y: { + bin: { extent: [0, 100] }, + 'field': 'Acceleration', + 'type': 'quantitative' + } + } + }); + chai_1.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 = util_1.parseUnitModelWithScale({ + mark: 'point', + encoding: { + y: { + bin: true, + 'field': 'Acceleration', + 'type': 'quantitative' + } + } + }); + var transform = assembleFromEncoding(model); + chai_1.assert.deepEqual(transform.length, 2); + chai_1.assert.deepEqual(transform[0], { + type: 'extent', + field: 'Acceleration', + signal: 'bin_maxbins_10_Acceleration_extent' + }); + chai_1.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 = util_1.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); + chai_1.assert.deepEqual(transform.length, 3); + chai_1.assert.deepEqual(transform[0], { + type: 'extent', + field: 'Rotten_Tomatoes_Rating', + signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_extent' + }); + chai_1.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' } + }); + chai_1.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 = util_1.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" + } + } + }); + chai_1.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 = util_1.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" + } + } + }); + chai_1.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", + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9iaW4udGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIscURBQXNEO0FBSXRELG1DQUFtRDtBQUVuRCw4QkFBOEIsS0FBcUI7SUFDakQsTUFBTSxDQUFDLGFBQU8sQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUN2RCxDQUFDO0FBRUQsK0JBQStCLEtBQVksRUFBRSxDQUFlO0lBQzFELE1BQU0sQ0FBQyxhQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxPQUFBLEVBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQzFELENBQUM7QUFFRCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7SUFDM0IsRUFBRSxDQUFDLHFFQUFxRSxFQUFFO1FBQ3hFLElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO1lBQ3BDLElBQUksRUFBRSxPQUFPO1lBQ2IsUUFBUSxFQUFFO2dCQUNSLENBQUMsRUFBRTtvQkFDRCxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUM7b0JBQ3ZCLE9BQU8sRUFBRSxjQUFjO29CQUN2QixNQUFNLEVBQUUsY0FBYztpQkFDdkI7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILGFBQU0sQ0FBQyxTQUFTLENBQWMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDNUQsSUFBSSxFQUFFLEtBQUs7WUFDWCxLQUFLLEVBQUUsY0FBYztZQUNyQixFQUFFLEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSw4Q0FBOEMsQ0FBQztZQUNoRyxPQUFPLEVBQUUsRUFBRTtZQUNYLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7WUFD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QkFBdUIsQ0FBQztZQUNwQyxJQUFJLEVBQUUsRUFBQyxHQUFHLEVBQUUsa0JBQWtCLEVBQUM7WUFDL0IsSUFBSSxFQUFFLFFBQVE7WUFDZCxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDZCxRQUFRLEVBQUU7Z0JBQ1IsQ0FBQyxFQUFFO29CQUNELEtBQUssRUFBRSx3QkFBd0I7b0JBQy9CLElBQUksRUFBRSxjQUFjO2lCQUNyQjtnQkFDRCxLQUFLLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLHdCQUF3QjtvQkFDL0IsSUFBSSxFQUFFLGNBQWM7aUJBQ3JCO2FBQ0Y7U0FDRixDQUFDLENBQUM7UUFFSCxhQUFNLENBQUMsU0FBUyxDQUFjLHFCQUFxQixDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNoRSxJQUFJLEVBQUUsS0FBSztZQUNYLEtBQUssRUFBRSxjQUFjO1lBQ3JCLFNBQVMsRUFBRSxFQUFFO1lBQ2IsRUFBRSxFQUFFLENBQUMscUJBQXFCLEVBQUUseUJBQXlCLENBQUM7WUFDdEQsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztZQUNoQixNQUFNLEVBQUUsK0NBQStDO1NBQ3hELENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuXG5pbXBvcnQge0Jpbk5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvYmluJztcbmltcG9ydCB7TW9kZWwsIE1vZGVsV2l0aEZpZWxkfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9tb2RlbCc7XG5pbXBvcnQge0JpblRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vLi4vc3JjL3RyYW5zZm9ybSc7XG5pbXBvcnQge1ZnVHJhbnNmb3JtfSBmcm9tICcuLi8uLi8uLi9zcmMvdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmZ1bmN0aW9uIGFzc2VtYmxlRnJvbUVuY29kaW5nKG1vZGVsOiBNb2RlbFdpdGhGaWVsZCkge1xuICByZXR1cm4gQmluTm9kZS5tYWtlQmluRnJvbUVuY29kaW5nKG1vZGVsKS5hc3NlbWJsZSgpO1xufVxuXG5mdW5jdGlvbiBhc3NlbWJsZUZyb21UcmFuc2Zvcm0obW9kZWw6IE1vZGVsLCB0OiBCaW5UcmFuc2Zvcm0pIHtcbiAgcmV0dXJuIEJpbk5vZGUubWFrZUZyb21UcmFuc2Zvcm0odCwge21vZGVsfSkuYXNzZW1ibGUoKTtcbn1cblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS9iaW4nLCBmdW5jdGlvbigpIHtcbiAgaXQoJ3Nob3VsZCBhZGQgYmluIHRyYW5zZm9ybSBhbmQgY29ycmVjdGx5IGFwcGx5IGJpbiB3aXRoIGN1c3RvbSBleHRlbnQnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICBlbmNvZGluZzoge1xuICAgICAgICB5OiB7XG4gICAgICAgICAgYmluOiB7ZXh0ZW50OiBbMCwgMTAwXX0sXG4gICAgICAgICAgJ2ZpZWxkJzogJ0FjY2VsZXJhdGlvbicsXG4gICAgICAgICAgJ3R5cGUnOiAncXVhbnRpdGF0aXZlJ1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhc3NlcnQuZGVlcEVxdWFsPFZnVHJhbnNmb3JtPihhc3NlbWJsZUZyb21FbmNvZGluZyhtb2RlbClbMF0sIHtcbiAgICAgIHR5cGU6ICdiaW4nLFxuICAgICAgZmllbGQ6ICdBY2NlbGVyYXRpb24nLFxuICAgICAgYXM6IFsnYmluX2V4dGVudF8wXzEwMF9tYXhiaW5zXzEwX0FjY2VsZXJhdGlvbicsICdiaW5fZXh0ZW50XzBfMTAwX21heGJpbnNfMTBfQWNjZWxlcmF0aW9uX2VuZCddLFxuICAgICAgbWF4YmluczogMTAsXG4gICAgICBleHRlbnQ6IFswLCAxMDBdLFxuICAgICAgc2lnbmFsOiBcImJpbl9leHRlbnRfMF8xMDBfbWF4Ymluc18xMF9BY2NlbGVyYXRpb25fYmluc1wiLFxuICAgIH0pO1xuICB9KTtcblxuICBpdCAoJ3Nob3VsZCBhZGQgYmluIHRyYW5zZm9ybSBhbmQgY29ycmVjdGx5IGFwcGx5IGJpbiBmb3IgYmlubmVkIGZpZWxkIHdpdGhvdXQgY3VzdG9tIGV4dGVudCcsICgpID0+IHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICBlbmNvZGluZzoge1xuICAgICAgICB5OiB7XG4gICAgICAgICAgYmluOiB0cnVlLFxuICAgICAgICAgICdmaWVsZCc6ICdBY2NlbGVyYXRpb24nLFxuICAgICAgICAgICd0eXBlJzogJ3F1YW50aXRhdGl2ZSdcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IGFzc2VtYmxlRnJvbUVuY29kaW5nKG1vZGVsKTtcbiAgICBhc3NlcnQuZGVlcEVxdWFsKHRyYW5zZm9ybS5sZW5ndGgsIDIpO1xuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm0+KHRyYW5zZm9ybVswXSwge1xuICAgICAgdHlwZTogJ2V4dGVudCcsXG4gICAgICBmaWVsZDogJ0FjY2VsZXJhdGlvbicsXG4gICAgICBzaWduYWw6ICdiaW5fbWF4Ymluc18xMF9BY2NlbGVyYXRpb25fZXh0ZW50J1xuICAgIH0pO1xuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm0+KHRyYW5zZm9ybVsxXSwge1xuICAgICAgdHlwZTogJ2JpbicsXG4gICAgICBmaWVsZDogJ0FjY2VsZXJhdGlvbicsXG4gICAgICBhczogWydiaW5fbWF4Ymluc18xMF9BY2NlbGVyYXRpb24nLCAnYmluX21heGJpbnNfMTBfQWNjZWxlcmF0aW9uX2VuZCddLFxuICAgICAgbWF4YmluczogMTAsXG4gICAgICBzaWduYWw6ICdiaW5fbWF4Ymluc18xMF9BY2NlbGVyYXRpb25fYmlucycsXG4gICAgICBleHRlbnQ6IHtzaWduYWw6ICdiaW5fbWF4Ymluc18xMF9BY2NlbGVyYXRpb25fZXh0ZW50J31cbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhcHBseSB0aGUgYmluIHRyYW5zZm9ybSBvbmx5IG9uY2UgZm9yIGEgYmlubmVkIGZpZWxkIGVuY29kZWQgaW4gbXVsdGlwbGUgY2hhbm5lbHMnLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICBkYXRhOiB7dXJsOiBcImRhdGEvbW92aWVzLmpzb25cIn0sXG4gICAgICBtYXJrOiBcImNpcmNsZVwiLFxuICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgeDoge1xuICAgICAgICAgIGJpbjogdHJ1ZSxcbiAgICAgICAgICBmaWVsZDogXCJSb3R0ZW5fVG9tYXRvZXNfUmF0aW5nXCIsXG4gICAgICAgICAgdHlwZTogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICB9LFxuICAgICAgICBjb2xvcjoge1xuICAgICAgICAgIGJpbjoge1wibWF4Ymluc1wiOiAxMH0sXG4gICAgICAgICAgZmllbGQ6IFwiUm90dGVuX1RvbWF0b2VzX1JhdGluZ1wiLFxuICAgICAgICAgIHR5cGU6IFwib3JkaW5hbFwiXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBhc3NlbWJsZUZyb21FbmNvZGluZyhtb2RlbCk7XG4gICAgYXNzZXJ0LmRlZXBFcXVhbCh0cmFuc2Zvcm0ubGVuZ3RoLCAzKTtcbiAgICBhc3NlcnQuZGVlcEVxdWFsPFZnVHJhbnNmb3JtPih0cmFuc2Zvcm1bMF0sIHtcbiAgICAgIHR5cGU6ICdleHRlbnQnLFxuICAgICAgZmllbGQ6ICdSb3R0ZW5fVG9tYXRvZXNfUmF0aW5nJyxcbiAgICAgIHNpZ25hbDogJ2Jpbl9tYXhiaW5zXzEwX1JvdHRlbl9Ub21hdG9lc19SYXRpbmdfZXh0ZW50J1xuICAgIH0pO1xuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm0+KHRyYW5zZm9ybVsxXSwge1xuICAgICAgdHlwZTogJ2JpbicsXG4gICAgICBmaWVsZDogJ1JvdHRlbl9Ub21hdG9lc19SYXRpbmcnLFxuICAgICAgYXM6XG4gICAgICBbICdiaW5fbWF4Ymluc18xMF9Sb3R0ZW5fVG9tYXRvZXNfUmF0aW5nJyxcbiAgICAgICAgJ2Jpbl9tYXhiaW5zXzEwX1JvdHRlbl9Ub21hdG9lc19SYXRpbmdfZW5kJyBdLFxuICAgICAgc2lnbmFsOiAnYmluX21heGJpbnNfMTBfUm90dGVuX1RvbWF0b2VzX1JhdGluZ19iaW5zJyxcbiAgICAgIG1heGJpbnM6IDEwLFxuICAgICAgZXh0ZW50OiB7c2lnbmFsOiAnYmluX21heGJpbnNfMTBfUm90dGVuX1RvbWF0b2VzX1JhdGluZ19leHRlbnQnfVxuICAgIH0pO1xuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm0+KHRyYW5zZm9ybVsyXSwge1xuICAgICAgdHlwZTogJ2Zvcm11bGEnLFxuICAgICAgYXM6ICdiaW5fbWF4Ymluc18xMF9Sb3R0ZW5fVG9tYXRvZXNfUmF0aW5nX3JhbmdlJyxcbiAgICAgIGV4cHI6IGBkYXR1bVtcImJpbl9tYXhiaW5zXzEwX1JvdHRlbl9Ub21hdG9lc19SYXRpbmdcIl0gPT09IG51bGwgfHwgaXNOYU4oZGF0dW1bXCJiaW5fbWF4Ymluc18xMF9Sb3R0ZW5fVG9tYXRvZXNfUmF0aW5nXCJdKSA/IFwibnVsbFwiIDogZm9ybWF0KGRhdHVtW1wiYmluX21heGJpbnNfMTBfUm90dGVuX1RvbWF0b2VzX1JhdGluZ1wiXSwgXCJcIikgKyBcIiAtIFwiICsgZm9ybWF0KGRhdHVtW1wiYmluX21heGJpbnNfMTBfUm90dGVuX1RvbWF0b2VzX1JhdGluZ19lbmRcIl0sIFwiXCIpYFxuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGFkZCBiaW4gdHJhbnNmb3JtIGZyb20gdHJhbnNmb3JtIGFycmF5IGFuZCBjb3JyZWN0bHkgYXBwbHkgYmluIHdpdGggY3VzdG9tIGV4dGVudCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHQ6IEJpblRyYW5zZm9ybSA9IHtcbiAgICAgIGJpbjoge2V4dGVudDogWzAsIDEwMF19LFxuICAgICAgZmllbGQ6ICdBY2NlbGVyYXRpb24nLFxuICAgICAgYXM6ICdiaW5uZWRfYWNjZWxlcmF0aW9uJ1xuICAgIH07XG5cbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgIGRhdGE6IHt1cmw6IFwiZGF0YS9tb3ZpZXMuanNvblwifSxcbiAgICAgIG1hcms6IFwiY2lyY2xlXCIsXG4gICAgICB0cmFuc2Zvcm06IFt0XSxcbiAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgIHg6IHtcbiAgICAgICAgICBmaWVsZDogXCJSb3R0ZW5fVG9tYXRvZXNfUmF0aW5nXCIsXG4gICAgICAgICAgdHlwZTogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICB9LFxuICAgICAgICBjb2xvcjoge1xuICAgICAgICAgIGZpZWxkOiBcIlJvdHRlbl9Ub21hdG9lc19SYXRpbmdcIixcbiAgICAgICAgICB0eXBlOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm0+KGFzc2VtYmxlRnJvbVRyYW5zZm9ybShtb2RlbCwgdClbMF0sIHtcbiAgICAgIHR5cGU6ICdiaW4nLFxuICAgICAgZmllbGQ6ICdBY2NlbGVyYXRpb24nLFxuICAgICAgXCJtYXhiaW5zXCI6IDEwLFxuICAgICAgYXM6IFsnYmlubmVkX2FjY2VsZXJhdGlvbicsICdiaW5uZWRfYWNjZWxlcmF0aW9uX2VuZCddLFxuICAgICAgZXh0ZW50OiBbMCwgMTAwXSxcbiAgICAgIHNpZ25hbDogXCJiaW5fZXh0ZW50XzBfMTAwX21heGJpbnNfMTBfQWNjZWxlcmF0aW9uX2JpbnNcIixcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhZGQgYmluIHRyYW5zZm9ybSBmcm9tIHRyYW5zZm9ybSBhcnJheSBhbmQgY29ycmVjdGx5IGFwcGx5IGJpbiB3aXRoIGN1c3RvbSBleHRlbnQnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCB0OiBCaW5UcmFuc2Zvcm0gPSB7XG4gICAgICBiaW46IHtleHRlbnQ6IFswLCAxMDBdLCBtYXhiaW5zOiAyMH0sXG4gICAgICBmaWVsZDogJ0FjY2VsZXJhdGlvbicsXG4gICAgICBhczogJ2Jpbm5lZF9hY2NlbGVyYXRpb24nXG4gICAgfTtcblxuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgZGF0YToge3VybDogXCJkYXRhL21vdmllcy5qc29uXCJ9LFxuICAgICAgbWFyazogXCJjaXJjbGVcIixcbiAgICAgIHRyYW5zZm9ybTogW3RdLFxuICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgeDoge1xuICAgICAgICAgIGZpZWxkOiBcIlJvdHRlbl9Ub21hdG9lc19SYXRpbmdcIixcbiAgICAgICAgICB0eXBlOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgIH0sXG4gICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgZmllbGQ6IFwiUm90dGVuX1RvbWF0b2VzX1JhdGluZ1wiLFxuICAgICAgICAgIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ1RyYW5zZm9ybT4oYXNzZW1ibGVGcm9tVHJhbnNmb3JtKG1vZGVsLCB0KVswXSwge1xuICAgICAgdHlwZTogJ2JpbicsXG4gICAgICBmaWVsZDogJ0FjY2VsZXJhdGlvbicsXG4gICAgICBcIm1heGJpbnNcIjogMjAsXG4gICAgICBhczogWydiaW5uZWRfYWNjZWxlcmF0aW9uJywgJ2Jpbm5lZF9hY2NlbGVyYXRpb25fZW5kJ10sXG4gICAgICBleHRlbnQ6IFswLCAxMDBdLFxuICAgICAgc2lnbmFsOiBcImJpbl9leHRlbnRfMF8xMDBfbWF4Ymluc18yMF9BY2NlbGVyYXRpb25fYmluc1wiLFxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/data/dataflow.test.js b/build/test/compile/data/dataflow.test.js new file mode 100644 index 0000000000..0438247af6 --- /dev/null +++ b/build/test/compile/data/dataflow.test.js @@ -0,0 +1,86 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var dataflow_1 = require("../../../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 dataflow_1.DataFlowNode('a'); + var b = new dataflow_1.DataFlowNode('b'); + b.parent = a; + var c = new dataflow_1.DataFlowNode('c'); + c.parent = b; + var d = new dataflow_1.DataFlowNode('d'); + d.parent = c; + c.swapWithParent(); + chai_1.assert.equal(a.numChildren(), 1); + chai_1.assert.equal(a.children[0].debugName, 'c'); + chai_1.assert.equal(b.numChildren(), 1); + chai_1.assert.equal(b.children[0].debugName, 'd'); + chai_1.assert.equal(c.numChildren(), 1); + chai_1.assert.equal(c.children[0].debugName, 'b'); + chai_1.assert.equal(d.numChildren(), 0); + }); + it('should correctly swap two nodes', function () { + var root = new dataflow_1.DataFlowNode('root'); + var parent = new dataflow_1.DataFlowNode('parent'); + parent.parent = root; + var node = new dataflow_1.DataFlowNode('node'); + node.parent = parent; + var child1 = new dataflow_1.DataFlowNode('child1'); + child1.parent = node; + var child2 = new dataflow_1.DataFlowNode('child2'); + child2.parent = node; + var parentChild1 = new dataflow_1.DataFlowNode('parentChild1'); + parentChild1.parent = parent; + var parentChild2 = new dataflow_1.DataFlowNode('parentChild2'); + parentChild2.parent = parent; + node.swapWithParent(); + chai_1.assert.equal(root.numChildren(), 1); + chai_1.assert.equal(root.children[0].debugName, 'node'); + chai_1.assert.equal(node.parent.debugName, 'root'); + chai_1.assert.equal(node.numChildren(), 1); + chai_1.assert.equal(node.children[0].debugName, 'parent'); + chai_1.assert.equal(parent.parent.debugName, 'node'); + chai_1.assert.equal(parent.numChildren(), 4); + parent.children.forEach(function (c) { + chai_1.assert.equal(c.numChildren(), 0); + chai_1.assert.equal(c.parent.debugName, 'parent'); + }); + }); + }); + describe('remove', function () { + it('should remove node from dataflow', function () { + var a = new dataflow_1.DataFlowNode('a'); + var b = new dataflow_1.DataFlowNode('b'); + b.parent = a; + var c = new dataflow_1.DataFlowNode('c'); + c.parent = b; + chai_1.assert.deepEqual(a.children, [b]); + chai_1.assert.equal(b.parent, a); + chai_1.assert.equal(c.parent, b); + b.remove(); + chai_1.assert.deepEqual(a.children, [c]); + chai_1.assert.equal(c.parent, a); + }); + }); + describe('insertAsParentOf', function () { + it('should insert node into dataflow', function () { + var a = new dataflow_1.DataFlowNode('a'); + var anotherChild = new dataflow_1.DataFlowNode('a'); + var b = new dataflow_1.DataFlowNode('b'); + var c = new dataflow_1.DataFlowNode('c'); + anotherChild.parent = a; + c.parent = a; + b.insertAsParentOf(c); + chai_1.assert.sameDeepMembers(a.children, [anotherChild, b]); + chai_1.assert.equal(b.parent, a); + chai_1.assert.equal(c.parent, b); + chai_1.assert.equal(anotherChild.parent, a); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWZsb3cudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL2RhdGFmbG93LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLCtEQUFnRTtBQUVoRSxRQUFRLENBQUMsdUJBQXVCLEVBQUU7SUFDaEMsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixRQUFRLENBQUMsTUFBTSxFQUFFO1lBQ2YsRUFBRSxDQUFDLG1EQUFtRCxFQUFFO2dCQUN0RCxJQUFNLENBQUMsR0FBRyxJQUFJLHVCQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2hDLElBQU0sQ0FBQyxHQUFHLElBQUksdUJBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDaEMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBRWIsSUFBTSxDQUFDLEdBQUcsSUFBSSx1QkFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFFYixJQUFNLENBQUMsR0FBRyxJQUFJLHVCQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2hDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUViLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFFbkIsYUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pDLGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBRTNDLGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNqQyxhQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFR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Q3hCLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUViLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFdEIsYUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDMUIsYUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUMxQixhQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtEYXRhRmxvd05vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvZGF0YWZsb3cnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9kYXRhL2RhdGFmbG93JywgZnVuY3Rpb24oKSB7XG4gIGRlc2NyaWJlKCdEYXRhRmxvd05vZGUnLCBmdW5jdGlvbigpIHtcbiAgICBkZXNjcmliZSgnc3dhcCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IHN3YXAgdHdvIG5vZGVzIGluIGEgc2ltcGxlIGNoYWluJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IGEgPSBuZXcgRGF0YUZsb3dOb2RlKCdhJyk7XG4gICAgICAgIGNvbnN0IGIgPSBuZXcgRGF0YUZsb3dOb2RlKCdiJyk7XG4gICAgICAgIGIucGFyZW50ID0gYTtcblxuICAgICAgICBjb25zdCBjID0gbmV3IERhdGFGbG93Tm9kZSgnYycpO1xuICAgICAgICBjLnBhcmVudCA9IGI7XG5cbiAgICAgICAgY29uc3QgZCA9IG5ldyBEYXRhRmxvd05vZGUoJ2QnKTtcbiAgICAgICAgZC5wYXJlbnQgPSBjO1xuXG4gICAgICAgIGMuc3dhcFdpdGhQYXJlbnQoKTtcblxuICAgICAgICBhc3NlcnQuZXF1YWwoYS5udW1DaGlsZHJlbigpLCAxKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGEuY2hpbGRyZW5bMF0uZGVidWdOYW1lLCAnYycpO1xuXG4gICAgICAgIGFzc2VydC5lcXVhbChiLm51bUNoaWxkcmVuKCksIDEpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoYi5jaGlsZHJlblswXS5kZWJ1Z05hbWUsICdkJyk7XG5cbiAgICAgICAgYXNzZXJ0LmVxdWFsKGMubnVtQ2hpbGRyZW4oKSwgMSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChjLmNoaWxkcmVuWzBdLmRlYnVnTmFtZSwgJ2InKTtcblxuICAgICAgICBhc3NlcnQuZXF1YWwoZC5udW1DaGlsZHJlbigpLCAwKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBzd2FwIHR3byBub2RlcycsIGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCByb290ID0gbmV3IERhdGFGbG93Tm9kZSgncm9vdCcpO1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBuZXcgRGF0YUZsb3dOb2RlKCdwYXJlbnQnKTtcbiAgICAgICAgcGFyZW50LnBhcmVudCA9IHJvb3Q7XG5cbiAgICAgICAgY29uc3Qgbm9kZSA9IG5ldyBEYXRhRmxvd05vZGUoJ25vZGUnKTtcbiAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7XG5cbiAgICAgICAgY29uc3QgY2hpbGQxID0gbmV3IERhdGFGbG93Tm9kZSgnY2hpbGQxJyk7XG4gICAgICAgIGNoaWxkMS5wYXJlbnQgPSBub2RlO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkMiA9IG5ldyBEYXRhRmxvd05vZGUoJ2NoaWxkMicpO1xuICAgICAgICBjaGlsZDIucGFyZW50ID0gbm9kZTtcblxuICAgICAgICBjb25zdCBwYXJlbnRDaGlsZDEgPSBuZXcgRGF0YUZsb3dOb2RlKCdwYXJlbnRDaGlsZDEnKTtcbiAgICAgICAgcGFyZW50Q2hpbGQxLnBhcmVudCA9IHBhcmVudDtcblxuICAgICAgICBjb25zdCBwYXJlbnRDaGlsZDIgPSBuZXcgRGF0YUZsb3dOb2RlKCdwYXJlbnRDaGlsZDInKTtcbiAgICAgICAgcGFyZW50Q2hpbGQyLnBhcmVudCA9IHBhcmVudDtcblxuICAgICAgICBub2RlLnN3YXBXaXRoUGFyZW50KCk7XG5cbiAgICAgICAgYXNzZXJ0LmVxdWFsKHJvb3QubnVtQ2hpbGRyZW4oKSwgMSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChyb290LmNoaWxkcmVuWzBdLmRlYnVnTmFtZSwgJ25vZGUnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG5vZGUucGFyZW50LmRlYnVnTmFtZSwgJ3Jvb3QnKTtcblxuICAgICAgICBhc3NlcnQuZXF1YWwobm9kZS5udW1DaGlsZHJlbigpLCAxKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG5vZGUuY2hpbGRyZW5bMF0uZGVidWdOYW1lLCAncGFyZW50Jyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChwYXJlbnQucGFyZW50LmRlYnVnTmFtZSwgJ25vZGUnKTtcblxuICAgICAgICBhc3NlcnQuZXF1YWwocGFyZW50Lm51bUNoaWxkcmVuKCksIDQpO1xuICAgICAgICBwYXJlbnQuY2hpbGRyZW4uZm9yRWFjaChjID0+IHtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwoYy5udW1DaGlsZHJlbigpLCAwKTtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwoYy5wYXJlbnQuZGVidWdOYW1lLCAncGFyZW50Jyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncmVtb3ZlJywgZnVuY3Rpb24oKSB7XG4gICAgICBpdCgnc2hvdWxkIHJlbW92ZSBub2RlIGZyb20gZGF0YWZsb3cnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY29uc3QgYSA9IG5ldyBEYXRhRmxvd05vZGUoJ2EnKTtcbiAgICAgICAgY29uc3QgYiA9IG5ldyBEYXRhRmxvd05vZGUoJ2InKTtcbiAgICAgICAgYi5wYXJlbnQgPSBhO1xuXG4gICAgICAgIGNvbnN0IGMgPSBuZXcgRGF0YUZsb3dOb2RlKCdjJyk7XG4gICAgICAgIGMucGFyZW50ID0gYjtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKGEuY2hpbGRyZW4sIFtiXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChiLnBhcmVudCwgYSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChjLnBhcmVudCwgYik7XG5cbiAgICAgICAgYi5yZW1vdmUoKTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKGEuY2hpbGRyZW4sIFtjXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChjLnBhcmVudCwgYSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdpbnNlcnRBc1BhcmVudE9mJywgZnVuY3Rpb24oKSB7XG4gICAgICBpdCgnc2hvdWxkIGluc2VydCBub2RlIGludG8gZGF0YWZsb3cnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY29uc3QgYSA9IG5ldyBEYXRhRmxvd05vZGUoJ2EnKTtcbiAgICAgICAgY29uc3QgYW5vdGhlckNoaWxkID0gbmV3IERhdGFGbG93Tm9kZSgnYScpO1xuICAgICAgICBjb25zdCBiID0gbmV3IERhdGFGbG93Tm9kZSgnYicpO1xuICAgICAgICBjb25zdCBjID0gbmV3IERhdGFGbG93Tm9kZSgnYycpO1xuXG4gICAgICAgIGFub3RoZXJDaGlsZC5wYXJlbnQgPSBhO1xuICAgICAgICBjLnBhcmVudCA9IGE7XG5cbiAgICAgICAgYi5pbnNlcnRBc1BhcmVudE9mKGMpO1xuXG4gICAgICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoYS5jaGlsZHJlbiwgW2Fub3RoZXJDaGlsZCwgYl0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwoYi5wYXJlbnQsIGEpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoYy5wYXJlbnQsIGIpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoYW5vdGhlckNoaWxkLnBhcmVudCwgYSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/data/facet.test.js b/build/test/compile/data/facet.test.js new file mode 100644 index 0000000000..5789b95bfd --- /dev/null +++ b/build/test/compile/data/facet.test.js @@ -0,0 +1,114 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var facet_1 = require("../../../src/compile/data/facet"); +var util_1 = require("../../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 = util_1.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 facet_1.FacetNode(model, 'facetName', 'dataName'); + var data = node.assemble(); + chai_1.assert.deepEqual(data[0], { + name: 'column_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['gender'], + fields: ['age'], + ops: ['distinct'] + }] + }); + }); + 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 = util_1.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 facet_1.FacetNode(model, 'facetName', 'dataName'); + var data = node.assemble(); + // crossed data + chai_1.assert.deepEqual(data[0], { + name: 'cross_column_domain_row_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['c', 'r'], + fields: ['a', 'b'], + ops: ['distinct', 'distinct'] + }] + }); + chai_1.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'] + }] + }); + chai_1.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'] + }] + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL2ZhY2V0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIseURBQTBEO0FBQzFELG1DQUFvRDtBQUVwRCxRQUFRLENBQUMsb0JBQW9CLEVBQUU7SUFDN0IsUUFBUSxDQUFDLFVBQVUsRUFBRTtRQUNuQixFQUFFLENBQUMsdUZBQXVGLEVBQUU7WUFDMUYsSUFBTSxLQUFLLEdBQUcsK0JBQXdCLENBQUM7Z0JBQ3JDLFNBQVMsRUFBRSxpREFBaUQ7Z0JBQzVELGFBQWEsRUFBRSw4RkFBOEY7Z0JBQzdHLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxzQkFBc0IsRUFBQztnQkFDdkMsT0FBTyxFQUFFLEVBQUMsUUFBUSxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDLEVBQUM7Z0JBQzNELE1BQU0sRUFBRTtvQkFDTixNQUFNLEVBQUUsS0FBSztvQkFDYixVQUFVLEVBQUU7d0JBQ1YsR0FBRyxFQUFFOzRCQUNILFdBQVcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsY0FBYzs0QkFDN0QsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQzt5QkFDaEM7d0JBQ0QsR0FBRyxFQUFFOzRCQUNILE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVM7NEJBQ2pDLE9BQU8sRUFBRSxFQUFDLFdBQVcsRUFBRSxFQUFFLEVBQUM7eUJBQzNCO3dCQUNELE9BQU8sRUFBRTs0QkFDUCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTOzRCQUNwQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxTQUFTLEVBQUMsU0FBUyxDQUFDLEVBQUM7eUJBQzFDO3FCQUNGO2lCQUNGO2dCQUNELFNBQVMsRUFB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QUFHLENBQUM7d0JBQ2xCLEdBQUcsRUFBRSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUM7cUJBQzlCLENBQUM7YUFDSCxDQUFDLENBQUM7WUFFSCxhQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDeEIsSUFBSSxFQUFFLGVBQWU7Z0JBQ3JCLE1BQU0sRUFBRSxnQ0FBZ0M7Z0JBQ3hDLFNBQVMsRUFBQyxDQUFDO3dCQUNULElBQUksRUFBRSxXQUFXO3dCQUNqQixPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUM7d0JBQ2QsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDO3dCQUN0QixHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUM7d0JBQ1osRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDO3FCQUNuQixDQUFDO2FBQ0gsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3hCLElBQUksRUFBRSxZQUFZO2dCQUNsQixNQUFNLEVBQUUsZ0NBQWdDO2dCQUN4QyxTQUFTLEVBQUMsQ0FBQzt3QkFDVCxJQUFJLEVBQUUsV0FBVzt3QkFDakIsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDO3dCQUNkLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQzt3QkFDdEIsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDO3dCQUNaLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQztxQkFDbkIsQ0FBQzthQUNILENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7RmFjZXROb2RlfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2ZhY2V0JztcbmltcG9ydCB7cGFyc2VGYWNldE1vZGVsV2l0aFNjYWxlfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS9mYWNldCcsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnYXNzZW1ibGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjYWxjdWxhdGUgY29sdW1uIGRpc3RpbmN0IGlmIGNoaWxkIGhhcyBhbiBpbmRlcGVuZGVudCBkaXNjcmV0ZSBzY2FsZSB3aXRoIHN0ZXAnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgICckc2NoZW1hJzogJ2h0dHBzOi8vdmVnYS5naXRodWIuaW8vc2NoZW1hL3ZlZ2EtbGl0ZS92Mi5qc29uJyxcbiAgICAgICAgJ2Rlc2NyaXB0aW9uJzogJ0EgdHJlbGxpcyBiYXIgY2hhcnQgc2hvd2luZyB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBhbmQgZ2VuZGVyIGluIDIwMDAuJyxcbiAgICAgICAgJ2RhdGEnOiB7J3VybCc6ICdkYXRhL3BvcHVsYXRpb24uanNvbid9LFxuICAgICAgICAnZmFjZXQnOiB7J2NvbHVtbic6IHsnZmllbGQnOiAnZ2VuZGVyJywgJ3R5cGUnOiAnbm9taW5hbCd9fSxcbiAgICAgICAgJ3NwZWMnOiB7XG4gICAgICAgICAgJ21hcmsnOiAnYmFyJyxcbiAgICAgICAgICAnZW5jb2RpbmcnOiB7XG4gICAgICAgICAgICAneSc6IHtcbiAgICAgICAgICAgICAgJ2FnZ3JlZ2F0ZSc6ICdzdW0nLCAnZmllbGQnOiAncGVvcGxlJywgJ3R5cGUnOiAncXVhbnRpdGF0aXZlJyxcbiAgICAgICAgICAgICAgJ2F4aXMnOiB7J3RpdGxlJzogJ3BvcHVsYXRpb24nfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICd4Jzoge1xuICAgICAgICAgICAgICAnZmllbGQnOiAnYWdlJywgJ3R5cGUnOiAnb3JkaW5hbCcsXG4gICAgICAgICAgICAgICdzY2FsZSc6IHsncmFuZ2VTdGVwJzogMTd9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ2NvbG9yJzoge1xuICAgICAgICAgICAgICAnZmllbGQnOiAnZ2VuZGVyJywgJ3R5cGUnOiAnbm9taW5hbCcsXG4gICAgICAgICAgICAgICdzY2FsZSc6IHsncmFuZ2UnOiBbJyNFQTk4RDInLCcjNjU5Q0NBJ119XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAncmVzb2x2ZSc6IHtcbiAgICAgICAgICAnc2NhbGUnOiB7J3gnOiAnaW5kZXBlbmRlbnQnfVxuICAgICAgICB9LFxuICAgICAgICAnY29uZmlnJzogeyd2aWV3JzogeydmaWxsJzogJ3llbGxvdyd9fVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG5vZGUgPSBuZXcgRmFjZXROb2RlKG1vZGVsLCAnZmFjZXROYW1lJywgJ2RhdGFOYW1lJyk7XG4gICAgICBjb25zdCBkYXRhID0gbm9kZS5hc3NlbWJsZSgpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGRhdGFbMF0sIHtcbiAgICAgICAgbmFtZTogJ2NvbHVtbl9kb21haW4nLFxuICAgICAgICBzb3VyY2U6ICdkYXRhTmFtZScsXG4gICAgICAgIHRyYW5zZm9ybTpbe1xuICAgICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICAgIGdyb3VwYnk6IFsnZ2VuZGVyJ10sXG4gICAgICAgICAgZmllbGRzOiBbJ2FnZSddLFxuICAgICAgICAgIG9wczogWydkaXN0aW5jdCddXG4gICAgICAgIH1dXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsY3VsYXRlIGNvbHVtbiBhbmQgcm93IGRpc3RpbmN0IGlmIGNoaWxkIGhhcyBhbiBpbmRlcGVuZGVudCBkaXNjcmV0ZSBzY2FsZSB3aXRoIHN0ZXAgYW5kIHRoZSBmYWNldCBoYXMgYm90aCByb3cgYW5kIGNvbHVtbicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgJyRzY2hlbWEnOiAnaHR0cHM6Ly92ZWdhLmdpdGh1Yi5pby9zY2hlbWEvdmVnYS1saXRlL3YyLmpzb24nLFxuICAgICAgICAnZGF0YSc6IHsndmFsdWVzJzogW1xuICAgICAgICAgIHsncic6ICdyMScsICdjJzogJ2MxJywgJ2EnOiAnYTEnLCAnYic6ICdiMSd9LFxuICAgICAgICAgIHsncic6ICdyMScsICdjJzogJ2MxJywgJ2EnOiAnYTInLCAnYic6ICdiMid9LFxuICAgICAgICAgIHsncic6ICdyMicsICdjJzogJ2MyJywgJ2EnOiAnYTEnLCAnYic6ICdiMSd9LFxuICAgICAgICAgIHsncic6ICdyMycsICdjJzogJ2MyJywgJ2EnOiAnYTMnLCAnYic6ICdiMid9XG4gICAgICAgIF19LFxuICAgICAgICAnZmFjZXQnOiB7XG4gICAgICAgICAgJ3Jvdyc6IHsnZmllbGQnOiAncicsICd0eXBlJzogJ25vbWluYWwnfSxcbiAgICAgICAgICAnY29sdW1uJzogeydmaWVsZCc6ICdjJywgJ3R5cGUnOiAnbm9taW5hbCd9XG4gICAgICAgIH0sXG4gICAgICAgICdzcGVjJzoge1xuICAgICAgICAgICdtYXJrJzogJ3JlY3QnLFxuICAgICAgICAgICdlbmNvZGluZyc6IHtcbiAgICAgICAgICAgICd5JzogeydmaWVsZCc6ICdiJywgJ3R5cGUnOiAnbm9taW5hbCd9LFxuICAgICAgICAgICAgJ3gnOiB7J2ZpZWxkJzogJ2EnLCAndHlwZSc6ICdub21pbmFsJ31cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgICdyZXNvbHZlJzoge1xuICAgICAgICAgICdzY2FsZSc6IHtcbiAgICAgICAgICAgICd4JzogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICd5JzogJ2luZGVwZW5kZW50J1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG5vZGUgPSBuZXcgRmFjZXROb2RlKG1vZGVsLCAnZmFjZXROYW1lJywgJ2RhdGFOYW1lJyk7XG4gICAgICBjb25zdCBkYXRhID0gbm9kZS5hc3NlbWJsZSgpO1xuXG4gICAgICAvLyBjcm9zc2VkIGRhdGFcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZGF0YVswXSwge1xuICAgICAgICBuYW1lOiAnY3Jvc3NfY29sdW1uX2RvbWFpbl9yb3dfZG9tYWluJyxcbiAgICAgICAgc291cmNlOiAnZGF0YU5hbWUnLFxuICAgICAgICB0cmFuc2Zvcm06W3tcbiAgICAgICAgICB0eXBlOiAnYWdncmVnYXRlJyxcbiAgICAgICAgICBncm91cGJ5OiBbJ2MnLCAnciddLFxuICAgICAgICAgIGZpZWxkczogWydhJywgJ2InXSxcbiAgICAgICAgICBvcHM6IFsnZGlzdGluY3QnLCAnZGlzdGluY3QnXVxuICAgICAgICB9XVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZGF0YVsxXSwge1xuICAgICAgICBuYW1lOiAnY29sdW1uX2RvbWFpbicsXG4gICAgICAgIHNvdXJjZTogJ2Nyb3NzX2NvbHVtbl9kb21haW5fcm93X2RvbWFpbicsXG4gICAgICAgIHRyYW5zZm9ybTpbe1xuICAgICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICAgIGdyb3VwYnk6IFsnYyddLFxuICAgICAgICAgIGZpZWxkczogWydkaXN0aW5jdF9hJ10sXG4gICAgICAgICAgb3BzOiBbJ21heCddLFxuICAgICAgICAgIGFzOiBbJ2Rpc3RpbmN0X2EnXVxuICAgICAgICB9XVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZGF0YVsyXSwge1xuICAgICAgICBuYW1lOiAncm93X2RvbWFpbicsXG4gICAgICAgIHNvdXJjZTogJ2Nyb3NzX2NvbHVtbl9kb21haW5fcm93X2RvbWFpbicsXG4gICAgICAgIHRyYW5zZm9ybTpbe1xuICAgICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICAgIGdyb3VwYnk6IFsnciddLFxuICAgICAgICAgIGZpZWxkczogWydkaXN0aW5jdF9iJ10sXG4gICAgICAgICAgb3BzOiBbJ21heCddLFxuICAgICAgICAgIGFzOiBbJ2Rpc3RpbmN0X2InXVxuICAgICAgICB9XVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/data/filter.test.js b/build/test/compile/data/filter.test.js new file mode 100644 index 0000000000..aba6fef5c2 --- /dev/null +++ b/build/test/compile/data/filter.test.js @@ -0,0 +1,46 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var formatparse_1 = require("../../../src/compile/data/formatparse"); +var parse_1 = require("../../../src/compile/data/parse"); +var util_1 = require("../../util"); +describe('compile/data/filter', function () { + it('should create parse for filtered fields', function () { + var model = util_1.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 node = parse_1.parseTransformArray(model).first; + while (node.numChildren() > 0) { + if (node instanceof formatparse_1.ParseNode) { + parse = __assign({}, parse, node.parse); + } + chai_1.assert.equal(node.numChildren(), 1); + node = node.children[0]; + } + chai_1.assert.deepEqual(parse, { + a: 'date', + b: 'string', + c: 'date', + d: 'number' + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9maWx0ZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsNkJBQTRCO0FBQzVCLHFFQUFnRTtBQUVoRSx5REFBb0U7QUFJcEUsbUNBQTBDO0FBRTFDLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtJQUM5QixFQUFFLENBQUMseUNBQXlDLEVBQUU7UUFDNUMsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztZQUMzQixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDO1lBQ3pCLFdBQVcsRUFBRTtnQkFDWCxFQUFDLFFBQVEsRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxFQUFDLEVBQUM7Z0JBQ2pELEVBQUMsUUFBUSxFQUFFLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUMsRUFBQztnQkFDL0MsRUFBQyxRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDLEVBQUMsRUFBQztnQkFDakUsRUFBQyxRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQyxFQUFDO2FBQzVDO1lBQ0QsTUFBTSxFQUFFLE9BQU87WUFDZixRQUFRLEVBQUUsRUFBRTtTQUNiLENBQUMsQ0FBQztRQUVILElBQUksS0FBSyxHQUFpQixFQUFFLENBQUM7UUFFN0IseUZBQXlGO1FBQ3BGLElBQUEsK0NBQVcsQ0FBK0I7UUFDL0MsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUIsRUFBRSxDQUFDLENBQUMsSUFBSSxZQUFZLHVCQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUM5QixLQUFLLGdCQUFPLEtBQUssRUFBSyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEMsQ0FBQztZQUNELGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3BDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFFRCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRTtZQUN0QixDQUFDLEVBQUUsTUFBTTtZQUNULENBQUMsRUFBRSxRQUFRO1lBQ1gsQ0FBQyxFQUFFLE1BQU07WUFDVCxDQUFDLEVBQUUsUUFBUTtTQUNaLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge1BhcnNlTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9mb3JtYXRwYXJzZSc7XG5pbXBvcnQge0xvb2t1cE5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvbG9va3VwJztcbmltcG9ydCB7cGFyc2VUcmFuc2Zvcm1BcnJheX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9wYXJzZSc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vc3JjL2xvZyc7XG5pbXBvcnQge0RpY3R9IGZyb20gJy4uLy4uLy4uL3NyYy91dGlsJztcbmltcG9ydCB7VmdMb29rdXBUcmFuc2Zvcm19IGZyb20gJy4uLy4uLy4uL3NyYy92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS9maWx0ZXInLCAoKSA9PiB7XG4gIGl0KCdzaG91bGQgY3JlYXRlIHBhcnNlIGZvciBmaWx0ZXJlZCBmaWVsZHMnLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAnZGF0YSc6IHsndXJsJzogJ2EuanNvbid9LFxuICAgICAgJ3RyYW5zZm9ybSc6IFtcbiAgICAgICAgeydmaWx0ZXInOiB7J2ZpZWxkJzogJ2EnLCAnZXF1YWwnOiB7eWVhcjogMjAwMH19fSxcbiAgICAgICAgeydmaWx0ZXInOiB7J2ZpZWxkJzogJ2InLCAnb25lT2YnOiBbJ2EnLCAnYiddfX0sXG4gICAgICAgIHsnZmlsdGVyJzogeydmaWVsZCc6ICdjJywgJ3JhbmdlJzogW3t5ZWFyOiAyMDAwfSwge3llYXI6IDIwMDF9XX19LFxuICAgICAgICB7J2ZpbHRlcic6IHsnZmllbGQnOiAnZCcsICdyYW5nZSc6IFsxLCAyXX19XG4gICAgICBdLFxuICAgICAgJ21hcmsnOiAncG9pbnQnLFxuICAgICAgZW5jb2Rpbmc6IHt9XG4gICAgfSk7XG5cbiAgICBsZXQgcGFyc2U6IERpY3Q8c3RyaW5nPiA9IHt9O1xuXG4gICAgLy8gZXh0cmFjdCB0aGUgcGFyc2UgZnJvbSB0aGUgcGFyc2Ugbm9kZXMgdGhhdCB3ZXJlIGdlbmVyYXRlZCBhbG9uZyB3aXRoIHRoZSBmaWx0ZXIgbm9kZXNcbiAgICBsZXQge2ZpcnN0OiBub2RlfSA9IHBhcnNlVHJhbnNmb3JtQXJyYXkobW9kZWwpO1xuICAgIHdoaWxlIChub2RlLm51bUNoaWxkcmVuKCkgPiAwKSB7XG4gICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFBhcnNlTm9kZSkge1xuICAgICAgICBwYXJzZSA9IHsuLi5wYXJzZSwgLi4ubm9kZS5wYXJzZX07XG4gICAgICB9XG4gICAgICBhc3NlcnQuZXF1YWwobm9kZS5udW1DaGlsZHJlbigpLCAxKTtcbiAgICAgIG5vZGUgPSBub2RlLmNoaWxkcmVuWzBdO1xuICAgIH1cblxuICAgIGFzc2VydC5kZWVwRXF1YWwocGFyc2UsIHtcbiAgICAgIGE6ICdkYXRlJyxcbiAgICAgIGI6ICdzdHJpbmcnLFxuICAgICAgYzogJ2RhdGUnLFxuICAgICAgZDogJ251bWJlcidcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/data/filterinvalid.test.js b/build/test/compile/data/filterinvalid.test.js new file mode 100644 index 0000000000..ac75c03638 --- /dev/null +++ b/build/test/compile/data/filterinvalid.test.js @@ -0,0 +1,62 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var filterinvalid_1 = require("../../../src/compile/data/filterinvalid"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../util"); +function parse(model) { + return filterinvalid_1.FilterInvalidNode.make(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 = util_2.parseUnitModelWithScale(spec); + chai_1.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 = util_2.parseUnitModelWithScale(util_1.mergeDeep(spec, { + config: { + invalidValues: 'filter' + } + })); + chai_1.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 = util_2.parseUnitModelWithScale(util_1.mergeDeep(spec, { + config: { + invalidValues: null + } + })); + chai_1.assert.deepEqual(parse(model), null); + }); + it('should add no null filter for count field', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + y: { aggregate: 'count', field: '*', type: "quantitative" } + } + }); + chai_1.assert.deepEqual(parse(model), null); + }); + }); + describe('assemble', function () { + // TODO: write + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyaW52YWxpZC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2RhdGEvZmlsdGVyaW52YWxpZC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUk1Qix5RUFBMEU7QUFHMUUsMENBQWtEO0FBQ2xELG1DQUFtRDtBQUVuRCxlQUFlLEtBQXFCO0lBQ2xDLE1BQU0sQ0FBQyxpQ0FBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUVELFFBQVEsQ0FBQyx5QkFBeUIsRUFBRTtJQUNsQyxRQUFRLENBQUMsYUFBYSxFQUFFO1FBQ3RCLElBQU0sSUFBSSxHQUFhO1lBQ3JCLElBQUksRUFBRSxPQUFPO1lBQ2IsUUFBUSxFQUFFO2dCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztnQkFDdEMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFDO2dCQUNsQyxLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7Z0JBQ3JDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzthQUN0QztTQUNGLENBQUM7UUFFRixFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsSUFBTSxLQUFLLEdBQUcsOEJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUMsYUFBTSxDQUFDLFNBQVMsQ0FBeUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRTtnQkFDNUQsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2dCQUN2QyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUM7YUFDcEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbUVBQW1FLEVBQUU7WUFDdEUsSUFBTSxLQUFLLEdBQUcsOEJBQXVCLENBQUMsZ0JBQVMsQ0FBcUIsSUFBSSxFQUFFO2dCQUN4RSxNQUFNLEVBQUU7b0JBQ04sYUFBYSxFQUFFLFFBQVE7aUJBQ3hCO2FBQ0YsQ0FBQyxDQUFDLENBQUM7WUFDSixhQUFNLENBQUMsU0FBUyxDQUF5QixLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUM1RCxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7Z0JBQ3ZDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBQzthQUNwQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5REFBeUQsRUFBRTtZQUM1RCxJQUFNLEtBQUssR0FBRyw4QkFBdUIsQ0FBQyxnQkFBUyxDQUFxQixJQUFJLEVBQUU7Z0JBQ3hFLE1BQU0sRUFBRTtvQkFDTixhQUFhLEVBQUUsSUFBSTtpQkFDcEI7YUFDRixDQUFDLENBQUMsQ0FBQztZQUNKLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFFLDJDQUEyQyxFQUFFO1lBQy9DLElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO2dCQUNwQyxJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7aUJBQzFEO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsY0FBYztJQUNoQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcblxuaW1wb3J0IHtUb3BMZXZlbCwgVW5pdFNwZWN9IGZyb20gJy4uLy4uLy4uL3NyYy9zcGVjJztcblxuaW1wb3J0IHtGaWx0ZXJJbnZhbGlkTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9maWx0ZXJpbnZhbGlkJztcbmltcG9ydCB7TW9kZWxXaXRoRmllbGR9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21vZGVsJztcbmltcG9ydCB7RmllbGREZWZ9IGZyb20gJy4uLy4uLy4uL3NyYy9maWVsZGRlZic7XG5pbXBvcnQge0RpY3QsIG1lcmdlRGVlcH0gZnJvbSAnLi4vLi4vLi4vc3JjL3V0aWwnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmZ1bmN0aW9uIHBhcnNlKG1vZGVsOiBNb2RlbFdpdGhGaWVsZCkge1xuICByZXR1cm4gRmlsdGVySW52YWxpZE5vZGUubWFrZShtb2RlbCk7XG59XG5cbmRlc2NyaWJlKCdjb21waWxlL2RhdGEvbnVsbGZpbHRlcicsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnY29tcGlsZVVuaXQnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBzcGVjOiBVbml0U3BlYyA9IHtcbiAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgIHk6IHtmaWVsZDogJ3FxJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIHg6IHtmaWVsZDogJ3R0JywgdHlwZTogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgY29sb3I6IHtmaWVsZDogJ29vJywgdHlwZTogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBzaGFwZToge2ZpZWxkOiAnbm4nLCB0eXBlOiBcIm5vbWluYWxcIn1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBhZGQgZmlsdGVyTnVsbCBmb3IgUSBhbmQgVCBieSBkZWZhdWx0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZShzcGVjKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8RGljdDxGaWVsZERlZjxzdHJpbmc+Pj4ocGFyc2UobW9kZWwpLmZpbHRlciwge1xuICAgICAgICBxcToge2ZpZWxkOiAncXEnLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgdHQ6IHtmaWVsZDogJ3R0JywgdHlwZTogXCJ0ZW1wb3JhbFwifVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBmaWx0ZXJOdWxsIGZvciBRIGFuZCBUIHdoZW4gaW52YWxpZFZhbHVlcyBpcyBcImZpbHRlclwiLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUobWVyZ2VEZWVwPFRvcExldmVsPFVuaXRTcGVjPj4oc3BlYywge1xuICAgICAgICBjb25maWc6IHtcbiAgICAgICAgICBpbnZhbGlkVmFsdWVzOiAnZmlsdGVyJ1xuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPERpY3Q8RmllbGREZWY8c3RyaW5nPj4+KHBhcnNlKG1vZGVsKS5maWx0ZXIsIHtcbiAgICAgICAgcXE6IHtmaWVsZDogJ3FxJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIHR0OiB7ZmllbGQ6ICd0dCcsIHR5cGU6IFwidGVtcG9yYWxcIn1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhZGQgbm8gbnVsbCBmaWx0ZXIgaWYgd2hlbiBpbnZhbGlkVmFsdWVzIGlzIG51bGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKG1lcmdlRGVlcDxUb3BMZXZlbDxVbml0U3BlYz4+KHNwZWMsIHtcbiAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgaW52YWxpZFZhbHVlczogbnVsbFxuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHBhcnNlKG1vZGVsKSwgbnVsbCk7XG4gICAgfSk7XG5cbiAgICBpdCAoJ3Nob3VsZCBhZGQgbm8gbnVsbCBmaWx0ZXIgZm9yIGNvdW50IGZpZWxkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB5OiB7YWdncmVnYXRlOiAnY291bnQnLCBmaWVsZDogJyonLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwYXJzZShtb2RlbCksIG51bGwpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYXNzZW1ibGUnLCBmdW5jdGlvbigpIHtcbiAgICAvLyBUT0RPOiB3cml0ZVxuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/data/formatparse.test.js b/build/test/compile/data/formatparse.test.js new file mode 100644 index 0000000000..079a1992a7 --- /dev/null +++ b/build/test/compile/data/formatparse.test.js @@ -0,0 +1,165 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* tslint:disable:quotemark */ +var chai_1 = require("chai"); +var formatparse_1 = require("../../../src/compile/data/formatparse"); +var log = require("../../../src/log"); +var util_1 = require("../../util"); +describe('compile/data/formatparse', function () { + describe('parseUnit', function () { + it('should return a correct parse for encoding mapping and filter transforms', function () { + var model = util_1.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" } + } + }); + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model).parse, { + a: 'number', + b: 'date', + date: 'date' + }); + }); + it('should parse binned fields as numbers.', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "a", "type": "ordinal", "bin": true }, + "y": { "field": "b", "type": "ordinal" } + } + }); + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model).parse, { + a: 'number' + }); + }); + it('should return a correct customized parse.', function () { + var model = util_1.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" } + } + }); + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model).parse, { + a: 'number', + b: 'date', + c: 'number', + d: 'date' + }); + }); + it('should include parse for all applicable fields, and exclude calculated fields', function () { + var model = util_1.parseUnitModel({ + transform: [{ calculate: 'datum["b"] * 2', as: 'b2' }], + mark: "point", + encoding: { + x: { field: 'a', type: "temporal" }, + y: { field: 'b', type: "quantitative" }, + color: { field: '*', type: "quantitative", aggregate: 'count' }, + size: { field: 'b2', type: "quantitative" }, + } + }); + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model).parse, { + 'a': 'date', + 'b': 'number' + }); + }); + it('should not parse fields with aggregate=missing/valid/distinct', function () { + var model = util_1.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" } + } + }); + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model), null); + }); + it('should not parse the same field twice', function () { + var model = util_1.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" } + } + } + }); + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model).parse, { + 'a': 'number' + }); + model.parseScale(); + model.parseData(); + chai_1.assert.deepEqual(model.child.component.data.ancestorParse, { + 'a': 'number', + 'b': 'date' + }); + // set the ancestor parse to see whether fields from it are not parsed + model.child.component.data.ancestorParse = { a: 'number' }; + chai_1.assert.deepEqual(formatparse_1.ParseNode.make(model.child).parse, { + 'b': 'date' + }); + }); + }); + describe('assembleTransforms', function () { + it('should assemble correct parse expressions', function () { + var p = new formatparse_1.ParseNode({ + n: 'number', + b: 'boolean', + s: 'string', + d1: 'date', + d2: 'date:"%y"', + d3: 'utc:"%y"' + }); + chai_1.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 show warning for unrecognized types', log.wrap(function (localLogger) { + var p = new formatparse_1.ParseNode({ + x: 'foo', + }); + chai_1.assert.deepEqual(p.assembleTransforms(), []); + chai_1.assert.equal(localLogger.warns[0], log.message.unrecognizedParse('foo')); + })); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0cGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL2Zvcm1hdHBhcnNlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw4QkFBOEI7QUFDOUIsNkJBQTRCO0FBRTVCLHFFQUFnRTtBQUVoRSxzQ0FBd0M7QUFDeEMsbUNBQTJEO0FBRTNELFFBQVEsQ0FBQywwQkFBMEIsRUFBRTtJQUNuQyxRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLEVBQUUsQ0FBQywwRUFBMEUsRUFBRTtZQUM3RSxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDO2dCQUN6QixXQUFXLEVBQUUsQ0FBQzt3QkFDWixRQUFRLEVBQUU7NEJBQ1IsS0FBSyxFQUFFO2dDQUNMLEtBQUssRUFBRSxDQUFDO3dDQUNOLElBQUksRUFBRTs0Q0FDSjtnREFDRSxVQUFVLEVBQUUsTUFBTTtnREFDbEIsT0FBTyxFQUFFLE1BQU07Z0RBQ2YsT0FBTyxFQUFFLElBQUk7NkNBQ2Q7NENBQ0QsYUFBYTt5Q0FDZDtxQ0FDRixDQUFDOzZCQUNIO3lCQUNGO3FCQUNGLENBQUM7Z0JBQ0YsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQztvQkFDM0MsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDO29CQUN2QyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7b0JBQzFDLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztpQkFDM0M7YUFDRixDQUFDLENBQUM7WUFFSCxhQUFN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b3RlbWFyayAqL1xuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuXG5pbXBvcnQge1BhcnNlTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9mb3JtYXRwYXJzZSc7XG5pbXBvcnQge01vZGVsV2l0aEZpZWxkfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9tb2RlbCc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vc3JjL2xvZyc7XG5pbXBvcnQge3BhcnNlRmFjZXRNb2RlbCwgcGFyc2VVbml0TW9kZWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9kYXRhL2Zvcm1hdHBhcnNlJywgKCkgPT4ge1xuICBkZXNjcmliZSgncGFyc2VVbml0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29ycmVjdCBwYXJzZSBmb3IgZW5jb2RpbmcgbWFwcGluZyBhbmQgZmlsdGVyIHRyYW5zZm9ybXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImEuanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW3tcbiAgICAgICAgICBcImZpbHRlclwiOiB7XG4gICAgICAgICAgICBcIm5vdFwiOiB7XG4gICAgICAgICAgICAgIFwiYW5kXCI6IFt7XG4gICAgICAgICAgICAgICAgXCJvclwiOiBbXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwidGltZVVuaXRcIjogXCJ5ZWFyXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJkYXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZXF1YWxcIjogMjAwNVxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIFwiZGF0dW0uYSA+IDVcIlxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgfV1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1dLFxuICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJjXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJzaGFwZVwiOiB7XCJmaWVsZFwiOiBcImRcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChQYXJzZU5vZGUubWFrZShtb2RlbCkucGFyc2UsIHtcbiAgICAgICAgYTogJ251bWJlcicsXG4gICAgICAgIGI6ICdkYXRlJyxcbiAgICAgICAgZGF0ZTogJ2RhdGUnXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYmlubmVkIGZpZWxkcyBhcyBudW1iZXJzLicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIiwgXCJiaW5cIjogdHJ1ZX0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKFBhcnNlTm9kZS5tYWtlKG1vZGVsKS5wYXJzZSwge1xuICAgICAgICBhOiAnbnVtYmVyJ1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIGNvcnJlY3QgY3VzdG9taXplZCBwYXJzZS4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImEuanNvblwiLCBcImZvcm1hdFwiOiB7XCJwYXJzZVwiOiB7XCJjXCI6IFwibnVtYmVyXCIsIFwiZFwiOiBcImRhdGVcIn19fSxcbiAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiY1wiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwic2hhcGVcIjoge1wiZmllbGRcIjogXCJjXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoUGFyc2VOb2RlLm1ha2UobW9kZWwpLnBhcnNlLCB7XG4gICAgICAgIGE6ICdudW1iZXInLFxuICAgICAgICBiOiAnZGF0ZScsXG4gICAgICAgIGM6ICdudW1iZXInLFxuICAgICAgICBkOiAnZGF0ZSdcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIHBhcnNlIGZvciBhbGwgYXBwbGljYWJsZSBmaWVsZHMsIGFuZCBleGNsdWRlIGNhbGN1bGF0ZWQgZmllbGRzJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgdHJhbnNmb3JtOiBbe2NhbGN1bGF0ZTogJ2RhdHVtW1wiYlwiXSAqIDInLCBhczogJ2IyJ31dLFxuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgeToge2ZpZWxkOiAnYicsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6ICcqJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIiwgYWdncmVnYXRlOiAnY291bnQnfSxcbiAgICAgICAgICBzaXplOiB7ZmllbGQ6ICdiMicsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChQYXJzZU5vZGUubWFrZShtb2RlbCkucGFyc2UsIHtcbiAgICAgICAgJ2EnOiAnZGF0ZScsXG4gICAgICAgICdiJzogJ251bWJlcidcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgcGFyc2UgZmllbGRzIHdpdGggYWdncmVnYXRlPW1pc3NpbmcvdmFsaWQvZGlzdGluY3QnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2FnZ3JlZ2F0ZTogJ21pc3NpbmcnLCBmaWVsZDogJ2InLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICB5OiB7YWdncmVnYXRlOiAndmFsaWQnLCBmaWVsZDogJ2InLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBjb2xvcjoge2FnZ3JlZ2F0ZTogJ2Rpc3RpbmN0JywgZmllbGQ6ICdiJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoUGFyc2VOb2RlLm1ha2UobW9kZWwpLCBudWxsKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHBhcnNlIHRoZSBzYW1lIGZpZWxkIHR3aWNlJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbCh7XG4gICAgICAgIGRhdGE6IHtcbiAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgICAgcGFyc2U6IHtcbiAgICAgICAgICAgICAgYTogJ251bWJlcidcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgcm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdiJywgdHlwZTogXCJ0ZW1wb3JhbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoUGFyc2VOb2RlLm1ha2UobW9kZWwpLnBhcnNlLCB7XG4gICAgICAgICdhJzogJ251bWJlcidcbiAgICAgIH0pO1xuICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICAgICAgbW9kZWwucGFyc2VEYXRhKCk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY2hpbGQuY29tcG9uZW50LmRhdGEuYW5jZXN0b3JQYXJzZSwge1xuICAgICAgICAnYSc6ICdudW1iZXInLFxuICAgICAgICAnYic6ICdkYXRlJ1xuICAgICAgfSk7XG5cbiAgICAgIC8vIHNldCB0aGUgYW5jZXN0b3IgcGFyc2UgdG8gc2VlIHdoZXRoZXIgZmllbGRzIGZyb20gaXQgYXJlIG5vdCBwYXJzZWRcbiAgICAgIG1vZGVsLmNoaWxkLmNvbXBvbmVudC5kYXRhLmFuY2VzdG9yUGFyc2UgPSB7YTogJ251bWJlcid9O1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChQYXJzZU5vZGUubWFrZShtb2RlbC5jaGlsZCBhcyBNb2RlbFdpdGhGaWVsZCkucGFyc2UsIHtcbiAgICAgICAgJ2InOiAnZGF0ZSdcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYXNzZW1ibGVUcmFuc2Zvcm1zJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCBhc3NlbWJsZSBjb3JyZWN0IHBhcnNlIGV4cHJlc3Npb25zJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBwID0gbmV3IFBhcnNlTm9kZSh7XG4gICAgICAgIG46ICdudW1iZXInLFxuICAgICAgICBiOiAnYm9vbGVhbicsXG4gICAgICAgIHM6ICdzdHJpbmcnLFxuICAgICAgICBkMTogJ2RhdGUnLFxuICAgICAgICBkMjogJ2RhdGU6XCIleVwiJyxcbiAgICAgICAgZDM6ICd1dGM6XCIleVwiJ1xuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocC5hc3NlbWJsZVRyYW5zZm9ybXMoKSwgW1xuICAgICAgICB7dHlwZTogJ2Zvcm11bGEnLCBleHByOiAndG9OdW1iZXIoZGF0dW1bXCJuXCJdKScsIGFzOiAnbid9LFxuICAgICAgICB7dHlwZTogJ2Zvcm11bGEnLCBleHByOiAndG9Cb29sZWFuKGRhdHVtW1wiYlwiXSknLCBhczogJ2InfSxcbiAgICAgICAge3R5cGU6ICdmb3JtdWxhJywgZXhwcjogJ3RvU3RyaW5nKGRhdHVtW1wic1wiXSknLCBhczogJ3MnfSxcbiAgICAgICAge3R5cGU6ICdmb3JtdWxhJywgZXhwcjogJ3RvRGF0ZShkYXR1bVtcImQxXCJdKScsIGFzOiAnZDEnfSxcbiAgICAgICAge3R5cGU6ICdmb3JtdWxhJywgZXhwcjogJ3RpbWVQYXJzZShkYXR1bVtcImQyXCJdLFwiJXlcIiknLCBhczogJ2QyJ30sXG4gICAgICAgIHt0eXBlOiAnZm9ybXVsYScsIGV4cHI6ICd1dGNQYXJzZShkYXR1bVtcImQzXCJdLFwiJXlcIiknLCBhczogJ2QzJ31cbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaG93IHdhcm5pbmcgZm9yIHVucmVjb2duaXplZCB0eXBlcycsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgY29uc3QgcCA9IG5ldyBQYXJzZU5vZGUoe1xuICAgICAgICB4OiAnZm9vJyxcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHAuYXNzZW1ibGVUcmFuc2Zvcm1zKCksIFtdKTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UudW5yZWNvZ25pemVkUGFyc2UoJ2ZvbycpKTtcbiAgICB9KSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/data/lookup.test.js b/build/test/compile/data/lookup.test.js new file mode 100644 index 0000000000..9d8fc0dac7 --- /dev/null +++ b/build/test/compile/data/lookup.test.js @@ -0,0 +1,78 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var lookup_1 = require("../../../src/compile/data/lookup"); +var parse_1 = require("../../../src/compile/data/parse"); +var log = require("../../../src/log"); +var util_1 = require("../../util"); +describe('compile/data/lookup', function () { + it('should parse lookup from array', function () { + var model = util_1.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 = parse_1.parseTransformArray(model); + chai_1.assert.deepEqual(t.first.assemble(), { + type: 'lookup', + from: 'lookup_0', + key: 'name', + fields: ['person'], + values: ['age', 'height'] + }); + }); + it('should create node for flat lookup', function () { + var lookup = new lookup_1.LookupNode({ + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name', + 'fields': ['age', 'height'] + } + }, 'lookup_0'); + chai_1.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 lookup_1.LookupNode({ + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name' + }, + 'as': 'foo' + }, 'lookup_0'); + chai_1.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 lookup_1.LookupNode({ + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name' + } + }, 'lookup_0'); + lookup.assemble(); + chai_1.assert.equal(localLogger.warns[0], log.message.NO_FIELDS_NEEDS_AS); + })); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9va3VwLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9sb29rdXAudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1QiwyREFBNEQ7QUFDNUQseURBQW9FO0FBQ3BFLHNDQUF3QztBQUV4QyxtQ0FBMEM7QUFFMUMsUUFBUSxDQUFDLHFCQUFxQixFQUFFO0lBQzlCLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRTtRQUNuQyxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1lBQzNCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSx3QkFBd0IsRUFBQztZQUN6QyxXQUFXLEVBQUUsQ0FBQztvQkFDWixRQUFRLEVBQUUsUUFBUTtvQkFDbEIsTUFBTSxFQUFFO3dCQUNOLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSx3QkFBd0IsRUFBQzt3QkFDekMsS0FBSyxFQUFFLE1BQU07d0JBQ2IsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQztxQkFDNUI7aUJBQ0YsQ0FBQztZQUNGLE1BQU0sRUFBRSxLQUFLO1lBQ2IsVUFBVSxFQUFFLEVBQUU7U0FDZixDQUFDLENBQUM7UUFFSCxJQUFNLENBQUMsR0FBRywyQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxhQUFNLENBQUMsU0FBUyxDQUFxQixDQUFDLENBQUMsS0FBb0IsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUN0RSxJQUFJLEVBQUUsUUFBUTtZQUNkLElBQUksRUFBRSxVQUFVO1lBQ2hCLEdBQUcsRUFBRSxNQUFNO1lBQ1gsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDO1lBQ2xCLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7U0FDMUIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUU7UUFDdkMsSUFBTSxNQUFNLEdBQUcsSUFBSSxtQkFBVSxDQUFDO1lBQzFCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLE1BQU0sRUFBRTtnQkFDTixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsd0JBQXdCLEVBQUM7Z0JBQ3pDLEtBQUssRUFBRSxNQUFNO2dCQUNiLFFBQVEsRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7YUFDNUI7U0FDRixFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRWpCLGFBQU0sQ0FBQyxTQUFTLENBQW9CLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNyRCxJQUFJLEVBQUUsUUFBUTtZQUNkLElBQUksRUFBRSxVQUFVO1lBQ2hCLEdBQUcsRUFBRSxNQUFNO1lBQ1gsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDO1lBQ2xCLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7U0FDMUIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsc0NBQXNDLEVBQUU7UUFDekMsSUFBTSxNQUFNLEdBQUcsSUFBSSxtQkFBVSxDQUFDO1lBQzFCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLE1BQU0sRUFBRTtnQkFDTixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsd0JBQXdCLEVBQUM7Z0JBQ3pDLEtBQUssRUFBRSxNQUFNO2FBQ2Q7WUFDRCxJQUFJLEVBQUUsS0FBSztTQUNaLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFakIsYUFBTSxDQUFDLFNBQVMsQ0FBb0IsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ3JELElBQUksRUFBRSxRQUFRO1lBQ2QsSUFBSSxFQUFFLFVBQVU7WUFDaEIsR0FBRyxFQUFFLE1BQU07WUFDWCxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUM7WUFDbEIsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDO1NBQ1osQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMkRBQTJELEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7UUFDbkYsSUFBTSxNQUFNLEdBQUcsSUFBSSxtQkFBVSxDQUFDO1lBQzFCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLE1BQU0sRUFBRTtnQkFDTixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsd0JBQXdCLEVBQUM7Z0JBQ3pDLEtBQUssRUFBRSxNQUFNO2FBQ2Q7U0FDRixFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2pCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUVsQixhQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDTixDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7TG9va3VwTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9sb29rdXAnO1xuaW1wb3J0IHtwYXJzZVRyYW5zZm9ybUFycmF5fSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3BhcnNlJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi8uLi9zcmMvbG9nJztcbmltcG9ydCB7VmdMb29rdXBUcmFuc2Zvcm19IGZyb20gJy4uLy4uLy4uL3NyYy92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS9sb29rdXAnLCBmdW5jdGlvbigpIHtcbiAgaXQoJ3Nob3VsZCBwYXJzZSBsb29rdXAgZnJvbSBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICdkYXRhJzogeyd1cmwnOiAnZGF0YS9sb29rdXBfZ3JvdXBzLmNzdid9LFxuICAgICAgJ3RyYW5zZm9ybSc6IFt7XG4gICAgICAgICdsb29rdXAnOiAncGVyc29uJyxcbiAgICAgICAgJ2Zyb20nOiB7XG4gICAgICAgICAgJ2RhdGEnOiB7J3VybCc6ICdkYXRhL2xvb2t1cF9wZW9wbGUuY3N2J30sXG4gICAgICAgICAgJ2tleSc6ICduYW1lJyxcbiAgICAgICAgICAnZmllbGRzJzogWydhZ2UnLCAnaGVpZ2h0J11cbiAgICAgICAgfVxuICAgICAgfV0sXG4gICAgICAnbWFyayc6ICdiYXInLFxuICAgICAgJ2VuY29kaW5nJzoge31cbiAgICB9KTtcblxuICAgIGNvbnN0IHQgPSBwYXJzZVRyYW5zZm9ybUFycmF5KG1vZGVsKTtcbiAgICBhc3NlcnQuZGVlcEVxdWFsPFZnTG9va3VwVHJhbnNmb3JtPigodC5maXJzdCBhcyBMb29rdXBOb2RlKS5hc3NlbWJsZSgpLCB7XG4gICAgICB0eXBlOiAnbG9va3VwJyxcbiAgICAgIGZyb206ICdsb29rdXBfMCcsXG4gICAgICBrZXk6ICduYW1lJyxcbiAgICAgIGZpZWxkczogWydwZXJzb24nXSxcbiAgICAgIHZhbHVlczogWydhZ2UnLCAnaGVpZ2h0J11cbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjcmVhdGUgbm9kZSBmb3IgZmxhdCBsb29rdXAnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbG9va3VwID0gbmV3IExvb2t1cE5vZGUoe1xuICAgICAgICAnbG9va3VwJzogJ3BlcnNvbicsXG4gICAgICAgICdmcm9tJzoge1xuICAgICAgICAgICdkYXRhJzogeyd1cmwnOiAnZGF0YS9sb29rdXBfcGVvcGxlLmNzdid9LFxuICAgICAgICAgICdrZXknOiAnbmFtZScsXG4gICAgICAgICAgJ2ZpZWxkcyc6IFsnYWdlJywgJ2hlaWdodCddXG4gICAgICAgIH1cbiAgICAgIH0sICdsb29rdXBfMCcpO1xuXG4gICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0xvb2t1cFRyYW5zZm9ybT4obG9va3VwLmFzc2VtYmxlKCksIHtcbiAgICAgIHR5cGU6ICdsb29rdXAnLFxuICAgICAgZnJvbTogJ2xvb2t1cF8wJyxcbiAgICAgIGtleTogJ25hbWUnLFxuICAgICAgZmllbGRzOiBbJ3BlcnNvbiddLFxuICAgICAgdmFsdWVzOiBbJ2FnZScsICdoZWlnaHQnXVxuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNyZWF0ZSBub2RlIGZvciBuZXN0ZWQgbG9va3VwJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGxvb2t1cCA9IG5ldyBMb29rdXBOb2RlKHtcbiAgICAgICAgJ2xvb2t1cCc6ICdwZXJzb24nLFxuICAgICAgICAnZnJvbSc6IHtcbiAgICAgICAgICAnZGF0YSc6IHsndXJsJzogJ2RhdGEvbG9va3VwX3Blb3BsZS5jc3YnfSxcbiAgICAgICAgICAna2V5JzogJ25hbWUnXG4gICAgICAgIH0sXG4gICAgICAgICdhcyc6ICdmb28nXG4gICAgICB9LCAnbG9va3VwXzAnKTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdMb29rdXBUcmFuc2Zvcm0+KGxvb2t1cC5hc3NlbWJsZSgpLCB7XG4gICAgICB0eXBlOiAnbG9va3VwJyxcbiAgICAgIGZyb206ICdsb29rdXBfMCcsXG4gICAgICBrZXk6ICduYW1lJyxcbiAgICAgIGZpZWxkczogWydwZXJzb24nXSxcbiAgICAgIGFzOiBbJ2ZvbyddXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgd2FybiBpZiBmaWVsZHMgYXJlIG5vdCBzcGVjaWZpZWQgYW5kIGFzIGlzIG1pc3NpbmcnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICBjb25zdCBsb29rdXAgPSBuZXcgTG9va3VwTm9kZSh7XG4gICAgICAgICdsb29rdXAnOiAncGVyc29uJyxcbiAgICAgICAgJ2Zyb20nOiB7XG4gICAgICAgICAgJ2RhdGEnOiB7J3VybCc6ICdkYXRhL2xvb2t1cF9wZW9wbGUuY3N2J30sXG4gICAgICAgICAgJ2tleSc6ICduYW1lJ1xuICAgICAgICB9XG4gICAgICB9LCAnbG9va3VwXzAnKTtcbiAgICBsb29rdXAuYXNzZW1ibGUoKTtcblxuICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuTk9fRklFTERTX05FRURTX0FTKTtcbiAgfSkpO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/data/parse.test.js b/build/test/compile/data/parse.test.js new file mode 100644 index 0000000000..d23c13a948 --- /dev/null +++ b/build/test/compile/data/parse.test.js @@ -0,0 +1,55 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var aggregate_1 = require("../../../src/compile/data/aggregate"); +var bin_1 = require("../../../src/compile/data/bin"); +var calculate_1 = require("../../../src/compile/data/calculate"); +var filter_1 = require("../../../src/compile/data/filter"); +var parse_1 = require("../../../src/compile/data/parse"); +var timeunit_1 = require("../../../src/compile/data/timeunit"); +var util_1 = require("../../util"); +describe('compile/data/parse', function () { + describe('parseTransformArray()', function () { + it('should return a CalculateNode and a FilterNode', function () { + var model = util_1.parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [{ calculate: 'calculate', as: 'as' }, { filter: 'filter' }], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var result = parse_1.parseTransformArray(model); + chai_1.assert.isTrue(result.first instanceof calculate_1.CalculateNode); + chai_1.assert.isTrue(result.last instanceof filter_1.FilterNode); + }); + it('should return a BinNode node and a TimeUnitNode', function () { + var model = util_1.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 result = parse_1.parseTransformArray(model); + chai_1.assert.isTrue(result.first instanceof bin_1.BinNode); + chai_1.assert.isTrue(result.last instanceof timeunit_1.TimeUnitNode); + }); + it('should return a BinNode and a AggregateNode', function () { + var model = util_1.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 result = parse_1.parseTransformArray(model); + chai_1.assert.isTrue(result.first instanceof bin_1.BinNode); + chai_1.assert.isTrue(result.last instanceof aggregate_1.AggregateNode); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL3BhcnNlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLGlFQUFrRTtBQUNsRSxxREFBc0Q7QUFDdEQsaUVBQWtFO0FBQ2xFLDJEQUE0RDtBQUM1RCx5REFBb0U7QUFDcEUsK0RBQWdFO0FBQ2hFLG1DQUEwQztBQUUxQyxRQUFRLENBQUMsb0JBQW9CLEVBQUU7SUFDN0IsUUFBUSxDQUFDLHVCQUF1QixFQUFFO1FBQ2hDLEVBQUUsQ0FBQyxnREFBZ0QsRUFBRTtZQUNuRCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsRUFBQyxNQUFNLEVBQUUsRUFBRSxFQUFDO2dCQUNsQixJQUFJLEVBQUUsT0FBTztnQkFDYixTQUFTLEVBQUUsQ0FBQyxFQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBQyxFQUFFLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBQyxDQUFDO2dCQUNuRSxRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUM7aUJBQ3JEO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsSUFBTSxNQUFNLEdBQUcsMkJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUMsYUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxZQUFZLHlCQUFhLENBQUMsQ0FBQztZQUNyRCxhQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFlBQVksbUJBQVUsQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlEQUFpRCxFQUFFO1lBQ3BELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLElBQUksRUFBRSxFQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUM7Z0JBQ2xCLElBQUksRUFBRSxPQUFPO2dCQUNiLFNBQVMsRUFBRSxDQUFDLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUMsRUFBRSxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFDLENBQUM7Z0JBQy9GLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBQztpQkFDckQ7YUFDRixDQUFDLENBQUM7WUFFSCxJQUFNLE1BQU0sR0FBRywyQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQyxhQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLFlBQVksYUFBTyxDQUFDLENBQUM7WUFDL0MsYUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxZQUFZLHVCQUFZLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsRUFBQyxNQUFNLEVBQUUsRUFBRSxFQUFDO2dCQUNsQixJQUFJLEVBQUUsT0FBTztnQkFDYixTQUFTLEVBQUUsQ0FBQyxFQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFDLEVBQUUsRUFBQyxTQUFTLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFDLEVBQUUsRUFBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUMsQ0FBQztnQkFDMUosUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFDO2lCQUNyRDthQUNGLENBQUMsQ0FBQztZQUVILElBQU0sTUFBTSxHQUFHLDJCQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzFDLGFBQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssWUFBWSxhQUFPLENBQUMsQ0FBQztZQUMvQyxhQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFlBQVkseUJBQWEsQ0FBQyxDQUFDO1FBQ3RELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge0FnZ3JlZ2F0ZU5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvYWdncmVnYXRlJztcbmltcG9ydCB7QmluTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9iaW4nO1xuaW1wb3J0IHtDYWxjdWxhdGVOb2RlfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2NhbGN1bGF0ZSc7XG5pbXBvcnQge0ZpbHRlck5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvZmlsdGVyJztcbmltcG9ydCB7cGFyc2VUcmFuc2Zvcm1BcnJheX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9wYXJzZSc7XG5pbXBvcnQge1RpbWVVbml0Tm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS90aW1ldW5pdCc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS9wYXJzZScsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3BhcnNlVHJhbnNmb3JtQXJyYXkoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIENhbGN1bGF0ZU5vZGUgYW5kIGEgRmlsdGVyTm9kZScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBkYXRhOiB7dmFsdWVzOiBbXX0sXG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIHRyYW5zZm9ybTogW3tjYWxjdWxhdGU6ICdjYWxjdWxhdGUnLCBhczogJ2FzJ30sIHtmaWx0ZXI6ICdmaWx0ZXInfV0sXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICd0ZW1wb3JhbCcsIHRpbWVVbml0OiAnbW9udGgnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VUcmFuc2Zvcm1BcnJheShtb2RlbCk7XG4gICAgICBhc3NlcnQuaXNUcnVlKHJlc3VsdC5maXJzdCBpbnN0YW5jZW9mIENhbGN1bGF0ZU5vZGUpO1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShyZXN1bHQubGFzdCBpbnN0YW5jZW9mIEZpbHRlck5vZGUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBCaW5Ob2RlIG5vZGUgYW5kIGEgVGltZVVuaXROb2RlJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIGRhdGE6IHt2YWx1ZXM6IFtdfSxcbiAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgdHJhbnNmb3JtOiBbe2JpbjogdHJ1ZSwgZmllbGQ6ICdmaWVsZCcsIGFzOiAnYSd9LCB7dGltZVVuaXQ6ICdtb250aCcsIGZpZWxkOiAnZmllbGQnLCBhczogJ2InfV0sXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICd0ZW1wb3JhbCcsIHRpbWVVbml0OiAnbW9udGgnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VUcmFuc2Zvcm1BcnJheShtb2RlbCk7XG4gICAgICBhc3NlcnQuaXNUcnVlKHJlc3VsdC5maXJzdCBpbnN0YW5jZW9mIEJpbk5vZGUpO1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShyZXN1bHQubGFzdCBpbnN0YW5jZW9mIFRpbWVVbml0Tm9kZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIEJpbk5vZGUgYW5kIGEgQWdncmVnYXRlTm9kZScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBkYXRhOiB7dmFsdWVzOiBbXX0sXG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIHRyYW5zZm9ybTogW3tiaW46IHRydWUsIGZpZWxkOiAnZmllbGQnLCBhczogJ2EnfSwge2FnZ3JlZ2F0ZTogW3tvcDogJ2NvdW50JywgZmllbGQ6ICdmJywgYXM6ICdiJ30sIHtvcDogJ3N1bScsIGZpZWxkOiAnZicsIGFzOiAnYyd9XSwgZ3JvdXBieTogWydmaWVsZCddfV0sXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICd0ZW1wb3JhbCcsIHRpbWVVbml0OiAnbW9udGgnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VUcmFuc2Zvcm1BcnJheShtb2RlbCk7XG4gICAgICBhc3NlcnQuaXNUcnVlKHJlc3VsdC5maXJzdCBpbnN0YW5jZW9mIEJpbk5vZGUpO1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShyZXN1bHQubGFzdCBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZU5vZGUpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/data/source.test.js b/build/test/compile/data/source.test.js new file mode 100644 index 0000000000..ae4974a983 --- /dev/null +++ b/build/test/compile/data/source.test.js @@ -0,0 +1,107 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var source_1 = require("../../../src/compile/data/source"); +function parse(data) { + return new source_1.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 () { + chai_1.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 () { + chai_1.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 () { + chai_1.assert.deepEqual(source.data.values, "a\n1\n2\n3"); + }); + it('should have correct type', function () { + chai_1.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 () { + chai_1.assert.equal(source.data.format.type, 'csv'); + }); + it('should have correct url', function () { + chai_1.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 () { + chai_1.assert.equal(source.data.format.type, 'json'); + }); + }); + describe('with no data specified', function () { + var source = parse(undefined); + it('should provide placeholder source data', function () { + chai_1.assert.equal(source.dataName, 'source'); + }); + }); + describe('with named data source provided', function () { + var source = parse({ name: 'foo' }); + it('should provide named source data', function () { + chai_1.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' } + }); + chai_1.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 () { + chai_1.assert.equal(source.data.format.type, 'topojson'); + }); + it('should have format.feature baz', function () { + chai_1.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 () { + chai_1.assert.equal(source.data.format.type, 'topojson'); + }); + it('should have format.mesh baz', function () { + chai_1.assert.equal(source.data.format.mesh, 'baz'); + }); + }); + }); + }); + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9zb3VyY2UudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIsMkRBQTREO0FBRzVELGVBQWUsSUFBVTtJQUN2QixNQUFNLENBQUMsSUFBSSxtQkFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRCxRQUFRLENBQUMscUJBQXFCLEVBQUU7SUFDOUIsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixRQUFRLENBQUMsc0JBQXNCLEVBQUU7WUFDL0IsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDO2dCQUNuQixNQUFNLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDO2FBQzdDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxvQkFBb0IsRUFBRTtnQkFDdkIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdFLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFO2dCQUN0QyxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lB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QUFDLENBQUM7b0JBQy9DLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFVBQVUsRUFBRTtRQUNuQixtQkFBbUI7SUFDckIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5cbmltcG9ydCB7U291cmNlTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9zb3VyY2UnO1xuaW1wb3J0IHtEYXRhfSBmcm9tICcuLi8uLi8uLi9zcmMvZGF0YSc7XG5cbmZ1bmN0aW9uIHBhcnNlKGRhdGE6IERhdGEpIHtcbiAgcmV0dXJuIG5ldyBTb3VyY2VOb2RlKGRhdGEpO1xufVxuXG5kZXNjcmliZSgnY29tcGlsZS9kYXRhL3NvdXJjZScsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnY29tcGlsZVVuaXQnLCBmdW5jdGlvbigpIHtcbiAgICBkZXNjcmliZSgnd2l0aCBleHBsaWNpdCB2YWx1ZXMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IHBhcnNlKHtcbiAgICAgICAgdmFsdWVzOiBbe2E6IDEsIGI6MiwgYzozfSwge2E6IDQsIGI6NSwgYzo2fV1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhdmUgdmFsdWVzJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc291cmNlLmRhdGEudmFsdWVzLCBbe2E6IDEsIGI6MiwgYzozfSwge2E6IDQsIGI6NSwgYzo2fV0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGF2ZSBubyBzb3VyY2UuZm9ybWF0LnR5cGUnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzb3VyY2UuZGF0YS5mb3JtYXQsIHVuZGVmaW5lZCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIGV4cGxpY2l0IHZhbHVlcyBhcyBDU1YnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IHBhcnNlKHtcbiAgICAgICAgdmFsdWVzOiBcImFcXG4xXFxuMlxcbjNcIixcbiAgICAgICAgZm9ybWF0OiB7dHlwZTogJ2Nzdid9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYXZlIHZhbHVlcycsIGZ1bmN0aW9uKCkge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHNvdXJjZS5kYXRhLnZhbHVlcywgXCJhXFxuMVxcbjJcXG4zXCIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IHR5cGUnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNvdXJjZS5kYXRhLmZvcm1hdC50eXBlLCAnY3N2Jyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIGxpbmsgdG8gdXJsJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwYXJzZSh7XG4gICAgICAgIHVybDogJ2h0dHA6Ly9mb28uYmFyL2ZpbGUuY3N2JyxcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhdmUgZm9ybWF0LnR5cGUgY3N2JywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChzb3VyY2UuZGF0YS5mb3JtYXQudHlwZSwgJ2NzdicpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCB1cmwnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNvdXJjZS5kYXRhLnVybCwgJ2h0dHA6Ly9mb28uYmFyL2ZpbGUuY3N2Jyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRob3V0IGZpbGUgZW5kaW5nJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwYXJzZSh7XG4gICAgICAgIHVybDogJ2h0dHA6Ly9mb28uYmFyL2ZpbGUuYmF6JyxcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhdmUgZm9ybWF0LnR5cGUganNvbicsIGZ1bmN0aW9uKCkge1xuICAgICAgICBhc3NlcnQuZXF1YWwoc291cmNlLmRhdGEuZm9ybWF0LnR5cGUsICdqc29uJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aXRoIG5vIGRhdGEgc3BlY2lmaWVkJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwYXJzZSh1bmRlZmluZWQpO1xuXG4gICAgICBpdCgnc2hvdWxkIHByb3ZpZGUgcGxhY2Vob2xkZXIgc291cmNlIGRhdGEnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNvdXJjZS5kYXRhTmFtZSwgJ3NvdXJjZScpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2l0aCBuYW1lZCBkYXRhIHNvdXJjZSBwcm92aWRlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3Qgc291cmNlID0gcGFyc2Uoe25hbWU6ICdmb28nfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcHJvdmlkZSBuYW1lZCBzb3VyY2UgZGF0YScsIGZ1bmN0aW9uKCkge1xuICAgICAgICBhc3NlcnQuZXF1YWwoc291cmNlLmRhdGFOYW1lLCAnZm9vJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdkYXRhIGZvcm1hdCcsIGZ1bmN0aW9uKCkge1xuICAgICAgZGVzY3JpYmUoJ2pzb24nLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgaW5jbHVkZSBwcm9wZXJ0eSBpZiBzcGVjaWZpZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2UgPSBwYXJzZSh7XG4gICAgICAgICAgICB1cmw6ICdodHRwOi8vZm9vLmJhcicsXG4gICAgICAgICAgICBmb3JtYXQ6IHt0eXBlOiAnanNvbicsIHByb3BlcnR5OiAnYmF6J31cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFzc2VydC5lcXVhbChzb3VyY2UuZGF0YS5mb3JtYXQucHJvcGVydHksICdiYXonKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3RvcG9qc29uJywgKCkgPT4ge1xuICAgICAgICBkZXNjcmliZSgnZmVhdHVyZSBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2UgPSBwYXJzZSh7XG4gICAgICAgICAgICB1cmw6ICdodHRwOi8vZm9vLmJhcicsXG4gICAgICAgICAgICBmb3JtYXQ6IHt0eXBlOiAndG9wb2pzb24nLCBmZWF0dXJlOiAnYmF6J31cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgaGF2ZSBmb3JtYXQudHlwZSB0b3BvanNvbicsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKHNvdXJjZS5kYXRhLmZvcm1hdC50eXBlLCAndG9wb2pzb24nKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpdCgnc2hvdWxkIGhhdmUgZm9ybWF0LmZlYXR1cmUgYmF6JywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwoc291cmNlLmRhdGEuZm9ybWF0LmZlYXR1cmUsICdiYXonKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ21lc2ggcHJvcGVydHkgaXMgc3BlY2lmaWVkJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gcGFyc2Uoe1xuICAgICAgICAgICAgdXJsOiAnaHR0cDovL2Zvby5iYXInLFxuICAgICAgICAgICAgZm9ybWF0OiB7dHlwZTogJ3RvcG9qc29uJywgbWVzaDogJ2Jheid9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIGhhdmUgZm9ybWF0LnR5cGUgdG9wb2pzb24nLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGFzc2VydC5lcXVhbChzb3VyY2UuZGF0YS5mb3JtYXQudHlwZSwgJ3RvcG9qc29uJyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaXQoJ3Nob3VsZCBoYXZlIGZvcm1hdC5tZXNoIGJheicsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKHNvdXJjZS5kYXRhLmZvcm1hdC5tZXNoLCAnYmF6Jyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhc3NlbWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIC8vIFRPRE86IHdyaXRlIHRlc3RcbiAgfSk7XG59KTtcblxuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/data/stack.test.js b/build/test/compile/data/stack.test.js new file mode 100644 index 0000000000..26eabcccc4 --- /dev/null +++ b/build/test/compile/data/stack.test.js @@ -0,0 +1,184 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var stack_1 = require("../../../src/compile/data/stack"); +var util_1 = require("../../util"); +function parse(model) { + return stack_1.StackNode.make(model).stack; +} +function assemble(model) { + return stack_1.StackNode.make(model).assemble(); +} +describe('compile/data/stack', function () { + it('should produce correct stack component for bar with color', function () { + var model = util_1.parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + chai_1.assert.deepEqual(parse(model), { + dimensionFieldDef: { field: 'b', type: 'nominal' }, + facetby: [], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false + }); + }); + 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 = util_1.parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "bin": true, "field": "b", "type": "quantitative" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + chai_1.assert.deepEqual(parse(model), { + dimensionFieldDef: { "bin": { maxbins: 10 }, "field": "b", "type": "quantitative" }, + facetby: [], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false + }); + }); + it('should produce correct stack component for 1D bar with color', function () { + var model = util_1.parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + chai_1.assert.deepEqual(parse(model), { + dimensionFieldDef: undefined, + facetby: [], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false + }); + chai_1.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 = util_1.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" } + } + }); + chai_1.assert.deepEqual(parse(model), { + dimensionFieldDef: { field: 'b', type: 'nominal' }, + facetby: [], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + offset: 'zero', + impute: true + }); + chai_1.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 = util_1.parseUnitModelWithScale({ + "mark": "area", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "bin": true, "field": "b", "type": "quantitative" }, + "color": { "field": "c", "type": "nominal" } + } + }); + chai_1.assert.deepEqual(parse(model), { + dimensionFieldDef: { "bin": { maxbins: 10 }, "field": "b", "type": "quantitative" }, + facetby: [], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: true + }); + chai_1.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' + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2sudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL3N0YWNrLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBRTVCLHlEQUEwRTtBQUkxRSxtQ0FBbUQ7QUFFbkQsZUFBZSxLQUFnQjtJQUM3QixNQUFNLENBQUMsaUJBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ3JDLENBQUM7QUFFRCxrQkFBa0IsS0FBZ0I7SUFDaEMsTUFBTSxDQUFDLGlCQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQzFDLENBQUM7QUFFRCxRQUFRLENBQUMsb0JBQW9CLEVBQUU7SUFDN0IsRUFBRSxDQUFDLDJEQUEyRCxFQUFFO1FBQzlELElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO1lBQ3BDLE1BQU0sRUFBRSxLQUFLO1lBQ2IsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMvRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7Z0JBQ3RDLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsR0FBRTthQUM1QztTQUNGLENBQUMsQ0FBQztRQUVILGFBQU0sQ0FBQyxTQUFTLENBQWlCLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUM3QyxpQkFBaUIsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQztZQUNoRCxPQUFPLEVBQUUsRUFBRTtZQUNYLEtBQUssRUFBRSxPQUFPO1lBQ2QsT0FBTyxFQUFFLENBQUMsR0FB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QUFNO1lBQ2QsTUFBTSxFQUFFLElBQUk7U0FDYixDQUFDLENBQUM7UUFFSCxhQUFNLENBQUMsU0FBUyxDQUFnQixRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDL0M7Z0JBQ0UsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsSUFBSSxFQUFFLGlFQUFpRTtnQkFDdkUsRUFBRSxFQUFFLHNCQUFzQjthQUMzQjtZQUNEO2dCQUNFLElBQUksRUFBRSxRQUFRO2dCQUNkLEtBQUssRUFBRSxPQUFPO2dCQUNkLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQztnQkFDZCxHQUFHLEVBQUUsc0JBQXNCO2dCQUMzQixNQUFNLEVBQUUsT0FBTztnQkFDZixLQUFLLEVBQUUsQ0FBQzthQUNUO1lBQ0Q7Z0JBQ0UsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsT0FBTyxFQUFFLENBQUMsc0JBQXNCLENBQUM7Z0JBQ2pDLEtBQUssRUFBRSxPQUFPO2dCQUNkLElBQUksRUFBRTtvQkFDSixLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUM7b0JBQ1osS0FBSyxFQUFFLENBQUMsWUFBWSxDQUFDO2lCQUN0QjtnQkFDRCxFQUFFLEVBQUUsQ0FBQyxhQUFhLEVBQUUsV0FBVyxDQUFDO2dCQUNoQyxNQUFNLEVBQUUsTUFBTTthQUNmO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5cbmltcG9ydCB7U3RhY2tDb21wb25lbnQsIFN0YWNrTm9kZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9zdGFjayc7XG5cbmltcG9ydCB7VW5pdE1vZGVsfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS91bml0JztcbmltcG9ydCB7VmdUcmFuc2Zvcm19IGZyb20gJy4uLy4uLy4uL3NyYy92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlfSBmcm9tICcuLi8uLi91dGlsJztcblxuZnVuY3Rpb24gcGFyc2UobW9kZWw6IFVuaXRNb2RlbCkge1xuICByZXR1cm4gU3RhY2tOb2RlLm1ha2UobW9kZWwpLnN0YWNrO1xufVxuXG5mdW5jdGlvbiBhc3NlbWJsZShtb2RlbDogVW5pdE1vZGVsKSB7XG4gIHJldHVybiBTdGFja05vZGUubWFrZShtb2RlbCkuYXNzZW1ibGUoKTtcbn1cblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS9zdGFjaycsICgpID0+IHtcbiAgaXQoJ3Nob3VsZCBwcm9kdWNlIGNvcnJlY3Qgc3RhY2sgY29tcG9uZW50IGZvciBiYXIgd2l0aCBjb2xvcicsICgpID0+IHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJjXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIix9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhc3NlcnQuZGVlcEVxdWFsPFN0YWNrQ29tcG9uZW50PihwYXJzZShtb2RlbCksIHtcbiAgICAgIGRpbWVuc2lvbkZpZWxkRGVmOiB7ZmllbGQ6ICdiJywgdHlwZTogJ25vbWluYWwnfSxcbiAgICAgIGZhY2V0Ynk6IFtdLFxuICAgICAgZmllbGQ6ICdzdW1fYScsXG4gICAgICBzdGFja2J5OiBbJ2MnXSxcbiAgICAgIHNvcnQ6IHtcbiAgICAgICAgZmllbGQ6IFsnYyddLFxuICAgICAgICBvcmRlcjogWydkZXNjZW5kaW5nJ11cbiAgICAgIH0sXG4gICAgICBvZmZzZXQ6ICd6ZXJvJyxcbiAgICAgIGltcHV0ZTogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwcm9kdWNlIGNvcnJlY3Qgc3RhY2sgY29tcG9uZW50IHdpdGggYm90aCBzdGFydCBhbmQgZW5kIG9mIHRoZSBiaW5uZWQgZmllbGQgZm9yIGJhciB3aXRoIGNvbG9yIGFuZCBiaW5uZWQgeScsICgpID0+IHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcImNcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwiLH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8U3RhY2tDb21wb25lbnQ+KHBhcnNlKG1vZGVsKSwge1xuICAgICAgZGltZW5zaW9uRmllbGREZWY6IHtcImJpblwiOiB7bWF4YmluczogMTB9LCBcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBmYWNldGJ5OiBbXSxcbiAgICAgIGZpZWxkOiAnc3VtX2EnLFxuICAgICAgc3RhY2tieTogWydjJ10sXG4gICAgICBzb3J0OiB7XG4gICAgICAgIGZpZWxkOiBbJ2MnXSxcbiAgICAgICAgb3JkZXI6IFsnZGVzY2VuZGluZyddXG4gICAgICB9LFxuICAgICAgb2Zmc2V0OiAnemVybycsXG4gICAgICBpbXB1dGU6IGZhbHNlXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJvZHVjZSBjb3JyZWN0IHN0YWNrIGNvbXBvbmVudCBmb3IgMUQgYmFyIHdpdGggY29sb3InLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcImNcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwiLH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8U3RhY2tDb21wb25lbnQ+KHBhcnNlKG1vZGVsKSwge1xuICAgICAgZGltZW5zaW9uRmllbGREZWY6IHVuZGVmaW5lZCxcbiAgICAgIGZhY2V0Ynk6IFtdLFxuICAgICAgZmllbGQ6ICdzdW1fYScsXG4gICAgICBzdGFja2J5OiBbJ2MnXSxcbiAgICAgIHNvcnQ6IHtcbiAgICAgICAgZmllbGQ6IFsnYyddLFxuICAgICAgICBvcmRlcjogWydkZXNjZW5kaW5nJ11cbiAgICAgIH0sXG4gICAgICBvZmZzZXQ6ICd6ZXJvJyxcbiAgICAgIGltcHV0ZTogZmFsc2VcbiAgICB9KTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm1bXT4oYXNzZW1ibGUobW9kZWwpLCBbe1xuICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAgICBncm91cGJ5OiBbXSxcbiAgICAgICAgZmllbGQ6ICdzdW1fYScsXG4gICAgICAgIHNvcnQ6IHtcbiAgICAgICAgICBmaWVsZDogWydjJ10sXG4gICAgICAgICAgb3JkZXI6IFsnZGVzY2VuZGluZyddXG4gICAgICAgIH0sXG4gICAgICAgIGFzOiBbJ3N1bV9hX3N0YXJ0JywgJ3N1bV9hX2VuZCddLFxuICAgICAgICBvZmZzZXQ6ICd6ZXJvJ1xuICAgICAgfVxuICAgIF0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByb2R1Y2UgY29ycmVjdCBzdGFjayBjb21wb25lbnQgZm9yIGFyZWEgd2l0aCBjb2xvciBhbmQgb3JkZXInLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiY1wiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcIm9yZGVyXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiBcImRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhc3NlcnQuZGVlcEVxdWFsPFN0YWNrQ29tcG9uZW50PihwYXJzZShtb2RlbCksIHtcbiAgICAgIGRpbWVuc2lvbkZpZWxkRGVmOiB7ZmllbGQ6ICdiJywgdHlwZTogJ25vbWluYWwnfSxcbiAgICAgIGZhY2V0Ynk6IFtdLFxuICAgICAgZmllbGQ6ICdzdW1fYScsXG4gICAgICBzdGFja2J5OiBbJ2MnXSxcbiAgICAgIHNvcnQ6IHtcbiAgICAgICAgZmllbGQ6IFsnbWVhbl9kJ10sXG4gICAgICAgIG9yZGVyOiBbJ2FzY2VuZGluZyddXG4gICAgICB9LFxuICAgICAgb2Zmc2V0OiAnemVybycsXG4gICAgICBpbXB1dGU6IHRydWVcbiAgICB9KTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdUcmFuc2Zvcm1bXT4oYXNzZW1ibGUobW9kZWwpLCBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdpbXB1dGUnLFxuICAgICAgICBmaWVsZDogJ3N1bV9hJyxcbiAgICAgICAgZ3JvdXBieTogWydjJ10sXG4gICAgICAgIGtleTogJ2InLFxuICAgICAgICBtZXRob2Q6IFwidmFsdWVcIixcbiAgICAgICAgdmFsdWU6IDBcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgIGdyb3VwYnk6IFsnYiddLFxuICAgICAgICBmaWVsZDogJ3N1bV9hJyxcbiAgICAgICAgc29ydDoge1xuICAgICAgICAgIGZpZWxkOiBbJ21lYW5fZCddLFxuICAgICAgICAgIG9yZGVyOiBbJ2FzY2VuZGluZyddXG4gICAgICAgIH0sXG4gICAgICAgIGFzOiBbJ3N1bV9hX3N0YXJ0JywgJ3N1bV9hX2VuZCddLFxuICAgICAgICBvZmZzZXQ6ICd6ZXJvJ1xuICAgICAgfVxuICAgIF0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByb2R1Y2UgY29ycmVjdCBzdGFjayBjb21wb25lbnQgZm9yIGFyZWEgd2l0aCBjb2xvciBhbmQgYmlubmVkIGRpbWVuc2lvbicsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcImNcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LmRlZXBFcXVhbDxTdGFja0NvbXBvbmVudD4ocGFyc2UobW9kZWwpLCB7XG4gICAgICBkaW1lbnNpb25GaWVsZERlZjoge1wiYmluXCI6IHttYXhiaW5zOiAxMH0sIFwiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgIGZhY2V0Ynk6IFtdLFxuICAgICAgZmllbGQ6ICdzdW1fYScsXG4gICAgICBzdGFja2J5OiBbJ2MnXSxcbiAgICAgIHNvcnQ6IHtcbiAgICAgICAgZmllbGQ6IFsnYyddLFxuICAgICAgICBvcmRlcjogWydkZXNjZW5kaW5nJ11cbiAgICAgIH0sXG4gICAgICBvZmZzZXQ6ICd6ZXJvJyxcbiAgICAgIGltcHV0ZTogdHJ1ZVxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ1RyYW5zZm9ybVtdPihhc3NlbWJsZShtb2RlbCksIFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ2Zvcm11bGEnLFxuICAgICAgICBleHByOiAnKGRhdHVtW1xcXCJiaW5fbWF4Ymluc18xMF9iXFxcIl0rZGF0dW1bXFxcImJpbl9tYXhiaW5zXzEwX2JfZW5kXFxcIl0pLzInLFxuICAgICAgICBhczogJ2Jpbl9tYXhiaW5zXzEwX2JfbWlkJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ2ltcHV0ZScsXG4gICAgICAgIGZpZWxkOiAnc3VtX2EnLFxuICAgICAgICBncm91cGJ5OiBbJ2MnXSxcbiAgICAgICAga2V5OiAnYmluX21heGJpbnNfMTBfYl9taWQnLFxuICAgICAgICBtZXRob2Q6IFwidmFsdWVcIixcbiAgICAgICAgdmFsdWU6IDBcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgIGdyb3VwYnk6IFsnYmluX21heGJpbnNfMTBfYl9taWQnXSxcbiAgICAgICAgZmllbGQ6ICdzdW1fYScsXG4gICAgICAgIHNvcnQ6IHtcbiAgICAgICAgICBmaWVsZDogWydjJ10sXG4gICAgICAgICAgb3JkZXI6IFsnZGVzY2VuZGluZyddXG4gICAgICAgIH0sXG4gICAgICAgIGFzOiBbJ3N1bV9hX3N0YXJ0JywgJ3N1bV9hX2VuZCddLFxuICAgICAgICBvZmZzZXQ6ICd6ZXJvJ1xuICAgICAgfVxuICAgIF0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/data/timeunit.test.js b/build/test/compile/data/timeunit.test.js new file mode 100644 index 0000000000..2639f180c7 --- /dev/null +++ b/build/test/compile/data/timeunit.test.js @@ -0,0 +1,39 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var timeunit_1 = require("../../../src/compile/data/timeunit"); +var util_1 = require("../../util"); +function assembleFromEncoding(model) { + return timeunit_1.TimeUnitNode.makeFromEncoding(model).assemble(); +} +function assembleFromTransform(t) { + return timeunit_1.TimeUnitNode.makeFromTransform(t).assemble(); +} +describe('compile/data/timeunit', function () { + describe('parseUnit', function () { + it('should return a dictionary of formula transform', function () { + var model = util_1.parseUnitModel({ + "data": { "values": [] }, + "mark": "point", + "encoding": { + "x": { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + chai_1.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' }; + chai_1.assert.deepEqual(assembleFromTransform(t), [{ + type: 'formula', + as: 'month_date', + expr: 'datetime(0, month(datum["date"]), 1, 0, 0, 0, 0)' + }]); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL3RpbWV1bml0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLCtEQUFnRTtBQUdoRSxtQ0FBMEM7QUFFMUMsOEJBQThCLEtBQXFCO0lBQ2pELE1BQU0sQ0FBQyx1QkFBWSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3pELENBQUM7QUFFRCwrQkFBK0IsQ0FBb0I7SUFDakQsTUFBTSxDQUFDLHVCQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDdEQsQ0FBQztBQUVELFFBQVEsQ0FBQyx1QkFBdUIsRUFBRTtJQUNoQyxRQUFRLENBQUMsV0FBVyxFQUFFO1FBRXBCLEVBQUUsQ0FBQyxpREFBaUQsRUFBRTtZQUVwRCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixNQUFNLEVBQUUsRUFBQyxRQUFRLEVBQUUsRUFBRSxFQUFDO2dCQUN0QixNQUFNLEVBQUUsT0FBTztnQkFDZixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUM7aUJBQ3ZEO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUM3QyxJQUFJLEVBQUUsU0FBUztvQkFDZixFQUFFLEVBQUUsU0FBUztvQkFDYixJQUFJLEVBQUUsK0NBQStDO2lCQUN0RCxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNFQUFzRSxFQUFFO1lBQ3pFLElBQU0sQ0FBQyxHQUFzQixFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFDLENBQUM7WUFFbEYsYUFBTSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUMxQyxJQUFJLEVBQUUsU0FBUztvQkFDZixFQUFFLEVBQUUsWUFBWTtvQkFDaEIsSUFBSSxFQUFFLGtEQUFrRDtpQkFDekQsQ0FBQyxDQUFDLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtUaW1lVW5pdE5vZGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvdGltZXVuaXQnO1xuaW1wb3J0IHtNb2RlbFdpdGhGaWVsZH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvbW9kZWwnO1xuaW1wb3J0IHtUaW1lVW5pdFRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vLi4vc3JjL3RyYW5zZm9ybSc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZnVuY3Rpb24gYXNzZW1ibGVGcm9tRW5jb2RpbmcobW9kZWw6IE1vZGVsV2l0aEZpZWxkKSB7XG4gIHJldHVybiBUaW1lVW5pdE5vZGUubWFrZUZyb21FbmNvZGluZyhtb2RlbCkuYXNzZW1ibGUoKTtcbn1cblxuZnVuY3Rpb24gYXNzZW1ibGVGcm9tVHJhbnNmb3JtKHQ6IFRpbWVVbml0VHJhbnNmb3JtKSB7XG4gIHJldHVybiBUaW1lVW5pdE5vZGUubWFrZUZyb21UcmFuc2Zvcm0odCkuYXNzZW1ibGUoKTtcbn1cblxuZGVzY3JpYmUoJ2NvbXBpbGUvZGF0YS90aW1ldW5pdCcsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3BhcnNlVW5pdCcsICgpID0+IHtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgZGljdGlvbmFyeSBvZiBmb3JtdWxhIHRyYW5zZm9ybScsICgpID0+IHtcblxuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ2YWx1ZXNcIjogW119LFxuICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge2ZpZWxkOiAnYScsIHR5cGU6ICd0ZW1wb3JhbCcsIHRpbWVVbml0OiAnbW9udGgnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChhc3NlbWJsZUZyb21FbmNvZGluZyhtb2RlbCksIFt7XG4gICAgICAgIHR5cGU6ICdmb3JtdWxhJyxcbiAgICAgICAgYXM6ICdtb250aF9hJyxcbiAgICAgICAgZXhwcjogJ2RhdGV0aW1lKDAsIG1vbnRoKGRhdHVtW1wiYVwiXSksIDEsIDAsIDAsIDAsIDApJ1xuICAgICAgfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBkaWN0aW9uYXJ5IG9mIGZvcm11bGEgdHJhbnNmb3JtIGZyb20gdHJhbnNmb3JtIGFycmF5JywgKCkgPT4ge1xuICAgICAgY29uc3QgdDogVGltZVVuaXRUcmFuc2Zvcm0gPSB7ZmllbGQ6ICdkYXRlJywgYXM6ICdtb250aF9kYXRlJywgdGltZVVuaXQ6ICdtb250aCd9O1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGFzc2VtYmxlRnJvbVRyYW5zZm9ybSh0KSwgW3tcbiAgICAgICAgdHlwZTogJ2Zvcm11bGEnLFxuICAgICAgICBhczogJ21vbnRoX2RhdGUnLFxuICAgICAgICBleHByOiAnZGF0ZXRpbWUoMCwgbW9udGgoZGF0dW1bXCJkYXRlXCJdKSwgMSwgMCwgMCwgMCwgMCknXG4gICAgICB9XSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/facet.test.js b/build/test/compile/facet.test.js new file mode 100644 index 0000000000..d0f1e007f3 --- /dev/null +++ b/build/test/compile/facet.test.js @@ -0,0 +1,346 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../src/channel"); +var log = require("../../src/log"); +var type_1 = require("../../src/type"); +var util_1 = require("../util"); +describe('FacetModel', function () { + describe('initFacet', function () { + it('should drop unsupported channel and throws warning', log.wrap(function (localLogger) { + var model = util_1.parseFacetModel({ + facet: ({ + shape: { field: 'a', type: 'quantitative' } + }), + spec: { + mark: 'point', + encoding: {} + } + }); + chai_1.assert.equal(model.facet['shape'], undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.incompatibleChannel(channel_1.SHAPE, 'facet')); + })); + it('should drop channel without field and value and throws warning', log.wrap(function (localLogger) { + var model = util_1.parseFacetModel({ + facet: { + row: { type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + chai_1.assert.equal(model.facet.row, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: type_1.ORDINAL }, channel_1.ROW)); + })); + it('should drop channel without field and value and throws warning', log.wrap(function (localLogger) { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + chai_1.assert.deepEqual(model.facet.row, { field: 'a', type: 'quantitative' }); + chai_1.assert.equal(localLogger.warns[0], log.message.facetChannelShouldBeDiscrete(channel_1.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 = util_1.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]; + chai_1.assert(columnHeader.title.text.signal, "timeFormat(parent[\"year_date\"], '%Y')"); + }); + it('applies number format for fieldref of a quantitative field', function () { + var model = util_1.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]; + chai_1.assert(columnHeader.title.text.signal, "format(parent[\"a\"], 'd')"); + }); + it('ignores number format for fieldref of a binned field', function () { + var model = util_1.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]; + chai_1.assert(columnHeader.title.text.signal, "parent[\"a\"]"); + }); + }); + describe('parseScale', function () { + it('should correctly set scale component for a model', function () { + var model = util_1.parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + }); + chai_1.assert(model.component.scales['x']); + }); + it('should create independent scales if resolve is set to independent', function () { + var model = util_1.parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + }, + resolve: { + scale: { + x: 'independent' + } + } + }); + chai_1.assert(!model.component.scales['x']); + }); + }); + describe('assembleHeaderMarks', function () { + it('should sort headers in ascending order', function () { + var model = util_1.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]; + chai_1.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 = util_1.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([]); + chai_1.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 = util_1.parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + }); + var layout = model.assembleLayout(); + chai_1.assert.deepEqual(layout, { + padding: { row: 10, column: 10 }, + offset: 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 = util_1.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(); + chai_1.assert.deepEqual(layout.columns, undefined); + }); + it('returns a layout with header band if child spec is also a facet', function () { + var model = util_1.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(); + chai_1.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 = util_1.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(); + chai_1.assert(marks[0].from.facet.aggregate.cross); + chai_1.assert.deepEqual(marks[0].sort, { + field: [ + 'datum["a"]', + 'datum["b"]' + ], + order: [ + 'ascending', + 'ascending' + ] + }); + }); + it('should add calculate cardinality for independent scales', function () { + var model = util_1.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(); + chai_1.assert.deepEqual(marks[0].from.facet.aggregate, { + fields: ['b', 'c'], + ops: ['distinct', 'distinct'] + }); + }); + it('should add calculate cardinality for child column facet', function () { + var model = util_1.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(); + chai_1.assert.deepEqual(marks[0].from.facet.aggregate, { + fields: ['c'], + ops: ['distinct'] + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvY29tcGlsZS9mYWNldC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1Qiw2Q0FBNkM7QUFJN0MsbUNBQXFDO0FBQ3JDLHVDQUF1QztBQUV2QyxnQ0FBa0U7QUFFbEUsUUFBUSxDQUFDLFlBQVksRUFBRTtJQUNyQixRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLEVBQUUsQ0FBQyxvREFBb0QsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztZQUM1RSxJQUFNLEtBQUssR0FBRyxzQkFBZSxDQUFDO2dCQUM1QixLQUFLLEVBQUUsQ0FBQztvQkFDTixLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7aUJBQzFDLENBQXlCO2dCQUMxQixJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLE9BQU87b0JBQ2IsUUFBUSxFQUFFLEVBQUU7aUJBQ2I7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDOUMsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsZUFBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdEYsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVKLEVBQUUsQ0FBQyxnRUFBZ0UsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztZQUN4RixJQUFNLEtBQUssR0FBRyxzQkFBZSxDQUFDO2dCQUM1QixLQUFLLEVBQUU7b0JBQ0wsR0FBRyxFQUFFLEVBQUMsSUFBSSxFQUFFLFNBQVMsRUFBQztpQkFDdkI7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Q0FBQyxLQUFLLEVBQUUsQ0FBQztZQUVkLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUVwQyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTtnQkFDOUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDO2dCQUNiLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQzthQUNsQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZSBxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtST1csIFNIQVBFfSBmcm9tICcuLi8uLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge0ZhY2V0TW9kZWx9IGZyb20gJy4uLy4uL3NyYy9jb21waWxlL2ZhY2V0JztcbmltcG9ydCB7RmFjZXRNYXBwaW5nfSBmcm9tICcuLi8uLi9zcmMvZmFjZXQnO1xuaW1wb3J0IHtQb3NpdGlvbkZpZWxkRGVmfSBmcm9tICcuLi8uLi9zcmMvZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uL3NyYy9sb2cnO1xuaW1wb3J0IHtPUkRJTkFMfSBmcm9tICcuLi8uLi9zcmMvdHlwZSc7XG5pbXBvcnQge1ZnTGF5b3V0fSBmcm9tICcuLi8uLi9zcmMvdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtwYXJzZUZhY2V0TW9kZWwsIHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdGYWNldE1vZGVsJywgZnVuY3Rpb24oKSB7XG4gIGRlc2NyaWJlKCdpbml0RmFjZXQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBkcm9wIHVuc3VwcG9ydGVkIGNoYW5uZWwgYW5kIHRocm93cyB3YXJuaW5nJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbCh7XG4gICAgICAgIGZhY2V0OiAoe1xuICAgICAgICAgIHNoYXBlOiB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH0pIGFzIEZhY2V0TWFwcGluZzxzdHJpbmc+LCAvLyBDYXN0IHRvIGFsbG93IGludmFsaWQgZmFjZXQgdHlwZSBmb3IgdGVzdFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge31cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuZmFjZXRbJ3NoYXBlJ10sIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmluY29tcGF0aWJsZUNoYW5uZWwoU0hBUEUsICdmYWNldCcpKTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIGRyb3AgY2hhbm5lbCB3aXRob3V0IGZpZWxkIGFuZCB2YWx1ZSBhbmQgdGhyb3dzIHdhcm5pbmcnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICByb3c6IHt0eXBlOiAnb3JkaW5hbCd9XG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7fVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5mYWNldC5yb3csIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmVtcHR5RmllbGREZWYoe3R5cGU6IE9SRElOQUx9LCBST1cpKTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIGRyb3AgY2hhbm5lbCB3aXRob3V0IGZpZWxkIGFuZCB2YWx1ZSBhbmQgdGhyb3dzIHdhcm5pbmcnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICByb3c6IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHt9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxQb3NpdGlvbkZpZWxkRGVmPHN0cmluZz4+KG1vZGVsLmZhY2V0LnJvdywge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmZhY2V0Q2hhbm5lbFNob3VsZEJlRGlzY3JldGUoUk9XKSk7XG4gICAgfSkpO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2VBeGlzQW5kSGVhZGVyJywgKCkgPT4ge1xuICAgIC8vIFRPRE86IGFkZCBtb3JlIHRlc3RzXG4gICAgLy8gLSBjb3JyZWN0bHkgam9pbiB0aXRsZSBmb3IgbmVzdGVkIGZhY2V0XG4gICAgLy8gLSBjb3JyZWN0bHkgZ2VuZXJhdGUgaGVhZGVycyB3aXRoIHJpZ2h0IGxhYmVscyBhbmQgYXhlc1xuXG5cbiAgICBpdCgnYXBwbGllcyB0ZXh0IGZvcm1hdCB0byB0aGUgZmllbGRyZWYgb2YgYSB0ZW1wb3JhbCBmaWVsZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICBjb2x1bW46IHt0aW1lVW5pdDoneWVhcicsIGZpZWxkOiAnZGF0ZScsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG1vZGVsLnBhcnNlQXhpc0FuZEhlYWRlcigpO1xuICAgICAgY29uc3QgaGVhZGVyTWFya3MgPSBtb2RlbC5hc3NlbWJsZUhlYWRlck1hcmtzKCk7XG4gICAgICBjb25zdCBjb2x1bW5IZWFkZXIgPSBoZWFkZXJNYXJrcy5maWx0ZXIoZnVuY3Rpb24oZCl7XG4gICAgICAgIHJldHVybiBkLm5hbWUgPT09IFwiY29sdW1uX2hlYWRlclwiO1xuICAgICAgfSlbMF07XG5cbiAgICAgIGFzc2VydChjb2x1bW5IZWFkZXIudGl0bGUudGV4dC5zaWduYWwsIFwidGltZUZvcm1hdChwYXJlbnRbXFxcInllYXJfZGF0ZVxcXCJdLCAnJVknKVwiKTtcbiAgICB9KTtcblxuICAgIGl0KCdhcHBsaWVzIG51bWJlciBmb3JtYXQgZm9yIGZpZWxkcmVmIG9mIGEgcXVhbnRpdGF0aXZlIGZpZWxkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBmYWNldDoge1xuICAgICAgICAgIGNvbHVtbjoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCBmb3JtYXQ6ICdkJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG1vZGVsLnBhcnNlQXhpc0FuZEhlYWRlcigpO1xuICAgICAgY29uc3QgaGVhZGVyTWFya3MgPSBtb2RlbC5hc3NlbWJsZUhlYWRlck1hcmtzKCk7XG4gICAgICBjb25zdCBjb2x1bW5IZWFkZXIgPSBoZWFkZXJNYXJrcy5maWx0ZXIoZnVuY3Rpb24oZCl7XG4gICAgICAgIHJldHVybiBkLm5hbWUgPT09IFwiY29sdW1uX2hlYWRlclwiO1xuICAgICAgfSlbMF07XG5cbiAgICAgIGFzc2VydChjb2x1bW5IZWFkZXIudGl0bGUudGV4dC5zaWduYWwsIFwiZm9ybWF0KHBhcmVudFtcXFwiYVxcXCJdLCAnZCcpXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2lnbm9yZXMgbnVtYmVyIGZvcm1hdCBmb3IgZmllbGRyZWYgb2YgYSBiaW5uZWQgZmllbGQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgY29sdW1uOiB7YmluOiB0cnVlLCBmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG1vZGVsLnBhcnNlQXhpc0FuZEhlYWRlcigpO1xuICAgICAgY29uc3QgaGVhZGVyTWFya3MgPSBtb2RlbC5hc3NlbWJsZUhlYWRlck1hcmtzKCk7XG4gICAgICBjb25zdCBjb2x1bW5IZWFkZXIgPSBoZWFkZXJNYXJrcy5maWx0ZXIoZnVuY3Rpb24oZCl7XG4gICAgICAgIHJldHVybiBkLm5hbWUgPT09IFwiY29sdW1uX2hlYWRlclwiO1xuICAgICAgfSlbMF07XG5cbiAgICAgIGFzc2VydChjb2x1bW5IZWFkZXIudGl0bGUudGV4dC5zaWduYWwsIFwicGFyZW50W1xcXCJhXFxcIl1cIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXJzZVNjYWxlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IHNldCBzY2FsZSBjb21wb25lbnQgZm9yIGEgbW9kZWwnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgcm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuXG4gICAgICBhc3NlcnQobW9kZWwuY29tcG9uZW50LnNjYWxlc1sneCddKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGluZGVwZW5kZW50IHNjYWxlcyBpZiByZXNvbHZlIGlzIHNldCB0byBpbmRlcGVuZGVudCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICByb3c6IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgICBzY2FsZToge1xuICAgICAgICAgICAgeDogJ2luZGVwZW5kZW50J1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydCghbW9kZWwuY29tcG9uZW50LnNjYWxlc1sneCddKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2Fzc2VtYmxlSGVhZGVyTWFya3MnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzb3J0IGhlYWRlcnMgaW4gYXNjZW5kaW5nIG9yZGVyJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBmYWNldDoge1xuICAgICAgICAgIGNvbHVtbjoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCBmb3JtYXQ6ICdkJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG1vZGVsLnBhcnNlQXhpc0FuZEhlYWRlcigpO1xuXG4gICAgICBjb25zdCBoZWFkZXJNYXJrcyA9IG1vZGVsLmFzc2VtYmxlSGVhZGVyTWFya3MoKTtcbiAgICAgIGNvbnN0IGNvbHVtbkhlYWRlciA9IGhlYWRlck1hcmtzLmZpbHRlcihmdW5jdGlvbihkKXtcbiAgICAgICAgcmV0dXJuIGQubmFtZSA9PT0gXCJjb2x1bW5faGVhZGVyXCI7XG4gICAgICB9KVswXTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChjb2x1bW5IZWFkZXIuc29ydCwge2ZpZWxkOiAnZGF0dW1bXCJhXCJdJywgb3JkZXI6ICdhc2NlbmRpbmcnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhc3NlbWJsZUdyb3VwJywgKCkgPT4ge1xuICAgIGl0KCdpbmNsdWRlcyBhIGNvbHVtbnMgZmllbGRzIGluIHRoZSBlbmNvZGUgYmxvY2sgZm9yIGZhY2V0IHdpdGggY29sdW1uIHRoYXQgcGFyZW50IGlzIGFsc28gYSBmYWNldC4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgY29sdW1uOiB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgICBjb2x1bW46IHtmaWVsZDogJ2MnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICB9LFxuICAgICAgICAgIHNwZWM6IHtcbiAgICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgICB4OiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IHJlbW92ZSBcImFueVwiIG9uY2Ugd2Ugc3VwcG9ydCBhbGwgZmFjZXQgbGlzdGVkIGluIGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EtbGl0ZS9pc3N1ZXMvMjc2MFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgbW9kZWwucGFyc2VEYXRhKCk7XG4gICAgICBjb25zdCBncm91cCA9IG1vZGVsLmNoaWxkLmFzc2VtYmxlR3JvdXAoW10pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChncm91cC5lbmNvZGUudXBkYXRlLmNvbHVtbnMsIHtmaWVsZDogJ2Rpc3RpbmN0X2MnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhc3NlbWJsZUxheW91dCcsICgpID0+IHtcbiAgICBpdCgncmV0dXJucyBhIGxheW91dCB3aXRoIGEgY29sdW1uIHNpZ25hbCBmb3IgZmFjZXQgd2l0aCBjb2x1bW4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgY29sdW1uOiB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGxheW91dCA9IG1vZGVsLmFzc2VtYmxlTGF5b3V0KCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPFZnTGF5b3V0PihsYXlvdXQsIHtcbiAgICAgICAgcGFkZGluZzoge3JvdzogMTAsIGNvbHVtbjogMTB9LFxuICAgICAgICBvZmZzZXQ6IDEwLFxuICAgICAgICBjb2x1bW5zOiB7XG4gICAgICAgICAgc2lnbmFsOiBcImxlbmd0aChkYXRhKCdjb2x1bW5fZG9tYWluJykpXCJcbiAgICAgICAgfSxcbiAgICAgICAgYm91bmRzOiAnZnVsbCcsXG4gICAgICAgIGFsaWduOiAnYWxsJ1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyBhIGxheW91dCB3aXRob3V0IGEgY29sdW1uIHNpZ25hbCBmb3IgZmFjZXQgd2l0aCBjb2x1bW4gdGhhdCBwYXJlbnQgaXMgYWxzbyBhIGZhY2V0LicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICBjb2x1bW46IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICAgIGNvbHVtbjoge2ZpZWxkOiAnYycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3BlYzoge1xuICAgICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gVE9ETzogcmVtb3ZlIFwiYW55XCIgb25jZSB3ZSBzdXBwb3J0IGFsbCBmYWNldCBsaXN0ZWQgaW4gaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS1saXRlL2lzc3Vlcy8yNzYwXG4gICAgICB9IGFzIGFueSk7XG4gICAgICBjb25zdCBsYXlvdXQgPSBtb2RlbC5jaGlsZC5hc3NlbWJsZUxheW91dCgpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChsYXlvdXQuY29sdW1ucywgdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIGEgbGF5b3V0IHdpdGggaGVhZGVyIGJhbmQgaWYgY2hpbGQgc3BlYyBpcyBhbHNvIGEgZmFjZXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIFwiJHNjaGVtYVwiOiBcImh0dHBzOi8vdmVnYS5naXRodWIuaW8vc2NoZW1hL3ZlZ2EtbGl0ZS92Mi5qc29uXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2NhcnMuanNvblwifSxcbiAgICAgICAgXCJmYWNldFwiOiB7XCJyb3dcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9fSxcbiAgICAgICAgXCJzcGVjXCI6IHtcbiAgICAgICAgICBcImZhY2V0XCI6IHtcInJvd1wiOiB7XCJmaWVsZFwiOiBcIkN5bGluZGVyc1wiLFwidHlwZVwiOiBcIm9yZGluYWxcIn19LFxuICAgICAgICAgIFwic3BlY1wiOiB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIkFjY2VsZXJhdGlvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPOiByZW1vdmUgXCJhbnlcIiBvbmNlIHdlIHN1cHBvcnQgYWxsIGZhY2V0IGxpc3RlZCBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzI3NjBcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIG1vZGVsLnBhcnNlTGF5b3V0U2l6ZSgpO1xuICAgICAgbW9kZWwucGFyc2VBeGlzQW5kSGVhZGVyKCk7XG4gICAgICBjb25zdCBsYXlvdXQgPSBtb2RlbC5hc3NlbWJsZUxheW91dCgpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChsYXlvdXQuaGVhZGVyQmFuZCwge3JvdzogMC41fSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhc3NlbWJsZU1hcmtzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYWRkIGNyb3NzIGFuZCBzb3J0IGlmIHdlIGZhY2V0IGJ5IG11bHRpcGxlIGRpbWVuc2lvbnMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbDogRmFjZXRNb2RlbCA9IHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgcm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfSxcbiAgICAgICAgICBjb2x1bW46IHtmaWVsZDogJ2InLCB0eXBlOiAnb3JkaW5hbCd9XG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG1vZGVsLnBhcnNlKCk7XG5cbiAgICAgIGNvbnN0IG1hcmtzID0gbW9kZWwuYXNzZW1ibGVNYXJrcygpO1xuXG4gICAgICBhc3NlcnQobWFya3NbMF0uZnJvbS5mYWNldC5hZ2dyZWdhdGUuY3Jvc3MpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtYXJrc1swXS5zb3J0LCB7XG4gICAgICAgIGZpZWxkOiBbXG4gICAgICAgICAgJ2RhdHVtW1wiYVwiXScsXG4gICAgICAgICAgJ2RhdHVtW1wiYlwiXSdcbiAgICAgICAgXSxcbiAgICAgICAgb3JkZXI6IFtcbiAgICAgICAgICAnYXNjZW5kaW5nJyxcbiAgICAgICAgICAnYXNjZW5kaW5nJ1xuICAgICAgICBdXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWRkIGNhbGN1bGF0ZSBjYXJkaW5hbGl0eSBmb3IgaW5kZXBlbmRlbnQgc2NhbGVzJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWw6IEZhY2V0TW9kZWwgPSBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBmYWNldDoge1xuICAgICAgICAgIHJvdzoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdyZWN0JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdub21pbmFsJ30sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ25vbWluYWwnfVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgcmVzb2x2ZToge1xuICAgICAgICAgIHNjYWxlOiB7XG4gICAgICAgICAgICB4OiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgeTogJ2luZGVwZW5kZW50J1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBtb2RlbC5wYXJzZSgpO1xuXG4gICAgICBjb25zdCBtYXJrcyA9IG1vZGVsLmFzc2VtYmxlTWFya3MoKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtYXJrc1swXS5mcm9tLmZhY2V0LmFnZ3JlZ2F0ZSwge1xuICAgICAgICBmaWVsZHM6IFsnYicsICdjJ10sXG4gICAgICAgIG9wczogWydkaXN0aW5jdCcsICdkaXN0aW5jdCddXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWRkIGNhbGN1bGF0ZSBjYXJkaW5hbGl0eSBmb3IgY2hpbGQgY29sdW1uIGZhY2V0JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWw6IEZhY2V0TW9kZWwgPSBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBmYWNldDoge1xuICAgICAgICAgIGNvbHVtbjoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICBmYWNldDoge1xuICAgICAgICAgICAgY29sdW1uOiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPOiByZW1vdmUgXCJhbnlcIiBvbmNlIHdlIHN1cHBvcnQgYWxsIGZhY2V0IGxpc3RlZCBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhLWxpdGUvaXNzdWVzLzI3NjBcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIG1vZGVsLnBhcnNlKCk7XG5cbiAgICAgIGNvbnN0IG1hcmtzID0gbW9kZWwuYXNzZW1ibGVNYXJrcygpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKG1hcmtzWzBdLmZyb20uZmFjZXQuYWdncmVnYXRlLCB7XG4gICAgICAgIGZpZWxkczogWydjJ10sXG4gICAgICAgIG9wczogWydkaXN0aW5jdCddXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/layer.test.js b/build/test/compile/layer.test.js new file mode 100644 index 0000000000..f3e23b71f8 --- /dev/null +++ b/build/test/compile/layer.test.js @@ -0,0 +1,97 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../util"); +describe('Layer', function () { + describe('parseScale', function () { + it('should merge domains', function () { + var model = util_1.parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'ordinal' } + } + }] + }); + chai_1.assert.equal(model.children.length, 2); + model.parseScale(); + chai_1.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 = util_1.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(); + chai_1.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 = util_1.parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + }], + resolve: { + scale: { + x: 'independent' + } + } + }); + chai_1.assert.equal(model.children.length, 2); + it('should leave scales in children when set to be independent', function () { + model.parseScale(); + chai_1.assert.equal(model.component.scales['x'], undefined); + chai_1.assert.deepEqual(model.children[0].component.scales['x'].domains, [{ + data: 'layer_0_main', + field: 'a' + }]); + chai_1.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(); + chai_1.assert.equal(model.component.axes['x'].length, 2); + chai_1.assert.equal(model.component.axes['x'][1].main.implicit.orient, 'top'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sYXllci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLGdDQUF3QztBQUV4QyxRQUFRLENBQUMsT0FBTyxFQUFFO0lBQ2hCLFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDckIsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1lBQ3pCLElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7Z0JBQzVCLEtBQUssRUFBRSxDQUFDO3dCQUNOLElBQUksRUFBRSxPQUFPO3dCQUNiLFFBQVEsRUFBRTs0QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7eUJBQ2pDO3FCQUNGLEVBQUM7d0JBQ0EsSUFBSSxFQUFFLE9BQU87d0JBQ2IsUUFBUSxFQUFFOzRCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzt5QkFDakM7cUJBQ0YsQ0FBQzthQUNILENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRW5CLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ25ELElBQUksRUFBRSxjQUFjO29CQUNwQixLQUFLLEVBQUUsR0FBRztvQkFDVixJQUFJLEVBQUUsSUFBSTtpQkFDWCxFQUFFO29CQUNELElBQUksRUFBRSxjQUFjO29CQUNwQixLQUFLLEVBQUUsR0FBRztvQkFDVixJQUFJLEVBQUUsSUFBSTtpQkFDWCxDQUFDLENBQUMsQ0FBQztRQUNSLENBQUMsQ0FBQyxDQUFD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LENBQUMsQ0FBQyxDQUFDO1lBQ2xELGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtwYXJzZUxheWVyTW9kZWx9IGZyb20gJy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnTGF5ZXInLCBmdW5jdGlvbigpIHtcbiAgZGVzY3JpYmUoJ3BhcnNlU2NhbGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBtZXJnZSBkb21haW5zJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUxheWVyTW9kZWwoe1xuICAgICAgICBsYXllcjogW3tcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICAgIH1cbiAgICAgICAgfSx7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgICB9XG4gICAgICAgIH1dXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5jaGlsZHJlbi5sZW5ndGgsIDIpO1xuICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKG1vZGVsLmNvbXBvbmVudC5zY2FsZXNbJ3gnXS5kb21haW5zLCBbe1xuICAgICAgICAgIGRhdGE6ICdsYXllcl8wX21haW4nLFxuICAgICAgICAgIGZpZWxkOiAnYScsXG4gICAgICAgICAgc29ydDogdHJ1ZVxuICAgICAgICB9LCB7XG4gICAgICAgICAgZGF0YTogJ2xheWVyXzFfbWFpbicsXG4gICAgICAgICAgZmllbGQ6ICdiJyxcbiAgICAgICAgICBzb3J0OiB0cnVlXG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdW5pb24gZXhwbGljaXQgYW5kIHJlZmVyZW5jZWQgZG9tYWlucycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VMYXllck1vZGVsKHtcbiAgICAgICAgbGF5ZXI6IFt7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge3NjYWxlOiB7ZG9tYWluOiBbMSwgMiwgM119LCBmaWVsZDogJ2InLCB0eXBlOiAnb3JkaW5hbCd9XG4gICAgICAgICAgfVxuICAgICAgICB9LCB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgICB9XG4gICAgICAgIH1dXG4gICAgICB9KTtcbiAgICAgIG1vZGVsLnBhcnNlU2NhbGUoKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtb2RlbC5jb21wb25lbnQuc2NhbGVzWyd4J10uZG9tYWlucywgW1xuICAgICAgICBbMSwgMiwgM10sXG4gICAgICAgIHtcbiAgICAgICAgICBkYXRhOiAnbGF5ZXJfMV9tYWluJyxcbiAgICAgICAgICBmaWVsZDogJ2InLFxuICAgICAgICAgIHNvcnQ6IHRydWVcbiAgICAgICAgfV0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZHVhbCBheGlzIGNoYXJ0JywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VMYXllck1vZGVsKHtcbiAgICAgIGxheWVyOiBbe1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfVxuICAgICAgfSwge1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfVxuICAgICAgfV0sXG4gICAgICByZXNvbHZlOiB7XG4gICAgICAgIHNjYWxlOiB7XG4gICAgICAgICAgeDogJ2luZGVwZW5kZW50J1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhc3NlcnQuZXF1YWwobW9kZWwuY2hpbGRyZW4ubGVuZ3RoLCAyKTtcblxuICAgIGl0KCdzaG91bGQgbGVhdmUgc2NhbGVzIGluIGNoaWxkcmVuIHdoZW4gc2V0IHRvIGJlIGluZGVwZW5kZW50JywgKCkgPT4ge1xuICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuY29tcG9uZW50LnNjYWxlc1sneCddLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtb2RlbC5jaGlsZHJlblswXS5jb21wb25lbnQuc2NhbGVzWyd4J10uZG9tYWlucywgW3tcbiAgICAgICAgZGF0YTogJ2xheWVyXzBfbWFpbicsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH1dKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY2hpbGRyZW5bMV0uY29tcG9uZW50LnNjYWxlc1sneCddLmRvbWFpbnMsIFt7XG4gICAgICAgIGRhdGE6ICdsYXllcl8xX21haW4nLFxuICAgICAgICBmaWVsZDogJ2InXG4gICAgICB9XSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBzZWNvbmQgYXhpcyBvbiB0b3AnLCAoKSA9PiB7XG4gICAgICBtb2RlbC5wYXJzZUF4aXNBbmRIZWFkZXIoKTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLmNvbXBvbmVudC5heGVzWyd4J10ubGVuZ3RoLCAyKTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5jb21wb25lbnQuYXhlc1sneCddWzFdLm1haW4uaW1wbGljaXQub3JpZW50LCAndG9wJyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/layout/header.test.js b/build/test/compile/layout/header.test.js new file mode 100644 index 0000000000..dd00af64d4 --- /dev/null +++ b/build/test/compile/layout/header.test.js @@ -0,0 +1,88 @@ +"use strict"; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var header_1 = require("../../../src/compile/layout/header"); +var util_1 = require("../../util"); +describe('compile/layout/header', function () { + describe('getTitleGroup', function () { + var model = util_1.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 = header_1.getTitleGroup(model, 'column'); + var marks = columnLabelGroup.marks, columnTitleGroupTopLevelProps = __rest(columnLabelGroup, ["marks"]); + it('returns a header group mark with correct name, role, type, and from.', function () { + chai_1.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 () { + chai_1.assert.equal(marks.length, 1); + chai_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 = header_1.getTitleGroup(model, 'row'); + var marks = rowTitleGroup.marks, rowTitleGroupTopLevelProps = __rest(rowTitleGroup, ["marks"]); + it('returns a header group mark with correct name, role, type, from, and encode.', function () { + chai_1.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 () { + chai_1.assert.equal(marks.length, 1); + chai_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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhZGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbGF5b3V0L2hlYWRlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUEsNkJBQTRCO0FBQzVCLDZEQUFpRTtBQUVqRSxtQ0FBMkM7QUFFM0MsUUFBUSxDQUFDLHVCQUF1QixFQUFFO0lBQ2hDLFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsSUFBTSxLQUFLLEdBQUcsc0JBQWUsQ0FBQztZQUM1QixLQUFLLEVBQUU7Z0JBQ0wsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO2dCQUNsQyxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7YUFDdEM7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztvQkFDckMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ25CLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQixRQUFRLENBQUMsWUFBWSxFQUFFO1lBQ3JCLElBQU0sZ0JBQWdCLEdBQUcsc0JBQWEsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDakQsSUFBQSw4QkFBSyxFQUFFLG1FQUFnQyxDQUFxQjtZQUNuRSxFQUFFLENBQUMsc0VBQXNFLEVBQUU7Z0JBRXpFLGFBQU0sQ0FBQyxTQUFTLENBQUMsNkJBQTZCLEVBQUU7b0JBQzlDLElBQUksRUFBRSxjQUFjO29CQUNwQixJQUFJLEVBQUUsT0FBTztvQkFDYixJQUFJLEVBQUUsY0FBYztpQkFDckIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFMUIsRUFBRSxDQUFDLHlGQUF5RixFQUFFO2dCQUM1RixhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLGFBQU0sQ0FBQyxTQUFTLENBQWMsUUFBUSxFQUFFO29CQUN0QyxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsbUJBQW1CO29CQUN6QixLQUFLLEVBQUUsYUFBYTtvQkFDcEIsTUFBTSxFQUFFO3dCQUNOLE1BQU0sRUFBRTs0QkFDTixJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDOzRCQUNsQixLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDO3lCQUN6QjtxQkFDRjtpQkFDRixDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLFNBQVMsRUFBRTtZQUNsQixJQUFNLGFBQWEsR0FBRyxzQkFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxJQUFBLDJCQUFLLEVBQUUsNkRBQTZCLENBQWtCO1lBQzdELEVBQUUsQ0FBQyw4RUFBOEUsRUFBRTtnQkFFakYsYUFBTSxDQUFDLFNBQVMsQ0FBQywwQkFBMEIsRUFBRTtvQkFDM0MsSUFBSSxFQUFFLFdBQVc7b0JBQ2pCLElBQUksRUFBRSxPQUFPO29CQUNiLElBQUksRUFBRSxXQUFXO2lCQUNsQixDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUNILElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUUxQixFQUFFLENBQUMseUZBQXlGLEVBQUU7Z0JBQzVGLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDOUIsYUFBTSxDQUFDLFNBQVMsQ0FBYyxRQUFRLEVBQUU7b0JBQ3RDLElBQUksRUFBRSxNQUFNO29CQUNaLElBQUksRUFBRSxnQkFBZ0I7b0JBQ3RCLEtBQUssRUFBRSxhQUFhO29CQUNwQixNQUFNLEVBQUU7d0JBQ04sTUFBTSxFQUFFOzRCQUNOLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUM7NEJBQ2xCLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUM7NEJBQ25CLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUM7eUJBQ3pCO3FCQUNGO2lCQUNGLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtnZXRUaXRsZUdyb3VwfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9sYXlvdXQvaGVhZGVyJztcbmltcG9ydCB7VmdNYXJrR3JvdXB9IGZyb20gJy4uLy4uLy4uL3NyYy92ZWdhLnNjaGVtYSc7XG5pbXBvcnQge3BhcnNlRmFjZXRNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdjb21waWxlL2xheW91dC9oZWFkZXInLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdnZXRUaXRsZUdyb3VwJywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHtcbiAgICAgIGZhY2V0OiB7XG4gICAgICAgIHJvdzoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ30sXG4gICAgICAgIGNvbHVtbjoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgIH0sXG4gICAgICBzcGVjOiB7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBtb2RlbC5wYXJzZVNjYWxlKCk7XG4gICAgbW9kZWwucGFyc2VMYXlvdXRTaXplKCk7XG4gICAgbW9kZWwucGFyc2VBeGlzQW5kSGVhZGVyKCk7XG5cbiAgICBkZXNjcmliZSgnZm9yIGNvbHVtbicsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbHVtbkxhYmVsR3JvdXAgPSBnZXRUaXRsZUdyb3VwKG1vZGVsLCAnY29sdW1uJyk7XG4gICAgICBjb25zdCB7bWFya3MsIC4uLmNvbHVtblRpdGxlR3JvdXBUb3BMZXZlbFByb3BzfSA9IGNvbHVtbkxhYmVsR3JvdXA7XG4gICAgICBpdCgncmV0dXJucyBhIGhlYWRlciBncm91cCBtYXJrIHdpdGggY29ycmVjdCBuYW1lLCByb2xlLCB0eXBlLCBhbmQgZnJvbS4nLCAoKSA9PiB7XG5cbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChjb2x1bW5UaXRsZUdyb3VwVG9wTGV2ZWxQcm9wcywge1xuICAgICAgICAgIG5hbWU6ICdjb2x1bW5fdGl0bGUnLFxuICAgICAgICAgIHR5cGU6ICdncm91cCcsXG4gICAgICAgICAgcm9sZTogJ2NvbHVtbi10aXRsZSdcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHRleHRNYXJrID0gbWFya3NbMF07XG5cbiAgICAgIGl0KCdjb250YWlucyBhIGNvcnJlY3QgdGV4dCBtYXJrIHdpdGggdGhlIGNvcnJlY3Qgcm9sZSBhbmQgZW5jb2RlIGFzIHRoZSBvbmx5IGl0ZW0gaW4gbWFya3MnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChtYXJrcy5sZW5ndGgsIDEpO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsPFZnTWFya0dyb3VwPih0ZXh0TWFyaywge1xuICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICByb2xlOiAnY29sdW1uLXRpdGxlLXRleHQnLFxuICAgICAgICAgIHN0eWxlOiAnZ3VpZGUtdGl0bGUnLFxuICAgICAgICAgIGVuY29kZToge1xuICAgICAgICAgICAgdXBkYXRlOiB7XG4gICAgICAgICAgICAgIHRleHQ6IHt2YWx1ZTogJ2EnfSxcbiAgICAgICAgICAgICAgYWxpZ246IHt2YWx1ZTogJ2NlbnRlcid9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2ZvciByb3cnLCAoKSA9PiB7XG4gICAgICBjb25zdCByb3dUaXRsZUdyb3VwID0gZ2V0VGl0bGVHcm91cChtb2RlbCwgJ3JvdycpO1xuICAgICAgY29uc3Qge21hcmtzLCAuLi5yb3dUaXRsZUdyb3VwVG9wTGV2ZWxQcm9wc30gPSByb3dUaXRsZUdyb3VwO1xuICAgICAgaXQoJ3JldHVybnMgYSBoZWFkZXIgZ3JvdXAgbWFyayB3aXRoIGNvcnJlY3QgbmFtZSwgcm9sZSwgdHlwZSwgZnJvbSwgYW5kIGVuY29kZS4nLCAoKSA9PiB7XG5cbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChyb3dUaXRsZUdyb3VwVG9wTGV2ZWxQcm9wcywge1xuICAgICAgICAgIG5hbWU6ICdyb3dfdGl0bGUnLFxuICAgICAgICAgIHR5cGU6ICdncm91cCcsXG4gICAgICAgICAgcm9sZTogJ3Jvdy10aXRsZSdcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHRleHRNYXJrID0gbWFya3NbMF07XG5cbiAgICAgIGl0KCdjb250YWlucyBhIGNvcnJlY3QgdGV4dCBtYXJrIHdpdGggdGhlIGNvcnJlY3Qgcm9sZSBhbmQgZW5jb2RlIGFzIHRoZSBvbmx5IGl0ZW0gaW4gbWFya3MnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChtYXJrcy5sZW5ndGgsIDEpO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsPFZnTWFya0dyb3VwPih0ZXh0TWFyaywge1xuICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICByb2xlOiAncm93LXRpdGxlLXRleHQnLFxuICAgICAgICAgIHN0eWxlOiAnZ3VpZGUtdGl0bGUnLFxuICAgICAgICAgIGVuY29kZToge1xuICAgICAgICAgICAgdXBkYXRlOiB7XG4gICAgICAgICAgICAgIHRleHQ6IHt2YWx1ZTogJ2EnfSxcbiAgICAgICAgICAgICAgYW5nbGU6IHt2YWx1ZTogMjcwfSxcbiAgICAgICAgICAgICAgYWxpZ246IHt2YWx1ZTogJ2NlbnRlcid9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/layoutsize/assemble.test.js b/build/test/compile/layoutsize/assemble.test.js new file mode 100644 index 0000000000..8713eb8d69 --- /dev/null +++ b/build/test/compile/layoutsize/assemble.test.js @@ -0,0 +1,165 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var channel_1 = require("../../../src/channel"); +var assemble_1 = require("../../../src/compile/layoutsize/assemble"); +var log = require("../../../src/log"); +describe('compile/layout', function () { + describe('sizeExpr', function () { + it('should return correct formula for ordinal-point scale', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'rect', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { padding: 0.3 } }, + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'rect', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { paddingInner: 0.3 } }, + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.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 = util_1.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 = assemble_1.sizeSignals(model.child, 'width'); + chai_1.assert.deepEqual(size, [{ + name: 'child_x_step', + value: 21 + }]); + }); + it('should return static view size for ordinal x-scale with null', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: null } } + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.assert.deepEqual(size, [{ name: 'width', value: 200 }]); + }); + it('should return static view size for ordinal y-scale with null', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + y: { field: 'a', type: 'ordinal', scale: { rangeStep: null } } + } + }); + var size = assemble_1.sizeSignals(model, 'height'); + chai_1.assert.deepEqual(size, [{ name: 'height', value: 200 }]); + }); + it('should return static view size for ordinal scale with top-level width', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + width: 205, + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize({ + width: 205, + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: 21 } } + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.assert.deepEqual(size, [{ name: 'width', value: 205 }]); + chai_1.assert.equal(localLogger.warns[0], log.message.rangeStepDropped(channel_1.X)); + })); + it('should return static view width for non-ordinal x-scale', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.assert.deepEqual(size, [{ name: 'width', value: 200 }]); + }); + it('should return static view size for non-ordinal y-scale', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + y: { field: 'a', type: 'quantitative' } + } + }); + var size = assemble_1.sizeSignals(model, 'height'); + chai_1.assert.deepEqual(size, [{ name: 'height', value: 200 }]); + }); + it('should return default rangeStep if axis is not mapped', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: {}, + config: { scale: { rangeStep: 17 } } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.assert.deepEqual(size, [{ name: 'width', value: 17 }]); + }); + it('should return textXRangeStep if axis is not mapped for X of text mark', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + var size = assemble_1.sizeSignals(model, 'width'); + chai_1.assert.deepEqual(size, [{ name: 'width', value: 91 }]); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sYXlvdXRzaXplL2Fzc2VtYmxlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLG1DQUFpRjtBQUVqRixnREFBdUM7QUFDdkMscUVBQXFFO0FBQ3JFLHNDQUF3QztBQUV4QyxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7SUFDekIsUUFBUSxDQUFDLFVBQVUsRUFBRTtRQUNuQixFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7aUJBQ2pDO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsSUFBTSxJQUFJLEdBQUcsc0JBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDekMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDdEIsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsS0FBSyxFQUFFLEVBQUU7aUJBQ1YsRUFBQztvQkFDQSxJQUFJLEVBQUUsT0FBTztvQkFDYixNQUFNLEVBQUUsa0RBQWtEO2lCQUMzRCxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBFQUEwRSxFQUFFO1lBQzdFLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxJQUFJLEVBQUUsTUFBTTtnQkFDWixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsRUFBQztpQkFD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TCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7cGFyc2VGYWNldE1vZGVsLCBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemV9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQge1h9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7c2l6ZVNpZ25hbHN9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2xheW91dHNpemUvYXNzZW1ibGUnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uLy4uL3NyYy9sb2cnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9sYXlvdXQnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdzaXplRXhwcicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IGZvcm11bGEgZm9yIG9yZGluYWwtcG9pbnQgc2NhbGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsIC8vIHBvaW50IG1hcmsgcHJvZHVjZSBvcmRpbmFsLXBvaW50IHNjYWxlIGJ5IGRlZmF1bHRcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2l6ZSA9IHNpemVTaWduYWxzKG1vZGVsLCAnd2lkdGgnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2l6ZSwgW3tcbiAgICAgICAgbmFtZTogJ3hfc3RlcCcsXG4gICAgICAgIHZhbHVlOiAyMVxuICAgICAgfSx7XG4gICAgICAgIG5hbWU6ICd3aWR0aCcsXG4gICAgICAgIHVwZGF0ZTogJ2JhbmRzcGFjZShkb21haW4oXFwneFxcJykubGVuZ3RoLCAxLCAwLjUpICogeF9zdGVwJ1xuICAgICAgfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBmb3JtdWxhIGZvciBvcmRpbmFsLWJhbmQgc2NhbGUgd2l0aCBjdXN0b20gcGFkZGluZycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgbWFyazogJ3JlY3QnLCAvLyByZWN0IHByb2R1Y2VzIG9yZGluYWwtYmFuZCBieSBkZWZhdWx0XG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJywgc2NhbGU6IHtwYWRkaW5nOiAwLjN9fSxcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNpemUgPSBzaXplU2lnbmFscyhtb2RlbCwgJ3dpZHRoJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNpemUsIFt7XG4gICAgICAgIG5hbWU6ICd4X3N0ZXAnLFxuICAgICAgICB2YWx1ZTogMjFcbiAgICAgIH0se1xuICAgICAgICBuYW1lOiAnd2lkdGgnLFxuICAgICAgICB1cGRhdGU6ICdiYW5kc3BhY2UoZG9tYWluKFxcJ3hcXCcpLmxlbmd0aCwgMC4zLCAwLjMpICogeF9zdGVwJ1xuICAgICAgfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBmb3JtdWxhIGZvciBvcmRpbmFsLWJhbmQgc2NhbGUgd2l0aCBjdXN0b20gcGFkZGluZ0lubmVyJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBtYXJrOiAncmVjdCcsIC8vIHJlY3QgcHJvZHVjZXMgb3JkaW5hbC1iYW5kIGJ5IGRlZmF1bHRcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnLCBzY2FsZToge3BhZGRpbmdJbm5lcjogMC4zfX0sXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzaXplID0gc2l6ZVNpZ25hbHMobW9kZWwsICd3aWR0aCcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaXplLCBbe1xuICAgICAgICBuYW1lOiAneF9zdGVwJyxcbiAgICAgICAgdmFsdWU6IDIxXG4gICAgICB9LHtcbiAgICAgICAgbmFtZTogJ3dpZHRoJyxcbiAgICAgICAgdXBkYXRlOiAnYmFuZHNwYWNlKGRvbWFpbihcXCd4XFwnKS5sZW5ndGgsIDAuMywgMC4xNSkgKiB4X3N0ZXAnXG4gICAgICB9XSk7XG4gICAgfSk7XG5cblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIG9ubHkgc3RlcCBpZiBwYXJlbnQgaXMgZmFjZXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbCh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgcm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdub21pbmFsJ31cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgICBzY2FsZToge3g6ICdpbmRlcGVuZGVudCd9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICAgICAgbW9kZWwucGFyc2VMYXlvdXRTaXplKCk7XG5cbiAgICAgIGNvbnN0IHNpemUgPSBzaXplU2lnbmFscyhtb2RlbC5jaGlsZCwgJ3dpZHRoJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNpemUsIFt7XG4gICAgICAgIG5hbWU6ICdjaGlsZF94X3N0ZXAnLFxuICAgICAgICB2YWx1ZTogMjFcbiAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHN0YXRpYyB2aWV3IHNpemUgZm9yIG9yZGluYWwgeC1zY2FsZSB3aXRoIG51bGwnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJywgc2NhbGU6IHtyYW5nZVN0ZXA6IG51bGx9fVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2l6ZSA9IHNpemVTaWduYWxzKG1vZGVsLCAnd2lkdGgnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2l6ZSwgW3tuYW1lOiAnd2lkdGgnLCB2YWx1ZTogMjAwfV0pO1xuICAgIH0pO1xuXG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdGF0aWMgdmlldyBzaXplIGZvciBvcmRpbmFsIHktc2NhbGUgd2l0aCBudWxsJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHk6IHtmaWVsZDogJ2EnLCB0eXBlOiAnb3JkaW5hbCcsIHNjYWxlOiB7cmFuZ2VTdGVwOiBudWxsfX1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNpemUgPSBzaXplU2lnbmFscyhtb2RlbCwgJ2hlaWdodCcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaXplLCBbe25hbWU6ICdoZWlnaHQnLCB2YWx1ZTogMjAwfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc3RhdGljIHZpZXcgc2l6ZSBmb3Igb3JkaW5hbCBzY2FsZSB3aXRoIHRvcC1sZXZlbCB3aWR0aCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgd2lkdGg6IDIwNSxcbiAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2l6ZSA9IHNpemVTaWduYWxzKG1vZGVsLCAnd2lkdGgnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2l6ZSwgW3tuYW1lOiAnd2lkdGgnLCB2YWx1ZTogMjA1fV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc3RhdGljIHZpZXcgc2l6ZSBmb3Igb3JkaW5hbCBzY2FsZSB3aXRoIHRvcC1sZXZlbCB3aWR0aCBldmVuIGlmIHRoZXJlIGlzIG51bWVyaWMgcmFuZ2VTdGVwJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIHdpZHRoOiAyMDUsXG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJywgc2NhbGU6IHtyYW5nZVN0ZXA6IDIxfX1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNpemUgPSBzaXplU2lnbmFscyhtb2RlbCwgJ3dpZHRoJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNpemUsIFt7bmFtZTogJ3dpZHRoJywgdmFsdWU6IDIwNX1dKTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UucmFuZ2VTdGVwRHJvcHBlZChYKSk7XG4gICAgfSkpO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc3RhdGljIHZpZXcgd2lkdGggZm9yIG5vbi1vcmRpbmFsIHgtc2NhbGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2l6ZSA9IHNpemVTaWduYWxzKG1vZGVsLCAnd2lkdGgnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2l6ZSwgW3tuYW1lOiAnd2lkdGgnLCB2YWx1ZTogMjAwfV0pO1xuICAgIH0pO1xuXG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdGF0aWMgdmlldyBzaXplIGZvciBub24tb3JkaW5hbCB5LXNjYWxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHk6IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNpemUgPSBzaXplU2lnbmFscyhtb2RlbCwgJ2hlaWdodCcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaXplLCBbe25hbWU6ICdoZWlnaHQnLCB2YWx1ZTogMjAwfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZGVmYXVsdCByYW5nZVN0ZXAgaWYgYXhpcyBpcyBub3QgbWFwcGVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge30sXG4gICAgICAgIGNvbmZpZzoge3NjYWxlOiB7cmFuZ2VTdGVwOiAxN319XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNpemUgPSBzaXplU2lnbmFscyhtb2RlbCwgJ3dpZHRoJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNpemUsIFt7bmFtZTogJ3dpZHRoJywgdmFsdWU6IDE3fV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGV4dFhSYW5nZVN0ZXAgaWYgYXhpcyBpcyBub3QgbWFwcGVkIGZvciBYIG9mIHRleHQgbWFyaycsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgbWFyazogJ3RleHQnLFxuICAgICAgICBlbmNvZGluZzoge30sXG4gICAgICAgIGNvbmZpZzoge3NjYWxlOiB7dGV4dFhSYW5nZVN0ZXA6IDkxfX1cbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2l6ZSA9IHNpemVTaWduYWxzKG1vZGVsLCAnd2lkdGgnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2l6ZSwgW3tuYW1lOiAnd2lkdGgnLCB2YWx1ZTogOTF9XSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/layoutsize/parse.test.js b/build/test/compile/layoutsize/parse.test.js new file mode 100644 index 0000000000..e663fdbaad --- /dev/null +++ b/build/test/compile/layoutsize/parse.test.js @@ -0,0 +1,73 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +describe('compile/layout', function () { + describe('parseUnitLayoutSize', function () { + it('should have width, height = provided top-level width, height', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + width: 123, + height: 456, + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + chai_1.assert.deepEqual(model.component.layoutSize.explicit.width, 123); + chai_1.assert.deepEqual(model.component.layoutSize.explicit.height, 456); + }); + it('should have width = default textXRangeStep for text mark without x', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: {}, + config: { scale: { rangeStep: 23 } } + }); + chai_1.assert.deepEqual(model.component.layoutSize.implicit.width, 23); + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + y: { field: 'b', type: 'quantitative' } + }, + config: { view: { width: 123, height: 456 } } + }); + chai_1.assert.deepEqual(model.component.layoutSize.implicit.width, 123); + chai_1.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 = util_1.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 } } + }); + chai_1.assert.deepEqual(model.component.layoutSize.implicit.width, 123); + chai_1.assert.deepEqual(model.component.layoutSize.implicit.height, 456); + }); + it('should have width/height = undefined for non-ordinal x,y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { view: { width: 123, height: 456 } } + }); + chai_1.assert.deepEqual(model.component.layoutSize.get('width'), 'range-step'); + chai_1.assert.deepEqual(model.component.layoutSize.get('height'), 'range-step'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sYXlvdXRzaXplL3BhcnNlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsbUNBQWdFO0FBRWhFLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUN4QixRQUFRLENBQUMscUJBQXFCLEVBQUU7UUFDL0IsRUFBRSxDQUFDLDhEQUE4RCxFQUFFO1lBQ2pFLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxLQUFLLEVBQUUsR0FBRztnQkFDVixNQUFNLEVBQUUsR0FBRztnQkFDWCxJQUFJLEVBQUUsTUFBTTtnQkFDWixRQUFRLEVBQUUsRUFBRTtnQkFDWixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsRUFBQyxjQUFjLEVBQUUsRUFBRSxFQUFDLEVBQUM7YUFDdEMsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2pFLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNwRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvRUFBb0UsRUFBRTtZQUN2RSxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsSUFBSSxFQUFFLE1BQU07Z0JBQ1osUUFBUSxFQUFFLEVBQUU7Z0JBQ1osTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsY0FBYyxFQUFFLEVBQUUsRUFBQyxFQUFDO2FBQ3RDLENBQUMsQ0FBQztZQUVILGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEtBQUssRUFB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QUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDLEVBQUM7YUFDMUMsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDeEUsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemV9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9sYXlvdXQnLCAoKSA9PiB7XG4gICBkZXNjcmliZSgncGFyc2VVbml0TGF5b3V0U2l6ZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGhhdmUgd2lkdGgsIGhlaWdodCA9IHByb3ZpZGVkIHRvcC1sZXZlbCB3aWR0aCwgaGVpZ2h0JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICB3aWR0aDogMTIzLFxuICAgICAgICBoZWlnaHQ6IDQ1NixcbiAgICAgICAgbWFyazogJ3RleHQnLFxuICAgICAgICBlbmNvZGluZzoge30sXG4gICAgICAgIGNvbmZpZzoge3NjYWxlOiB7dGV4dFhSYW5nZVN0ZXA6IDkxfX1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKG1vZGVsLmNvbXBvbmVudC5sYXlvdXRTaXplLmV4cGxpY2l0LndpZHRoLCAxMjMpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtb2RlbC5jb21wb25lbnQubGF5b3V0U2l6ZS5leHBsaWNpdC5oZWlnaHQsIDQ1Nik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgd2lkdGggPSBkZWZhdWx0IHRleHRYUmFuZ2VTdGVwIGZvciB0ZXh0IG1hcmsgd2l0aG91dCB4JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBtYXJrOiAndGV4dCcsXG4gICAgICAgIGVuY29kaW5nOiB7fSxcbiAgICAgICAgY29uZmlnOiB7c2NhbGU6IHt0ZXh0WFJhbmdlU3RlcDogOTF9fVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY29tcG9uZW50LmxheW91dFNpemUuaW1wbGljaXQud2lkdGgsIDkxKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSB3aWR0aC9oZWlnaHQgPSBjb25maWcuc2NhbGUucmFuZ2VTdGVwICBmb3Igbm9uLXRleHQgbWFyayB3aXRob3V0IHgseScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgZW5jb2Rpbmc6IHt9LFxuICAgICAgICBjb25maWc6IHtzY2FsZToge3JhbmdlU3RlcDogMjN9fVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY29tcG9uZW50LmxheW91dFNpemUuaW1wbGljaXQud2lkdGgsIDIzKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY29tcG9uZW50LmxheW91dFNpemUuaW1wbGljaXQuaGVpZ2h0LCAyMyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgd2lkdGgvaGVpZ2h0ID0gY29uZmlnLnZpZXcud2lkdGgvaGVpZ2h0IGZvciBub24tb3JkaW5hbCB4LHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICB5OiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZzoge3ZpZXc6IHt3aWR0aDogMTIzLCBoZWlnaHQ6IDQ1Nn19XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtb2RlbC5jb21wb25lbnQubGF5b3V0U2l6ZS5pbXBsaWNpdC53aWR0aCwgMTIzKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY29tcG9uZW50LmxheW91dFNpemUuaW1wbGljaXQuaGVpZ2h0LCA0NTYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHdpZHRoL2hlaWdodCA9IGNvbmZpZy52aWV3LndpZHRoL2hlaWdodCBmb3Igbm9uLW9yZGluYWwgeCx5JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAnb3JkaW5hbCcsIHNjYWxlOiB7cmFuZ2VTdGVwOiBudWxsfX0sXG4gICAgICAgICAgeToge2ZpZWxkOiAnYicsIHR5cGU6ICdvcmRpbmFsJywgc2NhbGU6IHtyYW5nZVN0ZXA6IG51bGx9fVxuICAgICAgICB9LFxuICAgICAgICBjb25maWc6IHt2aWV3OiB7d2lkdGg6IDEyMywgaGVpZ2h0OiA0NTZ9fVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY29tcG9uZW50LmxheW91dFNpemUuaW1wbGljaXQud2lkdGgsIDEyMyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKG1vZGVsLmNvbXBvbmVudC5sYXlvdXRTaXplLmltcGxpY2l0LmhlaWdodCwgNDU2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSB3aWR0aC9oZWlnaHQgPSB1bmRlZmluZWQgZm9yIG5vbi1vcmRpbmFsIHgseScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfSxcbiAgICAgICAgICB5OiB7ZmllbGQ6ICdiJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICB9LFxuICAgICAgICBjb25maWc6IHt2aWV3OiB7d2lkdGg6IDEyMywgaGVpZ2h0OiA0NTZ9fVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY29tcG9uZW50LmxheW91dFNpemUuZ2V0KCd3aWR0aCcpLCAncmFuZ2Utc3RlcCcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChtb2RlbC5jb21wb25lbnQubGF5b3V0U2l6ZS5nZXQoJ2hlaWdodCcpLCAncmFuZ2Utc3RlcCcpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/legend/assemble.test.js b/build/test/compile/legend/assemble.test.js new file mode 100644 index 0000000000..edc1601505 --- /dev/null +++ b/build/test/compile/legend/assemble.test.js @@ -0,0 +1,47 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +describe('legend/assemble', function () { + it('merges legend of the same field with the default type.', function () { + var model = util_1.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(); + chai_1.assert.equal(legends.length, 1); + chai_1.assert.equal(legends[0].title, 'Origin'); + chai_1.assert.equal(legends[0].stroke, 'color'); + chai_1.assert.equal(legends[0].shape, 'shape'); + }); + it('merges legend of the same field and favor symbol legend over gradient', function () { + var model = util_1.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(); + chai_1.assert.equal(legends.length, 1); + chai_1.assert.equal(legends[0].title, 'b'); + chai_1.assert.equal(legends[0].type, 'symbol'); + chai_1.assert.equal(legends[0].fill, 'color'); + chai_1.assert.equal(legends[0].size, 'size'); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sZWdlbmQvYXNzZW1ibGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQW1EO0FBR25ELFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtJQUMxQixFQUFFLENBQUMsd0RBQXdELEVBQUU7UUFDM0QsSUFBTSxLQUFLLEdBQUcsOEJBQXVCLENBQUM7WUFDcEMsU0FBUyxFQUFFLGlEQUFpRDtZQUM1RCxhQUFhLEVBQUUseURBQXlEO1lBQ3hFLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBQztZQUNqQyxNQUFNLEVBQUUsT0FBTztZQUNmLFVBQVUsRUFBRTtnQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7Z0JBQ3BELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMxRCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7Z0JBQy9DLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzthQUNoRDtTQUNGLENBQUMsQ0FBQztRQUNILEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVwQixJQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRWhDLGFBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN6QyxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDekMsYUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLENBQUMsQ0FBQyxDQUFDO0lBQ0gsRUFBRSxDQUFDLHVFQUF1RSxFQUFFO1FBQzFFLElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO1lBQ3BDLE1BQU0sRUFBRSxFQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUMsR0FBRyxFQUFFLEdBQUcsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFDLEVBQUMsRUFBQyxHQUFHLEVBQUUsR0FBRyxFQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUMsQ0FBQyxFQUFDO1lBQzNELE1BQU0sRUFBRSxLQUFLO1lBQ2IsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDckMsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMxQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7Z0JBQzlDLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQzthQUM5QztTQUNGLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVwQixJQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGFBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNwQyxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDeEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLGFBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN4QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWxXaXRoU2NhbGV9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5cbmRlc2NyaWJlKCdsZWdlbmQvYXNzZW1ibGUnLCAoKSA9PiB7XG4gIGl0KCdtZXJnZXMgbGVnZW5kIG9mIHRoZSBzYW1lIGZpZWxkIHdpdGggdGhlIGRlZmF1bHQgdHlwZS4nLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICBcIiRzY2hlbWFcIjogXCJodHRwczovL3ZlZ2EuZ2l0aHViLmlvL3NjaGVtYS92ZWdhLWxpdGUvdjIuanNvblwiLFxuICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgc2NhdHRlcnBsb3Qgc2hvd2luZyBob3JzZXBvd2VyIGFuZCBtaWxlcyBwZXIgZ2FsbG9ucy5cIixcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2NhcnMuanNvblwifSxcbiAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIk1pbGVzX3Blcl9HYWxsb25cIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgIFwic2hhcGVcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgfVxuICAgIH0pO1xuICAgIG1vZGVsLnBhcnNlTGVnZW5kKCk7XG5cbiAgICBjb25zdCBsZWdlbmRzID0gbW9kZWwuYXNzZW1ibGVMZWdlbmRzKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGxlZ2VuZHMubGVuZ3RoLCAxKTtcblxuICAgIGFzc2VydC5lcXVhbChsZWdlbmRzWzBdLnRpdGxlLCAnT3JpZ2luJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGxlZ2VuZHNbMF0uc3Ryb2tlLCAnY29sb3InKTtcbiAgICBhc3NlcnQuZXF1YWwobGVnZW5kc1swXS5zaGFwZSwgJ3NoYXBlJyk7XG4gIH0pO1xuICBpdCgnbWVyZ2VzIGxlZ2VuZCBvZiB0aGUgc2FtZSBmaWVsZCBhbmQgZmF2b3Igc3ltYm9sIGxlZ2VuZCBvdmVyIGdyYWRpZW50JywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgXCJkYXRhXCI6IHtcInZhbHVlc1wiOiBbe1wiYVwiOiBcIkFcIixcImJcIjogMjh9LHtcImFcIjogXCJCXCIsXCJiXCI6IDU1fV19LFxuICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJiXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInNpemVcIjoge1wiZmllbGRcIjogXCJiXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBtb2RlbC5wYXJzZUxlZ2VuZCgpO1xuXG4gICAgY29uc3QgbGVnZW5kcyA9IG1vZGVsLmFzc2VtYmxlTGVnZW5kcygpO1xuICAgIGFzc2VydC5lcXVhbChsZWdlbmRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKGxlZ2VuZHNbMF0udGl0bGUsICdiJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGxlZ2VuZHNbMF0udHlwZSwgJ3N5bWJvbCcpO1xuICAgIGFzc2VydC5lcXVhbChsZWdlbmRzWzBdLmZpbGwsICdjb2xvcicpO1xuICAgIGFzc2VydC5lcXVhbChsZWdlbmRzWzBdLnNpemUsICdzaXplJyk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/legend/encode.test.js b/build/test/compile/legend/encode.test.js new file mode 100644 index 0000000000..5a9a9d8b56 --- /dev/null +++ b/build/test/compile/legend/encode.test.js @@ -0,0 +1,97 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var encode = require("../../../src/compile/legend/encode"); +var timeunit_1 = require("../../../src/timeunit"); +var type_1 = require("../../../src/type"); +var util_1 = require("../../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' }, {}, util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { field: "a", type: "nominal" } + } + }), channel_1.COLOR, 'symbol'); + chai_1.assert.isUndefined((symbol || {}).fill); + chai_1.assert.isUndefined((symbol || {}).strokeDash); + chai_1.assert.isUndefined((symbol || {}).strokeDashOffset); + }); + it('should return specific symbols.shape.value if user has specified', function () { + var symbol = encode.symbols({ field: 'a', type: 'nominal' }, {}, util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + shape: { value: "square" } + } + }), channel_1.COLOR, 'symbol'); + chai_1.assert.deepEqual(symbol.shape.value, 'square'); + }); + it('should have default opacity', function () { + var symbol = encode.symbols({ field: 'a', type: 'nominal' }, {}, util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" } + } + }), channel_1.COLOR, 'symbol'); + chai_1.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' }, {}, util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + opacity: { + condition: { selection: "brush", value: 1 }, + value: 0 + } + } + }), channel_1.COLOR, 'symbol'); + chai_1.assert.deepEqual(symbol.opacity.value, 1); + }); + }); + describe('encode.gradient', function () { + it('should have default opacity', function () { + var gradient = encode.gradient({ field: 'a', type: 'quantitative' }, {}, util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "quantitative" } + } + }), channel_1.COLOR, 'gradient'); + chai_1.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 = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal" }, + color: { field: "a", type: "temporal", timeUnit: "month" } + } + }); + var fieldDef = { field: 'a', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.MONTH }; + var label = encode.labels(fieldDef, {}, model, channel_1.COLOR, 'gradient'); + var expected = "timeFormat(datum.value, '%b')"; + chai_1.assert.deepEqual(label.text.signal, expected); + }); + it('should return correct expression for the timeUnit: TimeUnit.QUARTER', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal" }, + color: { field: "a", type: "temporal", timeUnit: "quarter" } + } + }); + var fieldDef = { field: 'a', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.QUARTER }; + var label = encode.labels(fieldDef, {}, model, channel_1.COLOR, 'gradient'); + var expected = "'Q' + quarter(datum.value)"; + chai_1.assert.deepEqual(label.text.signal, expected); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbGVnZW5kL2VuY29kZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixnREFBMkM7QUFDM0MsMkRBQTZEO0FBQzdELGtEQUErQztBQUMvQywwQ0FBMkM7QUFDM0MsbUNBQW1EO0FBRW5ELFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUN6QixRQUFRLENBQUMsZ0JBQWdCLEVBQUU7UUFDekIsRUFBRSxDQUFDLHVEQUF1RCxFQUFFO1lBRTFELElBQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUMsRUFBRSxFQUFFLEVBQUUsOEJBQXVCLENBQUM7Z0JBQ3JGLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7b0JBQ2hDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQztpQkFDckM7YUFDRixDQUFDLEVBQUUsZUFBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3JCLGFBQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLElBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEMsYUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sSUFBRSxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM1QyxhQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxJQUFFLEVBQUUsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQUU7WUFF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RSxJQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLGVBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNwRSxJQUFNLFFBQVEsR0FBRyw0QkFBNEIsQ0FBQztZQUM5QyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge0NPTE9SfSBmcm9tICcuLi8uLi8uLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQgKiBhcyBlbmNvZGUgZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGVnZW5kL2VuY29kZSc7XG5pbXBvcnQge1RpbWVVbml0fSBmcm9tICcuLi8uLi8uLi9zcmMvdGltZXVuaXQnO1xuaW1wb3J0IHtURU1QT1JBTH0gZnJvbSAnLi4vLi4vLi4vc3JjL3R5cGUnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdjb21waWxlL2xlZ2VuZCcsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnZW5jb2RlLnN5bWJvbHMnLCBmdW5jdGlvbigpIHtcbiAgICBpdCgnc2hvdWxkIG5vdCBoYXZlIGZpbGwsIHN0cm9rZURhc2gsIG9yIHN0cm9rZURhc2hPZmZzZXQnLCBmdW5jdGlvbigpIHtcblxuICAgICAgY29uc3Qgc3ltYm9sID0gZW5jb2RlLnN5bWJvbHMoe2ZpZWxkOiAnYScsIHR5cGU6ICdub21pbmFsJ30sIHt9LCBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6IFwiYVwiLCB0eXBlOiBcIm5vbWluYWxcIn0sXG4gICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJub21pbmFsXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9KSwgQ09MT1IsICdzeW1ib2wnKTtcbiAgICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKChzeW1ib2x8fHt9KS5maWxsKTtcbiAgICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKChzeW1ib2x8fHt9KS5zdHJva2VEYXNoKTtcbiAgICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKChzeW1ib2x8fHt9KS5zdHJva2VEYXNoT2Zmc2V0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHNwZWNpZmljIHN5bWJvbHMuc2hhcGUudmFsdWUgaWYgdXNlciBoYXMgc3BlY2lmaWVkJywgZnVuY3Rpb24oKSB7XG5cbiAgICAgIGNvbnN0IHN5bWJvbCA9IGVuY29kZS5zeW1ib2xzKHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9LCB7fSwgcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgc2hhcGU6IHt2YWx1ZTogXCJzcXVhcmVcIn19XG4gICAgICAgIH0pLCBDT0xPUiwgJ3N5bWJvbCcpO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHN5bWJvbC5zaGFwZS52YWx1ZSwgJ3NxdWFyZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGRlZmF1bHQgb3BhY2l0eScsIGZ1bmN0aW9uKCkge1xuXG4gICAgICBjb25zdCBzeW1ib2wgPSBlbmNvZGUuc3ltYm9scyh7ZmllbGQ6ICdhJywgdHlwZTogJ25vbWluYWwnfSwge30sIHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogXCJhXCIsIHR5cGU6IFwibm9taW5hbFwifX1cbiAgICAgICAgfSksIENPTE9SLCAnc3ltYm9sJyk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc3ltYm9sLm9wYWNpdHkudmFsdWUsIDAuNyk7IC8vIGRlZmF1bHQgb3BhY2l0eSBpcyAwLjcuXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgbWF4aW11bSB2YWx1ZSB3aGVuIHRoZXJlIGlzIGEgY29uZGl0aW9uJywgZnVuY3Rpb24oKSB7XG5cbiAgICAgIGNvbnN0IHN5bWJvbCA9IGVuY29kZS5zeW1ib2xzKHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9LCB7fSwgcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgb3BhY2l0eToge1xuICAgICAgICAgICAgICBjb25kaXRpb246IHtzZWxlY3Rpb246IFwiYnJ1c2hcIiwgdmFsdWU6IDF9LFxuICAgICAgICAgICAgICB2YWx1ZTogMFxuICAgICAgICAgICAgfX1cbiAgICAgICAgfSksIENPTE9SLCAnc3ltYm9sJyk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc3ltYm9sLm9wYWNpdHkudmFsdWUsIDEpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZW5jb2RlLmdyYWRpZW50JywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCBoYXZlIGRlZmF1bHQgb3BhY2l0eScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgZ3JhZGllbnQgPSBlbmNvZGUuZ3JhZGllbnQoe2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwge30sIHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogXCJhXCIsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9fVxuICAgICAgICB9KSwgQ09MT1IsICdncmFkaWVudCcpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGdyYWRpZW50Lm9wYWNpdHkudmFsdWUsIDAuNyk7IC8vIGRlZmF1bHQgb3BhY2l0eSBpcyAwLjcuXG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdlbmNvZGUubGFiZWxzJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBleHByZXNzaW9uIGZvciB0aGUgdGltZVVuaXQ6IFRpbWVVbml0Lk1PTlRIJywgZnVuY3Rpb24oKSB7XG5cbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBjb2xvcjoge2ZpZWxkOiBcImFcIiwgdHlwZTogXCJ0ZW1wb3JhbFwiLCB0aW1lVW5pdDogXCJtb250aFwifVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZmllbGREZWYgPSB7ZmllbGQ6ICdhJywgdHlwZTogVEVNUE9SQUwsIHRpbWVVbml0OiBUaW1lVW5pdC5NT05USH07XG4gICAgICBjb25zdCBsYWJlbCA9IGVuY29kZS5sYWJlbHMoZmllbGREZWYsIHt9LCBtb2RlbCwgQ09MT1IsICdncmFkaWVudCcpO1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBgdGltZUZvcm1hdChkYXR1bS52YWx1ZSwgJyViJylgO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChsYWJlbC50ZXh0LnNpZ25hbCwgZXhwZWN0ZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBleHByZXNzaW9uIGZvciB0aGUgdGltZVVuaXQ6IFRpbWVVbml0LlFVQVJURVInLCBmdW5jdGlvbigpIHtcblxuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6IFwiYVwiLCB0eXBlOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6IFwiYVwiLCB0eXBlOiBcInRlbXBvcmFsXCIsIHRpbWVVbml0OiBcInF1YXJ0ZXJcIn19XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZmllbGREZWYgPSB7ZmllbGQ6ICdhJywgdHlwZTogVEVNUE9SQUwsIHRpbWVVbml0OiBUaW1lVW5pdC5RVUFSVEVSfTtcbiAgICAgIGNvbnN0IGxhYmVsID0gZW5jb2RlLmxhYmVscyhmaWVsZERlZiwge30sIG1vZGVsLCBDT0xPUiwgJ2dyYWRpZW50Jyk7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGAnUScgKyBxdWFydGVyKGRhdHVtLnZhbHVlKWA7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGxhYmVsLnRleHQuc2lnbmFsLCBleHBlY3RlZCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/legend/parse.test.js b/build/test/compile/legend/parse.test.js new file mode 100644 index 0000000000..3baf0f0894 --- /dev/null +++ b/build/test/compile/legend/parse.test.js @@ -0,0 +1,104 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var legendParse = require("../../../src/compile/legend/parse"); +var util_1 = require("../../util"); +describe('compile/legend', function () { + describe('parseLegendForChannel()', function () { + it('should produce a Vega legend object with correct type and scale for color', function () { + var model = util_1.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { field: "a", type: "quantitative" } + } + }); + var def = legendParse.parseLegendForChannel(model, channel_1.COLOR).combine(); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.title, 'a'); + chai_1.assert.equal(def.stroke, 'color'); + chai_1.assert.equal(def.type, 'gradient'); + }); + [channel_1.SIZE, channel_1.SHAPE, channel_1.OPACITY].forEach(function (channel) { + it("should produce a Vega legend object with correct type and scale for " + channel, function () { + var s = { + mark: "point", + encoding: { + x: { field: "a", type: "nominal" } + } + }; + s.encoding[channel] = { field: "a", type: "nominal" }; + var model = util_1.parseUnitModelWithScale(s); + var def = legendParse.parseLegendForChannel(model, channel).combine(); + if (channel !== channel_1.OPACITY) { + chai_1.assert.equal(def.encode.symbols.update.opacity.value, 0.7); + } + else { + chai_1.assert.isUndefined(def.encode.symbols.update.opacity); + } + chai_1.assert.isObject(def); + chai_1.assert.equal(def.title, "a"); + }); + }); + }); + describe('parseNonUnitLegend()', function () { + it('should correctly merge orient by favoring explicit orient', function () { + var model = util_1.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(); + chai_1.assert.equal(model.component.legends.color.explicit.orient, 'left'); + }); + it('should correctly merge legend that exists only on one plot', function () { + var model = util_1.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(); + chai_1.assert.isOk(model.component.legends.color); + chai_1.assert.isUndefined(model.children[0].component.legends.color); + chai_1.assert.isUndefined(model.children[1].component.legends.color); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sZWdlbmQvcGFyc2UudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsZ0RBQWlFO0FBQ2pFLCtEQUFpRTtBQUVqRSxtQ0FBb0U7QUFFcEUsUUFBUSxDQUFDLGdCQUFnQixFQUFFO0lBQ3pCLFFBQVEsQ0FBQyx5QkFBeUIsRUFBRTtRQUNsQyxFQUFFLENBQUMsMkVBQTJFLEVBQUU7WUFDOUUsSUFBTSxLQUFLLEdBQUcsOEJBQXVCLENBQUM7Z0JBQ3BDLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7b0JBQ2hDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztpQkFDMUM7YUFDRixDQUFDLENBQUM7WUFFSCxJQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMscUJBQXFCLENBQUMsS0FBSyxFQUFFLGVBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RFLGFBQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzdCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsQyxhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFFSCxDQUFDLGNBQUksRUFBRSxlQUFLLEVBQUUsaUJBQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFBLE9BQU87WUFDcEMs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S0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge0NPTE9SLCBPUEFDSVRZLCBTSEFQRSwgU0laRX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NoYW5uZWwnO1xuaW1wb3J0ICogYXMgbGVnZW5kUGFyc2UgZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGVnZW5kL3BhcnNlJztcbmltcG9ydCB7VW5pdFNwZWN9IGZyb20gJy4uLy4uLy4uL3NyYy9zcGVjJztcbmltcG9ydCB7cGFyc2VMYXllck1vZGVsLCBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdjb21waWxlL2xlZ2VuZCcsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgncGFyc2VMZWdlbmRGb3JDaGFubmVsKCknLCBmdW5jdGlvbigpIHtcbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSBWZWdhIGxlZ2VuZCBvYmplY3Qgd2l0aCBjb3JyZWN0IHR5cGUgYW5kIHNjYWxlIGZvciBjb2xvcicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6IFwiYVwiLCB0eXBlOiBcIm5vbWluYWxcIn0sXG4gICAgICAgICAgY29sb3I6IHtmaWVsZDogXCJhXCIsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBkZWYgPSBsZWdlbmRQYXJzZS5wYXJzZUxlZ2VuZEZvckNoYW5uZWwobW9kZWwsIENPTE9SKS5jb21iaW5lKCk7XG4gICAgICBhc3NlcnQuaXNPYmplY3QoZGVmKTtcbiAgICAgIGFzc2VydC5lcXVhbChkZWYudGl0bGUsICdhJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmLnN0cm9rZSwgJ2NvbG9yJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmLnR5cGUsICdncmFkaWVudCcpO1xuICAgIH0pO1xuXG4gICAgW1NJWkUsIFNIQVBFLCBPUEFDSVRZXS5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgaXQoYHNob3VsZCBwcm9kdWNlIGEgVmVnYSBsZWdlbmQgb2JqZWN0IHdpdGggY29ycmVjdCB0eXBlIGFuZCBzY2FsZSBmb3IgJHtjaGFubmVsfWAsIGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCBzOiBVbml0U3BlYyA9IHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogXCJhXCIsIHR5cGU6IFwibm9taW5hbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcy5lbmNvZGluZ1tjaGFubmVsXSA9IHtmaWVsZDogXCJhXCIsIHR5cGU6IFwibm9taW5hbFwifTtcblxuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHMpO1xuXG4gICAgICAgIGNvbnN0IGRlZiA9IGxlZ2VuZFBhcnNlLnBhcnNlTGVnZW5kRm9yQ2hhbm5lbChtb2RlbCwgY2hhbm5lbCkuY29tYmluZSgpO1xuXG4gICAgICAgIGlmIChjaGFubmVsICE9PSBPUEFDSVRZKSB7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKGRlZi5lbmNvZGUuc3ltYm9scy51cGRhdGUub3BhY2l0eS52YWx1ZSwgMC43KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhc3NlcnQuaXNVbmRlZmluZWQoZGVmLmVuY29kZS5zeW1ib2xzLnVwZGF0ZS5vcGFjaXR5KTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnQuaXNPYmplY3QoZGVmKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGRlZi50aXRsZSwgXCJhXCIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXJzZU5vblVuaXRMZWdlbmQoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBtZXJnZSBvcmllbnQgYnkgZmF2b3JpbmcgZXhwbGljaXQgb3JpZW50JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUxheWVyTW9kZWwoe1xuICAgICAgICBcIiRzY2hlbWFcIjogXCJodHRwczovL3ZlZ2EuZ2l0aHViLmlvL3NjaGVtYS92ZWdhLWxpdGUvdjIuanNvblwiLFxuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiR29vZ2xlJ3Mgc3RvY2sgcHJpY2Ugb3ZlciB0aW1lLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9zdG9ja3MuY3N2XCJ9LFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic3ltYm9sXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LHtcbiAgICAgICAgICAgIFwibWFya1wiOiB7XCJ0eXBlXCI6XCJwb2ludFwiLCBcImZpbGxlZFwiOiB0cnVlfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzeW1ib2xcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwiLCBcImxlZ2VuZFwiOiB7XCJvcmllbnRcIjogXCJsZWZ0XCJ9fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgICBtb2RlbC5wYXJzZVNjYWxlKCk7XG4gICAgICBtb2RlbC5wYXJzZUxlZ2VuZCgpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLmNvbXBvbmVudC5sZWdlbmRzLmNvbG9yLmV4cGxpY2l0Lm9yaWVudCwgJ2xlZnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IG1lcmdlIGxlZ2VuZCB0aGF0IGV4aXN0cyBvbmx5IG9uIG9uZSBwbG90JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUxheWVyTW9kZWwoe1xuICAgICAgICBcIiRzY2hlbWFcIjogXCJodHRwczovL3ZlZ2EuZ2l0aHViLmlvL3NjaGVtYS92ZWdhLWxpdGUvdjIuanNvblwiLFxuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiR29vZ2xlJ3Mgc3RvY2sgcHJpY2Ugb3ZlciB0aW1lLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9zdG9ja3MuY3N2XCJ9LFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSx7XG4gICAgICAgICAgICBcIm1hcmtcIjoge1widHlwZVwiOlwicG9pbnRcIiwgXCJmaWxsZWRcIjogdHJ1ZX0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic3ltYm9sXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICAgICAgbW9kZWwucGFyc2VMZWdlbmQoKTtcbiAgICAgIGFzc2VydC5pc09rKG1vZGVsLmNvbXBvbmVudC5sZWdlbmRzLmNvbG9yKTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChtb2RlbC5jaGlsZHJlblswXS5jb21wb25lbnQubGVnZW5kcy5jb2xvcik7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQobW9kZWwuY2hpbGRyZW5bMV0uY29tcG9uZW50LmxlZ2VuZHMuY29sb3IpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/legend/properties.test.js b/build/test/compile/legend/properties.test.js new file mode 100644 index 0000000000..5c21f0e6a1 --- /dev/null +++ b/build/test/compile/legend/properties.test.js @@ -0,0 +1,48 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var properties = require("../../../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 }] }); + chai_1.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] }); + chai_1.assert.deepEqual(values, [1, 2, 3, 4]); + }); + }); + describe('type()', function () { + it('should return gradient type for color scale', function () { + var t = properties.type('quantitative', channel_1.COLOR, 'sequential'); + chai_1.assert.equal(t, 'gradient'); + }); + it('should not return gradient type for size scale', function () { + var t = properties.type('quantitative', channel_1.SIZE, 'linear'); + chai_1.assert.equal(t, undefined); + }); + it('should return no type for color scale with bin', function () { + var t = properties.type('quantitative', channel_1.COLOR, 'bin-ordinal'); + chai_1.assert.equal(t, undefined); + }); + it('should return gradient type for color scale with time scale', function () { + var t = properties.type('temporal', channel_1.COLOR, 'time'); + chai_1.assert.equal(t, 'gradient'); + }); + it('should return no type for color scale with ordinal scale and temporal type', function () { + var t = properties.type('temporal', channel_1.COLOR, 'ordinal'); + chai_1.assert.equal(t, undefined); + }); + it('should return no type for color scale with ordinal scale and ordinal type', function () { + var t = properties.type('ordinal', channel_1.COLOR, 'ordinal'); + chai_1.assert.equal(t, undefined); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2xlZ2VuZC9wcm9wZXJ0aWVzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLGdEQUFpRDtBQUNqRCxtRUFBcUU7QUFFckUsUUFBUSxDQUFDLGdCQUFnQixFQUFFO0lBQ3pCLFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsRUFBRSxDQUFDLHNEQUFzRCxFQUFFO1lBQ3pELElBQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUV6RSxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtnQkFDdkIsRUFBQyxRQUFRLEVBQUUsa0NBQWtDLEVBQUM7Z0JBQzlDLEVBQUMsUUFBUSxFQUFFLGtDQUFrQyxFQUFDO2FBQy9DLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELElBQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7WUFFdEQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBRUwsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsUUFBUSxFQUFFO1FBQ2pCLEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxJQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxlQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDL0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsSUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsY0FBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzFELGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFO1lBQ25ELElBQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLGVBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztZQUNoRSxhQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRTtZQUNoRSxJQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxlQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDckQsYUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNEVBQTRFLEVBQUU7WUFDL0UsSUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsZUFBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3hELGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJFQUEyRSxFQUFFO1lBQzlFLElBQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGVBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztZQUN2RCxhQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtDT0xPUiwgU0laRX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NoYW5uZWwnO1xuaW1wb3J0ICogYXMgcHJvcGVydGllcyBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9sZWdlbmQvcHJvcGVydGllcyc7XG5cbmRlc2NyaWJlKCdjb21waWxlL2xlZ2VuZCcsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgndmFsdWVzKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCB0aW1lc3RhbXAgdmFsdWVzIGZvciBEYXRlVGltZXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBwcm9wZXJ0aWVzLnZhbHVlcyh7dmFsdWVzOiBbe3llYXI6IDE5NzB9LCB7eWVhcjogMTk4MH1dfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsdWVzLCBbXG4gICAgICAgIHtcInNpZ25hbFwiOiBcImRhdGV0aW1lKDE5NzAsIDAsIDEsIDAsIDAsIDAsIDApXCJ9LFxuICAgICAgICB7XCJzaWduYWxcIjogXCJkYXRldGltZSgxOTgwLCAwLCAxLCAwLCAwLCAwLCAwKVwifSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaW1wbHkgcmV0dXJuIHZhbHVlcyBmb3Igbm9uLURhdGVUaW1lJywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gcHJvcGVydGllcy52YWx1ZXMoe3ZhbHVlczogWzEsMiwzLDRdfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsdWVzLCBbMSwyLDMsNF0pO1xuICAgIH0pO1xuXG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd0eXBlKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZ3JhZGllbnQgdHlwZSBmb3IgY29sb3Igc2NhbGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ID0gcHJvcGVydGllcy50eXBlKCdxdWFudGl0YXRpdmUnLCBDT0xPUiwgJ3NlcXVlbnRpYWwnKTtcbiAgICAgIGFzc2VydC5lcXVhbCh0LCAnZ3JhZGllbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHJldHVybiBncmFkaWVudCB0eXBlIGZvciBzaXplIHNjYWxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgdCA9IHByb3BlcnRpZXMudHlwZSgncXVhbnRpdGF0aXZlJywgU0laRSwgJ2xpbmVhcicpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHQsIHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBubyB0eXBlIGZvciBjb2xvciBzY2FsZSB3aXRoIGJpbicsICgpID0+IHtcbiAgICAgIGNvbnN0IHQgPSBwcm9wZXJ0aWVzLnR5cGUoJ3F1YW50aXRhdGl2ZScsIENPTE9SLCAnYmluLW9yZGluYWwnKTtcbiAgICAgIGFzc2VydC5lcXVhbCh0LCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZ3JhZGllbnQgdHlwZSBmb3IgY29sb3Igc2NhbGUgd2l0aCB0aW1lIHNjYWxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgdCA9IHByb3BlcnRpZXMudHlwZSgndGVtcG9yYWwnLCBDT0xPUiwgJ3RpbWUnKTtcbiAgICAgIGFzc2VydC5lcXVhbCh0LCAnZ3JhZGllbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIG5vIHR5cGUgZm9yIGNvbG9yIHNjYWxlIHdpdGggb3JkaW5hbCBzY2FsZSBhbmQgdGVtcG9yYWwgdHlwZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHQgPSBwcm9wZXJ0aWVzLnR5cGUoJ3RlbXBvcmFsJywgQ09MT1IsICdvcmRpbmFsJyk7XG4gICAgICBhc3NlcnQuZXF1YWwodCwgdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIG5vIHR5cGUgZm9yIGNvbG9yIHNjYWxlIHdpdGggb3JkaW5hbCBzY2FsZSBhbmQgb3JkaW5hbCB0eXBlJywgKCkgPT4ge1xuICAgICAgY29uc3QgdCA9IHByb3BlcnRpZXMudHlwZSgnb3JkaW5hbCcsIENPTE9SLCAnb3JkaW5hbCcpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHQsIHVuZGVmaW5lZCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/mark/area.test.js b/build/test/compile/mark/area.test.js new file mode 100644 index 0000000000..1c71ca3216 --- /dev/null +++ b/build/test/compile/mark/area.test.js @@ -0,0 +1,220 @@ +"use strict"; +/* tslint:disable quotemark */ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var area_1 = require("../../../src/compile/mark/area"); +var util_1 = require("../../util"); +describe('Mark: Area', function () { + function verticalArea(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "area", + "encoding": __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 = util_1.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_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + }); + it('should has no height', function () { + chai_1.assert.isUndefined(props.height); + }); + }); + describe('stacked vertical area, with binned dimension', function () { + var model = util_1.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_1.area.encodeEntry(model); + it('should use bin_mid for x', function () { + chai_1.assert.deepEqual(props.x, { field: 'bin_maxbins_10_IMDB_Rating_mid', scale: 'x' }); + }); + }); + describe('vertical area, with zero=false', function () { + var model = util_1.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_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + }); + it('should has no height', function () { + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical area', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(verticalArea()); + var props = area_1.area.encodeEntry(model); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year_Year' }); + }); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'count_*' }); + }); + it('should have the correct value for y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('vertical area with binned dimension', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(verticalArea()); + var props = area_1.area.encodeEntry(model); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year_Year' }); + }); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'count_*' }); + }); + it('should have the correct value for y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('vertical stacked area with color', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(verticalArea({ + "color": { "field": "Origin", "type": "quantitative" } + })); + var props = area_1.area.encodeEntry(model); + it('should have the correct value for y and y2', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'count_*_end' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'count_*_start' }); + }); + it('should have correct orient', function () { + chai_1.assert.deepEqual(props.orient, { value: 'vertical' }); + }); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.fill, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); + function horizontalArea(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "area", + "encoding": __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 = util_1.parseUnitModelWithScaleAndLayoutSize(horizontalArea()); + var props = area_1.area.encodeEntry(model); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'year_Year' }); + }); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'count_*' }); + }); + it('should have the correct value for x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + }); + }); + describe('horizontal area, with log', function () { + var model = util_1.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_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + }); + it('should have no width', function () { + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal area, with zero=false', function () { + var model = util_1.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_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + }); + it('should have no width', function () { + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal stacked area with color', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(horizontalArea({ + "color": { "field": "Origin", "type": "nominal" } + })); + var props = area_1.area.encodeEntry(model); + it('should have the correct value for x and x2', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'count_*_end' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'count_*_start' }); + }); + it('should have correct orient', function () { + chai_1.assert.deepEqual(props.orient, { value: 'horizontal' }); + }); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.fill, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); + describe('ranged area', function () { + it('vertical area should work with aggregate', function () { + var model = util_1.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_1.area.encodeEntry(model); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'year_Year' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'min_Weight_in_lbs' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'max_Weight_in_lbs' }); + }); + it('horizontal area should work with aggregate', function () { + var model = util_1.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_1.area.encodeEntry(model); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'year_Year' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'min_Weight_in_lbs' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'max_Weight_in_lbs' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJlYS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvYXJlYS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7Ozs7Ozs7Ozs7QUFFOUIsNkJBQTRCO0FBQzVCLGdEQUFpRDtBQUNqRCx1REFBb0Q7QUFHcEQsbUNBQWdFO0FBRWhFLFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFDckIsc0JBQXNCLFlBQW1DO1FBQW5DLDZCQUFBLEVBQUEsaUJBQW1DO1FBQ3ZELE1BQU0sQ0FBQztZQUNMLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxhQUVOLEdBQUcsRUFBRSxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDLEVBQzlELEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQyxJQUNoRCxZQUFZLENBQ2hCO1lBQ0gsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO1NBQ2xDLENBQUM7SUFDSixDQUFDO0lBRUQsUUFBUSxDQUFDLHlCQUF5QixFQUFFO1FBQ2xDLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO1lBQ2pELE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFDO2dCQUNsRSxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUM7YUFDbEc7WUFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7U0FDcEMsQ0FBQyxDQUFDO1FBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMsb0JBQW9CLEVBQUU7WUFDdkIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQyxFQUFDLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQkFBc0IsRUFBRTtZQUN6QixhQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDhDQUE4QyxFQUFFO1FBQ3ZELElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO1lBQ2pELE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFDO2dCQUNsRSxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBQztnQkFDdEUsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFDO2FBQzNDO1lBQ0QsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDO1NBQ3BDLENBQUMsQ0FBQztRQUNILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLDBCQUEwQixFQUFFO1lBQzdCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxnQ0FBZ0MsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFDLENBQUMsQ0FBQztRQUNuRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGdDQUFnQyxFQUFFO1FBQ3pDLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO1lBQ2pELE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFDO2dCQUNsRSxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUM7YUFDbEc7WUFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7U0FDcEMsQ0FBQyxDQUFDO1FBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMsb0JBQW9CLEVBQUU7WUFDdkIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQyxFQUFDLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQkFBc0IsRUFBRTtZQUN6QixhQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLHlCQUF5QixFQUFFO1lBQzVCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBQyxDQUFDLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUJBQXlCLEVBQUU7WUFDNUIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFDLENBQUMsQ0FBQztRQUMxRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQ0FBc0MsRUFBRTtZQUN6QyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMscUNBQXFDLEVBQUU7UUFDOUMsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUNuRSxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlCQUF5QixFQUFFO1lBQzVCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBQyxDQUFDLENBQUM7UUFDMUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0NBQXNDLEVBQUU7WUFDekMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGtDQUFrQyxFQUFFO1FBQzNDLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDLFlBQVksQ0FBQztZQUM5RCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7U0FDckQsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRTtZQUMvQyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUMsQ0FBQyxDQUFDO1lBQzlELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNEJBQTRCLEVBQUU7WUFDL0IsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLFVBQVUsRUFBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkJBQTZCLEVBQUU7WUFDaEMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLGVBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsd0JBQXdCLFlBQW1DO1FBQW5DLDZCQUFBLEVBQUEsaUJBQW1DO1FBQ3pELE1BQU0sQ0FBQztZQUNMLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxhQUNOLEdBQUcsRUFBRSxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDLEVBQzlELEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQyxJQUNoRCxZQUFZLENBQ2hCO1lBQ0gsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO1NBQ2xDLENBQUM7SUFDSixDQUFDO0lBRUQsUUFBUSxDQUFDLGlCQUFpQixFQUFFO1FBQzFCLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDckUsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMseUJBQXlCLEVBQUU7WUFDNUIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQUMsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQztRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFO1lBQ3pDLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUcsS0FBSyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQywyQkFBMkIsRUFBRTtRQUNwQyxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFBRTtnQkFDVixHQUFHLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBQztnQkFDbEUsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFDO2FBQ2xHO1lBQ0QsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDO1NBQ3BDLENBQUMsQ0FBQztRQUVILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLG9CQUFvQixFQUFFO1lBQ3ZCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1lBQ3pCLGFBQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsa0NBQWtDLEVBQUU7UUFDM0MsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7WUFDakQsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUM7Z0JBQ2xFLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBQzthQUNsRztZQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztTQUNwQyxDQUFDLENBQUM7UUFFSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRTtZQUN2QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQkFBc0IsRUFBRTtZQUN6QixhQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG9DQUFvQyxFQUFFO1FBQzdDLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDLGNBQWMsQ0FBQztZQUNoRSxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7U0FDaEQsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRTtZQUMvQyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUMsQ0FBQyxDQUFDO1lBQzlELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNEJBQTRCLEVBQUU7WUFDL0IsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLFlBQVksRUFBQyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkJBQTZCLEVBQUU7WUFDaEMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLGVBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixFQUFFLENBQUUsMENBQTBDLEVBQUU7WUFDOUMsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBQztnQkFDakMsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDO29CQUM5RCxHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQztvQkFDM0UsSUFBSSxFQUFFLEVBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7aUJBQzdFO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0QyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1lBQzVELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFDLENBQUMsQ0FBQztZQUNwRSxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxtQkFBbUIsRUFBQyxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUUsNENBQTRDLEVBQUU7WUFDaEQsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBQztnQkFDakMsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDO29CQUM5RCxHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQztvQkFDM0UsSUFBSSxFQUFFLEVBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7aUJBQzdFO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0QyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1lBQzVELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFDLENBQUMsQ0FBQztZQUNwRSxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxtQkFBbUIsRUFBQyxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7Q09MT1IsIFgsIFl9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7YXJlYX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9hcmVhJztcbmltcG9ydCB7RW5jb2Rpbmd9IGZyb20gJy4uLy4uLy4uL3NyYy9lbmNvZGluZyc7XG5pbXBvcnQge1VuaXRTcGVjfSBmcm9tICcuLi8uLi8uLi9zcmMvc3BlYyc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdNYXJrOiBBcmVhJywgZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIHZlcnRpY2FsQXJlYShtb3JlRW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4gPSB7fSk6IFVuaXRTcGVjIHtcbiAgICByZXR1cm4ge1xuICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOlxuICAgICAgICB7XG4gICAgICAgICAgXCJ4XCI6IHtcInRpbWVVbml0XCI6IFwieWVhclwiLCBcImZpZWxkXCI6IFwiWWVhclwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwiY291bnRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIC4uLm1vcmVFbmNvZGluZyxcbiAgICAgICAgfSxcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2NhcnMuanNvblwifVxuICAgIH07XG4gIH1cblxuICBkZXNjcmliZSgndmVydGljYWwgYXJlYSwgd2l0aCBsb2cnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJhcmVhXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImJpblwiOiB0cnVlLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcIklNREJfUmF0aW5nXCJ9LFxuICAgICAgICBcInlcIjoge1wic2NhbGVcIjoge1widHlwZVwiOiAnbG9nJ30sIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdVU19Hcm9zcycsIFwiYWdncmVnYXRlXCI6IFwibWVhblwifVxuICAgICAgfSxcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvbW92aWVzLmpzb24nfVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gYXJlYS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGVuZCBvbiBheGlzJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7ZmllbGQ6IHtncm91cDogJ2hlaWdodCd9fSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhcyBubyBoZWlnaHQnLCBmdW5jdGlvbigpe1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLmhlaWdodCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzdGFja2VkIHZlcnRpY2FsIGFyZWEsIHdpdGggYmlubmVkIGRpbWVuc2lvbicsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiYmluXCI6IHRydWUsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiSU1EQl9SYXRpbmdcIn0sXG4gICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogJ1VTX0dyb3NzJywgXCJhZ2dyZWdhdGVcIjogXCJzdW1cIn0sXG4gICAgICAgIFwiY29sb3JcIjoge1widHlwZVwiOiBcIm5vbWluYWxcIiwgXCJmaWVsZFwiOiAnYyd9XG4gICAgICB9LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9tb3ZpZXMuanNvbid9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBhcmVhLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgdXNlIGJpbl9taWQgZm9yIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge2ZpZWxkOiAnYmluX21heGJpbnNfMTBfSU1EQl9SYXRpbmdfbWlkJywgc2NhbGU6ICd4J30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVydGljYWwgYXJlYSwgd2l0aCB6ZXJvPWZhbHNlJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJJTURCX1JhdGluZ1wifSxcbiAgICAgICAgXCJ5XCI6IHtcInNjYWxlXCI6IHtcInplcm9cIjogZmFsc2V9LCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiAnVVNfR3Jvc3MnLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgIH0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL21vdmllcy5qc29uJ31cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGFyZWEuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmQgb24gYXhpcycsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge2ZpZWxkOiB7Z3JvdXA6ICdoZWlnaHQnfX0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXMgbm8gaGVpZ2h0JywgZnVuY3Rpb24oKXtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChwcm9wcy5oZWlnaHQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVydGljYWwgYXJlYScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHZlcnRpY2FsQXJlYSgpKTtcbiAgICBjb25zdCBwcm9wcyA9IGFyZWEuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciB4JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogWCwgZmllbGQ6ICd5ZWFyX1llYXInfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgc2NhbGUgZm9yIHknLCBmdW5jdGlvbigpe1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6IFksIGZpZWxkOiAnY291bnRfKid9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSB0aGUgY29ycmVjdCB2YWx1ZSBmb3IgeTInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6ICd5JywgdmFsdWU6IDB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZlcnRpY2FsIGFyZWEgd2l0aCBiaW5uZWQgZGltZW5zaW9uJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUodmVydGljYWxBcmVhKCkpO1xuICAgIGNvbnN0IHByb3BzID0gYXJlYS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgc2NhbGUgZm9yIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ3llYXJfWWVhcid9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBzY2FsZSBmb3IgeScsIGZ1bmN0aW9uKCl7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogWSwgZmllbGQ6ICdjb3VudF8qJ30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHRoZSBjb3JyZWN0IHZhbHVlIGZvciB5MicsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtzY2FsZTogJ3knLCB2YWx1ZTogMH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVydGljYWwgc3RhY2tlZCBhcmVhIHdpdGggY29sb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUodmVydGljYWxBcmVhKHtcbiAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgfSkpO1xuXG4gICAgY29uc3QgcHJvcHMgPSBhcmVhLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSB0aGUgY29ycmVjdCB2YWx1ZSBmb3IgeSBhbmQgeTInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ2NvdW50XypfZW5kJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge3NjYWxlOiAneScsIGZpZWxkOiAnY291bnRfKl9zdGFydCd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IG9yaWVudCcsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMub3JpZW50LCB7dmFsdWU6ICd2ZXJ0aWNhbCd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBzY2FsZSBmb3IgY29sb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmZpbGwsIHtzY2FsZTogQ09MT1IsIGZpZWxkOiAnT3JpZ2luJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBmdW5jdGlvbiBob3Jpem9udGFsQXJlYShtb3JlRW5jb2Rpbmc6IEVuY29kaW5nPHN0cmluZz4gPSB7fSk6IFVuaXRTcGVjIHtcbiAgICByZXR1cm4ge1xuICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ5XCI6IHtcInRpbWVVbml0XCI6IFwieWVhclwiLCBcImZpZWxkXCI6IFwiWWVhclwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwiY291bnRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIC4uLm1vcmVFbmNvZGluZyxcbiAgICAgICAgfSxcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2NhcnMuanNvblwifVxuICAgIH07XG4gIH1cblxuICBkZXNjcmliZSgnaG9yaXpvbnRhbCBhcmVhJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoaG9yaXpvbnRhbEFyZWEoKSk7XG4gICAgY29uc3QgcHJvcHMgPSBhcmVhLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBzY2FsZSBmb3IgeScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6IFksIGZpZWxkOiAneWVhcl9ZZWFyJ30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciB4JywgZnVuY3Rpb24oKXtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ2NvdW50XyonfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgdGhlIGNvcnJlY3QgdmFsdWUgZm9yIHgyJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcgLCB2YWx1ZTogMH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaG9yaXpvbnRhbCBhcmVhLCB3aXRoIGxvZycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiSU1EQl9SYXRpbmdcIn0sXG4gICAgICAgIFwieFwiOiB7XCJzY2FsZVwiOiB7XCJ0eXBlXCI6ICdsb2cnfSwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogJ1VTX0dyb3NzJywgXCJhZ2dyZWdhdGVcIjogXCJtZWFuXCJ9XG4gICAgICB9LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9tb3ZpZXMuanNvbid9XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IGFyZWEuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmQgb24gYXhpcycsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3ZhbHVlOiAwfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgbm8gd2lkdGgnLCBmdW5jdGlvbigpe1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLndpZHRoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwgYXJlYSwgd2l0aCB6ZXJvPWZhbHNlJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJJTURCX1JhdGluZ1wifSxcbiAgICAgICAgXCJ4XCI6IHtcInNjYWxlXCI6IHtcInplcm9cIjogZmFsc2V9LCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiAnVVNfR3Jvc3MnLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgIH0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL21vdmllcy5qc29uJ31cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gYXJlYS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGVuZCBvbiBheGlzJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7dmFsdWU6IDB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBubyB3aWR0aCcsIGZ1bmN0aW9uKCl7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMud2lkdGgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaG9yaXpvbnRhbCBzdGFja2VkIGFyZWEgd2l0aCBjb2xvcicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZShob3Jpem9udGFsQXJlYSh7XG4gICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICB9KSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IGFyZWEuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHRoZSBjb3JyZWN0IHZhbHVlIGZvciB4IGFuZCB4MicsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiAneCcsIGZpZWxkOiAnY291bnRfKl9lbmQnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgZmllbGQ6ICdjb3VudF8qX3N0YXJ0J30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3Qgb3JpZW50JywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5vcmllbnQsIHt2YWx1ZTogJ2hvcml6b250YWwnfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgc2NhbGUgZm9yIGNvbG9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5maWxsLCB7c2NhbGU6IENPTE9SLCBmaWVsZDogJ09yaWdpbid9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JhbmdlZCBhcmVhJywgZnVuY3Rpb24gKCkge1xuICAgIGl0ICgndmVydGljYWwgYXJlYSBzaG91bGQgd29yayB3aXRoIGFnZ3JlZ2F0ZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9jYXJzLmpzb25cIn0sXG4gICAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcInRpbWVVbml0XCI6IFwieWVhclwiLCBcImZpZWxkXCI6IFwiWWVhclwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwibWluXCIsIFwiZmllbGRcIjogXCJXZWlnaHRfaW5fbGJzXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInkyXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLCBcImZpZWxkXCI6IFwiV2VpZ2h0X2luX2xic1wiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBwcm9wcyA9IGFyZWEuZW5jb2RlRW50cnkobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICd5ZWFyX1llYXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ21pbl9XZWlnaHRfaW5fbGJzJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge3NjYWxlOiAneScsIGZpZWxkOiAnbWF4X1dlaWdodF9pbl9sYnMnfSk7XG4gICAgfSk7XG5cbiAgICBpdCAoJ2hvcml6b250YWwgYXJlYSBzaG91bGQgd29yayB3aXRoIGFnZ3JlZ2F0ZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9jYXJzLmpzb25cIn0sXG4gICAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ5XCI6IHtcInRpbWVVbml0XCI6IFwieWVhclwiLCBcImZpZWxkXCI6IFwiWWVhclwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWluXCIsIFwiZmllbGRcIjogXCJXZWlnaHRfaW5fbGJzXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcIngyXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLCBcImZpZWxkXCI6IFwiV2VpZ2h0X2luX2xic1wiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBwcm9wcyA9IGFyZWEuZW5jb2RlRW50cnkobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICd5ZWFyX1llYXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ21pbl9XZWlnaHRfaW5fbGJzJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIGZpZWxkOiAnbWF4X1dlaWdodF9pbl9sYnMnfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/mark/bar.test.js b/build/test/compile/mark/bar.test.js new file mode 100644 index 0000000000..8058629440 --- /dev/null +++ b/build/test/compile/mark/bar.test.js @@ -0,0 +1,549 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var bar_1 = require("../../../src/compile/mark/bar"); +var log = require("../../../src/log"); +var mark_1 = require("../../../src/mark"); +var scale_1 = require("../../../src/scale"); +var util_1 = require("../../util"); +describe('Mark: Bar', function () { + describe('simple vertical', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar, with y from zero to field value and with band value for x/width ', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('simple horizontal', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar from zero to field value and with band value for x/width', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple horizontal with point scale', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar from zero to field value and y with center position and height = rangeStep - 1', function () { + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { value: scale_1.defaultScaleConfig.rangeStep - 1 }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple horizontal with size value', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should set height to 5 and center y', function () { + chai_1.assert.deepEqual(props.height, { value: 5 }); + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'Origin', band: 0.5 }); + }); + }); + describe('simple horizontal with size field', function () { + var model = util_1.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_1.bar.encodeEntry(model); + log.wrap(function (localLogger) { + it('should draw bar from zero to field value and with band value for x/width', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + it('should throw warning', function () { + chai_1.assert.equal(localLogger.warns[0], log.message.cannotUseSizeFieldWithBandSize('y')); + }); + }); + }); + describe('horizontal binned', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('horizontal binned, sort descending', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('horizontal binned, reverse', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical binned', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('vertical binned, sort descending', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal binned with ordinal', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_range' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + }); + }); + describe('vertical binned with ordinal', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_range' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + }); + }); + describe('horizontal binned with no spacing', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical binned with no spacing', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple horizontal binned with size', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with y centered on bin_mid and height = size field', function () { + chai_1.assert.deepEqual(props.yc, { signal: '(scale("y", datum["bin_maxbins_10_Horsepower"]) + scale("y", datum["bin_maxbins_10_Horsepower_end"]))/2' }); + chai_1.assert.deepEqual(props.height, { scale: 'size', field: 'mean_Acceleration' }); + }); + }); + describe('vertical binned with size', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should draw bar with x centered on bin_mid and width = size field', function () { + chai_1.assert.deepEqual(props.xc, { signal: '(scale(\"x\", datum[\"bin_maxbins_10_Horsepower\"]) + scale(\"x\", datum[\"bin_maxbins_10_Horsepower_end\"]))/2' }); + chai_1.assert.deepEqual(props.width, { scale: 'size', field: 'mean_Acceleration' }); + }); + }); + describe('vertical, with log', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should end on axis and has no height', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('horizontal, with log', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should end on axis and has no width', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('vertical, with fit mode', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should use x and with band true', function () { + chai_1.assert.deepEqual(props.x, { + scale: 'x', + field: 'Origin', + }); + chai_1.assert.deepEqual(props.width, { + scale: 'x', + band: true, + }); + }); + }); + describe('horizontal, with fit mode', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should use y with band true', function () { + chai_1.assert.deepEqual(props.y, { + scale: 'y', + field: 'Origin', + }); + chai_1.assert.deepEqual(props.height, { + scale: 'y', + band: true, + }); + }); + }); + describe('vertical with zero=false', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should end on axis nad have no height', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('horizontal with zero=false', function () { + var model = util_1.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_1.bar.encodeEntry(model); + it('should end on axis and have no width', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('1D vertical', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } }, + "data": { "url": 'data/movies.json' } + }); + var props = bar_1.bar.encodeEntry(model); + it('should have y end on axis, have no-height and have x-offset', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'sum_US_Gross' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + chai_1.assert.isUndefined(props.height); + chai_1.assert.deepEqual(props.xc, { + mult: 0.5, + signal: 'width' + }); + }); + }); + describe('1D vertical with size value', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" }, + "size": { "value": 5 } + }, + "data": { "url": 'data/movies.json' } + }); + var props = bar_1.bar.encodeEntry(model); + it('should have width = 5', function () { + chai_1.assert.deepEqual(props.width, { value: 5 }); + }); + }); + describe('1D vertical with barSize config', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/movies.json' }, + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "config": { + "bar": { "discreteBandSize": 5 } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should have width = 5', function () { + chai_1.assert.deepEqual(props.width, { value: 5 }); + }); + }); + describe('1D horizontal', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { "x": { "type": "quantitative", "field": 'US_Gross', "aggregate": 'sum' } }, + "data": { "url": 'data/movies.json' } + }); + var props = bar_1.bar.encodeEntry(model); + it('should end on axis, have no width, and have y-offset', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'sum_US_Gross' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + chai_1.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 = util_1.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_1.bar.encodeEntry(model); + it('should produce horizontal bar using x, x2', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'Horsepower' }); + chai_1.assert.deepEqual(props.height, { value: mark_1.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 = util_1.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_1.bar.encodeEntry(model); + it('should produce horizontal bar using x, x2', function () { + chai_1.assert.deepEqual(props.xc, { scale: 'x', field: 'Acceleration' }); + chai_1.assert.deepEqual(props.width, { value: mark_1.defaultBarConfig.continuousBandSize }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Horsepower' }); + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Origin', "type": "nominal" }, + "y": { "field": 'Cylinders', "type": "ordinal" } + } + }); + var props = bar_1.bar.encodeEntry(model); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Cylinders' }); + chai_1.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 = util_1.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_1.bar.encodeEntry(model); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'age' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'q1_people' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'q3_people' }); + }); + it('horizontal bars should work with aggregate', function () { + var model = util_1.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_1.bar.encodeEntry(model); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'age' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'q1_people' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'q3_people' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbWFyay9iYXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIscURBQWtEO0FBQ2xELHNDQUF3QztBQUN4QywwQ0FBbUQ7QUFDbkQsNENBQXNEO0FBQ3RELG1DQUFnRTtBQUVoRSxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ3BCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtRQUMxQixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUM7WUFDakMsTUFBTSxFQUFFLEtBQUs7WUFDYixVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO2dCQUMzQyxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBQzthQUM1RTtTQUNGLENBQUMsQ0FBQztRQUNILElBQU0sS0FBSyxHQUFHLFNBQUcsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFckMsRUFBRSxDQUFDLG1GQUFtRixFQUFFO1lBQ3RGLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7WUFDekQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQztZQUN4RCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FB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LDRDQUE0QyxFQUFFO1lBQy9DLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsc0JBQXNCLEVBQUM7Z0JBQ3ZDLE1BQU0sRUFBRSxLQUFLO2dCQUNiLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7b0JBQ3hDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO29CQUNuRSxJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQztpQkFDckU7YUFDRixDQUFDLENBQUM7WUFFSCxJQUFNLEtBQUssR0FBRyxTQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7WUFDdEQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQztZQUM1RCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlIHF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2Jhcn0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9iYXInO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uLy4uL3NyYy9sb2cnO1xuaW1wb3J0IHtkZWZhdWx0QmFyQ29uZmlnfSBmcm9tICcuLi8uLi8uLi9zcmMvbWFyayc7XG5pbXBvcnQge2RlZmF1bHRTY2FsZUNvbmZpZ30gZnJvbSAnLi4vLi4vLi4vc3JjL3NjYWxlJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ01hcms6IEJhcicsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnc2ltcGxlIHZlcnRpY2FsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyLCB3aXRoIHkgZnJvbSB6ZXJvIHRvIGZpZWxkIHZhbHVlIGFuZCB3aXRoIGJhbmQgdmFsdWUgZm9yIHgvd2lkdGggJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ09yaWdpbid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMud2lkdGgsIHtzY2FsZTogJ3gnLCBiYW5kOiB0cnVlfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ21lYW5fQWNjZWxlcmF0aW9uJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge3NjYWxlOiAneScsIHZhbHVlOiAwfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMuaGVpZ2h0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NpbXBsZSBob3Jpem9udGFsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIGZyb20gemVybyB0byBmaWVsZCB2YWx1ZSBhbmQgd2l0aCBiYW5kIHZhbHVlIGZvciB4L3dpZHRoJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ09yaWdpbid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuaGVpZ2h0LCB7c2NhbGU6ICd5JywgYmFuZDogdHJ1ZX0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICdtZWFuX0FjY2VsZXJhdGlvbid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueDIsIHtzY2FsZTogJ3gnLCB2YWx1ZTogMH0pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLndpZHRoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NpbXBsZSBob3Jpem9udGFsIHdpdGggcG9pbnQgc2NhbGUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIiwgXCJzY2FsZVwiOiB7XCJ0eXBlXCI6IFwicG9pbnRcIn19LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIGZyb20gemVybyB0byBmaWVsZCB2YWx1ZSBhbmQgeSB3aXRoIGNlbnRlciBwb3NpdGlvbiBhbmQgaGVpZ2h0ID0gcmFuZ2VTdGVwIC0gMScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Yywge3NjYWxlOiAneScsIGZpZWxkOiAnT3JpZ2luJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5oZWlnaHQsIHt2YWx1ZTogZGVmYXVsdFNjYWxlQ29uZmlnLnJhbmdlU3RlcCAtIDF9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiAneCcsIGZpZWxkOiAnbWVhbl9BY2NlbGVyYXRpb24nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgdmFsdWU6IDB9KTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChwcm9wcy53aWR0aCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaW1wbGUgaG9yaXpvbnRhbCB3aXRoIHNpemUgdmFsdWUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgaGVpZ2h0IHRvIDUgYW5kIGNlbnRlciB5JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmhlaWdodCwge3ZhbHVlOiA1fSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnljLCB7c2NhbGU6ICd5JywgZmllbGQ6ICdPcmlnaW4nLCBiYW5kOiAwLjV9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NpbXBsZSBob3Jpem9udGFsIHdpdGggc2l6ZSBmaWVsZCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInNpemVcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgZHJhdyBiYXIgZnJvbSB6ZXJvIHRvIGZpZWxkIHZhbHVlIGFuZCB3aXRoIGJhbmQgdmFsdWUgZm9yIHgvd2lkdGgnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICdPcmlnaW4nfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuaGVpZ2h0LCB7c2NhbGU6ICd5JywgYmFuZDogdHJ1ZX0pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ21lYW5fQWNjZWxlcmF0aW9uJ30pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgdmFsdWU6IDB9KTtcbiAgICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLndpZHRoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHdhcm5pbmcnLCAoKT0+IHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS5jYW5ub3RVc2VTaXplRmllbGRXaXRoQmFuZFNpemUoJ3knKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwgYmlubmVkJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJmaWVsZFwiOiAnSG9yc2Vwb3dlcicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBkcmF3IGJhciB3aXRoIHkgYW5kIHkyJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6ICd5JywgZmllbGQ6ICdiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICdiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyX2VuZCcsIG9mZnNldDogZGVmYXVsdEJhckNvbmZpZy5iaW5TcGFjaW5nfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMuaGVpZ2h0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwgYmlubmVkLCBzb3J0IGRlc2NlbmRpbmcnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImJpblwiOiB0cnVlLCBcImZpZWxkXCI6ICdIb3JzZXBvd2VyJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwic29ydFwiOiBcImRlc2NlbmRpbmdcIn0sXG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZHJhdyBiYXIgd2l0aCB5IGFuZCB5MicsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge3NjYWxlOiAneScsIGZpZWxkOiAnYmluX21heGJpbnNfMTBfSG9yc2Vwb3dlcicsIG9mZnNldDogZGVmYXVsdEJhckNvbmZpZy5iaW5TcGFjaW5nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJfZW5kJ30pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLmhlaWdodCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdob3Jpem9udGFsIGJpbm5lZCwgcmV2ZXJzZScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJzY2FsZVwiOiB7XCJyZXZlcnNlXCI6IHRydWV9fSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBkcmF3IGJhciB3aXRoIHkgYW5kIHkyJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6ICd5JywgZmllbGQ6ICdiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyJywgb2Zmc2V0OiBkZWZhdWx0QmFyQ29uZmlnLmJpblNwYWNpbmd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiAneScsIGZpZWxkOiAnYmluX21heGJpbnNfMTBfSG9yc2Vwb3dlcl9lbmQnfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMuaGVpZ2h0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZlcnRpY2FsIGJpbm5lZCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZHJhdyBiYXIgd2l0aCB4IGFuZCB4MicsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIGZpZWxkOiAnYmluX21heGJpbnNfMTBfSG9yc2Vwb3dlcicsIG9mZnNldDogZGVmYXVsdEJhckNvbmZpZy5iaW5TcGFjaW5nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJfZW5kJ30pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLndpZHRoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZlcnRpY2FsIGJpbm5lZCwgc29ydCBkZXNjZW5kaW5nJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJmaWVsZFwiOiAnSG9yc2Vwb3dlcicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcInNvcnRcIjogXCJkZXNjZW5kaW5nXCJ9LFxuICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIHdpdGggeCBhbmQgeDInLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueDIsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJfZW5kJywgb2Zmc2V0OiBkZWZhdWx0QmFyQ29uZmlnLmJpblNwYWNpbmd9KTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChwcm9wcy53aWR0aCk7XG4gICAgfSk7XG4gIH0pO1xuXG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwgYmlubmVkIHdpdGggb3JkaW5hbCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIHdpdGggeScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICdiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyX3JhbmdlJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5oZWlnaHQsIHtzY2FsZTogJ3knLCBiYW5kOiB0cnVlfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2ZXJ0aWNhbCBiaW5uZWQgd2l0aCBvcmRpbmFsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJmaWVsZFwiOiAnSG9yc2Vwb3dlcicsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZHJhdyBiYXIgd2l0aCB5JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJfcmFuZ2UnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLndpZHRoLCB7c2NhbGU6ICd4JywgYmFuZDogdHJ1ZX0pO1xuICAgIH0pO1xuICB9KTtcblxuXG4gIGRlc2NyaWJlKCdob3Jpem9udGFsIGJpbm5lZCB3aXRoIG5vIHNwYWNpbmcnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImJpblwiOiB0cnVlLCBcImZpZWxkXCI6ICdIb3JzZXBvd2VyJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH0sXG4gICAgICBcImNvbmZpZ1wiOiB7XCJiYXJcIjoge1wiYmluU3BhY2luZ1wiOiAwfX1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIHdpdGggeSBhbmQgeTInLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtzY2FsZTogJ3knLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJfZW5kJ30pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLmhlaWdodCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2ZXJ0aWNhbCBiaW5uZWQgd2l0aCBubyBzcGFjaW5nJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJmaWVsZFwiOiAnSG9yc2Vwb3dlcicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9LFxuICAgICAgXCJjb25maWdcIjoge1wiYmFyXCI6IHtcImJpblNwYWNpbmdcIjogMH19XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBkcmF3IGJhciB3aXRoIHggYW5kIHgyJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgZmllbGQ6ICdiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICdiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyX2VuZCd9KTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChwcm9wcy53aWR0aCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaW1wbGUgaG9yaXpvbnRhbCBiaW5uZWQgd2l0aCBzaXplJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJmaWVsZFwiOiAnSG9yc2Vwb3dlcicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInNpemVcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIHdpdGggeSBjZW50ZXJlZCBvbiBiaW5fbWlkIGFuZCBoZWlnaHQgPSBzaXplIGZpZWxkJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnljLCB7c2lnbmFsOiAnKHNjYWxlKFwieVwiLCBkYXR1bVtcImJpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJcIl0pICsgc2NhbGUoXCJ5XCIsIGRhdHVtW1wiYmluX21heGJpbnNfMTBfSG9yc2Vwb3dlcl9lbmRcIl0pKS8yJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5oZWlnaHQsIHtzY2FsZTogJ3NpemUnLCBmaWVsZDogJ21lYW5fQWNjZWxlcmF0aW9uJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVydGljYWwgYmlubmVkIHdpdGggc2l6ZScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJzaXplXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBkcmF3IGJhciB3aXRoIHggY2VudGVyZWQgb24gYmluX21pZCBhbmQgd2lkdGggPSBzaXplIGZpZWxkJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnhjLCB7c2lnbmFsOiAnKHNjYWxlKFxcXCJ4XFxcIiwgZGF0dW1bXFxcImJpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJcXFwiXSkgKyBzY2FsZShcXFwieFxcXCIsIGRhdHVtW1xcXCJiaW5fbWF4Ymluc18xMF9Ib3JzZXBvd2VyX2VuZFxcXCJdKSkvMid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMud2lkdGgsIHtzY2FsZTogJ3NpemUnLCBmaWVsZDogJ21lYW5fQWNjZWxlcmF0aW9uJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVydGljYWwsIHdpdGggbG9nJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcInlcIjoge1wic2NhbGVcIjoge1widHlwZVwiOiAnbG9nJ30sIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGVuZCBvbiBheGlzIGFuZCBoYXMgbm8gaGVpZ2h0JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7ZmllbGQ6IHtncm91cDogJ2hlaWdodCd9fSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMuaGVpZ2h0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwsIHdpdGggbG9nJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wic2NhbGVcIjoge1widHlwZVwiOiAnbG9nJ30sIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZW5kIG9uIGF4aXMgYW5kIGhhcyBubyB3aWR0aCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3ZhbHVlOiAwfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMud2lkdGgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVydGljYWwsIHdpdGggZml0IG1vZGUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIndpZHRoXCI6IDEyMCxcbiAgICAgIFwiaGVpZ2h0XCI6IDEyMCxcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgeCBhbmQgd2l0aCBiYW5kIHRydWUnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtcbiAgICAgICAgc2NhbGU6ICd4JyxcbiAgICAgICAgZmllbGQ6ICdPcmlnaW4nLFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLndpZHRoLCB7XG4gICAgICAgIHNjYWxlOiAneCcsXG4gICAgICAgIGJhbmQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwsIHdpdGggZml0IG1vZGUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIndpZHRoXCI6IDEyMCxcbiAgICAgIFwiaGVpZ2h0XCI6IDEyMCxcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgeSB3aXRoIGJhbmQgdHJ1ZScsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge1xuICAgICAgICBzY2FsZTogJ3knLFxuICAgICAgICBmaWVsZDogJ09yaWdpbicsXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuaGVpZ2h0LCB7XG4gICAgICAgIHNjYWxlOiAneScsXG4gICAgICAgIGJhbmQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZlcnRpY2FsIHdpdGggemVybz1mYWxzZScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgXCJ5XCI6IHtcInNjYWxlXCI6IHtcInplcm9cIjogZmFsc2V9LCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJhZ2dyZWdhdGVcIjogXCJtZWFuXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmQgb24gYXhpcyBuYWQgaGF2ZSBubyBoZWlnaHQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtmaWVsZDoge2dyb3VwOiAnaGVpZ2h0J319KTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChwcm9wcy5oZWlnaHQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaG9yaXpvbnRhbCB3aXRoIHplcm89ZmFsc2UnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgIFwieFwiOiB7XCJzY2FsZVwiOiB7XCJ6ZXJvXCI6IGZhbHNlfSwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwiYWdncmVnYXRlXCI6IFwibWVhblwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuICAgIGl0KCdzaG91bGQgZW5kIG9uIGF4aXMgYW5kIGhhdmUgbm8gd2lkdGgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueDIsIHt2YWx1ZTogMH0pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLndpZHRoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJzFEIHZlcnRpY2FsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XCJ5XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiAnVVNfR3Jvc3MnLCBcImFnZ3JlZ2F0ZVwiOiBcInN1bVwifX0sXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvbW92aWVzLmpzb24nfVxuICAgICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHkgZW5kIG9uIGF4aXMsIGhhdmUgbm8taGVpZ2h0IGFuZCBoYXZlIHgtb2Zmc2V0JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ3N1bV9VU19Hcm9zcyd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtzY2FsZTogJ3knLCB2YWx1ZTogMH0pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLmhlaWdodCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnhjLCB7XG4gICAgICAgIG11bHQ6IDAuNSxcbiAgICAgICAgc2lnbmFsOiAnd2lkdGgnXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJzFEIHZlcnRpY2FsIHdpdGggc2l6ZSB2YWx1ZScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogJ1VTX0dyb3NzJywgXCJhZ2dyZWdhdGVcIjogXCJzdW1cIn0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgIH0sXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvbW92aWVzLmpzb24nfVxuICAgICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHdpZHRoID0gNScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy53aWR0aCwge3ZhbHVlOiA1fSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcxRCB2ZXJ0aWNhbCB3aXRoIGJhclNpemUgY29uZmlnJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL21vdmllcy5qc29uJ30sXG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdVU19Hcm9zcycsIFwiYWdncmVnYXRlXCI6IFwic3VtXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICBcImJhclwiOiB7XCJkaXNjcmV0ZUJhbmRTaXplXCI6IDV9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSB3aWR0aCA9IDUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMud2lkdGgsIHt2YWx1ZTogNX0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnMUQgaG9yaXpvbnRhbCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XCJ4XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiAnVVNfR3Jvc3MnLCBcImFnZ3JlZ2F0ZVwiOiAnc3VtJ319LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9tb3ZpZXMuanNvbid9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmQgb24gYXhpcywgaGF2ZSBubyB3aWR0aCwgYW5kIGhhdmUgeS1vZmZzZXQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiAneCcsIGZpZWxkOiAnc3VtX1VTX0dyb3NzJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIHZhbHVlOiAwfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMud2lkdGgpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Yywge1xuICAgICAgICBtdWx0OiAwLjUsXG4gICAgICAgIHNpZ25hbDogJ2hlaWdodCdcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUXhRIGhvcml6b250YWwnLCBmdW5jdGlvbigpIHtcbiAgICAvLyBUaGlzIGlzIGdlbmVyYWxseSBhIHRlcnJpYmxlIGlkZWEsIGJ1dCB3ZSBzaG91bGQgc3RpbGwgdGVzdFxuICAgIC8vIGlmIHRoZSBvdXRwdXQgc2hvdyBleHBlY3RlZCByZXN1bHRzXG5cbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfSxcbiAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgIFwibWFya1wiOiB7XCJvcmllbnRcIjogXCJob3Jpem9udGFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBob3Jpem9udGFsIGJhciB1c2luZyB4LCB4MicsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICdBY2NlbGVyYXRpb24nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgdmFsdWU6IDB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueWMsIHtzY2FsZTogJ3knLCBmaWVsZDogJ0hvcnNlcG93ZXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmhlaWdodCwge3ZhbHVlOiBkZWZhdWx0QmFyQ29uZmlnLmNvbnRpbnVvdXNCYW5kU2l6ZX0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUXhRIHZlcnRpY2FsJywgZnVuY3Rpb24oKSB7XG4gICAgLy8gVGhpcyBpcyBnZW5lcmFsbHkgYSB0ZXJyaWJsZSBpZGVhLCBidXQgd2Ugc2hvdWxkIHN0aWxsIHRlc3RcbiAgICAvLyBpZiB0aGUgb3V0cHV0IHNob3cgZXhwZWN0ZWQgcmVzdWx0c1xuXG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6ICdIb3JzZXBvd2VyJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICBcIm1hcmtcIjoge1wib3JpZW50XCI6IFwidmVydGljYWxcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGhvcml6b250YWwgYmFyIHVzaW5nIHgsIHgyJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnhjLCB7c2NhbGU6ICd4JywgZmllbGQ6ICdBY2NlbGVyYXRpb24nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLndpZHRoLCB7dmFsdWU6IGRlZmF1bHRCYXJDb25maWcuY29udGludW91c0JhbmRTaXplfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ0hvcnNlcG93ZXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6ICd5JywgdmFsdWU6IDB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ094TicsIGZ1bmN0aW9uKCkge1xuICAgIC8vIFRoaXMgaXMgZ2VuZXJhbGx5IGEgdGVycmlibGUgaWRlYSwgYnV0IHdlIHNob3VsZCBzdGlsbCB0ZXN0XG4gICAgLy8gaWYgdGhlIG91dHB1dCBzaG93IGV4cGVjdGVkIHJlc3VsdHNcbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgdmVydGljYWwgYmFyIHVzaW5nIHgsIHdpZHRoJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogJ2RhdGEvY2Fycy5qc29uJ30sXG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogJ09yaWdpbicsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6ICdDeWxpbmRlcnMnLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJvcHMgPSBiYXIuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ09yaWdpbid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMud2lkdGgsIHtzY2FsZTogJ3gnLCBiYW5kOiB0cnVlfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ0N5bGluZGVycyd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuaGVpZ2h0LCB7c2NhbGU6ICd5JywgYmFuZDogdHJ1ZX0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmFuZ2VkIGJhcicsIGZ1bmN0aW9uKCkge1xuICAgIC8vIFRPRE86IGdhbnR0IGNoYXJ0IHdpdGggdGVtcG9yYWxcblxuICAgIC8vIFRPRE86IGdhbnR0IGNoYXJ0IHdpdGggb3JkaW5hbFxuXG4gICAgaXQoJ3ZlcnRpY2FsIGJhcnMgc2hvdWxkIHdvcmsgd2l0aCBhZ2dyZWdhdGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicGVvcGxlXCIsIFwiYWdncmVnYXRlXCI6IFwicTFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIFwieTJcIjoge1wiZmllbGRcIjogXCJwZW9wbGVcIiwgXCJhZ2dyZWdhdGVcIjogXCJxM1wiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHByb3BzID0gYmFyLmVuY29kZUVudHJ5KG1vZGVsKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiAneCcsIGZpZWxkOiAnYWdlJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICdxMV9wZW9wbGUnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6ICd5JywgZmllbGQ6ICdxM19wZW9wbGUnfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnaG9yaXpvbnRhbCBiYXJzIHNob3VsZCB3b3JrIHdpdGggYWdncmVnYXRlJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcInBlb3BsZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcInExXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcIngyXCI6IHtcImZpZWxkXCI6IFwicGVvcGxlXCIsIFwiYWdncmVnYXRlXCI6IFwicTNcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9wcyA9IGJhci5lbmNvZGVFbnRyeShtb2RlbCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ2FnZSd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiAneCcsIGZpZWxkOiAncTFfcGVvcGxlJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIGZpZWxkOiAncTNfcGVvcGxlJ30pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/mark/init.test.js b/build/test/compile/mark/init.test.js new file mode 100644 index 0000000000..f18d7a2cf4 --- /dev/null +++ b/build/test/compile/mark/init.test.js @@ -0,0 +1,258 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../src/log"); +var chai_1 = require("chai"); +var mark_1 = require("../../../src/mark"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../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 = [mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE]; _i < _a.length; _i++) { + var mark = _a[_i]; + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + mark: mark, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + chai_1.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 = [mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE]; _i < _a.length; _i++) { + var mark = _a[_i]; + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + mark: mark, + "encoding": { + "y": { "aggregate": "mean", "type": "quantitative", "field": "foo" }, + "x": { "type": "nominal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.opacity, undefined); + } + }); + it('should use specified opacity', function () { + for (var _i = 0, _a = [mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE]; _i < _a.length; _i++) { + var mark = _a[_i]; + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + mark: { type: mark, opacity: 0.9 }, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.opacity, 0.9); + } + }); + it('should return undefined by default for other marks', function () { + var otherMarks = util_1.without(mark_1.PRIMITIVE_MARKS, [mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE]); + for (var _i = 0, otherMarks_1 = otherMarks; _i < otherMarks_1.length; _i++) { + var mark = otherMarks_1[_i]; + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + mark: mark, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "nominal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.opacity, undefined); + } + }); + }); + describe('orient', function () { + it('should return correct default for QxQ', log.wrap(function (localLogger) { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + chai_1.assert.equal(localLogger.warns[0], log.message.unclearOrientContinuous(mark_1.BAR)); + })); + it('should return correct default for empty plot', log.wrap(function (localLogger) { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + encoding: {} + }); + chai_1.assert.equal(model.markDef.orient, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.unclearOrientDiscreteOrEmpty(mark_1.BAR)); + })); + it('should return correct orient for bar with both axes discrete', log.wrap(function (localLogger) { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "ordinal", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.unclearOrientDiscreteOrEmpty(mark_1.BAR)); + })); + it('should return correct orient for vertical bar', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal bar', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical bar with raw temporal dimension', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal bar with raw temporal dimension', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "temporal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical tick', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical tick with bin', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "quantitative", "field": "bar", "bin": true } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical tick of continuous timeUnit dotplot', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "type": "temporal", "field": "foo", "timeUnit": "yearmonthdate" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal tick', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rule', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "value": 0 }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal rule', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "value": 0 }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for horizontal rules without x2 ', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "b", "type": "quantitative" }, + "y": { "field": "a", "type": "ordinal" }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rules without y2 ', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "b", "type": "quantitative" }, + "x": { "field": "a", "type": "ordinal" }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical rule with range', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "type": "ordinal", "field": "foo" }, + "y": { "type": "quantitative", "field": "bar" }, + "y2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal rule with range', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "type": "ordinal", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" }, + "x2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for horizontal rule with range and no ordinal', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "type": "quantitative", "field": "bar" }, + "x2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rule with range and no ordinal', function () { + var model = util_2.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "type": "quantitative", "field": "bar" }, + "y2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvaW5pdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLHNDQUF3QztBQUV4Qyw2QkFBNEI7QUFDNUIsMENBQW9GO0FBQ3BGLDBDQUEwQztBQUMxQyxtQ0FBZ0U7QUFFaEUsUUFBUSxDQUFDLG1CQUFtQixFQUFFO0lBQzVCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixFQUFFLENBQUMsK0VBQStFLEVBQUU7WUFDbEYsR0FBRyxDQUFDLENBQWUsVUFBNkIsRUFBN0IsTUFBQyxZQUFLLEVBQUUsV0FBSSxFQUFFLGFBQU0sRUFBRSxhQUFNLENBQUMsRUFBN0IsY0FBNkIsRUFBN0IsSUFBNkI7Z0JBQTNDLElBQU0sSUFBSSxTQUFBO2dCQUNiLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO29CQUNqRCxJQUFJLE1BQUE7b0JBQ0osVUFBVSxFQUFFO3dCQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQzt3QkFDN0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO3FCQUM5QztpQkFDRixDQUFDLENBQUM7Z0JBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQzthQUMxQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1GQUFtRixFQUFFO1lBQ3RGLEdBQUcsQ0FBQyxDQUFlLFVBQTZCLEVBQTdCLE1BQUMsWUFBSyxFQUFFLFdBQUksRUFBRSxhQUFNLEVBQUUsYUFBTSxDQUFDLEVBQTdCLGNBQTZCLEVBQTdCLElBQTZCO2dCQUEzQyxJQUFNLElBQUksU0FBQTtnQkFDYixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztvQkFDakQsSUFBSSxNQUFBO29CQUNKLFVBQVUsRUFBRTt3QkFDVixHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQzt3QkFDbEUsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO3FCQUN6QztpQkFDRixDQUFDLENBQUM7Z0JBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQzthQUNoRDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhCQUE4QixFQUFFO1lBQ2pDLEdBQUcsQ0FBQyxDQUFlLFVBQTZCLEVBQTdCLE1BQUMsWUFBSyxFQUFFLFdBQUksRUFBRSxhQUFNLEVBQUUsYUFBTSxDQUFDLEVBQTdCLGNBQTZCLEVBQTdCLElBQTZCO2dCQUEzQyxJQUFNLElBQUksU0FBQTtnQkFDYixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztvQkFDakQsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFDO29CQUNoQyxVQUFVLEVBQUU7d0JBQ1YsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO3dCQUM3QyxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7cUJBQzlDO2lCQUNGLENBQUMsQ0FBQztnQkFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2FBQzFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsSUFBTSxVQUFVLEdBQUcsY0FBTyxDQUFDLHNCQUFlLEVBQUUsQ0FBQyxZQUFLLEVBQUUsV0FBSSxFQUFFLGFBQU0sRUFBRSxhQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzNFLEdBQUcsQ0FBQyxDQUFlLFVBQVUsRUFBVix5QkFBVSxFQUFWLHdCQUFVLEVBQVYsSUFBVTtnQkFBeEIsSUFBTSxJQUFJLG1CQUFBO2dCQUNiLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO29CQUNqRCxJQUFJLE1BQUE7b0JBQ0osVUFBVSxFQUFFO3dCQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQzt3QkFDN0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO3FCQUN6QztpQkFDRixDQUFDLENBQUM7Z0JBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQzthQUNoRDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsUUFBUSxFQUFFO1FBQ2pCLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztZQUMvRCxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDN0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO2lCQUM5QzthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDL0MsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsVUFBRyxDQUFDLENBQUMsQ0FBQztRQUMvRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRUosRUFBRSxDQUFDLDhDQUE4QyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBQyxXQUFXO1lBQ3RFLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsS0FBSztnQkFDYixRQUFRLEVBQUUsRUFBRTthQUNiLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDOUMsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsNEJBQTRCLENBQUMsVUFBRyxDQUFDLENBQUMsQ0FBQztRQUNwRixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRUosRUFBRSxDQUFDLDhEQUE4RCxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBQyxXQUFXO1lBQ3RGLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsS0FBSztnQkFDYixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO29CQUN4QyxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7aUJBQ3pDO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztZQUM5QyxhQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxVQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3BGLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFHSixFQUFFLENBQUMsK0NBQStDLEVBQUU7WUFDbEQsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxLQUFLO2dCQUNiLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7b0JBQzdDLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztpQkFDekM7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlEQUFpRCxFQUFFO1lBQ3BELElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsS0FBSztnQkFDYixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO29CQUM3QyxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7aUJBQ3pDO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyRUFBMkUsRUFBRTtZQUM5RSxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDN0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO2lCQUMxQzthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkVBQTZFLEVBQUU7WUFDaEYsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxLQUFLO2dCQUNiLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7b0JBQzdDLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztpQkFDMUM7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFO1lBQ25ELElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO29CQUM3QyxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7aUJBQ3pDO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5REFBeUQsRUFBRTtZQUM1RCxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDN0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUM7aUJBQzNEO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrRUFBK0UsRUFBRTtZQUNsRixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFDO29CQUN0RSxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7aUJBQ3pDO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDN0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO2lCQUN6QzthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxNQUFNO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDO2lCQUNsQjthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUU7WUFDckQsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxNQUFNO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDO2lCQUNsQjthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0RBQStELEVBQUU7WUFDbEUsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxNQUFNO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7b0JBQzNDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztpQkFDdkM7YUFDRixDQUFDLENBQUM7WUFFSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO1lBQ2hFLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO29CQUMzQyxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7aUJBQ3ZDO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyREFBMkQsRUFBRTtZQUM5RCxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDeEMsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO29CQUM3QyxJQUFJLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7aUJBQy9DO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRTtZQUNoRSxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDeEMsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO29CQUM3QyxJQUFJLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7aUJBQy9DO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0RUFBNEUsRUFBRTtZQUMvRSxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztnQkFDakQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztvQkFDN0MsSUFBSSxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDO2lCQUMvQzthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMEVBQTBFLEVBQUU7WUFDN0UsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxNQUFNO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7b0JBQzdDLElBQUksRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztpQkFDL0M7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlIHF1b3RlbWFyayAqL1xuXG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vc3JjL2xvZyc7XG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7QkFSLCBDSVJDTEUsIFBPSU5ULCBQUklNSVRJVkVfTUFSS1MsIFNRVUFSRSwgVElDS30gZnJvbSAnLi4vLi4vLi4vc3JjL21hcmsnO1xuaW1wb3J0IHt3aXRob3V0fSBmcm9tICcuLi8uLi8uLi9zcmMvdXRpbCc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdjb21waWxlL21hcmsvaW5pdCcsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnZGVmYXVsdE9wYWNpdHknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gMC43IGJ5IGRlZmF1bHQgZm9yIHVuYWdncmVnYXRlZCBwb2ludCwgdGljaywgY2lyY2xlLCBhbmQgc3F1YXJlJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBtYXJrIG9mIFtQT0lOVCwgVElDSywgQ0lSQ0xFLCBTUVVBUkVdKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgICBtYXJrLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ5XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImZvb1wifSxcbiAgICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJiYXJcIn1cbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3BhY2l0eSwgMC43KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBieSBkZWZhdWx0IGZvciBhZ2dyZWdhdGVkIHBvaW50LCB0aWNrLCBjaXJjbGUsIGFuZCBzcXVhcmUnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG1hcmsgb2YgW1BPSU5ULCBUSUNLLCBDSVJDTEUsIFNRVUFSRV0pIHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICAgIG1hcmssXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImZvb1wifSxcbiAgICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwibm9taW5hbFwiLCBcImZpZWxkXCI6IFwiYmFyXCJ9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5tYXJrRGVmLm9wYWNpdHksIHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBzcGVjaWZpZWQgb3BhY2l0eScsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgbWFyayBvZiBbUE9JTlQsIFRJQ0ssIENJUkNMRSwgU1FVQVJFXSkge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgICAgbWFyazoge3R5cGU6IG1hcmssIG9wYWNpdHk6IDAuOX0sXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiZm9vXCJ9LFxuICAgICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhclwifVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcGFjaXR5LCAwLjkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdW5kZWZpbmVkIGJ5IGRlZmF1bHQgZm9yIG90aGVyIG1hcmtzJywgKCkgPT4ge1xuICAgICAgY29uc3Qgb3RoZXJNYXJrcyA9IHdpdGhvdXQoUFJJTUlUSVZFX01BUktTLCBbUE9JTlQsIFRJQ0ssIENJUkNMRSwgU1FVQVJFXSk7XG4gICAgICBmb3IgKGNvbnN0IG1hcmsgb2Ygb3RoZXJNYXJrcykge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgICAgbWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJmb29cIn0sXG4gICAgICAgICAgICBcInhcIjoge1widHlwZVwiOiBcIm5vbWluYWxcIiwgXCJmaWVsZFwiOiBcImJhclwifVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcGFjaXR5LCB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnb3JpZW50JywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBkZWZhdWx0IGZvciBReFEnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJmb29cIn0sXG4gICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhclwifVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICd2ZXJ0aWNhbCcpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS51bmNsZWFyT3JpZW50Q29udGludW91cyhCQVIpKTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IGRlZmF1bHQgZm9yIGVtcHR5IHBsb3QnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgIGVuY29kaW5nOiB7fVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLnVuY2xlYXJPcmllbnREaXNjcmV0ZU9yRW1wdHkoQkFSKSk7XG4gICAgfSkpO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIGJhciB3aXRoIGJvdGggYXhlcyBkaXNjcmV0ZScsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJvcmRpbmFsXCIsIFwiZmllbGRcIjogXCJmb29cIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcInR5cGVcIjogXCJvcmRpbmFsXCIsIFwiZmllbGRcIjogXCJiYXJcIn1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS51bmNsZWFyT3JpZW50RGlzY3JldGVPckVtcHR5KEJBUikpO1xuICAgIH0pKTtcblxuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIHZlcnRpY2FsIGJhcicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ5XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImZvb1wifSxcbiAgICAgICAgICBcInhcIjoge1widHlwZVwiOiBcIm9yZGluYWxcIiwgXCJmaWVsZFwiOiBcImJhclwifVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICd2ZXJ0aWNhbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIGhvcml6b250YWwgYmFyJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiZm9vXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiYmFyXCJ9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5tYXJrRGVmLm9yaWVudCwgJ2hvcml6b250YWwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3Qgb3JpZW50IGZvciB2ZXJ0aWNhbCBiYXIgd2l0aCByYXcgdGVtcG9yYWwgZGltZW5zaW9uJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiZm9vXCJ9LFxuICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwidGVtcG9yYWxcIiwgXCJmaWVsZFwiOiBcImJhclwifVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICd2ZXJ0aWNhbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIGhvcml6b250YWwgYmFyIHdpdGggcmF3IHRlbXBvcmFsIGRpbWVuc2lvbicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImZvb1wifSxcbiAgICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInRlbXBvcmFsXCIsIFwiZmllbGRcIjogXCJiYXJcIn1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCAnaG9yaXpvbnRhbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIHZlcnRpY2FsIHRpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwidGlja1wiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiZm9vXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiYmFyXCJ9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5tYXJrRGVmLm9yaWVudCwgJ3ZlcnRpY2FsJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IG9yaWVudCBmb3IgdmVydGljYWwgdGljayB3aXRoIGJpbicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJ0aWNrXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJmb29cIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhclwiLCBcImJpblwiOiB0cnVlfVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICd2ZXJ0aWNhbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIHZlcnRpY2FsIHRpY2sgb2YgY29udGludW91cyB0aW1lVW5pdCBkb3RwbG90JywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInRpY2tcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJ0ZW1wb3JhbFwiLCBcImZpZWxkXCI6IFwiZm9vXCIsIFwidGltZVVuaXRcIjogXCJ5ZWFybW9udGhkYXRlXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiYmFyXCJ9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5tYXJrRGVmLm9yaWVudCwgJ3ZlcnRpY2FsJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IG9yaWVudCBmb3IgaG9yaXpvbnRhbCB0aWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInRpY2tcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ5XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImZvb1wifSxcbiAgICAgICAgICBcInhcIjoge1widHlwZVwiOiBcIm9yZGluYWxcIiwgXCJmaWVsZFwiOiBcImJhclwifVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICdob3Jpem9udGFsJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IG9yaWVudCBmb3IgdmVydGljYWwgcnVsZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJ2YWx1ZVwiOiAwfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCAndmVydGljYWwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3Qgb3JpZW50IGZvciBob3Jpem9udGFsIHJ1bGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInlcIjoge1widmFsdWVcIjogMH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5tYXJrRGVmLm9yaWVudCwgJ2hvcml6b250YWwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3Qgb3JpZW50IGZvciBob3Jpem9udGFsIHJ1bGVzIHdpdGhvdXQgeDIgJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5tYXJrRGVmLm9yaWVudCwgJ2hvcml6b250YWwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3Qgb3JpZW50IGZvciB2ZXJ0aWNhbCBydWxlcyB3aXRob3V0IHkyICcsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICd2ZXJ0aWNhbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIHZlcnRpY2FsIHJ1bGUgd2l0aCByYW5nZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiZm9vXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJiYXJcIn0sXG4gICAgICAgICAgXCJ5MlwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJiYXpcIn1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCAndmVydGljYWwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3Qgb3JpZW50IGZvciBob3Jpem9udGFsIHJ1bGUgd2l0aCByYW5nZScsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieVwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiZm9vXCJ9LFxuICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJiYXJcIn0sXG4gICAgICAgICAgXCJ4MlwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJiYXpcIn1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCAnaG9yaXpvbnRhbCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBvcmllbnQgZm9yIGhvcml6b250YWwgcnVsZSB3aXRoIHJhbmdlIGFuZCBubyBvcmRpbmFsJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhclwifSxcbiAgICAgICAgICBcIngyXCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhelwifVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICdob3Jpem9udGFsJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IG9yaWVudCBmb3IgdmVydGljYWwgcnVsZSB3aXRoIHJhbmdlIGFuZCBubyBvcmRpbmFsJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ5XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhclwifSxcbiAgICAgICAgICBcInkyXCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcImJhelwifVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwubWFya0RlZi5vcmllbnQsICd2ZXJ0aWNhbCcpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5cbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/mark/line.test.js b/build/test/compile/mark/line.test.js new file mode 100644 index 0000000000..efe075c084 --- /dev/null +++ b/build/test/compile/mark/line.test.js @@ -0,0 +1,140 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var log = require("../../../src/log"); +var channel_1 = require("../../../src/channel"); +var line_1 = require("../../../src/compile/mark/line"); +var mark_1 = require("../../../src/mark"); +describe('Mark: Line', function () { + describe('with x, y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative" } + } + }); + var props = line_1.line.encodeEntry(model); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year' }); + }); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'yield' }); + }); + }); + describe('with x, y, color', function () { + var model = util_1.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_1.line.encodeEntry(model); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'Acceleration' }); + }); + }); + describe('with x, y, size', function () { + it('should have scale for size', function () { + var model = util_1.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_1.line.encodeEntry(model); + chai_1.assert.deepEqual(props.strokeWidth, { scale: 'size', field: 'variety' }); + }); + it('should drop aggregate size field', log.wrap(function (localLogger) { + var model = util_1.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_1.line.encodeEntry(model); + // If size field is dropped, then strokeWidth only have value + chai_1.assert.isNotOk(props.strokeWidth && props.strokeWidth['scale']); + chai_1.assert.equal(localLogger.warns[0], log.message.incompatibleChannel(channel_1.SIZE, mark_1.LINE, 'when the field is aggregated.')); + })); + }); + describe('with stacked y', function () { + var model = util_1.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_1.line.encodeEntry(model); + it('should use y_end', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'sum_yield_end' }); + }); + }); + describe('with stacked x', function () { + var model = util_1.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_1.line.encodeEntry(model); + it('should use x_end', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'sum_yield_end' }); + }); + }); + describe('with x', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "line", + "encoding": { "x": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = line_1.line.encodeEntry(model); + it('should be centered on y', function () { + chai_1.assert.deepEqual(props.y, { + mult: 0.5, + signal: 'height' + }); + }); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year' }); + }); + }); + describe('with y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "line", + "encoding": { "y": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = line_1.line.encodeEntry(model); + it('should be centered on x', function () { + chai_1.assert.deepEqual(props.x, { + mult: 0.5, + signal: 'width' + }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'year' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvbGluZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBZ0U7QUFFaEUsc0NBQXdDO0FBRXhDLGdEQUF1RDtBQUN2RCx1REFBb0Q7QUFDcEQsMENBQXVDO0FBRXZDLFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFFckIsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7WUFDbkMsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO2dCQUN6QyxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7YUFDaEQ7U0FDRixDQUFDLENBQUM7UUFDSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlCQUF5QixFQUFFO1lBQzVCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMs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LENBQUMsbUJBQW1CLEVBQUU7WUFDdEIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQztRQUN2RCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFFBQVEsRUFBRTtRQUNqQixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQyxFQUFDO1lBQ3ZELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztTQUNwQyxDQUFDLENBQUM7UUFFSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ3hCLElBQUksRUFBRSxHQUFHO2dCQUNULE1BQU0sRUFBRSxPQUFPO2FBQ2hCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1CQUFtQixFQUFFO1lBQ3RCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uLy4uL3NyYy9sb2cnO1xuXG5pbXBvcnQge0NPTE9SLCBTSVpFLCBYLCBZfSBmcm9tICcuLi8uLi8uLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge2xpbmV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvbGluZSc7XG5pbXBvcnQge0xJTkV9IGZyb20gJy4uLy4uLy4uL3NyYy9tYXJrJztcblxuZGVzY3JpYmUoJ01hcms6IExpbmUnLCBmdW5jdGlvbigpIHtcblxuICBkZXNjcmliZSgnd2l0aCB4LCB5JywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwieWVhclwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGxpbmUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciB4JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogWCwgZmllbGQ6ICd5ZWFyJ30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciB5JywgZnVuY3Rpb24oKXtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiBZLCBmaWVsZDogJ3lpZWxkJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB4LCB5LCBjb2xvcicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJ5ZWFyXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIkFjY2VsZXJhdGlvblwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGxpbmUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciBjb2xvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuc3Ryb2tlLCB7c2NhbGU6IENPTE9SLCBmaWVsZDogJ0FjY2VsZXJhdGlvbid9KTtcbiAgICB9KTtcbiAgfSk7XG5cblxuICBkZXNjcmliZSgnd2l0aCB4LCB5LCBzaXplJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgaGF2ZSBzY2FsZSBmb3Igc2l6ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwieWVhclwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJvcHMgPSBsaW5lLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5zdHJva2VXaWR0aCwge3NjYWxlOiAnc2l6ZScsIGZpZWxkOiAndmFyaWV0eSd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZHJvcCBhZ2dyZWdhdGUgc2l6ZSBmaWVsZCcsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJ5ZWFyXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwieWllbGRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYWdncmVnYXRlXCI6IFwibWVhblwifSxcbiAgICAgICAgICBcInNpemVcIjoge1wiZmllbGRcIjogXCJBY2NlbGVyYXRpb25cIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYWdncmVnYXRlXCI6IFwibWVhblwifVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHByb3BzID0gbGluZS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICAgIC8vIElmIHNpemUgZmllbGQgaXMgZHJvcHBlZCwgdGhlbiBzdHJva2VXaWR0aCBvbmx5IGhhdmUgdmFsdWVcbiAgICAgIGFzc2VydC5pc05vdE9rKHByb3BzLnN0cm9rZVdpZHRoICYmIHByb3BzLnN0cm9rZVdpZHRoWydzY2FsZSddKTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuaW5jb21wYXRpYmxlQ2hhbm5lbChTSVpFLCBMSU5FLCAnd2hlbiB0aGUgZmllbGQgaXMgYWdncmVnYXRlZC4nKSk7XG4gICAgfSkpO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCBzdGFja2VkIHknLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJ5ZWFyXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcInN1bVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgfSxcbiAgICAgIFwiY29uZmlnXCI6IHtcInN0YWNrXCI6ICBcInplcm9cIn1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IGxpbmUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgeV9lbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiBZLCBmaWVsZDogJ3N1bV95aWVsZF9lbmQnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIHN0YWNrZWQgeCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2JhcmxleS5qc29uXCJ9LFxuICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInllYXJcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwieWllbGRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYWdncmVnYXRlXCI6IFwic3VtXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICB9LFxuICAgICAgXCJjb25maWdcIjoge1wic3RhY2tcIjogIFwiemVyb1wifVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gbGluZS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSB4X2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6IFgsIGZpZWxkOiAnc3VtX3lpZWxkX2VuZCd9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggeCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1wieFwiOiB7XCJmaWVsZFwiOiBcInllYXJcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifX0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBsaW5lLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgYmUgY2VudGVyZWQgb24geScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7XG4gICAgICAgIG11bHQ6IDAuNSxcbiAgICAgICAgc2lnbmFsOiAnaGVpZ2h0J1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNjYWxlIG9uIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ3llYXInfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIHknLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcInlcIjoge1wiZmllbGRcIjogXCJ5ZWFyXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn19LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gbGluZS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGNlbnRlcmVkIG9uIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge1xuICAgICAgICBtdWx0OiAwLjUsXG4gICAgICAgIHNpZ25hbDogJ3dpZHRoJ1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNjYWxlIG9uIHknLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiBZLCBmaWVsZDogJ3llYXInfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/mark/mark.test.js b/build/test/compile/mark/mark.test.js new file mode 100644 index 0000000000..b00da7b1fe --- /dev/null +++ b/build/test/compile/mark/mark.test.js @@ -0,0 +1,218 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var mark_1 = require("../../../src/compile/mark/mark"); +var util_1 = require("../../util"); +describe('Mark', function () { + describe('parseMarkGroup', function () { + // PATH + describe('Multi-series Line', function () { + it('should have a facet directive and a nested mark group that uses the faceted data.', function () { + var model = util_1.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" } + } + }); + var markGroup = mark_1.parseMarkGroup(model)[0]; + chai_1.assert.equal(markGroup.name, 'pathgroup'); + chai_1.assert.deepEqual(markGroup.from, { + facet: { + name: 'faceted_path_main', + data: 'main', + groupby: ['symbol'] + } + }); + var submarkGroup = markGroup.marks[0]; + chai_1.assert.equal(submarkGroup.name, 'marks'); + chai_1.assert.equal(submarkGroup.type, 'line'); + chai_1.assert.deepEqual(submarkGroup.style, ['line', 'trend']); + chai_1.assert.equal(submarkGroup.from.data, 'faceted_path_main'); + }); + }); + describe('Single Line', function () { + it('should have a facet directive and a nested mark group', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal", "axis": { "format": "%Y" } }, + "y": { "field": "price", "type": "quantitative" } + } + }); + var markGroup = mark_1.parseMarkGroup(model)[0]; + chai_1.assert.equal(markGroup.name, 'marks'); + chai_1.assert.equal(markGroup.type, 'line'); + chai_1.assert.equal(markGroup.from.data, 'main'); + }); + }); + // NON-PATH + describe('Aggregated Bar with a color with binned x', function () { + it(' should use main stacked data source', function () { + var model = util_1.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" } + } + }); + var markGroup = mark_1.parseMarkGroup(model); + chai_1.assert.equal(markGroup[0].from.data, 'main'); + chai_1.assert.equal(markGroup[0].style, 'bar'); + }); + }); + describe('Faceted aggregated Bar with a color with binned x', function () { + it('should use faceted data source', function () { + var model = util_1.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" } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + var markGroup = mark_1.parseMarkGroup(model.child); + chai_1.assert.equal(markGroup[0].from.data, 'child_main'); + }); + }); + describe('Aggregated bar', function () { + it('should use main aggregated data source', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" } + } + }); + var markGroup = mark_1.parseMarkGroup(model); + chai_1.assert.equal(markGroup[0].from.data, 'main'); + }); + }); + describe('Bar with tooltip', function () { + it('should pass tooltip value to encoding', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" }, + "tooltip": { "value": "foo" } + } + }); + var markGroup = mark_1.parseMarkGroup(model); + chai_1.assert.equal(markGroup[0].encode.update.tooltip.value, 'foo'); + }); + }); + }); + describe('getPathSort', function () { + describe('compileUnit', function () { + it('should order by order field for line with order (connected scatterplot)', function () { + var model = util_1.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" } + } + }); + chai_1.assert.deepEqual(mark_1.getPathSort(model), { + field: ['datum[\"year\"]'], + order: ['ascending'] + }); + }); + it('should order by x by default if x is the dimension', function () { + var model = util_1.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" + } + } + }); + chai_1.assert.deepEqual(mark_1.getPathSort(model), { + field: 'datum[\"bin_maxbins_10_IMDB_Rating\"]', + order: 'descending' + }); + }); + it('should not order by a missing dimension', function () { + var model = util_1.parseUnitModelWithScale({ + "data": { "url": "data/movies.json" }, + "mark": "line", + "encoding": { + "color": { + "field": "Source", + "type": "nominal" + }, + "y": { + "aggregate": "count", + "type": "quantitative" + } + } + }); + chai_1.assert.deepEqual(mark_1.getPathSort(model), undefined); + }); + }); + }); + describe('pathGroupingFields', function () { + it('should return fields for unaggregate detail, color, size, opacity fieldDefs.', function () { + for (var _i = 0, _a = [channel_1.DETAIL, channel_1.COLOR, channel_1.SIZE, channel_1.OPACITY]; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert.deepEqual(mark_1.pathGroupingFields((_b = {}, _b[channel] = { field: 'a', type: 'nominal' }, _b)), ['a']); + } + var _b; + }); + it('should not return fields for unaggregate detail, color, size, opacity fieldDefs.', function () { + for (var _i = 0, _a = [channel_1.DETAIL, channel_1.COLOR, channel_1.SIZE, channel_1.OPACITY]; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert.deepEqual(mark_1.pathGroupingFields((_b = {}, _b[channel] = { aggregate: 'mean', field: 'a', type: 'nominal' }, _b)), []); + } + var _b; + }); + it('should return condition detail fields for color, size, shape', function () { + for (var _i = 0, _a = [channel_1.COLOR, channel_1.SIZE, channel_1.OPACITY]; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert.deepEqual(mark_1.pathGroupingFields((_b = {}, _b[channel] = { + condition: { selection: 'sel', field: 'a', type: 'nominal' } + }, _b)), ['a']); + } + var _b; + }); + it('should not return errors for all channels', function () { + var _loop_1 = function (channel) { + chai_1.assert.doesNotThrow(function () { + mark_1.pathGroupingFields((_a = {}, + _a[channel] = { field: 'a', type: 'nominal' }, + _a)); + var _a; + }); + }; + for (var _i = 0, UNIT_CHANNELS_1 = channel_1.UNIT_CHANNELS; _i < UNIT_CHANNELS_1.length; _i++) { + var channel = UNIT_CHANNELS_1[_i]; + _loop_1(channel); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyay50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvbWFyay50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixnREFBaUY7QUFDakYsdURBQStGO0FBRS9GLG1DQUEwSDtBQUUxSCxRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1FBQ3pCLE9BQU87UUFDUCxRQUFRLENBQUMsbUJBQW1CLEVBQUU7WUFDNUIsRUFBRSxDQUFDLG1GQUFtRixFQUFFO2dCQUN0RixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztvQkFDakQsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFDO29CQUMxQyxVQUFVLEVBQUU7d0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUMsRUFBQzt3QkFDcEUsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO3dCQUMvQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7cUJBQ2hEO2lCQUNGLENBQUMsQ0FBQztnQkFDSCxJQUFNLFNBQVMsR0FBRyxxQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMzQyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7Z0JBQzFDLGFBQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTtvQkFDL0IsS0FBSyxFQUFFO3dCQUNMLElBQUksRUFBRSxtQkFBbUI7d0JBQ3pCLElBQUks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QUMsQ0FBa0IsVUFBYSxFQUFiLGtCQUFBLHVCQUFhLEVBQWIsMkJBQWEsRUFBYixJQUFhO2dCQUE5QixJQUFNLE9BQU8sc0JBQUE7d0JBQVAsT0FBTzthQVFqQjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge0NPTE9SLCBERVRBSUwsIE9QQUNJVFksIFNJWkUsIFVOSVRfQ0hBTk5FTFN9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7Z2V0UGF0aFNvcnQsIHBhcnNlTWFya0dyb3VwLCBwYXRoR3JvdXBpbmdGaWVsZHN9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvbWFyayc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvdW5pdCc7XG5pbXBvcnQge3BhcnNlRmFjZXRNb2RlbCwgcGFyc2VVbml0TW9kZWwsIHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlLCBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemV9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnTWFyaycsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgncGFyc2VNYXJrR3JvdXAnLCBmdW5jdGlvbigpIHtcbiAgICAvLyBQQVRIXG4gICAgZGVzY3JpYmUoJ011bHRpLXNlcmllcyBMaW5lJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYXZlIGEgZmFjZXQgZGlyZWN0aXZlIGFuZCBhIG5lc3RlZCBtYXJrIGdyb3VwIHRoYXQgdXNlcyB0aGUgZmFjZXRlZCBkYXRhLicsICgpID0+IHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICAgIFwibWFya1wiOiB7XCJ0eXBlXCI6IFwibGluZVwiLCBcInN0eWxlXCI6IFwidHJlbmRcIn0sXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCIsIFwiYXhpc1wiOiB7XCJmb3JtYXRcIjogXCIlWVwifX0sXG4gICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic3ltYm9sXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBtYXJrR3JvdXAgPSBwYXJzZU1hcmtHcm91cChtb2RlbClbMF07XG4gICAgICAgIGFzc2VydC5lcXVhbChtYXJrR3JvdXAubmFtZSwgJ3BhdGhncm91cCcpO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKG1hcmtHcm91cC5mcm9tLCB7XG4gICAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICAgIG5hbWU6ICdmYWNldGVkX3BhdGhfbWFpbicsXG4gICAgICAgICAgICBkYXRhOiAnbWFpbicsXG4gICAgICAgICAgICBncm91cGJ5OiBbJ3N5bWJvbCddXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgc3VibWFya0dyb3VwID0gbWFya0dyb3VwLm1hcmtzWzBdO1xuICAgICAgICBhc3NlcnQuZXF1YWwoc3VibWFya0dyb3VwLm5hbWUsICdtYXJrcycpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoc3VibWFya0dyb3VwLnR5cGUsICdsaW5lJyk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc3VibWFya0dyb3VwLnN0eWxlLCBbJ2xpbmUnLCAndHJlbmQnXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzdWJtYXJrR3JvdXAuZnJvbS5kYXRhLCAnZmFjZXRlZF9wYXRoX21haW4nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1NpbmdsZSBMaW5lJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYXZlIGEgZmFjZXQgZGlyZWN0aXZlIGFuZCBhIG5lc3RlZCBtYXJrIGdyb3VwJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwiLCBcImF4aXNcIjoge1wiZm9ybWF0XCI6IFwiJVlcIn19LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbWFya0dyb3VwID0gcGFyc2VNYXJrR3JvdXAobW9kZWwpWzBdO1xuICAgICAgICBhc3NlcnQuZXF1YWwobWFya0dyb3VwLm5hbWUsICdtYXJrcycpO1xuICAgICAgICBhc3NlcnQuZXF1YWwobWFya0dyb3VwLnR5cGUsICdsaW5lJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChtYXJrR3JvdXAuZnJvbS5kYXRhLCAnbWFpbicpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBOT04tUEFUSFxuICAgIGRlc2NyaWJlKCdBZ2dyZWdhdGVkIEJhciB3aXRoIGEgY29sb3Igd2l0aCBiaW5uZWQgeCcsICgpID0+IHtcbiAgICAgIGl0KCcgc2hvdWxkIHVzZSBtYWluIHN0YWNrZWQgZGF0YSBzb3VyY2UnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJDb3N0X19PdGhlclwiLCBcImFnZ3JlZ2F0ZVwiOiBcInN1bVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJDb3N0X19Ub3RhbF8kXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiRWZmZWN0X19BbW91bnRfb2ZfZGFtYWdlXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbWFya0dyb3VwID0gcGFyc2VNYXJrR3JvdXAobW9kZWwpO1xuICAgICAgICBhc3NlcnQuZXF1YWwobWFya0dyb3VwWzBdLmZyb20uZGF0YSwgJ21haW4nKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG1hcmtHcm91cFswXS5zdHlsZSwgJ2JhcicpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnRmFjZXRlZCBhZ2dyZWdhdGVkIEJhciB3aXRoIGEgY29sb3Igd2l0aCBiaW5uZWQgeCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgdXNlIGZhY2V0ZWQgZGF0YSBzb3VyY2UnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHtcbiAgICAgICAgICBmYWNldDoge1xuICAgICAgICAgICAgcm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ25vbWluYWwnfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3BlYzoge1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJmaWVsZFwiOiBcIkNvc3RfX090aGVyXCIsIFwiYWdncmVnYXRlXCI6IFwic3VtXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiQ29zdF9fVG90YWxfJFwifSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJ0eXBlXCI6IFwib3JkaW5hbFwiLCBcImZpZWxkXCI6IFwiRWZmZWN0X19BbW91bnRfb2ZfZGFtYWdlXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICAgICAgICBtb2RlbC5wYXJzZUxheW91dFNpemUoKTtcblxuICAgICAgICBjb25zdCBtYXJrR3JvdXAgPSBwYXJzZU1hcmtHcm91cChtb2RlbC5jaGlsZCBhcyBVbml0TW9kZWwpO1xuICAgICAgICBhc3NlcnQuZXF1YWwobWFya0dyb3VwWzBdLmZyb20uZGF0YSwgJ2NoaWxkX21haW4nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0FnZ3JlZ2F0ZWQgYmFyJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCB1c2UgbWFpbiBhZ2dyZWdhdGVkIGRhdGEgc291cmNlJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiQ29zdF9fT3RoZXJcIiwgXCJhZ2dyZWdhdGVcIjogXCJzdW1cIn0sXG4gICAgICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6IFwiQ29zdF9fVG90YWxfJFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG1hcmtHcm91cCA9IHBhcnNlTWFya0dyb3VwKG1vZGVsKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG1hcmtHcm91cFswXS5mcm9tLmRhdGEsICdtYWluJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdCYXIgd2l0aCB0b29sdGlwJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBwYXNzIHRvb2x0aXAgdmFsdWUgdG8gZW5jb2RpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJDb3N0X19PdGhlclwiLCBcImFnZ3JlZ2F0ZVwiOiBcInN1bVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiZmllbGRcIjogXCJDb3N0X19Ub3RhbF8kXCJ9LFxuICAgICAgICAgICAgXCJ0b29sdGlwXCI6IHtcInZhbHVlXCI6IFwiZm9vXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbWFya0dyb3VwID0gcGFyc2VNYXJrR3JvdXAobW9kZWwpO1xuICAgICAgICBhc3NlcnQuZXF1YWwobWFya0dyb3VwWzBdLmVuY29kZS51cGRhdGUudG9vbHRpcC52YWx1ZSwgJ2ZvbycpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRQYXRoU29ydCcsICgpID0+IHtcbiAgICBkZXNjcmliZSgnY29tcGlsZVVuaXQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGl0KCdzaG91bGQgb3JkZXIgYnkgb3JkZXIgZmllbGQgZm9yIGxpbmUgd2l0aCBvcmRlciAoY29ubmVjdGVkIHNjYXR0ZXJwbG90KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvZHJpdmluZy5qc29uXCJ9LFxuICAgICAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIm1pbGVzXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwic2NhbGVcIjoge1wiemVyb1wiOiBmYWxzZX19LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiZ2FzXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwic2NhbGVcIjoge1wiemVyb1wiOiBmYWxzZX19LFxuICAgICAgICAgICAgXCJvcmRlclwiOiB7XCJmaWVsZFwiOiBcInllYXJcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoZ2V0UGF0aFNvcnQobW9kZWwpLCB7XG4gICAgICAgICAgZmllbGQ6IFsnZGF0dW1bXFxcInllYXJcXFwiXSddLFxuICAgICAgICAgIG9yZGVyOiBbJ2FzY2VuZGluZyddXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgb3JkZXIgYnkgeCBieSBkZWZhdWx0IGlmIHggaXMgdGhlIGRpbWVuc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvbW92aWVzLmpzb25cIn0sXG4gICAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgXCJiaW5cIjoge1wibWF4Ymluc1wiOiAxMH0sXG4gICAgICAgICAgICAgIFwiZmllbGRcIjogXCJJTURCX1JhdGluZ1wiLFxuICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1xuICAgICAgICAgICAgICBcImZpZWxkXCI6IFwiU291cmNlXCIsXG4gICAgICAgICAgICAgIFwidHlwZVwiOiBcIm5vbWluYWxcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwiY291bnRcIixcbiAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKGdldFBhdGhTb3J0KG1vZGVsKSwge1xuICAgICAgICAgIGZpZWxkOiAnZGF0dW1bXFxcImJpbl9tYXhiaW5zXzEwX0lNREJfUmF0aW5nXFxcIl0nLFxuICAgICAgICAgIG9yZGVyOiAnZGVzY2VuZGluZydcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBub3Qgb3JkZXIgYnkgYSBtaXNzaW5nIGRpbWVuc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvbW92aWVzLmpzb25cIn0sXG4gICAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJjb2xvclwiOiB7XG4gICAgICAgICAgICAgIFwiZmllbGRcIjogXCJTb3VyY2VcIixcbiAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwibm9taW5hbFwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJjb3VudFwiLFxuICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoZ2V0UGF0aFNvcnQobW9kZWwpLCB1bmRlZmluZWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXRoR3JvdXBpbmdGaWVsZHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmllbGRzIGZvciB1bmFnZ3JlZ2F0ZSBkZXRhaWwsIGNvbG9yLCBzaXplLCBvcGFjaXR5IGZpZWxkRGVmcy4nLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgW0RFVEFJTCwgQ09MT1IsIFNJWkUsIE9QQUNJVFldKSB7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgcGF0aEdyb3VwaW5nRmllbGRzKHtbY2hhbm5lbF06IHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9fSksXG4gICAgICAgICAgWydhJ11cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHJldHVybiBmaWVsZHMgZm9yIHVuYWdncmVnYXRlIGRldGFpbCwgY29sb3IsIHNpemUsIG9wYWNpdHkgZmllbGREZWZzLicsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBbREVUQUlMLCBDT0xPUiwgU0laRSwgT1BBQ0lUWV0pIHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICBwYXRoR3JvdXBpbmdGaWVsZHMoe1tjaGFubmVsXToge2FnZ3JlZ2F0ZTogJ21lYW4nLCBmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9fSksXG4gICAgICAgICAgW11cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvbmRpdGlvbiBkZXRhaWwgZmllbGRzIGZvciBjb2xvciwgc2l6ZSwgc2hhcGUnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgW0NPTE9SLCBTSVpFLCBPUEFDSVRZXSkge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgIHBhdGhHcm91cGluZ0ZpZWxkcyh7W2NoYW5uZWxdOiB7XG4gICAgICAgICAgICBjb25kaXRpb246IHtzZWxlY3Rpb246ICdzZWwnLCBmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9XG4gICAgICAgICAgfX0pLFxuICAgICAgICAgIFsnYSddXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCByZXR1cm4gZXJyb3JzIGZvciBhbGwgY2hhbm5lbHMnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgVU5JVF9DSEFOTkVMUykge1xuICAgICAgICBhc3NlcnQuZG9lc05vdFRocm93KFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHBhdGhHcm91cGluZ0ZpZWxkcyh7XG4gICAgICAgICAgICAgIFtjaGFubmVsXToge2ZpZWxkOiAnYScsIHR5cGU6ICdub21pbmFsJ31cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/mark/mixins.test.js b/build/test/compile/mark/mixins.test.js new file mode 100644 index 0000000000..459f113aec --- /dev/null +++ b/build/test/compile/mark/mixins.test.js @@ -0,0 +1,50 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var mixins_1 = require("../../../src/compile/mark/mixins"); +var util_1 = require("../../util"); +describe('compile/mark/mixins', function () { + describe('color()', function () { + it('color should be mapped to fill for bar', function () { + var model = util_1.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 = mixins_1.color(model); + chai_1.assert.deepEqual(colorMixins.fill, { "field": "gender", "scale": "color" }); + }); + it('color should be mapped to stroke for point', function () { + var model = util_1.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 = mixins_1.color(model); + chai_1.assert.deepEqual(colorMixins.stroke, { "field": "gender", "scale": "color" }); + chai_1.assert.propertyVal(colorMixins.fill, 'value', "transparent"); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWl4aW5zLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbWFyay9taXhpbnMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsMkRBQXVEO0FBQ3ZELG1DQUFnRTtBQUVoRSxRQUFRLENBQUMscUJBQXFCLEVBQUU7SUFDOUIsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxLQUFLO2dCQUNiLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUU7d0JBQ0gsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUzt3QkFDcEMsT0FBTyxFQUFFLEVBQUMsV0FBVyxFQUFFLENBQUMsRUFBQzt3QkFDekIsTUFBTSxFQUFFLElBQUk7cUJBQ2I7b0JBQ0QsT0FBTyxFQUFFO3dCQUNQLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVM7d0JBQ3BDLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsRUFBQztxQkFDM0M7aUJBQ0Y7Z0JBQ0QsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLHNCQUFzQixFQUFDO2FBQ3hDLENBQUMsQ0FBQztZQUVILElBQU0sV0FBVyxHQUFHLGNBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqQyxhQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1lBQy9DLElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO2dCQUNqRCxNQUFNLEVBQUUsT0FBTztnQkFDZixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFO3dCQUNILE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVM7d0JBQ3BDLE9BQU8sRUFBRSxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUM7d0JBQ3pCLE1BQU0sRUFBRSxJQUFJO3FCQUNiO29CQUNELE9BQU8sRUFBRTt3QkFDUCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTO3dCQUNwQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUM7cUJBQzNDO2lCQUNGO2dCQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxzQkFBc0IsRUFBQzthQUN4QyxDQUFDLENBQUM7WUFFSCxJQUFNLFdBQVcsR0FBRyxjQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztZQUM1RSxhQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2NvbG9yfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL21peGlucyc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdjb21waWxlL21hcmsvbWl4aW5zJywgKCkgPT4ge1xuICBkZXNjcmliZSgnY29sb3IoKScsIGZ1bmN0aW9uKCkge1xuICAgIGl0KCdjb2xvciBzaG91bGQgYmUgbWFwcGVkIHRvIGZpbGwgZm9yIGJhcicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgICBcIm1hcmtcIjogXCJiYXJcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJnZW5kZXJcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwiLFxuICAgICAgICAgICAgXCJzY2FsZVwiOiB7XCJyYW5nZVN0ZXBcIjogNn0sXG4gICAgICAgICAgICBcImF4aXNcIjogbnVsbFxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb2xvclwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiZ2VuZGVyXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIixcbiAgICAgICAgICAgIFwic2NhbGVcIjoge1wicmFuZ2VcIjogW1wiI0VBOThEMlwiLCBcIiM2NTlDQ0FcIl19XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb2xvck1peGlucyA9IGNvbG9yKG1vZGVsKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoY29sb3JNaXhpbnMuZmlsbCwge1wiZmllbGRcIjogXCJnZW5kZXJcIiwgXCJzY2FsZVwiOiBcImNvbG9yXCJ9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjb2xvciBzaG91bGQgYmUgbWFwcGVkIHRvIHN0cm9rZSBmb3IgcG9pbnQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJnZW5kZXJcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwiLFxuICAgICAgICAgICAgXCJzY2FsZVwiOiB7XCJyYW5nZVN0ZXBcIjogNn0sXG4gICAgICAgICAgICBcImF4aXNcIjogbnVsbFxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb2xvclwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiZ2VuZGVyXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIixcbiAgICAgICAgICAgIFwic2NhbGVcIjoge1wicmFuZ2VcIjogW1wiI0VBOThEMlwiLCBcIiM2NTlDQ0FcIl19XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb2xvck1peGlucyA9IGNvbG9yKG1vZGVsKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoY29sb3JNaXhpbnMuc3Ryb2tlLCB7XCJmaWVsZFwiOiBcImdlbmRlclwiLCBcInNjYWxlXCI6IFwiY29sb3JcIn0pO1xuICAgICAgYXNzZXJ0LnByb3BlcnR5VmFsKGNvbG9yTWl4aW5zLmZpbGwsICd2YWx1ZScsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/mark/point.test.js b/build/test/compile/mark/point.test.js new file mode 100644 index 0000000000..5d8c553eab --- /dev/null +++ b/build/test/compile/mark/point.test.js @@ -0,0 +1,283 @@ +"use strict"; +/* tslint:disable quotemark */ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var point_1 = require("../../../src/compile/mark/point"); +var mark_1 = require("../../../src/mark"); +var util_1 = require("../../util"); +describe('Mark: Point', function () { + function pointXY(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "point", + "encoding": __assign({ "x": { "field": "year", "type": "ordinal" }, "y": { "field": "yield", "type": "quantitative" } }, moreEncoding), + "data": { "url": "data/barley.json" } + }; + } + describe('with x', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { "x": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = point_1.point.encodeEntry(model); + it('should be centered on y', function () { + chai_1.assert.deepEqual(props.y, { + mult: 0.5, + signal: 'height' + }); + }); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.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 = util_1.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_1.point.encodeEntry(model); + it('should use stack_end on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'sum_a_end' }); + }); + }); + describe('with y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { "y": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = point_1.point.encodeEntry(model); + it('should be centered on x', function () { + chai_1.assert.deepEqual(props.x, { + mult: 0.5, + signal: 'width' + }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.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 = util_1.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_1.point.encodeEntry(model); + it('should use stack_end on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'sum_a_end' }); + }); + }); + describe('with x and y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(pointXY()); + var props = point_1.point.encodeEntry(model); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year' }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'yield' }); + }); + it('should be an unfilled circle', function () { + chai_1.assert.deepEqual(props.fill, { value: 'transparent' }); + chai_1.assert.deepEqual(props.stroke, { value: mark_1.defaultMarkConfig.color }); + }); + }); + describe('with band x and quantitative y', function () { + it('should offset band position by half band', function () { + var model = util_1.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_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'year', band: 0.5 }); + }); + }); + describe('with x, y, size', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(pointXY({ + "size": { "aggregate": "count", "type": "quantitative" } + })); + var props = point_1.point.encodeEntry(model); + it('should have scale for size', function () { + chai_1.assert.deepEqual(props.size, { scale: channel_1.SIZE, field: 'count_*' }); + }); + }); + describe('with x, y, color', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(pointXY({ + "color": { "field": "yield", "type": "quantitative" } + })); + var props = point_1.point.encodeEntry(model); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'yield' }); + }); + }); + describe('with x, y, and condition-only color', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(__assign({}, pointXY({ + "color": { "condition": { "selection": "test", "field": "yield", "type": "quantitative" } } + }), { selection: { test: { type: 'single' } } })); + model.parseSelection(); + var props = point_1.point.encodeEntry(model); + it('should have one condition for color with scale for "yield"', function () { + chai_1.assert.isArray(props.stroke); + chai_1.assert.equal(props.stroke['length'], 1); + chai_1.assert.equal(props.stroke[0].scale, channel_1.COLOR); + chai_1.assert.equal(props.stroke[0].field, 'yield'); + }); + }); + describe('with x, y, shape', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(pointXY({ + "shape": { "field": "site", "type": "nominal" } + })); + var props = point_1.point.encodeEntry(model); + it('should have scale for shape', function () { + chai_1.assert.deepEqual(props.shape, { scale: channel_1.SHAPE, field: 'site' }); + }); + }); + describe('with constant color, shape, and size', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize(pointXY({ + "shape": { "value": "circle" }, + "color": { "value": "red" }, + "size": { "value": 23 } + })); + var props = point_1.point.encodeEntry(model); + it('should correct shape, color and size', function () { + chai_1.assert.deepEqual(props.shape, { value: "circle" }); + chai_1.assert.deepEqual(props.stroke, { value: "red" }); + chai_1.assert.deepEqual(props.size, { value: 23 }); + }); + }); + describe('with configs', function () { + it('should apply color from mark-specific config over general mark config', function () { + var model = util_1.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 = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.stroke, { value: "red" }); + }); + it('should apply stroke mark config over color mark config', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "mark": { "color": "red", "stroke": "blue" } } + }); + var props = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.stroke, { value: "blue" }); + }); + it('should apply stroke mark config over color mark config', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "point": { "color": "red", "stroke": "blue" } } + }); + var props = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.stroke, { value: "blue" }); + }); + }); +}); +describe('Mark: Square', function () { + it('should have correct shape', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = point_1.square.encodeEntry(model); + chai_1.assert.propertyVal(props.shape, 'value', 'square'); + }); + it('should be filled by default', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = point_1.square.encodeEntry(model); + chai_1.assert.propertyVal(props.fill, 'value', 'blue'); + }); + it('with config.mark.filled:false should have transparent fill', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + }, + "config": { + "mark": { + "filled": false + } + } + }); + var props = point_1.square.encodeEntry(model); + chai_1.assert.propertyVal(props.stroke, 'value', 'blue'); + chai_1.assert.propertyVal(props.fill, 'value', 'transparent'); + }); +}); +describe('Mark: Circle', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "circle", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = point_1.circle.encodeEntry(model); + it('should have correct shape', function () { + chai_1.assert.propertyVal(props.shape, 'value', 'circle'); + }); + it('should be filled by default', function () { + chai_1.assert.propertyVal(props.fill, 'value', 'blue'); + }); + it('with config.mark.filled:false should have transparent fill', function () { + var filledCircleModel = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "circle", + "encoding": { + "color": { "value": "blue" } + }, + "config": { + "mark": { + "filled": false + } + } + }); + var filledCircleProps = point_1.circle.encodeEntry(filledCircleModel); + chai_1.assert.propertyVal(filledCircleProps.stroke, 'value', 'blue'); + chai_1.assert.propertyVal(filledCircleProps.fill, 'value', 'transparent'); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9pbnQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9tYXJrL3BvaW50LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7Ozs7Ozs7OztBQUU5Qiw2QkFBNEI7QUFDNUIsZ0RBQThEO0FBQzlELHlEQUFzRTtBQUV0RSwwQ0FBb0Q7QUFFcEQsbUNBQWdFO0FBRWhFLFFBQVEsQ0FBQyxhQUFhLEVBQUU7SUFFdEIsaUJBQWlCLFlBQW1DO1FBQW5DLDZCQUFBLEVBQUEsaUJBQW1DO1FBQ2xELE1BQU0sQ0FBQztZQUNMLE1BQU0sRUFBRSxPQUFPO1lBQ2YsVUFBVSxhQUNOLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQyxFQUN6QyxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUMsSUFDNUMsWUFBWSxDQUNsQjtZQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztTQUNwQyxDQUFDO0lBQ0osQ0FBQztJQUVELFFBQVEsQ0FBQyxRQUFRLEVBQUU7UUFDakIsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7WUFDakQsTUFBTSxFQUFFLE9BQU87WUFDZixVQUFVLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUMsRUFBQztZQUN2RCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7U0FDcEMsQ0FBQyxDQUFDO1FBRUgsSUFBTSxLQUFLLEdBQUcsYUFBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV2QyxFQUFFLENBQUMseUJBQXlCLEVBQUU7WUFDNUIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUN4QixJQUFJLEVBQUUs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QUFNLGlCQUFpQixHQUFHLGNBQU0sQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUVoRSxhQUFNLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsYUFBTSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3JFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZSBxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtDT0xPUiwgU0hBUEUsIFNJWkUsIFgsIFl9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7Y2lyY2xlLCBwb2ludCwgc3F1YXJlfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL3BvaW50JztcbmltcG9ydCB7RW5jb2Rpbmd9IGZyb20gJy4uLy4uLy4uL3NyYy9lbmNvZGluZyc7XG5pbXBvcnQge2RlZmF1bHRNYXJrQ29uZmlnfSBmcm9tICcuLi8uLi8uLi9zcmMvbWFyayc7XG5pbXBvcnQge1VuaXRTcGVjfSBmcm9tICcuLi8uLi8uLi9zcmMvc3BlYyc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdNYXJrOiBQb2ludCcsIGZ1bmN0aW9uKCkge1xuXG4gIGZ1bmN0aW9uIHBvaW50WFkobW9yZUVuY29kaW5nOiBFbmNvZGluZzxzdHJpbmc+ID0ge30pOiBVbml0U3BlYyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJ5ZWFyXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwieWllbGRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIC4uLm1vcmVFbmNvZGluZyxcbiAgICAgIH0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifVxuICAgIH07XG4gIH1cblxuICBkZXNjcmliZSgnd2l0aCB4JywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1wieFwiOiB7XCJmaWVsZFwiOiBcInllYXJcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifX0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBwb2ludC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGNlbnRlcmVkIG9uIHknLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge1xuICAgICAgICBtdWx0OiAwLjUsXG4gICAgICAgIHNpZ25hbDogJ2hlaWdodCdcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzY2FsZSBvbiB4JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogWCwgZmllbGQ6ICd5ZWFyJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCBzdGFja2VkIHgnLCBmdW5jdGlvbigpIHtcbiAgICAvLyBUaGlzIGlzIGEgc2ltcGxpZmllZCBleGFtcGxlIGZvciBzdGFja2VkIHBvaW50LlxuICAgIC8vIEluIHJlYWxpdHkgdGhpcyB3aWxsIGJlIHVzZWQgYXMgc3RhY2tlZCdzIG92ZXJsYXllZCBtYXJrZXJcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9XG4gICAgICB9LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICBcImNvbmZpZ1wiOiB7XCJzdGFja1wiOiBcInplcm9cIn1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gcG9pbnQuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2Ugc3RhY2tfZW5kIG9uIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ3N1bV9hX2VuZCd9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggeScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcInlcIjoge1wiZmllbGRcIjogXCJ5ZWFyXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn19LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gcG9pbnQuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBjZW50ZXJlZCBvbiB4JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtcbiAgICAgICAgbXVsdDogMC41LFxuICAgICAgICBzaWduYWw6ICd3aWR0aCdcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzY2FsZSBvbiB5JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogWSwgZmllbGQ6ICd5ZWFyJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCBzdGFja2VkIHknLCBmdW5jdGlvbigpIHtcbiAgICAvLyBUaGlzIGlzIGEgc2ltcGxpZmllZCBleGFtcGxlIGZvciBzdGFja2VkIHBvaW50LlxuICAgIC8vIEluIHJlYWxpdHkgdGhpcyB3aWxsIGJlIHVzZWQgYXMgc3RhY2tlZCdzIG92ZXJsYXllZCBtYXJrZXJcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJwb2ludFwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9XG4gICAgICB9LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICBcImNvbmZpZ1wiOiB7XCJzdGFja1wiOiBcInplcm9cIn1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gcG9pbnQuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2Ugc3RhY2tfZW5kIG9uIHknLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiBZLCBmaWVsZDogJ3N1bV9hX2VuZCd9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggeCBhbmQgeScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHBvaW50WFkoKSk7XG4gICAgY29uc3QgcHJvcHMgPSBwb2ludC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIHNjYWxlIG9uIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ3llYXInfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNjYWxlIG9uIHknLCBmdW5jdGlvbigpe1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6IFksIGZpZWxkOiAneWllbGQnfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGFuIHVuZmlsbGVkIGNpcmNsZScsIGZ1bmN0aW9uKCl7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmZpbGwsIHt2YWx1ZTogJ3RyYW5zcGFyZW50J30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5zdHJva2UsIHt2YWx1ZTogZGVmYXVsdE1hcmtDb25maWcuY29sb3J9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggYmFuZCB4IGFuZCBxdWFudGl0YXRpdmUgeScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIG9mZnNldCBiYW5kIHBvc2l0aW9uIGJ5IGhhbGYgYmFuZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjp7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwieWVhclwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCIsIFwic2NhbGVcIjoge1widHlwZVwiOiBcImJhbmRcIn19LFxuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHByb3BzID0gcG9pbnQuZW5jb2RlRW50cnkobW9kZWwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICd5ZWFyJywgYmFuZDogMC41fSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIHgsIHksIHNpemUnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUocG9pbnRYWSh7XG4gICAgICBcInNpemVcIjoge1wiYWdncmVnYXRlXCI6IFwiY291bnRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgfSkpO1xuICAgIGNvbnN0IHByb3BzID0gcG9pbnQuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciBzaXplJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5zaXplLCB7c2NhbGU6IFNJWkUsIGZpZWxkOiAnY291bnRfKid9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggeCwgeSwgY29sb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUocG9pbnRYWSh7XG4gICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwieWllbGRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgfSkpO1xuICAgIGNvbnN0IHByb3BzID0gcG9pbnQuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHNjYWxlIGZvciBjb2xvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuc3Ryb2tlLCB7c2NhbGU6IENPTE9SLCBmaWVsZDogJ3lpZWxkJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB4LCB5LCBhbmQgY29uZGl0aW9uLW9ubHkgY29sb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgLi4ucG9pbnRYWSh7XG4gICAgICBcImNvbG9yXCI6IHtcImNvbmRpdGlvblwiOiB7XCJzZWxlY3Rpb25cIjogXCJ0ZXN0XCIsIFwiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn19XG4gICAgICB9KSxcbiAgICAgIHNlbGVjdGlvbjoge3Rlc3Q6IHt0eXBlOiAnc2luZ2xlJ319XG4gICAgfSk7XG4gICAgbW9kZWwucGFyc2VTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBwcm9wcyA9IHBvaW50LmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBvbmUgY29uZGl0aW9uIGZvciBjb2xvciB3aXRoIHNjYWxlIGZvciBcInlpZWxkXCInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuaXNBcnJheShwcm9wcy5zdHJva2UpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHByb3BzLnN0cm9rZVsnbGVuZ3RoJ10sIDEpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHByb3BzLnN0cm9rZVswXS5zY2FsZSwgQ09MT1IpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHByb3BzLnN0cm9rZVswXS5maWVsZCwgJ3lpZWxkJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIHgsIHksIHNoYXBlJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHBvaW50WFkoe1xuICAgICAgXCJzaGFwZVwiOiB7XCJmaWVsZFwiOiBcInNpdGVcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgIH0pKTtcbiAgICBjb25zdCBwcm9wcyA9IHBvaW50LmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBzY2FsZSBmb3Igc2hhcGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnNoYXBlLCB7c2NhbGU6IFNIQVBFLCBmaWVsZDogJ3NpdGUnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIGNvbnN0YW50IGNvbG9yLCBzaGFwZSwgYW5kIHNpemUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZShwb2ludFhZKHtcbiAgICAgIFwic2hhcGVcIjoge1widmFsdWVcIjogXCJjaXJjbGVcIn0sXG4gICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwicmVkXCJ9LFxuICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDIzfVxuICAgIH0pKTtcbiAgICBjb25zdCBwcm9wcyA9IHBvaW50LmVuY29kZUVudHJ5KG1vZGVsKTtcbiAgICBpdCgnc2hvdWxkIGNvcnJlY3Qgc2hhcGUsIGNvbG9yIGFuZCBzaXplJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5zaGFwZSwge3ZhbHVlOiBcImNpcmNsZVwifSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnN0cm9rZSwge3ZhbHVlOiBcInJlZFwifSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnNpemUsIHt2YWx1ZTogMjN9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggY29uZmlncycsIGZ1bmN0aW9uKCkge1xuICAgIGl0KCdzaG91bGQgYXBwbHkgY29sb3IgZnJvbSBtYXJrLXNwZWNpZmljIGNvbmZpZyBvdmVyIGdlbmVyYWwgbWFyayBjb25maWcnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcIm1hcmtcIjoge1wiY29sb3JcIjpcImJsdWVcIn0sIFwicG9pbnRcIjoge1wiY29sb3JcIjpcInJlZFwifX1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJvcHMgPSBwb2ludC5lbmNvZGVFbnRyeShtb2RlbCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnN0cm9rZSwge3ZhbHVlOiBcInJlZFwifSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFwcGx5IHN0cm9rZSBtYXJrIGNvbmZpZyBvdmVyIGNvbG9yIG1hcmsgY29uZmlnJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9LFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJtYXJrXCI6IHtcImNvbG9yXCI6XCJyZWRcIiwgXCJzdHJva2VcIjogXCJibHVlXCJ9fVxuICAgICAgfSk7XG4gICAgICBjb25zdCBwcm9wcyA9IHBvaW50LmVuY29kZUVudHJ5KG1vZGVsKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuc3Ryb2tlLCB7dmFsdWU6IFwiYmx1ZVwifSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFwcGx5IHN0cm9rZSBtYXJrIGNvbmZpZyBvdmVyIGNvbG9yIG1hcmsgY29uZmlnJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9LFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJwb2ludFwiOiB7XCJjb2xvclwiOlwicmVkXCIsIFwic3Ryb2tlXCI6IFwiYmx1ZVwifX1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJvcHMgPSBwb2ludC5lbmNvZGVFbnRyeShtb2RlbCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnN0cm9rZSwge3ZhbHVlOiBcImJsdWVcIn0pO1xuICAgIH0pO1xuXG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdNYXJrOiBTcXVhcmUnLCBmdW5jdGlvbigpIHtcbiAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3Qgc2hhcGUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJzcXVhcmVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwiYmx1ZVwifVxuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gc3F1YXJlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGFzc2VydC5wcm9wZXJ0eVZhbChwcm9wcy5zaGFwZSwgJ3ZhbHVlJywgJ3NxdWFyZScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGZpbGxlZCBieSBkZWZhdWx0JywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwic3F1YXJlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiOiBcImJsdWVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IHNxdWFyZS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBhc3NlcnQucHJvcGVydHlWYWwocHJvcHMuZmlsbCwgJ3ZhbHVlJywgJ2JsdWUnKTtcbiAgfSk7XG5cbiAgaXQoJ3dpdGggY29uZmlnLm1hcmsuZmlsbGVkOmZhbHNlIHNob3VsZCBoYXZlIHRyYW5zcGFyZW50IGZpbGwnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJzcXVhcmVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwiYmx1ZVwifVxuICAgICAgfSxcbiAgICAgIFwiY29uZmlnXCIgOiB7XG4gICAgICAgIFwibWFya1wiIDoge1xuICAgICAgICAgIFwiZmlsbGVkXCIgOiBmYWxzZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IHNxdWFyZS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBhc3NlcnQucHJvcGVydHlWYWwocHJvcHMuc3Ryb2tlLCAndmFsdWUnLCAnYmx1ZScpO1xuICAgIGFzc2VydC5wcm9wZXJ0eVZhbChwcm9wcy5maWxsLCAndmFsdWUnLCAndHJhbnNwYXJlbnQnKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ01hcms6IENpcmNsZScsIGZ1bmN0aW9uKCkge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgXCJtYXJrXCI6IFwiY2lyY2xlXCIsXG4gICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwiYmx1ZVwifVxuICAgIH1cbiAgfSk7XG4gIGNvbnN0IHByb3BzID0gY2lyY2xlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzaGFwZScsIGZ1bmN0aW9uKCkge1xuICAgIGFzc2VydC5wcm9wZXJ0eVZhbChwcm9wcy5zaGFwZSwgJ3ZhbHVlJywgJ2NpcmNsZScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGZpbGxlZCBieSBkZWZhdWx0JywgZnVuY3Rpb24oKSB7XG4gICAgYXNzZXJ0LnByb3BlcnR5VmFsKHByb3BzLmZpbGwsICd2YWx1ZScsICdibHVlJyk7XG4gIH0pO1xuXG4gIGl0KCd3aXRoIGNvbmZpZy5tYXJrLmZpbGxlZDpmYWxzZSBzaG91bGQgaGF2ZSB0cmFuc3BhcmVudCBmaWxsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgZmlsbGVkQ2lyY2xlTW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwiY2lyY2xlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiOiBcImJsdWVcIn1cbiAgICAgIH0sXG4gICAgICBcImNvbmZpZ1wiIDoge1xuICAgICAgICBcIm1hcmtcIiA6IHtcbiAgICAgICAgICBcImZpbGxlZFwiIDogZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZmlsbGVkQ2lyY2xlUHJvcHMgPSBjaXJjbGUuZW5jb2RlRW50cnkoZmlsbGVkQ2lyY2xlTW9kZWwpO1xuXG4gICAgYXNzZXJ0LnByb3BlcnR5VmFsKGZpbGxlZENpcmNsZVByb3BzLnN0cm9rZSwgJ3ZhbHVlJywgJ2JsdWUnKTtcbiAgICBhc3NlcnQucHJvcGVydHlWYWwoZmlsbGVkQ2lyY2xlUHJvcHMuZmlsbCwgJ3ZhbHVlJywgJ3RyYW5zcGFyZW50Jyk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/mark/rect.test.js b/build/test/compile/mark/rect.test.js new file mode 100644 index 0000000000..279ca958cc --- /dev/null +++ b/build/test/compile/mark/rect.test.js @@ -0,0 +1,139 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* tslint:disable quotemark */ +var chai_1 = require("chai"); +var rect_1 = require("../../../src/compile/mark/rect"); +var log = require("../../../src/log"); +var util_1 = require("../../util"); +describe('Mark: Rect', function () { + describe('simple vertical', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw bar, with y from zero to field value and x band', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('simple horizontal', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw bar from zero to field value and y band', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple horizontal with size field', function () { + var model = util_1.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_1.rect.encodeEntry(model); + log.wrap(function (localLogger) { + it('should draw bar from zero to field value and with band value for x/width', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + it('should throw warning', function () { + chai_1.assert.equal(localLogger.warns[0], log.message.cannotApplySizeToNonOrientedMark('rect')); + }); + }); + }); + describe('horizontal binned', function () { + var model = util_1.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_1.rect.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical binned', function () { + var model = util_1.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_1.rect.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end' }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple ranged', function () { + var model = util_1.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_1.rect.encodeEntry(model); + it('should draw rectange with x, x2, y, y2', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'min_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'max_Acceleration' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'min_Horsepower' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'max_Horsepower' }); + }); + }); + describe('simple heatmap', function () { + var model = util_1.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_1.rect.encodeEntry(model); + it('should draw rect with x and y bands', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Cylinders' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvcmVjdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOEJBQThCO0FBQzlCLDZCQUE0QjtBQUM1Qix1REFBb0Q7QUFDcEQsc0NBQXdDO0FBQ3hDLG1DQUFnRTtBQUVoRSxRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtRQUMxQixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUM7WUFDakMsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO2dCQUMzQyxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBQzthQUM1RTtTQUNGLENBQUMsQ0FBQztRQUNILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO1lBQ2hFLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7WUFDekQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQztZQUN4RCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxtQkFBbUIs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LEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDO1lBQ3pELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge3JlY3R9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvcmVjdCc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vc3JjL2xvZyc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdNYXJrOiBSZWN0JywgZnVuY3Rpb24oKSB7XG4gIGRlc2NyaWJlKCdzaW1wbGUgdmVydGljYWwnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwicmVjdFwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICBcInlcIjoge1widHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IHJlY3QuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBkcmF3IGJhciwgd2l0aCB5IGZyb20gemVybyB0byBmaWVsZCB2YWx1ZSBhbmQgeCBiYW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ09yaWdpbid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMud2lkdGgsIHtzY2FsZTogJ3gnLCBiYW5kOiB0cnVlfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ21lYW5fQWNjZWxlcmF0aW9uJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge3NjYWxlOiAneScsIHZhbHVlOiAwfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMuaGVpZ2h0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NpbXBsZSBob3Jpem9udGFsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcInJlY3RcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSByZWN0LmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZHJhdyBiYXIgZnJvbSB6ZXJvIHRvIGZpZWxkIHZhbHVlIGFuZCB5IGJhbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiAneScsIGZpZWxkOiAnT3JpZ2luJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5oZWlnaHQsIHtzY2FsZTogJ3knLCBiYW5kOiB0cnVlfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ21lYW5fQWNjZWxlcmF0aW9uJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIHZhbHVlOiAwfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMud2lkdGgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2ltcGxlIGhvcml6b250YWwgd2l0aCBzaXplIGZpZWxkJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcInJlY3RcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInNpemVcIjoge1wiYWdncmVnYXRlXCI6IFwibWVhblwiLCBcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IHJlY3QuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIGZyb20gemVybyB0byBmaWVsZCB2YWx1ZSBhbmQgd2l0aCBiYW5kIHZhbHVlIGZvciB4L3dpZHRoJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiAneScsIGZpZWxkOiAnT3JpZ2luJ30pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmhlaWdodCwge3NjYWxlOiAneScsIGJhbmQ6IHRydWV9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICdtZWFuX0FjY2VsZXJhdGlvbid9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIHZhbHVlOiAwfSk7XG4gICAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChwcm9wcy53aWR0aCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB3YXJuaW5nJywgKCk9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuY2Fubm90QXBwbHlTaXplVG9Ob25PcmllbnRlZE1hcmsoJ3JlY3QnKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hvcml6b250YWwgYmlubmVkJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcInJlY3RcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiYmluXCI6IHRydWUsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsIFwiZmllbGRcIjogJ0FjY2VsZXJhdGlvbicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gcmVjdC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGRyYXcgYmFyIHdpdGggeSBhbmQgeTInLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtzY2FsZTogJ3knLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ2Jpbl9tYXhiaW5zXzEwX0hvcnNlcG93ZXJfZW5kJ30pO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLmhlaWdodCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2ZXJ0aWNhbCBiaW5uZWQnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgICAgXCJtYXJrXCI6IFwicmVjdFwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJiaW5cIjogdHJ1ZSwgXCJmaWVsZFwiOiAnSG9yc2Vwb3dlcicsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSByZWN0LmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZHJhdyBiYXIgd2l0aCB4IGFuZCB4MicsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiAneCcsIGZpZWxkOiAnYmluX21heGJpbnNfMTBfSG9yc2Vwb3dlcid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiAneCcsIGZpZWxkOiAnYmluX21heGJpbnNfMTBfSG9yc2Vwb3dlcl9lbmQnfSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQocHJvcHMud2lkdGgpO1xuICAgIH0pO1xuICB9KTtcblxuXG4gIGRlc2NyaWJlKCdzaW1wbGUgcmFuZ2VkJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiAnZGF0YS9jYXJzLmpzb24nfSxcbiAgICAgIFwibWFya1wiOiBcInJlY3RcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwibWluXCIsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieTJcIjoge1wiYWdncmVnYXRlXCI6IFwibWF4XCIsIFwiZmllbGRcIjogJ0hvcnNlcG93ZXInLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtaW5cIiwgXCJmaWVsZFwiOiAnQWNjZWxlcmF0aW9uJywgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcIngyXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLCBcImZpZWxkXCI6ICdBY2NlbGVyYXRpb24nLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IHJlY3QuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBkcmF3IHJlY3RhbmdlIHdpdGggeCwgeDIsIHksIHkyJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogJ3gnLCBmaWVsZDogJ21pbl9BY2NlbGVyYXRpb24nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgZmllbGQ6ICdtYXhfQWNjZWxlcmF0aW9uJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICdtaW5fSG9yc2Vwb3dlcid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtzY2FsZTogJ3knLCBmaWVsZDogJ21heF9Ib3JzZXBvd2VyJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2ltcGxlIGhlYXRtYXAnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9jYXJzLmpzb25cIn0sXG4gICAgICBcIm1hcmtcIjogXCJyZWN0XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkN5bGluZGVyc1wiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIiwgXCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcHJvcHMgPSByZWN0LmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgZHJhdyByZWN0IHdpdGggeCBhbmQgeSBiYW5kcycsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICdDeWxpbmRlcnMnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLndpZHRoLCB7c2NhbGU6ICd4JywgYmFuZDogdHJ1ZX0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6ICd5JywgZmllbGQ6ICdPcmlnaW4nfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmhlaWdodCwge3NjYWxlOiAneScsIGJhbmQ6IHRydWV9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/mark/rule.test.js b/build/test/compile/mark/rule.test.js new file mode 100644 index 0000000000..12afdb850f --- /dev/null +++ b/build/test/compile/mark/rule.test.js @@ -0,0 +1,183 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var rule_1 = require("../../../src/compile/mark/rule"); +var util_1 = require("../../util"); +describe('Mark: Rule', function () { + describe('without encoding', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": {} + }); + var props = rule_1.rule.encodeEntry(model); + it('should not show anything', function () { + chai_1.assert.isUndefined(props.x); + chai_1.assert.isUndefined(props.y); + }); + }); + describe('with x-only', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { "x": { "field": "a", "type": "quantitative" } } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create vertical rule that fits height', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.y, { field: { group: 'height' } }); + chai_1.assert.deepEqual(props.y2, { value: 0 }); + }); + }); + describe('with y-only', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { "y": { "field": "a", "type": "quantitative" } } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rule that fits height', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + chai_1.assert.deepEqual(props.x, { value: 0 }); + chai_1.assert.deepEqual(props.x2, { field: { group: 'width' } }); + }); + }); + describe('with x and x2 only', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rule on the axis', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.x2, { scale: channel_1.X, field: 'a2' }); + chai_1.assert.deepEqual(props.y, { + mult: 0.5, + signal: 'height' + }); + }); + }); + describe('with y and y2 only', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "quantitative" }, + "y2": { "field": "a2", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rules on the axis', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + chai_1.assert.deepEqual(props.y2, { scale: channel_1.Y, field: 'a2' }); + chai_1.assert.deepEqual(props.x, { + mult: 0.5, + signal: 'width' + }); + }); + }); + describe('with x, x2, and y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rules', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.x2, { scale: channel_1.X, field: 'a2' }); + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'b' }); + }); + }); + describe('with y, y2, and x', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "quantitative" }, + "y2": { "field": "a2", "type": "quantitative" }, + "x": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create vertical rules', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + chai_1.assert.deepEqual(props.y2, { scale: channel_1.Y, field: 'a2' }); + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'b' }); + }); + }); + describe('with nominal x, quantitative y with no y2', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create vertical rule that emulates bar chart', function () { + chai_1.assert.equal(model.markDef.orient, 'vertical'); + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'b' }); + chai_1.assert.deepEqual(props.y2, { scale: channel_1.Y, value: 0 }); + }); + }); + describe('with nominal y, quantitative x with no y2', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "ordinal" }, + "x": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rule that emulates bar chart', function () { + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'b' }); + chai_1.assert.deepEqual(props.x2, { scale: channel_1.X, value: 0 }); + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + }); + }); + describe('horizontal stacked rule with color', function () { + var model = util_1.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_1.rule.encodeEntry(model); + it('should have the correct value for x, x2, and color', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'sum_b_end' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'sum_b_start' }); + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); + describe('vertical stacked rule with color', function () { + var model = util_1.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_1.rule.encodeEntry(model); + it('should have the correct value for y, y2, and color', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'sum_b_end' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'sum_b_start' }); + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvcnVsZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixnREFBaUQ7QUFDakQsdURBQW9EO0FBQ3BELG1DQUFnRTtBQUVoRSxRQUFRLENBQUMsWUFBWSxFQUFFO0lBRXJCLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRTtRQUMzQixJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFBRSxFQUFFO1NBQ2YsQ0FBQyxDQUFDO1FBRUgsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMsMEJBQTBCLEVBQUU7WUFDN0IsYUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUIsYUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxhQUFhLEVBQUU7UUFDdEIsSUFBTSxLQUFLLEdBQUcsMkNBQW9DLENBQUM7WUFDakQsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUMsRUFBQztTQUMxRCxDQUFDLENBQUM7UUFFSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBQyxFQUFFLEtBQUss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QUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQztZQUM1RCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUMsQ0FBQyxDQUFDO1lBQy9ELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxlQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7UUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7Q09MT1IsIFgsIFl9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7cnVsZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9ydWxlJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ01hcms6IFJ1bGUnLCBmdW5jdGlvbigpIHtcblxuICBkZXNjcmliZSgnd2l0aG91dCBlbmNvZGluZycsICgpID0+IHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHt9XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IHJ1bGUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBub3Qgc2hvdyBhbnl0aGluZycsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLngpO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHByb3BzLnkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB4LW9ubHknLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XCJ4XCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn19XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IHJ1bGUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgdmVydGljYWwgcnVsZSB0aGF0IGZpdHMgaGVpZ2h0JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogWCwgZmllbGQ6ICdhJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7ZmllbGQ6IHtncm91cDogJ2hlaWdodCd9fSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7dmFsdWU6IDB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggeS1vbmx5JywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1wieVwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9fVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBydWxlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGhvcml6b250YWwgcnVsZSB0aGF0IGZpdHMgaGVpZ2h0JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogWSwgZmllbGQ6ICdhJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7dmFsdWU6IDB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueDIsIHtmaWVsZDoge2dyb3VwOiAnd2lkdGgnfX0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB4IGFuZCB4MiBvbmx5JywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ4MlwiOiB7XCJmaWVsZFwiOiBcImEyXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBydWxlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGhvcml6b250YWwgcnVsZSBvbiB0aGUgYXhpcycsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6IFgsIGZpZWxkOiAnYSd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueDIsIHtzY2FsZTogWCwgZmllbGQ6ICdhMid9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge1xuICAgICAgICBtdWx0OiAwLjUsXG4gICAgICAgIHNpZ25hbDogJ2hlaWdodCdcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB5IGFuZCB5MiBvbmx5JywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ5MlwiOiB7XCJmaWVsZFwiOiBcImEyXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBydWxlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGhvcml6b250YWwgcnVsZXMgb24gdGhlIGF4aXMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiBZLCBmaWVsZDogJ2EnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6IFksIGZpZWxkOiAnYTInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtcbiAgICAgICAgbXVsdDogMC41LFxuICAgICAgICBzaWduYWw6ICd3aWR0aCdcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB4LCB4MiwgYW5kIHknLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcIngyXCI6IHtcImZpZWxkXCI6IFwiYTJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBydWxlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGhvcml6b250YWwgcnVsZXMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ2EnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6IFgsIGZpZWxkOiAnYTInfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogWSwgZmllbGQ6ICdiJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB5LCB5MiwgYW5kIHgnLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInkyXCI6IHtcImZpZWxkXCI6IFwiYTJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBydWxlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIHZlcnRpY2FsIHJ1bGVzJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogWSwgZmllbGQ6ICdhJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Miwge3NjYWxlOiBZLCBmaWVsZDogJ2EyJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6IFgsIGZpZWxkOiAnYid9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggbm9taW5hbCB4LCBxdWFudGl0YXRpdmUgeSB3aXRoIG5vIHkyJywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IHJ1bGUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgdmVydGljYWwgcnVsZSB0aGF0IGVtdWxhdGVzIGJhciBjaGFydCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCAndmVydGljYWwnKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6IFgsIGZpZWxkOiAnYSd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge3NjYWxlOiBZLCBmaWVsZDogJ2InfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnkyLCB7c2NhbGU6IFksIHZhbHVlOiAwfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIG5vbWluYWwgeSwgcXVhbnRpdGF0aXZlIHggd2l0aCBubyB5MicsICgpID0+IHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSBydWxlLmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGhvcml6b250YWwgcnVsZSB0aGF0IGVtdWxhdGVzIGJhciBjaGFydCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLm1hcmtEZWYub3JpZW50LCAnaG9yaXpvbnRhbCcpO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngsIHtzY2FsZTogWCwgZmllbGQ6ICdiJ30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Miwge3NjYWxlOiBYLCB2YWx1ZTogMH0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6IFksIGZpZWxkOiAnYSd9KTtcbiAgICB9KTtcbiAgfSk7XG5cblxuICBkZXNjcmliZSgnaG9yaXpvbnRhbCBzdGFja2VkIHJ1bGUgd2l0aCBjb2xvcicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICB9LFxuICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICBcInN0YWNrXCI6IFwiemVyb1wiXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IHJ1bGUuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIHRoZSBjb3JyZWN0IHZhbHVlIGZvciB4LCB4MiwgYW5kIGNvbG9yJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6ICd4JywgZmllbGQ6ICdzdW1fYl9lbmQnfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLngyLCB7c2NhbGU6ICd4JywgZmllbGQ6ICdzdW1fYl9zdGFydCd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuc3Ryb2tlLCB7c2NhbGU6IENPTE9SLCBmaWVsZDogJ09yaWdpbid9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZlcnRpY2FsIHN0YWNrZWQgcnVsZSB3aXRoIGNvbG9yJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImJcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgIH0sXG4gICAgICBcImNvbmZpZ1wiOiB7XG4gICAgICAgIFwic3RhY2tcIjogXCJ6ZXJvXCJcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gcnVsZS5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgdGhlIGNvcnJlY3QgdmFsdWUgZm9yIHksIHkyLCBhbmQgY29sb3InLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogJ3knLCBmaWVsZDogJ3N1bV9iX2VuZCd9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueTIsIHtzY2FsZTogJ3knLCBmaWVsZDogJ3N1bV9iX3N0YXJ0J30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5zdHJva2UsIHtzY2FsZTogQ09MT1IsIGZpZWxkOiAnT3JpZ2luJ30pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/mark/text.test.js b/build/test/compile/mark/text.test.js new file mode 100644 index 0000000000..2d60e8fd99 --- /dev/null +++ b/build/test/compile/mark/text.test.js @@ -0,0 +1,151 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var text_1 = require("../../../src/compile/mark/text"); +var util_1 = require("../../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 = util_1.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_1.text.encodeEntry(model); + it('should use stack_end on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.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 = util_1.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_1.text.encodeEntry(model); + it('should use stack_end on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize(spec); + var props = text_1.text.encodeEntry(model); + it('should use number template', function () { + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize(spec); + var props = text_1.text.encodeEntry(model); + it('should output correct bin range', function () { + chai_1.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 = util_1.parseUnitModelWithScaleAndLayoutSize(spec); + var props = text_1.text.encodeEntry(model); + it('should use date template', function () { + chai_1.assert.deepEqual(props.text, { signal: "timeFormat(datum[\"foo\"], '%b %d, %Y')" }); + }); + }); + 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 = util_1.parseUnitModelWithScaleAndLayoutSize(spec); + var props = text_1.text.encodeEntry(model); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'Acceleration' }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'Displacement' }); + }); + it('should be centered', function () { + chai_1.assert.deepEqual(props.align, { value: "center" }); + }); + it('should map text without template', function () { + chai_1.assert.deepEqual(props.text, { signal: "''+datum[\"Origin\"]" }); + }); + }); + describe('with row, column, text, and color', 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 = util_1.parseModelWithScale(spec); + model.parseLayoutSize(); + var childModel = model.children[0]; + var props = text_1.text.encodeEntry(childModel); + it('should fit the view on x', function () { + chai_1.assert.deepEqual(props.x, { field: { group: 'width' }, offset: -5 }); + }); + it('should center on y', function () { + chai_1.assert.deepEqual(props.y, { + mult: 0.5, + signal: 'child_height' + }); + }); + it('should map text to expression', function () { + chai_1.assert.deepEqual(props.text, { + signal: "format(datum[\"mean_Acceleration\"], \"\")" + }); + }); + it('should map color to fill', function () { + chai_1.assert.deepEqual(props.fill, { + scale: 'color', + field: 'mean_Acceleration' + }); + }); + it('should map size to fontSize', function () { + chai_1.assert.deepEqual(props.fontSize, { + scale: 'size', + field: 'mean_Acceleration' + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvdGV4dC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixnREFBMEM7QUFDMUMsdURBQW9EO0FBR3BELG1DQUFxRjtBQUVyRixRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixpREFBaUQ7UUFDakQsNkRBQTZEO1FBQzdELElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO1lBQ2pELE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMvRCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7YUFDM0M7WUFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7WUFDbkMsUUFBUSxFQUFFLEVBQUMsT0FBTyxFQUFHLE1BQU0sRUFBQztTQUM3QixDQUFDLENBQUM7UUFFSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQywyQkFBMkIsRUFBRTtZQUM5QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7UUFDekIsaURBQWlEO1FBQ2pELDZEQUE2RDtRQUM3RCxJQUFNLEtBQUssR0FBRywyQ0FBb0Ms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QyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0JBQW9CLEVBQUU7WUFDdkIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUN4QixJQUFJLEVBQUUsR0FBRztnQkFDVCxNQUFNLEVBQUUsY0FBYzthQUN2QixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrQkFBK0IsRUFBRTtZQUNsQyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7Z0JBQzNCLE1BQU0sRUFBRSw0Q0FBd0M7YUFDakQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMEJBQTBCLEVBQUU7WUFDN0IsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFO2dCQUMzQixLQUFLLEVBQUUsT0FBTztnQkFDZCxLQUFLLEVBQUUsbUJBQW1CO2FBQzNCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1lBQ2hDLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRTtnQkFDL0IsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsS0FBSyxFQUFFLG1CQUFtQjthQUMzQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZSBxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtYLCBZfSBmcm9tICcuLi8uLi8uLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge3RleHR9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvdGV4dCc7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvdW5pdCc7XG5pbXBvcnQge0ZhY2V0ZWRDb21wb3NpdGVVbml0U3BlYywgVW5pdFNwZWN9IGZyb20gJy4uLy4uLy4uL3NyYy9zcGVjJztcbmltcG9ydCB7cGFyc2VNb2RlbFdpdGhTY2FsZSwgcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ01hcms6IFRleHQnLCBmdW5jdGlvbigpIHtcbiAgZGVzY3JpYmUoJ3dpdGggc3RhY2tlZCB4JywgZnVuY3Rpb24oKSB7XG4gICAgLy8gVGhpcyBpcyBhIHNpbXBsaWZpZWQgZXhhbXBsZSBmb3Igc3RhY2tlZCB0ZXh0LlxuICAgIC8vIEluIHJlYWxpdHkgdGhpcyB3aWxsIGJlIHVzZWQgYXMgc3RhY2tlZCdzIG92ZXJsYXllZCBtYXJrZXJcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJ0ZXh0XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn1cbiAgICAgIH0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgIFwiY29uZmlnXCI6IHtcInN0YWNrXCI6ICBcInplcm9cIn1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gdGV4dC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBzdGFja19lbmQgb24geCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7c2NhbGU6IFgsIGZpZWxkOiAnc3VtX2FfZW5kJ30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCBzdGFja2VkIHknLCBmdW5jdGlvbigpIHtcbiAgICAvLyBUaGlzIGlzIGEgc2ltcGxpZmllZCBleGFtcGxlIGZvciBzdGFja2VkIHRleHQuXG4gICAgLy8gSW4gcmVhbGl0eSB0aGlzIHdpbGwgYmUgdXNlZCBhcyBzdGFja2VkJ3Mgb3ZlcmxheWVkIG1hcmtlclxuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgIFwibWFya1wiOiBcInRleHRcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcImJcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifVxuICAgICAgfSxcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2JhcmxleS5qc29uXCJ9LFxuICAgICAgXCJjb25maWdcIjoge1wic3RhY2tcIjogIFwiemVyb1wifVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSB0ZXh0LmVuY29kZUVudHJ5KG1vZGVsKTtcblxuICAgIGl0KCdzaG91bGQgdXNlIHN0YWNrX2VuZCBvbiB5JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnksIHtzY2FsZTogWSwgZmllbGQ6ICdzdW1fYV9lbmQnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIHF1YW50aXRhdGl2ZSBhbmQgZm9ybWF0JywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgc3BlYzogVW5pdFNwZWMgPSB7XG4gICAgICBcIm1hcmtcIjogXCJ0ZXh0XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ0ZXh0XCI6IHtcImZpZWxkXCI6IFwiZm9vXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZvcm1hdFwiOiBcImRcIn1cbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHNwZWMpO1xuICAgIGNvbnN0IHByb3BzID0gdGV4dC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBudW1iZXIgdGVtcGxhdGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMudGV4dCwge3NpZ25hbDogYGZvcm1hdChkYXR1bVtcImZvb1wiXSwgXCJkXCIpYH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCBiaW5uZWQgcXVhbnRpdGF0aXZlJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgc3BlYzogVW5pdFNwZWMgPSB7XG4gICAgICBcIm1hcmtcIjogXCJ0ZXh0XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ0ZXh0XCI6IHtcImJpblwiOiB0cnVlLCBcImZpZWxkXCI6IFwiZm9vXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImZvcm1hdFwiOiBcImRcIn1cbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHNwZWMpO1xuICAgIGNvbnN0IHByb3BzID0gdGV4dC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIG91dHB1dCBjb3JyZWN0IGJpbiByYW5nZScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy50ZXh0LCB7c2lnbmFsOiBgZGF0dW1bXCJiaW5fbWF4Ymluc18xMF9mb29cIl0gPT09IG51bGwgfHwgaXNOYU4oZGF0dW1bXCJiaW5fbWF4Ymluc18xMF9mb29cIl0pID8gXCJudWxsXCIgOiBmb3JtYXQoZGF0dW1bXCJiaW5fbWF4Ymluc18xMF9mb29cIl0sIFwiZFwiKSArIFwiIC0gXCIgKyBmb3JtYXQoZGF0dW1bXCJiaW5fbWF4Ymluc18xMF9mb29fZW5kXCJdLCBcImRcIilgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoIHRlbXBvcmFsJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgc3BlYzogVW5pdFNwZWMgPSB7XG4gICAgICBcIm1hcmtcIjogXCJ0ZXh0XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ0ZXh0XCI6IHtcImZpZWxkXCI6IFwiZm9vXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9XG4gICAgICB9XG4gICAgfTtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZShzcGVjKTtcbiAgICBjb25zdCBwcm9wcyA9IHRleHQuZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgZGF0ZSB0ZW1wbGF0ZScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy50ZXh0LCB7c2lnbmFsOiBgdGltZUZvcm1hdChkYXR1bVtcImZvb1wiXSwgJyViICVkLCAlWScpYH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCB4LCB5LCB0ZXh0IChvcmRpbmFsKScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHNwZWM6IFVuaXRTcGVjID0ge1xuICAgICAgXCJtYXJrXCI6IFwidGV4dFwiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkFjY2VsZXJhdGlvblwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJEaXNwbGFjZW1lbnRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInRleHRcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgIH0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9jYXJzLmpzb25cIn1cbiAgICB9O1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHNwZWMpO1xuICAgIGNvbnN0IHByb3BzID0gdGV4dC5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIHNjYWxlIG9uIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueCwge3NjYWxlOiBYLCBmaWVsZDogJ0FjY2VsZXJhdGlvbid9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHNjYWxlIG9uIHknLCBmdW5jdGlvbigpe1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55LCB7c2NhbGU6IFksIGZpZWxkOiAnRGlzcGxhY2VtZW50J30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBjZW50ZXJlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5hbGlnbiwge3ZhbHVlOiBcImNlbnRlclwifSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG1hcCB0ZXh0IHdpdGhvdXQgdGVtcGxhdGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMudGV4dCwge3NpZ25hbDogYCcnK2RhdHVtW1wiT3JpZ2luXCJdYH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aCByb3csIGNvbHVtbiwgdGV4dCwgYW5kIGNvbG9yJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgc3BlYzogRmFjZXRlZENvbXBvc2l0ZVVuaXRTcGVjID0ge1xuICAgICAgICBcIm1hcmtcIjogXCJ0ZXh0XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwicm93XCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJjb2x1bW5cIjoge1wiZmllbGRcIjogXCJDeWxpbmRlcnNcIiwgXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICBcInRleHRcIjoge1wiZmllbGRcIjogXCJBY2NlbGVyYXRpb25cIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYWdncmVnYXRlXCI6IFwibWVhblwifSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiQWNjZWxlcmF0aW9uXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcImZpZWxkXCI6IFwiQWNjZWxlcmF0aW9uXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIn1cbiAgICAgICAgfSxcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvY2Fycy5qc29uXCJ9XG4gICAgICB9O1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VNb2RlbFdpdGhTY2FsZShzcGVjKTtcbiAgICBtb2RlbC5wYXJzZUxheW91dFNpemUoKTtcblxuICAgIGNvbnN0IGNoaWxkTW9kZWwgPSBtb2RlbC5jaGlsZHJlblswXSBhcyBVbml0TW9kZWw7XG4gICAgY29uc3QgcHJvcHMgPSB0ZXh0LmVuY29kZUVudHJ5KGNoaWxkTW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBmaXQgdGhlIHZpZXcgb24geCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54LCB7ZmllbGQ6IHtncm91cDogJ3dpZHRoJ30sIG9mZnNldDogLTV9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2VudGVyIG9uIHknLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueSwge1xuICAgICAgICBtdWx0OiAwLjUsXG4gICAgICAgIHNpZ25hbDogJ2NoaWxkX2hlaWdodCdcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBtYXAgdGV4dCB0byBleHByZXNzaW9uJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnRleHQsIHtcbiAgICAgICAgc2lnbmFsOiBgZm9ybWF0KGRhdHVtW1wibWVhbl9BY2NlbGVyYXRpb25cIl0sIFwiXCIpYFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG1hcCBjb2xvciB0byBmaWxsJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmZpbGwsIHtcbiAgICAgICAgc2NhbGU6ICdjb2xvcicsXG4gICAgICAgIGZpZWxkOiAnbWVhbl9BY2NlbGVyYXRpb24nXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWFwIHNpemUgdG8gZm9udFNpemUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuZm9udFNpemUsIHtcbiAgICAgICAgc2NhbGU6ICdzaXplJyxcbiAgICAgICAgZmllbGQ6ICdtZWFuX0FjY2VsZXJhdGlvbidcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/mark/tick.test.js b/build/test/compile/mark/tick.test.js new file mode 100644 index 0000000000..ed7bb3d7ef --- /dev/null +++ b/build/test/compile/mark/tick.test.js @@ -0,0 +1,144 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +// 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) +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var tick_1 = require("../../../src/compile/mark/tick"); +var util_1 = require("../../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 = util_1.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_1.tick.encodeEntry(model); + it('should use stack_end on x', function () { + chai_1.assert.deepEqual(props.xc, { scale: channel_1.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 = util_1.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_1.tick.encodeEntry(model); + it('should use stack_end on y', function () { + chai_1.assert.deepEqual(props.yc, { scale: channel_1.Y, field: 'sum_a_end' }); + }); + }); + describe('with quantitative x', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { 'x': { 'field': 'Horsepower', 'type': 'quantitative' } }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick_1.tick.encodeEntry(model); + it('should be centered on y', function () { + chai_1.assert.deepEqual(props.yc, { + mult: 0.5, + signal: 'height' + }); + }); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.xc, { scale: channel_1.X, field: 'Horsepower' }); + }); + it('width should tick thickness with orient vertical', function () { + chai_1.assert.deepEqual(props.width, { value: 1 }); + }); + }); + describe('with quantitative y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { 'y': { 'field': 'Cylinders', 'type': 'quantitative' } }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick_1.tick.encodeEntry(model); + it('should be centered on x', function () { + chai_1.assert.deepEqual(props.xc, { + mult: 0.5, + signal: 'width' + }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.yc, { scale: channel_1.Y, field: 'Cylinders' }); + }); + it('height should tick thickness with orient horizontal', function () { + chai_1.assert.deepEqual(props.height, { value: 1 }); + }); + }); + describe('with quantitative x and ordinal y', function () { + var model = util_1.parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' } + }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick_1.tick.encodeEntry(model); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.xc, { scale: channel_1.X, field: 'Horsepower' }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.yc, { scale: channel_1.Y, field: 'Cylinders' }); + }); + it('wiidth should be tick thickness with default orient vertical', function () { + chai_1.assert.deepEqual(props.width, { value: 1 }); + }); + it('height should be matched to field with default orient vertical', function () { + chai_1.assert.deepEqual(props.height, { value: 14 }); + }); + }); + describe('width should be mapped to size', function () { + var model = util_1.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_1.tick.encodeEntry(model); + it('width should change with size field', function () { + chai_1.assert.deepEqual(props.height, { 'field': 'Acceleration', 'scale': channel_1.SIZE }); + }); + }); + describe('height should be mapped to size', function () { + var model = util_1.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_1.tick.encodeEntry(model); + it('height should change with size field', function () { + chai_1.assert.deepEqual(props.height, { 'field': 'Acceleration', 'scale': channel_1.SIZE }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGljay50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvdGljay50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRzlCLFFBQVE7QUFDUixnREFBZ0Q7QUFDaEQsK0NBQStDO0FBQy9DLEVBQUU7QUFDRiwwRUFBMEU7QUFDMUUsd0NBQXdDO0FBQ3hDLDZCQUE0QjtBQUM1QixnREFBZ0Q7QUFDaEQsdURBQW9EO0FBQ3BELG1DQUFnRTtBQUVoRSxRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixpREFBaUQ7UUFDakQsNkRBQTZEO1FBQzdELElBQU0sS0FBSyxHQUFHLDJDQUFvQyxDQUFDO1lBQ2pELE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMvRCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7YUFDM0M7WUFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7WUFDbkMsUUFBUSxFQUFFLEVBQUMsT0FBTyxFQUFHLE1BQU0sRUFBQztTQUM3QixDQUFDLENBQUM7UUFFSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQywyQkFBMkIsRUFBRTtZQUM5QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1FBQzdELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFHSCxRQUFR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Q0FBaUMsRUFBRTtRQUMxQyxJQUFNLEtBQUssR0FBRywyQ0FBb0MsQ0FBQztZQUNqRCxNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFDUjtnQkFDRSxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7Z0JBQ3BELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDOUMsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2FBQzFEO1lBQ0gsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO1NBQ2xDLENBQUMsQ0FBQztRQUNILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEMsRUFBRSxDQUFDLHNDQUFzQyxFQUFFO1lBQ3pDLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGNBQUksRUFBQyxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cblxuLy8gVE9ETzpcbi8vIHRlc3QgbWFyay10aWNrIHdpdGggdGhlIGZvbGxvd2luZyB0ZXN0IGNhc2VzLFxuLy8gbG9va2luZyBhdCBtYXJrLXBvaW50LnRlc3QudHMgYXMgaW5zcGlyYXRpb25cbi8vXG4vLyBBZnRlciBmaW5pc2hpbmcgYWxsIHRlc3QsIG1ha2Ugc3VyZSBhbGwgbGluZXMgaW4gbWFyay10aWNrLnRzIGlzIHRlc3RlZFxuLy8gKGV4Y2VwdCB0aGUgc2NhZmZvbGQgbGFiZWxzKCkgbWV0aG9kKVxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtTSVpFLCBYLCBZfSBmcm9tICcuLi8uLi8uLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge3RpY2t9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvdGljayc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdNYXJrOiBUaWNrJywgZnVuY3Rpb24oKSB7XG4gIGRlc2NyaWJlKCd3aXRoIHN0YWNrZWQgeCcsIGZ1bmN0aW9uKCkge1xuICAgIC8vIFRoaXMgaXMgYSBzaW1wbGlmaWVkIGV4YW1wbGUgZm9yIHN0YWNrZWQgdGljay5cbiAgICAvLyBJbiByZWFsaXR5IHRoaXMgd2lsbCBiZSB1c2VkIGFzIHN0YWNrZWQncyBvdmVybGF5ZWQgbWFya2VyXG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgXCJtYXJrXCI6IFwidGlja1wiLFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiYlwiLCBcInR5cGVcIjogXCJvcmRpbmFsXCJ9XG4gICAgICB9LFxuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICBcImNvbmZpZ1wiOiB7XCJzdGFja1wiOiAgXCJ6ZXJvXCJ9XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wcyA9IHRpY2suZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2Ugc3RhY2tfZW5kIG9uIHgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueGMsIHtzY2FsZTogWCwgZmllbGQ6ICdzdW1fYV9lbmQnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG5cbiAgZGVzY3JpYmUoJ3dpdGggc3RhY2tlZCB5JywgZnVuY3Rpb24oKSB7XG4gICAgLy8gVGhpcyBpcyBhIHNpbXBsaWZpZWQgZXhhbXBsZSBmb3Igc3RhY2tlZCB0aWNrLlxuICAgIC8vIEluIHJlYWxpdHkgdGhpcyB3aWxsIGJlIHVzZWQgYXMgc3RhY2tlZCdzIG92ZXJsYXllZCBtYXJrZXJcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICBcIm1hcmtcIjogXCJ0aWNrXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJiXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn1cbiAgICAgIH0sXG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgIFwiY29uZmlnXCI6IHtcInN0YWNrXCI6ICBcInplcm9cIn1cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gdGljay5lbmNvZGVFbnRyeShtb2RlbCk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBzdGFja19lbmQgb24geScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Yywge3NjYWxlOiBZLCBmaWVsZDogJ3N1bV9hX2VuZCd9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggcXVhbnRpdGF0aXZlIHgnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAnbWFyayc6ICd0aWNrJyxcbiAgICAgICdlbmNvZGluZyc6IHsneCc6IHsnZmllbGQnOiAnSG9yc2Vwb3dlcicsICd0eXBlJzogJ3F1YW50aXRhdGl2ZSd9fSxcbiAgICAgICdkYXRhJzogeyd1cmwnOiAnZGF0YS9jYXJzLmpzb24nfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcHMgPSB0aWNrLmVuY29kZUVudHJ5KG1vZGVsKTtcbiAgICBpdCgnc2hvdWxkIGJlIGNlbnRlcmVkIG9uIHknLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMueWMsIHtcbiAgICAgICAgbXVsdDogMC41LFxuICAgICAgICBzaWduYWw6ICdoZWlnaHQnXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2NhbGUgb24geCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy54Yywge3NjYWxlOiBYLCBmaWVsZDogJ0hvcnNlcG93ZXInfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnd2lkdGggc2hvdWxkIHRpY2sgdGhpY2tuZXNzIHdpdGggb3JpZW50IHZlcnRpY2FsJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLndpZHRoLCB7dmFsdWU6IDF9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggcXVhbnRpdGF0aXZlIHknLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlQW5kTGF5b3V0U2l6ZSh7XG4gICAgICAnbWFyayc6ICd0aWNrJyxcbiAgICAgICdlbmNvZGluZyc6IHsneSc6IHsnZmllbGQnOiAnQ3lsaW5kZXJzJywndHlwZSc6ICdxdWFudGl0YXRpdmUnfX0sXG4gICAgICAnZGF0YSc6IHsndXJsJzogJ2RhdGEvY2Fycy5qc29uJ31cbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3BzID0gdGljay5lbmNvZGVFbnRyeShtb2RlbCk7XG4gICAgaXQoJ3Nob3VsZCBiZSBjZW50ZXJlZCBvbiB4JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnhjLCB7XG4gICAgICAgIG11bHQ6IDAuNSxcbiAgICAgICAgc2lnbmFsOiAnd2lkdGgnXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2NhbGUgb24geScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Yywge3NjYWxlOiBZLCBmaWVsZDogJ0N5bGluZGVycyd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdoZWlnaHQgc2hvdWxkIHRpY2sgdGhpY2tuZXNzIHdpdGggb3JpZW50IGhvcml6b250YWwnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMuaGVpZ2h0LCB7dmFsdWU6IDF9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dpdGggcXVhbnRpdGF0aXZlIHggYW5kIG9yZGluYWwgeScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHtcbiAgICAgICdtYXJrJzogJ3RpY2snLFxuICAgICAgJ2VuY29kaW5nJzpcbiAgICAgICAge1xuICAgICAgICAgICd4JzogeydmaWVsZCc6ICdIb3JzZXBvd2VyJywgJ3R5cGUnOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgJ3knOiB7J2ZpZWxkJzogJ0N5bGluZGVycycsJ3R5cGUnOiAnb3JkaW5hbCd9XG4gICAgICAgIH0sXG4gICAgICAnZGF0YSc6IHsndXJsJzogJ2RhdGEvY2Fycy5qc29uJ31cbiAgICB9KTtcbiAgICBjb25zdCBwcm9wcyA9IHRpY2suZW5jb2RlRW50cnkobW9kZWwpO1xuXG4gICAgaXQoJ3Nob3VsZCBzY2FsZSBvbiB4JywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLnhjLCB7c2NhbGU6IFgsIGZpZWxkOiAnSG9yc2Vwb3dlcid9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2NhbGUgb24geScsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy55Yywge3NjYWxlOiBZLCBmaWVsZDogJ0N5bGluZGVycyd9KTtcbiAgICB9KTtcblxuICAgIGl0KCd3aWlkdGggc2hvdWxkIGJlIHRpY2sgdGhpY2tuZXNzIHdpdGggZGVmYXVsdCBvcmllbnQgdmVydGljYWwnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocHJvcHMud2lkdGgsIHt2YWx1ZTogMX0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hlaWdodCBzaG91bGQgYmUgbWF0Y2hlZCB0byBmaWVsZCB3aXRoIGRlZmF1bHQgb3JpZW50IHZlcnRpY2FsJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmhlaWdodCwge3ZhbHVlOiAxNH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2lkdGggc2hvdWxkIGJlIG1hcHBlZCB0byBzaXplJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgJ21hcmsnOiAndGljaycsXG4gICAgICAnY29uZmlnJzogeydtYXJrJzogeydvcmllbnQnOiAndmVydGljYWwnfX0sXG4gICAgICAnZW5jb2RpbmcnOlxuICAgICAgICB7XG4gICAgICAgICAgJ3gnOiB7J2ZpZWxkJzogJ0hvcnNlcG93ZXInLCAndHlwZSc6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAneSc6IHsnZmllbGQnOiAnQ3lsaW5kZXJzJywgJ3R5cGUnOiAnb3JkaW5hbCd9LFxuICAgICAgICAgICdzaXplJzogeydmaWVsZCc6ICdBY2NlbGVyYXRpb24nLCAndHlwZSc6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9LFxuICAgICAgJ2RhdGEnOiB7J3VybCc6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gdGljay5lbmNvZGVFbnRyeShtb2RlbCk7XG4gICAgaXQoJ3dpZHRoIHNob3VsZCBjaGFuZ2Ugd2l0aCBzaXplIGZpZWxkJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHByb3BzLmhlaWdodCwgeydmaWVsZCc6ICdBY2NlbGVyYXRpb24nLCAnc2NhbGUnOiBTSVpFfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdoZWlnaHQgc2hvdWxkIGJlIG1hcHBlZCB0byBzaXplJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZUFuZExheW91dFNpemUoe1xuICAgICAgJ21hcmsnOiAndGljaycsXG4gICAgICAnZW5jb2RpbmcnOlxuICAgICAgICB7XG4gICAgICAgICAgJ3gnOiB7J2ZpZWxkJzogJ0hvcnNlcG93ZXInLCAndHlwZSc6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAneSc6IHsnZmllbGQnOiAnQ3lsaW5kZXJzJywgJ3R5cGUnOiAnb3JkaW5hbCd9LFxuICAgICAgICAgICdzaXplJzogeydmaWVsZCc6ICdBY2NlbGVyYXRpb24nLCAndHlwZSc6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9LFxuICAgICAgJ2RhdGEnOiB7J3VybCc6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgIH0pO1xuICAgIGNvbnN0IHByb3BzID0gdGljay5lbmNvZGVFbnRyeShtb2RlbCk7XG4gICAgaXQoJ2hlaWdodCBzaG91bGQgY2hhbmdlIHdpdGggc2l6ZSBmaWVsZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChwcm9wcy5oZWlnaHQsIHsnZmllbGQnOiAnQWNjZWxlcmF0aW9uJywgJ3NjYWxlJzogU0laRX0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/model.test.js b/build/test/compile/model.test.js new file mode 100644 index 0000000000..65a4b32c1e --- /dev/null +++ b/build/test/compile/model.test.js @@ -0,0 +1,113 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var model_1 = require("../../src/compile/model"); +var util_1 = require("../util"); +describe('Model', function () { + describe('NameMap', function () { + it('should rename correctly', function () { + var map = new model_1.NameMap(); + chai_1.assert.equal(map.get('a'), 'a'); + map.rename('a', 'b'); + chai_1.assert.equal(map.get('a'), 'b'); + chai_1.assert.equal(map.get('b'), 'b'); + map.rename('b', 'c'); + chai_1.assert.equal(map.get('a'), 'c'); + chai_1.assert.equal(map.get('b'), 'c'); + chai_1.assert.equal(map.get('c'), 'c'); + map.rename('z', 'a'); + chai_1.assert.equal(map.get('a'), 'c'); + chai_1.assert.equal(map.get('b'), 'c'); + chai_1.assert.equal(map.get('c'), 'c'); + chai_1.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 = util_1.parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + } + }); + chai_1.assert(model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return true if a descendant plot has x', function () { + var model = util_1.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' } + } + },] + } + }); + chai_1.assert(model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return false if no descendant plot has a field on x', function () { + var model = util_1.parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + } + }); + chai_1.assert(!model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return false if no descendant plot has a field on x', function () { + var model = util_1.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' } + } + },] + } + }); + chai_1.assert(!model.hasDescendantWithFieldOnChannel('x')); + }); + }); + describe('getSizeSignalRef', function () { + it('returns formula for step if parent is facet', function () { + var model = util_1.parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'nominal', scale: { + padding: 0.345 + } } + } + }, + resolve: { + scale: { x: 'independent' } + } + }); + chai_1.assert.deepEqual(model.child.getSizeSignalRef('width'), { + signal: "bandspace(datum[\"distinct_b\"], 1, 0.345) * child_x_step" + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvY29tcGlsZS9tb2RlbC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLGlEQUFnRDtBQUNoRCxnQ0FBa0U7QUFFbEUsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixJQUFNLEdBQUcsR0FBRyxJQUFJLGVBQU8sRUFBRSxDQUFDO1lBQzFCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUVoQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNyQixhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRWhDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNoQyxhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRWhDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNoQyxhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2hDLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGlDQUFpQyxFQUFFO1FBQzFDLEVBQUUsQ0FBQyxxREFBcUQsRUFBRTtZQUN4RCxJQUFNLEtBQUssR0FBRyxzQkFBZSxDQUFDO2dCQUM1QixLQUFLLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUMsRUFBQztnQkFDM0MsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxPQUFPO29CQUNiLFFBQVEsRUFBRTt3QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7cUJBQ3RDO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtDQUErQyxFQUFFO1lBQ2xELElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7Z0JBQzVCLEtBQUssRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQyxFQUFDO2dCQUMzQyxJQUFJLEVBQUU7b0JBQ0osS0FBSyxFQUFFLENBQUM7NEJBQ04sSUFBSSxFQUFFLE9BQU87NEJBQ2IsUUFBUSxFQUFFO2dDQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQzs2QkFDdEM7eUJBQ0YsRUFBQzs0QkFDQSxJQUFJLEVBQUUsT0FBTzs0QkFDYixRQUFRLEVBQUU7Z0NBQ1IsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDOzZCQUMxQzt5QkFDRixFQUFFO2lCQUNKO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDREQUE0RCxFQUFFO1lBQy9ELElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7Z0JBQzVCLEtBQUssRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQyxFQUFDO2dCQUMzQyxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLE9BQU87b0JBQ2IsUUFBUSxFQUFFO3dCQUNSLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztxQkFDMUM7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsK0JBQStCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRTtZQUMvRCxJQUFNLEtBQUssR0FBRyxzQkFBZSxDQUFDO2dCQUM1QixLQUFLLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUMsRUFBQztnQkFDM0MsSUFBSSxFQUFFO29CQUNKLEtBQUssRUFBRSxDQUFDOzRCQUNOLElBQUksRUFBRSxPQUFPOzRCQUNiLFFBQVEsRUFBRTtnQ0FDUixLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7NkJBQzFDO3lCQUNGLEVBQUM7NEJBQ0EsSUFBSSxFQUFFLE9BQU87NEJBQ2IsUUFBUSxFQUFFO2dDQUNSLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQzs2QkFDMUM7eUJBQ0YsRUFBRTtpQkFDSjthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3RELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7UUFDM0IsRUFBRSxDQUFDLDZDQUE2QyxFQUFFO1lBQ2hELElBQU0sS0FBSyxHQUFHLCtCQUF3QixDQUFDO2dCQUNyQyxLQUFLLEVBQUU7b0JBQ0wsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO2lCQUNuQztnQkFDRCxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLE9BQU87b0JBQ2IsUUFBUSxFQUFFO3dCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUU7Z0NBQ3RDLE9BQU8sRUFBRSxLQUFLOzZCQUNmLEVBQUM7cUJBQ0g7aUJBQ0Y7Z0JBQ0QsT0FBTyxFQUFFO29CQUNQLEtBQUssRUFBRSxFQUFDLENBQUMsRUFBRSxhQUFhLEVBQUM7aUJBQzFCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUN0RCxNQUFNLEVBQUUsMkRBQTJEO2FBQ3BFLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7TmFtZU1hcH0gZnJvbSAnLi4vLi4vc3JjL2NvbXBpbGUvbW9kZWwnO1xuaW1wb3J0IHtwYXJzZUZhY2V0TW9kZWwsIHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdNb2RlbCcsICgpID0+IHtcbiAgZGVzY3JpYmUoJ05hbWVNYXAnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZW5hbWUgY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWFwID0gbmV3IE5hbWVNYXAoKTtcbiAgICAgIGFzc2VydC5lcXVhbChtYXAuZ2V0KCdhJyksICdhJyk7XG5cbiAgICAgIG1hcC5yZW5hbWUoJ2EnLCAnYicpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1hcC5nZXQoJ2EnKSwgJ2InKTtcbiAgICAgIGFzc2VydC5lcXVhbChtYXAuZ2V0KCdiJyksICdiJyk7XG5cbiAgICAgIG1hcC5yZW5hbWUoJ2InLCAnYycpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1hcC5nZXQoJ2EnKSwgJ2MnKTtcbiAgICAgIGFzc2VydC5lcXVhbChtYXAuZ2V0KCdiJyksICdjJyk7XG4gICAgICBhc3NlcnQuZXF1YWwobWFwLmdldCgnYycpLCAnYycpO1xuXG4gICAgICBtYXAucmVuYW1lKCd6JywgJ2EnKTtcbiAgICAgIGFzc2VydC5lcXVhbChtYXAuZ2V0KCdhJyksICdjJyk7XG4gICAgICBhc3NlcnQuZXF1YWwobWFwLmdldCgnYicpLCAnYycpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1hcC5nZXQoJ2MnKSwgJ2MnKTtcbiAgICAgIGFzc2VydC5lcXVhbChtYXAuZ2V0KCd6JyksICdjJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdoYXNEZXNjZW5kYW50V2l0aEZpZWxkT25DaGFubmVsJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgaWYgYSBjaGlsZCBwbG90IGhhcyBhIGZpZWxkIG9uIHgnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbCh7XG4gICAgICAgIGZhY2V0OiB7cm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ25vbWluYWwnfX0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICd4JywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydChtb2RlbC5oYXNEZXNjZW5kYW50V2l0aEZpZWxkT25DaGFubmVsKCd4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBpZiBhIGRlc2NlbmRhbnQgcGxvdCBoYXMgeCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHtcbiAgICAgICAgZmFjZXQ6IHtyb3c6IHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9fSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIGxheWVyOiBbe1xuICAgICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgIHg6IHtmaWVsZDogJ3gnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LHtcbiAgICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiAneCcsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydChtb2RlbC5oYXNEZXNjZW5kYW50V2l0aEZpZWxkT25DaGFubmVsKCd4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgaWYgbm8gZGVzY2VuZGFudCBwbG90IGhhcyBhIGZpZWxkIG9uIHgnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlRmFjZXRNb2RlbCh7XG4gICAgICAgIGZhY2V0OiB7cm93OiB7ZmllbGQ6ICdhJywgdHlwZTogJ25vbWluYWwnfX0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiAneCcsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQoIW1vZGVsLmhhc0Rlc2NlbmRhbnRXaXRoRmllbGRPbkNoYW5uZWwoJ3gnKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBpZiBubyBkZXNjZW5kYW50IHBsb3QgaGFzIGEgZmllbGQgb24geCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHtcbiAgICAgICAgZmFjZXQ6IHtyb3c6IHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9fSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIGxheWVyOiBbe1xuICAgICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6ICd4JywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSx7XG4gICAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgY29sb3I6IHtmaWVsZDogJ3gnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LF1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQoIW1vZGVsLmhhc0Rlc2NlbmRhbnRXaXRoRmllbGRPbkNoYW5uZWwoJ3gnKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRTaXplU2lnbmFsUmVmJywgKCkgPT4ge1xuICAgIGl0KCdyZXR1cm5zIGZvcm11bGEgZm9yIHN0ZXAgaWYgcGFyZW50IGlzIGZhY2V0JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBmYWNldDoge1xuICAgICAgICAgIHJvdzoge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAnbm9taW5hbCcsIHNjYWxlOiB7XG4gICAgICAgICAgICAgIHBhZGRpbmc6IDAuMzQ1XG4gICAgICAgICAgICB9fVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgcmVzb2x2ZToge1xuICAgICAgICAgIHNjYWxlOiB7eDogJ2luZGVwZW5kZW50J31cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwobW9kZWwuY2hpbGQuZ2V0U2l6ZVNpZ25hbFJlZignd2lkdGgnKSwge1xuICAgICAgICBzaWduYWw6IGBiYW5kc3BhY2UoZGF0dW1bXFxcImRpc3RpbmN0X2JcXFwiXSwgMSwgMC4zNDUpICogY2hpbGRfeF9zdGVwYFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/repeat.test.js b/build/test/compile/repeat.test.js new file mode 100644 index 0000000000..8414f237e9 --- /dev/null +++ b/build/test/compile/repeat.test.js @@ -0,0 +1,175 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var repeater_1 = require("../../src/compile/repeater"); +var log = require("../../src/log"); +var util_1 = require("../../src/util"); +var util_2 = require("../util"); +describe('Repeat', function () { + describe('resolveRepeat', function () { + it('should resolve repeated fields', function () { + var resolved = repeater_1.replaceRepeaterInEncoding({ + x: { field: { repeat: 'row' }, type: 'quantitative' }, + y: { field: 'bar', type: 'quantitative' } + }, { row: 'foo' }); + chai_1.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 = repeater_1.replaceRepeaterInEncoding({ + x: { field: { repeat: 'row' }, type: 'quantitative' }, + y: { field: 'bar', type: 'quantitative' } + }, { column: 'foo' }); + chai_1.assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row')); + chai_1.assert.deepEqual(resolved, { + y: { field: 'bar', type: 'quantitative' } + }); + })); + it('should support arrays fo field defs', function () { + var resolved = repeater_1.replaceRepeaterInEncoding({ + detail: [ + { field: { repeat: 'row' }, type: 'quantitative' }, + { field: 'bar', type: 'quantitative' } + ] + }, { row: 'foo' }); + chai_1.assert.deepEqual(resolved, { + detail: [{ field: 'foo', type: 'quantitative' }, { field: 'bar', type: 'quantitative' }] + }); + }); + it('should replace fields in sort', function () { + var resolved = repeater_1.replaceRepeaterInEncoding({ + x: { field: 'bar', type: 'quantitative', sort: { field: { repeat: 'row' }, op: 'min' } } + }, { row: 'foo' }); + chai_1.assert.deepEqual(resolved, { + x: { field: 'bar', type: 'quantitative', sort: { field: 'foo', op: 'min' } } + }); + }); + it('should replace fields in conditionals', function () { + var resolved = repeater_1.replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', field: { repeat: 'row' }, type: 'quantitative' }, + value: 'red' + } + }, { row: 'foo' }); + chai_1.assert.deepEqual(resolved, { + color: { + condition: { selection: 'test', field: 'foo', type: 'quantitative' }, + value: 'red' + } + }); + }); + it('should replace fields in reveresed conditionals', function () { + var resolved = repeater_1.replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', value: 'red' }, + field: { repeat: 'row' }, type: 'quantitative' + } + }, { row: 'foo' }); + chai_1.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 = repeater_1.replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', field: { repeat: 'row' }, type: 'quantitative' }, + value: 'red' + } + }, { column: 'foo' }); + chai_1.assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row')); + chai_1.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 = repeater_1.replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', value: 'red' }, + field: { repeat: 'row' }, type: 'quantitative' + } + }, { column: 'foo' }); + chai_1.assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row')); + chai_1.assert.deepEqual(resolved, { + color: { + condition: { selection: 'test', value: 'red' } + } + }); + })); + }); + describe('initialize children', function () { + it('should create a model per repeated value', function () { + var model = util_2.parseRepeatModel({ + repeat: { + row: ['Acceleration', 'Horsepower'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' } + } + } + }); + chai_1.assert.equal(model.children.length, 2); + }); + it('should create n*m models if row and column are specified', function () { + var model = util_2.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' } + } + } + }); + chai_1.assert.equal(model.children.length, 6); + }); + it('should union color scales and legends', function () { + var model = util_2.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']; + chai_1.assert.deepEqual(colorScale.domains.length, 4); + model.parseLegend(); + chai_1.assert.equal(util_1.keys(model.component.legends).length, 1); + }); + }); + describe('resolve', function () { + it('cannot share axes', log.wrap(function (localLogger) { + util_2.parseRepeatModel({ + repeat: {}, + spec: { + mark: 'point', + encoding: {} + }, + resolve: { + axis: { + x: 'shared' + } + } + }); + chai_1.assert.equal(localLogger.warns[0], log.message.REPEAT_CANNOT_SHARE_AXIS); + })); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwZWF0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2NvbXBpbGUvcmVwZWF0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFFNUIsdURBQXFFO0FBRXJFLG1DQUFxQztBQUNyQyx1Q0FBb0M7QUFDcEMsZ0NBQXlDO0FBRXpDLFFBQVEsQ0FBQyxRQUFRLEVBQUU7SUFDakIsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixFQUFFLENBQUMsZ0NBQWdDLEVBQUU7WUFDbkMsSUFBTSxRQUFRLEdBQUcsb0NBQXlCLENBQUM7Z0JBQ3pDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2dCQUNqRCxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7YUFDeEMsRUFBRSxFQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO1lBRWpCLGFBQU0sQ0FBQyxTQUFTLENBQW1CLFFBQVEsRUFBRTtnQkFDM0MsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2dCQUN2QyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7YUFDeEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0RBQStELEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7WUFDdkYsSUFBTSxRQUFRLEdBQUcsb0NBQXlCLENBQUM7Z0JBQ3pDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2dCQUNqRCxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsS0FB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J2NoYWknO1xuXG5pbXBvcnQge3JlcGxhY2VSZXBlYXRlckluRW5jb2Rpbmd9IGZyb20gJy4uLy4uL3NyYy9jb21waWxlL3JlcGVhdGVyJztcbmltcG9ydCB7RW5jb2Rpbmd9IGZyb20gJy4uLy4uL3NyYy9lbmNvZGluZyc7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vc3JjL2xvZyc7XG5pbXBvcnQge2tleXN9IGZyb20gJy4uLy4uL3NyYy91dGlsJztcbmltcG9ydCB7cGFyc2VSZXBlYXRNb2RlbH0gZnJvbSAnLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdSZXBlYXQnLCBmdW5jdGlvbigpIHtcbiAgZGVzY3JpYmUoJ3Jlc29sdmVSZXBlYXQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXNvbHZlIHJlcGVhdGVkIGZpZWxkcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gcmVwbGFjZVJlcGVhdGVySW5FbmNvZGluZyh7XG4gICAgICAgIHg6IHtmaWVsZDoge3JlcGVhdDogJ3Jvdyd9LCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgIHk6IHtmaWVsZDogJ2JhcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgfSwge3JvdzogJ2Zvbyd9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxFbmNvZGluZzxzdHJpbmc+PihyZXNvbHZlZCwge1xuICAgICAgICB4OiB7ZmllbGQ6ICdmb28nLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgIHk6IHtmaWVsZDogJ2JhcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNob3cgd2FybmluZyBpZiByZXBlYXQgaW4gZmllbGQgZGVmIGNhbm5vdCBiZSByZXNvbHZlZCcsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXBsYWNlUmVwZWF0ZXJJbkVuY29kaW5nKHtcbiAgICAgICAgeDoge2ZpZWxkOiB7cmVwZWF0OiAncm93J30sIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgeToge2ZpZWxkOiAnYmFyJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICB9LCB7Y29sdW1uOiAnZm9vJ30pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLm5vU3VjaFJlcGVhdGVkVmFsdWUoJ3JvdycpKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzb2x2ZWQsIHtcbiAgICAgICAgeToge2ZpZWxkOiAnYmFyJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICB9KTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1cHBvcnQgYXJyYXlzIGZvIGZpZWxkIGRlZnMnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHJlcGxhY2VSZXBlYXRlckluRW5jb2Rpbmcoe1xuICAgICAgICBkZXRhaWw6IFtcbiAgICAgICAgICB7ZmllbGQ6IHtyZXBlYXQ6ICdyb3cnfSwgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgIHtmaWVsZDogJ2JhcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICBdXG4gICAgICB9LCB7cm93OiAnZm9vJ30pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPEVuY29kaW5nPHN0cmluZz4+KHJlc29sdmVkLCB7XG4gICAgICAgIGRldGFpbDogW3tmaWVsZDogJ2ZvbycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwge2ZpZWxkOiAnYmFyJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcGxhY2UgZmllbGRzIGluIHNvcnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHJlcGxhY2VSZXBlYXRlckluRW5jb2Rpbmcoe1xuICAgICAgICB4OiB7ZmllbGQ6ICdiYXInLCB0eXBlOiAncXVhbnRpdGF0aXZlJywgc29ydDoge2ZpZWxkOiB7cmVwZWF0OiAncm93J30sIG9wOiAnbWluJ319XG4gICAgICB9LCB7cm93OiAnZm9vJ30pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPEVuY29kaW5nPHN0cmluZz4+KHJlc29sdmVkLCB7XG4gICAgICAgIHg6IHtmaWVsZDogJ2JhcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCBzb3J0OiB7ZmllbGQ6ICdmb28nLCBvcDogJ21pbid9fVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcGxhY2UgZmllbGRzIGluIGNvbmRpdGlvbmFscycsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gcmVwbGFjZVJlcGVhdGVySW5FbmNvZGluZyh7XG4gICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgY29uZGl0aW9uOiB7c2VsZWN0aW9uOiAndGVzdCcsIGZpZWxkOiB7cmVwZWF0OiAncm93J30sIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICB2YWx1ZTogJ3JlZCdcbiAgICAgICAgfVxuICAgICAgfSwge3JvdzogJ2Zvbyd9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxFbmNvZGluZzxzdHJpbmc+PihyZXNvbHZlZCwge1xuICAgICAgICBjb2xvcjoge1xuICAgICAgICAgIGNvbmRpdGlvbjoge3NlbGVjdGlvbjogJ3Rlc3QnLCBmaWVsZDogJ2ZvbycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICB2YWx1ZTogJ3JlZCdcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcGxhY2UgZmllbGRzIGluIHJldmVyZXNlZCBjb25kaXRpb25hbHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHJlcGxhY2VSZXBlYXRlckluRW5jb2Rpbmcoe1xuICAgICAgICBjb2xvcjoge1xuICAgICAgICAgIGNvbmRpdGlvbjoge3NlbGVjdGlvbjogJ3Rlc3QnLCB2YWx1ZTogJ3JlZCd9LFxuICAgICAgICAgIGZpZWxkOiB7cmVwZWF0OiAncm93J30sIHR5cGU6ICdxdWFudGl0YXRpdmUnXG4gICAgICAgIH1cbiAgICAgIH0sIHtyb3c6ICdmb28nfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8RW5jb2Rpbmc8c3RyaW5nPj4ocmVzb2x2ZWQsIHtcbiAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICBjb25kaXRpb246IHtzZWxlY3Rpb246ICd0ZXN0JywgdmFsdWU6ICdyZWQnfSxcbiAgICAgICAgICBmaWVsZDogJ2ZvbycsIHR5cGU6ICdxdWFudGl0YXRpdmUnXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaG93IHdhcm5pbmcgaWYgcmVwZWF0IGluIGNvbmRpdGlvbmFsIGNhbm5vdCBiZSByZXNvbHZlZCcsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXBsYWNlUmVwZWF0ZXJJbkVuY29kaW5nKHtcbiAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICBjb25kaXRpb246IHtzZWxlY3Rpb246ICd0ZXN0JywgZmllbGQ6IHtyZXBlYXQ6ICdyb3cnfSwgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgIHZhbHVlOiAncmVkJ1xuICAgICAgICB9XG4gICAgICB9LCB7Y29sdW1uOiAnZm9vJ30pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLm5vU3VjaFJlcGVhdGVkVmFsdWUoJ3JvdycpKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzb2x2ZWQsIHtcbiAgICAgICAgY29sb3I6IHt2YWx1ZTogJ3JlZCd9XG4gICAgICB9KTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIHNob3cgd2FybmluZyBpZiByZXBlYXQgaW4gYSBjb25kaXRpb24gZmllbGQgZGVmIGNhbm5vdCBiZSByZXNvbHZlZCcsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXBsYWNlUmVwZWF0ZXJJbkVuY29kaW5nKHtcbiAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICBjb25kaXRpb246IHtzZWxlY3Rpb246ICd0ZXN0JywgdmFsdWU6ICdyZWQnfSxcbiAgICAgICAgICBmaWVsZDoge3JlcGVhdDogJ3Jvdyd9LCB0eXBlOiAncXVhbnRpdGF0aXZlJ1xuICAgICAgICB9XG4gICAgICB9LCB7Y29sdW1uOiAnZm9vJ30pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLm5vU3VjaFJlcGVhdGVkVmFsdWUoJ3JvdycpKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzb2x2ZWQsIHtcbiAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICBjb25kaXRpb246IHtzZWxlY3Rpb246ICd0ZXN0JywgdmFsdWU6ICdyZWQnfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpbml0aWFsaXplIGNoaWxkcmVuJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbW9kZWwgcGVyIHJlcGVhdGVkIHZhbHVlJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVJlcGVhdE1vZGVsKHtcbiAgICAgICAgcmVwZWF0OiB7XG4gICAgICAgICAgcm93OiBbJ0FjY2VsZXJhdGlvbicsICdIb3JzZXBvd2VyJ11cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDoge3JlcGVhdDogJ3Jvdyd9LCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuY2hpbGRyZW4ubGVuZ3RoLCAyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIG4qbSBtb2RlbHMgaWYgcm93IGFuZCBjb2x1bW4gYXJlIHNwZWNpZmllZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VSZXBlYXRNb2RlbCh7XG4gICAgICAgIHJlcGVhdDoge1xuICAgICAgICAgIHJvdzogWydBY2NlbGVyYXRpb24nLCAnSG9yc2Vwb3dlcicsICdEaXNwbGFjZW1lbnQnXSxcbiAgICAgICAgICBjb2x1bW46IFsnT3JpZ2luJywgJ051bUN5bGluZGVycyddXG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6IHtyZXBlYXQ6ICdyb3cnfSwgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiB7cmVwZWF0OiAnY29sdW1uJ30sIHR5cGU6ICdvcmRpbmFsJ31cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuY2hpbGRyZW4ubGVuZ3RoLCA2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdW5pb24gY29sb3Igc2NhbGVzIGFuZCBsZWdlbmRzJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVJlcGVhdE1vZGVsKHtcbiAgICAgICAgcmVwZWF0OiB7XG4gICAgICAgICAgcm93OiBbJ2ZvbycsICdiYXInXSxcbiAgICAgICAgICBjb2x1bW46IFsnZm9vJywgJ2JhciddXG4gICAgICAgIH0sXG4gICAgICAgIHNwZWM6IHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6IHtyZXBlYXQ6ICdyb3cnfSwgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiB7cmVwZWF0OiAnY29sdW1uJ30sIHR5cGU6ICdvcmRpbmFsJ30sXG4gICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiAnYmF6JywgdHlwZTogJ25vbWluYWwnfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG1vZGVsLnBhcnNlU2NhbGUoKTtcbiAgICAgIGNvbnN0IGNvbG9yU2NhbGUgPSBtb2RlbC5jb21wb25lbnQuc2NhbGVzWydjb2xvciddO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGNvbG9yU2NhbGUuZG9tYWlucy5sZW5ndGgsIDQpO1xuXG4gICAgICBtb2RlbC5wYXJzZUxlZ2VuZCgpO1xuXG4gICAgICBhc3NlcnQuZXF1YWwoa2V5cyhtb2RlbC5jb21wb25lbnQubGVnZW5kcykubGVuZ3RoLCAxKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Jlc29sdmUnLCAoKSA9PiB7XG4gICAgaXQoJ2Nhbm5vdCBzaGFyZSBheGVzJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBwYXJzZVJlcGVhdE1vZGVsKHtcbiAgICAgICAgcmVwZWF0OiB7fSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHt9XG4gICAgICAgIH0sXG4gICAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgICBheGlzOiB7XG4gICAgICAgICAgICB4OiAnc2hhcmVkJ1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLlJFUEVBVF9DQU5OT1RfU0hBUkVfQVhJUyk7XG4gICAgfSkpO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/resolve.test.js b/build/test/compile/resolve.test.js new file mode 100644 index 0000000000..5cde46d187 --- /dev/null +++ b/build/test/compile/resolve.test.js @@ -0,0 +1,106 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var resolve_1 = require("../../src/compile/resolve"); +var log = require("../../src/log"); +var util_1 = require("../util"); +describe('compile/resolve', function () { + describe('defaultScaleResolve', function () { + it('shares scales for layer model by default.', function () { + var model = util_1.parseLayerModel({ + layer: [] + }); + chai_1.assert.equal(resolve_1.defaultScaleResolve('x', model), 'shared'); + }); + it('shares scales for facet model by default.', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'nominal' } + }, + spec: { mark: 'point', encoding: {} } + }); + chai_1.assert.equal(resolve_1.defaultScaleResolve('x', model), 'shared'); + }); + it('separates xy scales for concat model by default.', function () { + var model = util_1.parseConcatModel({ + hconcat: [] + }); + chai_1.assert.equal(resolve_1.defaultScaleResolve('x', model), 'independent'); + }); + it('shares non-xy scales for concat model by default.', function () { + var model = util_1.parseConcatModel({ + hconcat: [] + }); + chai_1.assert.equal(resolve_1.defaultScaleResolve('color', model), 'shared'); + }); + it('separates xy scales for repeat model by default.', function () { + var model = util_1.parseRepeatModel({ + repeat: { + row: ['a', 'b'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' }, + color: { field: 'color', type: 'quantitative' } + } + } + }); + chai_1.assert.equal(resolve_1.defaultScaleResolve('x', model), 'independent'); + }); + it('shares non-xy scales for repeat model by default.', function () { + var model = util_1.parseRepeatModel({ + repeat: { + row: ['a', 'b'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' }, + color: { field: 'color', type: 'quantitative' } + } + } + }); + chai_1.assert.equal(resolve_1.defaultScaleResolve('color', model), 'shared'); + }); + }); + describe('parseGuideResolve', function () { + it('shares axis for a shared scale by default', function () { + var axisResolve = resolve_1.parseGuideResolve({ + scale: { x: 'shared' }, + axis: {} + }, 'x'); + chai_1.assert.equal(axisResolve, 'shared'); + }); + it('separates axis for a shared scale if specified', function () { + var axisResolve = resolve_1.parseGuideResolve({ + scale: { x: 'shared' }, + axis: { x: 'independent' } + }, 'x'); + chai_1.assert.equal(axisResolve, 'independent'); + }); + it('separates legend for a shared scale if specified', function () { + var legendResolve = resolve_1.parseGuideResolve({ + scale: { color: 'shared' }, + legend: { color: 'independent' } + }, 'color'); + chai_1.assert.equal(legendResolve, 'independent'); + }); + it('separates axis for an independent scale by default', function () { + var axisResolve = resolve_1.parseGuideResolve({ + scale: { x: 'independent' }, + axis: {} + }, 'x'); + chai_1.assert.equal(axisResolve, 'independent'); + }); + it('separates axis for an independent scale even "shared" is specified and throw warning', log.wrap(function (localLogger) { + var axisResolve = resolve_1.parseGuideResolve({ + scale: { x: 'independent' }, + axis: { x: 'shared' } + }, 'x'); + chai_1.assert.equal(axisResolve, 'independent'); + chai_1.assert.equal(localLogger.warns[0], log.message.independentScaleMeansIndependentGuide('x')); + })); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC9jb21waWxlL3Jlc29sdmUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1QixxREFBaUY7QUFDakYsbUNBQXFDO0FBQ3JDLGdDQUE2RjtBQUU3RixRQUFRLENBQUMsaUJBQWlCLEVBQUU7SUFDMUIsUUFBUSxDQUFDLHFCQUFxQixFQUFFO1FBQzlCLEVBQUUsQ0FBQywyQ0FBMkMsRUFBRTtZQUM5QyxJQUFNLEtBQUssR0FBRyxzQkFBZSxDQUFDO2dCQUM1QixLQUFLLEVBQUUsRUFBRTthQUNWLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsNkJBQW1CLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJDQUEyQyxFQUFFO1lBQzlDLElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7Z0JBQzVCLEtBQUssRUFBRTtvQkFDTCxHQUFHLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7aUJBQ25DO2dCQUNELElBQUksRUFBRSxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBQzthQUNwQyxDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLDZCQUFtQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMxRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxJQUFNLEtBQUssR0FBRyx1QkFBZ0IsQ0FBQztnQkFDN0IsT0FBTyxFQUFFLEVBQUU7YUFDWixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLDZCQUFtQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtREFBbUQsRUFBRTtZQUN0RCxJQUFNLEtBQUssR0FBRyx1QkFBZ0IsQ0FBQztnQkFDN0IsT0FBTyxFQUFFLEVBQUU7YUFDWixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLDZCQUFtQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxJQUFNLEtBQUssR0FBRyx1QkFBZ0IsQ0FBQztnQkFDN0IsTUFBTSxFQUFFO29CQUNOLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7aUJBQ2hCO2dCQUNELElBQUksRUFBRTtvQkFDSixJQUFJLEVBQUUsT0FBTztvQkFDYixRQUFRLEVBQUU7d0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7d0JBQ2pELEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztxQkFDOUM7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLDZCQUFtQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtREFBbUQsRUFBRTtZQUN0RCxJQUFNLEtBQUssR0FBRyx1QkFBZ0IsQ0FBQztnQkFDN0IsTUFBTSxFQUFFO29CQUNOLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7aUJBQ2hCO2dCQUNELElBQUksRUFBRTtvQkFDSixJQUFJLEVBQUUsT0FBTztvQkFDYixRQUFRLEVBQUU7d0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7d0JBQ2pELEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztxQkFDOUM7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLDZCQUFtQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG1CQUFtQixFQUFFO1FBQzVCLEVBQUUsQ0FBQywyQ0FBMkMsRUFBRTtZQUM5QyxJQUFNLFdBQVcsR0FBRywyQkFBaUIsQ0FBQztnQkFDcEMsS0FBSyxFQUFFLEVBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBQztnQkFDcEIsSUFBSSxFQUFFLEVBQUU7YUFDVCxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ1IsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsSUFBTSxXQUFXLEdBQUcsMkJBQWlCLENBQUM7Z0JBQ3BDLEtBQUssRUFBRSxFQUFDLENBQUMsRUFBRSxRQUFRLEVBQUM7Z0JBQ3BCLElBQUksRUFBRSxFQUFDLENBQUMsRUFBRSxhQUFhLEVBQUM7YUFDekIsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNSLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFO1lBQ3JELElBQU0sYUFBYSxHQUFHLDJCQUFpQixDQUFDO2dCQUN0QyxLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDO2dCQUN4QixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFDO2FBQy9CLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDWixhQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvREFBb0QsRUFBRTtZQUN2RCxJQUFNLFdBQVcsR0FBRywyQkFBaUIsQ0FBQztnQkFDcEMsS0FBSyxFQUFFLEVBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBQztnQkFDekIsSUFBSSxFQUFFLEVBQUU7YUFDVCxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ1IsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0ZBQXNGLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7WUFDOUcsSUFBTSxXQUFXLEdBQUcsMkJBQWlCLENBQUM7Z0JBQ3BDLEtBQUssRUFBRSxFQUFDLENBQUMsRUFBRSxhQUFhLEVBQUM7Z0JBQ3pCLElBQUksRUFBRSxFQUFDLENBQUMsRUFBRSxRQUFRLEVBQUM7YUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNSLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQ3pDLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLHFDQUFxQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0YsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNOLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2RlZmF1bHRTY2FsZVJlc29sdmUsIHBhcnNlR3VpZGVSZXNvbHZlfSBmcm9tICcuLi8uLi9zcmMvY29tcGlsZS9yZXNvbHZlJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi9zcmMvbG9nJztcbmltcG9ydCB7cGFyc2VDb25jYXRNb2RlbCwgcGFyc2VGYWNldE1vZGVsLCBwYXJzZUxheWVyTW9kZWwsIHBhcnNlUmVwZWF0TW9kZWx9IGZyb20gJy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9yZXNvbHZlJywgKCkgPT4ge1xuICBkZXNjcmliZSgnZGVmYXVsdFNjYWxlUmVzb2x2ZScsICgpID0+IHtcbiAgICBpdCgnc2hhcmVzIHNjYWxlcyBmb3IgbGF5ZXIgbW9kZWwgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlTGF5ZXJNb2RlbCh7XG4gICAgICAgIGxheWVyOiBbXVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFNjYWxlUmVzb2x2ZSgneCcsIG1vZGVsKSwgJ3NoYXJlZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NoYXJlcyBzY2FsZXMgZm9yIGZhY2V0IG1vZGVsIGJ5IGRlZmF1bHQuJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUZhY2V0TW9kZWwoe1xuICAgICAgICBmYWNldDoge1xuICAgICAgICAgIHJvdzoge2ZpZWxkOiAnYScsIHR5cGU6ICdub21pbmFsJ31cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge21hcms6ICdwb2ludCcsIGVuY29kaW5nOiB7fX1cbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRlZmF1bHRTY2FsZVJlc29sdmUoJ3gnLCBtb2RlbCksICdzaGFyZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZXBhcmF0ZXMgeHkgc2NhbGVzIGZvciBjb25jYXQgbW9kZWwgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlQ29uY2F0TW9kZWwoe1xuICAgICAgICBoY29uY2F0OiBbXVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFNjYWxlUmVzb2x2ZSgneCcsIG1vZGVsKSwgJ2luZGVwZW5kZW50Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hhcmVzIG5vbi14eSBzY2FsZXMgZm9yIGNvbmNhdCBtb2RlbCBieSBkZWZhdWx0LicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VDb25jYXRNb2RlbCh7XG4gICAgICAgIGhjb25jYXQ6IFtdXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChkZWZhdWx0U2NhbGVSZXNvbHZlKCdjb2xvcicsIG1vZGVsKSwgJ3NoYXJlZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NlcGFyYXRlcyB4eSBzY2FsZXMgZm9yIHJlcGVhdCBtb2RlbCBieSBkZWZhdWx0LicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VSZXBlYXRNb2RlbCh7XG4gICAgICAgIHJlcGVhdDoge1xuICAgICAgICAgIHJvdzogWydhJywgJ2InXVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiB7cmVwZWF0OiAncm93J30sIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6ICdjb2xvcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFNjYWxlUmVzb2x2ZSgneCcsIG1vZGVsKSwgJ2luZGVwZW5kZW50Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hhcmVzIG5vbi14eSBzY2FsZXMgZm9yIHJlcGVhdCBtb2RlbCBieSBkZWZhdWx0LicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VSZXBlYXRNb2RlbCh7XG4gICAgICAgIHJlcGVhdDoge1xuICAgICAgICAgIHJvdzogWydhJywgJ2InXVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiB7cmVwZWF0OiAncm93J30sIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6ICdjb2xvcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFNjYWxlUmVzb2x2ZSgnY29sb3InLCBtb2RlbCksICdzaGFyZWQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3BhcnNlR3VpZGVSZXNvbHZlJywgKCkgPT4ge1xuICAgIGl0KCdzaGFyZXMgYXhpcyBmb3IgYSBzaGFyZWQgc2NhbGUgYnkgZGVmYXVsdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGF4aXNSZXNvbHZlID0gcGFyc2VHdWlkZVJlc29sdmUoe1xuICAgICAgICBzY2FsZToge3g6ICdzaGFyZWQnfSxcbiAgICAgICAgYXhpczoge31cbiAgICAgIH0sICd4Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoYXhpc1Jlc29sdmUsICdzaGFyZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZXBhcmF0ZXMgYXhpcyBmb3IgYSBzaGFyZWQgc2NhbGUgaWYgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgYXhpc1Jlc29sdmUgPSBwYXJzZUd1aWRlUmVzb2x2ZSh7XG4gICAgICAgIHNjYWxlOiB7eDogJ3NoYXJlZCd9LFxuICAgICAgICBheGlzOiB7eDogJ2luZGVwZW5kZW50J31cbiAgICAgIH0sICd4Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoYXhpc1Jlc29sdmUsICdpbmRlcGVuZGVudCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NlcGFyYXRlcyBsZWdlbmQgZm9yIGEgc2hhcmVkIHNjYWxlIGlmIHNwZWNpZmllZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGxlZ2VuZFJlc29sdmUgPSBwYXJzZUd1aWRlUmVzb2x2ZSh7XG4gICAgICAgIHNjYWxlOiB7Y29sb3I6ICdzaGFyZWQnfSxcbiAgICAgICAgbGVnZW5kOiB7Y29sb3I6ICdpbmRlcGVuZGVudCd9XG4gICAgICB9LCAnY29sb3InKTtcbiAgICAgIGFzc2VydC5lcXVhbChsZWdlbmRSZXNvbHZlLCAnaW5kZXBlbmRlbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZXBhcmF0ZXMgYXhpcyBmb3IgYW4gaW5kZXBlbmRlbnQgc2NhbGUgYnkgZGVmYXVsdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGF4aXNSZXNvbHZlID0gcGFyc2VHdWlkZVJlc29sdmUoe1xuICAgICAgICBzY2FsZToge3g6ICdpbmRlcGVuZGVudCd9LFxuICAgICAgICBheGlzOiB7fVxuICAgICAgfSwgJ3gnKTtcbiAgICAgIGFzc2VydC5lcXVhbChheGlzUmVzb2x2ZSwgJ2luZGVwZW5kZW50Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2VwYXJhdGVzIGF4aXMgZm9yIGFuIGluZGVwZW5kZW50IHNjYWxlIGV2ZW4gXCJzaGFyZWRcIiBpcyBzcGVjaWZpZWQgYW5kIHRocm93IHdhcm5pbmcnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IGF4aXNSZXNvbHZlID0gcGFyc2VHdWlkZVJlc29sdmUoe1xuICAgICAgICBzY2FsZToge3g6ICdpbmRlcGVuZGVudCd9LFxuICAgICAgICBheGlzOiB7eDogJ3NoYXJlZCd9XG4gICAgICB9LCAneCcpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGF4aXNSZXNvbHZlLCAnaW5kZXBlbmRlbnQnKTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuaW5kZXBlbmRlbnRTY2FsZU1lYW5zSW5kZXBlbmRlbnRHdWlkZSgneCcpKTtcbiAgICB9KSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/scale/assemble.test.js b/build/test/compile/scale/assemble.test.js new file mode 100644 index 0000000000..4e4070a31b --- /dev/null +++ b/build/test/compile/scale/assemble.test.js @@ -0,0 +1,123 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var assemble_1 = require("../../../src/compile/scale/assemble"); +var util_1 = require("../../util"); +describe('compile/scale/assemble', function () { + describe('assembleScales', function () { + it('includes all scales for concat', function () { + var model = util_1.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 = assemble_1.assembleScales(model); + chai_1.assert.equal(scales.length, 3); + }); + it('includes all scales from children for layer, both shared and independent', function () { + var model = util_1.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 = assemble_1.assembleScales(model); + chai_1.assert.equal(scales.length, 3); // 2 x, 1 y + }); + it('includes all scales for repeat', function () { + var model = util_1.parseRepeatModel({ + repeat: { + row: ['Acceleration', 'Horsepower'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' } + } + } + }); + model.parseScale(); + var scales = assemble_1.assembleScales(model); + chai_1.assert.equal(scales.length, 2); + }); + it('includes shared scales, but not independent scales (as they are nested) for facet.', function () { + var model = util_1.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 = assemble_1.assembleScales(model); + chai_1.assert.equal(scales.length, 1); + chai_1.assert.equal(scales[0].name, 'y'); + }); + }); + describe('assembleScaleRange', function () { + it('replaces a range step constant with a signal', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'x', type: 'nominal' } + } + }); + chai_1.assert.deepEqual(assemble_1.assembleScaleRange({ step: 21 }, 'x', model, 'x'), { step: { signal: 'x_step' } }); + }); + it('updates width signal when renamed.', function () { + var model = util_1.parseUnitModelWithScale({ + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + }); + // mock renaming + model.renameLayoutSize('width', 'new_width'); + chai_1.assert.deepEqual(assemble_1.assembleScaleRange([0, { signal: 'width' }], 'x', model, 'x'), [0, { signal: 'new_width' }]); + }); + it('updates height signal when renamed.', function () { + var model = util_1.parseUnitModelWithScale({ + mark: 'point', + encoding: { + x: { field: 'y', type: 'quantitative' } + } + }); + // mock renaming + model.renameLayoutSize('height', 'new_height'); + chai_1.assert.deepEqual(assemble_1.assembleScaleRange([0, { signal: 'height' }], 'x', model, 'x'), [0, { signal: 'new_height' }]); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZW1ibGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zY2FsZS9hc3NlbWJsZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLGdFQUF1RjtBQUN2RixtQ0FBa0o7QUFFbEosUUFBUSxDQUFDLHdCQUF3QixFQUFFO0lBQ2pDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixFQUFFLENBQUMsZ0NBQWdDLEVBQUU7WUFDbkMsSUFBTSxLQUFLLEdBQUcsdUJBQWdCLENBQUM7Z0JBQzdCLE9BQU8sRUFBRSxDQUFDO3dCQUNSLElBQUksRUFBRSxPQUFPO3dCQUNiLFFBQVEsRUFBRTs0QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7eUJBQ2pDO3FCQUNGLEVBQUM7d0JBQ0EsSUFBSSxFQUFFLEtBQUs7d0JBQ1gsUUFBUSxFQUFFOzRCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzs0QkFDaEMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO3lCQUN0QztxQkFDRixDQUFDO2FBQ0gsQ0FBQyxDQUFDO1lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ25CLElBQU0sTUFBTSxHQUFHLHlCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsYUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBR0gsRUFBRSxDQUFDLDBFQUEwRSxFQUFFO1lBQzdFLElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7Z0JBQzVCLEtBQUssRUFBRSxDQUFDO3dCQUNOLElBQUksRUFBRSxPQUFPO3dCQUNiLFFBQVEs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Z0I7WUFDaEIsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUUvQyxhQUFNLENBQUMsU0FBUyxDQUNkLDZCQUFrQixDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsRUFDNUQsQ0FBQyxDQUFDLEVBQUUsRUFBQyxNQUFNLEVBQUUsWUFBWSxFQUFDLENBQUMsQ0FDNUIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7YXNzZW1ibGVTY2FsZVJhbmdlLCBhc3NlbWJsZVNjYWxlc30gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvYXNzZW1ibGUnO1xuaW1wb3J0IHtwYXJzZUNvbmNhdE1vZGVsLCBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGUsIHBhcnNlTGF5ZXJNb2RlbCwgcGFyc2VSZXBlYXRNb2RlbCwgcGFyc2VVbml0TW9kZWwsIHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvc2NhbGUvYXNzZW1ibGUnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdhc3NlbWJsZVNjYWxlcycsICgpID0+IHtcbiAgICBpdCgnaW5jbHVkZXMgYWxsIHNjYWxlcyBmb3IgY29uY2F0JywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUNvbmNhdE1vZGVsKHtcbiAgICAgICAgdmNvbmNhdDogW3tcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICAgIH1cbiAgICAgICAgfSx7XG4gICAgICAgICAgbWFyazogJ2JhcicsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAnb3JkaW5hbCd9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiAnYycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfV1cbiAgICAgIH0pO1xuXG4gICAgICBtb2RlbC5wYXJzZVNjYWxlKCk7XG4gICAgICBjb25zdCBzY2FsZXMgPSBhc3NlbWJsZVNjYWxlcyhtb2RlbCk7XG4gICAgICBhc3NlcnQuZXF1YWwoc2NhbGVzLmxlbmd0aCwgMyk7XG4gICAgfSk7XG5cblxuICAgIGl0KCdpbmNsdWRlcyBhbGwgc2NhbGVzIGZyb20gY2hpbGRyZW4gZm9yIGxheWVyLCBib3RoIHNoYXJlZCBhbmQgaW5kZXBlbmRlbnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlTGF5ZXJNb2RlbCh7XG4gICAgICAgIGxheWVyOiBbe1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgICB5OiB7ZmllbGQ6ICdjJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9LHtcbiAgICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiAnYycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfV0sXG4gICAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgICBzY2FsZToge1xuICAgICAgICAgICAgeDogJ2luZGVwZW5kZW50J1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG1vZGVsLnBhcnNlU2NhbGUoKTtcbiAgICAgIGNvbnN0IHNjYWxlcyA9IGFzc2VtYmxlU2NhbGVzKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChzY2FsZXMubGVuZ3RoLCAzKTsgLy8gMiB4LCAxIHlcbiAgICB9KTtcblxuICAgIGl0KCdpbmNsdWRlcyBhbGwgc2NhbGVzIGZvciByZXBlYXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlUmVwZWF0TW9kZWwoe1xuICAgICAgICByZXBlYXQ6IHtcbiAgICAgICAgICByb3c6IFsnQWNjZWxlcmF0aW9uJywgJ0hvcnNlcG93ZXInXVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiB7cmVwZWF0OiAncm93J30sIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG1vZGVsLnBhcnNlU2NhbGUoKTtcbiAgICAgIGNvbnN0IHNjYWxlcyA9IGFzc2VtYmxlU2NhbGVzKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChzY2FsZXMubGVuZ3RoLCAyKTtcbiAgICB9KTtcblxuICAgIGl0KCdpbmNsdWRlcyBzaGFyZWQgc2NhbGVzLCBidXQgbm90IGluZGVwZW5kZW50IHNjYWxlcyAoYXMgdGhleSBhcmUgbmVzdGVkKSBmb3IgZmFjZXQuJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZUZhY2V0TW9kZWxXaXRoU2NhbGVcbiAgICAgICh7XG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgY29sdW1uOiB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZScsIGZvcm1hdDogJ2QnfVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAgIHk6IHtmaWVsZDogJ2MnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgICBzY2FsZToge3g6ICdpbmRlcGVuZGVudCd9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzY2FsZXMgPSBhc3NlbWJsZVNjYWxlcyhtb2RlbCk7XG4gICAgICBhc3NlcnQuZXF1YWwoc2NhbGVzLmxlbmd0aCwgMSk7XG4gICAgICBhc3NlcnQuZXF1YWwoc2NhbGVzWzBdLm5hbWUsICd5Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhc3NlbWJsZVNjYWxlUmFuZ2UnLCAoKSA9PiB7XG4gICAgaXQoJ3JlcGxhY2VzIGEgcmFuZ2Ugc3RlcCBjb25zdGFudCB3aXRoIGEgc2lnbmFsJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAneCcsIHR5cGU6ICdub21pbmFsJ31cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgIGFzc2VtYmxlU2NhbGVSYW5nZSh7c3RlcDogMjF9LCAneCcsIG1vZGVsLCAneCcpLFxuICAgICAgICB7c3RlcDoge3NpZ25hbDogJ3hfc3RlcCd9fVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCd1cGRhdGVzIHdpZHRoIHNpZ25hbCB3aGVuIHJlbmFtZWQuJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAneCcsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gbW9jayByZW5hbWluZ1xuICAgICAgbW9kZWwucmVuYW1lTGF5b3V0U2l6ZSgnd2lkdGgnLCAnbmV3X3dpZHRoJyk7XG5cblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgYXNzZW1ibGVTY2FsZVJhbmdlKFswLCB7c2lnbmFsOiAnd2lkdGgnfV0sICd4JywgbW9kZWwsICd4JyksXG4gICAgICAgIFswLCB7c2lnbmFsOiAnbmV3X3dpZHRoJ31dXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3VwZGF0ZXMgaGVpZ2h0IHNpZ25hbCB3aGVuIHJlbmFtZWQuJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAneScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gbW9jayByZW5hbWluZ1xuICAgICAgbW9kZWwucmVuYW1lTGF5b3V0U2l6ZSgnaGVpZ2h0JywgJ25ld19oZWlnaHQnKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgYXNzZW1ibGVTY2FsZVJhbmdlKFswLCB7c2lnbmFsOiAnaGVpZ2h0J31dLCAneCcsIG1vZGVsLCAneCcpLFxuICAgICAgICBbMCwge3NpZ25hbDogJ25ld19oZWlnaHQnfV1cbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/scale/domain.test.js b/build/test/compile/scale/domain.test.js new file mode 100644 index 0000000000..49ac8c06d4 --- /dev/null +++ b/build/test/compile/scale/domain.test.js @@ -0,0 +1,726 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var domain_1 = require("../../../src/compile/scale/domain"); +var parse_1 = require("../../../src/compile/scale/parse"); +var data_1 = require("../../../src/data"); +var log = require("../../../src/log"); +var scale_1 = require("../../../src/scale"); +var util_1 = require("../../util"); +describe('compile/scale', function () { + describe('parseDomainForChannel()', function () { + function testParseDomainForChannel(model, channel) { + // Cannot parseDomain before parseScaleCore + parse_1.parseScaleCore(model); + return domain_1.parseDomainForChannel(model, channel); + } + it('should have correct domain with x and x2 channel', function () { + var model = util_1.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'); + chai_1.assert.deepEqual(xDomain, [{ data: 'main', field: 'a' }, { data: 'main', field: 'b' }]); + var yDomain = testParseDomainForChannel(model, 'y'); + chai_1.assert.deepEqual(yDomain, [{ data: 'main', field: 'c' }, { data: 'main', field: 'd' }]); + }); + it('should have correct domain for color', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + color: { field: 'a', type: 'quantitative' }, + } + }); + var xDomain = testParseDomainForChannel(model, 'color'); + chai_1.assert.deepEqual(xDomain, [{ data: 'main', field: 'a' }]); + }); + it('should have correct domain for color ConditionField', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + color: { + condition: { selection: 'sel', field: 'a', type: 'quantitative' } + } + } + }); + var xDomain = testParseDomainForChannel(model, 'color'); + chai_1.assert.deepEqual(xDomain, [{ data: 'main', field: 'a' }]); + }); + it('should return domain for stack', function () { + var model = util_1.parseUnitModel({ + mark: "bar", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + type: 'quantitative' + }, + x: { field: 'x', type: "ordinal" }, + color: { field: 'color', type: "ordinal" } + } + }); + chai_1.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 = util_1.parseUnitModel({ + mark: "bar", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + type: 'quantitative' + }, + x: { field: 'x', type: "ordinal" }, + color: { field: 'color', type: "ordinal" } + }, + config: { + stack: "normalize" + } + }); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: fieldDef + } + }); + chai_1.assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: 'main', + field: 'bin_maxbins_15_origin' + }, { + data: 'main', + field: 'bin_maxbins_15_origin_end' + }]); + chai_1.assert.equal(localLogger.warns[0], log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)); + })); + it('should return the unaggregated domain if requested for non-bin, non-sum Q', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'mean', + field: 'acceleration', + scale: { domain: 'unaggregated' }, + type: "quantitative" + } + } + }); + chai_1.assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: data_1.MAIN, + field: 'min_acceleration' + }, { + data: data_1.MAIN, + field: 'max_acceleration' + }]); + }); + it('should return the aggregated domain for sum Q', log.wrap(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + scale: { domain: 'unaggregated' }, + type: "quantitative" + } + } + }); + testParseDomainForChannel(model, 'y'); + chai_1.assert.equal(localLogger.warns[0], log.message.unaggregateDomainWithNonSharedDomainOp('sum')); + })); + it('should return the right custom domain', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'horsepower', + type: "quantitative", + scale: { domain: [0, 200] } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + chai_1.assert.deepEqual(_domain, [[0, 200]]); + }); + it('should ignore the custom domain when binned', log.wrap(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: 'quantitative', + scale: { domain: [0, 200] }, + bin: { maxbins: 15 } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + chai_1.assert.deepEqual(_domain, [{ + data: 'main', + field: 'bin_maxbins_15_origin' + }, { + data: 'main', + field: 'bin_maxbins_15_origin_end' + }]); + chai_1.assert.equal(localLogger.warns[0], log.message.conflictedDomain("y")); + })); + it('should return the aggregated domain if we do not override it', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'min', + field: 'origin', + type: "quantitative" + } + } + }); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'min', + field: 'acceleration', + type: "quantitative" + } + }, + config: { + scale: { + useUnaggregatedDomain: true + } + } + }); + chai_1.assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: data_1.MAIN, + field: 'min_acceleration' + }, { + data: data_1.MAIN, + field: 'max_acceleration' + }]); + }); + }); + describe('for time', function () { + it('should return the correct domain for month T', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "temporal", + timeUnit: 'month' + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + chai_1.assert.deepEqual(_domain, [{ data: 'main', field: 'month_origin' }]); + }); + it('should return the correct domain for month O', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "ordinal", + timeUnit: 'month' + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + chai_1.assert.deepEqual(_domain, [{ data: 'main', field: 'month_origin', sort: true }]); + }); + it('should return the correct domain for yearmonth T', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "temporal", + timeUnit: 'yearmonth' + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + chai_1.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 = util_1.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'); + chai_1.assert.deepEqual(_domain, [{ + data: 'raw', + field: 'month_date', + sort: sortDef + }]); + }); + it('should return the right custom domain with DateTime objects', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'year', + type: "temporal", + scale: { domain: [{ year: 1970 }, { year: 1980 }] } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + chai_1.assert.deepEqual(_domain, [ + { "signal": "{data: datetime(1970, 0, 1, 0, 0, 0, 0)}" }, + { "signal": "{data: datetime(1980, 0, 1, 0, 0, 0, 0)}" } + ]); + }); + }); + describe('for ordinal', function () { + it('should have correct domain for binned ordinal color', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + color: { field: 'a', bin: true, type: 'ordinal' }, + } + }); + var xDomain = testParseDomainForChannel(model, 'color'); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "nominal", sort: sortDef } + } + }); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "nominal", sort: sortDef } + } + }); + chai_1.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 = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "nominal" } + } + }); + chai_1.assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: "main", + field: 'origin', + sort: true + }]); + }); + }); + }); + describe('mergeDomains()', function () { + it('should merge the same domains', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }); + }); + it('should drop field if op is count', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { op: 'count', field: 'b' } + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { op: 'count' } + }); + }); + it('should sort the output domain if one domain is sorted', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean', order: 'descending' } + }]); + chai_1.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 = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: true + }, { + data: 'foo', + field: 'b', + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'], + sort: true + }); + }); + it('should not sort if no domain is sorted', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b', + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'] + }); + }); + it('should ignore order ascending as it is the default', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean', order: 'ascending' } + }, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }); + }); + it('should merge domains with the same data', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'a' + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + field: 'a' + }); + }); + it('should merge domains with the same data source', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b' + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'] + }); + }); + it('should merge domains with different data source', function () { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: true + }, { + data: 'bar', + field: 'a', + sort: true + }]); + chai_1.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 = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'count' + } + }, { + data: 'bar', + field: 'a' + }]); + chai_1.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 = domain_1.mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b' + }, { + data: 'bar', + field: 'a' + }]); + chai_1.assert.deepEqual(domain, { + fields: [{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b' + }, { + data: 'bar', + field: 'a' + }] + }); + }); + it('should merge signal domains', function () { + var domain = domain_1.mergeDomains([{ + signal: 'foo' + }, { + data: 'bar', + field: 'a' + }]); + chai_1.assert.deepEqual(domain, { + fields: [{ + signal: 'foo' + }, { + data: 'bar', + field: 'a' + } + ] + }); + }); + it('should warn if sorts conflict', log.wrap(function (localLogger) { + var domain = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'count' + } + }, { + data: 'foo', + field: 'b', + sort: true + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'], + sort: true + }); + chai_1.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 = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'count' + } + }, { + data: 'foo', + field: 'a', + sort: true + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: true + }); + chai_1.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 = domain_1.mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'mean', + field: 'c' + } + }, { + data: 'foo', + field: 'b' + }]); + chai_1.assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'], + sort: true + }); + chai_1.assert.equal(localLogger.warns[0], log.message.domainSortDropped({ + op: 'mean', + field: 'c' + })); + })); + it('should not sort explicit domains', function () { + var domain = domain_1.mergeDomains([[1, 2, 3, 4], [3, 4, 5, 6]]); + chai_1.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 = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.LINEAR); + chai_1.assert.deepEqual(sort, undefined); + }); + it('should return true by default for discrete domain', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL); + chai_1.assert.deepEqual(sort, true); + }); + it('should return true for ascending', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative', sort: 'ascending' }, + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL); + chai_1.assert.deepEqual(sort, true); + }); + it('should return undefined if sort = null', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'quantitative', sort: null }, + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL); + chai_1.assert.deepEqual(sort, undefined); + }); + it('should return normal sort spec if specified and aggregration is not count', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal', sort: { op: 'sum', field: 'y' } }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL); + chai_1.assert.deepEqual(sort, { op: 'sum', field: 'y' }); + }); + it('should return normal sort spec if aggregration is count and field not specified', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal', sort: { op: 'count' } }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL); + chai_1.assert.deepEqual(sort, { op: 'count' }); + }); + it('should return true if sort is not specified', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal' }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + var sort = domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL); + chai_1.assert.deepEqual(sort, true); + }); + it('should return undefined if sort is specified', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal', sort: "descending" }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + chai_1.assert.deepEqual(domain_1.domainSort(model, 'x', scale_1.ScaleType.ORDINAL), { op: 'min', field: 'a', order: 'descending' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2NhbGUvZG9tYWluLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBRTVCLDREQUFrRztBQUNsRywwREFBZ0U7QUFFaEUsMENBQXVDO0FBRXZDLHNDQUF3QztBQUN4Qyw0Q0FBNkM7QUFHN0MsbUNBQTBDO0FBRTFDLFFBQVEsQ0FBQyxlQUFlLEVBQUU7SUFDeEIsUUFBUSxDQUFDLHlCQUF5QixFQUFFO1FBQ2xDLG1DQUFtQyxLQUFnQixFQUFFLE9BQXFCO1lBQ3hFLDJDQUEyQztZQUMzQyxzQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RCLE1BQU0sQ0FBQyw4QkFBcUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUVELEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUN6QixJQUFJLEVBQUUsS0FBSztnQkFDWCxRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO29CQUNyQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7b0JBQ3RDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztvQkFDckMsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN2QzthQUNGLENBQUMsQ0FBQztZQUVMLElBQU0sT0FBTyxHQUFHLHlCQUF5QixDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN0RCxhQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVB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bUJBQVUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLGlCQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBQyxDQUFDLENBQUM7UUFDekgsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7U2NhbGVDaGFubmVsfSBmcm9tICcuLi8uLi8uLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge2RvbWFpblNvcnQsIG1lcmdlRG9tYWlucywgcGFyc2VEb21haW5Gb3JDaGFubmVsfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9kb21haW4nO1xuaW1wb3J0IHtwYXJzZVNjYWxlQ29yZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvcGFyc2UnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3VuaXQnO1xuaW1wb3J0IHtNQUlOfSBmcm9tICcuLi8uLi8uLi9zcmMvZGF0YSc7XG5pbXBvcnQge1Bvc2l0aW9uRmllbGREZWZ9IGZyb20gJy4uLy4uLy4uL3NyYy9maWVsZGRlZic7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vLi4vc3JjL2xvZyc7XG5pbXBvcnQge1NjYWxlVHlwZX0gZnJvbSAnLi4vLi4vLi4vc3JjL3NjYWxlJztcbmltcG9ydCB7U29ydEZpZWxkfSBmcm9tICcuLi8uLi8uLi9zcmMvc29ydCc7XG5pbXBvcnQge1ZnRG9tYWluLCBWZ1NvcnRGaWVsZH0gZnJvbSAnLi4vLi4vLi4vc3JjL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9zY2FsZScsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3BhcnNlRG9tYWluRm9yQ2hhbm5lbCgpJywgKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWw6IFVuaXRNb2RlbCwgY2hhbm5lbDogU2NhbGVDaGFubmVsKSB7XG4gICAgICAvLyBDYW5ub3QgcGFyc2VEb21haW4gYmVmb3JlIHBhcnNlU2NhbGVDb3JlXG4gICAgICBwYXJzZVNjYWxlQ29yZShtb2RlbCk7XG4gICAgICByZXR1cm4gcGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCBjaGFubmVsKTtcbiAgICB9XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBkb21haW4gd2l0aCB4IGFuZCB4MiBjaGFubmVsJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiAnYmFyJyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAgIHgyOiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiAnYycsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICAgIHkyOiB7ZmllbGQ6ICdkJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgY29uc3QgeERvbWFpbiA9IHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsICd4Jyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHhEb21haW4sIFt7ZGF0YTogJ21haW4nLCBmaWVsZDogJ2EnfSwge2RhdGE6ICdtYWluJywgZmllbGQ6ICdiJ31dKTtcblxuICAgICAgY29uc3QgeURvbWFpbiA9IHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsICd5Jyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHlEb21haW4sIFt7ZGF0YTogJ21haW4nLCBmaWVsZDogJ2MnfSwge2RhdGE6ICdtYWluJywgZmllbGQ6ICdkJ31dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IGRvbWFpbiBmb3IgY29sb3InLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCB4RG9tYWluID0gdGVzdFBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbCwgJ2NvbG9yJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHhEb21haW4sIFt7ZGF0YTogJ21haW4nLCBmaWVsZDogJ2EnfV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgZG9tYWluIGZvciBjb2xvciBDb25kaXRpb25GaWVsZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgbWFyazogJ2JhcicsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgICAgIGNvbmRpdGlvbjoge3NlbGVjdGlvbjogJ3NlbCcsIGZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHhEb21haW4gPSB0ZXN0UGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCAnY29sb3InKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoeERvbWFpbiwgW3tkYXRhOiAnbWFpbicsIGZpZWxkOiAnYSd9XSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBkb21haW4gZm9yIHN0YWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgbWFyazogXCJiYXJcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB5OiB7XG4gICAgICAgICAgICBhZ2dyZWdhdGU6ICdzdW0nLFxuICAgICAgICAgICAgZmllbGQ6ICdvcmlnaW4nLFxuICAgICAgICAgICAgdHlwZTogJ3F1YW50aXRhdGl2ZSdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHg6IHtmaWVsZDogJ3gnLCB0eXBlOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgY29sb3I6IHtmaWVsZDogJ2NvbG9yJywgdHlwZTogXCJvcmRpbmFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKSwgW3tcbiAgICAgICAgZGF0YTogJ21haW4nLFxuICAgICAgICBmaWVsZDogJ3N1bV9vcmlnaW5fc3RhcnQnXG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdtYWluJyxcbiAgICAgICAgZmllbGQ6ICdzdW1fb3JpZ2luX2VuZCdcbiAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIG5vcm1hbGl6ZSBkb21haW4gZm9yIHN0YWNrIGlmIHNwZWNpZmllZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6IFwiYmFyXCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeToge1xuICAgICAgICAgICAgYWdncmVnYXRlOiAnc3VtJyxcbiAgICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICAgIHR5cGU6ICdxdWFudGl0YXRpdmUnXG4gICAgICAgICAgfSxcbiAgICAgICAgICB4OiB7ZmllbGQ6ICd4JywgdHlwZTogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6ICdjb2xvcicsIHR5cGU6IFwib3JkaW5hbFwifVxuICAgICAgICB9LFxuICAgICAgICBjb25maWc6IHtcbiAgICAgICAgICBzdGFjazogXCJub3JtYWxpemVcIlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh0ZXN0UGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCd5JyksIFtbMCwgMV1dKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdmb3IgcXVhbnRpdGF0aXZlJywgZnVuY3Rpb24oKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgcmlnaHQgZG9tYWluIGZvciBiaW5uZWQgUScsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZERlZjogUG9zaXRpb25GaWVsZERlZjxzdHJpbmc+ID0ge1xuICAgICAgICAgIGJpbjoge21heGJpbnM6IDE1fSxcbiAgICAgICAgICBmaWVsZDogJ29yaWdpbicsXG4gICAgICAgICAgc2NhbGU6IHtkb21haW46ICd1bmFnZ3JlZ2F0ZWQnfSxcbiAgICAgICAgICB0eXBlOiAncXVhbnRpdGF0aXZlJ1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHk6IGZpZWxkRGVmXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKSwgW3tcbiAgICAgICAgICAgIGRhdGE6ICdtYWluJyxcbiAgICAgICAgICAgIGZpZWxkOiAnYmluX21heGJpbnNfMTVfb3JpZ2luJ1xuICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgIGRhdGE6ICdtYWluJyxcbiAgICAgICAgICAgIGZpZWxkOiAnYmluX21heGJpbnNfMTVfb3JpZ2luX2VuZCdcbiAgICAgICAgICB9XSk7XG5cbiAgICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS51bmFnZ3JlZ2F0ZURvbWFpbkhhc05vRWZmZWN0Rm9yUmF3RmllbGQoZmllbGREZWYpKTtcbiAgICAgIH0pKTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHVuYWdncmVnYXRlZCBkb21haW4gaWYgcmVxdWVzdGVkIGZvciBub24tYmluLCBub24tc3VtIFEnLFxuICAgICAgICBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgIHk6IHtcbiAgICAgICAgICAgICAgICBhZ2dyZWdhdGU6ICdtZWFuJyxcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2FjY2VsZXJhdGlvbicsXG4gICAgICAgICAgICAgICAgc2NhbGU6IHtkb21haW46ICd1bmFnZ3JlZ2F0ZWQnfSxcbiAgICAgICAgICAgICAgICB0eXBlOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwodGVzdFBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbCwneScpLCBbe1xuICAgICAgICAgICAgZGF0YTogTUFJTixcbiAgICAgICAgICAgIGZpZWxkOiAnbWluX2FjY2VsZXJhdGlvbidcbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICBkYXRhOiBNQUlOLFxuICAgICAgICAgICAgZmllbGQ6ICdtYXhfYWNjZWxlcmF0aW9uJ1xuICAgICAgICAgIH1dKTtcbiAgICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBhZ2dyZWdhdGVkIGRvbWFpbiBmb3Igc3VtIFEnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB5OiB7XG4gICAgICAgICAgICAgIGFnZ3JlZ2F0ZTogJ3N1bScsXG4gICAgICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICAgICAgc2NhbGU6IHtkb21haW46ICd1bmFnZ3JlZ2F0ZWQnfSxcbiAgICAgICAgICAgICAgdHlwZTogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS51bmFnZ3JlZ2F0ZURvbWFpbldpdGhOb25TaGFyZWREb21haW5PcCgnc3VtJylcbiAgICAgICAgKTtcbiAgICAgIH0pKTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHJpZ2h0IGN1c3RvbSBkb21haW4nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeToge1xuICAgICAgICAgICAgICBmaWVsZDogJ2hvcnNlcG93ZXInLFxuICAgICAgICAgICAgICB0eXBlOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICBzY2FsZToge2RvbWFpbjogWzAsMjAwXX1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBfZG9tYWluID0gdGVzdFBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbCwneScpO1xuXG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoX2RvbWFpbiwgW1swLCAyMDBdXSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBpZ25vcmUgdGhlIGN1c3RvbSBkb21haW4gd2hlbiBiaW5uZWQnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB5OiB7XG4gICAgICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3F1YW50aXRhdGl2ZScsXG4gICAgICAgICAgICAgIHNjYWxlOiB7ZG9tYWluOiBbMCwyMDBdfSxcbiAgICAgICAgICAgICAgYmluOiB7bWF4YmluczogMTV9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgX2RvbWFpbiA9IHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKF9kb21haW4sIFt7XG4gICAgICAgICAgICBkYXRhOiAnbWFpbicsXG4gICAgICAgICAgICBmaWVsZDogJ2Jpbl9tYXhiaW5zXzE1X29yaWdpbidcbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICBkYXRhOiAnbWFpbicsXG4gICAgICAgICAgICBmaWVsZDogJ2Jpbl9tYXhiaW5zXzE1X29yaWdpbl9lbmQnXG4gICAgICAgICAgfV0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmNvbmZsaWN0ZWREb21haW4oXCJ5XCIpKTtcbiAgICAgIH0pKTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGFnZ3JlZ2F0ZWQgZG9tYWluIGlmIHdlIGRvIG5vdCBvdmVycmlkZSBpdCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHk6IHtcbiAgICAgICAgICAgICAgYWdncmVnYXRlOiAnbWluJyxcbiAgICAgICAgICAgICAgZmllbGQ6ICdvcmlnaW4nLFxuICAgICAgICAgICAgICB0eXBlOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKSwgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRhdGE6ICdtYWluJyxcbiAgICAgICAgICAgIGZpZWxkOiAnbWluX29yaWdpbidcbiAgICAgICAgICB9XG4gICAgICAgIF0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXNlIHRoZSBhZ2dyZWdhdGVkIGRhdGEgZm9yIGRvbWFpbiBpZiBzcGVjaWZpZWQgaW4gY29uZmlnJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeToge1xuICAgICAgICAgICAgICBhZ2dyZWdhdGU6ICdtaW4nLFxuICAgICAgICAgICAgICBmaWVsZDogJ2FjY2VsZXJhdGlvbicsXG4gICAgICAgICAgICAgIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgc2NhbGU6IHtcbiAgICAgICAgICAgICAgdXNlVW5hZ2dyZWdhdGVkRG9tYWluOiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKSwgW3tcbiAgICAgICAgICAgIGRhdGE6IE1BSU4sXG4gICAgICAgICAgICBmaWVsZDogJ21pbl9hY2NlbGVyYXRpb24nXG4gICAgICAgICAgfSwge1xuICAgICAgICAgICAgZGF0YTogTUFJTixcbiAgICAgICAgICAgIGZpZWxkOiAnbWF4X2FjY2VsZXJhdGlvbidcbiAgICAgICAgICB9XSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdmb3IgdGltZScsIGZ1bmN0aW9uKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGNvcnJlY3QgZG9tYWluIGZvciBtb250aCBUJyxcbiAgICAgICAgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgICB5OiB7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdvcmlnaW4nLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwidGVtcG9yYWxcIixcbiAgICAgICAgICAgICAgICB0aW1lVW5pdDogJ21vbnRoJ1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3QgX2RvbWFpbiA9IHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKTtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKF9kb21haW4sIFt7ZGF0YTogJ21haW4nLCBmaWVsZDogJ21vbnRoX29yaWdpbid9XSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IGRvbWFpbiBmb3IgbW9udGggTycsXG4gICAgICAgICAgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgICAgIHk6IHtcbiAgICAgICAgICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICAgICAgICAgIHR5cGU6IFwib3JkaW5hbFwiLFxuICAgICAgICAgICAgICAgICAgdGltZVVuaXQ6ICdtb250aCdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgX2RvbWFpbiA9IHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3knKTtcbiAgICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoX2RvbWFpbiwgW3tkYXRhOiAnbWFpbicsIGZpZWxkOiAnbW9udGhfb3JpZ2luJywgc29ydDogdHJ1ZX1dKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgY29ycmVjdCBkb21haW4gZm9yIHllYXJtb250aCBUJyxcbiAgICAgICAgICBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgICAgeToge1xuICAgICAgICAgICAgICAgICAgZmllbGQ6ICdvcmlnaW4nLFxuICAgICAgICAgICAgICAgICAgdHlwZTogXCJ0ZW1wb3JhbFwiLFxuICAgICAgICAgICAgICAgICAgdGltZVVuaXQ6ICd5ZWFybW9udGgnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IF9kb21haW4gPSB0ZXN0UGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCd5Jyk7XG5cbiAgICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoX2RvbWFpbiwgW3tkYXRhOiAnbWFpbicsIGZpZWxkOiAneWVhcm1vbnRoX29yaWdpbid9XSk7XG4gICAgICAgICAgfSk7XG5cblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgY29ycmVjdCBkb21haW4gZm9yIG1vbnRoIE8gd2hlbiBzcGVjaWZ5IHNvcnQnLFxuICAgICAgICAgIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3Qgc29ydERlZjogU29ydEZpZWxkPHN0cmluZz4gPSB7b3A6ICdtZWFuJywgZmllbGQ6ICdwcmVjaXBpdGF0aW9uJywgb3JkZXI6ICdkZXNjZW5kaW5nJ30gO1xuICAgICAgICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgICAgIG1hcms6IFwiYmFyXCIsXG4gICAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgICAgeDoge1xuICAgICAgICAgICAgICAgICAgdGltZVVuaXQ6ICdtb250aCcsXG4gICAgICAgICAgICAgICAgICBmaWVsZDogJ2RhdGUnLFxuICAgICAgICAgICAgICAgICAgdHlwZTogJ29yZGluYWwnLFxuICAgICAgICAgICAgICAgICAgc29ydDogc29ydERlZlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgeToge1xuICAgICAgICAgICAgICAgICAgYWdncmVnYXRlOiAnbWVhbicsXG4gICAgICAgICAgICAgICAgICBmaWVsZDogJ3ByZWNpcGl0YXRpb24nLFxuICAgICAgICAgICAgICAgICAgdHlwZTogJ3F1YW50aXRhdGl2ZSdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgX2RvbWFpbiA9IHRlc3RQYXJzZURvbWFpbkZvckNoYW5uZWwobW9kZWwsJ3gnKTtcblxuICAgICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChfZG9tYWluLCBbe1xuICAgICAgICAgICAgICBkYXRhOiAncmF3JyxcbiAgICAgICAgICAgICAgZmllbGQ6ICdtb250aF9kYXRlJyxcbiAgICAgICAgICAgICAgc29ydDogc29ydERlZlxuICAgICAgICAgICAgfV0pO1xuICAgICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHJpZ2h0IGN1c3RvbSBkb21haW4gd2l0aCBEYXRlVGltZSBvYmplY3RzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHk6IHtcbiAgICAgICAgICAgICAgZmllbGQ6ICd5ZWFyJyxcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZW1wb3JhbFwiLFxuICAgICAgICAgICAgICBzY2FsZToge2RvbWFpbjogW3t5ZWFyOiAxOTcwfSwge3llYXI6IDE5ODB9XX1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBfZG9tYWluID0gdGVzdFBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbCwneScpO1xuXG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoX2RvbWFpbiwgW1xuICAgICAgICAgIHtcInNpZ25hbFwiOiBcIntkYXRhOiBkYXRldGltZSgxOTcwLCAwLCAxLCAwLCAwLCAwLCAwKX1cIn0sXG4gICAgICAgICAge1wic2lnbmFsXCI6IFwie2RhdGE6IGRhdGV0aW1lKDE5ODAsIDAsIDEsIDAsIDAsIDAsIDApfVwifVxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2ZvciBvcmRpbmFsJywgZnVuY3Rpb24oKSB7XG4gICAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBkb21haW4gZm9yIGJpbm5lZCBvcmRpbmFsIGNvbG9yJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiAnYScsIGJpbjogdHJ1ZSwgdHlwZTogJ29yZGluYWwnfSxcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHhEb21haW4gPSB0ZXN0UGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCAnY29sb3InKTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh4RG9tYWluLCBbe2RhdGE6ICdtYWluJywgZmllbGQ6ICdiaW5fbWF4Ymluc182X2FfcmFuZ2UnLCBzb3J0OiB7ZmllbGQ6ICdiaW5fbWF4Ymluc182X2EnLCBvcDogJ21pbid9fV0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZm9yIG5vbWluYWwnLCBmdW5jdGlvbigpIHtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgZG9tYWluIHdpdGggdGhlIHByb3ZpZGVkIHNvcnQgcHJvcGVydHknLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc29ydERlZjogU29ydEZpZWxkPHN0cmluZz4gPSB7b3A6ICdtaW4nIGFzICdtaW4nLCBmaWVsZDonQWNjZWxlcmF0aW9uJ307XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgeToge2ZpZWxkOiAnb3JpZ2luJywgdHlwZTogXCJub21pbmFsXCIsIHNvcnQ6IHNvcnREZWZ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwodGVzdFBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbCwneScpLCBbe1xuICAgICAgICAgICAgZGF0YTogXCJyYXdcIixcbiAgICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICAgIHNvcnQ6IHNvcnREZWZcbiAgICAgICAgICB9XSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBkb21haW4gd2l0aCB0aGUgcHJvdmlkZWQgc29ydCBwcm9wZXJ0eSB3aXRoIG9yZGVyIHByb3BlcnR5JywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IHNvcnREZWY6IFNvcnRGaWVsZDxzdHJpbmc+ID0ge29wOiAnbWluJywgZmllbGQ6J0FjY2VsZXJhdGlvbicsIG9yZGVyOiBcImRlc2NlbmRpbmdcIn0gO1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICAgIHk6IHtmaWVsZDogJ29yaWdpbicsIHR5cGU6IFwibm9taW5hbFwiLCBzb3J0OiBzb3J0RGVmfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwodGVzdFBhcnNlRG9tYWluRm9yQ2hhbm5lbChtb2RlbCwneScpLCBbe1xuICAgICAgICAgICAgZGF0YTogXCJyYXdcIixcbiAgICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICAgIHNvcnQ6IHNvcnREZWZcbiAgICAgICAgfV0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgZG9tYWluIHdpdGhvdXQgc29ydCBpZiBzb3J0IGlzIG5vdCBwcm92aWRlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHk6IHtmaWVsZDogJ29yaWdpbicsIHR5cGU6IFwibm9taW5hbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh0ZXN0UGFyc2VEb21haW5Gb3JDaGFubmVsKG1vZGVsLCd5JyksIFt7XG4gICAgICAgICAgZGF0YTogXCJtYWluXCIsXG4gICAgICAgICAgZmllbGQ6ICdvcmlnaW4nLFxuICAgICAgICAgIHNvcnQ6IHRydWVcbiAgICAgICAgfV0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdtZXJnZURvbWFpbnMoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIG1lcmdlIHRoZSBzYW1lIGRvbWFpbnMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkb21haW4gPSBtZXJnZURvbWFpbnMoW3tcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYScsXG4gICAgICAgIHNvcnQ6IHtmaWVsZDogJ2InLCBvcDogJ21lYW4nfVxuICAgICAgfSwge1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge2ZpZWxkOiAnYicsIG9wOiAnbWVhbid9XG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VmdEb21haW4+KGRvbWFpbiwge1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge2ZpZWxkOiAnYicsIG9wOiAnbWVhbid9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZHJvcCBmaWVsZCBpZiBvcCBpcyBjb3VudCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbe1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge29wOiAnY291bnQnLCBmaWVsZDogJ2InfVxuICAgICAgfV0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPFZnRG9tYWluPihkb21haW4sIHtcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYScsXG4gICAgICAgIHNvcnQ6IHtvcDogJ2NvdW50J31cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzb3J0IHRoZSBvdXRwdXQgZG9tYWluIGlmIG9uZSBkb21haW4gaXMgc29ydGVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluID0gbWVyZ2VEb21haW5zKFt7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnXG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnLFxuICAgICAgICBzb3J0OiB7ZmllbGQ6ICdiJywgb3A6ICdtZWFuJywgb3JkZXI6ICdkZXNjZW5kaW5nJ31cbiAgICAgIH1dKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0RvbWFpbj4oZG9tYWluLCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnLFxuICAgICAgICBzb3J0OiB7ZmllbGQ6ICdiJywgb3A6ICdtZWFuJywgb3JkZXI6ICdkZXNjZW5kaW5nJ31cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzb3J0IHRoZSBvdXRwdXQgZG9tYWluIGlmIG9uZSBkb21haW4gaXMgc29ydGVkIHdpdGggdHJ1ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbe1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDogdHJ1ZVxuICAgICAgfSwge1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdiJyxcbiAgICAgIH1dKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChkb21haW4sIHtcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkczogWydhJywgJ2InXSxcbiAgICAgICAgc29ydDogdHJ1ZVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBzb3J0IGlmIG5vIGRvbWFpbiBpcyBzb3J0ZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkb21haW4gPSBtZXJnZURvbWFpbnMoW3tcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH0sIHtcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYicsXG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZG9tYWluLCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZHM6IFsnYScsICdiJ11cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpZ25vcmUgb3JkZXIgYXNjZW5kaW5nIGFzIGl0IGlzIHRoZSBkZWZhdWx0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluID0gbWVyZ2VEb21haW5zKFt7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnLFxuICAgICAgICBzb3J0OiB7ZmllbGQ6ICdiJywgb3A6ICdtZWFuJywgb3JkZXI6ICdhc2NlbmRpbmcnfVxuICAgICAgfSwge1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge2ZpZWxkOiAnYicsIG9wOiAnbWVhbid9XG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VmdEb21haW4+KGRvbWFpbiwge1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge2ZpZWxkOiAnYicsIG9wOiAnbWVhbid9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWVyZ2UgZG9tYWlucyB3aXRoIHRoZSBzYW1lIGRhdGEnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkb21haW4gPSBtZXJnZURvbWFpbnMoW3tcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH0sIHtcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH1dKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0RvbWFpbj4oZG9tYWluLCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWVyZ2UgZG9tYWlucyB3aXRoIHRoZSBzYW1lIGRhdGEgc291cmNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluID0gbWVyZ2VEb21haW5zKFt7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnXG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2InXG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VmdEb21haW4+KGRvbWFpbiwge1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGRzOiBbJ2EnLCAnYiddXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWVyZ2UgZG9tYWlucyB3aXRoIGRpZmZlcmVudCBkYXRhIHNvdXJjZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbe1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDogdHJ1ZVxuICAgICAgfSwge1xuICAgICAgICBkYXRhOiAnYmFyJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDogdHJ1ZVxuICAgICAgfV0pO1xuXG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGRvbWFpbiwge1xuICAgICAgICBmaWVsZHM6IFt7XG4gICAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgICAgZmllbGQ6ICdhJ1xuICAgICAgICB9LCB7XG4gICAgICAgICAgZGF0YTogJ2JhcicsXG4gICAgICAgICAgZmllbGQ6ICdhJ1xuICAgICAgICB9XSxcbiAgICAgICAgc29ydDogdHJ1ZVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG1lcmdlIGRvbWFpbnMgd2l0aCBkaWZmZXJlbnQgZGF0YSBhbmQgc29ydCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbe1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge1xuICAgICAgICAgIG9wOiAnY291bnQnXG4gICAgICAgIH1cbiAgICAgIH0sIHtcbiAgICAgICAgZGF0YTogJ2JhcicsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH1dKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0RvbWFpbj4oZG9tYWluLCB7XG4gICAgICAgIGZpZWxkczogW3tcbiAgICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgICBmaWVsZDogJ2EnXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBkYXRhOiAnYmFyJyxcbiAgICAgICAgICBmaWVsZDogJ2EnXG4gICAgICAgIH1dLFxuICAgICAgICBzb3J0OiB7XG4gICAgICAgICAgb3A6ICdjb3VudCdcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG1lcmdlIGRvbWFpbnMgd2l0aCB0aGUgc2FtZSBhbmQgZGlmZmVyZW50IGRhdGEnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkb21haW4gPSBtZXJnZURvbWFpbnMoW3tcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH0sIHtcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYidcbiAgICAgIH0sIHtcbiAgICAgICAgZGF0YTogJ2JhcicsXG4gICAgICAgIGZpZWxkOiAnYSdcbiAgICAgIH1dKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChkb21haW4sIHtcbiAgICAgICAgZmllbGRzOiBbe1xuICAgICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICAgIGZpZWxkOiAnYSdcbiAgICAgICAgfSwge1xuICAgICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICAgIGZpZWxkOiAnYidcbiAgICAgICAgfSwge1xuICAgICAgICAgIGRhdGE6ICdiYXInLFxuICAgICAgICAgIGZpZWxkOiAnYSdcbiAgICAgICAgfV1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBtZXJnZSBzaWduYWwgZG9tYWlucycsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbe1xuICAgICAgICBzaWduYWw6ICdmb28nXG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdiYXInLFxuICAgICAgICBmaWVsZDogJ2EnXG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZG9tYWluLCB7XG4gICAgICAgIGZpZWxkczogW3tcbiAgICAgICAgICAgIHNpZ25hbDogJ2ZvbydcbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICBkYXRhOiAnYmFyJyxcbiAgICAgICAgICAgIGZpZWxkOiAnYSdcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB3YXJuIGlmIHNvcnRzIGNvbmZsaWN0JywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBkb21haW4gPSBtZXJnZURvbWFpbnMoW3tcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYScsXG4gICAgICAgIHNvcnQ6IHtcbiAgICAgICAgICBvcDogJ2NvdW50J1xuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2InLFxuICAgICAgICBzb3J0OiB0cnVlXG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZG9tYWluLCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZHM6IFsnYScsICdiJ10sXG4gICAgICAgIHNvcnQ6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLk1PUkVfVEhBTl9PTkVfU09SVCk7XG4gICAgfSkpO1xuXG4gICAgaXQoJ3Nob3VsZCB3YXJuIGlmIHNvcnRzIGNvbmZsaWN0IGV2ZW4gaWYgd2UgZG8gbm90IHVuaW9uJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBkb21haW4gPSBtZXJnZURvbWFpbnMoW3tcbiAgICAgICAgZGF0YTogJ2ZvbycsXG4gICAgICAgIGZpZWxkOiAnYScsXG4gICAgICAgIHNvcnQ6IHtcbiAgICAgICAgICBvcDogJ2NvdW50J1xuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnLFxuICAgICAgICBzb3J0OiB0cnVlXG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZG9tYWluLCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2EnLFxuICAgICAgICBzb3J0OiB0cnVlXG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS5NT1JFX1RIQU5fT05FX1NPUlQpO1xuICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgd2FybiBpZiB3ZSBoYWQgdG8gZHJvcCBjb21wbGV4IHNvcnQnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbe1xuICAgICAgICBkYXRhOiAnZm9vJyxcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgc29ydDoge1xuICAgICAgICAgIG9wOiAnbWVhbicsXG4gICAgICAgICAgZmllbGQ6ICdjJ1xuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZDogJ2InXG4gICAgICB9XSk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZG9tYWluLCB7XG4gICAgICAgIGRhdGE6ICdmb28nLFxuICAgICAgICBmaWVsZHM6IFsnYScsICdiJ10sXG4gICAgICAgIHNvcnQ6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmRvbWFpblNvcnREcm9wcGVkKHtcbiAgICAgICAgb3A6ICdtZWFuJyxcbiAgICAgICAgZmllbGQ6ICdjJ1xuICAgICAgfSkpO1xuICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgbm90IHNvcnQgZXhwbGljaXQgZG9tYWlucycsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IG1lcmdlRG9tYWlucyhbWzEsMiwzLDRdLCBbMyw0LDUsNl1dKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChkb21haW4sIHtcbiAgICAgICAgZmllbGRzOiBbWzEsMiwzLDRdLCBbMyw0LDUsNl1dXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2RvbWFpblNvcnQoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB1bmRlZmluZWQgZm9yIGNvbnRpbnVvdXMgZG9tYWluJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSxcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgY29uc3Qgc29ydCA9IGRvbWFpblNvcnQobW9kZWwsICd4JywgU2NhbGVUeXBlLkxJTkVBUik7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNvcnQsIHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGJ5IGRlZmF1bHQgZm9yIGRpc2NyZXRlIGRvbWFpbicsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6ICdwb2ludCcsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAnb3JkaW5hbCd9LFxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBzb3J0ID0gZG9tYWluU29ydChtb2RlbCwgJ3gnLCBTY2FsZVR5cGUuT1JESU5BTCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNvcnQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYXNjZW5kaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCBzb3J0OiAnYXNjZW5kaW5nJ30sXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IHNvcnQgPSBkb21haW5Tb3J0KG1vZGVsLCAneCcsIFNjYWxlVHlwZS5PUkRJTkFMKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoc29ydCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB1bmRlZmluZWQgaWYgc29ydCA9IG51bGwnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiAnYmFyJyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCBzb3J0OiBudWxsfSxcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgY29uc3Qgc29ydCA9IGRvbWFpblNvcnQobW9kZWwsICd4JywgU2NhbGVUeXBlLk9SRElOQUwpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzb3J0LCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbm9ybWFsIHNvcnQgc3BlYyBpZiBzcGVjaWZpZWQgYW5kIGFnZ3JlZ3JhdGlvbiBpcyBub3QgY291bnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgbWFyazogJ2JhcicsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdub21pbmFsJywgc29ydDoge29wOiAnc3VtJywgZmllbGQ6J3knfX0sXG4gICAgICAgICAgeToge2ZpZWxkOiAnYicsIGFnZ3JlZ2F0ZTogJ3N1bScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNvcnQgPSBkb21haW5Tb3J0KG1vZGVsLCAneCcsIFNjYWxlVHlwZS5PUkRJTkFMKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VmdTb3J0RmllbGQ+KHNvcnQsIHtvcDogJ3N1bScsIGZpZWxkOiAneSd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIG5vcm1hbCBzb3J0IHNwZWMgaWYgYWdncmVncmF0aW9uIGlzIGNvdW50IGFuZCBmaWVsZCBub3Qgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCcsIHNvcnQ6IHtvcDogJ2NvdW50J319LFxuICAgICAgICAgIHk6IHtmaWVsZDogJ2InLCBhZ2dyZWdhdGU6ICdzdW0nLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBzb3J0ID0gZG9tYWluU29ydChtb2RlbCwgJ3gnLCBTY2FsZVR5cGUuT1JESU5BTCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPFZnU29ydEZpZWxkPihzb3J0LCB7b3A6ICdjb3VudCd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgaWYgc29ydCBpcyBub3Qgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9LFxuICAgICAgICAgIHk6IHtmaWVsZDogJ2InLCBhZ2dyZWdhdGU6ICdzdW0nLCB0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBzb3J0ID0gZG9tYWluU29ydChtb2RlbCwgJ3gnLCBTY2FsZVR5cGUuT1JESU5BTCk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHNvcnQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdW5kZWZpbmVkIGlmIHNvcnQgaXMgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCcsIHNvcnQ6IFwiZGVzY2VuZGluZ1wifSxcbiAgICAgICAgICB5OiB7ZmllbGQ6ICdiJywgYWdncmVnYXRlOiAnc3VtJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ1NvcnRGaWVsZD4oZG9tYWluU29ydChtb2RlbCwgJ3gnLCBTY2FsZVR5cGUuT1JESU5BTCksIHtvcDogJ21pbicsIGZpZWxkOiAnYScsIG9yZGVyOiAnZGVzY2VuZGluZyd9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/scale/parse.test.js b/build/test/compile/scale/parse.test.js new file mode 100644 index 0000000000..86e0be9e10 --- /dev/null +++ b/build/test/compile/scale/parse.test.js @@ -0,0 +1,326 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var parse_1 = require("../../../src/compile/scale/parse"); +var selection_1 = require("../../../src/compile/selection/selection"); +var log = require("../../../src/log"); +var scale_1 = require("../../../src/scale"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../util"); +describe('src/compile', function () { + it('NON_TYPE_RANGE_SCALE_PROPERTIES should be SCALE_PROPERTIES wihtout type, domain, and range properties', function () { + chai_1.assert.deepEqual(util_1.toSet(scale_1.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES), util_1.toSet(util_1.without(scale_1.SCALE_PROPERTIES, ['type', 'domain', 'range', 'rangeStep', 'scheme']))); + }); + describe('parseScaleCore', function () { + it('respects explicit scale type', function () { + var model = util_2.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" } + } + } + } + ] + }); + parse_1.parseScaleCore(model); + chai_1.assert.equal(model.getScaleComponent('y').explicit.type, 'log'); + }); + it('respects explicit scale type', function () { + var model = util_2.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" + } + } + } + ] + }); + parse_1.parseScaleCore(model); + chai_1.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 = util_2.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" } + } + } + } + ] + }); + parse_1.parseScaleCore(model); + chai_1.assert.equal(model.getScaleComponent('y').explicit.type, 'log'); + chai_1.assert.equal(localLogger.warns[0], log.message.mergeConflictingProperty('type', 'scale', 'log', 'pow')); + })); + it('favors the band over point', function () { + var model = util_2.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" } + } + }, + ] + }); + parse_1.parseScaleCore(model); + chai_1.assert.equal(model.getScaleComponent('x').implicit.type, 'band'); + }); + }); + describe('parseScale', function () { + describe('x ordinal point', function () { + it('should create an x point scale with rangeStep and no range', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: 'origin', type: "nominal" } + } + }); + var scale = model.getScaleComponent('x'); + chai_1.assert.equal(scale.implicit.type, 'point'); + chai_1.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 = util_2.parseUnitModelWithScale({ + mark: 'bar', + encoding: { + x: { field: 'origin', type: "nominal", scale: { type: 'band', padding: 0.6 } } + } + }); + var scale = model.getScaleComponent('x'); + chai_1.assert.equal(scale.explicit.padding, 0.6); + chai_1.assert.isUndefined(scale.get('paddingInner')); + chai_1.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 = util_2.parseUnitModelWithScale({ + mark: 'bar', + encoding: { + x: { field: 'origin', type: "nominal", scale: { type: 'band' } } + }, + config: { + scale: { bandPaddingInner: 0.3 } + } + }); + var scale = model.getScaleComponent('x'); + chai_1.assert.equal(scale.implicit.paddingInner, 0.3); + chai_1.assert.equal(scale.implicit.paddingOuter, 0.15); + chai_1.assert.isUndefined(scale.get('padding')); + }); + describe('nominal with color', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: 'origin', type: "nominal" } + } + }); + var scale = model.getScaleComponent('color'); + it('should create correct color scale', function () { + chai_1.assert.equal(scale.implicit.name, 'color'); + chai_1.assert.equal(scale.implicit.type, 'ordinal'); + chai_1.assert.deepEqual(scale.domains, [{ + data: 'main', + field: 'origin', + sort: true + }]); + chai_1.assert.equal(scale.implicit.range, 'category'); + }); + }); + describe('ordinal with color', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: 'origin', type: "ordinal" } + } + }); + var scale = model.getScaleComponent('color'); + it('should create sequential color scale', function () { + chai_1.assert.equal(scale.implicit.name, 'color'); + chai_1.assert.equal(scale.implicit.type, 'ordinal'); + chai_1.assert.deepEqual(scale.domains, [{ + data: 'main', + field: 'origin', + sort: true + }]); + }); + }); + describe('quantitative with color', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: "origin", type: "quantitative" } + } + }); + var scale = model.getScaleComponent('color'); + it('should create linear color scale', function () { + chai_1.assert.equal(scale.implicit.name, 'color'); + chai_1.assert.equal(scale.implicit.type, 'sequential'); + chai_1.assert.equal(scale.implicit.range, 'ramp'); + chai_1.assert.deepEqual(scale.domains, [{ + data: 'main', + field: 'origin' + }]); + }); + }); + describe('color with bin', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: "origin", type: "quantitative", bin: true } + } + }); + var scale = model.getScaleComponent('color'); + it('should add correct scales', function () { + chai_1.assert.equal(scale.implicit.name, 'color'); + chai_1.assert.equal(scale.implicit.type, 'bin-ordinal'); + }); + }); + describe('ordinal color with bin', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: "origin", type: "ordinal", bin: true } + } + }); + var scale = model.getScaleComponent('color'); + it('should add correct scales', function () { + chai_1.assert.equal(scale.implicit.name, 'color'); + chai_1.assert.equal(scale.implicit.type, 'ordinal'); + }); + }); + describe('opacity with bin', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + opacity: { field: "origin", type: "quantitative", bin: true } + } + }); + var scale = model.getScaleComponent('opacity'); + it('should add correct scales', function () { + chai_1.assert.equal(scale.implicit.name, 'opacity'); + chai_1.assert.equal(scale.implicit.type, 'bin-linear'); + }); + }); + describe('size with bin', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + size: { field: "origin", type: "quantitative", bin: true } + } + }); + var scale = model.getScaleComponent('size'); + it('should add correct scales', function () { + chai_1.assert.equal(scale.implicit.name, 'size'); + chai_1.assert.equal(scale.implicit.type, 'bin-linear'); + }); + }); + describe('color with time unit', function () { + var model = util_2.parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: 'origin', type: "temporal", timeUnit: "year" } + } + }); + var scale = model.getScaleComponent('color'); + it('should add correct scales', function () { + chai_1.assert.equal(scale.implicit.name, 'color'); + chai_1.assert.equal(scale.implicit.type, 'sequential'); + }); + }); + describe('selection domain', function () { + var model = util_2.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 () { + chai_1.assert.property(xScale.explicit, 'domainRaw'); + chai_1.assert.propertyVal(xScale.explicit.domainRaw, 'signal', selection_1.SELECTION_DOMAIN + '{"selection":"brush","encoding":"x"}'); + chai_1.assert.property(yscale.explicit, 'domainRaw'); + chai_1.assert.propertyVal(yscale.explicit.domainRaw, 'signal', selection_1.SELECTION_DOMAIN + '{"selection":"foobar","field":"Miles_per_Gallon"}'); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zY2FsZS9wYXJzZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QiwwREFBZ0U7QUFDaEUsc0VBQTBFO0FBQzFFLHNDQUF3QztBQUN4Qyw0Q0FBaUc7QUFDakcsMENBQWlEO0FBQ2pELG1DQUErRDtBQUUvRCxRQUFRLENBQUMsYUFBYSxFQUFFO0lBQ3RCLEVBQUUsQ0FBQyx1R0FBdUcsRUFBRTtRQUMxRyxhQUFNLENBQUMsU0FBUyxDQUNkLFlBQUssQ0FBQyxtREFBMkMsQ0FBQyxFQUNsRCxZQUFLLENBQUMsY0FBTyxDQUFDLHdCQUFnQixFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FDckYsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1FBQ3pCLEVBQUUsQ0FBQyw4QkFBOEIsRUFBRTtZQUNqQyxJQUFNLEtBQUssR0FBRyxpQkFBVSxDQUFDO2dCQUN2QixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsMEJBQTBCLEVBQUM7Z0JBQzNDLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxNQUFNLEVBQUUsS0FBSzt3QkFDYixVQUFVLEVBQUU7NEJBQ1YsR0FBRyxFQUFFO2dDQUNILFdBQVcsRUFBRSxNQUFNO2dDQUNuQixPQUFPLEVBQUUsZUFBZTtnQ0FDeEIsTUFBTSxFQUFFLGNBQWM7NkJBQ3ZCO3lCQUNGO3FCQUNGO29CQUNEO3dCQUNFLE1BQU0sRUFBRSxNQUFNO3dCQUNkLFVBQVUsRUFBRTs0QkFDVixHQUFHLEVBQUU7Z0NBQ0gsV0FBVyxFQUFFLE1BQU07Z0NBQ25CLE9BQU8sRUFBRSxlQUFlO2dDQUN4QixNQUFNLEVBQUUsY0FBYztnQ0FDdEIsT0FB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QVEsRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDOUMsYUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQ3BELDRCQUFnQixHQUFHLG1EQUFtRCxDQUFDLENBQUM7WUFDNUUsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtwYXJzZVNjYWxlQ29yZX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvcGFyc2UnO1xuaW1wb3J0IHtTRUxFQ1RJT05fRE9NQUlOfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi8uLi9zcmMvbG9nJztcbmltcG9ydCB7Tk9OX1RZUEVfRE9NQUlOX1JBTkdFX1ZFR0FfU0NBTEVfUFJPUEVSVElFUywgU0NBTEVfUFJPUEVSVElFU30gZnJvbSAnLi4vLi4vLi4vc3JjL3NjYWxlJztcbmltcG9ydCB7dG9TZXQsIHdpdGhvdXR9IGZyb20gJy4uLy4uLy4uL3NyYy91dGlsJztcbmltcG9ydCB7cGFyc2VNb2RlbCwgcGFyc2VVbml0TW9kZWxXaXRoU2NhbGV9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnc3JjL2NvbXBpbGUnLCBmdW5jdGlvbigpIHtcbiAgaXQoJ05PTl9UWVBFX1JBTkdFX1NDQUxFX1BST1BFUlRJRVMgc2hvdWxkIGJlIFNDQUxFX1BST1BFUlRJRVMgd2lodG91dCB0eXBlLCBkb21haW4sIGFuZCByYW5nZSBwcm9wZXJ0aWVzJywgKCkgPT4ge1xuICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICB0b1NldChOT05fVFlQRV9ET01BSU5fUkFOR0VfVkVHQV9TQ0FMRV9QUk9QRVJUSUVTKSxcbiAgICAgIHRvU2V0KHdpdGhvdXQoU0NBTEVfUFJPUEVSVElFUywgWyd0eXBlJywgJ2RvbWFpbicsICdyYW5nZScsICdyYW5nZVN0ZXAnLCAnc2NoZW1lJ10pKVxuICAgICk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXJzZVNjYWxlQ29yZScsICgpID0+IHtcbiAgICBpdCgncmVzcGVjdHMgZXhwbGljaXQgc2NhbGUgdHlwZScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VNb2RlbCh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3NlYXR0bGUtd2VhdGhlci5jc3ZcIn0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInByZWNpcGl0YXRpb25cIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicHJlY2lwaXRhdGlvblwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwic2NhbGVcIjoge1widHlwZVwiOiBcImxvZ1wifVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgICAgIHBhcnNlU2NhbGVDb3JlKG1vZGVsKTtcbiAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5nZXRTY2FsZUNvbXBvbmVudCgneScpLmV4cGxpY2l0LnR5cGUsICdsb2cnKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXNwZWN0cyBleHBsaWNpdCBzY2FsZSB0eXBlJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZU1vZGVsKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvc2VhdHRsZS13ZWF0aGVyLmNzdlwifSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicHJlY2lwaXRhdGlvblwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwic2NhbGVcIjoge1widHlwZVwiOiBcImxvZ1wifVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicHJlY2lwaXRhdGlvblwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICAgICAgcGFyc2VTY2FsZUNvcmUobW9kZWwpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd5JykuZXhwbGljaXQudHlwZSwgJ2xvZycpO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETzogdGhpcyBhY3R1YWxseSBzaG91bGRuJ3QgZ2V0IG1lcmdlZFxuICAgIGl0KCdmYXZvcnMgdGhlIGZpcnN0IGV4cGxpY2l0IHNjYWxlIHR5cGUnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VNb2RlbCh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3NlYXR0bGUtd2VhdGhlci5jc3ZcIn0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcImJhclwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInByZWNpcGl0YXRpb25cIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcInNjYWxlXCI6IHtcInR5cGVcIjogXCJsb2dcIn1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInByZWNpcGl0YXRpb25cIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcInNjYWxlXCI6IHtcInR5cGVcIjogXCJwb3dcIn1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgICBwYXJzZVNjYWxlQ29yZShtb2RlbCk7XG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoJ3knKS5leHBsaWNpdC50eXBlLCAnbG9nJyk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLm1lcmdlQ29uZmxpY3RpbmdQcm9wZXJ0eSgndHlwZScsICdzY2FsZScsICdsb2cnLCAncG93JykpO1xuICAgIH0pKTtcblxuICAgIGl0KCdmYXZvcnMgdGhlIGJhbmQgb3ZlciBwb2ludCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VNb2RlbCh7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3NlYXR0bGUtd2VhdGhlci5jc3ZcIn0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicHJlY2lwaXRhdGlvblwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIndlYXRoZXJcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0se1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwiYmFyXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicHJlY2lwaXRhdGlvblwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIndlYXRoZXJcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIF1cbiAgICAgIH0pO1xuICAgICAgcGFyc2VTY2FsZUNvcmUobW9kZWwpO1xuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd4JykuaW1wbGljaXQudHlwZSwgJ2JhbmQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3BhcnNlU2NhbGUnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ3ggb3JkaW5hbCBwb2ludCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgY3JlYXRlIGFuIHggcG9pbnQgc2NhbGUgd2l0aCByYW5nZVN0ZXAgYW5kIG5vIHJhbmdlJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHg6IHtmaWVsZDogJ29yaWdpbicsIHR5cGU6IFwibm9taW5hbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoJ3gnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0LnR5cGUsICdwb2ludCcpO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHNjYWxlLmltcGxpY2l0LnJhbmdlLCB7c3RlcDogMjF9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBvdXRwdXQgb25seSBwYWRkaW5nIHdpdGhvdXQgZGVmYXVsdCBwYWRkaW5nSW5uZXIgYW5kIHBhZGRpbmdPdXRlciBpZiBwYWRkaW5nIGlzIHNwZWNpZmllZCBmb3IgYSBiYW5kIHNjYWxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ29yaWdpbicsIHR5cGU6IFwibm9taW5hbFwiLCBzY2FsZToge3R5cGU6ICdiYW5kJywgcGFkZGluZzogMC42fX1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBzY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd4Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuZXhwbGljaXQucGFkZGluZywgMC42KTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChzY2FsZS5nZXQoJ3BhZGRpbmdJbm5lcicpKTtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChzY2FsZS5nZXQoJ3BhZGRpbmdPdXRlcicpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgb3V0cHV0IGRlZmF1bHQgcGFkZGluZ0lubmVyIGFuZCBwYWRkaW5nT3V0ZXIgPSBwYWRkaW5nSW5uZXIvMiBpZiBub25lIG9mIHBhZGRpbmcgcHJvcGVydGllcyBpcyBzcGVjaWZpZWQgZm9yIGEgYmFuZCBzY2FsZScsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICBtYXJrOiAnYmFyJyxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6ICdvcmlnaW4nLCB0eXBlOiBcIm5vbWluYWxcIiwgc2NhbGU6IHt0eXBlOiAnYmFuZCd9fVxuICAgICAgICB9LFxuICAgICAgICBjb25maWc6IHtcbiAgICAgICAgICBzY2FsZToge2JhbmRQYWRkaW5nSW5uZXI6IDAuM31cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBzY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd4Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuaW1wbGljaXQucGFkZGluZ0lubmVyLCAwLjMpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0LnBhZGRpbmdPdXRlciwgMC4xNSk7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQoc2NhbGUuZ2V0KCdwYWRkaW5nJykpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25vbWluYWwgd2l0aCBjb2xvcicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBjb2xvcjoge2ZpZWxkOiAnb3JpZ2luJywgdHlwZTogXCJub21pbmFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCdjb2xvcicpO1xuXG4gICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBjb3JyZWN0IGNvbG9yIHNjYWxlJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChzY2FsZS5pbXBsaWNpdC5uYW1lLCAnY29sb3InKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0LnR5cGUsICdvcmRpbmFsJyk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2NhbGUuZG9tYWlucywgW3tcbiAgICAgICAgICBkYXRhOiAnbWFpbicsXG4gICAgICAgICAgZmllbGQ6ICdvcmlnaW4nLFxuICAgICAgICAgIHNvcnQ6IHRydWVcbiAgICAgICAgfV0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuaW1wbGljaXQucmFuZ2UsICdjYXRlZ29yeScpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnb3JkaW5hbCB3aXRoIGNvbG9yJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6ICdvcmlnaW4nLCB0eXBlOiBcIm9yZGluYWxcIn1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoJ2NvbG9yJyk7XG5cbiAgICAgIGl0KCdzaG91bGQgY3JlYXRlIHNlcXVlbnRpYWwgY29sb3Igc2NhbGUnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0Lm5hbWUsICdjb2xvcicpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuaW1wbGljaXQudHlwZSwgJ29yZGluYWwnKTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHNjYWxlLmRvbWFpbnMsIFt7XG4gICAgICAgICAgZGF0YTogJ21haW4nLFxuICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJyxcbiAgICAgICAgICBzb3J0OiB0cnVlXG4gICAgICAgIH1dKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3F1YW50aXRhdGl2ZSB3aXRoIGNvbG9yJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6IFwib3JpZ2luXCIsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudCgnY29sb3InKTtcblxuICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgbGluZWFyIGNvbG9yIHNjYWxlJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChzY2FsZS5pbXBsaWNpdC5uYW1lLCAnY29sb3InKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0LnR5cGUsICdzZXF1ZW50aWFsJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzY2FsZS5pbXBsaWNpdC5yYW5nZSwgJ3JhbXAnKTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHNjYWxlLmRvbWFpbnMsIFt7XG4gICAgICAgICAgZGF0YTogJ21haW4nLFxuICAgICAgICAgIGZpZWxkOiAnb3JpZ2luJ1xuICAgICAgICB9XSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjb2xvciB3aXRoIGJpbicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgICAgICAgbWFyazogXCJwb2ludFwiLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICBjb2xvcjoge2ZpZWxkOiBcIm9yaWdpblwiLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwiLCBiaW46IHRydWV9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudCgnY29sb3InKTtcblxuICAgICAgaXQoJ3Nob3VsZCBhZGQgY29ycmVjdCBzY2FsZXMnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0Lm5hbWUsICdjb2xvcicpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuaW1wbGljaXQudHlwZSwgJ2Jpbi1vcmRpbmFsJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdvcmRpbmFsIGNvbG9yIHdpdGggYmluJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIGNvbG9yOiB7ZmllbGQ6IFwib3JpZ2luXCIsIHR5cGU6IFwib3JkaW5hbFwiLCBiaW46IHRydWV9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudCgnY29sb3InKTtcblxuICAgICAgaXQoJ3Nob3VsZCBhZGQgY29ycmVjdCBzY2FsZXMnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0Lm5hbWUsICdjb2xvcicpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuaW1wbGljaXQudHlwZSwgJ29yZGluYWwnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ29wYWNpdHkgd2l0aCBiaW4nLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgb3BhY2l0eToge2ZpZWxkOiBcIm9yaWdpblwiLCB0eXBlOiBcInF1YW50aXRhdGl2ZVwiLCBiaW46IHRydWV9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudCgnb3BhY2l0eScpO1xuXG4gICAgICBpdCgnc2hvdWxkIGFkZCBjb3JyZWN0IHNjYWxlcycsIGZ1bmN0aW9uKCkge1xuICAgICAgICBhc3NlcnQuZXF1YWwoc2NhbGUuaW1wbGljaXQubmFtZSwgJ29wYWNpdHknKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0LnR5cGUsICdiaW4tbGluZWFyJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzaXplIHdpdGggYmluJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgICBtYXJrOiBcInBvaW50XCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIHNpemU6IHtmaWVsZDogXCJvcmlnaW5cIiwgdHlwZTogXCJxdWFudGl0YXRpdmVcIiwgYmluOiB0cnVlfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoJ3NpemUnKTtcblxuICAgICAgaXQoJ3Nob3VsZCBhZGQgY29ycmVjdCBzY2FsZXMnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0Lm5hbWUsICdzaXplJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzY2FsZS5pbXBsaWNpdC50eXBlLCAnYmluLWxpbmVhcicpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY29sb3Igd2l0aCB0aW1lIHVuaXQnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoe1xuICAgICAgICAgIG1hcms6IFwicG9pbnRcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgY29sb3I6IHtmaWVsZDogJ29yaWdpbicsIHR5cGU6IFwidGVtcG9yYWxcIiwgdGltZVVuaXQ6IFwieWVhclwifVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNjYWxlID0gbW9kZWwuZ2V0U2NhbGVDb21wb25lbnQoJ2NvbG9yJyk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWRkIGNvcnJlY3Qgc2NhbGVzJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChzY2FsZS5pbXBsaWNpdC5uYW1lLCAnY29sb3InKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlLmltcGxpY2l0LnR5cGUsICdzZXF1ZW50aWFsJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZWxlY3Rpb24gZG9tYWluJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICAgICAgbWFyazogXCJhcmVhXCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge1xuICAgICAgICAgICAgZmllbGQ6IFwiZGF0ZVwiLCB0eXBlOiBcInRlbXBvcmFsXCIsXG4gICAgICAgICAgICBzY2FsZToge2RvbWFpbjoge3NlbGVjdGlvbjogXCJicnVzaFwiLCBlbmNvZGluZzogXCJ4XCJ9fSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHk6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcImRhdGVcIiwgdHlwZTogXCJ0ZW1wb3JhbFwiLFxuICAgICAgICAgICAgc2NhbGU6IHtkb21haW46IHtzZWxlY3Rpb246IFwiZm9vYmFyXCIsIGZpZWxkOiBcIk1pbGVzX3Blcl9HYWxsb25cIn19LFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHhTY2FsZSA9IG1vZGVsLmdldFNjYWxlQ29tcG9uZW50KCd4Jyk7XG4gICAgICBjb25zdCB5c2NhbGUgPSBtb2RlbC5nZXRTY2FsZUNvbXBvbmVudCgneScpO1xuICAgICAgaXQoJ3Nob3VsZCBhZGQgYSByYXcgc2VsZWN0aW9uIGRvbWFpbicsIGZ1bmN0aW9uKCkge1xuICAgICAgICBhc3NlcnQucHJvcGVydHkoeFNjYWxlLmV4cGxpY2l0LCAnZG9tYWluUmF3Jyk7XG4gICAgICAgIGFzc2VydC5wcm9wZXJ0eVZhbCh4U2NhbGUuZXhwbGljaXQuZG9tYWluUmF3LCAnc2lnbmFsJyxcbiAgICAgICAgICBTRUxFQ1RJT05fRE9NQUlOICsgJ3tcInNlbGVjdGlvblwiOlwiYnJ1c2hcIixcImVuY29kaW5nXCI6XCJ4XCJ9Jyk7XG5cbiAgICAgICAgYXNzZXJ0LnByb3BlcnR5KHlzY2FsZS5leHBsaWNpdCwgJ2RvbWFpblJhdycpO1xuICAgICAgICBhc3NlcnQucHJvcGVydHlWYWwoeXNjYWxlLmV4cGxpY2l0LmRvbWFpblJhdywgJ3NpZ25hbCcsXG4gICAgICAgICAgU0VMRUNUSU9OX0RPTUFJTiArICd7XCJzZWxlY3Rpb25cIjpcImZvb2JhclwiLFwiZmllbGRcIjpcIk1pbGVzX3Blcl9HYWxsb25cIn0nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/scale/properties.test.js b/build/test/compile/scale/properties.test.js new file mode 100644 index 0000000000..3f24ebee58 --- /dev/null +++ b/build/test/compile/scale/properties.test.js @@ -0,0 +1,129 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var rules = require("../../../src/compile/scale/properties"); +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]; + chai_1.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]; + chai_1.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]; + chai_1.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]; + chai_1.assert.equal(rules.padding(c, 'point', { pointPadding: 13 }, undefined, undefined, undefined), 13); + } + }); + it('should be continuousBandSize for linear x-scale of vertical bar.', function () { + chai_1.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 () { + chai_1.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 () { + chai_1.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 () { + chai_1.assert.equal(rules.paddingInner(10, 'x', {}), undefined); + }); + it('should be bandPaddingInner if channel is x or y and padding is not specified.', function () { + chai_1.assert.equal(rules.paddingInner(undefined, 'x', { bandPaddingInner: 15 }), 15); + chai_1.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 = channel_1.NONPOSITION_SCALE_CHANNELS; _i < NONPOSITION_SCALE_CHANNELS_1.length; _i++) { + var c = NONPOSITION_SCALE_CHANNELS_1[_i]; + chai_1.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]; + chai_1.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]; + chai_1.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]; + chai_1.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 = channel_1.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]; + chai_1.assert.equal(rules.paddingOuter(undefined, c, scaleType, 0, {}), undefined); + } + } + }); + }); + describe('reverse', function () { + it('should return true for a continuous scale with sort = "descending".', function () { + chai_1.assert.isTrue(rules.reverse('linear', 'descending')); + }); + it('should return false for a discrete scale with sort = "descending".', function () { + chai_1.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 () { + chai_1.assert(rules.zero('x', { field: 'a', type: 'quantitative' }, 'unaggregated')); + }); + it('should return true when mapping a quantitative field to size', function () { + chai_1.assert(rules.zero('size', { field: 'a', type: 'quantitative' }, undefined)); + }); + it('should return false when mapping a ordinal field to size', function () { + chai_1.assert(!rules.zero('size', { field: 'a', type: 'ordinal' }, undefined)); + }); + it('should return true when mapping a non-binned quantitative field to x/y', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(rules.zero(channel, { field: 'a', type: 'quantitative' }, undefined)); + } + }); + 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]; + chai_1.assert(!rules.zero(channel, { bin: true, field: 'a', type: 'quantitative' }, undefined)); + } + }); + 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]; + chai_1.assert(!rules.zero(channel, { + bin: true, field: 'a', type: 'quantitative' + }, [3, 5])); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NjYWxlL3Byb3BlcnRpZXMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIsZ0RBQXlFO0FBR3pFLDZEQUErRDtBQUUvRCxRQUFRLENBQUMsZUFBZSxFQUFFO0lBQ3hCLFFBQVEsQ0FBQyxNQUFNLEVBQUU7UUFDZixFQUFFLENBQUMsaUNBQWlDLEVBQUU7WUFDcEMsR0FBRyxDQUFDLENBQVksVUFBdUIsRUFBdkIsS0FBQSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQWMsRUFBdkIsY0FBdUIsRUFBdkIsSUFBdUI7Z0JBQWxDLElBQU0sQ0FBQyxTQUFBO2dCQUNWLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDckU7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRTtZQUMvQyxHQUFHLENBQUMsQ0FBWSxVQUF1QixFQUF2QixLQUFBLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBYyxFQUF2QixjQUF1QixFQUF2QixJQUF1QjtnQkFBbEMsSUFBTSxDQUFDLFNBQUE7Z0JBQ1YsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ3JGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsR0FBRyxDQUFDLENBQVksVUFBdUIsRUFBdkIsS0FBQSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQWMsRUFBdkIsY0FBdUIsRUFBdkIsSUFBdUI7Z0JBQWxDLElBQU0sQ0FBQyxTQUFBO2dCQUNWLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLFVBQVUsRUFBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDcEU7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUMsMkZBQTJGLEVBQUU7WUFDOUYsR0FBRyxDQUFDLENBQVksVUFBdUIsRUFBdkIsS0FBQSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQWMsRUFBdkIsY0FBdUIsRUFBdkIsSUFBdUI7Z0JBQWxDLElBQU0sQ0FBQyxTQUFBO2dCQUNWLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUMsWUFBWSxFQUFFLEVBQUUsRUFBQyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDbEc7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrRUFBa0UsRUFBRTtZQUNyRSxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBQyxFQUFFLEVBQUMsa0JBQWtCLEVBQUUsRUFBRSxFQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNySixDQUFDLENBQUMsQ0FBQztRQUdILEVBQUUsQ0FBQywwRUFBMEUsRUFBRTtZQUM3RSxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDLEVBQUUsRUFBQyxrQkFBa0IsRUFBRSxFQUFFLEVBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZLLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9FQUFvRSxFQUFFO1lBQ3ZFLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFDLEVBQUUsRUFBQyxrQkFBa0IsRUFBRSxFQUFFLEVBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMzRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrRUFBK0UsRUFBRTtZQUNsRixhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxFQUFDLGdCQUFnQixFQUFFLEVBQUUsRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDN0UsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsRUFBQyxnQkFBZ0IsRUFBRSxFQUFFLEVBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFO1lBQzdDLEdBQUcsQ0FBQyxDQUFZLFVBQTBCLEVBQTFCLCtCQUFBLG9DQUEwQixFQUExQix3Q0FBMEIsRUFBMUIsSUFBMEI7Z0JBQXJDLElBQU0sQ0FBQyxtQ0FBQTtnQkFDVixhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFDLGdCQUFnQixFQUFFLEVBQUUsRUFBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDbkY7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsR0FBRyxDQUFDLENBQW9CLFVBQWdDLEVBQWhDLEtBQUEsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFnQixFQUFoQyxjQUFnQyxFQUFoQyxJQUFnQztnQkFBbkQsSUFBTSxTQUFTLFNBQUE7Z0JBQ2xCLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDeEU7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2SUFBNkksRUFBRTtZQUNoSixHQUFHLENBQUMsQ0FBWSxVQUF1QixFQUF2QixLQUFBLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBYyxFQUF2QixjQUF1QixFQUF2QixJQUF1QjtnQkFBbEMsSUFBTSxDQUFDLFNBQUE7Z0JBQ1YsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFDLGdCQUFnQixFQUFFLEVBQUUsRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDdkY7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILEVBQUUsQ0FBQyw4SEFBOEgsRUFBRTtZQUNqSSxHQUFHLENBQUMsQ0FBWSxVQUF1QixFQUF2QixLQUFBLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBYyxFQUF2QixjQUF1QixFQUF2QixJQUF1QjtnQkFBbEMsSUFBTSxDQUFDLFNBQUE7Z0JBQ1YsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUNuRTtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFO1lBQzdDLEdBQUcsQ0FBQyxDQUFZLFVBQTBCLEVBQTFCLCtCQUFBLG9DQUEwQixFQUExQix3Q0FBMEIsRUFBMUIsSUFBMEI7Z0JBQXJDLElBQU0sQ0FBQyxtQ0FBQTtnQkFDVixHQUFHLENBQUMsQ0FBb0IsVUFBZ0MsRUFBaEMsS0FBQSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQWdCLEVBQWhDLGNBQWdDLEVBQWhDLElBQWdDO29CQUFuRCxJQUFNLFNBQVMsU0FBQTtvQkFDbEIsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztpQkFDN0U7YUFDRjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyxxRUFBcUUsRUFBRTtZQUN4RSxhQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0VBQW9FLEVBQUU7WUFDdkUsYUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsTUFBTSxFQUFFO1FBQ2YsRUFBRSxDQUFDLDhGQUE4RixFQUFFO1lBQ2pHLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDOUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOERBQThELEVBQUU7WUFDakUsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwREFBMEQsRUFBRTtZQUM3RCxhQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0VBQXdFLEVBQUU7WUFDM0UsR0FBRyxDQUFDLENBQWtCLFVBQXVCLEVBQXZCLEtBQUEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFjLEVBQXZCLGNBQXVCLEVBQXZCLElBQXVCO2dCQUF4QyxJQUFNLE9BQU8sU0FBQTtnQkFDaEIsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQzthQUM1RTtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFFQUFxRSxFQUFFO1lBQ3hFLEdBQUcsQ0FBQyxDQUFrQixVQUF1QixFQUF2QixLQUFBLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBYyxFQUF2QixjQUF1QixFQUF2QixJQUF1QjtnQkFBeEMsSUFBTSxPQUFPLFNBQUE7Z0JBQ2hCLGFBQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO2FBQ3hGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNEZBQTRGLEVBQUU7WUFDL0YsR0FBRyxDQUFDLENBQWtCLFVBQXVCLEVBQXZCLEtBQUEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFjLEVBQXZCLGNBQXVCLEVBQXZCLElBQXVCO2dCQUF4QyxJQUFNLE9BQU8sU0FBQTtnQkFDaEIsYUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7b0JBQzFCLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYztpQkFDNUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDYjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5cbmltcG9ydCB7Q2hhbm5lbCwgTk9OUE9TSVRJT05fU0NBTEVfQ0hBTk5FTFN9IGZyb20gJy4uLy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuLi8uLi8uLi9zcmMvc2NhbGUnO1xuXG5pbXBvcnQgKiBhcyBydWxlcyBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9wcm9wZXJ0aWVzJztcblxuZGVzY3JpYmUoJ2NvbXBpbGUvc2NhbGUnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCduaWNlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIG5pY2UgZm9yIHggYW5kIHkuJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIFsneCcsICd5J10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChydWxlcy5uaWNlKCdsaW5lYXInLCBjLCB7dHlwZTogJ3F1YW50aXRhdGl2ZSd9KSwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCByZXR1cm4gbmljZSBmb3IgYmlubmVkIHggYW5kIHkuJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIFsneCcsICd5J10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChydWxlcy5uaWNlKCdsaW5lYXInLCBjLCB7dHlwZTogJ3F1YW50aXRhdGl2ZScsIGJpbjogdHJ1ZX0pLCB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgcmV0dXJuIG5pY2UgZm9yIHRlbXBvcmFsIHggYW5kIHkuJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIFsneCcsICd5J10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChydWxlcy5uaWNlKCd0aW1lJywgYywge3R5cGU6ICd0ZW1wb3JhbCd9KSwgdW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3BhZGRpbmcnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSBwb2ludFBhZGRpbmcgZm9yIHBvaW50IHNjYWxlIGlmIGNoYW5uZWwgaXMgeCBvciB5IGFuZCBwYWRkaW5nIGlzIG5vdCBzcGVjaWZpZWQuJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIFsneCcsICd5J10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChydWxlcy5wYWRkaW5nKGMsICdwb2ludCcsIHtwb2ludFBhZGRpbmc6IDEzfSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCksIDEzKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgY29udGludW91c0JhbmRTaXplIGZvciBsaW5lYXIgeC1zY2FsZSBvZiB2ZXJ0aWNhbCBiYXIuJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKHJ1bGVzLnBhZGRpbmcoJ3gnLCAnbGluZWFyJywge30sIHtmaWVsZDogJ2RhdGUnLCB0eXBlOiAndGVtcG9yYWwnfSwge3R5cGU6ICdiYXInLCBvcmllbnQ6ICd2ZXJ0aWNhbCd9LCB7Y29udGludW91c0JhbmRTaXplOiAxM30pLCAxMyk7XG4gICAgfSk7XG5cblxuICAgIGl0KCdzaG91bGQgYmUgdW5kZWZpbmVkIGZvciBsaW5lYXIgeC1zY2FsZSBmb3IgYmlubmVkIGZpZWxkIG9mIHZlcnRpY2FsIGJhci4nLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwocnVsZXMucGFkZGluZygneCcsICdsaW5lYXInLCB7fSwge2JpbjogdHJ1ZSwgZmllbGQ6ICdkYXRlJywgdHlwZTogJ3RlbXBvcmFsJ30sIHt0eXBlOiAnYmFyJywgb3JpZW50OiAndmVydGljYWwnfSwge2NvbnRpbnVvdXNCYW5kU2l6ZTogMTN9KSwgdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgY29udGludW91c0JhbmRTaXplIGZvciBsaW5lYXIgeS1zY2FsZSBvZiBob3Jpem9udGFsIGJhci4nLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwocnVsZXMucGFkZGluZygneScsICdsaW5lYXInLCB7fSwge2ZpZWxkOiAnZGF0ZScsIHR5cGU6ICd0ZW1wb3JhbCd9LCB7dHlwZTogJ2JhcicsIG9yaWVudDogJ2hvcml6b250YWwnfSwge2NvbnRpbnVvdXNCYW5kU2l6ZTogMTN9KSwgMTMpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFkZGluZ0lubmVyJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYmUgdW5kZWZpbmVkIGlmIHBhZGRpbmcgaXMgc3BlY2lmaWVkLicsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChydWxlcy5wYWRkaW5nSW5uZXIoMTAsICd4Jywge30pLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBiYW5kUGFkZGluZ0lubmVyIGlmIGNoYW5uZWwgaXMgeCBvciB5IGFuZCBwYWRkaW5nIGlzIG5vdCBzcGVjaWZpZWQuJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKHJ1bGVzLnBhZGRpbmdJbm5lcih1bmRlZmluZWQsICd4Jywge2JhbmRQYWRkaW5nSW5uZXI6IDE1fSksIDE1KTtcbiAgICAgIGFzc2VydC5lcXVhbChydWxlcy5wYWRkaW5nSW5uZXIodW5kZWZpbmVkLCAneScsIHtiYW5kUGFkZGluZ0lubmVyOiAxNX0pLCAxNSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIHVuZGVmaW5lZCBmb3Igbm9uLXh5IGNoYW5uZWxzLicsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgYyBvZiBOT05QT1NJVElPTl9TQ0FMRV9DSEFOTkVMUykge1xuICAgICAgICBhc3NlcnQuZXF1YWwocnVsZXMucGFkZGluZ0lubmVyKHVuZGVmaW5lZCwgYywge2JhbmRQYWRkaW5nSW5uZXI6IDE1fSksIHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYWRkaW5nT3V0ZXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSB1bmRlZmluZWQgaWYgcGFkZGluZyBpcyBzcGVjaWZpZWQuJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBzY2FsZVR5cGUgb2YgWydwb2ludCcsICdiYW5kJ10gYXMgU2NhbGVUeXBlW10pIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHJ1bGVzLnBhZGRpbmdPdXRlcigxMCwgJ3gnLCBzY2FsZVR5cGUsIDAsIHt9KSwgdW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgY29uZmlnLnNjYWxlLmJhbmRQYWRkaW5nT3V0ZXIgZm9yIGJhbmQgc2NhbGUgaWYgY2hhbm5lbCBpcyB4IG9yIHkgYW5kIHBhZGRpbmcgaXMgbm90IHNwZWNpZmllZCBhbmQgY29uZmlnLnNjYWxlLmJhbmRQYWRkaW5nT3V0ZXIuJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIFsneCcsICd5J10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChydWxlcy5wYWRkaW5nT3V0ZXIodW5kZWZpbmVkLCBjLCAnYmFuZCcsIDAsIHtiYW5kUGFkZGluZ091dGVyOiAxNn0pLCAxNik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBiZSBwYWRkaW5nSW5uZXIvMiBmb3IgYmFuZCBzY2FsZSBpZiBjaGFubmVsIGlzIHggb3IgeSBhbmQgcGFkZGluZyBpcyBub3Qgc3BlY2lmaWVkIGFuZCBjb25maWcuc2NhbGUuYmFuZFBhZGRpbmdPdXRlci4nLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGMgb2YgWyd4JywgJ3knXSBhcyBDaGFubmVsW10pIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHJ1bGVzLnBhZGRpbmdPdXRlcih1bmRlZmluZWQsIGMsICdiYW5kJywgMTAsIHt9KSwgNSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIHVuZGVmaW5lZCBmb3Igbm9uLXh5IGNoYW5uZWxzLicsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgYyBvZiBOT05QT1NJVElPTl9TQ0FMRV9DSEFOTkVMUykge1xuICAgICAgICBmb3IgKGNvbnN0IHNjYWxlVHlwZSBvZiBbJ3BvaW50JywgJ2JhbmQnXSBhcyBTY2FsZVR5cGVbXSkge1xuICAgICAgICAgIGFzc2VydC5lcXVhbChydWxlcy5wYWRkaW5nT3V0ZXIodW5kZWZpbmVkLCBjLCBzY2FsZVR5cGUsIDAsIHt9KSwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmV2ZXJzZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBhIGNvbnRpbnVvdXMgc2NhbGUgd2l0aCBzb3J0ID0gXCJkZXNjZW5kaW5nXCIuJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShydWxlcy5yZXZlcnNlKCdsaW5lYXInLCAnZGVzY2VuZGluZycpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBhIGRpc2NyZXRlIHNjYWxlIHdpdGggc29ydCA9IFwiZGVzY2VuZGluZ1wiLicsICgpID0+IHtcbiAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChydWxlcy5yZXZlcnNlKCdwb2ludCcsICdkZXNjZW5kaW5nJykpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnemVybycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gbWFwcGluZyBhIHF1YW50aXRhdGl2ZSBmaWVsZCB0byB4IHdpdGggc2NhbGUuZG9tYWluID0gXCJ1bmFnZ3JlZ2F0ZWRcIicsICgpID0+IHtcbiAgICAgIGFzc2VydChydWxlcy56ZXJvKCd4Jywge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwgJ3VuYWdncmVnYXRlZCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiBtYXBwaW5nIGEgcXVhbnRpdGF0aXZlIGZpZWxkIHRvIHNpemUnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQocnVsZXMuemVybygnc2l6ZScsIHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sIHVuZGVmaW5lZCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiBtYXBwaW5nIGEgb3JkaW5hbCBmaWVsZCB0byBzaXplJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0KCFydWxlcy56ZXJvKCdzaXplJywge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ30sIHVuZGVmaW5lZCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIG1hcHBpbmcgYSBub24tYmlubmVkIHF1YW50aXRhdGl2ZSBmaWVsZCB0byB4L3knLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWyd4JywgJ3knXSBhcyBDaGFubmVsW10pIHtcbiAgICAgICAgYXNzZXJ0KHJ1bGVzLnplcm8oY2hhbm5lbCwge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwgdW5kZWZpbmVkKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSB3aGVuIG1hcHBpbmcgYSBiaW5uZWQgcXVhbnRpdGF0aXZlIGZpZWxkIHRvIHgveScsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBbJ3gnLCAneSddIGFzIENoYW5uZWxbXSkge1xuICAgICAgICBhc3NlcnQoIXJ1bGVzLnplcm8oY2hhbm5lbCwge2JpbjogdHJ1ZSwgZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LCB1bmRlZmluZWQpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIHdoZW4gbWFwcGluZyBhIG5vbi1iaW5uZWQgcXVhbnRpdGF0aXZlIGZpZWxkIHdpdGggY3VzdG9tIGRvbWFpbiB0byB4L3knLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWyd4JywgJ3knXSBhcyBDaGFubmVsW10pIHtcbiAgICAgICAgYXNzZXJ0KCFydWxlcy56ZXJvKGNoYW5uZWwsIHtcbiAgICAgICAgICBiaW46IHRydWUsIGZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnXG4gICAgICAgIH0sIFszLCA1XSkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/scale/range.test.js b/build/test/compile/scale/range.test.js new file mode 100644 index 0000000000..1e7b0c70a9 --- /dev/null +++ b/build/test/compile/scale/range.test.js @@ -0,0 +1,203 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var range_1 = require("../../../src/compile/scale/range"); +var split_1 = require("../../../src/compile/split"); +var config_1 = require("../../../src/config"); +var log = require("../../../src/log"); +var scale_1 = require("../../../src/scale"); +var type_1 = require("../../../src/type"); +describe('compile/scale', function () { + describe('parseRange()', function () { + describe('position', function () { + it('should return [0, plot_width] for x-continous scales by default.', function () { + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_1 = scale_1.CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_1.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_1[_i]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, 'point', false, 'plot_width', []), split_1.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 = scale_1.CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_2.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_2[_i]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('y', scaleType, type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, 'point', false, 'plot_height', []), split_1.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 = scale_1.DISCRETE_DOMAIN_SCALES; _i < DISCRETE_DOMAIN_SCALES_1.length; _i++) { + var scaleType = DISCRETE_DOMAIN_SCALES_1[_i]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('y', scaleType, type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, 'point', true, 'plot_height', []), split_1.makeImplicit([0, { signal: 'plot_height' }])); + } + }); + it('should support custom range.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', 'linear', type_1.QUANTITATIVE, { range: [0, 100] }, config_1.defaultConfig, true, 'point', false, 'plot_width', []), split_1.makeExplicit([0, 100])); + chai_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, {}, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, {}, { scale: { textXRangeStep: 55 } }, undefined, 'text', false, 'plot_width', []), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, { rangeStep: 23 }, config_1.defaultConfig, undefined, 'text', false, 'plot_width', []), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, { rangeStep: 23 }, config_1.defaultConfig, undefined, 'text', true, 'plot_width', []), split_1.makeImplicit([0, { signal: 'plot_width' }])); + } + chai_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, { rangeStep: null }, config_1.defaultConfig, undefined, 'text', false, 'plot_width', []), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, {}, { view: { width: 200 }, scale: { rangeStep: null } }, undefined, 'point', false, 'plot_width', []), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.NOMINAL, {}, { view: { width: 200 }, scale: { textXRangeStep: null } }, undefined, 'text', false, 'plot_width', []), split_1.makeImplicit([0, { signal: 'plot_width' }])); + } + }); + it('should drop rangeStep for continuous scales', function () { + var _loop_1 = function (scaleType) { + log.wrap(function (localLogger) { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('x', scaleType, type_1.QUANTITATIVE, { rangeStep: 23 }, config_1.defaultConfig, undefined, 'text', true, 'plot_width', []), split_1.makeImplicit([0, { signal: 'plot_width' }])); + chai_1.assert.equal(localLogger.warns[0], log.message.scalePropertyNotWorkWithScaleType(scaleType, 'rangeStep', 'x')); + })(); + }; + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_3 = scale_1.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 () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'ordinal', type_1.NOMINAL, { scheme: 'warm' }, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeExplicit({ scheme: 'warm' })); + }); + it('should use the specified scheme with extent for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'ordinal', type_1.NOMINAL, { scheme: { name: 'warm', extent: [0.2, 1] } }, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeExplicit({ scheme: 'warm', extent: [0.2, 1] })); + }); + it('should use the specified range for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'ordinal', type_1.NOMINAL, { range: ['red', 'green', 'blue'] }, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeExplicit(['red', 'green', 'blue'])); + }); + it('should use default category range in Vega for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'ordinal', type_1.NOMINAL, {}, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeImplicit('category')); + }); + it('should use default ordinal range in Vega for an ordinal color field.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'ordinal', type_1.ORDINAL, {}, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeImplicit('ordinal')); + }); + it('should use default ramp range in Vega for a temporal/quantitative color field.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'sequential', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeImplicit('ramp')); + }); + it('should use the specified scheme with count for a quantitative color field.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('color', 'ordinal', type_1.QUANTITATIVE, { scheme: { name: 'viridis', count: 3 } }, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeExplicit({ scheme: 'viridis', count: 3 })); + }); + }); + describe('opacity', function () { + it('should use default opacityRange as opacity\'s scale range.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('opacity', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeImplicit([config_1.defaultConfig.scale.minOpacity, config_1.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 } + }; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config, undefined, 'bar', false, 'plot_width', []), split_1.makeImplicit([2, 9])); + }); + it('should return [continuousBandSize, xRangeStep-1] by default since min/maxSize config are not specified', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'bar', false, 'plot_width', []), split_1.makeImplicit([2, config_1.defaultConfig.scale.rangeStep - 1])); + }); + }); + describe('tick', function () { + it('should return [minBandSize, maxBandSize] if both are specified', function () { + var config = { + scale: { minBandSize: 4, maxBandSize: 9 } + }; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config, undefined, 'tick', false, 'plot_width', []), split_1.makeImplicit([4, 9])); + }); + it('should return [(default)minBandSize, rangeStep-1] by default since maxSize config is not specified', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'tick', false, 'plot_width', []), split_1.makeImplicit([config_1.defaultConfig.scale.minBandSize, config_1.defaultConfig.scale.rangeStep - 1])); + }); + }); + describe('text', function () { + it('should return [minFontSize, maxFontSize]', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'text', false, 'plot_width', []), split_1.makeImplicit([config_1.defaultConfig.scale.minFontSize, config_1.defaultConfig.scale.maxFontSize])); + }); + }); + describe('rule', function () { + it('should return [minStrokeWidth, maxStrokeWidth]', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'rule', false, 'plot_width', []), split_1.makeImplicit([config_1.defaultConfig.scale.minStrokeWidth, config_1.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 + } + }; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config, undefined, m, false, 'plot_width', []), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, m, false, 'plot_width', [11, 13] // xyRangeSteps + ), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, false, m, false, 'plot_width', [11, 13] // xyRangeSteps + ), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, false, m, false, 'plot_width', [11, 13] // xyRangeSteps + ), split_1.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]; + chai_1.assert.deepEqual(range_1.parseRangeForChannel('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, m, false, 'plot_width', [11] // xyRangeSteps only have one value + ), split_1.makeImplicit([0, 81])); + } + }); + }); + }); + describe('shape', function () { + it('should use default symbol range in Vega as shape\'s scale range.', function () { + chai_1.assert.deepEqual(range_1.parseRangeForChannel('shape', 'ordinal', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'point', false, 'plot_width', []), split_1.makeImplicit('symbol')); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zY2FsZS9yYW5nZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUU1QiwwREFBc0U7QUFDdEUsb0RBQXNFO0FBQ3RFLDhDQUFrRDtBQUNsRCxzQ0FBd0M7QUFFeEMsNENBQXNHO0FBQ3RHLDBDQUFpRTtBQUVqRSxRQUFRLENBQUMsZUFBZSxFQUFFO0lBQ3hCLFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDdkIsUUFBUSxDQUFDLFVBQVUsRUFBRTtZQUNuQixFQUFFLENBQUMsa0VBQWtFLEVBQUU7Z0JBQ3JFLEdBQUcsQ0FBQyxDQUFvQixVQUErQixFQUEvQixvQ0FBQSx1Q0FBK0IsRUFBL0IsNkNBQStCLEVBQS9CLElBQStCO29CQUFsRCxJQUFNLFNBQVMsd0NBQUE7b0JBQ2xCLGFBQU0sQ0FBQyxTQUFTLENBQ2QsNEJBQW9CLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxtQkFBWSxFQUFFLEVBQUUsRUFBRSxzQkFBYSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxFQUFFLENBQUMsRUFDN0csb0JBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUMsQ0FBQyxDQUFDLENBQzFDLENBQUM7aUJBQ0g7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxtRUFBbUUsRUFBRTtnQkFDdEUsR0FBRyxDQUFDLENBQW9CLFVBQStCLEVBQS9CLG9DQUFBLHVDQUErQixFQUEvQiw2Q0FBK0IsRUFBL0IsSUFBK0I7b0JBQWxELElBQU0sU0FBUyx3Q0FBQTtvQkFDbEIsYUFBTSxDQUFDLFNBQVMsQ0FDZCw0QkFBb0IsQ0FBQyxHQUFHLEVBQUUsU0FBUyxFQUFFLG1CQUFZLEVBQUUsRUFBRSxFQUFFLHNCQUFhLEVBQUUs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QUE7d0JBQ1osYUFBTSxDQUFDLFNBQVMsQ0FDZCw0QkFBb0IsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLG1CQUFZLEVBQUUsRUFBRSxFQUFFLHNCQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUNsRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLG1DQUFtQzt5QkFDekMsRUFDRCxvQkFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQ3RCLENBQUM7cUJBQ0g7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLE9BQU8sRUFBRTtZQUNoQixFQUFFLENBQUMsa0VBQWtFLEVBQUU7Z0JBQ3JFLGFBQU0sQ0FBQyxTQUFTLENBQ2QsNEJBQW9CLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxtQkFBWSxFQUFFLEVBQUUsRUFBRSxzQkFBYSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxFQUFFLENBQUMsRUFDdEgsb0JBQVksQ0FBQyxRQUFRLENBQUMsQ0FDdkIsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcblxuaW1wb3J0IHtwYXJzZVJhbmdlRm9yQ2hhbm5lbH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvcmFuZ2UnO1xuaW1wb3J0IHttYWtlRXhwbGljaXQsIG1ha2VJbXBsaWNpdH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc3BsaXQnO1xuaW1wb3J0IHtkZWZhdWx0Q29uZmlnfSBmcm9tICcuLi8uLi8uLi9zcmMvY29uZmlnJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi8uLi9zcmMvbG9nJztcbmltcG9ydCB7TWFya30gZnJvbSAnLi4vLi4vLi4vc3JjL21hcmsnO1xuaW1wb3J0IHtDT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfU0NBTEVTLCBESVNDUkVURV9ET01BSU5fU0NBTEVTLCBTY2FsZVR5cGV9IGZyb20gJy4uLy4uLy4uL3NyYy9zY2FsZSc7XG5pbXBvcnQge05PTUlOQUwsIE9SRElOQUwsIFFVQU5USVRBVElWRX0gZnJvbSAnLi4vLi4vLi4vc3JjL3R5cGUnO1xuXG5kZXNjcmliZSgnY29tcGlsZS9zY2FsZScsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3BhcnNlUmFuZ2UoKScsIGZ1bmN0aW9uKCkge1xuICAgIGRlc2NyaWJlKCdwb3NpdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIFswLCBwbG90X3dpZHRoXSBmb3IgeC1jb250aW5vdXMgc2NhbGVzIGJ5IGRlZmF1bHQuJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHNjYWxlVHlwZSBvZiBDT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfU0NBTEVTKSB7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4Jywgc2NhbGVUeXBlLCBRVUFOVElUQVRJVkUsIHt9LCBkZWZhdWx0Q29uZmlnLCB0cnVlLCAncG9pbnQnLCBmYWxzZSwgJ3Bsb3Rfd2lkdGgnLCBbXSksXG4gICAgICAgICAgICBtYWtlSW1wbGljaXQoWzAsIHtzaWduYWw6ICdwbG90X3dpZHRoJ31dKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBbcGxvdF9oZWlnaHQsMF0gZm9yIHktY29udGludW91cyBzY2FsZXMgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIENPTlRJTlVPVVNfVE9fQ09OVElOVU9VU19TQ0FMRVMpIHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3knLCBzY2FsZVR5cGUsIFFVQU5USVRBVElWRSwge30sIGRlZmF1bHRDb25maWcsIHRydWUsICdwb2ludCcsIGZhbHNlLCAncGxvdF9oZWlnaHQnLCBbXSksXG4gICAgICAgICAgICBtYWtlSW1wbGljaXQoW3tzaWduYWw6ICdwbG90X2hlaWdodCd9LCAwXSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gWzAsIHBsb3RfaGVpZ2h0XSBmb3IgeS1kaXNjcmV0ZSBzY2FsZXMgd2l0aCBoZWlnaHQgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIERJU0NSRVRFX0RPTUFJTl9TQ0FMRVMpIHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3knLCBzY2FsZVR5cGUsIFFVQU5USVRBVElWRSwge30sIGRlZmF1bHRDb25maWcsIHRydWUsICdwb2ludCcsIHRydWUsICdwbG90X2hlaWdodCcsIFtdKSxcbiAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbMCwge3NpZ25hbDogJ3Bsb3RfaGVpZ2h0J31dKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN1cHBvcnQgY3VzdG9tIHJhbmdlLicsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4JywgJ2xpbmVhcicsIFFVQU5USVRBVElWRSwge3JhbmdlOiBbMCwgMTAwXX0sIGRlZmF1bHRDb25maWcsIHRydWUsICdwb2ludCcsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICBtYWtlRXhwbGljaXQoWzAsIDEwMF0pXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwobG9jYWxMb2dnZXIud2FybnMubGVuZ3RoLCAwKTtcbiAgICAgIH0pKTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gY29uZmlnLnNjYWxlLnJhbmdlU3RlcCBmb3IgYmFuZC9wb2ludCBzY2FsZXMgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIFsncG9pbnQnLCAnYmFuZCddIGFzIFNjYWxlVHlwZVtdKSB7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4Jywgc2NhbGVUeXBlLCBOT01JTkFMLCB7fSwgZGVmYXVsdENvbmZpZywgdW5kZWZpbmVkLCAncG9pbnQnLCBmYWxzZSwgJ3Bsb3Rfd2lkdGgnLCBbXSksXG4gICAgICAgICAgICBtYWtlSW1wbGljaXQoe3N0ZXA6IDIxfSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gY29uZmlnLnNjYWxlLnRleHRYUmFuZ2VTdGVwIGJ5IGRlZmF1bHQgZm9yIHRleHQgbWFya1xcJ3MgeCBiYW5kL3BvaW50IHNjYWxlcy4nLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIFsncG9pbnQnLCAnYmFuZCddIGFzIFNjYWxlVHlwZVtdKSB7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4Jywgc2NhbGVUeXBlLCBOT01JTkFMLCB7fSwge3NjYWxlOiB7dGV4dFhSYW5nZVN0ZXA6IDU1fX0sIHVuZGVmaW5lZCwgJ3RleHQnLCBmYWxzZSwgJ3Bsb3Rfd2lkdGgnLCBbXSksXG4gICAgICAgICAgICBtYWtlSW1wbGljaXQoe3N0ZXA6IDU1fSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gc3BlY2lmaWVkIHJhbmdlU3RlcCBpZiB0b3BMZXZlbFNpemUgaXMgdW5kZWZpbmVkIGZvciBiYW5kL3BvaW50IHNjYWxlcycsICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBzY2FsZVR5cGUgb2YgWydwb2ludCcsICdiYW5kJ10gYXMgU2NhbGVUeXBlW10pIHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3gnLCBzY2FsZVR5cGUsIE5PTUlOQUwsIHtyYW5nZVN0ZXA6IDIzfSwgZGVmYXVsdENvbmZpZywgdW5kZWZpbmVkLCAndGV4dCcsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICAgIG1ha2VFeHBsaWNpdCh7c3RlcDogMjN9KVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGRyb3AgcmFuZ2VTdGVwIGlmIHRvcExldmVsU2l6ZSBpcyBzcGVjaWZpZWQgZm9yIGJhbmQvcG9pbnQgc2NhbGVzJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIFsncG9pbnQnLCAnYmFuZCddIGFzIFNjYWxlVHlwZVtdKSB7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4Jywgc2NhbGVUeXBlLCBOT01JTkFMLCB7cmFuZ2VTdGVwOiAyM30sIGRlZmF1bHRDb25maWcsIHVuZGVmaW5lZCwgJ3RleHQnLCB0cnVlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbMCwge3NpZ25hbDogJ3Bsb3Rfd2lkdGgnfV0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLnJhbmdlU3RlcERyb3BwZWQoJ3gnKSk7XG4gICAgICB9KSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRlZmF1bHQgdG9wTGV2ZWxTaXplIGlmIHJhbmdlU3RlcCBpcyBudWxsIGZvciBiYW5kL3BvaW50IHNjYWxlcycsICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBzY2FsZVR5cGUgb2YgWydwb2ludCcsICdiYW5kJ10gYXMgU2NhbGVUeXBlW10pIHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3gnLCBzY2FsZVR5cGUsIE5PTUlOQUwsIHtyYW5nZVN0ZXA6IG51bGx9LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICd0ZXh0JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgbWFrZUltcGxpY2l0KFswLCB7c2lnbmFsOiAncGxvdF93aWR0aCd9XSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZGVmYXVsdCB0b3BMZXZlbFNpemUgaWYgcmFuZ2VTdGVwIGNvbmZpZyBpcyBudWxsJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHNjYWxlVHlwZSBvZiBbJ3BvaW50JywgJ2JhbmQnXSBhcyBTY2FsZVR5cGVbXSkge1xuICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgneCcsIHNjYWxlVHlwZSwgTk9NSU5BTCwge30sIHt2aWV3OiB7d2lkdGg6IDIwMH0sIHNjYWxlOiB7cmFuZ2VTdGVwOiBudWxsfX0sIHVuZGVmaW5lZCwgJ3BvaW50JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgbWFrZUltcGxpY2l0KFswLCB7c2lnbmFsOiAncGxvdF93aWR0aCd9XSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZGVmYXVsdCB0b3BMZXZlbFNpemUgZm9yIHRleHQgaWYgdGV4dFhSYW5nZVN0ZXAgY29uZmlnIGlzIG51bGwnLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIFsncG9pbnQnLCAnYmFuZCddIGFzIFNjYWxlVHlwZVtdKSB7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4Jywgc2NhbGVUeXBlLCBOT01JTkFMLCB7fSwge3ZpZXc6IHt3aWR0aDogMjAwfSwgc2NhbGU6IHt0ZXh0WFJhbmdlU3RlcDogbnVsbH19LCB1bmRlZmluZWQsICd0ZXh0JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgbWFrZUltcGxpY2l0KFswLCB7c2lnbmFsOiAncGxvdF93aWR0aCd9XSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBkcm9wIHJhbmdlU3RlcCBmb3IgY29udGludW91cyBzY2FsZXMnLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIENPTlRJTlVPVVNfVE9fQ09OVElOVU9VU19TQ0FMRVMpIHtcbiAgICAgICAgICBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCd4Jywgc2NhbGVUeXBlLCBRVUFOVElUQVRJVkUsIHtyYW5nZVN0ZXA6IDIzfSwgZGVmYXVsdENvbmZpZywgdW5kZWZpbmVkLCAndGV4dCcsIHRydWUsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgICBtYWtlSW1wbGljaXQoWzAsIHtzaWduYWw6ICdwbG90X3dpZHRoJ31dKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2Uuc2NhbGVQcm9wZXJ0eU5vdFdvcmtXaXRoU2NhbGVUeXBlKHNjYWxlVHlwZSwgJ3JhbmdlU3RlcCcsICd4JykpO1xuICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbG9yJywgZnVuY3Rpb24oKSB7XG4gICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgc3BlY2lmaWVkIHNjaGVtZSBmb3IgYSBub21pbmFsIGNvbG9yIGZpZWxkLicsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnY29sb3InLCAnb3JkaW5hbCcsIE5PTUlOQUwsIHtzY2hlbWU6ICd3YXJtJ30sIGRlZmF1bHRDb25maWcsIHVuZGVmaW5lZCwgJ3BvaW50JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgIG1ha2VFeHBsaWNpdCh7c2NoZW1lOiAnd2FybSd9KVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXNlIHRoZSBzcGVjaWZpZWQgc2NoZW1lIHdpdGggZXh0ZW50IGZvciBhIG5vbWluYWwgY29sb3IgZmllbGQuJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCdjb2xvcicsICdvcmRpbmFsJywgTk9NSU5BTCwge3NjaGVtZToge25hbWU6ICd3YXJtJywgZXh0ZW50OiBbMC4yLCAxXX19LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICdwb2ludCcsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICBtYWtlRXhwbGljaXQoe3NjaGVtZTogJ3dhcm0nLCBleHRlbnQ6IFswLjIsIDFdfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgc3BlY2lmaWVkIHJhbmdlIGZvciBhIG5vbWluYWwgY29sb3IgZmllbGQuJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCdjb2xvcicsICdvcmRpbmFsJywgTk9NSU5BTCwge3JhbmdlOiBbJ3JlZCcsICdncmVlbicsICdibHVlJ119LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICdwb2ludCcsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICBtYWtlRXhwbGljaXQoWydyZWQnLCAnZ3JlZW4nLCAnYmx1ZSddKVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgY2F0ZWdvcnkgcmFuZ2UgaW4gVmVnYSBmb3IgYSBub21pbmFsIGNvbG9yIGZpZWxkLicsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnY29sb3InLCAnb3JkaW5hbCcsIE5PTUlOQUwsIHt9LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICdwb2ludCcsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICBtYWtlSW1wbGljaXQoJ2NhdGVnb3J5JylcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVzZSBkZWZhdWx0IG9yZGluYWwgcmFuZ2UgaW4gVmVnYSBmb3IgYW4gb3JkaW5hbCBjb2xvciBmaWVsZC4nLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ2NvbG9yJywgJ29yZGluYWwnLCBPUkRJTkFMLCB7fSwgZGVmYXVsdENvbmZpZywgdW5kZWZpbmVkLCAncG9pbnQnLCBmYWxzZSwgJ3Bsb3Rfd2lkdGgnLCBbXSksXG4gICAgICAgICAgbWFrZUltcGxpY2l0KCdvcmRpbmFsJylcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVzZSBkZWZhdWx0IHJhbXAgcmFuZ2UgaW4gVmVnYSBmb3IgYSB0ZW1wb3JhbC9xdWFudGl0YXRpdmUgY29sb3IgZmllbGQuJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCdjb2xvcicsICdzZXF1ZW50aWFsJywgUVVBTlRJVEFUSVZFLCB7fSwgZGVmYXVsdENvbmZpZywgdW5kZWZpbmVkLCAncG9pbnQnLCBmYWxzZSwgJ3Bsb3Rfd2lkdGgnLCBbXSksXG4gICAgICAgICAgbWFrZUltcGxpY2l0KCdyYW1wJylcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgc3BlY2lmaWVkIHNjaGVtZSB3aXRoIGNvdW50IGZvciBhIHF1YW50aXRhdGl2ZSBjb2xvciBmaWVsZC4nLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ2NvbG9yJywgJ29yZGluYWwnLCBRVUFOVElUQVRJVkUsIHtzY2hlbWU6IHtuYW1lOiAndmlyaWRpcycsIGNvdW50OiAzfX0sIGRlZmF1bHRDb25maWcsIHVuZGVmaW5lZCwgJ3BvaW50JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgIG1ha2VFeHBsaWNpdCh7c2NoZW1lOiAndmlyaWRpcycsIGNvdW50OiAzfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ29wYWNpdHknLCBmdW5jdGlvbigpIHtcbiAgICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgb3BhY2l0eVJhbmdlIGFzIG9wYWNpdHlcXCdzIHNjYWxlIHJhbmdlLicsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnb3BhY2l0eScsICdsaW5lYXInLCBRVUFOVElUQVRJVkUsIHt9LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICdwb2ludCcsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICBtYWtlSW1wbGljaXQoW2RlZmF1bHRDb25maWcuc2NhbGUubWluT3BhY2l0eSwgZGVmYXVsdENvbmZpZy5zY2FsZS5tYXhPcGFjaXR5XSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NpemUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGRlc2NyaWJlKCdiYXInLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gW21pbkJhbmRTaXplLCBtYXhCYW5kU2l6ZV0gaWYgYm90aCBhcmUgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgIHNjYWxlOiB7bWluQmFuZFNpemU6IDIsIG1heEJhbmRTaXplOiA5fVxuICAgICAgICAgIH07XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCdzaXplJywgJ2xpbmVhcicsIFFVQU5USVRBVElWRSwge30sIGNvbmZpZywgdW5kZWZpbmVkLCAnYmFyJywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgbWFrZUltcGxpY2l0KFsyLCA5XSlcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBbY29udGludW91c0JhbmRTaXplLCB4UmFuZ2VTdGVwLTFdIGJ5IGRlZmF1bHQgc2luY2UgbWluL21heFNpemUgY29uZmlnIGFyZSBub3Qgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnc2l6ZScsICdsaW5lYXInLCBRVUFOVElUQVRJVkUsIHt9LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICdiYXInLCBmYWxzZSwgJ3Bsb3Rfd2lkdGgnLCBbXSksXG4gICAgICAgICAgICBtYWtlSW1wbGljaXQoWzIsIGRlZmF1bHRDb25maWcuc2NhbGUucmFuZ2VTdGVwIC0gMV0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3RpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gW21pbkJhbmRTaXplLCBtYXhCYW5kU2l6ZV0gaWYgYm90aCBhcmUgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgIHNjYWxlOiB7bWluQmFuZFNpemU6IDQsIG1heEJhbmRTaXplOiA5fVxuICAgICAgICAgIH07XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCdzaXplJywgJ2xpbmVhcicsIFFVQU5USVRBVElWRSwge30sIGNvbmZpZywgdW5kZWZpbmVkLCAndGljaycsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbNCwgOV0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gWyhkZWZhdWx0KW1pbkJhbmRTaXplLCByYW5nZVN0ZXAtMV0gYnkgZGVmYXVsdCBzaW5jZSBtYXhTaXplIGNvbmZpZyBpcyBub3Qgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnc2l6ZScsICdsaW5lYXInLCBRVUFOVElUQVRJVkUsIHt9LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICd0aWNrJywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgbWFrZUltcGxpY2l0KFtkZWZhdWx0Q29uZmlnLnNjYWxlLm1pbkJhbmRTaXplLCBkZWZhdWx0Q29uZmlnLnNjYWxlLnJhbmdlU3RlcCAtIDFdKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd0ZXh0JywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIFttaW5Gb250U2l6ZSwgbWF4Rm9udFNpemVdJywgKCkgPT4ge1xuICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnc2l6ZScsICdsaW5lYXInLCBRVUFOVElUQVRJVkUsIHt9LCBkZWZhdWx0Q29uZmlnLCB1bmRlZmluZWQsICd0ZXh0JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgbWFrZUltcGxpY2l0KFtkZWZhdWx0Q29uZmlnLnNjYWxlLm1pbkZvbnRTaXplLCBkZWZhdWx0Q29uZmlnLnNjYWxlLm1heEZvbnRTaXplXSlcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgncnVsZScsIGZ1bmN0aW9uKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBbbWluU3Ryb2tlV2lkdGgsIG1heFN0cm9rZVdpZHRoXScsICgpID0+IHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3NpemUnLCAnbGluZWFyJywgUVVBTlRJVEFUSVZFLCB7fSwgZGVmYXVsdENvbmZpZywgdW5kZWZpbmVkLCAncnVsZScsIGZhbHNlLCAncGxvdF93aWR0aCcsIFtdKSxcbiAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbZGVmYXVsdENvbmZpZy5zY2FsZS5taW5TdHJva2VXaWR0aCwgZGVmYXVsdENvbmZpZy5zY2FsZS5tYXhTdHJva2VXaWR0aF0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3BvaW50LCBzcXVhcmUsIGNpcmNsZScsIGZ1bmN0aW9uKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBbbWluU2l6ZSwgbWF4U2l6ZV0nLCAoKSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCBtIG9mIFsncG9pbnQnLCAnc3F1YXJlJywgJ2NpcmNsZSddIGFzIE1hcmtbXSkge1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgICAgICAgICBzY2FsZToge1xuICAgICAgICAgICAgICAgIG1pblNpemU6IDUsXG4gICAgICAgICAgICAgICAgbWF4U2l6ZTogMjVcblxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnc2l6ZScsICdsaW5lYXInLCBRVUFOVElUQVRJVkUsIHt9LCBjb25maWcsIHVuZGVmaW5lZCwgbSwgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgICAgICBtYWtlSW1wbGljaXQoWzUsIDI1XSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBbMCwgKG1pbkJhbmRTaXplLTIpXjJdIGlmIGJvdGggeCBhbmQgeSBhcmUgZGlzY3JldGUgYW5kIHNpemUgaXMgcXVhbnRpdGF0aXZlICh0aHVzIHVzZSB6ZXJvPXRydWUsIGJ5IGRlZmF1bHQpJywgKCkgPT4ge1xuICAgICAgICAgIGZvciAoY29uc3QgbSBvZiBbJ3BvaW50JywgJ3NxdWFyZScsICdjaXJjbGUnXSBhcyBNYXJrW10pIHtcbiAgICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICAgIHBhcnNlUmFuZ2VGb3JDaGFubmVsKCdzaXplJywgJ2xpbmVhcicsIFFVQU5USVRBVElWRSwge30sIGRlZmF1bHRDb25maWcsIHRydWUsIG0sIGZhbHNlLCAncGxvdF93aWR0aCcsXG4gICAgICAgICAgICAgICAgWzExLCAxM10gLy8geHlSYW5nZVN0ZXBzXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbMCwgODFdKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIFs5LCAobWluQmFuZFNpemUtMileMl0gaWYgYm90aCB4IGFuZCB5IGFyZSBkaXNjcmV0ZSBhbmQgc2l6ZSBpcyBub3QgcXVhbnRpdGF0aXZlICh0aHVzIHVzZSB6ZXJvPWZhbHNlLCBieSBkZWZhdWx0KScsICgpID0+IHtcbiAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgWydwb2ludCcsICdzcXVhcmUnLCAnY2lyY2xlJ10gYXMgTWFya1tdKSB7XG4gICAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnc2l6ZScsICdsaW5lYXInLCBRVUFOVElUQVRJVkUsIHt9LCBkZWZhdWx0Q29uZmlnLCBmYWxzZSwgbSwgZmFsc2UsICdwbG90X3dpZHRoJyxcbiAgICAgICAgICAgICAgICBbMTEsIDEzXSAvLyB4eVJhbmdlU3RlcHNcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgbWFrZUltcGxpY2l0KFs5LCA4MV0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gWzksIChtaW5CYW5kU2l6ZS0yKV4yXSBpZiBib3RoIHggYW5kIHkgYXJlIGRpc2NyZXRlIGFuZCBzaXplIGlzIHF1YW50aXRhdGl2ZSBidXQgdXNlIHplcm89ZmFsc2UnLCAoKSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCBtIG9mIFsncG9pbnQnLCAnc3F1YXJlJywgJ2NpcmNsZSddIGFzIE1hcmtbXSkge1xuICAgICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3NpemUnLCAnbGluZWFyJywgUVVBTlRJVEFUSVZFLCB7fSwgZGVmYXVsdENvbmZpZywgZmFsc2UsIG0sIGZhbHNlLCAncGxvdF93aWR0aCcsXG4gICAgICAgICAgICAgICAgWzExLCAxM10gLy8geHlSYW5nZVN0ZXBzXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbOSwgODFdKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIFswLCAoeFJhbmdlU3RlcC0yKV4yXSBpZiB4IGlzIGRpc2NyZXRlIGFuZCB5IGlzIGNvbnRpbnVvdXMgYW5kIHNpemUgaXMgcXVhbnRpdGF0aXZlICh0aHVzIHVzZSB6ZXJvPXRydWUsIGJ5IGRlZmF1bHQpJywgKCkgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBtIG9mIFsncG9pbnQnLCAnc3F1YXJlJywgJ2NpcmNsZSddIGFzIE1hcmtbXSkge1xuICAgICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgICAgcGFyc2VSYW5nZUZvckNoYW5uZWwoJ3NpemUnLCAnbGluZWFyJywgUVVBTlRJVEFUSVZFLCB7fSwgZGVmYXVsdENvbmZpZywgdHJ1ZSwgbSwgZmFsc2UsICdwbG90X3dpZHRoJyxcbiAgICAgICAgICAgICAgICBbMTFdIC8vIHh5UmFuZ2VTdGVwcyBvbmx5IGhhdmUgb25lIHZhbHVlXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIG1ha2VJbXBsaWNpdChbMCwgODFdKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2hhcGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgc3ltYm9sIHJhbmdlIGluIFZlZ2EgYXMgc2hhcGVcXCdzIHNjYWxlIHJhbmdlLicsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICBwYXJzZVJhbmdlRm9yQ2hhbm5lbCgnc2hhcGUnLCAnb3JkaW5hbCcsIFFVQU5USVRBVElWRSwge30sIGRlZmF1bHRDb25maWcsIHVuZGVmaW5lZCwgJ3BvaW50JywgZmFsc2UsICdwbG90X3dpZHRoJywgW10pLFxuICAgICAgICAgIG1ha2VJbXBsaWNpdCgnc3ltYm9sJylcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/scale/type.test.js b/build/test/compile/scale/type.test.js new file mode 100644 index 0000000000..f30a6997b4 --- /dev/null +++ b/build/test/compile/scale/type.test.js @@ -0,0 +1,158 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var type_1 = require("../../../src/compile/scale/type"); +var config_1 = require("../../../src/config"); +var log = require("../../../src/log"); +var mark_1 = require("../../../src/mark"); +var scale_1 = require("../../../src/scale"); +var timeunit_1 = require("../../../src/timeunit"); +var type_2 = require("../../../src/type"); +var util = require("../../../src/util"); +var defaultScaleConfig = config_1.defaultConfig.scale; +describe('compile/scale', function () { + describe('type()', function () { + it('should return null for channel without scale', function () { + chai_1.assert.deepEqual(type_1.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) { + chai_1.assert.deepEqual(type_1.scaleType('point', 'color', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), scale_1.ScaleType.BIN_ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.scaleTypeNotWorkWithFieldDef(scale_1.ScaleType.POINT, scale_1.ScaleType.BIN_ORDINAL)); + })); + describe('nominal/ordinal', function () { + describe('color', function () { + it('should return ordinal scale for nominal data by default.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'color', { type: 'nominal' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + }); + it('should return ordinal scale for ordinal data.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'color', { type: 'nominal' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + }); + }); + describe('discrete channel (shape)', function () { + it('should return ordinal for nominal field', function () { + chai_1.assert.deepEqual(type_1.scaleType(undefined, 'shape', { type: 'nominal' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + }); + it('should return ordinal even if other type is specified', log.wrap(function (localLogger) { + [scale_1.ScaleType.LINEAR, scale_1.ScaleType.BAND, scale_1.ScaleType.POINT].forEach(function (badScaleType) { + chai_1.assert.deepEqual(type_1.scaleType(badScaleType, 'shape', { type: 'nominal' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + var warns = localLogger.warns; + chai_1.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) { + chai_1.assert.deepEqual(type_1.scaleType(undefined, 'shape', { type: 'ordinal' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + chai_1.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 and bar', function () { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + if (util.contains(['bar', 'rect'], mark)) { + return; + } + [type_2.ORDINAL, type_2.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_1.scaleType(undefined, channel, { type: t }, mark, defaultScaleConfig), scale_1.ScaleType.POINT); + }); + }); + }); + }); + it('should return band scale for ordinal X,Y when mark is rect', function () { + [type_2.ORDINAL, type_2.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_1.scaleType(undefined, channel, { type: t }, 'rect', defaultScaleConfig), scale_1.ScaleType.BAND); + }); + }); + }); + it('should return point scale for X,Y when mark is point', function () { + [type_2.ORDINAL, type_2.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_1.scaleType(undefined, channel, { type: t }, 'point', defaultScaleConfig), scale_1.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) { + [type_2.ORDINAL, type_2.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_1.scaleType('ordinal', channel, { type: t }, 'point', defaultScaleConfig), scale_1.ScaleType.POINT); + var warns = localLogger.warns; + chai_1.assert.equal(warns[warns.length - 1], log.message.scaleTypeNotWorkWithChannel(channel, 'ordinal', 'point')); + }); + }); + })); + it('should return point scale for ordinal/nominal fields for continous channels other than x and y.', function () { + var OTHER_CONTINUOUS_CHANNELS = channel_1.SCALE_CHANNELS.filter(function (c) { return channel_1.rangeType(c) === 'continuous' && !util.contains([channel_1.X, channel_1.Y], c); }); + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + [type_2.ORDINAL, type_2.NOMINAL].forEach(function (t) { + OTHER_CONTINUOUS_CHANNELS.forEach(function (channel) { + chai_1.assert.equal(type_1.scaleType(undefined, channel, { type: t }, mark, defaultScaleConfig), scale_1.ScaleType.POINT, channel + ", " + mark + ", " + t + " " + type_1.scaleType(undefined, channel, { type: t }, mark, defaultScaleConfig)); + }); + }); + }); + }); + }); + }); + describe('temporal', function () { + it('should return sequential scale for temporal color field by default.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'color', { type: 'temporal' }, 'point', defaultScaleConfig), scale_1.ScaleType.SEQUENTIAL); + }); + it('should return ordinal for temporal field and throw a warning.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(type_1.scaleType(undefined, 'shape', { type: 'temporal', timeUnit: 'yearmonth' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + chai_1.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 = timeunit_1.TIMEUNITS; _i < TIMEUNITS_1.length; _i++) { + var timeUnit = TIMEUNITS_1[_i]; + chai_1.assert.deepEqual(type_1.scaleType(undefined, channel_1.Y, { type: 'temporal', timeUnit: timeUnit }, 'point', defaultScaleConfig), scale_1.ScaleType.TIME); + } + }); + }); + describe('quantitative', function () { + it('should return sequential scale for quantitative color field by default.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'color', { type: 'quantitative' }, 'point', defaultScaleConfig), scale_1.ScaleType.SEQUENTIAL); + }); + it('should return ordinal bin scale for quantitative color field with binning.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'color', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), scale_1.ScaleType.BIN_ORDINAL); + }); + it('should return ordinal for encoding quantitative field with a discrete channel and throw a warning.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(type_1.scaleType(undefined, 'shape', { type: 'quantitative' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'quantitative')); + })); + it('should return linear scale for quantitative by default.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'x', { type: 'quantitative' }, 'point', defaultScaleConfig), scale_1.ScaleType.LINEAR); + }); + it('should return bin linear scale for quantitative by default.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'opacity', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), scale_1.ScaleType.BIN_LINEAR); + }); + it('should return linear scale for quantitative x and y.', function () { + chai_1.assert.equal(type_1.scaleType(undefined, 'x', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), scale_1.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 () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.ORDINAL, 'shape', { type: 'ordinal' }, 'point', defaultScaleConfig), scale_1.ScaleType.ORDINAL); + }); + it('should return default scale type if data type is temporal but specified scale type is not time or utc', function () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.LINEAR, 'x', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), scale_1.ScaleType.TIME); + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.LINEAR, 'color', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), scale_1.ScaleType.SEQUENTIAL); + }); + it('should return time if data type is temporal but specified scale type is discrete', function () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.POINT, 'x', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), scale_1.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 () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.LINEAR, 'x', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), scale_1.ScaleType.TIME); + }); + it('should return default scale type if data type is quantative but scale type do not support quantative', function () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.TIME, 'color', { type: 'quantitative' }, 'point', defaultScaleConfig), scale_1.ScaleType.SEQUENTIAL); + }); + it('should return default scale type if data type is quantative and scale type supports quantative', function () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.TIME, 'x', { type: 'quantitative' }, 'point', defaultScaleConfig), scale_1.ScaleType.LINEAR); + }); + it('should return default scale type if data type is quantative and scale type supports quantative', function () { + chai_1.assert.equal(type_1.scaleType(scale_1.ScaleType.TIME, 'x', { type: 'temporal' }, 'point', defaultScaleConfig), scale_1.ScaleType.TIME); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NjYWxlL3R5cGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1QixnREFBcUU7QUFDckUsd0RBQTBEO0FBQzFELDhDQUFrRDtBQUNsRCxzQ0FBd0M7QUFDeEMsMENBQWtEO0FBQ2xELDRDQUE2QztBQUM3QyxrREFBZ0Q7QUFDaEQsMENBQW1EO0FBQ25ELHdDQUEwQztBQUUxQyxJQUFNLGtCQUFrQixHQUFHLHNCQUFhLENBQUMsS0FBSyxDQUFDO0FBRS9DLFFBQVEsQ0FBQyxlQUFlLEVBQUU7SUFDeEIsUUFBUSxDQUFDLFFBQVEsRUFBRTtRQUNqQixFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsYUFBTSxDQUFDLFNBQVMsQ0FDZCxnQkFBUyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsRUFBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUMsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLENBQUMsRUFDdEcsSUFBSSxDQUNMLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvRUFBb0UsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztZQUM1RixhQUFNLENBQUMsU0FBUyxDQUNkLGdCQUFTLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFDLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBQyxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxFQUMzRixpQkFBUyxDQUFDLFdBQVcsQ0FDdEIsQ0FBQztZQUNGLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLDRCQUE0QixDQUFDLGlCQUFTLENBQUMsS0FBSyxFQUFFLGlCQUFTLENBQUMs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LGtCQUFrQixDQUFDLEVBQy9FLGlCQUFTLENBQUMsSUFBSSxDQUNmLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7cmFuZ2VUeXBlLCBTQ0FMRV9DSEFOTkVMUywgWCwgWX0gZnJvbSAnLi4vLi4vLi4vc3JjL2NoYW5uZWwnO1xuaW1wb3J0IHtzY2FsZVR5cGV9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NjYWxlL3R5cGUnO1xuaW1wb3J0IHtkZWZhdWx0Q29uZmlnfSBmcm9tICcuLi8uLi8uLi9zcmMvY29uZmlnJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi8uLi8uLi9zcmMvbG9nJztcbmltcG9ydCB7UFJJTUlUSVZFX01BUktTfSBmcm9tICcuLi8uLi8uLi9zcmMvbWFyayc7XG5pbXBvcnQge1NjYWxlVHlwZX0gZnJvbSAnLi4vLi4vLi4vc3JjL3NjYWxlJztcbmltcG9ydCB7VElNRVVOSVRTfSBmcm9tICcuLi8uLi8uLi9zcmMvdGltZXVuaXQnO1xuaW1wb3J0IHtOT01JTkFMLCBPUkRJTkFMfSBmcm9tICcuLi8uLi8uLi9zcmMvdHlwZSc7XG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gJy4uLy4uLy4uL3NyYy91dGlsJztcblxuY29uc3QgZGVmYXVsdFNjYWxlQ29uZmlnID0gZGVmYXVsdENvbmZpZy5zY2FsZTtcblxuZGVzY3JpYmUoJ2NvbXBpbGUvc2NhbGUnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCd0eXBlKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbnVsbCBmb3IgY2hhbm5lbCB3aXRob3V0IHNjYWxlJywgZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICBzY2FsZVR5cGUodW5kZWZpbmVkLCAnZGV0YWlsJywge3R5cGU6ICd0ZW1wb3JhbCcsIHRpbWVVbml0OiAneWVhcm1vbnRoJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgIG51bGxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNob3cgd2FybmluZyBpZiB1c2VycyB0cnkgdG8gb3ZlcnJpZGUgdGhlIHNjYWxlIGFuZCB1c2UgYmluJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICBzY2FsZVR5cGUoJ3BvaW50JywgJ2NvbG9yJywge3R5cGU6ICdxdWFudGl0YXRpdmUnLCBiaW46IHRydWV9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICBTY2FsZVR5cGUuQklOX09SRElOQUxcbiAgICAgICk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLnNjYWxlVHlwZU5vdFdvcmtXaXRoRmllbGREZWYoU2NhbGVUeXBlLlBPSU5ULCBTY2FsZVR5cGUuQklOX09SRElOQUwpKTtcbiAgICB9KSk7XG5cbiAgICBkZXNjcmliZSgnbm9taW5hbC9vcmRpbmFsJywgKCkgPT4ge1xuICAgICAgZGVzY3JpYmUoJ2NvbG9yJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBvcmRpbmFsIHNjYWxlIGZvciBub21pbmFsIGRhdGEgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ2NvbG9yJywge3R5cGU6ICdub21pbmFsJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgICBTY2FsZVR5cGUuT1JESU5BTFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG9yZGluYWwgc2NhbGUgZm9yIG9yZGluYWwgZGF0YS4nLCAoKSA9PiB7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ2NvbG9yJywge3R5cGU6ICdub21pbmFsJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgICBTY2FsZVR5cGUuT1JESU5BTFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdkaXNjcmV0ZSBjaGFubmVsIChzaGFwZSknLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG9yZGluYWwgZm9yIG5vbWluYWwgZmllbGQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ3NoYXBlJywge3R5cGU6ICdub21pbmFsJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgICBTY2FsZVR5cGUuT1JESU5BTFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG9yZGluYWwgZXZlbiBpZiBvdGhlciB0eXBlIGlzIHNwZWNpZmllZCcsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgICAgIFtTY2FsZVR5cGUuTElORUFSLCBTY2FsZVR5cGUuQkFORCwgU2NhbGVUeXBlLlBPSU5UXS5mb3JFYWNoKChiYWRTY2FsZVR5cGUpID0+IHtcbiAgICAgICAgICAgIGFzc2VydC5kZWVwRXF1YWwoXG4gICAgICAgICAgICAgIHNjYWxlVHlwZShiYWRTY2FsZVR5cGUsICdzaGFwZScsIHt0eXBlOiAnbm9taW5hbCd9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICAgICAgICBTY2FsZVR5cGUuT1JESU5BTFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdhcm5zID0gbG9jYWxMb2dnZXIud2FybnM7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwod2FybnNbd2FybnMubGVuZ3RoLTFdLCBsb2cubWVzc2FnZS5zY2FsZVR5cGVOb3RXb3JrV2l0aENoYW5uZWwoJ3NoYXBlJywgYmFkU2NhbGVUeXBlLCAnb3JkaW5hbCcpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG9yZGluYWwgZm9yIGFuIG9yZGluYWwgZmllbGQgYW5kIHRocm93IGEgd2FybmluZy4nLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ3NoYXBlJywge3R5cGU6ICdvcmRpbmFsJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgICBTY2FsZVR5cGUuT1JESU5BTFxuICAgICAgICAgICk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS5kaXNjcmV0ZUNoYW5uZWxDYW5ub3RFbmNvZGUoJ3NoYXBlJywgJ29yZGluYWwnKSk7XG4gICAgICAgIH0pKTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnY29udGludW91cycsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gcG9pbnQgc2NhbGUgZm9yIG9yZGluYWwgWCxZIGZvciBtYXJrcyBvdGhlcnMgdGhhbiByZWN0IGFuZCBiYXInLCAoKSA9PiB7XG4gICAgICAgICAgUFJJTUlUSVZFX01BUktTLmZvckVhY2goKG1hcmspID0+IHtcbiAgICAgICAgICAgIGlmICh1dGlsLmNvbnRhaW5zKFsnYmFyJywgJ3JlY3QnXSwgbWFyaykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBbT1JESU5BTCwgTk9NSU5BTF0uZm9yRWFjaCgodCkgPT4ge1xuICAgICAgICAgICAgICBbWCwgWV0uZm9yRWFjaCgoY2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICAgICAgICAgIHNjYWxlVHlwZSh1bmRlZmluZWQsIGNoYW5uZWwsIHt0eXBlOiB0fSwgbWFyaywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICAgICAgICAgIFNjYWxlVHlwZS5QT0lOVFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGJhbmQgc2NhbGUgZm9yIG9yZGluYWwgWCxZIHdoZW4gbWFyayBpcyByZWN0JywgKCkgPT4ge1xuICAgICAgICAgIFtPUkRJTkFMLCBOT01JTkFMXS5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgICAgICBbWCwgWV0uZm9yRWFjaCgoY2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgY2hhbm5lbCwge3R5cGU6IHR9LCAncmVjdCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgICAgICAgU2NhbGVUeXBlLkJBTkRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBwb2ludCBzY2FsZSBmb3IgWCxZIHdoZW4gbWFyayBpcyBwb2ludCcsICgpID0+IHtcbiAgICAgICAgICBbT1JESU5BTCwgTk9NSU5BTF0uZm9yRWFjaCgodCkgPT4ge1xuICAgICAgICAgICAgW1gsIFldLmZvckVhY2goKGNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlVHlwZSh1bmRlZmluZWQsIGNoYW5uZWwsIHt0eXBlOiB0fSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSwgU2NhbGVUeXBlLlBPSU5UKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBwb2ludCBzY2FsZSBmb3IgWCxZIHdoZW4gbWFyayBpcyBwb2ludCB3aGVuIE9SRElOQUwgU0NBTEUgVFlQRSBpcyBzcGVjaWZpZWQgYW5kIHRocm93IHdhcm5pbmcnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgICAgICBbT1JESU5BTCwgTk9NSU5BTF0uZm9yRWFjaCgodCkgPT4ge1xuICAgICAgICAgICAgW1gsIFldLmZvckVhY2goKGNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKHNjYWxlVHlwZSgnb3JkaW5hbCcsIGNoYW5uZWwsIHt0eXBlOiB0fSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSwgU2NhbGVUeXBlLlBPSU5UKTtcbiAgICAgICAgICAgICAgY29uc3Qgd2FybnMgPSBsb2NhbExvZ2dlci53YXJucztcbiAgICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKHdhcm5zW3dhcm5zLmxlbmd0aC0xXSwgbG9nLm1lc3NhZ2Uuc2NhbGVUeXBlTm90V29ya1dpdGhDaGFubmVsKGNoYW5uZWwsICdvcmRpbmFsJywgJ3BvaW50JykpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pKTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBwb2ludCBzY2FsZSBmb3Igb3JkaW5hbC9ub21pbmFsIGZpZWxkcyBmb3IgY29udGlub3VzIGNoYW5uZWxzIG90aGVyIHRoYW4geCBhbmQgeS4nLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgT1RIRVJfQ09OVElOVU9VU19DSEFOTkVMUyA9IFNDQUxFX0NIQU5ORUxTLmZpbHRlcigoYykgPT4gcmFuZ2VUeXBlKGMpID09PSAnY29udGludW91cycgJiYgIXV0aWwuY29udGFpbnMoW1gsIFldLCBjKSk7XG4gICAgICAgICAgUFJJTUlUSVZFX01BUktTLmZvckVhY2goKG1hcmspID0+IHtcbiAgICAgICAgICAgIFtPUkRJTkFMLCBOT01JTkFMXS5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgICAgICAgIE9USEVSX0NPTlRJTlVPVVNfQ0hBTk5FTFMuZm9yRWFjaCgoY2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICAgICAgICAgIHNjYWxlVHlwZSh1bmRlZmluZWQsIGNoYW5uZWwsIHt0eXBlOiB0fSwgbWFyaywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICAgICAgICAgIFNjYWxlVHlwZS5QT0lOVCxcbiAgICAgICAgICAgICAgICAgIGAke2NoYW5uZWx9LCAke21hcmt9LCAke3R9IGAgKyBzY2FsZVR5cGUodW5kZWZpbmVkLCBjaGFubmVsLCB7dHlwZTogdH0sIG1hcmssIGRlZmF1bHRTY2FsZUNvbmZpZylcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3RlbXBvcmFsJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gc2VxdWVudGlhbCBzY2FsZSBmb3IgdGVtcG9yYWwgY29sb3IgZmllbGQgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICBzY2FsZVR5cGUodW5kZWZpbmVkLCAnY29sb3InLCB7dHlwZTogJ3RlbXBvcmFsJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgU2NhbGVUeXBlLlNFUVVFTlRJQUxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBvcmRpbmFsIGZvciB0ZW1wb3JhbCBmaWVsZCBhbmQgdGhyb3cgYSB3YXJuaW5nLicsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKFxuICAgICAgICAgIHNjYWxlVHlwZSh1bmRlZmluZWQsICdzaGFwZScsIHt0eXBlOiAndGVtcG9yYWwnLCB0aW1lVW5pdDogJ3llYXJtb250aCd9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICAgIFNjYWxlVHlwZS5PUkRJTkFMXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuZGlzY3JldGVDaGFubmVsQ2Fubm90RW5jb2RlKCdzaGFwZScsICd0ZW1wb3JhbCcpKTtcbiAgICAgIH0pKTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGltZSBmb3IgYWxsIHRpbWUgdW5pdHMuJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGZvciAoY29uc3QgdGltZVVuaXQgb2YgVElNRVVOSVRTKSB7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICAgIHNjYWxlVHlwZSh1bmRlZmluZWQsIFksIHt0eXBlOiAndGVtcG9yYWwnLCB0aW1lVW5pdDogdGltZVVuaXR9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICAgICAgU2NhbGVUeXBlLlRJTUVcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgncXVhbnRpdGF0aXZlJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gc2VxdWVudGlhbCBzY2FsZSBmb3IgcXVhbnRpdGF0aXZlIGNvbG9yIGZpZWxkIGJ5IGRlZmF1bHQuJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ2NvbG9yJywge3R5cGU6ICdxdWFudGl0YXRpdmUnfSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICBTY2FsZVR5cGUuU0VRVUVOVElBTFxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG9yZGluYWwgYmluIHNjYWxlIGZvciBxdWFudGl0YXRpdmUgY29sb3IgZmllbGQgd2l0aCBiaW5uaW5nLicsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIHNjYWxlVHlwZSh1bmRlZmluZWQsICdjb2xvcicsIHt0eXBlOiAncXVhbnRpdGF0aXZlJywgYmluOiB0cnVlfSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICBTY2FsZVR5cGUuQklOX09SRElOQUxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBvcmRpbmFsIGZvciBlbmNvZGluZyBxdWFudGl0YXRpdmUgZmllbGQgd2l0aCBhIGRpc2NyZXRlIGNoYW5uZWwgYW5kIHRocm93IGEgd2FybmluZy4nLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChcbiAgICAgICAgICBzY2FsZVR5cGUodW5kZWZpbmVkLCAnc2hhcGUnLCB7dHlwZTogJ3F1YW50aXRhdGl2ZSd9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICAgIFNjYWxlVHlwZS5PUkRJTkFMXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuZGlzY3JldGVDaGFubmVsQ2Fubm90RW5jb2RlKCdzaGFwZScsICdxdWFudGl0YXRpdmUnKSk7XG4gICAgICB9KSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGxpbmVhciBzY2FsZSBmb3IgcXVhbnRpdGF0aXZlIGJ5IGRlZmF1bHQuJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ3gnLCB7dHlwZTogJ3F1YW50aXRhdGl2ZSd9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICAgIFNjYWxlVHlwZS5MSU5FQVJcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBiaW4gbGluZWFyIHNjYWxlIGZvciBxdWFudGl0YXRpdmUgYnkgZGVmYXVsdC4nLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICBzY2FsZVR5cGUodW5kZWZpbmVkLCAnb3BhY2l0eScsIHt0eXBlOiAncXVhbnRpdGF0aXZlJywgYmluOiB0cnVlfSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICBTY2FsZVR5cGUuQklOX0xJTkVBUlxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGxpbmVhciBzY2FsZSBmb3IgcXVhbnRpdGF0aXZlIHggYW5kIHkuJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgc2NhbGVUeXBlKHVuZGVmaW5lZCwgJ3gnLCB7dHlwZTogJ3F1YW50aXRhdGl2ZScsIGJpbjogdHJ1ZX0sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgU2NhbGVUeXBlLkxJTkVBUlxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZGF0YVR5cGVNYXRjaFNjYWxlVHlwZSgpJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gc3BlY2lmaWVkIHZhbHVlIGlmIGRhdGF0eXBlIGlzIG9yZGluYWwgb3Igbm9taW5hbCBhbmQgc3BlY2lmaWVkIHNjYWxlIHR5cGUgaXMgdGhlIG9yZGluYWwgb3Igbm9taW5hbCcsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIHNjYWxlVHlwZShTY2FsZVR5cGUuT1JESU5BTCwgJ3NoYXBlJywge3R5cGU6ICdvcmRpbmFsJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgU2NhbGVUeXBlLk9SRElOQUxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBkZWZhdWx0IHNjYWxlIHR5cGUgaWYgZGF0YSB0eXBlIGlzIHRlbXBvcmFsIGJ1dCBzcGVjaWZpZWQgc2NhbGUgdHlwZSBpcyBub3QgdGltZSBvciB1dGMnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICBzY2FsZVR5cGUoU2NhbGVUeXBlLkxJTkVBUiwgJ3gnLCB7dHlwZTogJ3RlbXBvcmFsJywgdGltZVVuaXQ6ICd5ZWFyJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgU2NhbGVUeXBlLlRJTUVcbiAgICAgICAgKTtcblxuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgc2NhbGVUeXBlKFNjYWxlVHlwZS5MSU5FQVIsICdjb2xvcicsIHt0eXBlOiAndGVtcG9yYWwnLCB0aW1lVW5pdDogJ3llYXInfSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICBTY2FsZVR5cGUuU0VRVUVOVElBTFxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRpbWUgaWYgZGF0YSB0eXBlIGlzIHRlbXBvcmFsIGJ1dCBzcGVjaWZpZWQgc2NhbGUgdHlwZSBpcyBkaXNjcmV0ZScsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIHNjYWxlVHlwZShTY2FsZVR5cGUuUE9JTlQsICd4Jywge3R5cGU6ICd0ZW1wb3JhbCcsIHRpbWVVbml0OiAneWVhcid9LCAncG9pbnQnLCBkZWZhdWx0U2NhbGVDb25maWcpLFxuICAgICAgICAgIFNjYWxlVHlwZS5USU1FXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZGVmYXVsdCBzY2FsZSB0eXBlIGlmIGRhdGEgdHlwZSBpcyB0ZW1wb3JhbCBidXQgc3BlY2lmaWVkIHNjYWxlIHR5cGUgaXMgdGltZSBvciB1dGMgb3IgYW55IGRpc2NyZXRlIHR5cGUnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICBzY2FsZVR5cGUoU2NhbGVUeXBlLkxJTkVBUiwgJ3gnLCB7dHlwZTogJ3RlbXBvcmFsJywgdGltZVVuaXQ6ICd5ZWFyJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgU2NhbGVUeXBlLlRJTUVcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBkZWZhdWx0IHNjYWxlIHR5cGUgaWYgZGF0YSB0eXBlIGlzIHF1YW50YXRpdmUgYnV0IHNjYWxlIHR5cGUgZG8gbm90IHN1cHBvcnQgcXVhbnRhdGl2ZScsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIHNjYWxlVHlwZShTY2FsZVR5cGUuVElNRSwgJ2NvbG9yJywge3R5cGU6ICdxdWFudGl0YXRpdmUnfSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICBTY2FsZVR5cGUuU0VRVUVOVElBTFxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRlZmF1bHQgc2NhbGUgdHlwZSBpZiBkYXRhIHR5cGUgaXMgcXVhbnRhdGl2ZSBhbmQgc2NhbGUgdHlwZSBzdXBwb3J0cyBxdWFudGF0aXZlJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgc2NhbGVUeXBlKFNjYWxlVHlwZS5USU1FLCAneCcsIHt0eXBlOiAncXVhbnRpdGF0aXZlJ30sICdwb2ludCcsIGRlZmF1bHRTY2FsZUNvbmZpZyksXG4gICAgICAgICAgU2NhbGVUeXBlLkxJTkVBUlxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRlZmF1bHQgc2NhbGUgdHlwZSBpZiBkYXRhIHR5cGUgaXMgcXVhbnRhdGl2ZSBhbmQgc2NhbGUgdHlwZSBzdXBwb3J0cyBxdWFudGF0aXZlJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgc2NhbGVUeXBlKFNjYWxlVHlwZS5USU1FLCAneCcsIHt0eXBlOiAndGVtcG9yYWwnfSwgJ3BvaW50JywgZGVmYXVsdFNjYWxlQ29uZmlnKSxcbiAgICAgICAgICBTY2FsZVR5cGUuVElNRVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/selection/facets.test.js b/build/test/compile/selection/facets.test.js new file mode 100644 index 0000000000..9aed1e9b13 --- /dev/null +++ b/build/test/compile/selection/facets.test.js @@ -0,0 +1,51 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var selection = require("../../../src/compile/selection/selection"); +var util_1 = require("../../util"); +describe('Faceted Selections', function () { + var model = util_1.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 () { + chai_1.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 () { + chai_1.assert.equal(selection.unitName(unit), "\"child_layer_1\" + '_' + facet[\"bin_maxbins_6_X\"] + '_' + facet[\"Series\"]"); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL2ZhY2V0cy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixvRUFBc0U7QUFFdEUsbUNBQXNDO0FBRXRDLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRTtJQUM3QixJQUFNLEtBQUssR0FBRyxpQkFBVSxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxvQkFBb0IsRUFBQztRQUNyQyxPQUFPLEVBQUU7WUFDUCxRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7WUFDaEQsS0FBSyxFQUFFLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUM7U0FDdEQ7UUFDRCxNQUFNLEVBQUU7WUFDTixPQUFPLEVBQUUsQ0FBQztvQkFDUixNQUFNLEVBQUUsTUFBTTtvQkFDZCxVQUFVLEVBQUUsRUFBQyxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsRUFBRSxFQUFDLEVBQUM7aUJBQ2pDLEVBQUU7b0JBQ0QsV0FBVyxFQUFFO3dCQUNYLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUM7d0JBQ3pCLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUM7d0JBQ3hCLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUM7cUJBQzlCO29CQUNELE1BQU0sRUFBRSxNQUFNO29CQUNkLFVBQVUsRUFBRTt3QkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsRUFBRSxFQUFDO3FCQUNuQjtpQkFDRixDQUFDO1NBQ0g7S0FDRixDQUFDLENBQUM7SUFFSCxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDZCxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQWMsQ0FBQztJQUV4RCxFQUFFLENBQUMsZ0NBQWdDLEVBQUU7UUFDbkMsYUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyw0QkFBNEIsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUU7WUFDMUU7Z0JBQ0UsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsSUFBSSxFQUFFO29CQUNKO3dCQUNFLFFBQVEsRUFBRSxDQUFDLEVBQUMsUUFBUSxFQUFFLE9BQU8sRUFBQyxNQUFNLEVBQUUsV0FBVyxFQUFDLENBQUM7d0JBQ25ELFFBQVEsRUFBRSxnREFBZ0Q7cUJBQzNEO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRTtRQUM3QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQ25DLGdGQUEwRSxDQUFDLENBQUM7SUFDaEYsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlIHF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQgKiBhcyBzZWxlY3Rpb24gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvdW5pdCc7XG5pbXBvcnQge3BhcnNlTW9kZWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnRmFjZXRlZCBTZWxlY3Rpb25zJywgZnVuY3Rpb24oKSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VNb2RlbCh7XG4gICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYW5zY29tYmUuanNvblwifSxcbiAgICBcImZhY2V0XCI6IHtcbiAgICAgIFwiY29sdW1uXCI6IHtcImZpZWxkXCI6IFwiU2VyaWVzXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICBcInJvd1wiOiB7XCJmaWVsZFwiOiBcIlhcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwiLCBcImJpblwiOiB0cnVlfSxcbiAgICB9LFxuICAgIFwic3BlY1wiOiB7XG4gICAgICBcImxheWVyXCI6IFt7XG4gICAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XCJ5XCI6IHtcInZhbHVlXCI6IDEwfX1cbiAgICAgIH0sIHtcbiAgICAgICAgXCJzZWxlY3Rpb25cIjoge1xuICAgICAgICAgIFwib25lXCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIn0sXG4gICAgICAgICAgXCJ0d3BcIjoge1widHlwZVwiOiBcIm11bHRpXCJ9LFxuICAgICAgICAgIFwidGhyZWVcIjoge1widHlwZVwiOiBcImludGVydmFsXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcInZhbHVlXCI6IDEwfVxuICAgICAgICB9XG4gICAgICB9XVxuICAgIH1cbiAgfSk7XG5cbiAgbW9kZWwucGFyc2UoKTtcbiAgY29uc3QgdW5pdCA9IG1vZGVsLmNoaWxkcmVuWzBdLmNoaWxkcmVuWzFdIGFzIFVuaXRNb2RlbDtcblxuICBpdCgnc2hvdWxkIGFzc2VtYmxlIGEgZmFjZXQgc2lnbmFsJywgZnVuY3Rpb24oKSB7XG4gICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyh1bml0LCBbXSksIFtcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwiZmFjZXRcIixcbiAgICAgICAgXCJ2YWx1ZVwiOiB7fSxcbiAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJldmVudHNcIjogW3tcInNvdXJjZVwiOiBcInNjb3BlXCIsXCJ0eXBlXCI6IFwibW91c2Vtb3ZlXCJ9XSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiaXNUdXBsZShmYWNldCkgPyBmYWNldCA6IGdyb3VwKFxcXCJjZWxsXFxcIikuZGF0dW1cIlxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIG5hbWUgdGhlIHVuaXQgd2l0aCB0aGUgZmFjZXQga2V5cycsIGZ1bmN0aW9uKCkge1xuICAgIGFzc2VydC5lcXVhbChzZWxlY3Rpb24udW5pdE5hbWUodW5pdCksXG4gICAgICBgXCJjaGlsZF9sYXllcl8xXCIgKyAnXycgKyBmYWNldFtcImJpbl9tYXhiaW5zXzZfWFwiXSArICdfJyArIGZhY2V0W1wiU2VyaWVzXCJdYCk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/selection/identifier.test.js b/build/test/compile/selection/identifier.test.js new file mode 100644 index 0000000000..44274309e0 --- /dev/null +++ b/build/test/compile/selection/identifier.test.js @@ -0,0 +1,79 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var assemble_1 = require("../../../src/compile/data/assemble"); +var optimize_1 = require("../../../src/compile/data/optimize"); +var util_1 = require("../../util"); +/* tslint:disable:quotemark */ +function getVgData(selection, x, y, mark, enc, transform) { + var model = util_1.parseModel({ + data: { url: 'data/cars.json' }, + transform: transform, + selection: selection, + mark: mark || 'circle', + encoding: __assign({ x: __assign({ field: 'Horsepower', type: 'quantitative' }, x), y: __assign({ field: 'Miles-per-Gallon', type: 'quantitative' }, y), color: { field: 'Origin', type: 'nominal' } }, enc) + }); + model.parse(); + optimize_1.optimizeDataflow(model.component.data); + return assemble_1.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]; + chai_1.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 } }); + chai_1.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'); }); + chai_1.assert.isAtLeast(aggr, 0); + chai_1.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'); }); + chai_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWRlbnRpZmllci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NlbGVjdGlvbi9pZGVudGlmaWVyLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLDZCQUE0QjtBQUM1QiwrREFBb0U7QUFDcEUsK0RBQW9FO0FBR3BFLG1DQUFzQztBQUV0Qyw4QkFBOEI7QUFFOUIsbUJBQW1CLFNBQWMsRUFBRSxDQUFPLEVBQUUsQ0FBTyxFQUFFLElBQVcsRUFBRSxHQUFTLEVBQUUsU0FBZTtJQUMxRixJQUFNLEtBQUssR0FBRyxpQkFBVSxDQUFDO1FBQ3ZCLElBQUksRUFBRSxFQUFDLEdBQUcsRUFBRSxnQkFBZ0IsRUFBQztRQUM3QixTQUFTLFdBQUE7UUFDVCxTQUFTLFdBQUE7UUFDVCxJQUFJLEVBQUUsSUFBSSxJQUFJLFFBQVE7UUFDdEIsUUFBUSxhQUNOLENBQUMsYUFBRyxLQUFLLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxjQUFjLElBQUssQ0FBQyxHQUNuRCxDQUFDLGFBQUcsS0FBSyxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRSxjQUFjLElBQUssQ0FBQyxHQUN6RCxLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUMsSUFDdEMsR0FBRyxDQUNQO0tBQ0YsQ0FBQyxDQUFDO0lBQ0gsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2QsMkJBQWdCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxNQUFNLENBQUMsMkJBQWdCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsUUFBUSxDQUFDLHNCQUFzQixFQUFFO0lBQy9CLEVBQUUsQ0FBQyw0QkFBNEIsRUFBRTtRQUMvQixjQUFjLE1BQVk7WUFDeEIsSUFBTSxJQUFJLEdBQUcs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QyxFQUFFO2dDQUN2QyxJQUFJO1lBQ2IsSUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLEVBQUMsRUFBRSxFQUFFLEVBQUMsSUFBSSxNQUFBLEVBQUMsRUFBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFDekQsQ0FBQyxFQUFDLFNBQVMsRUFBRSxzQkFBc0IsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BELElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2QsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBQyxDQUFDLEVBQUUsQ0FBQyxJQUFLLE9BQUEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLEVBQWxELENBQWtELENBQUMsQ0FBQztZQUNyRixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBTkQsR0FBRyxDQUFDLENBQWUsVUFBbUIsRUFBbkIsTUFBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEVBQW5CLGNBQW1CLEVBQW5CLElBQW1CO1lBQWpDLElBQU0sSUFBSSxTQUFBO29CQUFKLElBQUk7U0FNZDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2Fzc2VtYmxlUm9vdERhdGF9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvYXNzZW1ibGUnO1xuaW1wb3J0IHtvcHRpbWl6ZURhdGFmbG93fSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL29wdGltaXplJztcbmltcG9ydCB7TWFya30gZnJvbSAnLi4vLi4vLi4vc3JjL21hcmsnO1xuaW1wb3J0IHtWZ1RyYW5zZm9ybX0gZnJvbSAnLi4vLi4vLi4vc3JjL3ZlZ2Euc2NoZW1hJztcbmltcG9ydCB7cGFyc2VNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5mdW5jdGlvbiBnZXRWZ0RhdGEoc2VsZWN0aW9uOiBhbnksIHg/OiBhbnksIHk/OiBhbnksIG1hcms/OiBNYXJrLCBlbmM/OiBhbnksIHRyYW5zZm9ybT86IGFueSkge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlTW9kZWwoe1xuICAgIGRhdGE6IHt1cmw6ICdkYXRhL2NhcnMuanNvbid9LFxuICAgIHRyYW5zZm9ybSxcbiAgICBzZWxlY3Rpb24sXG4gICAgbWFyazogbWFyayB8fCAnY2lyY2xlJyxcbiAgICBlbmNvZGluZzoge1xuICAgICAgeDoge2ZpZWxkOiAnSG9yc2Vwb3dlcicsIHR5cGU6ICdxdWFudGl0YXRpdmUnLCAuLi54fSxcbiAgICAgIHk6IHtmaWVsZDogJ01pbGVzLXBlci1HYWxsb24nLCB0eXBlOiAncXVhbnRpdGF0aXZlJywgLi4ueX0sXG4gICAgICBjb2xvcjoge2ZpZWxkOiAnT3JpZ2luJywgdHlwZTogJ25vbWluYWwnfSxcbiAgICAgIC4uLmVuY1xuICAgIH1cbiAgfSk7XG4gIG1vZGVsLnBhcnNlKCk7XG4gIG9wdGltaXplRGF0YWZsb3cobW9kZWwuY29tcG9uZW50LmRhdGEpO1xuICByZXR1cm4gYXNzZW1ibGVSb290RGF0YShtb2RlbC5jb21wb25lbnQuZGF0YSk7XG59XG5cbmRlc2NyaWJlKCdJZGVudGlmaWVyIHRyYW5zZm9ybScsIGZ1bmN0aW9uKCkge1xuICBpdCgnaXMgbm90IHVubmVjZXNzYXJpbHkgYWRkZWQnLCBmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiB0ZXN0KHNlbERlZj86IGFueSkge1xuICAgICAgY29uc3QgZGF0YSA9IGdldFZnRGF0YShzZWxEZWYpO1xuICAgICAgZm9yIChjb25zdCBkIG9mIGRhdGEpIHtcbiAgICAgICAgYXNzZXJ0LmlzTm90VHJ1ZShkLnRyYW5zZm9ybSAmJiBkLnRyYW5zZm9ybS5zb21lKCh0KSA9PiB0LnR5cGUgPT09ICdpZGVudGlmaWVyJykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRlc3QoKTtcbiAgICBmb3IgKGNvbnN0IHR5cGUgb2YgWydzaW5nbGUnLCAnbXVsdGknXSkge1xuICAgICAgdGVzdCh7cHQ6IHt0eXBlLCBlbmNvZGluZ3M6IFsneCddfX0pO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2lzIGFkZGVkIGZvciBkZWZhdWx0IHBvaW50IHNlbGVjdGlvbnMnLCBmdW5jdGlvbigpIHtcbiAgICBmb3IgKGNvbnN0IHR5cGUgb2YgWydzaW5nbGUnLCAnbXVsdGknXSkge1xuICAgICAgY29uc3QgdXJsID0gZ2V0VmdEYXRhKHtwdDoge3R5cGV9fSk7XG4gICAgICBhc3NlcnQuZXF1YWwodXJsWzBdLnRyYW5zZm9ybVswXS50eXBlLCAnaWRlbnRpZmllcicpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2lzIGFkZGVkIGltbWVkaWF0ZWx5IGFmdGVyIGFnZ3JlZ2F0ZSB0cmFuc2Zvcm1zJywgZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gdGVzdCh0cmFuc2Zvcm06IFZnVHJhbnNmb3JtW10pIHtcbiAgICAgIGxldCBhZ2dyID0gLTE7XG4gICAgICB0cmFuc2Zvcm0uc29tZSgodCwgaSkgPT4gKGFnZ3IgPSBpLCB0LnR5cGUgPT09ICdhZ2dyZWdhdGUnKSk7XG4gICAgICBhc3NlcnQuaXNBdExlYXN0KGFnZ3IsIDApO1xuICAgICAgYXNzZXJ0LmVxdWFsKHRyYW5zZm9ybVthZ2dyICsgMV0udHlwZSwgJ2lkZW50aWZpZXInKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHR5cGUgb2YgWydzaW5nbGUnLCAnbXVsdGknXSkge1xuICAgICAgY29uc3Qgc2VsID0ge3B0OiB7dHlwZX19O1xuICAgICAgbGV0IGRhdGEgPSBnZXRWZ0RhdGEoc2VsLCB7YmluOiB0cnVlfSwge2FnZ3JlZ2F0ZTogJ2NvdW50J30pO1xuICAgICAgdGVzdChkYXRhWzBdLnRyYW5zZm9ybSk7XG5cbiAgICAgIGRhdGEgPSBnZXRWZ0RhdGEoc2VsLCB7YWdncmVnYXRlOiAnc3VtJ30sIG51bGwsICdiYXInLFxuICAgICAgICB7Y29sdW1uOiB7ZmllbGQ6ICdDeWxpbmRlcnMnLCB0eXBlOiAnb3JkaW5hbCd9fSk7XG4gICAgICB0ZXN0KGRhdGFbMF0udHJhbnNmb3JtKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdpcyBhZGRlZCBiZWZvcmUgYW55IHVzZXItc3BlY2lmaWVkIHRyYW5zZm9ybXMnLCBmdW5jdGlvbigpIHtcbiAgICBmb3IgKGNvbnN0IHR5cGUgb2YgWydzaW5nbGUnLCAnbXVsdGknXSkge1xuICAgICAgY29uc3QgZGF0YSA9IGdldFZnRGF0YSh7cHQ6IHt0eXBlfX0sIG51bGwsIG51bGwsIG51bGwsIG51bGwsXG4gICAgICAgIFt7Y2FsY3VsYXRlOiAnZGF0dW0uSG9yc2Vwb3dlciAqIDInLCBhczogJ2Zvbyd9XSk7XG4gICAgICBsZXQgY2FsYyA9IC0xO1xuICAgICAgZGF0YVswXS50cmFuc2Zvcm0uc29tZSgodCwgaSkgPT4gKGNhbGMgPSBpLCB0LnR5cGUgPT09ICdmb3JtdWxhJyAmJiB0LmFzID09PSAnZm9vJykpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGFbMF0udHJhbnNmb3JtW2NhbGMgLSAxXS50eXBlLCAnaWRlbnRpZmllcicpO1xuICAgIH1cbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/selection/inputs.test.js b/build/test/compile/selection/inputs.test.js new file mode 100644 index 0000000000..a70e935c02 --- /dev/null +++ b/build/test/compile/selection/inputs.test.js @@ -0,0 +1,149 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var selection = require("../../../src/compile/selection/selection"); +var inputs_1 = require("../../../src/compile/selection/transforms/inputs"); +var util_1 = require("../../util"); +describe('Inputs Selection Transform', function () { + var model = util_1.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 () { + chai_1.assert.isNotFalse(inputs_1.default.has(selCmpts['one'])); + chai_1.assert.isNotFalse(inputs_1.default.has(selCmpts['two'])); + chai_1.assert.isNotFalse(inputs_1.default.has(selCmpts['three'])); + chai_1.assert.isNotTrue(inputs_1.default.has(selCmpts['four'])); + chai_1.assert.isNotTrue(inputs_1.default.has(selCmpts['six'])); + }); + it('adds widget binding for default projection', function () { + model.component.selection = { one: selCmpts['one'] }; + chai_1.assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [ + { + "name": "one_tuple", + "update": "one__vgsid_ ? {fields: [\"_vgsid_\"], values: [one__vgsid_]} : null" + } + ]); + chai_1.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'] }; + chai_1.assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [ + { + "name": "two_tuple", + "update": "two_Cylinders && two_Horsepower ? {fields: [\"Cylinders\", \"Horsepower\"], values: [two_Cylinders, two_Horsepower]} : null" + } + ]); + chai_1.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'] }; + chai_1.assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [ + { + "name": "three_tuple", + "update": "three_Cylinders && three_Origin ? {fields: [\"Cylinders\", \"Origin\"], values: [three_Cylinders, three_Origin]} : null" + } + ]); + chai_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL2lucHV0cy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixvRUFBc0U7QUFDdEUsMkVBQXNFO0FBQ3RFLG1DQUEwQztBQUUxQyxRQUFRLENBQUMsNEJBQTRCLEVBQUU7SUFDckMsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO1NBQ2hEO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLElBQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDbkQsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLFFBQVE7WUFDaEIsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBQztTQUMzRDtRQUNELEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLFFBQVEsRUFBRSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUM7WUFDckMsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFF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dCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZSBxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0ICogYXMgc2VsZWN0aW9uIGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi9zZWxlY3Rpb24nO1xuaW1wb3J0IGlucHV0cyBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vdHJhbnNmb3Jtcy9pbnB1dHMnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdJbnB1dHMgU2VsZWN0aW9uIFRyYW5zZm9ybScsIGZ1bmN0aW9uKCkge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICBcIm1hcmtcIjogXCJjaXJjbGVcIixcbiAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgfVxuICB9KTtcblxuICBtb2RlbC5wYXJzZVNjYWxlKCk7XG4gIGNvbnN0IHNlbENtcHRzID0gc2VsZWN0aW9uLnBhcnNlVW5pdFNlbGVjdGlvbihtb2RlbCwge1xuICAgIFwib25lXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcInNpbmdsZVwiLFxuICAgICAgXCJiaW5kXCI6IHtcImlucHV0XCI6IFwicmFuZ2VcIiwgXCJtaW5cIjogMCwgXCJtYXhcIjogMTAsIFwic3RlcFwiOiAxfVxuICAgIH0sXG4gICAgXCJ0d29cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic2luZ2xlXCIsXG4gICAgICBcImZpZWxkc1wiOiBbXCJDeWxpbmRlcnNcIiwgXCJIb3JzZXBvd2VyXCJdLFxuICAgICAgXCJiaW5kXCI6IHtcImlucHV0XCI6IFwicmFuZ2VcIiwgXCJtaW5cIjogMCwgXCJtYXhcIjogMTAsIFwic3RlcFwiOiAxfVxuICAgIH0sXG4gICAgXCJ0aHJlZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJuZWFyZXN0XCI6IHRydWUsXG4gICAgICBcImZpZWxkc1wiOiBbXCJDeWxpbmRlcnNcIiwgXCJPcmlnaW5cIl0sXG4gICAgICBcImJpbmRcIjoge1xuICAgICAgICBcIkhvcnNlcG93ZXJcIjoge1wiaW5wdXRcIjogXCJyYW5nZVwiLCBcIm1pblwiOiAwLCBcIm1heFwiOiAxMCwgXCJzdGVwXCI6IDF9LFxuICAgICAgICBcIk9yaWdpblwiOiB7XCJpbnB1dFwiOiBcInNlbGVjdFwiLCBcIm9wdGlvbnNcIjogW1wiSmFwYW5cIiwgXCJVU0FcIiwgXCJFdXJvcGVcIl19XG4gICAgICB9XG4gICAgfSxcbiAgICBcImZvdXJcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic2luZ2xlXCIsIFwiYmluZFwiOiBudWxsXG4gICAgfSxcbiAgICBcInNpeFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlcnZhbFwiLFxuICAgICAgXCJiaW5kXCI6IFwic2NhbGVzXCJcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdpZGVudGlmaWVzIHRyYW5zZm9ybSBpbnZvY2F0aW9uJywgZnVuY3Rpb24oKSB7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UoaW5wdXRzLmhhcyhzZWxDbXB0c1snb25lJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RGYWxzZShpbnB1dHMuaGFzKHNlbENtcHRzWyd0d28nXSkpO1xuICAgIGFzc2VydC5pc05vdEZhbHNlKGlucHV0cy5oYXMoc2VsQ21wdHNbJ3RocmVlJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RUcnVlKGlucHV0cy5oYXMoc2VsQ21wdHNbJ2ZvdXInXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUoaW5wdXRzLmhhcyhzZWxDbXB0c1snc2l4J10pKTtcbiAgfSk7XG5cbiAgaXQoJ2FkZHMgd2lkZ2V0IGJpbmRpbmcgZm9yIGRlZmF1bHQgcHJvamVjdGlvbicsIGZ1bmN0aW9uKCkge1xuICAgIG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb24gPSB7b25lOiBzZWxDbXB0c1snb25lJ119O1xuICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKSwgW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJvbmVfdHVwbGVcIixcbiAgICAgICAgXCJ1cGRhdGVcIjogXCJvbmVfX3Znc2lkXyA/IHtmaWVsZHM6IFtcXFwiX3Znc2lkX1xcXCJdLCB2YWx1ZXM6IFtvbmVfX3Znc2lkX119IDogbnVsbFwiXG4gICAgICB9XG4gICAgXSk7XG5cbiAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNlbGVjdGlvbi5hc3NlbWJsZVRvcExldmVsU2lnbmFscyhtb2RlbCwgW10pLCBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIm9uZV9fdmdzaWRfXCIsXG4gICAgICAgIFwidmFsdWVcIjogXCJcIixcbiAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJldmVudHNcIjogW3tcInNvdXJjZVwiOiBcInNjb3BlXCIsXCJ0eXBlXCI6IFwiY2xpY2tcIn1dLFxuICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJkYXR1bSAmJiBpdGVtKCkubWFyay5tYXJrdHlwZSAhPT0gJ2dyb3VwJyA/IGRhdHVtW1xcXCJfdmdzaWRfXFxcIl0gOiBudWxsXCJcbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwiYmluZFwiOiB7XCJpbnB1dFwiOiBcInJhbmdlXCIsXCJtaW5cIjogMCxcIm1heFwiOiAxMCxcInN0ZXBcIjogMX1cbiAgICAgIH1cbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJ2FkZHMgc2luZ2xlIHdpZGdldCBiaW5kaW5nIGZvciBjb21wb3VuZCBwcm9qZWN0aW9uJywgZnVuY3Rpb24oKSB7XG4gICAgbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbiA9IHt0d286IHNlbENtcHRzWyd0d28nXX07XG4gICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pLCBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcInR3b190dXBsZVwiLFxuICAgICAgICBcInVwZGF0ZVwiOiBcInR3b19DeWxpbmRlcnMgJiYgdHdvX0hvcnNlcG93ZXIgPyB7ZmllbGRzOiBbXFxcIkN5bGluZGVyc1xcXCIsIFxcXCJIb3JzZXBvd2VyXFxcIl0sIHZhbHVlczogW3R3b19DeWxpbmRlcnMsIHR3b19Ib3JzZXBvd2VyXX0gOiBudWxsXCJcbiAgICAgIH1cbiAgICBdKTtcblxuICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2VsZWN0aW9uLmFzc2VtYmxlVG9wTGV2ZWxTaWduYWxzKG1vZGVsLCBbXSksIFtcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwidHdvX0hvcnNlcG93ZXJcIixcbiAgICAgICAgXCJ2YWx1ZVwiOiBcIlwiLFxuICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiBbe1wic291cmNlXCI6IFwic2NvcGVcIixcInR5cGVcIjogXCJjbGlja1wifV0sXG4gICAgICAgICAgICBcInVwZGF0ZVwiOiBcImRhdHVtICYmIGl0ZW0oKS5tYXJrLm1hcmt0eXBlICE9PSAnZ3JvdXAnID8gZGF0dW1bXFxcIkhvcnNlcG93ZXJcXFwiXSA6IG51bGxcIlxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJiaW5kXCI6IHtcImlucHV0XCI6IFwicmFuZ2VcIixcIm1pblwiOiAwLFwibWF4XCI6IDEwLFwic3RlcFwiOiAxfVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwidHdvX0N5bGluZGVyc1wiLFxuICAgICAgICBcInZhbHVlXCI6IFwiXCIsXG4gICAgICAgIFwib25cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiZXZlbnRzXCI6IFt7XCJzb3VyY2VcIjogXCJzY29wZVwiLFwidHlwZVwiOiBcImNsaWNrXCJ9XSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiZGF0dW0gJiYgaXRlbSgpLm1hcmsubWFya3R5cGUgIT09ICdncm91cCcgPyBkYXR1bVtcXFwiQ3lsaW5kZXJzXFxcIl0gOiBudWxsXCJcbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwiYmluZFwiOiB7XCJpbnB1dFwiOiBcInJhbmdlXCIsXCJtaW5cIjogMCxcIm1heFwiOiAxMCxcInN0ZXBcIjogMX1cbiAgICAgIH1cbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJ2FkZHMgcHJvamVjdGlvbi1zcGVjaWZpYyB3aWRnZXQgYmluZGluZ3MnLCBmdW5jdGlvbigpIHtcbiAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3RocmVlOiBzZWxDbXB0c1sndGhyZWUnXX07XG4gICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pLCBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcInRocmVlX3R1cGxlXCIsXG4gICAgICAgIFwidXBkYXRlXCI6IFwidGhyZWVfQ3lsaW5kZXJzICYmIHRocmVlX09yaWdpbiA/IHtmaWVsZHM6IFtcXFwiQ3lsaW5kZXJzXFxcIiwgXFxcIk9yaWdpblxcXCJdLCB2YWx1ZXM6IFt0aHJlZV9DeWxpbmRlcnMsIHRocmVlX09yaWdpbl19IDogbnVsbFwiXG4gICAgICB9XG4gICAgXSk7XG5cbiAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNlbGVjdGlvbi5hc3NlbWJsZVRvcExldmVsU2lnbmFscyhtb2RlbCwgW10pLCBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcInRocmVlX09yaWdpblwiLFxuICAgICAgICBcInZhbHVlXCI6IFwiXCIsXG4gICAgICAgIFwib25cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiZXZlbnRzXCI6IFt7XCJzb3VyY2VcIjogXCJzY29wZVwiLFwidHlwZVwiOiBcImNsaWNrXCJ9XSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiZGF0dW0gJiYgaXRlbSgpLm1hcmsubWFya3R5cGUgIT09ICdncm91cCcgPyAoaXRlbSgpLmlzVm9yb25vaSA/IGRhdHVtLmRhdHVtIDogZGF0dW0pW1xcXCJPcmlnaW5cXFwiXSA6IG51bGxcIlxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJiaW5kXCI6IHtcbiAgICAgICAgICBcImlucHV0XCI6IFwic2VsZWN0XCIsXG4gICAgICAgICAgXCJvcHRpb25zXCI6IFtcIkphcGFuXCIsXCJVU0FcIixcIkV1cm9wZVwiXVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJ0aHJlZV9DeWxpbmRlcnNcIixcbiAgICAgICAgXCJ2YWx1ZVwiOiBcIlwiLFxuICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiBbe1wic291cmNlXCI6IFwic2NvcGVcIixcInR5cGVcIjogXCJjbGlja1wifV0sXG4gICAgICAgICAgICBcInVwZGF0ZVwiOiBcImRhdHVtICYmIGl0ZW0oKS5tYXJrLm1hcmt0eXBlICE9PSAnZ3JvdXAnID8gKGl0ZW0oKS5pc1Zvcm9ub2kgPyBkYXR1bS5kYXR1bSA6IGRhdHVtKVtcXFwiQ3lsaW5kZXJzXFxcIl0gOiBudWxsXCJcbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwiYmluZFwiOiB7XG4gICAgICAgICAgXCJIb3JzZXBvd2VyXCI6IHtcImlucHV0XCI6IFwicmFuZ2VcIixcIm1pblwiOiAwLFwibWF4XCI6IDEwLFwic3RlcFwiOiAxfSxcbiAgICAgICAgICBcIk9yaWdpblwiOiB7XG4gICAgICAgICAgICBcImlucHV0XCI6IFwic2VsZWN0XCIsXG4gICAgICAgICAgICBcIm9wdGlvbnNcIjogW1wiSmFwYW5cIixcIlVTQVwiLFwiRXVyb3BlXCJdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgXSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/selection/interval.test.js b/build/test/compile/selection/interval.test.js new file mode 100644 index 0000000000..9391d91673 --- /dev/null +++ b/build/test/compile/selection/interval.test.js @@ -0,0 +1,393 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var vega_event_selector_1 = require("vega-event-selector"); +var interval_1 = require("../../../src/compile/selection/interval"); +var selection = require("../../../src/compile/selection/selection"); +var util_1 = require("../../util"); +describe('Interval Selections', function () { + var model = util_1.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_1.default.signals(model, selCmpts['one']); + chai_1.assert.includeDeepMembers(oneSg, [{ + "name": "one_x", + "value": [], + "on": [ + { + "events": vega_event_selector_1.selector('mousedown', 'scope')[0], + "update": "[x(unit), x(unit)]" + }, + { + "events": vega_event_selector_1.selector('[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_1.default.signals(model, selCmpts['two']); + chai_1.assert.includeDeepMembers(twoSg, [{ + "name": "two_Miles_per_Gallon", + "on": [] + }]); + var threeSg = interval_1.default.signals(model, selCmpts['thr_ee']); + chai_1.assert.includeDeepMembers(threeSg, [ + { + "name": "thr_ee_x", + "value": [], + "on": [ + { + "events": vega_event_selector_1.selector('mousedown', 'scope')[0], + "update": "[x(unit), x(unit)]" + }, + { + "events": vega_event_selector_1.selector('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "[thr_ee_x[0], clamp(x(unit), 0, width)]" + }, + { + "events": vega_event_selector_1.selector('keydown', 'scope')[0], + "update": "[x(unit), x(unit)]" + }, + { + "events": vega_event_selector_1.selector('[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": vega_event_selector_1.selector('mousedown', 'scope')[0], + "update": "[y(unit), y(unit)]" + }, + { + "events": vega_event_selector_1.selector('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "[thr_ee_y[0], clamp(y(unit), 0, height)]" + }, + { + "events": vega_event_selector_1.selector('keydown', 'scope')[0], + "update": "[y(unit), y(unit)]" + }, + { + "events": vega_event_selector_1.selector('[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_1.default.signals(model, selCmpts['one']); + chai_1.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_1.default.signals(model, selCmpts['two']); + chai_1.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_1.default.signals(model, selCmpts['thr_ee']); + chai_1.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('builds modify signals', function () { + var oneExpr = interval_1.default.modifyExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'one_tuple, true'); + var twoExpr = interval_1.default.modifyExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'two_tuple, true'); + var threeExpr = interval_1.default.modifyExpr(model, selCmpts['thr_ee']); + chai_1.assert.equal(threeExpr, 'thr_ee_tuple, {unit: \"\"}'); + var signals = selection.assembleUnitSelectionSignals(model, []); + chai_1.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" }]; + chai_1.assert.sameDeepMembers(interval_1.default.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" }, + "stroke": { "value": "white" } + }, + "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 + } + ] + } + } + } + ]); + // Scale-bound interval selections should not add a brush mark. + chai_1.assert.sameDeepMembers(interval_1.default.marks(model, selCmpts['two'], marks), marks); + chai_1.assert.sameDeepMembers(interval_1.default.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" }, + "stroke": { "value": "black" }, + "strokeWidth": { "value": 4 }, + "strokeDash": { "value": [10, 5] }, + "strokeDashOffset": { "value": 3 }, + "strokeOpacity": { "value": 0.25 } + }, + "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]" + } + } + } + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJ2YWwudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vaW50ZXJ2YWwudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsMkRBQThEO0FBRTlELG9FQUErRDtBQUMvRCxvRUFBc0U7QUFDdEUsbUNBQTBDO0FBRTFDLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtJQUM5QixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1FBQzNCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRTtZQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUNuRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUN6RCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7U0FDaEQ7S0FDRixDQUFDLENBQUM7SUFDSCxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7SUFFbkIsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRTtRQUMvRSxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQztRQUNsRixLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsVUFBVTtZQUNsQixXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDbEIsTUFBTSxFQUFFLFFBQVE7WUFDaEIsV0FBVyxFQUFFLEtBQUs7WUFDbEIsTUFBTSxFQUFFLEtBQUs7U0FDZDtRQUNELFFBQVEsRUFBRTtZ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QUFDO3dCQUNoQyxRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFDO3dCQUM1QixhQUFhLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDO3dCQUMzQixZQUFZLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUM7d0JBQ2hDLGtCQUFrQixFQUFFLEVBQUMsT0FBTyxFQUFFLENBQUMsRUFBQzt3QkFDaEMsZUFBZSxFQUFFLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQztxQkFDakM7b0JBQ0QsUUFBUSxFQUFFO3dCQUNSLEdBQUcsRUFBRTs0QkFDSCxRQUFRLEVBQUUsYUFBYTt5QkFDeEI7d0JBQ0QsR0FBRyxFQUFFOzRCQUNILFFBQVEsRUFBRSxhQUFhO3lCQUN4Qjt3QkFDRCxJQUFJLEVBQUU7NEJBQ0osUUFBUSxFQUFFLGFBQWE7eUJBQ3hCO3dCQUNELElBQUksRUFBRTs0QkFDSixRQUFRLEVBQUUsYUFBYTt5QkFDeEI7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZSBxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtzZWxlY3RvciBhcyBwYXJzZVNlbGVjdG9yfSBmcm9tICd2ZWdhLWV2ZW50LXNlbGVjdG9yJztcblxuaW1wb3J0IGludGVydmFsIGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi9pbnRlcnZhbCc7XG5pbXBvcnQgKiBhcyBzZWxlY3Rpb24gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ0ludGVydmFsIFNlbGVjdGlvbnMnLCBmdW5jdGlvbigpIHtcbiAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgXCJtYXJrXCI6IFwiY2lyY2xlXCIsXG4gICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICBcInhcIjoge1wiZmllbGRcIjogXCJIb3JzZXBvd2VyXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiTWlsZXMtcGVyLUdhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgIH1cbiAgfSk7XG4gIG1vZGVsLnBhcnNlU2NhbGUoKTtcblxuICBjb25zdCBzZWxDbXB0cyA9IG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb24gPSBzZWxlY3Rpb24ucGFyc2VVbml0U2VsZWN0aW9uKG1vZGVsLCB7XG4gICAgXCJvbmVcIjoge1widHlwZVwiOiBcImludGVydmFsXCIsIFwiZW5jb2RpbmdzXCI6IFtcInhcIl0sIFwidHJhbnNsYXRlXCI6IGZhbHNlLCBcInpvb21cIjogZmFsc2V9LFxuICAgIFwidHdvXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVydmFsXCIsXG4gICAgICBcImVuY29kaW5nc1wiOiBbXCJ5XCJdLFxuICAgICAgXCJiaW5kXCI6IFwic2NhbGVzXCIsXG4gICAgICBcInRyYW5zbGF0ZVwiOiBmYWxzZSxcbiAgICAgIFwiem9vbVwiOiBmYWxzZVxuICAgIH0sXG4gICAgXCJ0aHItZWVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIixcbiAgICAgIFwib25cIjogXCJbbW91c2Vkb3duLCBtb3VzZXVwXSA+IG1vdXNlbW92ZSwgW2tleWRvd24sIGtleXVwXSA+IGtleXByZXNzXCIsXG4gICAgICBcInRyYW5zbGF0ZVwiOiBmYWxzZSxcbiAgICAgIFwiem9vbVwiOiBmYWxzZSxcbiAgICAgIFwicmVzb2x2ZVwiOiBcImludGVyc2VjdFwiLFxuICAgICAgXCJtYXJrXCI6IHtcbiAgICAgICAgXCJmaWxsXCI6IFwicmVkXCIsXG4gICAgICAgIFwiZmlsbE9wYWNpdHlcIjogMC43NSxcbiAgICAgICAgXCJzdHJva2VcIjogXCJibGFja1wiLFxuICAgICAgICBcInN0cm9rZVdpZHRoXCI6IDQsXG4gICAgICAgIFwic3Ryb2tlRGFzaFwiOiBbMTAsIDVdLFxuICAgICAgICBcInN0cm9rZURhc2hPZmZzZXRcIjogMyxcbiAgICAgICAgXCJzdHJva2VPcGFjaXR5XCI6IDAuMjVcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUdXBsZSBTaWduYWxzJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ2J1aWxkcyBwcm9qZWN0aW9uIHNpZ25hbHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IG9uZVNnID0gaW50ZXJ2YWwuc2lnbmFscyhtb2RlbCwgc2VsQ21wdHNbJ29uZSddKTtcbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMob25lU2csIFt7XG4gICAgICAgIFwibmFtZVwiOiBcIm9uZV94XCIsXG4gICAgICAgIFwidmFsdWVcIjogW10sXG4gICAgICAgIFwib25cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ21vdXNlZG93bicsICdzY29wZScpWzBdLFxuICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJbeCh1bml0KSwgeCh1bml0KV1cIlxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJldmVudHNcIjogcGFyc2VTZWxlY3RvcignW21vdXNlZG93biwgd2luZG93Om1vdXNldXBdID4gd2luZG93Om1vdXNlbW92ZSEnLCAnc2NvcGUnKVswXSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiW29uZV94WzBdLCBjbGFtcCh4KHVuaXQpLCAwLCB3aWR0aCldXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcIm9uZV9zY2FsZV90cmlnZ2VyXCJ9LFxuICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJbc2NhbGUoXFxcInhcXFwiLCBvbmVfSG9yc2Vwb3dlclswXSksIHNjYWxlKFxcXCJ4XFxcIiwgb25lX0hvcnNlcG93ZXJbMV0pXVwiXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LCB7XG4gICAgICAgIFwibmFtZVwiOiBcIm9uZV9Ib3JzZXBvd2VyXCIsXG4gICAgICAgIFwib25cIjogW3tcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJvbmVfeFwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcIm9uZV94WzBdID09PSBvbmVfeFsxXSA/IG51bGwgOiBpbnZlcnQoXFxcInhcXFwiLCBvbmVfeClcIlxuICAgICAgICB9XVxuICAgICAgfSwge1xuICAgICAgICBcIm5hbWVcIjogXCJvbmVfc2NhbGVfdHJpZ2dlclwiLFxuICAgICAgICBcInVwZGF0ZVwiOiBcIighaXNBcnJheShvbmVfSG9yc2Vwb3dlcikgfHwgKCtpbnZlcnQoXFxcInhcXFwiLCBvbmVfeClbMF0gPT09ICtvbmVfSG9yc2Vwb3dlclswXSAmJiAraW52ZXJ0KFxcXCJ4XFxcIiwgb25lX3gpWzFdID09PSArb25lX0hvcnNlcG93ZXJbMV0pKSA/IG9uZV9zY2FsZV90cmlnZ2VyIDoge31cIlxuICAgICAgfV0pO1xuXG4gICAgICBjb25zdCB0d29TZyA9IGludGVydmFsLnNpZ25hbHMobW9kZWwsIHNlbENtcHRzWyd0d28nXSk7XG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHR3b1NnLCBbe1xuICAgICAgICBcIm5hbWVcIjogXCJ0d29fTWlsZXNfcGVyX0dhbGxvblwiLFxuICAgICAgICBcIm9uXCI6IFtdXG4gICAgICB9XSk7XG5cbiAgICAgIGNvbnN0IHRocmVlU2cgPSBpbnRlcnZhbC5zaWduYWxzKG1vZGVsLCBzZWxDbXB0c1sndGhyX2VlJ10pO1xuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyh0aHJlZVNnLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0aHJfZWVfeFwiLFxuICAgICAgICAgIFwidmFsdWVcIjogW10sXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ21vdXNlZG93bicsICdzY29wZScpWzBdLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcIlt4KHVuaXQpLCB4KHVuaXQpXVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiBwYXJzZVNlbGVjdG9yKCdbbW91c2Vkb3duLCBtb3VzZXVwXSA+IG1vdXNlbW92ZScsICdzY29wZScpWzBdLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcIlt0aHJfZWVfeFswXSwgY2xhbXAoeCh1bml0KSwgMCwgd2lkdGgpXVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiBwYXJzZVNlbGVjdG9yKCdrZXlkb3duJywgJ3Njb3BlJylbMF0sXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiW3godW5pdCksIHgodW5pdCldXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ1trZXlkb3duLCBrZXl1cF0gPiBrZXlwcmVzcycsICdzY29wZScpWzBdLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcIlt0aHJfZWVfeFswXSwgY2xhbXAoeCh1bml0KSwgMCwgd2lkdGgpXVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJ0aHJfZWVfc2NhbGVfdHJpZ2dlclwifSxcbiAgICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJbc2NhbGUoXFxcInhcXFwiLCB0aHJfZWVfSG9yc2Vwb3dlclswXSksIHNjYWxlKFxcXCJ4XFxcIiwgdGhyX2VlX0hvcnNlcG93ZXJbMV0pXVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJuYW1lXCI6IFwidGhyX2VlX0hvcnNlcG93ZXJcIixcbiAgICAgICAgICBcIm9uXCI6IFt7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJ0aHJfZWVfeFwifSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwidGhyX2VlX3hbMF0gPT09IHRocl9lZV94WzFdID8gbnVsbCA6IGludmVydChcXFwieFxcXCIsIHRocl9lZV94KVwiXG4gICAgICAgICAgfV1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcInRocl9lZV95XCIsXG4gICAgICAgICAgXCJ2YWx1ZVwiOiBbXSxcbiAgICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJldmVudHNcIjogcGFyc2VTZWxlY3RvcignbW91c2Vkb3duJywgJ3Njb3BlJylbMF0sXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiW3kodW5pdCksIHkodW5pdCldXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ1ttb3VzZWRvd24sIG1vdXNldXBdID4gbW91c2Vtb3ZlJywgJ3Njb3BlJylbMF0sXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiW3Rocl9lZV95WzBdLCBjbGFtcCh5KHVuaXQpLCAwLCBoZWlnaHQpXVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiBwYXJzZVNlbGVjdG9yKCdrZXlkb3duJywgJ3Njb3BlJylbMF0sXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiW3kodW5pdCksIHkodW5pdCldXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ1trZXlkb3duLCBrZXl1cF0gPiBrZXlwcmVzcycsICdzY29wZScpWzBdLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcIlt0aHJfZWVfeVswXSwgY2xhbXAoeSh1bml0KSwgMCwgaGVpZ2h0KV1cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwidGhyX2VlX3NjYWxlX3RyaWdnZXJcIn0sXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwiW3NjYWxlKFxcXCJ5XFxcIiwgdGhyX2VlX01pbGVzX3Blcl9HYWxsb25bMF0pLCBzY2FsZShcXFwieVxcXCIsIHRocl9lZV9NaWxlc19wZXJfR2FsbG9uWzFdKV1cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcInRocl9lZV9NaWxlc19wZXJfR2FsbG9uXCIsXG4gICAgICAgICAgXCJvblwiOiBbe1xuICAgICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwidGhyX2VlX3lcIn0sXG4gICAgICAgICAgICBcInVwZGF0ZVwiOiBcInRocl9lZV95WzBdID09PSB0aHJfZWVfeVsxXSA/IG51bGwgOiBpbnZlcnQoXFxcInlcXFwiLCB0aHJfZWVfeSlcIlxuICAgICAgICAgIH1dXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0aHJfZWVfc2NhbGVfdHJpZ2dlclwiLFxuICAgICAgICAgIFwidXBkYXRlXCI6IFwiKCFpc0FycmF5KHRocl9lZV9Ib3JzZXBvd2VyKSB8fCAoK2ludmVydChcXFwieFxcXCIsIHRocl9lZV94KVswXSA9PT0gK3Rocl9lZV9Ib3JzZXBvd2VyWzBdICYmICtpbnZlcnQoXFxcInhcXFwiLCB0aHJfZWVfeClbMV0gPT09ICt0aHJfZWVfSG9yc2Vwb3dlclsxXSkpICYmICghaXNBcnJheSh0aHJfZWVfTWlsZXNfcGVyX0dhbGxvbikgfHwgKCtpbnZlcnQoXFxcInlcXFwiLCB0aHJfZWVfeSlbMF0gPT09ICt0aHJfZWVfTWlsZXNfcGVyX0dhbGxvblswXSAmJiAraW52ZXJ0KFxcXCJ5XFxcIiwgdGhyX2VlX3kpWzFdID09PSArdGhyX2VlX01pbGVzX3Blcl9HYWxsb25bMV0pKSA/IHRocl9lZV9zY2FsZV90cmlnZ2VyIDoge31cIlxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZHMgdHJpZ2dlciBzaWduYWxzJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBvbmVTZyA9IGludGVydmFsLnNpZ25hbHMobW9kZWwsIHNlbENtcHRzWydvbmUnXSk7XG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKG9uZVNnLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJvbmVfdHVwbGVcIixcbiAgICAgICAgICBcIm9uXCI6IFt7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiBbe1wic2lnbmFsXCI6IFwib25lX0hvcnNlcG93ZXJcIn1dLFxuICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJvbmVfSG9yc2Vwb3dlciA/IHt1bml0OiBcXFwiXFxcIiwgaW50ZXJ2YWxzOiBbe2VuY29kaW5nOiBcXFwieFxcXCIsIGZpZWxkOiBcXFwiSG9yc2Vwb3dlclxcXCIsIGV4dGVudDogb25lX0hvcnNlcG93ZXJ9XX0gOiBudWxsXCJcbiAgICAgICAgICB9XVxuICAgICAgICB9XG4gICAgICBdKTtcblxuICAgICAgY29uc3QgdHdvU2cgPSBpbnRlcnZhbC5zaWduYWxzKG1vZGVsLCBzZWxDbXB0c1sndHdvJ10pO1xuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyh0d29TZywgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJuYW1lXCI6IFwidHdvX3R1cGxlXCIsXG4gICAgICAgICAgXCJvblwiOiBbe1xuICAgICAgICAgICAgXCJldmVudHNcIjogW3tcInNpZ25hbFwiOiBcInR3b19NaWxlc19wZXJfR2FsbG9uXCJ9XSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwidHdvX01pbGVzX3Blcl9HYWxsb24gPyB7dW5pdDogXFxcIlxcXCIsIGludGVydmFsczogW3tlbmNvZGluZzogXFxcInlcXFwiLCBmaWVsZDogXFxcIk1pbGVzLXBlci1HYWxsb25cXFwiLCBleHRlbnQ6IHR3b19NaWxlc19wZXJfR2FsbG9ufV19IDogbnVsbFwiXG4gICAgICAgICAgfV1cbiAgICAgICAgfVxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IHRocmVlU2cgPSBpbnRlcnZhbC5zaWduYWxzKG1vZGVsLCBzZWxDbXB0c1sndGhyX2VlJ10pO1xuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyh0aHJlZVNnLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0aHJfZWVfdHVwbGVcIixcbiAgICAgICAgICBcIm9uXCI6IFt7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiBbe1wic2lnbmFsXCI6IFwidGhyX2VlX0hvcnNlcG93ZXJcIn0sIHtcInNpZ25hbFwiOiBcInRocl9lZV9NaWxlc19wZXJfR2FsbG9uXCJ9XSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IFwidGhyX2VlX0hvcnNlcG93ZXIgJiYgdGhyX2VlX01pbGVzX3Blcl9HYWxsb24gPyB7dW5pdDogXFxcIlxcXCIsIGludGVydmFsczogW3tlbmNvZGluZzogXFxcInhcXFwiLCBmaWVsZDogXFxcIkhvcnNlcG93ZXJcXFwiLCBleHRlbnQ6IHRocl9lZV9Ib3JzZXBvd2VyfSwge2VuY29kaW5nOiBcXFwieVxcXCIsIGZpZWxkOiBcXFwiTWlsZXMtcGVyLUdhbGxvblxcXCIsIGV4dGVudDogdGhyX2VlX01pbGVzX3Blcl9HYWxsb259XX0gOiBudWxsXCJcbiAgICAgICAgICB9XVxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ2J1aWxkcyBtb2RpZnkgc2lnbmFscycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG9uZUV4cHIgPSBpbnRlcnZhbC5tb2RpZnlFeHByKG1vZGVsLCBzZWxDbXB0c1snb25lJ10pO1xuICAgIGFzc2VydC5lcXVhbChvbmVFeHByLCAnb25lX3R1cGxlLCB0cnVlJyk7XG5cbiAgICBjb25zdCB0d29FeHByID0gaW50ZXJ2YWwubW9kaWZ5RXhwcihtb2RlbCwgc2VsQ21wdHNbJ3R3byddKTtcbiAgICBhc3NlcnQuZXF1YWwodHdvRXhwciwgJ3R3b190dXBsZSwgdHJ1ZScpO1xuXG4gICAgY29uc3QgdGhyZWVFeHByID0gaW50ZXJ2YWwubW9kaWZ5RXhwcihtb2RlbCwgc2VsQ21wdHNbJ3Rocl9lZSddKTtcbiAgICBhc3NlcnQuZXF1YWwodGhyZWVFeHByLCAndGhyX2VlX3R1cGxlLCB7dW5pdDogXFxcIlxcXCJ9Jyk7XG5cbiAgICBjb25zdCBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMsIFtcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwib25lX21vZGlmeVwiLFxuICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJvbmVfdHVwbGVcIn0sXG4gICAgICAgICAgICBcInVwZGF0ZVwiOiBgbW9kaWZ5KFxcXCJvbmVfc3RvcmVcXFwiLCAke29uZUV4cHJ9KWBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcInR3b19tb2RpZnlcIixcbiAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwidHdvX3R1cGxlXCJ9LFxuICAgICAgICAgICAgXCJ1cGRhdGVcIjogYG1vZGlmeShcXFwidHdvX3N0b3JlXFxcIiwgJHt0d29FeHByfSlgXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJ0aHJfZWVfbW9kaWZ5XCIsXG4gICAgICAgIFwib25cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcInRocl9lZV90dXBsZVwifSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IGBtb2RpZnkoXFxcInRocl9lZV9zdG9yZVxcXCIsICR7dGhyZWVFeHByfSlgXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9XG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZHMgYnJ1c2ggbWFyaycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1hcmtzOiBhbnlbXSA9IFt7aGVsbG86IFwid29ybGRcIn1dO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoaW50ZXJ2YWwubWFya3MobW9kZWwsIHNlbENtcHRzWydvbmUnXSwgbWFya3MpLCBbXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcIm9uZV9icnVzaF9iZ1wiLFxuICAgICAgICBcInR5cGVcIjogXCJyZWN0XCIsXG4gICAgICAgIFwiY2xpcFwiOiB0cnVlLFxuICAgICAgICBcImVuY29kZVwiOiB7XG4gICAgICAgICAgXCJlbnRlclwiOiB7XG4gICAgICAgICAgICBcImZpbGxcIjoge1widmFsdWVcIjogXCIjMzMzXCJ9LFxuICAgICAgICAgICAgXCJmaWxsT3BhY2l0eVwiOiB7XCJ2YWx1ZVwiOiAwLjEyNX1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwib25lX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcIlxcXCJcIixcbiAgICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcIm9uZV94WzBdXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJ5XCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcImRhdGEoXFxcIm9uZV9zdG9yZVxcXCIpLmxlbmd0aCAmJiBkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKVswXS51bml0ID09PSBcXFwiXFxcIlwiLFxuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcIngyXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcImRhdGEoXFxcIm9uZV9zdG9yZVxcXCIpLmxlbmd0aCAmJiBkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKVswXS51bml0ID09PSBcXFwiXFxcIlwiLFxuICAgICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwib25lX3hbMV1cIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcInkyXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcImRhdGEoXFxcIm9uZV9zdG9yZVxcXCIpLmxlbmd0aCAmJiBkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKVswXS51bml0ID09PSBcXFwiXFxcIlwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjoge1xuICAgICAgICAgICAgICAgICAgXCJncm91cFwiOiBcImhlaWdodFwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7XCJoZWxsb1wiOiBcIndvcmxkXCJ9LFxuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJvbmVfYnJ1c2hcIixcbiAgICAgICAgXCJ0eXBlXCI6IFwicmVjdFwiLFxuICAgICAgICBcImNsaXBcIjogdHJ1ZSxcbiAgICAgICAgXCJlbmNvZGVcIjoge1xuICAgICAgICAgIFwiZW50ZXJcIjoge1xuICAgICAgICAgICAgXCJmaWxsXCI6IHtcInZhbHVlXCI6IFwidHJhbnNwYXJlbnRcIn0sXG4gICAgICAgICAgICBcInN0cm9rZVwiOiB7XCJ2YWx1ZVwiOiBcIndoaXRlXCJ9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiB7XG4gICAgICAgICAgICBcInhcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ0ZXN0XCI6IFwiZGF0YShcXFwib25lX3N0b3JlXFxcIikubGVuZ3RoICYmIGRhdGEoXFxcIm9uZV9zdG9yZVxcXCIpWzBdLnVuaXQgPT09IFxcXCJcXFwiXCIsXG4gICAgICAgICAgICAgICAgXCJzaWduYWxcIjogXCJvbmVfeFswXVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInZhbHVlXCI6IDBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwieVwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwib25lX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcIlxcXCJcIixcbiAgICAgICAgICAgICAgICBcInZhbHVlXCI6IDBcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJ4MlwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwib25lX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcIlxcXCJcIixcbiAgICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcIm9uZV94WzFdXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJ5MlwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwib25lX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcIlxcXCJcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IHtcbiAgICAgICAgICAgICAgICAgIFwiZ3JvdXBcIjogXCJoZWlnaHRcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgXSk7XG5cbiAgICAvLyBTY2FsZS1ib3VuZCBpbnRlcnZhbCBzZWxlY3Rpb25zIHNob3VsZCBub3QgYWRkIGEgYnJ1c2ggbWFyay5cbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKGludGVydmFsLm1hcmtzKG1vZGVsLCBzZWxDbXB0c1sndHdvJ10sIG1hcmtzKSwgbWFya3MpO1xuXG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhpbnRlcnZhbC5tYXJrcyhtb2RlbCwgc2VsQ21wdHNbJ3Rocl9lZSddLCBtYXJrcyksIFtcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwidGhyX2VlX2JydXNoX2JnXCIsXG4gICAgICAgIFwidHlwZVwiOiBcInJlY3RcIixcbiAgICAgICAgXCJjbGlwXCI6IHRydWUsXG4gICAgICAgIFwiZW5jb2RlXCI6IHtcbiAgICAgICAgICBcImVudGVyXCI6IHtcbiAgICAgICAgICAgIFwiZmlsbFwiOiB7XCJ2YWx1ZVwiOiBcInJlZFwifSxcbiAgICAgICAgICAgIFwiZmlsbE9wYWNpdHlcIjoge1widmFsdWVcIjogMC43NX1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwidGhyX2VlX3hbMF1cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwidGhyX2VlX3lbMF1cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcInRocl9lZV94WzFdXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgXCJzaWduYWxcIjogXCJ0aHJfZWVfeVsxXVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAge1wiaGVsbG9cIjogXCJ3b3JsZFwifSxcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwidGhyX2VlX2JydXNoXCIsXG4gICAgICAgIFwidHlwZVwiOiBcInJlY3RcIixcbiAgICAgICAgXCJjbGlwXCI6IHRydWUsXG4gICAgICAgIFwiZW5jb2RlXCI6IHtcbiAgICAgICAgICBcImVudGVyXCI6IHtcbiAgICAgICAgICAgIFwiZmlsbFwiOiB7XCJ2YWx1ZVwiOiBcInRyYW5zcGFyZW50XCJ9LFxuICAgICAgICAgICAgXCJzdHJva2VcIjoge1widmFsdWVcIjogXCJibGFja1wifSxcbiAgICAgICAgICAgIFwic3Ryb2tlV2lkdGhcIjoge1widmFsdWVcIjogNH0sXG4gICAgICAgICAgICBcInN0cm9rZURhc2hcIjoge1widmFsdWVcIjogWzEwLCA1XX0sXG4gICAgICAgICAgICBcInN0cm9rZURhc2hPZmZzZXRcIjoge1widmFsdWVcIjogM30sXG4gICAgICAgICAgICBcInN0cm9rZU9wYWNpdHlcIjoge1widmFsdWVcIjogMC4yNX1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwidGhyX2VlX3hbMF1cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwidGhyX2VlX3lbMF1cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcInRocl9lZV94WzFdXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgXCJzaWduYWxcIjogXCJ0aHJfZWVfeVsxXVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgXSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/selection/layers.test.js b/build/test/compile/selection/layers.test.js new file mode 100644 index 0000000000..2f359f0ac2 --- /dev/null +++ b/build/test/compile/selection/layers.test.js @@ -0,0 +1,221 @@ +"use strict"; +/* tslint:disable quotemark */ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var selection = require("../../../src/compile/selection/selection"); +var util_1 = require("../../util"); +describe('Layered Selections', function () { + var layers = util_1.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]; + chai_1.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 () { + chai_1.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 + } + } + } + }]); + chai_1.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]; + chai_1.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 + } + ] + } + } + }, + __assign({}, child0, { clip: true }), + __assign({}, child1, { clip: true }), + // Foreground brush mark for "brush" selection. + { + "name": "brush_brush", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "transparent" }, + "stroke": { "value": "white" } + }, + "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 + } + ] + } + } + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL2xheWVycy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7Ozs7Ozs7Ozs7QUFFOUIsNkJBQTRCO0FBQzVCLG9FQUFzRTtBQUV0RSxtQ0FBMkM7QUFFM0MsUUFBUSxDQUFDLG9CQUFvQixFQUFFO0lBQzdCLElBQU0sTUFBTSxHQUFHLHNCQUFlLENBQUM7UUFDN0IsS0FBSyxFQUFFLENBQUM7Z0JBQ04sV0FBVyxFQUFFO29CQUNYLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUM7aUJBQzlCO2dCQUNELE1BQU0sRUFBRSxRQUFRO2dCQUNoQixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO29CQUNuRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztvQkFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO2lCQUNoRDthQUNGLEVBQUU7Z0JBQ0QsV0FBVyxFQUFFO29CQUNYLE1BQU0sRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBQztpQkFDL0M7Z0JBQ0QsTUFBTSxFQUFFLFFBQVE7Z0JBQ2hCLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7b0JBQ25ELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO29CQUN6RCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7aUJB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LEVBQUU7d0JBQ1IsR0FBRyxFQUFFOzRCQUNIO2dDQUNFLE1BQU0sRUFBRSwrRUFBK0U7Z0NBQ3ZGLFFBQVEsRUFBRSxZQUFZOzZCQUN2Qjs0QkFDRDtnQ0FDRSxPQUFPLEVBQUUsQ0FBQzs2QkFDWDt5QkFDRjt3QkFDRCxHQUFHLEVBQUU7NEJBQ0g7Z0NBQ0UsTUFBTSxFQUFFLCtFQUErRTtnQ0FDdkYsUUFBUSxFQUFFLFlBQVk7NkJBQ3ZCOzRCQUNEO2dDQUNFLE9BQU8sRUFBRSxDQUFDOzZCQUNYO3lCQUNGO3dCQUNELElBQUksRUFBRTs0QkFDSjtnQ0FDRSxNQUFNLEVBQUUsK0VBQStFO2dDQUN2RixRQUFRLEVBQUUsWUFBWTs2QkFDdkI7NEJBQ0Q7Z0NBQ0UsT0FBTyxFQUFFLENBQUM7NkJBQ1g7eUJBQ0Y7d0JBQ0QsSUFBSSxFQUFFOzRCQUNKO2dDQUNFLE1BQU0sRUFBRSwrRUFBK0U7Z0NBQ3ZGLFFBQVEsRUFBRSxZQUFZOzZCQUN2Qjs0QkFDRDtnQ0FDRSxPQUFPLEVBQUUsQ0FBQzs2QkFDWDt5QkFDRjtxQkFDRjtpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlIHF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQgKiBhcyBzZWxlY3Rpb24gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge1VuaXRNb2RlbH0gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvdW5pdCc7XG5pbXBvcnQge3BhcnNlTGF5ZXJNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdMYXllcmVkIFNlbGVjdGlvbnMnLCBmdW5jdGlvbigpIHtcbiAgY29uc3QgbGF5ZXJzID0gcGFyc2VMYXllck1vZGVsKHtcbiAgICBsYXllcjogW3tcbiAgICAgIFwic2VsZWN0aW9uXCI6IHtcbiAgICAgICAgXCJicnVzaFwiOiB7XCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIn1cbiAgICAgIH0sXG4gICAgICBcIm1hcmtcIjogXCJjaXJjbGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJIb3JzZXBvd2VyXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBcInNlbGVjdGlvblwiOiB7XG4gICAgICAgIFwiZ3JpZFwiOiB7XCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIiwgXCJiaW5kXCI6IFwic2NhbGVzXCJ9XG4gICAgICB9LFxuICAgICAgXCJtYXJrXCI6IFwic3F1YXJlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICB9XG4gICAgfV1cbiAgfSk7XG5cbiAgbGF5ZXJzLnBhcnNlKCk7XG5cbiAgaXQoJ3Nob3VsZCBhcHByb3ByaWF0ZWx5IG5hbWUgdGhlIHVuaXQnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCB1bml0ID0gbGF5ZXJzLmNoaWxkcmVuWzBdIGFzIFVuaXRNb2RlbDtcbiAgICBhc3NlcnQuZXF1YWwoc2VsZWN0aW9uLnVuaXROYW1lKHVuaXQpLCAnXCJsYXllcl8wXCInKTtcbiAgfSk7XG5cbiAgLy8gU2VsZWN0aW9ucyBzaG91bGQgYXVnbWVudCBsYXllcmVkIG1hcmtzIHRvZ2V0aGVyLCByYXRoZXIgdGhhbiBlYWNoXG4gIC8vIG1hcmsgaW5kaXZpZHVhbGx5LiBUaGlzIGVuc3VyZXMgY29ycmVjdCBpbnRlcmxlYXZpbmcgb2YgYnJ1c2ggbWFya3NcbiAgLy8gKGkuZS4sIHRoYXQgdGhlIGJydXNoIG1hcmsgYXBwZWFycyBhYm92ZSBhbGwgbGF5ZXJzIGFuZCB0aHVzIGNhbiBiZVxuICAvLyBtb3ZlZCBhcm91bmQpLlxuICBpdCgnc2hvdWxkIHBhc3MgdGhyb3VnaCB1bml0IG1hcmsgYXNzZW1ibHknLCBmdW5jdGlvbigpIHtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKGxheWVycy5jaGlsZHJlblswXS5hc3NlbWJsZU1hcmtzKCksIFt7XG4gICAgICBcIm5hbWVcIjogXCJsYXllcl8wX21hcmtzXCIsXG4gICAgICBcInR5cGVcIjogXCJzeW1ib2xcIixcbiAgICAgIFwic3R5bGVcIjogW1wiY2lyY2xlXCJdLFxuICAgICAgXCJmcm9tXCI6IHtcbiAgICAgICAgXCJkYXRhXCI6IFwibGF5ZXJfMF9tYWluXCJcbiAgICAgIH0sXG4gICAgICBcImNsaXBcIjogdHJ1ZSxcbiAgICAgIFwiZW5jb2RlXCI6IHtcbiAgICAgICAgXCJ1cGRhdGVcIjoge1xuICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICBcInNjYWxlXCI6IFwieFwiLFxuICAgICAgICAgICAgXCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIlxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgIFwic2NhbGVcIjogXCJ5XCIsXG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICBcImZpbGxcIjoge1xuICAgICAgICAgICAgXCJzY2FsZVwiOiBcImNvbG9yXCIsXG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiT3JpZ2luXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2hhcGVcIjoge1xuICAgICAgICAgICAgXCJ2YWx1ZVwiOiBcImNpcmNsZVwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICBcIm9wYWNpdHlcIjoge1xuICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwLjdcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XSk7XG5cbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKGxheWVycy5jaGlsZHJlblsxXS5hc3NlbWJsZU1hcmtzKCksIFt7XG4gICAgICBcIm5hbWVcIjogXCJsYXllcl8xX21hcmtzXCIsXG4gICAgICBcInR5cGVcIjogXCJzeW1ib2xcIixcbiAgICAgIFwic3R5bGVcIjogW1wic3F1YXJlXCJdLFxuICAgICAgXCJmcm9tXCI6IHtcbiAgICAgICAgXCJkYXRhXCI6IFwibGF5ZXJfMV9tYWluXCJcbiAgICAgIH0sXG4gICAgICBcImNsaXBcIjogdHJ1ZSxcbiAgICAgIFwiZW5jb2RlXCI6IHtcbiAgICAgICAgXCJ1cGRhdGVcIjoge1xuICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICBcInNjYWxlXCI6IFwieFwiLFxuICAgICAgICAgICAgXCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIlxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgIFwic2NhbGVcIjogXCJ5XCIsXG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICBcImZpbGxcIjoge1xuICAgICAgICAgICAgXCJzY2FsZVwiOiBcImNvbG9yXCIsXG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiT3JpZ2luXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2hhcGVcIjoge1xuICAgICAgICAgICAgXCJ2YWx1ZVwiOiBcInNxdWFyZVwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICBcIm9wYWNpdHlcIjoge1xuICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwLjdcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYXNzZW1ibGUgc2VsZWN0aW9uIG1hcmtzIGFjcm9zcyBsYXllcnMnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBjaGlsZDAgPSBsYXllcnMuY2hpbGRyZW5bMF0uYXNzZW1ibGVNYXJrcygpWzBdO1xuICAgIGNvbnN0IGNoaWxkMSA9IGxheWVycy5jaGlsZHJlblsxXS5hc3NlbWJsZU1hcmtzKClbMF07XG5cbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKGxheWVycy5hc3NlbWJsZU1hcmtzKCksIFtcbiAgICAgIC8vIEJhY2tncm91bmQgYnJ1c2ggbWFyayBmb3IgXCJicnVzaFwiIHNlbGVjdGlvbi5cbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwiYnJ1c2hfYnJ1c2hfYmdcIixcbiAgICAgICAgXCJ0eXBlXCI6IFwicmVjdFwiLFxuICAgICAgICBcImNsaXBcIjogdHJ1ZSxcbiAgICAgICAgXCJlbmNvZGVcIjoge1xuICAgICAgICAgIFwiZW50ZXJcIjoge1xuICAgICAgICAgICAgXCJmaWxsXCI6IHtcInZhbHVlXCI6IFwiIzMzM1wifSxcbiAgICAgICAgICAgIFwiZmlsbE9wYWNpdHlcIjoge1widmFsdWVcIjogMC4xMjV9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiB7XG4gICAgICAgICAgICBcInhcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ0ZXN0XCI6IFwiZGF0YShcXFwiYnJ1c2hfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwiYnJ1c2hfc3RvcmVcXFwiKVswXS51bml0ID09PSBcXFwibGF5ZXJfMFxcXCJcIixcbiAgICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcImJydXNoX3hbMF1cIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcInlcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ0ZXN0XCI6IFwiZGF0YShcXFwiYnJ1c2hfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwiYnJ1c2hfc3RvcmVcXFwiKVswXS51bml0ID09PSBcXFwibGF5ZXJfMFxcXCJcIixcbiAgICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcImJydXNoX3lbMF1cIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcIngyXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcImRhdGEoXFxcImJydXNoX3N0b3JlXFxcIikubGVuZ3RoICYmIGRhdGEoXFxcImJydXNoX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcImxheWVyXzBcXFwiXCIsXG4gICAgICAgICAgICAgICAgXCJzaWduYWxcIjogXCJicnVzaF94WzFdXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJ5MlwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJkYXRhKFxcXCJicnVzaF9zdG9yZVxcXCIpLmxlbmd0aCAmJiBkYXRhKFxcXCJicnVzaF9zdG9yZVxcXCIpWzBdLnVuaXQgPT09IFxcXCJsYXllcl8wXFxcIlwiLFxuICAgICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwiYnJ1c2hfeVsxXVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInZhbHVlXCI6IDBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIExheWVyIG1hcmtzXG4gICAgICB7Li4uY2hpbGQwLCBjbGlwOiB0cnVlfSwgey4uLmNoaWxkMSwgY2xpcDogdHJ1ZX0sXG4gICAgICAvLyBGb3JlZ3JvdW5kIGJydXNoIG1hcmsgZm9yIFwiYnJ1c2hcIiBzZWxlY3Rpb24uXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcImJydXNoX2JydXNoXCIsXG4gICAgICAgIFwidHlwZVwiOiBcInJlY3RcIixcbiAgICAgICAgXCJjbGlwXCI6IHRydWUsXG4gICAgICAgIFwiZW5jb2RlXCI6IHtcbiAgICAgICAgICBcImVudGVyXCI6IHtcbiAgICAgICAgICAgIFwiZmlsbFwiOiB7XCJ2YWx1ZVwiOiBcInRyYW5zcGFyZW50XCJ9LFxuICAgICAgICAgICAgXCJzdHJva2VcIjoge1widmFsdWVcIjogXCJ3aGl0ZVwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcImRhdGEoXFxcImJydXNoX3N0b3JlXFxcIikubGVuZ3RoICYmIGRhdGEoXFxcImJydXNoX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcImxheWVyXzBcXFwiXCIsXG4gICAgICAgICAgICAgICAgXCJzaWduYWxcIjogXCJicnVzaF94WzBdXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJ5XCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcImRhdGEoXFxcImJydXNoX3N0b3JlXFxcIikubGVuZ3RoICYmIGRhdGEoXFxcImJydXNoX3N0b3JlXFxcIilbMF0udW5pdCA9PT0gXFxcImxheWVyXzBcXFwiXCIsXG4gICAgICAgICAgICAgICAgXCJzaWduYWxcIjogXCJicnVzaF95WzBdXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwidmFsdWVcIjogMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJ4MlwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJkYXRhKFxcXCJicnVzaF9zdG9yZVxcXCIpLmxlbmd0aCAmJiBkYXRhKFxcXCJicnVzaF9zdG9yZVxcXCIpWzBdLnVuaXQgPT09IFxcXCJsYXllcl8wXFxcIlwiLFxuICAgICAgICAgICAgICAgIFwic2lnbmFsXCI6IFwiYnJ1c2hfeFsxXVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcInZhbHVlXCI6IDBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwieTJcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ0ZXN0XCI6IFwiZGF0YShcXFwiYnJ1c2hfc3RvcmVcXFwiKS5sZW5ndGggJiYgZGF0YShcXFwiYnJ1c2hfc3RvcmVcXFwiKVswXS51bml0ID09PSBcXFwibGF5ZXJfMFxcXCJcIixcbiAgICAgICAgICAgICAgICBcInNpZ25hbFwiOiBcImJydXNoX3lbMV1cIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJ2YWx1ZVwiOiAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICBdKTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/selection/multi.test.js b/build/test/compile/selection/multi.test.js new file mode 100644 index 0000000000..567436a402 --- /dev/null +++ b/build/test/compile/selection/multi.test.js @@ -0,0 +1,60 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var multi_1 = require("../../../src/compile/selection/multi"); +var selection = require("../../../src/compile/selection/selection"); +var util_1 = require("../../util"); +describe('Multi Selection', function () { + var model = util_1.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_1.default.signals(model, selCmpts['one']); + chai_1.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_1.default.signals(model, selCmpts['two']); + chai_1.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, []); + chai_1.assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds unit datasets', function () { + var data = []; + chai_1.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'] }; + chai_1.assert.equal(selection.assembleUnitSelectionMarks(model, marks), marks); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGkudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vbXVsdGkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsOERBQXlEO0FBQ3pELG9FQUFzRTtBQUN0RSxtQ0FBbUQ7QUFFbkQsUUFBUSxDQUFDLGlCQUFpQixFQUFFO0lBQzFCLElBQU0sS0FBSyxHQUFHLDhCQUF1QixDQUFDO1FBQ3BDLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRTtZQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUNuRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFDO1lBQ3RFLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztTQUNoRDtLQUNGLENBQUMsQ0FBQztJQUVILElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDL0UsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQztRQUN4QixLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJO1lBQ2hDLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDO1NBQzFFO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1FBQ3pCLElBQU0sS0FBSyxHQUFHLGVBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3BELGFBQU0sQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzdCLElBQUksRUFBRSxXQUFXO2dCQUNqQixLQUFLLEVBQUUsRUFBRTtnQkFDVCxFQUFFLEVBQUUsQ0FBQzt3QkFDSCxNQUFNLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU07d0JBQzlCLE1BQU0sRUFBRSxxSUFBcUk7d0JBQzdJLEtBQUssRUFBRSxJQUFJO3FCQUNaLENBQUM7YUFDSCxDQUFDLENBQUMsQ0FBQztRQUVKLElBQU0sS0FBSyxHQUFHLGVBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3BELGFBQU0sQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzdCLElBQUksRUFBRSxXQUFXO2dCQUNqQixLQUFLLEVBQUUsRUFBRTtnQkFDVCxFQUFFLEVBQUUsQ0FBQzt3QkFDSCxNQUFNLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU07d0JBQzlCLE1BQU0sRUFBRSw2WUFBNlk7d0JBQ3JaLEtBQUssRUFBRSxJQUFJO3FCQUNaLENBQUM7YUFDSCxDQUFDLENBQUMsQ0FBQztRQUVKLElBQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEUsYUFBTSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsc0JBQXNCLEVBQUU7UUFDekIsSUFBTSxJQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ3ZCLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLHlCQUF5QixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRTtZQUN2RSxFQUFDLElBQUksRUFBRSxXQUFXLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxXQUFXLEVBQUM7U0FDekMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsb0JBQW9CLEVBQUU7UUFDdkIsSUFBTSxLQUFLLEdBQVUsRUFBRSxDQUFDO1FBQ3hCLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLEVBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDO1FBQ25ELGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLDBCQUEwQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMxRSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCBtdWx0aSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vbXVsdGknO1xuaW1wb3J0ICogYXMgc2VsZWN0aW9uIGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi9zZWxlY3Rpb24nO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZX0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdNdWx0aSBTZWxlY3Rpb24nLCBmdW5jdGlvbigpIHtcbiAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbFdpdGhTY2FsZSh7XG4gICAgXCJtYXJrXCI6IFwiY2lyY2xlXCIsXG4gICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICBcInhcIjoge1wiZmllbGRcIjogXCJIb3JzZXBvd2VyXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImJpblwiOiB0cnVlfSxcbiAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3Qgc2VsQ21wdHMgPSBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0gc2VsZWN0aW9uLnBhcnNlVW5pdFNlbGVjdGlvbihtb2RlbCwge1xuICAgIFwib25lXCI6IHtcInR5cGVcIjogXCJtdWx0aVwifSxcbiAgICBcInR3b1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJtdWx0aVwiLCBcIm5lYXJlc3RcIjogdHJ1ZSxcbiAgICAgIFwib25cIjogXCJtb3VzZW92ZXJcIiwgXCJ0b2dnbGVcIjogXCJldmVudC5jdHJsS2V5XCIsIFwiZW5jb2RpbmdzXCI6IFtcInlcIiwgXCJjb2xvclwiXVxuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2J1aWxkcyB0dXBsZSBzaWduYWxzJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgb25lU2cgPSBtdWx0aS5zaWduYWxzKG1vZGVsLCBzZWxDbXB0c1snb25lJ10pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMob25lU2csIFt7XG4gICAgICBuYW1lOiAnb25lX3R1cGxlJyxcbiAgICAgIHZhbHVlOiB7fSxcbiAgICAgIG9uOiBbe1xuICAgICAgICBldmVudHM6IHNlbENtcHRzWydvbmUnXS5ldmVudHMsXG4gICAgICAgIHVwZGF0ZTogXCJkYXR1bSAmJiBpdGVtKCkubWFyay5tYXJrdHlwZSAhPT0gJ2dyb3VwJyA/IHt1bml0OiBcXFwiXFxcIiwgZW5jb2RpbmdzOiBbXSwgZmllbGRzOiBbXFxcIl92Z3NpZF9cXFwiXSwgdmFsdWVzOiBbZGF0dW1bXFxcIl92Z3NpZF9cXFwiXV19IDogbnVsbFwiLFxuICAgICAgICBmb3JjZTogdHJ1ZVxuICAgICAgfV1cbiAgICB9XSk7XG5cbiAgICBjb25zdCB0d29TZyA9IG11bHRpLnNpZ25hbHMobW9kZWwsIHNlbENtcHRzWyd0d28nXSk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyh0d29TZywgW3tcbiAgICAgIG5hbWU6ICd0d29fdHVwbGUnLFxuICAgICAgdmFsdWU6IHt9LFxuICAgICAgb246IFt7XG4gICAgICAgIGV2ZW50czogc2VsQ21wdHNbJ3R3byddLmV2ZW50cyxcbiAgICAgICAgdXBkYXRlOiBcImRhdHVtICYmIGl0ZW0oKS5tYXJrLm1hcmt0eXBlICE9PSAnZ3JvdXAnID8ge3VuaXQ6IFxcXCJcXFwiLCBlbmNvZGluZ3M6IFtcXFwieVxcXCIsIFxcXCJjb2xvclxcXCJdLCBmaWVsZHM6IFtcXFwiTWlsZXNfcGVyX0dhbGxvblxcXCIsIFxcXCJPcmlnaW5cXFwiXSwgdmFsdWVzOiBbWyhpdGVtKCkuaXNWb3Jvbm9pID8gZGF0dW0uZGF0dW0gOiBkYXR1bSlbXFxcImJpbl9tYXhiaW5zXzEwX01pbGVzX3Blcl9HYWxsb25cXFwiXSwgKGl0ZW0oKS5pc1Zvcm9ub2kgPyBkYXR1bS5kYXR1bSA6IGRhdHVtKVtcXFwiYmluX21heGJpbnNfMTBfTWlsZXNfcGVyX0dhbGxvbl9lbmRcXFwiXV0sIChpdGVtKCkuaXNWb3Jvbm9pID8gZGF0dW0uZGF0dW0gOiBkYXR1bSlbXFxcIk9yaWdpblxcXCJdXSwgXFxcImJpbl9NaWxlc19wZXJfR2FsbG9uXFxcIjogMX0gOiBudWxsXCIsXG4gICAgICAgIGZvcmNlOiB0cnVlXG4gICAgICB9XVxuICAgIH1dKTtcblxuICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscywgb25lU2cuY29uY2F0KHR3b1NnKSk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZHMgdW5pdCBkYXRhc2V0cycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IGRhdGE6IGFueVtdID0gW107XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uRGF0YShtb2RlbCwgZGF0YSksIFtcbiAgICAgIHtuYW1lOiAnb25lX3N0b3JlJ30sIHtuYW1lOiAndHdvX3N0b3JlJ31cbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJ2xlYXZlcyBtYXJrcyBhbG9uZScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1hcmtzOiBhbnlbXSA9IFtdO1xuICAgIG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb24gPSB7b25lOiBzZWxDbXB0c1snb25lJ119O1xuICAgIGFzc2VydC5lcXVhbChzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uTWFya3MobW9kZWwsIG1hcmtzKSwgbWFya3MpO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/selection/nearest.test.js b/build/test/compile/selection/nearest.test.js new file mode 100644 index 0000000000..b1138a39a6 --- /dev/null +++ b/build/test/compile/selection/nearest.test.js @@ -0,0 +1,99 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var selection = require("../../../src/compile/selection/selection"); +var nearest_1 = require("../../../src/compile/selection/transforms/nearest"); +var log = require("../../../src/log"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../util"); +function getModel(markType) { + var model = util_2.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 || "datum.x", + "y": y || "datum.y", + "size": [{ "signal": "width" }, { "signal": "height" }] + } + ] + } + ]; +} +describe('Nearest Selection Transform', function () { + it('identifies transform invocation', function () { + var selCmpts = getModel('circle').component.selection; + chai_1.assert.isNotFalse(nearest_1.default.has(selCmpts['one'])); + chai_1.assert.isNotFalse(nearest_1.default.has(selCmpts['two'])); + chai_1.assert.isNotTrue(nearest_1.default.has(selCmpts['three'])); + chai_1.assert.isNotTrue(nearest_1.default.has(selCmpts['four'])); + chai_1.assert.isNotTrue(nearest_1.default.has(selCmpts['five'])); + chai_1.assert.isNotTrue(nearest_1.default.has(selCmpts['six'])); + }); + it('adds voronoi for non-path marks', function () { + var model = getModel('circle'); + var selCmpts = model.component.selection; + var marks = [{ hello: "world" }]; + chai_1.assert.sameDeepMembers(nearest_1.default.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 = []; + chai_1.assert.equal(nearest_1.default.marks(model, selCmpts['one'], marks), marks); + chai_1.assert.equal(localLogger.warns[1], 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_1.default.marks(model, selCmpts['one'], marks); + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['two'], marks2), voronoiMark()); + }); + it('supports 1D voronoi', function () { + var model = getModel('circle'); + var selCmpts = model.component.selection; + var marks = [{ hello: "world" }]; + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['seven'], util_1.duplicate(marks)), voronoiMark("datum.x", { "expr": "0" })); + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['eight'], util_1.duplicate(marks)), voronoiMark({ "expr": "0" }, "datum.y")); + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['nine'], util_1.duplicate(marks)), voronoiMark("datum.x", "datum.y")); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVhcmVzdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NlbGVjdGlvbi9uZWFyZXN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLG9FQUFzRTtBQUN0RSw2RUFBd0U7QUFDeEUsc0NBQXdDO0FBQ3hDLDBDQUE0QztBQUM1QyxtQ0FBMEM7QUFFMUMsa0JBQWtCLFFBQWE7SUFDN0IsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO1NBQ2hEO0tBQ0YsQ0FBQyxDQUFDO0lBQ0gsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN2QixLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO1FBQzlELEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBQztRQUMxQyxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUM7UUFDekMsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBQztRQUM3QixNQUFNLEVBQUUsRUFBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUM7UUFDNUMsTUFBTSxFQUFFLEVBQUMs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cG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCAqIGFzIHNlbGVjdGlvbiBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCBuZWFyZXN0IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL25lYXJlc3QnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uLy4uLy4uL3NyYy9sb2cnO1xuaW1wb3J0IHtkdXBsaWNhdGV9IGZyb20gJy4uLy4uLy4uL3NyYy91dGlsJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5mdW5jdGlvbiBnZXRNb2RlbChtYXJrVHlwZTogYW55KSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgIFwibWFya1wiOiBtYXJrVHlwZSxcbiAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgfVxuICB9KTtcbiAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICBtb2RlbC5wYXJzZU1hcmtHcm91cCgpO1xuICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0gc2VsZWN0aW9uLnBhcnNlVW5pdFNlbGVjdGlvbihtb2RlbCwge1xuICAgIFwib25lXCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJuZWFyZXN0XCI6IHRydWV9LFxuICAgIFwidHdvXCI6IHtcInR5cGVcIjogXCJtdWx0aVwiLCBcIm5lYXJlc3RcIjogdHJ1ZX0sXG4gICAgXCJ0aHJlZVwiOiB7XCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIn0sXG4gICAgXCJmb3VyXCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJuZWFyZXN0XCI6IGZhbHNlfSxcbiAgICBcImZpdmVcIjoge1widHlwZVwiOiBcIm11bHRpXCJ9LFxuICAgIFwic2l4XCI6IHtcInR5cGVcIjogXCJtdWx0aVwiLCBcIm5lYXJlc3RcIjogbnVsbH0sXG4gICAgXCJzZXZlblwiOiB7XCJ0eXBlXCI6IFwic2luZ2xlXCIsIFwibmVhcmVzdFwiOiB0cnVlLCBcImVuY29kaW5nc1wiOiBbXCJ4XCJdfSxcbiAgICBcImVpZ2h0XCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJuZWFyZXN0XCI6IHRydWUsIFwiZW5jb2RpbmdzXCI6IFtcInlcIl19LFxuICAgIFwibmluZVwiOiB7XCJ0eXBlXCI6IFwic2luZ2xlXCIsIFwibmVhcmVzdFwiOiB0cnVlLCBcImVuY29kaW5nc1wiOiBbXCJjb2xvclwiXX1cbiAgfSk7XG5cbiAgcmV0dXJuIG1vZGVsO1xufVxuXG5mdW5jdGlvbiB2b3Jvbm9pTWFyayh4Pzogc3RyaW5nIHwge2V4cHI6IHN0cmluZ30sIHk/OiBzdHJpbmcgfCB7ZXhwcjogc3RyaW5nfSkge1xuICByZXR1cm4gW1xuICAgIHtoZWxsbzogXCJ3b3JsZFwifSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJ2b3Jvbm9pXCIsXG4gICAgICBcInR5cGVcIjogXCJwYXRoXCIsXG4gICAgICBcImZyb21cIjoge1wiZGF0YVwiOiBcIm1hcmtzXCJ9LFxuICAgICAgXCJlbmNvZGVcIjoge1xuICAgICAgICBcImVudGVyXCI6IHtcbiAgICAgICAgICBcImZpbGxcIjoge1widmFsdWVcIjogXCJ0cmFuc3BhcmVudFwifSxcbiAgICAgICAgICBcInN0cm9rZVdpZHRoXCI6IHtcInZhbHVlXCI6IDAuMzV9LFxuICAgICAgICAgIFwic3Ryb2tlXCI6IHtcInZhbHVlXCI6IFwidHJhbnNwYXJlbnRcIn0sXG4gICAgICAgICAgXCJpc1Zvcm9ub2lcIjoge1widmFsdWVcIjogdHJ1ZX1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFwidHJhbnNmb3JtXCI6IFtcbiAgICAgICAge1xuICAgICAgICAgIFwidHlwZVwiOiBcInZvcm9ub2lcIixcbiAgICAgICAgICBcInhcIjogeCB8fCBcImRhdHVtLnhcIixcbiAgICAgICAgICBcInlcIjogeSB8fCBcImRhdHVtLnlcIixcbiAgICAgICAgICBcInNpemVcIjogW3tcInNpZ25hbFwiOiBcIndpZHRoXCJ9LHtcInNpZ25hbFwiOiBcImhlaWdodFwifV1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH1cbiAgXTtcbn1cblxuZGVzY3JpYmUoJ05lYXJlc3QgU2VsZWN0aW9uIFRyYW5zZm9ybScsIGZ1bmN0aW9uKCkge1xuICBpdCgnaWRlbnRpZmllcyB0cmFuc2Zvcm0gaW52b2NhdGlvbicsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHNlbENtcHRzID0gZ2V0TW9kZWwoJ2NpcmNsZScpLmNvbXBvbmVudC5zZWxlY3Rpb247XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UobmVhcmVzdC5oYXMoc2VsQ21wdHNbJ29uZSddKSk7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UobmVhcmVzdC5oYXMoc2VsQ21wdHNbJ3R3byddKSk7XG4gICAgYXNzZXJ0LmlzTm90VHJ1ZShuZWFyZXN0LmhhcyhzZWxDbXB0c1sndGhyZWUnXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUobmVhcmVzdC5oYXMoc2VsQ21wdHNbJ2ZvdXInXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUobmVhcmVzdC5oYXMoc2VsQ21wdHNbJ2ZpdmUnXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUobmVhcmVzdC5oYXMoc2VsQ21wdHNbJ3NpeCddKSk7XG4gIH0pO1xuXG4gIGl0KCdhZGRzIHZvcm9ub2kgZm9yIG5vbi1wYXRoIG1hcmtzJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBnZXRNb2RlbCgnY2lyY2xlJyk7XG4gICAgY29uc3Qgc2VsQ21wdHMgPSBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uO1xuICAgIGNvbnN0IG1hcmtzOiBhbnlbXSA9IFt7aGVsbG86IFwid29ybGRcIn1dO1xuXG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhcbiAgICAgIG5lYXJlc3QubWFya3MobW9kZWwsIHNlbENtcHRzWydvbmUnXSwgbWFya3MpLCB2b3Jvbm9pTWFyaygpKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB3YXJuIGZvciBwYXRoIG1hcmtzJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgY29uc3QgbW9kZWwgPSBnZXRNb2RlbCgnbGluZScpO1xuICAgIGNvbnN0IHNlbENtcHRzID0gbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbjtcbiAgICBjb25zdCBtYXJrczogYW55W10gPSBbXTtcbiAgICBhc3NlcnQuZXF1YWwobmVhcmVzdC5tYXJrcyhtb2RlbCwgc2VsQ21wdHNbJ29uZSddLCBtYXJrcyksIG1hcmtzKTtcbiAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMV0sIGxvZy5tZXNzYWdlLm5lYXJlc3ROb3RTdXBwb3J0Rm9yQ29udGludW91cygnbGluZScpKTtcbiAgfSkpO1xuXG4gIGl0KCdsaW1pdHMgdG8gYSBzaW5nbGUgdm9yb25vaSBwZXIgdW5pdCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gZ2V0TW9kZWwoJ2NpcmNsZScpO1xuICAgIGNvbnN0IHNlbENtcHRzID0gbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbjtcbiAgICBjb25zdCBtYXJrczogYW55W10gPSBbe2hlbGxvOiBcIndvcmxkXCJ9XTtcblxuICAgIGNvbnN0IG1hcmtzMiA9IG5lYXJlc3QubWFya3MobW9kZWwsIHNlbENtcHRzWydvbmUnXSwgbWFya3MpO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoXG4gICAgICBuZWFyZXN0Lm1hcmtzKG1vZGVsLCBzZWxDbXB0c1sndHdvJ10sIG1hcmtzMiksIHZvcm9ub2lNYXJrKCkpO1xuICB9KTtcblxuICBpdCgnc3VwcG9ydHMgMUQgdm9yb25vaScsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gZ2V0TW9kZWwoJ2NpcmNsZScpO1xuICAgIGNvbnN0IHNlbENtcHRzID0gbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbjtcbiAgICBjb25zdCBtYXJrczogYW55W10gPSBbe2hlbGxvOiBcIndvcmxkXCJ9XTtcblxuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoXG4gICAgICBuZWFyZXN0Lm1hcmtzKG1vZGVsLCBzZWxDbXB0c1snc2V2ZW4nXSwgZHVwbGljYXRlKG1hcmtzKSksXG4gICAgICB2b3Jvbm9pTWFyayhcImRhdHVtLnhcIiwge1wiZXhwclwiOiBcIjBcIn0pKTtcblxuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoXG4gICAgICBuZWFyZXN0Lm1hcmtzKG1vZGVsLCBzZWxDbXB0c1snZWlnaHQnXSwgZHVwbGljYXRlKG1hcmtzKSksXG4gICAgICB2b3Jvbm9pTWFyayh7XCJleHByXCI6IFwiMFwifSwgXCJkYXR1bS55XCIpKTtcblxuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoXG4gICAgICBuZWFyZXN0Lm1hcmtzKG1vZGVsLCBzZWxDbXB0c1snbmluZSddLCBkdXBsaWNhdGUobWFya3MpKSxcbiAgICAgIHZvcm9ub2lNYXJrKFwiZGF0dW0ueFwiLCBcImRhdHVtLnlcIikpO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/selection/parse.test.js b/build/test/compile/selection/parse.test.js new file mode 100644 index 0000000000..dd98188a84 --- /dev/null +++ b/build/test/compile/selection/parse.test.js @@ -0,0 +1,107 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var vega_event_selector_1 = require("vega-event-selector"); +var selection = require("../../../src/compile/selection/selection"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../util"); +describe('Selection', function () { + var model = util_2.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" } + }); + chai_1.assert.sameMembers(util_1.keys(component), ['one', 'two', 'three']); + chai_1.assert.equal(component.one.name, 'one'); + chai_1.assert.equal(component.one.type, 'single'); + chai_1.assert.sameDeepMembers(component['one'].project, [{ field: '_vgsid_', channel: null }]); + chai_1.assert.sameDeepMembers(component['one'].events, vega_event_selector_1.selector('click', 'scope')); + chai_1.assert.equal(component.two.name, 'two'); + chai_1.assert.equal(component.two.type, 'multi'); + chai_1.assert.equal(component.two.toggle, 'event.shiftKey'); + chai_1.assert.sameDeepMembers(component['two'].project, [{ field: '_vgsid_', channel: null }]); + chai_1.assert.sameDeepMembers(component['two'].events, vega_event_selector_1.selector('click', 'scope')); + chai_1.assert.equal(component.three.name, 'three'); + chai_1.assert.equal(component.three.type, 'interval'); + chai_1.assert.equal(component.three.translate, '[mousedown, window:mouseup] > window:mousemove!'); + chai_1.assert.equal(component.three.zoom, 'wheel!'); + chai_1.assert.sameDeepMembers(component['three'].project, [{ field: 'Horsepower', channel: 'x' }, { field: 'Miles_per_Gallon', channel: 'y' }]); + chai_1.assert.sameDeepMembers(component['three'].events, vega_event_selector_1.selector('[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]" + } + }); + chai_1.assert.sameMembers(util_1.keys(component), ['one', 'two', 'three']); + chai_1.assert.equal(component.one.name, 'one'); + chai_1.assert.equal(component.one.type, 'single'); + chai_1.assert.sameDeepMembers(component['one'].project, [{ field: 'Cylinders', channel: null }]); + chai_1.assert.sameDeepMembers(component['one'].events, vega_event_selector_1.selector('dblclick', 'scope')); + chai_1.assert.equal(component.two.name, 'two'); + chai_1.assert.equal(component.two.type, 'multi'); + chai_1.assert.equal(component.two.toggle, 'event.ctrlKey'); + chai_1.assert.sameDeepMembers(component['two'].project, [{ field: 'Origin', channel: 'color' }]); + chai_1.assert.sameDeepMembers(component['two'].events, vega_event_selector_1.selector('mouseover', 'scope')); + chai_1.assert.equal(component.three.name, 'three'); + chai_1.assert.equal(component.three.type, 'interval'); + chai_1.assert.equal(component.three.translate, false); + chai_1.assert.equal(component.three.zoom, 'wheel[event.altKey]'); + chai_1.assert.sameDeepMembers(component['three'].project, [{ field: 'Miles_per_Gallon', channel: 'y' }]); + chai_1.assert.sameDeepMembers(component['three'].events, vega_event_selector_1.selector('[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" } + }); + chai_1.assert.sameMembers(util_1.keys(component), ['one', 'two', 'three']); + chai_1.assert.equal(component.one.name, 'one'); + chai_1.assert.equal(component.one.type, 'single'); + chai_1.assert.sameDeepMembers(component['one'].project, [{ field: 'Cylinders', channel: null }]); + chai_1.assert.sameDeepMembers(component['one'].events, vega_event_selector_1.selector('dblclick', 'scope')); + chai_1.assert.equal(component.two.name, 'two'); + chai_1.assert.equal(component.two.type, 'multi'); + chai_1.assert.equal(component.two.toggle, 'event.ctrlKey'); + chai_1.assert.sameDeepMembers(component['two'].project, [{ field: 'Origin', channel: 'color' }]); + chai_1.assert.sameDeepMembers(component['two'].events, vega_event_selector_1.selector('mouseover', 'scope')); + chai_1.assert.equal(component.three.name, 'three'); + chai_1.assert.equal(component.three.type, 'interval'); + chai_1.assert(!component.three.translate); + chai_1.assert.equal(component.three.zoom, 'wheel[event.altKey]'); + chai_1.assert.sameDeepMembers(component['three'].project, [{ field: 'Miles_per_Gallon', channel: 'y' }]); + chai_1.assert.sameDeepMembers(component['three'].events, vega_event_selector_1.selector('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope')); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vcGFyc2UudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsMkRBQThEO0FBQzlELG9FQUFzRTtBQUN0RSwwQ0FBdUM7QUFDdkMsbUNBQTBDO0FBRTFDLFFBQVEsQ0FBQyxXQUFXLEVBQUU7SUFDcEIsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO1NBQ2hEO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFO1FBQ3pDLElBQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7WUFDcEQsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBQztZQUN6QixLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDO1lBQ3hCLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUM7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsYUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFN0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RGLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSw4QkFBYSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRWpGLGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxQyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDckQsYUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEYsYUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLDhCQUFhLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFakYsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM1QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQy9DLGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsaURBQWlELENBQUMsQ0FBQztRQUMzRixhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdDLGFBQU0sQ0FBQyxlQUFlLENBQTZCLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDLEtBQUssRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakssYUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLDhCQUFhLENBQUMsaURBQWlELEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUMvSCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRTtRQUN0QyxJQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO1lBQ3BELEtBQUssRUFBRTtnQkFDTCxNQUFNLEVBQUUsUUFBUTtnQkFDaEIsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxXQUFXLENBQUM7YUFDMUM7WUFDRCxLQUFLLEVBQUU7Z0JBQ0wsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsSUFBSSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzthQUNyRTtZQUNELE9BQU8sRUFBRTtnQkFDUCxNQUFNLEVBQUUsVUFBVTtnQkFDbEIsSUFBSSxFQUFFLG1EQUFtRDtnQkFDekQsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUscUJBQXFCO2FBQ3RFO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsYUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFN0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hGLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSw4QkFBYSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRXBGLGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxQyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQ3BELGFBQU0sQ0FBQyxlQUFlLENBQTZCLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQztRQUNwSCxhQUFNLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsOEJBQWEsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUVyRixhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVDLGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDL0MsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDMUQsYUFBTSxDQUFDLGVBQWUsQ0FBNkIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUgsYUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLDhCQUFhLENBQUMsbURBQW1ELEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNqSSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw0QkFBNEIsRUFBRTtRQUMvQixLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsR0FBRztZQUN2QixNQUFNLEVBQUUsRUFBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFDO1lBQy9DLEtBQUssRUFBRSxFQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBQztZQUN2RSxRQUFRLEVBQUU7Z0JBQ1IsRUFBRSxFQUFFLG1EQUFtRDtnQkFDdkQsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2dCQUNoQixJQUFJLEVBQUUscUJBQXFCO2FBQzVCO1NBQ0YsQ0FBQztRQUVGLElBQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7WUFDcEQsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBQztZQUN6QixLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDO1lBQ3hCLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUM7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsYUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFN0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hGLGFBQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSw4QkFBYSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRXBGLGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxQyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQ3BELGFBQU0sQ0FBQyxlQUFlLENBQTZCLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQztRQUNwSCxhQUFNLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsOEJBQWEsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUVyRixhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVDLGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDL0MsYUFBTSxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDMUQsYUFBTSxDQUFDLGVBQWUsQ0FBNkIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUgsYUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLDhCQUFhLENBQUMsbURBQW1ELEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNqSSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7c2VsZWN0b3IgYXMgcGFyc2VTZWxlY3Rvcn0gZnJvbSAndmVnYS1ldmVudC1zZWxlY3Rvcic7XG5pbXBvcnQgKiBhcyBzZWxlY3Rpb24gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge2tleXN9IGZyb20gJy4uLy4uLy4uL3NyYy91dGlsJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnU2VsZWN0aW9uJywgZnVuY3Rpb24oKSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgIFwibWFya1wiOiBcImNpcmNsZVwiLFxuICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIk1pbGVzX3Blcl9HYWxsb25cIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdwYXJzZXMgZGVmYXVsdCBzZWxlY3Rpb24gZGVmaW5pdGlvbnMnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSBzZWxlY3Rpb24ucGFyc2VVbml0U2VsZWN0aW9uKG1vZGVsLCB7XG4gICAgICBcIm9uZVwiOiB7XCJ0eXBlXCI6IFwic2luZ2xlXCJ9LFxuICAgICAgXCJ0d29cIjoge1widHlwZVwiOiBcIm11bHRpXCJ9LFxuICAgICAgXCJ0aHJlZVwiOiB7XCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIn1cbiAgICB9KTtcblxuICAgIGFzc2VydC5zYW1lTWVtYmVycyhrZXlzKGNvbXBvbmVudCksIFsnb25lJywgJ3R3bycsICd0aHJlZSddKTtcblxuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQub25lLm5hbWUsICdvbmUnKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50Lm9uZS50eXBlLCAnc2luZ2xlJyk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ29uZSddLnByb2plY3QsIFt7ZmllbGQ6ICdfdmdzaWRfJywgY2hhbm5lbDogbnVsbH1dKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKGNvbXBvbmVudFsnb25lJ10uZXZlbnRzLCBwYXJzZVNlbGVjdG9yKCdjbGljaycsICdzY29wZScpKTtcblxuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudHdvLm5hbWUsICd0d28nKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50LnR3by50eXBlLCAnbXVsdGknKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50LnR3by50b2dnbGUsICdldmVudC5zaGlmdEtleScpO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoY29tcG9uZW50Wyd0d28nXS5wcm9qZWN0LCBbe2ZpZWxkOiAnX3Znc2lkXycsIGNoYW5uZWw6IG51bGx9XSk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ3R3byddLmV2ZW50cywgcGFyc2VTZWxlY3RvcignY2xpY2snLCAnc2NvcGUnKSk7XG5cbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50LnRocmVlLm5hbWUsICd0aHJlZScpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudGhyZWUudHlwZSwgJ2ludGVydmFsJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGNvbXBvbmVudC50aHJlZS50cmFuc2xhdGUsICdbbW91c2Vkb3duLCB3aW5kb3c6bW91c2V1cF0gPiB3aW5kb3c6bW91c2Vtb3ZlIScpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudGhyZWUuem9vbSwgJ3doZWVsIScpO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnM8c2VsZWN0aW9uLlByb2plY3RDb21wb25lbnQ+KGNvbXBvbmVudFsndGhyZWUnXS5wcm9qZWN0LCBbe2ZpZWxkOiAnSG9yc2Vwb3dlcicsIGNoYW5uZWw6ICd4J30sIHtmaWVsZDogJ01pbGVzX3Blcl9HYWxsb24nLCBjaGFubmVsOiAneSd9XSk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ3RocmVlJ10uZXZlbnRzLCBwYXJzZVNlbGVjdG9yKCdbbW91c2Vkb3duLCB3aW5kb3c6bW91c2V1cF0gPiB3aW5kb3c6bW91c2Vtb3ZlIScsICdzY29wZScpKTtcbiAgfSk7XG5cbiAgaXQoJ3N1cHBvcnRzIGlubGluZSBkZWZhdWx0IG92ZXJyaWRlcycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IHNlbGVjdGlvbi5wYXJzZVVuaXRTZWxlY3Rpb24obW9kZWwsIHtcbiAgICAgIFwib25lXCI6IHtcbiAgICAgICAgXCJ0eXBlXCI6IFwic2luZ2xlXCIsXG4gICAgICAgIFwib25cIjogXCJkYmxjbGlja1wiLCBcImZpZWxkc1wiOiBbXCJDeWxpbmRlcnNcIl1cbiAgICAgIH0sXG4gICAgICBcInR3b1wiOiB7XG4gICAgICAgIFwidHlwZVwiOiBcIm11bHRpXCIsXG4gICAgICAgIFwib25cIjogXCJtb3VzZW92ZXJcIiwgXCJ0b2dnbGVcIjogXCJldmVudC5jdHJsS2V5XCIsIFwiZW5jb2RpbmdzXCI6IFtcImNvbG9yXCJdXG4gICAgICB9LFxuICAgICAgXCJ0aHJlZVwiOiB7XG4gICAgICAgIFwidHlwZVwiOiBcImludGVydmFsXCIsXG4gICAgICAgIFwib25cIjogXCJbbW91c2Vkb3duWyFldmVudC5zaGlmdEtleV0sIG1vdXNldXBdID4gbW91c2Vtb3ZlXCIsXG4gICAgICAgIFwiZW5jb2RpbmdzXCI6IFtcInlcIl0sIFwidHJhbnNsYXRlXCI6IGZhbHNlLCBcInpvb21cIjogXCJ3aGVlbFtldmVudC5hbHRLZXldXCJcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGFzc2VydC5zYW1lTWVtYmVycyhrZXlzKGNvbXBvbmVudCksIFsnb25lJywgJ3R3bycsICd0aHJlZSddKTtcblxuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQub25lLm5hbWUsICdvbmUnKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50Lm9uZS50eXBlLCAnc2luZ2xlJyk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ29uZSddLnByb2plY3QsIFt7ZmllbGQ6ICdDeWxpbmRlcnMnLCBjaGFubmVsOiBudWxsfV0pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoY29tcG9uZW50WydvbmUnXS5ldmVudHMsIHBhcnNlU2VsZWN0b3IoJ2RibGNsaWNrJywgJ3Njb3BlJykpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGNvbXBvbmVudC50d28ubmFtZSwgJ3R3bycpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudHdvLnR5cGUsICdtdWx0aScpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudHdvLnRvZ2dsZSwgJ2V2ZW50LmN0cmxLZXknKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzPHNlbGVjdGlvbi5Qcm9qZWN0Q29tcG9uZW50Pihjb21wb25lbnRbJ3R3byddLnByb2plY3QsIFt7ZmllbGQ6ICdPcmlnaW4nLCBjaGFubmVsOiAnY29sb3InfV0pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoY29tcG9uZW50Wyd0d28nXS5ldmVudHMsIHBhcnNlU2VsZWN0b3IoJ21vdXNlb3ZlcicsICdzY29wZScpKTtcblxuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudGhyZWUubmFtZSwgJ3RocmVlJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGNvbXBvbmVudC50aHJlZS50eXBlLCAnaW50ZXJ2YWwnKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50LnRocmVlLnRyYW5zbGF0ZSwgZmFsc2UpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudGhyZWUuem9vbSwgJ3doZWVsW2V2ZW50LmFsdEtleV0nKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzPHNlbGVjdGlvbi5Qcm9qZWN0Q29tcG9uZW50Pihjb21wb25lbnRbJ3RocmVlJ10ucHJvamVjdCwgW3tmaWVsZDogJ01pbGVzX3Blcl9HYWxsb24nLCBjaGFubmVsOiAneSd9XSk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ3RocmVlJ10uZXZlbnRzLCBwYXJzZVNlbGVjdG9yKCdbbW91c2Vkb3duWyFldmVudC5zaGlmdEtleV0sIG1vdXNldXBdID4gbW91c2Vtb3ZlJywgJ3Njb3BlJykpO1xuICB9KTtcblxuICBpdCgncmVzcGVjdHMgc2VsZWN0aW9uIGNvbmZpZ3MnLCBmdW5jdGlvbigpIHtcbiAgICBtb2RlbC5jb25maWcuc2VsZWN0aW9uID0ge1xuICAgICAgc2luZ2xlOiB7b246ICdkYmxjbGljaycsIGZpZWxkczogWydDeWxpbmRlcnMnXX0sXG4gICAgICBtdWx0aToge29uOiAnbW91c2VvdmVyJywgZW5jb2RpbmdzOiBbJ2NvbG9yJ10sIHRvZ2dsZTogJ2V2ZW50LmN0cmxLZXknfSxcbiAgICAgIGludGVydmFsOiB7XG4gICAgICAgIG9uOiAnW21vdXNlZG93blshZXZlbnQuc2hpZnRLZXldLCBtb3VzZXVwXSA+IG1vdXNlbW92ZScsXG4gICAgICAgIGVuY29kaW5nczogWyd5J10sXG4gICAgICAgIHpvb206ICd3aGVlbFtldmVudC5hbHRLZXldJ1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBjb21wb25lbnQgPSBzZWxlY3Rpb24ucGFyc2VVbml0U2VsZWN0aW9uKG1vZGVsLCB7XG4gICAgICBcIm9uZVwiOiB7XCJ0eXBlXCI6IFwic2luZ2xlXCJ9LFxuICAgICAgXCJ0d29cIjoge1widHlwZVwiOiBcIm11bHRpXCJ9LFxuICAgICAgXCJ0aHJlZVwiOiB7XCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIn1cbiAgICB9KTtcblxuICAgIGFzc2VydC5zYW1lTWVtYmVycyhrZXlzKGNvbXBvbmVudCksIFsnb25lJywgJ3R3bycsICd0aHJlZSddKTtcblxuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQub25lLm5hbWUsICdvbmUnKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tcG9uZW50Lm9uZS50eXBlLCAnc2luZ2xlJyk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ29uZSddLnByb2plY3QsIFt7ZmllbGQ6ICdDeWxpbmRlcnMnLCBjaGFubmVsOiBudWxsfV0pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoY29tcG9uZW50WydvbmUnXS5ldmVudHMsIHBhcnNlU2VsZWN0b3IoJ2RibGNsaWNrJywgJ3Njb3BlJykpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGNvbXBvbmVudC50d28ubmFtZSwgJ3R3bycpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudHdvLnR5cGUsICdtdWx0aScpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudHdvLnRvZ2dsZSwgJ2V2ZW50LmN0cmxLZXknKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzPHNlbGVjdGlvbi5Qcm9qZWN0Q29tcG9uZW50Pihjb21wb25lbnRbJ3R3byddLnByb2plY3QsIFt7ZmllbGQ6ICdPcmlnaW4nLCBjaGFubmVsOiAnY29sb3InfV0pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoY29tcG9uZW50Wyd0d28nXS5ldmVudHMsIHBhcnNlU2VsZWN0b3IoJ21vdXNlb3ZlcicsICdzY29wZScpKTtcblxuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudGhyZWUubmFtZSwgJ3RocmVlJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGNvbXBvbmVudC50aHJlZS50eXBlLCAnaW50ZXJ2YWwnKTtcbiAgICBhc3NlcnQoIWNvbXBvbmVudC50aHJlZS50cmFuc2xhdGUpO1xuICAgIGFzc2VydC5lcXVhbChjb21wb25lbnQudGhyZWUuem9vbSwgJ3doZWVsW2V2ZW50LmFsdEtleV0nKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzPHNlbGVjdGlvbi5Qcm9qZWN0Q29tcG9uZW50Pihjb21wb25lbnRbJ3RocmVlJ10ucHJvamVjdCwgW3tmaWVsZDogJ01pbGVzX3Blcl9HYWxsb24nLCBjaGFubmVsOiAneSd9XSk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhjb21wb25lbnRbJ3RocmVlJ10uZXZlbnRzLCBwYXJzZVNlbGVjdG9yKCdbbW91c2Vkb3duWyFldmVudC5zaGlmdEtleV0sIG1vdXNldXBdID4gbW91c2Vtb3ZlJywgJ3Njb3BlJykpO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/selection/predicate.test.js b/build/test/compile/selection/predicate.test.js new file mode 100644 index 0000000000..578ddb4636 --- /dev/null +++ b/build/test/compile/selection/predicate.test.js @@ -0,0 +1,95 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var mixins_1 = require("../../../src/compile/mark/mixins"); +var selection = require("../../../src/compile/selection/selection"); +var filter_1 = require("../../../src/filter"); +var util_1 = require("../../util"); +var predicate = selection.predicate; +describe('Selection Predicate', function () { + var model = util_1.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 () { + chai_1.assert.equal(predicate(model, "one"), '!(length(data("one_store"))) || (vlSingle("one_store", datum))'); + chai_1.assert.equal(predicate(model, "four"), '(vlSingle("four_store", datum))'); + chai_1.assert.equal(predicate(model, { "not": "one" }), '!(length(data("one_store"))) || (!(vlSingle("one_store", datum)))'); + chai_1.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"))))'); + chai_1.assert.equal(predicate(model, { "not": { "and": ["one", "four"] } }), '!(length(data("one_store"))) || ' + + '(!((vlSingle("one_store", datum)) && ' + + '(vlSingle("four_store", datum))))'); + chai_1.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"))))'); + chai_1.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 () { + chai_1.assert.deepEqual(mixins_1.nonPosition('color', model, { vgChannel: 'fill' }), { + fill: [ + { test: '!(length(data("one_store"))) || (vlSingle("one_store", datum))', value: "grey" }, + { scale: "color", field: "Cylinders" } + ] + }); + chai_1.assert.deepEqual(mixins_1.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 () { + chai_1.assert.equal(filter_1.expression(model, { "selection": "one" }), '!(length(data("one_store"))) || (vlSingle("one_store", datum))'); + chai_1.assert.equal(filter_1.expression(model, { "selection": { "not": "one" } }), '!(length(data("one_store"))) || (!(vlSingle("one_store", datum)))'); + chai_1.assert.equal(filter_1.expression(model, { "selection": { "not": { "and": ["one", "two"] } } }), '!(length(data("one_store")) || length(data("two_store"))) || ' + + '(!((vlSingle("one_store", datum)) && ' + + '(vlMulti("two_store", datum, "union"))))'); + chai_1.assert.equal(filter_1.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"))))'); + chai_1.assert.equal(filter_1.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 () { + chai_1.assert.throws(function () { return predicate(model, 'helloworld'); }, 'Cannot find a selection named "helloworld"'); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlZGljYXRlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3ByZWRpY2F0ZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QiwyREFBNkQ7QUFDN0Qsb0VBQXNFO0FBQ3RFLDhDQUErQztBQUUvQyxtQ0FBMEM7QUFFMUMsSUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQztBQUV0QyxRQUFRLENBQUMscUJBQXFCLEVBQUU7SUFDOUIsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFO2dCQUNQLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFNBQVM7Z0JBQ3ZDLFdBQVcsRUFBRTtvQkFDWCxXQUFXLEVBQUUsS0FBSztvQkFDbEIsT0FBTyxFQUFFLE1BQU07aUJBQ2hCO2FBQ0Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUztnQkFDcEMsV0FBVyxFQUFFO29CQUNYLFdBQVcsRUFBRSxFQUFDLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQztvQkFDakUsT0FBTyxFQUFFLEdBQUc7aUJBQ2I7YUFDRjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBRW5CLEtB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O1lBQy9GLHFDQUFxQztZQUNyQyw2Q0FBNkM7WUFDN0MsdURBQXVELENBQUMsQ0FBQztJQUM3RCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRTtRQUMzQyxhQUFNLENBQUMsTUFBTSxDQUFDLGNBQU0sT0FBQSxTQUFTLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxFQUE5QixDQUE4QixFQUFFLDRDQUE0QyxDQUFDLENBQUM7SUFDcEcsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlIHF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge25vblBvc2l0aW9ufSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL21peGlucyc7XG5pbXBvcnQgKiBhcyBzZWxlY3Rpb24gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQge2V4cHJlc3Npb259IGZyb20gJy4uLy4uLy4uL3NyYy9maWx0ZXInO1xuaW1wb3J0IHtWZ0VuY29kZUVudHJ5fSBmcm9tICcuLi8uLi8uLi9zcmMvdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmNvbnN0IHByZWRpY2F0ZSA9IHNlbGVjdGlvbi5wcmVkaWNhdGU7XG5cbmRlc2NyaWJlKCdTZWxlY3Rpb24gUHJlZGljYXRlJywgZnVuY3Rpb24oKSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgIFwibWFya1wiOiBcImNpcmNsZVwiLFxuICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIk1pbGVzX3Blcl9HYWxsb25cIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBcImNvbG9yXCI6IHtcbiAgICAgICAgXCJmaWVsZFwiOiBcIkN5bGluZGVyc1wiLCBcInR5cGVcIjogXCJvcmRpbmFsXCIsXG4gICAgICAgIFwiY29uZGl0aW9uXCI6IHtcbiAgICAgICAgICBcInNlbGVjdGlvblwiOiBcIm9uZVwiLFxuICAgICAgICAgIFwidmFsdWVcIjogXCJncmV5XCJcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFwib3BhY2l0eVwiOiB7XG4gICAgICAgIFwiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwiLFxuICAgICAgICBcImNvbmRpdGlvblwiOiB7XG4gICAgICAgICAgXCJzZWxlY3Rpb25cIjoge1wib3JcIjogW1wib25lXCIsIHtcImFuZFwiOiBbXCJ0d29cIiwge1wibm90XCI6IFwidGhyLWVlXCJ9XX1dfSxcbiAgICAgICAgICBcInZhbHVlXCI6IDAuNVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBtb2RlbC5wYXJzZVNjYWxlKCk7XG5cbiAgbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbiA9IHNlbGVjdGlvbi5wYXJzZVVuaXRTZWxlY3Rpb24obW9kZWwsIHtcbiAgICBcIm9uZVwiOiB7XCJ0eXBlXCI6IFwic2luZ2xlXCJ9LFxuICAgIFwidHdvXCI6IHtcInR5cGVcIjogXCJtdWx0aVwiLCBcInJlc29sdmVcIjogXCJ1bmlvblwifSxcbiAgICBcInRoci1lZVwiOiB7XCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIiwgXCJyZXNvbHZlXCI6IFwiaW50ZXJzZWN0XCJ9LFxuICAgIFwiZm91clwiOiB7XCJ0eXBlXCI6IFwic2luZ2xlXCIsIFwiZW1wdHlcIjogXCJub25lXCJ9XG4gIH0pO1xuXG4gIGl0KCdnZW5lcmF0ZXMgdGhlIHByZWRpY2F0ZSBleHByZXNzaW9uJywgZnVuY3Rpb24oKSB7XG4gICAgYXNzZXJ0LmVxdWFsKHByZWRpY2F0ZShtb2RlbCwgXCJvbmVcIiksXG4gICAgICAnIShsZW5ndGgoZGF0YShcIm9uZV9zdG9yZVwiKSkpIHx8ICh2bFNpbmdsZShcIm9uZV9zdG9yZVwiLCBkYXR1bSkpJyk7XG5cbiAgICBhc3NlcnQuZXF1YWwocHJlZGljYXRlKG1vZGVsLCBcImZvdXJcIiksICcodmxTaW5nbGUoXCJmb3VyX3N0b3JlXCIsIGRhdHVtKSknKTtcblxuICAgIGFzc2VydC5lcXVhbChwcmVkaWNhdGUobW9kZWwsIHtcIm5vdFwiOiBcIm9uZVwifSksXG4gICAgICAnIShsZW5ndGgoZGF0YShcIm9uZV9zdG9yZVwiKSkpIHx8ICghKHZsU2luZ2xlKFwib25lX3N0b3JlXCIsIGRhdHVtKSkpJyk7XG5cbiAgICBhc3NlcnQuZXF1YWwocHJlZGljYXRlKG1vZGVsLCB7XCJub3RcIjoge1wiYW5kXCI6IFtcIm9uZVwiLCBcInR3b1wiXX19KSxcbiAgICAgICchKGxlbmd0aChkYXRhKFwib25lX3N0b3JlXCIpKSB8fCBsZW5ndGgoZGF0YShcInR3b19zdG9yZVwiKSkpIHx8ICcgK1xuICAgICAgJyghKCh2bFNpbmdsZShcIm9uZV9zdG9yZVwiLCBkYXR1bSkpICYmICcgK1xuICAgICAgJyh2bE11bHRpKFwidHdvX3N0b3JlXCIsIGRhdHVtLCBcInVuaW9uXCIpKSkpJyk7XG5cbiAgICAgIGFzc2VydC5lcXVhbChwcmVkaWNhdGUobW9kZWwsIHtcIm5vdFwiOiB7XCJhbmRcIjogW1wib25lXCIsIFwiZm91clwiXX19KSxcbiAgICAgICchKGxlbmd0aChkYXRhKFwib25lX3N0b3JlXCIpKSkgfHwgJyArXG4gICAgICAnKCEoKHZsU2luZ2xlKFwib25lX3N0b3JlXCIsIGRhdHVtKSkgJiYgJyArXG4gICAgICAnKHZsU2luZ2xlKFwiZm91cl9zdG9yZVwiLCBkYXR1bSkpKSknKTtcblxuICAgIGFzc2VydC5lcXVhbChwcmVkaWNhdGUobW9kZWwsIHtcImFuZFwiOiBbXCJvbmVcIiwgXCJ0d29cIiwge1wibm90XCI6IFwidGhyLWVlXCJ9XX0pLFxuICAgICAgJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpIHx8IGxlbmd0aChkYXRhKFwidHdvX3N0b3JlXCIpKSB8fCBsZW5ndGgoZGF0YShcInRocl9lZV9zdG9yZVwiKSkpIHx8ICcgK1xuICAgICAgJygodmxTaW5nbGUoXCJvbmVfc3RvcmVcIiwgZGF0dW0pKSAmJiAnICtcbiAgICAgICcodmxNdWx0aShcInR3b19zdG9yZVwiLCBkYXR1bSwgXCJ1bmlvblwiKSkgJiYgJyArXG4gICAgICAnKCEodmxJbnRlcnZhbChcInRocl9lZV9zdG9yZVwiLCBkYXR1bSwgXCJpbnRlcnNlY3RcIikpKSknKTtcblxuICAgIGFzc2VydC5lcXVhbChwcmVkaWNhdGUobW9kZWwsIHtcIm9yXCI6IFtcIm9uZVwiLCB7XCJhbmRcIjogW1widHdvXCIsIHtcIm5vdFwiOiBcInRoci1lZVwifV19XX0pLFxuICAgICAgJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpIHx8IGxlbmd0aChkYXRhKFwidHdvX3N0b3JlXCIpKSB8fCBsZW5ndGgoZGF0YShcInRocl9lZV9zdG9yZVwiKSkpIHx8ICcgK1xuICAgICAgJygodmxTaW5nbGUoXCJvbmVfc3RvcmVcIiwgZGF0dW0pKSB8fCAnICtcbiAgICAgICcoKHZsTXVsdGkoXCJ0d29fc3RvcmVcIiwgZGF0dW0sIFwidW5pb25cIikpICYmICcgK1xuICAgICAgJyghKHZsSW50ZXJ2YWwoXCJ0aHJfZWVfc3RvcmVcIiwgZGF0dW0sIFwiaW50ZXJzZWN0XCIpKSkpKScpO1xuICB9KTtcblxuICBpdCgnZ2VuZXJhdGVzIFZlZ2EgcHJvZHVjdGlvbiBydWxlcycsIGZ1bmN0aW9uKCkge1xuICAgIGFzc2VydC5kZWVwRXF1YWw8VmdFbmNvZGVFbnRyeT4obm9uUG9zaXRpb24oJ2NvbG9yJywgbW9kZWwsIHt2Z0NoYW5uZWw6ICdmaWxsJ30pLCB7XG4gICAgICBmaWxsOiBbXG4gICAgICAgIHt0ZXN0OiAnIShsZW5ndGgoZGF0YShcIm9uZV9zdG9yZVwiKSkpIHx8ICh2bFNpbmdsZShcIm9uZV9zdG9yZVwiLCBkYXR1bSkpJywgdmFsdWU6IFwiZ3JleVwifSxcbiAgICAgICAge3NjYWxlOiBcImNvbG9yXCIsIGZpZWxkOiBcIkN5bGluZGVyc1wifVxuICAgICAgXVxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LmRlZXBFcXVhbDxWZ0VuY29kZUVudHJ5Pihub25Qb3NpdGlvbignb3BhY2l0eScsIG1vZGVsKSwge1xuICAgICAgb3BhY2l0eTogW1xuICAgICAgICB7dGVzdDogJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpIHx8IGxlbmd0aChkYXRhKFwidHdvX3N0b3JlXCIpKSB8fCBsZW5ndGgoZGF0YShcInRocl9lZV9zdG9yZVwiKSkpIHx8ICcgK1xuICAgICAgICAgICAgICAnKCh2bFNpbmdsZShcIm9uZV9zdG9yZVwiLCBkYXR1bSkpIHx8ICcgK1xuICAgICAgICAgICAgICAnKCh2bE11bHRpKFwidHdvX3N0b3JlXCIsIGRhdHVtLCBcInVuaW9uXCIpKSAmJiAnICtcbiAgICAgICAgICAgICAgJyghKHZsSW50ZXJ2YWwoXCJ0aHJfZWVfc3RvcmVcIiwgZGF0dW0sIFwiaW50ZXJzZWN0XCIpKSkpKScsXG4gICAgICAgICAgdmFsdWU6IDAuNX0sXG4gICAgICAgIHtzY2FsZTogXCJvcGFjaXR5XCIsIGZpZWxkOiBcIk9yaWdpblwifVxuICAgICAgXVxuICAgIH0pO1xuICB9KTtcblxuICBpdCgnZ2VuZXJhdGVzIGEgc2VsZWN0aW9uIGZpbHRlcicsIGZ1bmN0aW9uKCkge1xuICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uKG1vZGVsLCB7XCJzZWxlY3Rpb25cIjogXCJvbmVcIn0pLFxuICAgICAgJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpKSB8fCAodmxTaW5nbGUoXCJvbmVfc3RvcmVcIiwgZGF0dW0pKScpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGV4cHJlc3Npb24obW9kZWwsIHtcInNlbGVjdGlvblwiOiB7XCJub3RcIjogXCJvbmVcIn19KSxcbiAgICAgICchKGxlbmd0aChkYXRhKFwib25lX3N0b3JlXCIpKSkgfHwgKCEodmxTaW5nbGUoXCJvbmVfc3RvcmVcIiwgZGF0dW0pKSknKTtcblxuICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uKG1vZGVsLCB7XCJzZWxlY3Rpb25cIjoge1wibm90XCI6IHtcImFuZFwiOiBbXCJvbmVcIiwgXCJ0d29cIl19fX0pLFxuICAgICAgJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpIHx8IGxlbmd0aChkYXRhKFwidHdvX3N0b3JlXCIpKSkgfHwgJyArXG4gICAgICAnKCEoKHZsU2luZ2xlKFwib25lX3N0b3JlXCIsIGRhdHVtKSkgJiYgJyArXG4gICAgICAnKHZsTXVsdGkoXCJ0d29fc3RvcmVcIiwgZGF0dW0sIFwidW5pb25cIikpKSknKTtcblxuICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uKG1vZGVsLCB7XCJzZWxlY3Rpb25cIjoge1wiYW5kXCI6IFtcIm9uZVwiLCBcInR3b1wiLCB7XCJub3RcIjogXCJ0aHItZWVcIn1dfX0pLFxuICAgICAgJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpIHx8IGxlbmd0aChkYXRhKFwidHdvX3N0b3JlXCIpKSB8fCBsZW5ndGgoZGF0YShcInRocl9lZV9zdG9yZVwiKSkpIHx8ICcgK1xuICAgICAgJygodmxTaW5nbGUoXCJvbmVfc3RvcmVcIiwgZGF0dW0pKSAmJiAnICtcbiAgICAgICcodmxNdWx0aShcInR3b19zdG9yZVwiLCBkYXR1bSwgXCJ1bmlvblwiKSkgJiYgJyArXG4gICAgICAnKCEodmxJbnRlcnZhbChcInRocl9lZV9zdG9yZVwiLCBkYXR1bSwgXCJpbnRlcnNlY3RcIikpKSknKTtcblxuICAgIGFzc2VydC5lcXVhbChleHByZXNzaW9uKG1vZGVsLCB7XCJzZWxlY3Rpb25cIjoge1wib3JcIjogW1wib25lXCIsIHtcImFuZFwiOiBbXCJ0d29cIiwge1wibm90XCI6IFwidGhyLWVlXCJ9XX1dfX0pLFxuICAgICAgJyEobGVuZ3RoKGRhdGEoXCJvbmVfc3RvcmVcIikpIHx8IGxlbmd0aChkYXRhKFwidHdvX3N0b3JlXCIpKSB8fCBsZW5ndGgoZGF0YShcInRocl9lZV9zdG9yZVwiKSkpIHx8ICcgK1xuICAgICAgJygodmxTaW5nbGUoXCJvbmVfc3RvcmVcIiwgZGF0dW0pKSB8fCAnICtcbiAgICAgICcoKHZsTXVsdGkoXCJ0d29fc3RvcmVcIiwgZGF0dW0sIFwidW5pb25cIikpICYmICcgK1xuICAgICAgJyghKHZsSW50ZXJ2YWwoXCJ0aHJfZWVfc3RvcmVcIiwgZGF0dW0sIFwiaW50ZXJzZWN0XCIpKSkpKScpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGFuIGVycm9yIGZvciB1bmtub3duIHNlbGVjdGlvbnMnLCBmdW5jdGlvbigpIHtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHByZWRpY2F0ZShtb2RlbCwgJ2hlbGxvd29ybGQnKSwgJ0Nhbm5vdCBmaW5kIGEgc2VsZWN0aW9uIG5hbWVkIFwiaGVsbG93b3JsZFwiJyk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/selection/scales.test.js b/build/test/compile/selection/scales.test.js new file mode 100644 index 0000000000..d92ee512a8 --- /dev/null +++ b/build/test/compile/selection/scales.test.js @@ -0,0 +1,75 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var assemble_1 = require("../../../src/compile/scale/assemble"); +var util_1 = require("../../util"); +describe('Selection + Scales', function () { + it('assembles domainRaw from selection parameter', function () { + var model = util_1.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 = assemble_1.assembleScalesForModel(model.children[1]); + var xscale = scales[0]; + var yscale = scales[1]; + var cscale = scales[2]; + var oscale = scales[3]; + chai_1.assert.isObject(xscale.domain); + chai_1.assert.property(xscale, 'domainRaw'); + chai_1.assert.propertyVal(xscale.domainRaw, 'signal', "vlIntervalDomain(\"brush_store\", \"x\", null)"); + chai_1.assert.isObject(yscale.domain); + chai_1.assert.property(yscale, 'domainRaw'); + chai_1.assert.deepPropertyVal(yscale.domainRaw, 'signal', "vlMultiDomain(\"brush2_store\", null, \"price\", \"intersect\")"); + chai_1.assert.isObject(cscale.domain); + chai_1.assert.property(cscale, 'domainRaw'); + chai_1.assert.propertyVal(cscale.domainRaw, 'signal', "vlMultiDomain(\"brush2_store\", null, \"price\", \"intersect\")"); + chai_1.assert.isObject(oscale.domain); + chai_1.assert.property(oscale, 'domainRaw'); + chai_1.assert.propertyVal(oscale.domainRaw, 'signal', 'null'); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGVzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3NjYWxlcy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixnRUFBMkU7QUFFM0UsbUNBQTRDO0FBRTVDLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRTtJQUM3QixFQUFFLENBQUMsOENBQThDLEVBQUU7UUFDakQsSUFBTSxLQUFLLEdBQUcsdUJBQWdCLENBQUM7WUFDN0IsT0FBTyxFQUFFO2dCQUNQO29CQUNFLElBQUksRUFBRSxNQUFNO29CQUNaLFNBQVMsRUFBRTt3QkFDVCxLQUFLLEVBQUUsRUFBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFDO3dCQUMzQyxNQUFNLEVBQUUsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUM7cUJBQ2pFO29CQUNELFFBQVEsRUFBRTt3QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUM7d0JBQ3BDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztxQkFDMUM7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsU0FBUyxFQUFFO3dCQUNULE1BQU0sRUFBRSxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUM7cUJBQzNCO29CQUNELElBQUksRUFBRSxNQUFNO29CQUNaLFFBQVEsRUFBRTt3QkFDUixDQUFDLEVBQUU7NEJBQ0QsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVTs0QkFDL0IsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFDLEVBQUM7eUJBQ3JEO3dCQUNELENBQUMsRUFBRTs0QkFDRCxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxjQUFjOzRCQUNwQyxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsRUFBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUMsRUFBQzt5QkFDdkQ7d0JBQ0QsS0FBSyxFQUFFOzRCQUNMLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVM7NEJBQ2hDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQVcsRUFBQzt5QkFDakQ7d0JBQ0QsT0FBTyxFQUFFOzRCQUNQLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVM7NEJBQ2hDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQVcsRUFBQzt5QkFDakQ7cUJBQ0Y7aUJBQ0Y7YUFDRjtZQUNELE9BQU8sRUFBRTtnQkFDUCxLQUFLLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLGFBQWE7b0JBQ3BCLE9BQU8sRUFBRSxhQUFhO2lCQUN2QjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ25CLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUV2QixJQUFNLE1BQU0sR0FBRyxpQ0FBc0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekQsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pCLElBQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QixJQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekIsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpCLGFBQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9CLGFBQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3JDLGFBQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQzNDLGdEQUFnRCxDQUFDLENBQUM7UUFFcEQsYUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0IsYUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDckMsYUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFDL0MsaUVBQWlFLENBQUMsQ0FBQztRQUVyRSxhQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQixhQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNyQyxhQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUMzQyxpRUFBaUUsQ0FBQyxDQUFDO1FBRXJFLGFBQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9CLGFBQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3JDLGFBQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2Fzc2VtYmxlU2NhbGVzRm9yTW9kZWx9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NjYWxlL2Fzc2VtYmxlJztcbmltcG9ydCB7RG9tYWlufSBmcm9tICcuLi8uLi8uLi9zcmMvc2NhbGUnO1xuaW1wb3J0IHtwYXJzZUNvbmNhdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZGVzY3JpYmUoJ1NlbGVjdGlvbiArIFNjYWxlcycsIGZ1bmN0aW9uKCkge1xuICBpdCgnYXNzZW1ibGVzIGRvbWFpblJhdyBmcm9tIHNlbGVjdGlvbiBwYXJhbWV0ZXInLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtb2RlbCA9IHBhcnNlQ29uY2F0TW9kZWwoe1xuICAgICAgdmNvbmNhdDogW1xuICAgICAgICB7XG4gICAgICAgICAgbWFyazogXCJhcmVhXCIsXG4gICAgICAgICAgc2VsZWN0aW9uOiB7XG4gICAgICAgICAgICBicnVzaDoge3R5cGU6IFwiaW50ZXJ2YWxcIiwgZW5jb2RpbmdzOiBbXCJ4XCJdfSxcbiAgICAgICAgICAgIGJydXNoMjoge3R5cGU6IFwibXVsdGlcIiwgZmllbGRzOiBbXCJwcmljZVwiXSwgcmVzb2x2ZTogXCJpbnRlcnNlY3RcIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICB4OiB7ZmllbGQ6IFwiZGF0ZVwiLCB0eXBlOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgICAgeToge2ZpZWxkOiBcInByaWNlXCIsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc2VsZWN0aW9uOiB7XG4gICAgICAgICAgICBicnVzaDM6IHt0eXBlOiBcImludGVydmFsXCJ9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBtYXJrOiBcImFyZWFcIixcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge1xuICAgICAgICAgICAgICBmaWVsZDogXCJkYXRlXCIsIHR5cGU6IFwidGVtcG9yYWxcIixcbiAgICAgICAgICAgICAgc2NhbGU6IHtkb21haW46IHtzZWxlY3Rpb246IFwiYnJ1c2hcIiwgZW5jb2Rpbmc6IFwieFwifX1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5OiB7XG4gICAgICAgICAgICAgIGZpZWxkOiBcInByaWNlXCIsIHR5cGU6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgIHNjYWxlOiB7ZG9tYWluOiB7c2VsZWN0aW9uOiBcImJydXNoMlwiLCBmaWVsZDogXCJwcmljZVwifX1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xvcjoge1xuICAgICAgICAgICAgICBmaWVsZDogXCJzeW1ib2xcIiwgdHlwZTogXCJub21pbmFsXCIsXG4gICAgICAgICAgICAgIHNjYWxlOiB7ZG9tYWluOiB7c2VsZWN0aW9uOiBcImJydXNoMlwifSBhcyBEb21haW59XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3BhY2l0eToge1xuICAgICAgICAgICAgICBmaWVsZDogXCJzeW1ib2xcIiwgdHlwZTogXCJub21pbmFsXCIsXG4gICAgICAgICAgICAgIHNjYWxlOiB7ZG9tYWluOiB7c2VsZWN0aW9uOiBcImJydXNoM1wifSBhcyBEb21haW59XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgcmVzb2x2ZToge1xuICAgICAgICBzY2FsZToge1xuICAgICAgICAgIGNvbG9yOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIG9wYWNpdHk6ICdpbmRlcGVuZGVudCdcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICAgIG1vZGVsLnBhcnNlU2VsZWN0aW9uKCk7XG5cbiAgICBjb25zdCBzY2FsZXMgPSBhc3NlbWJsZVNjYWxlc0Zvck1vZGVsKG1vZGVsLmNoaWxkcmVuWzFdKTtcbiAgICBjb25zdCB4c2NhbGUgPSBzY2FsZXNbMF07XG4gICAgY29uc3QgeXNjYWxlID0gc2NhbGVzWzFdO1xuICAgIGNvbnN0IGNzY2FsZSA9IHNjYWxlc1syXTtcbiAgICBjb25zdCBvc2NhbGUgPSBzY2FsZXNbM107XG5cbiAgICBhc3NlcnQuaXNPYmplY3QoeHNjYWxlLmRvbWFpbik7XG4gICAgYXNzZXJ0LnByb3BlcnR5KHhzY2FsZSwgJ2RvbWFpblJhdycpO1xuICAgIGFzc2VydC5wcm9wZXJ0eVZhbCh4c2NhbGUuZG9tYWluUmF3LCAnc2lnbmFsJyxcbiAgICAgIFwidmxJbnRlcnZhbERvbWFpbihcXFwiYnJ1c2hfc3RvcmVcXFwiLCBcXFwieFxcXCIsIG51bGwpXCIpO1xuXG4gICAgYXNzZXJ0LmlzT2JqZWN0KHlzY2FsZS5kb21haW4pO1xuICAgIGFzc2VydC5wcm9wZXJ0eSh5c2NhbGUsICdkb21haW5SYXcnKTtcbiAgICBhc3NlcnQuZGVlcFByb3BlcnR5VmFsKHlzY2FsZS5kb21haW5SYXcsICdzaWduYWwnLFxuICAgICAgXCJ2bE11bHRpRG9tYWluKFxcXCJicnVzaDJfc3RvcmVcXFwiLCBudWxsLCBcXFwicHJpY2VcXFwiLCBcXFwiaW50ZXJzZWN0XFxcIilcIik7XG5cbiAgICBhc3NlcnQuaXNPYmplY3QoY3NjYWxlLmRvbWFpbik7XG4gICAgYXNzZXJ0LnByb3BlcnR5KGNzY2FsZSwgJ2RvbWFpblJhdycpO1xuICAgIGFzc2VydC5wcm9wZXJ0eVZhbChjc2NhbGUuZG9tYWluUmF3LCAnc2lnbmFsJyxcbiAgICAgIFwidmxNdWx0aURvbWFpbihcXFwiYnJ1c2gyX3N0b3JlXFxcIiwgbnVsbCwgXFxcInByaWNlXFxcIiwgXFxcImludGVyc2VjdFxcXCIpXCIpO1xuXG4gICAgYXNzZXJ0LmlzT2JqZWN0KG9zY2FsZS5kb21haW4pO1xuICAgIGFzc2VydC5wcm9wZXJ0eShvc2NhbGUsICdkb21haW5SYXcnKTtcbiAgICBhc3NlcnQucHJvcGVydHlWYWwob3NjYWxlLmRvbWFpblJhdywgJ3NpZ25hbCcsICdudWxsJyk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/selection/single.test.js b/build/test/compile/selection/single.test.js new file mode 100644 index 0000000000..69e69856ae --- /dev/null +++ b/build/test/compile/selection/single.test.js @@ -0,0 +1,105 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var selection = require("../../../src/compile/selection/selection"); +var single_1 = require("../../../src/compile/selection/single"); +var util_1 = require("../../util"); +describe('Single Selection', function () { + var model = util_1.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_1.default.signals(model, selCmpts['one']); + chai_1.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_1.default.signals(model, selCmpts['two']); + chai_1.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, []); + chai_1.assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds modify signals', function () { + var oneExpr = single_1.default.modifyExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'one_tuple, true'); + var twoExpr = single_1.default.modifyExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'two_tuple, true'); + var signals = selection.assembleUnitSelectionSignals(model, []); + chai_1.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_1.default.topLevelSignals(model, selCmpts['one'], []); + chai_1.assert.sameDeepMembers(oneSg, [{ + name: 'one', update: 'data(\"one_store\").length && {_vgsid_: data(\"one_store\")[0].values[0]}' + }]); + var twoSg = single_1.default.topLevelSignals(model, selCmpts['two'], []); + chai_1.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, []); + chai_1.assert.deepEqual(signals, [ + { + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'isTuple(group()) ? group() : unit' }] + } + ].concat(oneSg, twoSg)); + }); + it('builds unit datasets', function () { + var data = []; + chai_1.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'] }; + chai_1.assert.equal(selection.assembleUnitSelectionMarks(model, marks), marks); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3NpbmdsZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixvRUFBc0U7QUFDdEUsZ0VBQTJEO0FBQzNELG1DQUFtRDtBQUVuRCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7SUFDM0IsSUFBTSxLQUFLLEdBQUcsOEJBQXVCLENBQUM7UUFDcEMsTUFBTSxFQUFFLFFBQVE7UUFDaEIsVUFBVSxFQUFFO1lBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ25ELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUM7WUFDdEUsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO1NBQ2hEO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRTtRQUMvRSxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsUUFBUSxFQUFDO1FBQ3pCLEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUk7WUFDakMsSUFBSSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDO1NBQy9DO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1FBQ3pCLElBQU0sS0FBSyxHQUFHLGdCQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztR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aW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0ICogYXMgc2VsZWN0aW9uIGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi9zZWxlY3Rpb24nO1xuaW1wb3J0IHNpbmdsZSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vc2luZ2xlJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWxXaXRoU2NhbGV9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnU2luZ2xlIFNlbGVjdGlvbicsIGZ1bmN0aW9uKCkge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHtcbiAgICBcIm1hcmtcIjogXCJjaXJjbGVcIixcbiAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYmluXCI6IHRydWV9LFxuICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBzZWxDbXB0cyA9IG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb24gPSBzZWxlY3Rpb24ucGFyc2VVbml0U2VsZWN0aW9uKG1vZGVsLCB7XG4gICAgXCJvbmVcIjoge1widHlwZVwiOiBcInNpbmdsZVwifSxcbiAgICBcInR3b1wiOiB7XG4gICAgICBcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJuZWFyZXN0XCI6IHRydWUsXG4gICAgICBcIm9uXCI6IFwibW91c2VvdmVyXCIsIFwiZW5jb2RpbmdzXCI6IFtcInlcIiwgXCJjb2xvclwiXVxuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2J1aWxkcyB0dXBsZSBzaWduYWxzJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgb25lU2cgPSBzaW5nbGUuc2lnbmFscyhtb2RlbCwgc2VsQ21wdHNbJ29uZSddKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKG9uZVNnLCBbe1xuICAgICAgbmFtZTogJ29uZV90dXBsZScsXG4gICAgICB2YWx1ZToge30sXG4gICAgICBvbjogW3tcbiAgICAgICAgZXZlbnRzOiBzZWxDbXB0c1snb25lJ10uZXZlbnRzLFxuICAgICAgICB1cGRhdGU6IFwiZGF0dW0gJiYgaXRlbSgpLm1hcmsubWFya3R5cGUgIT09ICdncm91cCcgPyB7dW5pdDogXFxcIlxcXCIsIGVuY29kaW5nczogW10sIGZpZWxkczogW1xcXCJfdmdzaWRfXFxcIl0sIHZhbHVlczogW2RhdHVtW1xcXCJfdmdzaWRfXFxcIl1dfSA6IG51bGxcIixcbiAgICAgICAgZm9yY2U6IHRydWVcbiAgICAgIH1dXG4gICAgfV0pO1xuXG4gICAgY29uc3QgdHdvU2cgPSBzaW5nbGUuc2lnbmFscyhtb2RlbCwgc2VsQ21wdHNbJ3R3byddKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKHR3b1NnLCBbe1xuICAgICAgbmFtZTogJ3R3b190dXBsZScsXG4gICAgICB2YWx1ZToge30sXG4gICAgICBvbjogW3tcbiAgICAgICAgZXZlbnRzOiBzZWxDbXB0c1sndHdvJ10uZXZlbnRzLFxuICAgICAgICB1cGRhdGU6IFwiZGF0dW0gJiYgaXRlbSgpLm1hcmsubWFya3R5cGUgIT09ICdncm91cCcgPyB7dW5pdDogXFxcIlxcXCIsIGVuY29kaW5nczogW1xcXCJ5XFxcIiwgXFxcImNvbG9yXFxcIl0sIGZpZWxkczogW1xcXCJNaWxlc19wZXJfR2FsbG9uXFxcIiwgXFxcIk9yaWdpblxcXCJdLCB2YWx1ZXM6IFtbKGl0ZW0oKS5pc1Zvcm9ub2kgPyBkYXR1bS5kYXR1bSA6IGRhdHVtKVtcXFwiYmluX21heGJpbnNfMTBfTWlsZXNfcGVyX0dhbGxvblxcXCJdLCAoaXRlbSgpLmlzVm9yb25vaSA/IGRhdHVtLmRhdHVtIDogZGF0dW0pW1xcXCJiaW5fbWF4Ymluc18xMF9NaWxlc19wZXJfR2FsbG9uX2VuZFxcXCJdXSwgKGl0ZW0oKS5pc1Zvcm9ub2kgPyBkYXR1bS5kYXR1bSA6IGRhdHVtKVtcXFwiT3JpZ2luXFxcIl1dLCBcXFwiYmluX01pbGVzX3Blcl9HYWxsb25cXFwiOiAxfSA6IG51bGxcIixcbiAgICAgICAgZm9yY2U6IHRydWVcbiAgICAgIH1dXG4gICAgfV0pO1xuXG4gICAgY29uc3Qgc2lnbmFscyA9IHNlbGVjdGlvbi5hc3NlbWJsZVVuaXRTZWxlY3Rpb25TaWduYWxzKG1vZGVsLCBbXSk7XG4gICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLCBvbmVTZy5jb25jYXQodHdvU2cpKTtcbiAgfSk7XG5cbiAgaXQoJ2J1aWxkcyBtb2RpZnkgc2lnbmFscycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG9uZUV4cHIgPSBzaW5nbGUubW9kaWZ5RXhwcihtb2RlbCwgc2VsQ21wdHNbJ29uZSddKTtcbiAgICBhc3NlcnQuZXF1YWwob25lRXhwciwgJ29uZV90dXBsZSwgdHJ1ZScpO1xuXG4gICAgY29uc3QgdHdvRXhwciA9IHNpbmdsZS5tb2RpZnlFeHByKG1vZGVsLCBzZWxDbXB0c1sndHdvJ10pO1xuICAgIGFzc2VydC5lcXVhbCh0d29FeHByLCAndHdvX3R1cGxlLCB0cnVlJyk7XG5cbiAgICBjb25zdCBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMsIFtcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwib25lX21vZGlmeVwiLFxuICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJvbmVfdHVwbGVcIn0sXG4gICAgICAgICAgICBcInVwZGF0ZVwiOiBgbW9kaWZ5KFxcXCJvbmVfc3RvcmVcXFwiLCAke29uZUV4cHJ9KWBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIFwibmFtZVwiOiBcInR3b19tb2RpZnlcIixcbiAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwidHdvX3R1cGxlXCJ9LFxuICAgICAgICAgICAgXCJ1cGRhdGVcIjogYG1vZGlmeShcXFwidHdvX3N0b3JlXFxcIiwgJHt0d29FeHByfSlgXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9XG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZHMgdG9wLWxldmVsIHNpZ25hbHMnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBvbmVTZyA9IHNpbmdsZS50b3BMZXZlbFNpZ25hbHMobW9kZWwsIHNlbENtcHRzWydvbmUnXSwgW10pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMob25lU2csIFt7XG4gICAgICBuYW1lOiAnb25lJywgdXBkYXRlOiAnZGF0YShcXFwib25lX3N0b3JlXFxcIikubGVuZ3RoICYmIHtfdmdzaWRfOiBkYXRhKFxcXCJvbmVfc3RvcmVcXFwiKVswXS52YWx1ZXNbMF19J1xuICAgIH1dKTtcblxuICAgIGNvbnN0IHR3b1NnID0gc2luZ2xlLnRvcExldmVsU2lnbmFscyhtb2RlbCwgc2VsQ21wdHNbJ3R3byddLCBbXSk7XG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyh0d29TZywgW3tcbiAgICAgIG5hbWU6ICd0d28nLCB1cGRhdGU6ICdkYXRhKFxcXCJ0d29fc3RvcmVcXFwiKS5sZW5ndGggJiYge01pbGVzX3Blcl9HYWxsb246IGRhdGEoXFxcInR3b19zdG9yZVxcXCIpWzBdLnZhbHVlc1swXSwgT3JpZ2luOiBkYXRhKFxcXCJ0d29fc3RvcmVcXFwiKVswXS52YWx1ZXNbMV19J1xuICAgIH1dKTtcblxuICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVUb3BMZXZlbFNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICBhc3NlcnQuZGVlcEVxdWFsKHNpZ25hbHMsIFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3VuaXQnLFxuICAgICAgICB2YWx1ZToge30sXG4gICAgICAgIG9uOiBbe2V2ZW50czogJ21vdXNlbW92ZScsIHVwZGF0ZTogJ2lzVHVwbGUoZ3JvdXAoKSkgPyBncm91cCgpIDogdW5pdCd9XVxuICAgICAgfVxuICAgIF0uY29uY2F0KG9uZVNnLCB0d29TZykpO1xuICB9KTtcblxuICBpdCgnYnVpbGRzIHVuaXQgZGF0YXNldHMnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBkYXRhOiBhbnlbXSA9IFtdO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMoc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvbkRhdGEobW9kZWwsIGRhdGEpLCBbXG4gICAgICB7bmFtZTogJ29uZV9zdG9yZSd9LCB7bmFtZTogJ3R3b19zdG9yZSd9XG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCdsZWF2ZXMgbWFya3MgYWxvbmUnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBtYXJrczogYW55W10gPSBbXTtcbiAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge29uZTogc2VsQ21wdHNbJ29uZSddfTtcbiAgICBhc3NlcnQuZXF1YWwoc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvbk1hcmtzKG1vZGVsLCBtYXJrcyksIG1hcmtzKTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/selection/timeunit.test.js b/build/test/compile/selection/timeunit.test.js new file mode 100644 index 0000000000..ae7bee1a2a --- /dev/null +++ b/build/test/compile/selection/timeunit.test.js @@ -0,0 +1,123 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var assemble_1 = require("../../../src/compile/data/assemble"); +var optimize_1 = require("../../../src/compile/data/optimize"); +var timeunit_1 = require("../../../src/compile/data/timeunit"); +var selection = require("../../../src/compile/selection/selection"); +var util_1 = require("../../util"); +function getData(model) { + optimize_1.optimizeDataflow(model.component.data); + return assemble_1.assembleRootData(model.component.data); +} +function getModel(unit2) { + var model = util_1.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 = util_1.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"] } + }); + chai_1.assert.isUndefined(selCmpts['one'].timeUnit); + chai_1.assert.instanceOf(selCmpts['two'].timeUnit, timeunit_1.TimeUnitNode); + var as = selCmpts['two'].timeUnit.assemble().map(function (tx) { return tx.as; }); + chai_1.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; + chai_1.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; + } + }); + chai_1.assert.notEqual(tuIdx, -1); + chai_1.assert.notEqual(selIdx, -1); + chai_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; + chai_1.assert.equal(data2.filter(function (tx) { return tx.type === 'formula' && tx.as === 'seconds_date'; }).length, 1); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vdGltZXVuaXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFDNUIsK0RBQW9FO0FBQ3BFLCtEQUFvRTtBQUNwRSwrREFBZ0U7QUFFaEUsb0VBQXNFO0FBRXRFLG1DQUFzRDtBQUV0RCxpQkFBaUIsS0FBWTtJQUMzQiwyQkFBZ0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sQ0FBQywyQkFBZ0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRCxrQkFBa0IsS0FBZTtJQUMvQixJQUFNLEtBQUssR0FBRyxpQkFBVSxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxFQUFDLFFBQVEsRUFBRTtnQkFDakIsRUFBQyxNQUFNLEVBQUUsMkJBQTJCLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQztnQkFDbEQsRUFBQyxNQUFNLEVBQUUsMkJBQTJCLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQztnQkFDbEQsRUFBQyxNQUFNLEVBQUUsMkJBQTJCLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQztnQkFDbEQsRUFBQyxNQUFNLEVBQUUsMkJBQTJCLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQztnQkFDbEQsRUFBQyxNQUFNLEVBQUUsMkJBQTJCLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQzthQUNuRCxFQUFDO1FBQ0YsU0FBUyxFQUFFLENBQUM7Z0JBQ1YsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsV0FBVyxFQUFFO29CQUNYLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFDO2lCQUNuRDtnQkFDRCxVQUFVLEVB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SUFDbEcsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOnF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2Fzc2VtYmxlUm9vdERhdGF9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvYXNzZW1ibGUnO1xuaW1wb3J0IHtvcHRpbWl6ZURhdGFmbG93fSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL29wdGltaXplJztcbmltcG9ydCB7VGltZVVuaXROb2RlfSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3RpbWV1bml0JztcbmltcG9ydCB7TW9kZWx9IGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL21vZGVsJztcbmltcG9ydCAqIGFzIHNlbGVjdGlvbiBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vc2VsZWN0aW9uJztcbmltcG9ydCB7VW5pdFNwZWN9IGZyb20gJy4uLy4uLy4uL3NyYy9zcGVjJztcbmltcG9ydCB7cGFyc2VNb2RlbCwgcGFyc2VVbml0TW9kZWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5mdW5jdGlvbiBnZXREYXRhKG1vZGVsOiBNb2RlbCkge1xuICBvcHRpbWl6ZURhdGFmbG93KG1vZGVsLmNvbXBvbmVudC5kYXRhKTtcbiAgcmV0dXJuIGFzc2VtYmxlUm9vdERhdGEobW9kZWwuY29tcG9uZW50LmRhdGEpO1xufVxuXG5mdW5jdGlvbiBnZXRNb2RlbCh1bml0MjogVW5pdFNwZWMpIHtcbiAgY29uc3QgbW9kZWwgPSBwYXJzZU1vZGVsKHtcbiAgICBcImRhdGFcIjoge1widmFsdWVzXCI6IFtcbiAgICAgIHtcImRhdGVcIjogXCJTdW4sIDAxIEphbiAyMDEyIDIzOjAwOjAxXCIsXCJwcmljZVwiOiAxNTB9LFxuICAgICAge1wiZGF0ZVwiOiBcIlN1biwgMDIgSmFuIDIwMTIgMDA6MTA6MDJcIixcInByaWNlXCI6IDEwMH0sXG4gICAgICB7XCJkYXRlXCI6IFwiU3VuLCAwMiBKYW4gMjAxMiAwMToyMDowM1wiLFwicHJpY2VcIjogMTcwfSxcbiAgICAgIHtcImRhdGVcIjogXCJTdW4sIDAyIEphbiAyMDEyIDAyOjMwOjA0XCIsXCJwcmljZVwiOiAxNjV9LFxuICAgICAge1wiZGF0ZVwiOiBcIlN1biwgMDIgSmFuIDIwMTIgMDM6NDA6MDVcIixcInByaWNlXCI6IDIwMH1cbiAgICBdfSxcbiAgICBcImhjb25jYXRcIjogW3tcbiAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICBcInNlbGVjdGlvblwiOiB7XG4gICAgICAgIFwidHdvXCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJlbmNvZGluZ3NcIjogW1wieFwiLCBcInlcIl19XG4gICAgICB9LFxuICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgXCJmaWVsZFwiOiBcImRhdGVcIixcbiAgICAgICAgICBcInR5cGVcIjogXCJ0ZW1wb3JhbFwiLFxuICAgICAgICAgIFwidGltZVVuaXRcIjogXCJzZWNvbmRzXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9LCB1bml0Ml1cbiAgfSk7XG4gIG1vZGVsLnBhcnNlKCk7XG4gIHJldHVybiBtb2RlbDtcbn1cblxuZGVzY3JpYmUoJ1NlbGVjdGlvbiB0aW1lIHVuaXQnLCBmdW5jdGlvbigpIHtcbiAgaXQoJ2RhdGFmbG93IG5vZGVzIGFyZSBjb25zdHJ1Y3RlZCcsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCIsIFwidGltZVVuaXRcIjogXCJzZWNvbmRzXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCIsIFwidGltZVVuaXRcIjogXCJtaW51dGVzXCJ9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3Qgc2VsQ21wdHMgPSBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0gc2VsZWN0aW9uLnBhcnNlVW5pdFNlbGVjdGlvbihtb2RlbCwge1xuICAgICAgXCJvbmVcIjoge1widHlwZVwiOiBcInNpbmdsZVwifSxcbiAgICAgIFwidHdvXCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIiwgXCJlbmNvZGluZ3NcIjogW1wieFwiLCBcInlcIl19XG4gICAgfSk7XG5cbiAgICBhc3NlcnQuaXNVbmRlZmluZWQoc2VsQ21wdHNbJ29uZSddLnRpbWVVbml0KTtcbiAgICBhc3NlcnQuaW5zdGFuY2VPZihzZWxDbXB0c1sndHdvJ10udGltZVVuaXQsIFRpbWVVbml0Tm9kZSk7XG5cbiAgICBjb25zdCBhcyA9IHNlbENtcHRzWyd0d28nXS50aW1lVW5pdC5hc3NlbWJsZSgpLm1hcCgodHgpID0+IHR4LmFzKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKGFzLCBbJ3NlY29uZHNfZGF0ZScsICdtaW51dGVzX2RhdGUnXSk7XG4gIH0pO1xuXG4gIGl0KCdpcyBhZGRlZCB3aXRoIGNvbmRpdGlvbmFsIGVuY29kaW5ncycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gZ2V0TW9kZWwoe1xuICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1xuICAgICAgICAgIFwiZmllbGRcIjogXCJkYXRlXCIsXG4gICAgICAgICAgXCJ0eXBlXCI6IFwidGVtcG9yYWxcIixcbiAgICAgICAgICBcInRpbWVVbml0XCI6IFwibWludXRlc1wiXG4gICAgICAgIH0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcImNvbG9yXCI6IHtcbiAgICAgICAgICBcImNvbmRpdGlvblwiOiB7XCJzZWxlY3Rpb25cIjogXCJ0d29cIiwgXCJ2YWx1ZVwiOiBcImdvbGRlbnJvZFwifSxcbiAgICAgICAgICBcInZhbHVlXCI6IFwic3RlZWxibHVlXCJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZGF0YTIgPSBnZXREYXRhKG1vZGVsKS5maWx0ZXIoKGQpID0+IGQubmFtZSA9PT0gJ2RhdGFfMicpWzBdLnRyYW5zZm9ybTtcbiAgICBhc3NlcnQuZXF1YWwoZGF0YTIuZmlsdGVyKCh0eCkgPT4gdHgudHlwZSA9PT0gJ2Zvcm11bGEnICYmIHR4LmFzID09PSAnc2Vjb25kc19kYXRlJykubGVuZ3RoLCAxKTtcbiAgfSk7XG5cbiAgaXQoJ2lzIGFkZGVkIGJlZm9yZSBzZWxlY3Rpb24gZmlsdGVycycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IG1vZGVsID0gZ2V0TW9kZWwoe1xuICAgICAgXCJ0cmFuc2Zvcm1cIjogW3tcImZpbHRlclwiOiB7XCJzZWxlY3Rpb25cIjogXCJ0d29cIn19XSxcbiAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICBcImZpZWxkXCI6IFwiZGF0ZVwiLFxuICAgICAgICAgIFwidHlwZVwiOiBcInRlbXBvcmFsXCIsXG4gICAgICAgICAgXCJ0aW1lVW5pdFwiOiBcIm1pbnV0ZXNcIlxuICAgICAgICB9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZGF0YTIgPSBnZXREYXRhKG1vZGVsKS5maWx0ZXIoKGQpID0+IGQubmFtZSA9PT0gJ2RhdGFfMicpWzBdLnRyYW5zZm9ybTtcbiAgICBsZXQgdHVJZHggPSAtMTtcbiAgICBsZXQgc2VsSWR4ID0gLTE7XG5cbiAgICBkYXRhMi5mb3JFYWNoKCh0eCwgaWR4KSA9PiB7XG4gICAgICBpZiAodHgudHlwZSA9PT0gJ2Zvcm11bGEnICYmIHR4LmFzID09PSAnc2Vjb25kc19kYXRlJykge1xuICAgICAgICB0dUlkeCA9IGlkeDtcbiAgICAgIH0gZWxzZSBpZiAodHgudHlwZSA9PT0gJ2ZpbHRlcicgJiYgdHguZXhwci5pbmRleE9mKCd2bFNpbmdsZScpID49IDApIHtcbiAgICAgICAgc2VsSWR4ID0gaWR4O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXNzZXJ0Lm5vdEVxdWFsKHR1SWR4LCAtMSk7XG4gICAgYXNzZXJ0Lm5vdEVxdWFsKHNlbElkeCwgLTEpO1xuICAgIGFzc2VydC5pc0Fib3ZlKHNlbElkeCwgdHVJZHgpO1xuICB9KTtcblxuICBpdCgncmVtb3ZlcyBkdXBsaWNhdGUgdGltZSB1bml0IGZvcm11bGFlJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbW9kZWwgPSBnZXRNb2RlbCh7XG4gICAgICBcInRyYW5zZm9ybVwiOiBbe1wiZmlsdGVyXCI6IHtcInNlbGVjdGlvblwiOiBcInR3b1wifX1dLFxuICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1xuICAgICAgICAgIFwiZmllbGRcIjogXCJkYXRlXCIsXG4gICAgICAgICAgXCJ0eXBlXCI6IFwidGVtcG9yYWxcIixcbiAgICAgICAgICBcInRpbWVVbml0XCI6IFwic2Vjb25kc1wiXG4gICAgICAgIH0sXG4gICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBkYXRhMiA9IGdldERhdGEobW9kZWwpLmZpbHRlcigoZCkgPT4gZC5uYW1lID09PSAnZGF0YV8yJylbMF0udHJhbnNmb3JtO1xuICAgIGFzc2VydC5lcXVhbChkYXRhMi5maWx0ZXIoKHR4KSA9PiB0eC50eXBlID09PSAnZm9ybXVsYScgJiYgdHguYXMgPT09ICdzZWNvbmRzX2RhdGUnKS5sZW5ndGgsIDEpO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/compile/selection/toggle.test.js b/build/test/compile/selection/toggle.test.js new file mode 100644 index 0000000000..f2bc04f9d4 --- /dev/null +++ b/build/test/compile/selection/toggle.test.js @@ -0,0 +1,87 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var selection = require("../../../src/compile/selection/selection"); +var toggle_1 = require("../../../src/compile/selection/transforms/toggle"); +var util_1 = require("../../util"); +describe('Toggle Selection Transform', function () { + var model = util_1.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 () { + chai_1.assert.isNotFalse(toggle_1.default.has(selCmpts['one'])); + chai_1.assert.isNotFalse(toggle_1.default.has(selCmpts['two'])); + chai_1.assert.isNotTrue(toggle_1.default.has(selCmpts['three'])); + chai_1.assert.isNotTrue(toggle_1.default.has(selCmpts['four'])); + chai_1.assert.isNotTrue(toggle_1.default.has(selCmpts['five'])); + chai_1.assert.isNotTrue(toggle_1.default.has(selCmpts['six'])); + }); + it('builds toggle signals', function () { + var oneSg = toggle_1.default.signals(model, selCmpts['one'], []); + chai_1.assert.sameDeepMembers(oneSg, [{ + name: 'one_toggle', + value: false, + on: [{ + events: selCmpts['one'].events, + update: 'event.shiftKey' + }] + }]); + var twoSg = toggle_1.default.signals(model, selCmpts['two'], []); + chai_1.assert.sameDeepMembers(twoSg, [{ + name: 'two_toggle', + value: false, + on: [{ + events: selCmpts['two'].events, + update: 'event.ctrlKey' + }] + }]); + var signals = selection.assembleUnitSelectionSignals(model, []); + chai_1.assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds modify expr', function () { + var oneExpr = toggle_1.default.modifyExpr(model, selCmpts['one'], ''); + chai_1.assert.equal(oneExpr, 'one_toggle ? null : one_tuple, one_toggle ? null : true, one_toggle ? one_tuple : null'); + var twoExpr = toggle_1.default.modifyExpr(model, selCmpts['two'], ''); + chai_1.assert.equal(twoExpr, 'two_toggle ? null : two_tuple, two_toggle ? null : {unit: \"\"}, two_toggle ? two_tuple : null'); + var signals = selection.assembleUnitSelectionSignals(model, []); + chai_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3RvZ2dsZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QixvRUFBc0U7QUFDdEUsMkVBQXNFO0FBQ3RFLG1DQUEwQztBQUUxQyxRQUFRLENBQUMsNEJBQTRCLEVBQUU7SUFDckMsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO1NBQ2hEO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDL0UsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQztRQUN4QixLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPO1lBQ25DLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDO1NBQzFFO1FBQ0QsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFDO1FBQzNDLE1BQU0sRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFP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Qyw0QkFBNEIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEUsYUFBTSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRTtZQUNqQztnQkFDRSxNQUFNLEVBQUUsWUFBWTtnQkFDcEIsSUFBSSxFQUFFO29CQUNKO3dCQUNFLFFBQVEsRUFBRSxFQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUM7d0JBQ2pDLFFBQVEsRUFBRSwyQkFBeUIsT0FBTyxNQUFHO3FCQUM5QztpQkFDRjthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLFlBQVk7Z0JBQ3BCLElBQUksRUFBRTtvQkFDSjt3QkFDRSxRQUFRLEVBQUUsRUFBQyxRQUFRLEVBQUUsV0FBVyxFQUFDO3dCQUNqQyxRQUFRLEVBQUUsMkJBQXlCLE9BQU8sTUFBRztxQkFDOUM7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZSBxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0ICogYXMgc2VsZWN0aW9uIGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi9zZWxlY3Rpb24nO1xuaW1wb3J0IHRvZ2dsZSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vdHJhbnNmb3Jtcy90b2dnbGUnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmRlc2NyaWJlKCdUb2dnbGUgU2VsZWN0aW9uIFRyYW5zZm9ybScsIGZ1bmN0aW9uKCkge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICBcIm1hcmtcIjogXCJjaXJjbGVcIixcbiAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIkhvcnNlcG93ZXJcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcIk9yaWdpblwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgfVxuICB9KTtcblxuICBtb2RlbC5wYXJzZVNjYWxlKCk7XG4gIGNvbnN0IHNlbENtcHRzID0gbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbiA9IHNlbGVjdGlvbi5wYXJzZVVuaXRTZWxlY3Rpb24obW9kZWwsIHtcbiAgICBcIm9uZVwiOiB7XCJ0eXBlXCI6IFwibXVsdGlcIn0sXG4gICAgXCJ0d29cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibXVsdGlcIiwgXCJyZXNvbHZlXCI6IFwidW5pb25cIixcbiAgICAgIFwib25cIjogXCJtb3VzZW92ZXJcIiwgXCJ0b2dnbGVcIjogXCJldmVudC5jdHJsS2V5XCIsIFwiZW5jb2RpbmdzXCI6IFtcInlcIiwgXCJjb2xvclwiXVxuICAgIH0sXG4gICAgXCJ0aHJlZVwiOiB7XCJ0eXBlXCI6IFwibXVsdGlcIiwgXCJ0b2dnbGVcIjogZmFsc2V9LFxuICAgIFwiZm91clwiOiB7XCJ0eXBlXCI6IFwibXVsdGlcIiwgXCJ0b2dnbGVcIjogbnVsbH0sXG4gICAgXCJmaXZlXCI6IHtcInR5cGVcIjogXCJzaW5nbGVcIn0sXG4gICAgXCJzaXhcIjoge1widHlwZVwiOiBcImludGVydmFsXCJ9XG4gIH0pO1xuXG4gIGl0KCdpZGVudGlmaWVzIHRyYW5zZm9ybSBpbnZvY2F0aW9uJywgZnVuY3Rpb24oKSB7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UodG9nZ2xlLmhhcyhzZWxDbXB0c1snb25lJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RGYWxzZSh0b2dnbGUuaGFzKHNlbENtcHRzWyd0d28nXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUodG9nZ2xlLmhhcyhzZWxDbXB0c1sndGhyZWUnXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUodG9nZ2xlLmhhcyhzZWxDbXB0c1snZm91ciddKSk7XG4gICAgYXNzZXJ0LmlzTm90VHJ1ZSh0b2dnbGUuaGFzKHNlbENtcHRzWydmaXZlJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RUcnVlKHRvZ2dsZS5oYXMoc2VsQ21wdHNbJ3NpeCddKSk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZHMgdG9nZ2xlIHNpZ25hbHMnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBvbmVTZyA9IHRvZ2dsZS5zaWduYWxzKG1vZGVsLCBzZWxDbXB0c1snb25lJ10sIFtdKTtcbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKG9uZVNnLCBbe1xuICAgICAgbmFtZTogJ29uZV90b2dnbGUnLFxuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgb246IFt7XG4gICAgICAgIGV2ZW50czogc2VsQ21wdHNbJ29uZSddLmV2ZW50cyxcbiAgICAgICAgdXBkYXRlOiAnZXZlbnQuc2hpZnRLZXknXG4gICAgICB9XVxuICAgIH1dKTtcblxuICAgIGNvbnN0IHR3b1NnID0gdG9nZ2xlLnNpZ25hbHMobW9kZWwsIHNlbENtcHRzWyd0d28nXSwgW10pO1xuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnModHdvU2csIFt7XG4gICAgICBuYW1lOiAndHdvX3RvZ2dsZScsXG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICBvbjogW3tcbiAgICAgICAgZXZlbnRzOiBzZWxDbXB0c1sndHdvJ10uZXZlbnRzLFxuICAgICAgICB1cGRhdGU6ICdldmVudC5jdHJsS2V5J1xuICAgICAgfV1cbiAgICB9XSk7XG5cbiAgICBjb25zdCBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMsIG9uZVNnLmNvbmNhdCh0d29TZykpO1xuICB9KTtcblxuICBpdCgnYnVpbGRzIG1vZGlmeSBleHByJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgb25lRXhwciA9IHRvZ2dsZS5tb2RpZnlFeHByKG1vZGVsLCBzZWxDbXB0c1snb25lJ10sICcnKTtcbiAgICBhc3NlcnQuZXF1YWwob25lRXhwciwgJ29uZV90b2dnbGUgPyBudWxsIDogb25lX3R1cGxlLCBvbmVfdG9nZ2xlID8gbnVsbCA6IHRydWUsIG9uZV90b2dnbGUgPyBvbmVfdHVwbGUgOiBudWxsJyk7XG5cbiAgICBjb25zdCB0d29FeHByID0gdG9nZ2xlLm1vZGlmeUV4cHIobW9kZWwsIHNlbENtcHRzWyd0d28nXSwgJycpO1xuICAgIGFzc2VydC5lcXVhbCh0d29FeHByLCAndHdvX3RvZ2dsZSA/IG51bGwgOiB0d29fdHVwbGUsIHR3b190b2dnbGUgPyBudWxsIDoge3VuaXQ6IFxcXCJcXFwifSwgdHdvX3RvZ2dsZSA/IHR3b190dXBsZSA6IG51bGwnKTtcblxuICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscywgW1xuICAgICAge1xuICAgICAgICBcIm5hbWVcIjogXCJvbmVfbW9kaWZ5XCIsXG4gICAgICAgIFwib25cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcIm9uZV90dXBsZVwifSxcbiAgICAgICAgICAgIFwidXBkYXRlXCI6IGBtb2RpZnkoXFxcIm9uZV9zdG9yZVxcXCIsICR7b25lRXhwcn0pYFxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgXCJuYW1lXCI6IFwidHdvX21vZGlmeVwiLFxuICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJ0d29fdHVwbGVcIn0sXG4gICAgICAgICAgICBcInVwZGF0ZVwiOiBgbW9kaWZ5KFxcXCJ0d29fc3RvcmVcXFwiLCAke3R3b0V4cHJ9KWBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH1cbiAgICBdKTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/selection/translate.test.js b/build/test/compile/selection/translate.test.js new file mode 100644 index 0000000000..a754506230 --- /dev/null +++ b/build/test/compile/selection/translate.test.js @@ -0,0 +1,209 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var vega_event_selector_1 = require("vega-event-selector"); +var selection = require("../../../src/compile/selection/selection"); +var translate_1 = require("../../../src/compile/selection/transforms/translate"); +var util_1 = require("../../util"); +function getModel(xscale, yscale) { + var model = util_1.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; + chai_1.assert.isNotTrue(translate_1.default.has(selCmpts['one'])); + chai_1.assert.isNotTrue(translate_1.default.has(selCmpts['two'])); + chai_1.assert.isNotTrue(translate_1.default.has(selCmpts['three'])); + chai_1.assert.isNotFalse(translate_1.default.has(selCmpts['four'])); + chai_1.assert.isNotFalse(translate_1.default.has(selCmpts['five'])); + chai_1.assert.isNotFalse(translate_1.default.has(selCmpts['six'])); + chai_1.assert.isNotTrue(translate_1.default.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, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "four_translate_anchor", + "value": {}, + "on": [ + { + "events": vega_event_selector_1.selector('@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": vega_event_selector_1.selector('[@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, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "five_translate_anchor", + "value": {}, + "on": [ + { + "events": vega_event_selector_1.selector('@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": vega_event_selector_1.selector('[@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, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "six_translate_anchor", + "value": {}, + "on": [ + { + "events": vega_event_selector_1.selector('mousedown', 'scope'), + "update": "{x: x(unit), y: y(unit), extent_x: domain(\"x\"), extent_y: domain(\"y\")}" + } + ] + }, + { + "name": "six_translate_delta", + "value": {}, + "on": [ + { + "events": vega_event_selector_1.selector('[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, []); + chai_1.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)" + } + ]); + chai_1.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, []); + chai_1.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)" + } + ]); + chai_1.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, []); + chai_1.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)" + } + ]); + chai_1.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, []); + chai_1.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)" + } + ]); + chai_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zbGF0ZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4QkFBOEI7O0FBRTlCLDZCQUE0QjtBQUM1QiwyREFBOEQ7QUFDOUQsb0VBQXNFO0FBQ3RFLGlGQUE0RTtBQUU1RSxtQ0FBMEM7QUFFMUMsa0JBQWtCLE1BQWtCLEVBQUUsTUFBa0I7SUFDdEQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxRQUFRLEVBQUMsRUFBQztZQUMxRixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsTUFBTSxJQUFJLFFBQVEsRUFBQyxFQUFDO1lBQ2hHLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztTQUNoRDtLQUNGLENBQUMsQ0FBQztJQUVILEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNuQixJQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO1FBQ25ELEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxRQUFRO1NBQ2pCO1FBQ0QsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLE9BQU87U0FDaEI7UUFDRCxPQUFPLEVBQUU7WUFDUCxNQUFNLEVBQUUsVUFBVTtZQUNsQixXQUFXLEVBQUUsS0FBSztTQUNuQjtRQUNELE1BQU0sRUFBRTtZQUNOLE1BQU0sRUFBRSxVQUFVO1NBQ25CO1FB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Q0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsQ0FBQyxDQUFDLElBQUksS0FBSyxzQkFBc0IsRUFBakMsQ0FBaUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDeEY7b0JBQ0UsUUFBUSxFQUFFLEVBQUMsUUFBUSxFQUFFLHFCQUFxQixFQUFDO29CQUMzQyxRQUFRLEVBQUUsMEVBQTBFO2lCQUNyRjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlIHF1b3RlbWFyayAqL1xuXG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge3NlbGVjdG9yIGFzIHBhcnNlU2VsZWN0b3J9IGZyb20gJ3ZlZ2EtZXZlbnQtc2VsZWN0b3InO1xuaW1wb3J0ICogYXMgc2VsZWN0aW9uIGZyb20gJy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi9zZWxlY3Rpb24nO1xuaW1wb3J0IHRyYW5zbGF0ZSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vdHJhbnNmb3Jtcy90cmFuc2xhdGUnO1xuaW1wb3J0IHtTY2FsZVR5cGV9IGZyb20gJy4uLy4uLy4uL3NyYy9zY2FsZSc7XG5pbXBvcnQge3BhcnNlVW5pdE1vZGVsfSBmcm9tICcuLi8uLi91dGlsJztcblxuZnVuY3Rpb24gZ2V0TW9kZWwoeHNjYWxlPzogU2NhbGVUeXBlLCB5c2NhbGU/OiBTY2FsZVR5cGUpIHtcbiAgY29uc3QgbW9kZWwgPSBwYXJzZVVuaXRNb2RlbCh7XG4gICAgXCJtYXJrXCI6IFwiY2lyY2xlXCIsXG4gICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICBcInhcIjoge1wiZmllbGRcIjogXCJIb3JzZXBvd2VyXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwic2NhbGVcIjoge1widHlwZVwiOiB4c2NhbGUgfHwgXCJsaW5lYXJcIn19LFxuICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcInNjYWxlXCI6IHtcInR5cGVcIjogeXNjYWxlIHx8IFwibGluZWFyXCJ9fSxcbiAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJPcmlnaW5cIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgIH1cbiAgfSk7XG5cbiAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICBjb25zdCBzZWxDbXB0cyA9IHNlbGVjdGlvbi5wYXJzZVVuaXRTZWxlY3Rpb24obW9kZWwsIHtcbiAgICBcIm9uZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzaW5nbGVcIlxuICAgIH0sXG4gICAgXCJ0d29cIjoge1xuICAgICAgXCJ0eXBlXCI6IFwibXVsdGlcIlxuICAgIH0sXG4gICAgXCJ0aHJlZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlcnZhbFwiLFxuICAgICAgXCJ0cmFuc2xhdGVcIjogZmFsc2VcbiAgICB9LFxuICAgIFwiZm91clwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlcnZhbFwiXG4gICAgfSxcbiAgICBcImZpdmVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIixcbiAgICAgIFwidHJhbnNsYXRlXCI6IFwiW21vdXNlZG93biwgbW91c2V1cF0gPiBtb3VzZW1vdmUsIFtrZXlkb3duLCBrZXl1cF0gPiB0b3VjaG1vdmVcIlxuICAgIH0sXG4gICAgXCJzaXhcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIixcbiAgICAgIFwiYmluZFwiOiBcInNjYWxlc1wiXG4gICAgfSxcbiAgICBcInNldmVuXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVydmFsXCIsXG4gICAgICBcInRyYW5zbGF0ZVwiOiBudWxsXG4gICAgfVxuICB9KTtcblxuICByZXR1cm4ge21vZGVsLCBzZWxDbXB0c307XG59XG5cbmRlc2NyaWJlKCdUcmFuc2xhdGUgU2VsZWN0aW9uIFRyYW5zZm9ybScsIGZ1bmN0aW9uKCkge1xuICBpdCgnaWRlbnRpZmllcyB0cmFuc2Zvcm0gaW52b2NhdGlvbicsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHttb2RlbDogX21vZGVsLCBzZWxDbXB0c30gPSBnZXRNb2RlbCgpO1xuICAgIGFzc2VydC5pc05vdFRydWUodHJhbnNsYXRlLmhhcyhzZWxDbXB0c1snb25lJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RUcnVlKHRyYW5zbGF0ZS5oYXMoc2VsQ21wdHNbJ3R3byddKSk7XG4gICAgYXNzZXJ0LmlzTm90VHJ1ZSh0cmFuc2xhdGUuaGFzKHNlbENtcHRzWyd0aHJlZSddKSk7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UodHJhbnNsYXRlLmhhcyhzZWxDbXB0c1snZm91ciddKSk7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UodHJhbnNsYXRlLmhhcyhzZWxDbXB0c1snZml2ZSddKSk7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2UodHJhbnNsYXRlLmhhcyhzZWxDbXB0c1snc2l4J10pKTtcbiAgICBhc3NlcnQuaXNOb3RUcnVlKHRyYW5zbGF0ZS5oYXMoc2VsQ21wdHNbJ3NldmVuJ10pKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FuY2hvci9EZWx0YSBzaWduYWxzJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qge21vZGVsLCBzZWxDbXB0c30gPSBnZXRNb2RlbCgpO1xuXG4gICAgaXQoJ2J1aWxkcyB0aGVtIGZvciBkZWZhdWx0IGludm9jYXRpb24nLCBmdW5jdGlvbigpIHtcbiAgICAgIG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb24gPSB7Zm91cjogc2VsQ21wdHNbJ2ZvdXInXX07XG4gICAgICBjb25zdCBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscywgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJuYW1lXCI6IFwiZm91cl90cmFuc2xhdGVfYW5jaG9yXCIsXG4gICAgICAgICAgXCJ2YWx1ZVwiOiB7fSxcbiAgICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJldmVudHNcIjogcGFyc2VTZWxlY3RvcignQGZvdXJfYnJ1c2g6bW91c2Vkb3duJywgJ3Njb3BlJyksXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwie3g6IHgodW5pdCksIHk6IHkodW5pdCksIGV4dGVudF94OiBzbGljZShmb3VyX3gpLCBleHRlbnRfeTogc2xpY2UoZm91cl95KX1cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcImZvdXJfdHJhbnNsYXRlX2RlbHRhXCIsXG4gICAgICAgICAgXCJ2YWx1ZVwiOiB7fSxcbiAgICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJldmVudHNcIjogcGFyc2VTZWxlY3RvcignW0Bmb3VyX2JydXNoOm1vdXNlZG93biwgd2luZG93Om1vdXNldXBdID4gd2luZG93Om1vdXNlbW92ZSEnLCAnc2NvcGUnKSxcbiAgICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJ7eDogZm91cl90cmFuc2xhdGVfYW5jaG9yLnggLSB4KHVuaXQpLCB5OiBmb3VyX3RyYW5zbGF0ZV9hbmNob3IueSAtIHkodW5pdCl9XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2J1aWxkcyB0aGVtIGZvciBjdXN0b20gZXZlbnRzJywgZnVuY3Rpb24oKSB7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge2ZpdmU6IHNlbENtcHRzWydmaXZlJ119O1xuICAgICAgY29uc3Qgc2lnbmFscyA9IHNlbGVjdGlvbi5hc3NlbWJsZVVuaXRTZWxlY3Rpb25TaWduYWxzKG1vZGVsLCBbXSk7XG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMsIFtcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcImZpdmVfdHJhbnNsYXRlX2FuY2hvclwiLFxuICAgICAgICAgIFwidmFsdWVcIjoge30sXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ0BmaXZlX2JydXNoOm1vdXNlZG93biwgQGZpdmVfYnJ1c2g6a2V5ZG93bicsICdzY29wZScpLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcInt4OiB4KHVuaXQpLCB5OiB5KHVuaXQpLCBleHRlbnRfeDogc2xpY2UoZml2ZV94KSwgZXh0ZW50X3k6IHNsaWNlKGZpdmVfeSl9XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaXZlX3RyYW5zbGF0ZV9kZWx0YVwiLFxuICAgICAgICAgIFwidmFsdWVcIjoge30sXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ1tAZml2ZV9icnVzaDptb3VzZWRvd24sIG1vdXNldXBdID4gbW91c2Vtb3ZlLCBbQGZpdmVfYnJ1c2g6a2V5ZG93biwga2V5dXBdID4gdG91Y2htb3ZlJywgJ3Njb3BlJyksXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwie3g6IGZpdmVfdHJhbnNsYXRlX2FuY2hvci54IC0geCh1bml0KSwgeTogZml2ZV90cmFuc2xhdGVfYW5jaG9yLnkgLSB5KHVuaXQpfVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZHMgdGhlbSBmb3Igc2NhbGUtYm91bmQgaW50ZXJ2YWxzJywgZnVuY3Rpb24oKSB7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3NpeDogc2VsQ21wdHNbJ3NpeCddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJzaXhfdHJhbnNsYXRlX2FuY2hvclwiLFxuICAgICAgICAgIFwidmFsdWVcIjoge30sXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ21vdXNlZG93bicsICdzY29wZScpLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcInt4OiB4KHVuaXQpLCB5OiB5KHVuaXQpLCBleHRlbnRfeDogZG9tYWluKFxcXCJ4XFxcIiksIGV4dGVudF95OiBkb21haW4oXFxcInlcXFwiKX1cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcInNpeF90cmFuc2xhdGVfZGVsdGFcIixcbiAgICAgICAgICBcInZhbHVlXCI6IHt9LFxuICAgICAgICAgIFwib25cIjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiBwYXJzZVNlbGVjdG9yKCdbbW91c2Vkb3duLCB3aW5kb3c6bW91c2V1cF0gPiB3aW5kb3c6bW91c2Vtb3ZlIScsICdzY29wZScpLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcInt4OiBzaXhfdHJhbnNsYXRlX2FuY2hvci54IC0geCh1bml0KSwgeTogc2l4X3RyYW5zbGF0ZV9hbmNob3IueSAtIHkodW5pdCl9XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIF0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNsYXRlIFNpZ25hbCcsIGZ1bmN0aW9uKCkge1xuICAgIGl0KCdhbHdheXMgYnVpbGRzIHBhbkxpbmVhciBleHBycyBmb3IgYnJ1c2hlcycsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3Qge21vZGVsLCBzZWxDbXB0c30gPSBnZXRNb2RlbCgpO1xuICAgICAgbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbiA9IHtmb3VyOiBzZWxDbXB0c1snZm91ciddfTtcbiAgICAgIGxldCBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscy5maWx0ZXIoKHMpID0+IHMubmFtZSA9PT0gJ2ZvdXJfeCcpWzBdLm9uLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJmb3VyX3RyYW5zbGF0ZV9kZWx0YVwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcImNsYW1wUmFuZ2UocGFuTGluZWFyKGZvdXJfdHJhbnNsYXRlX2FuY2hvci5leHRlbnRfeCwgZm91cl90cmFuc2xhdGVfZGVsdGEueCAvIHNwYW4oZm91cl90cmFuc2xhdGVfYW5jaG9yLmV4dGVudF94KSksIDAsIHdpZHRoKVwiXG4gICAgICAgIH1cbiAgICAgIF0pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdmb3VyX3knKVswXS5vbiwgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwiZm91cl90cmFuc2xhdGVfZGVsdGFcIn0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjogXCJjbGFtcFJhbmdlKHBhbkxpbmVhcihmb3VyX3RyYW5zbGF0ZV9hbmNob3IuZXh0ZW50X3ksIGZvdXJfdHJhbnNsYXRlX2RlbHRhLnkgLyBzcGFuKGZvdXJfdHJhbnNsYXRlX2FuY2hvci5leHRlbnRfeSkpLCAwLCBoZWlnaHQpXCJcbiAgICAgICAgfVxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IG1vZGVsMiA9IGdldE1vZGVsKCdsb2cnLCAncG93JykubW9kZWw7XG4gICAgICBtb2RlbDIuY29tcG9uZW50LnNlbGVjdGlvbiA9IHtmb3VyOiBzZWxDbXB0c1snZm91ciddfTtcbiAgICAgIHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbDIsIFtdKTtcbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscy5maWx0ZXIoKHMpID0+IHMubmFtZSA9PT0gJ2ZvdXJfeCcpWzBdLm9uLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJmb3VyX3RyYW5zbGF0ZV9kZWx0YVwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcImNsYW1wUmFuZ2UocGFuTGluZWFyKGZvdXJfdHJhbnNsYXRlX2FuY2hvci5leHRlbnRfeCwgZm91cl90cmFuc2xhdGVfZGVsdGEueCAvIHNwYW4oZm91cl90cmFuc2xhdGVfYW5jaG9yLmV4dGVudF94KSksIDAsIHdpZHRoKVwiXG4gICAgICAgIH1cbiAgICAgIF0pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdmb3VyX3knKVswXS5vbiwgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwiZm91cl90cmFuc2xhdGVfZGVsdGFcIn0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjogXCJjbGFtcFJhbmdlKHBhbkxpbmVhcihmb3VyX3RyYW5zbGF0ZV9hbmNob3IuZXh0ZW50X3ksIGZvdXJfdHJhbnNsYXRlX2RlbHRhLnkgLyBzcGFuKGZvdXJfdHJhbnNsYXRlX2FuY2hvci5leHRlbnRfeSkpLCAwLCBoZWlnaHQpXCJcbiAgICAgICAgfVxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRzIHBhbkxpbmVhciBleHBycyBmb3Igc2NhbGUtYm91bmQgaW50ZXJ2YWxzJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB7bW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCk7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3NpeDogc2VsQ21wdHNbJ3NpeCddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdzaXhfSG9yc2Vwb3dlcicpWzBdLm9uLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJzaXhfdHJhbnNsYXRlX2RlbHRhXCJ9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IFwicGFuTGluZWFyKHNpeF90cmFuc2xhdGVfYW5jaG9yLmV4dGVudF94LCAtc2l4X3RyYW5zbGF0ZV9kZWx0YS54IC8gd2lkdGgpXCJcbiAgICAgICAgfVxuICAgICAgXSk7XG5cbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscy5maWx0ZXIoKHMpID0+IHMubmFtZSA9PT0gJ3NpeF9NaWxlc19wZXJfR2FsbG9uJylbMF0ub24sIFtcbiAgICAgICAge1xuICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcInNpeF90cmFuc2xhdGVfZGVsdGFcIn0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjogXCJwYW5MaW5lYXIoc2l4X3RyYW5zbGF0ZV9hbmNob3IuZXh0ZW50X3ksIHNpeF90cmFuc2xhdGVfZGVsdGEueSAvIGhlaWdodClcIlxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZHMgcGFuTG9nL3BhblBvdyBleHBycyBmb3Igc2NhbGUtYm91bmQgaW50ZXJ2YWxzJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB7bW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCdsb2cnLCAncG93Jyk7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3NpeDogc2VsQ21wdHNbJ3NpeCddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdzaXhfSG9yc2Vwb3dlcicpWzBdLm9uLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJzaXhfdHJhbnNsYXRlX2RlbHRhXCJ9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IFwicGFuTG9nKHNpeF90cmFuc2xhdGVfYW5jaG9yLmV4dGVudF94LCAtc2l4X3RyYW5zbGF0ZV9kZWx0YS54IC8gd2lkdGgpXCJcbiAgICAgICAgfVxuICAgICAgXSk7XG5cbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscy5maWx0ZXIoKHMpID0+IHMubmFtZSA9PT0gJ3NpeF9NaWxlc19wZXJfR2FsbG9uJylbMF0ub24sIFtcbiAgICAgICAge1xuICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcInNpeF90cmFuc2xhdGVfZGVsdGFcIn0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjogXCJwYW5Qb3coc2l4X3RyYW5zbGF0ZV9hbmNob3IuZXh0ZW50X3ksIHNpeF90cmFuc2xhdGVfZGVsdGEueSAvIGhlaWdodCwgMSlcIlxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/compile/selection/zoom.test.js b/build/test/compile/selection/zoom.test.js new file mode 100644 index 0000000000..65bb5a6b18 --- /dev/null +++ b/build/test/compile/selection/zoom.test.js @@ -0,0 +1,208 @@ +"use strict"; +/* tslint:disable quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var vega_event_selector_1 = require("vega-event-selector"); +var selection = require("../../../src/compile/selection/selection"); +var zoom_1 = require("../../../src/compile/selection/transforms/zoom"); +var util_1 = require("../../util"); +function getModel(xscale, yscale) { + var model = util_1.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; + chai_1.assert.isNotTrue(zoom_1.default.has(selCmpts['one'])); + chai_1.assert.isNotTrue(zoom_1.default.has(selCmpts['two'])); + chai_1.assert.isNotTrue(zoom_1.default.has(selCmpts['three'])); + chai_1.assert.isNotFalse(zoom_1.default.has(selCmpts['four'])); + chai_1.assert.isNotFalse(zoom_1.default.has(selCmpts['five'])); + chai_1.assert.isNotFalse(zoom_1.default.has(selCmpts['six'])); + chai_1.assert.isNotTrue(zoom_1.default.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, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "four_zoom_anchor", + "on": [ + { + "events": vega_event_selector_1.selector('@four_brush:wheel!', 'scope'), + "update": "{x: x(unit), y: y(unit)}" + } + ] + }, + { + "name": "four_zoom_delta", + "on": [ + { + "events": vega_event_selector_1.selector('@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, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "five_zoom_anchor", + "on": [ + { + "events": vega_event_selector_1.selector('@five_brush:wheel, @five_brush:pinch', 'scope'), + "update": "{x: x(unit), y: y(unit)}" + } + ] + }, + { + "name": "five_zoom_delta", + "on": [ + { + "events": vega_event_selector_1.selector('@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, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "six_zoom_anchor", + "on": [ + { + "events": vega_event_selector_1.selector('wheel!', 'scope'), + "update": "{x: invert(\"x\", x(unit)), y: invert(\"y\", y(unit))}" + } + ] + }, + { + "name": "six_zoom_delta", + "on": [ + { + "events": vega_event_selector_1.selector('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, []); + chai_1.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)" + } + ]); + chai_1.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, []); + chai_1.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)" + } + ]); + chai_1.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, []); + chai_1.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)" + } + ]); + chai_1.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, []); + chai_1.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)" + } + ]); + chai_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NlbGVjdGlvbi96b29tLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBQzVCLDJEQUE4RDtBQUM5RCxvRUFBc0U7QUFDdEUsdUVBQWtFO0FBRWxFLG1DQUEwQztBQUUxQyxrQkFBa0IsTUFBa0IsRUFBRSxNQUFrQjtJQUN0RCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1FBQzNCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRTtZQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsTUFBTSxJQUFJLFFBQVEsRUFBQyxFQUFDO1lBQzFGLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxNQUFNLElBQUksUUFBUSxFQUFDLEVBQUM7WUFDaEcsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO1NBQ2hEO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLElBQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDbkQsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLFFBQVE7U0FDakI7UUFDRCxLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsT0FBTztTQUNoQjtRQUNELE9BQU8sRUFBRTtZQUNQLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLE1BQU0sRUFBRSxLQUFLO1NBQ2Q7UUFDRCxNQUFNLEVBQUU7WUFDTixNQUFNLEVBQUUsVUFBVTtTQUNuQjtRQUNELE1BQU0sRUFB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TSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsSUFBSSxLQUFLLHNCQUFzQixFQUFqQyxDQUFpQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO2dCQUN4RjtvQkFDRSxRQUFRLEVBQUUsRUFBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUM7b0JBQ3RDLFFBQVEsRUFBRSw4REFBOEQ7aUJBQ3pFO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgcXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7c2VsZWN0b3IgYXMgcGFyc2VTZWxlY3Rvcn0gZnJvbSAndmVnYS1ldmVudC1zZWxlY3Rvcic7XG5pbXBvcnQgKiBhcyBzZWxlY3Rpb24gZnJvbSAnLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbic7XG5pbXBvcnQgem9vbSBmcm9tICcuLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vdHJhbnNmb3Jtcy96b29tJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuLi8uLi8uLi9zcmMvc2NhbGUnO1xuaW1wb3J0IHtwYXJzZVVuaXRNb2RlbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmZ1bmN0aW9uIGdldE1vZGVsKHhzY2FsZT86IFNjYWxlVHlwZSwgeXNjYWxlPzogU2NhbGVUeXBlKSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgIFwibWFya1wiOiBcImNpcmNsZVwiLFxuICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcInNjYWxlXCI6IHtcInR5cGVcIjogeHNjYWxlIHx8IFwibGluZWFyXCJ9fSxcbiAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIk1pbGVzX3Blcl9HYWxsb25cIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJzY2FsZVwiOiB7XCJ0eXBlXCI6IHlzY2FsZSB8fCBcImxpbmVhclwifX0sXG4gICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwiT3JpZ2luXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICB9XG4gIH0pO1xuXG4gIG1vZGVsLnBhcnNlU2NhbGUoKTtcbiAgY29uc3Qgc2VsQ21wdHMgPSBzZWxlY3Rpb24ucGFyc2VVbml0U2VsZWN0aW9uKG1vZGVsLCB7XG4gICAgXCJvbmVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwic2luZ2xlXCJcbiAgICB9LFxuICAgIFwidHdvXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcIm11bHRpXCJcbiAgICB9LFxuICAgIFwidGhyZWVcIjoge1xuICAgICAgXCJ0eXBlXCI6IFwiaW50ZXJ2YWxcIixcbiAgICAgIFwiem9vbVwiOiBmYWxzZVxuICAgIH0sXG4gICAgXCJmb3VyXCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVydmFsXCJcbiAgICB9LFxuICAgIFwiZml2ZVwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlcnZhbFwiLFxuICAgICAgXCJ6b29tXCI6IFwid2hlZWwsIHBpbmNoXCJcbiAgICB9LFxuICAgIFwic2l4XCI6IHtcbiAgICAgIFwidHlwZVwiOiBcImludGVydmFsXCIsXG4gICAgICBcImJpbmRcIjogXCJzY2FsZXNcIlxuICAgIH0sXG4gICAgXCJzZXZlblwiOiB7XG4gICAgICBcInR5cGVcIjogXCJpbnRlcnZhbFwiLFxuICAgICAgXCJ6b29tXCI6IG51bGxcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7bW9kZWwsIHNlbENtcHRzfTtcbn1cblxuZGVzY3JpYmUoJ1pvb20gU2VsZWN0aW9uIFRyYW5zZm9ybScsIGZ1bmN0aW9uKCkge1xuXG4gIGl0KCdpZGVudGlmaWVzIHRyYW5zZm9ybSBpbnZvY2F0aW9uJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qge21vZGVsOiBfbW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCk7XG4gICAgYXNzZXJ0LmlzTm90VHJ1ZSh6b29tLmhhcyhzZWxDbXB0c1snb25lJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RUcnVlKHpvb20uaGFzKHNlbENtcHRzWyd0d28nXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUoem9vbS5oYXMoc2VsQ21wdHNbJ3RocmVlJ10pKTtcbiAgICBhc3NlcnQuaXNOb3RGYWxzZSh6b29tLmhhcyhzZWxDbXB0c1snZm91ciddKSk7XG4gICAgYXNzZXJ0LmlzTm90RmFsc2Uoem9vbS5oYXMoc2VsQ21wdHNbJ2ZpdmUnXSkpO1xuICAgIGFzc2VydC5pc05vdEZhbHNlKHpvb20uaGFzKHNlbENtcHRzWydzaXgnXSkpO1xuICAgIGFzc2VydC5pc05vdFRydWUoem9vbS5oYXMoc2VsQ21wdHNbJ3NldmVuJ10pKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FuY2hvci9EZWx0YSBzaWduYWxzJywgZnVuY3Rpb24oKSB7XG4gICAgaXQoJ2J1aWxkcyB0aGVuIGZvciBkZWZhdWx0IGludm9jYXRpb24nLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IHttb2RlbCwgc2VsQ21wdHN9ID0gZ2V0TW9kZWwoKTtcbiAgICAgIG1vZGVsLmNvbXBvbmVudC5zZWxlY3Rpb24gPSB7Zm91cjogc2VsQ21wdHNbJ2ZvdXInXX07XG4gICAgICBjb25zdCBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwsIFtdKTtcbiAgICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoc2lnbmFscywgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJuYW1lXCI6IFwiZm91cl96b29tX2FuY2hvclwiLFxuICAgICAgICAgIFwib25cIjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiBwYXJzZVNlbGVjdG9yKCdAZm91cl9icnVzaDp3aGVlbCEnLCAnc2NvcGUnKSxcbiAgICAgICAgICAgICAgXCJ1cGRhdGVcIjogXCJ7eDogeCh1bml0KSwgeTogeSh1bml0KX1cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcImZvdXJfem9vbV9kZWx0YVwiLFxuICAgICAgICAgIFwib25cIjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImV2ZW50c1wiOiBwYXJzZVNlbGVjdG9yKCdAZm91cl9icnVzaDp3aGVlbCEnLCAnc2NvcGUnKSxcbiAgICAgICAgICAgICAgXCJmb3JjZVwiOiB0cnVlLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcInBvdygxLjAwMSwgZXZlbnQuZGVsdGFZICogcG93KDE2LCBldmVudC5kZWx0YU1vZGUpKVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZHMgdGhlbSBmb3IgY3VzdG9tIGV2ZW50cycsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3Qge21vZGVsLCBzZWxDbXB0c30gPSBnZXRNb2RlbCgpO1xuICAgICAgbW9kZWwuY29tcG9uZW50LnNlbGVjdGlvbiA9IHtmaXZlOiBzZWxDbXB0c1snZml2ZSddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaXZlX3pvb21fYW5jaG9yXCIsXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ0BmaXZlX2JydXNoOndoZWVsLCBAZml2ZV9icnVzaDpwaW5jaCcsICdzY29wZScpLFxuICAgICAgICAgICAgICBcInVwZGF0ZVwiOiBcInt4OiB4KHVuaXQpLCB5OiB5KHVuaXQpfVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJuYW1lXCI6IFwiZml2ZV96b29tX2RlbHRhXCIsXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ0BmaXZlX2JydXNoOndoZWVsLCBAZml2ZV9icnVzaDpwaW5jaCcsICdzY29wZScpLFxuICAgICAgICAgICAgICBcImZvcmNlXCI6IHRydWUsXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwicG93KDEuMDAxLCBldmVudC5kZWx0YVkgKiBwb3coMTYsIGV2ZW50LmRlbHRhTW9kZSkpXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2J1aWxkcyB0aGVtIGZvciBzY2FsZS1ib3VuZCB6b29tJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB7bW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCk7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3NpeDogc2VsQ21wdHNbJ3NpeCddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJzaXhfem9vbV9hbmNob3JcIixcbiAgICAgICAgICBcIm9uXCI6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJldmVudHNcIjogcGFyc2VTZWxlY3Rvcignd2hlZWwhJywgJ3Njb3BlJyksXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwie3g6IGludmVydChcXFwieFxcXCIsIHgodW5pdCkpLCB5OiBpbnZlcnQoXFxcInlcXFwiLCB5KHVuaXQpKX1cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcInNpeF96b29tX2RlbHRhXCIsXG4gICAgICAgICAgXCJvblwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiZXZlbnRzXCI6IHBhcnNlU2VsZWN0b3IoJ3doZWVsIScsICdzY29wZScpLFxuICAgICAgICAgICAgICBcImZvcmNlXCI6IHRydWUsXG4gICAgICAgICAgICAgIFwidXBkYXRlXCI6IFwicG93KDEuMDAxLCBldmVudC5kZWx0YVkgKiBwb3coMTYsIGV2ZW50LmRlbHRhTW9kZSkpXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIF0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnWm9vbSBTaWduYWwnLCBmdW5jdGlvbigpIHtcbiAgICBpdCgnYWx3YXlzIGJ1aWxkcyB6b29tTGluZWFyIGV4cHJzIGZvciBicnVzaGVzJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB7bW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCk7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge2ZvdXI6IHNlbENtcHRzWydmb3VyJ119O1xuICAgICAgbGV0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdmb3VyX3gnKVswXS5vbiwgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwiZm91cl96b29tX2RlbHRhXCJ9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IFwiY2xhbXBSYW5nZSh6b29tTGluZWFyKGZvdXJfeCwgZm91cl96b29tX2FuY2hvci54LCBmb3VyX3pvb21fZGVsdGEpLCAwLCB3aWR0aClcIlxuICAgICAgICB9XG4gICAgICBdKTtcblxuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLmZpbHRlcigocykgPT4gcy5uYW1lID09PSAnZm91cl95JylbMF0ub24sIFtcbiAgICAgICAge1xuICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcImZvdXJfem9vbV9kZWx0YVwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcImNsYW1wUmFuZ2Uoem9vbUxpbmVhcihmb3VyX3ksIGZvdXJfem9vbV9hbmNob3IueSwgZm91cl96b29tX2RlbHRhKSwgMCwgaGVpZ2h0KVwiXG4gICAgICAgIH1cbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBtb2RlbDIgPSBnZXRNb2RlbCgnbG9nJywgJ3BvdycpLm1vZGVsO1xuICAgICAgbW9kZWwyLmNvbXBvbmVudC5zZWxlY3Rpb24gPSB7Zm91cjogc2VsQ21wdHNbJ2ZvdXInXX07XG4gICAgICBzaWduYWxzID0gc2VsZWN0aW9uLmFzc2VtYmxlVW5pdFNlbGVjdGlvblNpZ25hbHMobW9kZWwyLCBbXSk7XG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdmb3VyX3gnKVswXS5vbiwgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwiZm91cl96b29tX2RlbHRhXCJ9LFxuICAgICAgICAgIFwidXBkYXRlXCI6IFwiY2xhbXBSYW5nZSh6b29tTGluZWFyKGZvdXJfeCwgZm91cl96b29tX2FuY2hvci54LCBmb3VyX3pvb21fZGVsdGEpLCAwLCB3aWR0aClcIlxuICAgICAgICB9XG4gICAgICBdKTtcblxuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLmZpbHRlcigocykgPT4gcy5uYW1lID09PSAnZm91cl95JylbMF0ub24sIFtcbiAgICAgICAge1xuICAgICAgICAgIFwiZXZlbnRzXCI6IHtcInNpZ25hbFwiOiBcImZvdXJfem9vbV9kZWx0YVwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcImNsYW1wUmFuZ2Uoem9vbUxpbmVhcihmb3VyX3ksIGZvdXJfem9vbV9hbmNob3IueSwgZm91cl96b29tX2RlbHRhKSwgMCwgaGVpZ2h0KVwiXG4gICAgICAgIH1cbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2J1aWxkcyB6b29tTGluZWFyIGV4cHJzIGZvciBzY2FsZS1ib3VuZCB6b29tJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB7bW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCk7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3NpeDogc2VsQ21wdHNbJ3NpeCddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdzaXhfSG9yc2Vwb3dlcicpWzBdLm9uLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJzaXhfem9vbV9kZWx0YVwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcInpvb21MaW5lYXIoZG9tYWluKFxcXCJ4XFxcIiksIHNpeF96b29tX2FuY2hvci54LCBzaXhfem9vbV9kZWx0YSlcIlxuICAgICAgICB9XG4gICAgICBdKTtcblxuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLmZpbHRlcigocykgPT4gcy5uYW1lID09PSAnc2l4X01pbGVzX3Blcl9HYWxsb24nKVswXS5vbiwgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwic2l4X3pvb21fZGVsdGFcIn0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjogXCJ6b29tTGluZWFyKGRvbWFpbihcXFwieVxcXCIpLCBzaXhfem9vbV9hbmNob3IueSwgc2l4X3pvb21fZGVsdGEpXCJcbiAgICAgICAgfVxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRzIHpvb21Mb2cvUG93IGV4cHJzIGZvciBzY2FsZS1ib3VuZCB6b29tJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCB7bW9kZWwsIHNlbENtcHRzfSA9IGdldE1vZGVsKCdsb2cnLCAncG93Jyk7XG4gICAgICBtb2RlbC5jb21wb25lbnQuc2VsZWN0aW9uID0ge3NpeDogc2VsQ21wdHNbJ3NpeCddfTtcbiAgICAgIGNvbnN0IHNpZ25hbHMgPSBzZWxlY3Rpb24uYXNzZW1ibGVVbml0U2VsZWN0aW9uU2lnbmFscyhtb2RlbCwgW10pO1xuXG4gICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKHNpZ25hbHMuZmlsdGVyKChzKSA9PiBzLm5hbWUgPT09ICdzaXhfSG9yc2Vwb3dlcicpWzBdLm9uLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImV2ZW50c1wiOiB7XCJzaWduYWxcIjogXCJzaXhfem9vbV9kZWx0YVwifSxcbiAgICAgICAgICBcInVwZGF0ZVwiOiBcInpvb21Mb2coZG9tYWluKFxcXCJ4XFxcIiksIHNpeF96b29tX2FuY2hvci54LCBzaXhfem9vbV9kZWx0YSlcIlxuICAgICAgICB9XG4gICAgICBdKTtcblxuICAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhzaWduYWxzLmZpbHRlcigocykgPT4gcy5uYW1lID09PSAnc2l4X01pbGVzX3Blcl9HYWxsb24nKVswXS5vbiwgW1xuICAgICAgICB7XG4gICAgICAgICAgXCJldmVudHNcIjoge1wic2lnbmFsXCI6IFwic2l4X3pvb21fZGVsdGFcIn0sXG4gICAgICAgICAgXCJ1cGRhdGVcIjogXCJ6b29tUG93KGRvbWFpbihcXFwieVxcXCIpLCBzaXhfem9vbV9hbmNob3IueSwgc2l4X3pvb21fZGVsdGEsIDEpXCJcbiAgICAgICAgfVxuICAgICAgXSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/compile/unit.test.js b/build/test/compile/unit.test.js new file mode 100644 index 0000000000..afdf42aa06 --- /dev/null +++ b/build/test/compile/unit.test.js @@ -0,0 +1,71 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../src/channel"); +var log = require("../../src/log"); +var mark_1 = require("../../src/mark"); +var type_1 = require("../../src/type"); +var util_1 = require("../util"); +describe('UnitModel', function () { + describe('initEncoding', function () { + it('should drop unsupported channel and throws warning', log.wrap(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + shape: { field: 'a', type: 'quantitative' } + } + }); + chai_1.assert.equal(model.encoding.shape, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.incompatibleChannel(channel_1.SHAPE, mark_1.BAR)); + })); + it('should drop channel without field and value and throws warning', log.wrap(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { type: 'quantitative' } + } + }); + chai_1.assert.equal(model.encoding.x, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: type_1.QUANTITATIVE }, channel_1.X)); + })); + it('should drop a fieldDef without field and value from the channel def list and throws warning', log.wrap(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + detail: [ + { field: 'a', type: 'ordinal' }, + { type: 'quantitative' } + ] + } + }); + chai_1.assert.deepEqual(model.encoding.detail, [ + { field: 'a', type: 'ordinal' } + ]); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: type_1.QUANTITATIVE }, channel_1.DETAIL)); + })); + }); + describe('initAxes', function () { + it('should not include properties of non-VlOnlyAxisConfig in config.axis', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { axis: { domainWidth: 123 } } + }); + chai_1.assert.equal(model.axis(channel_1.X)['domainWidth'], undefined); + }); + it('it should have axis.offset = encode.x.axis.offset', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', axis: { offset: 345 } }, + y: { field: 'b', type: 'ordinal' } + } + }); + chai_1.assert.equal(model.axis(channel_1.X).offset, 345); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC9jb21waWxlL3VuaXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1Qiw2Q0FBbUQ7QUFFbkQsbUNBQXFDO0FBQ3JDLHVDQUFtQztBQUNuQyx1Q0FBNEM7QUFDNUMsZ0NBQXVDO0FBRXZDLFFBQVEsQ0FBQyxXQUFXLEVBQUU7SUFDcEIsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7WUFDMUUsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsUUFBUSxFQUFFO29CQUNSLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztpQkFDMUM7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzlDLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLGVBQUssRUFBRSxVQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFTixFQUFFLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7WUFDdEYsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxjQUFjLEVBQUM7aUJBQzFCO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMxQyxhQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsRUFBQyxJQUFJLEVBQUUsbUJBQVksRUFBQyxFQUFFLFdBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekYsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVOLEVBQUUsQ0FBQyw2RkFBNkYsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztZQUNuSCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsS0FBSztnQkFDWCxRQUFRLEVBQUU7b0JBQ1IsTUFBTSxFQUFFO3dCQUNOLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO3dCQUM3QixFQUFDLElBQUksRUFBRSxjQUFjLEVBQUM7cUJBQ3ZCO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLFNBQVMsQ0FBd0MsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7Z0JBQzdFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO2FBQzlCLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFDLElBQUksRUFBRSxtQkFBWSxFQUFDLEVBQUUsZ0JBQU0sQ0FBQyxDQUFDLENBQUM7UUFDOUYsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVSLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFVBQVUsRUFBRTtRQUNuQixFQUFFLENBQUMsc0VBQXNFLEVBQUU7WUFDekUsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQztvQkFDaEMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO2lCQUNqQztnQkFDRCxNQUFNLEVBQUUsRUFBQyxJQUFJLEVBQUUsRUFBQyxXQUFXLEVBQUUsR0FBRyxFQUFDLEVBQUM7YUFDbkMsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFO1lBQ3RELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUMsTUFBTSxFQUFFLEdBQUcsRUFBQyxFQUFDO29CQUNyRCxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7aUJBQ2pDO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge0RFVEFJTCwgU0hBUEUsIFh9IGZyb20gJy4uLy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7RmllbGREZWZ9IGZyb20gJy4uLy4uL3NyYy9maWVsZGRlZic7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vLi4vc3JjL2xvZyc7XG5pbXBvcnQge0JBUn0gZnJvbSAnLi4vLi4vc3JjL21hcmsnO1xuaW1wb3J0IHtRVUFOVElUQVRJVkV9IGZyb20gJy4uLy4uL3NyYy90eXBlJztcbmltcG9ydCB7cGFyc2VVbml0TW9kZWx9IGZyb20gJy4uL3V0aWwnO1xuXG5kZXNjcmliZSgnVW5pdE1vZGVsJywgZnVuY3Rpb24oKSB7XG4gIGRlc2NyaWJlKCdpbml0RW5jb2RpbmcnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBkcm9wIHVuc3VwcG9ydGVkIGNoYW5uZWwgYW5kIHRocm93cyB3YXJuaW5nJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICBzaGFwZToge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5lbmNvZGluZy5zaGFwZSwgdW5kZWZpbmVkKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS5pbmNvbXBhdGlibGVDaGFubmVsKFNIQVBFLCBCQVIpKTtcbiAgICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgZHJvcCBjaGFubmVsIHdpdGhvdXQgZmllbGQgYW5kIHZhbHVlIGFuZCB0aHJvd3Mgd2FybmluZycsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgICBtYXJrOiAnYmFyJyxcbiAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgeDoge3R5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChtb2RlbC5lbmNvZGluZy54LCB1bmRlZmluZWQpO1xuICAgICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmVtcHR5RmllbGREZWYoe3R5cGU6IFFVQU5USVRBVElWRX0sIFgpKTtcbiAgICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgZHJvcCBhIGZpZWxkRGVmIHdpdGhvdXQgZmllbGQgYW5kIHZhbHVlIGZyb20gdGhlIGNoYW5uZWwgZGVmIGxpc3QgYW5kIHRocm93cyB3YXJuaW5nJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICAgIG1hcms6ICdiYXInLFxuICAgICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgICBkZXRhaWw6IFtcbiAgICAgICAgICAgICAge2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ30sXG4gICAgICAgICAgICAgIHt0eXBlOiAncXVhbnRpdGF0aXZlJ31cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsPEZpZWxkRGVmPHN0cmluZz4gfCBGaWVsZERlZjxzdHJpbmc+W10+KG1vZGVsLmVuY29kaW5nLmRldGFpbCwgW1xuICAgICAgICAgIHtmaWVsZDogJ2EnLCB0eXBlOiAnb3JkaW5hbCd9XG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmVtcHR5RmllbGREZWYoe3R5cGU6IFFVQU5USVRBVElWRX0sIERFVEFJTCkpO1xuICAgICAgfSkpO1xuXG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpbml0QXhlcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIG5vdCBpbmNsdWRlIHByb3BlcnRpZXMgb2Ygbm9uLVZsT25seUF4aXNDb25maWcgaW4gY29uZmlnLmF4aXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsKHtcbiAgICAgICAgbWFyazogJ3BvaW50JyxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB4OiB7ZmllbGQ6ICdhJywgdHlwZTogJ29yZGluYWwnfSxcbiAgICAgICAgICB5OiB7ZmllbGQ6ICdiJywgdHlwZTogJ29yZGluYWwnfVxuICAgICAgICB9LFxuICAgICAgICBjb25maWc6IHtheGlzOiB7ZG9tYWluV2lkdGg6IDEyM319XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKG1vZGVsLmF4aXMoWClbJ2RvbWFpbldpZHRoJ10sIHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnaXQgc2hvdWxkIGhhdmUgYXhpcy5vZmZzZXQgPSBlbmNvZGUueC5heGlzLm9mZnNldCcsICgpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoe1xuICAgICAgICBtYXJrOiAncG9pbnQnLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAnb3JkaW5hbCcsIGF4aXM6IHtvZmZzZXQ6IDM0NX19LFxuICAgICAgICAgIHk6IHtmaWVsZDogJ2InLCB0eXBlOiAnb3JkaW5hbCd9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuZXF1YWwobW9kZWwuYXhpcyhYKS5vZmZzZXQsIDM0NSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ No newline at end of file diff --git a/build/test/compositemark.test.d.ts b/build/test/compositemark.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compositemark.test.js b/build/test/compositemark.test.js new file mode 100644 index 0000000000..5efa8d6024 --- /dev/null +++ b/build/test/compositemark.test.js @@ -0,0 +1,1722 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../src/log"); +var spec_1 = require("../src/spec"); +var config_1 = require("./../src/config"); +describe("normalizeErrorBar", function () { + it("should produce correct layered specs for horizontal error bar", function () { + chai_1.assert.deepEqual(spec_1.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 } + } + }, config_1.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 () { + chai_1.assert.throws(function () { + spec_1.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 } + } + }, config_1.defaultConfig); + }, Error, 'Neither x2 or y2 provided'); + }); +}); +describe("normalizeBoxMinMax", function () { + it("should produce an error if both axes have aggregate boxplot", function () { + chai_1.assert.throws(function () { + spec_1.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": { "aggregate": "box-plot", "field": "people", "type": "quantitative" }, + "y": { + "aggregate": "box-plot", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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" } + } + }, config_1.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 () { + chai_1.assert.throws(function () { + spec_1.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: { + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce a warning if continuous axis has aggregate property", log.wrap(function (localLogger) { + spec_1.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" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.defaultConfig); + chai_1.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 () { + chai_1.assert.throws(function () { + spec_1.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" } + } + }, config_1.defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce an error if both axes are discrete", function () { + chai_1.assert.throws(function () { + spec_1.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" }, + "y": { + "field": "age", + "type": "ordinal", + "axis": { "title": "age" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.throws(function () { + spec_1.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" }, + "y": { + "type": "ordinal", + "axis": { "title": "age" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce an error if 1D boxplot only axis is discrete", function () { + chai_1.assert.throws(function () { + spec_1.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" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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" + }, + encoding: { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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", + "aggregate": "box-plot", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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: { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "people", + "type": "quantitative", + "aggregate": "box-plot", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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": "people", + "type": "quantitative", + "axis": { "title": "population" } + } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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: { + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + } + } + }, config_1.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", function () { + chai_1.assert.deepEqual(spec_1.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" } + } + }, config_1.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 () { + chai_1.assert.deepEqual(spec_1.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" + } + } + }, config_1.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=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9zaXRlbWFyay50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC9jb21wb3NpdGVtYXJrLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBRzVCLGdDQUFrQztBQUVsQyxvQ0FBb0U7QUFDcEUsMENBQThDO0FBRTlDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtJQUUxQixFQUFFLENBQUMsK0RBQStELEVBQUU7UUFDbEUsYUFBTSxDQUFDLFNBQVMsQ0FBa0UsZ0JBQVMsQ0FBQztZQUMxRixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsc0JBQXNCLEVBQUM7WUFDdkMsSUFBSSxFQUFFLFdBQVc7WUFDakIsUUFBUSxFQUFFO2dCQUNSLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDdkMsR0FBRyxFQUFFO29CQUNILFdBQVcsRUFBRSxLQUFLO29CQUNsQixPQUFPLEVBQUUsUUFBUTtvQkFDakIsTUFBTSxFQUFFLGNBQWM7b0JBQ3RCLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUM7aUJBQ2hDO2dCQUNELElBQUksRUFBRTtvQkFDSixXQUFXLEVBQUUsS0FBSztvQkFDbEIsT0FBTyxFQUFFLFFBQVE7b0JBQ2pCLE1BQU0sRUFBRSxjQUFjO2lCQUN2QjtnQkFDRCxNQUFNLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDO2FBQ3JCO1NBQ0YsRUFBRSxzQkFBYSxDQUFDLEVBQUU7WUFDakIsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLHNCQUFzQixFQUFDO1lBQ3ZDLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxNQUFNLEVBQUUsTUFBTTtvQkFDZCxVQUFVLEVBQUU7d0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFDO3dCQUN2QyxHQUFHLEVB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T0FBTyxFQUFFLGtCQUFrQjs0QkFDM0IsTUFBTSxFQUFFLGNBQWM7eUJBQ3ZCO3dCQUNELElBQUksRUFBRTs0QkFDSixPQUFPLEVBQUUsa0JBQWtCOzRCQUMzQixNQUFNLEVBQUUsY0FBYzt5QkFDdkI7d0JBQ0QsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLENBQUMsRUFBQzt3QkFDcEIsT0FBTyxFQUFFOzRCQUNQLE9BQU8sRUFBRSxhQUFhOzRCQUN0QixNQUFNLEVBQUUsY0FBYzt5QkFDdkI7cUJBQ0Y7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFO3dCQUNKLElBQUksRUFBRSxNQUFNO3dCQUNaLEtBQUssRUFBRSxRQUFRO3FCQUNoQjtvQkFDRCxVQUFVLEVBQUU7d0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO3dCQUM1QyxHQUFHLEVBQUU7NEJBQ0gsT0FBTyxFQUFFLGdCQUFnQjs0QkFDekIsTUFBTSxFQUFFLGNBQWM7eUJBQ3ZCO3dCQUNELE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUM7d0JBQzNCLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUM7cUJBQ3JCO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztBQUVMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7RW5jb2Rpbmd9IGZyb20gJy4uL3NyYy9lbmNvZGluZyc7XG5pbXBvcnQge0ZpZWxkfSBmcm9tICcuLi9zcmMvZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL3NyYy9sb2cnO1xuaW1wb3J0IHtNYXJrLCBNYXJrRGVmfSBmcm9tICcuLi9zcmMvbWFyayc7XG5pbXBvcnQge0dlbmVyaWNTcGVjLCBHZW5lcmljVW5pdFNwZWMsIG5vcm1hbGl6ZX0gZnJvbSAnLi4vc3JjL3NwZWMnO1xuaW1wb3J0IHtkZWZhdWx0Q29uZmlnfSBmcm9tICcuLy4uL3NyYy9jb25maWcnO1xuXG5kZXNjcmliZShcIm5vcm1hbGl6ZUVycm9yQmFyXCIsICgpID0+IHtcblxuICAgIGl0KFwic2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciBob3Jpem9udGFsIGVycm9yIGJhclwiLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiBcImVycm9yLWJhclwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWluXCIsXG4gICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtYXhcIixcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWF4XCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcInRpY2tcIixcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWluXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJ0aWNrXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICAvLyBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgIGl0KFwic2hvdWxkIHRocm93IGVycm9yIHdoZW4gbWlzc2luZyB4MiBhbmQgeTJcIiwgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIG5vcm1hbGl6ZSh7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICAgIG1hcms6IFwiZXJyb3ItYmFyXCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBkZWZhdWx0Q29uZmlnKTtcbiAgICAgIH0sIEVycm9yLCAnTmVpdGhlciB4MiBvciB5MiBwcm92aWRlZCcpO1xuICAgIH0pO1xuIH0pO1xuXG5kZXNjcmliZShcIm5vcm1hbGl6ZUJveE1pbk1heFwiLCAoKSA9PiB7XG4gIGl0KFwic2hvdWxkIHByb2R1Y2UgYW4gZXJyb3IgaWYgYm90aCBheGVzIGhhdmUgYWdncmVnYXRlIGJveHBsb3RcIiwgKCkgPT4ge1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4ge1xuICAgICAgbm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IFwiYm94LXBsb3RcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwiYm94LXBsb3RcIiwgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJib3gtcGxvdFwiLFxuICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiIDogXCJza3libHVlXCJ9XG4gICAgICAgIH1cbiAgICAgIH0sIGRlZmF1bHRDb25maWcpO1xuICAgIH0sIEVycm9yLCAnQm90aCB4IGFuZCB5IGNhbm5vdCBoYXZlIGFnZ3JlZ2F0ZScpO1xuICB9KTtcblxuaXQoXCJzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGxheWVyZWQgc3BlY3MgZm9yIHZlcnRpY2FsIGJveHBsb3Qgd2l0aCB0d28gcXVhbnRpdGF0aXZlIGF4ZXMgYW5kIHVzZSBkZWZhdWx0IG9yaWVudGF0aW9uXCIsICgpID0+IHtcbiAgICAgYXNzZXJ0LmRlZXBFcXVhbDxHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8RmllbGQ+LCBzdHJpbmcgfCBNYXJrRGVmPj4+KG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiBcImJveC1wbG90XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTFcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInEzXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtZWRpYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1pZF9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXCJhZ2VcIl1cbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAnYmFyJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3gnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3RpY2snLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveE1pZCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJtaWRfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIjogXCJ3aGl0ZVwifSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJzaG91bGQgcHJvZHVjZSBhbiBlcnJvciBpZiBuZWl0aGVyIHRoZSB4IGF4aXMgb3IgeSBheGlzIGlzIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICBub3JtYWxpemUoe1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgbWFyazogXCJib3gtcGxvdFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyk7XG4gICAgfSwgRXJyb3IsICdOZWVkIGEgdmFsaWQgY29udGludW91cyBheGlzIGZvciBib3hwbG90cycpO1xuICB9KTtcblxuICBpdChcInNob3VsZCBwcm9kdWNlIGEgd2FybmluZyBpZiBjb250aW51b3VzIGF4aXMgaGFzIGFnZ3JlZ2F0ZSBwcm9wZXJ0eVwiLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICBub3JtYWxpemUoe1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgbWFyazogXCJib3gtcGxvdFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWluXCIsXG4gICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgIH0sIGRlZmF1bHRDb25maWcpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCAnQ29udGludW91cyBheGlzIHNob3VsZCBub3QgaGF2ZSBjdXN0b21pemVkIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uIG1pbicpO1xuICB9KSk7XG5cbiAgaXQoXCJzaG91bGQgcHJvZHVjZSBhbiBlcnJvciBpZiBidWlsZCAxRCBib3hwbG90IHdpdGggYSBkaXNjcmV0ZSBheGlzXCIsICgpID0+IHtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgIG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiBcImJveC1wbG90XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsIFwidHlwZVwiOiBcIm9yZGluYWxcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyk7XG4gICAgfSwgRXJyb3IsICdOZWVkIGEgdmFsaWQgY29udGludW91cyBheGlzIGZvciBib3hwbG90cycpO1xuICB9KTtcblxuICBpdChcInNob3VsZCBwcm9kdWNlIGFuIGVycm9yIGlmIGJvdGggYXhlcyBhcmUgZGlzY3JldGVcIiwgKCkgPT4ge1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4ge1xuICAgICAgbm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IFwiYm94LXBsb3RcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwiYWdlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJvcmRpbmFsXCIsXG4gICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJhZ2VcIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyk7XG4gICAgfSwgRXJyb3IsICdOZWVkIGEgdmFsaWQgY29udGludW91cyBheGlzIGZvciBib3hwbG90cycpO1xuICB9KTtcblxuICBpdChcInNob3VsZCBwcm9kdWNlIGFuIGVycm9yIGlmIGluIDJEIGJveHBsb3QgYm90aCBheGVzIGFyZSBub3QgdmFsaWQgZmllbGQgZGVmaW5pdGlvbnNcIiwgKCkgPT4ge1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4ge1xuICAgICAgbm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IFwiYm94LXBsb3RcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICBcInR5cGVcIjogXCJvcmRpbmFsXCIsXG4gICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJhZ2VcIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyk7XG4gICAgfSwgRXJyb3IsICdOZWVkIGEgdmFsaWQgY29udGludW91cyBheGlzIGZvciBib3hwbG90cycpO1xuICB9KTtcblxuICBpdChcInNob3VsZCBwcm9kdWNlIGFuIGVycm9yIGlmIDFEIGJveHBsb3Qgb25seSBheGlzIGlzIGRpc2NyZXRlXCIsICgpID0+IHtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgIG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiBcImJveC1wbG90XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiIDogXCJza3libHVlXCJ9XG4gICAgICAgIH1cbiAgICAgIH0sIGRlZmF1bHRDb25maWcpO1xuICAgIH0sIEVycm9yLCAnTmVlZCBhIHZhbGlkIGNvbnRpbnVvdXMgYXhpcyBmb3IgYm94cGxvdHMnKTtcbiAgfSk7XG5cbiAgaXQoXCJzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGxheWVyZWQgc3BlY3MgZm9yIHZlcnRpY2FsIGJveHBsb3Qgd2l0aCB0d28gcXVhbnRpdGF0aXZlIGF4ZXMgYW5kIHNwZWNpZnkgb3JpZW50YXRpb24gd2l0aCBvcmllbnRcIiwgKCkgPT4ge1xuICAgIGFzc2VydC5kZWVwRXF1YWw8R2VuZXJpY1NwZWM8R2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPEZpZWxkPiwgTWFyayB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IHtcbiAgICAgICAgICB0eXBlOiBcImJveC1wbG90XCIsXG4gICAgICAgICAgb3JpZW50OiBcInZlcnRpY2FsXCIsXG4gICAgICAgICAgZXh0ZW50OiBcIm1pbi1tYXhcIlxuICAgICAgICB9LFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiIDogXCJza3libHVlXCJ9XG4gICAgICAgIH1cbiAgICAgIH0sIGRlZmF1bHRDb25maWcpLCB7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBcInRyYW5zZm9ybVwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInExXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxM1wiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwibWVkaWFuXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJtaWRfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwibWluXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJsb3dlcl93aGlza2VyX3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwibWF4XCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJ1cHBlcl93aGlza2VyX3Blb3BsZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcImdyb3VwYnlcIjogW1wiYWdlXCJdXG4gICAgICAgICAgfVxuICAgICAgICBdLFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdydWxlJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hXaGlza2VyJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl93aGlza2VyX3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2JhcicsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94J1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiIDogXCJza3libHVlXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICd0aWNrJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hNaWQnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibWlkX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwid2hpdGVcIn0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciBob3Jpem9udGFsIGJveHBsb3Qgd2l0aCB0d28gcXVhbnRpdGF0aXZlIGF4ZXMgYW5kIHNwZWNpZnkgb3JpZW50YXRpb24gd2l0aCBvcmllbnRcIiwgKCkgPT4ge1xuICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIE1hcmsgfCBNYXJrRGVmPj4+KG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgdHlwZTogXCJib3gtcGxvdFwiLFxuICAgICAgICAgIG9yaWVudDogXCJob3Jpem9udGFsXCJcbiAgICAgICAgfSxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICB9XG4gICAgICB9LCBkZWZhdWx0Q29uZmlnKSwge1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxMVwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTNcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1lZGlhblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibWlkX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1heFwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJncm91cGJ5XCI6IFtcImFnZVwiXVxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl93aGlza2VyX3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ4MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdydWxlJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hXaGlza2VyJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcIngyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ4MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAndGljaycsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94TWlkJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcIm1pZF9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiOiBcIndoaXRlXCJ9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGxheWVyZWQgc3BlY3MgZm9yIHZlcnRpY2FsIGJveHBsb3Qgd2l0aCB0d28gcXVhbnRpdGF0aXZlIGF4ZXMgYW5kIHNwZWNpZnkgb3JpZW50YXRpb24gd2l0aCBhZ2dyZWdhdGVcIiwgKCkgPT4ge1xuICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IFwiYm94LXBsb3RcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJib3gtcGxvdFwiLFxuICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICB9XG4gICAgICB9LCBkZWZhdWx0Q29uZmlnKSwge1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxMVwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTNcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1lZGlhblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibWlkX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1heFwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJncm91cGJ5XCI6IFtcImFnZVwiXVxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl93aGlza2VyX3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdydWxlJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hXaGlza2VyJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAndGljaycsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94TWlkJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcIm1pZF9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiOiBcIndoaXRlXCJ9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICB9KTtcblxuICBpdChcInNob3VsZCBwcm9kdWNlIGNvcnJlY3QgbGF5ZXJlZCBzcGVjcyBmb3IgaG9yaXpvbnRhbCBib3hwbG90IHdpdGggdHdvIHF1YW50aXRhdGl2ZSBheGVzIGFuZCBzcGVjaWZ5IG9yaWVudGF0aW9uIHdpdGggYWdncmVnYXRlXCIsICgpID0+IHtcbiAgICAgYXNzZXJ0LmRlZXBFcXVhbDxHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8RmllbGQ+LCBzdHJpbmcgfCBNYXJrRGVmPj4+KG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiBcImJveC1wbG90XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwiYm94LXBsb3RcIixcbiAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTFcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInEzXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtZWRpYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1pZF9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXCJhZ2VcIl1cbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ4MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAnYmFyJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3gnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3RpY2snLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveE1pZCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJtaWRfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIjogXCJ3aGl0ZVwifSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciB2ZXJ0aWNhbCBib3hwbG90IHdpdGggbWluIGFuZCBtYXhcIiwgKCkgPT4ge1xuICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IFwiYm94LXBsb3RcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTFcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInEzXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtZWRpYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1pZF9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXCJhZ2VcIl1cbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3RpY2snLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveE1pZCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibWlkX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwid2hpdGVcIn0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciBob3Jpem9udGFsIGJveHBsb3Qgd2l0aCBtaW4gYW5kIG1heFwiLCAoKSA9PiB7XG4gICAgIGFzc2VydC5kZWVwRXF1YWw8R2VuZXJpY1NwZWM8R2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPEZpZWxkPiwgc3RyaW5nIHwgTWFya0RlZj4+Pihub3JtYWxpemUoe1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgbWFyazogXCJib3gtcGxvdFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICB9XG4gICAgICB9LCBkZWZhdWx0Q29uZmlnKSwge1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxMVwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTNcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1lZGlhblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibWlkX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1heFwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJncm91cGJ5XCI6IFtcImFnZVwiXVxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl93aGlza2VyX3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2JhcicsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94J1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ4MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAndGljaycsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94TWlkJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJtaWRfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIjogXCJ3aGl0ZVwifSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciBob3Jpem9udGFsIHdpdGggbm8gbm9ucG9zaXRpb25hbCBlbmNvZGluZyBwcm9wZXJ0aWVzIGJveHBsb3Qgd2l0aCBtaW4gYW5kIG1heFwiLCAoKSA9PiB7XG4gICAgIGFzc2VydC5kZWVwRXF1YWw8R2VuZXJpY1NwZWM8R2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPEZpZWxkPiwgc3RyaW5nIHwgTWFya0RlZj4+Pihub3JtYWxpemUoe1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgbWFyazogXCJib3gtcGxvdFwiLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTFcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInEzXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtZWRpYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1pZF9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXCJhZ2VcIl1cbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcIngyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcIngyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDE0fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAndGljaycsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94TWlkJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJtaWRfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIjogXCJ3aGl0ZVwifSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDE0fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciAxRCBib3hwbG90IHdpdGggb25seSB4XCIsICgpID0+IHtcbiAgICAgYXNzZXJ0LmRlZXBFcXVhbDxHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8RmllbGQ+LCBzdHJpbmcgfCBNYXJrRGVmPj4+KG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiBcImJveC1wbG90XCIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSwgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTFcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInEzXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtZWRpYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1pZF9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXVxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieDJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl93aGlza2VyX3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2JhcicsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94J1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ4MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogMTR9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICd0aWNrJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hNaWQnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcIm1pZF9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJ2YWx1ZVwiOiBcIndoaXRlXCJ9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogMTR9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGxheWVyZWQgc3BlY3MgZm9yIDFEIGJveHBsb3Qgd2l0aCBvbmx5IHlcIiwgKCkgPT4ge1xuICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgYm94IHBsb3Qgc2hvd2luZyBtZWRpYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIG1hcms6IFwiYm94LXBsb3RcIixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCBkZWZhdWx0Q29uZmlnKSwge1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxMVwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTNcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1lZGlhblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibWlkX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1heFwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwidXBwZXJfd2hpc2tlcl9wZW9wbGVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJncm91cGJ5XCI6IFtdXG4gICAgICAgICAgfVxuICAgICAgICBdLFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdydWxlJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hXaGlza2VyJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl93aGlza2VyX3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdydWxlJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hXaGlza2VyJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAnYmFyJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3gnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImxvd2VyX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiAxNH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3RpY2snLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveE1pZCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibWlkX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwid2hpdGVcIn0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiAxNH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICB9KTtcbn0pO1xuXG5cbmRlc2NyaWJlKFwibm9ybWFsaXplQm94SVFSXCIsICgpID0+IHtcblxuICBpdChcInNob3VsZCBwcm9kdWNlIGNvcnJlY3QgbGF5ZXJlZCBzcGVjcyBmb3IgdmVydGljYWwgYm94cGxvdCB3aXRoIHR3byBxdWFudGl0YXRpdmUgYXhlcyBhbmQgdXNlIGRlZmF1bHQgb3JpZW50YXRpb24gZm9yIGEgMS41ICogSVFSIHdoaXNrZXJzXCIsICgpID0+IHtcbiAgICAgYXNzZXJ0LmRlZXBFcXVhbDxHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8RmllbGQ+LCBzdHJpbmcgfCBNYXJrRGVmPj4+KG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgXCJ0eXBlXCI6IFwiYm94LXBsb3RcIixcbiAgICAgICAgICBcImV4dGVudFwiOiAxLjVcbiAgICAgICAgfSxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIiA6IFwic2t5Ymx1ZVwifVxuICAgICAgICB9XG4gICAgICB9LCBkZWZhdWx0Q29uZmlnKSwge1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxMVwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwicTNcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1lZGlhblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibWlkX2JveF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwibWluX3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwibWF4XCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJtYXhfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXCJhZ2VcIl1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNhbGN1bGF0ZTogJ2RhdHVtLnVwcGVyX2JveF9wZW9wbGUgLSBkYXR1bS5sb3dlcl9ib3hfcGVvcGxlJyxcbiAgICAgICAgICAgIGFzOiAnaXFyX3Blb3BsZSdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiY2FsY3VsYXRlXCI6IFwibWluKGRhdHVtLnVwcGVyX2JveF9wZW9wbGUgKyBkYXR1bS5pcXJfcGVvcGxlICogMS41LCBkYXR1bS5tYXhfcGVvcGxlKVwiLFxuICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiY2FsY3VsYXRlXCI6IFwibWF4KGRhdHVtLmxvd2VyX2JveF9wZW9wbGUgLSBkYXR1bS5pcXJfcGVvcGxlICogMS41LCBkYXR1bS5taW5fcGVvcGxlKVwiLFxuICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAnYmFyJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3gnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCIgOiBcInNreWJsdWVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3RpY2snLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveE1pZCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJtaWRfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1widmFsdWVcIjogXCJ3aGl0ZVwifSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGxheWVyZWQgc3BlY3MgZm9yIHZlcnRpY2FsIElRUiBib3hwbG90IHdoZXJlIGNvbG9yIGVuY29kZXMgdGhlIG1lYW4gb2YgdGhlIHBlb3BsZSBmaWVsZFwiLCAoKSA9PiB7XG4gICAgIGFzc2VydC5kZWVwRXF1YWw8R2VuZXJpY1NwZWM8R2VuZXJpY1VuaXRTcGVjPEVuY29kaW5nPEZpZWxkPiwgc3RyaW5nIHwgTWFya0RlZj4+Pihub3JtYWxpemUoe1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBib3ggcGxvdCBzaG93aW5nIG1lZGlhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgbWFyazoge1xuICAgICAgICAgIFwidHlwZVwiOiBcImJveC1wbG90XCIsXG4gICAgICAgICAgXCJleHRlbnRcIjogMS41XG4gICAgICAgIH0sXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcbiAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWVhblwiLFxuICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIGRlZmF1bHRDb25maWcpLCB7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGJveCBwbG90IHNob3dpbmcgbWVkaWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBcInRyYW5zZm9ybVwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcInExXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJxM1wiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcImFzXCI6IFwidXBwZXJfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwibWVkaWFuXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJtaWRfYm94X3Blb3BsZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBcIm9wXCI6IFwibWluXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwiYXNcIjogXCJtaW5fcGVvcGxlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwib3BcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1heF9wZW9wbGVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJvcFwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJhc1wiOiBcIm1lYW5fcGVvcGxlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwiZ3JvdXBieVwiOiBbXCJhZ2VcIl1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNhbGN1bGF0ZTogJ2RhdHVtLnVwcGVyX2JveF9wZW9wbGUgLSBkYXR1bS5sb3dlcl9ib3hfcGVvcGxlJyxcbiAgICAgICAgICAgIGFzOiAnaXFyX3Blb3BsZSdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiY2FsY3VsYXRlXCI6IFwibWluKGRhdHVtLnVwcGVyX2JveF9wZW9wbGUgKyBkYXR1bS5pcXJfcGVvcGxlICogMS41LCBkYXR1bS5tYXhfcGVvcGxlKVwiLFxuICAgICAgICAgICAgXCJhc1wiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwiY2FsY3VsYXRlXCI6IFwibWF4KGRhdHVtLmxvd2VyX2JveF9wZW9wbGUgLSBkYXR1bS5pcXJfcGVvcGxlICogMS41LCBkYXR1bS5taW5fcGVvcGxlKVwiLFxuICAgICAgICAgICAgXCJhc1wiOiBcImxvd2VyX3doaXNrZXJfcGVvcGxlXCJcbiAgICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1hcms6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3J1bGUnLFxuICAgICAgICAgICAgICBzdHlsZTogJ2JveFdoaXNrZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfd2hpc2tlcl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJsb3dlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAncnVsZScsXG4gICAgICAgICAgICAgIHN0eWxlOiAnYm94V2hpc2tlcidcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInVwcGVyX3doaXNrZXJfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazoge1xuICAgICAgICAgICAgICB0eXBlOiAnYmFyJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3gnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibG93ZXJfYm94X3Blb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwieTJcIjoge1xuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJ1cHBlcl9ib3hfcGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibWVhbl9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXJrOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICd0aWNrJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICdib3hNaWQnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwibWlkX2JveF9wZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcInZhbHVlXCI6IFwid2hpdGVcIn0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gIH0pO1xuXG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/config.test.js b/build/test/config.test.js new file mode 100644 index 0000000000..ebce49a3a5 --- /dev/null +++ b/build/test/config.test.js @@ -0,0 +1,53 @@ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var config_1 = require("../src/config"); +var mark_1 = require("../src/mark"); +var util_1 = require("../src/util"); +describe('config', function () { + describe('stripAndRedirectConfig', function () { + var config = __assign({}, config_1.defaultConfig, { mark: __assign({}, config_1.defaultConfig.mark, { opacity: 0.3 }), bar: __assign({ opacity: 0.5 }, config_1.defaultConfig.bar), view: { + fill: '#eee' + }, title: { + color: 'red', + fontWeight: 'bold' + } }); + var copy = util_1.duplicate(config); + var output = config_1.stripAndRedirectConfig(config); + it('should not cause side-effect to the input', function () { + chai_1.assert.deepEqual(config, copy); + }); + it('should remove VL only mark config but keep Vega mark config', function () { + chai_1.assert.isUndefined(output.mark.color); + chai_1.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 = mark_1.PRIMITIVE_MARKS; _i < PRIMITIVE_MARKS_1.length; _i++) { + var mark = PRIMITIVE_MARKS_1[_i]; + chai_1.assert.isUndefined(output[mark], mark + " config should be redirected"); + } + chai_1.assert.isUndefined(output.style.bar['binSpacing'], "VL only Bar config should be removed"); + chai_1.assert.isUndefined(output.style.cell['width'], "VL only cell config should be removed"); + chai_1.assert.isUndefined(output.style.cell['height'], "VL only cell config should be removed"); + chai_1.assert.equal(output.style.cell['fill'], '#eee', "config.view should be redirect to config.style.cell"); + chai_1.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 () { + chai_1.assert.deepEqual(output.title, undefined); + chai_1.assert.deepEqual(output.style['group-title'].fontWeight, 'bold'); + chai_1.assert.deepEqual(output.style['group-title'].fill, 'red'); + }); + it('should remove empty config object', function () { + chai_1.assert.isUndefined(output.axisTop); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2NvbmZpZy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFDQSw2QkFBNEI7QUFDNUIsd0NBQTRFO0FBQzVFLG9DQUE0QztBQUM1QyxvQ0FBc0M7QUFFdEMsUUFBUSxDQUFDLFFBQVEsRUFBRTtJQUNqQixRQUFRLENBQUMsd0JBQXdCLEVBQUU7UUFDakMsSUFBTSxNQUFNLGdCQUNQLHNCQUFhLElBQ2hCLElBQUksZUFDQyxzQkFBYSxDQUFDLElBQUksSUFDckIsT0FBTyxFQUFFLEdBQUcsS0FFZCxHQUFHLGFBQ0QsT0FBTyxFQUFFLEdBQUcsSUFDVCxzQkFBYSxDQUFDLEdBQUcsR0FFdEIsSUFBSSxFQUFFO2dCQUNKLElBQUksRUFBRSxNQUFNO2FBQ2IsRUFDRCxLQUFLLEVBQUU7Z0JBQ0wsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osVUFBVSxFQUFFLE1BQU07YUFDbkIsR0FDRixDQUFDO1FBQ0YsSUFBTSxJQUFJLEdBQUcsZ0JBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQixJQUFNLE1BQU0sR0FBRywrQkFBc0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU5QyxFQUFFLENBQUMsMkNBQTJDLEVBQUU7WUFDOUMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkRBQTZELEVBQUU7WUFDaEUsYUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RDLGFBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOEVBQThFLEVBQUU7WUFDakYsR0FBRyxDQUFDLENBQWUsVUFBZSxFQUFmLG9CQUFBLHNCQUFlLEVBQWYsNkJBQWUsRUFBZixJQUFlO2dCQUE3QixJQUFNLElBQUksd0JBQUE7Z0JBQ2IsYUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUssSUFBSSxpQ0FBOEIsQ0FBQyxDQUFDO2FBQ3pFO1lBQ0QsYUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRSxzQ0FBc0MsQ0FBQyxDQUFDO1lBQzNGLGFBQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsdUNBQXVDLENBQUMsQ0FBQztZQUN4RixhQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLHVDQUF1QyxDQUFDLENBQUM7WUFDekYsYUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUscURBQXFELENBQUMsQ0FBQztZQUV2RyxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUscURBQXFELENBQUMsQ0FBQztRQUN6RyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtRkFBbUYsRUFBRTtZQUN0RixhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDMUMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNqRSxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFO1lBQ3RDLGFBQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtDb25maWcsIGRlZmF1bHRDb25maWcsIHN0cmlwQW5kUmVkaXJlY3RDb25maWd9IGZyb20gJy4uL3NyYy9jb25maWcnO1xuaW1wb3J0IHtQUklNSVRJVkVfTUFSS1N9IGZyb20gJy4uL3NyYy9tYXJrJztcbmltcG9ydCB7ZHVwbGljYXRlfSBmcm9tICcuLi9zcmMvdXRpbCc7XG5cbmRlc2NyaWJlKCdjb25maWcnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdzdHJpcEFuZFJlZGlyZWN0Q29uZmlnJywgKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZzogQ29uZmlnID0ge1xuICAgICAgLi4uZGVmYXVsdENvbmZpZyxcbiAgICAgIG1hcms6IHtcbiAgICAgICAgLi4uZGVmYXVsdENvbmZpZy5tYXJrLFxuICAgICAgICBvcGFjaXR5OiAwLjMsXG4gICAgICB9LFxuICAgICAgYmFyOiB7XG4gICAgICAgIG9wYWNpdHk6IDAuNSxcbiAgICAgICAgLi4uZGVmYXVsdENvbmZpZy5iYXJcbiAgICAgIH0sXG4gICAgICB2aWV3OiB7XG4gICAgICAgIGZpbGw6ICcjZWVlJ1xuICAgICAgfSxcbiAgICAgIHRpdGxlOiB7XG4gICAgICAgIGNvbG9yOiAncmVkJyxcbiAgICAgICAgZm9udFdlaWdodDogJ2JvbGQnXG4gICAgICB9XG4gICAgfTtcbiAgICBjb25zdCBjb3B5ID0gZHVwbGljYXRlKGNvbmZpZyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gc3RyaXBBbmRSZWRpcmVjdENvbmZpZyhjb25maWcpO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgY2F1c2Ugc2lkZS1lZmZlY3QgdG8gdGhlIGlucHV0JywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChjb25maWcsIGNvcHkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZW1vdmUgVkwgb25seSBtYXJrIGNvbmZpZyBidXQga2VlcCBWZWdhIG1hcmsgY29uZmlnJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKG91dHB1dC5tYXJrLmNvbG9yKTtcbiAgICAgIGFzc2VydC5lcXVhbChvdXRwdXQubWFyay5vcGFjaXR5LCAwLjMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWRpcmVjdCBtYXJrIGNvbmZpZyB0byBzdHlsZSBhbmQgcmVtb3ZlIFZMIG9ubHkgbWFyay1zcGVjaWZpYyBjb25maWcnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG1hcmsgb2YgUFJJTUlUSVZFX01BUktTKSB7XG4gICAgICAgIGFzc2VydC5pc1VuZGVmaW5lZChvdXRwdXRbbWFya10sIGAke21hcmt9IGNvbmZpZyBzaG91bGQgYmUgcmVkaXJlY3RlZGApO1xuICAgICAgfVxuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKG91dHB1dC5zdHlsZS5iYXJbJ2JpblNwYWNpbmcnXSwgYFZMIG9ubHkgQmFyIGNvbmZpZyBzaG91bGQgYmUgcmVtb3ZlZGApO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKG91dHB1dC5zdHlsZS5jZWxsWyd3aWR0aCddLCBgVkwgb25seSBjZWxsIGNvbmZpZyBzaG91bGQgYmUgcmVtb3ZlZGApO1xuICAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKG91dHB1dC5zdHlsZS5jZWxsWydoZWlnaHQnXSwgYFZMIG9ubHkgY2VsbCBjb25maWcgc2hvdWxkIGJlIHJlbW92ZWRgKTtcbiAgICAgIGFzc2VydC5lcXVhbChvdXRwdXQuc3R5bGUuY2VsbFsnZmlsbCddLCAnI2VlZScsIGBjb25maWcudmlldyBzaG91bGQgYmUgcmVkaXJlY3QgdG8gY29uZmlnLnN0eWxlLmNlbGxgKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQuc3R5bGUuYmFyLm9wYWNpdHksIDAuNSwgJ0JhciBjb25maWcgc2hvdWxkIGJlIHJlZGlyZWN0ZWQgdG8gY29uZmlnLnN0eWxlLmJhcicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWRpcmVjdCBjb25maWcudGl0bGUgdG8gY29uZmlnLnN0eWxlLmdyb3VwLXRpdGxlIGFuZCByZW5hbWUgY29sb3IgdG8gZmlsbCcsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LnRpdGxlLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQuc3R5bGVbJ2dyb3VwLXRpdGxlJ10uZm9udFdlaWdodCwgJ2JvbGQnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LnN0eWxlWydncm91cC10aXRsZSddLmZpbGwsICdyZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVtb3ZlIGVtcHR5IGNvbmZpZyBvYmplY3QnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuaXNVbmRlZmluZWQob3V0cHV0LmF4aXNUb3ApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/datetime.test.js b/build/test/datetime.test.js new file mode 100644 index 0000000000..029e2a40dd --- /dev/null +++ b/build/test/datetime.test.js @@ -0,0 +1,98 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var datetime_1 = require("../src/datetime"); +var log = require("../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 = datetime_1.dateTimeExpr(d, true); + chai_1.assert.equal(expr, 'datetime(2007, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(localLogger.warns[0], log.message.droppedDay(d)); + })); + it('should normalize numeric quarter correctly', function () { + var expr = datetime_1.dateTimeExpr({ + quarter: 2 + }, true); + chai_1.assert.equal(expr, 'datetime(0, 1*3, 1, 0, 0, 0, 0)'); + }); + it('should log warning for quarter > 4', log.wrap(function (localLogger) { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + quarter: 5 + }, true), 'datetime(0, 4*3, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(localLogger.warns[0], log.message.invalidTimeUnit('quarter', 5)); + })); + it('should throw error for invalid quarter', function () { + chai_1.assert.throws(function () { + datetime_1.dateTimeExpr({ quarter: 'Q' }, true); + }, Error, log.message.invalidTimeUnit('quarter', 'Q')); + }); + it('should normalize numeric month correctly', function () { + var expr = datetime_1.dateTimeExpr({ + month: 1 + }, true); + chai_1.assert.equal(expr, 'datetime(0, 0, 1, 0, 0, 0, 0)'); + }); + it('should normalize month name correctly', function () { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'January' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'january' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'Jan' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'jan' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + }); + it('should throw error for invalid month', function () { + chai_1.assert.throws(function () { + datetime_1.dateTimeExpr({ month: 'J' }, true); + }, Error, log.message.invalidTimeUnit('month', 'J')); + }); + it('should normalize numeric day (of week) correctly', function () { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 0 + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.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 () { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'Sunday' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'sunday' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'Sun' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'sun' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + }); + it('should throw error for invalid day', function () { + chai_1.assert.throws(function () { + datetime_1.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 = datetime_1.dateTimeExpr(d, true); + chai_1.assert.equal(expr, 'utc(2007, 0, 1, 0, 0, 0, 0)'); + }); + // Note: Other part of coverage handled by timeUnit.fieldExpr's test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvZGF0ZXRpbWUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1Qiw0Q0FBNkM7QUFDN0MsZ0NBQWtDO0FBRWxDLFFBQVEsQ0FBQyxVQUFVLEVBQUU7SUFDbkIsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMseURBQXlELEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7WUFDakYsSUFBTSxDQUFDLEdBQUc7Z0JBQ1IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsR0FBRyxFQUFFLFFBQVE7YUFDZCxDQUFDO1lBQ0YsSUFBTSxJQUFJLEdBQUcsdUJBQVksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbkMsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztZQUN2RCxhQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRUosRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1lBQy9DLElBQU0sSUFBSSxHQUFHLHVCQUFZLENBQUM7Z0JBQ3hCLE9BQU8sRUFBRSxDQUFDO2FBQ1gsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNULGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLFdBQVc7WUFDNUQsYUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBWSxDQUFDO2dCQUN4QixPQUFPLEVBQUUsQ0FBQzthQUNYLEVBQUUsSUFBSSxD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QUksQ0FBQyxFQUFFLG9DQUFvQyxDQUFDLENBQUM7WUFDaEQsYUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBWSxDQUFDO2dCQUN4QixHQUFHLEVBQUUsS0FBSzthQUNYLEVBQUUsSUFBSSxDQUFDLEVBQUUsb0NBQW9DLENBQUMsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtZQUN2QyxhQUFNLENBQUMsTUFBTSxDQUFDO2dCQUNaLHVCQUFZLENBQUMsRUFBQyxHQUFHLEVBQUUsR0FBRyxFQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDakMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRTtZQUNsRCxJQUFNLENBQUMsR0FBRztnQkFDUixJQUFJLEVBQUUsSUFBSTtnQkFDVixHQUFHLEVBQUUsUUFBUTtnQkFDYixHQUFHLEVBQUUsSUFBSTthQUNWLENBQUM7WUFDRixJQUFNLElBQUksR0FBRyx1QkFBWSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNuQyxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQyxDQUFDO1FBRUgsb0VBQW9FO0lBQ3RFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2RhdGVUaW1lRXhwcn0gZnJvbSAnLi4vc3JjL2RhdGV0aW1lJztcbmltcG9ydCAqIGFzIGxvZyBmcm9tICcuLi9zcmMvbG9nJztcblxuZGVzY3JpYmUoJ2RhdGV0aW1lJywgKCkgPT4ge1xuICBkZXNjcmliZSgnZGF0ZVRpbWVFeHByJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZHJvcCBkYXkgaWYgZGF5IGlzIGNvbWJpbmVkIHdpdGggeWVhci9tb250aC9kYXRlJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBkID0ge1xuICAgICAgICB5ZWFyOiAyMDA3LFxuICAgICAgICBkYXk6ICdtb25kYXknXG4gICAgICB9O1xuICAgICAgY29uc3QgZXhwciA9IGRhdGVUaW1lRXhwcihkLCB0cnVlKTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByLCAnZGF0ZXRpbWUoMjAwNywgMCwgMSwgMCwgMCwgMCwgMCknKTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuZHJvcHBlZERheShkKSk7XG4gICAgfSkpO1xuXG4gICAgaXQoJ3Nob3VsZCBub3JtYWxpemUgbnVtZXJpYyBxdWFydGVyIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGNvbnN0IGV4cHIgPSBkYXRlVGltZUV4cHIoe1xuICAgICAgICBxdWFydGVyOiAyXG4gICAgICB9LCB0cnVlKTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByLCAnZGF0ZXRpbWUoMCwgMSozLCAxLCAwLCAwLCAwLCAwKScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsb2cgd2FybmluZyBmb3IgcXVhcnRlciA+IDQnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlVGltZUV4cHIoe1xuICAgICAgICBxdWFydGVyOiA1XG4gICAgICB9LCB0cnVlKSwgJ2RhdGV0aW1lKDAsIDQqMywgMSwgMCwgMCwgMCwgMCknKTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuaW52YWxpZFRpbWVVbml0KCdxdWFydGVyJywgNSkpO1xuICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgcXVhcnRlcicsICgpID0+IHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4ge1xuICAgICAgICBkYXRlVGltZUV4cHIoe3F1YXJ0ZXI6ICdRJ30sIHRydWUpO1xuICAgICAgfSwgRXJyb3IsIGxvZy5tZXNzYWdlLmludmFsaWRUaW1lVW5pdCgncXVhcnRlcicsICdRJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3JtYWxpemUgbnVtZXJpYyBtb250aCBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHByID0gZGF0ZVRpbWVFeHByKHtcbiAgICAgICAgbW9udGg6IDFcbiAgICAgIH0sIHRydWUpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHIsICdkYXRldGltZSgwLCAwLCAxLCAwLCAwLCAwLCAwKScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3JtYWxpemUgbW9udGggbmFtZSBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZVRpbWVFeHByKHtcbiAgICAgICAgbW9udGg6ICdKYW51YXJ5J1xuICAgICAgfSwgdHJ1ZSksICdkYXRldGltZSgwLCAwLCAxLCAwLCAwLCAwLCAwKScpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGVUaW1lRXhwcih7XG4gICAgICAgIG1vbnRoOiAnamFudWFyeSdcbiAgICAgIH0sIHRydWUpLCAnZGF0ZXRpbWUoMCwgMCwgMSwgMCwgMCwgMCwgMCknKTtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlVGltZUV4cHIoe1xuICAgICAgICBtb250aDogJ0phbidcbiAgICAgIH0sIHRydWUpLCAnZGF0ZXRpbWUoMCwgMCwgMSwgMCwgMCwgMCwgMCknKTtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlVGltZUV4cHIoe1xuICAgICAgICBtb250aDogJ2phbidcbiAgICAgIH0sIHRydWUpLCAnZGF0ZXRpbWUoMCwgMCwgMSwgMCwgMCwgMCwgMCknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgbW9udGgnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgZGF0ZVRpbWVFeHByKHttb250aDogJ0onfSwgdHJ1ZSk7XG4gICAgICB9LCBFcnJvciwgbG9nLm1lc3NhZ2UuaW52YWxpZFRpbWVVbml0KCdtb250aCcsICdKJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3JtYWxpemUgbnVtZXJpYyBkYXkgKG9mIHdlZWspIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlVGltZUV4cHIoe1xuICAgICAgICBkYXk6IDBcbiAgICAgIH0sIHRydWUpLCAnZGF0ZXRpbWUoMjAwNiwgMCwgMCsxLCAwLCAwLCAwLCAwKScpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGVUaW1lRXhwcih7XG4gICAgICAgIGRheTogN1xuICAgICAgfSwgdHJ1ZSksICdkYXRldGltZSgyMDA2LCAwLCAwKzEsIDAsIDAsIDAsIDApJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vcm1hbGl6ZSBkYXkgbmFtZSBjb3JyZWN0bHkgYW5kIHVzZSB5ZWFyIDIwMDYgdG8gZW5zdXJlIGNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZVRpbWVFeHByKHtcbiAgICAgICAgZGF5OiAnU3VuZGF5J1xuICAgICAgfSwgdHJ1ZSksICdkYXRldGltZSgyMDA2LCAwLCAwKzEsIDAsIDAsIDAsIDApJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZVRpbWVFeHByKHtcbiAgICAgICAgZGF5OiAnc3VuZGF5J1xuICAgICAgfSwgdHJ1ZSksICdkYXRldGltZSgyMDA2LCAwLCAwKzEsIDAsIDAsIDAsIDApJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZVRpbWVFeHByKHtcbiAgICAgICAgZGF5OiAnU3VuJ1xuICAgICAgfSwgdHJ1ZSksICdkYXRldGltZSgyMDA2LCAwLCAwKzEsIDAsIDAsIDAsIDApJyk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZVRpbWVFeHByKHtcbiAgICAgICAgZGF5OiAnc3VuJ1xuICAgICAgfSwgdHJ1ZSksICdkYXRldGltZSgyMDA2LCAwLCAwKzEsIDAsIDAsIDAsIDApJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIGRheScsICgpID0+IHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4ge1xuICAgICAgICBkYXRlVGltZUV4cHIoe2RheTogJ1MnfSwgdHJ1ZSk7XG4gICAgICB9LCBFcnJvciwgbG9nLm1lc3NhZ2UuaW52YWxpZFRpbWVVbml0KCdkYXknLCAnUycpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXNlIHV0YyBleHByZXNzaW9uIGlmIHV0YyBpcyBzcGVjaWZpZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkID0ge1xuICAgICAgICB5ZWFyOiAyMDA3LFxuICAgICAgICBkYXk6ICdtb25kYXknLFxuICAgICAgICB1dGM6IHRydWVcbiAgICAgIH07XG4gICAgICBjb25zdCBleHByID0gZGF0ZVRpbWVFeHByKGQsIHRydWUpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHIsICd1dGMoMjAwNywgMCwgMSwgMCwgMCwgMCwgMCknKTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGU6IE90aGVyIHBhcnQgb2YgY292ZXJhZ2UgaGFuZGxlZCBieSB0aW1lVW5pdC5maWVsZEV4cHIncyB0ZXN0XG4gIH0pO1xufSk7XG4iXX0= \ 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..e69de29bb2 diff --git a/build/test/fielddef.test.js b/build/test/fielddef.test.js new file mode 100644 index 0000000000..209091875e --- /dev/null +++ b/build/test/fielddef.test.js @@ -0,0 +1,181 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var aggregate_1 = require("../src/aggregate"); +var fielddef_1 = require("../src/fielddef"); +var log = require("../src/log"); +var timeunit_1 = require("../src/timeunit"); +var type_1 = require("../src/type"); +describe('fieldDef', function () { + describe('field()', function () { + it('should construct paths', function () { + chai_1.assert.deepEqual(fielddef_1.field({ field: 'foo.bar\\.baz' }, { expr: 'datum' }), 'datum["foo"]["bar.baz"]'); + }); + }); + describe('defaultType()', function () { + it('should return temporal if there is timeUnit', function () { + chai_1.assert.equal(fielddef_1.defaultType({ timeUnit: 'month', field: 'a' }, 'x'), 'temporal'); + }); + it('should return quantitative if there is bin', function () { + chai_1.assert.equal(fielddef_1.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]; + chai_1.assert.equal(fielddef_1.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]; + chai_1.assert.equal(fielddef_1.defaultType({ field: 'a' }, c), 'nominal', c); + } + }); + }); + describe('normalize()', function () { + it('should convert primitive type to value def', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(fielddef_1.normalize(5, 'x'), { value: 5 }); + chai_1.assert.equal(localLogger.warns.length, 1); + })); + it('should return fieldDef with full type name.', function () { + var fieldDef = { field: 'a', type: 'q' }; + chai_1.assert.deepEqual(fielddef_1.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' + }; + chai_1.assert.deepEqual(fielddef_1.normalize(fieldDef, 'x'), { timeUnit: 'yearmonthdate', field: 'a', type: 'temporal' }); + chai_1.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 = aggregate_1.COUNTING_OPS; _i < COUNTING_OPS_1.length; _i++) { + var aggregate = COUNTING_OPS_1[_i]; + var fieldDef = { aggregate: aggregate, field: 'a', type: 'nominal' }; + chai_1.assert.deepEqual(fielddef_1.normalize(fieldDef, 'x'), { aggregate: aggregate, field: 'a', type: 'quantitative' }); + } + chai_1.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' }; + chai_1.assert.deepEqual(fielddef_1.normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + chai_1.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' }; + chai_1.assert.deepEqual(fielddef_1.normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + chai_1.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]; + chai_1.assert(!fielddef_1.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]; + chai_1.assert(fielddef_1.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]; + chai_1.assert(fielddef_1.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]; + chai_1.assert(fielddef_1.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]; + chai_1.assert(fielddef_1.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]; + chai_1.assert(fielddef_1.channelCompatibility({ bin: true, field: 'a', type: 'quantitative' }, channel).compatible); + } + }); + it('is incompatible with discrete field', function () { + for (var _i = 0, _a = ['opacity', 'size', 'x2', 'y2']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + } + }); + }); + describe('shape', function () { + it('is compatible with nominal field', function () { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, 'shape').compatible); + }); + it('is incompatible with ordinal field', function () { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'ordinal' }, 'shape').compatible); + }); + it('is incompatible with quantitative field', function () { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, 'shape').compatible); + }); + }); + describe('order', function () { + it('is incompatible with nominal field', function () { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, 'order').compatible); + }); + it('is compatible with ordinal field', function () { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'ordinal' }, 'order').compatible); + }); + it('is compatible with quantitative field', function () { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, 'order').compatible); + }); + }); + }); + describe('title()', function () { + it('should return correct title for aggregate', function () { + chai_1.assert.equal(fielddef_1.title({ field: 'f', type: type_1.QUANTITATIVE, aggregate: 'mean' }, {}), 'Mean of f'); + }); + it('should return correct title for count', function () { + chai_1.assert.equal(fielddef_1.title({ field: '*', type: type_1.QUANTITATIVE, aggregate: 'count' }, { countTitle: 'baz!' }), 'baz!'); + }); + it('should return correct title for bin', function () { + var fieldDef = { field: 'f', type: type_1.QUANTITATIVE, bin: true }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f (binned)'); + }); + it('should return correct title for bin', function () { + var fieldDef = { field: 'f', type: type_1.QUANTITATIVE, bin: true }; + chai_1.assert.equal(fielddef_1.title(fieldDef, { fieldTitle: 'functional' }), 'BIN(f)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.MONTH }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f (month)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.YEARMONTHDATE }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f (year-month-date)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.DAY }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f (day)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.YEARQUARTER }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f (year-quarter)'); + }); + it('should return correct title for raw field', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRkZWYudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvZmllbGRkZWYudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUU1Qiw4Q0FBOEM7QUFFOUMsNENBQWlIO0FBQ2pILGdDQUFrQztBQUNsQyw0Q0FBeUM7QUFDekMsb0NBQW1EO0FBRW5ELFFBQVEsQ0FBQyxVQUFVLEVBQUU7SUFDbkIsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUUsd0JBQXdCLEVBQUU7WUFDNUIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxnQkFBSyxDQUFDLEVBQUMsS0FBSyxFQUFFLGVBQWUsRUFBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLEVBQUUseUJBQXlCLENBQUMsQ0FBQztRQUNoRyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixFQUFFLENBQUMsNkNBQTZDLEVBQUU7WUFDaEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBVyxDQUFDLEVBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFxQixFQUFFLEdBQUcsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2xHLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1lBQy9DLGFBQU0sQ0FBQyxLQUFLLENBQUMsc0JBQVcsQ0FBQyxFQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBcUIsRUFBRSxHQUFHLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUM5RixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnRUFBZ0UsRUFBRTtZQUNuRSxHQUFHLENBQUMsQ0FBWSxVQUFtRCxFQUFuRCxLQUFBLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsU0FB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cm9tICdjaGFpJztcblxuaW1wb3J0IHtDT1VOVElOR19PUFN9IGZyb20gJy4uL3NyYy9hZ2dyZWdhdGUnO1xuaW1wb3J0IHtDaGFubmVsfSBmcm9tICcuLi9zcmMvY2hhbm5lbCc7XG5pbXBvcnQge2NoYW5uZWxDb21wYXRpYmlsaXR5LCBDaGFubmVsRGVmLCBkZWZhdWx0VHlwZSwgZmllbGQsIEZpZWxkRGVmLCBub3JtYWxpemUsIHRpdGxlfSBmcm9tICcuLi9zcmMvZmllbGRkZWYnO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL3NyYy9sb2cnO1xuaW1wb3J0IHtUaW1lVW5pdH0gZnJvbSAnLi4vc3JjL3RpbWV1bml0JztcbmltcG9ydCB7UVVBTlRJVEFUSVZFLCBURU1QT1JBTH0gZnJvbSAnLi4vc3JjL3R5cGUnO1xuXG5kZXNjcmliZSgnZmllbGREZWYnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdmaWVsZCgpJywgKCkgPT4ge1xuICAgIGl0ICgnc2hvdWxkIGNvbnN0cnVjdCBwYXRocycsICgpID0+IHtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoZmllbGQoe2ZpZWxkOiAnZm9vLmJhclxcXFwuYmF6J30sIHtleHByOiAnZGF0dW0nfSksICdkYXR1bVtcImZvb1wiXVtcImJhci5iYXpcIl0nKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2RlZmF1bHRUeXBlKCknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGVtcG9yYWwgaWYgdGhlcmUgaXMgdGltZVVuaXQnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFR5cGUoe3RpbWVVbml0OiAnbW9udGgnLCBmaWVsZDogJ2EnfSBhcyBGaWVsZERlZjxzdHJpbmc+LCAneCcpLCAndGVtcG9yYWwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHF1YW50aXRhdGl2ZSBpZiB0aGVyZSBpcyBiaW4nLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFR5cGUoe2JpbjogdHJ1ZSwgZmllbGQ6ICdhJ30gYXMgRmllbGREZWY8c3RyaW5nPiwgJ3gnKSwgJ3F1YW50aXRhdGl2ZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gcXVhbnRpdGF0aXZlIGZvciBhIGNoYW5uZWwgdGhhdCBzdXBwb3J0cyBtZWFzdXJlJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIFsneCcsICd5JywgJ3NpemUnLCAnb3BhY2l0eScsICdvcmRlciddIGFzIENoYW5uZWxbXSkge1xuICAgICAgICBhc3NlcnQuZXF1YWwoZGVmYXVsdFR5cGUoe2ZpZWxkOiAnYSd9IGFzIEZpZWxkRGVmPHN0cmluZz4sIGMpLCAncXVhbnRpdGF0aXZlJywgYyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBub21pbmFsIGZvciBhIGNoYW5uZWwgdGhhdCBkb2VzIG5vdCBzdXBwb3J0IG1lYXN1cmUnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGMgb2YgWydjb2xvcicsICdzaGFwZScsICdyb3cnLCAnY29sdW1uJ10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChkZWZhdWx0VHlwZSh7ZmllbGQ6ICdhJ30gYXMgRmllbGREZWY8c3RyaW5nPiwgYyksICdub21pbmFsJywgYyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdub3JtYWxpemUoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgcHJpbWl0aXZlIHR5cGUgdG8gdmFsdWUgZGVmJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPENoYW5uZWxEZWY8c3RyaW5nPj4obm9ybWFsaXplKDUgYXMgYW55LCAneCcpLCB7dmFsdWU6IDV9KTtcbiAgICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJucy5sZW5ndGgsIDEpO1xuICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZpZWxkRGVmIHdpdGggZnVsbCB0eXBlIG5hbWUuJywgKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGREZWY6IEZpZWxkRGVmPHN0cmluZz4gPSB7ZmllbGQ6ICdhJywgdHlwZTogJ3EnIGFzIGFueX07XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPENoYW5uZWxEZWY8c3RyaW5nPj4obm9ybWFsaXplKGZpZWxkRGVmLCAneCcpLCB7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9KTtcbiAgICB9KTtcblxuICAgIGl0KCdub3JtYWxpemVzIHllYXJtb250aGRheSB0byBiZWNvbWUgeWVhcm1vbnRoZGF0ZS4nLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkRGVmOiBGaWVsZERlZjxzdHJpbmc+ID0ge1xuICAgICAgICB0aW1lVW5pdDogJ3llYXJtb250aGRheScgYXMgVGltZVVuaXQsICAvLyBOZWVkIHRvIGNhc3QgaGVyZSBhcyB0aGlzIGlzIGludGVudGlvbmFsbHkgd3JvbmdcbiAgICAgICAgZmllbGQ6ICdhJyxcbiAgICAgICAgdHlwZTogJ3RlbXBvcmFsJ1xuICAgICAgfTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8Q2hhbm5lbERlZjxzdHJpbmc+Pihub3JtYWxpemUoZmllbGREZWYsICd4JyksIHt0aW1lVW5pdDogJ3llYXJtb250aGRhdGUnLCBmaWVsZDogJ2EnLCB0eXBlOiAndGVtcG9yYWwnfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmRheVJlcGxhY2VkV2l0aERhdGUoJ3llYXJtb250aGRheScpKTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcGxhY2Ugb3RoZXIgdHlwZSB3aXRoIHF1YW50aXRhdGl2ZSBmb3IgYSBmaWVsZCB3aXRoIGNvdW50aW5nIGFnZ3JlZ2F0ZS4nLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICAgIGZvciAoY29uc3QgYWdncmVnYXRlIG9mIENPVU5USU5HX09QUykge1xuICAgICAgICBjb25zdCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiA9IHthZ2dyZWdhdGUsIGZpZWxkOiAnYScsIHR5cGU6ICdub21pbmFsJ307XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWw8Q2hhbm5lbERlZjxzdHJpbmc+Pihub3JtYWxpemUoZmllbGREZWYsICd4JyksIHthZ2dyZWdhdGUsIGZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSk7XG4gICAgICB9XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnMubGVuZ3RoLCA0KTtcbiAgICB9KSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmaWVsZERlZiB3aXRoIGRlZmF1bHQgdHlwZSBhbmQgdGhyb3cgd2FybmluZyBpZiB0eXBlIGlzIG1pc3NpbmcuJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IHtmaWVsZDogJ2EnfSBhcyBGaWVsZERlZjxzdHJpbmc+O1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxDaGFubmVsRGVmPHN0cmluZz4+KG5vcm1hbGl6ZShmaWVsZERlZiwgJ3gnKSwge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSk7XG4gICAgICBhc3NlcnQuZXF1YWwobG9jYWxMb2dnZXIud2FybnNbMF0sIGxvZy5tZXNzYWdlLmVtcHR5T3JJbnZhbGlkRmllbGRUeXBlKHVuZGVmaW5lZCwgJ3gnLCAncXVhbnRpdGF0aXZlJykpO1xuICAgIH0pKTtcblxuICAgIGl0KCdzaG91bGQgZHJvcCBpbnZhbGlkIGFnZ3JlZ2F0ZSBvcHMgYW5kIHRocm93IHdhcm5pbmcuJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZERlZjogRmllbGREZWY8c3RyaW5nPiA9IHthZ2dyZWdhdGU6ICdib3gtcGxvdCcsIGZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8Q2hhbm5lbERlZjxzdHJpbmc+Pihub3JtYWxpemUoZmllbGREZWYsICd4JyksIHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGxvY2FsTG9nZ2VyLndhcm5zWzBdLCBsb2cubWVzc2FnZS5pbnZhbGlkQWdncmVnYXRlKCdib3gtcGxvdCcpKTtcbiAgICB9KSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjaGFubmVsQ29tcGF0YWJpbGl0eScsICgpID0+IHtcbiAgICBkZXNjcmliZSgncm93L2NvbHVtbicsICgpID0+IHtcbiAgICAgIGl0KCdpcyBpbmNvbXBhdGlibGUgd2l0aCBjb250aW51b3VzIGZpZWxkJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWydyb3cnLCAnY29sdW1uJ10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgICAgYXNzZXJ0KCFjaGFubmVsQ29tcGF0aWJpbGl0eSh7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LCBjaGFubmVsKS5jb21wYXRpYmxlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpdCgnaXMgY29tcGF0aWJsZSB3aXRoIGRpc2NyZXRlIGZpZWxkJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWydyb3cnLCAnY29sdW1uJ10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgICAgYXNzZXJ0KGNoYW5uZWxDb21wYXRpYmlsaXR5KHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9LCBjaGFubmVsKS5jb21wYXRpYmxlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgneC95L2NvbG9yL3RleHQvZGV0YWlsJywgKCkgPT4ge1xuICAgICAgaXQoJ2lzIGNvbXBhdGlibGUgd2l0aCBjb250aW51b3VzIGZpZWxkJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWyd4JywgJ3knLCAnY29sb3InLCAndGV4dCcsICdkZXRhaWwnXSBhcyBDaGFubmVsW10pIHtcbiAgICAgICAgICBhc3NlcnQoY2hhbm5lbENvbXBhdGliaWxpdHkoe2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwgY2hhbm5lbCkuY29tcGF0aWJsZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaXQoJ2lzIGNvbXBhdGlibGUgd2l0aCBkaXNjcmV0ZSBmaWVsZCcsICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBjaGFubmVsIG9mIFsneCcsICd5JywgJ2NvbG9yJywgJ3RleHQnLCAnZGV0YWlsJ10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgICAgYXNzZXJ0KGNoYW5uZWxDb21wYXRpYmlsaXR5KHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9LCBjaGFubmVsKS5jb21wYXRpYmxlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnb3BhY2l0eS9zaXplL3gyL3kyJywgKCkgPT4ge1xuICAgICAgaXQoJ2lzIGNvbXBhdGlibGUgd2l0aCBjb250aW51b3VzIGZpZWxkJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgWydvcGFjaXR5JywgJ3NpemUnLCAneDInLCAneTInXSBhcyBDaGFubmVsW10pIHtcbiAgICAgICAgICBhc3NlcnQoY2hhbm5lbENvbXBhdGliaWxpdHkoe2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwgY2hhbm5lbCkuY29tcGF0aWJsZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnaXMgY29tcGF0aWJsZSB3aXRoIGJpbm5lZCBmaWVsZCcsICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBjaGFubmVsIG9mIFsnb3BhY2l0eScsICdzaXplJywgJ3gyJywgJ3kyJ10gYXMgQ2hhbm5lbFtdKSB7XG4gICAgICAgICAgYXNzZXJ0KGNoYW5uZWxDb21wYXRpYmlsaXR5KHtiaW46IHRydWUsIGZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSwgY2hhbm5lbCkuY29tcGF0aWJsZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnaXMgaW5jb21wYXRpYmxlIHdpdGggZGlzY3JldGUgZmllbGQnLCAoKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBbJ29wYWNpdHknLCAnc2l6ZScsICd4MicsICd5MiddIGFzIENoYW5uZWxbXSkge1xuICAgICAgICAgIGFzc2VydCghY2hhbm5lbENvbXBhdGliaWxpdHkoe2ZpZWxkOiAnYScsIHR5cGU6ICdub21pbmFsJ30sIGNoYW5uZWwpLmNvbXBhdGlibGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzaGFwZScsICgpID0+IHtcbiAgICAgIGl0KCdpcyBjb21wYXRpYmxlIHdpdGggbm9taW5hbCBmaWVsZCcsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0KGNoYW5uZWxDb21wYXRpYmlsaXR5KHtmaWVsZDogJ2EnLCB0eXBlOiAnbm9taW5hbCd9LCAnc2hhcGUnKS5jb21wYXRpYmxlKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ2lzIGluY29tcGF0aWJsZSB3aXRoIG9yZGluYWwgZmllbGQnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydCghY2hhbm5lbENvbXBhdGliaWxpdHkoe2ZpZWxkOiAnYScsIHR5cGU6ICdvcmRpbmFsJ30sICdzaGFwZScpLmNvbXBhdGlibGUpO1xuICAgICAgfSk7XG4gICAgICBpdCgnaXMgaW5jb21wYXRpYmxlIHdpdGggcXVhbnRpdGF0aXZlIGZpZWxkJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQoIWNoYW5uZWxDb21wYXRpYmlsaXR5KHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sICdzaGFwZScpLmNvbXBhdGlibGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnb3JkZXInLCAoKSA9PiB7XG4gICAgICBpdCgnaXMgaW5jb21wYXRpYmxlIHdpdGggbm9taW5hbCBmaWVsZCcsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0KCFjaGFubmVsQ29tcGF0aWJpbGl0eSh7ZmllbGQ6ICdhJywgdHlwZTogJ25vbWluYWwnfSwgJ29yZGVyJykuY29tcGF0aWJsZSk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdpcyBjb21wYXRpYmxlIHdpdGggb3JkaW5hbCBmaWVsZCcsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0KGNoYW5uZWxDb21wYXRpYmlsaXR5KHtmaWVsZDogJ2EnLCB0eXBlOiAnb3JkaW5hbCd9LCAnb3JkZXInKS5jb21wYXRpYmxlKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ2lzIGNvbXBhdGlibGUgd2l0aCBxdWFudGl0YXRpdmUgZmllbGQnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydChjaGFubmVsQ29tcGF0aWJpbGl0eSh7ZmllbGQ6ICdhJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9LCAnb3JkZXInKS5jb21wYXRpYmxlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndGl0bGUoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IHRpdGxlIGZvciBhZ2dyZWdhdGUnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwodGl0bGUoe2ZpZWxkOiAnZicsIHR5cGU6IFFVQU5USVRBVElWRSwgYWdncmVnYXRlOiAnbWVhbid9LCB7fSksICdNZWFuIG9mIGYnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGl0bGUgZm9yIGNvdW50JywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKHRpdGxlKHtmaWVsZDogJyonLCB0eXBlOiBRVUFOVElUQVRJVkUsIGFnZ3JlZ2F0ZTogJ2NvdW50J30sIHtjb3VudFRpdGxlOiAnYmF6ISd9KSwgJ2JheiEnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGl0bGUgZm9yIGJpbicsICgpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkRGVmID0ge2ZpZWxkOiAnZicsIHR5cGU6IFFVQU5USVRBVElWRSwgYmluOiB0cnVlfTtcbiAgICAgIGFzc2VydC5lcXVhbCh0aXRsZShmaWVsZERlZix7fSksICdmIChiaW5uZWQpJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IHRpdGxlIGZvciBiaW4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IHtmaWVsZDogJ2YnLCB0eXBlOiBRVUFOVElUQVRJVkUsIGJpbjogdHJ1ZX07XG4gICAgICBhc3NlcnQuZXF1YWwodGl0bGUoZmllbGREZWYse2ZpZWxkVGl0bGU6ICdmdW5jdGlvbmFsJ30pLCAnQklOKGYpJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IHRpdGxlIGZvciB0aW1lVW5pdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkRGVmID0ge2ZpZWxkOiAnZicsIHR5cGU6IFRFTVBPUkFMLCB0aW1lVW5pdDogVGltZVVuaXQuTU9OVEh9O1xuICAgICAgYXNzZXJ0LmVxdWFsKHRpdGxlKGZpZWxkRGVmLHt9KSwgJ2YgKG1vbnRoKScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCB0aXRsZSBmb3IgdGltZVVuaXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZERlZiA9IHtmaWVsZDogJ2YnLCB0eXBlOiBURU1QT1JBTCwgdGltZVVuaXQ6IFRpbWVVbml0LllFQVJNT05USERBVEV9O1xuICAgICAgYXNzZXJ0LmVxdWFsKHRpdGxlKGZpZWxkRGVmLHt9KSwgJ2YgKHllYXItbW9udGgtZGF0ZSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGl0bGUgZm9yIHRpbWVVbml0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGREZWYgPSB7ZmllbGQ6ICdmJywgdHlwZTogVEVNUE9SQUwsIHRpbWVVbml0OiBUaW1lVW5pdC5EQVl9O1xuICAgICAgYXNzZXJ0LmVxdWFsKHRpdGxlKGZpZWxkRGVmLHt9KSwgJ2YgKGRheSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGl0bGUgZm9yIHRpbWVVbml0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGREZWYgPSB7ZmllbGQ6ICdmJywgdHlwZTogVEVNUE9SQUwsIHRpbWVVbml0OiBUaW1lVW5pdC5ZRUFSUVVBUlRFUn07XG4gICAgICBhc3NlcnQuZXF1YWwodGl0bGUoZmllbGREZWYse30pLCAnZiAoeWVhci1xdWFydGVyKScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCB0aXRsZSBmb3IgcmF3IGZpZWxkJywgKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGREZWYgPSB7ZmllbGQ6ICdmJywgdHlwZTogVEVNUE9SQUx9O1xuICAgICAgYXNzZXJ0LmVxdWFsKHRpdGxlKGZpZWxkRGVmLHt9KSwgJ2YnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ No newline at end of file diff --git a/build/test/filter.test.d.ts b/build/test/filter.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/filter.test.js b/build/test/filter.test.js new file mode 100644 index 0000000000..a8d02f3500 --- /dev/null +++ b/build/test/filter.test.js @@ -0,0 +1,124 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var filter_1 = require("../src/filter"); +var timeunit_1 = require("../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'; + describe('isEqualFilter', function () { + it('should return true for an equal filter', function () { + chai_1.assert.isTrue(filter_1.isEqualFilter(equalFilter)); + }); + it('should return false for other filters', function () { + [oneOfFilter, rangeFilter, exprFilter].forEach(function (filter) { + chai_1.assert.isFalse(filter_1.isEqualFilter(filter)); + }); + }); + }); + describe('isOneOfFilter', function () { + it('should return true for an in filter', function () { + chai_1.assert.isTrue(filter_1.isOneOfFilter(oneOfFilter)); + }); + it('should return false for other filters', function () { + [equalFilter, rangeFilter, exprFilter].forEach(function (filter) { + chai_1.assert.isFalse(filter_1.isOneOfFilter(filter)); + }); + }); + }); + describe('isRangeFilter', function () { + it('should return true for a range filter', function () { + chai_1.assert.isTrue(filter_1.isRangeFilter(rangeFilter)); + }); + it('should return false for other filters', function () { + [oneOfFilter, equalFilter, exprFilter].forEach(function (filter) { + chai_1.assert.isFalse(filter_1.isRangeFilter(filter)); + }); + }); + }); + describe('expression', function () { + it('should return a correct expression for an EqualFilter', function () { + var expr = filter_1.expression(null, { field: 'color', equal: 'red' }); + chai_1.assert.equal(expr, 'datum["color"]==="red"'); + }); + it('should return a correct expression for an EqualFilter with datetime object', function () { + var expr = filter_1.expression(null, { + field: 'date', + equal: { + month: 'January' + } + }); + chai_1.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 = filter_1.expression(null, { + timeUnit: timeunit_1.TimeUnit.MONTH, + field: 'date', + equal: { + month: 'January' + } + }); + chai_1.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 ojbect', function () { + var expr = filter_1.expression(null, { + timeUnit: timeunit_1.TimeUnit.MONTH, + field: 'date', + equal: 'January' + }); + chai_1.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 = filter_1.expression(null, { field: 'color', oneOf: ['red', 'yellow'] }); + chai_1.assert.equal(expr, 'indexof(["red","yellow"], datum["color"]) !== -1'); + }); + it('should return a correct expression for a RangeFilter', function () { + var expr = filter_1.expression(null, { field: 'x', range: [0, 5] }); + chai_1.assert.equal(expr, 'inrange(datum["x"], [0, 5])'); + }); + it('should return a correct expression for a RangeFilter with no lower bound', function () { + var expr = filter_1.expression(null, { field: 'x', range: [null, 5] }); + chai_1.assert.equal(expr, 'datum["x"] <= 5'); + }); + it('should return a correct expression for a RangeFilter with no upper bound', function () { + var expr = filter_1.expression(null, { field: 'x', range: [0, null] }); + chai_1.assert.equal(expr, 'datum["x"] >= 0'); + }); + it('should return true for a RangeFilter with no bound', function () { + var expr = filter_1.expression(null, { field: 'x', range: [null, null] }); + chai_1.assert.equal(expr, 'true'); + }); + it('should return a correct expression for an expression filter', function () { + var expr = filter_1.expression(null, 'datum["x"]===5'); + chai_1.assert.equal(expr, 'datum["x"]===5'); + }); + }); + it('generates expressions for composed filters', function () { + var expr = filter_1.expression(null, { not: { field: 'color', equal: 'red' } }); + chai_1.assert.equal(expr, '!(datum["color"]==="red")'); + expr = filter_1.expression(null, { and: [ + { field: 'color', equal: 'red' }, + { field: 'x', range: [0, 5] } + ] }); + chai_1.assert.equal(expr, '(datum["color"]==="red") && (inrange(datum["x"], [0, 5]))'); + expr = filter_1.expression(null, { and: [ + { field: 'color', oneOf: ['red', 'yellow'] }, + { or: [ + { field: 'x', range: [0, null] }, + 'datum.price > 10', + { not: 'datum["x"]===5' } + ] } + ] }); + chai_1.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 = filter_1.fieldFilterExpression({ field: 'x', range: [0, 5] }, false); + chai_1.assert.equal(expr, 'datum["x"] >= 0 && datum["x"] <= 5'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2ZpbHRlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLHdDQUE2RztBQUM3Ryw0Q0FBeUM7QUFFekMsUUFBUSxDQUFDLFFBQVEsRUFBRTtJQUNqQixJQUFNLFdBQVcsR0FBRyxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDO0lBQ25ELElBQU0sV0FBVyxHQUFHLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEVBQUMsQ0FBQztJQUMvRCxJQUFNLFdBQVcsR0FBRyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFDLENBQUM7SUFDaEQsSUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUM7SUFFcEMsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsYUFBTSxDQUFDLE1BQU0sQ0FBQyxzQkFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLE1BQU07Z0JBQ3BELGFBQU0sQ0FBQyxPQUFPLENBQUMsc0JBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFDLHFDQUFxQyxFQUFFO1lBQ3hDLGFBQU0sQ0FBQyxNQUFNLENBQUMsc0JBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVDQUF1QyxFQUFFO1lBQzFDLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQyxNQUFNO2dCQUNwRCxhQUFNLENBQUMsT0FBTyxDQUFDLHNCQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRTtZQUMxQyxhQUFNLENBQUMsTUFBTSxDQUFDLHNCQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRTtZQUMxQyxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsTUFBTTtnQkFDcEQsYUFBTSxDQUFDLE9BQU8sQ0FBQyxzQkFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsSUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO1lBQzlELGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNEVBQTRFLEVBQUU7WUFDL0UsSUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxJQUFJLEVBQUU7Z0JBQzVCLEtBQUssRUFBRSxNQUFNO2dCQUNiLEtBQUssRUFBRTtvQkFDTCxLQUFLLEVBQUUsU0FBUztpQkFDakI7YUFDRixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxxREFBcUQsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBGQUEwRixFQUFFO1lBQzdGLElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFO2dCQUM1QixRQUFRLEVBQUUsbUJBQVEsQ0FBQyxLQUFLO2dCQUN4QixLQUFLLEVBQUUsTUFBTTtnQkFDYixLQUFLLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLFNBQVM7aUJBQ2pCO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsOEZBQThGLENBQUMsQ0FBQztRQUNySCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0RUFBNEUsRUFBRTtZQUMvRSxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDLElBQUksRUFBRTtnQkFDNUIsUUFBUSxFQUFFLG1CQUFRLENBQUMsS0FBSztnQkFDeEIsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsS0FBSyxFQUFFLFNBQVM7YUFDakIsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsOEZBQThGLENBQUMsQ0FBQztRQUNySCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvREFBb0QsRUFBRTtZQUN2RCxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUMxRSxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxrREFBa0QsQ0FBQyxDQUFDO1FBQ3pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNEQUFzRCxFQUFFO1lBQ3pELElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQzNELGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLDZCQUE2QixDQUFDLENBQUM7UUFDcEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMEVBQTBFLEVBQUU7WUFDN0UsSUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7WUFDOUQsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwRUFBMEUsRUFBRTtZQUM3RSxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUM5RCxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBR0gsRUFBRSxDQUFDLG9EQUFvRCxFQUFFO1lBQ3ZELElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQ2pFLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO1lBQ2hFLElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFDaEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1FBQy9DLElBQUksSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFLEVBQUMsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFDLEVBQUMsQ0FBQyxDQUFDO1FBQ25FLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLDJCQUEyQixDQUFDLENBQUM7UUFFaEQsSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFLEVBQUMsR0FBRyxFQUFFO2dCQUM1QixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQztnQkFDOUIsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQzthQUM1QixFQUFDLENBQUMsQ0FBQztRQUVKLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLDJEQUEyRCxDQUFDLENBQUM7UUFFaEYsSUFBSSxHQUFHLG1CQUFVLENBQUMsSUFBSSxFQUFFLEVBQUMsR0FBRyxFQUFFO2dCQUM1QixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxFQUFDO2dCQUMxQyxFQUFDLEVBQUUsRUFBRTt3QkFDSCxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFDO3dCQUM5QixrQkFBa0I7d0JBQ2xCLEVBQUMsR0FBRyxFQUFFLGdCQUFnQixFQUFDO3FCQUN4QixFQUFDO2FBQ0gsRUFBQyxDQUFDLENBQUM7UUFFSixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSx3REFBd0Q7WUFDekUsa0VBQWtFLENBQUMsQ0FBQztJQUN4RSxDQUFDLENBQUMsQ0FBQztJQUdILFFBQVEsQ0FBQyx1QkFBdUIsRUFBRTtRQUNoQyxFQUFFLENBQUMsc0VBQXNFLEVBQUU7WUFDekUsSUFBTSxJQUFJLEdBQUcsOEJBQXFCLENBQUMsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3ZFLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLG9DQUFvQyxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtleHByZXNzaW9uLCBmaWVsZEZpbHRlckV4cHJlc3Npb24sIGlzRXF1YWxGaWx0ZXIsIGlzT25lT2ZGaWx0ZXIsIGlzUmFuZ2VGaWx0ZXJ9IGZyb20gJy4uL3NyYy9maWx0ZXInO1xuaW1wb3J0IHtUaW1lVW5pdH0gZnJvbSAnLi4vc3JjL3RpbWV1bml0JztcblxuZGVzY3JpYmUoJ2ZpbHRlcicsICgpID0+IHtcbiAgY29uc3QgZXF1YWxGaWx0ZXIgPSB7ZmllbGQ6ICdjb2xvcicsIGVxdWFsOiAncmVkJ307XG4gIGNvbnN0IG9uZU9mRmlsdGVyID0ge2ZpZWxkOiAnY29sb3InLCBvbmVPZjogWydyZWQnLCAneWVsbG93J119O1xuICBjb25zdCByYW5nZUZpbHRlciA9IHtmaWVsZDogJ3gnLCByYW5nZTogWzAsIDVdfTtcbiAgY29uc3QgZXhwckZpbHRlciA9ICdkYXR1bVtcInhcIl09PT01JztcblxuICBkZXNjcmliZSgnaXNFcXVhbEZpbHRlcicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBhbiBlcXVhbCBmaWx0ZXInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuaXNUcnVlKGlzRXF1YWxGaWx0ZXIoZXF1YWxGaWx0ZXIpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBvdGhlciBmaWx0ZXJzJywgKCkgPT4ge1xuICAgICAgW29uZU9mRmlsdGVyLCByYW5nZUZpbHRlciwgZXhwckZpbHRlcl0uZm9yRWFjaCgoZmlsdGVyKSA9PiB7XG4gICAgICAgIGFzc2VydC5pc0ZhbHNlKGlzRXF1YWxGaWx0ZXIoZmlsdGVyKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzT25lT2ZGaWx0ZXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYW4gaW4gZmlsdGVyJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShpc09uZU9mRmlsdGVyKG9uZU9mRmlsdGVyKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3Igb3RoZXIgZmlsdGVycycsICgpID0+IHtcbiAgICAgIFtlcXVhbEZpbHRlciwgcmFuZ2VGaWx0ZXIsIGV4cHJGaWx0ZXJdLmZvckVhY2goKGZpbHRlcikgPT4ge1xuICAgICAgICBhc3NlcnQuaXNGYWxzZShpc09uZU9mRmlsdGVyKGZpbHRlcikpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1JhbmdlRmlsdGVyJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGEgcmFuZ2UgZmlsdGVyJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShpc1JhbmdlRmlsdGVyKHJhbmdlRmlsdGVyKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3Igb3RoZXIgZmlsdGVycycsICgpID0+IHtcbiAgICAgIFtvbmVPZkZpbHRlciwgZXF1YWxGaWx0ZXIsIGV4cHJGaWx0ZXJdLmZvckVhY2goKGZpbHRlcikgPT4ge1xuICAgICAgICBhc3NlcnQuaXNGYWxzZShpc1JhbmdlRmlsdGVyKGZpbHRlcikpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdleHByZXNzaW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29ycmVjdCBleHByZXNzaW9uIGZvciBhbiBFcXVhbEZpbHRlcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGV4cHIgPSBleHByZXNzaW9uKG51bGwsIHtmaWVsZDogJ2NvbG9yJywgZXF1YWw6ICdyZWQnfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZXhwciwgJ2RhdHVtW1wiY29sb3JcIl09PT1cInJlZFwiJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIGNvcnJlY3QgZXhwcmVzc2lvbiBmb3IgYW4gRXF1YWxGaWx0ZXIgd2l0aCBkYXRldGltZSBvYmplY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHByID0gZXhwcmVzc2lvbihudWxsLCB7XG4gICAgICAgIGZpZWxkOiAnZGF0ZScsXG4gICAgICAgIGVxdWFsOiB7XG4gICAgICAgICAgbW9udGg6ICdKYW51YXJ5J1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByLCAnZGF0dW1bXCJkYXRlXCJdPT09dGltZShkYXRldGltZSgwLCAwLCAxLCAwLCAwLCAwLCAwKSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29ycmVjdCBleHByZXNzaW9uIGZvciBhbiBFcXVhbEZpbHRlciB3aXRoIHRpbWUgdW5pdCBhbmQgZGF0ZXRpbWUgb2JqZWN0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZXhwciA9IGV4cHJlc3Npb24obnVsbCwge1xuICAgICAgICB0aW1lVW5pdDogVGltZVVuaXQuTU9OVEgsXG4gICAgICAgIGZpZWxkOiAnZGF0ZScsXG4gICAgICAgIGVxdWFsOiB7XG4gICAgICAgICAgbW9udGg6ICdKYW51YXJ5J1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByLCAndGltZShkYXRldGltZSgwLCBtb250aChkYXR1bVtcImRhdGVcIl0pLCAxLCAwLCAwLCAwLCAwKSk9PT10aW1lKGRhdGV0aW1lKDAsIDAsIDEsIDAsIDAsIDAsIDApKScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBjb3JyZWN0IGV4cHJlc3Npb24gZm9yIGFuIEVxdWFsRmlsdGVyIHdpdGggZGF0ZXRpbWUgb2piZWN0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZXhwciA9IGV4cHJlc3Npb24obnVsbCwge1xuICAgICAgICB0aW1lVW5pdDogVGltZVVuaXQuTU9OVEgsXG4gICAgICAgIGZpZWxkOiAnZGF0ZScsXG4gICAgICAgIGVxdWFsOiAnSmFudWFyeSdcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHIsICd0aW1lKGRhdGV0aW1lKDAsIG1vbnRoKGRhdHVtW1wiZGF0ZVwiXSksIDEsIDAsIDAsIDAsIDApKT09PXRpbWUoZGF0ZXRpbWUoMCwgMCwgMSwgMCwgMCwgMCwgMCkpJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIGNvcnJlY3QgZXhwcmVzc2lvbiBmb3IgYW4gSW5GaWx0ZXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHByID0gZXhwcmVzc2lvbihudWxsLCB7ZmllbGQ6ICdjb2xvcicsIG9uZU9mOiBbJ3JlZCcsICd5ZWxsb3cnXX0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHIsICdpbmRleG9mKFtcInJlZFwiLFwieWVsbG93XCJdLCBkYXR1bVtcImNvbG9yXCJdKSAhPT0gLTEnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29ycmVjdCBleHByZXNzaW9uIGZvciBhIFJhbmdlRmlsdGVyJywgKCkgPT4ge1xuICAgICAgY29uc3QgZXhwciA9IGV4cHJlc3Npb24obnVsbCwge2ZpZWxkOiAneCcsIHJhbmdlOiBbMCwgNV19KTtcbiAgICAgIGFzc2VydC5lcXVhbChleHByLCAnaW5yYW5nZShkYXR1bVtcInhcIl0sIFswLCA1XSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29ycmVjdCBleHByZXNzaW9uIGZvciBhIFJhbmdlRmlsdGVyIHdpdGggbm8gbG93ZXIgYm91bmQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHByID0gZXhwcmVzc2lvbihudWxsLCB7ZmllbGQ6ICd4JywgcmFuZ2U6IFtudWxsLCA1XX0pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHIsICdkYXR1bVtcInhcIl0gPD0gNScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBjb3JyZWN0IGV4cHJlc3Npb24gZm9yIGEgUmFuZ2VGaWx0ZXIgd2l0aCBubyB1cHBlciBib3VuZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGV4cHIgPSBleHByZXNzaW9uKG51bGwsIHtmaWVsZDogJ3gnLCByYW5nZTogWzAsIG51bGxdfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZXhwciwgJ2RhdHVtW1wieFwiXSA+PSAwJyk7XG4gICAgfSk7XG5cblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGEgUmFuZ2VGaWx0ZXIgd2l0aCBubyBib3VuZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGV4cHIgPSBleHByZXNzaW9uKG51bGwsIHtmaWVsZDogJ3gnLCByYW5nZTogW251bGwsIG51bGxdfSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZXhwciwgJ3RydWUnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29ycmVjdCBleHByZXNzaW9uIGZvciBhbiBleHByZXNzaW9uIGZpbHRlcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGV4cHIgPSBleHByZXNzaW9uKG51bGwsICdkYXR1bVtcInhcIl09PT01Jyk7XG4gICAgICBhc3NlcnQuZXF1YWwoZXhwciwgJ2RhdHVtW1wieFwiXT09PTUnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ2dlbmVyYXRlcyBleHByZXNzaW9ucyBmb3IgY29tcG9zZWQgZmlsdGVycycsICgpID0+IHtcbiAgICBsZXQgZXhwciA9IGV4cHJlc3Npb24obnVsbCwge25vdDoge2ZpZWxkOiAnY29sb3InLCBlcXVhbDogJ3JlZCd9fSk7XG4gICAgYXNzZXJ0LmVxdWFsKGV4cHIsICchKGRhdHVtW1wiY29sb3JcIl09PT1cInJlZFwiKScpO1xuXG4gICAgZXhwciA9IGV4cHJlc3Npb24obnVsbCwge2FuZDogW1xuICAgICAge2ZpZWxkOiAnY29sb3InLCBlcXVhbDogJ3JlZCd9LFxuICAgICAge2ZpZWxkOiAneCcsIHJhbmdlOiBbMCwgNV19XG4gICAgXX0pO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGV4cHIsICcoZGF0dW1bXCJjb2xvclwiXT09PVwicmVkXCIpICYmIChpbnJhbmdlKGRhdHVtW1wieFwiXSwgWzAsIDVdKSknKTtcblxuICAgIGV4cHIgPSBleHByZXNzaW9uKG51bGwsIHthbmQ6IFtcbiAgICAgIHtmaWVsZDogJ2NvbG9yJywgb25lT2Y6IFsncmVkJywgJ3llbGxvdyddfSxcbiAgICAgIHtvcjogW1xuICAgICAgICB7ZmllbGQ6ICd4JywgcmFuZ2U6IFswLCBudWxsXX0sXG4gICAgICAgICdkYXR1bS5wcmljZSA+IDEwJyxcbiAgICAgICAge25vdDogJ2RhdHVtW1wieFwiXT09PTUnfVxuICAgICAgXX1cbiAgICBdfSk7XG5cbiAgICBhc3NlcnQuZXF1YWwoZXhwciwgJyhpbmRleG9mKFtcInJlZFwiLFwieWVsbG93XCJdLCBkYXR1bVtcImNvbG9yXCJdKSAhPT0gLTEpICYmICcgK1xuICAgICAgJygoZGF0dW1bXCJ4XCJdID49IDApIHx8IChkYXR1bS5wcmljZSA+IDEwKSB8fCAoIShkYXR1bVtcInhcIl09PT01KSkpJyk7XG4gIH0pO1xuXG5cbiAgZGVzY3JpYmUoJ2ZpZWxkRmlsdGVyRXhwcmVzc2lvbicsICgpID0+IHtcbiAgICBpdCgnZ2VuZXJhdGVzIGEgcmFuZ2UgcHJlZGljYXRlIHVzaW5nIGluZXF1YWxpdGllcyB3aGVuIHVzZUluUmFuZ2U9ZmFsc2UnLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHByID0gZmllbGRGaWx0ZXJFeHByZXNzaW9uKHtmaWVsZDogJ3gnLCByYW5nZTogWzAsIDVdfSwgZmFsc2UpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGV4cHIsICdkYXR1bVtcInhcIl0gPj0gMCAmJiBkYXR1bVtcInhcIl0gPD0gNScpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/scale.test.js b/build/test/scale.test.js new file mode 100644 index 0000000000..1828dcd53f --- /dev/null +++ b/build/test/scale.test.js @@ -0,0 +1,87 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../src/channel"); +var scale = require("../src/scale"); +var scale_1 = require("../src/scale"); +var util_1 = require("../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) { + chai_1.assert(util_1.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.) + chai_1.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]; + chai_1.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) { + chai_1.assert(util_1.some(scale_1.SCALE_TYPES, function (scaleType) { + return scale_1.channelSupportScaleType(channel, scaleType); + })); + }; + for (var _i = 0, SCALE_CHANNELS_1 = channel_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) { + chai_1.assert(util_1.some(channel_1.SCALE_CHANNELS, function (channel) { + return scale_1.channelSupportScaleType(channel, scaleType); + })); + }; + for (var _i = 0, SCALE_TYPES_1 = scale_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 () { + chai_1.assert(scale_1.channelSupportScaleType('shape', 'ordinal')); + var nonOrdinal = util_1.without(scale_1.SCALE_TYPES, ['ordinal']); + for (var _i = 0, nonOrdinal_1 = nonOrdinal; _i < nonOrdinal_1.length; _i++) { + var scaleType = nonOrdinal_1[_i]; + chai_1.assert(!scale_1.channelSupportScaleType('shape', scaleType)); + } + }); + it('color should support all scale types except band', function () { + for (var _i = 0, SCALE_TYPES_2 = scale_1.SCALE_TYPES; _i < SCALE_TYPES_2.length; _i++) { + var scaleType = SCALE_TYPES_2[_i]; + chai_1.assert.equal(scale_1.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 = scale_1.CONTINUOUS_TO_CONTINUOUS_SCALES.concat([scale_1.ScaleType.BAND, scale_1.ScaleType.POINT]); + for (var _i = 0, _a = ['x', 'y', 'size', 'opacity']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(!scale_1.channelSupportScaleType(channel, 'ordinal')); + chai_1.assert(!scale_1.channelSupportScaleType(channel, 'sequential')); + for (var _b = 0, scaleTypes_1 = scaleTypes; _b < scaleTypes_1.length; _b++) { + var scaleType = scaleTypes_1[_b]; + chai_1.assert(scale_1.channelSupportScaleType(channel, scaleType), "Error: " + channel + ", " + scaleType); + } + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3Qvc2NhbGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1QiwwQ0FBNEQ7QUFDNUQsb0NBQXNDO0FBQ3RDLHNDQUE4RztBQUM5RyxvQ0FBMEM7QUFFMUMsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixRQUFRLENBQUMsMEJBQTBCLEVBQUU7UUFDbkMsd0RBQXdEO1FBQ3hELEVBQUUsQ0FBQyx5RUFBeUUsRUFBRTtvQ0FDakUsSUFBSTtnQkFDYixhQUFNLENBQUMsV0FBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsVUFBQyxTQUFTO29CQUN2QyxNQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDekQsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNOLENBQUM7WUFKRCxHQUFHLENBQUMsQ0FBZSxVQUFzQixFQUF0QixLQUFBLEtBQUssQ0FBQyxnQkFBZ0IsRUFBdEIsY0FBc0IsRUFBdEIsSUFBc0I7Z0JBQXBDLElBQU0sSUFBSSxTQUFBO3dCQUFKLElBQUk7YUFJZDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsZ0ZBQWdGO1FBRWhGLGFBQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixFQUFFLENBQUMsd0RBQXdELEVBQUU7WUFDM0QsR0FBRyxDQUFDLENBQW9CLFVBQWlCLEVBQWpCLEtBQUEsS0FBSyxDQUFDLFdBQVcsRUFBakIsY0FBaUIsRUFBakIsSUFBaUI7Z0JBQXBDLElBQU0sU0FBUyxTQUFBO2dCQUNsQixhQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxLQUFLLEtB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QUFTLENBQUMsRUFBRSxZQUFVLE9BQU8sVUFBSyxTQUFXLENBQUMsQ0FBQztpQkFDeEY7YUFDRjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7U0NBTEVfQ0hBTk5FTFMsIFNjYWxlQ2hhbm5lbH0gZnJvbSAnLi4vc3JjL2NoYW5uZWwnO1xuaW1wb3J0ICogYXMgc2NhbGUgZnJvbSAnLi4vc3JjL3NjYWxlJztcbmltcG9ydCB7Y2hhbm5lbFN1cHBvcnRTY2FsZVR5cGUsIENPTlRJTlVPVVNfVE9fQ09OVElOVU9VU19TQ0FMRVMsIFNDQUxFX1RZUEVTLCBTY2FsZVR5cGV9IGZyb20gJy4uL3NyYy9zY2FsZSc7XG5pbXBvcnQge3NvbWUsIHdpdGhvdXR9IGZyb20gJy4uL3NyYy91dGlsJztcblxuZGVzY3JpYmUoJ3NjYWxlJywgKCkgPT4ge1xuICBkZXNjcmliZSgnc2NhbGVUeXBlU3VwcG9ydFByb3BlcnR5JywgKCkgPT4ge1xuICAgIC8vIE1ha2Ugc3VyZSB3ZSBhbHdheXMgZWRpdCB0aGlzIHdoZW4gd2UgYWRkIG5ldyBjaGFubmVsXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGF0IGxlYXN0IG9uZSBzdXBwb3J0ZWQgc2NhbGUgdHlwZXMgZm9yIGFsbCBzY2FsZSBwcm9wZXJ0aWVzJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBwcm9wIG9mIHNjYWxlLlNDQUxFX1BST1BFUlRJRVMpIHtcbiAgICAgICAgYXNzZXJ0KHNvbWUoc2NhbGUuU0NBTEVfVFlQRVMsIChzY2FsZVR5cGUpID0+IHtcbiAgICAgICAgICByZXR1cm4gc2NhbGUuc2NhbGVUeXBlU3VwcG9ydFByb3BlcnR5KHNjYWxlVHlwZSwgcHJvcCk7XG4gICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFRPRE86IHdyaXRlIG1vcmUgdGVzdCBibGluZGx5IChEb24ndCBsb29rIGF0IG91ciBjb2RlLCBqdXN0IGxvb2sgYXQgRDMgY29kZS4pXG5cbiAgICBhc3NlcnQuaXNGYWxzZShzY2FsZS5zY2FsZVR5cGVTdXBwb3J0UHJvcGVydHkoJ2Jpbi1saW5lYXInLCAnemVybycpKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NjYWxlVHlwZXMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBlaXRoZXIgaGFzQ29udGludW91c0RvbWFpbiBvciBoYXNEaXNjcmV0ZURvbWFpbicsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIHNjYWxlLlNDQUxFX1RZUEVTKSB7XG4gICAgICAgIGFzc2VydChzY2FsZS5oYXNDb250aW51b3VzRG9tYWluKHNjYWxlVHlwZSkgIT09IHNjYWxlLmhhc0Rpc2NyZXRlRG9tYWluKHNjYWxlVHlwZSkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuXG4gIGRlc2NyaWJlKCdjaGFubmVsU3VwcG9ydFNjYWxlVHlwZScsICgpID0+IHtcbiAgICAvLyBNYWtlIHN1cmUgd2UgYWx3YXlzIGVkaXQgdGhpcyB3aGVuIHdlIGFkZCBuZXcgY2hhbm5lbFxuICAgIGl0KCdzaG91bGQgaGF2ZSBhdCBsZWFzdCBvbmUgc3VwcG9ydGVkIHNjYWxlIHR5cGVzIGZvciBhbGwgY2hhbm5lbHMgd2l0aCBzY2FsZScsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBTQ0FMRV9DSEFOTkVMUykge1xuICAgICAgICBhc3NlcnQoc29tZShTQ0FMRV9UWVBFUywgKHNjYWxlVHlwZSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjaGFubmVsU3VwcG9ydFNjYWxlVHlwZShjaGFubmVsLCBzY2FsZVR5cGUpO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBNYWtlIHN1cmUgd2UgYWx3YXlzIGVkaXQgdGhpcyB3aGVuIHdlIGFkZCBuZXcgc2NhbGUgdHlwZVxuICAgIGl0KCdzaG91bGQgaGF2ZSBhdCBsZWFzdCBvbmUgc3VwcG9ydGVkIGNoYW5uZWwgZm9yIGFsbCBzY2FsZSB0eXBlcycsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIFNDQUxFX1RZUEVTKSB7XG4gICAgICAgIGFzc2VydChzb21lKFNDQUxFX0NIQU5ORUxTLCAoY2hhbm5lbCkgPT4ge1xuICAgICAgICAgIHJldHVybiBjaGFubmVsU3VwcG9ydFNjYWxlVHlwZShjaGFubmVsLCBzY2FsZVR5cGUpO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hhcGUgc2hvdWxkIHN1cHBvcnQgb25seSBvcmRpbmFsJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0KGNoYW5uZWxTdXBwb3J0U2NhbGVUeXBlKCdzaGFwZScsICdvcmRpbmFsJykpO1xuICAgICAgY29uc3Qgbm9uT3JkaW5hbCA9IHdpdGhvdXQ8U2NhbGVUeXBlPihTQ0FMRV9UWVBFUywgWydvcmRpbmFsJ10pO1xuICAgICAgZm9yIChjb25zdCBzY2FsZVR5cGUgb2Ygbm9uT3JkaW5hbCkge1xuICAgICAgICBhc3NlcnQoIWNoYW5uZWxTdXBwb3J0U2NhbGVUeXBlKCdzaGFwZScsIHNjYWxlVHlwZSkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ2NvbG9yIHNob3VsZCBzdXBwb3J0IGFsbCBzY2FsZSB0eXBlcyBleGNlcHQgYmFuZCcsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIFNDQUxFX1RZUEVTKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbChjaGFubmVsU3VwcG9ydFNjYWxlVHlwZSgnY29sb3InLCBzY2FsZVR5cGUpLCBzY2FsZVR5cGUgIT09ICdiYW5kJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgneCwgeSwgc2l6ZSwgb3BhY2l0eSBzaG91bGQgc3VwcG9ydCBhbGwgY29udGludW91cyBzY2FsZSB0eXBlIGFzIHdlbGwgYXMgYmFuZCBhbmQgcG9pbnQnLCAoKSA9PiB7XG4gICAgICAvLyB4LHkgc2hvdWxkIHVzZSBlaXRoZXIgYmFuZCBvciBwb2ludCBmb3Igb3JkaW5hbCBpbnB1dFxuICAgICAgY29uc3Qgc2NhbGVUeXBlcyA9IFsuLi5DT05USU5VT1VTX1RPX0NPTlRJTlVPVVNfU0NBTEVTLCBTY2FsZVR5cGUuQkFORCwgU2NhbGVUeXBlLlBPSU5UXTtcblxuICAgICAgZm9yIChjb25zdCBjaGFubmVsIG9mIFsneCcsICd5JywgJ3NpemUnLCAnb3BhY2l0eSddIGFzIFNjYWxlQ2hhbm5lbFtdKSB7XG4gICAgICAgIGFzc2VydCghY2hhbm5lbFN1cHBvcnRTY2FsZVR5cGUoY2hhbm5lbCwgJ29yZGluYWwnKSk7XG4gICAgICAgIGFzc2VydCghY2hhbm5lbFN1cHBvcnRTY2FsZVR5cGUoY2hhbm5lbCwgJ3NlcXVlbnRpYWwnKSk7XG4gICAgICAgIGZvciAoY29uc3Qgc2NhbGVUeXBlIG9mIHNjYWxlVHlwZXMpIHtcbiAgICAgICAgICBhc3NlcnQoY2hhbm5lbFN1cHBvcnRTY2FsZVR5cGUoY2hhbm5lbCwgc2NhbGVUeXBlKSwgYEVycm9yOiAke2NoYW5uZWx9LCAke3NjYWxlVHlwZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/spec.test.js b/build/test/spec.test.js new file mode 100644 index 0000000000..1a908af6f0 --- /dev/null +++ b/build/test/spec.test.js @@ -0,0 +1,654 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var spec_1 = require("../src/spec"); +var config_1 = require("./../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 = config_1.initConfig(spec.config); + chai_1.assert.deepEqual(spec_1.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 = config_1.initConfig(spec.config); + chai_1.assert.deepEqual(spec_1.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 () { + chai_1.assert.deepEqual(spec_1.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 } + } + } + ] + } + }, config_1.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('should produce correct layered specs for mean point and vertical error bar', function () { + chai_1.assert.deepEqual(spec_1.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" }], + 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 } + } + } + ] + }, config_1.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" }], + 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('normalizeOverlay', 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": { "overlay": { "line": true } } + }; + var normalizedSpec = spec_1.normalize(spec, spec.config); + chai_1.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", "filled": true, "style": "pointOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + "config": { "overlay": { "line": true } } + }); + }); + 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": { "overlay": { "line": true } } + }; + var normalizedSpec = spec_1.normalize(spec, spec.config); + chai_1.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", "filled": true, "style": "pointOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + }, + "config": { "overlay": { "line": true } } + }); + }); + 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": { "overlay": { "area": 'linepoint' } } + }; + var normalizedSpec = spec_1.normalize(spec, spec.config); + chai_1.assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "line", "style": "lineOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "point", "filled": true, "style": "pointOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + "config": { "overlay": { "area": 'linepoint' } } + }); + }); + it('correctly normalizes area with overlay line', 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": { "overlay": { "area": 'line' } } + }; + var normalizedSpec = spec_1.normalize(spec, spec.config); + chai_1.assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "line", "style": "lineOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + "config": { "overlay": { "area": 'line' } } + }); + }); + 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": { "overlay": { "area": 'line' } } + }; + var normalizedSpec = spec_1.normalize(spec, spec.config); + chai_1.assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + } + }, + { + "mark": { "type": "line", "style": "lineOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "zero" }, + "color": { "field": "symbol", "type": "nominal" } + } + } + ], + "config": { "overlay": { "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": { "overlay": { "area": 'line' } } + }; + var normalizedSpec = spec_1.normalize(spec, spec.config); + chai_1.assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "center" }, + "color": { "field": "symbol", "type": "nominal" } + } + }, + { + "mark": { "type": "line", "style": "lineOverlay" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "center" }, + "color": { "field": "symbol", "type": "nominal" } + } + } + ], + "config": { "overlay": { "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" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec, config_1.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" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec, config_1.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" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec, config_1.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" } + } + }; + chai_1.assert.sameDeepMembers(spec_1.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 } } + } + ] + }; + chai_1.assert.sameDeepMembers(spec_1.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 } } + } + ] + }; + chai_1.assert.sameDeepMembers(spec_1.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" } + } + } + }; + chai_1.assert.sameDeepMembers(spec_1.fieldDefs(facetSpec), [ + { "field": "MPAA_Rating", "type": "ordinal" }, + { "field": "Worldwide_Gross", "type": "quantitative" }, + { "field": "US_DVD_Sales", "type": "quantitative" } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlYy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC9zcGVjLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUE4Qjs7QUFFOUIsNkJBQTRCO0FBSTVCLG9DQUEyRztBQUMzRywwQ0FBMEQ7QUFFMUQsNEVBQTRFO0FBRTVFLFFBQVEsQ0FBQyxhQUFhLEVBQUU7SUFDdEIsUUFBUSxDQUFDLHNCQUFzQixFQUFFO1FBQy9CLEVBQUUsQ0FBQyx1RUFBdUUsRUFBRTtZQUMxRSxJQUFNLElBQUksR0FBUTtnQkFDaEIsTUFBTSxFQUFFLFNBQVM7Z0JBQ2pCLE9BQU8sRUFBRSxHQUFHO2dCQUNaLFFBQVEsRUFBRSxHQUFHO2dCQUNiLGFBQWEsRUFBRSxjQUFjO2dCQUM3QixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7Z0JBQ25DLE1BQU0sRUFBRSxPQUFPO2dCQUNmLFVBQVUsRUFBRTtvQkFDVixRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUM7b0JBQ3BELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO29CQUN4RCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsY0FBYyxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7aUJBQ3REO2FBQ0YsQ0FBQztZQUNGLElBQU0sTUFBTSxHQUFHLG1CQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZDLGFBQU0sQ0FBQyxTQUFTLENBQWtFLGdCQUFTLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFO2dCQUN6RyxNQUFNLEVBQUUsU0FBUztnQkFDakIsYUFBYSxFQUFFLGNBQWM7Z0JBQzdCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztnQkFDbkMsT0FBTyxFQUFFO29CQUNQLFFBQVEsRUFBRSxFQUFDLE9B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QUMvRSxJQUFNLFNBQVMsR0FBUTtZQUNyQixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7WUFDbkMsT0FBTyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsT0FBTyxFQUFFLGFBQWEsRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFDLEVBQUM7WUFDNUQsTUFBTSxFQUFFO2dCQUNOLE1BQU0sRUFBRSxPQUFPO2dCQUNmLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztvQkFDeEQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGNBQWMsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO2lCQUN0RDthQUNGO1NBQ0YsQ0FBQztRQUVGLGFBQU0sQ0FBQyxlQUFlLENBQWtCLGdCQUFTLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDNUQsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUM7WUFDMUMsRUFBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUNuRCxFQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztTQUNqRCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6cXVvdGVtYXJrICovXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7RW5jb2Rpbmd9IGZyb20gJy4uL3NyYy9lbmNvZGluZyc7XG5pbXBvcnQge0ZpZWxkLCBGaWVsZERlZn0gZnJvbSAnLi4vc3JjL2ZpZWxkZGVmJztcbmltcG9ydCB7TWFya0RlZn0gZnJvbSAnLi4vc3JjL21hcmsnO1xuaW1wb3J0IHtmaWVsZERlZnMsIEdlbmVyaWNTcGVjLCBHZW5lcmljVW5pdFNwZWMsIG5vcm1hbGl6ZSwgU3BlYywgVG9wTGV2ZWxFeHRlbmRlZFNwZWN9IGZyb20gJy4uL3NyYy9zcGVjJztcbmltcG9ydCB7ZGVmYXVsdENvbmZpZywgaW5pdENvbmZpZ30gZnJvbSAnLi8uLi9zcmMvY29uZmlnJztcblxuLy8gZGVzY3JpYmUoJ2lzU3RhY2tlZCgpJykgLS0gdGVzdGVkIGFzIHBhcnQgb2Ygc3RhY2tPZmZzZXQgaW4gc3RhY2sudGVzdC50c1xuXG5kZXNjcmliZSgnbm9ybWFsaXplKCknLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCdub3JtYWxpemVGYWNldGVkVW5pdCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgc2luZ2xlIGV4dGVuZGVkIHNwZWMgd2l0aCBjb2x1bW4gaW50byBhIGNvbXBvc2l0ZSBzcGVjJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBzcGVjOiBhbnkgPSB7XG4gICAgICAgIFwibmFtZVwiOiBcImZhY2V0ZWRcIixcbiAgICAgICAgXCJ3aWR0aFwiOiAxMjMsXG4gICAgICAgIFwiaGVpZ2h0XCI6IDIzNCxcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcImZhY2V0ZWQgc3BlY1wiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9tb3ZpZXMuanNvblwifSxcbiAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJjb2x1bW5cIjoge1wiZmllbGRcIjogXCJNUEFBX1JhdGluZ1wiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiV29ybGR3aWRlX0dyb3NzXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIlVTX0RWRF9TYWxlc1wiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgY29uc3QgY29uZmlnID0gaW5pdENvbmZpZyhzcGVjLmNvbmZpZyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHNwZWMsIGNvbmZpZyksIHtcbiAgICAgICAgXCJuYW1lXCI6IFwiZmFjZXRlZFwiLFxuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiZmFjZXRlZCBzcGVjXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL21vdmllcy5qc29uXCJ9LFxuICAgICAgICBcImZhY2V0XCI6IHtcbiAgICAgICAgICBcImNvbHVtblwiOiB7XCJmaWVsZFwiOiBcIk1QQUFfUmF0aW5nXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifVxuICAgICAgICB9LFxuICAgICAgICBcInNwZWNcIjoge1xuICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgXCJ3aWR0aFwiOiAxMjMsXG4gICAgICAgICAgXCJoZWlnaHRcIjogMjM0LFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiV29ybGR3aWRlX0dyb3NzXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwiVVNfRFZEX1NhbGVzXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29udmVydCBzaW5nbGUgZXh0ZW5kZWQgc3BlYyB3aXRoIHJvdyBpbnRvIGEgY29tcG9zaXRlIHNwZWMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IHNwZWM6IGFueSA9IHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvbW92aWVzLmpzb25cIn0sXG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwicm93XCI6IHtcImZpZWxkXCI6IFwiTVBBQV9SYXRpbmdcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIldvcmxkd2lkZV9Hcm9zc1wiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJVU19EVkRfU2FsZXNcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uZmlnID0gaW5pdENvbmZpZyhzcGVjLmNvbmZpZyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHNwZWMsIGNvbmZpZyksIHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvbW92aWVzLmpzb25cIn0sXG4gICAgICAgIFwiZmFjZXRcIjoge1xuICAgICAgICAgIFwicm93XCI6IHtcImZpZWxkXCI6IFwiTVBBQV9SYXRpbmdcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwic3BlY1wiOiB7XG4gICAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIldvcmxkd2lkZV9Hcm9zc1wiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcIlVTX0RWRF9TYWxlc1wiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdub3JtYWxpemVGYWNldCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgY29ycmVjdCBsYXllcmVkIHNwZWNzIGZvciBtZWFuIHBvaW50IGFuZCB2ZXJ0aWNhbCBlcnJvciBiYXInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPEdlbmVyaWNTcGVjPEdlbmVyaWNVbml0U3BlYzxFbmNvZGluZzxGaWVsZD4sIHN0cmluZyB8IE1hcmtEZWY+Pj4obm9ybWFsaXplKHtcbiAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkEgZXJyb3IgYmFyIHBsb3Qgc2hvd2luZyBtZWFuLCBtaW4sIGFuZCBtYXggaW4gdGhlIFVTIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIG9mIGFnZSBncm91cHMgaW4gMjAwMC5cIixcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvcG9wdWxhdGlvbi5qc29uXCJ9LFxuICAgICAgICBcInRyYW5zZm9ybVwiOiBbe1wiZmlsdGVyXCI6IFwiZGF0dW0ueWVhciA9PSAyMDAwXCJ9XSxcbiAgICAgICAgZmFjZXQ6IHtcbiAgICAgICAgICBcInJvd1wiOiB7XCJmaWVsZFwiOiBcIk1QQUFfUmF0aW5nXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifVxuICAgICAgICB9LFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgbGF5ZXI6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtZWFuXCIsXG4gICAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiAyfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtYXJrOiAnZXJyb3ItYmFyJyxcbiAgICAgICAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWF4XCIsXG4gICAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIH0sIGRlZmF1bHRDb25maWcpLCB7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGVycm9yIGJhciBwbG90IHNob3dpbmcgbWVhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW3tcImZpbHRlclwiOiBcImRhdHVtLnllYXIgPT0gMjAwMFwifV0sXG4gICAgICAgIGZhY2V0OiB7XG4gICAgICAgICAgXCJyb3dcIjoge1wiZmllbGRcIjogXCJNUEFBX1JhdGluZ1wiLFwidHlwZVwiOiBcIm9yZGluYWxcIn1cbiAgICAgICAgfSxcbiAgICAgICAgc3BlYzoge1xuICAgICAgICAgIGxheWVyOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWVhblwiLFxuICAgICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogMn1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtaW5cIixcbiAgICAgICAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLFxuICAgICAgICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBcIm1hcmtcIjogXCJ0aWNrXCIsXG4gICAgICAgICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiA1fVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgXCJtYXJrXCI6IFwidGlja1wiLFxuICAgICAgICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgLy8gXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbm9ybWFsaXplTGF5ZXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGNvcnJlY3QgbGF5ZXJlZCBzcGVjcyBmb3IgbWVhbiBwb2ludCBhbmQgdmVydGljYWwgZXJyb3IgYmFyJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxHZW5lcmljU3BlYzxHZW5lcmljVW5pdFNwZWM8RW5jb2Rpbmc8RmllbGQ+LCBzdHJpbmcgfCBNYXJrRGVmPj4+KG5vcm1hbGl6ZSh7XG4gICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJBIGVycm9yIGJhciBwbG90IHNob3dpbmcgbWVhbiwgbWluLCBhbmQgbWF4IGluIHRoZSBVUyBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBvZiBhZ2UgZ3JvdXBzIGluIDIwMDAuXCIsXG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgICAgXCJ0cmFuc2Zvcm1cIjogW3tcImZpbHRlclwiOiBcImRhdHVtLnllYXIgPT0gMjAwMFwifV0sXG4gICAgICAgIGxheWVyOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWVhblwiLFxuICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIixcbiAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIFwic2l6ZVwiOiB7XCJ2YWx1ZVwiOiAyfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFyazogJ2Vycm9yLWJhcicsXG4gICAgICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWluXCIsXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5MlwiOiB7XG4gICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LCBkZWZhdWx0Q29uZmlnKSwge1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBlcnJvciBiYXIgcGxvdCBzaG93aW5nIG1lYW4sIG1pbiwgYW5kIG1heCBpbiB0aGUgVVMgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gb2YgYWdlIGdyb3VwcyBpbiAyMDAwLlwiLFxuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IFt7XCJmaWx0ZXJcIjogXCJkYXR1bS55ZWFyID09IDIwMDBcIn1dLFxuICAgICAgICBsYXllcjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcbiAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1lYW5cIixcbiAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgXCJheGlzXCI6IHtcInRpdGxlXCI6IFwicG9wdWxhdGlvblwifVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogMn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJtYXJrXCI6IFwicnVsZVwiLFxuICAgICAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWluXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBcInkyXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgXCJhZ2dyZWdhdGVcIjogXCJtYXhcIixcbiAgICAgICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcInBlb3BsZVwiLFxuICAgICAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFwibWFya1wiOiBcInRpY2tcIixcbiAgICAgICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgICAgICAgICAgICBcInlcIjoge1xuICAgICAgICAgICAgICAgICAgICBcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLFxuICAgICAgICAgICAgICAgICAgICBcImZpZWxkXCI6IFwicGVvcGxlXCIsXG4gICAgICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLFxuICAgICAgICAgICAgICAgICAgICBcImF4aXNcIjoge1widGl0bGVcIjogXCJwb3B1bGF0aW9uXCJ9XG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgXCJzaXplXCI6IHtcInZhbHVlXCI6IDV9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgXCJtYXJrXCI6IFwidGlja1wiLFxuICAgICAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgICAgICAgICAgIFwieVwiOiB7XG4gICAgICAgICAgICAgICAgICAgIFwiYWdncmVnYXRlXCI6IFwibWF4XCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZmllbGRcIjogXCJwZW9wbGVcIixcbiAgICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsXG4gICAgICAgICAgICAgICAgICAgIC8vIFwiYXhpc1wiOiB7XCJ0aXRsZVwiOiBcInBvcHVsYXRpb25cIn1cbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBcInNpemVcIjoge1widmFsdWVcIjogNX1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbm9ybWFsaXplT3ZlcmxheScsICgpID0+IHtcbiAgICBpdCgnY29ycmVjdGx5IG5vcm1hbGl6ZXMgbGluZSB3aXRoIG92ZXJsYXllZCBwb2ludC4nLCAoKSA9PiB7XG4gICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbEV4dGVuZGVkU3BlYyA9IHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvc3RvY2tzLmNzdlwiLCBcImZvcm1hdFwiOiB7XCJ0eXBlXCI6IFwiY3N2XCJ9fSxcbiAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9LFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJvdmVybGF5XCI6IHtcImxpbmVcIjogdHJ1ZX19XG4gICAgICB9O1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFNwZWMgPSBub3JtYWxpemUoc3BlYywgc3BlYy5jb25maWcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxUb3BMZXZlbEV4dGVuZGVkU3BlYz4obm9ybWFsaXplZFNwZWMsIHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvc3RvY2tzLmNzdlwiLFwiZm9ybWF0XCI6IHtcInR5cGVcIjogXCJjc3ZcIn19LFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiB7XCJ0eXBlXCI6IFwicG9pbnRcIiwgXCJmaWxsZWRcIjogdHJ1ZSwgXCJzdHlsZVwiOiBcInBvaW50T3ZlcmxheVwifSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdLFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJvdmVybGF5XCI6IHtcImxpbmVcIjogdHJ1ZX19XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjb3JyZWN0bHkgbm9ybWFsaXplcyBmYWNldGVkIGxpbmUgcGxvdHMgd2l0aCBvdmVybGF5ZWQgcG9pbnQuJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWxFeHRlbmRlZFNwZWMgPSB7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3N0b2Nrcy5jc3ZcIiwgXCJmb3JtYXRcIjoge1widHlwZVwiOiBcImNzdlwifX0sXG4gICAgICAgIFwibWFya1wiOiBcImxpbmVcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJyb3dcIjoge1wiZmllbGRcIjogXCJzeW1ib2xcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICB9LFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJvdmVybGF5XCI6IHtcImxpbmVcIjogdHJ1ZX19XG4gICAgICB9O1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFNwZWMgPSBub3JtYWxpemUoc3BlYywgc3BlYy5jb25maWcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxUb3BMZXZlbEV4dGVuZGVkU3BlYz4obm9ybWFsaXplZFNwZWMsIHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvc3RvY2tzLmNzdlwiLFwiZm9ybWF0XCI6IHtcInR5cGVcIjogXCJjc3ZcIn19LFxuICAgICAgICBcImZhY2V0XCI6IHtcbiAgICAgICAgICBcInJvd1wiOiB7XCJmaWVsZFwiOiBcInN5bWJvbFwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICB9LFxuICAgICAgICBcInNwZWNcIjoge1xuICAgICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIiwgXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJtYXJrXCI6IHtcInR5cGVcIjogXCJwb2ludFwiLCBcImZpbGxlZFwiOiB0cnVlLCBcInN0eWxlXCI6IFwicG9pbnRPdmVybGF5XCJ9LFxuICAgICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcIm92ZXJsYXlcIjoge1wibGluZVwiOiB0cnVlfX1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NvcnJlY3RseSBub3JtYWxpemVzIGFyZWEgd2l0aCBvdmVybGF5IGxpbmUgYW5kIHBvaW50JywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWxFeHRlbmRlZFNwZWMgPSB7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3N0b2Nrcy5jc3ZcIiwgXCJmb3JtYXRcIjoge1widHlwZVwiOiBcImNzdlwifX0sXG4gICAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLCBcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfSxcbiAgICAgICAgXCJjb25maWdcIjoge1wib3ZlcmxheVwiOiB7XCJhcmVhXCI6ICdsaW5lcG9pbnQnfX1cbiAgICAgIH07XG4gICAgICBjb25zdCBub3JtYWxpemVkU3BlYyA9IG5vcm1hbGl6ZShzcGVjLCBzcGVjLmNvbmZpZyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsPFRvcExldmVsRXh0ZW5kZWRTcGVjPihub3JtYWxpemVkU3BlYywge1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9zdG9ja3MuY3N2XCIsXCJmb3JtYXRcIjoge1widHlwZVwiOiBcImNzdlwifX0sXG4gICAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiBcImFyZWFcIixcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjoge1widHlwZVwiOiBcImxpbmVcIiwgXCJzdHlsZVwiOiBcImxpbmVPdmVybGF5XCJ9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiB7XCJ0eXBlXCI6IFwicG9pbnRcIiwgXCJmaWxsZWRcIjogdHJ1ZSwgXCJzdHlsZVwiOiBcInBvaW50T3ZlcmxheVwifSxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdLFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJvdmVybGF5XCI6IHtcImFyZWFcIjogJ2xpbmVwb2ludCd9fVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY29ycmVjdGx5IG5vcm1hbGl6ZXMgYXJlYSB3aXRoIG92ZXJsYXkgbGluZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsRXh0ZW5kZWRTcGVjID0ge1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9zdG9ja3MuY3N2XCIsIFwiZm9ybWF0XCI6IHtcInR5cGVcIjogXCJjc3ZcIn19LFxuICAgICAgICBcIm1hcmtcIjogXCJhcmVhXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIiwgXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcIm92ZXJsYXlcIjoge1wiYXJlYVwiOiAnbGluZSd9fVxuICAgICAgfTtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTcGVjID0gbm9ybWFsaXplKHNwZWMsIHNwZWMuY29uZmlnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VG9wTGV2ZWxFeHRlbmRlZFNwZWM+KG5vcm1hbGl6ZWRTcGVjLCB7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3N0b2Nrcy5jc3ZcIixcImZvcm1hdFwiOiB7XCJ0eXBlXCI6IFwiY3N2XCJ9fSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFwibWFya1wiOiB7XCJ0eXBlXCI6IFwibGluZVwiLCBcInN0eWxlXCI6IFwibGluZU92ZXJsYXlcIn0sXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJjb25maWdcIjoge1wib3ZlcmxheVwiOiB7XCJhcmVhXCI6ICdsaW5lJ319XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjb3JyZWN0bHkgbm9ybWFsaXplcyBzdGFja2VkIGFyZWEgd2l0aCBvdmVybGF5IGxpbmUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbEV4dGVuZGVkU3BlYyA9IHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvc3RvY2tzLmNzdlwiLCBcImZvcm1hdFwiOiB7XCJ0eXBlXCI6IFwiY3N2XCJ9fSxcbiAgICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsIFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInByaWNlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic3ltYm9sXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgfSxcbiAgICAgICAgXCJjb25maWdcIjoge1wib3ZlcmxheVwiOiB7XCJhcmVhXCI6ICdsaW5lJ319XG4gICAgICB9O1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFNwZWMgPSBub3JtYWxpemUoc3BlYywgc3BlYy5jb25maWcpO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbDxUb3BMZXZlbEV4dGVuZGVkU3BlYz4obm9ybWFsaXplZFNwZWMsIHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvc3RvY2tzLmNzdlwiLFwiZm9ybWF0XCI6IHtcInR5cGVcIjogXCJjc3ZcIn19LFxuICAgICAgICBcImxheWVyXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjogXCJhcmVhXCIsXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJwcmljZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInN5bWJvbFwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjoge1widHlwZVwiOiBcImxpbmVcIiwgXCJzdHlsZVwiOiBcImxpbmVPdmVybGF5XCJ9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJzdGFja1wiOiBcInplcm9cIn0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzeW1ib2xcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgXCJjb25maWdcIjoge1wib3ZlcmxheVwiOiB7XCJhcmVhXCI6ICdsaW5lJ319XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjb3JyZWN0bHkgbm9ybWFsaXplcyBzdHJlYW1ncmFwaCB3aXRoIG92ZXJsYXkgbGluZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsRXh0ZW5kZWRTcGVjID0ge1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9zdG9ja3MuY3N2XCIsIFwiZm9ybWF0XCI6IHtcInR5cGVcIjogXCJjc3ZcIn19LFxuICAgICAgICBcIm1hcmtcIjogXCJhcmVhXCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIiwgXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwicHJpY2VcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwic3RhY2tcIjogXCJjZW50ZXJcIn0sXG4gICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInN5bWJvbFwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgIH0sXG4gICAgICAgIFwiY29uZmlnXCI6IHtcIm92ZXJsYXlcIjoge1wiYXJlYVwiOiAnbGluZSd9fVxuICAgICAgfTtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTcGVjID0gbm9ybWFsaXplKHNwZWMsIHNwZWMuY29uZmlnKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWw8VG9wTGV2ZWxFeHRlbmRlZFNwZWM+KG5vcm1hbGl6ZWRTcGVjLCB7XG4gICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3N0b2Nrcy5jc3ZcIixcImZvcm1hdFwiOiB7XCJ0eXBlXCI6IFwiY3N2XCJ9fSxcbiAgICAgICAgXCJsYXllclwiOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJtYXJrXCI6IFwiYXJlYVwiLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJzdGFja1wiOiBcImNlbnRlclwifSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInN5bWJvbFwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBcIm1hcmtcIjoge1widHlwZVwiOiBcImxpbmVcIiwgXCJzdHlsZVwiOiBcImxpbmVPdmVybGF5XCJ9LFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJzdGFja1wiOiBcImNlbnRlclwifSxcbiAgICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInN5bWJvbFwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICBdLFxuICAgICAgICBcImNvbmZpZ1wiOiB7XCJvdmVybGF5XCI6IHtcImFyZWFcIjogJ2xpbmUnfX1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnbm9ybWFsaXplUmFuZ2VkVW5pdFNwZWMnLCAoKSA9PiB7XG4gIGl0KCdzaG91bGQgY29udmVydCB5MiAtPiB5IGlmIHRoZXJlIGlzIG5vIHkgaW4gdGhlIGVuY29kaW5nJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgc3BlYzogU3BlYyA9IHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInkyXCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLCBcImZpZWxkXCI6IFwicGVvcGxlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ4MlwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtYXhcIiwgXCJmaWVsZFwiOiBcInBlb3BsZVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgYXNzZXJ0LmRlZXBFcXVhbDxTcGVjPihub3JtYWxpemUoc3BlYywgZGVmYXVsdENvbmZpZyksIHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWluXCIsIFwiZmllbGRcIjogXCJwZW9wbGVcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcIngyXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLCBcImZpZWxkXCI6IFwicGVvcGxlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm8gbWlzc2luZyB4IG9yIHknLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBzcGVjOiBUb3BMZXZlbEV4dGVuZGVkU3BlYyA9IHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3BvcHVsYXRpb24uanNvblwifSxcbiAgICAgIFwibWFya1wiOiBcInJ1bGVcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJhZ2VcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwibWluXCIsIFwiZmllbGRcIjogXCJwZW9wbGVcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcIngyXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1heFwiLCBcImZpZWxkXCI6IFwicGVvcGxlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgfVxuICAgIH07XG5cbiAgICBhc3NlcnQuZGVlcEVxdWFsPFRvcExldmVsRXh0ZW5kZWRTcGVjPihub3JtYWxpemUoc3BlYywgZGVmYXVsdENvbmZpZyksIHNwZWMpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNvbnZlcnQgeDIgLT4geCBpZiB0aGVyZSBpcyBubyB4IGluIHRoZSBlbmNvZGluZycsIGZ1bmN0aW9uKCkge1xuICAgIGNvbnN0IHNwZWM6IFNwZWMgPSB7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4MlwiOiB7XCJmaWVsZFwiOiBcImFnZVwiLFwidHlwZVwiOiBcIm9yZGluYWxcIn0sXG4gICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtaW5cIiwgXCJmaWVsZFwiOiBcInBlb3BsZVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgIFwieTJcIjoge1wiYWdncmVnYXRlXCI6IFwibWF4XCIsIFwiZmllbGRcIjogXCJwZW9wbGVcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGFzc2VydC5kZWVwRXF1YWw8U3BlYz4obm9ybWFsaXplKHNwZWMsIGRlZmF1bHRDb25maWcpLCB7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9wb3B1bGF0aW9uLmpzb25cIn0sXG4gICAgICBcIm1hcmtcIjogXCJydWxlXCIsXG4gICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYWdlXCIsXCJ0eXBlXCI6IFwib3JkaW5hbFwifSxcbiAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcIm1pblwiLCBcImZpZWxkXCI6IFwicGVvcGxlXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgXCJ5MlwiOiB7XCJhZ2dyZWdhdGVcIjogXCJtYXhcIiwgXCJmaWVsZFwiOiBcInBlb3BsZVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ2ZpZWxkRGVmcygpJywgZnVuY3Rpb24oKSB7XG4gIGl0KCdzaG91bGQgZ2V0IGFsbCBub24tZHVwbGljYXRlIGZpZWxkRGVmcyBmcm9tIGFuIGVuY29kaW5nJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgc3BlYzogYW55ID0ge1xuICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvY2Fycy5qc29uXCJ9LFxuICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJIb3JzZXBvd2VyXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJNaWxlc19wZXJfR2FsbG9uXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGFzc2VydC5zYW1lRGVlcE1lbWJlcnM8RmllbGREZWY8RmllbGQ+PihmaWVsZERlZnMoc3BlYyksIFtcbiAgICAgIHtcImZpZWxkXCI6IFwiSG9yc2Vwb3dlclwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgIHtcImZpZWxkXCI6IFwiTWlsZXNfcGVyX0dhbGxvblwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgIF0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGdldCBhbGwgbm9uLWR1cGxpY2F0ZSBmaWVsZERlZnMgZnJvbSBhbGwgbGF5ZXIgaW4gYSBMYXllclNwZWMnLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBsYXllclNwZWM6IGFueSA9IHtcbiAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL3N0b2Nrcy5jc3ZcIixcImZvcm1hdFwiOiB7XCJ0eXBlXCI6IFwiY3N2XCJ9fSxcbiAgICAgIFwibGF5ZXJcIjogW1xuICAgICAgICB7XG4gICAgICAgICAgXCJkZXNjcmlwdGlvblwiOiBcIkdvb2dsZSdzIHN0b2NrIHByaWNlIG92ZXIgdGltZS5cIixcbiAgICAgICAgICBcIm1hcmtcIjogXCJsaW5lXCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJHb29nbGUncyBzdG9jayBwcmljZSBvdmVyIHRpbWUuXCIsXG4gICAgICAgICAgXCJtYXJrXCI6IFwicG9pbnRcIixcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInByaWNlXCIsXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInN5bWJvbFwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBcImNvbmZpZ1wiOiB7XCJtYXJrXCI6IHtcImZpbGxlZFwiOiB0cnVlfX1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH07XG5cbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzPEZpZWxkRGVmPEZpZWxkPj4oZmllbGREZWZzKGxheWVyU3BlYyksIFtcbiAgICAgIHtcImZpZWxkXCI6IFwiZGF0ZVwiLFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAge1wiZmllbGRcIjogXCJwcmljZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgIHtcImZpZWxkXCI6IFwic3ltYm9sXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBnZXQgYWxsIG5vbi1kdXBsaWNhdGUgZmllbGREZWZzIGZyb20gYWxsIGxheWVyIGluIGEgTGF5ZXJTcGVjIChtZXJnaW5nIGR1cGxpY2F0ZSBmaWVsZHMgd2l0aCBkaWZmZXJlbnQgc2NhbGUgdHlwZXMpJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgbGF5ZXJTcGVjOiBhbnkgPSB7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9zdG9ja3MuY3N2XCIsXCJmb3JtYXRcIjoge1widHlwZVwiOiBcImNzdlwifX0sXG4gICAgICBcImxheWVyXCI6IFtcbiAgICAgICAge1xuICAgICAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJHb29nbGUncyBzdG9jayBwcmljZSBvdmVyIHRpbWUuXCIsXG4gICAgICAgICAgXCJtYXJrXCI6IFwibGluZVwiLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiZGF0ZVwiLFwidHlwZVwiOiBcInRlbXBvcmFsXCJ9LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwiR29vZ2xlJ3Mgc3RvY2sgcHJpY2Ugb3ZlciB0aW1lLlwiLFxuICAgICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIn0sXG4gICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJwcmljZVwiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJkYXRlXCIsXCJ0eXBlXCI6IFwidGVtcG9yYWxcIiwgXCJzY2FsZVwiOiB7XCJ0eXBlXCI6IFwicG93XCJ9fVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb25maWdcIjoge1wibWFya1wiOiB7XCJmaWxsZWRcIjogdHJ1ZX19XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICB9O1xuXG4gICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVyczxGaWVsZERlZjxGaWVsZD4+KGZpZWxkRGVmcyhsYXllclNwZWMpLCBbXG4gICAgICB7XCJmaWVsZFwiOiBcImRhdGVcIixcInR5cGVcIjogXCJ0ZW1wb3JhbFwifSxcbiAgICAgIHtcImZpZWxkXCI6IFwicHJpY2VcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBnZXQgYWxsIG5vbi1kdXBsaWNhdGUgZmllbGREZWZzIGZyb20gZmFjZXQgYW5kIGxheWVyIGluIGEgRmFjZXRTcGVjJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc3QgZmFjZXRTcGVjOiBhbnkgPSB7XG4gICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9tb3ZpZXMuanNvblwifSxcbiAgICAgIFwiZmFjZXRcIjoge1wicm93XCI6IHtcImZpZWxkXCI6IFwiTVBBQV9SYXRpbmdcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9fSxcbiAgICAgIFwic3BlY1wiOiB7XG4gICAgICAgIFwibWFya1wiOiBcInBvaW50XCIsXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcIldvcmxkd2lkZV9Hcm9zc1wiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJVU19EVkRfU2FsZXNcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzPEZpZWxkRGVmPEZpZWxkPj4oZmllbGREZWZzKGZhY2V0U3BlYyksIFtcbiAgICAgIHtcImZpZWxkXCI6IFwiTVBBQV9SYXRpbmdcIixcInR5cGVcIjogXCJvcmRpbmFsXCJ9LFxuICAgICAge1wiZmllbGRcIjogXCJXb3JsZHdpZGVfR3Jvc3NcIixcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICB7XCJmaWVsZFwiOiBcIlVTX0RWRF9TYWxlc1wiLFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgIF0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/stack.test.js b/build/test/stack.test.js new file mode 100644 index 0000000000..b4b3025936 --- /dev/null +++ b/build/test/stack.test.js @@ -0,0 +1,466 @@ +"use strict"; +/* tslint:disable:quotemark */ +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../src/log"); +var channel_1 = require("../src/channel"); +var mark_1 = require("../src/mark"); +var scale_1 = require("../src/scale"); +var spec_1 = require("../src/spec"); +var stack_1 = require("../src/stack"); +describe('stack', function () { + var NON_STACKABLE_MARKS = [mark_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.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 () { + stack_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(stackProps.fieldChannel, 'x'); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should prioritize axis with stack', function () { + stack_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(stackProps.fieldChannel, 'x'); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should always be disabled if there is no stackby channel', function () { + var _loop_2 = function (stacked) { + mark_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.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) { + mark_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.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) { + mark_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.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_1.STACK_BY_DEFAULT_MARKS : stack_1.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_1.stack(spec.mark, spec.encoding, spec.config.stack); + chai_1.assert.isOk(_stack); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + chai_1.assert.equal(_stack.stackBy[0].channel, channel_1.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_1.STACK_BY_DEFAULT_MARKS : stack_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.isOk(_stack); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + chai_1.assert.equal(_stack.stackBy[0].channel, channel_1.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) { + mark_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.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) { + mark_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.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', log.wrap(function (localLogger) { + var _loop_9 = function (stacked) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + var warns = localLogger.warns; + chai_1.assert.equal(warns[warns.length - 1], log.message.cannotStackRangedMark(channel_1.X), JSON.stringify({ stacked: stacked, mark: mark })); + }); + }; + 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', log.wrap(function (localLogger) { + var _loop_10 = function (stacked) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + var warns = localLogger.warns; + chai_1.assert.equal(warns[warns.length - 1], log.message.cannotStackRangedMark(channel_1.Y), JSON.stringify({ stacked: stacked, mark: mark })); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_10(stacked); + } + })); + it('should always be disabled if the aggregated axis has non-linear scale', log.wrap(function (localLogger) { + var _loop_11 = function (stacked) { + [scale_1.ScaleType.LOG, scale_1.ScaleType.POW, scale_1.ScaleType.SQRT].forEach(function (scaleType) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.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 + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + var warns = localLogger.warns; + chai_1.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 (stack_2) { + var _loop_13 = function (aggregate) { + var marks = stack_2 === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { + aggregate: aggregate, stack: stack_2, + "field": "a", "type": "quantitative" + }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + chai_1.assert.isTrue(spec_1.isStacked(spec)); + var warns = localLogger.warns; + chai_1.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 stack_2 = _a[_i]; + _loop_12(stack_2); + } + })); + describe('stack().groupbyChannel, .fieldChannel', function () { + it('should be correct for horizontal', function () { + [mark_1.BAR, mark_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.X); + chai_1.assert.equal(_stack.groupbyChannel, channel_1.Y); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be correct for horizontal (single)', function () { + [mark_1.BAR, mark_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.X); + chai_1.assert.equal(_stack.groupbyChannel, null); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be correct for vertical', function () { + [mark_1.BAR, mark_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.Y); + chai_1.assert.equal(_stack.groupbyChannel, channel_1.X); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be correct for vertical (single)', function () { + [mark_1.BAR, mark_1.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_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.Y); + chai_1.assert.equal(_stack.groupbyChannel, null); + chai_1.assert.isTrue(spec_1.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 () { + [mark_1.BAR, mark_1.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" } + } + }; + chai_1.assert.equal(stack_1.stack(spec.mark, spec.encoding, undefined).offset, 'zero'); + chai_1.assert.isTrue(spec_1.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) { + [mark_1.BAR, mark_1.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 + } + }; + chai_1.assert.equal(stack_1.stack(spec.mark, spec.encoding, spec.config.stack).offset, stacked); + chai_1.assert.equal(spec_1.isStacked(spec), true); + }); + }; + for (var _i = 0, _a = ['center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_14(stacked); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2sudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3Qvc3RhY2sudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsOEJBQThCOztBQUU5Qiw2QkFBNEI7QUFFNUIsZ0NBQWtDO0FBR2xDLDBDQUE0QztBQUM1QyxvQ0FBNkQ7QUFDN0Qsc0NBQXVDO0FBQ3ZDLG9DQUEwRDtBQUMxRCxzQ0FBeUY7QUFFekYsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFNLG1CQUFtQixHQUFHLENBQUMsV0FBSSxDQUFDLENBQUM7SUFFbkMsRUFBRSxDQUFDLGtGQUFrRixFQUFFO2dDQUMxRSxPQUFPO1lBQ2hCLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxVQUFDLGdCQUFnQjtnQkFDM0MsSUFBTSxJQUFJLEdBQXVCO29CQUMvQixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7b0JBQ25DLE1BQU0sRUFBRSxnQkFBZ0I7b0JBQ3hCLFVBQVUsRUFBRTt3QkFDVixHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQzt3QkFDbkUsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO3dCQUM1QyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7cUJBQzlDO29CQUNELFFBQVEsRUFBRTt3QkFDUixPQUFPLEVBQUUsT0FBTztxQkFDakI7aUJBQ0YsQ0FBQztnQkFDRixhQUFNLENBQUMsTUFBTSxDQUFDLGFBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxhQUFNLENBQUMsT0FBTyxDQUFDLGdCQUFTLENBQUMsSUFB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LEVBQUM7d0JBQ25DLE1BQU0sRUFBRSxhQUFhO3dCQUNyQixVQUFVLEVBQUU7NEJBQ1YsR0FBRyxFQUFFLEVBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7NEJBQ25FLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzs0QkFDNUMsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO3lCQUM5Qzt3QkFDRCxRQUFRLEVBQUU7NEJBQ1IsT0FBTyxFQUFFLE9BQU87eUJBQ2pCO3FCQUNGLENBQUM7b0JBQ0YsYUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFLLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUNqRixhQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3RDLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQWpCRCxHQUFHLENBQUMsQ0FBa0IsVUFBZ0QsRUFBaEQsS0FBQSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFrQixFQUFoRCxjQUFnRCxFQUFoRCxJQUFnRDtnQkFBakUsSUFBTSxPQUFPLFNBQUE7eUJBQVAsT0FBTzthQWlCakI7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTpxdW90ZW1hcmsgKi9cblxuaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuXG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnLi4vc3JjL2xvZyc7XG5cbmltcG9ydCB7QWdncmVnYXRlT3B9IGZyb20gJy4uL3NyYy9hZ2dyZWdhdGUnO1xuaW1wb3J0IHtERVRBSUwsIFgsIFl9IGZyb20gJy4uL3NyYy9jaGFubmVsJztcbmltcG9ydCB7QVJFQSwgQkFSLCBQUklNSVRJVkVfTUFSS1MsIFJFQ1R9IGZyb20gJy4uL3NyYy9tYXJrJztcbmltcG9ydCB7U2NhbGVUeXBlfSBmcm9tICcuLi9zcmMvc2NhbGUnO1xuaW1wb3J0IHtpc1N0YWNrZWQsIFRvcExldmVsLCBVbml0U3BlY30gZnJvbSAnLi4vc3JjL3NwZWMnO1xuaW1wb3J0IHtzdGFjaywgU1RBQ0tfQllfREVGQVVMVF9NQVJLUywgU1RBQ0tBQkxFX01BUktTLCBTdGFja09mZnNldH0gZnJvbSAnLi4vc3JjL3N0YWNrJztcblxuZGVzY3JpYmUoJ3N0YWNrJywgKCkgPT4ge1xuICBjb25zdCBOT05fU1RBQ0tBQkxFX01BUktTID0gW1JFQ1RdO1xuXG4gIGl0KCdzaG91bGQgYmUgZGlzYWJsZWQgZm9yIG5vbi1zdGFja2FibGUgbWFya3Mgd2l0aCBhdCBsZWFzdCBvZiBvZiB0aGUgc3RhY2sgY2hhbm5lbCcsICgpID0+IHtcbiAgICBmb3IgKGNvbnN0IHN0YWNrZWQgb2YgW3VuZGVmaW5lZCwgJ2NlbnRlcicsICd6ZXJvJywgJ25vcm1hbGl6ZScsIG51bGwsICdub25lJ10gYXMgU3RhY2tPZmZzZXRbXSkge1xuICAgICAgTk9OX1NUQUNLQUJMRV9NQVJLUy5mb3JFYWNoKChub25TdGFja2FibGVNYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICBcIm1hcmtcIjogbm9uU3RhY2thYmxlTWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInZhcmlldHlcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwic3RhY2tcIjogc3RhY2tlZFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXNzZXJ0LmlzTnVsbChzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHNwZWMuY29uZmlnLnN0YWNrKSk7XG4gICAgICAgIGFzc2VydC5pc0ZhbHNlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYmUgYWxsb3dlZCBmb3IgcmF3IHBsb3QnLCAoKSA9PiB7XG4gICAgU1RBQ0tBQkxFX01BUktTLmZvckVhY2goKG1hcmspID0+IHtcbiAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgIFwibWFya1wiOiBtYXJrLFxuICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJzdGFja1wiOiBcInplcm9cIn0sXG4gICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0YWNrUHJvcHMgPSBzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQuZXF1YWwoc3RhY2tQcm9wcy5maWVsZENoYW5uZWwsICd4Jyk7XG4gICAgICBhc3NlcnQuaXNUcnVlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgfSk7XG4gIH0pO1xuXG5cbiAgaXQoJ3Nob3VsZCBwcmlvcml0aXplIGF4aXMgd2l0aCBzdGFjaycsICgpID0+IHtcbiAgICBTVEFDS0FCTEVfTUFSS1MuZm9yRWFjaCgobWFyaykgPT4ge1xuICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWw8VW5pdFNwZWM+ID0ge1xuICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgXCJtYXJrXCI6IG1hcmssXG4gICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgIFwieFwiOiB7XCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcInN0YWNrXCI6IFwiemVyb1wifSxcbiAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJ2YXJpZXR5XCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic2l0ZVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBjb25zdCBzdGFja1Byb3BzID0gc3RhY2soc3BlYy5tYXJrLCBzcGVjLmVuY29kaW5nLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHN0YWNrUHJvcHMuZmllbGRDaGFubmVsLCAneCcpO1xuICAgICAgYXNzZXJ0LmlzVHJ1ZShpc1N0YWNrZWQoc3BlYykpO1xuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGFsd2F5cyBiZSBkaXNhYmxlZCBpZiB0aGVyZSBpcyBubyBzdGFja2J5IGNoYW5uZWwnLCAoKSA9PiB7XG4gICAgZm9yIChjb25zdCBzdGFja2VkIG9mIFt1bmRlZmluZWQsICdjZW50ZXInLCAnemVybycsICdub3JtYWxpemUnLCBudWxsLCAnbm9uZSddIGFzIFN0YWNrT2Zmc2V0W10pIHtcbiAgICAgIFBSSU1JVElWRV9NQVJLUy5mb3JFYWNoKChtYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICBcIm1hcmtcIjogbWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInZhcmlldHlcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgICAgXCJzdGFja1wiOiBzdGFja2VkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhc3NlcnQuaXNOdWxsKHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZywgc3BlYy5jb25maWcuc3RhY2spKTtcbiAgICAgICAgYXNzZXJ0LmlzRmFsc2UoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhbHdheXMgYmUgZGlzYWJsZWQgaWYgdGhlIHN0YWNrYnkgY2hhbm5lbCBpcyBhZ2dyZWdhdGVkJywgKCkgPT4ge1xuICAgIGZvciAoY29uc3Qgc3RhY2tlZCBvZiBbdW5kZWZpbmVkLCAnY2VudGVyJywgJ3plcm8nLCAnbm9ybWFsaXplJywgbnVsbCwgJ25vbmUnXSBhcyBTdGFja09mZnNldFtdKSB7XG4gICAgICBQUklNSVRJVkVfTUFSS1MuZm9yRWFjaCgobWFyaykgPT4ge1xuICAgICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4gPSB7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgICAgXCJtYXJrXCI6IG1hcmssXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJ2YXJpZXR5XCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgICAgICBcImNvbG9yXCI6IHtcImFnZ3JlZ2F0ZVwiOiBcImNvdW50XCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgICAgXCJzdGFja1wiOiBzdGFja2VkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhc3NlcnQuaXNOdWxsKHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZywgc3BlYy5jb25maWcuc3RhY2spKTtcbiAgICAgICAgYXNzZXJ0LmlzRmFsc2UoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhbHdheXMgYmUgZGlzYWJsZWQgaWYgdGhlIHN0YWNrYnkgY2hhbm5lbCBpcyBpZGVudGljYWwgdG8geScsICgpID0+IHtcbiAgICBmb3IgKGNvbnN0IHN0YWNrZWQgb2YgW3VuZGVmaW5lZCwgJ2NlbnRlcicsICd6ZXJvJywgJ25vcm1hbGl6ZScsIG51bGwsICdub25lJ10gYXMgU3RhY2tPZmZzZXRbXSkge1xuICAgICAgUFJJTUlUSVZFX01BUktTLmZvckVhY2goKG1hcmspID0+IHtcbiAgICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWw8VW5pdFNwZWM+ID0ge1xuICAgICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2JhcmxleS5qc29uXCJ9LFxuICAgICAgICAgIFwibWFya1wiOiBtYXJrLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwieWllbGRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInZhcmlldHlcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwic3RhY2tcIjogc3RhY2tlZFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXNzZXJ0LmlzTnVsbChzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHNwZWMuY29uZmlnLnN0YWNrKSk7XG4gICAgICAgIGFzc2VydC5pc0ZhbHNlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdjYW4gZW5hYmxlZCBpZiBvbmUgb2YgdGhlIHN0YWNrYnkgY2hhbm5lbHMgaXMgbm90IGFnZ3JlZ2F0ZWQnLCAoKSA9PiB7XG4gICAgZm9yIChjb25zdCBzdGFja2VkIG9mIFt1bmRlZmluZWQsICdjZW50ZXInLCAnemVybycsICdub3JtYWxpemUnXSBhcyBTdGFja09mZnNldFtdKSB7XG4gICAgICBjb25zdCBtYXJrcyA9IHN0YWNrZWQgPT09IHVuZGVmaW5lZCA/IFNUQUNLX0JZX0RFRkFVTFRfTUFSS1MgOiBTVEFDS0FCTEVfTUFSS1M7XG4gICAgICBtYXJrcy5mb3JFYWNoKChtYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICBcIm1hcmtcIjogbWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInZhcmlldHlcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1wiYWdncmVnYXRlXCI6IFwiY291bnRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgXCJkZXRhaWxcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwic3RhY2tcIjogc3RhY2tlZFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgX3N0YWNrID0gc3RhY2soc3BlYy5tYXJrLCBzcGVjLmVuY29kaW5nLCBzcGVjLmNvbmZpZy5zdGFjayk7XG4gICAgICAgIGFzc2VydC5pc09rKF9zdGFjayk7XG4gICAgICAgIGFzc2VydC5pc1RydWUoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKF9zdGFjay5zdGFja0J5WzBdLmNoYW5uZWwsIERFVEFJTCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdjYW4gZW5hYmxlZCBpZiBvbmUgb2YgdGhlIHN0YWNrYnkgY2hhbm5lbHMgaXMgbm90IGFnZ3JlZ2F0ZWQnLCAoKSA9PiB7XG4gICAgZm9yIChjb25zdCBzdGFja2VkIG9mIFt1bmRlZmluZWQsICdjZW50ZXInLCAnemVybycsICdub3JtYWxpemUnXSBhcyBTdGFja09mZnNldFtdKSB7XG4gICAgICBjb25zdCBtYXJrcyA9IHN0YWNrZWQgPT09IHVuZGVmaW5lZCA/IFNUQUNLX0JZX0RFRkFVTFRfTUFSS1MgOiBTVEFDS0FCTEVfTUFSS1M7XG4gICAgICBtYXJrcy5mb3JFYWNoKChtYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICBcIm1hcmtcIjogbWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcInN0YWNrXCI6IHN0YWNrZWR9LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJhZ2dyZWdhdGVcIjogXCJjb3VudFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICBcImRldGFpbFwiOiB7XCJmaWVsZFwiOiBcInNpdGVcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBfc3RhY2sgPSBzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHVuZGVmaW5lZCk7XG4gICAgICAgIGFzc2VydC5pc09rKF9zdGFjayk7XG4gICAgICAgIGFzc2VydC5pc1RydWUoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKF9zdGFjay5zdGFja0J5WzBdLmNoYW5uZWwsIERFVEFJTCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYWx3YXlzIGJlIGRpc2FibGVkIGlmIGJvdGggeCBhbmQgeSBhcmUgYWdncmVnYXRlJywgKCkgPT4ge1xuICAgIGZvciAoY29uc3Qgc3RhY2tlZCBvZiBbdW5kZWZpbmVkLCAnY2VudGVyJywgJ3plcm8nLCAnbm9ybWFsaXplJywgbnVsbCwgJ25vbmUnXSBhcyBTdGFja09mZnNldFtdKSB7XG4gICAgICBQUklNSVRJVkVfTUFSS1MuZm9yRWFjaCgobWFyaykgPT4ge1xuICAgICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4gPSB7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgICAgXCJtYXJrXCI6IG1hcmssXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICBcInlcIjoge1wiYWdncmVnYXRlXCI6IFwiY291bnRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInNpdGVcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgICAgXCJzdGFja1wiOiBzdGFja2VkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhc3NlcnQuaXNOdWxsKHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZywgc3BlYy5jb25maWcuc3RhY2spKTtcbiAgICAgICAgYXNzZXJ0LmlzRmFsc2UoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhbHdheXMgYmUgZGlzYWJsZWQgaWYgbmVpdGhlciB4IG5vciB5IGlzIGFnZ3JlZ2F0ZSBvciBzdGFjaycsICgpID0+IHtcbiAgICBmb3IgKGNvbnN0IHN0YWNrZWQgb2YgW3VuZGVmaW5lZCwgJ2NlbnRlcicsICd6ZXJvJywgJ25vcm1hbGl6ZScsIG51bGwsICdub25lJ10gYXMgU3RhY2tPZmZzZXRbXSkge1xuICAgICAgUFJJTUlUSVZFX01BUktTLmZvckVhY2goKG1hcmspID0+IHtcbiAgICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWw8VW5pdFNwZWM+ID0ge1xuICAgICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2JhcmxleS5qc29uXCJ9LFxuICAgICAgICAgIFwibWFya1wiOiBtYXJrLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInNpdGVcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgICAgXCJzdGFja1wiOiBzdGFja2VkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhc3NlcnQuaXNOdWxsKHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZywgc3BlYy5jb25maWcuc3RhY2spKTtcbiAgICAgICAgYXNzZXJ0LmlzRmFsc2UoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhbHdheXMgYmUgZGlzYWJsZWQgaWYgdGhlcmUgaXMgYm90aCB4IGFuZCB4MicsIGxvZy53cmFwKChsb2NhbExvZ2dlcikgPT4ge1xuICAgIGZvciAoY29uc3Qgc3RhY2tlZCBvZiBbdW5kZWZpbmVkLCAnY2VudGVyJywgJ3plcm8nLCAnbm9ybWFsaXplJ10gYXMgU3RhY2tPZmZzZXRbXSkge1xuICAgICAgY29uc3QgbWFya3MgPSBzdGFja2VkID09PSB1bmRlZmluZWQgPyBTVEFDS19CWV9ERUZBVUxUX01BUktTIDogU1RBQ0tBQkxFX01BUktTO1xuICAgICAgbWFya3MuZm9yRWFjaCgobWFyaykgPT4ge1xuICAgICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4gPSB7XG4gICAgICAgICAgXCJtYXJrXCI6IG1hcmssXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcInN1bVwifSxcbiAgICAgICAgICAgIFwieDJcIjoge1wiZmllbGRcIjogXCJhXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwiLCBcImFnZ3JlZ2F0ZVwiOiBcInN1bVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInZhcmlldHlcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwic3RhY2tcIjogc3RhY2tlZFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXNzZXJ0LmlzTnVsbChzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHNwZWMuY29uZmlnLnN0YWNrKSk7XG4gICAgICAgIGFzc2VydC5pc0ZhbHNlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgICAgIGNvbnN0IHdhcm5zID0gbG9jYWxMb2dnZXIud2FybnM7XG4gICAgICAgIGFzc2VydC5lcXVhbCh3YXJuc1t3YXJucy5sZW5ndGgtMV0sIGxvZy5tZXNzYWdlLmNhbm5vdFN0YWNrUmFuZ2VkTWFyayhYKSxcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7c3RhY2tlZDogc3RhY2tlZCwgbWFyazogbWFya30pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pKTtcblxuICBpdCgnc2hvdWxkIGFsd2F5cyBiZSBkaXNhYmxlZCBpZiB0aGVyZSBpcyBib3RoIHkgYW5kIHkyJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgZm9yIChjb25zdCBzdGFja2VkIG9mIFt1bmRlZmluZWQsICdjZW50ZXInLCAnemVybycsICdub3JtYWxpemUnXSBhcyBTdGFja09mZnNldFtdKSB7XG4gICAgICBjb25zdCBtYXJrcyA9IHN0YWNrZWQgPT09IHVuZGVmaW5lZCA/IFNUQUNLX0JZX0RFRkFVTFRfTUFSS1MgOiBTVEFDS0FCTEVfTUFSS1M7XG4gICAgICBtYXJrcy5mb3JFYWNoKChtYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcIm1hcmtcIjogbWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYWdncmVnYXRlXCI6IFwic3VtXCJ9LFxuICAgICAgICAgICAgXCJ5MlwiOiB7XCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCIsIFwiYWdncmVnYXRlXCI6IFwic3VtXCJ9LFxuICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInNpdGVcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgICAgXCJzdGFja1wiOiBzdGFja2VkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhc3NlcnQuaXNOdWxsKHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZywgc3BlYy5jb25maWcuc3RhY2spKTtcbiAgICAgICAgYXNzZXJ0LmlzRmFsc2UoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgICAgY29uc3Qgd2FybnMgPSBsb2NhbExvZ2dlci53YXJucztcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHdhcm5zW3dhcm5zLmxlbmd0aC0xXSwgbG9nLm1lc3NhZ2UuY2Fubm90U3RhY2tSYW5nZWRNYXJrKFkpLFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtzdGFja2VkOiBzdGFja2VkLCBtYXJrOiBtYXJrfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSkpO1xuXG4gIGl0KCdzaG91bGQgYWx3YXlzIGJlIGRpc2FibGVkIGlmIHRoZSBhZ2dyZWdhdGVkIGF4aXMgaGFzIG5vbi1saW5lYXIgc2NhbGUnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICBmb3IgKGNvbnN0IHN0YWNrZWQgb2YgW3VuZGVmaW5lZCwgJ2NlbnRlcicsICd6ZXJvJywgJ25vcm1hbGl6ZSddIGFzIFN0YWNrT2Zmc2V0W10pIHtcbiAgICAgIFtTY2FsZVR5cGUuTE9HLCBTY2FsZVR5cGUuUE9XLCBTY2FsZVR5cGUuU1FSVF0uZm9yRWFjaCgoc2NhbGVUeXBlKSA9PiB7XG4gICAgICAgIGNvbnN0IG1hcmtzID0gc3RhY2tlZCA9PT0gdW5kZWZpbmVkID8gU1RBQ0tfQllfREVGQVVMVF9NQVJLUyA6IFNUQUNLQUJMRV9NQVJLUztcbiAgICAgICAgbWFya3MuZm9yRWFjaCgobWFyaykgPT4ge1xuICAgICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2JhcmxleS5qc29uXCJ9LFxuICAgICAgICAgICAgXCJtYXJrXCI6IG1hcmssXG4gICAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwiYVwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIiwgXCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJzY2FsZVwiOiB7XCJ0eXBlXCI6IHNjYWxlVHlwZX19LFxuICAgICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJ2YXJpZXR5XCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBcImNvbmZpZ1wiOiB7XG4gICAgICAgICAgICAgIFwic3RhY2tcIjogc3RhY2tlZFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgICAgYXNzZXJ0LmlzTnVsbChzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHNwZWMuY29uZmlnLnN0YWNrKSk7XG4gICAgICAgICAgYXNzZXJ0LmlzRmFsc2UoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgICAgICBjb25zdCB3YXJucyA9IGxvY2FsTG9nZ2VyLndhcm5zO1xuICAgICAgICAgIGFzc2VydC5lcXVhbCh3YXJuc1t3YXJucy5sZW5ndGgtMV0sIGxvZy5tZXNzYWdlLmNhbm5vdFN0YWNrTm9uTGluZWFyU2NhbGUoc2NhbGVUeXBlKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9KSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvd3Mgd2FybmluZyBpZiB0aGUgYWdncmVnYXRlZCBheGlzIGhhcyBhIG5vbi1zdW1tYXRpdmUgYWdncmVnYXRlJywgbG9nLndyYXAoKGxvY2FsTG9nZ2VyKSA9PiB7XG4gICAgZm9yIChjb25zdCBzdGFjayBvZiBbdW5kZWZpbmVkLCAnY2VudGVyJywgJ3plcm8nLCAnbm9ybWFsaXplJ10gYXMgU3RhY2tPZmZzZXRbXSkge1xuICAgICAgZm9yIChjb25zdCBhZ2dyZWdhdGUgb2YgWydhdmVyYWdlJywgJ3ZhcmlhbmNlJywgJ3EzJ10gYXMgQWdncmVnYXRlT3BbXSkge1xuICAgICAgICBjb25zdCBtYXJrcyA9IHN0YWNrID09PSB1bmRlZmluZWQgPyBTVEFDS19CWV9ERUZBVUxUX01BUktTIDogU1RBQ0tBQkxFX01BUktTO1xuICAgICAgICBtYXJrcy5mb3JFYWNoKChtYXJrKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWw8VW5pdFNwZWM+ID0ge1xuICAgICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgICAgICBcIm1hcmtcIjogbWFyayxcbiAgICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgICBcInhcIjoge1xuICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZSwgc3RhY2ssXG4gICAgICAgICAgICAgICAgXCJmaWVsZFwiOiBcImFcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic2l0ZVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgICBhc3NlcnQuaXNUcnVlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgICAgICAgY29uc3Qgd2FybnMgPSBsb2NhbExvZ2dlci53YXJucztcbiAgICAgICAgICBhc3NlcnQuZXF1YWwod2FybnNbd2FybnMubGVuZ3RoLTFdLCBsb2cubWVzc2FnZS5zdGFja05vblN1bW1hdGl2ZUFnZ3JlZ2F0ZShhZ2dyZWdhdGUpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9KSk7XG5cbiAgZGVzY3JpYmUoJ3N0YWNrKCkuZ3JvdXBieUNoYW5uZWwsIC5maWVsZENoYW5uZWwnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSBjb3JyZWN0IGZvciBob3Jpem9udGFsJywgKCkgPT4ge1xuICAgICAgW0JBUiwgQVJFQV0uZm9yRWFjaCgoc3RhY2thYmxlTWFyaykgPT4ge1xuICAgICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4gPSB7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgICAgXCJtYXJrXCI6IHN0YWNrYWJsZU1hcmssXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICBcInlcIjoge1wiZmllbGRcIjogXCJ2YXJpZXR5XCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn0sXG4gICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic2l0ZVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBfc3RhY2sgPSBzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHVuZGVmaW5lZCk7XG4gICAgICAgIGFzc2VydC5lcXVhbChfc3RhY2suZmllbGRDaGFubmVsLCBYKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKF9zdGFjay5ncm91cGJ5Q2hhbm5lbCwgWSk7XG4gICAgICAgIGFzc2VydC5pc1RydWUoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBjb3JyZWN0IGZvciBob3Jpem9udGFsIChzaW5nbGUpJywgKCkgPT4ge1xuICAgICAgW0JBUiwgQVJFQV0uZm9yRWFjaCgoc3RhY2thYmxlTWFyaykgPT4ge1xuICAgICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4gPSB7XG4gICAgICAgICAgXCJkYXRhXCI6IHtcInVybFwiOiBcImRhdGEvYmFybGV5Lmpzb25cIn0sXG4gICAgICAgICAgXCJtYXJrXCI6IHN0YWNrYWJsZU1hcmssXG4gICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICBcInhcIjoge1wiYWdncmVnYXRlXCI6IFwic3VtXCIsIFwiZmllbGRcIjogXCJ5aWVsZFwiLCBcInR5cGVcIjogXCJxdWFudGl0YXRpdmVcIn0sXG4gICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic2l0ZVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBfc3RhY2sgPSBzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHVuZGVmaW5lZCk7XG4gICAgICAgIGFzc2VydC5lcXVhbChfc3RhY2suZmllbGRDaGFubmVsLCBYKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKF9zdGFjay5ncm91cGJ5Q2hhbm5lbCwgbnVsbCk7XG4gICAgICAgIGFzc2VydC5pc1RydWUoaXNTdGFja2VkKHNwZWMpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBjb3JyZWN0IGZvciB2ZXJ0aWNhbCcsICgpID0+IHtcbiAgICAgIFtCQVIsIEFSRUFdLmZvckVhY2goKHN0YWNrYWJsZU1hcmspID0+IHtcbiAgICAgICAgY29uc3Qgc3BlYzogVG9wTGV2ZWw8VW5pdFNwZWM+ID0ge1xuICAgICAgICAgIFwiZGF0YVwiOiB7XCJ1cmxcIjogXCJkYXRhL2JhcmxleS5qc29uXCJ9LFxuICAgICAgICAgIFwibWFya1wiOiBzdGFja2FibGVNYXJrLFxuICAgICAgICAgIFwiZW5jb2RpbmdcIjoge1xuICAgICAgICAgICAgXCJ5XCI6IHtcImFnZ3JlZ2F0ZVwiOiBcInN1bVwiLCBcImZpZWxkXCI6IFwieWllbGRcIiwgXCJ0eXBlXCI6IFwicXVhbnRpdGF0aXZlXCJ9LFxuICAgICAgICAgICAgXCJ4XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgXCJjb2xvclwiOiB7XCJmaWVsZFwiOiBcInNpdGVcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgX3N0YWNrID0gc3RhY2soc3BlYy5tYXJrLCBzcGVjLmVuY29kaW5nLCB1bmRlZmluZWQpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoX3N0YWNrLmZpZWxkQ2hhbm5lbCwgWSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChfc3RhY2suZ3JvdXBieUNoYW5uZWwsIFgpO1xuICAgICAgICBhc3NlcnQuaXNUcnVlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgY29ycmVjdCBmb3IgdmVydGljYWwgKHNpbmdsZSknLCAoKSA9PiB7XG4gICAgICBbQkFSLCBBUkVBXS5mb3JFYWNoKChzdGFja2FibGVNYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICBcIm1hcmtcIjogc3RhY2thYmxlTWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieVwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IF9zdGFjayA9IHN0YWNrKHNwZWMubWFyaywgc3BlYy5lbmNvZGluZywgdW5kZWZpbmVkKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKF9zdGFjay5maWVsZENoYW5uZWwsIFkpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoX3N0YWNrLmdyb3VwYnlDaGFubmVsLCBudWxsKTtcbiAgICAgICAgYXNzZXJ0LmlzVHJ1ZShpc1N0YWNrZWQoc3BlYykpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzdGFjaygpLm9mZnNldCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJlIHplcm8gZm9yIHN0YWNrYWJsZSBtYXJrcyB3aXRoIGF0IGxlYXN0IG9mIG9mIHRoZSBzdGFjayBjaGFubmVsIGlmIHN0YWNrZWQgaXMgdW5zcGVjaWZpZWQnLCAoKSA9PiB7XG4gICAgICBbQkFSLCBBUkVBXS5mb3JFYWNoKChzdGFja2FibGVNYXJrKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPiA9IHtcbiAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICBcIm1hcmtcIjogc3RhY2thYmxlTWFyayxcbiAgICAgICAgICBcImVuY29kaW5nXCI6IHtcbiAgICAgICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgIFwieVwiOiB7XCJmaWVsZFwiOiBcInZhcmlldHlcIiwgXCJ0eXBlXCI6IFwibm9taW5hbFwifSxcbiAgICAgICAgICAgIFwiY29sb3JcIjoge1wiZmllbGRcIjogXCJzaXRlXCIsIFwidHlwZVwiOiBcIm5vbWluYWxcIn1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGFzc2VydC5lcXVhbChzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHVuZGVmaW5lZCkub2Zmc2V0LCAnemVybycpO1xuICAgICAgICBhc3NlcnQuaXNUcnVlKGlzU3RhY2tlZChzcGVjKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgdGhlIHNwZWNpZmllZCBzdGFja2VkIGZvciBzdGFja2FibGUgbWFya3Mgd2l0aCBhdCBsZWFzdCBvbmUgb2YgdGhlIHN0YWNrIGNoYW5uZWwnLCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHN0YWNrZWQgb2YgWydjZW50ZXInLCAnemVybycsICdub3JtYWxpemUnXSBhcyBTdGFja09mZnNldFtdKSB7XG4gICAgICAgIFtCQVIsIEFSRUFdLmZvckVhY2goKHN0YWNrYWJsZU1hcmspID0+IHtcbiAgICAgICAgICBjb25zdCBzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4gPSB7XG4gICAgICAgICAgICBcImRhdGFcIjoge1widXJsXCI6IFwiZGF0YS9iYXJsZXkuanNvblwifSxcbiAgICAgICAgICAgIFwibWFya1wiOiBzdGFja2FibGVNYXJrLFxuICAgICAgICAgICAgXCJlbmNvZGluZ1wiOiB7XG4gICAgICAgICAgICAgIFwieFwiOiB7XCJhZ2dyZWdhdGVcIjogXCJzdW1cIiwgXCJmaWVsZFwiOiBcInlpZWxkXCIsIFwidHlwZVwiOiBcInF1YW50aXRhdGl2ZVwifSxcbiAgICAgICAgICAgICAgXCJ5XCI6IHtcImZpZWxkXCI6IFwidmFyaWV0eVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9LFxuICAgICAgICAgICAgICBcImNvbG9yXCI6IHtcImZpZWxkXCI6IFwic2l0ZVwiLCBcInR5cGVcIjogXCJub21pbmFsXCJ9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJjb25maWdcIjoge1xuICAgICAgICAgICAgICBcInN0YWNrXCI6IHN0YWNrZWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICAgIGFzc2VydC5lcXVhbChzdGFjayhzcGVjLm1hcmssIHNwZWMuZW5jb2RpbmcsIHNwZWMuY29uZmlnLnN0YWNrKS5vZmZzZXQsIHN0YWNrZWQpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbChpc1N0YWNrZWQoc3BlYyksIHRydWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/timeunit.test.js b/build/test/timeunit.test.js new file mode 100644 index 0000000000..3a324bec83 --- /dev/null +++ b/build/test/timeunit.test.js @@ -0,0 +1,153 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var timeunit_1 = require("../src/timeunit"); +describe('timeUnit', function () { + describe('containsTimeUnit', function () { + it('should return true for quarter given quarter', function () { + var fullTimeUnit = timeunit_1.TimeUnit.QUARTER; + var timeUnit = timeunit_1.TimeUnit.QUARTER; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for yearquarter given quarter', function () { + var fullTimeUnit = timeunit_1.TimeUnit.YEARQUARTER; + var timeUnit = timeunit_1.TimeUnit.QUARTER; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for SECONDS and MILLISECONDS given SECONDSMILLISECONDS', function () { + var fullTimeUnit = timeunit_1.TimeUnit.SECONDSMILLISECONDS; + var timeUnit = timeunit_1.TimeUnit.SECONDS; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for MILLISECONDS given SECONDSMILLISECONDS', function () { + var fullTimeUnit = timeunit_1.TimeUnit.SECONDSMILLISECONDS; + var timeUnit = timeunit_1.TimeUnit.MILLISECONDS; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return false for quarter given year', function () { + var fullTimeUnit = timeunit_1.TimeUnit.YEAR; + var timeUnit = timeunit_1.TimeUnit.QUARTER; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), false); + }); + it('should return false for SECONDS given MILLISECONDS', function () { + var fullTimeUnit = timeunit_1.TimeUnit.MILLISECONDS; + var timeUnit = timeunit_1.TimeUnit.SECONDS; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), false); + }); + }); + describe('fieldExpr', function () { + it('should return correct field expression for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.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 () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.QUARTER, 'x'), 'datetime(0, (quarter(datum["x"])-1)*3, 1, 0, 0, 0, 0)'); + }); + it('should return correct field expression for DAY', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.DAY, 'x'), 'datetime(2006, 0, day(datum["x"])+1, 0, 0, 0, 0)'); + }); + it('should return correct field expression for MILLISECONDS', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.MILLISECONDS, 'x'), 'datetime(0, 0, 1, 0, 0, 0, milliseconds(datum["x"]))'); + }); + it('should return correct field expression with utc for MILLISECONDS', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.UTCQUARTER, 'x'), 'datetime(0, (utcquarter(datum["x"])-1)*3, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.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 () { + chai_1.assert.throws(function () { + timeunit_1.convert(timeunit_1.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 = timeunit_1.convert(timeunit_1.TimeUnit.YEARQUARTER, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 9, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for UTCYEARQUARTER', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.UTCYEARQUARTER, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999))); + chai_1.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 = timeunit_1.convert(timeunit_1.TimeUnit.YEARQUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTH', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for UTCYEARMONTH', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.UTCYEARMONTH, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999))); + chai_1.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 = timeunit_1.convert(timeunit_1.TimeUnit.UTCYEAR, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999))); + chai_1.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 = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATE, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATEHOURS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURSMINUTES', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 59, 0).getTime()); + }); + it('should return expected result for QUARTERMONTH', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.QUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for HOURSMINUTES', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.HOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 0, 0).getTime()); + }); + it('should return expected result for HOURSMINUTESSECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.HOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 59, 0).getTime()); + }); + it('should return expected result for MINUTESSECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.MINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 59, 59, 0).getTime()); + }); + it('should return expected result for SECONDSMILLISECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.SECONDSMILLISECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.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 () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.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 () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.YEARMONTH, 'datum.x', undefined, false), "timeFormat(datum.x, '%b %Y')"); + }); + it('should return correct template for DAY', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.DAY, 'datum.x', undefined, false), "timeFormat(datum.x, '%A')"); + }); + it('should return correct template for DAY (shortened)', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.DAY, 'datum.x', true, false), "timeFormat(datum.x, '%a')"); + }); + it('should return correct template for QUARTER', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.QUARTER, 'datum.x', undefined, false), "'Q' + quarter(datum.x)"); + }); + it('should return correct template for YEARQUARTER', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.YEARQUARTER, 'datum.x', undefined, false), "'Q' + quarter(datum.x) + ' ' + timeFormat(datum.x, '%Y')"); + }); + it('should return correct template for milliseconds', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.MILLISECONDS, 'datum.x', undefined, false), "timeFormat(datum.x, '%L')"); + }); + it('should return correct template for no timeUnit', function () { + chai_1.assert.equal(timeunit_1.formatExpression(undefined, 'datum.x', undefined, false), undefined); + }); + it('should return correct template for YEARMONTH (No comma) with utc scale', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.YEARMONTH, 'datum.x', undefined, true), "utcFormat(datum.x, '%b %Y')"); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdGltZXVuaXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1Qiw0Q0FBaUc7QUFHakcsUUFBUSxDQUFDLFVBQVUsRUFBRTtJQUNuQixRQUFRLENBQUMsa0JBQWtCLEVBQUU7UUFDM0IsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELElBQU0sWUFBWSxHQUFHLG1CQUFRLENBQUMsT0FBTyxDQUFDO1lBQ3RDLElBQU0sUUFBUSxHQUFHLG1CQUFRLENBQUMsT0FBTyxDQUFDO1lBQ2xDLGFBQU0sQ0FBQyxLQUFLLENBQUMsMkJBQWdCLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFO1lBQ3JELElBQU0sWUFBWSxHQUFHLG1CQUFRLENBQUMsV0FBVyxDQUFDO1lBQzFDLElBQU0sUUFBUSxHQUFHLG1CQUFRLENBQUMsT0FBTyxDQUFDO1lBQ2xDLGFBQU0sQ0FBQyxLQUFLLENBQUMsMkJBQWdCLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJFQUEyRSxFQUFFO1lBQzlFLElBQU0sWUFBWSxHQUFHLG1CQUFRLENBQUMsbUJBQW1CLENBQUM7WUFDbEQsSUFBTSxRQUFRLEdBQUcsbUJBQVEsQ0FBQyxPQUFPLENBQUM7WUFDbEMsYUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDL0QsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0RBQStELEVBQUU7WUFDbEUsSUFBTSxZQUFZLEdBQUcsbUJBQVEsQ0FBQyxtQkFBbUIs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QUM7UUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsSUFBTSxJQUFJLEdBQVMsa0JBQU8sQ0FBQyxtQkFBUSxDQUFDLFlBQVksRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzFGLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsSUFBTSxJQUFJLEdBQVMsa0JBQU8sQ0FBQyxtQkFBUSxDQUFDLFlBQVksRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzFGLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDN0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsSUFBTSxJQUFJLEdBQVMsa0JBQU8sQ0FBQyxtQkFBUSxDQUFDLG1CQUFtQixFQUFFLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcs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QUFDLEtBQUssQ0FDViwyQkFBZ0IsQ0FBQyxtQkFBUSxDQUFDLFdBQVcsRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUNsRSwwREFBMEQsQ0FDM0QsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlEQUFpRCxFQUFFO1lBQ3BELGFBQU0sQ0FBQyxLQUFLLENBQ1YsMkJBQWdCLENBQUMsbUJBQVEsQ0FBQyxZQUFZLEVBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDbkUsMkJBQTJCLENBQzVCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnREFBZ0QsRUFBRTtZQUNuRCxhQUFNLENBQUMsS0FBSyxDQUNWLDJCQUFnQixDQUFDLFNBQVMsRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUN2RCxTQUFTLENBQ1YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdFQUF3RSxFQUFFO1lBQzNFLGFBQU0sQ0FBQyxLQUFLLENBQ1YsMkJBQWdCLENBQUMsbUJBQVEsQ0FBQyxTQUFTLEVBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFDL0QsNkJBQTZCLENBQzlCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Fzc2VydH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2NvbnRhaW5zVGltZVVuaXQsIGNvbnZlcnQsIGZpZWxkRXhwciwgZm9ybWF0RXhwcmVzc2lvbiwgVGltZVVuaXR9IGZyb20gJy4uL3NyYy90aW1ldW5pdCc7XG5cblxuZGVzY3JpYmUoJ3RpbWVVbml0JywgKCkgPT4ge1xuICBkZXNjcmliZSgnY29udGFpbnNUaW1lVW5pdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBxdWFydGVyIGdpdmVuIHF1YXJ0ZXInLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGZ1bGxUaW1lVW5pdCA9IFRpbWVVbml0LlFVQVJURVI7XG4gICAgICBjb25zdCB0aW1lVW5pdCA9IFRpbWVVbml0LlFVQVJURVI7XG4gICAgICBhc3NlcnQuZXF1YWwoY29udGFpbnNUaW1lVW5pdChmdWxsVGltZVVuaXQsIHRpbWVVbml0KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB5ZWFycXVhcnRlciBnaXZlbiBxdWFydGVyJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBmdWxsVGltZVVuaXQgPSBUaW1lVW5pdC5ZRUFSUVVBUlRFUjtcbiAgICAgIGNvbnN0IHRpbWVVbml0ID0gVGltZVVuaXQuUVVBUlRFUjtcbiAgICAgIGFzc2VydC5lcXVhbChjb250YWluc1RpbWVVbml0KGZ1bGxUaW1lVW5pdCwgdGltZVVuaXQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIFNFQ09ORFMgYW5kIE1JTExJU0VDT05EUyBnaXZlbiBTRUNPTkRTTUlMTElTRUNPTkRTJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBmdWxsVGltZVVuaXQgPSBUaW1lVW5pdC5TRUNPTkRTTUlMTElTRUNPTkRTO1xuICAgICAgY29uc3QgdGltZVVuaXQgPSBUaW1lVW5pdC5TRUNPTkRTO1xuICAgICAgYXNzZXJ0LmVxdWFsKGNvbnRhaW5zVGltZVVuaXQoZnVsbFRpbWVVbml0LCB0aW1lVW5pdCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgTUlMTElTRUNPTkRTIGdpdmVuIFNFQ09ORFNNSUxMSVNFQ09ORFMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGZ1bGxUaW1lVW5pdCA9IFRpbWVVbml0LlNFQ09ORFNNSUxMSVNFQ09ORFM7XG4gICAgICBjb25zdCB0aW1lVW5pdCA9IFRpbWVVbml0Lk1JTExJU0VDT05EUztcbiAgICAgIGFzc2VydC5lcXVhbChjb250YWluc1RpbWVVbml0KGZ1bGxUaW1lVW5pdCwgdGltZVVuaXQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBxdWFydGVyIGdpdmVuIHllYXInLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGZ1bGxUaW1lVW5pdCA9IFRpbWVVbml0LllFQVI7XG4gICAgICBjb25zdCB0aW1lVW5pdCA9IFRpbWVVbml0LlFVQVJURVI7XG4gICAgICBhc3NlcnQuZXF1YWwoY29udGFpbnNUaW1lVW5pdChmdWxsVGltZVVuaXQsIHRpbWVVbml0KSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIFNFQ09ORFMgZ2l2ZW4gTUlMTElTRUNPTkRTJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBmdWxsVGltZVVuaXQgPSBUaW1lVW5pdC5NSUxMSVNFQ09ORFM7XG4gICAgICBjb25zdCB0aW1lVW5pdCA9IFRpbWVVbml0LlNFQ09ORFM7XG4gICAgICBhc3NlcnQuZXF1YWwoY29udGFpbnNUaW1lVW5pdChmdWxsVGltZVVuaXQsIHRpbWVVbml0KSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZmllbGRFeHByJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgZmllbGQgZXhwcmVzc2lvbiBmb3IgWUVBUk1PTlRIREFURUhPVVJTTUlOVVRFU1NFQ09ORFMnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGZpZWxkRXhwcihUaW1lVW5pdC5ZRUFSTU9OVEhEQVRFSE9VUlNNSU5VVEVTU0VDT05EUywgJ3gnKSxcbiAgICAgICAgJ2RhdGV0aW1lKHllYXIoZGF0dW1bXCJ4XCJdKSwgbW9udGgoZGF0dW1bXCJ4XCJdKSwgZGF0ZShkYXR1bVtcInhcIl0pLCBob3VycyhkYXR1bVtcInhcIl0pLCBtaW51dGVzKGRhdHVtW1wieFwiXSksIHNlY29uZHMoZGF0dW1bXCJ4XCJdKSwgMCknXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBmaWVsZCBleHByZXNzaW9uIGZvciBRVUFSVEVSJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBmaWVsZEV4cHIoVGltZVVuaXQuUVVBUlRFUiwgJ3gnKSxcbiAgICAgICAgJ2RhdGV0aW1lKDAsIChxdWFydGVyKGRhdHVtW1wieFwiXSktMSkqMywgMSwgMCwgMCwgMCwgMCknXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBmaWVsZCBleHByZXNzaW9uIGZvciBEQVknLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGZpZWxkRXhwcihUaW1lVW5pdC5EQVksICd4JyksXG4gICAgICAgICdkYXRldGltZSgyMDA2LCAwLCBkYXkoZGF0dW1bXCJ4XCJdKSsxLCAwLCAwLCAwLCAwKSdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IGZpZWxkIGV4cHJlc3Npb24gZm9yIE1JTExJU0VDT05EUycsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgZmllbGRFeHByKFRpbWVVbml0Lk1JTExJU0VDT05EUywgJ3gnKSxcbiAgICAgICAgJ2RhdGV0aW1lKDAsIDAsIDEsIDAsIDAsIDAsIG1pbGxpc2Vjb25kcyhkYXR1bVtcInhcIl0pKSdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IGZpZWxkIGV4cHJlc3Npb24gd2l0aCB1dGMgZm9yIE1JTExJU0VDT05EUycsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgZmllbGRFeHByKFRpbWVVbml0LlVUQ1FVQVJURVIsICd4JyksXG4gICAgICAgICdkYXRldGltZSgwLCAodXRjcXVhcnRlcihkYXR1bVtcInhcIl0pLTEpKjMsIDEsIDAsIDAsIDAsIDApJ1xuICAgICAgKTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBmaWVsZEV4cHIoVGltZVVuaXQuVVRDTUlMTElTRUNPTkRTLCAneCcpLFxuICAgICAgICAnZGF0ZXRpbWUoMCwgMCwgMSwgMCwgMCwgMCwgdXRjbWlsbGlzZWNvbmRzKGRhdHVtW1wieFwiXSkpJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NvbnZlcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgdGhlIERBWSB0aW1ldW5pdCcsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhmdW5jdGlvbigpIHtcbiAgICAgICAgY29udmVydChUaW1lVW5pdC5EQVksIG5ldyBEYXRlKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKTtcbiAgICAgIH0sIEVycm9yLCAnQ2Fubm90IGNvbnZlcnQgdG8gVGltZVVuaXRzIGNvbnRhaW5pbmcgXFwnZGF5XFwnJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBleHBlY3RlZCByZXN1bHQgZm9yIFlFQVJRVUFSVEVSJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5ZRUFSUVVBUlRFUiwgbmV3IERhdGUoMjAwMCwgMTEsIDIsIDIzLCA1OSwgNTksIDk5OSkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGUuZ2V0VGltZSgpLCBuZXcgRGF0ZSgyMDAwLCA5LCAxLCAwLCAwLCAwLCAwKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBVVENZRUFSUVVBUlRFUicsIGZ1bmN0aW9uKCkge1xuICAgICAgY29uc3QgZGF0ZTogRGF0ZSA9IGNvbnZlcnQoVGltZVVuaXQuVVRDWUVBUlFVQVJURVIsIG5ldyBEYXRlKERhdGUuVVRDKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKERhdGUuVVRDKDIwMDAsIDksIDEsIDAsIDAsIDAsIDApKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBZRUFSUVVBUlRFUk1PTlRIJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5ZRUFSUVVBUlRFUk1PTlRILCBuZXcgRGF0ZSgyMDAwLCAxMSwgMiwgMjMsIDU5LCA1OSwgOTk5KSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKDIwMDAsIDExLCAxLCAwLCAwLCAwLCAwKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBZRUFSTU9OVEgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LllFQVJNT05USCwgbmV3IERhdGUoMjAwMCwgMTEsIDIsIDIzLCA1OSwgNTksIDk5OSkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGUuZ2V0VGltZSgpLCBuZXcgRGF0ZSgyMDAwLCAxMSwgMSwgMCwgMCwgMCwgMCkuZ2V0VGltZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdCBmb3IgVVRDWUVBUk1PTlRIJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5VVENZRUFSTU9OVEgsIG5ldyBEYXRlKERhdGUuVVRDKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKERhdGUuVVRDKDIwMDAsIDExLCAxLCAwLCAwLCAwLCAwKSkuZ2V0VGltZSgpKTtcbiAgICB9KTtcblxuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBVVENZRUFSTU9OVEgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LlVUQ1lFQVIsIG5ldyBEYXRlKERhdGUuVVRDKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKERhdGUuVVRDKDIwMDAsIDAsIDEsIDAsIDAsIDAsIDApKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBZRUFSTU9OVEhEQVRFJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5ZRUFSTU9OVEhEQVRFLCBuZXcgRGF0ZSgyMDAwLCAxMSwgMiwgMjMsIDU5LCA1OSwgOTk5KSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKDIwMDAsIDExLCAyLCAwLCAwLCAwLCAwKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBZRUFSTU9OVEhEQVRFSE9VUlMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LllFQVJNT05USERBVEVIT1VSUywgbmV3IERhdGUoMjAwMCwgMTEsIDIsIDIzLCA1OSwgNTksIDk5OSkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGUuZ2V0VGltZSgpLCBuZXcgRGF0ZSgyMDAwLCAxMSwgMiwgMjMsIDAsIDAsIDApLmdldFRpbWUoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBleHBlY3RlZCByZXN1bHQgZm9yIFlFQVJNT05USERBVEVIT1VSU01JTlVURVMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LllFQVJNT05USERBVEVIT1VSU01JTlVURVMsIG5ldyBEYXRlKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKTtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlLmdldFRpbWUoKSwgbmV3IERhdGUoMjAwMCwgMTEsIDIsIDIzLCA1OSwgMCwgMCkuZ2V0VGltZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdCBmb3IgWUVBUk1PTlRIREFURUhPVVJTTUlOVVRFU1NFQ09ORFMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LllFQVJNT05USERBVEVIT1VSU01JTlVURVNTRUNPTkRTLCBuZXcgRGF0ZSgyMDAwLCAxMSwgMiwgMjMsIDU5LCA1OSwgOTk5KSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCAwKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBRVUFSVEVSTU9OVEgnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LlFVQVJURVJNT05USCwgbmV3IERhdGUoMjAwMCwgMTEsIDIsIDIzLCA1OSwgNTksIDk5OSkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGUuZ2V0VGltZSgpLCBuZXcgRGF0ZSgxOTAwLCAxMSwgMSwgMCwgMCwgMCwgMCkuZ2V0VGltZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdCBmb3IgSE9VUlNNSU5VVEVTJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5IT1VSU01JTlVURVMsIG5ldyBEYXRlKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKTtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlLmdldFRpbWUoKSwgbmV3IERhdGUoMTkwMCwgMCwgMSwgMjMsIDU5LCAwLCAwKS5nZXRUaW1lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBIT1VSU01JTlVURVNTRUNPTkRTJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5IT1VSU01JTlVURVNTRUNPTkRTLCBuZXcgRGF0ZSgyMDAwLCAxMSwgMiwgMjMsIDU5LCA1OSwgOTk5KSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZGF0ZS5nZXRUaW1lKCksIG5ldyBEYXRlKDE5MDAsIDAsIDEsIDIzLCA1OSwgNTksIDApLmdldFRpbWUoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBleHBlY3RlZCByZXN1bHQgZm9yIE1JTlVURVNTRUNPTkRTJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBkYXRlOiBEYXRlID0gY29udmVydChUaW1lVW5pdC5NSU5VVEVTU0VDT05EUywgbmV3IERhdGUoMjAwMCwgMTEsIDIsIDIzLCA1OSwgNTksIDk5OSkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGRhdGUuZ2V0VGltZSgpLCBuZXcgRGF0ZSgxOTAwLCAwLCAxLCAwLCA1OSwgNTksIDApLmdldFRpbWUoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBleHBlY3RlZCByZXN1bHQgZm9yIFNFQ09ORFNNSUxMSVNFQ09ORFMnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGRhdGU6IERhdGUgPSBjb252ZXJ0KFRpbWVVbml0LlNFQ09ORFNNSUxMSVNFQ09ORFMsIG5ldyBEYXRlKDIwMDAsIDExLCAyLCAyMywgNTksIDU5LCA5OTkpKTtcbiAgICAgIGFzc2VydC5lcXVhbChkYXRlLmdldFRpbWUoKSwgbmV3IERhdGUoMTkwMCwgMCwgMSwgMCwgMCwgNTksIDk5OSkuZ2V0VGltZSgpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3RlbXBsYXRlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGVtcGxhdGUgZm9yIFlFQVJNT05USERBVEVIT1VSU01JTlVURVNTRUNPTkRTJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBmb3JtYXRFeHByZXNzaW9uKFRpbWVVbml0LllFQVJNT05USERBVEVIT1VSU01JTlVURVNTRUNPTkRTLCdkYXR1bS54JywgdW5kZWZpbmVkLCBmYWxzZSksXG4gICAgICAgIFwidGltZUZvcm1hdChkYXR1bS54LCAnJWIgJWQsICVZICVIOiVNOiVTJylcIlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGVtcGxhdGUgZm9yIFlFQVJNT05USCAoTm8gY29tbWEpJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBmb3JtYXRFeHByZXNzaW9uKFRpbWVVbml0LllFQVJNT05USCwnZGF0dW0ueCcsIHVuZGVmaW5lZCwgZmFsc2UpLFxuICAgICAgICBcInRpbWVGb3JtYXQoZGF0dW0ueCwgJyViICVZJylcIlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGVtcGxhdGUgZm9yIERBWScsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgZm9ybWF0RXhwcmVzc2lvbihUaW1lVW5pdC5EQVksJ2RhdHVtLngnLCB1bmRlZmluZWQsIGZhbHNlKSxcbiAgICAgICAgXCJ0aW1lRm9ybWF0KGRhdHVtLngsICclQScpXCJcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IHRlbXBsYXRlIGZvciBEQVkgKHNob3J0ZW5lZCknLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGZvcm1hdEV4cHJlc3Npb24oVGltZVVuaXQuREFZLCdkYXR1bS54JywgdHJ1ZSwgZmFsc2UpLFxuICAgICAgICBcInRpbWVGb3JtYXQoZGF0dW0ueCwgJyVhJylcIlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGVtcGxhdGUgZm9yIFFVQVJURVInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGZvcm1hdEV4cHJlc3Npb24oVGltZVVuaXQuUVVBUlRFUiwnZGF0dW0ueCcsIHVuZGVmaW5lZCwgZmFsc2UpLFxuICAgICAgICBcIidRJyArIHF1YXJ0ZXIoZGF0dW0ueClcIlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGVtcGxhdGUgZm9yIFlFQVJRVUFSVEVSJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBmb3JtYXRFeHByZXNzaW9uKFRpbWVVbml0LllFQVJRVUFSVEVSLCdkYXR1bS54JywgdW5kZWZpbmVkLCBmYWxzZSksXG4gICAgICAgIFwiJ1EnICsgcXVhcnRlcihkYXR1bS54KSArICcgJyArIHRpbWVGb3JtYXQoZGF0dW0ueCwgJyVZJylcIlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgdGVtcGxhdGUgZm9yIG1pbGxpc2Vjb25kcycsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgZm9ybWF0RXhwcmVzc2lvbihUaW1lVW5pdC5NSUxMSVNFQ09ORFMsJ2RhdHVtLngnLCB1bmRlZmluZWQsIGZhbHNlKSxcbiAgICAgICAgXCJ0aW1lRm9ybWF0KGRhdHVtLngsICclTCcpXCJcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IHRlbXBsYXRlIGZvciBubyB0aW1lVW5pdCcsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgZm9ybWF0RXhwcmVzc2lvbih1bmRlZmluZWQsJ2RhdHVtLngnLCB1bmRlZmluZWQsIGZhbHNlKSxcbiAgICAgICAgdW5kZWZpbmVkXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCB0ZW1wbGF0ZSBmb3IgWUVBUk1PTlRIIChObyBjb21tYSkgd2l0aCB1dGMgc2NhbGUnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGZvcm1hdEV4cHJlc3Npb24oVGltZVVuaXQuWUVBUk1PTlRILCdkYXR1bS54JywgdW5kZWZpbmVkLCB0cnVlKSxcbiAgICAgICAgXCJ1dGNGb3JtYXQoZGF0dW0ueCwgJyViICVZJylcIlxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/transform.test.js b/build/test/transform.test.js new file mode 100644 index 0000000000..9b133fb65b --- /dev/null +++ b/build/test/transform.test.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../src/log"); +var transform_1 = require("../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 } + ]; + chai_1.assert.deepEqual(transform_1.normalizeTransform(transform), [{ + filter: { + and: [ + { not: { timeUnit: 'yearmonthdate', field: 'd', equal: { year: 2008 } } }, + { or: [{ field: 'a', equal: 5 }] } + ] + } + }]); + chai_1.assert.equal(localLogger.warns[0], log.message.dayReplacedWithDate('yearmonthday')); + })); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L3RyYW5zZm9ybS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBRTVCLGdDQUFrQztBQUdsQyw4Q0FBK0Q7QUFFL0QsUUFBUSxDQUFDLHNCQUFzQixFQUFFO0lBQy9CLEVBQUUsQ0FBQyw0RkFBNEYsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQUMsV0FBVztRQUNwSCxJQUFNLE1BQU0sR0FBMkI7WUFDckMsR0FBRyxFQUFFO2dCQUNILEVBQUMsR0FBRyxFQUFFLEVBQUMsUUFBUSxFQUFFLGNBQTBCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBQyxJQUFJLEVBQUUsSUFBSSxFQUFDLEVBQUMsRUFBQztnQkFDOUUsRUFBQyxFQUFFLEVBQUUsQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUM7YUFDL0I7U0FDRixDQUFDO1FBQ0YsSUFBTSxTQUFTLEdBQWdCO1lBQzdCLEVBQUMsTUFBTSxRQUFBLEVBQUM7U0FDVCxDQUFDO1FBQ0YsYUFBTSxDQUFDLFNBQVMsQ0FBQyw4QkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUMvQyxNQUFNLEVBQUU7b0JBQ04sR0FBRyxFQUFFO3dCQUNILEVBQUMsR0FBRyxFQUFFLEVBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsRUFBQyxFQUFDO3dCQUNuRSxFQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBQztxQkFDL0I7aUJBQ0Y7YUFDRixDQUFDLENBQUMsQ0FBQztRQUNKLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7SUFDdEYsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNOLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtGaWx0ZXJ9IGZyb20gJy4uL3NyYy9maWx0ZXInO1xuaW1wb3J0ICogYXMgbG9nIGZyb20gJy4uL3NyYy9sb2cnO1xuaW1wb3J0IHtMb2dpY2FsT3BlcmFuZH0gZnJvbSAnLi4vc3JjL2xvZ2ljYWwnO1xuaW1wb3J0IHtUaW1lVW5pdH0gZnJvbSAnLi4vc3JjL3RpbWV1bml0JztcbmltcG9ydCB7bm9ybWFsaXplVHJhbnNmb3JtLCBUcmFuc2Zvcm19IGZyb20gJy4uL3NyYy90cmFuc2Zvcm0nO1xuXG5kZXNjcmliZSgnbm9ybWFsaXplVHJhbnNmb3JtKCknLCAoKSA9PiB7XG4gIGl0KCdyZXBsYWNlcyBmaWx0ZXIgd2l0aCB0aW1lVW5pdD15ZWFybW9udGhkYXkgd2l0aCB5ZWFybW9udGhkYXRlIGFuZCB0aHJvd3MgdGhlIHJpZ2h0IHdhcm5pbmcnLCBsb2cud3JhcCgobG9jYWxMb2dnZXIpID0+IHtcbiAgICBjb25zdCBmaWx0ZXI6IExvZ2ljYWxPcGVyYW5kPEZpbHRlcj4gPSB7XG4gICAgICBhbmQ6IFtcbiAgICAgICAge25vdDoge3RpbWVVbml0OiAneWVhcm1vbnRoZGF5JyBhcyBUaW1lVW5pdCwgZmllbGQ6ICdkJywgZXF1YWw6IHt5ZWFyOiAyMDA4fX19LFxuICAgICAgICB7b3I6IFt7ZmllbGQ6ICdhJywgZXF1YWw6IDV9XX1cbiAgICAgIF1cbiAgICB9O1xuICAgIGNvbnN0IHRyYW5zZm9ybTogVHJhbnNmb3JtW10gPSBbXG4gICAgICB7ZmlsdGVyfVxuICAgIF07XG4gICAgYXNzZXJ0LmRlZXBFcXVhbChub3JtYWxpemVUcmFuc2Zvcm0odHJhbnNmb3JtKSwgW3tcbiAgICAgIGZpbHRlcjoge1xuICAgICAgICBhbmQ6IFtcbiAgICAgICAgICB7bm90OiB7dGltZVVuaXQ6ICd5ZWFybW9udGhkYXRlJywgZmllbGQ6ICdkJywgZXF1YWw6IHt5ZWFyOiAyMDA4fX19LFxuICAgICAgICAgIHtvcjogW3tmaWVsZDogJ2EnLCBlcXVhbDogNX1dfVxuICAgICAgICBdXG4gICAgICB9XG4gICAgfV0pO1xuICAgIGFzc2VydC5lcXVhbChsb2NhbExvZ2dlci53YXJuc1swXSwgbG9nLm1lc3NhZ2UuZGF5UmVwbGFjZWRXaXRoRGF0ZSgneWVhcm1vbnRoZGF5JykpO1xuICB9KSk7XG59KTtcbiJdfQ== \ 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..e69de29bb2 diff --git a/build/test/type.test.js b/build/test/type.test.js new file mode 100644 index 0000000000..85119618ff --- /dev/null +++ b/build/test/type.test.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var type = require("../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]; + chai_1.assert.equal(type.getFullName(t), 'quantitative'); + } + for (var _b = 0, _c = ['t', 'T', 'temporal', 'TEMPORAL']; _b < _c.length; _b++) { + var t = _c[_b]; + chai_1.assert.equal(type.getFullName(t), 'temporal'); + } + for (var _d = 0, _e = ['o', 'O', 'ordinal', 'ORDINAL']; _d < _e.length; _d++) { + var t = _e[_d]; + chai_1.assert.equal(type.getFullName(t), 'ordinal'); + } + for (var _f = 0, _g = ['n', 'N', 'nominal', 'NOMINAL']; _f < _g.length; _f++) { + var t = _g[_f]; + chai_1.assert.equal(type.getFullName(t), 'nominal'); + } + }); + it('should return undefined for invalid type', function () { + chai_1.assert.equal(type.getFullName('haha'), undefined); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC90eXBlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFFNUIsa0NBQW9DO0FBRXBDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyxtREFBbUQsRUFBRTtZQUN0RCxHQUFHLENBQUMsQ0FBWSxVQUEwQyxFQUExQyxNQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxFQUExQyxjQUEwQyxFQUExQyxJQUEwQztnQkFBckQsSUFBTSxDQUFDLFNBQUE7Z0JBQ1YsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO2FBQ25EO1lBQ0QsR0FBRyxDQUFDLENBQVksVUFBa0MsRUFBbEMsTUFBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsRUFBbEMsY0FBa0MsRUFBbEMsSUFBa0M7Z0JBQTdDLElBQU0sQ0FBQyxTQUFBO2dCQUNWLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQzthQUMvQztZQUNELEdBQUcsQ0FBQyxDQUFZLFVBQWdDLEVBQWhDLE1BQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQWhDLGNBQWdDLEVBQWhDLElBQWdDO2dCQUEzQyxJQUFNLENBQUMsU0FBQTtnQkFDVixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDOUM7WUFDRCxHQUFHLENBQUMsQ0FBWSxVQUFnQyxFQUFoQyxNQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxFQUFoQyxjQUFnQyxFQUFoQyxJQUFnQztnQkFBM0MsSUFBTSxDQUFDLFNBQUE7Z0JBQ1YsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQzlDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUU7WUFDN0MsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YXNzZXJ0fSBmcm9tICdjaGFpJztcblxuaW1wb3J0ICogYXMgdHlwZSBmcm9tICcuLi9zcmMvdHlwZSc7XG5cbmRlc2NyaWJlKCd0eXBlJywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnZ2V0RnVsbE5hbWUoKScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBjb3JyZWN0IGxvd2VyY2FzZSwgZnVsbCB0eXBlIG5hbWVzLicsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgdCBvZiBbJ3EnLCAnUScsICdxdWFudGl0YXRpdmUnLCAnUVVBTlRJVEFUSVZFJ10pIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHR5cGUuZ2V0RnVsbE5hbWUodCksICdxdWFudGl0YXRpdmUnKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgdCBvZiBbJ3QnLCAnVCcsICd0ZW1wb3JhbCcsICdURU1QT1JBTCddKSB7XG4gICAgICAgIGFzc2VydC5lcXVhbCh0eXBlLmdldEZ1bGxOYW1lKHQpLCAndGVtcG9yYWwnKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgdCBvZiBbJ28nLCAnTycsICdvcmRpbmFsJywgJ09SRElOQUwnXSkge1xuICAgICAgICBhc3NlcnQuZXF1YWwodHlwZS5nZXRGdWxsTmFtZSh0KSwgJ29yZGluYWwnKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgdCBvZiBbJ24nLCAnTicsICdub21pbmFsJywgJ05PTUlOQUwnXSkge1xuICAgICAgICBhc3NlcnQuZXF1YWwodHlwZS5nZXRGdWxsTmFtZSh0KSwgJ25vbWluYWwnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBmb3IgaW52YWxpZCB0eXBlJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LmVxdWFsKHR5cGUuZ2V0RnVsbE5hbWUoJ2hhaGEnKSwgdW5kZWZpbmVkKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ== \ 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..39e3b996d2 --- /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 { ConcatSpec, FacetSpec, LayerSpec, RepeatSpec, TopLevel, TopLevelExtendedSpec, UnitSpec } from '../src/spec'; +export declare function parseModel(inputSpec: TopLevelExtendedSpec): Model; +export declare function parseModelWithScale(inputSpec: TopLevelExtendedSpec): 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..76785a104d --- /dev/null +++ b/build/test/util.js @@ -0,0 +1,64 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var buildmodel_1 = require("../src/compile/buildmodel"); +var concat_1 = require("../src/compile/concat"); +var facet_1 = require("../src/compile/facet"); +var layer_1 = require("../src/compile/layer"); +var repeat_1 = require("../src/compile/repeat"); +var unit_1 = require("../src/compile/unit"); +var config_1 = require("../src/config"); +var spec_1 = require("../src/spec"); +var spec_2 = require("../src/spec"); +var toplevelprops_1 = require("../src/toplevelprops"); +function parseModel(inputSpec) { + var config = config_1.initConfig(inputSpec.config); + var spec = spec_1.normalize(inputSpec, config); + var autosize = toplevelprops_1.normalizeAutoSize(inputSpec.autosize, config.autosize, spec_2.isLayerSpec(spec) || spec_2.isUnitSpec(spec)); + return buildmodel_1.buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit'); +} +exports.parseModel = parseModel; +function parseModelWithScale(inputSpec) { + var model = parseModel(inputSpec); + model.parseScale(); + return model; +} +exports.parseModelWithScale = parseModelWithScale; +function parseUnitModel(spec) { + return new unit_1.UnitModel(spec, null, '', undefined, undefined, config_1.initConfig(spec.config), toplevelprops_1.normalizeAutoSize(spec.autosize, spec.config ? spec.config.autosize : undefined, true).type === 'fit'); +} +exports.parseUnitModel = parseUnitModel; +function parseUnitModelWithScale(spec) { + var model = parseUnitModel(spec); + model.parseScale(); + return model; +} +exports.parseUnitModelWithScale = parseUnitModelWithScale; +function parseUnitModelWithScaleAndLayoutSize(spec) { + var model = parseUnitModelWithScale(spec); + model.parseLayoutSize(); + return model; +} +exports.parseUnitModelWithScaleAndLayoutSize = parseUnitModelWithScaleAndLayoutSize; +function parseLayerModel(spec) { + return new layer_1.LayerModel(spec, null, '', undefined, undefined, config_1.initConfig(spec.config), toplevelprops_1.normalizeAutoSize(spec.autosize, spec.config ? spec.config.autosize : undefined, true).type === 'fit'); +} +exports.parseLayerModel = parseLayerModel; +function parseFacetModel(spec) { + return new facet_1.FacetModel(spec, null, '', undefined, config_1.initConfig(spec.config)); +} +exports.parseFacetModel = parseFacetModel; +function parseFacetModelWithScale(spec) { + var model = parseFacetModel(spec); + model.parseScale(); + return model; +} +exports.parseFacetModelWithScale = parseFacetModelWithScale; +function parseRepeatModel(spec) { + return new repeat_1.RepeatModel(spec, null, '', undefined, config_1.initConfig(spec.config)); +} +exports.parseRepeatModel = parseRepeatModel; +function parseConcatModel(spec) { + return new concat_1.ConcatModel(spec, null, '', undefined, config_1.initConfig(spec.config)); +} +exports.parseConcatModel = parseConcatModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHdEQUFxRDtBQUNyRCxnREFBa0Q7QUFDbEQsOENBQWdEO0FBQ2hELDhDQUFnRDtBQUVoRCxnREFBa0Q7QUFDbEQsNENBQThDO0FBQzlDLHdDQUF5QztBQUN6QyxvQ0FTcUI7QUFDckIsb0NBQW9EO0FBQ3BELHNEQUF1RDtBQUV2RCxvQkFBMkIsU0FBK0I7SUFDeEQsSUFBTSxNQUFNLEdBQUcsbUJBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUMsSUFBTSxJQUFJLEdBQUcsZ0JBQVMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDMUMsSUFBTSxRQUFRLEdBQUcsaUNBQWlCLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLGtCQUFXLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQy9HLE1BQU0sQ0FBQyx1QkFBVSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUM7QUFDM0YsQ0FBQztBQUxELGdDQUtDO0FBRUQsNkJBQW9DLFNBQStCO0lBQ2pFLElBQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNwQyxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDbkIsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFKRCxrREFJQztBQUVELHdCQUErQixJQUF3QjtJQUNyRCxNQUFNLENBQUMsSUFBSSxnQkFBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsbUJBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsaUNBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQztBQUM3TCxDQUFDO0FBRkQsd0NBRUM7QUFFRCxpQ0FBd0MsSUFBd0I7SUFDOUQsSUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25DLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNuQixNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUpELDBEQUlDO0FBRUQsOENBQXFELElBQXdCO0lBQzNFLElBQU0sS0FBSyxHQUFHLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUpELG9GQUlDO0FBR0QseUJBQWdDLElBQXlCO0lBQ3ZELE1BQU0sQ0FBQyxJQUFJLGtCQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxtQkFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxpQ0FBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDO0FBQzlMLENBQUM7QUFGRCwwQ0FFQztBQUVELHlCQUFnQyxJQUF5QjtJQUN2RCxNQUFNLENBQUMsSUFBSSxrQkFBVSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxtQkFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQzVFLENBQUM7QUFGRCwwQ0FFQztBQUVELGtDQUF5QyxJQUF5QjtJQUNoRSxJQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDO0FBSkQsNERBSUM7QUFFRCwwQkFBaUMsSUFBMEI7SUFDekQsTUFBTSxDQUFDLElBQUksb0JBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsbUJBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRkQsNENBRUM7QUFFRCwwQkFBaUMsSUFBMEI7SUFDekQsTUFBTSxDQUFDLElBQUksb0JBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsbUJBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRkQsNENBRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2J1aWxkTW9kZWx9IGZyb20gJy4uL3NyYy9jb21waWxlL2J1aWxkbW9kZWwnO1xuaW1wb3J0IHtDb25jYXRNb2RlbH0gZnJvbSAnLi4vc3JjL2NvbXBpbGUvY29uY2F0JztcbmltcG9ydCB7RmFjZXRNb2RlbH0gZnJvbSAnLi4vc3JjL2NvbXBpbGUvZmFjZXQnO1xuaW1wb3J0IHtMYXllck1vZGVsfSBmcm9tICcuLi9zcmMvY29tcGlsZS9sYXllcic7XG5pbXBvcnQge01vZGVsfSBmcm9tICcuLi9zcmMvY29tcGlsZS9tb2RlbCc7XG5pbXBvcnQge1JlcGVhdE1vZGVsfSBmcm9tICcuLi9zcmMvY29tcGlsZS9yZXBlYXQnO1xuaW1wb3J0IHtVbml0TW9kZWx9IGZyb20gJy4uL3NyYy9jb21waWxlL3VuaXQnO1xuaW1wb3J0IHtpbml0Q29uZmlnfSBmcm9tICcuLi9zcmMvY29uZmlnJztcbmltcG9ydCB7XG4gIENvbmNhdFNwZWMsXG4gIEZhY2V0U3BlYyxcbiAgTGF5ZXJTcGVjLFxuICBub3JtYWxpemUsXG4gIFJlcGVhdFNwZWMsXG4gIFRvcExldmVsLFxuICBUb3BMZXZlbEV4dGVuZGVkU3BlYyxcbiAgVW5pdFNwZWMsXG59IGZyb20gJy4uL3NyYy9zcGVjJztcbmltcG9ydCB7aXNMYXllclNwZWMsIGlzVW5pdFNwZWN9IGZyb20gJy4uL3NyYy9zcGVjJztcbmltcG9ydCB7bm9ybWFsaXplQXV0b1NpemV9IGZyb20gJy4uL3NyYy90b3BsZXZlbHByb3BzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTW9kZWwoaW5wdXRTcGVjOiBUb3BMZXZlbEV4dGVuZGVkU3BlYyk6IE1vZGVsIHtcbiAgY29uc3QgY29uZmlnID0gaW5pdENvbmZpZyhpbnB1dFNwZWMuY29uZmlnKTtcbiAgY29uc3Qgc3BlYyA9IG5vcm1hbGl6ZShpbnB1dFNwZWMsIGNvbmZpZyk7XG4gIGNvbnN0IGF1dG9zaXplID0gbm9ybWFsaXplQXV0b1NpemUoaW5wdXRTcGVjLmF1dG9zaXplLCBjb25maWcuYXV0b3NpemUsIGlzTGF5ZXJTcGVjKHNwZWMpIHx8IGlzVW5pdFNwZWMoc3BlYykpO1xuICByZXR1cm4gYnVpbGRNb2RlbChzcGVjLCBudWxsLCAnJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGNvbmZpZywgYXV0b3NpemUudHlwZSA9PT0gJ2ZpdCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VNb2RlbFdpdGhTY2FsZShpbnB1dFNwZWM6IFRvcExldmVsRXh0ZW5kZWRTcGVjKTogTW9kZWwge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlTW9kZWwoaW5wdXRTcGVjKTtcbiAgbW9kZWwucGFyc2VTY2FsZSgpO1xuICByZXR1cm4gbW9kZWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVVuaXRNb2RlbChzcGVjOiBUb3BMZXZlbDxVbml0U3BlYz4pIHtcbiAgcmV0dXJuIG5ldyBVbml0TW9kZWwoc3BlYywgbnVsbCwgJycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBpbml0Q29uZmlnKHNwZWMuY29uZmlnKSwgbm9ybWFsaXplQXV0b1NpemUoc3BlYy5hdXRvc2l6ZSwgc3BlYy5jb25maWcgPyBzcGVjLmNvbmZpZy5hdXRvc2l6ZSA6IHVuZGVmaW5lZCwgdHJ1ZSkudHlwZSA9PT0gJ2ZpdCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGUoc3BlYzogVG9wTGV2ZWw8VW5pdFNwZWM+KSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VVbml0TW9kZWwoc3BlYyk7XG4gIG1vZGVsLnBhcnNlU2NhbGUoKTtcbiAgcmV0dXJuIG1vZGVsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VVbml0TW9kZWxXaXRoU2NhbGVBbmRMYXlvdXRTaXplKHNwZWM6IFRvcExldmVsPFVuaXRTcGVjPikge1xuICBjb25zdCBtb2RlbCA9IHBhcnNlVW5pdE1vZGVsV2l0aFNjYWxlKHNwZWMpO1xuICBtb2RlbC5wYXJzZUxheW91dFNpemUoKTtcbiAgcmV0dXJuIG1vZGVsO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxheWVyTW9kZWwoc3BlYzogVG9wTGV2ZWw8TGF5ZXJTcGVjPikge1xuICByZXR1cm4gbmV3IExheWVyTW9kZWwoc3BlYywgbnVsbCwgJycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBpbml0Q29uZmlnKHNwZWMuY29uZmlnKSwgbm9ybWFsaXplQXV0b1NpemUoc3BlYy5hdXRvc2l6ZSwgc3BlYy5jb25maWcgPyBzcGVjLmNvbmZpZy5hdXRvc2l6ZSA6IHVuZGVmaW5lZCwgdHJ1ZSkudHlwZSA9PT0gJ2ZpdCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VGYWNldE1vZGVsKHNwZWM6IFRvcExldmVsPEZhY2V0U3BlYz4pIHtcbiAgcmV0dXJuIG5ldyBGYWNldE1vZGVsKHNwZWMsIG51bGwsICcnLCB1bmRlZmluZWQsIGluaXRDb25maWcoc3BlYy5jb25maWcpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRmFjZXRNb2RlbFdpdGhTY2FsZShzcGVjOiBUb3BMZXZlbDxGYWNldFNwZWM+KSB7XG4gIGNvbnN0IG1vZGVsID0gcGFyc2VGYWNldE1vZGVsKHNwZWMpO1xuICBtb2RlbC5wYXJzZVNjYWxlKCk7XG4gIHJldHVybiBtb2RlbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVwZWF0TW9kZWwoc3BlYzogVG9wTGV2ZWw8UmVwZWF0U3BlYz4pIHtcbiAgcmV0dXJuIG5ldyBSZXBlYXRNb2RlbChzcGVjLCBudWxsLCAnJywgdW5kZWZpbmVkLCBpbml0Q29uZmlnKHNwZWMuY29uZmlnKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNvbmNhdE1vZGVsKHNwZWM6IFRvcExldmVsPENvbmNhdFNwZWM+KSB7XG4gIHJldHVybiBuZXcgQ29uY2F0TW9kZWwoc3BlYywgbnVsbCwgJycsIHVuZGVmaW5lZCwgaW5pdENvbmZpZyhzcGVjLmNvbmZpZykpO1xufVxuIl19 \ 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..e69de29bb2 diff --git a/build/test/util.test.js b/build/test/util.test.js new file mode 100644 index 0000000000..5a00da714c --- /dev/null +++ b/build/test/util.test.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../src/util"); +describe('util', function () { + describe('varName', function () { + it('replace all non-alphanumeric characters with _', function () { + chai_1.assert.equal(util_1.varName('bin-mpg$!@#%_+1'), 'bin_mpg_______1'); + }); + it('prepends _ if the string starts with number', function () { + chai_1.assert.equal(util_1.varName('1a'), '_1a'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC91dGlsLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsb0NBQW9DO0FBRXBDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyxnREFBZ0QsRUFBRTtZQUNuRCxhQUFNLENBQUMsS0FBSyxDQUFDLGNBQU8sQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUU7WUFDaEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHt2YXJOYW1lfSBmcm9tICcuLi9zcmMvdXRpbCc7XG5cbmRlc2NyaWJlKCd1dGlsJywgKCkgPT4ge1xuICBkZXNjcmliZSgndmFyTmFtZScsICgpID0+IHtcbiAgICBpdCgncmVwbGFjZSBhbGwgbm9uLWFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggXycsICgpID0+IHtcbiAgICAgIGFzc2VydC5lcXVhbCh2YXJOYW1lKCdiaW4tbXBnJCFAIyVfKzEnKSwgJ2Jpbl9tcGdfX19fX19fMScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ByZXBlbmRzIF8gaWYgdGhlIHN0cmluZyBzdGFydHMgd2l0aCBudW1iZXInLCAoKSA9PiB7XG4gICAgICBhc3NlcnQuZXF1YWwodmFyTmFtZSgnMWEnKSwgJ18xYScpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19 \ 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..e69de29bb2 diff --git a/build/test/validate.test.js b/build/test/validate.test.js new file mode 100644 index 0000000000..6483327b1a --- /dev/null +++ b/build/test/validate.test.js @@ -0,0 +1,70 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var mark_1 = require("../src/mark"); +var validate_1 = require("../src/validate"); +describe('vl.validate', function () { + describe('getEncodingMappingError()', function () { + it('should return no error for valid specs', function () { + chai_1.assert.isNull(validate_1.getEncodingMappingError({ + mark: mark_1.BAR, + encoding: { + x: { field: 'a', type: 'quantitative' } + } + })); + chai_1.assert.isNull(validate_1.getEncodingMappingError({ + mark: mark_1.LINE, + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'a', type: 'quantitative' } + } + })); + chai_1.assert.isNull(validate_1.getEncodingMappingError({ + mark: mark_1.AREA, + encoding: { + x: { field: 'a', type: 'quantitative' }, + y: { field: 'b', type: 'quantitative' } + } + })); + }); + it('should return error for invalid specs', function () { + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.LINE, + encoding: { + x: { field: 'b', type: 'quantitative' } // missing y + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.AREA, + encoding: { + y: { field: 'b', type: 'quantitative' } // missing x + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.TEXT, + encoding: { + y: { field: 'b', type: 'quantitative' } // missing text + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.LINE, + encoding: { + shape: { field: 'b', type: 'quantitative' } // using shape with line + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.AREA, + encoding: { + shape: { field: 'b', type: 'quantitative' } // using shape with area + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.BAR, + encoding: { + shape: { field: 'b', type: 'quantitative' } // using shape with bar + } + })); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdmFsaWRhdGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1QixvQ0FBa0Q7QUFDbEQsNENBQXdEO0FBRXhELFFBQVEsQ0FBQyxhQUFhLEVBQUU7SUFDdEIsUUFBUSxDQUFDLDJCQUEyQixFQUFFO1FBQ3BDLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRTtZQUMzQyxhQUFNLENBQUMsTUFBTSxDQUFDLGtDQUF1QixDQUFDO2dCQUNwQyxJQUFJLEVBQUUsVUFBRztnQkFDVCxRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosYUFBTSxDQUFDLE1BQU0sQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDcEMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztvQkFDckMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosYUFBTSxDQUFDLE1BQU0sQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDcEMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztvQkFDckMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLFlBQVk7aUJBQ25EO2FBQ0YsQ0FBQyxDQUFDLENBQUM7WUFFSixhQUFNLENBQUMsU0FBUyxDQUFDLGtDQUF1QixDQUFDO2dCQUN2QyxJQUFJLEVBQUUsV0FBSTtnQkFDVixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDLENBQUMsWUFBWTtpQkFDbkQ7YUFDRixDQUFDLENBQUMsQ0FBQztZQUVKLGFBQU0sQ0FBQyxTQUFTLENBQUMsa0NBQXVCLENBQUM7Z0JBQ3ZDLElBQUksRUFBRSxXQUFJO2dCQUNWLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsQ0FBQyxlQUFlO2lCQUN0RDthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLHdCQUF3QjtpQkFDbkU7YUFDRixDQUFDLENBQUMsQ0FBQztZQUVKLGFBQU0sQ0FBQyxTQUFTLENBQUMsa0NBQXVCLENBQUM7Z0JBQ3ZDLElBQUksRUFBRSxXQUFJO2dCQUNWLFFBQVEsRUFBRTtvQkFDUixLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsQ0FBQyx3QkFBd0I7aUJBQ25FO2FBQ0YsQ0FBQyxDQUFDLENBQUM7WUFFSixhQUFNLENBQUMsU0FBUyxDQUFDLGtDQUF1QixDQUFDO2dCQUN2QyxJQUFJLEVBQUUsVUFBRztnQkFDVCxRQUFRLEVBQUU7b0JBQ1IsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDLENBQUMsdUJBQXVCO2lCQUNsRTthQUNGLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHthc3NlcnR9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtBUkVBLCBCQVIsIExJTkUsIFRFWFR9IGZyb20gJy4uL3NyYy9tYXJrJztcbmltcG9ydCB7Z2V0RW5jb2RpbmdNYXBwaW5nRXJyb3J9IGZyb20gJy4uL3NyYy92YWxpZGF0ZSc7XG5cbmRlc2NyaWJlKCd2bC52YWxpZGF0ZScsIGZ1bmN0aW9uKCkge1xuICBkZXNjcmliZSgnZ2V0RW5jb2RpbmdNYXBwaW5nRXJyb3IoKScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBubyBlcnJvciBmb3IgdmFsaWQgc3BlY3MnLCBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydC5pc051bGwoZ2V0RW5jb2RpbmdNYXBwaW5nRXJyb3Ioe1xuICAgICAgICBtYXJrOiBCQVIsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KSk7XG5cbiAgICAgIGFzc2VydC5pc051bGwoZ2V0RW5jb2RpbmdNYXBwaW5nRXJyb3Ioe1xuICAgICAgICBtYXJrOiBMSU5FLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgeToge2ZpZWxkOiAnYScsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KSk7XG5cbiAgICAgIGFzc2VydC5pc051bGwoZ2V0RW5jb2RpbmdNYXBwaW5nRXJyb3Ioe1xuICAgICAgICBtYXJrOiBBUkVBLFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHg6IHtmaWVsZDogJ2EnLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30sXG4gICAgICAgICAgeToge2ZpZWxkOiAnYicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfVxuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlcnJvciBmb3IgaW52YWxpZCBzcGVjcycsIGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0LmlzTm90TnVsbChnZXRFbmNvZGluZ01hcHBpbmdFcnJvcih7XG4gICAgICAgIG1hcms6IExJTkUsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgeDoge2ZpZWxkOiAnYicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSAvLyBtaXNzaW5nIHlcbiAgICAgICAgfVxuICAgICAgfSkpO1xuXG4gICAgICBhc3NlcnQuaXNOb3ROdWxsKGdldEVuY29kaW5nTWFwcGluZ0Vycm9yKHtcbiAgICAgICAgbWFyazogQVJFQSxcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICB5OiB7ZmllbGQ6ICdiJywgdHlwZTogJ3F1YW50aXRhdGl2ZSd9IC8vIG1pc3NpbmcgeFxuICAgICAgICB9XG4gICAgICB9KSk7XG5cbiAgICAgIGFzc2VydC5pc05vdE51bGwoZ2V0RW5jb2RpbmdNYXBwaW5nRXJyb3Ioe1xuICAgICAgICBtYXJrOiBURVhULFxuICAgICAgICBlbmNvZGluZzoge1xuICAgICAgICAgIHk6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30gLy8gbWlzc2luZyB0ZXh0XG4gICAgICAgIH1cbiAgICAgIH0pKTtcblxuICAgICAgYXNzZXJ0LmlzTm90TnVsbChnZXRFbmNvZGluZ01hcHBpbmdFcnJvcih7XG4gICAgICAgIG1hcms6IExJTkUsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgc2hhcGU6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30gLy8gdXNpbmcgc2hhcGUgd2l0aCBsaW5lXG4gICAgICAgIH1cbiAgICAgIH0pKTtcblxuICAgICAgYXNzZXJ0LmlzTm90TnVsbChnZXRFbmNvZGluZ01hcHBpbmdFcnJvcih7XG4gICAgICAgIG1hcms6IEFSRUEsXG4gICAgICAgIGVuY29kaW5nOiB7XG4gICAgICAgICAgc2hhcGU6IHtmaWVsZDogJ2InLCB0eXBlOiAncXVhbnRpdGF0aXZlJ30gLy8gdXNpbmcgc2hhcGUgd2l0aCBhcmVhXG4gICAgICAgIH1cbiAgICAgIH0pKTtcblxuICAgICAgYXNzZXJ0LmlzTm90TnVsbChnZXRFbmNvZGluZ01hcHBpbmdFcnJvcih7XG4gICAgICAgIG1hcms6IEJBUixcbiAgICAgICAgZW5jb2Rpbmc6IHtcbiAgICAgICAgICBzaGFwZToge2ZpZWxkOiAnYicsIHR5cGU6ICdxdWFudGl0YXRpdmUnfSAvLyB1c2luZyBzaGFwZSB3aXRoIGJhclxuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0= \ No newline at end of file diff --git a/build/vega-lite.js b/build/vega-lite.js new file mode 100644 index 0000000000..86c2241e0d --- /dev/null +++ b/build/vega-lite.js @@ -0,0 +1,14705 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vl = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= '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("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("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("Unexpected '" + ch + "'"); + }, + + value, // Place holder for the value function. + + array = 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("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('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("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(); + 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. + +module.exports = function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("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; +}; + +},{}],4:[function(require,module,exports){ +var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + 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; + } +} + +module.exports = 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}); +}; + +},{}],5:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],6:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],7:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],8:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./support/isBuffer":7,"_process":5,"inherits":6}],9:[function(require,module,exports){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.vega = global.vega || {}))); +}(this, (function (exports) { 'use strict'; + +/** + * Parse an event selector string. + * Returns an array of event stream definitions. + */ +var eventSelector = function(selector, source, marks) { + DEFAULT_SOURCE = source || VIEW; + MARKS = marks || DEFAULT_MARKS; + return parseMerge(selector.trim()).map(parseSelector); +}; + +var VIEW = 'view'; +var LBRACK = '['; +var RBRACK = ']'; +var LBRACE = '{'; +var RBRACE = '}'; +var COLON = ':'; +var COMMA = ','; +var NAME = '@'; +var GT = '>'; +var ILLEGAL = /[[\]{}]/; +var DEFAULT_SOURCE; +var MARKS; +var 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(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); + + stream = parseSelector(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; + }); +} + +exports.selector = eventSelector; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); + +},{}],10:[function(require,module,exports){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.vega = global.vega || {}))); +}(this, (function (exports) { 'use strict'; + +var accessor = function(fn, fields, name) { + fn.fields = fields || []; + fn.fname = name; + return fn; +}; + +function accessorName(fn) { + return fn == null ? null : fn.fname; +} + +function accessorFields(fn) { + return fn == null ? null : fn.fields; +} + +var error = function(message) { + throw Error(message); +}; + +var splitAccessPath = function(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; + +var isObject = function(_) { + return _ === Object(_); +}; + +var isString = function(_) { + 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; +} + +var field = function(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; + +var logger = function(_) { + 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; + } + } +}; + +var peek = function(array) { + return array[array.length - 1]; +}; + +var toNumber = function(_) { + return _ == null || _ === '' ? null : +_; +}; + +function exp(sign) { + return function(x) { return sign * Math.exp(x); }; +} + +function log$1(sign) { + return function(x) { return Math.log(sign * x); }; +} + +function pow(exponent) { + return function(x) { + return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); + }; +} + +function pan(domain, delta, lift, ground) { + var d0 = lift(domain[0]), + d1 = lift(peek(domain)), + dd = (d1 - d0) * delta; + + return [ + ground(d0 - dd), + ground(d1 - dd) + ]; +} + +function panLinear(domain, delta) { + return pan(domain, delta, toNumber, identity); +} + +function panLog(domain, delta) { + var sign = Math.sign(domain[0]); + return pan(domain, delta, log$1(sign), exp(sign)); +} + +function panPow(domain, delta, exponent) { + return pan(domain, delta, pow(exponent), pow(1/exponent)); +} + +function zoom(domain, anchor, scale, lift, ground) { + var d0 = lift(domain[0]), + d1 = lift(peek(domain)), + da = anchor != null ? lift(anchor) : (d0 + d1) / 2; + + return [ + ground(da + (d0 - da) * scale), + ground(da + (d1 - da) * scale) + ]; +} + +function zoomLinear(domain, anchor, scale) { + return zoom(domain, anchor, scale, toNumber, identity); +} + +function zoomLog(domain, anchor, scale) { + var sign = Math.sign(domain[0]); + return zoom(domain, anchor, scale, log$1(sign), exp(sign)); +} + +function zoomPow(domain, anchor, scale, exponent) { + return zoom(domain, anchor, scale, pow(exponent), pow(1/exponent)); +} + +var array = function(_) { + return _ != null ? (isArray(_) ? _ : [_]) : []; +}; + +var isFunction = function(_) { + return typeof _ === 'function'; +}; + +var compare = function(fields, orders) { + var idx = [], + cmp = (fields = array(fields)).map(function(f, i) { + if (f == null) { + return null; + } else { + idx.push(i); + return isFunction(f) ? f + : splitAccessPath(f).map($).join(']['); + } + }), + n = idx.length - 1, + ord = array(orders), + code = 'var u,v;return ', + i, j, f, u, v, d, t, lt, gt; + + if (n < 0) return null; + + for (j=0; j<=n; ++j) { + i = idx[j]; + f = cmp[i]; + + if (isFunction(f)) { + d = 'f' + i; + u = '(u=this.' + d + '(a))'; + v = '(v=this.' + d + '(b))'; + (t = t || {})[d] = f; + } else { + u = '(u=a['+f+'])'; + v = '(v=b['+f+'])'; + } + + d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))'; + + if (ord[i] !== 'descending') { + gt = 1; + lt = -1; + } else { + gt = -1; + lt = 1; + } + + code += '(' + u+'<'+v+'||u==null)&&v!=null?' + lt + + ':(u>v||v==null)&&u!=null?' + gt + + ':'+d+'!==u&&v===v?' + lt + + ':v!==v&&u===u?' + gt + + (i < n ? ':' : ':0'); + } + + f = Function('a', 'b', code + ';'); + if (t) f = f.bind(t); + + fields = fields.reduce(function(map, field) { + if (isFunction(field)) { + (accessorFields(field) || []).forEach(function(_) { map[_] = 1; }); + } else if (field != null) { + map[field + ''] = 1; + } + return map; + }, {}); + + return accessor(f, Object.keys(fields)); +}; + +var constant = function(_) { + return isFunction(_) ? _ : function() { return _; }; +}; + +var debounce = function(delay, handler) { + var tid, evt; + + function callback() { + handler(evt); + tid = evt = null; + } + + return function(e) { + evt = e; + if (tid) clearTimeout(tid); + tid = setTimeout(callback, delay); + }; +}; + +var extend = function(_) { + for (var x, k, i=1, len=arguments.length; i= b) { + a = c = b; + break; + } + } + u = v = i; + while (++i < n) { + b = array[i]; + if (b != null) { + if (a > b) { + a = b; + u = i; + } + if (c < b) { + c = b; + v = i; + } + } + } + } else { + while (++i < n) { + b = f(array[i], i, array); + if (b != null && b >= b) { + a = c = b; + break; + } + } + u = v = i; + while (++i < n) { + b = f(array[i], i, array); + if (b != null) { + if (a > b) { + a = b; + u = i; + } + if (c < b) { + c = b; + v = i; + } + } + } + } + + return [u, v]; +}; + +var NULL = {}; + +var fastmap = function(input) { + var obj = {}, + map, + test; + + function has(key) { + return obj.hasOwnProperty(key) && obj[key] !== NULL; + } + + map = { + size: 0, + empty: 0, + object: obj, + has: has, + get: function(key) { + return has(key) ? obj[key] : undefined; + }, + set: function(key, value) { + if (!has(key)) { + ++map.size; + if (obj[key] === NULL) --map.empty; + } + obj[key] = value; + return this; + }, + delete: function(key) { + if (has(key)) { + --map.size; + ++map.empty; + obj[key] = NULL; + } + return this; + }, + clear: function() { + map.size = map.empty = 0; + map.object = obj = {}; + }, + test: function(_) { + if (arguments.length) { + test = _; + return map; + } else { + return test; + } + }, + clean: function() { + var next = {}, + size = 0, + key, value; + for (key in obj) { + value = obj[key]; + if (value !== NULL && (!test || !test(value))) { + next[key] = value; + ++size; + } + } + map.size = size; + map.empty = 0; + map.object = (obj = next); + } + }; + + if (input) Object.keys(input).forEach(function(key) { + map.set(key, input[key]); + }); + + return map; +}; + +var inherits = function(child, parent) { + var proto = (child.prototype = Object.create(parent.prototype)); + proto.constructor = child; + return proto; +}; + +var isBoolean = function(_) { + return typeof _ === 'boolean'; +}; + +var isDate = function(_) { + return Object.prototype.toString.call(_) === '[object Date]'; +}; + +var isNumber = function(_) { + return typeof _ === 'number'; +}; + +var isRegExp = function(_) { + return Object.prototype.toString.call(_) === '[object RegExp]'; +}; + +var key = function(fields, flat) { + if (fields) { + fields = flat + ? array(fields).map(function(f) { return f.replace(/\\(.)/g, '$1'); }) + : array(fields); + } + + var fn = !(fields && fields.length) + ? function() { return ''; } + : Function('_', 'return \'\'+' + + fields.map(function(f) { + return '_[' + (flat + ? $(f) + : splitAccessPath(f).map($).join('][') + ) + ']'; + }).join('+\'|\'+') + ';'); + + return accessor(fn, fields, 'key'); +}; + +var merge = function(compare, array0, array1, output) { + var n0 = array0.length, + n1 = array1.length; + + if (!n1) return array0; + if (!n0) return array1; + + var merged = output || new array0.constructor(n0 + n1), + i0 = 0, i1 = 0, i = 0; + + for (; i0 0 + ? array1[i1++] + : array0[i0++]; + } + + for (; i0= 0) s += str; + return s; +}; + +var pad = function(str, length, padchar, align) { + var c = padchar || ' ', + s = str + '', + n = length - s.length; + + return n <= 0 ? s + : align === 'left' ? repeat(c, n) + s + : align === 'center' ? repeat(c, ~~(n/2)) + s + repeat(c, Math.ceil(n/2)) + : s + repeat(c, n); +}; + +var toBoolean = function(_) { + return _ == null || _ === '' ? null : !_ || _ === 'false' || _ === '0' ? false : !!_; +}; + +function defaultParser(_) { + return isNumber(_) ? _ : isDate(_) ? _ : Date.parse(_); +} + +var toDate = function(_, parser) { + parser = parser || defaultParser; + return _ == null || _ === '' ? null : parser(_); +}; + +var toString = function(_) { + return _ == null || _ === '' ? null : _ + ''; +}; + +var toSet = function(_) { + for (var s={}, i=0, n=_.length; i (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 provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.", + "main": "build/src/index.js", + "types": "typings/vega-lite.d.ts", + "bin": { + "vl2png": "./bin/vl2png", + "vl2svg": "./bin/vl2svg", + "vl2vg": "./bin/vl2vg" + }, + "directories": { + "test": "test" + }, + "scripts": { + "pretsc": "mkdir -p build && rm -rf build/*/** && cp package.json build/", + "tsc": "tsc", + "prebuild": "mkdir -p build/site build/test-gallery", + "build": "npm run build:only", + "build:only": "npm run tsc && cp package.json build && browserify src/index.ts -p tsify -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js", + "postbuild": "node node_modules/uglify-js/bin/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 && npm run build:only && npm run build:examples-only", + "build:examples-only": "npm run build:example && npm run build:examples-normalized", + "build:examples-normalized": "rm -f examples/specs/normalized/*.vl.json && scripts/build-normalized-examples", + "build:example": "TZ=America/Los_Angeles scripts/build-examples.sh", + + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "browserify site/static/main.ts -p [tsify -p site] -d | exorcist build/site/main.js.map > build/site/main.js", + "build:versions": "scripts/update-version.sh", + "build:test-gallery": "browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js", + "check:examples": "scripts/check-examples.sh", + "check:schema": "scripts/check-schema.sh", + "clean": "rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\.(js|js.map|d.ts)' -delete && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -exec rm -f {} +", + "data": "rsync -r node_modules/vega-datasets/data/* data", + "link": "npm link && npm link vega-lite", + + "deploy": "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + + "prestart": "npm run data && npm run build && scripts/index-examples", + "start": "nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'", + "poststart": "rm examples/all-examples.json", + + "preschema": "npm run prebuild", + "schema": "ts-json-schema-generator --path tsconfig.json --type TopLevelExtendedSpec > 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": "npm run build:only && npm run test:only && npm run test:runtime && npm run lint", + "posttest": "npm run schema && npm run data && npm run mocha:examples", + "test:nocompile": "npm run test:only && npm run test:runtime && npm run lint && npm run mocha:examples", + "test:only": "nyc --reporter=html --reporter=text-summary npm run mocha:test", + "test:runtime": "TZ=America/Los_Angeles wdio wdio.conf.js", + "test:runtime:generate": "rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime", + "test:debug": "npm run tsc && mocha --recursive --debug-brk --inspect build/test", + "test:debug-examples": "npm run tsc && npm run schema && mocha --recursive --debug-brk --inspect build/examples", + "mocha:test": "mocha --require source-map-support/register --reporter dot --recursive build/test", + "mocha:examples": "mocha --require source-map-support/register --reporter dot --recursive build/examples", + + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json", + "watch:build": "watchify src/index.ts -p tsify -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'", + "watch:tsc": "npm run tsc -- -w", + "watch:test": "nodemon -x 'npm test'", + "watch": "nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build" + }, + "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.0.6", + "@types/d3": "^4.12.0", + "@types/highlight.js": "^9.12.2", + "@types/json-stable-stringify": "^1.0.32", + "@types/mkdirp": "^0.5.1", + "@types/mocha": "^2.2.44", + "@types/node": "^8.0.53", + "@types/webdriverio": "^4.8.6", + "ajv": "^5.5.0", + "browser-sync": "^2.18.13", + "browserify": "^14.5.0", + "browserify-shim": "^3.8.14", + "chai": "^4.1.2", + "cheerio": "^1.0.0-rc.2", + "chromedriver": "^2.33.2", + "codecov": "^3.0.0", + "d3": "^4.12.0", + "exorcist": "^1.0.0", + "highlight.js": "^9.12.0", + "mkdirp": "^0.5.1", + "mocha": "^4.0.1", + "nodemon": "^1.12.1", + "nyc": "^11.3.0", + "source-map-support": "^0.5.0", + "svg2png-many": "^0.0.7", + "ts-json-schema-generator": "^0.18.0", + "ts-node": "^3.3.0", + "tsify": "^3.0.3", + "tslint": "5.4.3", + "tslint-eslint-rules": "^4.1.1", + "typescript": "^2.6.2", + "uglify-js": "^3.2.0", + "vega": "^3.0.8", + "vega-datasets": "^1.11.0", + "vega-embed": "^3.0.0-rc7", + "vega-tooltip": "^0.4.4", + "watchify": "^3.9.0", + "wdio-chromedriver-service": "^0.1.1", + "wdio-dot-reporter": "0.0.9", + "wdio-mocha-framework": "^0.5.11", + "wdio-static-server-service": "^1.0.1", + "webdriverio": "^4.9.11", + "yaml-front-matter": "^3.4.0" + }, + "dependencies": { + "json-stable-stringify": "^1.0.1", + "tslib": "^1.8.0", + "vega-event-selector": "^2.0.0", + "vega-util": "^1.6.2", + "yargs": "^10.0.3" + } +} + +},{}],12:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var AGGREGATE_OP_INDEX = { + values: 1, + count: 1, + valid: 1, + missing: 1, + distinct: 1, + sum: 1, + mean: 1, + average: 1, + variance: 1, + variancep: 1, + stdev: 1, + stdevp: 1, + median: 1, + q1: 1, + q3: 1, + ci0: 1, + ci1: 1, + min: 1, + max: 1, + argmin: 1, + argmax: 1, +}; +exports.AGGREGATE_OPS = util_1.flagKeys(AGGREGATE_OP_INDEX); +function isAggregateOp(a) { + return !!AGGREGATE_OP_INDEX[a]; +} +exports.isAggregateOp = isAggregateOp; +exports.COUNTING_OPS = ['count', 'valid', 'missing', 'distinct']; +function isCountingAggregateOp(aggregate) { + return aggregate && util_1.contains(exports.COUNTING_OPS, aggregate); +} +exports.isCountingAggregateOp = isCountingAggregateOp; +/** Additive-based aggregation operations. These can be applied to stack. */ +exports.SUM_OPS = [ + 'count', + 'sum', + 'distinct', + 'valid', + 'missing' +]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +exports.SHARED_DOMAIN_OPS = [ + 'mean', + 'average', + 'median', + 'q1', + 'q3', + 'min', + 'max', +]; +exports.SHARED_DOMAIN_OP_INDEX = util_1.toSet(exports.SHARED_DOMAIN_OPS); + +},{"./util":118}],13:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +/** + * 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) + */ +exports.AXIS_PROPERTY_TYPE = { + grid: 'grid', + labelOverlap: 'main', + offset: 'main', + title: 'main' +}; +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]; +} +exports.isAxisProperty = isAxisProperty; +exports.VG_AXIS_PROPERTIES = util_1.flagKeys(VG_AXIS_PROPERTIES_INDEX); +// Export for dependent projects +exports.AXIS_PROPERTIES = util_1.flagKeys(AXIS_PROPERTIES_INDEX); + +},{"./util":118}],14:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var util_1 = require("./util"); +function binToString(bin) { + if (util_1.isBoolean(bin)) { + return 'bin'; + } + return 'bin' + util_1.keys(bin).map(function (p) { return ("_" + p + "_" + bin[p]).replace(',', '_'); }).join(''); +} +exports.binToString = binToString; +function autoMaxBins(channel) { + switch (channel) { + case channel_1.ROW: + case channel_1.COLUMN: + case channel_1.SIZE: + case channel_1.COLOR: + case channel_1.OPACITY: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule + case channel_1.SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } +} +exports.autoMaxBins = autoMaxBins; + +},{"./channel":15,"./util":118}],15:[function(require,module,exports){ +"use strict"; +/* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var Channel; +(function (Channel) { + // Facet + Channel.ROW = 'row'; + Channel.COLUMN = 'column'; + // Position + Channel.X = 'x'; + Channel.Y = 'y'; + Channel.X2 = 'x2'; + Channel.Y2 = 'y2'; + // Mark property with scale + Channel.COLOR = 'color'; + Channel.SHAPE = 'shape'; + Channel.SIZE = 'size'; + Channel.OPACITY = 'opacity'; + // Non-scale channel + Channel.TEXT = 'text'; + Channel.ORDER = 'order'; + Channel.DETAIL = 'detail'; + Channel.TOOLTIP = 'tooltip'; +})(Channel = exports.Channel || (exports.Channel = {})); +exports.X = Channel.X; +exports.Y = Channel.Y; +exports.X2 = Channel.X2; +exports.Y2 = Channel.Y2; +exports.ROW = Channel.ROW; +exports.COLUMN = Channel.COLUMN; +exports.SHAPE = Channel.SHAPE; +exports.SIZE = Channel.SIZE; +exports.COLOR = Channel.COLOR; +exports.TEXT = Channel.TEXT; +exports.DETAIL = Channel.DETAIL; +exports.ORDER = Channel.ORDER; +exports.OPACITY = Channel.OPACITY; +exports.TOOLTIP = Channel.TOOLTIP; +var UNIT_CHANNEL_INDEX = { + x: 1, + y: 1, + x2: 1, + y2: 1, + size: 1, + shape: 1, + color: 1, + order: 1, + opacity: 1, + text: 1, + detail: 1, + tooltip: 1 +}; +var FACET_CHANNEL_INDEX = { + row: 1, + column: 1 +}; +var CHANNEL_INDEX = __assign({}, UNIT_CHANNEL_INDEX, FACET_CHANNEL_INDEX); +exports.CHANNELS = util_1.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 projecttion won't work with "detail" and "order".) + */ +exports.SINGLE_DEF_CHANNELS = util_1.flagKeys(SINGLE_DEF_CHANNEL_INDEX); +function isChannel(str) { + return !!CHANNEL_INDEX[str]; +} +exports.isChannel = isChannel; +// CHANNELS without COLUMN, ROW +exports.UNIT_CHANNELS = util_1.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, +// The rest of unit channels then have scale +NONPOSITION_CHANNEL_INDEX = __rest(UNIT_CHANNEL_INDEX, ["x", "y", "x2", "y2"]); +exports.NONPOSITION_CHANNELS = util_1.flagKeys(NONPOSITION_CHANNEL_INDEX); +// POSITION_SCALE_CHANNELS = X and Y; +var POSITION_SCALE_CHANNEL_INDEX = { x: 1, y: 1 }; +exports.POSITION_SCALE_CHANNELS = util_1.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 has format instead of scale +_t = NONPOSITION_CHANNEL_INDEX.text, _tt = NONPOSITION_CHANNEL_INDEX.tooltip, +// detail and order have no scale +_dd = NONPOSITION_CHANNEL_INDEX.detail, _oo = NONPOSITION_CHANNEL_INDEX.order, NONPOSITION_SCALE_CHANNEL_INDEX = __rest(NONPOSITION_CHANNEL_INDEX, ["text", "tooltip", "detail", "order"]); +exports.NONPOSITION_SCALE_CHANNELS = util_1.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 */ +exports.SCALE_CHANNELS = util_1.flagKeys(SCALE_CHANNEL_INDEX); +function isScaleChannel(channel) { + return !!SCALE_CHANNEL_INDEX[channel]; +} +exports.isScaleChannel = isScaleChannel; +/** + * 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); +} +exports.supportMark = supportMark; +/** + * 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 exports.X: + case exports.Y: + case exports.COLOR: + case exports.DETAIL: + case exports.TOOLTIP: + case exports.ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case exports.OPACITY: + case exports.ROW: + case exports.COLUMN: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, area: true, text: true + }; + case exports.X2: + case exports.Y2: + return { + rule: true, bar: true, rect: true, area: true + }; + case exports.SIZE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, text: true, line: true + }; + case exports.SHAPE: + return { point: true }; + case exports.TEXT: + return { text: true }; + } +} +exports.getSupportedMark = getSupportedMark; +function rangeType(channel) { + switch (channel) { + case exports.X: + case exports.Y: + case exports.SIZE: + case exports.OPACITY: + // X2 and Y2 use X and Y scales, so they similarly have continuous range. + case exports.X2: + case exports.Y2: + return 'continuous'; + case exports.ROW: + case exports.COLUMN: + case exports.SHAPE: + // TEXT and TOOLTIP have no scale but have discrete output + case exports.TEXT: + case exports.TOOLTIP: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case exports.COLOR: + return 'flexible'; + // No scale, no range type. + case exports.DETAIL: + case exports.ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('getSupportedRole not implemented for ' + channel); +} +exports.rangeType = rangeType; + +},{"./util":118}],16:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var mainAxisReducer = getAxisReducer('main'); +var gridAxisReducer = getAxisReducer('grid'); +function getAxisReducer(axisType) { + return function (axes, axis) { + if (axis[axisType]) { + // Need to cast here so it's not longer partial type. + axes.push(axis[axisType].combine()); + } + return axes; + }; +} +function assembleAxes(axisComponents) { + return [].concat(axisComponents.x ? [].concat(axisComponents.x.reduce(mainAxisReducer, []), axisComponents.x.reduce(gridAxisReducer, [])) : [], axisComponents.y ? [].concat(axisComponents.y.reduce(mainAxisReducer, []), axisComponents.y.reduce(gridAxisReducer, [])) : []); +} +exports.assembleAxes = assembleAxes; + +},{}],17:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var split_1 = require("../split"); +var AxisComponentPart = /** @class */ (function (_super) { + __extends(AxisComponentPart, _super); + function AxisComponentPart() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AxisComponentPart; +}(split_1.Split)); +exports.AxisComponentPart = AxisComponentPart; + +},{"../split":89}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +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; +} +exports.getAxisConfig = getAxisConfig; + +},{}],19:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var config_1 = require("./config"); +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 (fielddef_1.isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === scale_1.ScaleType.UTC; + labelsSpec.text = { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale) + }; + } + // Label Angle + var angle = config_1.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 && channel === 'x') { + var align = labelAlign(angle, orient); + if (align) { + labelsSpec.align = { value: align }; + } + // Auto set baseline if x is rotated by 90, or -90 + if (util_1.contains([90, 270], angle)) { + labelsSpec.baseline = { value: 'middle' }; + } + } + labelsSpec = __assign({}, labelsSpec, specifiedLabelsSpec); + return util_1.keys(labelsSpec).length === 0 ? undefined : labelsSpec; +} +exports.labels = labels; +function labelAngle(axis, channel, fieldDef) { + if (axis.labelAngle !== undefined) { + // Make angle within [0,360) + return ((axis.labelAngle % 360) + 360) % 360; + } + else { + if (channel === channel_1.X && util_1.contains([type_1.NOMINAL, type_1.ORDINAL], fieldDef.type)) { + return 270; + } + } + return undefined; +} +exports.labelAngle = labelAngle; +function labelAlign(angle, orient) { + if (angle > 0) { + if (angle % 360 > 180) { + return orient === 'top' ? 'left' : 'right'; + } + else if (angle % 360 < 180) { + return orient === 'top' ? 'right' : 'left'; + } + } + else if (angle < 0) { + return labelAlign((angle % 360) + 360 /* convert to positive value*/, orient); + } + return undefined; +} +exports.labelAlign = labelAlign; + +},{"../../channel":15,"../../fielddef":100,"../../scale":108,"../../type":117,"../../util":118,"../common":24,"./config":18}],20:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var axis_1 = require("../../axis"); +var channel_1 = require("../../channel"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var resolve_1 = require("../resolve"); +var split_1 = require("../split"); +var component_1 = require("./component"); +var config_1 = require("./config"); +var encode = require("./encode"); +var properties = require("./properties"); +var AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title']; +function parseUnitAxis(model) { + return channel_1.POSITION_SCALE_CHANNELS.reduce(function (axis, channel) { + if (model.axis(channel)) { + var axisComponent = {}; + // TODO: support multiple axis + var main = parseMainAxis(channel, model); + if (main && isVisibleAxis(main)) { + axisComponent.main = main; + } + var grid = parseGridAxis(channel, model); + if (grid && isVisibleAxis(grid)) { + axisComponent.grid = grid; + } + axis[channel] = [axisComponent]; + } + return axis; + }, {}); +} +exports.parseUnitAxis = parseUnitAxis; +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 = util_1.keys(child.component.axes); _c < _d.length; _c++) { + var channel = _d[_c]; + resolve.axis[channel] = resolve_1.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.main.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.main.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]; + } + } +} +exports.parseLayerAxis = parseLayerAxis; +function mergeAxisComponents(mergedAxisCmpts, childAxisCmpts) { + if (mergedAxisCmpts) { + 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 mergedMain = mergedAxisCmpts[i].main; + var childMain = childAxisCmpts[i].main; + if ((!!mergedMain) !== (!!childMain)) { + return undefined; + } + else if (mergedMain && childMain) { + var mergedOrient = mergedMain.getWithExplicit('orient'); + var childOrient = childMain.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].main = mergeAxisComponentPart(mergedMain, childMain); + } + } + var mergedGrid = mergedAxisCmpts[i].grid; + var childGrid = childAxisCmpts[i].grid; + if ((!!mergedGrid) !== (!!childGrid)) { + return undefined; + } + else if (mergedGrid && childGrid) { + mergedAxisCmpts[i].grid = mergeAxisComponentPart(mergedGrid, childGrid); + } + } + } + else { + // For first one, return a copy of the child + return childAxisCmpts.map(function (axisComponent) { return (__assign({}, (axisComponent.main ? { main: axisComponent.main.clone() } : {}), (axisComponent.grid ? { grid: axisComponent.grid.clone() } : {}))); }); + } + return mergedAxisCmpts; +} +function mergeAxisComponentPart(merged, child) { + var _loop_1 = function (prop) { + var mergedValueWithExplicit = split_1.mergeValuesWithExplicit(merged.getWithExplicit(prop), child.getWithExplicit(prop), prop, 'axis', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return common_1.titleMerger(v1, v2); + case 'gridScale': + return { + explicit: v1.explicit, + value: v1.value || v2.value + }; + } + return split_1.defaultTieBreaker(v1, v2, prop, 'axis'); + }); + merged.setWithExplicit(prop, mergedValueWithExplicit); + }; + for (var _i = 0, VG_AXIS_PROPERTIES_1 = axis_1.VG_AXIS_PROPERTIES; _i < VG_AXIS_PROPERTIES_1.length; _i++) { + var prop = VG_AXIS_PROPERTIES_1[_i]; + _loop_1(prop); + } + return merged; +} +function isFalseOrNull(v) { + return v === false || v === null; +} +/** + * Return if an axis is visible (shows at least one part of the axis). + */ +function isVisibleAxis(axis) { + return util_1.some(AXIS_PARTS, function (part) { return hasAxisPart(axis, part); }); +} +function hasAxisPart(axis, part) { + // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme. + if (part === 'axis') { + return true; + } + if (part === 'grid' || part === 'title') { + return !!axis.get(part); + } + // Other parts are enabled by default, so they should not be false or null. + return !isFalseOrNull(axis.get(part)); +} +/** + * Make an inner axis for showing grid for shared axis. + */ +function parseGridAxis(channel, model) { + // FIXME: support adding ticks for grid axis that are inner axes of faceted plots. + return parseAxis(channel, model, true); +} +exports.parseGridAxis = parseGridAxis; +function parseMainAxis(channel, model) { + return parseAxis(channel, model, false); +} +exports.parseMainAxis = parseMainAxis; +function parseAxis(channel, model, isGridAxis) { + var axis = model.axis(channel); + var axisComponent = new component_1.AxisComponentPart(); + // 1.2. Add properties + axis_1.VG_AXIS_PROPERTIES.forEach(function (property) { + var value = getProperty(property, axis, channel, model, isGridAxis); + 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 : + value === axis[property]; + var configValue = config_1.getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type')); + if (explicit || configValue === undefined || + // A lot of rules need to be applied for the grid axis + // FIXME: this is not perfectly correct, but we need to rewrite axis component to have one axis and separate them later during assembly anyway. + isGridAxis) { + // Do not apply implicit rule if there is a config value + axisComponent.set(property, value, explicit); + } + } + }); + // 2) Add guide encode definition groups + var axisEncoding = axis.encoding || {}; + var axisEncode = AXIS_PARTS.reduce(function (e, part) { + if (!hasAxisPart(axisComponent, part)) { + // No need to create encode for a disabled part. + return e; + } + var value = part === 'labels' ? + encode.labels(model, channel, axisEncoding.labels || {}, axisComponent.get('orient')) : + axisEncoding[part] || {}; + if (value !== undefined && util_1.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 (util_1.keys(axisEncode).length > 0) { + axisComponent.set('encode', axisEncode, !!axis.encoding || !!axis.labelAngle); + } + return axisComponent; +} +function getProperty(property, specifiedAxis, channel, model, isGridAxis) { + var fieldDef = model.fieldDef(channel); + if ((isGridAxis && axis_1.AXIS_PROPERTY_TYPE[property] === 'main') || + (!isGridAxis && axis_1.AXIS_PROPERTY_TYPE[property] === 'grid')) { + // Do not apply unapplicable properties + return undefined; + } + switch (property) { + case 'scale': + return model.scaleName(channel); + case 'gridScale': + return properties.gridScale(model, channel, isGridAxis); + case 'domain': + return properties.domain(property, specifiedAxis, isGridAxis, channel); + case 'format': + // We don't include temporal field here as we apply format in encode block + return common_1.numberFormat(fieldDef, specifiedAxis.format, model.config); + case 'grid': { + var scaleType = model.getScaleComponent(channel).get('type'); + return common_1.getSpecifiedOrDefaultValue(specifiedAxis.grid, properties.grid(scaleType, fieldDef)); + } + case 'labels': + return isGridAxis ? false : specifiedAxis.labels; + case 'labelFlush': + return properties.labelFlush(fieldDef, channel, specifiedAxis, isGridAxis); + case 'labelOverlap': { + var scaleType = model.getScaleComponent(channel).get('type'); + return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType); + } + case 'minExtent': { + return properties.minMaxExtent(specifiedAxis.minExtent, isGridAxis); + } + case 'maxExtent': { + return properties.minMaxExtent(specifiedAxis.maxExtent, isGridAxis); + } + case 'orient': + return common_1.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 common_1.getSpecifiedOrDefaultValue(specifiedAxis.tickCount, properties.tickCount(channel, fieldDef, scaleType, size)); + } + case 'ticks': + return properties.ticks(property, specifiedAxis, isGridAxis, channel); + case 'title': + return common_1.getSpecifiedOrDefaultValue(specifiedAxis.title, properties.title(specifiedAxis.titleMaxLength, fieldDef, model.config)); + case 'values': + return properties.values(specifiedAxis, model, fieldDef); + case 'zindex': + return common_1.getSpecifiedOrDefaultValue(specifiedAxis.zindex, properties.zindex(isGridAxis)); + } + // Otherwise, return specified property. + return axis_1.isAxisProperty(property) ? specifiedAxis[property] : undefined; +} + +},{"../../axis":13,"../../channel":15,"../../util":118,"../common":24,"../resolve":69,"../split":89,"./component":17,"./config":18,"./encode":19,"./properties":21}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bin_1 = require("../../bin"); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function domainAndTicks(property, specifiedAxis, isGridAxis, channel) { + if (isGridAxis) { + return false; + } + return specifiedAxis[property]; +} +exports.domainAndTicks = domainAndTicks; +exports.domain = domainAndTicks; +exports.ticks = domainAndTicks; +// 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 !scale_1.hasDiscreteDomain(scaleType) && !fieldDef.bin; +} +exports.grid = grid; +function gridScale(model, channel, isGridAxis) { + if (isGridAxis) { + var gridChannel = channel === 'x' ? 'y' : 'x'; + if (model.getScaleComponent(gridChannel)) { + return model.scaleName(gridChannel); + } + } + return undefined; +} +exports.gridScale = gridScale; +function labelFlush(fieldDef, channel, specifiedAxis, isGridAxis) { + if (isGridAxis) { + return undefined; + } + if (specifiedAxis.labelFlush !== undefined) { + return specifiedAxis.labelFlush; + } + if (channel === 'x' && util_1.contains(['quantitative', 'temporal'], fieldDef.type)) { + return true; + } + return undefined; +} +exports.labelFlush = labelFlush; +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; +} +exports.labelOverlap = labelOverlap; +function minMaxExtent(specifiedExtent, isGridAxis) { + if (isGridAxis) { + // Always return 0 to make sure that `config.axis*.minExtent` and `config.axis*.maxExtent` + // would not affect gridAxis + return 0; + } + else { + return specifiedExtent; + } +} +exports.minMaxExtent = minMaxExtent; +function orient(channel) { + switch (channel) { + case channel_1.X: + return 'bottom'; + case channel_1.Y: + return 'left'; + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS); +} +exports.orient = orient; +function tickCount(channel, fieldDef, scaleType, size) { + if (!scale_1.hasDiscreteDomain(scaleType) && scaleType !== 'log' && !util_1.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; +} +exports.tickCount = tickCount; +function title(maxLength, fieldDef, config) { + // if not defined, automatically determine axis title from field def + var fieldTitle = fielddef_1.title(fieldDef, config); + return maxLength ? util_1.truncate(fieldTitle, maxLength) : fieldTitle; +} +exports.title = title; +function values(specifiedAxis, model, fieldDef) { + var vals = specifiedAxis.values; + if (specifiedAxis.values && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return { signal: datetime_1.dateTimeExpr(dt, true) }; + }); + } + if (!vals && fieldDef.bin && fieldDef.type === type_1.QUANTITATIVE) { + var signal = model.getName(bin_1.binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return { signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }; + } + return vals; +} +exports.values = values; +function zindex(isGridAxis) { + if (isGridAxis) { + // if grid is true, need to put layer on the back so that grid is behind marks + return 0; + } + return 1; // otherwise return undefined and use Vega's default. +} +exports.zindex = zindex; + +},{"../../bin":14,"../../channel":15,"../../datetime":97,"../../fielddef":100,"../../log":105,"../../scale":108,"../../type":117,"../../util":118}],22:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../util"); +var parse_1 = require("./data/parse"); +var assemble_1 = require("./layoutsize/assemble"); +var model_1 = require("./model"); +var BaseConcatModel = /** @class */ (function (_super) { + __extends(BaseConcatModel, _super); + function BaseConcatModel(spec, parent, parentGivenName, config, resolve) { + return _super.call(this, spec, parent, parentGivenName, config, resolve) || this; + } + BaseConcatModel.prototype.parseData = function () { + this.component.data = parse_1.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(); + util_1.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()); + }, assemble_1.assembleLayoutSignals(this)); + }; + BaseConcatModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, []); + }; + 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_1.Model)); +exports.BaseConcatModel = BaseConcatModel; + +},{"../util":118,"./data/parse":40,"./layoutsize/assemble":47,"./model":66}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var spec_1 = require("../spec"); +var concat_1 = require("./concat"); +var facet_1 = require("./facet"); +var layer_1 = require("./layer"); +var repeat_1 = require("./repeat"); +var unit_1 = require("./unit"); +function buildModel(spec, parent, parentGivenName, unitSize, repeater, config, fit) { + if (spec_1.isFacetSpec(spec)) { + return new facet_1.FacetModel(spec, parent, parentGivenName, repeater, config); + } + if (spec_1.isLayerSpec(spec)) { + return new layer_1.LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (spec_1.isUnitSpec(spec)) { + return new unit_1.UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (spec_1.isRepeatSpec(spec)) { + return new repeat_1.RepeatModel(spec, parent, parentGivenName, repeater, config); + } + if (spec_1.isConcatSpec(spec)) { + return new concat_1.ConcatModel(spec, parent, parentGivenName, repeater, config); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.buildModel = buildModel; + +},{"../log":105,"../spec":111,"./concat":26,"./facet":44,"./layer":45,"./repeat":67,"./unit":90}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var fielddef_1 = require("../fielddef"); +var scale_1 = require("../scale"); +var timeunit_1 = require("../timeunit"); +var type_1 = require("../type"); +var util_1 = require("../util"); +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; +} +exports.applyConfig = applyConfig; +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; +} +exports.applyMarkConfig = applyMarkConfig; +function getStyles(mark) { + return [].concat(mark.type, mark.style || []); +} +exports.getStyles = getStyles; +/** + * 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; +} +exports.getMarkConfig = getMarkConfig; +function formatSignalRef(fieldDef, specifiedFormat, expr, config) { + var format = numberFormat(fieldDef, specifiedFormat, config); + if (fieldDef.bin) { + var startField = fielddef_1.field(fieldDef, { expr: expr }); + var endField = fielddef_1.field(fieldDef, { expr: expr, binSuffix: 'end' }); + return { + signal: binFormatExpression(startField, endField, format, config) + }; + } + else if (fieldDef.type === 'quantitative') { + return { + signal: "" + formatExpr(fielddef_1.field(fieldDef, { expr: expr }), format) + }; + } + else if (fielddef_1.isTimeFieldDef(fieldDef)) { + var isUTCScale = fielddef_1.isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === scale_1.ScaleType.UTC; + return { + signal: timeFormatExpression(fielddef_1.field(fieldDef, { expr: expr }), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale) + }; + } + else { + return { + signal: "''+" + fielddef_1.field(fieldDef, { expr: expr }) + }; + } +} +exports.formatSignalRef = formatSignalRef; +function getSpecifiedOrDefaultValue(specifiedValue, defaultValue) { + if (specifiedValue !== undefined) { + return specifiedValue; + } + return defaultValue; +} +exports.getSpecifiedOrDefaultValue = getSpecifiedOrDefaultValue; +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +function numberFormat(fieldDef, specifiedFormat, config) { + if (fieldDef.type === type_1.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; +} +exports.numberFormat = numberFormat; +function formatExpr(field, format) { + return "format(" + field + ", \"" + (format || '') + "\")"; +} +function numberFormatExpr(field, specifiedFormat, config) { + return formatExpr(field, specifiedFormat || config.numberFormat); +} +exports.numberFormatExpr = numberFormatExpr; +function binFormatExpression(startField, endField, format, config) { + return startField + " === null || isNaN(" + startField + ") ? \"null\" : " + numberFormatExpr(startField, format, config) + " + \" - \" + " + numberFormatExpr(endField, format, config); +} +exports.binFormatExpression = binFormatExpression; +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +function timeFormatExpression(field, timeUnit, format, shortTimeLabels, timeFormatConfig, isUTCScale) { + if (!timeUnit || format) { + // If there is not time unit, or if user explicitly specify format for axis/legend/text. + var _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit. + if (isUTCScale) { + return "utcFormat(" + field + ", '" + _format + "')"; + } + else { + return "timeFormat(" + field + ", '" + _format + "')"; + } + } + else { + return timeunit_1.formatExpression(timeUnit, field, shortTimeLabels, isUTCScale); + } +} +exports.timeFormatExpression = timeFormatExpression; +/** + * Return Vega sort parameters (tuple of field and order). + */ +function sortParams(orderDef, fieldRefOption) { + return (util_1.isArray(orderDef) ? orderDef : [orderDef]).reduce(function (s, orderChannelDef) { + s.field.push(fielddef_1.field(orderChannelDef, fieldRefOption)); + s.order.push(orderChannelDef.sort || 'ascending'); + return s; + }, { field: [], order: [] }); +} +exports.sortParams = sortParams; +function titleMerger(v1, v2) { + return { + explicit: v1.explicit, + value: v1.value === v2.value ? + v1.value : // if title is the same just use one of them + v1.value + ', ' + v2.value // join title with comma if different + }; +} +exports.titleMerger = titleMerger; +/** + * 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 channel_1.isScaleChannel(channel) && util_1.contains(['ordinal', 'nominal'], fieldDef.type); +} +exports.binRequiresRange = binRequiresRange; + +},{"../channel":15,"../fielddef":100,"../scale":108,"../timeunit":113,"../type":117,"../util":118}],25:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var config_1 = require("../config"); +var vlFieldDef = require("../fielddef"); +var log = require("../log"); +var spec_1 = require("../spec"); +var toplevelprops_1 = require("../toplevelprops"); +var util_1 = require("../util"); +var buildmodel_1 = require("./buildmodel"); +var assemble_1 = require("./data/assemble"); +var optimize_1 = require("./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 + * | + * | (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 + 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 = config_1.initConfig(util_1.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 = spec_1.normalize(inputSpec, config); + // - Normalize autosize to be a autosize properties object. + var autosize = toplevelprops_1.normalizeAutoSize(inputSpec.autosize, config.autosize, spec_1.isLayerSpec(spec) || spec_1.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_1.buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit'); + // 4 Parse: Model --> Model with components (components = intermediate that can be merged + // and assembled easily) + // 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. + optimize_1.optimizeDataflow(model.component.data); + // 6. Assemble: convert model and 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(); + } + } +} +exports.compile = compile; +function getTopLevelProperties(topLevelSpec, config, autosize) { + return __assign({ autosize: util_1.keys(autosize).length === 1 && autosize.type ? autosize.type : autosize }, toplevelprops_1.extractTopLevelProperties(config), toplevelprops_1.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 ? config_1.stripAndRedirectConfig(model.config) : undefined; + 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 = __assign({ $schema: 'https://vega.github.io/schema/vega/v3.0.json' }, (model.description ? { description: model.description } : {}), topLevelProperties, (title ? { title: title } : {}), (style ? { style: style } : {}), { data: [].concat(model.assembleSelectionData([]), + // only assemble data in the root + assemble_1.assembleRootData(model.component.data)) }, model.assembleGroup(layoutSignals.concat(model.assembleSelectionTopLevelSignals([]))), (vgConfig ? { config: vgConfig } : {})); + return { + spec: output + // TODO: add warning / errors here + }; +} + +},{"../config":95,"../fielddef":100,"../log":105,"../spec":111,"../toplevelprops":115,"../util":118,"./buildmodel":23,"./data/assemble":28,"./data/optimize":38}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var spec_1 = require("../spec"); +var baseconcat_1 = require("./baseconcat"); +var buildmodel_1 = require("./buildmodel"); +var parse_1 = require("./layoutsize/parse"); +var ConcatModel = /** @class */ (function (_super) { + __extends(ConcatModel, _super); + function ConcatModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, 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 = spec_1.isVConcatSpec(spec); + _this.children = (spec_1.isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map(function (child, i) { + return buildmodel_1.buildModel(child, _this, _this.getName('concat_' + i), undefined, repeater, config, false); + }); + return _this; + } + ConcatModel.prototype.parseLayoutSize = function () { + parse_1.parseConcatLayoutSize(this); + }; + ConcatModel.prototype.parseAxisGroup = function () { + return null; + }; + ConcatModel.prototype.assembleLayout = function () { + // TODO: allow customization + return __assign({ padding: { row: 10, column: 10 }, offset: 10 }, (this.isVConcat ? { columns: 1 } : {}), { bounds: 'full', + // Use align each so it can work with multiple plots with different size + align: 'each' }); + }; + return ConcatModel; +}(baseconcat_1.BaseConcatModel)); +exports.ConcatModel = ConcatModel; + +},{"../log":105,"../spec":111,"./baseconcat":22,"./buildmodel":23,"./layoutsize/parse":48}],27:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var dataflow_1 = require("./dataflow"); +function addDimension(dims, channel, fieldDef) { + if (fieldDef.bin) { + dims[fielddef_1.field(fieldDef, {})] = true; + dims[fielddef_1.field(fieldDef, { binSuffix: 'end' })] = true; + if (common_1.binRequiresRange(fieldDef, channel)) { + dims[fielddef_1.field(fieldDef, { binSuffix: 'range' })] = true; + } + } + else { + dims[fielddef_1.field(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(dimensions, measures) { + var _this = _super.call(this) || this; + _this.dimensions = dimensions; + _this.measures = measures; + return _this; + } + AggregateNode.prototype.clone = function () { + return new AggregateNode(__assign({}, this.dimensions), util_1.duplicate(this.measures)); + }; + AggregateNode.makeFromEncoding = function (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) { + if (fieldDef.aggregate) { + if (fieldDef.aggregate === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = fielddef_1.field(fieldDef, { aggregate: 'count' }); + } + else { + meas[fieldDef.field] = meas[fieldDef.field] || {}; + meas[fieldDef.field][fieldDef.aggregate] = fielddef_1.field(fieldDef); + // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain + if (channel_1.isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') { + meas[fieldDef.field]['min'] = fielddef_1.field(fieldDef, { aggregate: 'min' }); + meas[fieldDef.field]['max'] = fielddef_1.field(fieldDef, { aggregate: 'max' }); + } + } + } + else { + addDimension(dims, channel, fieldDef); + } + }); + if ((util_1.keys(dims).length + util_1.keys(meas).length) === 0) { + return null; + } + return new AggregateNode(dims, meas); + }; + AggregateNode.makeFromTransform = function (t) { + var dims = {}; + var meas = {}; + for (var _i = 0, _a = t.aggregate; _i < _a.length; _i++) { + var s = _a[_i]; + if (s.op) { + if (s.op === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = s.as || fielddef_1.field(s); + } + else { + meas[s.field] = meas[s.field] || {}; + meas[s.field][s.op] = s.as || fielddef_1.field(s); + } + } + } + for (var _b = 0, _c = t.groupby; _b < _c.length; _b++) { + var s = _c[_b]; + dims[s] = true; + } + if ((util_1.keys(dims).length + util_1.keys(meas).length) === 0) { + return null; + } + return new AggregateNode(dims, meas); + }; + AggregateNode.prototype.merge = function (other) { + if (!util_1.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 = {}; + util_1.keys(this.dimensions).forEach(function (f) { return out[f] = true; }); + util_1.keys(this.measures).forEach(function (m) { return out[m] = true; }); + return out; + }; + AggregateNode.prototype.producedFields = function () { + var _this = this; + var out = {}; + util_1.keys(this.measures).forEach(function (field) { + util_1.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 = util_1.keys(this.measures); _i < _a.length; _i++) { + var field_1 = _a[_i]; + for (var _b = 0, _c = util_1.keys(this.measures[field_1]); _b < _c.length; _b++) { + var op = _c[_b]; + as.push(this.measures[field_1][op]); + ops.push(op); + fields.push(field_1); + } + } + var result = { + type: 'aggregate', + groupby: util_1.keys(this.dimensions), + ops: ops, + fields: fields, + as: as + }; + return result; + }; + return AggregateNode; +}(dataflow_1.DataFlowNode)); +exports.AggregateNode = AggregateNode; + +},{"../../channel":15,"../../fielddef":100,"../../log":105,"../../util":118,"../common":24,"./dataflow":31}],28:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var aggregate_1 = require("./aggregate"); +var bin_1 = require("./bin"); +var calculate_1 = require("./calculate"); +var dataflow_1 = require("./dataflow"); +var facet_1 = require("./facet"); +var filter_1 = require("./filter"); +var filterinvalid_1 = require("./filterinvalid"); +var formatparse_1 = require("./formatparse"); +var indentifier_1 = require("./indentifier"); +var lookup_1 = require("./lookup"); +var source_1 = require("./source"); +var stack_1 = require("./stack"); +var timeunit_1 = require("./timeunit"); +/** + * 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 source_1.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 (!data_1.isUrlData(node.data)) { + data.push(dataSource); + var newData = { + name: null, + source: dataSource.name, + transform: [] + }; + dataSource = newData; + } + } + if (node instanceof formatparse_1.ParseNode) { + if (node.parent instanceof source_1.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() }); + } + else { + // Otherwise use Vega expression to parse + dataSource.transform = dataSource.transform.concat(node.assembleTransforms()); + } + } + if (node instanceof facet_1.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 filter_1.FilterNode || + node instanceof calculate_1.CalculateNode || + node instanceof aggregate_1.AggregateNode || + node instanceof lookup_1.LookupNode || + node instanceof indentifier_1.IdentifierNode) { + dataSource.transform.push(node.assemble()); + } + if (node instanceof filterinvalid_1.FilterInvalidNode || + node instanceof bin_1.BinNode || + node instanceof timeunit_1.TimeUnitNode || + node instanceof stack_1.StackNode) { + dataSource.transform = dataSource.transform.concat(node.assemble()); + } + if (node instanceof aggregate_1.AggregateNode) { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + } + if (node instanceof dataflow_1.OutputNode) { + if (dataSource.source && dataSource.transform.length === 0) { + node.setSource(dataSource.source); + } + else if (node.parent instanceof dataflow_1.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 dataflow_1.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_2 = dataSource.name; + if (!dataSource.source || dataSource.transform.length > 0) { + data.push(dataSource); + } + else { + source_2 = dataSource.source; + } + node.children.forEach(function (child) { + var newData = { + name: null, + source: source_2, + 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; +} +exports.assembleFacetData = assembleFacetData; +/** + * 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) { + var roots = util_1.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 + data.sort(function (a, b) { return (a.transform || []).length === 0 ? -1 : ((b.transform || []).length === 0 ? 1 : 0); }); + // now fix the from references in lookup transforms + for (var _i = 0, data_2 = data; _i < data_2.length; _i++) { + var d = data_2[_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(); + } + } + } + return data; +} +exports.assembleRootData = assembleRootData; + +},{"../../data":96,"../../util":118,"./aggregate":27,"./bin":29,"./calculate":30,"./dataflow":31,"./facet":32,"./filter":33,"./filterinvalid":34,"./formatparse":35,"./indentifier":36,"./lookup":37,"./source":41,"./stack":42,"./timeunit":43}],29:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var bin_1 = require("../../bin"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var model_1 = require("../model"); +var dataflow_1 = require("./dataflow"); +function rangeFormula(model, fieldDef, channel, config) { + if (common_1.binRequiresRange(fieldDef, channel)) { + // read format from axis or legend, if there is no format then use config.numberFormat + var guide = model_1.isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {}; + var startField = fielddef_1.field(fieldDef, { expr: 'datum', }); + var endField = fielddef_1.field(fieldDef, { expr: 'datum', binSuffix: 'end' }); + return { + formulaAs: fielddef_1.field(fieldDef, { binSuffix: 'range' }), + formula: common_1.binFormatExpression(startField, endField, guide.format, config) + }; + } + return {}; +} +function binKey(bin, field) { + return bin_1.binToString(bin) + "_" + field; +} +function isModelParams(p) { + return !!p['model']; +} +function getSignalsFromParams(params, key) { + if (isModelParams(params)) { + var model = params.model; + return { + signal: model.getName(key + "_bins"), + extentSignal: model.getName(key + "_extent") + }; + } + return params; +} +function isBinTransform(t) { + return 'as' in t; +} +function createBinComponent(t, params) { + var as; + if (isBinTransform(t)) { + as = [t.as, t.as + "_end"]; + } + else { + as = [fielddef_1.field(t, {}), fielddef_1.field(t, { binSuffix: 'end' })]; + } + var bin = fielddef_1.normalizeBin(t.bin, undefined) || {}; + var key = binKey(bin, t.field); + var _a = getSignalsFromParams(params, key), 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, binComponent: binComponent }; +} +var BinNode = /** @class */ (function (_super) { + __extends(BinNode, _super); + function BinNode(bins) { + var _this = _super.call(this) || this; + _this.bins = bins; + return _this; + } + BinNode.prototype.clone = function () { + return new BinNode(util_1.duplicate(this.bins)); + }; + BinNode.makeBinFromEncoding = function (model) { + var bins = model.reduceFieldDef(function (binComponentIndex, fieldDef, channel) { + if (fieldDef.bin) { + var _a = createBinComponent(fieldDef, { model: model }), key = _a.key, binComponent = _a.binComponent; + binComponentIndex[key] = __assign({}, binComponent, binComponentIndex[key], rangeFormula(model, fieldDef, channel, model.config)); + } + return binComponentIndex; + }, {}); + if (util_1.keys(bins).length === 0) { + return null; + } + return new BinNode(bins); + }; + /** + * Creates a bin node from BinTransform. + * The optional parameter should provide + */ + BinNode.makeFromTransform = function (t, params) { + var _a = createBinComponent(t, params), key = _a.key, binComponent = _a.binComponent; + return new BinNode((_b = {}, + _b[key] = binComponent, + _b)); + var _b; + }; + BinNode.prototype.merge = function (other) { + this.bins = __assign({}, this.bins, other.bins); + other.remove(); + }; + BinNode.prototype.producedFields = function () { + var out = {}; + util_1.vals(this.bins).forEach(function (c) { + c.as.forEach(function (f) { return out[f] = true; }); + }); + return out; + }; + BinNode.prototype.dependentFields = function () { + var out = {}; + util_1.vals(this.bins).forEach(function (c) { + out[c.field] = true; + }); + return out; + }; + BinNode.prototype.assemble = function () { + return util_1.flatten(util_1.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; +}(dataflow_1.DataFlowNode)); +exports.BinNode = BinNode; + +},{"../../bin":14,"../../fielddef":100,"../../util":118,"../common":24,"../model":66,"./dataflow":31}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var dataflow_1 = require("./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) { + __extends(CalculateNode, _super); + function CalculateNode(transform) { + var _this = _super.call(this) || this; + _this.transform = transform; + return _this; + } + CalculateNode.prototype.clone = function () { + return new CalculateNode(util_1.duplicate(this.transform)); + }; + 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; +}(dataflow_1.DataFlowNode)); +exports.CalculateNode = CalculateNode; + +},{"../../util":118,"./dataflow":31}],31:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * A node in the dataflow tree. + */ +var DataFlowNode = /** @class */ (function () { + function DataFlowNode(debugName) { + this.debugName = debugName; + this._children = []; + this._parent = null; + } + /** + * 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; +}()); +exports.DataFlowNode = 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(source, type, refCounts) { + var _this = _super.call(this, 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)); +exports.OutputNode = OutputNode; + +},{}],32:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var domain_1 = require("../scale/domain"); +var dataflow_1 = require("./dataflow"); +/** + * 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(model, name, data) { + var _this = _super.call(this) || this; + _this.model = model; + _this.name = name; + _this.data = data; + if (model.facet.column) { + _this.columnFields = [model.field(channel_1.COLUMN)]; + _this.columnName = model.getName('column_domain'); + if (model.fieldDef(channel_1.COLUMN).bin) { + _this.columnFields.push(model.field(channel_1.COLUMN, { binSuffix: 'end' })); + } + } + if (model.facet.row) { + _this.rowFields = [model.field(channel_1.ROW)]; + _this.rowName = model.getName('row_domain'); + if (model.fieldDef(channel_1.ROW).bin) { + _this.rowFields.push(model.field(channel_1.ROW, { binSuffix: 'end' })); + } + } + _this.childModel = model.child; + return _this; + } + Object.defineProperty(FacetNode.prototype, "fields", { + get: function () { + var fields = []; + if (this.columnFields) { + fields = fields.concat(this.columnFields); + } + if (this.rowFields) { + fields = fields.concat(this.rowFields); + } + return 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 (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var domain = domain_1.assembleDomain(this.childModel, channel); + var field = domain_1.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 aggregateChildField = {}; + var childChannel = channel === 'row' ? 'y' : 'x'; + if (childIndependentFieldsWithStep[childChannel]) { + if (crossedDataName) { + aggregateChildField = { + // If there is a crossed data, calculate max + fields: ["distinct_" + childIndependentFieldsWithStep[childChannel]], + ops: ['max'], + // Although it is technically a max, just name it distinct so it's easier to refer to it + as: ["distinct_" + childIndependentFieldsWithStep[childChannel]] + }; + } + else { + aggregateChildField = { + // If there is no crossed data, just calculate distinct + fields: [childIndependentFieldsWithStep[childChannel]], + ops: ['distinct'] + }; + } + } + return { + name: channel === 'row' ? this.rowName : this.columnName, + // Use data from the crossed one if it exist + source: crossedDataName || this.data, + transform: [__assign({ type: 'aggregate', groupby: channel === 'row' ? this.rowFields : this.columnFields }, aggregateChildField)] + }; + }; + FacetNode.prototype.assemble = function () { + var data = []; + var crossedDataName = null; + var childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep(); + if (this.columnName && this.rowName && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) { + // Need to create a cross dataset to correctly calculate cardinality + crossedDataName = "cross_" + this.columnName + "_" + this.rowName; + 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.columnFields.concat(this.rowFields), + fields: fields, + ops: ops + }] + }); + } + if (this.columnName) { + data.push(this.assembleRowColumnData('column', crossedDataName, childIndependentFieldsWithStep)); + } + if (this.rowName) { + data.push(this.assembleRowColumnData('row', crossedDataName, childIndependentFieldsWithStep)); + } + return data; + }; + return FacetNode; +}(dataflow_1.DataFlowNode)); +exports.FacetNode = FacetNode; + +},{"../../channel":15,"../../log":105,"../../scale":108,"../../vega.schema":120,"../scale/domain":72,"./dataflow":31}],33:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var filter_1 = require("../../filter"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var FilterNode = /** @class */ (function (_super) { + __extends(FilterNode, _super); + function FilterNode(model, filter) { + var _this = _super.call(this) || this; + _this.model = model; + _this.filter = filter; + _this.expr = filter_1.expression(_this.model, _this.filter, _this); + return _this; + } + FilterNode.prototype.clone = function () { + return new FilterNode(this.model, util_1.duplicate(this.filter)); + }; + FilterNode.prototype.assemble = function () { + return { + type: 'filter', + expr: this.expr + }; + }; + return FilterNode; +}(dataflow_1.DataFlowNode)); +exports.FilterNode = FilterNode; + +},{"../../filter":101,"../../util":118,"./dataflow":31}],34:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var FilterInvalidNode = /** @class */ (function (_super) { + __extends(FilterInvalidNode, _super); + function FilterInvalidNode(fieldDefs) { + var _this = _super.call(this) || this; + _this.fieldDefs = fieldDefs; + return _this; + } + FilterInvalidNode.prototype.clone = function () { + return new FilterInvalidNode(__assign({}, this.fieldDefs)); + }; + FilterInvalidNode.make = function (model) { + if (model.config.invalidValues !== 'filter') { + return null; + } + var filter = model.reduceFieldDef(function (aggregator, fieldDef, channel) { + var scaleComponent = channel_1.isScaleChannel(channel) && model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + // only automatically filter null for continuous domain since discrete domain scales can handle invalid values. + if (scale_1.hasContinuousDomain(scaleType) && !fieldDef.aggregate) { + aggregator[fieldDef.field] = fieldDef; + } + } + return aggregator; + }, {}); + if (!util_1.keys(filter).length) { + return null; + } + return new FilterInvalidNode(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 = util_1.keys(this.filter).reduce(function (vegaFilters, field) { + var fieldDef = _this.fieldDefs[field]; + var ref = fielddef_1.field(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; +}(dataflow_1.DataFlowNode)); +exports.FilterInvalidNode = FilterInvalidNode; + +},{"../../channel":15,"../../fielddef":100,"../../scale":108,"../../util":118,"./dataflow":31}],35:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var aggregate_1 = require("../../aggregate"); +var fielddef_1 = require("../../fielddef"); +var filter_1 = require("../../filter"); +var log = require("../../log"); +var logical_1 = require("../../logical"); +var transform_1 = require("../../transform"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var dataflow_1 = require("./dataflow"); +function parseExpression(field, parse) { + var f = "datum" + util_1.accessPath(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.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) { + __extends(ParseNode, _super); + function ParseNode(parse) { + var _this = _super.call(this) || this; + _this._parse = {}; + _this._parse = parse; + return _this; + } + ParseNode.prototype.clone = function () { + return new ParseNode(util_1.duplicate(this.parse)); + }; + ParseNode.make = function (model) { + var parse = {}; + var calcFieldMap = {}; + (model.transforms || []).forEach(function (transform) { + if (transform_1.isCalculate(transform)) { + calcFieldMap[transform.as] = true; + } + else if (transform_1.isFilter(transform)) { + logical_1.forEachLeave(transform.filter, function (filter) { + if (filter_1.isEqualFilter(filter) || filter_1.isRangeFilter(filter) || filter_1.isOneOfFilter(filter)) { + if (filter.timeUnit) { + parse[filter.field] = 'date'; + } + } + }); + } + }, {}); + if (model_1.isUnitModel(model) || model_1.isFacetModel(model)) { + // Parse encoded fields + model.forEachFieldDef(function (fieldDef) { + if (fielddef_1.isTimeFieldDef(fieldDef)) { + parse[fieldDef.field] = 'date'; + } + else if (fielddef_1.isNumberFieldDef(fieldDef)) { + if (calcFieldMap[fieldDef.field] || aggregate_1.isCountingAggregateOp(fieldDef.aggregate)) { + return; + } + parse[fieldDef.field] = 'number'; + } + }); + } + // Custom parse should override inferred parse + var data = model.data; + if (data && data.format && data.format.parse) { + var p_1 = data.format.parse; + util_1.keys(p_1).forEach(function (field) { + parse[field] = p_1[field]; + }); + } + // We should not parse what has already been parsed in a parent + var modelParse = model.component.data.ancestorParse; + util_1.keys(modelParse).forEach(function (field) { + if (parse[field] !== modelParse[field]) { + log.warn(log.message.differentParse(field, parse[field], modelParse[field])); + } + else { + delete parse[field]; + } + }); + if (util_1.keys(parse).length === 0) { + return null; + } + return new ParseNode(parse); + }; + 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(); + }; + ParseNode.prototype.assembleFormatParse = function () { + return this._parse; + }; + // format parse depends and produces all fields in its parse + ParseNode.prototype.producedFields = function () { + return util_1.toSet(util_1.keys(this.parse)); + }; + ParseNode.prototype.dependentFields = function () { + return util_1.toSet(util_1.keys(this.parse)); + }; + ParseNode.prototype.assembleTransforms = function () { + var _this = this; + return util_1.keys(this._parse).map(function (field) { + var expr = parseExpression(field, _this._parse[field]); + if (!expr) { + return null; + } + var formula = { + type: 'formula', + expr: expr, + as: field + }; + return formula; + }).filter(function (t) { return t !== null; }); + }; + return ParseNode; +}(dataflow_1.DataFlowNode)); +exports.ParseNode = ParseNode; + +},{"../../aggregate":12,"../../fielddef":100,"../../filter":101,"../../log":105,"../../logical":106,"../../transform":116,"../../util":118,"../model":66,"./dataflow":31}],36:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("../../selection"); +var dataflow_1 = require("./dataflow"); +var IdentifierNode = /** @class */ (function (_super) { + __extends(IdentifierNode, _super); + function IdentifierNode() { + return _super.call(this) || this; + } + IdentifierNode.prototype.clone = function () { + return new IdentifierNode(); + }; + IdentifierNode.prototype.producedFields = function () { + return _a = {}, _a[selection_1.SELECTION_ID] = true, _a; + var _a; + }; + IdentifierNode.prototype.assemble = function () { + return { type: 'identifier', as: selection_1.SELECTION_ID }; + }; + return IdentifierNode; +}(dataflow_1.DataFlowNode)); +exports.IdentifierNode = IdentifierNode; + +},{"../../selection":109,"./dataflow":31}],37:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var log = require("../../log"); +var dataflow_1 = require("./dataflow"); +var source_1 = require("./source"); +var LookupNode = /** @class */ (function (_super) { + __extends(LookupNode, _super); + function LookupNode(transform, secondary) { + var _this = _super.call(this) || this; + _this.transform = transform; + _this.secondary = secondary; + return _this; + } + LookupNode.make = function (model, transform, counter) { + var sources = model.component.data.sources; + var s = new source_1.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 dataflow_1.OutputNode(fromOutputName, 'lookup', model.component.data.outputNodeRefCounts); + fromOutputNode.parent = fromSource; + model.component.data.outputNodes[fromOutputName] = fromOutputNode; + return new LookupNode(transform, fromOutputNode.getSource()); + }; + LookupNode.prototype.producedFields = function () { + return vega_util_1.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 (!vega_util_1.isString(asName)) { + log.warn(log.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; +}(dataflow_1.DataFlowNode)); +exports.LookupNode = LookupNode; + +},{"../../log":105,"./dataflow":31,"./source":41,"vega-util":10}],38:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var aggregate_1 = require("./aggregate"); +var dataflow_1 = require("./dataflow"); +var facet_1 = require("./facet"); +var filterinvalid_1 = require("./filterinvalid"); +var optimizers = require("./optimizers"); +var stack_1 = require("./stack"); +exports.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 facet_1.FacetNode)) { + var copy_1 = node.clone(); + if (copy_1 instanceof dataflow_1.OutputNode) { + var newName = exports.FACET_SCALE_PREFIX + copy_1.getSource(); + copy_1.setSource(newName); + facet.model.component.data.outputNodes[newName] = copy_1; + } + else if (copy_1 instanceof aggregate_1.AggregateNode || copy_1 instanceof stack_1.StackNode) { + copy_1.addDimensions(facet.fields); + } + util_1.flatten(node.children.map(clone)).forEach(function (n) { return n.parent = copy_1; }); + return [copy_1]; + } + return util_1.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 facet_1.FacetNode) { + if (node.numChildren() === 1 && !(node.children[0] instanceof dataflow_1.OutputNode)) { + // move down until we hit a fork or output node + var child = node.children[0]; + if (child instanceof aggregate_1.AggregateNode || child instanceof stack_1.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 = util_1.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 dataflow_1.OutputNode && node.type === data_1.MAIN) { + if (node.numChildren() === 1) { + var child = node.children[0]; + if (!(child instanceof facet_1.FacetNode)) { + child.swapWithParent(); + moveMainDownToFacet(node); + } + } + } +} +/** + * Start optimization path from the root. Useful for removing nodes. + */ +function removeUnnecessaryNodes(node) { + // remove empty null filter nodes + if (node instanceof filterinvalid_1.FilterInvalidNode && util_1.every(util_1.vals(node.filter), function (f) { return f === null; })) { + node.remove(); + } + // remove output nodes that are not required + if (node instanceof dataflow_1.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 = util_1.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); + util_1.keys(dataComponent.sources).forEach(function (s) { + if (dataComponent.sources[s].numChildren() === 0) { + delete dataComponent.sources[s]; + } + }); +} +exports.optimizeDataflow = optimizeDataflow; + +},{"../../data":96,"../../util":118,"./aggregate":27,"./dataflow":31,"./facet":32,"./filterinvalid":34,"./optimizers":39,"./stack":42}],39:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var formatparse_1 = require("./formatparse"); +var source_1 = require("./source"); +var timeunit_1 = require("./timeunit"); +/** + * 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 source_1.SourceNode) { + return; + } + var next = node.parent; + if (f(node)) { + optimizeNextFromLeaves(next); + } + } + return optimizeNextFromLeaves; +} +exports.iterateFromLeaves = iterateFromLeaves; +/** + * Move parse nodes up to forks. + */ +function moveParseUp(node) { + var parent = node.parent; + // move parse up by merging or swapping + if (node instanceof formatparse_1.ParseNode) { + if (parent instanceof source_1.SourceNode) { + return false; + } + if (parent.numChildren() > 1) { + // don't move parse further up but continue with parent. + return true; + } + if (parent instanceof formatparse_1.ParseNode) { + parent.merge(node); + } + else { + // don't swap with nodes that produce something that the parse node depends on (e.g. lookup) + if (util_1.hasIntersection(parent.producedFields(), node.dependentFields())) { + return true; + } + node.swapWithParent(); + } + } + return true; +} +exports.moveParseUp = moveParseUp; +/** + * Repeatedly remove leaf nodes that are not output nodes. + * The reason is that we don't need subtrees that don't have any output nodes. + */ +function removeUnusedSubtrees(node) { + if (node instanceof dataflow_1.OutputNode || node.numChildren() > 0) { + // 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; +} +exports.removeUnusedSubtrees = removeUnusedSubtrees; +/** + * 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 timeunit_1.TimeUnitNode) { + var pfields = node.producedFields(); + var dupe = util_1.keys(pfields).every(function (k) { return !!fields[k]; }); + if (dupe) { + node.remove(); + } + else { + fields = __assign({}, fields, pfields); + } + } + return true; + })(leaf); +} +exports.removeDuplicateTimeUnits = removeDuplicateTimeUnits; + +},{"../../util":118,"./dataflow":31,"./formatparse":35,"./source":41,"./timeunit":43}],40:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var data_1 = require("../../data"); +var datetime_1 = require("../../datetime"); +var filter_1 = require("../../filter"); +var log = require("../../log"); +var transform_1 = require("../../transform"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var selection_1 = require("../selection/selection"); +var aggregate_1 = require("./aggregate"); +var bin_1 = require("./bin"); +var calculate_1 = require("./calculate"); +var dataflow_1 = require("./dataflow"); +var facet_1 = require("./facet"); +var filter_2 = require("./filter"); +var filterinvalid_1 = require("./filterinvalid"); +var formatparse_1 = require("./formatparse"); +var indentifier_1 = require("./indentifier"); +var lookup_1 = require("./lookup"); +var source_1 = require("./source"); +var stack_1 = require("./stack"); +var timeunit_1 = require("./timeunit"); +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 source_1.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. + */ +function parseTransformArray(model) { + var first = null; + var node; + var previous; + var lookupCounter = 0; + function insert(newNode) { + if (!first) { + // A parent may be inserted during node construction + // (e.g., selection FilterNodes may add a TimeUnitNode). + first = newNode.parent || newNode; + } + else if (newNode.parent) { + previous.insertAsParentOf(newNode); + } + else { + newNode.parent = previous; + } + previous = newNode; + } + model.transforms.forEach(function (t) { + if (transform_1.isCalculate(t)) { + node = new calculate_1.CalculateNode(t); + } + else if (transform_1.isFilter(t)) { + // Automatically add a parse node for filters with filter objects + var parse = {}; + var filter = t.filter; + 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 (filter_1.isEqualFilter(filter)) { + val = filter.equal; + } + else if (filter_1.isRangeFilter(filter)) { + val = filter.range[0]; + } + else if (filter_1.isOneOfFilter(filter)) { + val = (filter.oneOf || filter['in'])[0]; + } // else -- for filter expression, we can't infer anything + if (val) { + if (datetime_1.isDateTime(val)) { + parse[filter['field']] = 'date'; + } + else if (vega_util_1.isNumber(val)) { + parse[filter['field']] = 'number'; + } + else if (vega_util_1.isString(val)) { + parse[filter['field']] = 'string'; + } + } + if (util_1.keys(parse).length > 0) { + var parseNode = new formatparse_1.ParseNode(parse); + insert(parseNode); + } + node = new filter_2.FilterNode(model, t.filter); + } + else if (transform_1.isBin(t)) { + node = bin_1.BinNode.makeFromTransform(t, { model: model }); + } + else if (transform_1.isTimeUnit(t)) { + node = timeunit_1.TimeUnitNode.makeFromTransform(t); + } + else if (transform_1.isAggregate(t)) { + node = aggregate_1.AggregateNode.makeFromTransform(t); + if (selection_1.requiresSelectionId(model)) { + insert(node); + node = new indentifier_1.IdentifierNode(); + } + } + else if (transform_1.isLookup(t)) { + node = lookup_1.LookupNode.make(model, t, lookupCounter++); + } + else { + log.warn(log.message.invalidTransformIgnored(t)); + return; + } + insert(node); + }); + var last = node; + return { first: first, last: last }; +} +exports.parseTransformArray = parseTransformArray; +/* +Description of the dataflow (http://asciiflow.com/): + +--------+ + | Source | + +---+----+ + | + v + Transforms +(Filter, Calculate, ...) + | + v + FormatParse + | + v + Binning + | + v + Timeunit + | + v + +--+--+ + | Raw | + +-----+ + | + v + Aggregate + | + v + Stack + | + v + Path Order + | + v + Invalid Filter + | + v + +----------+ + | Main | + +----------+ + | + v + +-------+ + | Facet |----> "column", "column-layout", and "row" + +-------+ + | + v + ...Child data... +*/ +function parseData(model) { + var root = parseRoot(model, model.component.data.sources); + var outputNodes = model.component.data.outputNodes; + var outputNodeRefCounts = model.component.data.outputNodeRefCounts; + // the current head of the tree that we are appending to + var head = root; + // 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 (selection_1.requiresSelectionId(model) && !model.parent) { + var ident = new indentifier_1.IdentifierNode(); + ident.parent = head; + head = ident; + } + // 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 && model_1.isLayerModel(model.parent); + if (model_1.isUnitModel(model) || model_1.isFacetModel(model)) { + if (parentIsLayer) { + var bin = bin_1.BinNode.makeBinFromEncoding(model); + if (bin) { + bin.parent = head; + head = bin; + } + } + } + if (model.transforms.length > 0) { + var _a = parseTransformArray(model), first = _a.first, last = _a.last; + first.parent = head; + head = last; + } + var parse = formatparse_1.ParseNode.make(model); + if (parse) { + parse.parent = head; + head = parse; + } + if (model_1.isUnitModel(model) || model_1.isFacetModel(model)) { + if (!parentIsLayer) { + var bin = bin_1.BinNode.makeBinFromEncoding(model); + if (bin) { + bin.parent = head; + head = bin; + } + } + var tu = timeunit_1.TimeUnitNode.makeFromEncoding(model); + if (tu) { + tu.parent = head; + head = tu; + } + } + // add an output node pre aggregation + var rawName = model.getName(data_1.RAW); + var raw = new dataflow_1.OutputNode(rawName, data_1.RAW, outputNodeRefCounts); + outputNodes[rawName] = raw; + raw.parent = head; + head = raw; + if (model_1.isUnitModel(model)) { + var agg = aggregate_1.AggregateNode.makeFromEncoding(model); + if (agg) { + agg.parent = head; + head = agg; + if (selection_1.requiresSelectionId(model)) { + var ident = new indentifier_1.IdentifierNode(); + ident.parent = head; + head = ident; + } + } + var stack = stack_1.StackNode.make(model); + if (stack) { + stack.parent = head; + head = stack; + } + } + if (model_1.isUnitModel(model)) { + var filter = filterinvalid_1.FilterInvalidNode.make(model); + if (filter) { + filter.parent = head; + head = filter; + } + } + // output node for marks + var mainName = model.getName(data_1.MAIN); + var main = new dataflow_1.OutputNode(mainName, data_1.MAIN, outputNodeRefCounts); + outputNodes[mainName] = main; + main.parent = head; + head = main; + // add facet marker + var facetRoot = null; + if (model_1.isFacetModel(model)) { + var facetName = model.getName('facet'); + facetRoot = new facet_1.FacetNode(model, facetName, main.getSource()); + outputNodes[facetName] = facetRoot; + facetRoot.parent = head; + head = facetRoot; + } + // add the format parse from this model so that children don't parse the same field again + var ancestorParse = __assign({}, model.component.data.ancestorParse, (parse ? parse.parse : {})); + return __assign({}, model.component.data, { outputNodes: outputNodes, + outputNodeRefCounts: outputNodeRefCounts, + raw: raw, + main: main, + facetRoot: facetRoot, + ancestorParse: ancestorParse }); +} +exports.parseData = parseData; + +},{"../../data":96,"../../datetime":97,"../../filter":101,"../../log":105,"../../transform":116,"../../util":118,"../model":66,"../selection/selection":79,"./aggregate":27,"./bin":29,"./calculate":30,"./dataflow":31,"./facet":32,"./filter":33,"./filterinvalid":34,"./formatparse":35,"./indentifier":36,"./lookup":37,"./source":41,"./stack":42,"./timeunit":43,"vega-util":10}],41:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var SourceNode = /** @class */ (function (_super) { + __extends(SourceNode, _super); + function SourceNode(data) { + var _this = _super.call(this) || this; + data = data || { name: 'source' }; + if (data_1.isInlineData(data)) { + _this._data = { values: data.values }; + } + else if (data_1.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 (!util_1.contains(['json', 'csv', 'tsv', 'topojson'], defaultExtension)) { + defaultExtension = 'json'; + } + // defaultExtension has type string but we ensure that it is DataFormatType above + data.format.type = defaultExtension; + } + } + else if (data_1.isNamedData(data)) { + _this._name = data.name; + _this._data = {}; + } + if (!data_1.isNamedData(data) && data.format) { + var _a = data.format, _b = _a.parse, parse = _b === void 0 ? null : _b, 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 (data_1.isInlineData(this._data)) { + if (!this._hash) { + // Hashing can be expensive for large inline datasets. + this._hash = util_1.hash(this._data); + } + return this._hash; + } + else if (data_1.isUrlData(this._data)) { + return util_1.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; +}(dataflow_1.DataFlowNode)); +exports.SourceNode = SourceNode; + +},{"../../data":96,"../../util":118,"./dataflow":31}],42:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var dataflow_1 = require("./dataflow"); +function getStackByFields(model) { + return model.stack.stackBy.reduce(function (fields, by) { + var fieldDef = by.fieldDef; + var _field = fielddef_1.field(fieldDef); + if (_field) { + fields.push(_field); + } + return fields; + }, []); +} +var StackNode = /** @class */ (function (_super) { + __extends(StackNode, _super); + function StackNode(stack) { + var _this = _super.call(this) || this; + _this._stack = stack; + return _this; + } + StackNode.prototype.clone = function () { + return new StackNode(util_1.duplicate(this._stack)); + }; + StackNode.make = function (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 (orderDef) { + sort = common_1.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: [] }); + } + return new StackNode({ + dimensionFieldDef: dimensionFieldDef, + field: model.field(stackProperties.fieldChannel), + facetby: [], + stackby: stackby, + sort: sort, + offset: stackProperties.offset, + impute: stackProperties.impute, + }); + }; + 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.field] = 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; + vega_util_1.isArray(field) ? field.forEach(function (f) { return out[f] = true; }) : out[field] = true; + return out; + }; + StackNode.prototype.producedFields = function () { + var out = {}; + out[this._stack.field + '_start'] = true; + out[this._stack.field + '_end'] = true; + return out; + }; + StackNode.prototype.getGroupbyFields = function () { + var _a = this._stack, dimensionFieldDef = _a.dimensionFieldDef, impute = _a.impute; + 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 [fielddef_1.field(dimensionFieldDef, { binSuffix: 'mid' })]; + } + return [ + // For binned group by field without impute, we need both bin (start) and bin_end + fielddef_1.field(dimensionFieldDef, {}), + fielddef_1.field(dimensionFieldDef, { binSuffix: 'end' }) + ]; + } + return [fielddef_1.field(dimensionFieldDef)]; + } + return []; + }; + StackNode.prototype.assemble = function () { + var transform = []; + var _a = this._stack, facetby = _a.facetby, stackField = _a.field, dimensionFieldDef = _a.dimensionFieldDef, impute = _a.impute, offset = _a.offset, sort = _a.sort, stackby = _a.stackby; + // Impute + if (impute && dimensionFieldDef) { + var dimensionField = dimensionFieldDef ? fielddef_1.field(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: '(' + + fielddef_1.field(dimensionFieldDef, { expr: 'datum' }) + + '+' + + fielddef_1.field(dimensionFieldDef, { expr: 'datum', binSuffix: 'end' }) + + ')/2', + as: dimensionField + }); + } + transform.push({ + type: 'impute', + field: stackField, + groupby: stackby, + key: dimensionField, + method: 'value', + value: 0 + }); + } + // Stack + transform.push({ + type: 'stack', + groupby: this.getGroupbyFields().concat(facetby), + field: stackField, + sort: sort, + as: [ + stackField + '_start', + stackField + '_end' + ], + offset: offset + }); + return transform; + }; + return StackNode; +}(dataflow_1.DataFlowNode)); +exports.StackNode = StackNode; + +},{"../../fielddef":100,"../../util":118,"../common":24,"./dataflow":31,"vega-util":10}],43:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../../fielddef"); +var timeunit_1 = require("../../timeunit"); +var util_1 = require("../../util"); +var dataflow_1 = require("./dataflow"); +var TimeUnitNode = /** @class */ (function (_super) { + __extends(TimeUnitNode, _super); + function TimeUnitNode(formula) { + var _this = _super.call(this) || this; + _this.formula = formula; + return _this; + } + TimeUnitNode.prototype.clone = function () { + return new TimeUnitNode(util_1.duplicate(this.formula)); + }; + TimeUnitNode.makeFromEncoding = function (model) { + var formula = model.reduceFieldDef(function (timeUnitComponent, fieldDef) { + if (fieldDef.timeUnit) { + var f = fielddef_1.field(fieldDef); + timeUnitComponent[f] = { + as: f, + timeUnit: fieldDef.timeUnit, + field: fieldDef.field + }; + } + return timeUnitComponent; + }, {}); + if (util_1.keys(formula).length === 0) { + return null; + } + return new TimeUnitNode(formula); + }; + TimeUnitNode.makeFromTransform = function (t) { + return new TimeUnitNode((_a = {}, + _a[t.field] = { + as: t.as, + timeUnit: t.timeUnit, + field: t.field + }, + _a)); + var _a; + }; + TimeUnitNode.prototype.merge = function (other) { + this.formula = __assign({}, this.formula, other.formula); + other.remove(); + }; + TimeUnitNode.prototype.producedFields = function () { + var out = {}; + util_1.vals(this.formula).forEach(function (f) { + out[f.as] = true; + }); + return out; + }; + TimeUnitNode.prototype.dependentFields = function () { + var out = {}; + util_1.vals(this.formula).forEach(function (f) { + out[f.field] = true; + }); + return out; + }; + TimeUnitNode.prototype.assemble = function () { + return util_1.vals(this.formula).map(function (c) { + return { + type: 'formula', + as: c.as, + expr: timeunit_1.fieldExpr(c.timeUnit, c.field) + }; + }); + }; + return TimeUnitNode; +}(dataflow_1.DataFlowNode)); +exports.TimeUnitNode = TimeUnitNode; + +},{"../../fielddef":100,"../../timeunit":113,"../../util":118,"./dataflow":31}],44:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var log = require("../log"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +var vega_schema_1 = require("../vega.schema"); +var buildmodel_1 = require("./buildmodel"); +var assemble_1 = require("./data/assemble"); +var parse_1 = require("./data/parse"); +var header_1 = require("./layout/header"); +var parse_2 = require("./layoutsize/parse"); +var model_1 = require("./model"); +var repeater_1 = require("./repeater"); +var resolve_1 = require("./resolve"); +var domain_1 = require("./scale/domain"); +var FacetModel = /** @class */ (function (_super) { + __extends(FacetModel, _super); + function FacetModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, spec.resolve) || this; + _this.type = 'facet'; + _this.child = buildmodel_1.buildModel(spec.spec, _this, _this.getName('child'), undefined, repeater, config, false); + _this.children = [_this.child]; + var facet = repeater_1.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 encoding_1.reduce(facet, function (normalizedFacet, fieldDef, channel) { + if (!util_1.contains([channel_1.ROW, channel_1.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] = fielddef_1.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 = parse_1.parseData(this); + this.child.parseData(); + }; + FacetModel.prototype.parseLayoutSize = function () { + parse_2.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 = header.title !== undefined ? header.title : fielddef_1.title(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] = resolve_1.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 mainAxis = axisComponent.main; + var headerType = header_1.getHeaderType(mainAxis.get('orient')); + layoutHeader[headerType] = layoutHeader[headerType] || + [this.makeHeaderComponent(headerChannel, false)]; + // LayoutHeader no longer keep track of property precedence, thus let's combine. + layoutHeader[headerType][0].axes.push(mainAxis.combine()); + delete axisComponent.main; + } + } + 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.getLayoutBandMixins = function (headerType) { + var bandMixins = {}; + var bandType = headerType === 'header' ? 'headerBand' : 'footerBand'; + for (var _i = 0, _a = ['row', 'column']; _i < _a.length; _i++) { + var channel = _a[_i]; + var layoutHeaderComponent = this.component.layoutHeaders[channel]; + var headerComponent = layoutHeaderComponent[headerType]; + if (headerComponent && headerComponent[0]) { + var sizeType = channel === 'row' ? 'height' : 'width'; + if (!this.child.component.layoutSize.get(sizeType)) { + // If facet child does not have size signal, then apply headerBand + bandMixins[bandType] = bandMixins[bandType] || {}; + bandMixins[bandType][channel] = 0.5; + } + } + } + return bandMixins; + }; + FacetModel.prototype.assembleLayout = function () { + var columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1; + // TODO: determine default align based on shared / independent scales + return __assign({ padding: { row: 10, column: 10 } }, this.getLayoutBandMixins('header'), this.getLayoutBandMixins('footer'), { + // TODO: support offset for rowHeader/rowFooter/rowTitle/columnHeader/columnFooter/columnTitle + offset: 10, 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: fielddef_1.field(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 = []; + if (this.child instanceof FacetModel) { + if (this.child.channelHasField('column')) { + fields.push(fielddef_1.field(this.child.facet.column)); + ops.push('distinct'); + } + } + 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 (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var domain = domain_1.assembleDomain(this.child, channel); + var field_1 = domain_1.getFieldFromDomain(domain); + if (field_1) { + fields.push(field_1); + ops.push('distinct'); + } + else { + log.warn('Unknown field for ${channel}. Cannot calculate view size.'); + } + } + } + } + } + return fields.length ? { fields: fields, ops: ops } : undefined; + }; + FacetModel.prototype.assembleMarks = function () { + var _a = this, child = _a.child, facet = _a.facet; + var facetRoot = this.component.data.facetRoot; + var data = assemble_1.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 hasRow = this.channelHasField(channel_1.ROW); + var hasColumn = this.channelHasField(channel_1.COLUMN); + var layoutSizeEncodeEntry = child.assembleLayoutSize(); + var aggregateMixins = {}; + if (hasRow && hasColumn) { + aggregateMixins.aggregate = { cross: true }; + } + var cardinalityAggregateForChild = this.getCardinalityAggregateForChild(); + if (cardinalityAggregateForChild) { + aggregateMixins.aggregate = __assign({}, aggregateMixins.aggregate, cardinalityAggregateForChild); + } + var title = child.assembleTitle(); + var style = child.assembleGroupStyle(); + var markGroup = __assign({ name: this.getName('cell'), type: 'group' }, (title ? { title: title } : {}), (style ? { style: style } : {}), { from: { + facet: __assign({ name: facetRoot.name, data: facetRoot.data, groupby: [].concat(hasRow ? [this.field(channel_1.ROW)] : [], hasColumn ? [this.field(channel_1.COLUMN)] : []) }, aggregateMixins) + }, sort: { + field: [].concat(hasRow ? [this.field(channel_1.ROW, { expr: 'datum', })] : [], hasColumn ? [this.field(channel_1.COLUMN, { expr: 'datum' })] : []), + order: [].concat(hasRow ? [(facet.row.sort) || 'ascending'] : [], hasColumn ? [(facet.column.sort) || 'ascending'] : []) + } }, (data.length > 0 ? { data: data } : {}), (layoutSizeEncodeEntry ? { encode: { update: layoutSizeEncodeEntry } } : {}), child.assembleGroup()); + return [markGroup]; + }; + FacetModel.prototype.getMapping = function () { + return this.facet; + }; + return FacetModel; +}(model_1.ModelWithField)); +exports.FacetModel = FacetModel; + +},{"../channel":15,"../encoding":98,"../fielddef":100,"../log":105,"../scale":108,"../util":118,"../vega.schema":120,"./buildmodel":23,"./data/assemble":28,"./data/parse":40,"./layout/header":46,"./layoutsize/parse":48,"./model":66,"./repeater":68,"./resolve":69,"./scale/domain":72}],45:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var spec_1 = require("../spec"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var parse_2 = require("./data/parse"); +var assemble_1 = require("./layoutsize/assemble"); +var parse_3 = require("./layoutsize/parse"); +var assemble_2 = require("./legend/assemble"); +var model_1 = require("./model"); +var selection_1 = require("./selection/selection"); +var unit_1 = require("./unit"); +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, 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 (spec_1.isLayerSpec(layer)) { + return new LayerModel(layer, _this, _this.getName('layer_' + i), layoutSize, repeater, config, fit); + } + if (spec_1.isUnitSpec(layer)) { + return new unit_1.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 = parse_2.parseData(this); + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseData(); + } + }; + LayerModel.prototype.parseLayoutSize = function () { + parse_3.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(); + util_1.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 () { + parse_1.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()); + }, assemble_1.assembleLayoutSignals(this)); + }; + LayerModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, []); + }; + 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 selection_1.assembleLayerSelectionMarks(this, util_1.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()); + }, assemble_2.assembleLegends(this)); + }; + return LayerModel; +}(model_1.Model)); +exports.LayerModel = LayerModel; + +},{"../log":105,"../spec":111,"../util":118,"./axis/parse":20,"./data/parse":40,"./layoutsize/assemble":47,"./layoutsize/parse":48,"./legend/assemble":49,"./model":66,"./selection/selection":79,"./unit":90}],46:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +exports.HEADER_CHANNELS = ['row', 'column']; +exports.HEADER_TYPES = ['header', 'footer']; +function getHeaderType(orient) { + if (orient === 'top' || orient === 'left') { + return 'header'; + } + return 'footer'; +} +exports.getHeaderType = getHeaderType; +function getTitleGroup(model, channel) { + var title = model.component.layoutHeaders[channel].title; + var textOrient = channel === 'row' ? 'vertical' : undefined; + var update = __assign({ align: { value: 'center' }, text: { value: title } }, (textOrient === 'vertical' ? { angle: { value: 270 } } : {})); + return { + name: model.getName(channel + "_title"), + role: channel + "-title", + type: 'group', + marks: [__assign({ type: 'text', role: channel + "-title-text", style: 'guide-title' }, (util_1.keys(update).length > 0 ? { encode: { update: update } } : {}))] + }; +} +exports.getTitleGroup = getTitleGroup; +function getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt) { + if (headerCmpt) { + var title = null; + if (layoutHeader.facetFieldDef && headerCmpt.labels) { + var facetFieldDef = layoutHeader.facetFieldDef; + var _a = facetFieldDef.header, header = _a === void 0 ? {} : _a; + var format = header.format, labelAngle = header.labelAngle; + var update = __assign({}, (labelAngle ? { angle: { value: labelAngle } } : {}) + // TODO(https://github.com/vega/vega-lite/issues/2446): apply label* (e.g, labelAlign, labelBaseline) here + ); + title = __assign({ text: common_1.formatSignalRef(facetFieldDef, format, 'parent', model.config), offset: 10, orient: channel === 'row' ? 'left' : 'top', style: 'guide-label' }, (util_1.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 __assign({ name: model.getName(channel + "_" + headerType), type: 'group', role: channel + "-" + headerType }, (layoutHeader.facetFieldDef ? { + from: { data: model.getName(channel + '_domain') }, + sort: { + field: fielddef_1.field(layoutHeader.facetFieldDef, { expr: 'datum' }), + order: (layoutHeader.facetFieldDef.header && layoutHeader.facetFieldDef.sort) || 'ascending' + } + } : {}), (title ? { title: title } : {}), (headerCmpt.sizeSignal ? { + encode: { + update: (_b = {}, + _b[sizeChannel] = headerCmpt.sizeSignal, + _b) + } + } : {}), (hasAxes ? { axes: axes } : {})); + } + } + return null; + var _b; +} +exports.getHeaderGroup = getHeaderGroup; + +},{"../../fielddef":100,"../../util":118,"../common":24}],47:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var model_1 = require("../model"); +function assembleLayoutSignals(model) { + return [].concat(sizeSignals(model, 'width'), sizeSignals(model, 'height')); +} +exports.assembleLayoutSignals = assembleLayoutSignals; +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 (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var scaleName = model.scaleName(channel); + if (model_1.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 + }]; + } +} +exports.sizeSignals = sizeSignals; +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"; +} +exports.sizeExpr = sizeExpr; + +},{"../../scale":108,"../../vega.schema":120,"../model":66}],48:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var split_1 = require("../split"); +function parseLayerLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width')); + layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height')); +} +exports.parseLayerLayoutSize = parseLayerLayoutSize; +exports.parseRepeatLayoutSize = parseLayerLayoutSize; +function parseConcatLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + var sizeTypeToMerge = model.isVConcat ? 'width' : 'height'; + layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge)); +} +exports.parseConcatLayoutSize = parseConcatLayoutSize; +function parseChildrenLayoutSize(model) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseLayoutSize(); + } +} +exports.parseChildrenLayoutSize = parseChildrenLayoutSize; +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 = split_1.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); + } +} +exports.parseUnitLayoutSize = parseUnitLayoutSize; +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 (scale_1.hasDiscreteDomain(scaleType) && vega_schema_1.isVgRangeStep(range)) { + // For discrete domain with range.step, use dynamic width/height + return 'range-step'; + } + else { + 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 || scale_1.defaultScaleConfig.rangeStep; + } +} + +},{"../../scale":108,"../../vega.schema":120,"../split":89}],49:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var util_1 = require("../../util"); +var parse_1 = require("./parse"); +function assembleLegends(model) { + var legendComponentIndex = model.component.legends; + var legendByDomain = {}; + for (var _i = 0, _a = util_1.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 = parse_1.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 util_1.flatten(util_1.vals(legendByDomain)).map(function (legendCmpt) { return legendCmpt.combine(); }); +} +exports.assembleLegends = assembleLegends; + +},{"../../util":118,"./parse":52,"json-stable-stringify":1}],50:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var split_1 = require("../split"); +var LegendComponent = /** @class */ (function (_super) { + __extends(LegendComponent, _super); + function LegendComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return LegendComponent; +}(split_1.Split)); +exports.LegendComponent = LegendComponent; + +},{"../split":89}],51:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var mark_1 = require("../../mark"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var mixins = require("../mark/mixins"); +function symbols(fieldDef, symbolsSpec, model, channel, type) { + if (type === 'gradient') { + return undefined; + } + var symbols = {}; + var mark = model.mark(); + switch (mark) { + case mark_1.BAR: + case mark_1.TICK: + case mark_1.TEXT: + symbols.shape = { value: 'square' }; + break; + case mark_1.CIRCLE: + case mark_1.SQUARE: + symbols.shape = { value: mark }; + break; + case mark_1.POINT: + case mark_1.LINE: + case mark_1.AREA: + // use default circle + break; + } + var filled = model.markDef.filled; + var config = channel === channel_1.COLOR ? + /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */ + util_1.without(mark_1.FILL_STROKE_CONFIG, [filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) : + /* For other legend, no need to omit. */ + mark_1.FILL_STROKE_CONFIG; + config = util_1.without(config, ['strokeDash', 'strokeDashOffset']); + common_1.applyMarkConfig(symbols, model, config); + if (channel !== channel_1.COLOR) { + var colorMixins = mixins.color(model); + // If there are field for fill or stroke, remove them as we already apply channels. + if (colorMixins.fill && (colorMixins.fill['field'] || colorMixins.fill['value'] === 'transparent')) { + delete colorMixins.fill; + } + if (colorMixins.stroke && (colorMixins.stroke['field'] || colorMixins.stroke['value'] === 'transparent')) { + delete colorMixins.stroke; + } + symbols = __assign({}, symbols, colorMixins); + } + if (channel !== channel_1.SHAPE) { + var shapeDef = model.encoding.shape; + if (fielddef_1.isValueDef(shapeDef)) { + symbols.shape = { value: shapeDef.value }; + } + } + if (channel !== channel_1.OPACITY) { + var opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity; + if (opacity) { + symbols.opacity = { value: opacity }; + } + } + symbols = __assign({}, symbols, symbolsSpec); + return util_1.keys(symbols).length > 0 ? symbols : undefined; +} +exports.symbols = symbols; +function gradient(fieldDef, gradientSpec, model, channel, type) { + var gradient = {}; + if (type === 'gradient') { + var opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity; + if (opacity) { + gradient.opacity = { value: opacity }; + } + } + gradient = __assign({}, gradient, gradientSpec); + return util_1.keys(gradient).length > 0 ? gradient : undefined; +} +exports.gradient = gradient; +function labels(fieldDef, labelsSpec, model, channel, type) { + var legend = model.legend(channel); + var config = model.config; + var labels = {}; + if (fielddef_1.isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === scale_1.ScaleType.UTC; + labelsSpec = __assign({ text: { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale) + } }, labelsSpec); + } + labels = __assign({}, labels, labelsSpec); + return util_1.keys(labels).length > 0 ? labels : undefined; +} +exports.labels = labels; +function getOpacityValue(opacityDef) { + if (fielddef_1.isValueDef(opacityDef)) { + if (fielddef_1.hasConditionalValueDef(opacityDef)) { + var values = vega_util_1.isArray(opacityDef.condition) ? opacityDef.condition.map(function (c) { return c.value; }) : [opacityDef.condition.value]; + return Math.max.apply(null, [opacityDef.value].concat(values)); + } + else { + return opacityDef.value; + } + } + return undefined; +} + +},{"../../channel":15,"../../fielddef":100,"../../mark":107,"../../scale":108,"../../util":118,"../common":24,"../mark/mixins":59,"vega-util":10}],52:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var legend_1 = require("../../legend"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var model_1 = require("../model"); +var resolve_1 = require("../resolve"); +var split_1 = require("../split"); +var split_2 = require("../split"); +var component_1 = require("./component"); +var encode = require("./encode"); +var properties = require("./properties"); +function parseLegend(model) { + if (model_1.isUnitModel(model)) { + model.component.legends = parseUnitLegend(model); + } + else { + model.component.legends = parseNonUnitLegend(model); + } +} +exports.parseLegend = parseLegend; +function parseUnitLegend(model) { + return [channel_1.COLOR, channel_1.SIZE, channel_1.SHAPE, channel_1.OPACITY].reduce(function (legendComponent, channel) { + if (model.legend(channel)) { + legendComponent[channel] = parseLegendForChannel(model, channel); + } + return legendComponent; + }, {}); +} +function getLegendDefWithScale(model, channel) { + // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels + switch (channel) { + case channel_1.COLOR: + var scale = model.scaleName(channel_1.COLOR); + return model.markDef.filled ? { fill: scale } : { stroke: scale }; + case channel_1.SIZE: + return { size: model.scaleName(channel_1.SIZE) }; + case channel_1.SHAPE: + return { shape: model.scaleName(channel_1.SHAPE) }; + case channel_1.OPACITY: + return { opacity: model.scaleName(channel_1.OPACITY) }; + } + return null; +} +function parseLegendForChannel(model, channel) { + var fieldDef = model.fieldDef(channel); + var legend = model.legend(channel); + var legendCmpt = new component_1.LegendComponent({}, getLegendDefWithScale(model, channel)); + legend_1.LEGEND_PROPERTIES.forEach(function (property) { + var value = getProperty(property, legend, channel, model); + if (value !== undefined) { + var explicit = property === 'values' ? + !!legend.values : // specified legend.values is already respected, but may get transformed. + 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 value = encode[part] ? + // TODO: replace legendCmpt with type is sufficient + encode[part](fieldDef, legendEncoding[part], model, channel, legendCmpt.get('type')) : // apply rule + legendEncoding[part]; // no rule -- just default values + if (value !== undefined && util_1.keys(value).length > 0) { + e[part] = { update: value }; + } + return e; + }, {}); + if (util_1.keys(legendEncode).length > 0) { + legendCmpt.set('encode', legendEncode, !!legend.encoding); + } + return legendCmpt; +} +exports.parseLegendForChannel = parseLegendForChannel; +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 common_1.numberFormat(fieldDef, specifiedLegend.format, model.config); + case 'title': + return common_1.getSpecifiedOrDefaultValue(specifiedLegend.title, fielddef_1.title(fieldDef, model.config)); + case 'values': + return properties.values(specifiedLegend); + case 'type': + return common_1.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); + util_1.keys(child.component.legends).forEach(function (channel) { + resolve.legend[channel] = resolve_1.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); + } + util_1.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 = split_2.mergeValuesWithExplicit(mergedLegend.getWithExplicit(prop), childLegend.getWithExplicit(prop), prop, 'legend', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return common_1.titleMerger(v1, v2); + case 'type': + // There are only two types. If we have different types, then prefer symbol over gradient. + typeMerged = true; + return split_1.makeImplicit('symbol'); + } + return split_2.defaultTieBreaker(v1, v2, prop, 'legend'); + }); + mergedLegend.setWithExplicit(prop, mergedValueWithExplicit); + }; + // Otherwise, let's merge + for (var _i = 0, VG_LEGEND_PROPERTIES_1 = legend_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) { + util_1.deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']); + } + if (((mergedLegend.explicit || {}).encode || {}).gradient) { + util_1.deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']); + } + } + return mergedLegend; +} +exports.mergeLegendComponent = mergeLegendComponent; + +},{"../../channel":15,"../../fielddef":100,"../../legend":104,"../../util":118,"../common":24,"../model":66,"../resolve":69,"../split":89,"./component":50,"./encode":51,"./properties":53}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +function values(legend) { + var vals = legend.values; + if (vals && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return { signal: datetime_1.dateTimeExpr(dt, true) }; + }); + } + return vals; +} +exports.values = values; +function type(type, channel, scaleType) { + if (channel === channel_1.COLOR && ((type === 'quantitative' && !scale_1.isBinScale(scaleType)) || + (type === 'temporal' && util_1.contains(['time', 'utc'], scaleType)))) { + return 'gradient'; + } + return undefined; +} +exports.type = type; + +},{"../../channel":15,"../../datetime":97,"../../scale":108,"../../util":118}],54:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mixins = require("./mixins"); +exports.area = { + vgMark: 'area', + encodeEntry: function (model) { + return __assign({}, mixins.markDefProperties(model.markDef), mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin'), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model)); + } +}; + +},{"./mixins":59}],55:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var vega_schema_1 = require("../../vega.schema"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.bar = { + vgMark: 'rect', + encodeEntry: function (model) { + var stack = model.stack; + return __assign({}, mixins.markDefProperties(model.markDef, true), x(model, stack), y(model, stack), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model)); + } +}; +function x(model, stack) { + var config = model.config, width = model.width; + var orient = model.markDef.orient; + var sizeDef = model.encoding.size; + var xDef = model.encoding.x; + var xScaleName = model.scaleName(channel_1.X); + var xScale = model.getScaleComponent(channel_1.X); + // x, x2, and width -- we must specify two of these in all conditions + if (orient === 'horizontal') { + return __assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(xDef)) { + var xScaleType = xScale.get('type'); + if (xDef.bin && !sizeDef && !scale_1.hasDiscreteDomain(xScaleType)) { + return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), config.bar.binSpacing, xScale.get('reverse')); + } + else { + if (xScaleType === scale_1.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, __assign({}, ref.mid(width)), defaultSizeRef(xScaleName, xScale, config)); + } +} +function y(model, stack) { + var config = model.config, encoding = model.encoding, height = model.height; + var orient = model.markDef.orient; + var sizeDef = encoding.size; + var yDef = encoding.y; + var yScaleName = model.scaleName(channel_1.Y); + var yScale = model.getScaleComponent(channel_1.Y); + // y, y2 & height -- we must specify two of these in all conditions + if (orient === 'vertical') { + return __assign({}, mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(yDef)) { + var yScaleType = yScale.get('type'); + if (yDef.bin && !sizeDef && !scale_1.hasDiscreteDomain(yScaleType)) { + return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), config.bar.binSpacing, yScale.get('reverse')); + } + else if (yScaleType === scale_1.ScaleType.BAND) { + return mixins.bandPosition(yDef, 'y', model); + } + } + return mixins.centeredBandPosition('y', model, ref.mid(height), defaultSizeRef(yScaleName, yScale, config)); + } +} +function defaultSizeRef(scaleName, scale, config) { + if (config.bar.discreteBandSize) { + return { value: config.bar.discreteBandSize }; + } + if (scale) { + var scaleType = scale.get('type'); + if (scaleType === scale_1.ScaleType.POINT) { + var scaleRange = scale.get('range'); + if (vega_schema_1.isVgRangeStep(scaleRange) && vega_util_1.isNumber(scaleRange.step)) { + return { value: scaleRange.step - 1 }; + } + log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL); + } + else if (scaleType === scale_1.ScaleType.BAND) { + return ref.band(scaleName); + } + else { + return { value: config.bar.continuousBandSize }; + } + } + if (config.scale.rangeStep && config.scale.rangeStep !== null) { + return { value: config.scale.rangeStep - 1 }; + } + return { value: 20 }; +} + +},{"../../channel":15,"../../fielddef":100,"../../log":105,"../../scale":108,"../../vega.schema":120,"./mixins":59,"./valueref":65,"vega-util":10}],56:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var mark_1 = require("../../mark"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function normalizeMarkDef(mark, encoding, config) { + var markDef = mark_1.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 || common_1.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 || common_1.getMarkConfig('opacity', markDef, config); + if (specifiedOpacity === undefined) { + markDef.opacity = defaultOpacity(markDef.type, encoding); + } + var specifiedFilled = markDef.filled; + if (specifiedFilled === undefined) { + markDef.filled = filled(markDef, config); + } + return markDef; +} +exports.normalizeMarkDef = normalizeMarkDef; +function defaultOpacity(mark, encoding) { + if (util_1.contains([mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE], mark)) { + // point-based marks + if (!encoding_1.isAggregate(encoding)) { + return 0.7; + } + } + return undefined; +} +function filled(markDef, config) { + var filledConfig = common_1.getMarkConfig('filled', markDef, config); + var mark = markDef.type; + return filledConfig !== undefined ? filledConfig : mark !== mark_1.POINT && mark !== mark_1.LINE && mark !== mark_1.RULE; +} +function orient(mark, encoding, specifiedOrient) { + switch (mark) { + case mark_1.POINT: + case mark_1.CIRCLE: + case mark_1.SQUARE: + case mark_1.TEXT: + case mark_1.RECT: + // orient is meaningless for these marks. + return undefined; + } + var yIsRange = encoding.y2; + var xIsRange = encoding.x2; + switch (mark) { + case mark_1.RULE: + case mark_1.BAR: + case mark_1.AREA: + // 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 === mark_1.RULE) { + if (encoding.x && !encoding.y) { + return 'vertical'; + } + else if (encoding.y && !encoding.x) { + return 'horizontal'; + } + } + /* tslint:disable */ + case mark_1.LINE: // intentional fall through + case mark_1.TICK:// Tick is opposite to bar, line, area and never have ranged mark. + /* tslint:enable */ + var xIsContinuous = fielddef_1.isFieldDef(encoding.x) && fielddef_1.isContinuous(encoding.x); + var yIsContinuous = fielddef_1.isFieldDef(encoding.y) && fielddef_1.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 === type_1.TEMPORAL; + var yIsTemporal = yDef.type === type_1.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; + } + if (!(mark === mark_1.LINE && encoding.order)) { + // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots. + log.warn(log.message.unclearOrientContinuous(mark)); + } + return 'vertical'; + } + else { + // For Discrete x Discrete case, return undefined. + log.warn(log.message.unclearOrientDiscreteOrEmpty(mark)); + return undefined; + } + } + return 'vertical'; +} + +},{"../../encoding":98,"../../fielddef":100,"../../log":105,"../../mark":107,"../../type":117,"../../util":118,"../common":24}],57:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.line = { + vgMark: 'line', + encodeEntry: function (model) { + var width = model.width, height = model.height; + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's line size is strokeWidth + })); + } +}; + +},{"./mixins":59,"./valueref":65}],58:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var data_1 = require("../../data"); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var mark_1 = require("../../mark"); +var sort_1 = require("../../sort"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +var area_1 = require("./area"); +var bar_1 = require("./bar"); +var line_1 = require("./line"); +var point_1 = require("./point"); +var rect_1 = require("./rect"); +var rule_1 = require("./rule"); +var text_1 = require("./text"); +var tick_1 = require("./tick"); +var markCompiler = { + area: area_1.area, + bar: bar_1.bar, + line: line_1.line, + point: point_1.point, + text: text_1.text, + tick: tick_1.tick, + rect: rect_1.rect, + rule: rule_1.rule, + circle: point_1.circle, + square: point_1.square +}; +function parseMarkGroup(model) { + if (util_1.contains([mark_1.LINE, mark_1.AREA], model.mark())) { + return parsePathMark(model); + } + else { + return parseNonPathMark(model); + } +} +exports.parseMarkGroup = parseMarkGroup; +var FACETED_PATH_PREFIX = 'faceted_path_'; +function parsePathMark(model) { + var mark = model.mark(); + var details = pathGroupingFields(model.encoding); + var clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model); + var style = common_1.getStyles(model.markDef); + var sort = getPathSort(model); + var pathMarks = [ + __assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (clip ? { clip: true } : {}), (style ? { style: style } : {}), (sort ? { sort: sort } : {}), { + // If has subfacet for line/area group, need to use faceted data from below. + // FIXME: support sorting path order (in connected scatterplot) + from: { data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + model.requestDataName(data_1.MAIN) }, encode: { update: markCompiler[mark].encodeEntry(model) } }) + ]; + if (details.length > 0) { + // 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(data_1.MAIN), + data: model.requestDataName(data_1.MAIN), + groupby: details, + } + }, + encode: { + update: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } } + } + }, + marks: pathMarks + }]; + } + else { + return pathMarks; + } +} +function getPathSort(model) { + if (model.mark() === 'line' && model.channelHasField('order')) { + // For only line, sort by the order field if it is specified. + return common_1.sortParams(model.encoding.order, { expr: 'datum' }); + } + else { + // For both line and area, we sort values based on dimension by default + var dimensionChannel = model.markDef.orient === 'horizontal' ? 'y' : 'x'; + var s = model.sort(dimensionChannel); + var sortField = sort_1.isSortField(s) ? + fielddef_1.field({ + // FIXME: this op might not already exist? + // FIXME: what if dimensionChannel (x or y) contains custom domain? + aggregate: encoding_1.isAggregate(model.encoding) ? s.op : undefined, + field: s.field + }, { expr: 'datum' }) : + model.field(dimensionChannel, { + // For stack with imputation, we only have bin_mid + binSuffix: model.stack && model.stack.impute ? 'mid' : undefined, + expr: 'datum' + }); + return sortField ? + { + field: sortField, + order: 'descending' + } : + undefined; + } +} +exports.getPathSort = getPathSort; +function parseNonPathMark(model) { + var mark = model.mark(); + var style = common_1.getStyles(model.markDef); + var clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model); + var marks = []; // TODO: vgMarks + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + marks.push(__assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (clip ? { clip: true } : {}), (style ? { style: style } : {}), { from: { data: model.requestDataName(data_1.MAIN) }, encode: { update: markCompiler[mark].encodeEntry(model) } })); + return marks; +} +/** + * Returns list of path grouping fields + * that the model's spec contains. + */ +function pathGroupingFields(encoding) { + return util_1.keys(encoding).reduce(function (details, channel) { + switch (channel) { + // x, y, x2, y2, order, tooltip, href, cursor should not cause lines to group + case 'x': + case 'y': + case 'order': + case 'tooltip': + case 'x2': + case 'y2': + // TODO: case 'href', 'cursor': + // text, shape, shouldn't be a part of line/area + case 'text': + case 'shape': + return details; + case 'detail': + var channelDef = encoding[channel]; + if (channelDef) { + (vega_util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + if (!fieldDef.aggregate) { + details.push(fielddef_1.field(fieldDef, {})); + } + }); + } + return details; + case 'color': + case 'size': + case 'opacity': + // TODO strokeDashOffset: + var fieldDef = fielddef_1.getFieldDef(encoding[channel]); + if (fieldDef && !fieldDef.aggregate) { + details.push(fielddef_1.field(fieldDef, {})); + } + return details; + default: + throw new Error("Bug: Channel " + channel + " unimplemented for line mark"); + } + }, []); +} +exports.pathGroupingFields = pathGroupingFields; +/** + * 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; +} + +},{"../../data":96,"../../encoding":98,"../../fielddef":100,"../../mark":107,"../../sort":110,"../../util":118,"../common":24,"./area":54,"./bar":55,"./line":57,"./point":60,"./rect":61,"./rule":62,"./text":63,"./tick":64,"vega-util":10}],59:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var util = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var common_1 = require("../common"); +var selection_1 = require("../selection/selection"); +var ref = require("./valueref"); +function color(model) { + var config = model.config; + var filled = model.markDef.filled; + var vgChannel = filled ? 'fill' : 'stroke'; + var e = nonPosition('color', model, { + vgChannel: vgChannel, + // Mark definition has higher predecence than config; + // fill/stroke has higher precedence than color. + defaultValue: model.markDef[vgChannel] || + model.markDef.color || + common_1.getMarkConfig(vgChannel, model.markDef, config) || + common_1.getMarkConfig('color', model.markDef, config) + }); + // If there is no fill, always fill symbols + // with transparent fills https://github.com/vega/vega-lite/issues/1316 + if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) { + e.fill = { value: 'transparent' }; + } + return e; +} +exports.color = color; +function markDefProperties(mark, ignoreOrient) { + return vega_schema_1.VG_MARK_CONFIGS.reduce(function (m, prop) { + if (mark[prop] && (!ignoreOrient || prop !== 'orient')) { + m[prop] = { value: mark[prop] }; + } + return m; + }, {}); +} +exports.markDefProperties = markDefProperties; +function valueIfDefined(prop, value) { + if (value !== undefined) { + return _a = {}, _a[prop] = { value: value }, _a; + } + return undefined; + var _a; +} +exports.valueIfDefined = valueIfDefined; +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +function nonPosition(channel, model, opt) { + // TODO: refactor how we refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + 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); + }); +} +exports.nonPosition = nonPosition; +/** + * 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 condition = channelDef && channelDef.condition; + var valueRef = refFn(channelDef); + if (condition) { + var conditions = vega_util_1.isArray(condition) ? condition : [condition]; + var vgConditions = conditions.map(function (c) { + var conditionValueRef = refFn(c); + return __assign({ test: selection_1.predicate(model, c.selection) }, conditionValueRef); + }); + return _a = {}, + _a[vgChannel] = vgConditions.concat((valueRef !== undefined ? [valueRef] : [])), + _a; + } + else { + return valueRef !== undefined ? (_b = {}, _b[vgChannel] = valueRef, _b) : {}; + } + var _a, _b; +} +function text(model, channel) { + if (channel === void 0) { channel = 'text'; } + var channelDef = model.encoding[channel]; + return wrapCondition(model, channelDef, channel, function (cDef) { return ref.text(cDef, model.config); }); +} +exports.text = text; +function bandPosition(fieldDef, channel, model) { + var scaleName = model.scaleName(channel); + var sizeChannel = channel === 'x' ? 'width' : 'height'; + if (model.encoding.size) { + 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 (fielddef_1.getFieldDef(model.encoding.size)) { + log.warn(log.message.cannotUseSizeFieldWithBandSize(channel)); + // TODO: apply size to band and set scale range to some values between 0-1. + // return { + // ...centeredBandPositionMixins, + // ...bandSize('size', model, {vgChannel: sizeChannel}) + // }; + } + else if (fielddef_1.isValueDef(model.encoding.size)) { + return __assign({}, centeredBandPositionMixins, nonPosition('size', model, { vgChannel: sizeChannel })); + } + } + else { + log.warn(log.message.cannotApplySizeToNonOrientedMark(model.markDef.type)); + } + } + return _b = {}, + _b[channel] = ref.fieldRef(fieldDef, scaleName, { binSuffix: 'range' }), + _b[sizeChannel] = ref.band(scaleName), + _b; + var _a, _b; +} +exports.bandPosition = bandPosition; +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 })); +} +exports.centeredBandPosition = centeredBandPosition; +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) + }; + } +} +exports.binnedPosition = binnedPosition; +/** + * 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 encoding = model.encoding, stack = model.stack; + var valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.getScaleComponent(channel), stack, defaultRef); + return _a = {}, + _a[vgChannel || channel] = valueRef, + _a; + var _a; +} +exports.pointPosition = pointPosition; +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +function pointPosition2(model, defaultRef, channel) { + var encoding = model.encoding, markDef = model.markDef, stack = model.stack; + channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2'); + var baseChannel = channel === 'x2' ? 'x' : 'y'; + var valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.getScaleComponent(baseChannel), stack, defaultRef); + return _a = {}, _a[channel] = valueRef, _a; + var _a; +} +exports.pointPosition2 = pointPosition2; + +},{"../../fielddef":100,"../../log":105,"../../util":118,"../../vega.schema":120,"../common":24,"../selection/selection":79,"./valueref":65,"vega-util":10}],60:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("../common"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +function encodeEntry(model, fixedShape) { + var config = model.config, width = model.width, height = model.height; + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('size', model), shapeMixins(model, config, fixedShape), mixins.nonPosition('opacity', model)); +} +function shapeMixins(model, config, fixedShape) { + if (fixedShape) { + return { shape: { value: fixedShape } }; + } + return mixins.nonPosition('shape', model, { defaultValue: common_1.getMarkConfig('shape', model.markDef, config) }); +} +exports.shapeMixins = shapeMixins; +exports.point = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model); + } +}; +exports.circle = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'circle'); + } +}; +exports.square = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'square'); + } +}; + +},{"../common":24,"./mixins":59,"./valueref":65}],61:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var log = require("../../log"); +var mark_1 = require("../../mark"); +var scale_1 = require("../../scale"); +var mixins = require("./mixins"); +exports.rect = { + vgMark: 'rect', + encodeEntry: function (model) { + return __assign({}, mixins.markDefProperties(model.markDef, true), x(model), y(model), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model)); + } +}; +function x(model) { + var xDef = model.encoding.x; + var x2Def = model.encoding.x2; + var xScale = model.getScaleComponent(channel_1.X); + var xScaleType = xScale ? xScale.get('type') : undefined; + if (fielddef_1.isFieldDef(xDef) && xDef.bin && !x2Def) { + return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse')); + } + else if (fielddef_1.isFieldDef(xDef) && xScale && scale_1.hasDiscreteDomain(xScaleType)) { + /* istanbul ignore else */ + if (xScaleType === scale_1.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(mark_1.RECT, xScaleType)); + } + } + else { + return __assign({}, mixins.pointPosition('x', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'x2')); + } +} +function y(model) { + var yDef = model.encoding.y; + var y2Def = model.encoding.y2; + var yScale = model.getScaleComponent(channel_1.Y); + var yScaleType = yScale ? yScale.get('type') : undefined; + if (fielddef_1.isFieldDef(yDef) && yDef.bin && !y2Def) { + return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse')); + } + else if (fielddef_1.isFieldDef(yDef) && yScale && scale_1.hasDiscreteDomain(yScaleType)) { + /* istanbul ignore else */ + if (yScaleType === scale_1.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(mark_1.RECT, yScaleType)); + } + } + else { + return __assign({}, mixins.pointPosition('y', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'y2')); + } +} + +},{"../../channel":15,"../../fielddef":100,"../../log":105,"../../mark":107,"../../scale":108,"./mixins":59}],62:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.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) { + // if we have neither x or y, show nothing + return {}; + } + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)), mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)), mixins.pointPosition2(model, 'zeroOrMax'), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's rule size is strokeWidth + })); + } +}; + +},{"./mixins":59,"./valueref":65}],63:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var common_1 = require("../common"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.text = { + vgMark: 'text', + encodeEntry: function (model) { + var config = model.config, encoding = model.encoding, height = model.height; + var textDef = encoding.text; + return __assign({}, mixins.markDefProperties(model.markDef, true), mixins.pointPosition('x', model, xDefault(config, textDef)), mixins.pointPosition('y', model, ref.mid(height)), mixins.text(model), mixins.color(model), mixins.text(model, 'tooltip'), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'fontSize' // VL's text size is fontSize + }), mixins.valueIfDefined('align', align(model.markDef, encoding, config))); + } +}; +function xDefault(config, textDef) { + if (fielddef_1.isFieldDef(textDef) && textDef.type === type_1.QUANTITATIVE) { + return { field: { group: 'width' }, offset: -5 }; + } + // TODO: allow this to fit (Be consistent with ref.midX()) + return { value: config.scale.textXRangeStep / 2 }; +} +function align(markDef, encoding, config) { + var align = markDef.align || common_1.getMarkConfig('align', markDef, config); + if (align === undefined) { + return encoding_1.channelHasField(encoding, channel_1.X) ? 'center' : 'right'; + } + // If there is a config, Vega-parser will process this already. + return undefined; +} + +},{"../../channel":15,"../../encoding":98,"../../fielddef":100,"../../type":117,"../common":24,"./mixins":59,"./valueref":65}],64:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_schema_1 = require("../../vega.schema"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.tick = { + vgMark: 'rect', + encodeEntry: function (model) { + 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({}, mixins.markDefProperties(model.markDef, true), 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: config.tick.thickness }, _a), mixins.color(model), mixins.nonPosition('opacity', model)); + var _a; + } +}; +function defaultSize(model) { + var config = model.config; + var orient = model.markDef.orient; + var scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y'); + if (config.tick.bandSize !== undefined) { + return config.tick.bandSize; + } + else { + var scaleRange = scale ? scale.get('range') : undefined; + var rangeStep = scaleRange && vega_schema_1.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; + } +} + +},{"../../vega.schema":120,"./mixins":59,"./valueref":65}],65:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Utility files for producing Vega ValueRef for marks + */ +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var common_1 = require("../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 stackable x or y + */ +function stackable(channel, channelDef, scaleName, scale, stack, defaultRef) { + if (fielddef_1.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); +} +exports.stackable = stackable; +/** + * @return Vega ValueRef for stackable x2 or y2 + */ +function stackable2(channel, aFieldDef, a2fieldDef, scaleName, scale, stack, defaultRef) { + if (fielddef_1.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); +} +exports.stackable2 = stackable2; +/** + * Value Ref for binned fields + */ +function bin(fieldDef, scaleName, side, offset) { + var binSuffix = side === 'start' ? undefined : 'end'; + return fieldRef(fieldDef, scaleName, { binSuffix: binSuffix }, offset ? { offset: offset } : {}); +} +exports.bin = bin; +function fieldRef(fieldDef, scaleName, opt, mixins) { + var ref = { + scale: scaleName, + field: fielddef_1.field(fieldDef, opt), + }; + if (mixins) { + return __assign({}, ref, mixins); + } + return ref; +} +exports.fieldRef = fieldRef; +function band(scaleName, band) { + if (band === void 0) { band = true; } + return { + scale: scaleName, + band: band + }; +} +exports.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 + "\", " + fielddef_1.field(fieldDef, { expr: 'datum' }) + ")") + + " + " + + ("scale(\"" + scaleName + "\", " + fielddef_1.field(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 (fielddef_1.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 (util_1.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, common_1.binRequiresRange(channelDef, channel) ? { binSuffix: 'range' } : {}); + } + var scaleType = scale.get('type'); + if (scale_1.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' }); + } + else { + return fieldRef(channelDef, scaleName, {}); // no need for bin suffix + } + } + else if (fielddef_1.isValueDef(channelDef)) { + return { value: channelDef.value }; + } + else { + return undefined; + } + } + if (defaultRef === 'zeroOrMin') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMinX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMinY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + else if (defaultRef === 'zeroOrMax') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMaxX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMaxY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + return defaultRef; +} +exports.midPoint = midPoint; +function text(textDef, config) { + // text + if (textDef) { + if (fielddef_1.isFieldDef(textDef)) { + return common_1.formatSignalRef(textDef, textDef.format, 'datum', config); + } + else if (fielddef_1.isValueDef(textDef)) { + return { value: textDef.value }; + } + } + return undefined; +} +exports.text = text; +function mid(sizeRef) { + return __assign({}, sizeRef, { mult: 0.5 }); +} +exports.mid = mid; +function zeroOrMinX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the x-axis + return { value: 0 }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + return { field: { group: 'width' } }; +} +function zeroOrMinY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { field: { group: 'height' } }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.get('type')) && + scale.get('zero') !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { value: 0 }; +} + +},{"../../channel":15,"../../fielddef":100,"../../scale":108,"../../util":118,"../common":24}],66:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../channel"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var log = require("../log"); +var scale_1 = require("../scale"); +var title_1 = require("../title"); +var transform_1 = require("../transform"); +var util_1 = require("../util"); +var vega_schema_1 = require("../vega.schema"); +var assemble_1 = require("./axis/assemble"); +var header_1 = require("./layout/header"); +var assemble_2 = require("./layoutsize/assemble"); +var assemble_3 = require("./legend/assemble"); +var parse_1 = require("./legend/parse"); +var assemble_4 = require("./scale/assemble"); +var domain_1 = require("./scale/domain"); +var parse_2 = require("./scale/parse"); +var split_1 = require("./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; +}()); +exports.NameMap = 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'; +} +exports.isUnitModel = isUnitModel; +function isFacetModel(model) { + return model && model.type === 'facet'; +} +exports.isFacetModel = isFacetModel; +function isRepeatModel(model) { + return model && model.type === 'repeat'; +} +exports.isRepeatModel = isRepeatModel; +function isConcatModel(model) { + return model && model.type === 'concat'; +} +exports.isConcatModel = isConcatModel; +function isLayerModel(model) { + return model && model.type === 'layer'; +} +exports.isLayerModel = isLayerModel; +var Model = /** @class */ (function () { + function Model(spec, parent, parentGivenName, config, 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; + // If name is not provided, always use parent's givenName to avoid name conflicts. + this.name = spec.name || parentGivenName; + this.title = vega_util_1.isString(spec.title) ? { text: spec.title } : spec.title; + // Shared name maps + this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap(); + this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap(); + this.data = spec.data; + this.description = spec.description; + this.transforms = transform_1.normalizeTransform(spec.transform || []); + this.component = { + data: { + sources: parent ? parent.component.data.sources : {}, + outputNodes: parent ? parent.component.data.outputNodes : {}, + outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {}, + ancestorParse: parent ? __assign({}, parent.component.data.ancestorParse) : {} + }, + layoutSize: new split_1.Split(), + layoutHeaders: { row: {}, column: {} }, + mark: null, + resolve: __assign({ scale: {}, axis: {}, legend: {} }, (resolve || {})), + selection: null, + scales: 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.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections. + 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 () { + parse_2.parseScale(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 () { + parse_1.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.assembleHeaderMarks = function () { + var layoutHeaders = this.component.layoutHeaders; + var headerMarks = []; + for (var _i = 0, HEADER_CHANNELS_1 = header_1.HEADER_CHANNELS; _i < HEADER_CHANNELS_1.length; _i++) { + var channel = HEADER_CHANNELS_1[_i]; + if (layoutHeaders[channel].title) { + headerMarks.push(header_1.getTitleGroup(this, channel)); + } + } + for (var _a = 0, HEADER_CHANNELS_2 = header_1.HEADER_CHANNELS; _a < HEADER_CHANNELS_2.length; _a++) { + var channel = HEADER_CHANNELS_2[_a]; + var layoutHeader = layoutHeaders[channel]; + for (var _b = 0, HEADER_TYPES_1 = header_1.HEADER_TYPES; _b < HEADER_TYPES_1.length; _b++) { + var headerType = HEADER_TYPES_1[_b]; + if (layoutHeader[headerType]) { + for (var _c = 0, _d = layoutHeader[headerType]; _c < _d.length; _c++) { + var header = _d[_c]; + var headerGroup = header_1.getHeaderGroup(this, channel, headerType, layoutHeader, header); + if (headerGroup) { + headerMarks.push(headerGroup); + } + } + } + } + } + return headerMarks; + }; + Model.prototype.assembleAxes = function () { + return assemble_1.assembleAxes(this.component.axes); + }; + Model.prototype.assembleLegends = function () { + return assemble_3.assembleLegends(this); + }; + Model.prototype.assembleTitle = function () { + var title = __assign({}, title_1.extractTitleConfig(this.config.title).nonMark, this.title); + if (title.text) { + if (!util_1.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 util_1.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)) ? assemble_4.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 util_1.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) { + var type = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (scale_1.hasDiscreteDomain(type) && vega_schema_1.isVgRangeStep(range)) { + var scaleName = scaleComponent.get('name'); + var domain = domain_1.assembleDomain(this, channel); + var fieldName = domain_1.getFieldFromDomain(domain); + if (fieldName) { + var fieldRef = fielddef_1.field({ aggregate: 'distinct', field: fieldName }, { expr: 'datum' }); + return { + signal: assemble_2.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); + }; + /** + * @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 + (channel_1.isChannel(originalScaleName) && channel_1.isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) || + // in the scale name map (the the scale get merged by its parent) + this.scaleNameMap.has(this.getName(originalScaleName))) { + return this.scaleNameMap.get(this.getName(originalScaleName)); + } + 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 (varName, origName) { + var sel = this.component.selection[varName]; + if (!sel && this.parent) { + sel = this.parent.getSelectionComponent(varName, origName); + } + if (!sel) { + throw new Error(log.message.selectionNotFound(origName)); + } + return sel; + }; + return Model; +}()); +exports.Model = 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.field = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (!fieldDef) { + return undefined; + } + return fielddef_1.field(fieldDef, opt); + }; + ModelWithField.prototype.reduceFieldDef = function (f, init, t) { + return encoding_1.reduce(this.getMapping(), function (acc, cd, c) { + var fieldDef = fielddef_1.getFieldDef(cd); + if (fieldDef) { + return f(acc, fieldDef, c); + } + return acc; + }, init, t); + }; + ModelWithField.prototype.forEachFieldDef = function (f, t) { + encoding_1.forEach(this.getMapping(), function (cd, c) { + var fieldDef = fielddef_1.getFieldDef(cd); + if (fieldDef) { + f(fieldDef, c); + } + }, t); + }; + return ModelWithField; +}(Model)); +exports.ModelWithField = ModelWithField; + +},{"../channel":15,"../encoding":98,"../fielddef":100,"../log":105,"../scale":108,"../title":114,"../transform":116,"../util":118,"../vega.schema":120,"./axis/assemble":16,"./layout/header":46,"./layoutsize/assemble":47,"./legend/assemble":49,"./legend/parse":52,"./scale/assemble":70,"./scale/domain":72,"./scale/parse":73,"./split":89,"vega-util":10}],67:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var baseconcat_1 = require("./baseconcat"); +var buildmodel_1 = require("./buildmodel"); +var parse_1 = require("./layoutsize/parse"); +var RepeatModel = /** @class */ (function (_super) { + __extends(RepeatModel, _super); + function RepeatModel(spec, parent, parentGivenName, repeatValues, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, 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_1.buildModel(spec.spec, this, this.getName('child' + name_1), undefined, childRepeat, config, false)); + } + } + return children; + }; + RepeatModel.prototype.parseLayoutSize = function () { + parse_1.parseRepeatLayoutSize(this); + }; + RepeatModel.prototype.assembleLayout = function () { + // TODO: allow customization + return { + padding: { row: 10, column: 10 }, + offset: 10, + columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1, + bounds: 'full', + align: 'all' + }; + }; + return RepeatModel; +}(baseconcat_1.BaseConcatModel)); +exports.RepeatModel = RepeatModel; + +},{"../log":105,"./baseconcat":22,"./buildmodel":23,"./layoutsize/parse":48}],68:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../fielddef"); +var log = require("../log"); +var sort_1 = require("../sort"); +var util_1 = require("../util"); +function replaceRepeaterInFacet(facet, repeater) { + return replaceRepeater(facet, repeater); +} +exports.replaceRepeaterInFacet = replaceRepeaterInFacet; +function replaceRepeaterInEncoding(encoding, repeater) { + return replaceRepeater(encoding, repeater); +} +exports.replaceRepeaterInEncoding = replaceRepeaterInEncoding; +/** + * Replaces repeated value and returns if the repeated value is valid. + */ +function replaceRepeat(o, repeater) { + if (fielddef_1.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 { + 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 && sort_1.isSortField(fieldDef.sort)) { + var sort = replaceRepeat(fieldDef.sort, repeater); + fieldDef = __assign({}, fieldDef, (sort ? { sort: sort } : {})); + } + return fieldDef; +} +function replaceRepeaterInChannelDef(channelDef, repeater) { + if (fielddef_1.isFieldDef(channelDef)) { + var fd = replaceRepeaterInFieldDef(channelDef, repeater); + if (fd) { + return fd; + } + else if (fielddef_1.isConditionalDef(channelDef)) { + return { condition: channelDef.condition }; + } + } + else { + if (fielddef_1.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 (util_1.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; +} + +},{"../fielddef":100,"../log":105,"../sort":110,"../util":118}],69:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var log = require("../log"); +var util_1 = require("../util"); +var model_1 = require("./model"); +function defaultScaleResolve(channel, model) { + if (model_1.isLayerModel(model) || model_1.isFacetModel(model)) { + return 'shared'; + } + else if (model_1.isConcatModel(model) || model_1.isRepeatModel(model)) { + return util_1.contains(channel_1.POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared'; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('invalid model type for resolve'); +} +exports.defaultScaleResolve = defaultScaleResolve; +function parseGuideResolve(resolve, channel) { + var channelScaleResolve = resolve.scale[channel]; + var guide = util_1.contains(channel_1.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'; +} +exports.parseGuideResolve = parseGuideResolve; + +},{"../channel":15,"../log":105,"../util":118,"./model":66}],70:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var util_1 = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var model_1 = require("../model"); +var selection_1 = require("../selection/selection"); +var domain_1 = require("./domain"); +function assembleScales(model) { + if (model_1.isLayerModel(model) || model_1.isConcatModel(model) || model_1.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); + } +} +exports.assembleScales = assembleScales; +function assembleScalesForModel(model) { + return util_1.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 && selection_1.isRawSelectionDomain(domainRaw)) { + domainRaw = selection_1.selectionScaleDomain(model, domainRaw); + } + scales.push(__assign({ name: name, + type: type, domain: domain_1.assembleDomain(model, channel) }, (domainRaw ? { domainRaw: domainRaw } : {}), { range: range }, otherScaleProps)); + return scales; + }, []); +} +exports.assembleScalesForModel = assembleScalesForModel; +function assembleScaleRange(scaleRange, scaleName, model, channel) { + // add signals to x/y range + if (channel === 'x' || channel === 'y') { + if (vega_schema_1.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 (vega_util_1.isArray(scaleRange) && scaleRange.length === 2) { + var r0 = scaleRange[0]; + var r1 = scaleRange[1]; + if (r0 === 0 && vega_schema_1.isVgSignalRef(r1)) { + // Replace width signal just in case it is renamed. + return [0, { signal: model.getSizeName(r1.signal) }]; + } + else if (vega_schema_1.isVgSignalRef(r0) && r1 === 0) { + // Replace height signal just in case it is renamed. + return [{ signal: model.getSizeName(r0.signal) }, 0]; + } + } + } + return scaleRange; +} +exports.assembleScaleRange = assembleScaleRange; + +},{"../../util":118,"../../vega.schema":120,"../model":66,"../selection/selection":79,"./domain":72,"vega-util":10}],71:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var split_1 = require("../split"); +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_1.Split)); +exports.ScaleComponent = ScaleComponent; + +},{"../split":89}],72:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var aggregate_1 = require("../../aggregate"); +var bin_1 = require("../../bin"); +var channel_1 = require("../../channel"); +var data_1 = require("../../data"); +var datetime_1 = require("../../datetime"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var sort_1 = require("../../sort"); +var util = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var vega_schema_2 = require("../../vega.schema"); +var common_1 = require("../common"); +var optimize_1 = require("../data/optimize"); +var model_1 = require("../model"); +var selection_1 = require("../selection/selection"); +function parseScaleDomain(model) { + if (model_1.isUnitModel(model)) { + parseUnitScaleDomain(model); + } + else { + parseNonUnitScaleDomain(model); + } +} +exports.parseScaleDomain = parseScaleDomain; +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 (scale_1.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_1.SELECTION_DOMAIN + JSON.stringify(specifiedDomain) + }, true); + } + }); +} +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) { + // FIXME: Arvind -- Please revise logic for merging selectionDomain / domainRaw + var domains; + 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); + } + } + } + if (model_1.isFacetModel(model)) { + domains.forEach(function (domain) { + // Replace the scale domain with data output from a cloned subtree after the facet. + if (vega_schema_1.isDataRefDomain(domain)) { + // use data from cloned subtree (which is the same as data but with a prefix added once) + domain.data = optimize_1.FACET_SCALE_PREFIX + domain.data.replace(optimize_1.FACET_SCALE_PREFIX, ''); + } + }); + } + localScaleComponents[channel].domains = domains; + }); +} +/** + * 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; +} +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); +} +exports.parseDomainForChannel = parseDomainForChannel; +function parseSingleChannelDomain(scaleType, domain, model, channel) { + var fieldDef = model.fieldDef(channel); + if (domain && domain !== 'unaggregated' && !scale_1.isSelectionDomain(domain)) { + if (fieldDef.bin) { + log.warn(log.message.conflictedDomain(channel)); + } + else { + if (datetime_1.isDateTime(domain[0])) { + return domain.map(function (dt) { + return { signal: "{data: " + datetime_1.dateTimeExpr(dt, true) + "}" }; + }); + } + return [domain]; + } + } + var stack = model.stack; + if (stack && channel === stack.fieldChannel) { + if (stack.offset === 'normalize') { + return [[0, 1]]; + } + var data = model.requestDataName(data_1.MAIN); + return [{ + data: data, + field: model.field(channel, { suffix: 'start' }) + }, { + data: data, + field: model.field(channel, { suffix: 'end' }) + }]; + } + var sort = channel_1.isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined; + if (domain === 'unaggregated') { + var data = model.requestDataName(data_1.MAIN); + return [{ + data: data, + field: model.field(channel, { aggregate: 'min' }) + }, { + data: data, + field: model.field(channel, { aggregate: 'max' }) + }]; + } + else if (fieldDef.bin) { + if (scale_1.isBinScale(scaleType)) { + var signal = model.getName(bin_1.binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return [{ signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }]; + } + if (scale_1.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(data_1.MAIN) : model.requestDataName(data_1.RAW), + // Use range if we added it and the scale does not support computing a range as a signal. + field: model.field(channel, common_1.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 || !sort_1.isSortField(sort) ? { + field: model.field(channel, {}), + op: 'min' // min or max doesn't matter since we sort by the start of the bin range + } : sort + }]; + } + else { + if (channel === 'x' || channel === 'y') { + // X/Y position have to include start and end for non-ordinal scale + var data = model.requestDataName(data_1.MAIN); + return [{ + data: data, + field: model.field(channel, {}) + }, { + data: data, + field: model.field(channel, { binSuffix: 'end' }) + }]; + } + else { + // TODO: use bin_mid + return [{ + data: model.requestDataName(data_1.MAIN), + field: model.field(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(data_1.MAIN) : model.requestDataName(data_1.RAW), + field: model.field(channel), + sort: sort + }]; + } + else { + return [{ + data: model.requestDataName(data_1.MAIN), + field: model.field(channel) + }]; + } +} +function domainSort(model, channel, scaleType) { + if (!scale_1.hasDiscreteDomain(scaleType)) { + return undefined; + } + var sort = model.sort(channel); + // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale) + if (sort_1.isSortField(sort)) { + return sort; + } + if (sort === 'descending') { + return { + op: 'min', + field: model.field(channel), + order: 'descending' + }; + } + if (util.contains(['ascending', undefined /* default =ascending*/], sort)) { + return true; + } + // sort == null + return undefined; +} +exports.domainSort = domainSort; +/** + * 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: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef) + }; + } + if (!aggregate_1.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 }; +} +exports.canUseUnaggregatedDomain = canUseUnaggregatedDomain; +/** + * Converts an array of domains to a single Vega scale domain. + */ +function mergeDomains(domains) { + var uniqueDomains = util.unique(domains.map(function (domain) { + // ignore sort property when computing the unique domains + if (vega_schema_1.isDataRefDomain(domain)) { + var _s = domain.sort, domainWithoutSort = __rest(domain, ["sort"]); + return domainWithoutSort; + } + return domain; + }), util.hash); + var sorts = util.unique(domains.map(function (d) { + if (vega_schema_1.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 (vega_schema_1.isDataRefDomain(domain) && sorts.length > 0) { + var sort_2 = sorts[0]; + if (sorts.length > 1) { + log.warn(log.message.MORE_THAN_ONE_SORT); + sort_2 = true; + } + return __assign({}, domain, { sort: sort_2 }); + } + 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 (vega_schema_1.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 } : {})); +} +exports.mergeDomains = mergeDomains; +/** + * Return a field if a scale single field. + * Return `undefined` otherwise. + * + */ +function getFieldFromDomain(domain) { + if (vega_schema_1.isDataRefDomain(domain) && util.isString(domain.field)) { + return domain.field; + } + else if (vega_schema_2.isDataRefUnionedDomain(domain)) { + var field = void 0; + for (var _i = 0, _a = domain.fields; _i < _a.length; _i++) { + var nonUnionDomain = _a[_i]; + if (vega_schema_1.isDataRefDomain(nonUnionDomain) && util.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 (vega_schema_2.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 util.isString(field) ? field : undefined; + } + return undefined; +} +exports.getFieldFromDomain = getFieldFromDomain; +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 (vega_schema_1.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); +} +exports.assembleDomain = assembleDomain; + +},{"../../aggregate":12,"../../bin":14,"../../channel":15,"../../data":96,"../../datetime":97,"../../log":105,"../../scale":108,"../../sort":110,"../../util":118,"../../vega.schema":120,"../common":24,"../data/optimize":38,"../model":66,"../selection/selection":79}],73:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var resolve_1 = require("../resolve"); +var split_1 = require("../split"); +var component_1 = require("./component"); +var domain_1 = require("./domain"); +var properties_1 = require("./properties"); +var range_1 = require("./range"); +var type_1 = require("./type"); +function parseScale(model) { + parseScaleCore(model); + domain_1.parseScaleDomain(model); + for (var _i = 0, NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1 = scale_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]; + properties_1.parseScaleProperty(model, prop); + } + // range depends on zero + range_1.parseScaleRange(model); +} +exports.parseScale = parseScale; +function parseScaleCore(model) { + if (model_1.isUnitModel(model)) { + model.component.scales = parseUnitScaleCore(model); + } + else { + model.component.scales = parseNonUnitScaleCore(model); + } +} +exports.parseScaleCore = parseScaleCore; +/** + * Parse scales for all channels of a model. + */ +function parseUnitScaleCore(model) { + var encoding = model.encoding, config = model.config; + var mark = model.mark(); + return channel_1.SCALE_CHANNELS.reduce(function (scaleComponents, channel) { + var fieldDef; + var specifiedScale = {}; + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale || {}; + } + else if (fielddef_1.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 = fielddef_1.getFieldDef(encoding.x2); + } + else if (channel === 'y') { + fieldDef = fielddef_1.getFieldDef(encoding.y2); + } + if (fieldDef) { + var specifiedScaleType = specifiedScale.type; + var sType = type_1.scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale); + scaleComponents[channel] = new component_1.ScaleComponent(model.scaleName(channel + '', true), { value: sType, explicit: specifiedScaleType === sType }); + } + return scaleComponents; + }, {}); +} +var scaleTypeTieBreaker = split_1.tieBreakByComparing(function (st1, st2) { return (scale_1.scaleTypePrecedence(st1) - scale_1.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! + util_1.keys(child.component.scales).forEach(function (channel) { + // if resolve is undefined, set default first + resolve.scale[channel] = resolve.scale[channel] || resolve_1.defaultScaleResolve(channel, model); + if (resolve.scale[channel] === 'shared') { + var scaleType_1 = scaleTypeWithExplicitIndex[channel]; + var childScaleType = child.component.scales[channel].getWithExplicit('type'); + if (scaleType_1) { + if (scale_1.scaleCompatible(scaleType_1.value, childScaleType.value)) { + // merge scale component if type are compatible + scaleTypeWithExplicitIndex[channel] = split_1.mergeValuesWithExplicit(scaleType_1, 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 + util_1.keys(scaleTypeWithExplicitIndex).forEach(function (channel) { + // Create new merged scale component + var name = model.scaleName(channel, true); + var typeWithExplicit = scaleTypeWithExplicitIndex[channel]; + scaleComponents[channel] = new component_1.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; +} + +},{"../../channel":15,"../../fielddef":100,"../../scale":108,"../../util":118,"../model":66,"../resolve":69,"../split":89,"./component":71,"./domain":72,"./properties":74,"./range":75,"./type":76}],74:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var util = require("../../util"); +var model_1 = require("../model"); +var split_1 = require("../split"); +var range_1 = require("./range"); +function parseScaleProperty(model, property) { + if (model_1.isUnitModel(model)) { + parseUnitScaleProperty(model, property); + } + else { + parseNonUnitScaleProperty(model, property); + } +} +exports.parseScaleProperty = parseScaleProperty; +function parseUnitScaleProperty(model, property) { + var localScaleComponents = model.component.scales; + util_1.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 sort = model.sort(channel); + var config = model.config; + var specifiedValue = specifiedScale[property]; + var sType = mergedScaleCmpt.get('type'); + var supportedByScaleType = scale_1.scaleTypeSupportProperty(sType, property); + var channelIncompatability = scale_1.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) { + 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, sort, 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, sort, 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, sort); + case 'zero': + return zero(channel, fieldDef, specifiedDomain); + } + // Otherwise, use scale config + return scaleConfig[property]; +} +exports.getDefaultValue = getDefaultValue; +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') { + range_1.parseScaleRange(child); + } + else { + parseScaleProperty(child, property); + } + } + util_1.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 = split_1.mergeValuesWithExplicit(valueWithExplicit, childValueWithExplicit, property, 'scale', split_1.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; + } + return 0; + })); + } + } + localScaleComponents[channel].setWithExplicit(property, valueWithExplicit); + }); +} +exports.parseNonUnitScaleProperty = parseNonUnitScaleProperty; +function nice(scaleType, channel, fieldDef) { + if (fieldDef.bin || util.contains([scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scaleType)) { + return undefined; + } + return util.contains([channel_1.X, channel_1.Y], channel); // return true for quantitative X/Y unless binned +} +exports.nice = nice; +function padding(channel, scaleType, scaleConfig, fieldDef, markDef, barConfig) { + if (util.contains([channel_1.X, channel_1.Y], channel)) { + if (scale_1.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 === scale_1.ScaleType.POINT) { + return scaleConfig.pointPadding; + } + } + return undefined; +} +exports.padding = padding; +function paddingInner(padding, channel, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingInner. + return undefined; + } + if (util.contains([channel_1.X, channel_1.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; +} +exports.paddingInner = paddingInner; +function paddingOuter(padding, channel, scaleType, paddingInner, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingOuter. + return undefined; + } + if (util.contains([channel_1.X, channel_1.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 === scale_1.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 paddingInner / 2; + } + } + return undefined; +} +exports.paddingOuter = paddingOuter; +function reverse(scaleType, sort) { + if (scale_1.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; +} +exports.reverse = reverse; +function zero(channel, fieldDef, specifiedScale) { + // By default, 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 if no custom domain is provided. + // (For binning, we should not include zero by default because binning are calculated without zero. + // Similar, if users explicitly provide a domain range, we should not augment zero as that will be unexpected.) + var hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated'; + if (!hasCustomDomain && !fieldDef.bin && util.contains([channel_1.X, channel_1.Y], channel)) { + return true; + } + return false; +} +exports.zero = zero; + +},{"../../channel":15,"../../log":105,"../../scale":108,"../../util":118,"../model":66,"../split":89,"./range":75}],75:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var scale_2 = require("../../scale"); +var util = require("../../util"); +var vega_schema_1 = require("../../vega.schema"); +var model_1 = require("../model"); +var split_1 = require("../split"); +var properties_1 = require("./properties"); +exports.RANGE_PROPERTIES = ['range', 'rangeStep', 'scheme']; +function parseScaleRange(model) { + if (model_1.isUnitModel(model)) { + parseUnitScaleRange(model); + } + else { + properties_1.parseNonUnitScaleProperty(model, 'range'); + } +} +exports.parseScaleRange = parseScaleRange; +function parseUnitScaleRange(model) { + var localScaleComponents = model.component.scales; + // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first! + channel_1.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 && vega_schema_1.isVgRangeStep(xRange) && vega_util_1.isNumber(xRange.step)) { + xyRangeSteps.push(xRange.step); + } + var yScale = model.getScaleComponent('y'); + var yRange = yScale && yScale.get('range'); + if (yRange && vega_schema_1.isVgRangeStep(yRange) && vega_util_1.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, 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 = exports.RANGE_PROPERTIES; _i < RANGE_PROPERTIES_1.length; _i++) { + var property = RANGE_PROPERTIES_1[_i]; + if (specifiedScale[property] !== undefined) { + var supportedByScaleType = scale_1.scaleTypeSupportProperty(scaleType, property); + var channelIncompatability = scale_1.channelScalePropertyIncompatability(channel, property); + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel)); + } + else if (channelIncompatability) { + log.warn(channelIncompatability); + } + else { + switch (property) { + case 'range': + return split_1.makeExplicit(specifiedScale[property]); + case 'scheme': + return split_1.makeExplicit(parseScheme(specifiedScale[property])); + case 'rangeStep': + var rangeStep = specifiedScale[property]; + if (rangeStep !== null) { + if (!sizeSpecified) { + return split_1.makeExplicit({ step: rangeStep }); + } + else { + // If top-level size is specified, we ignore specified rangeStep. + log.warn(log.message.rangeStepDropped(channel)); + } + } + } + } + } + } + return split_1.makeImplicit(defaultRange(channel, scaleType, type, config, zero, mark, sizeSignal, xyRangeSteps, noRangeStep)); +} +exports.parseRangeForChannel = parseRangeForChannel; +function parseScheme(scheme) { + if (scale_1.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, mark, sizeSignal, xyRangeSteps, noRangeStep) { + switch (channel) { + case channel_1.X: + case channel_1.Y: + if (util.contains(['point', 'band'], scaleType) && !noRangeStep) { + if (channel === channel_1.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 === channel_1.Y && scale_2.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 channel_1.SIZE: + // TODO: support custom rangeMin, rangeMax + var rangeMin = sizeRangeMin(mark, zero, config); + var rangeMax = sizeRangeMax(mark, xyRangeSteps, config); + return [rangeMin, rangeMax]; + case channel_1.SHAPE: + return 'symbol'; + case channel_1.COLOR: + if (scaleType === 'ordinal') { + // Only nominal data uses ordinal scale by default + return type === 'nominal' ? 'category' : 'ordinal'; + } + return mark === 'rect' ? 'heatmap' : 'ramp'; + case channel_1.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); +} +exports.defaultRange = defaultRange; +function sizeRangeMin(mark, zero, config) { + if (zero) { + return 0; + } + switch (mark) { + case 'bar': + case 'tick': + return config.scale.minBandSize; + case 'line': + 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; + // TODO(#1168): make max size scale based on rangeStep / overall plot size + switch (mark) { + case 'bar': + case 'tick': + if (config.scale.maxBandSize !== undefined) { + return config.scale.maxBandSize; + } + return minXYRangeStep(xyRangeSteps, config.scale) - 1; + case 'line': + 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. +} + +},{"../../channel":15,"../../log":105,"../../scale":108,"../../util":118,"../../vega.schema":120,"../model":66,"../split":89,"./properties":74,"vega-util":10}],76:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var scale_2 = require("../../scale"); +var type_1 = require("../../type"); +var util = require("../../util"); +var util_1 = require("../../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. +function scaleType(specifiedType, channel, fieldDef, mark, scaleConfig) { + var defaultScaleType = defaultType(channel, fieldDef, mark, scaleConfig); + if (!channel_1.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 (!scale_1.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 (!fieldDefMatchScaleType(specifiedType, fieldDef)) { + log.warn(log.message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType)); + return defaultScaleType; + } + return specifiedType; + } + return defaultScaleType; +} +exports.scaleType = scaleType; +/** + * Determine appropriate default scale type. + */ +// NOTE: Voyager uses this method. +function defaultType(channel, fieldDef, mark, scaleConfig) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + if (channel === 'color' || channel_1.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 (mark === 'rect') { + // The rect mark should fit into a band. + 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 (channel === 'color') { + return 'sequential'; + } + else if (channel_1.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 (channel === 'color') { + 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 (channel_1.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'; + } + /* istanbul ignore next: should never reach this */ + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +function fieldDefMatchScaleType(specifiedType, fieldDef) { + var type = fieldDef.type; + if (util_1.contains([type_1.Type.ORDINAL, type_1.Type.NOMINAL], type)) { + return specifiedType === undefined || scale_2.hasDiscreteDomain(specifiedType); + } + else if (type === type_1.Type.TEMPORAL) { + return util_1.contains([scale_1.ScaleType.TIME, scale_1.ScaleType.UTC, scale_1.ScaleType.SEQUENTIAL, undefined], specifiedType); + } + else if (type === type_1.Type.QUANTITATIVE) { + if (fieldDef.bin) { + return util_1.contains([scale_1.ScaleType.BIN_LINEAR, scale_1.ScaleType.BIN_ORDINAL, scale_1.ScaleType.LINEAR], specifiedType); + } + return util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.POW, scale_1.ScaleType.SQRT, scale_1.ScaleType.QUANTILE, scale_1.ScaleType.QUANTIZE, scale_1.ScaleType.LINEAR, scale_1.ScaleType.SEQUENTIAL, undefined], specifiedType); + } + return true; +} +exports.fieldDefMatchScaleType = fieldDefMatchScaleType; + +},{"../../channel":15,"../../log":105,"../../scale":108,"../../type":117,"../../util":118}],77:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var log_1 = require("../../log"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var selection_1 = require("./selection"); +var scales_1 = require("./transforms/scales"); +exports.BRUSH = '_brush'; +exports.SCALE_TRIGGER = '_scale_trigger'; +var interval = { + predicate: 'vlInterval', + scaleDomain: 'vlIntervalDomain', + signals: function (model, selCmpt) { + var name = selCmpt.name; + var hasScales = scales_1.default.has(selCmpt); + var signals = []; + var intervals = []; + var tupleTriggers = []; + var scaleTriggers = []; + if (selCmpt.translate && !hasScales) { + var filterExpr_1 = "!event.item || event.item.mark.name !== " + util_1.stringValue(name + exports.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 !== channel_1.X && channel !== channel_1.Y) { + log_1.warn('Interval selections only support x and y encoding channels.'); + return; + } + var cs = channelSignals(model, selCmpt, channel); + var dname = selection_1.channelSignalName(selCmpt, channel, 'data'); + var vname = selection_1.channelSignalName(selCmpt, channel, 'visual'); + var scaleStr = util_1.stringValue(model.scaleName(channel)); + var scaleType = model.getScaleComponent(channel).get('type'); + var toNum = scale_1.hasContinuousDomain(scaleType) ? '+' : ''; + signals.push.apply(signals, cs); + tupleTriggers.push(dname); + intervals.push("{encoding: " + util_1.stringValue(channel) + ", " + + ("field: " + util_1.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 + exports.SCALE_TRIGGER, + update: scaleTriggers.map(function (t) { return t.expr; }).join(' && ') + + (" ? " + (name + exports.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 + selection_1.TUPLE, + on: [{ + events: tupleTriggers.map(function (t) { return ({ signal: t }); }), + update: tupleTriggers.join(' && ') + + (" ? {unit: " + selection_1.unitName(model) + ", intervals: [" + intervals.join(', ') + "]} : null") + }] + }); + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + selection_1.TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + selection_1.unitName(model) + "}"); + }, + marks: function (model, selCmpt, marks) { + var name = selCmpt.name; + var _a = selection_1.positionalProjections(selCmpt), xi = _a.xi, yi = _a.yi; + var store = "data(" + util_1.stringValue(selCmpt.name + selection_1.STORE) + ")"; + // Do not add a brush if we're binding to scales. + if (scales_1.default.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 = util_1.keys(update); _i < _b.length; _i++) { + var key = _b[_i]; + update[key] = [__assign({ test: store + ".length && " + store + "[0].unit === " + selection_1.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 = __rest(_c, ["fill", "fillOpacity"]); + var vgStroke = util_1.keys(stroke).reduce(function (def, k) { + def[k] = { value: stroke[k] }; + return def; + }, {}); + return [{ + name: name + exports.BRUSH + '_bg', + type: 'rect', + clip: true, + encode: { + enter: { + fill: { value: fill }, + fillOpacity: { value: fillOpacity } + }, + update: update + } + }].concat(marks, { + name: name + exports.BRUSH, + type: 'rect', + clip: true, + encode: { + enter: __assign({ fill: { value: 'transparent' } }, vgStroke), + update: update + } + }); + } +}; +exports.default = interval; +/** + * Returns the visual and data signals for an interval selection. + */ +function channelSignals(model, selCmpt, channel) { + var vname = selection_1.channelSignalName(selCmpt, channel, 'visual'); + var dname = selection_1.channelSignalName(selCmpt, channel, 'data'); + var hasScales = scales_1.default.has(selCmpt); + var scaleName = model.scaleName(channel); + var scaleStr = util_1.stringValue(scaleName); + var scale = model.getScaleComponent(channel); + var scaleType = scale ? scale.get('type') : undefined; + var size = model.getSizeSignalRef(channel === channel_1.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 + exports.SCALE_TRIGGER }, + update: scale_1.hasContinuousDomain(scaleType) && !scale_1.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) { + log_1.warn(evt + " is not an ordered event stream for interval selections"); + return on; + } + return cb(on, evt); + }, []); +} + +},{"../../channel":15,"../../log":105,"../../scale":108,"../../util":118,"./selection":79,"./transforms/scales":84}],78:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var selection_1 = require("./selection"); +var nearest_1 = require("./transforms/nearest"); +var multi = { + predicate: 'vlMulti', + scaleDomain: 'vlMultiDomain', + signals: function (model, selCmpt) { + var proj = selCmpt.project; + var datum = nearest_1.default.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + var bins = []; + var encodings = proj.map(function (p) { return util_1.stringValue(p.channel); }).filter(function (e) { return e; }).join(', '); + var fields = proj.map(function (p) { return util_1.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), + "[" + datum + util_1.accessPath(model.field(channel, {})) + ", " + + ("" + datum + util_1.accessPath(model.field(channel, { binSuffix: 'end' })) + "]")) : + "" + datum + util_1.accessPath(p.field); + }).join(', '); + // Only add a discrete selection to the store if a datum is present _and_ + // the interaction isn't occuring 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 + selection_1.TUPLE, + value: {}, + on: [{ + events: selCmpt.events, + update: "datum && item().mark.marktype !== 'group' ? " + + ("{unit: " + selection_1.unitName(model) + ", encodings: [" + encodings + "], ") + + ("fields: [" + fields + "], values: [" + values + "]") + + (bins.length ? ', ' + bins.map(function (b) { return util_1.stringValue('bin_' + b) + ": 1"; }).join(', ') : '') + + '} : null', + force: true + }] + }]; + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + selection_1.TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'null' : "{unit: " + selection_1.unitName(model) + "}"); + } +}; +exports.default = multi; + +},{"../../util":118,"./selection":79,"./transforms/nearest":82}],79:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_event_selector_1 = require("vega-event-selector"); +var channel_1 = require("../../channel"); +var log_1 = require("../../log"); +var selection_1 = require("../../selection"); +var util_1 = require("../../util"); +var model_1 = require("../model"); +var interval_1 = require("./interval"); +var multi_1 = require("./multi"); +var single_1 = require("./single"); +var transforms_1 = require("./transforms/transforms"); +exports.STORE = '_store'; +exports.TUPLE = '_tuple'; +exports.MODIFY = '_modify'; +exports.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 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] = __assign({}, cfg[key], selDef[key]); + } + if (selDef[key] === undefined || selDef[key] === true) { + selDef[key] = cfg[key] || selDef[key]; + } + } + name_1 = util_1.varName(name_1); + var selCmpt = selCmpts[name_1] = __assign({}, selDef, { name: name_1, events: util_1.isString(selDef.on) ? vega_event_selector_1.selector(selDef.on, 'scope') : selDef.on }); + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.parse) { + txCompiler.parse(model, selDef, selCmpt); + } + }); + }; + for (var name_1 in selDefs) { + _loop_1(name_1); + } + return selCmpts; +} +exports.parseUnitSelection = parseUnitSelection; +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)); + transforms_1.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 + exports.MODIFY, + on: [{ + events: { signal: name + exports.TUPLE }, + update: "modify(" + util_1.stringValue(selCmpt.name + exports.STORE) + ", " + modifyExpr + ")" + }] + }); + }); + var facetModel = getFacetModel(model); + if (signals.length && facetModel) { + var name_2 = util_1.stringValue(facetModel.getName('cell')); + signals.unshift({ + name: 'facet', + value: {}, + on: [{ + events: vega_event_selector_1.selector('mousemove', 'scope'), + update: "isTuple(facet) ? facet : group(" + name_2 + ").datum" + }] + }); + } + return signals; +} +exports.assembleUnitSelectionSignals = assembleUnitSelectionSignals; +function assembleTopLevelSignals(model, signals) { + var needsUnit = false; + forEachSelection(model, function (selCmpt, selCompiler) { + if (selCompiler.topLevelSignals) { + signals = selCompiler.topLevelSignals(model, selCmpt, signals); + } + transforms_1.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; +} +exports.assembleTopLevelSignals = assembleTopLevelSignals; +function assembleUnitSelectionData(model, data) { + forEachSelection(model, function (selCmpt) { + var contains = data.filter(function (d) { return d.name === selCmpt.name + exports.STORE; }); + if (!contains.length) { + data.push({ name: selCmpt.name + exports.STORE }); + } + }); + return data; +} +exports.assembleUnitSelectionData = assembleUnitSelectionData; +function assembleUnitSelectionMarks(model, marks) { + forEachSelection(model, function (selCmpt, selCompiler) { + marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks; + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.marks) { + marks = txCompiler.marks(model, selCmpt, marks); + } + }); + }); + return marks; +} +exports.assembleUnitSelectionMarks = assembleUnitSelectionMarks; +function assembleLayerSelectionMarks(model, marks) { + model.children.forEach(function (child) { + if (model_1.isUnitModel(child)) { + marks = assembleUnitSelectionMarks(child, marks); + } + }); + return marks; +} +exports.assembleLayerSelectionMarks = assembleLayerSelectionMarks; +function predicate(model, selections, dfnode) { + var stores = []; + function expr(name) { + var vname = util_1.varName(name); + var selCmpt = model.getSelectionComponent(vname, name); + var store = util_1.stringValue(vname + exports.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' ? ')' : ", " + util_1.stringValue(selCmpt.resolve) + ")"); + } + var predicateStr = util_1.logicalExpr(selections, expr); + return (stores.length + ? '!(' + stores.map(function (s) { return "length(data(" + s + "))"; }).join(' || ') + ') || ' + : '') + ("(" + predicateStr + ")"); +} +exports.predicate = predicate; +// 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(exports.SELECTION_DOMAIN) >= 0; +} +exports.isRawSelectionDomain = isRawSelectionDomain; +function selectionScaleDomain(model, domainRaw) { + var selDomain = JSON.parse(domainRaw.signal.replace(exports.SELECTION_DOMAIN, '')); + var name = util_1.varName(selDomain.selection); + var selCmpt = model.component.selection && model.component.selection[name]; + if (selCmpt) { + log_1.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) { + log_1.warn('A "field" or "encoding" must be specified when using a selection as a scale domain. ' + + ("Using \"field\": " + util_1.stringValue(selDomain.field) + ".")); + } + } + return { + signal: compiler(selCmpt.type).scaleDomain + + ("(" + util_1.stringValue(name + exports.STORE) + ", " + util_1.stringValue(selDomain.encoding || null) + ", ") + + util_1.stringValue(selDomain.field || null) + + (selCmpt.resolve === 'global' ? ')' : ", " + util_1.stringValue(selCmpt.resolve) + ")") + }; + } + return { signal: 'null' }; +} +exports.selectionScaleDomain = selectionScaleDomain; +// 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_1.default; + case 'multi': + return multi_1.default; + case 'interval': + return interval_1.default; + } + return null; +} +function getFacetModel(model) { + var parent = model.parent; + while (parent) { + if (model_1.isFacetModel(parent)) { + break; + } + parent = parent.parent; + } + return parent; +} +function unitName(model) { + var name = util_1.stringValue(model.name); + var facet = getFacetModel(model); + if (facet) { + name += (facet.facet.row ? " + '_' + facet" + util_1.accessPath(facet.field('row')) : '') + + (facet.facet.column ? " + '_' + facet" + util_1.accessPath(facet.field('column')) : ''); + } + return name; +} +exports.unitName = unitName; +function requiresSelectionId(model) { + var identifier = false; + forEachSelection(model, function (selCmpt) { + identifier = identifier || selCmpt.project.some(function (proj) { return proj.field === selection_1.SELECTION_ID; }); + }); + return identifier; +} +exports.requiresSelectionId = requiresSelectionId; +function channelSignalName(selCmpt, channel, range) { + return util_1.varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel])); +} +exports.channelSignalName = channelSignalName; +function positionalProjections(selCmpt) { + var x = null; + var xi = null; + var y = null; + var yi = null; + selCmpt.project.forEach(function (p, i) { + if (p.channel === channel_1.X) { + x = p; + xi = i; + } + else if (p.channel === channel_1.Y) { + y = p; + yi = i; + } + }); + return { x: x, xi: xi, y: y, yi: yi }; +} +exports.positionalProjections = positionalProjections; + +},{"../../channel":15,"../../log":105,"../../selection":109,"../../util":118,"../model":66,"./interval":77,"./multi":78,"./single":80,"./transforms/transforms":86,"vega-event-selector":9}],80:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var multi_1 = require("./multi"); +var selection_1 = require("./selection"); +var single = { + predicate: 'vlSingle', + scaleDomain: 'vlSingleDomain', + signals: multi_1.default.signals, + topLevelSignals: function (model, selCmpt, signals) { + var hasSignal = signals.filter(function (s) { return s.name === selCmpt.name; }); + var data = "data(" + util_1.stringValue(selCmpt.name + selection_1.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 + selection_1.TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + selection_1.unitName(model) + "}"); + } +}; +exports.default = single; + +},{"../../util":118,"./multi":78,"./selection":79}],81:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../../util"); +var selection_1 = require("../selection"); +var nearest_1 = require("./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_1.default.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + proj.forEach(function (p) { + var sgname = util_1.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' ? " + datum + util_1.accessPath(p.field) + " : 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 + selection_1.TUPLE; })[0]; + var fields = proj.map(function (p) { return util_1.stringValue(p.field); }).join(', '); + var values = proj.map(function (p) { return util_1.varName(name + "_" + p.field); }); + signal.update = values.join(' && ') + " ? {fields: [" + fields + "], values: [" + values.join(', ') + "]} : null"; + delete signal.value; + delete signal.on; + return signals; + } +}; +exports.default = inputBindings; + +},{"../../../util":118,"../selection":79,"./nearest":82}],82:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../log"); +var selection_1 = require("../selection"); +var VORONOI = 'voronoi'; +var nearest = { + has: function (selCmpt) { + return selCmpt.type !== 'interval' && selCmpt.nearest; + }, + marks: function (model, selCmpt, marks) { + var _a = selection_1.positionalProjections(selCmpt), x = _a.x, y = _a.y; + var markType = model.mark(); + if (markType === 'line' || markType === 'area') { + 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: (x || (!x && !y)) ? 'datum.x' : { expr: '0' }, + y: (y || (!x && !y)) ? 'datum.y' : { expr: '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; + } +}; +exports.default = nearest; + +},{"../../../log":105,"../selection":79}],83:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../log"); +var util_1 = require("../../../util"); +var timeunit_1 = require("../../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.field(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 (util_1.keys(timeUnits).length) { + selCmpt.timeUnit = new timeunit_1.TimeUnitNode(timeUnits); + } + } +}; +exports.default = project; + +},{"../../../log":105,"../../../util":118,"../../data/timeunit":43}],84:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../log"); +var scale_1 = require("../../../scale"); +var util_1 = require("../../../util"); +var selection_1 = require("../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 || !scale_1.hasContinuousDomain(scaleType) || scale_1.isBinScale(scaleType)) { + log.warn(log.message.SCALE_BINDINGS_CONTINUOUS); + return; + } + scale.set('domainRaw', { signal: selection_1.channelSignalName(selCmpt, channel, 'data') }, true); + bound.push(channel); + }); + }, + 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 === selection_1.channelSignalName(selCmpt, channel, 'data'); }).length); + }); + return signals.concat(channels.map(function (channel) { + return { name: selection_1.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 === selection_1.channelSignalName(selCmpt, channel, 'data'); })[0]; + signal.push = 'outer'; + delete signal.value; + delete signal.update; + }); + } + return signals; + } +}; +exports.default = scaleBindings; +function domain(model, channel) { + var scale = util_1.stringValue(model.scaleName(channel)); + return "domain(" + scale + ")"; +} +exports.domain = domain; + +},{"../../../log":105,"../../../scale":108,"../../../util":118,"../selection":79}],85:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("../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 + selection_1.TUPLE; + var signal = selCmpt.name + TOGGLE; + return signal + " ? null : " + tpl + ", " + + (selCmpt.resolve === 'global' ? + signal + " ? null : true, " : + signal + " ? null : {unit: " + selection_1.unitName(model) + "}, ") + + (signal + " ? " + tpl + " : null"); + } +}; +exports.default = toggle; + +},{"../selection":79}],86:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var inputs_1 = require("./inputs"); +var nearest_1 = require("./nearest"); +var project_1 = require("./project"); +var scales_1 = require("./scales"); +var toggle_1 = require("./toggle"); +var translate_1 = require("./translate"); +var zoom_1 = require("./zoom"); +var compilers = { project: project_1.default, toggle: toggle_1.default, scales: scales_1.default, + translate: translate_1.default, zoom: zoom_1.default, inputs: inputs_1.default, nearest: nearest_1.default }; +function forEachTransform(selCmpt, cb) { + for (var t in compilers) { + if (compilers[t].has(selCmpt)) { + cb(compilers[t]); + } + } +} +exports.forEachTransform = forEachTransform; + +},{"./inputs":81,"./nearest":82,"./project":83,"./scales":84,"./toggle":85,"./translate":87,"./zoom":88}],87:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_event_selector_1 = require("vega-event-selector"); +var channel_1 = require("../../../channel"); +var interval_1 = require("../interval"); +var selection_1 = require("../selection"); +var scales_1 = require("./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 = scales_1.default.has(selCmpt); + var anchor = name + ANCHOR; + var _a = selection_1.positionalProjections(selCmpt), x = _a.x, y = _a.y; + var events = vega_event_selector_1.selector(selCmpt.translate, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.between[0].markname = name + interval_1.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 ? scales_1.domain(model, channel_1.X) : + "slice(" + selection_1.channelSignalName(selCmpt, 'x', 'visual') + ")") : '') + + (y !== null ? ', extent_y: ' + (hasScales ? scales_1.domain(model, channel_1.Y) : + "slice(" + selection_1.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, channel_1.X, 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, channel_1.Y, 'height', signals); + } + return signals; + } +}; +exports.default = translate; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scales_1.default.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === selection_1.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 === channel_1.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 + ")" + }); +} + +},{"../../../channel":15,"../interval":77,"../selection":79,"./scales":84,"vega-event-selector":9}],88:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_event_selector_1 = require("vega-event-selector"); +var channel_1 = require("../../../channel"); +var util_1 = require("../../../util"); +var interval_1 = require("../interval"); +var selection_1 = require("../selection"); +var scales_1 = require("./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 = scales_1.default.has(selCmpt); + var delta = name + DELTA; + var _a = selection_1.positionalProjections(selCmpt), x = _a.x, y = _a.y; + var sx = util_1.stringValue(model.scaleName(channel_1.X)); + var sy = util_1.stringValue(model.scaleName(channel_1.Y)); + var events = vega_event_selector_1.selector(selCmpt.zoom, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.markname = name + interval_1.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; + } +}; +exports.default = zoom; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scales_1.default.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === selection_1.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 ? scales_1.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 + ")" + }); +} + +},{"../../../channel":15,"../../../util":118,"../interval":77,"../selection":79,"./scales":84,"vega-event-selector":9}],89:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var util_1 = require("../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(util_1.duplicate(this.explicit), util_1.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); + } + }; + return Split; +}()); +exports.Split = Split; +function makeExplicit(value) { + return { + explicit: true, + value: value + }; +} +exports.makeExplicit = makeExplicit; +function makeImplicit(value) { + return { + explicit: false, + value: value + }; +} +exports.makeImplicit = makeImplicit; +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); + }; +} +exports.tieBreakByComparing = tieBreakByComparing; +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; +} +exports.defaultTieBreaker = defaultTieBreaker; +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 (v1.value === v2.value) { + return v1; + } + else { + return tieBreaker(v1, v2, property, propertyOf); + } +} +exports.mergeValuesWithExplicit = mergeValuesWithExplicit; + +},{"../log":105,"../util":118}],90:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var vlEncoding = require("../encoding"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var mark_1 = require("../mark"); +var stack_1 = require("../stack"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var parse_2 = require("./data/parse"); +var assemble_1 = require("./layoutsize/assemble"); +var parse_3 = require("./layoutsize/parse"); +var init_1 = require("./mark/init"); +var mark_2 = require("./mark/mark"); +var model_1 = require("./model"); +var repeater_1 = require("./repeater"); +var selection_1 = require("./selection/selection"); +/** + * 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, undefined) || this; + _this.fit = fit; + _this.type = 'unit'; + _this.specifiedScales = {}; + _this.specifiedAxes = {}; + _this.specifiedLegends = {}; + _this.selection = {}; + _this.children = []; + _this.initSize(__assign({}, parentGivenSize, (spec.width ? { width: spec.width } : {}), (spec.height ? { height: spec.height } : {}))); + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = _this.encoding = encoding_1.normalizeEncoding(repeater_1.replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark); + _this.markDef = init_1.normalizeMarkDef(spec.mark, encoding, config); + // calculate stack properties + _this.stack = stack_1.stack(mark, encoding, _this.config.stack); + _this.specifiedScales = _this.initScales(mark, encoding); + _this.specifiedAxes = _this.initAxes(encoding); + _this.specifiedLegends = _this.initLegend(encoding); + // Selections will be initialized upon parse. + _this.selection = spec.selection; + return _this; + } + /** + * 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.sort = function (channel) { + return (this.getMapping()[channel] || {}).sort; + }; + 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 channel_1.SCALE_CHANNELS.reduce(function (scales, channel) { + var fieldDef; + var specifiedScale; + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale; + } + else if (fielddef_1.hasConditionalFieldDef(channelDef)) { + fieldDef = channelDef.condition; + specifiedScale = channelDef.condition['scale']; + } + else if (channel === 'x') { + fieldDef = fielddef_1.getFieldDef(encoding.x2); + } + else if (channel === 'y') { + fieldDef = fielddef_1.getFieldDef(encoding.y2); + } + if (fieldDef) { + scales[channel] = specifiedScale || {}; + } + return scales; + }, {}); + }; + UnitModel.prototype.initAxes = function (encoding) { + return [channel_1.X, channel_1.Y].reduce(function (_axis, channel) { + // Position Axis + // TODO: handle ConditionFieldDef + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef) || + (channel === channel_1.X && fielddef_1.isFieldDef(encoding.x2)) || + (channel === channel_1.Y && fielddef_1.isFieldDef(encoding.y2))) { + var axisSpec = fielddef_1.isFieldDef(channelDef) ? channelDef.axis : null; + // We no longer support false in the schema, but we keep false here for backward compatability. + if (axisSpec !== null && axisSpec !== false) { + _axis[channel] = __assign({}, axisSpec); + } + } + return _axis; + }, {}); + }; + UnitModel.prototype.initLegend = function (encoding) { + return channel_1.NONPOSITION_SCALE_CHANNELS.reduce(function (_legend, channel) { + var channelDef = encoding[channel]; + if (channelDef) { + var legend = fielddef_1.isFieldDef(channelDef) ? channelDef.legend : + (fielddef_1.hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null; + if (legend !== null && legend !== false) { + _legend[channel] = __assign({}, legend); + } + } + return _legend; + }, {}); + }; + UnitModel.prototype.parseData = function () { + this.component.data = parse_2.parseData(this); + }; + UnitModel.prototype.parseLayoutSize = function () { + parse_3.parseUnitLayoutSize(this); + }; + UnitModel.prototype.parseSelection = function () { + this.component.selection = selection_1.parseUnitSelection(this, this.selection); + }; + UnitModel.prototype.parseMarkGroup = function () { + this.component.mark = mark_2.parseMarkGroup(this); + }; + UnitModel.prototype.parseAxisAndHeader = function () { + this.component.axes = parse_1.parseUnitAxis(this); + }; + UnitModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return selection_1.assembleTopLevelSignals(this, signals); + }; + UnitModel.prototype.assembleSelectionSignals = function () { + return selection_1.assembleUnitSelectionSignals(this, []); + }; + UnitModel.prototype.assembleSelectionData = function (data) { + return selection_1.assembleUnitSelectionData(this, data); + }; + UnitModel.prototype.assembleLayout = function () { + return null; + }; + UnitModel.prototype.assembleLayoutSignals = function () { + return assemble_1.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 || !model_1.isLayerModel(this.parent)) { + marks = selection_1.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 = util_1.duplicate(this.encoding); + var spec; + spec = { + mark: this.markDef, + encoding: encoding + }; + if (!excludeConfig) { + spec.config = util_1.duplicate(this.config); + } + if (!excludeData) { + spec.data = util_1.duplicate(this.data); + } + // remove defaults + return spec; + }; + UnitModel.prototype.mark = function () { + return this.markDef.type; + }; + UnitModel.prototype.channelHasField = function (channel) { + return vlEncoding.channelHasField(this.encoding, channel); + }; + UnitModel.prototype.fieldDef = function (channel) { + var channelDef = this.encoding[channel]; + return fielddef_1.getFieldDef(channelDef); + }; + return UnitModel; +}(model_1.ModelWithField)); +exports.UnitModel = UnitModel; + +},{"../channel":15,"../encoding":98,"../fielddef":100,"../mark":107,"../stack":112,"../util":118,"./axis/parse":20,"./data/parse":40,"./layoutsize/assemble":47,"./layoutsize/parse":48,"./mark/init":56,"./mark/mark":58,"./model":66,"./repeater":68,"./selection/selection":79}],91:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +var encoding_1 = require("../encoding"); +var encoding_2 = require("./../encoding"); +var fielddef_1 = require("./../fielddef"); +var log = require("./../log"); +var common_1 = require("./common"); +exports.BOXPLOT = 'box-plot'; +function isBoxPlotDef(mark) { + return !!mark['type']; +} +exports.isBoxPlotDef = isBoxPlotDef; +exports.BOXPLOT_STYLES = ['boxWhisker', 'box', 'boxMid']; +exports.VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX = { + box: ['size', 'color'], + boxWhisker: ['color'], + boxMid: ['color'] +}; +var supportedChannels = ['x', 'y', 'color', 'detail', 'opacity', 'size']; +function filterUnsupportedChannels(spec) { + return __assign({}, spec, { encoding: encoding_1.reduce(spec.encoding, function (newEncoding, fieldDef, channel) { + if (supportedChannels.indexOf(channel) > -1) { + newEncoding[channel] = fieldDef; + } + else { + log.warn(log.message.incompatibleChannel(channel, exports.BOXPLOT)); + } + return newEncoding; + }, {}) }); +} +exports.filterUnsupportedChannels = filterUnsupportedChannels; +function normalizeBoxPlot(spec, config) { + spec = filterUnsupportedChannels(spec); + // TODO: use selection + var mark = spec.mark, encoding = spec.encoding, selection = spec.selection, outerSpec = __rest(spec, ["mark", "encoding", "selection"]); + var kIQRScalar = undefined; + if (isBoxPlotDef(mark)) { + if (mark.extent) { + if (vega_util_1.isNumber(mark.extent)) { + kIQRScalar = mark.extent; + } + } + } + var orient = boxOrient(spec); + var _a = boxParams(spec, orient, kIQRScalar), transform = _a.transform, continuousAxisChannelDef = _a.continuousAxisChannelDef, continuousAxis = _a.continuousAxis, encodingWithoutContinuousAxis = _a.encodingWithoutContinuousAxis; + var color = encodingWithoutContinuousAxis.color, 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 } : common_1.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((_b = {}, _b[continuousAxis] = __assign({ field: 'lower_whisker_' + continuousAxisChannelDef.field, type: continuousAxisChannelDef.type }, continuousAxisScaleAndAxis), _b[continuousAxis + '2'] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _b), encodingWithoutSizeColorAndContinuousAxis, common_1.getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + encoding: __assign((_c = {}, _c[continuousAxis] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c[continuousAxis + '2'] = { + field: 'upper_whisker_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c), encodingWithoutSizeColorAndContinuousAxis, common_1.getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, + __assign({}, (selection ? { selection: selection } : {}), { mark: { + type: 'bar', + style: 'box' + }, encoding: __assign((_d = {}, _d[continuousAxis] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _d[continuousAxis + '2'] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _d), encodingWithoutContinuousAxis, (encodingWithoutContinuousAxis.color ? {} : common_1.getMarkSpecificConfigMixins(config.box, 'color')), sizeMixins) }), + { + mark: { + type: 'tick', + style: 'boxMid' + }, + encoding: __assign((_e = {}, _e[continuousAxis] = { + field: 'mid_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _e), encodingWithoutSizeColorAndContinuousAxis, common_1.getMarkSpecificConfigMixins(config.boxMid, 'color'), sizeMixins) + } + ] }); + var _b, _c, _d, _e; +} +exports.normalizeBoxPlot = normalizeBoxPlot; +function boxOrient(spec) { + var mark = spec.mark, encoding = spec.encoding, _outerSpec = __rest(spec, ["mark", "encoding"]); + if (fielddef_1.isFieldDef(encoding.x) && fielddef_1.isContinuous(encoding.x)) { + // x is continuous + if (fielddef_1.isFieldDef(encoding.y) && fielddef_1.isContinuous(encoding.y)) { + // both x and y are continuous + if (encoding.x.aggregate === undefined && encoding.y.aggregate === exports.BOXPLOT) { + return 'vertical'; + } + else if (encoding.y.aggregate === undefined && encoding.x.aggregate === exports.BOXPLOT) { + return 'horizontal'; + } + else if (encoding.x.aggregate === exports.BOXPLOT && encoding.y.aggregate === exports.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 (fielddef_1.isFieldDef(encoding.y) && fielddef_1.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, _outerSpec = __rest(spec, ["mark", "encoding"]); + var continuousAxisChannelDef; + var continuousAxis; + if (orient === 'vertical') { + continuousAxis = 'y'; + continuousAxisChannelDef = encoding.y; // Safe to cast because if y is not continous fielddef, the orient would not be vertical. + } + else { + continuousAxis = 'x'; + continuousAxisChannelDef = encoding.x; // Safe to cast because if x is not continous fielddef, the orient would not be horizontal. + } + if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) { + var aggregate = continuousAxisChannelDef.aggregate, continuousAxisWithoutAggregate = __rest(continuousAxisChannelDef, ["aggregate"]); + if (aggregate !== exports.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 = {}; + encoding_2.forEach(encoding, function (channelDef, channel) { + if (channel === continuousAxis) { + // Skip continuous axis as we already handle it separately + return; + } + if (fielddef_1.isFieldDef(channelDef)) { + if (channelDef.aggregate && channelDef.aggregate !== exports.BOXPLOT) { + aggregate.push({ + op: channelDef.aggregate, + field: channelDef.field, + as: fielddef_1.field(channelDef) + }); + } + else if (channelDef.aggregate === undefined) { + var transformedField = fielddef_1.field(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_2 = channelDef.field; + timeUnits.push({ timeUnit: timeUnit, field: field_2, as: transformedField }); + } + groupby.push(transformedField); + } + // now the field should refer to post-transformed field instead + encodingWithoutContinuousAxis[channel] = { + field: fielddef_1.field(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 + }; +} + +},{"../encoding":98,"./../encoding":98,"./../fielddef":100,"./../log":105,"./common":92,"vega-util":10}],92:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function getMarkSpecificConfigMixins(markSpecificConfig, channel) { + var value = markSpecificConfig[channel]; + return value !== undefined ? (_a = {}, _a[channel] = { value: value }, _a) : {}; + var _a; +} +exports.getMarkSpecificConfigMixins = getMarkSpecificConfigMixins; + +},{}],93:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ERRORBAR = 'error-bar'; +function normalizeErrorBar(spec) { + // TODO: use selection + var _m = spec.mark, _sel = spec.selection, encoding = spec.encoding, outerSpec = __rest(spec, ["mark", "selection", "encoding"]); + var _s = encoding.size, encodingWithoutSize = __rest(encoding, ["size"]); + var _x2 = encoding.x2, _y2 = encoding.y2, encodingWithoutX2Y2 = __rest(encoding, ["x2", "y2"]); + var _x = encodingWithoutX2Y2.x, _y = encodingWithoutX2Y2.y, 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) + } + ] }); +} +exports.normalizeErrorBar = normalizeErrorBar; + +},{}],94:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var mark_1 = require("./../mark"); +var boxplot_1 = require("./boxplot"); +var errorbar_1 = require("./errorbar"); +/** + * Registry index for all composite mark's normalizer + */ +var normalizerRegistry = {}; +function add(mark, normalizer) { + normalizerRegistry[mark] = normalizer; +} +exports.add = add; +function remove(mark) { + delete normalizerRegistry[mark]; +} +exports.remove = remove; +exports.COMPOSITE_MARK_STYLES = boxplot_1.BOXPLOT_STYLES; +exports.VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = __assign({}, boxplot_1.VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX); +add(boxplot_1.BOXPLOT, boxplot_1.normalizeBoxPlot); +add(errorbar_1.ERRORBAR, errorbar_1.normalizeErrorBar); +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +function normalize( + // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels. + spec, config) { + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var normalizer = normalizerRegistry[mark]; + if (normalizer) { + return normalizer(spec, config); + } + throw new Error("Unregistered composite mark " + mark); +} +exports.normalize = normalize; + +},{"./../mark":107,"./boxplot":91,"./errorbar":93}],95:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var compositemark_1 = require("./compositemark"); +var index_1 = require("./compositemark/index"); +var guide_1 = require("./guide"); +var legend_1 = require("./legend"); +var mark_1 = require("./mark"); +var mark = require("./mark"); +var scale_1 = require("./scale"); +var selection_1 = require("./selection"); +var title_1 = require("./title"); +var util_1 = require("./util"); +exports.defaultViewConfig = { + width: 200, + height: 200 +}; +exports.defaultConfig = { + padding: 5, + timeFormat: '%b %d, %Y', + countTitle: 'Number of Records', + invalidValues: 'filter', + view: exports.defaultViewConfig, + mark: mark.defaultMarkConfig, + area: {}, + bar: mark.defaultBarConfig, + circle: {}, + line: {}, + point: {}, + rect: {}, + rule: { color: 'black' }, + square: {}, + text: { color: 'black' }, + tick: mark.defaultTickConfig, + box: { size: 14 }, + boxWhisker: {}, + boxMid: { color: 'white' }, + scale: scale_1.defaultScaleConfig, + axis: {}, + axisX: {}, + axisY: { minExtent: 30 }, + axisLeft: {}, + axisRight: {}, + axisTop: {}, + axisBottom: {}, + axisBand: {}, + legend: legend_1.defaultLegendConfig, + selection: selection_1.defaultConfig, + style: {}, + title: {}, +}; +function initConfig(config) { + return util_1.mergeDeep(util_1.duplicate(exports.defaultConfig), config); +} +exports.initConfig = initConfig; +var MARK_STYLES = ['view'].concat(mark_1.PRIMITIVE_MARKS, compositemark_1.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'] }, mark_1.VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX, index_1.VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX); +function stripAndRedirectConfig(config) { + config = util_1.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 = guide_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 = guide_1.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 = mark_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 mark_2 = MARK_STYLES_1[_d]; + // Remove Vega-Lite-only mark config + for (var _e = 0, VL_ONLY_MARK_CONFIG_PROPERTIES_2 = mark_1.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[mark_2][prop]; + } + // Remove Vega-Lite only mark-specific config + var vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[mark_2]; + if (vlOnlyMarkSpecificConfigs) { + for (var _f = 0, vlOnlyMarkSpecificConfigs_1 = vlOnlyMarkSpecificConfigs; _f < vlOnlyMarkSpecificConfigs_1.length; _f++) { + var prop = vlOnlyMarkSpecificConfigs_1[_f]; + delete config[mark_2][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, mark_2); + } + // 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 (util_1.isObject(config[prop]) && util_1.keys(config[prop]).length === 0) { + delete config[prop]; + } + } + return util_1.keys(config).length > 0 ? config : undefined; +} +exports.stripAndRedirectConfig = stripAndRedirectConfig; +function redirectConfig(config, prop, toProp) { + var propConfig = prop === 'title' ? title_1.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 (util_1.keys(style).length > 0) { + config.style[toProp || prop] = style; + } + delete config[prop]; +} + +},{"./compositemark":94,"./compositemark/index":94,"./guide":102,"./legend":104,"./mark":107,"./scale":108,"./selection":109,"./title":114,"./util":118}],96:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isUrlData(data) { + return !!data['url']; +} +exports.isUrlData = isUrlData; +function isInlineData(data) { + return !!data['values']; +} +exports.isInlineData = isInlineData; +function isNamedData(data) { + return !!data['name']; +} +exports.isNamedData = isNamedData; +exports.MAIN = 'main'; +exports.RAW = 'raw'; + +},{}],97:[function(require,module,exports){ +"use strict"; +// DateTime definition object +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("./log"); +var util_1 = require("./util"); +/* + * 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); +} +exports.isDateTime = isDateTime; +exports.MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; +exports.SHORT_MONTHS = exports.MONTHS.map(function (m) { return m.substr(0, 3); }); +exports.DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; +exports.SHORT_DAYS = exports.DAYS.map(function (d) { return d.substr(0, 3); }); +function normalizeQuarter(q) { + if (util_1.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 (util_1.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 = exports.MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + var shortM = lowerM.substr(0, 3); + var shortMonthIndex = exports.SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(log.message.invalidTimeUnit('month', m)); + } +} +function normalizeDay(d) { + if (util_1.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 = exports.DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + var shortD = lowerD.substr(0, 3); + var shortDayIndex = exports.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. + */ +function dateTimeExpr(d, normalize) { + if (normalize === void 0) { normalize = false; } + var units = []; + if (normalize && d.day !== undefined) { + if (util_1.keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = util_1.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(', ') + ")"; + } +} +exports.dateTimeExpr = dateTimeExpr; + +},{"./log":105,"./util":118}],98:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var fielddef_1 = require("./fielddef"); +var log = require("./log"); +var util_1 = require("./util"); +function channelHasField(encoding, channel) { + var channelDef = encoding && encoding[channel]; + if (channelDef) { + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.field; }); + } + else { + return fielddef_1.isFieldDef(channelDef) || fielddef_1.hasConditionalFieldDef(channelDef); + } + } + return false; +} +exports.channelHasField = channelHasField; +function isAggregate(encoding) { + return util_1.some(channel_1.CHANNELS, function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.aggregate; }); + } + else { + var fieldDef = fielddef_1.getFieldDef(channelDef); + return fieldDef && !!fieldDef.aggregate; + } + } + return false; + }); +} +exports.isAggregate = isAggregate; +function normalizeEncoding(encoding, mark) { + return util_1.keys(encoding).reduce(function (normalizedEncoding, channel) { + if (!channel_1.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 = fielddef_1.getFieldDef(encoding[channel]); + if (fieldDef && fieldDef.aggregate) { + log.warn(log.message.incompatibleChannel(channel, mark, 'when the field is aggregated.')); + return normalizedEncoding; + } + } + if (channel === 'detail' || channel === 'order') { + var channelDef = encoding[channel]; + if (channelDef) { + // Array of fieldDefs for detail channel (or production rule) + normalizedEncoding[channel] = (util_1.isArray(channelDef) ? channelDef : [channelDef]) + .reduce(function (fieldDefs, fieldDef) { + if (!fielddef_1.isFieldDef(fieldDef)) { + log.warn(log.message.emptyFieldDef(fieldDef, channel)); + } + else { + fieldDefs.push(fielddef_1.normalizeFieldDef(fieldDef, channel)); + } + return fieldDefs; + }, []); + } + } + else { + // FIXME: remove this casting. (I don't know why Typescript doesn't infer this correctly here.) + var channelDef = encoding[channel]; + if (!fielddef_1.isFieldDef(channelDef) && !fielddef_1.isValueDef(channelDef) && !fielddef_1.isConditionalDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + return normalizedEncoding; + } + normalizedEncoding[channel] = fielddef_1.normalize(channelDef, channel); + } + return normalizedEncoding; + }, {}); +} +exports.normalizeEncoding = normalizeEncoding; +function isRanged(encoding) { + return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2)); +} +exports.isRanged = isRanged; +function fieldDefs(encoding) { + var arr = []; + channel_1.CHANNELS.forEach(function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (def) { + if (fielddef_1.isFieldDef(def)) { + arr.push(def); + } + else if (fielddef_1.hasConditionalFieldDef(def)) { + arr.push(def.condition); + } + }); + } + }); + return arr; +} +exports.fieldDefs = fieldDefs; +function forEach(mapping, f, thisArg) { + if (!mapping) { + return; + } + var _loop_1 = function (channel) { + if (util_1.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 = util_1.keys(mapping); _i < _a.length; _i++) { + var channel = _a[_i]; + _loop_1(channel); + } +} +exports.forEach = forEach; +function reduce(mapping, f, init, thisArg) { + if (!mapping) { + return init; + } + return util_1.keys(mapping).reduce(function (r, channel) { + var map = mapping[channel]; + if (util_1.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); +} +exports.reduce = reduce; + +},{"./channel":15,"./fielddef":100,"./log":105,"./util":118}],99:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +},{}],100:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Declaration and utility for variants of a field definition object +var aggregate_1 = require("./aggregate"); +var bin_1 = require("./bin"); +var channel_1 = require("./channel"); +var log = require("./log"); +var timeunit_1 = require("./timeunit"); +var type_1 = require("./type"); +var util_1 = require("./util"); +function isRepeatRef(field) { + return field && !util_1.isString(field) && 'repeat' in field; +} +exports.isRepeatRef = isRepeatRef; +function isConditionalDef(channelDef) { + return !!channelDef && !!channelDef.condition; +} +exports.isConditionalDef = isConditionalDef; +/** + * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef + */ +function hasConditionalFieldDef(channelDef) { + return !!channelDef && !!channelDef.condition && !util_1.isArray(channelDef.condition) && isFieldDef(channelDef.condition); +} +exports.hasConditionalFieldDef = hasConditionalFieldDef; +function hasConditionalValueDef(channelDef) { + return !!channelDef && !!channelDef.condition && (util_1.isArray(channelDef.condition) || isValueDef(channelDef.condition)); +} +exports.hasConditionalValueDef = hasConditionalValueDef; +function isFieldDef(channelDef) { + return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); +} +exports.isFieldDef = isFieldDef; +function isStringFieldDef(fieldDef) { + return isFieldDef(fieldDef) && util_1.isString(fieldDef.field); +} +exports.isStringFieldDef = isStringFieldDef; +function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; +} +exports.isValueDef = isValueDef; +function isScaleFieldDef(channelDef) { + return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']); +} +exports.isScaleFieldDef = isScaleFieldDef; +function field(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 (fieldDef.bin) { + fn = bin_1.binToString(fieldDef.bin); + suffix = opt.binSuffix || ''; + } + else if (fieldDef.aggregate) { + fn = String(opt.aggregate || fieldDef.aggregate); + } + else if (fieldDef.timeUnit) { + fn = String(fieldDef.timeUnit); + } + } + if (fn) { + field = fn + "_" + field; + } + } + if (suffix) { + field = field + "_" + suffix; + } + if (prefix) { + field = prefix + "_" + field; + } + if (opt.expr) { + field = "" + opt.expr + util_1.accessPath(field); + } + return field; +} +exports.field = field; +function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'temporal': + return false; + } + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +exports.isDiscrete = isDiscrete; +function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); +} +exports.isContinuous = isContinuous; +function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; +} +exports.isCount = isCount; +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 = timeunit_1.getTimeUnitParts(timeUnit).join('-'); + return field + " (" + units + ")"; + } + else if (aggregate) { + return util_1.titlecase(aggregate) + " of " + field; + } + return field; +} +exports.verbalTitleFormatter = verbalTitleFormatter; +function functionalTitleFormatter(fieldDef, config) { + var fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin'); + if (fn) { + return fn.toUpperCase() + '(' + fieldDef.field + ')'; + } + else { + return fieldDef.field; + } +} +exports.functionalTitleFormatter = functionalTitleFormatter; +exports.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 = exports.defaultTitleFormatter; +function setTitleFormatter(formatter) { + titleFormatter = formatter; +} +exports.setTitleFormatter = setTitleFormatter; +function resetTitleFormatter() { + setTitleFormatter(exports.defaultTitleFormatter); +} +exports.resetTitleFormatter = resetTitleFormatter; +function title(fieldDef, config) { + return titleFormatter(fieldDef, config); +} +exports.title = title; +function defaultType(fieldDef, channel) { + if (fieldDef.timeUnit) { + return 'temporal'; + } + if (fieldDef.bin) { + return 'quantitative'; + } + switch (channel_1.rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible':// color + return 'nominal'; + default: + return 'quantitative'; + } +} +exports.defaultType = defaultType; +/** + * 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; +} +exports.getFieldDef = getFieldDef; +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +function normalize(channelDef, channel) { + if (util_1.isString(channelDef) || util_1.isNumber(channelDef) || util_1.isBoolean(channelDef)) { + var primitiveType = util_1.isString(channelDef) ? 'string' : + util_1.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 __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; +} +exports.normalize = normalize; +function normalizeFieldDef(fieldDef, channel) { + // Drop invalid aggregate + if (fieldDef.aggregate && !aggregate_1.isAggregateOp(fieldDef.aggregate)) { + var aggregate = fieldDef.aggregate, fieldDefWithoutAggregate = __rest(fieldDef, ["aggregate"]); + log.warn(log.message.invalidAggregate(fieldDef.aggregate)); + fieldDef = fieldDefWithoutAggregate; + } + // Normalize Time Unit + if (fieldDef.timeUnit) { + fieldDef = __assign({}, fieldDef, { timeUnit: timeunit_1.normalizeTimeUnit(fieldDef.timeUnit) }); + } + // Normalize bin + if (fieldDef.bin) { + fieldDef = __assign({}, fieldDef, { bin: normalizeBin(fieldDef.bin, channel) }); + } + // Normalize Type + if (fieldDef.type) { + var fullType = type_1.getFullName(fieldDef.type); + if (fieldDef.type !== fullType) { + // convert short type to full type + fieldDef = __assign({}, fieldDef, { type: fullType }); + } + if (fieldDef.type !== 'quantitative') { + if (aggregate_1.isCountingAggregateOp(fieldDef.aggregate)) { + log.warn(log.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); + log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType)); + fieldDef = __assign({}, fieldDef, { type: newType }); + } + var _a = channelCompatibility(fieldDef, channel), compatible = _a.compatible, warning = _a.warning; + if (!compatible) { + log.warn(warning); + } + return fieldDef; +} +exports.normalizeFieldDef = normalizeFieldDef; +function normalizeBin(bin, channel) { + if (util_1.isBoolean(bin)) { + return { maxbins: bin_1.autoMaxBins(channel) }; + } + else if (!bin.maxbins && !bin.step) { + return __assign({}, bin, { maxbins: bin_1.autoMaxBins(channel) }); + } + else { + return bin; + } +} +exports.normalizeBin = normalizeBin; +var COMPATIBLE = { compatible: true }; +function channelCompatibility(fieldDef, channel) { + switch (channel) { + case 'row': + case 'column': + if (isContinuous(fieldDef) && !fieldDef.timeUnit) { + // TODO:(https://github.com/vega/vega-lite/issues/2011): + // with timeUnit it's not always strictly continuous + return { + compatible: false, + warning: log.message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'text': + case 'detail': + case 'tooltip': + return COMPATIBLE; + case 'opacity': + case 'size': + case 'x2': + case 'y2': + if (isDiscrete(fieldDef) && !fieldDef.bin) { + return { + compatible: false, + warning: "Channel " + channel + " should not be used with discrete field." + }; + } + return COMPATIBLE; + case 'shape': + if (fieldDef.type !== 'nominal') { + return { + compatible: false, + warning: 'Shape channel should be used with nominal data only' + }; + } + return COMPATIBLE; + case 'order': + if (fieldDef.type === 'nominal') { + 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); +} +exports.channelCompatibility = channelCompatibility; +function isNumberFieldDef(fieldDef) { + return fieldDef.type === 'quantitative' || !!fieldDef.bin; +} +exports.isNumberFieldDef = isNumberFieldDef; +function isTimeFieldDef(fieldDef) { + return fieldDef.type === 'temporal' || !!fieldDef.timeUnit; +} +exports.isTimeFieldDef = isTimeFieldDef; + +},{"./aggregate":12,"./bin":14,"./channel":15,"./log":105,"./timeunit":113,"./type":117,"./util":118}],101:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./compile/selection/selection"); +var datetime_1 = require("./datetime"); +var fielddef_1 = require("./fielddef"); +var timeunit_1 = require("./timeunit"); +var util_1 = require("./util"); +function isSelectionFilter(filter) { + return filter && filter['selection']; +} +exports.isSelectionFilter = isSelectionFilter; +function isEqualFilter(filter) { + return filter && !!filter.field && filter.equal !== undefined; +} +exports.isEqualFilter = isEqualFilter; +function isRangeFilter(filter) { + if (filter && filter.field) { + if (util_1.isArray(filter.range) && filter.range.length === 2) { + return true; + } + } + return false; +} +exports.isRangeFilter = isRangeFilter; +function isOneOfFilter(filter) { + return filter && !!filter.field && (util_1.isArray(filter.oneOf) || + util_1.isArray(filter.in) // backward compatibility + ); +} +exports.isOneOfFilter = isOneOfFilter; +function isFieldFilter(filter) { + return isOneOfFilter(filter) || isEqualFilter(filter) || isRangeFilter(filter); +} +exports.isFieldFilter = isFieldFilter; +/** + * Converts a filter into an expression. + */ +// model is only used for selection filters. +function expression(model, filterOp, node) { + return util_1.logicalExpr(filterOp, function (filter) { + if (util_1.isString(filter)) { + return filter; + } + else if (isSelectionFilter(filter)) { + return selection_1.predicate(model, filter.selection, node); + } + else { + return fieldFilterExpression(filter); + } + }); +} +exports.expression = expression; +// This method is used by Voyager. Do not change its behavior without changing Voyager. +function fieldFilterExpression(filter, useInRange) { + if (useInRange === void 0) { useInRange = true; } + var fieldExpr = filter.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(' + timeunit_1.fieldExpr(filter.timeUnit, filter.field) + ')') : + fielddef_1.field(filter, { expr: 'datum' }); + if (isEqualFilter(filter)) { + return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit); + } + else if (isOneOfFilter(filter)) { + // "oneOf" was formerly "in" -- so we need to add backward compatibility + var oneOf = filter.oneOf || filter['in']; + return 'indexof([' + + oneOf.map(function (v) { return valueExpr(v, filter.timeUnit); }).join(',') + + '], ' + fieldExpr + ') !== -1'; + } + else if (isRangeFilter(filter)) { + var lower = filter.range[0]; + var upper = filter.range[1]; + if (lower !== null && upper !== null && useInRange) { + return 'inrange(' + fieldExpr + ', [' + + valueExpr(lower, filter.timeUnit) + ', ' + + valueExpr(upper, filter.timeUnit) + '])'; + } + var exprs = []; + if (lower !== null) { + exprs.push(fieldExpr + " >= " + valueExpr(lower, filter.timeUnit)); + } + if (upper !== null) { + exprs.push(fieldExpr + " <= " + valueExpr(upper, filter.timeUnit)); + } + return exprs.length > 0 ? exprs.join(' && ') : 'true'; + } + /* istanbul ignore next: it should never reach here */ + throw new Error("Invalid field filter: " + JSON.stringify(filter)); +} +exports.fieldFilterExpression = fieldFilterExpression; +function valueExpr(v, timeUnit) { + if (datetime_1.isDateTime(v)) { + var expr = datetime_1.dateTimeExpr(v, true); + return 'time(' + expr + ')'; + } + if (timeunit_1.isLocalSingleTimeUnit(timeUnit)) { + var datetime = {}; + datetime[timeUnit] = v; + var expr = datetime_1.dateTimeExpr(datetime, true); + return 'time(' + expr + ')'; + } + else if (timeunit_1.isUtcSingleTimeUnit(timeUnit)) { + return valueExpr(v, timeunit_1.getLocalTimeUnit(timeUnit)); + } + return JSON.stringify(v); +} +function normalizeFilter(f) { + if (isFieldFilter(f) && f.timeUnit) { + return __assign({}, f, { timeUnit: timeunit_1.normalizeTimeUnit(f.timeUnit) }); + } + return f; +} +exports.normalizeFilter = normalizeFilter; + +},{"./compile/selection/selection":79,"./datetime":97,"./fielddef":100,"./timeunit":113,"./util":118}],102:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.VL_ONLY_GUIDE_CONFIG = ['shortTimeLabels']; + +},{}],103:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.axis = require("./axis"); +exports.aggregate = require("./aggregate"); +exports.bin = require("./bin"); +exports.channel = require("./channel"); +exports.compositeMark = require("./compositemark"); +var compile_1 = require("./compile/compile"); +exports.compile = compile_1.compile; +exports.config = require("./config"); +exports.data = require("./data"); +exports.datetime = require("./datetime"); +exports.encoding = require("./encoding"); +exports.facet = require("./facet"); +exports.fieldDef = require("./fielddef"); +exports.legend = require("./legend"); +exports.mark = require("./mark"); +exports.scale = require("./scale"); +exports.sort = require("./sort"); +exports.spec = require("./spec"); +exports.stack = require("./stack"); +exports.timeUnit = require("./timeunit"); +exports.transform = require("./transform"); +exports.type = require("./type"); +exports.util = require("./util"); +exports.validate = require("./validate"); +exports.version = require('../package.json').version; + +},{"../package.json":11,"./aggregate":12,"./axis":13,"./bin":14,"./channel":15,"./compile/compile":25,"./compositemark":94,"./config":95,"./data":96,"./datetime":97,"./encoding":98,"./facet":99,"./fielddef":100,"./legend":104,"./mark":107,"./scale":108,"./sort":110,"./spec":111,"./stack":112,"./timeunit":113,"./transform":116,"./type":117,"./util":118,"./validate":119}],104:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +exports.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 }); +exports.LEGEND_PROPERTIES = util_1.flagKeys(COMMON_LEGEND_PROPERTY_INDEX); +exports.VG_LEGEND_PROPERTIES = util_1.flagKeys(VG_LEGEND_PROPERTY_INDEX); + +},{"./util":118}],105:[function(require,module,exports){ +"use strict"; +/** + * Vega-Lite's singleton logger utility. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var vega_util_1 = require("vega-util"); +/** + * Main (default) Vega Logger instance for Vega-Lite + */ +var main = vega_util_1.logger(vega_util_1.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]; + } + (_a = this.warns).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.infos).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.debug = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.debugs).push.apply(_a, args); + return this; + var _a; + }; + return LocalLogger; +}()); +exports.LocalLogger = LocalLogger; +function wrap(f) { + return function () { + var logger = current = new LocalLogger(); + f(logger); + reset(); + }; +} +exports.wrap = wrap; +/** + * Set the singleton logger to be a custom logger + */ +function set(logger) { + current = logger; + return current; +} +exports.set = set; +/** + * Reset the main logger to use the default Vega Logger + */ +function reset() { + current = main; + return current; +} +exports.reset = reset; +function warn() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.warn.apply(current, arguments); +} +exports.warn = warn; +function info() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.info.apply(current, arguments); +} +exports.info = info; +function debug() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.debug.apply(current, arguments); +} +exports.debug = debug; +/** + * 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) { + 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: " + JSON.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 the data from the secondary source.'; + // ENCODING & FACET + function primitiveChannelDef(channel, type, value) { + return "Channel " + channel + " is a " + type + ". Converted to {value: " + value + "}."; + } + message.primitiveChannelDef = primitiveChannelDef; + function invalidFieldType(type) { + return "Invalid field type \"" + type + "\""; + } + message.invalidFieldType = invalidFieldType; + 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 emptyFieldDef(fieldDef, channel) { + return "Dropping " + JSON.stringify(fieldDef) + " from channel \"" + channel + "\" since it does not contain data field or value."; + } + message.emptyFieldDef = emptyFieldDef; + function incompatibleChannel(channel, markOrFacet, when) { + return channel + " dropped as it is incompatible with \"" + markOrFacet + "\"" + (when ? " when " + when : '') + "."; + } + message.incompatibleChannel = incompatibleChannel; + 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 unclearOrientContinuous(mark) { + return "Cannot clearly determine orientation for \"" + mark + "\" since both x and y channel encode continous fields. In this case, we use vertical by default"; + } + message.unclearOrientContinuous = unclearOrientContinuous; + function unclearOrientDiscreteOrEmpty(mark) { + return "Cannot clearly determine orientation for \"" + mark + "\" since both x and y channel encode discrete or empty fields."; + } + message.unclearOrientDiscreteOrEmpty = unclearOrientDiscreteOrEmpty; + 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 (" + JSON.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 (" + JSON.stringify(fieldDef) + ")."; + } + message.unaggregatedDomainWithLogScale = unaggregatedDomainWithLogScale; + function cannotUseSizeFieldWithBandSize(positionChannel) { + return "Using size field when " + positionChannel + "-channel has a band scale is not supported."; + } + message.cannotUseSizeFieldWithBandSize = cannotUseSizeFieldWithBandSize; + 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 + " property \"" + property + "\" (\"" + v1 + "\" and \"" + v2 + "\"). Using \"" + 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 conflictedDomain(channel) { + return "Cannot set " + channel + "-scale's \"domain\" as it is binned. Please use \"bin\"'s \"extent\" instead."; + } + message.conflictedDomain = conflictedDomain; + function domainSortDropped(sort) { + return "Dropping sort property \"" + JSON.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 + ": \"" + 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 " + JSON.stringify(d) + " as day cannot be combined with other units."; + } + message.droppedDay = droppedDay; +})(message = exports.message || (exports.message = {})); + +},{"vega-util":10}],106:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isLogicalOr(op) { + return !!op.or; +} +exports.isLogicalOr = isLogicalOr; +function isLogicalAnd(op) { + return !!op.and; +} +exports.isLogicalAnd = isLogicalAnd; +function isLogicalNot(op) { + return !!op.not; +} +exports.isLogicalNot = isLogicalNot; +function forEachLeave(op, fn) { + if (isLogicalNot(op)) { + forEachLeave(op.not, fn); + } + else if (isLogicalAnd(op)) { + for (var _i = 0, _a = op.and; _i < _a.length; _i++) { + var subop = _a[_i]; + forEachLeave(subop, fn); + } + } + else if (isLogicalOr(op)) { + for (var _b = 0, _c = op.or; _b < _c.length; _b++) { + var subop = _c[_b]; + forEachLeave(subop, fn); + } + } + else { + fn(op); + } +} +exports.forEachLeave = forEachLeave; +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); + } +} +exports.normalizeLogicalOperand = normalizeLogicalOperand; + +},{}],107:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +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.CIRCLE = 'circle'; + Mark.SQUARE = 'square'; +})(Mark = exports.Mark || (exports.Mark = {})); +exports.AREA = Mark.AREA; +exports.BAR = Mark.BAR; +exports.LINE = Mark.LINE; +exports.POINT = Mark.POINT; +exports.TEXT = Mark.TEXT; +exports.TICK = Mark.TICK; +exports.RECT = Mark.RECT; +exports.RULE = Mark.RULE; +exports.CIRCLE = Mark.CIRCLE; +exports.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, + rect: 1, + rule: 1, + circle: 1, + square: 1 +}; +function isMark(m) { + return !!MARK_INDEX[m]; +} +exports.isMark = isMark; +exports.PRIMITIVE_MARKS = util_1.flagKeys(MARK_INDEX); +function isMarkDef(mark) { + return mark['type']; +} +exports.isMarkDef = isMarkDef; +var PRIMITIVE_MARK_INDEX = util_1.toSet(exports.PRIMITIVE_MARKS); +function isPrimitiveMark(mark) { + var markType = isMarkDef(mark) ? mark.type : mark; + return markType in PRIMITIVE_MARK_INDEX; +} +exports.isPrimitiveMark = isPrimitiveMark; +exports.STROKE_CONFIG = ['stroke', 'strokeWidth', + 'strokeDash', 'strokeDashOffset', 'strokeOpacity']; +exports.FILL_CONFIG = ['fill', 'fillOpacity']; +exports.FILL_STROKE_CONFIG = [].concat(exports.STROKE_CONFIG, exports.FILL_CONFIG); +exports.VL_ONLY_MARK_CONFIG_PROPERTIES = ['filled', 'color']; +exports.VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = { + bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'], + text: ['shortTimeLabels'], + tick: ['bandSize', 'thickness'] +}; +exports.defaultMarkConfig = { + color: '#4c78a8', +}; +exports.defaultBarConfig = { + binSpacing: 1, + continuousBandSize: 5 +}; +exports.defaultTickConfig = { + thickness: 1 +}; + +},{"./util":118}],108:[function(require,module,exports){ +"use strict"; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var log = require("./log"); +var util_1 = require("./util"); +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 = exports.ScaleType || (exports.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' +}; +exports.SCALE_TYPES = util_1.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'); +} +exports.scaleCompatible = scaleCompatible; +/** + * Index for scale predecence -- 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]; +} +exports.scaleTypePrecedence = scaleTypePrecedence; +exports.CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc']; +var CONTINUOUS_TO_CONTINUOUS_INDEX = util_1.toSet(exports.CONTINUOUS_TO_CONTINUOUS_SCALES); +exports.CONTINUOUS_DOMAIN_SCALES = exports.CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]); +var CONTINUOUS_DOMAIN_INDEX = util_1.toSet(exports.CONTINUOUS_DOMAIN_SCALES); +exports.DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; +var DISCRETE_DOMAIN_INDEX = util_1.toSet(exports.DISCRETE_DOMAIN_SCALES); +var BIN_SCALES_INDEX = util_1.toSet(['bin-linear', 'bin-ordinal']); +exports.TIME_SCALE_TYPES = ['time', 'utc']; +function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; +} +exports.hasDiscreteDomain = hasDiscreteDomain; +function isBinScale(type) { + return type in BIN_SCALES_INDEX; +} +exports.isBinScale = isBinScale; +function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; +} +exports.hasContinuousDomain = hasContinuousDomain; +function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; +} +exports.isContinuousToContinuous = isContinuousToContinuous; +exports.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']; +} +exports.isExtendedScheme = isExtendedScheme; +function isSelectionDomain(domain) { + return domain && domain['selection']; +} +exports.isSelectionDomain = isSelectionDomain; +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 +}; +exports.SCALE_PROPERTIES = util_1.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 = __rest(SCALE_PROPERTY_INDEX, ["type", "domain", "range", "rangeStep", "scheme"]); +exports.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = util_1.flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX); +function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'reverse': + case 'range': + return true; + case 'scheme': + return util_1.contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType); + case 'interpolate': + // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal? + return util_1.contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType); + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'padding': + return isContinuousToContinuous(scaleType) || util_1.contains(['point', 'band'], scaleType); + case 'paddingOuter': + case 'rangeStep': + return util_1.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) && !util_1.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 + "."); +} +exports.scaleTypeSupportProperty = scaleTypeSupportProperty; +/** + * Returns undefined if the input channel supports the input scale property name + */ +function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'interpolate': + case 'scheme': + if (channel !== 'color') { + 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 + "\"."); +} +exports.channelScalePropertyIncompatability = channelScalePropertyIncompatability; +function channelSupportScaleType(channel, scaleType) { + switch (channel) { + case channel_1.Channel.X: + case channel_1.Channel.Y: + case channel_1.Channel.SIZE: // TODO: size and opacity can support ordinal with more modification + case channel_1.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) || util_1.contains(['band', 'point'], scaleType); + case channel_1.Channel.COLOR: + return scaleType !== 'band'; // band does not make sense with color + case channel_1.Channel.SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; +} +exports.channelSupportScaleType = channelSupportScaleType; + +},{"./channel":15,"./log":105,"./util":118}],109:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SELECTION_ID = '_vgsid_'; +exports.defaultConfig = { + single: { + on: 'click', + fields: [exports.SELECTION_ID], + resolve: 'global', + empty: 'all' + }, + multi: { + on: 'click', + fields: [exports.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' + } +}; + +},{}],110:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isSortField(sort) { + return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op']; +} +exports.isSortField = isSortField; + +},{}],111:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var compositeMark = require("./compositemark"); +var encoding_1 = require("./encoding"); +var vlEncoding = require("./encoding"); +var log = require("./log"); +var mark_1 = require("./mark"); +var stack_1 = require("./stack"); +var util_1 = require("./util"); +/* Custom type guards */ +function isFacetSpec(spec) { + return spec['facet'] !== undefined; +} +exports.isFacetSpec = isFacetSpec; +function isUnitSpec(spec) { + return !!spec['mark']; +} +exports.isUnitSpec = isUnitSpec; +function isLayerSpec(spec) { + return spec['layer'] !== undefined; +} +exports.isLayerSpec = isLayerSpec; +function isRepeatSpec(spec) { + return spec['repeat'] !== undefined; +} +exports.isRepeatSpec = isRepeatSpec; +function isConcatSpec(spec) { + return isVConcatSpec(spec) || isHConcatSpec(spec); +} +exports.isConcatSpec = isConcatSpec; +function isVConcatSpec(spec) { + return spec['vconcat'] !== undefined; +} +exports.isVConcatSpec = isVConcatSpec; +function isHConcatSpec(spec) { + return spec['hconcat'] !== undefined; +} +exports.isHConcatSpec = isHConcatSpec; +/** + * 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(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 = encoding_1.channelHasField(spec.encoding, channel_1.ROW); + var hasColumn = encoding_1.channelHasField(spec.encoding, channel_1.COLUMN); + if (hasRow || hasColumn) { + return normalizeFacetedUnit(spec, config); + } + return normalizeNonFacetUnit(spec, config); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.normalize = normalize; +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(subspec, config) }); +} +function normalizeLayer(spec, config) { + var layer = spec.layer, rest = __rest(spec, ["layer"]); + return __assign({}, rest, { layer: layer.map(function (subspec) { return isLayerSpec(subspec) ? normalizeLayer(subspec, config) : normalizeNonFacetUnit(subspec, config); }) }); +} +function normalizeRepeat(spec, config) { + var subspec = spec.spec, rest = __rest(spec, ["spec"]); + return __assign({}, rest, { spec: normalize(subspec, config) }); +} +function normalizeVConcat(spec, config) { + var vconcat = spec.vconcat, rest = __rest(spec, ["vconcat"]); + return __assign({}, rest, { vconcat: vconcat.map(function (subspec) { return normalize(subspec, config); }) }); +} +function normalizeHConcat(spec, config) { + var hconcat = spec.hconcat, rest = __rest(spec, ["hconcat"]); + return __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 = __rest(_a, ["row", "column"]); + // Mark and encoding should be moved into the inner spec + var mark = spec.mark, width = spec.width, height = spec.height, selection = spec.selection, _ = spec.encoding, outerSpec = __rest(spec, ["mark", "width", "height", "selection", "encoding"]); + return __assign({}, outerSpec, { facet: __assign({}, (row ? { row: row } : {}), (column ? { column: column } : {})), spec: normalizeNonFacetUnit(__assign({ mark: mark }, (width ? { width: width } : {}), (height ? { height: height } : {}), { encoding: encoding }, (selection ? { selection: selection } : {})), config) }); +} +function isNonFacetUnitSpecWithPrimitiveMark(spec) { + return mark_1.isPrimitiveMark(spec.mark); +} +function normalizeNonFacetUnit(spec, config) { + if (isNonFacetUnitSpecWithPrimitiveMark(spec)) { + // TODO: thoroughly test + if (encoding_1.isRanged(spec.encoding)) { + return normalizeRangedUnit(spec); + } + var overlayConfig = config && config.overlay; + var overlayWithLine = overlayConfig && spec.mark === mark_1.AREA && + util_1.contains(['linepoint', 'line'], overlayConfig.area); + var overlayWithPoint = overlayConfig && ((overlayConfig.line && spec.mark === mark_1.LINE) || + (overlayConfig.area === 'linepoint' && spec.mark === mark_1.AREA)); + // TODO: consider moving this to become another case of compositeMark + if (overlayWithPoint || overlayWithLine) { + return normalizeOverlay(spec, overlayWithPoint, overlayWithLine, config); + } + return spec; // Nothing to normalize + } + else { + return compositeMark.normalize(spec, config); + } +} +function normalizeRangedUnit(spec) { + var hasX = encoding_1.channelHasField(spec.encoding, channel_1.X); + var hasY = encoding_1.channelHasField(spec.encoding, channel_1.Y); + var hasX2 = encoding_1.channelHasField(spec.encoding, channel_1.X2); + var hasY2 = encoding_1.channelHasField(spec.encoding, channel_1.Y2); + if ((hasX2 && !hasX) || (hasY2 && !hasY)) { + var normalizedSpec = util_1.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; +} +// FIXME(#1804): re-design this +function normalizeOverlay(spec, overlayWithPoint, overlayWithLine, config) { + var mark = spec.mark, selection = spec.selection, encoding = spec.encoding, outerSpec = __rest(spec, ["mark", "selection", "encoding"]); + var layer = [{ mark: mark, encoding: encoding }]; + // Need to copy stack config to overlayed layer + var stackProps = stack_1.stack(mark, 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 (overlayWithLine) { + layer.push(__assign({ mark: { + type: 'line', + style: 'lineOverlay' + } }, (selection ? { selection: selection } : {}), { encoding: overlayEncoding })); + } + if (overlayWithPoint) { + layer.push(__assign({ mark: { + type: 'point', + filled: true, + style: 'pointOverlay' + } }, (selection ? { selection: selection } : {}), { encoding: overlayEncoding })); + } + return __assign({}, outerSpec, { layer: layer }); + var _a; +} +// TODO: add vl.spec.validate & move stuff from vl.validate to here +/* Accumulate non-duplicate fieldDefs in a dictionary */ +function accumulate(dict, fieldDefs) { + fieldDefs.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 = util_1.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 { + accumulate(dict, vlEncoding.fieldDefs(spec.encoding)); + } + return dict; +} +/* Returns all non-duplicate fieldDefs in a spec in a flat array */ +function fieldDefs(spec) { + return util_1.vals(fieldDefIndex(spec)); +} +exports.fieldDefs = fieldDefs; +function isStacked(spec, config) { + config = config || spec.config; + if (mark_1.isPrimitiveMark(spec.mark)) { + return stack_1.stack(spec.mark, spec.encoding, config ? config.stack : undefined) !== null; + } + return false; +} +exports.isStacked = isStacked; + +},{"./channel":15,"./compositemark":94,"./encoding":98,"./log":105,"./mark":107,"./stack":112,"./util":118}],112:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var aggregate_1 = require("./aggregate"); +var channel_1 = require("./channel"); +var encoding_1 = require("./encoding"); +var fielddef_1 = require("./fielddef"); +var log = require("./log"); +var mark_1 = require("./mark"); +var scale_1 = require("./scale"); +var util_1 = require("./util"); +var STACK_OFFSET_INDEX = { + zero: 1, + center: 1, + normalize: 1 +}; +function isStackOffset(stack) { + return !!STACK_OFFSET_INDEX[stack]; +} +exports.isStackOffset = isStackOffset; +exports.STACKABLE_MARKS = [mark_1.BAR, mark_1.AREA, mark_1.RULE, mark_1.POINT, mark_1.CIRCLE, mark_1.SQUARE, mark_1.LINE, mark_1.TEXT, mark_1.TICK]; +exports.STACK_BY_DEFAULT_MARKS = [mark_1.BAR, mark_1.AREA]; +function potentialStackedChannel(encoding) { + var xDef = encoding.x; + var yDef = encoding.y; + if (fielddef_1.isFieldDef(xDef) && fielddef_1.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 (fielddef_1.isFieldDef(xDef) && xDef.type === 'quantitative') { + return 'x'; + } + else if (fielddef_1.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 = mark_1.isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!util_1.contains(exports.STACKABLE_MARKS, mark)) { + return null; + } + var fieldChannel = potentialStackedChannel(encoding); + if (!fieldChannel) { + return null; + } + var stackedFieldDef = encoding[fieldChannel]; + var stackedField = fielddef_1.isStringFieldDef(stackedFieldDef) ? fielddef_1.field(stackedFieldDef, {}) : undefined; + var dimensionChannel = fieldChannel === 'x' ? 'y' : 'x'; + var dimensionDef = encoding[dimensionChannel]; + var dimensionField = fielddef_1.isStringFieldDef(dimensionDef) ? fielddef_1.field(dimensionDef, {}) : undefined; + // Should have grouping level of detail that is different from the dimension field + var stackBy = channel_1.NONPOSITION_CHANNELS.reduce(function (sc, channel) { + if (encoding_1.channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (cDef) { + var fieldDef = fielddef_1.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 = fielddef_1.isStringFieldDef(fieldDef) ? fielddef_1.field(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 (util_1.contains(exports.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; + } + // If stacked, check scale type if it is linear + if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== scale_1.ScaleType.LINEAR) { + log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type)); + return null; + } + // Check if it is a ranged mark + if (encoding_1.channelHasField(encoding, fieldChannel === channel_1.X ? channel_1.X2 : channel_1.Y2)) { + log.warn(log.message.cannotStackRangedMark(fieldChannel)); + return null; + } + // Warn if stacking summative aggregate + if (stackedFieldDef.aggregate && !util_1.contains(aggregate_1.SUM_OPS, stackedFieldDef.aggregate)) { + log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate)); + } + return { + groupbyChannel: dimensionDef ? dimensionChannel : undefined, + fieldChannel: fieldChannel, + impute: util_1.contains(['area', 'line'], mark), + stackBy: stackBy, + offset: offset + }; +} +exports.stack = stack; + +},{"./aggregate":12,"./channel":15,"./encoding":98,"./fielddef":100,"./log":105,"./mark":107,"./scale":108,"./util":118}],113:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("./datetime"); +var log = require("./log"); +var util_1 = require("./util"); +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 = exports.TimeUnit || (exports.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 +}; +exports.TIMEUNIT_PARTS = util_1.flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX); +function isLocalSingleTimeUnit(timeUnit) { + return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit]; +} +exports.isLocalSingleTimeUnit = isLocalSingleTimeUnit; +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]; +} +exports.isUtcSingleTimeUnit = isUtcSingleTimeUnit; +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]; +} +exports.isUTCTimeUnit = isUTCTimeUnit; +function getLocalTimeUnit(t) { + return t.substr(3); +} +exports.getLocalTimeUnit = getLocalTimeUnit; +var TIMEUNIT_INDEX = __assign({}, LOCAL_SINGLE_TIMEUNIT_INDEX, UTC_SINGLE_TIMEUNIT_INDEX, LOCAL_MULTI_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); +exports.TIMEUNITS = util_1.flagKeys(TIMEUNIT_INDEX); +function isTimeUnit(t) { + return !!TIMEUNIT_INDEX[t]; +} +exports.isTimeUnit = isTimeUnit; +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 = exports.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; +} +exports.convert = convert; +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 exports.TIMEUNIT_PARTS.reduce(function (parts, part) { + if (containsTimeUnit(timeUnit, part)) { + return parts.concat(part); + } + return parts; + }, []); +} +exports.getTimeUnitParts = getTimeUnitParts; +/** 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 + ); +} +exports.containsTimeUnit = containsTimeUnit; +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +function fieldExpr(fullTimeUnit, field) { + var fieldRef = "datum" + util_1.accessPath(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 = exports.TIMEUNIT_PARTS.reduce(function (dateExpr, tu) { + if (containsTimeUnit(fullTimeUnit, tu)) { + dateExpr[tu] = func(tu); + } + return dateExpr; + }, {}); + return datetime_1.dateTimeExpr(d); +} +exports.fieldExpr = fieldExpr; +/** + * 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; +} +exports.formatExpression = formatExpression; +function normalizeTimeUnit(timeUnit) { + if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) { + log.warn(log.message.dayReplacedWithDate(timeUnit)); + return timeUnit.replace('day', 'date'); + } + return timeUnit; +} +exports.normalizeTimeUnit = normalizeTimeUnit; + +},{"./datetime":97,"./log":105,"./util":118}],114:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +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 }; +} +exports.extractTitleConfig = extractTitleConfig; + +},{}],115:[function(require,module,exports){ +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("util"); +var log = require("./log"); +function _normalizeAutoSize(autosize) { + return util_1.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) { + log.warn(log.message.FIT_NON_SINGLE); + autosize.type = 'pad'; + } + } + return autosize; +} +exports.normalizeAutoSize = normalizeAutoSize; +var TOP_LEVEL_PROPERTIES = [ + 'background', 'padding' + // 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; + }, {}); +} +exports.extractTopLevelProperties = extractTopLevelProperties; + +},{"./log":105,"util":8}],116:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var filter_1 = require("./filter"); +var logical_1 = require("./logical"); +function isFilter(t) { + return t['filter'] !== undefined; +} +exports.isFilter = isFilter; +function isLookup(t) { + return t['lookup'] !== undefined; +} +exports.isLookup = isLookup; +function isCalculate(t) { + return t['calculate'] !== undefined; +} +exports.isCalculate = isCalculate; +function isBin(t) { + return !!t['bin']; +} +exports.isBin = isBin; +function isTimeUnit(t) { + return t['timeUnit'] !== undefined; +} +exports.isTimeUnit = isTimeUnit; +function isAggregate(t) { + return t['aggregate'] !== undefined; +} +exports.isAggregate = isAggregate; +function normalizeTransform(transform) { + return transform.map(function (t) { + if (isFilter(t)) { + return { + filter: logical_1.normalizeLogicalOperand(t.filter, filter_1.normalizeFilter) + }; + } + return t; + }); +} +exports.normalizeTransform = normalizeTransform; + +},{"./filter":101,"./logical":106}],117:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** 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 = exports.Type || (exports.Type = {})); +var TYPE_INDEX = { + quantitative: 1, + ordinal: 1, + temporal: 1, + nominal: 1 +}; +function isType(t) { + return !!TYPE_INDEX[t]; +} +exports.isType = isType; +exports.QUANTITATIVE = Type.QUANTITATIVE; +exports.ORDINAL = Type.ORDINAL; +exports.TEMPORAL = Type.TEMPORAL; +exports.NOMINAL = Type.NOMINAL; +/** + * 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 exports.QUANTITATIVE: + return 'quantitative'; + case 't': + case exports.TEMPORAL: + return 'temporal'; + case 'o': + case exports.ORDINAL: + return 'ordinal'; + case 'n': + case exports.NOMINAL: + return 'nominal'; + } + } + // If we get invalid input, return undefined type. + return undefined; +} +exports.getFullName = getFullName; + +},{}],118:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var vega_util_1 = require("vega-util"); +var logical_1 = require("./logical"); +var vega_util_2 = require("vega-util"); +exports.isArray = vega_util_2.isArray; +exports.isObject = vega_util_2.isObject; +exports.isNumber = vega_util_2.isNumber; +exports.isString = vega_util_2.isString; +exports.truncate = vega_util_2.truncate; +exports.toSet = vega_util_2.toSet; +exports.stringValue = vega_util_2.stringValue; +exports.splitAccessPath = vega_util_2.splitAccessPath; +/** + * 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; +} +exports.pick = 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. + */ +function omit(obj, props) { + var copy = duplicate(obj); + for (var _i = 0, props_2 = props; _i < props_2.length; _i++) { + var prop = props_2[_i]; + delete copy[prop]; + } + return copy; +} +exports.omit = omit; +function hash(a) { + if (vega_util_1.isString(a) || vega_util_1.isNumber(a) || isBoolean(a)) { + return String(a); + } + var str = stringify(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; +} +exports.hash = hash; +function contains(array, item) { + return array.indexOf(item) > -1; +} +exports.contains = contains; +/** Returns the array without the elements in item */ +function without(array, excludedItems) { + return array.filter(function (item) { return !contains(excludedItems, item); }); +} +exports.without = without; +function union(array, other) { + return array.concat(without(other, array)); +} +exports.union = union; +/** + * 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; +} +exports.some = some; +/** + * 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; +} +exports.every = every; +function flatten(arrays) { + return [].concat.apply([], arrays); +} +exports.flatten = flatten; +/** + * 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; +} +exports.mergeDeep = mergeDeep; +// 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' || vega_util_1.isArray(src[p]) || src[p] === null) { + dest[p] = src[p]; + } + else if (typeof dest[p] !== 'object' || dest[p] === null) { + dest[p] = mergeDeep(vega_util_1.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; +} +exports.unique = unique; +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +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; +} +exports.differ = differ; +function hasIntersection(a, b) { + for (var key in a) { + if (key in b) { + return true; + } + } + return false; +} +exports.hasIntersection = hasIntersection; +function isNumeric(num) { + return !isNaN(num); +} +exports.isNumeric = isNumeric; +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; +} +exports.differArray = differArray; +// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208 +exports.keys = Object.keys; +function vals(x) { + var _vals = []; + for (var k in x) { + if (x.hasOwnProperty(k)) { + _vals.push(x[k]); + } + } + return _vals; +} +exports.vals = vals; +function flagKeys(f) { + return exports.keys(f); +} +exports.flagKeys = flagKeys; +function duplicate(obj) { + return JSON.parse(JSON.stringify(obj)); +} +exports.duplicate = duplicate; +function isBoolean(b) { + return b === true || b === false; +} +exports.isBoolean = isBoolean; +/** + * 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; +} +exports.varName = varName; +function logicalExpr(op, cb) { + if (logical_1.isLogicalNot(op)) { + return '!(' + logicalExpr(op.not, cb) + ')'; + } + else if (logical_1.isLogicalAnd(op)) { + return '(' + op.and.map(function (and) { return logicalExpr(and, cb); }).join(') && (') + ')'; + } + else if (logical_1.isLogicalOr(op)) { + return '(' + op.or.map(function (or) { return logicalExpr(or, cb); }).join(') || (') + ')'; + } + else { + return cb(op); + } +} +exports.logicalExpr = logicalExpr; +/** + * Delete nested property of an object, and delete the ancestors of the property if they become empty. + */ +function deleteNestedProperty(obj, orderedProps) { + var isEmpty = true; + while (orderedProps.length > 0 && isEmpty) { + var o = obj; + for (var i = 0; i < orderedProps.length - 1; i++) { + o = o[orderedProps[i]]; + } + delete o[orderedProps.pop()]; + if (exports.keys(o).length !== 0) { + isEmpty = false; + } + } +} +exports.deleteNestedProperty = deleteNestedProperty; +function titlecase(s) { + return s.charAt(0).toUpperCase() + s.substr(1); +} +exports.titlecase = titlecase; +/** + * Converts a path to an access path. + */ +function accessPath(path) { + return "[" + vega_util_1.splitAccessPath(path).map(vega_util_1.stringValue).join('][') + "]"; +} +exports.accessPath = accessPath; + +},{"./logical":106,"json-stable-stringify":1,"vega-util":10}],119:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var mark_1 = require("./mark"); +var mark_2 = require("./mark"); +var util_1 = require("./util"); +/** + * Required Encoding Channels for each mark type + */ +exports.DEFAULT_REQUIRED_CHANNEL_MAP = { + text: ['text'], + line: ['x', 'y'], + area: ['x', 'y'] +}; +/** + * Supported Encoding Channel for each mark type + */ +exports.DEFAULT_SUPPORTED_CHANNEL_TYPE = { + bar: util_1.toSet(['row', 'column', 'x', 'y', 'size', 'color', 'detail']), + line: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + area: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + tick: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + circle: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + square: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + point: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']), + text: util_1.toSet(['row', 'column', 'size', 'color', '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 = exports.DEFAULT_REQUIRED_CHANNEL_MAP; } + if (supportedChannelMap === void 0) { supportedChannelMap = exports.DEFAULT_SUPPORTED_CHANNEL_TYPE; } + var mark = mark_1.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) { + if (!(requiredChannels[i] in encoding)) { + return 'Missing encoding channel \"' + requiredChannels[i] + + '\" for mark \"' + mark + '\"'; + } + } + for (var channel in encoding) { + if (!supportedChannels[channel]) { + return 'Encoding channel \"' + channel + + '\" is not supported by mark type \"' + mark + '\"'; + } + } + if (mark === mark_2.BAR && !encoding.x && !encoding.y) { + return 'Missing both x and y for bar'; + } + return null; +} +exports.getEncodingMappingError = getEncodingMappingError; + +},{"./mark":107,"./util":118}],120:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +function isVgSignalRef(o) { + return !!o['signal']; +} +exports.isVgSignalRef = isVgSignalRef; +function isVgRangeStep(range) { + return !!range['step']; +} +exports.isVgRangeStep = isVgRangeStep; +function isDataRefUnionedDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && !('data' in domain); + } + return false; +} +exports.isDataRefUnionedDomain = isDataRefUnionedDomain; +function isFieldRefUnionDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && 'data' in domain; + } + return false; +} +exports.isFieldRefUnionDomain = isFieldRefUnionDomain; +function isDataRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'field' in domain && 'data' in domain; + } + return false; +} +exports.isDataRefDomain = isDataRefDomain; +function isSignalRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'signal' in domain; + } + return false; +} +exports.isSignalRefDomain = isSignalRefDomain; +var VG_MARK_CONFIG_INDEX = { + opacity: 1, + fill: 1, + fillOpacity: 1, + stroke: 1, + strokeWidth: 1, + strokeOpacity: 1, + strokeDash: 1, + strokeDashOffset: 1, + size: 1, + shape: 1, + interpolate: 1, + tension: 1, + orient: 1, + align: 1, + baseline: 1, + text: 1, + limit: 1, + dx: 1, + dy: 1, + radius: 1, + theta: 1, + angle: 1, + font: 1, + fontSize: 1, + fontWeight: 1, + fontStyle: 1 + // commented below are vg channel that do not have mark config. + // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height' + // cursor: 1, + // clip: 1, + // dir: 1, + // ellipsis: 1, + // endAngle: 1, + // path: 1, + // innerRadius: 1, + // outerRadius: 1, + // startAngle: 1, + // url: 1, +}; +exports.VG_MARK_CONFIGS = util_1.flagKeys(VG_MARK_CONFIG_INDEX); + +},{"./util":118}]},{},[103])(103) +}); +//# 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..54a0ca9774 --- /dev/null +++ b/build/vega-lite.js.map @@ -0,0 +1,251 @@ +{ + "version": 3, + "sources": [ + "node_modules/browser-pack/_prelude.js", + "node_modules/json-stable-stringify/index.js", + "node_modules/jsonify/index.js", + "node_modules/jsonify/lib/parse.js", + "node_modules/jsonify/lib/stringify.js", + "node_modules/process/browser.js", + "node_modules/util/node_modules/inherits/inherits_browser.js", + "node_modules/util/support/isBufferBrowser.js", + "node_modules/util/util.js", + "node_modules/vega-event-selector/build/vega-event-selector.js", + "node_modules/vega-util/build/vega-util.js", + "package.json", + "src/aggregate.ts", + "src/axis.ts", + "src/bin.ts", + "src/channel.ts", + "src/compile/axis/assemble.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/baseconcat.ts", + "src/compile/buildmodel.ts", + "src/compile/common.ts", + "src/compile/compile.ts", + "src/compile/concat.ts", + "src/compile/data/aggregate.ts", + "src/compile/data/assemble.ts", + "src/compile/data/bin.ts", + "src/compile/data/calculate.ts", + "src/compile/data/dataflow.ts", + "src/compile/data/facet.ts", + "src/compile/data/filter.ts", + "src/compile/data/filterinvalid.ts", + "src/compile/data/formatparse.ts", + "src/compile/data/indentifier.ts", + "src/compile/data/lookup.ts", + "src/compile/data/optimize.ts", + "src/compile/data/optimizers.ts", + "src/compile/data/parse.ts", + "src/compile/data/source.ts", + "src/compile/data/stack.ts", + "src/compile/data/timeunit.ts", + "src/compile/facet.ts", + "src/compile/layer.ts", + "src/compile/layout/header.ts", + "src/compile/layoutsize/assemble.ts", + "src/compile/layoutsize/parse.ts", + "src/compile/legend/assemble.ts", + "src/compile/legend/component.ts", + "src/compile/legend/encode.ts", + "src/compile/legend/parse.ts", + "src/compile/legend/properties.ts", + "src/compile/mark/area.ts", + "src/compile/mark/bar.ts", + "src/compile/mark/init.ts", + "src/compile/mark/line.ts", + "src/compile/mark/mark.ts", + "src/compile/mark/mixins.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/valueref.ts", + "src/compile/model.ts", + "src/compile/repeat.ts", + "src/compile/repeater.ts", + "src/compile/resolve.ts", + "src/compile/scale/assemble.ts", + "src/compile/scale/component.ts", + "src/compile/scale/domain.ts", + "src/compile/scale/parse.ts", + "src/compile/scale/properties.ts", + "src/compile/scale/range.ts", + "src/compile/scale/type.ts", + "src/compile/selection/interval.ts", + "src/compile/selection/multi.ts", + "src/compile/selection/selection.ts", + "src/compile/selection/single.ts", + "src/compile/selection/transforms/inputs.ts", + "src/compile/selection/transforms/nearest.ts", + "src/compile/selection/transforms/project.ts", + "src/compile/selection/transforms/scales.ts", + "src/compile/selection/transforms/toggle.ts", + "src/compile/selection/transforms/transforms.ts", + "src/compile/selection/transforms/translate.ts", + "src/compile/selection/transforms/zoom.ts", + "src/compile/split.ts", + "src/compile/unit.ts", + "src/compositemark/boxplot.ts", + "src/compositemark/common.ts", + "src/compositemark/errorbar.ts", + "src/compositemark/index.ts", + "src/config.ts", + "src/data.ts", + "src/datetime.ts", + "src/encoding.ts", + "src/fielddef.ts", + "src/filter.ts", + "src/guide.ts", + "src/index.ts", + "src/legend.ts", + "src/log.ts", + "src/logical.ts", + "src/mark.ts", + "src/scale.ts", + "src/selection.ts", + "src/sort.ts", + "src/spec.ts", + "src/stack.ts", + "src/timeunit.ts", + "src/title.ts", + "src/toplevelprops.ts", + "src/transform.ts", + "src/type.ts", + "src/util.ts", + "src/validate.ts", + "src/vega.schema.ts" + ], + "names": [], + "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpFA;AACA;AACA;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC1kBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9oBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACxIA,+BAAuD;AASvD,IAAM,kBAAkB,GAAsB;IAC5C,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,EAAE,E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", + "file": "generated.js", + "sourceRoot": "", + "sourcesContent": [ + "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o= '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", + "// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n", + "if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n", + "module.exports = function isBuffer(arg) {\n return arg && typeof arg === 'object'\n && typeof arg.copy === 'function'\n && typeof arg.fill === 'function'\n && typeof arg.readUInt8 === 'function';\n}", + "// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n if (!isString(f)) {\n var objects = [];\n for (var i = 0; i < arguments.length; i++) {\n objects.push(inspect(arguments[i]));\n }\n return objects.join(' ');\n }\n\n var i = 1;\n var args = arguments;\n var len = args.length;\n var str = String(f).replace(formatRegExp, function(x) {\n if (x === '%%') return '%';\n if (i >= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n // Allow for deprecating things in the process of starting up.\n if (isUndefined(global.process)) {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n if (process.noDeprecation === true) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = process.env.NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n", + "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.vega = global.vega || {})));\n}(this, (function (exports) { 'use strict';\n\n/**\n * Parse an event selector string.\n * Returns an array of event stream definitions.\n */\nvar eventSelector = 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';\nvar LBRACK = '[';\nvar RBRACK = ']';\nvar LBRACE = '{';\nvar RBRACE = '}';\nvar COLON = ':';\nvar COMMA = ',';\nvar NAME = '@';\nvar GT = '>';\nvar ILLEGAL = /[[\\]{}]/;\nvar DEFAULT_SOURCE;\nvar MARKS;\nvar 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\nexports.selector = eventSelector;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n", + "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.vega = global.vega || {})));\n}(this, (function (exports) { 'use strict';\n\nvar accessor = function(fn, fields, name) {\n fn.fields = fields || [];\n fn.fname = name;\n return fn;\n};\n\nfunction accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nfunction accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n\nvar error = function(message) {\n throw Error(message);\n};\n\nvar splitAccessPath = 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\nvar isArray = Array.isArray;\n\nvar isObject = function(_) {\n return _ === Object(_);\n};\n\nvar isString = function(_) {\n return typeof _ === 'string';\n};\n\nfunction $(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\nvar field = function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map($).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n};\n\nvar empty = [];\n\nvar id = field('id');\n\nvar identity = accessor(function(_) { return _; }, empty, 'identity');\n\nvar zero = accessor(function() { return 0; }, empty, 'zero');\n\nvar one = accessor(function() { return 1; }, empty, 'one');\n\nvar truthy = accessor(function() { return true; }, empty, 'true');\n\nvar falsy = accessor(function() { return false; }, empty, 'false');\n\nfunction 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\nvar None = 0;\nvar Error$1 = 1;\nvar Warn = 2;\nvar Info = 3;\nvar Debug = 4;\n\nvar logger = 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$1) 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\nvar peek = function(array) {\n return array[array.length - 1];\n};\n\nvar toNumber = function(_) {\n return _ == null || _ === '' ? null : +_;\n};\n\nfunction exp(sign) {\n return function(x) { return sign * Math.exp(x); };\n}\n\nfunction log$1(sign) {\n return function(x) { return Math.log(sign * x); };\n}\n\nfunction pow(exponent) {\n return function(x) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n };\n}\n\nfunction pan(domain, delta, lift, ground) {\n var d0 = lift(domain[0]),\n d1 = lift(peek(domain)),\n dd = (d1 - d0) * delta;\n\n return [\n ground(d0 - dd),\n ground(d1 - dd)\n ];\n}\n\nfunction panLinear(domain, delta) {\n return pan(domain, delta, toNumber, identity);\n}\n\nfunction panLog(domain, delta) {\n var sign = Math.sign(domain[0]);\n return pan(domain, delta, log$1(sign), exp(sign));\n}\n\nfunction panPow(domain, delta, exponent) {\n return pan(domain, delta, pow(exponent), pow(1/exponent));\n}\n\nfunction zoom(domain, anchor, scale, lift, ground) {\n var d0 = lift(domain[0]),\n d1 = lift(peek(domain)),\n da = anchor != null ? lift(anchor) : (d0 + d1) / 2;\n\n return [\n ground(da + (d0 - da) * scale),\n ground(da + (d1 - da) * scale)\n ];\n}\n\nfunction zoomLinear(domain, anchor, scale) {\n return zoom(domain, anchor, scale, toNumber, identity);\n}\n\nfunction zoomLog(domain, anchor, scale) {\n var sign = Math.sign(domain[0]);\n return zoom(domain, anchor, scale, log$1(sign), exp(sign));\n}\n\nfunction zoomPow(domain, anchor, scale, exponent) {\n return zoom(domain, anchor, scale, pow(exponent), pow(1/exponent));\n}\n\nvar array = function(_) {\n return _ != null ? (isArray(_) ? _ : [_]) : [];\n};\n\nvar isFunction = function(_) {\n return typeof _ === 'function';\n};\n\nvar compare = function(fields, orders) {\n var idx = [],\n cmp = (fields = array(fields)).map(function(f, i) {\n if (f == null) {\n return null;\n } else {\n idx.push(i);\n return isFunction(f) ? f\n : splitAccessPath(f).map($).join('][');\n }\n }),\n n = idx.length - 1,\n ord = array(orders),\n code = 'var u,v;return ',\n i, j, f, u, v, d, t, lt, gt;\n\n if (n < 0) return null;\n\n for (j=0; j<=n; ++j) {\n i = idx[j];\n f = cmp[i];\n\n if (isFunction(f)) {\n d = 'f' + i;\n u = '(u=this.' + d + '(a))';\n v = '(v=this.' + d + '(b))';\n (t = t || {})[d] = f;\n } else {\n u = '(u=a['+f+'])';\n v = '(v=b['+f+'])';\n }\n\n d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))';\n\n if (ord[i] !== 'descending') {\n gt = 1;\n lt = -1;\n } else {\n gt = -1;\n lt = 1;\n }\n\n code += '(' + u+'<'+v+'||u==null)&&v!=null?' + lt\n + ':(u>v||v==null)&&u!=null?' + gt\n + ':'+d+'!==u&&v===v?' + lt\n + ':v!==v&&u===u?' + gt\n + (i < n ? ':' : ':0');\n }\n\n f = Function('a', 'b', code + ';');\n if (t) f = f.bind(t);\n\n fields = fields.reduce(function(map, field) {\n if (isFunction(field)) {\n (accessorFields(field) || []).forEach(function(_) { map[_] = 1; });\n } else if (field != null) {\n map[field + ''] = 1;\n }\n return map;\n }, {});\n\n return accessor(f, Object.keys(fields));\n};\n\nvar constant = function(_) {\n return isFunction(_) ? _ : function() { return _; };\n};\n\nvar debounce = function(delay, handler) {\n var tid, evt;\n\n function callback() {\n handler(evt);\n tid = evt = null;\n }\n\n return function(e) {\n evt = e;\n if (tid) clearTimeout(tid);\n tid = setTimeout(callback, delay);\n };\n};\n\nvar extend = function(_) {\n for (var x, k, i=1, len=arguments.length; i= b) {\n a = c = b;\n break;\n }\n }\n u = v = i;\n while (++i < n) {\n b = array[i];\n if (b != null) {\n if (a > b) {\n a = b;\n u = i;\n }\n if (c < b) {\n c = b;\n v = i;\n }\n }\n }\n } else {\n while (++i < n) {\n b = f(array[i], i, array);\n if (b != null && b >= b) {\n a = c = b;\n break;\n }\n }\n u = v = i;\n while (++i < n) {\n b = f(array[i], i, array);\n if (b != null) {\n if (a > b) {\n a = b;\n u = i;\n }\n if (c < b) {\n c = b;\n v = i;\n }\n }\n }\n }\n\n return [u, v];\n};\n\nvar NULL = {};\n\nvar fastmap = function(input) {\n var obj = {},\n map,\n test;\n\n function has(key) {\n return obj.hasOwnProperty(key) && obj[key] !== NULL;\n }\n\n map = {\n size: 0,\n empty: 0,\n object: obj,\n has: has,\n get: function(key) {\n return has(key) ? obj[key] : undefined;\n },\n set: function(key, value) {\n if (!has(key)) {\n ++map.size;\n if (obj[key] === NULL) --map.empty;\n }\n obj[key] = value;\n return this;\n },\n delete: function(key) {\n if (has(key)) {\n --map.size;\n ++map.empty;\n obj[key] = NULL;\n }\n return this;\n },\n clear: function() {\n map.size = map.empty = 0;\n map.object = obj = {};\n },\n test: function(_) {\n if (arguments.length) {\n test = _;\n return map;\n } else {\n return test;\n }\n },\n clean: function() {\n var next = {},\n size = 0,\n key, value;\n for (key in obj) {\n value = obj[key];\n if (value !== NULL && (!test || !test(value))) {\n next[key] = value;\n ++size;\n }\n }\n map.size = size;\n map.empty = 0;\n map.object = (obj = next);\n }\n };\n\n if (input) Object.keys(input).forEach(function(key) {\n map.set(key, input[key]);\n });\n\n return map;\n};\n\nvar inherits = function(child, parent) {\n var proto = (child.prototype = Object.create(parent.prototype));\n proto.constructor = child;\n return proto;\n};\n\nvar isBoolean = function(_) {\n return typeof _ === 'boolean';\n};\n\nvar isDate = function(_) {\n return Object.prototype.toString.call(_) === '[object Date]';\n};\n\nvar isNumber = function(_) {\n return typeof _ === 'number';\n};\n\nvar isRegExp = function(_) {\n return Object.prototype.toString.call(_) === '[object RegExp]';\n};\n\nvar key = function(fields, flat) {\n if (fields) {\n fields = flat\n ? array(fields).map(function(f) { return f.replace(/\\\\(.)/g, '$1'); })\n : array(fields);\n }\n\n var fn = !(fields && fields.length)\n ? function() { return ''; }\n : Function('_', 'return \\'\\'+' +\n fields.map(function(f) {\n return '_[' + (flat\n ? $(f)\n : splitAccessPath(f).map($).join('][')\n ) + ']';\n }).join('+\\'|\\'+') + ';');\n\n return accessor(fn, fields, 'key');\n};\n\nvar merge = function(compare, array0, array1, output) {\n var n0 = array0.length,\n n1 = array1.length;\n\n if (!n1) return array0;\n if (!n0) return array1;\n\n var merged = output || new array0.constructor(n0 + n1),\n i0 = 0, i1 = 0, i = 0;\n\n for (; i0 0\n ? array1[i1++]\n : array0[i0++];\n }\n\n for (; i0= 0) s += str;\n return s;\n};\n\nvar pad = function(str, length, padchar, align) {\n var c = padchar || ' ',\n s = str + '',\n n = length - s.length;\n\n return n <= 0 ? s\n : align === 'left' ? repeat(c, n) + s\n : align === 'center' ? repeat(c, ~~(n/2)) + s + repeat(c, Math.ceil(n/2))\n : s + repeat(c, n);\n};\n\nvar toBoolean = function(_) {\n return _ == null || _ === '' ? null : !_ || _ === 'false' || _ === '0' ? false : !!_;\n};\n\nfunction defaultParser(_) {\n return isNumber(_) ? _ : isDate(_) ? _ : Date.parse(_);\n}\n\nvar toDate = function(_, parser) {\n parser = parser || defaultParser;\n return _ == null || _ === '' ? null : parser(_);\n};\n\nvar toString = function(_) {\n return _ == null || _ === '' ? null : _ + '';\n};\n\nvar toSet = function(_) {\n for (var s={}, i=0, n=_.length; i (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 provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.\",\n \"main\": \"build/src/index.js\",\n \"types\": \"typings/vega-lite.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 \"pretsc\": \"mkdir -p build && rm -rf build/*/** && cp package.json build/\",\n \"tsc\": \"tsc\",\n \"prebuild\": \"mkdir -p build/site build/test-gallery\",\n \"build\": \"npm run build:only\",\n \"build:only\": \"npm run tsc && cp package.json build && browserify src/index.ts -p tsify -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js\",\n \"postbuild\": \"node node_modules/uglify-js/bin/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 && npm run build:only && npm run build:examples-only\",\n \"build:examples-only\": \"npm run build:example && npm run build:examples-normalized\",\n \"build:examples-normalized\": \"rm -f examples/specs/normalized/*.vl.json && scripts/build-normalized-examples\",\n \"build:example\": \"TZ=America/Los_Angeles scripts/build-examples.sh\",\n\n \"build:toc\": \"bundle exec jekyll build -q && scripts/generate-toc\",\n \"build:site\": \"browserify site/static/main.ts -p [tsify -p site] -d | exorcist build/site/main.js.map > build/site/main.js\",\n \"build:versions\": \"scripts/update-version.sh\",\n \"build:test-gallery\": \"browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js\",\n \"check:examples\": \"scripts/check-examples.sh\",\n \"check:schema\": \"scripts/check-schema.sh\",\n \"clean\": \"rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\\\.(js|js.map|d.ts)' -delete && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -exec rm -f {} +\",\n \"data\": \"rsync -r node_modules/vega-datasets/data/* data\",\n \"link\": \"npm link && npm link vega-lite\",\n\n \"deploy\": \"scripts/deploy.sh\",\n \"deploy:gh\": \"scripts/deploy-gh.sh\",\n \"deploy:schema\": \"scripts/deploy-schema.sh\",\n\n \"prestart\": \"npm run data && npm run build && scripts/index-examples\",\n \"start\": \"nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'\",\n \"poststart\": \"rm examples/all-examples.json\",\n\n \"preschema\": \"npm run prebuild\",\n \"schema\": \"ts-json-schema-generator --path tsconfig.json --type TopLevelExtendedSpec > 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\n \"lint\": \"tslint -p .\",\n \"test\": \"npm run build:only && npm run test:only && npm run test:runtime && npm run lint\",\n \"posttest\": \"npm run schema && npm run data && npm run mocha:examples\",\n \"test:nocompile\": \"npm run test:only && npm run test:runtime && npm run lint && npm run mocha:examples\",\n \"test:only\": \"nyc --reporter=html --reporter=text-summary npm run mocha:test\",\n \"test:runtime\": \"TZ=America/Los_Angeles wdio wdio.conf.js\",\n \"test:runtime:generate\": \"rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime\",\n \"test:debug\": \"npm run tsc && mocha --recursive --debug-brk --inspect build/test\",\n \"test:debug-examples\": \"npm run tsc && npm run schema && mocha --recursive --debug-brk --inspect build/examples\",\n \"mocha:test\": \"mocha --require source-map-support/register --reporter dot --recursive build/test\",\n \"mocha:examples\": \"mocha --require source-map-support/register --reporter dot --recursive build/examples\",\n\n \"codecov\": \"nyc report --reporter=json && codecov -f coverage/*.json\",\n \"watch:build\": \"watchify src/index.ts -p tsify -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'\",\n \"watch:tsc\": \"npm run tsc -- -w\",\n \"watch:test\": \"nodemon -x 'npm test'\",\n \"watch\": \"nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build\"\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.0.6\",\n \"@types/d3\": \"^4.12.0\",\n \"@types/highlight.js\": \"^9.12.2\",\n \"@types/json-stable-stringify\": \"^1.0.32\",\n \"@types/mkdirp\": \"^0.5.1\",\n \"@types/mocha\": \"^2.2.44\",\n \"@types/node\": \"^8.0.53\",\n \"@types/webdriverio\": \"^4.8.6\",\n \"ajv\": \"^5.5.0\",\n \"browser-sync\": \"^2.18.13\",\n \"browserify\": \"^14.5.0\",\n \"browserify-shim\": \"^3.8.14\",\n \"chai\": \"^4.1.2\",\n \"cheerio\": \"^1.0.0-rc.2\",\n \"chromedriver\": \"^2.33.2\",\n \"codecov\": \"^3.0.0\",\n \"d3\": \"^4.12.0\",\n \"exorcist\": \"^1.0.0\",\n \"highlight.js\": \"^9.12.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^4.0.1\",\n \"nodemon\": \"^1.12.1\",\n \"nyc\": \"^11.3.0\",\n \"source-map-support\": \"^0.5.0\",\n \"svg2png-many\": \"^0.0.7\",\n \"ts-json-schema-generator\": \"^0.18.0\",\n \"ts-node\": \"^3.3.0\",\n \"tsify\": \"^3.0.3\",\n \"tslint\": \"5.4.3\",\n \"tslint-eslint-rules\": \"^4.1.1\",\n \"typescript\": \"^2.6.2\",\n \"uglify-js\": \"^3.2.0\",\n \"vega\": \"^3.0.8\",\n \"vega-datasets\": \"^1.11.0\",\n \"vega-embed\": \"^3.0.0-rc7\",\n \"vega-tooltip\": \"^0.4.4\",\n \"watchify\": \"^3.9.0\",\n \"wdio-chromedriver-service\": \"^0.1.1\",\n \"wdio-dot-reporter\": \"0.0.9\",\n \"wdio-mocha-framework\": \"^0.5.11\",\n \"wdio-static-server-service\": \"^1.0.1\",\n \"webdriverio\": \"^4.9.11\",\n \"yaml-front-matter\": \"^3.4.0\"\n },\n \"dependencies\": {\n \"json-stable-stringify\": \"^1.0.1\",\n \"tslib\": \"^1.8.0\",\n \"vega-event-selector\": \"^2.0.0\",\n \"vega-util\": \"^1.6.2\",\n \"yargs\": \"^10.0.3\"\n }\n}\n", + "import {contains, Flag, flagKeys, toSet} from './util';\n\n\nexport type AggregateOp = 'argmax' | 'argmin' | 'average' | 'count'\n | 'distinct' | 'max' | 'mean' | 'median' | 'min' | 'missing'\n | 'q1' | 'q3' | 'ci0' | 'ci1' | 'stdev' | 'stdevp' | 'sum' | 'valid' | 'values' | 'variance'\n | 'variancep';\n\n\nconst AGGREGATE_OP_INDEX: Flag = {\n values: 1,\n count: 1,\n valid: 1,\n missing: 1,\n distinct: 1,\n sum: 1,\n mean: 1,\n average: 1,\n variance: 1,\n variancep: 1,\n stdev: 1,\n stdevp: 1,\n median: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n min: 1,\n max: 1,\n argmin: 1,\n argmax: 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](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[] | 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/**\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'\n} = {\n grid: 'grid',\n labelOverlap: 'main',\n offset: 'main',\n title: 'main'\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](axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](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", + "import {Channel, COLOR, COLUMN, OPACITY, ROW, SHAPE, SIZE} from './channel';\nimport {isBoolean, keys} 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 * 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 => `_${p}_${bin[p]}`.replace(',', '_')).join('');\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 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", + "/*\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 {SCALE_TYPES, ScaleType} from './scale';\nimport {contains, 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 // Mark property with scale\n export const COLOR: 'color' = 'color';\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 TOOLTIP: 'tooltip' = 'tooltip';\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;\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;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\nexport const TOOLTIP = Channel.TOOLTIP;\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n size: 1,\n shape: 1,\n color: 1,\n order: 1,\n opacity: 1,\n text: 1,\n detail: 1,\n tooltip: 1\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 projecttion 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' | 'row' | 'column' | 'size' | 'shape' | 'color' | 'opacity' | 'text' | 'tooltip';\n\n\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 // 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 has format instead of scale\n text: _t, tooltip: _tt,\n // detail and order have no scale\n detail: _dd, 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 interface SupportedMark {\n point?: boolean;\n tick?: boolean;\n rule?: boolean;\n circle?: boolean;\n square?: boolean;\n bar?: boolean;\n rect?: boolean;\n line?: boolean;\n area?: boolean;\n text?: boolean;\n tooltip?: 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 X:\n case Y:\n case COLOR:\n case DETAIL:\n case TOOLTIP:\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, area: true, text: true\n };\n case X2:\n case Y2:\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\n };\n case SHAPE:\n return {point: 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 and TOOLTIP have no scale but have discrete output\n case TEXT:\n case TOOLTIP:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n return 'flexible';\n\n // No scale, no range type.\n case DETAIL:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('getSupportedRole not implemented for ' + channel);\n}\n", + "import {VgAxis} from '../../vega.schema';\nimport {AxisComponent, AxisComponentIndex} from './component';\n\n\nconst mainAxisReducer = getAxisReducer('main');\nconst gridAxisReducer = getAxisReducer('grid');\n\nfunction getAxisReducer(axisType: 'main' | 'grid') {\n return (axes: VgAxis[], axis: AxisComponent) => {\n if (axis[axisType]) {\n // Need to cast here so it's not longer partial type.\n axes.push(axis[axisType].combine() as VgAxis);\n }\n return axes;\n };\n}\n\nexport function assembleAxes(axisComponents: AxisComponentIndex): VgAxis[] {\n return [].concat(\n axisComponents.x ? [].concat(\n axisComponents.x.reduce(mainAxisReducer, []),\n axisComponents.x.reduce(gridAxisReducer, [])\n ) : [],\n axisComponents.y ? [].concat(\n axisComponents.y.reduce(mainAxisReducer, []),\n axisComponents.y.reduce(gridAxisReducer, []),\n ) : []\n );\n}\n\n", + "import {Axis} from '../../axis';\nimport {VgAxis} from '../../vega.schema';\nimport {Split} from '../split';\n\nexport class AxisComponentPart extends Split> {}\n\nexport interface AxisComponent {\n main?: AxisComponentPart;\n grid?: AxisComponentPart;\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 labelsSpec.text = {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale)\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 && channel === 'x') {\n const align = labelAlign(angle, orient);\n if (align) {\n labelsSpec.align = {value: align};\n }\n\n // Auto set baseline if x is rotated by 90, or -90\n if (contains([90, 270], angle)) {\n labelsSpec.baseline = {value: 'middle'};\n }\n }\n\n labelsSpec = {\n ...labelsSpec,\n ...specifiedLabelsSpec\n };\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\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 if (angle > 0) {\n if (angle % 360 > 180) {\n return orient === 'top' ? 'left' : 'right';\n } else if (angle % 360 < 180) {\n return orient === 'top' ? 'right': 'left';\n }\n } else if (angle < 0) {\n return labelAlign((angle % 360) + 360 /* convert to positive value*/, orient);\n }\n return undefined;\n}\n\n", + "import {Axis, AXIS_PROPERTY_TYPE, AxisEncoding, isAxisProperty, VG_AXIS_PROPERTIES} from '../../axis';\nimport {POSITION_SCALE_CHANNELS, PositionScaleChannel} from '../../channel';\nimport {keys, some} from '../../util';\nimport {AxisOrient, VgAxis, VgAxisEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, numberFormat, titleMerger} from '../common';\nimport {LayerModel} from '../layer';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {AxisComponent, AxisComponentIndex, AxisComponentPart} from './component';\nimport {getAxisConfig} from './config';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\ntype AxisPart = keyof AxisEncoding;\nconst AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\nexport function parseUnitAxis(model: UnitModel): AxisComponentIndex {\n return POSITION_SCALE_CHANNELS.reduce(function(axis, channel) {\n if (model.axis(channel)) {\n const axisComponent: AxisComponent = {};\n // TODO: support multiple axis\n const main = parseMainAxis(channel, model);\n if (main && isVisibleAxis(main)) {\n axisComponent.main = main;\n }\n\n const grid = parseGridAxis(channel, model);\n if (grid && isVisibleAxis(grid)) {\n axisComponent.grid = grid;\n }\n\n axis[channel] = [axisComponent];\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.main.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.main.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 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 mergedMain = mergedAxisCmpts[i].main;\n const childMain = childAxisCmpts[i].main;\n\n if ((!!mergedMain) !== (!!childMain)) {\n return undefined;\n } else if (mergedMain && childMain) {\n const mergedOrient = mergedMain.getWithExplicit('orient');\n const childOrient = childMain.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 // Cannot merge due to inconsistent orient\n return undefined;\n } else {\n mergedAxisCmpts[i].main = mergeAxisComponentPart(mergedMain, childMain);\n }\n }\n\n const mergedGrid = mergedAxisCmpts[i].grid;\n const childGrid = childAxisCmpts[i].grid;\n if ((!!mergedGrid) !== (!!childGrid)) {\n return undefined;\n } else if (mergedGrid && childGrid) {\n mergedAxisCmpts[i].grid = mergeAxisComponentPart(mergedGrid, childGrid);\n }\n }\n } else {\n // For first one, return a copy of the child\n return childAxisCmpts.map(axisComponent => ({\n ...(axisComponent.main ? {main: axisComponent.main.clone()} : {}),\n ...(axisComponent.grid ? {grid: axisComponent.grid.clone()} : {})\n }));\n }\n return mergedAxisCmpts;\n}\n\nfunction mergeAxisComponentPart(merged: AxisComponentPart, child: AxisComponentPart): AxisComponentPart {\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 titleMerger(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 isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\n/**\n * Return if an axis is visible (shows at least one part of the axis).\n */\nfunction isVisibleAxis(axis: AxisComponentPart) {\n return some(AXIS_PARTS, (part) => hasAxisPart(axis, part));\n}\n\nfunction hasAxisPart(axis: AxisComponentPart, 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') {\n return true;\n }\n\n if (part === 'grid' || part === 'title') {\n return !!axis.get(part);\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(axis.get(part));\n}\n\n/**\n * Make an inner axis for showing grid for shared axis.\n */\nexport function parseGridAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponentPart {\n // FIXME: support adding ticks for grid axis that are inner axes of faceted plots.\n return parseAxis(channel, model, true);\n}\n\nexport function parseMainAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponentPart {\n return parseAxis(channel, model, false);\n}\n\nfunction parseAxis(channel: PositionScaleChannel, model: UnitModel, isGridAxis: boolean): AxisComponentPart {\n const axis = model.axis(channel);\n\n const axisComponent = new AxisComponentPart();\n\n // 1.2. Add properties\n VG_AXIS_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, axis, channel, model, isGridAxis);\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 value === axis[property];\n\n const configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type'));\n\n if (\n explicit || configValue === undefined ||\n // A lot of rules need to be applied for the grid axis\n // FIXME: this is not perfectly correct, but we need to rewrite axis component to have one axis and separate them later during assembly anyway.\n isGridAxis\n ) {\n // Do not apply implicit rule if there is a config value\n axisComponent.set(property, value, explicit);\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 (!hasAxisPart(axisComponent, part)) {\n // No need to create encode for a disabled part.\n return e;\n }\n\n const value = part === 'labels' ?\n encode.labels(model, channel, axisEncoding.labels || {}, axisComponent.get('orient')) :\n axisEncoding[part] || {};\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);\n }\n\n return axisComponent;\n}\n\nfunction getProperty(property: K, specifiedAxis: Axis, channel: PositionScaleChannel, model: UnitModel, isGridAxis: boolean): VgAxis[K] {\n const fieldDef = model.fieldDef(channel);\n\n if ((isGridAxis && AXIS_PROPERTY_TYPE[property] === 'main') ||\n (!isGridAxis && AXIS_PROPERTY_TYPE[property] === 'grid')) {\n // Do not apply unapplicable properties\n return undefined;\n }\n\n switch (property) {\n case 'scale':\n return model.scaleName(channel);\n case 'gridScale':\n return properties.gridScale(model, channel, isGridAxis);\n\n case 'domain':\n return properties.domain(property, specifiedAxis, isGridAxis, 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 'labels':\n return isGridAxis ? false : specifiedAxis.labels;\n case 'labelFlush':\n return properties.labelFlush(fieldDef, channel, specifiedAxis, isGridAxis);\n case 'labelOverlap': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType);\n }\n case 'minExtent': {\n return properties.minMaxExtent(specifiedAxis.minExtent, isGridAxis);\n }\n case 'maxExtent': {\n return properties.minMaxExtent(specifiedAxis.maxExtent, isGridAxis);\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 'ticks':\n return properties.ticks(property, specifiedAxis, isGridAxis, channel);\n case 'title':\n return getSpecifiedOrDefaultValue(specifiedAxis.title, properties.title(specifiedAxis.titleMaxLength, fieldDef, model.config));\n case 'values':\n return properties.values(specifiedAxis, model, fieldDef);\n case 'zindex':\n return getSpecifiedOrDefaultValue(specifiedAxis.zindex, properties.zindex(isGridAxis));\n }\n // Otherwise, return specified property.\n return isAxisProperty(property) ? specifiedAxis[property] : undefined;\n}\n", + "import {Axis} from '../../axis';\nimport {binToString} from '../../bin';\nimport {PositionScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {DateTime, dateTimeExpr, isDateTime} from '../../datetime';\nimport {FieldDef, title as fieldDefTitle} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {QUANTITATIVE} from '../../type';\nimport {contains, truncate} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {UnitModel} from '../unit';\n\n\nexport function domainAndTicks(property: 'domain' | 'ticks', specifiedAxis: Axis, isGridAxis: boolean, channel: PositionScaleChannel) {\n if (isGridAxis) {\n return false;\n }\n return specifiedAxis[property];\n}\n\nexport const domain = domainAndTicks;\nexport const ticks = domainAndTicks;\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, isGridAxis: boolean) {\n if (isGridAxis) {\n const gridChannel: PositionScaleChannel = channel === 'x' ? 'y' : 'x';\n if (model.getScaleComponent(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n }\n return undefined;\n}\n\nexport function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis, isGridAxis: boolean) {\n if (isGridAxis) {\n return undefined;\n }\n\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 minMaxExtent(specifiedExtent: number, isGridAxis: boolean) {\n if (isGridAxis) {\n // Always return 0 to make sure that `config.axis*.minExtent` and `config.axis*.maxExtent`\n // would not affect gridAxis\n return 0;\n } else {\n return specifiedExtent;\n }\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) {\n const vals = specifiedAxis.values;\n if (specifiedAxis.values && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return {signal: dateTimeExpr(dt, true)};\n });\n }\n\n if (!vals && fieldDef.bin && fieldDef.type === QUANTITATIVE) {\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 vals;\n}\n\nexport function zindex(isGridAxis: boolean) {\n if (isGridAxis) {\n // if grid is true, need to put layer on the back so that grid is behind marks\n return 0;\n }\n return 1; // otherwise return undefined and use Vega's default.\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';\n\nexport abstract class BaseConcatModel extends Model {\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, resolve: Resolve) {\n super(spec, parent, parentGivenName, config, 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), []);\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 {isConcatSpec, isFacetSpec, isLayerSpec, isRepeatSpec, isUnitSpec, LayoutSizeMixins, Spec} 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: Spec, 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 {Channel, isScaleChannel} from '../channel';\nimport {Config, ViewConfig} from '../config';\nimport {field, FieldDef, FieldRefOption, isScaleFieldDef, isTimeFieldDef, OrderFieldDef} from '../fielddef';\nimport {MarkConfig, MarkDef, TextConfig} from '../mark';\nimport {ScaleType} from '../scale';\nimport {TimeUnit} from '../timeunit';\nimport {formatExpression} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {contains, isArray} from '../util';\nimport {VgEncodeEntry, VgMarkConfig, VgSort} from '../vega.schema';\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 = field(fieldDef, {expr});\n const endField = field(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(field(fieldDef, {expr}), format)}`\n };\n } else if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC;\n return {\n signal: timeFormatExpression(field(fieldDef, {expr}), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale)\n };\n } else {\n return {\n signal: `''+${field(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): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n const _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n if (isUTCScale) {\n return `utcFormat(${field}, '${_format}')`;\n } else {\n return `timeFormat(${field}, '${_format}')`;\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(field(orderChannelDef, fieldRefOption));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n\nexport function titleMerger(v1: Explicit, v2: Explicit) {\n return {\n explicit: v1.explicit, // keep the old explicit\n value: v1.value === v2.value ?\n v1.value : // if title is the same just use one of them\n v1.value + ', ' + v2.value // join title with comma if different\n };\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", + "import {Config, initConfig, stripAndRedirectConfig} from '../config';\nimport * as vlFieldDef from '../fielddef';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, normalize, TopLevel, TopLevelExtendedSpec} 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\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: TopLevelExtendedSpec, 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 (components = intermediate that can be merged\n // and assembled easily)\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 and 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 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.0.json',\n ...(model.description ? {description: model.description} : {}),\n ...topLevelProperties,\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n data: [].concat(\n model.assembleSelectionData([]),\n // only assemble data in the root\n assembleRootData(model.component.data)\n ),\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 {Config} from '../config';\nimport * as log from '../log';\nimport {ConcatSpec, isVConcatSpec} 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: ConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, 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 public assembleLayout(): VgLayout {\n // TODO: allow customization\n return {\n padding: {row: 10, column: 10},\n offset: 10,\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 {AggregateOp} from '../../aggregate';\nimport {Channel, isScaleChannel} from '../../channel';\nimport {field, FieldDef} 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[field(fieldDef, {})] = true;\n dims[field(fieldDef, {binSuffix: 'end'})] = true;\n\n if (binRequiresRange(fieldDef, channel)) {\n dims[field(fieldDef, {binSuffix: 'range'})] = true;\n }\n } else {\n dims[field(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({...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(private dimensions: StringSet, private measures: Dict<{[key in AggregateOp]?: string}>) {\n super();\n }\n\n public static makeFromEncoding(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 if (fieldDef.aggregate) {\n if (fieldDef.aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = field(fieldDef, {aggregate: 'count'});\n } else {\n meas[fieldDef.field] = meas[fieldDef.field] || {};\n meas[fieldDef.field][fieldDef.aggregate] = field(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[fieldDef.field]['min'] = field(fieldDef, {aggregate: 'min'});\n meas[fieldDef.field]['max'] = field(fieldDef, {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(dims, meas);\n }\n\n public static makeFromTransform(t: AggregateTransform): AggregateNode {\n const dims = {};\n const meas = {};\n for(const s of t.aggregate) {\n if (s.op) {\n if (s.op === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = s.as || field(s);\n } else {\n meas[s.field] = meas[s.field] || {};\n meas[s.field][s.op] = s.as || field(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(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 {isUrlData} from '../../data';\nimport {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 {IdentifierNode} from './indentifier';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\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 } 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 AggregateNode ||\n node instanceof LookupNode ||\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): 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 data.sort((a, b) => (a.transform || []).length === 0 ? -1 : ((b.transform || []).length === 0 ? 1 : 0));\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 return data;\n}\n", + "import {BinParams, binToString} from '../../bin';\nimport {Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {field, FieldDef, normalizeBin} 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\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 = field(fieldDef, {expr: 'datum',});\n const endField = field(fieldDef, {expr: 'datum', binSuffix: 'end'});\n\n return {\n formulaAs: field(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 isModelParams(p: {model: Model} | {signal?: string, extentSignal?: string}): p is {model: Model} {\n return !!p['model'];\n}\n\nfunction getSignalsFromParams(\n params: {model: Model} | {signal?: string, extentSignal?: string},\n key: string\n) {\n if (isModelParams(params)) {\n const model = params.model;\n return {\n signal: model.getName(`${key}_bins`),\n extentSignal: model.getName(`${key}_extent`)\n };\n }\n return params;\n}\n\nfunction isBinTransform(t: FieldDef | BinTransform): t is BinTransform {\n return 'as' in t;\n}\n\nfunction createBinComponent(\n t: FieldDef | BinTransform,\n params: {model: Model} | {signal?: string, extentSignal?: string}\n) {\n let as: [string, string];\n\n if (isBinTransform(t)) {\n as = [t.as, `${t.as}_end`];\n } else {\n as = [field(t, {}), field(t, {binSuffix: 'end'})];\n }\n\n const bin = normalizeBin(t.bin, undefined) || {};\n const key = binKey(bin, t.field);\n const {signal, extentSignal} = getSignalsFromParams(params, 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(duplicate(this.bins));\n }\n\n constructor(private bins: Dict) {\n super();\n }\n\n public static makeBinFromEncoding(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(bins);\n }\n\n /**\n * Creates a bin node from BinTransform.\n * The optional parameter should provide\n */\n public static makeFromTransform(t: BinTransform, params: {model: Model} | {signal?: string, extentSignal?: string}) {\n const {key, binComponent} = createBinComponent(t, params);\n return new BinNode({\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 {CalculateTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\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(duplicate(this.transform));\n }\n\n constructor(private transform: CalculateTransform) {\n super();\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", + "\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(public readonly debugName?: string) { }\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(source: string, public readonly type: DataSourceType, private readonly refCounts: Dict) {\n super(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 {AggregateOp} from '../../aggregate';\nimport {COLUMN, ROW, ScaleChannel} from '../../channel';\nimport * as log from '../../log';\nimport {hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep, VgAggregateTransform, VgData} from '../../vega.schema';\nimport {FacetModel} from '../facet';\nimport {Model} from '../model';\nimport {assembleDomain, getFieldFromDomain} from '../scale/domain';\nimport {DataFlowNode} from './dataflow';\n\ntype ChildIndependentFieldsWithStep = {\n x?: string,\n y?: 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 columnFields: string[];\n private readonly columnName: string;\n\n private readonly rowFields: string[];\n private readonly rowName: string;\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(public readonly model: FacetModel, public readonly name: string, public data: string) {\n super();\n\n if (model.facet.column) {\n this.columnFields = [model.field(COLUMN)];\n this.columnName = model.getName('column_domain');\n if (model.fieldDef(COLUMN).bin) {\n this.columnFields.push(model.field(COLUMN, {binSuffix: 'end'}));\n }\n }\n\n if (model.facet.row) {\n this.rowFields = [model.field(ROW)];\n this.rowName = model.getName('row_domain');\n if (model.fieldDef(ROW).bin) {\n this.rowFields.push(model.field(ROW, {binSuffix: 'end'}));\n }\n }\n\n this.childModel = model.child;\n }\n\n get fields() {\n let fields: string[] = [];\n if (this.columnFields) {\n fields = fields.concat(this.columnFields);\n }\n if (this.rowFields) {\n fields = fields.concat(this.rowFields);\n }\n return fields;\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 let aggregateChildField: Partial = {};\n const childChannel = channel === 'row' ? 'y' : 'x';\n\n if (childIndependentFieldsWithStep[childChannel]) {\n if (crossedDataName) {\n aggregateChildField = {\n // If there is a crossed data, calculate max\n fields: [`distinct_${childIndependentFieldsWithStep[childChannel]}`],\n ops: ['max'],\n // Although it is technically a max, just name it distinct so it's easier to refer to it\n as: [`distinct_${childIndependentFieldsWithStep[childChannel]}`]\n };\n } else {\n aggregateChildField = {\n // If there is no crossed data, just calculate distinct\n fields: [childIndependentFieldsWithStep[childChannel]],\n ops: ['distinct']\n };\n }\n }\n\n return {\n name: channel === 'row' ? this.rowName : this.columnName,\n // Use data from the crossed one if it exist\n source: crossedDataName || this.data,\n transform: [{\n type: 'aggregate',\n groupby: channel === 'row' ? this.rowFields : this.columnFields,\n ...aggregateChildField\n }]\n };\n }\n\n public assemble() {\n const data: VgData[] = [];\n let crossedDataName = null;\n const childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep();\n\n if (this.columnName && this.rowName && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) {\n // Need to create a cross dataset to correctly calculate cardinality\n crossedDataName = `cross_${this.columnName}_${this.rowName}`;\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.columnFields.concat(this.rowFields),\n fields: fields,\n ops\n }]\n });\n }\n\n if (this.columnName) {\n data.push(this.assembleRowColumnData('column', crossedDataName, childIndependentFieldsWithStep));\n }\n\n if (this.rowName) {\n data.push(this.assembleRowColumnData('row', crossedDataName, childIndependentFieldsWithStep));\n }\n\n return data;\n }\n}\n", + "import {expression, Filter} from '../../filter';\nimport {LogicalOperand} from '../../logical';\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(this.model, duplicate(this.filter));\n }\n\n constructor(private readonly model: Model, private filter: LogicalOperand) {\n super();\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 {isScaleChannel} from '../../channel';\nimport {field as fieldRef, FieldDef} from '../../fielddef';\nimport {hasContinuousDomain, ScaleType} from '../../scale';\nimport {Dict, keys} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterInvalidNode extends DataFlowNode {\n public clone() {\n return new FilterInvalidNode({...this.fieldDefs});\n }\n\n constructor(private fieldDefs: Dict>) {\n super();\n }\n\n public static make(model: ModelWithField): FilterInvalidNode {\n if (model.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 // only automatically filter null for continuous domain since discrete domain scales can handle invalid values.\n if (hasContinuousDomain(scaleType) && !fieldDef.aggregate) {\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(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\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 {isCountingAggregateOp} from '../../aggregate';\nimport {isNumberFieldDef, isTimeFieldDef} from '../../fielddef';\nimport {isEqualFilter, isOneOfFilter, isRangeFilter} from '../../filter';\nimport * as log from '../../log';\nimport {forEachLeave} from '../../logical';\nimport {isCalculate, isFilter, Transform} from '../../transform';\nimport {accessPath, Dict, duplicate, keys, toSet} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {DataFlowNode} from './dataflow';\n\n\nfunction parseExpression(field: string, parse: string): string {\n const f = `datum${accessPath(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.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(duplicate(this.parse));\n }\n\n constructor(parse: Dict) {\n super();\n\n this._parse = parse;\n }\n\n public static make(model: Model) {\n const parse = {};\n const calcFieldMap = {};\n\n (model.transforms || []).forEach((transform: Transform) => {\n if (isCalculate(transform)) {\n calcFieldMap[transform.as] = true;\n } else if (isFilter(transform)) {\n forEachLeave(transform.filter, (filter) => {\n if (isEqualFilter(filter) || isRangeFilter(filter) || isOneOfFilter(filter)) {\n if (filter.timeUnit) {\n parse[filter.field] = 'date';\n }\n }\n });\n }\n }, {});\n\n if (isUnitModel(model) || isFacetModel(model)) {\n // Parse encoded fields\n model.forEachFieldDef(fieldDef => {\n if (isTimeFieldDef(fieldDef)) {\n parse[fieldDef.field] = 'date';\n } else if (isNumberFieldDef(fieldDef)) {\n if (calcFieldMap[fieldDef.field] || isCountingAggregateOp(fieldDef.aggregate)) {\n return;\n }\n parse[fieldDef.field] = 'number';\n }\n });\n }\n\n // Custom parse should override inferred parse\n const data = model.data;\n if (data && data.format && data.format.parse) {\n const p = data.format.parse;\n keys(p).forEach(field => {\n parse[field] = p[field];\n });\n }\n\n // We should not parse what has already been parsed in a parent\n const modelParse = model.component.data.ancestorParse;\n keys(modelParse).forEach(field => {\n if (parse[field] !== modelParse[field]) {\n log.warn(log.message.differentParse(field, parse[field], modelParse[field]));\n } else {\n delete parse[field];\n }\n });\n\n if (keys(parse).length === 0) {\n return null;\n }\n\n return new ParseNode(parse);\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 public assembleFormatParse() {\n return this._parse;\n }\n\n // format parse depends and produces all fields in its parse\n public producedFields() {\n return toSet(keys(this.parse));\n }\n\n public dependentFields() {\n return toSet(keys(this.parse));\n }\n\n public assembleTransforms(): VgFormulaTransform[] {\n return keys(this._parse).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: field\n };\n return formula;\n }).filter(t => t !== null);\n }\n}\n", + "import {SELECTION_ID} from '../../selection';\nimport {VgIdentifierTransform} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class IdentifierNode extends DataFlowNode {\n public clone() {\n return new IdentifierNode();\n }\n\n constructor() {\n super();\n }\n\n public producedFields() {\n return {[SELECTION_ID]: true};\n }\n\n public assemble(): VgIdentifierTransform {\n return {type: 'identifier', as: SELECTION_ID};\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(public readonly transform: LookupTransform, public readonly secondary: string) {\n super();\n }\n\n public static make(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(fromOutputName, 'lookup', model.component.data.outputNodeRefCounts);\n fromOutputNode.parent = fromSource;\n\n model.component.data.outputNodes[fromOutputName] = fromOutputNode;\n\n return new LookupNode(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 {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 * Start optimization path from the root. Useful for removing nodes.\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 {hasIntersection, keys} from '../../util';\nimport {DataFlowNode, OutputNode} from './dataflow';\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 nodes.\n * The reason is that we don't need subtrees that don't have any output nodes.\n */\nexport function removeUnusedSubtrees(node: DataFlowNode) {\n if (node instanceof OutputNode || node.numChildren() > 0) {\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 {isNumber, isString} from 'vega-util';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime, isDateTime} from '../../datetime';\nimport {isEqualFilter, isOneOfFilter, isRangeFilter} from '../../filter';\nimport * as log from '../../log';\nimport {isAggregate, isBin, isCalculate, isFilter, isLookup, isTimeUnit} 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 {IdentifierNode} from './indentifier';\nimport {DataComponent} from './index';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\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(model: Model) {\n let first: DataFlowNode = null;\n let node: DataFlowNode;\n let previous: DataFlowNode;\n let lookupCounter = 0;\n\n function insert(newNode: DataFlowNode) {\n if (!first) {\n // A parent may be inserted during node construction\n // (e.g., selection FilterNodes may add a TimeUnitNode).\n first = newNode.parent || newNode;\n } else if (newNode.parent) {\n previous.insertAsParentOf(newNode);\n } else {\n newNode.parent = previous;\n }\n\n previous = newNode;\n }\n\n model.transforms.forEach(t => {\n if (isCalculate(t)) {\n node = new CalculateNode(t);\n } else if (isFilter(t)) {\n // Automatically add a parse node for filters with filter objects\n const parse = {};\n const filter = t.filter;\n let val: string | number | boolean | DateTime = null;\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 (isEqualFilter(filter)) {\n val = filter.equal;\n } else if (isRangeFilter(filter)) {\n val = filter.range[0];\n } else if (isOneOfFilter(filter)) {\n val = (filter.oneOf || filter['in'])[0];\n } // else -- for filter expression, we can't infer anything\n\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 (keys(parse).length > 0) {\n const parseNode = new ParseNode(parse);\n insert(parseNode);\n }\n\n node = new FilterNode(model, t.filter);\n } else if (isBin(t)) {\n node = BinNode.makeFromTransform(t, {model});\n } else if (isTimeUnit(t)) {\n node = TimeUnitNode.makeFromTransform(t);\n } else if (isAggregate(t)) {\n node = AggregateNode.makeFromTransform(t);\n\n if (requiresSelectionId(model)) {\n insert(node);\n node = new IdentifierNode();\n }\n } else if (isLookup(t)) {\n node = LookupNode.make(model, t, lookupCounter++);\n } else {\n log.warn(log.message.invalidTransformIgnored(t));\n return;\n }\n\n insert(node);\n });\n\n const last = node;\n\n return {first, last};\n}\n\n/*\nDescription of the dataflow (http://asciiflow.com/):\n +--------+\n | Source |\n +---+----+\n |\n v\n Transforms\n(Filter, Calculate, ...)\n |\n v\n FormatParse\n |\n v\n Binning\n |\n v\n Timeunit\n |\n v\n +--+--+\n | Raw |\n +-----+\n |\n v\n Aggregate\n |\n v\n Stack\n |\n v\n Path Order\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 const root = parseRoot(model, model.component.data.sources);\n\n const outputNodes = model.component.data.outputNodes;\n const outputNodeRefCounts = model.component.data.outputNodeRefCounts;\n\n // the current head of the tree that we are appending to\n let head = root;\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) && !model.parent) {\n const ident = new IdentifierNode();\n ident.parent = head;\n head = ident;\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 const bin = BinNode.makeBinFromEncoding(model);\n if (bin) {\n bin.parent = head;\n head = bin;\n }\n }\n }\n\n if (model.transforms.length > 0) {\n const {first, last} = parseTransformArray(model);\n first.parent = head;\n head = last;\n }\n\n const parse = ParseNode.make(model);\n if (parse) {\n parse.parent = head;\n head = parse;\n }\n\n if (isUnitModel(model) || isFacetModel(model)) {\n\n if (!parentIsLayer) {\n const bin = BinNode.makeBinFromEncoding(model);\n if (bin) {\n bin.parent = head;\n head = bin;\n }\n }\n\n const tu = TimeUnitNode.makeFromEncoding(model);\n if (tu) {\n tu.parent = head;\n head = tu;\n }\n }\n\n // add an output node pre aggregation\n const rawName = model.getName(RAW);\n const raw = new OutputNode(rawName, RAW, outputNodeRefCounts);\n outputNodes[rawName] = raw;\n raw.parent = head;\n head = raw;\n\n if (isUnitModel(model)) {\n const agg = AggregateNode.makeFromEncoding(model);\n if (agg) {\n agg.parent = head;\n head = agg;\n\n if (requiresSelectionId(model)) {\n const ident = new IdentifierNode();\n ident.parent = head;\n head = ident;\n }\n }\n\n const stack = StackNode.make(model);\n if (stack) {\n stack.parent = head;\n head = stack;\n }\n }\n\n if (isUnitModel(model)) {\n const filter = FilterInvalidNode.make(model);\n if (filter) {\n filter.parent = head;\n head = filter;\n }\n }\n\n // output node for marks\n const mainName = model.getName(MAIN);\n const main = new OutputNode(mainName, MAIN, outputNodeRefCounts);\n outputNodes[mainName] = main;\n main.parent = head;\n head = main;\n\n // add facet marker\n let facetRoot = null;\n if (isFacetModel(model)) {\n const facetName = model.getName('facet');\n facetRoot = new FacetNode(model, facetName, main.getSource());\n outputNodes[facetName] = facetRoot;\n facetRoot.parent = head;\n head = facetRoot;\n }\n\n // add the format parse from this model so that children don't parse the same field again\n const ancestorParse = {...model.component.data.ancestorParse, ...(parse ? parse.parse : {})};\n\n return {\n ...model.component.data,\n outputNodes,\n outputNodeRefCounts,\n raw,\n main,\n facetRoot,\n ancestorParse\n };\n}\n", + "import {Data, DataFormat, DataFormatType, isInlineData, isNamedData, isUrlData} from '../../data';\nimport {contains, duplicate, hash, keys} 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();\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', '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._name = data.name;\n this._data = {};\n }\n\n if (!isNamedData(data) && 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 {isArray} from 'vega-util';\nimport {field, FieldDef} from '../../fielddef';\nimport {StackOffset} from '../../stack';\nimport {duplicate} from '../../util';\nimport {VgSort, VgTransform} from '../../vega.schema';\nimport {sortParams} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\n\nfunction getStackByFields(model: UnitModel): string[] {\n return model.stack.stackBy.reduce((fields, by) => {\n const fieldDef = by.fieldDef;\n\n const _field = field(fieldDef);\n if (_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\nexport interface StackComponent {\n /**\n * Faceted field.\n */\n facetby: string[];\n\n dimensionFieldDef: FieldDef;\n\n /**\n * Stack measure's field\n */\n field: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n */\n stackby: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n */\n sort: VgSort;\n\n /** Mode for stacking marks. */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking.\n */\n impute: boolean;\n}\n\nexport class StackNode extends DataFlowNode {\n private _stack: StackComponent;\n\n public clone() {\n return new StackNode(duplicate(this._stack));\n }\n\n constructor(stack: StackComponent) {\n super();\n\n this._stack = stack;\n }\n\n public static make(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 (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\n return new StackNode({\n dimensionFieldDef,\n field: model.field(stackProperties.fieldChannel),\n facetby: [],\n stackby,\n sort,\n offset: stackProperties.offset,\n impute: stackProperties.impute,\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.field] = 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 const out = {};\n\n out[this._stack.field + '_start'] = true;\n out[this._stack.field + '_end'] = true;\n\n return out;\n }\n\n private getGroupbyFields() {\n const {dimensionFieldDef, impute} = 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 [field(dimensionFieldDef, {binSuffix: 'mid'})];\n }\n return [\n // For binned group by field without impute, we need both bin (start) and bin_end\n field(dimensionFieldDef, {}),\n field(dimensionFieldDef, {binSuffix: 'end'})\n ];\n }\n return [field(dimensionFieldDef)];\n }\n return [];\n }\n\n public assemble(): VgTransform[] {\n const transform: VgTransform[] = [];\n\n const {facetby, field: stackField, dimensionFieldDef, impute, offset, sort, stackby} = this._stack;\n\n // Impute\n if (impute && dimensionFieldDef) {\n const dimensionField = dimensionFieldDef ? field(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 field(dimensionFieldDef, {expr: 'datum'}) +\n '+' +\n field(dimensionFieldDef, {expr: 'datum', binSuffix: 'end'}) +\n ')/2',\n as: dimensionField\n });\n }\n\n transform.push({\n type: 'impute',\n field: stackField,\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: stackField,\n sort,\n as: [\n stackField + '_start',\n stackField + '_end'\n ],\n offset\n });\n\n return transform;\n }\n}\n", + "import {field} 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(duplicate(this.formula));\n }\n\n constructor(private formula: Dict) {\n super();\n }\n\n public static makeFromEncoding(model: ModelWithField) {\n const formula = model.reduceFieldDef((timeUnitComponent: TimeUnitComponent, fieldDef) => {\n if (fieldDef.timeUnit) {\n const f = field(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(formula);\n }\n\n public static makeFromTransform(t: TimeUnitTransform) {\n return new TimeUnitNode({\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 {AggregateOp} from '../aggregate';\nimport {Channel, COLUMN, ROW, ScaleChannel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {field, FieldDef, normalize, title as fieldDefTitle} from '../fielddef';\nimport * as log from '../log';\nimport {hasDiscreteDomain} from '../scale';\nimport {FacetSpec} from '../spec';\nimport {contains} from '../util';\nimport {isVgRangeStep, RowCol, VgAxis, VgData, VgLayout, VgMarkGroup, VgScale, VgSignal} from '../vega.schema';\nimport {buildModel} from './buildmodel';\nimport {assembleFacetData} from './data/assemble';\nimport {parseData} from './data/parse';\nimport {getHeaderType, HeaderChannel, HeaderComponent} from './layout/header';\nimport {parseChildrenLayoutSize} from './layoutsize/parse';\nimport {Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInFacet} from './repeater';\nimport {parseGuideResolve} from './resolve';\nimport {assembleScalesForModel} from './scale/assemble';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\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: FacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, 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 = 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 mainAxis = axisComponent.main;\n const headerType = getHeaderType(mainAxis.get('orient'));\n layoutHeader[headerType] = layoutHeader[headerType] ||\n [this.makeHeaderComponent(headerChannel, false)];\n\n // LayoutHeader no longer keep track of property precedence, thus let's combine.\n layoutHeader[headerType][0].axes.push(mainAxis.combine() as VgAxis);\n delete axisComponent.main;\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 getLayoutBandMixins(headerType: 'header' | 'footer'): {\n headerBand?: RowCol,\n footerBand?: RowCol\n } {\n const bandMixins = {};\n\n const bandType = headerType === 'header' ? 'headerBand' : 'footerBand';\n\n for (const channel of ['row', 'column'] as ('row' | 'column')[]) {\n const layoutHeaderComponent = this.component.layoutHeaders[channel];\n const headerComponent = layoutHeaderComponent[headerType];\n if (headerComponent && headerComponent[0]) {\n const sizeType = channel === 'row' ? 'height' : 'width';\n\n if (!this.child.component.layoutSize.get(sizeType)) {\n // If facet child does not have size signal, then apply headerBand\n bandMixins[bandType] = bandMixins[bandType] || {};\n bandMixins[bandType][channel] = 0.5;\n }\n }\n }\n return bandMixins;\n }\n\n public assembleLayout(): 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 padding: {row: 10, column: 10},\n ...this.getLayoutBandMixins('header'),\n ...this.getLayoutBandMixins('footer'),\n\n // TODO: support offset for rowHeader/rowFooter/rowTitle/columnHeader/columnFooter/columnTitle\n offset: 10,\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: field(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 if (this.child instanceof FacetModel) {\n if (this.child.channelHasField('column')) {\n fields.push(field(this.child.facet.column));\n ops.push('distinct');\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 } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n }\n return fields.length ? {fields, ops} : undefined;\n }\n\n public assembleMarks(): VgMarkGroup[] {\n const {child, facet} = 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 hasRow = this.channelHasField(ROW);\n const hasColumn = this.channelHasField(COLUMN);\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n\n const aggregateMixins: any = {};\n if (hasRow && hasColumn) {\n aggregateMixins.aggregate = {cross: true};\n }\n const cardinalityAggregateForChild = this.getCardinalityAggregateForChild();\n if (cardinalityAggregateForChild) {\n aggregateMixins.aggregate = {\n ...aggregateMixins.aggregate,\n ...cardinalityAggregateForChild\n };\n }\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: {\n name: facetRoot.name,\n data: facetRoot.data,\n groupby: [].concat(\n hasRow ? [this.field(ROW)] : [],\n hasColumn ? [this.field(COLUMN)] : []\n ),\n ...aggregateMixins\n }\n },\n sort: {\n field: [].concat(\n hasRow ? [this.field(ROW, {expr: 'datum',})] : [],\n hasColumn ? [this.field(COLUMN, {expr: 'datum'})] : []\n ),\n order: [].concat(\n hasRow ? [ (facet.row.sort) || 'ascending'] : [],\n hasColumn ? [ (facet.column.sort) || 'ascending'] : []\n )\n },\n ...(data.length > 0 ? {data: data} : {}),\n ...(layoutSizeEncodeEntry ? {encode: {update: layoutSizeEncodeEntry}} : {}),\n ...child.assembleGroup()\n };\n\n return [markGroup];\n }\n\n protected getMapping() {\n return this.facet;\n }\n}\n", + "import {Config} from '../config';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayerSpec, LayoutSizeMixins} 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: LayerSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean) {\n\n super(spec, parent, parentGivenName, config, 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), []);\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", + "/**\n * Utility for generating row / column headers\n */\nimport {FacetFieldDef} from '../../facet';\nimport {field} from '../../fielddef';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis} 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 getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent) {\n if (headerCmpt) {\n let title = null;\n if (layoutHeader.facetFieldDef && headerCmpt.labels) {\n const {facetFieldDef} = layoutHeader;\n const {header = {}} = facetFieldDef;\n const {format, labelAngle} = header;\n\n const update = {\n ...(\n labelAngle ? {angle: {value: labelAngle}} : {}\n )\n\n // TODO(https://github.com/vega/vega-lite/issues/2446): apply label* (e.g, labelAlign, labelBaseline) here\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 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: {\n field: field(layoutHeader.facetFieldDef, {expr: 'datum'}),\n order: (layoutHeader.facetFieldDef.header && layoutHeader.facetFieldDef.sort) || 'ascending'\n }\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", + "\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 {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 {\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 * as stringify from 'json-stable-stringify';\n\nimport {flatten, keys, 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 {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';\nimport {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE} from '../../channel';\nimport {FieldDef, FieldDefWithCondition, hasConditionalValueDef, isTimeFieldDef, isValueDef, MarkPropFieldDef, ValueDefWithCondition} from '../../fielddef';\nimport {AREA, BAR, CIRCLE, FILL_STROKE_CONFIG, LINE, POINT, SQUARE, TEXT, TICK} from '../../mark';\nimport {ScaleType} from '../../scale';\nimport {keys, without} from '../../util';\nimport {LegendType} 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) {\n if (type === 'gradient') {\n return undefined;\n }\n\n let symbols:any = {};\n const mark = model.mark();\n\n switch (mark) {\n case BAR:\n case TICK:\n case TEXT:\n symbols.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n symbols.shape = {value: mark};\n break;\n case POINT:\n case LINE:\n case AREA:\n // use default circle\n break;\n }\n\n const filled = model.markDef.filled;\n\n let config = channel === COLOR ?\n /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */\n without(FILL_STROKE_CONFIG, [ filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) :\n /* For other legend, no need to omit. */\n FILL_STROKE_CONFIG;\n\n config = without(config, ['strokeDash', 'strokeDashOffset']);\n\n applyMarkConfig(symbols, model, config);\n\n if (channel !== COLOR) {\n const colorMixins = mixins.color(model);\n\n // If there are field for fill or stroke, remove them as we already apply channels.\n if (colorMixins.fill && (colorMixins.fill['field'] || colorMixins.fill['value'] === 'transparent')) {\n delete colorMixins.fill;\n }\n if (colorMixins.stroke && (colorMixins.stroke['field'] || colorMixins.stroke['value'] === 'transparent')) {\n delete colorMixins.stroke;\n }\n symbols = {...symbols, ...colorMixins};\n }\n\n if (channel !== SHAPE) {\n const shapeDef = model.encoding.shape;\n if (isValueDef(shapeDef)) {\n symbols.shape = {value: shapeDef.value};\n }\n }\n\n if (channel !== OPACITY) {\n const opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n symbols.opacity = {value: opacity};\n }\n }\n\n symbols = {...symbols, ...symbolsSpec};\n\n return keys(symbols).length > 0 ? symbols : undefined;\n}\n\nexport function gradient(fieldDef: FieldDef, gradientSpec: any, model: UnitModel, channel: Channel, type: LegendType) {\n let gradient:any = {};\n\n if (type === 'gradient') {\n const opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n gradient.opacity = {value: opacity};\n }\n }\n\n gradient = {...gradient, ...gradientSpec};\n return keys(gradient).length > 0 ? gradient : 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 labels: any = {};\n\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n labelsSpec = {\n text: {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale)\n },\n ...labelsSpec,\n };\n }\n\n labels = {...labels, ...labelsSpec};\n\n return keys(labels).length > 0 ? labels : undefined;\n}\n\nfunction getOpacityValue(opacityDef: FieldDefWithCondition> | ValueDefWithCondition>): number {\n if (isValueDef(opacityDef)) {\n if (hasConditionalValueDef(opacityDef)) {\n const values = isArray(opacityDef.condition) ? opacityDef.condition.map(c => c.value) : [opacityDef.condition.value];\n return Math.max.apply(null, [opacityDef.value].concat(values));\n } else {\n return opacityDef.value as number;\n }\n }\n return undefined;\n}\n", + "import {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE, SIZE} from '../../channel';\nimport {title as fieldDefTitle} from '../../fielddef';\nimport {Legend, LEGEND_PROPERTIES, VG_LEGEND_PROPERTIES} from '../../legend';\nimport {deleteNestedProperty, keys} from '../../util';\nimport {VgLegend, VgLegendEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, numberFormat, titleMerger} from '../common';\nimport {isUnitModel, Model} from '../model';\nimport {parseGuideResolve} from '../resolve';\nimport {Explicit, makeImplicit} from '../split';\nimport {defaultTieBreaker, 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 return [COLOR, SIZE, SHAPE, OPACITY].reduce(function(legendComponent, channel) {\n if (model.legend(channel)) {\n legendComponent[channel] = parseLegendForChannel(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: Channel): 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 SIZE:\n return {size: model.scaleName(SIZE)};\n case SHAPE:\n return {shape: model.scaleName(SHAPE)};\n case OPACITY:\n return {opacity: model.scaleName(OPACITY)};\n }\n return null;\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 = property === 'values' ?\n !!legend.values : // specified legend.values is already respected, but may get transformed.\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 value = encode[part] ?\n // TODO: replace legendCmpt with type is sufficient\n encode[part](fieldDef, legendEncoding[part], model, channel, legendCmpt.get('type')) : // apply rule\n legendEncoding[part]; // 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 return getSpecifiedOrDefaultValue(specifiedLegend.title, fieldDefTitle(fieldDef, model.config));\n case 'values':\n return properties.values(specifiedLegend);\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) {\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 titleMerger(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, COLOR} from '../../channel';\nimport {DateTime, dateTimeExpr, isDateTime} from '../../datetime';\nimport {Legend} from '../../legend';\nimport {isBinScale, ScaleType} from '../../scale';\nimport {Type} from '../../type';\nimport {contains} from '../../util';\n\nexport function values(legend: Legend) {\n const vals = legend.values;\n if (vals && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return {signal: dateTimeExpr(dt, true)};\n });\n }\n return vals;\n}\n\nexport function type(type: Type, channel: Channel, scaleType: ScaleType): 'gradient' {\n if (\n channel === COLOR && (\n (type === 'quantitative' && !isBinScale(scaleType)) ||\n (type === 'temporal' && contains(['time', 'utc'], scaleType))\n )\n ) {\n return 'gradient';\n }\n return undefined;\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.markDefProperties(model.markDef),\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', 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 {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {VgValueRef} from '../../vega.schema';\nimport {isVgRangeStep, VgEncodeEntry} 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 const stack = model.stack;\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...x(model, stack),\n ...y(model, stack),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model)\n };\n }\n};\n\nfunction x(model: UnitModel, stack: StackProperties): VgEncodeEntry {\n const {config, width} = model;\n const orient = model.markDef.orient;\n const sizeDef = model.encoding.size;\n\n const xDef = model.encoding.x;\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') {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\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'), config.bar.binSpacing, 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(xScaleName, xScale, config)\n );\n }\n}\n\nfunction y(model: UnitModel, stack: StackProperties) {\n const {config, encoding, height} = model;\n const orient = model.markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const yScaleName = model.scaleName(Y);\n const yScale = model.getScaleComponent(Y);\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical') {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\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'), config.bar.binSpacing, 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(yScaleName, yScale, config)\n );\n }\n}\n\nfunction defaultSizeRef(scaleName: string, scale: ScaleComponent, config: Config): VgValueRef {\n if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n }\n\n 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.band(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n }\n if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n return {value: 20};\n}\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 {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 || getMarkConfig('opacity', markDef, config);\n if (specifiedOpacity === undefined) {\n markDef.opacity = defaultOpacity(markDef.type, encoding);\n }\n\n const specifiedFilled = markDef.filled;\n if (specifiedFilled === undefined) {\n markDef.filled = filled(markDef, config);\n }\n return markDef;\n}\n\nfunction defaultOpacity(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 RULE:\n case BAR:\n case AREA:\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 /* tslint:disable */\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 if (!(mark === LINE && encoding.order)) {\n // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots.\n log.warn(log.message.unclearOrientContinuous(mark));\n }\n return 'vertical';\n } else {\n // For Discrete x Discrete case, return undefined.\n log.warn(log.message.unclearOrientDiscreteOrEmpty(mark));\n return undefined;\n }\n }\n return 'vertical';\n}\n\n", + "import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n })\n };\n }\n};\n", + "import {isArray} from 'vega-util';\nimport {MAIN} from '../../data';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {field, getFieldDef} from '../../fielddef';\nimport {AREA, LINE} 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 {line} 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: {[type: string]: MarkCompiler} = {\n area: area,\n bar: bar,\n line: line,\n point: point,\n text: text,\n tick: tick,\n rect: rect,\n rule: rule,\n circle: circle,\n square: square\n};\n\n\nexport function parseMarkGroup(model: UnitModel): any[] {\n if (contains([LINE, AREA], model.mark())) {\n return parsePathMark(model);\n } else {\n return parseNonPathMark(model);\n }\n}\n\nconst FACETED_PATH_PREFIX = 'faceted_path_';\n\nfunction parsePathMark(model: UnitModel) {\n const mark = model.mark();\n const details = pathGroupingFields(model.encoding);\n\n const clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model);\n const style = getStyles(model.markDef);\n const sort = getPathSort(model);\n\n const pathMarks: any = [\n {\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style? {style} : {}),\n ...(sort? {sort} : {}),\n // If has subfacet for line/area group, need to use faceted data from below.\n // FIXME: support sorting path order (in connected scatterplot)\n from: {data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + model.requestDataName(MAIN)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n }\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 getPathSort(model: UnitModel) {\n if (model.mark() === 'line' && model.channelHasField('order')) {\n // For only line, sort by the order field if it is specified.\n return sortParams(model.encoding.order, {expr: 'datum'});\n } else {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannel: 'x' | 'y' = model.markDef.orient === 'horizontal' ? 'y' : 'x';\n const s = model.sort(dimensionChannel);\n const sortField = isSortField(s) ?\n field({\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 model.field(dimensionChannel, {\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 sortField ?\n {\n field: sortField,\n order: 'descending'\n } :\n undefined;\n }\n}\n\nfunction parseNonPathMark(model: UnitModel) {\n const mark = model.mark();\n\n const style = getStyles(model.markDef);\n const clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model);\n\n const marks: any[] = []; // TODO: vgMarks\n\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n marks.push({\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style? {style} : {}),\n from: {data: model.requestDataName(MAIN)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n });\n\n return marks;\n}\n\n/**\n * Returns list of path grouping fields\n * that the model's spec contains.\n */\nexport function pathGroupingFields(encoding: Encoding): string[] {\n return keys(encoding).reduce((details, channel) => {\n switch (channel) {\n // x, y, x2, y2, order, tooltip, href, cursor should not cause lines to group\n case 'x':\n case 'y':\n case 'order':\n case 'tooltip':\n case 'x2':\n case 'y2':\n // TODO: case 'href', 'cursor':\n\n // text, shape, shouldn't be a part of line/area\n case 'text':\n case 'shape':\n return details;\n\n case 'detail':\n const channelDef = encoding[channel];\n if (channelDef) {\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (!fieldDef.aggregate) {\n details.push(field(fieldDef, {}));\n }\n });\n }\n return details;\n case 'color':\n case 'size':\n case 'opacity':\n // TODO strokeDashOffset:\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && !fieldDef.aggregate) {\n details.push(field(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 {isArray} from 'vega-util';\nimport {NONPOSITION_SCALE_CHANNELS} from '../../channel';\nimport {ChannelDef, FieldDef, getFieldDef, isValueDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport * as util from '../../util';\nimport {VG_MARK_CONFIGS, VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {predicate} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport * as ref from './valueref';\n\n\nexport function color(model: UnitModel) {\n const config = model.config;\n const filled = model.markDef.filled;\n const vgChannel = filled ? 'fill' : 'stroke';\n const e = nonPosition('color', model, {\n vgChannel,\n // Mark definition has higher predecence than config;\n // fill/stroke has higher precedence than color.\n defaultValue: model.markDef[vgChannel] ||\n model.markDef.color ||\n getMarkConfig(vgChannel, model.markDef, config) ||\n getMarkConfig('color', model.markDef, config)\n });\n\n // If there is no fill, always fill symbols\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) {\n e.fill = {value: 'transparent'};\n }\n return e;\n}\n\nexport function markDefProperties(mark: MarkDef, ignoreOrient?: boolean) {\n return VG_MARK_CONFIGS.reduce((m, prop) => {\n if (mark[prop] && (!ignoreOrient || prop !== 'orient')) {\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\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 // TODO: refactor how we refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\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 */\nfunction 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 return {\n test: predicate(model, c.selection),\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 text(model: UnitModel, channel: 'text' | 'tooltip' = 'text') {\n const channelDef = model.encoding[channel];\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) {\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 log.warn(log.message.cannotUseSizeFieldWithBandSize(channel));\n // TODO: apply size to band and set scale range to some values between 0-1.\n // return {\n // ...centeredBandPositionMixins,\n // ...bandSize('size', model, {vgChannel: sizeChannel})\n // };\n } else if (isValueDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\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.band(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 * 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, stack} = model;\n const valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.getScaleComponent(channel), stack, defaultRef);\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, markDef, stack} = model;\n channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2');\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n\n const valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.getScaleComponent(baseChannel), stack, defaultRef);\n return {[channel]: valueRef};\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.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n ...mixins.nonPosition('opacity', model),\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 {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...x(model),\n ...y(model),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction x(model: UnitModel) {\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\nfunction y(model: UnitModel) {\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\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) {\n // if we have neither x or y, show nothing\n return {};\n }\n\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)),\n ...mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)),\n ...mixins.pointPosition2(model, 'zeroOrMax'),\n\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's rule size is strokeWidth\n })\n };\n }\n};\n", + "import {X} from '../../channel';\nimport {Config} from '../../config';\nimport {channelHasField, Encoding} from '../../encoding';\nimport {ChannelDef, isFieldDef} from '../../fielddef';\nimport {MarkDef} from '../../mark';\nimport {QUANTITATIVE} from '../../type';\nimport {VgValueRef} 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\nexport const text: MarkCompiler = {\n vgMark: 'text',\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding, height} = model;\n const textDef = encoding.text;\n\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, xDefault(config, textDef)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.text(model),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(model.markDef, encoding, config))\n };\n }\n};\n\nfunction xDefault(config: Config, textDef: ChannelDef): VgValueRef {\n if (isFieldDef(textDef) && textDef.type === QUANTITATIVE) {\n return {field: {group: 'width'}, offset: -5};\n }\n // TODO: allow this to fit (Be consistent with ref.midX())\n return {value: config.scale.textXRangeStep / 2};\n}\n\nfunction align(markDef: MarkDef, encoding: Encoding, config: Config) {\n const align = markDef.align || getMarkConfig('align', markDef, config);\n if (align === undefined) {\n return channelHasField(encoding, X) ? 'center' : 'right';\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.markDefProperties(model.markDef, true),\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: config.tick.thickness},\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config} = model;\n const orient = model.markDef.orient;\n const scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y');\n\n 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", + "/**\n * Utility files for producing Vega ValueRef for marks\n */\nimport {Channel, X, X2, Y, Y2} from '../../channel';\nimport {Config} from '../../config';\nimport {\n ChannelDef,\n ChannelDefWithCondition,\n field,\n FieldDef,\n FieldRefOption,\n isFieldDef,\n isValueDef,\n TextFieldDef,\n} from '../../fielddef';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {contains} 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 stackable x or y\n */\nexport function stackable(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): 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 stackable x2 or y2\n */\nexport function stackable2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): 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 * 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 const ref: VgValueRef = {\n scale: scaleName,\n field: field(fieldDef, opt),\n };\n if (mixins) {\n return {\n ...ref,\n ...mixins\n };\n }\n return ref;\n}\n\nexport function band(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}\", ${field(fieldDef, {expr: 'datum'})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${field(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(channel: Channel, channelDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties,\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax',): 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 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 } else {\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n }\n } else if (isValueDef(channelDef)) {\n return {value: channelDef.value};\n } else {\n return undefined;\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMinX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMinY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n } else if (defaultRef === 'zeroOrMax') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMaxX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMaxY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n }\n return 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\nfunction zeroOrMinX(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the x-axis\n return {value: 0};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxX(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n return {field: {group: 'width'}};\n}\n\nfunction zeroOrMinY(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {field: {group: 'height'}};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxY(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {value: 0};\n}\n", + "import {isString} from 'vega-util';\n\nimport {Channel, isChannel, isScaleChannel, ScaleChannel, SingleDefChannel} from '../channel';\nimport {Config} from '../config';\nimport {Data, DataSourceType} from '../data';\nimport {forEach, reduce} from '../encoding';\nimport {ChannelDef, field, FieldDef, FieldRefOption, getFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {Resolve} from '../resolve';\nimport {hasDiscreteDomain} from '../scale';\nimport {BaseSpec} from '../spec';\nimport {extractTitleConfig, TitleParams} from '../title';\nimport {normalizeTransform, Transform} from '../transform';\nimport {contains, Dict, keys, varName} from '../util';\nimport {\n isVgRangeStep,\n VgAxis,\n VgData,\n VgEncodeEntry,\n VgLayout,\n VgLegend,\n VgMarkGroup,\n VgSignal,\n VgSignalRef,\n VgTitle,\n} from '../vega.schema';\nimport {assembleAxes} from './axis/assemble';\nimport {AxisComponentIndex} from './axis/component';\nimport {ConcatModel} from './concat';\nimport {DataComponent} from './data/index';\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {getHeaderGroup, getTitleGroup, HEADER_CHANNELS, HEADER_TYPES, LayoutHeaderComponent} from './layout/header';\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 {RepeatModel} from './repeat';\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/**\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 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\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\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected layoutSizeNameMap: NameMapInterface;\n\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, resolve: Resolve) {\n this.parent = parent;\n this.config = config;\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.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\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 ancestorParse: parent ? {...parent.component.data.ancestorParse} : {}\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 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.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections.\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 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 abstract assembleLayout(): VgLayout;\n\n public abstract assembleLayoutSignals(): VgSignal[];\n\n public assembleHeaderMarks(): VgMarkGroup[] {\n const {layoutHeaders} = this.component;\n const 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 const layoutHeader = layoutHeaders[channel];\n for (const headerType of HEADER_TYPES) {\n if (layoutHeader[headerType]) {\n for (const header of layoutHeader[headerType]) {\n const headerGroup = getHeaderGroup(this, channel, headerType, layoutHeader, header);\n if (headerGroup) {\n headerMarks.push(headerGroup);\n }\n }\n }\n }\n }\n return headerMarks;\n }\n\n public abstract assembleMarks(): VgMarkGroup[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return assembleAxes(this.component.axes);\n }\n\n public assembleLegends(): VgLegend[] {\n return assembleLegends(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 fieldName = getFieldFromDomain(domain);\n if (fieldName) {\n const fieldRef = field({aggregate: 'distinct', field: fieldName}, {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 /**\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 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 * 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(varName: string, origName: string): SelectionComponent {\n let sel = this.component.selection[varName];\n if (!sel && this.parent) {\n sel = this.parent.getSelectionComponent(varName, 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 field(channel: SingleDefChannel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (!fieldDef) {\n return undefined;\n }\n\n return field(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", + "\nimport {Config} from '../config';\nimport * as log from '../log';\nimport {Repeat} from '../repeat';\nimport {RepeatSpec} 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: RepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, 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: RepeatSpec, 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 public assembleLayout(): VgLayout {\n // TODO: allow customization\n return {\n padding: {row: 10, column: 10},\n offset: 10,\n columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1,\n bounds: 'full',\n align: 'all'\n };\n }\n}\n", + "import {Encoding} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {Field, FieldDef, hasConditionalFieldDef, isConditionalDef, isFieldDef, isRepeatRef, ValueDef} from '../fielddef';\nimport {ChannelDef, ScaleFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {isSortField} from '../sort';\nimport {isArray} from '../util';\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 {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 {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 = Partial>;\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 {SHARED_DOMAIN_OP_INDEX} from '../../aggregate';\nimport {binToString} from '../../bin';\nimport {isScaleChannel, ScaleChannel} from '../../channel';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime, dateTimeExpr, isDateTime} from '../../datetime';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Domain, hasDiscreteDomain, isBinScale, isSelectionDomain, ScaleConfig, ScaleType} from '../../scale';\nimport {isSortField, SortField} from '../../sort';\nimport * as util from '../../util';\nimport {\n isDataRefDomain,\n VgDataRef,\n VgDomain,\n VgFieldRefUnionDomain,\n VgNonUnionDomain,\n VgSortField,\n VgUnionSortField\n} from '../../vega.schema';\nimport {isDataRefUnionedDomain, isFieldRefUnionDomain} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\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 + JSON.stringify(specifiedDomain)\n }, true);\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 // FIXME: Arvind -- Please revise logic for merging selectionDomain / domainRaw\n\n let domains: VgNonUnionDomain[];\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 }\n\n if (isFacetModel(model)) {\n domains.forEach((domain) => {\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 localScaleComponents[channel].domains = domains;\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 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 if (fieldDef.bin) {\n log.warn(log.message.conflictedDomain(channel));\n } else {\n if (isDateTime(domain[0])) {\n return (domain as DateTime[]).map((dt) => {\n return {signal: `{data: ${dateTimeExpr(dt, true)}}`};\n });\n }\n return [domain];\n }\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.field(channel, {suffix: 'start'})\n }, {\n data,\n field: model.field(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 return [{\n data,\n field: model.field(channel, {aggregate: 'min'})\n }, {\n data,\n field: model.field(channel, {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.field(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.field(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 // 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.field(channel, {})\n }, {\n data,\n field: model.field(channel, {binSuffix: 'end'})\n }];\n } else {\n // TODO: use bin_mid\n return [{\n data: model.requestDataName(MAIN),\n field: model.field(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.field(channel),\n sort: sort\n }];\n } else {\n return [{\n data: model.requestDataName(MAIN),\n field: model.field(channel)\n }];\n }\n}\n\n\nexport function domainSort(model: UnitModel, channel: ScaleChannel, scaleType: ScaleType): true | SortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const sort = model.sort(channel);\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n return sort;\n }\n\n if (sort === 'descending') {\n return {\n op: 'min',\n field: model.field(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) && util.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) && util.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 util.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 {SCALE_CHANNELS, ScaleChannel} from '../../channel';\nimport {FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../../fielddef';\nimport {\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES,\n Scale,\n scaleCompatible,\n ScaleType,\n scaleTypePrecedence,\n} from '../../scale';\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} = model;\n const mark = model.mark();\n\n return SCALE_CHANNELS.reduce((scaleComponents: ScaleComponentIndex, channel: ScaleChannel) => {\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'] || {}; // 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) {\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 scaleType = scaleTypeWithExplicitIndex[channel];\n const childScaleType = child.component.scales[channel].getWithExplicit('type');\n\n if (scaleType) {\n if (scaleCompatible(scaleType.value, childScaleType.value)) {\n // merge scale component if type are compatible\n scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(\n scaleType, 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 {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef} 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 {SortField, SortOrder} from '../../sort';\nimport {keys} from '../../util';\nimport * as util from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponent, 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 sort = model.sort(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, sort,\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: FieldDef, sort: SortOrder | SortField,\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, sort);\n case 'zero':\n return zero(channel, fieldDef, specifiedDomain);\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(padding: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (padding !== 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(padding: number, channel: Channel, scaleType: ScaleType, paddingInner: number, scaleConfig: ScaleConfig) {\n if (padding !== 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 paddingInner / 2;\n }\n }\n return undefined;\n}\n\nexport function reverse(scaleType: ScaleType, sort: SortOrder | SortField) {\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) {\n // By default, 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 if no custom domain is provided.\n // (For binning, we should not include zero by default because binning are calculated without zero.\n // Similar, 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 && !fieldDef.bin && util.contains([X, Y], channel)) {\n return true;\n }\n return false;\n}\n", + "import {isNumber} from 'vega-util';\n\nimport {Channel, COLOR, OPACITY, SCALE_CHANNELS, ScaleChannel, SHAPE, SIZE, 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 if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' ? '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 '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 // TODO(#1168): make max size scale based on rangeStep / overall plot size\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 '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, isScaleChannel, rangeType} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, ScaleConfig, ScaleType} from '../../scale';\nimport {hasDiscreteDomain} from '../../scale';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {contains} from '../../util';\n\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 (!fieldDefMatchScaleType(specifiedType, fieldDef)) {\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 (channel === 'color' || 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 (mark === 'rect') {\n // The rect mark should fit into a band.\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 (channel === 'color') {\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 (channel === 'color') {\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\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function fieldDefMatchScaleType(specifiedType: ScaleType, fieldDef: FieldDef):boolean {\n const type: Type = fieldDef.type;\n if (contains([Type.ORDINAL, Type.NOMINAL], type)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (type === Type.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType);\n } else if (type === Type.QUANTITATIVE) {\n if (fieldDef.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", + "import {X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {hasContinuousDomain, isBinScale} from '../../scale';\nimport {keys, stringValue} 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] = {value: stroke[k]};\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 ...vgStroke\n },\n update: update\n }\n });\n }\n};\nexport {interval as default};\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 {accessPath, stringValue} from '../../util';\nimport {SelectionCompiler, TUPLE, unitName} from './selection';\nimport nearest from './transforms/nearest';\n\n\nconst multi:SelectionCompiler = {\n predicate: 'vlMulti',\n scaleDomain: 'vlMultiDomain',\n\n signals: function(model, selCmpt) {\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 `[${datum}${accessPath(model.field(channel, {}))}, ` +\n `${datum}${accessPath(model.field(channel, {binSuffix: 'end'}))}]`) :\n `${datum}${accessPath(p.field)}`;\n }).join(', ');\n\n // Only add a discrete selection to the store if a datum is present _and_\n // the interaction isn't occuring 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\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 {multi as default};\n", + "import {selector as parseSelector} from 'vega-event-selector';\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 {accessPath, Dict, isString, logicalExpr, stringValue, 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 // 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 predicate(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 ? ` + '_' + facet${accessPath(facet.field('row'))}` : '')\n + (facet.facet.column ? ` + '_' + facet${accessPath(facet.field('column'))}` : '');\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 return varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel]));\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 {stringValue} from '../../util';\nimport multi from './multi';\nimport {SelectionCompiler, STORE, TUPLE, unitName} from './selection';\n\n\nconst single:SelectionCompiler = {\n predicate: 'vlSingle',\n scaleDomain: 'vlSingleDomain',\n\n signals: multi.signals,\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 {single as default};\n", + "import {accessPath, stringValue, 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' ? ${datum}${accessPath(p.field)} : 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 signal.update = `${values.join(' && ')} ? {fields: [${fields}], values: [${values.join(', ')}]} : null`;\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport {inputBindings as default};\n", + "import * as log from '../../../log';\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 (markType === 'line' || markType === 'area') {\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: (x || (!x && !y)) ? 'datum.x' : {expr: '0'},\n y: (y || (!x && !y)) ? 'datum.y' : {expr: '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 {nearest as default};\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.field(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(timeUnits);\n }\n }\n};\n\nexport {project as default};\n", + "import {Channel} from '../../../channel';\nimport * as log from '../../../log';\nimport {hasContinuousDomain, isBinScale} from '../../../scale';\nimport {stringValue} from '../../../util';\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 },\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 {scaleBindings as default};\n\nexport function domain(model: UnitModel, channel: Channel) {\n const scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\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 {toggle as default};\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 {ScaleChannel, X, Y} from '../../../channel';\nimport {VgEventHandler, 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 = '_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 {translate as default};\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 {ScaleChannel, X, Y} from '../../../channel';\nimport {stringValue} from '../../../util';\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 {zoom as default};\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", + "\nimport * as log from '../log';\nimport {duplicate} from '../util';\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(public readonly explicit: T = {} as T, public readonly implicit: T = {} as T) {}\n\n public clone() {\n return new Split(duplicate(this.explicit), duplicate(this.implicit));\n }\n\n public combine(): T {\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: K, 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: K, s: S) {\n // Explicit has higher precedence\n if (s[key] !== undefined) {\n this.set(key, s[key], true);\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): 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) {\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 (v1.value === v2.value) {\n return v1;\n } else {\n return tieBreaker(v1, v2, property, propertyOf);\n }\n}\n", + "import {Axis} from '../axis';\nimport {Channel, 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 {isMarkDef, Mark, MarkDef} from '../mark';\nimport {Domain, Scale} from '../scale';\nimport {SelectionDef} from '../selection';\nimport {SortField, SortOrder} from '../sort';\nimport {LayoutSizeMixins, UnitSpec} 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 {\n assembleTopLevelSignals,\n assembleUnitSelectionData,\n assembleUnitSelectionMarks,\n assembleUnitSelectionSignals,\n parseUnitSelection,\n} 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 readonly selection: Dict = {};\n public children: Model[] = [];\n\n constructor(spec: UnitSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins = {}, repeater: RepeaterValue, config: Config, public fit: boolean) {\n\n super(spec, parent, parentGivenName, config, 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\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\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 sort(channel: Channel): SortField | SortOrder {\n return (this.getMapping()[channel] || {}).sort;\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 compatability.\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 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 {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, Field, FieldDef, isContinuous, isFieldDef, PositionFieldDef} from './../fielddef';\nimport * as log from './../log';\nimport {MarkConfig} from './../mark';\nimport {GenericUnitSpec, LayerSpec} 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](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 * - `\"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 * __Default value:__ `\"min-max\"`.\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}\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'],\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): LayerSpec {\n spec = filterUnsupportedChannels(spec);\n // TODO: use selection\n const {mark, encoding, selection, ...outerSpec} = spec;\n\n let kIQRScalar: number = undefined;\n if (isBoxPlotDef(mark)) {\n if (mark.extent) {\n if(isNumber(mark.extent)) {\n kIQRScalar = mark.extent;\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, ..._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, ..._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 continous 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 continous 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: field(channelDef)\n });\n } else if (channelDef.aggregate === undefined) {\n const transformedField = field(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: field(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 {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 {Field} from '../fielddef';\nimport {Encoding} from './../encoding';\nimport {GenericUnitSpec, LayerSpec} from './../spec';\n\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): LayerSpec {\n // TODO: use selection\n const {mark: _m, selection: _sel, 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, LayerSpec} from './../spec';\nimport {BOXPLOT, BOXPLOT_STYLES, BoxPlotConfigMixins, BoxPlotDef, normalizeBoxPlot, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX} from './boxplot';\nimport {ERRORBAR, normalizeErrorBar} from './errorbar';\n\n\nexport {BoxPlotConfig} from './boxplot';\nexport type UnitNormalizer = (spec: GenericUnitSpec, config: Config)=> LayerSpec;\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_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 ): LayerSpec {\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(`Unregistered composite mark ${mark}`);\n}\n", + "import {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 {defaultLegendConfig, LegendConfig} from './legend';\nimport {Mark, MarkConfigMixins, PRIMITIVE_MARKS, VL_ONLY_MARK_CONFIG_PROPERTIES, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './mark';\nimport * as mark from './mark';\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, isObject, keys, mergeDeep} from './util';\nimport {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\nexport const defaultViewConfig: ViewConfig = {\n width: 200,\n height: 200\n};\n\nexport type RangeConfigValue = (number|string)[] | VgScheme | {step: number};\n\nexport interface RangeConfig {\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 [name: string]: RangeConfigValue;\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 are filtered.\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:__ `'%b %d, %Y'`.\n *\n */\n timeFormat?: string;\n\n\n /** Default properties for [single view plots](spec.html#single). */\n view?: ViewConfig;\n\n /**\n * Scale configuration determines default properties for all [scales](scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](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\nexport type AreaOverlay = 'line' | 'linepoint' | 'none';\n\nexport interface OverlayConfig {\n /**\n * Whether to overlay line with point.\n */\n line?: boolean;\n\n /**\n * Type of overlay for area mark (line or linepoint)\n */\n area?: AreaOverlay;\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](scale.html#config).\n */\n range?: RangeConfig;\n\n /**\n * Legend configuration, which determines default properties for all [legends](legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](legend.html#config).\n */\n legend?: LegendConfig;\n\n /**\n * Title configuration, which determines default properties for all [titles](title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](title.html#config).\n */\n title?: VgTitleConfig;\n\n /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](mark.html#mark-def). The keys represent styles names; the value are valid [mark configuration objects](mark.html#config). */\n style?: StyleConfigIndex;\n\n /**\n * @hide\n */\n overlay?: OverlayConfig;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n timeFormat: '%b %d, %Y',\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 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\n box: {size: 14},\n boxWhisker: {},\n boxMid: {color: 'white'},\n\n scale: defaultScaleConfig,\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 mark of MARK_STYLES) {\n // Remove Vega-Lite-only mark config\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config[mark][prop];\n }\n\n // Remove Vega-Lite only mark-specific config\n const vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[mark];\n if (vlOnlyMarkSpecificConfigs) {\n for (const prop of vlOnlyMarkSpecificConfigs) {\n delete config[mark][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, mark);\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 {VgData} from './vega.schema';\n/*\n * Constants and utilities for data.\n */\n\nexport interface DataFormatBase {\n /**\n * If set to auto (the default), perform automatic type inference to determine the desired data types.\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\"` or `\"date\"`).\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](timeunit.html#utc)\n */\n parse?: 'auto' | object;\n}\n\nexport interface CsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`.\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 JsonDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`.\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\"`.\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 | JsonDataFormat | TopoDataFormat;\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport interface UrlData {\n /**\n * An object that specifies the format for parsing the data file.\n */\n format?: DataFormat;\n\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 {\n /**\n * An object that specifies the format for parsing the data values.\n */\n format?: DataFormat;\n /**\n * The full data set, included inline. This can be an array of objects or primitive values 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: number[] | string[] | boolean[] | object[] | string | object;\n}\n\nexport interface NamedData {\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 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'];\n}\n\nexport type DataSourceType = 'raw' | 'main' | 'row' | 'column' | 'lookup';\n\nexport const MAIN: 'main' = 'main';\nexport const RAW: 'raw' = 'raw';\n", + "// DateTime definition object\n\nimport * as log from './log';\nimport {duplicate, isNumber, 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", + "\nimport {Channel, CHANNELS, 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 {isArray, 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 * Color of the marks – either fill or stroke color based on mark type.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](config.html#mark)'s `color` property.\n *\n * _Note:_ See the scale documentation for more information about customizing [color scheme](scale.html#scheme).\n */\n color?: FieldDefWithCondition> | ValueDefWithCondition>;\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](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 currently unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`.\n */\n size?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * The symbol's shape (only 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 * __Default value:__ If undefined, the default shape depends on [mark config](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 and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | 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>;\n\n /**\n * Stack order for stacked marks or order of data points in line marks for connected scatter plots.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[];\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) => {\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.incompatibleChannel(channel, mark, 'when the field is aggregated.'));\n return normalizedEncoding;\n }\n }\n\n if (channel === 'detail' || channel === 'order') {\n const channelDef = encoding[channel];\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef])\n .reduce((fieldDefs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n fieldDefs.push(normalizeFieldDef(fieldDef, channel));\n }\n return fieldDefs;\n }, []);\n }\n } else {\n // FIXME: remove this casting. (I don't know why Typescript doesn't infer this correctly here.)\n const channelDef = encoding[channel] as ChannelDef;\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, 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", + "// Declaration and utility for variants of a field definition object\nimport {AggregateOp, 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 {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Scale} from './scale';\nimport {SortField, SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {getTimeUnitParts, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {getFullName, Type} from './type';\nimport {accessPath, isArray, isBoolean, isNumber, isString, 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\n\nexport type Conditional = {\n /**\n * A [selection name](selection.html), or a series of [composed selections](selection.html#compose).\n */\n selection: LogicalOperand;\n} & T;\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\nexport type FieldDefWithCondition> = F & {\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](encoding.html#value-def)\n * since Vega-Lite only allows at mosty one encoded field per encoding channel.\n */\n condition?: Conditional | Conditional[];\n};\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`](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](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](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](bin.html#params).\n * If `true`, default [binning parameters](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 */\n aggregate?: Aggregate;\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef extends FieldDefBase {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\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 ScaleFieldDef extends FieldDef {\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 * __Default value:__ If undefined, default [scale properties](scale.html) are applied.\n */\n scale?: Scale;\n\n /**\n * Sort order for the encoded field.\n * Supported `sort` values include `\"ascending\"`, `\"descending\"` and `null` (no sorting).\n * For fields with discrete domains, `sort` can also be a [sort field definition object](sort.html#sort-field).\n *\n * __Default value:__ `\"ascending\"`\n */\n sort?: SortOrder | SortField | 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](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](stack.html#bar) and [area](stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](stack.html#streamgraph)).\n * - `null` - No-stacking. This will produce layered [bar](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](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](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 | 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 /** Overrride which aggregate to use. Needed for unaggregated domain. */\n aggregate?: AggregateOp;\n}\n\nexport function field(fieldDef: FieldDefBase, 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 (fieldDef.bin) {\n fn = binToString(fieldDef.bin);\n suffix = opt.binSuffix || '';\n } else if (fieldDef.aggregate) {\n fn = String(opt.aggregate || fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (fn) {\n field = `${fn}_${field}`;\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 field = `${opt.expr}${accessPath(field)}`;\n }\n\n return field;\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\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: FieldDef, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDef, config: Config) {\n const {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: FieldDef, 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: FieldDef, 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: (fieldDef: FieldDef, config: Config) => string) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(fieldDef: FieldDef, 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 switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef) && !fieldDef.timeUnit) {\n // TODO:(https://github.com/vega/vega-lite/issues/2011):\n // with timeUnit it's not always strictly continuous\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 'text':\n case 'detail':\n case 'tooltip':\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if (isDiscrete(fieldDef) && !fieldDef.bin) {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with nominal data only'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal') {\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", + "import {DataFlowNode} from './compile/data/dataflow';\nimport {Model} from './compile/model';\nimport {predicate} from './compile/selection/selection';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {field} from './fielddef';\nimport {LogicalOperand} from './logical';\nimport {fieldExpr as timeUnitFieldExpr, getLocalTimeUnit, isLocalSingleTimeUnit, isUtcSingleTimeUnit, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {isArray, isString, logicalExpr} from './util';\n\n\nexport type Filter =\n // FieldFilter (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 EqualFilter | RangeFilter | OneOfFilter |\n SelectionFilter | string;\n\nexport type FieldFilter = EqualFilter | RangeFilter | OneOfFilter;\n\nexport interface SelectionFilter {\n /**\n * Filter using a selection name.\n */\n selection: LogicalOperand;\n}\n\nexport function isSelectionFilter(filter: LogicalOperand): filter is SelectionFilter {\n return filter && filter['selection'];\n}\n\nexport interface EqualFilter {\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 /**\n * The value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isEqualFilter(filter: any): filter is EqualFilter {\n return filter && !!filter.field && filter.equal!==undefined;\n}\n\nexport interface RangeFilter {\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 /**\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)[];\n\n}\n\nexport function isRangeFilter(filter: any): filter is RangeFilter {\n if (filter && filter.field) {\n if (isArray(filter.range) && filter.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface OneOfFilter {\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 /**\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 isOneOfFilter(filter: any): filter is OneOfFilter {\n return filter && !!filter.field && (\n isArray(filter.oneOf) ||\n isArray(filter.in) // backward compatibility\n );\n}\n\nexport function isFieldFilter(filter: Filter): filter is OneOfFilter | EqualFilter | RangeFilter {\n return isOneOfFilter(filter) || isEqualFilter(filter) || isRangeFilter(filter);\n}\n\n/**\n * Converts a filter 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, (filter: Filter) => {\n if (isString(filter)) {\n return filter;\n } else if (isSelectionFilter(filter)) {\n return predicate(model, filter.selection, node);\n } else { // Filter Object\n return fieldFilterExpression(filter);\n }\n });\n}\n\n// This method is used by Voyager. Do not change its behavior without changing Voyager.\nexport function fieldFilterExpression(filter: FieldFilter, useInRange=true) {\n const fieldExpr = filter.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(filter.timeUnit, filter.field) + ')') :\n field(filter, {expr: 'datum'});\n\n if (isEqualFilter(filter)) {\n return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit);\n } else if (isOneOfFilter(filter)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n const oneOf: OneOfFilter[] = filter.oneOf || filter['in'];\n return 'indexof([' +\n oneOf.map((v) => valueExpr(v, filter.timeUnit)).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isRangeFilter(filter)) {\n const lower = filter.range[0];\n const upper = filter.range[1];\n\n if (lower !== null && upper !== null && useInRange) {\n return 'inrange(' + fieldExpr + ', [' +\n valueExpr(lower, filter.timeUnit) + ', ' +\n valueExpr(upper, filter.timeUnit) + '])';\n }\n\n const exprs = [];\n if (lower !== null) {\n exprs.push(`${fieldExpr} >= ${valueExpr(lower, filter.timeUnit)}`);\n }\n if (upper !== null) {\n exprs.push(`${fieldExpr} <= ${valueExpr(upper, filter.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 filter: ${JSON.stringify(filter)}`);\n}\n\nfunction valueExpr(v: any, timeUnit: TimeUnit): string {\n if (isDateTime(v)) {\n const expr = dateTimeExpr(v, true);\n return 'time(' + expr + ')';\n }\n if (isLocalSingleTimeUnit(timeUnit)) {\n const datetime: DateTime = {};\n datetime[timeUnit] = v;\n const expr = dateTimeExpr(datetime, true);\n return 'time(' + expr + ')';\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n return valueExpr(v, getLocalTimeUnit(timeUnit));\n }\n return JSON.stringify(v);\n}\n\nexport function normalizeFilter(f: Filter): Filter {\n if (isFieldFilter(f) && f.timeUnit) {\n return {\n ...f,\n timeUnit: normalizeTimeUnit(f.timeUnit)\n };\n }\n return f;\n}\n", + "import {ValueDef} from './fielddef';\nimport {VgEncodeChannel} from './vega.schema';\n\n\nexport interface Guide {\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](format.html) for more information.\n *\n * __Default value:__ derived from [numberFormat](config.html#format) config for quantitative fields and from [timeFormat](config.html#format) config for temporal fields.\n */\n format?: string;\n\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 a part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function will be denoted in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n *\n * __Note__: You can customize the default field title format by providing the [`fieldTitle` property in the [config](config.html) or [`fieldTitle` function via the `compile` function's options](compile.html#field-title).\n */\n title?: string | null;\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;\n};\n\nexport const VL_ONLY_GUIDE_CONFIG: (keyof VlOnlyGuideConfig)[] = ['shortTimeLabels'];\n", + "export import axis = require('./axis');\nexport import aggregate = require('./aggregate');\nexport import bin = require('./bin');\nexport import channel = require('./channel');\nexport import compositeMark = require('./compositemark');\nexport {compile} from './compile/compile';\nexport import config = require('./config');\nexport import data = require('./data');\nexport import datetime = require('./datetime');\nexport import encoding = require('./encoding');\nexport import facet = require('./facet');\nexport import fieldDef = require('./fielddef');\nexport import legend = require('./legend');\nexport import mark = require('./mark');\nexport import scale = require('./scale');\nexport import sort = require('./sort');\nexport import spec = require('./spec');\nexport import stack = require('./stack');\nexport import timeUnit = require('./timeunit');\nexport import transform = require('./transform');\nexport import type = require('./type');\nexport import util = require('./util');\nexport import validate = require('./validate');\n\nexport const version: string = require('../package.json').version;\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[] | 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", + "/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport {AggregateOp} from './aggregate';\nimport {Channel} from './channel';\nimport {CompositeMark} from './compositemark';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {ScaleType} from './scale';\nimport {Type} from './type';\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 const logger = current = new LocalLogger();\n f(logger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(logger: LoggerInterface) {\n current = logger;\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: ${JSON.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 the data from the secondary source.';\n\n // ENCODING & FACET\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: ${value}}.`;\n }\n\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\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\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${JSON.stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n }\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 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 unclearOrientContinuous(mark: Mark) {\n return `Cannot clearly determine orientation for \"${mark}\" since both x and y channel encode continous fields. In this case, we use vertical by default`;\n }\n\n export function unclearOrientDiscreteOrEmpty(mark: Mark) {\n return `Cannot clearly determine orientation for \"${mark}\" since both x and y channel encode discrete or empty fields.`;\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 (${JSON.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 (${JSON.stringify(fieldDef)}).`;\n }\n\n export function cannotUseSizeFieldWithBandSize(positionChannel: 'x'|'y') {\n return `Using size field when ${positionChannel}-channel has a band scale is not supported.`;\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, propertyOf: string, v1: T, v2: T) {\n return `Conflicting ${propertyOf} property \"${property}\" (\"${v1}\" and \"${v2}\"). Using \"${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 conflictedDomain(channel: Channel) {\n return `Cannot set ${channel}-scale's \"domain\" as it is binned. Please use \"bin\"'s \"extent\" instead.`;\n }\n\n export function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property \"${JSON.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}: \"${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 ${JSON.stringify(d)} as day cannot be combined with other units.`;\n }\n}\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 forEachLeave(op: LogicalOperand, fn: (op: T) => void) {\n if (isLogicalNot(op)) {\n forEachLeave(op.not, fn);\n } else if (isLogicalAnd(op)) {\n for (const subop of op.and) {\n forEachLeave(subop, fn);\n }\n } else if (isLogicalOr(op)) {\n for (const subop of op.or) {\n forEachLeave(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 {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {flagKeys, toSet} 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 CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE;\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 RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\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 rect: 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 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](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](mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface MarkDef extends MarkConfig {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n\n /**\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](mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](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\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'];\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 bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\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?: MarkConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: MarkConfig;\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\nexport interface BarConfig extends MarkConfig {\n /**\n * Offset between bar 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 * 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 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 {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 2/3 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n", + "import {Channel} from './channel';\nimport {ScaleComponentProps} from './compile/scale/component';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport {contains, Flag, flagKeys, keys, toSet} from './util';\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 predecence -- 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 strokeWidth (or rule/line's size) scale with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for strokeWidth (or rule/line's size) scale.\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 scheme, 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](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](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**](scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](scale.html#linear), [`\"pow\"`](scale.html#pow), [`\"sqrt\"`](scale.html#sqrt), [`\"log\"`](scale.html#log), [`\"time\"`](scale.html#time), [`\"utc\"`](scale.html#utc), [`\"sequential\"`](scale.html#sequential)).\n *\n * 2) [**Discrete Scales**](scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](scale.html#ordinal)) or continuous ([`\"band\"`](scale.html#band) and [`\"point\"`](scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`\"bin-linear\"`](scale.html#bin-linear) and [`\"bin-ordinal\"`](scale.html#bin-ordinal)).\n *\n * __Default value:__ please see the [scale type table](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](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](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](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](scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](scale.html#piecewise).\n *\n * - For [discrete](scale.html#discrete) and [discretizing](scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For [sequential](scale.html#sequential), [ordinal](scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](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](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](scale.html#band) and [point](scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](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](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](scale.html#scheme) name (e.g., `\"category10\"` or `\"viridis\"`) or a [scheme parameter object](scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](scale.html#discrete) or [discretizing](scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](scales.html#sequential) scales.\n *\n * For the full list of supported scheme, 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](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](scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](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](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](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](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?: Interpolate | InterpolateParams;\n}\n\nexport type Interpolate = 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n\nexport interface InterpolateParams {\n type: 'rgb' | 'cubehelix' | 'cubehelix-long';\n gamma?: number;\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 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 (channel !== 'color') {\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 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 case Channel.COLOR:\n return scaleType !== 'band'; // band does not make sense with color\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", + "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](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](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](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](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`](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`](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`](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 {AggregateOp} from './aggregate';\n\n\nexport type SortOrder = 'ascending' | 'descending' | null;\n\nexport interface SortField {\n /**\n * The data [field](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](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](aggregate.html#ops).\n */\n op: AggregateOp;\n\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n order?: SortOrder;\n}\n\nexport function isSortField(sort: SortOrder | SortField): sort is SortField {\n return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op'];\n}\n", + "import {COLUMN, ROW, X, X2, Y, Y2} from './channel';\nimport * as compositeMark from './compositemark';\nimport {Config, OverlayConfig} from './config';\nimport {Data} from './data';\nimport {channelHasField, Encoding, EncodingWithFacet, isRanged} from './encoding';\nimport * as vlEncoding from './encoding';\nimport {FacetMapping} from './facet';\nimport {Field, FieldDef, RepeatRef} from './fielddef';\nimport * as log from './log';\nimport {AnyMark, AREA, isPrimitiveMark, LINE, Mark, MarkDef} from './mark';\nimport {Repeat} from './repeat';\nimport {Resolve} from './resolve';\nimport {SelectionDef} from './selection';\nimport {stack} from './stack';\nimport {TitleParams} from './title';\nimport {TopLevelProperties} from './toplevelprops';\nimport {Transform} from './transform';\nimport {contains, Dict, duplicate, hash, 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 interface BaseSpec {\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\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`](size.html#autosize) type is `\"fit\"` or its x-channel has a [continuous scale](scale.html#continuous), the width will be the value of [`config.view.width`](spec.html#config).\n * - For x-axis with a band or point scale: if [`rangeStep`](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](scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](spec.html#config).\n * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](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](encoding.html#facet), this represents the width of a single view.\n *\n * __See also:__ The documentation for [width and height](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`](size.html#autosize) type is `\"fit\"` or its y-channel has a [continuous scale](scale.html#continuous), the height will be the value of [`config.view.height`](spec.html#config).\n * - For y-axis with a band or point scale: if [`rangeStep`](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](scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](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](encoding.html#facet), this represents the height of a single view.\n *\n * __See also:__ The documentation for [width and height](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\"`, and `\"text\"`) or a [mark definition object](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 * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type UnitSpec = 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\nexport type LayerSpec = GenericLayerSpec;\n\nexport interface GenericFacetSpec> extends BaseSpec {\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: GenericLayerSpec | 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 FacetSpec = GenericFacetSpec;\n\nexport interface GenericRepeatSpec> extends BaseSpec {\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 RepeatSpec = GenericRepeatSpec;\n\nexport interface GenericVConcatSpec> extends BaseSpec {\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> extends BaseSpec {\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 ConcatSpec = GenericVConcatSpec | GenericHConcatSpec;\n\nexport type GenericSpec> = U | GenericLayerSpec | GenericFacetSpec | GenericRepeatSpec | GenericVConcatSpec | GenericHConcatSpec;\n\nexport type Spec = GenericSpec;\n\nexport type TopLevelExtendedSpec = TopLevel | TopLevel> | TopLevel> | TopLevel> | TopLevel> | TopLevel>;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: GenericSpec>): spec is GenericFacetSpec> {\n return spec['facet'] !== undefined;\n}\n\nexport function isUnitSpec(spec: GenericSpec>): spec is FacetedCompositeUnitSpec | UnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: GenericSpec>): spec is GenericLayerSpec> {\n return spec['layer'] !== undefined;\n}\n\nexport function isRepeatSpec(spec: GenericSpec>): spec is GenericRepeatSpec> {\n return spec['repeat'] !== undefined;\n}\n\nexport function isConcatSpec(spec: GenericSpec>): spec is GenericVConcatSpec> | GenericHConcatSpec> {\n return isVConcatSpec(spec) || isHConcatSpec(spec);\n}\n\nexport function isVConcatSpec(spec: GenericSpec>): spec is GenericVConcatSpec> {\n return spec['vconcat'] !== undefined;\n}\n\nexport function isHConcatSpec(spec: GenericSpec>): 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: TopLevelExtendedSpec, config: Config): Spec {\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): FacetSpec {\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 normalizeLayer(spec: GenericLayerSpec, config: Config): LayerSpec {\n const {layer: layer, ...rest} = spec;\n return {\n ...rest,\n layer: layer.map((subspec) => isLayerSpec(subspec) ? normalizeLayer(subspec, config) : normalizeNonFacetUnit(subspec, config))\n };\n}\n\nfunction normalizeRepeat(spec: GenericRepeatSpec, config: Config): RepeatSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalize(subspec, config)\n };\n}\n\nfunction normalizeVConcat(spec: GenericVConcatSpec, config: Config): ConcatSpec {\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): ConcatSpec {\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): FacetSpec {\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, height, selection, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\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\n\nfunction normalizeNonFacetUnit(spec: GenericUnitSpec, AnyMark>, config: Config) {\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(spec.encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n const overlayConfig: OverlayConfig = config && config.overlay;\n const overlayWithLine = overlayConfig && spec.mark === AREA &&\n contains(['linepoint', 'line'], overlayConfig.area);\n const overlayWithPoint = overlayConfig && (\n (overlayConfig.line && spec.mark === LINE) ||\n (overlayConfig.area === 'linepoint' && spec.mark === AREA)\n );\n // TODO: consider moving this to become another case of compositeMark\n if (overlayWithPoint || overlayWithLine) {\n return normalizeOverlay(spec, overlayWithPoint, overlayWithLine, config);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec, config);\n }\n}\n\nfunction normalizeRangedUnit(spec: UnitSpec) {\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\n\n// FIXME(#1804): re-design this\nfunction normalizeOverlay(spec: UnitSpec, overlayWithPoint: boolean, overlayWithLine: boolean, config: Config): LayerSpec {\n const {mark, selection, encoding, ...outerSpec} = spec;\n const layer = [{mark, encoding}];\n\n // Need to copy stack config to overlayed layer\n const stackProps = stack(mark, 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 (overlayWithLine) {\n layer.push({\n mark: {\n type: 'line',\n style: 'lineOverlay'\n },\n ...(selection ? {selection} : {}),\n encoding: overlayEncoding\n });\n }\n if (overlayWithPoint) {\n layer.push({\n mark: {\n type: 'point',\n filled: true,\n style: 'pointOverlay'\n },\n ...(selection ? {selection} : {}),\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, fieldDefs: FieldDef[]): any {\n fieldDefs.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 {SUM_OPS} from './aggregate';\nimport {NONPOSITION_CHANNELS, NonPositionChannel, X, X2, Y2} from './channel';\nimport {channelHasField, Encoding} from './encoding';\nimport {Field, field, FieldDef, getFieldDef, isFieldDef, isStringFieldDef, PositionFieldDef} from './fielddef';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag, isArray} 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(stack: string): stack is StackOffset {\n return !!STACK_OFFSET_INDEX[stack];\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) ? field(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? field(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) ? field(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 // If stacked, check scale type if it is linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n return null;\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\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: contains(['area', 'line'], mark),\n stackBy,\n offset\n };\n}\n", + "import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPath, 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 = `datum${accessPath(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 {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](spec.html) and [layered](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](spec.html) and [layered](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](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 {isString} from 'util';\nimport * as log from './log';\n\n/**\n * @minimum 0\n */\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\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\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\"`) inteprets 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'\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", + "import {AggregateOp} from './aggregate';\nimport {BinParams} from './bin';\nimport {Data} from './data';\nimport {Filter, normalizeFilter} from './filter';\nimport {LogicalOperand, normalizeLogicalOperand} from './logical';\nimport {TimeUnit} from './timeunit';\n\n\nexport interface FilterTransform {\n /**\n * The `filter` property must be either (1) a filter object for [equal-filters](filter.html#equalfilter),\n * [range-filters](filter.html#rangefilter), [one-of filters](filter.html#oneoffilter), or [selection filters](filter.html#selectionfilter);\n * (2) a [Vega Expression](filter.html#expression) string,\n * where `datum` can be used to refer to the current data object; or (3) an array of filters (either objects or expression strings) that must all be true for a datum to pass the filter and be included.\n */\n filter: LogicalOperand;\n}\n\nexport function isFilter(t: Transform): t is FilterTransform {\n return t['filter'] !== undefined;\n}\n\n\nexport interface CalculateTransform {\n /**\n * A string containing a Vega Expression. Use the variable `datum` to refer to the current data object.\n */\n calculate: string;\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;\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.\n */\n field: string;\n\n /**\n * The output field names to use for each aggregated field.\n */\n as: string;\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 specificied, 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\nexport function isLookup(t: Transform): t is LookupTransform {\n return t['lookup'] !== 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 type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform;\n\nexport function normalizeTransform(transform: Transform[]) {\n return transform.map(t => {\n if (isFilter(t)) {\n return {\n filter: normalizeLogicalOperand(t.filter, normalizeFilter)\n };\n }\n return t;\n });\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}\nexport type Type = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\n\nconst TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 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\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 }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n", + "import * as stringify from 'json-stable-stringify';\nimport {isArray, isNumber, isString, splitAccessPath, stringValue} from 'vega-util';\nimport {isLogicalAnd, isLogicalNot, isLogicalOr, LogicalOperand} from './logical';\n\n\nexport {isArray, isObject, isNumber, isString, truncate, toSet, stringValue, splitAccessPath} from 'vega-util';\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: object, props: string[]) {\n const copy = {};\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: object, props: string[]) {\n const copy = duplicate(obj);\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\nexport function hash(a: any) {\n if (isString(a) || isNumber(a) || isBoolean(a)) {\n return String(a);\n }\n\n const str = stringify(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) => (keyof T)[];\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\n// Omit from http://ideasintosoftware.com/typescript-advanced-tricks/\nexport type Diff = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];\nexport type Omit = {[P in Diff]: T[P]};\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 let isEmpty = true;\n while (orderedProps.length > 0 && isEmpty) {\n let o = obj;\n for (let i=0; i < orderedProps.length-1; i++) {\n o = o[orderedProps[i]];\n }\n delete o[orderedProps.pop()];\n if (keys(o).length !== 0) {\n isEmpty = false;\n }\n }\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.\n */\nexport function accessPath(path: string) {\n return `[${splitAccessPath(path).map(stringValue).join('][')}]`;\n}\n", + "import {isMarkDef} from './mark';\nimport {BAR} from './mark';\nimport {FacetedCompositeUnitSpec} from './spec';\nimport {toSet} from './util';\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 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', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'detail']), // TODO: add size when Vega supports\n area: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', '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 {AggregateOp} from './aggregate';\nimport {BaseBin} from './bin';\nimport {NiceTime, ScaleType} from './scale';\nimport {SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {Flag, flagKeys, isArray} 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 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?: 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n nice?: boolean | NiceTime;\n padding?: number;\n paddingInner?: number;\n paddingOuter?: number;\n reverse?: boolean;\n round?: boolean;\n zero?: boolean;\n}\n\nexport type VgLayoutAlign = 'none' | 'each' | 'all';\n\nexport type RowCol = {\n row?: T,\n column?: T\n};\n\nexport interface VgLayout {\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 | {\n row: VgLayoutAlign,\n column: VgLayoutAlign\n };\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'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'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';\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;\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?: 'ascending' | 'descending';\n} | {\n field: string[];\n order?: ('ascending' | 'descending')[];\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](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. (e.g., `\"bold\"`).\n */\n titleFontWeight?: string | number;\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 */\n titleFontWeight?: string | number;\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';\nexport type FontWeight = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\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';\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 * 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 // ---------- 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, 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 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 (default 0, indicating no limit). The text value will be automatically truncated if the rendered size exceeds the limit.\n */\n limit?: number;\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 (e.g., `\"bold\"`).\n */\n fontWeight?: FontWeight | FontWeightNumber;\n\n /**\n * Placeholder text if the `text` channel is not specified\n */\n text?: string;\n}\n\nconst VG_MARK_CONFIG_INDEX: Flag = {\n opacity: 1,\n fill: 1,\n fillOpacity: 1,\n stroke: 1,\n strokeWidth: 1,\n strokeOpacity: 1,\n strokeDash: 1,\n strokeDashOffset: 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 limit: 1,\n dx: 1,\n dy: 1,\n radius: 1,\n theta: 1,\n angle: 1,\n font: 1,\n fontSize: 1,\n fontWeight: 1,\n fontStyle: 1\n // commented below are vg channel that do not have mark config.\n // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'\n // cursor: 1,\n // clip: 1,\n // dir: 1,\n // ellipsis: 1,\n // endAngle: 1,\n // path: 1,\n // innerRadius: 1,\n // outerRadius: 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](spec.html) and [layered](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](spec.html) and [layered](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 */\n fontWeight?: FontWeight | FontWeightNumber;\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" + ] +} \ 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..2fff1da57f --- /dev/null +++ b/build/vega-lite.min.js @@ -0,0 +1 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).vl=e()}}(function(){return function e(t,n,r){function i(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[o]={exports:{}};t[o][0].call(u.exports,function(e){var n=t[o][1][e];return i(n||e)},u,u.exports,e,t,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o="0"&&i<="9";)t+=i,c();if("."===i)for(t+=".";c()&&i>="0"&&i<="9";)t+=i;if("e"===i||"E"===i)for(t+=i,c(),"-"!==i&&"+"!==i||(t+=i,c());i>="0"&&i<="9";)t+=i,c();if(e=+t,isFinite(e))return e;l("Bad number")},f=function(){var e,t,n,r="";if('"'===i)for(;c();){if('"'===i)return c(),r;if("\\"===i)if(c(),"u"===i){for(n=0,t=0;t<4&&(e=parseInt(c(),16),isFinite(e));t+=1)n=16*n+e;r+=String.fromCharCode(n)}else{if("string"!=typeof s[i])break;r+=s[i]}else r+=i}l("Bad string")},d=function(){for(;i&&i<=" ";)c()};o=function(){switch(d(),i){case"{":return function(){var e,t={};if("{"===i){if(c("{"),d(),"}"===i)return c("}"),t;for(;i;){if(e=f(),d(),c(":"),Object.hasOwnProperty.call(t,e)&&l('Duplicate key "'+e+'"'),t[e]=o(),d(),"}"===i)return c("}"),t;c(","),d()}}l("Bad object")}();case"[":return function(){var e=[];if("["===i){if(c("["),d(),"]"===i)return c("]"),e;for(;i;){if(e.push(o()),d(),"]"===i)return c("]"),e;c(","),d()}}l("Bad array")}();case'"':return f();case"-":return u();default:return i>="0"&&i<="9"?u():function(){switch(i){case"t":return c("t"),c("r"),c("u"),c("e"),!0;case"f":return c("f"),c("a"),c("l"),c("s"),c("e"),!1;case"n":return c("n"),c("u"),c("l"),c("l"),null}l("Unexpected '"+i+"'")}()}},t.exports=function(e,t){var n;return a=e,r=0,i=" ",n=o(),d(),i&&l("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)}({"":n},""):n}},{}],4:[function(e,t,n){function r(e){return l.lastIndex=0,l.test(e)?'"'+e.replace(l,function(e){var t=c[e];return"string"==typeof t?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function i(e,t){var n,l,c,u,f,d=a,p=t[e];switch(p&&"object"==typeof p&&"function"==typeof p.toJSON&&(p=p.toJSON(e)),"function"==typeof s&&(p=s.call(t,e,p)),typeof p){case"string":return r(p);case"number":return isFinite(p)?String(p):"null";case"boolean":case"null":return String(p);case"object":if(!p)return"null";if(a+=o,f=[],"[object Array]"===Object.prototype.toString.apply(p)){for(u=p.length,n=0;n1)for(var n=1;n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),f(t)?r.showHidden=t:t&&n._extend(r,t),g(r.showHidden)&&(r.showHidden=!1),g(r.depth)&&(r.depth=2),g(r.colors)&&(r.colors=!1),g(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),s(r,e,r.depth)}function a(e,t){var n=i.styles[t];return n?"["+i.colors[n][0]+"m"+e+"["+i.colors[n][1]+"m":e}function o(e,t){return e}function s(e,t,r){if(e.customInspect&&t&&_(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return m(i)||(i=s(e,i,r)),i}var a=function(e,t){if(g(t))return e.stylize("undefined","undefined");if(m(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(p(t))return e.stylize(""+t,"number");if(f(t))return e.stylize(""+t,"boolean");if(d(t))return e.stylize("null","null")}(e,t);if(a)return a;var o=Object.keys(t),v=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(o);if(e.showHidden&&(o=Object.getOwnPropertyNames(t)),b(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return l(t);if(0===o.length){if(_(t)){var O=t.name?": "+t.name:"";return e.stylize("[Function"+O+"]","special")}if(h(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(y(t))return e.stylize(Date.prototype.toString.call(t),"date");if(b(t))return l(t)}var S="",w=!1,E=["{","}"];if(u(t)&&(w=!0,E=["[","]"]),_(t)){S=" [Function"+(t.name?": "+t.name:"")+"]"}if(h(t)&&(S=" "+RegExp.prototype.toString.call(t)),y(t)&&(S=" "+Date.prototype.toUTCString.call(t)),b(t)&&(S=" "+l(t)),0===o.length&&(!w||0==t.length))return E[0]+S+E[1];if(r<0)return h(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=w?function(e,t,n,r,i){for(var a=[],o=0,s=t.length;o=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(N,S,E)}function l(e){return"["+Error.prototype.toString.call(e)+"]"}function c(e,t,n,r,i,a){var o,l,c;if((c=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]}).get?l=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(l=e.stylize("[Setter]","special")),x(r,i)||(o="["+i+"]"),l||(e.seen.indexOf(c.value)<0?(l=d(n)?s(e,c.value,null):s(e,c.value,n-1)).indexOf("\n")>-1&&(l=a?l.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+l.split("\n").map(function(e){return" "+e}).join("\n")):l=e.stylize("[Circular]","special")),g(o)){if(a&&i.match(/^\d+$/))return l;(o=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+l}function u(e){return Array.isArray(e)}function f(e){return"boolean"==typeof e}function d(e){return null===e}function p(e){return"number"==typeof e}function m(e){return"string"==typeof e}function g(e){return void 0===e}function h(e){return v(e)&&"[object RegExp]"===O(e)}function v(e){return"object"==typeof e&&null!==e}function y(e){return v(e)&&"[object Date]"===O(e)}function b(e){return v(e)&&("[object Error]"===O(e)||e instanceof Error)}function _(e){return"function"==typeof e}function O(e){return Object.prototype.toString.call(e)}function S(e){return e<10?"0"+e.toString(10):e.toString(10)}function x(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var w=/%[sdj%]/g;n.format=function(e){if(!m(e)){for(var t=[],n=0;n=a)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),s=r[n];n=0?--o:r&&r.indexOf(a)>=0&&++o}return t}function n(e){for(var n=[],r=0,i=e.length,a=0;a' after between selector: "+e;{if(i=i.map(r),(a=r(e.slice(1).trim())).between)return{between:i,stream:a};a.between=i}return a}(e):function(e){var n,r,o={source:i},m=[],h=[0,0],v=0,y=0,b=e.length,_=0;if(e[b-1]===u){if(!((_=e.lastIndexOf(c))>=0))throw"Unmatched right brace: "+e;try{h=function(e){var t=e.split(d);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(_+1,b-1))}catch(t){throw"Invalid throttle specification: "+e}e=e.slice(0,_).trim(),b=e.length,_=0}if(!b)throw e;e[0]===p&&(v=++_);(n=t(e,_,f))1?(o.type=m[1],v?o.markname=m[0].slice(1):!function(e){return a.hasOwnProperty(e)}(m[0])?o.source=m[0]:o.marktype=m[0]):o.type=m[0];"!"===o.type.slice(-1)&&(o.consume=!0,o.type=o.type.slice(0,-1));null!=r&&(o.filter=r);h[0]&&(o.throttle=h[0]);h[1]&&(o.debounce=h[1]);return o}(e)}var i,a,o="view",s="[",l="]",c="{",u="}",f=":",d=",",p="@",m=">",g=/[[\]{}]/,h={"*":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};e.selector=function(e,t,s){return i=t||o,a=s||h,n(e.trim()).map(r)},Object.defineProperty(e,"__esModule",{value:!0})})},{}],10:[function(e,t,n){!function(e,r){r("object"==typeof n&&void 0!==t?n:e.vega=e.vega||{})}(this,function(e){"use strict";function t(e){return null==e?null:e.fields}function n(e){return d(e)?"["+e.map(n)+"]":p(e)||m(e)?JSON.stringify(e).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):e}function r(e,t,n){var r=[t].concat([].slice.call(n));console[e].apply(console,r)}function i(e){return function(t){return e*Math.exp(t)}}function a(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 s(e,t,n,r){var i=n(e[0]),a=n(x(e)),o=(a-i)*t;return[r(i-o),r(a-o)]}function l(e,t,n,r,i){var a=r(e[0]),o=r(x(e)),s=null!=t?r(t):(a+o)/2;return[i(s+(a-s)*n),i(s+(o-s)*n)]}var c=function(e,t,n){return e.fields=t||[],e.fname=n,e},u=function(e){throw Error(e)},f=function(e){function t(){a.push(c+e.substring(n,r)),c="",n=r+1}var n,r,i,a=[],o=null,s=0,l=e.length,c="";for(e+="",n=r=0;rn&&t(),s=n=r+1):"]"===i&&(s||u("Access path missing open bracket: "+e),s>0&&t(),s=0,n=r+1):r>n?t():n=r+1}return s&&u("Access path missing closing bracket: "+e),o&&u("Access path missing closing quote: "+e),r>n&&(r++,t()),a},d=Array.isArray,p=function(e){return e===Object(e)},m=function(e){return"string"==typeof e},g=function(e,t){var r=f(e),i="return _["+r.map(n).join("][")+"];";return c(Function("_",i),[e=1===r.length?r[0]:e],t||e)},h=[],v=g("id"),y=c(function(e){return e},h,"identity"),b=c(function(){return 0},h,"zero"),_=c(function(){return 1},h,"one"),O=c(function(){return!0},h,"true"),S=c(function(){return!1},h,"false"),x=function(e){return e[e.length-1]},w=function(e){return null==e||""===e?null:+e},E=function(e){return null!=e?d(e)?e:[e]:[]},N=function(e){return"function"==typeof e},T={},P=function(e){return"[object Date]"===Object.prototype.toString.call(e)},k=function(e){return"number"==typeof e},D=function(e,t){for(var n="";--t>=0;)n+=e;return n};e.accessor=c,e.accessorName=function(e){return null==e?null:e.fname},e.accessorFields=t,e.id=v,e.identity=y,e.zero=b,e.one=_,e.truthy=O,e.falsy=S,e.logger=function(e){var t=e||0;return{level:function(e){return arguments.length?(t=+e,this):t},error:function(){return t>=1&&r("error","ERROR",arguments),this},warn:function(){return t>=2&&r("warn","WARN",arguments),this},info:function(){return t>=3&&r("log","INFO",arguments),this},debug:function(){return t>=4&&r("log","DEBUG",arguments),this}}},e.None=0,e.Error=1,e.Warn=2,e.Info=3,e.Debug=4,e.panLinear=function(e,t){return s(e,t,w,y)},e.panLog=function(e,t){var n=Math.sign(e[0]);return s(e,t,a(n),i(n))},e.panPow=function(e,t,n){return s(e,t,o(n),o(1/n))},e.zoomLinear=function(e,t,n){return l(e,t,n,w,y)},e.zoomLog=function(e,t,n){var r=Math.sign(e[0]);return l(e,t,n,a(r),i(r))},e.zoomPow=function(e,t,n,r){return l(e,t,n,o(r),o(1/r))},e.array=E,e.compare=function(e,r){var i,a,o,s,l,u,d,p,m,g=[],h=(e=E(e)).map(function(e,t){return null==e?null:(g.push(t),N(e)?e:f(e).map(n).join("]["))}),v=g.length-1,y=E(r),b="var u,v;return ";if(v<0)return null;for(a=0;a<=v;++a)o=h[i=g[a]],N(o)?(s="(u=this."+(u="f"+i)+"(a))",l="(v=this."+u+"(b))",(d=d||{})[u]=o):(s="(u=a["+o+"])",l="(v=b["+o+"])"),u="((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))","descending"!==y[i]?(m=1,p=-1):(m=-1,p=1),b+="("+s+"<"+l+"||u==null)&&v!=null?"+p+":(u>v||v==null)&&u!=null?"+m+":"+u+"!==u&&v===v?"+p+":v!==v&&u===u?"+m+(i=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 (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 provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.",main:"build/src/index.js",types:"typings/vega-lite.d.ts",bin:{vl2png:"./bin/vl2png",vl2svg:"./bin/vl2svg",vl2vg:"./bin/vl2vg"},directories:{test:"test"},scripts:{pretsc:"mkdir -p build && rm -rf build/*/** && cp package.json build/",tsc:"tsc",prebuild:"mkdir -p build/site build/test-gallery",build:"npm run build:only","build:only":"npm run tsc && cp package.json build && browserify src/index.ts -p tsify -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js",postbuild:"node node_modules/uglify-js/bin/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 && npm run build:only && npm run build:examples-only","build:examples-only":"npm run build:example && npm run build:examples-normalized","build:examples-normalized":"rm -f examples/specs/normalized/*.vl.json && scripts/build-normalized-examples","build:example":"TZ=America/Los_Angeles scripts/build-examples.sh","build:toc":"bundle exec jekyll build -q && scripts/generate-toc","build:site":"browserify site/static/main.ts -p [tsify -p site] -d | exorcist build/site/main.js.map > build/site/main.js","build:versions":"scripts/update-version.sh","build:test-gallery":"browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js","check:examples":"scripts/check-examples.sh","check:schema":"scripts/check-schema.sh",clean:"rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\.(js|js.map|d.ts)' -delete && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -exec rm -f {} +",data:"rsync -r node_modules/vega-datasets/data/* data",link:"npm link && npm link vega-lite",deploy:"scripts/deploy.sh","deploy:gh":"scripts/deploy-gh.sh","deploy:schema":"scripts/deploy-schema.sh",prestart:"npm run data && npm run build && scripts/index-examples",start:"nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'",poststart:"rm examples/all-examples.json",preschema:"npm run prebuild",schema:"ts-json-schema-generator --path tsconfig.json --type TopLevelExtendedSpec > 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:"npm run build:only && npm run test:only && npm run test:runtime && npm run lint",posttest:"npm run schema && npm run data && npm run mocha:examples","test:nocompile":"npm run test:only && npm run test:runtime && npm run lint && npm run mocha:examples","test:only":"nyc --reporter=html --reporter=text-summary npm run mocha:test","test:runtime":"TZ=America/Los_Angeles wdio wdio.conf.js","test:runtime:generate":"rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime","test:debug":"npm run tsc && mocha --recursive --debug-brk --inspect build/test","test:debug-examples":"npm run tsc && npm run schema && mocha --recursive --debug-brk --inspect build/examples","mocha:test":"mocha --require source-map-support/register --reporter dot --recursive build/test","mocha:examples":"mocha --require source-map-support/register --reporter dot --recursive build/examples",codecov:"nyc report --reporter=json && codecov -f coverage/*.json","watch:build":"watchify src/index.ts -p tsify -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'","watch:tsc":"npm run tsc -- -w","watch:test":"nodemon -x 'npm test'",watch:"nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build"},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.0.6","@types/d3":"^4.12.0","@types/highlight.js":"^9.12.2","@types/json-stable-stringify":"^1.0.32","@types/mkdirp":"^0.5.1","@types/mocha":"^2.2.44","@types/node":"^8.0.53","@types/webdriverio":"^4.8.6",ajv:"^5.5.0","browser-sync":"^2.18.13",browserify:"^14.5.0","browserify-shim":"^3.8.14",chai:"^4.1.2",cheerio:"^1.0.0-rc.2",chromedriver:"^2.33.2",codecov:"^3.0.0",d3:"^4.12.0",exorcist:"^1.0.0","highlight.js":"^9.12.0",mkdirp:"^0.5.1",mocha:"^4.0.1",nodemon:"^1.12.1",nyc:"^11.3.0","source-map-support":"^0.5.0","svg2png-many":"^0.0.7","ts-json-schema-generator":"^0.18.0","ts-node":"^3.3.0",tsify:"^3.0.3",tslint:"5.4.3","tslint-eslint-rules":"^4.1.1",typescript:"^2.6.2","uglify-js":"^3.2.0",vega:"^3.0.8","vega-datasets":"^1.11.0","vega-embed":"^3.0.0-rc7","vega-tooltip":"^0.4.4",watchify:"^3.9.0","wdio-chromedriver-service":"^0.1.1","wdio-dot-reporter":"0.0.9","wdio-mocha-framework":"^0.5.11","wdio-static-server-service":"^1.0.1",webdriverio:"^4.9.11","yaml-front-matter":"^3.4.0"},dependencies:{"json-stable-stringify":"^1.0.1",tslib:"^1.8.0","vega-event-selector":"^2.0.0","vega-util":"^1.6.2",yargs:"^10.0.3"}}},{}],12:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./util"),i={values:1,count:1,valid:1,missing:1,distinct:1,sum:1,mean:1,average:1,variance:1,variancep:1,stdev:1,stdevp:1,median:1,q1:1,q3:1,ci0:1,ci1:1,min:1,max:1,argmin:1,argmax:1};n.AGGREGATE_OPS=r.flagKeys(i),n.isAggregateOp=function(e){return!!i[e]},n.COUNTING_OPS=["count","valid","missing","distinct"],n.isCountingAggregateOp=function(e){return e&&r.contains(n.COUNTING_OPS,e)},n.SUM_OPS=["count","sum","distinct","valid","missing"],n.SHARED_DOMAIN_OPS=["mean","average","median","q1","q3","min","max"],n.SHARED_DOMAIN_OP_INDEX=r.toSet(n.SHARED_DOMAIN_OPS)},{"./util":118}],13:[function(e,t,n){"use strict";var r=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0){if(e%360>180)return"top"===t?"left":"right";if(e%360<180)return"top"===t?"right":"left"}else if(e<0)return i(e%360+360,t)}var a=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&(n[r]={update:s}),n},{});return d.keys(s).length>0&&i.set("encode",s,!!r.encoding||!!r.labelAngle),i}var c=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&!E){var N=O[w];a[w]>a[N]&&S.main.set("orient",N,!1)}a[w]++}}delete y.component.axes[g]}}},n.parseGridAxis=o,n.parseMainAxis=s},{"../../axis":13,"../../channel":15,"../../util":118,"../common":24,"../resolve":69,"../split":89,"./component":17,"./config":18,"./encode":19,"./properties":21}],21:[function(e,t,n){"use strict";function r(e,t,n,r){return!n&&t[e]}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../bin"),a=e("../../channel"),o=e("../../datetime"),s=e("../../fielddef"),l=e("../../log"),c=e("../../scale"),u=e("../../type"),f=e("../../util");n.domainAndTicks=r,n.domain=r,n.ticks=r,n.grid=function(e,t){return!c.hasDiscreteDomain(e)&&!t.bin},n.gridScale=function(e,t,n){if(n){var r="x"===t?"y":"x";if(e.getScaleComponent(r))return e.scaleName(r)}},n.labelFlush=function(e,t,n,r){if(!r)return void 0!==n.labelFlush?n.labelFlush:!("x"!==t||!f.contains(["quantitative","temporal"],e.type))||void 0},n.labelOverlap=function(e,t,n,r){return void 0!==t.labelOverlap?t.labelOverlap:"nominal"!==e.type?"log"!==r||"greedy":void 0},n.minMaxExtent=function(e,t){return t?0:e},n.orient=function(e){switch(e){case a.X:return"bottom";case a.Y:return"left"}throw new Error(l.message.INVALID_CHANNEL_FOR_AXIS)},n.tickCount=function(e,t,n,r){if(!c.hasDiscreteDomain(n)&&"log"!==n&&!f.contains(["month","hours","day","quarter"],t.timeUnit))return t.bin?{signal:"ceil("+r.signal+"/20)"}:{signal:"ceil("+r.signal+"/40)"}},n.title=function(e,t,n){var r=s.title(t,n);return e?f.truncate(r,e):r},n.values=function(e,t,n){var r=e.values;if(e.values&&o.isDateTime(r[0]))return r.map(function(e){return{signal:o.dateTimeExpr(e,!0)}});if(!r&&n.bin&&n.type===u.QUANTITATIVE){var a=t.getName(i.binToString(n.bin)+"_"+n.field+"_bins");return{signal:"sequence("+a+".start, "+a+".stop + "+a+".step, "+a+".step)"}}return r},n.zindex=function(e){return e?0:1}},{"../../bin":14,"../../channel":15,"../../datetime":97,"../../fielddef":100,"../../log":105,"../../scale":108,"../../type":117,"../../util":118}],22:[function(e,t,n){"use strict";var r=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?(e.push(o),r.data=o.name):r.data=o.source,void r.assemble().forEach(function(t){return e.push(t)});if((r instanceof d.FilterNode||r instanceof c.CalculateNode||r instanceof s.AggregateNode||r instanceof h.LookupNode||r instanceof g.IdentifierNode)&&o.transform.push(r.assemble()),(r instanceof p.FilterInvalidNode||r instanceof l.BinNode||r instanceof b.TimeUnitNode||r instanceof y.StackNode)&&(o.transform=o.transform.concat(r.assemble())),r instanceof s.AggregateNode&&(o.name||(o.name="data_"+n++)),r instanceof u.OutputNode)if(o.source&&0===o.transform.length)r.setSource(o.source);else if(r.parent instanceof u.OutputNode)r.setSource(o.name);else if(o.name||(o.name="data_"+n++),r.setSource(o.name),1===r.numChildren()){e.push(o);var _={name:null,source:o.name,transform:[]};o=_}switch(r.numChildren()){case 0:r instanceof u.OutputNode&&(!o.source||o.transform.length>0)&&e.push(o);break;case 1:t(r.children[0],o);break;default:o.name||(o.name="data_"+n++);var O=o.name;!o.source||o.transform.length>0?e.push(o):O=o.source,r.children.forEach(function(e){t(e,{name:null,source:O,transform:[]})})}}var n=0;return t}var i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?{type:"filter",expr:t.join(" && ")}:null},t}(e("./dataflow").DataFlowNode);n.FilterInvalidNode=c},{"../../channel":15,"../../fielddef":100,"../../scale":108,"../../util":118,"./dataflow":31}],35:[function(e,t,n){"use strict";function r(e,t){var n="datum"+d.accessPath(e);if("number"===t)return"toNumber("+n+")";if("boolean"===t)return"toBoolean("+n+")";if("string"===t)return"toString("+n+")";if("date"===t)return"toDate("+n+")";if(0===t.indexOf("date:")){return"timeParse("+n+","+(r=t.slice(5,t.length))+")"}if(0===t.indexOf("utc:")){var r=t.slice(4,t.length);return"utcParse("+n+","+r+")"}return c.warn(c.message.unrecognizedParse(t)),null}var i=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),a=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0})).forEach(p.iterateFromLeaves(p.removeUnusedSubtrees)),o(t=t.filter(function(e){return e.numChildren()>0})).forEach(p.iterateFromLeaves(p.moveParseUp)),o(t).forEach(p.removeDuplicateTimeUnits),t.forEach(r),l.keys(e.sources).forEach(function(t){0===e.sources[t].numChildren()&&delete e.sources[t]})}},{"../../data":96,"../../util":118,"./aggregate":27,"./dataflow":31,"./facet":32,"./filterinvalid":34,"./optimizers":39,"./stack":42}],39:[function(e,t,n){"use strict";function r(e){function t(n){if(!(n instanceof l.SourceNode)){var r=n.parent;e(n)&&t(r)}}return t}var i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n1)return!0;if(t instanceof s.ParseNode)t.merge(e);else{if(a.hasIntersection(t.producedFields(),e.dependentFields()))return!0;e.swapWithParent()}}return!0},n.removeUnusedSubtrees=function(e){return!(e instanceof o.OutputNode||e.numChildren()>0||(e.remove(),0))},n.removeDuplicateTimeUnits=function(e){var t={};return r(function(e){if(e instanceof c.TimeUnitNode){var n=e.producedFields();a.keys(n).every(function(e){return!!t[e]})?e.remove():t=i({},t,n)}return!0})(e)}},{"../../util":118,"./dataflow":31,"./formatparse":35,"./source":41,"./timeunit":43}],40:[function(e,t,n){"use strict";function r(e){function t(e){i?e.parent?r.insertAsParentOf(e):e.parent=r:i=e.parent||e,r=e}var n,r,i=null,o=0;e.transforms.forEach(function(r){if(u.isCalculate(r))n=new h.CalculateNode(r);else if(u.isFilter(r)){var i={},d=r.filter,v=null;if(l.isEqualFilter(d)?v=d.equal:l.isRangeFilter(d)?v=d.range[0]:l.isOneOfFilter(d)&&(v=(d.oneOf||d.in)[0]),v&&(s.isDateTime(v)?i[d.field]="date":a.isNumber(v)?i[d.field]="number":a.isString(v)&&(i[d.field]="string")),f.keys(i).length>0){t(new O.ParseNode(i))}n=new b.FilterNode(e,r.filter)}else if(u.isBin(r))n=g.BinNode.makeFromTransform(r,{model:e});else if(u.isTimeUnit(r))n=N.TimeUnitNode.makeFromTransform(r);else if(u.isAggregate(r))n=m.AggregateNode.makeFromTransform(r),p.requiresSelectionId(e)&&(t(n),n=new S.IdentifierNode);else{if(!u.isLookup(r))return void c.warn(c.message.invalidTransformIgnored(r));n=x.LookupNode.make(e,r,o++)}t(n)});return{first:i,last:n}}var i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0){var c=r(e),u=c.first,f=c.last;u.parent=s,s=f}var h=O.ParseNode.make(e);if(h&&(h.parent=s,s=h),d.isUnitModel(e)||d.isFacetModel(e)){if(!l){var b=g.BinNode.makeBinFromEncoding(e);b&&(b.parent=s,s=b)}var x=N.TimeUnitNode.makeFromEncoding(e);x&&(x.parent=s,s=x)}var T=e.getName(o.RAW),P=new v.OutputNode(T,o.RAW,a);if(n[T]=P,P.parent=s,s=P,d.isUnitModel(e)){var k=m.AggregateNode.makeFromEncoding(e);if(k&&(k.parent=s,s=k,p.requiresSelectionId(e))){var D=new S.IdentifierNode;D.parent=s,s=D}var C=E.StackNode.make(e);C&&(C.parent=s,s=C)}if(d.isUnitModel(e)){var A=_.FilterInvalidNode.make(e);A&&(A.parent=s,s=A)}var M=e.getName(o.MAIN),j=new v.OutputNode(M,o.MAIN,a);n[M]=j,j.parent=s,s=j;var R=null;if(d.isFacetModel(e)){var I=e.getName("facet");R=new y.FacetNode(e,I,j.getSource()),n[I]=R,R.parent=s,s=R}var L=i({},e.component.data.ancestorParse,h?h.parse:{});return i({},e.component.data,{outputNodes:n,outputNodeRefCounts:a,raw:P,main:j,facetRoot:R,ancestorParse:L})}},{"../../data":96,"../../datetime":97,"../../filter":101,"../../log":105,"../../transform":116,"../../util":118,"../model":66,"../selection/selection":79,"./aggregate":27,"./bin":29,"./calculate":30,"./dataflow":31,"./facet":32,"./filter":33,"./filterinvalid":34,"./formatparse":35,"./indentifier":36,"./lookup":37,"./source":41,"./stack":42,"./timeunit":43,"vega-util":10}],41:[function(e,t,n){"use strict";var r=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?{data:r}:{},l?{encode:{update:l}}:{},e.assembleGroup())]},t.prototype.getMapping=function(){return this.facet},t}(v.ModelWithField);n.FacetModel=O},{"../channel":15,"../encoding":98,"../fielddef":100,"../log":105,"../scale":108,"../util":118,"../vega.schema":120,"./buildmodel":23,"./data/assemble":28,"./data/parse":40,"./layout/header":46,"./layoutsize/parse":48,"./model":66,"./repeater":68,"./resolve":69,"./scale/domain":72}],45:[function(e,t,n){"use strict";var r=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?{encode:{update:i}}:{})]}},n.getHeaderGroup=function(e,t,n,s,l){if(l){var c=null;if(s.facetFieldDef&&l.labels){var u=s.facetFieldDef,f=u.header,d=void 0===f?{}:f,p=d.format,m=d.labelAngle,g=r({},m?{angle:{value:m}}:{});c=r({text:o.formatSignalRef(u,p,"parent",e.config),offset:10,orient:"row"===t?"left":"top",style:"guide-label"},a.keys(g).length>0?{encode:{update:g}}:{})}var h=l.axes,v=h&&h.length>0;if(c||v){var y="row"===t?"height":"width";return r({name:e.getName(t+"_"+n),type:"group",role:t+"-"+n},s.facetFieldDef?{from:{data:e.getName(t+"_domain")},sort:{field:i.field(s.facetFieldDef,{expr:"datum"}),order:s.facetFieldDef.header&&s.facetFieldDef.sort||"ascending"}}:{},c?{title:c}:{},l.sizeSignal?{encode:{update:(b={},b[y]=l.sizeSignal,b)}}:{},v?{axes:h}:{})}}return null;var b}},{"../../fielddef":100,"../../util":118,"../common":24}],47:[function(e,t,n){"use strict";function r(e,t){var n="width"===t?"x":"y",r=e.component.layoutSize.get(t);if(!r||"merged"===r)return[];var c=e.getSizeSignalRef(t).signal;if("range-step"===r){var u=e.getScaleComponent(n);if(u){var f=u.get("type"),d=u.get("range");if(o.hasDiscreteDomain(f)&&s.isVgRangeStep(d)){var p=e.scaleName(n);if(l.isFacetModel(e.parent)){if("independent"===e.parent.component.resolve.scale[n])return[i(p,d)]}return[i(p,d),{name:c,update:a(p,u,"domain('"+p+"').length")}]}}throw new Error("layout size is range step although there is no rangeStep.")}return[{name:c,value:r}]}function i(e,t){return{name:e+"_step",value:t.step}}function a(e,t,n){var r=t.get("type"),i=t.get("padding"),a=t.get("paddingOuter");a=void 0!==a?a:i;var o=t.get("paddingInner");return o="band"===r?void 0!==o?o:i:1,"bandspace("+n+", "+o+", "+a+") * "+e+"_step"}Object.defineProperty(n,"__esModule",{value:!0});var o=e("../../scale"),s=e("../../vega.schema"),l=e("../model");n.assembleLayoutSignals=function(e){return[].concat(r(e,"width"),r(e,"height"))},n.sizeSignals=r,n.sizeExpr=a},{"../../scale":108,"../../vega.schema":120,"../model":66}],48:[function(e,t,n){"use strict";function r(e){i(e);var t=e.component.layoutSize;t.setWithExplicit("width",a(e,"width")),t.setWithExplicit("height",a(e,"height"))}function i(e){for(var t=0,n=e.children;t0?p:void 0}},n.gradient=function(e,t,n,a,o){var s={};if("gradient"===o){var l=r(n.encoding.opacity)||n.markDef.opacity;l&&(s.opacity={value:l})}return s=i({},s,t),u.keys(s).length>0?s:void 0},n.labels=function(e,t,n,r,a){var o=n.legend(r),l=n.config,d={};if(s.isTimeFieldDef(e)){var p=n.getScaleComponent(r).get("type")===c.ScaleType.UTC;t=i({text:{signal:f.timeFormatExpression("datum.value",e.timeUnit,o.format,l.legend.shortTimeLabels,l.timeFormat,p)}},t)}return d=i({},d,t),u.keys(d).length>0?d:void 0}},{"../../channel":15,"../../fielddef":100,"../../mark":107,"../../scale":108,"../../util":118,"../common":24,"../mark/mixins":59,"vega-util":10}],52:[function(e,t,n){"use strict";function r(e){f.isUnitModel(e)?e.component.legends=function(e){return[o.COLOR,o.SIZE,o.SHAPE,o.OPACITY].reduce(function(t,n){return e.legend(n)&&(t[n]=i(e,n)),t},{})}(e):e.component.legends=function(e){for(var t=e.component,n=t.legends,i=t.resolve,o=function(t){r(t),c.keys(t.component.legends).forEach(function(r){i.legend[r]=d.parseGuideResolve(e.component.resolve,r),"shared"===i.legend[r]&&(n[r]=a(n[r],t.component.legends[r]),n[r]||(i.legend[r]="independent",delete n[r]))})},s=0,l=e.children;s0&&(r[o]={update:s}),r},{});return c.keys(f).length>0&&i.set("encode",f,!!r.encoding),i}function a(e,t){if(!e)return t.clone();var n=e.getWithExplicit("orient"),r=t.getWithExplicit("orient");if(!n.explicit||!r.explicit||n.value===r.value){for(var i=!1,a=function(n){var r=m.mergeValuesWithExplicit(e.getWithExplicit(n),t.getWithExplicit(n),n,"legend",function(e,t){switch(n){case"title":return u.titleMerger(e,t);case"type":return i=!0,p.makeImplicit("symbol")}return m.defaultTieBreaker(e,t,n,"legend")});e.setWithExplicit(n,r)},o=0,s=l.VG_LEGEND_PROPERTIES;o0?w:"")+e.requestDataName(l.MAIN)},encode:{update:x[t].encodeEntry(e)}})];return n.length>0?[{name:e.getName("pathgroup"),type:"group",from:{facet:{name:w+e.requestDataName(l.MAIN),data:e.requestDataName(l.MAIN),groupby:n}},encode:{update:{width:{field:{group:"width"}},height:{field:{group:"height"}}}},marks:f}]:f}(e):function(e){var t=e.mark(),n=m.getStyles(e.markDef),r=void 0!==e.markDef.clip?!!e.markDef.clip:a(e),i=[];return i.push(o({name:e.getName("marks"),type:x[t].vgMark},r?{clip:!0}:{},n?{style:n}:{},{from:{data:e.requestDataName(l.MAIN)},encode:{update:x[t].encodeEntry(e)}})),i}(e)};var w="faceted_path_";n.getPathSort=r,n.pathGroupingFields=i},{"../../data":96,"../../encoding":98,"../../fielddef":100,"../../mark":107,"../../sort":110,"../../util":118,"../common":24,"./area":54,"./bar":55,"./line":57,"./point":60,"./rect":61,"./rule":62,"./text":63,"./tick":64,"vega-util":10}],59:[function(e,t,n){"use strict";function r(e,t,n){void 0===n&&(n={});var r=n.defaultValue,a=n.vgChannel,o=n.defaultRef||(void 0!==r?{value:r}:void 0),s=t.encoding[e];return i(t,s,a||e,function(n){return m.midPoint(e,n,t.scaleName(e),t.getScaleComponent(e),null,o)})}function i(e,t,n,r){var i=t&&t.condition,a=r(t);if(i){var l=(s.isArray(i)?i:[i]).map(function(t){var n=r(t);return o({test:p.predicate(e,t.selection)},n)});return c={},c[n]=l.concat(void 0!==a?[a]:[]),c}return void 0!==a?(u={},u[n]=a,u):{};var c,u}function a(e,t,n,r){var i=t.encoding,a=t.stack,o=m.stackable(e,i[e],t.scaleName(e),t.getScaleComponent(e),a,n);return s={},s[r||e]=o,s;var s}var o=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?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||i(this.parent)?S.assembleScales(this):[];r.length>0&&(t.scales=r);var a=this.assembleAxes();a.length>0&&(t.axes=a);var o=this.assembleLegends();return o.length>0&&(t.legends=o),t},e.prototype.hasDescendantWithFieldOnChannel=function(e){for(var t=0,n=this.children;t0){var r=n[0];return n.length>1&&(v.warn(v.message.MORE_THAN_ONE_SORT),r=!0),u({},s,{sort:r})}return s}var i=_.unique(n.map(function(e){return!0===e?e:"count"===e.op?e:(v.warn(v.message.domainSortDropped(e)),!0)}),_.hash),a=void 0;1===i.length?a=i[0]:i.length>1&&(v.warn(v.message.MORE_THAN_ONE_SORT),a=!0);var o=_.unique(e.map(function(e){return O.isDataRefDomain(e)?e.data:null}),function(e){return e});if(1===o.length&&null!==o[0]){var s;return s=u({data:o[0],fields:t.map(function(e){return e.field})},a?{sort:a}:{})}return u({fields:t},a?{sort:a}:{})}var u=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?Math.min.apply(null,e):t.rangeStep?t.rangeStep:21}Object.defineProperty(n,"__esModule",{value:!0});var o=e("vega-util"),s=e("../../channel"),l=e("../../log"),c=e("../../scale"),u=e("../../scale"),f=e("../../util"),d=e("../../vega.schema"),p=e("../model"),m=e("../split"),g=e("./properties");n.RANGE_PROPERTIES=["range","rangeStep","scheme"],n.parseScaleRange=function(e){p.isUnitModel(e)?function(e){var t=e.component.scales;s.SCALE_CHANNELS.forEach(function(n){var i=t[n];if(i){var a=e.getScaleComponent(n),s=e.specifiedScales[n],c=e.fieldDef(n),u="x"===n?"width":"y"===n?"height":void 0,p=u?!!e.component.layoutSize.get(u):void 0,m=a.get("type"),g=f.contains(["point","band"],m)||!!s.rangeStep;u&&e.fit&&!p&&g&&(l.warn(l.message.CANNOT_FIX_RANGE_STEP_WITH_FIT),p=!0);var h=function(e){var t=[],n=e.getScaleComponent("x"),r=n&&n.get("range");r&&d.isVgRangeStep(r)&&o.isNumber(r.step)&&t.push(r.step);var i=e.getScaleComponent("y"),a=i&&i.get("range");return a&&d.isVgRangeStep(a)&&o.isNumber(a.step)&&t.push(a.step),t}(e),v=r(n,m,c.type,s,e.config,i.get("zero"),e.mark(),p,e.getName(u),h);i.setWithExplicit("range",v)}})}(e):g.parseNonUnitScaleProperty(e,"range")},n.parseRangeForChannel=r,n.defaultRange=i},{"../../channel":15,"../../log":105,"../../scale":108,"../../util":118,"../../vega.schema":120,"../model":66,"../split":89,"./properties":74,"vega-util":10}],76:[function(e,t,n){"use strict";function r(e,t){var n=t.type;return u.contains([l.Type.ORDINAL,l.Type.NOMINAL],n)?void 0===e||s.hasDiscreteDomain(e):n===l.Type.TEMPORAL?u.contains([o.ScaleType.TIME,o.ScaleType.UTC,o.ScaleType.SEQUENTIAL,void 0],e):n!==l.Type.QUANTITATIVE||(t.bin?u.contains([o.ScaleType.BIN_LINEAR,o.ScaleType.BIN_ORDINAL,o.ScaleType.LINEAR],e):u.contains([o.ScaleType.LOG,o.ScaleType.POW,o.ScaleType.SQRT,o.ScaleType.QUANTILE,o.ScaleType.QUANTIZE,o.ScaleType.LINEAR,o.ScaleType.SEQUENTIAL,void 0],e))}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../channel"),a=e("../../log"),o=e("../../scale"),s=e("../../scale"),l=e("../../type"),c=e("../../util"),u=e("../../util");n.scaleType=function(e,t,n,s,l){var u=function(e,t,n,r){switch(t.type){case"nominal":case"ordinal":if("color"===e||"discrete"===i.rangeType(e))return"shape"===e&&"ordinal"===t.type&&a.warn(a.message.discreteChannelCannotEncode(e,"ordinal")),"ordinal";if(c.contains(["x","y"],e)){if("rect"===n)return"band";if("bar"===n)return"band"}return"point";case"temporal":return"color"===e?"sequential":"discrete"===i.rangeType(e)?(a.warn(a.message.discreteChannelCannotEncode(e,"temporal")),"ordinal"):"time";case"quantitative":return"color"===e?t.bin?"bin-ordinal":"sequential":"discrete"===i.rangeType(e)?(a.warn(a.message.discreteChannelCannotEncode(e,"quantitative")),"ordinal"):t.bin&&"x"!==e&&"y"!==e?"bin-linear":"linear"}throw new Error(a.message.invalidFieldType(t.type))}(t,n,s);return i.isScaleChannel(t)?void 0!==e?o.channelSupportScaleType(t,e)?r(e,n)?e:(a.warn(a.message.scaleTypeNotWorkWithFieldDef(e,u)),u):(a.warn(a.message.scaleTypeNotWorkWithChannel(t,e,u)),u):u:null},n.fieldDefMatchScaleType=r},{"../../channel":15,"../../log":105,"../../scale":108,"../../type":117,"../../util":118}],77:[function(e,t,n){"use strict";function r(e,t){return e.events.reduce(function(e,n){return n.between?t(e,n):(s.warn(n+" is not an ordered event stream for interval selections"),e)},[])}var i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n=0},n.selectionScaleDomain=function(e,t){var r=JSON.parse(t.signal.replace(n.SELECTION_DOMAIN,"")),i=d.varName(r.selection),o=e.component.selection&&e.component.selection[i];return o?(u.warn('Use "bind": "scales" to setup a binding for scales and selections within the same view.'),{signal:"null"}):(o=e.getSelectionComponent(i,r.selection),r.encoding||r.field||(r.field=o.project[0].field,o.project.length>1&&u.warn('A "field" or "encoding" must be specified when using a selection as a scale domain. Using "field": '+d.stringValue(r.field)+".")),{signal:a(o.type).scaleDomain+"("+d.stringValue(i+n.STORE)+", "+d.stringValue(r.encoding||null)+", "+d.stringValue(r.field||null)+("global"===o.resolve?")":", "+d.stringValue(o.resolve)+")")})},n.unitName=function(e){var t=d.stringValue(e.name),n=o(e);return n&&(t+=(n.facet.row?" + '_' + facet"+d.accessPath(n.field("row")):"")+(n.facet.column?" + '_' + facet"+d.accessPath(n.field("column")):"")),t},n.requiresSelectionId=function(e){var t=!1;return i(e,function(e){t=t||e.project.some(function(e){return e.field===f.SELECTION_ID})}),t},n.channelSignalName=function(e,t,n){return d.varName(e.name+"_"+("visual"===n?t:e.fields[t]))},n.positionalProjections=function(e){var t=null,n=null,r=null,i=null;return e.project.forEach(function(e,a){e.channel===c.X?(t=e,n=a):e.channel===c.Y&&(r=e,i=a)}),{x:t,xi:n,y:r,yi:i}}},{"../../channel":15,"../../log":105,"../../selection":109,"../../util":118,"../model":66,"./interval":77,"./multi":78,"./single":80,"./transforms/transforms":86,"vega-event-selector":9}],80:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../util"),i=e("./multi"),a=e("./selection"),o={predicate:"vlSingle",scaleDomain:"vlSingleDomain",signals:i.default.signals,topLevelSignals:function(e,t,n){var i=n.filter(function(e){return e.name===t.name}),o="data("+r.stringValue(t.name+a.STORE)+")",s=o+"[0].values";return i.length?n:n.concat({name:t.name,update:o+".length && {"+t.project.map(function(e,t){return e.field+": "+s+"["+t+"]"}).join(", ")+"}"})},modifyExpr:function(e,t){return t.name+a.TUPLE+", "+("global"===t.resolve?"true":"{unit: "+a.unitName(e)+"}")}};n.default=o},{"../../util":118,"./multi":78,"./selection":79}],81:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../../util"),i=e("../selection"),a=e("./nearest"),o={has:function(e){return"single"===e.type&&"global"===e.resolve&&e.bind&&"scales"!==e.bind},topLevelSignals:function(e,t,n){var i=t.name,o=t.project,s=t.bind,l=a.default.has(t)?"(item().isVoronoi ? datum.datum : datum)":"datum";return o.forEach(function(e){var a=r.varName(i+"_"+e.field);n.filter(function(e){return e.name===a}).length||n.unshift({name:a,value:"",on:[{events:t.events,update:"datum && item().mark.marktype !== 'group' ? "+l+r.accessPath(e.field)+" : null"}],bind:s[e.field]||s[e.channel]||s})}),n},signals:function(e,t,n){var a=t.name,o=t.project,s=n.filter(function(e){return e.name===a+i.TUPLE})[0],l=o.map(function(e){return r.stringValue(e.field)}).join(", "),c=o.map(function(e){return r.varName(a+"_"+e.field)});return s.update=c.join(" && ")+" ? {fields: ["+l+"], values: ["+c.join(", ")+"]} : null",delete s.value,delete s.on,n}};n.default=o},{"../../../util":118,"../selection":79,"./nearest":82}],82:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../../log"),i=e("../selection"),a={has:function(e){return"interval"!==e.type&&e.nearest},marks:function(e,t,n){var a=i.positionalProjections(t),o=a.x,s=a.y,l=e.mark();if("line"===l||"area"===l)return r.warn(r.message.nearestNotSupportForContinuous(l)),n;var c={name:e.getName("voronoi"),type:"path",from:{data:e.getName("marks")},encode:{enter:{fill:{value:"transparent"},strokeWidth:{value:.35},stroke:{value:"transparent"},isVoronoi:{value:!0}}},transform:[{type:"voronoi",x:o||!o&&!s?"datum.x":{expr:"0"},y:s||!o&&!s?"datum.y":{expr:"0"},size:[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")]}]},u=0,f=!1;return n.forEach(function(t,n){var r=t.name||"";r===e.component.mark[0].name?u=n:r.indexOf("voronoi")>=0&&(f=!0)}),f||n.splice(u+1,0,c),n}};n.default=a},{"../../../log":105,"../selection":79}],83:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../../log"),i=e("../../../util"),a=e("../../data/timeunit"),o={has:function(e){var t=e;return void 0!==t.fields||void 0!==t.encodings},parse:function(e,t,n){var o={},s={};(t.fields||[]).forEach(function(e){return o[e]=null}),(t.encodings||[]).forEach(function(t){var n=e.fieldDef(t);if(n)if(n.timeUnit){var i=e.field(t);o[i]=t,s[i]={as:i,field:n.field,timeUnit:n.timeUnit}}else o[n.field]=t;else r.warn(r.message.cannotProjectOnChannelWithoutField(t))});var l=n.project||(n.project=[]);for(var c in o)o.hasOwnProperty(c)&&l.push({field:c,channel:o[c]});var u=n.fields||(n.fields={});l.filter(function(e){return e.channel}).forEach(function(e){return u[e.channel]=e.field}),i.keys(s).length&&(n.timeUnit=new a.TimeUnitNode(s))}};n.default=o},{"../../../log":105,"../../../util":118,"../../data/timeunit":43}],84:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../../log"),i=e("../../../scale"),a=e("../../../util"),o=e("../selection"),s={has:function(e){return"interval"===e.type&&"global"===e.resolve&&e.bind&&"scales"===e.bind},parse:function(e,t,n){var a=n.scales=[];n.project.forEach(function(t){var s=t.channel,l=e.getScaleComponent(s),c=l?l.get("type"):void 0;l&&i.hasContinuousDomain(c)&&!i.isBinScale(c)?(l.set("domainRaw",{signal:o.channelSignalName(n,s,"data")},!0),a.push(s)):r.warn(r.message.SCALE_BINDINGS_CONTINUOUS)})},topLevelSignals:function(e,t,n){if(!e.parent)return n;var r=t.scales.filter(function(e){return!n.filter(function(n){return n.name===o.channelSignalName(t,e,"data")}).length});return n.concat(r.map(function(e){return{name:o.channelSignalName(t,e,"data")}}))},signals:function(e,t,n){return e.parent&&t.scales.forEach(function(e){var r=n.filter(function(n){return n.name===o.channelSignalName(t,e,"data")})[0];r.push="outer",delete r.value,delete r.update}),n}};n.default=s,n.domain=function(e,t){return"domain("+a.stringValue(e.scaleName(t))+")"}},{"../../../log":105,"../../../scale":108,"../../../util":118,"../selection":79}],85:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../selection"),i={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 i=t.name+r.TUPLE,a=t.name+"_toggle";return a+" ? null : "+i+", "+("global"===t.resolve?a+" ? null : true, ":a+" ? null : {unit: "+r.unitName(e)+"}, ")+a+" ? "+i+" : null"}};n.default=i},{"../selection":79}],86:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./inputs"),i=e("./nearest"),a=e("./project"),o=e("./scales"),s=e("./toggle"),l=e("./translate"),c=e("./zoom"),u={project:a.default,toggle:s.default,scales:o.default,translate:l.default,zoom:c.default,inputs:r.default,nearest:i.default};n.forEachTransform=function(e,t){for(var n in u)u[n].has(e)&&t(u[n])}},{"./inputs":81,"./nearest":82,"./project":83,"./scales":84,"./toggle":85,"./translate":87,"./zoom":88}],87:[function(e,t,n){"use strict";function r(e,t,n,r,i){var o=t.name,f=l.default.has(t),d=i.filter(function(e){return e.name===s.channelSignalName(t,n,f?"data":"visual")})[0],p=o+c,m=o+u,g=e.getSizeSignalRef(r).signal,h=e.getScaleComponent(n),v=h.get("type"),y=f&&n===a.X?"-":"",b=p+".extent_"+n,_=(f?"log"===v?"panLog":"pow"===v?"panPow":"panLinear":"panLinear")+"("+b+", "+(""+y+m+"."+n+" / "+(f?""+g:"span("+b+")"))+(f&&"pow"===v?", "+(h.get("exponent")||1):"")+")";d.on.push({events:{signal:m},update:f?_:"clampRange("+_+", 0, "+g+")"})}Object.defineProperty(n,"__esModule",{value:!0});var i=e("vega-event-selector"),a=e("../../../channel"),o=e("../interval"),s=e("../selection"),l=e("./scales"),c="_translate_anchor",u="_translate_delta",f={has:function(e){return"interval"===e.type&&e.translate},signals:function(e,t,n){var f=t.name,d=l.default.has(t),p=f+c,m=s.positionalProjections(t),g=m.x,h=m.y,v=i.selector(t.translate,"scope");return d||(v=v.map(function(e){return e.between[0].markname=f+o.BRUSH,e})),n.push({name:p,value:{},on:[{events:v.map(function(e){return e.between[0]}),update:"{x: x(unit), y: y(unit)"+(null!==g?", extent_x: "+(d?l.domain(e,a.X):"slice("+s.channelSignalName(t,"x","visual")+")"):"")+(null!==h?", extent_y: "+(d?l.domain(e,a.Y):"slice("+s.channelSignalName(t,"y","visual")+")"):"")+"}"}]},{name:f+u,value:{},on:[{events:v,update:"{x: "+p+".x - x(unit), y: "+p+".y - y(unit)}"}]}),null!==g&&r(e,t,a.X,"width",n),null!==h&&r(e,t,a.Y,"height",n),n}};n.default=f},{"../../../channel":15,"../interval":77,"../selection":79,"./scales":84,"vega-event-selector":9}],88:[function(e,t,n){"use strict";function r(e,t,n,r,i){var a=t.name,o=c.default.has(t),s=i.filter(function(e){return e.name===l.channelSignalName(t,n,o?"data":"visual")})[0],d=e.getSizeSignalRef(r).signal,p=e.getScaleComponent(n),m=p.get("type"),g=o?c.domain(e,n):s.name,h=a+f,v=(o?"log"===m?"zoomLog":"pow"===m?"zoomPow":"zoomLinear":"zoomLinear")+"("+g+", "+(""+a+u+"."+n)+", "+h+(o&&"pow"===m?", "+(p.get("exponent")||1):"")+")";s.on.push({events:{signal:h},update:o?v:"clampRange("+v+", 0, "+d+")"})}Object.defineProperty(n,"__esModule",{value:!0});var i=e("vega-event-selector"),a=e("../../../channel"),o=e("../../../util"),s=e("../interval"),l=e("../selection"),c=e("./scales"),u="_zoom_anchor",f="_zoom_delta",d={has:function(e){return"interval"===e.type&&e.zoom},signals:function(e,t,n){var d=t.name,p=c.default.has(t),m=d+f,g=l.positionalProjections(t),h=g.x,v=g.y,y=o.stringValue(e.scaleName(a.X)),b=o.stringValue(e.scaleName(a.Y)),_=i.selector(t.zoom,"scope");return p||(_=_.map(function(e){return e.markname=d+s.BRUSH,e})),n.push({name:d+u,on:[{events:_,update:p?"{"+[y?"x: invert("+y+", x(unit))":"",b?"y: invert("+b+", y(unit))":""].filter(function(e){return!!e}).join(", ")+"}":"{x: x(unit), y: y(unit)}"}]},{name:m,on:[{events:_,force:!0,update:"pow(1.001, event.deltaY * pow(16, event.deltaMode))"}]}),null!==h&&r(e,t,"x","width",n),null!==v&&r(e,t,"y","height",n),n}};n.default=d},{"../../../channel":15,"../../../util":118,"../interval":77,"../selection":79,"./scales":84,"vega-event-selector":9}],89:[function(e,t,n){"use strict";function r(e,t,n,r){return e.explicit&&t.explicit&&a.warn(a.message.mergeConflictingProperty(n,r,e.value,t.value)),e}var i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?t:o<0?n:r(t,n,i,a)}},n.defaultTieBreaker=r,n.mergeValuesWithExplicit=function(e,t,n,i,a){return void 0===a&&(a=r),void 0===e||void 0===e.value?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:e.value===t.value?e:a(e,t,n,i)}},{"../log":105,"../util":118}],90:[function(e,t,n){"use strict";var r=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n-1?e[r]=t:f.warn(f.message.incompatibleChannel(r,n.BOXPLOT)),e},{})})}var a=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&(e.style[n||t]=a),delete e[t]}var i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0?e:void 0}},{"./compositemark":94,"./compositemark/index":94,"./guide":102,"./legend":104,"./mark":107,"./scale":108,"./selection":109,"./title":114,"./util":118}],96:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.isUrlData=function(e){return!!e.url},n.isInlineData=function(e){return!!e.values},n.isNamedData=function(e){return!!e.name},n.MAIN="main",n.RAW="raw"},{}],97:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./log"),i=e("./util"),a=2006;n.isDateTime=function(e){return!(!e||!(e.year||e.quarter||e.month||e.date||e.day||e.hours||e.minutes||e.seconds||e.milliseconds))},n.MONTHS=["january","february","march","april","may","june","july","august","september","october","november","december"],n.SHORT_MONTHS=n.MONTHS.map(function(e){return e.substr(0,3)}),n.DAYS=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],n.SHORT_DAYS=n.DAYS.map(function(e){return e.substr(0,3)}),n.dateTimeExpr=function(e,t){void 0===t&&(t=!1);var o=[];if(t&&void 0!==e.day&&i.keys(e).length>1&&(r.warn(r.message.droppedDay(e)),delete(e=i.duplicate(e)).day),void 0!==e.year?o.push(e.year):void 0!==e.day?o.push(a):o.push(0),void 0!==e.month){var s=t?function(e){if(i.isNumber(e))return e-1+"";var t=e.toLowerCase(),a=n.MONTHS.indexOf(t);if(-1!==a)return a+"";var o=t.substr(0,3),s=n.SHORT_MONTHS.indexOf(o);if(-1!==s)return s+"";throw new Error(r.message.invalidTimeUnit("month",e))}(e.month):e.month;o.push(s)}else if(void 0!==e.quarter){var l=t?function(e){if(i.isNumber(e))return e>4&&r.warn(r.message.invalidTimeUnit("quarter",e)),e-1+"";throw new Error(r.message.invalidTimeUnit("quarter",e))}(e.quarter):e.quarter;o.push(l+"*3")}else o.push(0);if(void 0!==e.date)o.push(e.date);else if(void 0!==e.day){var c=t?function(e){if(i.isNumber(e))return e%7+"";var t=e.toLowerCase(),a=n.DAYS.indexOf(t);if(-1!==a)return a+"";var o=t.substr(0,3),s=n.SHORT_DAYS.indexOf(o);if(-1!==s)return s+"";throw new Error(r.message.invalidTimeUnit("day",e))}(e.day):e.day;o.push(c+"+1")}else o.push(1);for(var u=0,f=["hours","minutes","seconds","milliseconds"];u= "+c(r,e.timeUnit)),null!==s&&l.push(n+" <= "+c(s,e.timeUnit)),l.length>0?l.join(" && "):"true"}throw new Error("Invalid field filter: "+JSON.stringify(e))}function c(e,t){if(d.isDateTime(e)){return"time("+(r=d.dateTimeExpr(e,!0))+")"}if(m.isLocalSingleTimeUnit(t)){var n={};n[t]=e;var r=d.dateTimeExpr(n,!0);return"time("+r+")"}return m.isUtcSingleTimeUnit(t)?c(e,m.getLocalTimeUnit(t)):JSON.stringify(e)}var u=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n window:mousemove!",encodings:["x","y"],translate:"[mousedown, window:mouseup] > window:mousemove!",zoom:"wheel!",mark:{fill:"#333",fillOpacity:.125,stroke:"white"},resolve:"global"}}},{}],110:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.isSortField=function(e){return!(!e||"count"!==e.op&&!e.field||!e.op)}},{}],111:[function(e,t,n){"use strict";function r(e){return void 0!==e.facet}function i(e){return!!e.mark}function a(e){return void 0!==e.layer}function o(e){return void 0!==e.repeat}function s(e){return l(e)||c(e)}function l(e){return void 0!==e.vconcat}function c(e){return void 0!==e.hconcat}function u(e,t){if(r(e))return function(e,t){var n=e.spec,r=h(e,["spec"]);return g({},r,{spec:u(n,t)})}(e,t);if(a(e))return f(e,t);if(o(e))return function(e,t){var n=e.spec,r=h(e,["spec"]);return g({},r,{spec:u(n,t)})}(e,t);if(l(e))return function(e,t){var n=e.vconcat,r=h(e,["vconcat"]);return g({},r,{vconcat:n.map(function(e){return u(e,t)})})}(e,t);if(c(e))return function(e,t){var n=e.hconcat,r=h(e,["hconcat"]);return g({},r,{hconcat:n.map(function(e){return u(e,t)})})}(e,t);if(i(e)){var n=b.channelHasField(e.encoding,v.ROW),s=b.channelHasField(e.encoding,v.COLUMN);return n||s?function(e,t){var n=e.encoding,r=n.row,i=n.column,a=h(n,["row","column"]),o=e.mark,s=e.width,l=e.height,c=e.selection,u=(e.encoding,h(e,["mark","width","height","selection","encoding"]));return g({},u,{facet:g({},r?{row:r}:{},i?{column:i}:{}),spec:d(g({mark:o},s?{width:s}:{},l?{height:l}:{},{encoding:a},c?{selection:c}:{}),t)})}(e,t):d(e,t)}throw new Error(O.message.INVALID_SPEC)}function f(e,t){var n=e.layer,r=h(e,["layer"]);return g({},r,{layer:n.map(function(e){return a(e)?f(e,t):d(e,t)})})}function d(e,t){if(function(e){return S.isPrimitiveMark(e.mark)}(e)){if(b.isRanged(e.encoding))return function(e){var t=b.channelHasField(e.encoding,v.X),n=b.channelHasField(e.encoding,v.Y),r=b.channelHasField(e.encoding,v.X2),i=b.channelHasField(e.encoding,v.Y2);if(r&&!t||i&&!n){var a=w.duplicate(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);var n=t&&t.overlay,r=n&&e.mark===S.AREA&&w.contains(["linepoint","line"],n.area),i=n&&(n.line&&e.mark===S.LINE||"linepoint"===n.area&&e.mark===S.AREA);return i||r?function(e,t,n,r){var i=e.mark,a=e.selection,o=e.encoding,s=h(e,["mark","selection","encoding"]),l=[{mark:i,encoding:o}],c=x.stack(i,o,r?r.stack:void 0),u=o;if(c){var f=c.fieldChannel,d=c.offset;u=g({},o,(p={},p[f]=g({},o[f],d?{stack:d}:{}),p))}n&&l.push(g({mark:{type:"line",style:"lineOverlay"}},a?{selection:a}:{},{encoding:u}));t&&l.push(g({mark:{type:"point",filled:!0,style:"pointOverlay"}},a?{selection:a}:{},{encoding:u}));return g({},s,{layer:l});var p}(e,i,r,t):e}return y.normalize(e,t)}function p(e,t){return t.forEach(function(t){var n=["field","type","value","timeUnit","bin","aggregate"].reduce(function(e,n){return void 0!==t[n]&&(e[n]=t[n]),e},{}),r=w.hash(n);e[r]=e[r]||t}),e}function m(e,t){if(void 0===t&&(t={}),a(e))e.layer.forEach(function(e){i(e)?p(t,_.fieldDefs(e.encoding)):m(e,t)});else if(r(e))p(t,_.fieldDefs(e.facet)),m(e.spec,t);else if(o(e))m(e.spec,t);else if(s(e)){(l(e)?e.vconcat:e.hconcat).forEach(function(e){return m(e,t)})}else p(t,_.fieldDefs(e.encoding));return t}var g=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n-1&&(t!==s.SECONDS||0===n||"i"!==e.charAt(n-1))}var o=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&u.push(i.join(" ")),c.length>0&&u.push(c.join(":")),u.length>0&&(o&&(o+=" + ' ' + "),o+=r?"utcFormat("+t+", '"+u.join(" ")+"')":"timeFormat("+t+", '"+u.join(" ")+"')"),o||void 0}},n.normalizeTimeUnit=function(e){return"day"!==e&&e.indexOf("day")>=0?(c.warn(c.message.dayReplacedWithDate(e)),e.replace("day","date")):e}},{"./datetime":97,"./log":105,"./util":118}],114:[function(e,t,n){"use strict";var r=this&&this.__assign||Object.assign||function(e){for(var t,n=1,r=arguments.length;n-1}function i(e,t){return e.filter(function(e){return!r(t,e)})}function a(e){for(var t=[],n=1;n0&&r;){for(var i=e,a=0;a= '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","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n","module.exports = function isBuffer(arg) {\n return arg && typeof arg === 'object'\n && typeof arg.copy === 'function'\n && typeof arg.fill === 'function'\n && typeof arg.readUInt8 === 'function';\n}","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n if (!isString(f)) {\n var objects = [];\n for (var i = 0; i < arguments.length; i++) {\n objects.push(inspect(arguments[i]));\n }\n return objects.join(' ');\n }\n\n var i = 1;\n var args = arguments;\n var len = args.length;\n var str = String(f).replace(formatRegExp, function(x) {\n if (x === '%%') return '%';\n if (i >= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n // Allow for deprecating things in the process of starting up.\n if (isUndefined(global.process)) {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n if (process.noDeprecation === true) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = process.env.NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.vega = global.vega || {})));\n}(this, (function (exports) { 'use strict';\n\n/**\n * Parse an event selector string.\n * Returns an array of event stream definitions.\n */\nvar eventSelector = 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';\nvar LBRACK = '[';\nvar RBRACK = ']';\nvar LBRACE = '{';\nvar RBRACE = '}';\nvar COLON = ':';\nvar COMMA = ',';\nvar NAME = '@';\nvar GT = '>';\nvar ILLEGAL = /[[\\]{}]/;\nvar DEFAULT_SOURCE;\nvar MARKS;\nvar 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\nexports.selector = eventSelector;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.vega = global.vega || {})));\n}(this, (function (exports) { 'use strict';\n\nvar accessor = function(fn, fields, name) {\n fn.fields = fields || [];\n fn.fname = name;\n return fn;\n};\n\nfunction accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nfunction accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n\nvar error = function(message) {\n throw Error(message);\n};\n\nvar splitAccessPath = 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\nvar isArray = Array.isArray;\n\nvar isObject = function(_) {\n return _ === Object(_);\n};\n\nvar isString = function(_) {\n return typeof _ === 'string';\n};\n\nfunction $(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\nvar field = function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map($).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n};\n\nvar empty = [];\n\nvar id = field('id');\n\nvar identity = accessor(function(_) { return _; }, empty, 'identity');\n\nvar zero = accessor(function() { return 0; }, empty, 'zero');\n\nvar one = accessor(function() { return 1; }, empty, 'one');\n\nvar truthy = accessor(function() { return true; }, empty, 'true');\n\nvar falsy = accessor(function() { return false; }, empty, 'false');\n\nfunction 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\nvar None = 0;\nvar Error$1 = 1;\nvar Warn = 2;\nvar Info = 3;\nvar Debug = 4;\n\nvar logger = 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$1) 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\nvar peek = function(array) {\n return array[array.length - 1];\n};\n\nvar toNumber = function(_) {\n return _ == null || _ === '' ? null : +_;\n};\n\nfunction exp(sign) {\n return function(x) { return sign * Math.exp(x); };\n}\n\nfunction log$1(sign) {\n return function(x) { return Math.log(sign * x); };\n}\n\nfunction pow(exponent) {\n return function(x) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n };\n}\n\nfunction pan(domain, delta, lift, ground) {\n var d0 = lift(domain[0]),\n d1 = lift(peek(domain)),\n dd = (d1 - d0) * delta;\n\n return [\n ground(d0 - dd),\n ground(d1 - dd)\n ];\n}\n\nfunction panLinear(domain, delta) {\n return pan(domain, delta, toNumber, identity);\n}\n\nfunction panLog(domain, delta) {\n var sign = Math.sign(domain[0]);\n return pan(domain, delta, log$1(sign), exp(sign));\n}\n\nfunction panPow(domain, delta, exponent) {\n return pan(domain, delta, pow(exponent), pow(1/exponent));\n}\n\nfunction zoom(domain, anchor, scale, lift, ground) {\n var d0 = lift(domain[0]),\n d1 = lift(peek(domain)),\n da = anchor != null ? lift(anchor) : (d0 + d1) / 2;\n\n return [\n ground(da + (d0 - da) * scale),\n ground(da + (d1 - da) * scale)\n ];\n}\n\nfunction zoomLinear(domain, anchor, scale) {\n return zoom(domain, anchor, scale, toNumber, identity);\n}\n\nfunction zoomLog(domain, anchor, scale) {\n var sign = Math.sign(domain[0]);\n return zoom(domain, anchor, scale, log$1(sign), exp(sign));\n}\n\nfunction zoomPow(domain, anchor, scale, exponent) {\n return zoom(domain, anchor, scale, pow(exponent), pow(1/exponent));\n}\n\nvar array = function(_) {\n return _ != null ? (isArray(_) ? _ : [_]) : [];\n};\n\nvar isFunction = function(_) {\n return typeof _ === 'function';\n};\n\nvar compare = function(fields, orders) {\n var idx = [],\n cmp = (fields = array(fields)).map(function(f, i) {\n if (f == null) {\n return null;\n } else {\n idx.push(i);\n return isFunction(f) ? f\n : splitAccessPath(f).map($).join('][');\n }\n }),\n n = idx.length - 1,\n ord = array(orders),\n code = 'var u,v;return ',\n i, j, f, u, v, d, t, lt, gt;\n\n if (n < 0) return null;\n\n for (j=0; j<=n; ++j) {\n i = idx[j];\n f = cmp[i];\n\n if (isFunction(f)) {\n d = 'f' + i;\n u = '(u=this.' + d + '(a))';\n v = '(v=this.' + d + '(b))';\n (t = t || {})[d] = f;\n } else {\n u = '(u=a['+f+'])';\n v = '(v=b['+f+'])';\n }\n\n d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))';\n\n if (ord[i] !== 'descending') {\n gt = 1;\n lt = -1;\n } else {\n gt = -1;\n lt = 1;\n }\n\n code += '(' + u+'<'+v+'||u==null)&&v!=null?' + lt\n + ':(u>v||v==null)&&u!=null?' + gt\n + ':'+d+'!==u&&v===v?' + lt\n + ':v!==v&&u===u?' + gt\n + (i < n ? ':' : ':0');\n }\n\n f = Function('a', 'b', code + ';');\n if (t) f = f.bind(t);\n\n fields = fields.reduce(function(map, field) {\n if (isFunction(field)) {\n (accessorFields(field) || []).forEach(function(_) { map[_] = 1; });\n } else if (field != null) {\n map[field + ''] = 1;\n }\n return map;\n }, {});\n\n return accessor(f, Object.keys(fields));\n};\n\nvar constant = function(_) {\n return isFunction(_) ? _ : function() { return _; };\n};\n\nvar debounce = function(delay, handler) {\n var tid, evt;\n\n function callback() {\n handler(evt);\n tid = evt = null;\n }\n\n return function(e) {\n evt = e;\n if (tid) clearTimeout(tid);\n tid = setTimeout(callback, delay);\n };\n};\n\nvar extend = function(_) {\n for (var x, k, i=1, len=arguments.length; i= b) {\n a = c = b;\n break;\n }\n }\n u = v = i;\n while (++i < n) {\n b = array[i];\n if (b != null) {\n if (a > b) {\n a = b;\n u = i;\n }\n if (c < b) {\n c = b;\n v = i;\n }\n }\n }\n } else {\n while (++i < n) {\n b = f(array[i], i, array);\n if (b != null && b >= b) {\n a = c = b;\n break;\n }\n }\n u = v = i;\n while (++i < n) {\n b = f(array[i], i, array);\n if (b != null) {\n if (a > b) {\n a = b;\n u = i;\n }\n if (c < b) {\n c = b;\n v = i;\n }\n }\n }\n }\n\n return [u, v];\n};\n\nvar NULL = {};\n\nvar fastmap = function(input) {\n var obj = {},\n map,\n test;\n\n function has(key) {\n return obj.hasOwnProperty(key) && obj[key] !== NULL;\n }\n\n map = {\n size: 0,\n empty: 0,\n object: obj,\n has: has,\n get: function(key) {\n return has(key) ? obj[key] : undefined;\n },\n set: function(key, value) {\n if (!has(key)) {\n ++map.size;\n if (obj[key] === NULL) --map.empty;\n }\n obj[key] = value;\n return this;\n },\n delete: function(key) {\n if (has(key)) {\n --map.size;\n ++map.empty;\n obj[key] = NULL;\n }\n return this;\n },\n clear: function() {\n map.size = map.empty = 0;\n map.object = obj = {};\n },\n test: function(_) {\n if (arguments.length) {\n test = _;\n return map;\n } else {\n return test;\n }\n },\n clean: function() {\n var next = {},\n size = 0,\n key, value;\n for (key in obj) {\n value = obj[key];\n if (value !== NULL && (!test || !test(value))) {\n next[key] = value;\n ++size;\n }\n }\n map.size = size;\n map.empty = 0;\n map.object = (obj = next);\n }\n };\n\n if (input) Object.keys(input).forEach(function(key) {\n map.set(key, input[key]);\n });\n\n return map;\n};\n\nvar inherits = function(child, parent) {\n var proto = (child.prototype = Object.create(parent.prototype));\n proto.constructor = child;\n return proto;\n};\n\nvar isBoolean = function(_) {\n return typeof _ === 'boolean';\n};\n\nvar isDate = function(_) {\n return Object.prototype.toString.call(_) === '[object Date]';\n};\n\nvar isNumber = function(_) {\n return typeof _ === 'number';\n};\n\nvar isRegExp = function(_) {\n return Object.prototype.toString.call(_) === '[object RegExp]';\n};\n\nvar key = function(fields, flat) {\n if (fields) {\n fields = flat\n ? array(fields).map(function(f) { return f.replace(/\\\\(.)/g, '$1'); })\n : array(fields);\n }\n\n var fn = !(fields && fields.length)\n ? function() { return ''; }\n : Function('_', 'return \\'\\'+' +\n fields.map(function(f) {\n return '_[' + (flat\n ? $(f)\n : splitAccessPath(f).map($).join('][')\n ) + ']';\n }).join('+\\'|\\'+') + ';');\n\n return accessor(fn, fields, 'key');\n};\n\nvar merge = function(compare, array0, array1, output) {\n var n0 = array0.length,\n n1 = array1.length;\n\n if (!n1) return array0;\n if (!n0) return array1;\n\n var merged = output || new array0.constructor(n0 + n1),\n i0 = 0, i1 = 0, i = 0;\n\n for (; i0 0\n ? array1[i1++]\n : array0[i0++];\n }\n\n for (; i0= 0) s += str;\n return s;\n};\n\nvar pad = function(str, length, padchar, align) {\n var c = padchar || ' ',\n s = str + '',\n n = length - s.length;\n\n return n <= 0 ? s\n : align === 'left' ? repeat(c, n) + s\n : align === 'center' ? repeat(c, ~~(n/2)) + s + repeat(c, Math.ceil(n/2))\n : s + repeat(c, n);\n};\n\nvar toBoolean = function(_) {\n return _ == null || _ === '' ? null : !_ || _ === 'false' || _ === '0' ? false : !!_;\n};\n\nfunction defaultParser(_) {\n return isNumber(_) ? _ : isDate(_) ? _ : Date.parse(_);\n}\n\nvar toDate = function(_, parser) {\n parser = parser || defaultParser;\n return _ == null || _ === '' ? null : parser(_);\n};\n\nvar toString = function(_) {\n return _ == null || _ === '' ? null : _ + '';\n};\n\nvar toSet = function(_) {\n for (var s={}, i=0, n=_.length; i (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 provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.\",\n \"main\": \"build/src/index.js\",\n \"types\": \"typings/vega-lite.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 \"pretsc\": \"mkdir -p build && rm -rf build/*/** && cp package.json build/\",\n \"tsc\": \"tsc\",\n \"prebuild\": \"mkdir -p build/site build/test-gallery\",\n \"build\": \"npm run build:only\",\n \"build:only\": \"npm run tsc && cp package.json build && browserify src/index.ts -p tsify -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js\",\n \"postbuild\": \"node node_modules/uglify-js/bin/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 && npm run build:only && npm run build:examples-only\",\n \"build:examples-only\": \"npm run build:example && npm run build:examples-normalized\",\n \"build:examples-normalized\": \"rm -f examples/specs/normalized/*.vl.json && scripts/build-normalized-examples\",\n \"build:example\": \"TZ=America/Los_Angeles scripts/build-examples.sh\",\n\n \"build:toc\": \"bundle exec jekyll build -q && scripts/generate-toc\",\n \"build:site\": \"browserify site/static/main.ts -p [tsify -p site] -d | exorcist build/site/main.js.map > build/site/main.js\",\n \"build:versions\": \"scripts/update-version.sh\",\n \"build:test-gallery\": \"browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js\",\n \"check:examples\": \"scripts/check-examples.sh\",\n \"check:schema\": \"scripts/check-schema.sh\",\n \"clean\": \"rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\\\.(js|js.map|d.ts)' -delete && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -exec rm -f {} +\",\n \"data\": \"rsync -r node_modules/vega-datasets/data/* data\",\n \"link\": \"npm link && npm link vega-lite\",\n\n \"deploy\": \"scripts/deploy.sh\",\n \"deploy:gh\": \"scripts/deploy-gh.sh\",\n \"deploy:schema\": \"scripts/deploy-schema.sh\",\n\n \"prestart\": \"npm run data && npm run build && scripts/index-examples\",\n \"start\": \"nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'\",\n \"poststart\": \"rm examples/all-examples.json\",\n\n \"preschema\": \"npm run prebuild\",\n \"schema\": \"ts-json-schema-generator --path tsconfig.json --type TopLevelExtendedSpec > 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\n \"lint\": \"tslint -p .\",\n \"test\": \"npm run build:only && npm run test:only && npm run test:runtime && npm run lint\",\n \"posttest\": \"npm run schema && npm run data && npm run mocha:examples\",\n \"test:nocompile\": \"npm run test:only && npm run test:runtime && npm run lint && npm run mocha:examples\",\n \"test:only\": \"nyc --reporter=html --reporter=text-summary npm run mocha:test\",\n \"test:runtime\": \"TZ=America/Los_Angeles wdio wdio.conf.js\",\n \"test:runtime:generate\": \"rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime\",\n \"test:debug\": \"npm run tsc && mocha --recursive --debug-brk --inspect build/test\",\n \"test:debug-examples\": \"npm run tsc && npm run schema && mocha --recursive --debug-brk --inspect build/examples\",\n \"mocha:test\": \"mocha --require source-map-support/register --reporter dot --recursive build/test\",\n \"mocha:examples\": \"mocha --require source-map-support/register --reporter dot --recursive build/examples\",\n\n \"codecov\": \"nyc report --reporter=json && codecov -f coverage/*.json\",\n \"watch:build\": \"watchify src/index.ts -p tsify -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'\",\n \"watch:tsc\": \"npm run tsc -- -w\",\n \"watch:test\": \"nodemon -x 'npm test'\",\n \"watch\": \"nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build\"\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.0.6\",\n \"@types/d3\": \"^4.12.0\",\n \"@types/highlight.js\": \"^9.12.2\",\n \"@types/json-stable-stringify\": \"^1.0.32\",\n \"@types/mkdirp\": \"^0.5.1\",\n \"@types/mocha\": \"^2.2.44\",\n \"@types/node\": \"^8.0.53\",\n \"@types/webdriverio\": \"^4.8.6\",\n \"ajv\": \"^5.5.0\",\n \"browser-sync\": \"^2.18.13\",\n \"browserify\": \"^14.5.0\",\n \"browserify-shim\": \"^3.8.14\",\n \"chai\": \"^4.1.2\",\n \"cheerio\": \"^1.0.0-rc.2\",\n \"chromedriver\": \"^2.33.2\",\n \"codecov\": \"^3.0.0\",\n \"d3\": \"^4.12.0\",\n \"exorcist\": \"^1.0.0\",\n \"highlight.js\": \"^9.12.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^4.0.1\",\n \"nodemon\": \"^1.12.1\",\n \"nyc\": \"^11.3.0\",\n \"source-map-support\": \"^0.5.0\",\n \"svg2png-many\": \"^0.0.7\",\n \"ts-json-schema-generator\": \"^0.18.0\",\n \"ts-node\": \"^3.3.0\",\n \"tsify\": \"^3.0.3\",\n \"tslint\": \"5.4.3\",\n \"tslint-eslint-rules\": \"^4.1.1\",\n \"typescript\": \"^2.6.2\",\n \"uglify-js\": \"^3.2.0\",\n \"vega\": \"^3.0.8\",\n \"vega-datasets\": \"^1.11.0\",\n \"vega-embed\": \"^3.0.0-rc7\",\n \"vega-tooltip\": \"^0.4.4\",\n \"watchify\": \"^3.9.0\",\n \"wdio-chromedriver-service\": \"^0.1.1\",\n \"wdio-dot-reporter\": \"0.0.9\",\n \"wdio-mocha-framework\": \"^0.5.11\",\n \"wdio-static-server-service\": \"^1.0.1\",\n \"webdriverio\": \"^4.9.11\",\n \"yaml-front-matter\": \"^3.4.0\"\n },\n \"dependencies\": {\n \"json-stable-stringify\": \"^1.0.1\",\n \"tslib\": \"^1.8.0\",\n \"vega-event-selector\": \"^2.0.0\",\n \"vega-util\": \"^1.6.2\",\n \"yargs\": \"^10.0.3\"\n }\n}\n","import {contains, Flag, flagKeys, toSet} from './util';\n\n\nexport type AggregateOp = 'argmax' | 'argmin' | 'average' | 'count'\n | 'distinct' | 'max' | 'mean' | 'median' | 'min' | 'missing'\n | 'q1' | 'q3' | 'ci0' | 'ci1' | 'stdev' | 'stdevp' | 'sum' | 'valid' | 'values' | 'variance'\n | 'variancep';\n\n\nconst AGGREGATE_OP_INDEX: Flag = {\n values: 1,\n count: 1,\n valid: 1,\n missing: 1,\n distinct: 1,\n sum: 1,\n mean: 1,\n average: 1,\n variance: 1,\n variancep: 1,\n stdev: 1,\n stdevp: 1,\n median: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n min: 1,\n max: 1,\n argmin: 1,\n argmax: 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](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[] | 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/**\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'\n} = {\n grid: 'grid',\n labelOverlap: 'main',\n offset: 'main',\n title: 'main'\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](axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](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","import {Channel, COLOR, COLUMN, OPACITY, ROW, SHAPE, SIZE} from './channel';\nimport {isBoolean, keys} 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 * 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 => `_${p}_${bin[p]}`.replace(',', '_')).join('');\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 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","/*\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 {SCALE_TYPES, ScaleType} from './scale';\nimport {contains, 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 // Mark property with scale\n export const COLOR: 'color' = 'color';\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 TOOLTIP: 'tooltip' = 'tooltip';\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;\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;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\nexport const TOOLTIP = Channel.TOOLTIP;\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n size: 1,\n shape: 1,\n color: 1,\n order: 1,\n opacity: 1,\n text: 1,\n detail: 1,\n tooltip: 1\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 projecttion 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' | 'row' | 'column' | 'size' | 'shape' | 'color' | 'opacity' | 'text' | 'tooltip';\n\n\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 // 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 has format instead of scale\n text: _t, tooltip: _tt,\n // detail and order have no scale\n detail: _dd, 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 interface SupportedMark {\n point?: boolean;\n tick?: boolean;\n rule?: boolean;\n circle?: boolean;\n square?: boolean;\n bar?: boolean;\n rect?: boolean;\n line?: boolean;\n area?: boolean;\n text?: boolean;\n tooltip?: 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 X:\n case Y:\n case COLOR:\n case DETAIL:\n case TOOLTIP:\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, area: true, text: true\n };\n case X2:\n case Y2:\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\n };\n case SHAPE:\n return {point: 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 and TOOLTIP have no scale but have discrete output\n case TEXT:\n case TOOLTIP:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n return 'flexible';\n\n // No scale, no range type.\n case DETAIL:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('getSupportedRole not implemented for ' + channel);\n}\n","import {VgAxis} from '../../vega.schema';\nimport {AxisComponent, AxisComponentIndex} from './component';\n\n\nconst mainAxisReducer = getAxisReducer('main');\nconst gridAxisReducer = getAxisReducer('grid');\n\nfunction getAxisReducer(axisType: 'main' | 'grid') {\n return (axes: VgAxis[], axis: AxisComponent) => {\n if (axis[axisType]) {\n // Need to cast here so it's not longer partial type.\n axes.push(axis[axisType].combine() as VgAxis);\n }\n return axes;\n };\n}\n\nexport function assembleAxes(axisComponents: AxisComponentIndex): VgAxis[] {\n return [].concat(\n axisComponents.x ? [].concat(\n axisComponents.x.reduce(mainAxisReducer, []),\n axisComponents.x.reduce(gridAxisReducer, [])\n ) : [],\n axisComponents.y ? [].concat(\n axisComponents.y.reduce(mainAxisReducer, []),\n axisComponents.y.reduce(gridAxisReducer, []),\n ) : []\n );\n}\n\n","import {Axis} from '../../axis';\nimport {VgAxis} from '../../vega.schema';\nimport {Split} from '../split';\n\nexport class AxisComponentPart extends Split> {}\n\nexport interface AxisComponent {\n main?: AxisComponentPart;\n grid?: AxisComponentPart;\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 labelsSpec.text = {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale)\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 && channel === 'x') {\n const align = labelAlign(angle, orient);\n if (align) {\n labelsSpec.align = {value: align};\n }\n\n // Auto set baseline if x is rotated by 90, or -90\n if (contains([90, 270], angle)) {\n labelsSpec.baseline = {value: 'middle'};\n }\n }\n\n labelsSpec = {\n ...labelsSpec,\n ...specifiedLabelsSpec\n };\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\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 if (angle > 0) {\n if (angle % 360 > 180) {\n return orient === 'top' ? 'left' : 'right';\n } else if (angle % 360 < 180) {\n return orient === 'top' ? 'right': 'left';\n }\n } else if (angle < 0) {\n return labelAlign((angle % 360) + 360 /* convert to positive value*/, orient);\n }\n return undefined;\n}\n\n","import {Axis, AXIS_PROPERTY_TYPE, AxisEncoding, isAxisProperty, VG_AXIS_PROPERTIES} from '../../axis';\nimport {POSITION_SCALE_CHANNELS, PositionScaleChannel} from '../../channel';\nimport {keys, some} from '../../util';\nimport {AxisOrient, VgAxis, VgAxisEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, numberFormat, titleMerger} from '../common';\nimport {LayerModel} from '../layer';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {AxisComponent, AxisComponentIndex, AxisComponentPart} from './component';\nimport {getAxisConfig} from './config';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\ntype AxisPart = keyof AxisEncoding;\nconst AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\nexport function parseUnitAxis(model: UnitModel): AxisComponentIndex {\n return POSITION_SCALE_CHANNELS.reduce(function(axis, channel) {\n if (model.axis(channel)) {\n const axisComponent: AxisComponent = {};\n // TODO: support multiple axis\n const main = parseMainAxis(channel, model);\n if (main && isVisibleAxis(main)) {\n axisComponent.main = main;\n }\n\n const grid = parseGridAxis(channel, model);\n if (grid && isVisibleAxis(grid)) {\n axisComponent.grid = grid;\n }\n\n axis[channel] = [axisComponent];\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.main.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.main.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 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 mergedMain = mergedAxisCmpts[i].main;\n const childMain = childAxisCmpts[i].main;\n\n if ((!!mergedMain) !== (!!childMain)) {\n return undefined;\n } else if (mergedMain && childMain) {\n const mergedOrient = mergedMain.getWithExplicit('orient');\n const childOrient = childMain.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 // Cannot merge due to inconsistent orient\n return undefined;\n } else {\n mergedAxisCmpts[i].main = mergeAxisComponentPart(mergedMain, childMain);\n }\n }\n\n const mergedGrid = mergedAxisCmpts[i].grid;\n const childGrid = childAxisCmpts[i].grid;\n if ((!!mergedGrid) !== (!!childGrid)) {\n return undefined;\n } else if (mergedGrid && childGrid) {\n mergedAxisCmpts[i].grid = mergeAxisComponentPart(mergedGrid, childGrid);\n }\n }\n } else {\n // For first one, return a copy of the child\n return childAxisCmpts.map(axisComponent => ({\n ...(axisComponent.main ? {main: axisComponent.main.clone()} : {}),\n ...(axisComponent.grid ? {grid: axisComponent.grid.clone()} : {})\n }));\n }\n return mergedAxisCmpts;\n}\n\nfunction mergeAxisComponentPart(merged: AxisComponentPart, child: AxisComponentPart): AxisComponentPart {\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 titleMerger(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 isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\n/**\n * Return if an axis is visible (shows at least one part of the axis).\n */\nfunction isVisibleAxis(axis: AxisComponentPart) {\n return some(AXIS_PARTS, (part) => hasAxisPart(axis, part));\n}\n\nfunction hasAxisPart(axis: AxisComponentPart, 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') {\n return true;\n }\n\n if (part === 'grid' || part === 'title') {\n return !!axis.get(part);\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(axis.get(part));\n}\n\n/**\n * Make an inner axis for showing grid for shared axis.\n */\nexport function parseGridAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponentPart {\n // FIXME: support adding ticks for grid axis that are inner axes of faceted plots.\n return parseAxis(channel, model, true);\n}\n\nexport function parseMainAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponentPart {\n return parseAxis(channel, model, false);\n}\n\nfunction parseAxis(channel: PositionScaleChannel, model: UnitModel, isGridAxis: boolean): AxisComponentPart {\n const axis = model.axis(channel);\n\n const axisComponent = new AxisComponentPart();\n\n // 1.2. Add properties\n VG_AXIS_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, axis, channel, model, isGridAxis);\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 value === axis[property];\n\n const configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type'));\n\n if (\n explicit || configValue === undefined ||\n // A lot of rules need to be applied for the grid axis\n // FIXME: this is not perfectly correct, but we need to rewrite axis component to have one axis and separate them later during assembly anyway.\n isGridAxis\n ) {\n // Do not apply implicit rule if there is a config value\n axisComponent.set(property, value, explicit);\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 (!hasAxisPart(axisComponent, part)) {\n // No need to create encode for a disabled part.\n return e;\n }\n\n const value = part === 'labels' ?\n encode.labels(model, channel, axisEncoding.labels || {}, axisComponent.get('orient')) :\n axisEncoding[part] || {};\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);\n }\n\n return axisComponent;\n}\n\nfunction getProperty(property: K, specifiedAxis: Axis, channel: PositionScaleChannel, model: UnitModel, isGridAxis: boolean): VgAxis[K] {\n const fieldDef = model.fieldDef(channel);\n\n if ((isGridAxis && AXIS_PROPERTY_TYPE[property] === 'main') ||\n (!isGridAxis && AXIS_PROPERTY_TYPE[property] === 'grid')) {\n // Do not apply unapplicable properties\n return undefined;\n }\n\n switch (property) {\n case 'scale':\n return model.scaleName(channel);\n case 'gridScale':\n return properties.gridScale(model, channel, isGridAxis);\n\n case 'domain':\n return properties.domain(property, specifiedAxis, isGridAxis, 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 'labels':\n return isGridAxis ? false : specifiedAxis.labels;\n case 'labelFlush':\n return properties.labelFlush(fieldDef, channel, specifiedAxis, isGridAxis);\n case 'labelOverlap': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType);\n }\n case 'minExtent': {\n return properties.minMaxExtent(specifiedAxis.minExtent, isGridAxis);\n }\n case 'maxExtent': {\n return properties.minMaxExtent(specifiedAxis.maxExtent, isGridAxis);\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 'ticks':\n return properties.ticks(property, specifiedAxis, isGridAxis, channel);\n case 'title':\n return getSpecifiedOrDefaultValue(specifiedAxis.title, properties.title(specifiedAxis.titleMaxLength, fieldDef, model.config));\n case 'values':\n return properties.values(specifiedAxis, model, fieldDef);\n case 'zindex':\n return getSpecifiedOrDefaultValue(specifiedAxis.zindex, properties.zindex(isGridAxis));\n }\n // Otherwise, return specified property.\n return isAxisProperty(property) ? specifiedAxis[property] : undefined;\n}\n","import {Axis} from '../../axis';\nimport {binToString} from '../../bin';\nimport {PositionScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {DateTime, dateTimeExpr, isDateTime} from '../../datetime';\nimport {FieldDef, title as fieldDefTitle} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {QUANTITATIVE} from '../../type';\nimport {contains, truncate} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {UnitModel} from '../unit';\n\n\nexport function domainAndTicks(property: 'domain' | 'ticks', specifiedAxis: Axis, isGridAxis: boolean, channel: PositionScaleChannel) {\n if (isGridAxis) {\n return false;\n }\n return specifiedAxis[property];\n}\n\nexport const domain = domainAndTicks;\nexport const ticks = domainAndTicks;\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, isGridAxis: boolean) {\n if (isGridAxis) {\n const gridChannel: PositionScaleChannel = channel === 'x' ? 'y' : 'x';\n if (model.getScaleComponent(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n }\n return undefined;\n}\n\nexport function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis, isGridAxis: boolean) {\n if (isGridAxis) {\n return undefined;\n }\n\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 minMaxExtent(specifiedExtent: number, isGridAxis: boolean) {\n if (isGridAxis) {\n // Always return 0 to make sure that `config.axis*.minExtent` and `config.axis*.maxExtent`\n // would not affect gridAxis\n return 0;\n } else {\n return specifiedExtent;\n }\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) {\n const vals = specifiedAxis.values;\n if (specifiedAxis.values && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return {signal: dateTimeExpr(dt, true)};\n });\n }\n\n if (!vals && fieldDef.bin && fieldDef.type === QUANTITATIVE) {\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 vals;\n}\n\nexport function zindex(isGridAxis: boolean) {\n if (isGridAxis) {\n // if grid is true, need to put layer on the back so that grid is behind marks\n return 0;\n }\n return 1; // otherwise return undefined and use Vega's default.\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';\n\nexport abstract class BaseConcatModel extends Model {\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, resolve: Resolve) {\n super(spec, parent, parentGivenName, config, 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), []);\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 {isConcatSpec, isFacetSpec, isLayerSpec, isRepeatSpec, isUnitSpec, LayoutSizeMixins, Spec} 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: Spec, 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 {Channel, isScaleChannel} from '../channel';\nimport {Config, ViewConfig} from '../config';\nimport {field, FieldDef, FieldRefOption, isScaleFieldDef, isTimeFieldDef, OrderFieldDef} from '../fielddef';\nimport {MarkConfig, MarkDef, TextConfig} from '../mark';\nimport {ScaleType} from '../scale';\nimport {TimeUnit} from '../timeunit';\nimport {formatExpression} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {contains, isArray} from '../util';\nimport {VgEncodeEntry, VgMarkConfig, VgSort} from '../vega.schema';\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 = field(fieldDef, {expr});\n const endField = field(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(field(fieldDef, {expr}), format)}`\n };\n } else if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC;\n return {\n signal: timeFormatExpression(field(fieldDef, {expr}), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale)\n };\n } else {\n return {\n signal: `''+${field(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): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n const _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n if (isUTCScale) {\n return `utcFormat(${field}, '${_format}')`;\n } else {\n return `timeFormat(${field}, '${_format}')`;\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(field(orderChannelDef, fieldRefOption));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n\nexport function titleMerger(v1: Explicit, v2: Explicit) {\n return {\n explicit: v1.explicit, // keep the old explicit\n value: v1.value === v2.value ?\n v1.value : // if title is the same just use one of them\n v1.value + ', ' + v2.value // join title with comma if different\n };\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","import {Config, initConfig, stripAndRedirectConfig} from '../config';\nimport * as vlFieldDef from '../fielddef';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, normalize, TopLevel, TopLevelExtendedSpec} 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\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: TopLevelExtendedSpec, 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 (components = intermediate that can be merged\n // and assembled easily)\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 and 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 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.0.json',\n ...(model.description ? {description: model.description} : {}),\n ...topLevelProperties,\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n data: [].concat(\n model.assembleSelectionData([]),\n // only assemble data in the root\n assembleRootData(model.component.data)\n ),\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 {Config} from '../config';\nimport * as log from '../log';\nimport {ConcatSpec, isVConcatSpec} 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: ConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, 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 public assembleLayout(): VgLayout {\n // TODO: allow customization\n return {\n padding: {row: 10, column: 10},\n offset: 10,\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 {AggregateOp} from '../../aggregate';\nimport {Channel, isScaleChannel} from '../../channel';\nimport {field, FieldDef} 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[field(fieldDef, {})] = true;\n dims[field(fieldDef, {binSuffix: 'end'})] = true;\n\n if (binRequiresRange(fieldDef, channel)) {\n dims[field(fieldDef, {binSuffix: 'range'})] = true;\n }\n } else {\n dims[field(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({...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(private dimensions: StringSet, private measures: Dict<{[key in AggregateOp]?: string}>) {\n super();\n }\n\n public static makeFromEncoding(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 if (fieldDef.aggregate) {\n if (fieldDef.aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = field(fieldDef, {aggregate: 'count'});\n } else {\n meas[fieldDef.field] = meas[fieldDef.field] || {};\n meas[fieldDef.field][fieldDef.aggregate] = field(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[fieldDef.field]['min'] = field(fieldDef, {aggregate: 'min'});\n meas[fieldDef.field]['max'] = field(fieldDef, {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(dims, meas);\n }\n\n public static makeFromTransform(t: AggregateTransform): AggregateNode {\n const dims = {};\n const meas = {};\n for(const s of t.aggregate) {\n if (s.op) {\n if (s.op === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = s.as || field(s);\n } else {\n meas[s.field] = meas[s.field] || {};\n meas[s.field][s.op] = s.as || field(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(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 {isUrlData} from '../../data';\nimport {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 {IdentifierNode} from './indentifier';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\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 } 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 AggregateNode ||\n node instanceof LookupNode ||\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): 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 data.sort((a, b) => (a.transform || []).length === 0 ? -1 : ((b.transform || []).length === 0 ? 1 : 0));\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 return data;\n}\n","import {BinParams, binToString} from '../../bin';\nimport {Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {field, FieldDef, normalizeBin} 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\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 = field(fieldDef, {expr: 'datum',});\n const endField = field(fieldDef, {expr: 'datum', binSuffix: 'end'});\n\n return {\n formulaAs: field(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 isModelParams(p: {model: Model} | {signal?: string, extentSignal?: string}): p is {model: Model} {\n return !!p['model'];\n}\n\nfunction getSignalsFromParams(\n params: {model: Model} | {signal?: string, extentSignal?: string},\n key: string\n) {\n if (isModelParams(params)) {\n const model = params.model;\n return {\n signal: model.getName(`${key}_bins`),\n extentSignal: model.getName(`${key}_extent`)\n };\n }\n return params;\n}\n\nfunction isBinTransform(t: FieldDef | BinTransform): t is BinTransform {\n return 'as' in t;\n}\n\nfunction createBinComponent(\n t: FieldDef | BinTransform,\n params: {model: Model} | {signal?: string, extentSignal?: string}\n) {\n let as: [string, string];\n\n if (isBinTransform(t)) {\n as = [t.as, `${t.as}_end`];\n } else {\n as = [field(t, {}), field(t, {binSuffix: 'end'})];\n }\n\n const bin = normalizeBin(t.bin, undefined) || {};\n const key = binKey(bin, t.field);\n const {signal, extentSignal} = getSignalsFromParams(params, 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(duplicate(this.bins));\n }\n\n constructor(private bins: Dict) {\n super();\n }\n\n public static makeBinFromEncoding(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(bins);\n }\n\n /**\n * Creates a bin node from BinTransform.\n * The optional parameter should provide\n */\n public static makeFromTransform(t: BinTransform, params: {model: Model} | {signal?: string, extentSignal?: string}) {\n const {key, binComponent} = createBinComponent(t, params);\n return new BinNode({\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 {CalculateTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\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(duplicate(this.transform));\n }\n\n constructor(private transform: CalculateTransform) {\n super();\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","\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(public readonly debugName?: string) { }\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(source: string, public readonly type: DataSourceType, private readonly refCounts: Dict) {\n super(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 {AggregateOp} from '../../aggregate';\nimport {COLUMN, ROW, ScaleChannel} from '../../channel';\nimport * as log from '../../log';\nimport {hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep, VgAggregateTransform, VgData} from '../../vega.schema';\nimport {FacetModel} from '../facet';\nimport {Model} from '../model';\nimport {assembleDomain, getFieldFromDomain} from '../scale/domain';\nimport {DataFlowNode} from './dataflow';\n\ntype ChildIndependentFieldsWithStep = {\n x?: string,\n y?: 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 columnFields: string[];\n private readonly columnName: string;\n\n private readonly rowFields: string[];\n private readonly rowName: string;\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(public readonly model: FacetModel, public readonly name: string, public data: string) {\n super();\n\n if (model.facet.column) {\n this.columnFields = [model.field(COLUMN)];\n this.columnName = model.getName('column_domain');\n if (model.fieldDef(COLUMN).bin) {\n this.columnFields.push(model.field(COLUMN, {binSuffix: 'end'}));\n }\n }\n\n if (model.facet.row) {\n this.rowFields = [model.field(ROW)];\n this.rowName = model.getName('row_domain');\n if (model.fieldDef(ROW).bin) {\n this.rowFields.push(model.field(ROW, {binSuffix: 'end'}));\n }\n }\n\n this.childModel = model.child;\n }\n\n get fields() {\n let fields: string[] = [];\n if (this.columnFields) {\n fields = fields.concat(this.columnFields);\n }\n if (this.rowFields) {\n fields = fields.concat(this.rowFields);\n }\n return fields;\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 let aggregateChildField: Partial = {};\n const childChannel = channel === 'row' ? 'y' : 'x';\n\n if (childIndependentFieldsWithStep[childChannel]) {\n if (crossedDataName) {\n aggregateChildField = {\n // If there is a crossed data, calculate max\n fields: [`distinct_${childIndependentFieldsWithStep[childChannel]}`],\n ops: ['max'],\n // Although it is technically a max, just name it distinct so it's easier to refer to it\n as: [`distinct_${childIndependentFieldsWithStep[childChannel]}`]\n };\n } else {\n aggregateChildField = {\n // If there is no crossed data, just calculate distinct\n fields: [childIndependentFieldsWithStep[childChannel]],\n ops: ['distinct']\n };\n }\n }\n\n return {\n name: channel === 'row' ? this.rowName : this.columnName,\n // Use data from the crossed one if it exist\n source: crossedDataName || this.data,\n transform: [{\n type: 'aggregate',\n groupby: channel === 'row' ? this.rowFields : this.columnFields,\n ...aggregateChildField\n }]\n };\n }\n\n public assemble() {\n const data: VgData[] = [];\n let crossedDataName = null;\n const childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep();\n\n if (this.columnName && this.rowName && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) {\n // Need to create a cross dataset to correctly calculate cardinality\n crossedDataName = `cross_${this.columnName}_${this.rowName}`;\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.columnFields.concat(this.rowFields),\n fields: fields,\n ops\n }]\n });\n }\n\n if (this.columnName) {\n data.push(this.assembleRowColumnData('column', crossedDataName, childIndependentFieldsWithStep));\n }\n\n if (this.rowName) {\n data.push(this.assembleRowColumnData('row', crossedDataName, childIndependentFieldsWithStep));\n }\n\n return data;\n }\n}\n","import {expression, Filter} from '../../filter';\nimport {LogicalOperand} from '../../logical';\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(this.model, duplicate(this.filter));\n }\n\n constructor(private readonly model: Model, private filter: LogicalOperand) {\n super();\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 {isScaleChannel} from '../../channel';\nimport {field as fieldRef, FieldDef} from '../../fielddef';\nimport {hasContinuousDomain, ScaleType} from '../../scale';\nimport {Dict, keys} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterInvalidNode extends DataFlowNode {\n public clone() {\n return new FilterInvalidNode({...this.fieldDefs});\n }\n\n constructor(private fieldDefs: Dict>) {\n super();\n }\n\n public static make(model: ModelWithField): FilterInvalidNode {\n if (model.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 // only automatically filter null for continuous domain since discrete domain scales can handle invalid values.\n if (hasContinuousDomain(scaleType) && !fieldDef.aggregate) {\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(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\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 {isCountingAggregateOp} from '../../aggregate';\nimport {isNumberFieldDef, isTimeFieldDef} from '../../fielddef';\nimport {isEqualFilter, isOneOfFilter, isRangeFilter} from '../../filter';\nimport * as log from '../../log';\nimport {forEachLeave} from '../../logical';\nimport {isCalculate, isFilter, Transform} from '../../transform';\nimport {accessPath, Dict, duplicate, keys, toSet} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {DataFlowNode} from './dataflow';\n\n\nfunction parseExpression(field: string, parse: string): string {\n const f = `datum${accessPath(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.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(duplicate(this.parse));\n }\n\n constructor(parse: Dict) {\n super();\n\n this._parse = parse;\n }\n\n public static make(model: Model) {\n const parse = {};\n const calcFieldMap = {};\n\n (model.transforms || []).forEach((transform: Transform) => {\n if (isCalculate(transform)) {\n calcFieldMap[transform.as] = true;\n } else if (isFilter(transform)) {\n forEachLeave(transform.filter, (filter) => {\n if (isEqualFilter(filter) || isRangeFilter(filter) || isOneOfFilter(filter)) {\n if (filter.timeUnit) {\n parse[filter.field] = 'date';\n }\n }\n });\n }\n }, {});\n\n if (isUnitModel(model) || isFacetModel(model)) {\n // Parse encoded fields\n model.forEachFieldDef(fieldDef => {\n if (isTimeFieldDef(fieldDef)) {\n parse[fieldDef.field] = 'date';\n } else if (isNumberFieldDef(fieldDef)) {\n if (calcFieldMap[fieldDef.field] || isCountingAggregateOp(fieldDef.aggregate)) {\n return;\n }\n parse[fieldDef.field] = 'number';\n }\n });\n }\n\n // Custom parse should override inferred parse\n const data = model.data;\n if (data && data.format && data.format.parse) {\n const p = data.format.parse;\n keys(p).forEach(field => {\n parse[field] = p[field];\n });\n }\n\n // We should not parse what has already been parsed in a parent\n const modelParse = model.component.data.ancestorParse;\n keys(modelParse).forEach(field => {\n if (parse[field] !== modelParse[field]) {\n log.warn(log.message.differentParse(field, parse[field], modelParse[field]));\n } else {\n delete parse[field];\n }\n });\n\n if (keys(parse).length === 0) {\n return null;\n }\n\n return new ParseNode(parse);\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 public assembleFormatParse() {\n return this._parse;\n }\n\n // format parse depends and produces all fields in its parse\n public producedFields() {\n return toSet(keys(this.parse));\n }\n\n public dependentFields() {\n return toSet(keys(this.parse));\n }\n\n public assembleTransforms(): VgFormulaTransform[] {\n return keys(this._parse).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: field\n };\n return formula;\n }).filter(t => t !== null);\n }\n}\n","import {SELECTION_ID} from '../../selection';\nimport {VgIdentifierTransform} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class IdentifierNode extends DataFlowNode {\n public clone() {\n return new IdentifierNode();\n }\n\n constructor() {\n super();\n }\n\n public producedFields() {\n return {[SELECTION_ID]: true};\n }\n\n public assemble(): VgIdentifierTransform {\n return {type: 'identifier', as: SELECTION_ID};\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(public readonly transform: LookupTransform, public readonly secondary: string) {\n super();\n }\n\n public static make(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(fromOutputName, 'lookup', model.component.data.outputNodeRefCounts);\n fromOutputNode.parent = fromSource;\n\n model.component.data.outputNodes[fromOutputName] = fromOutputNode;\n\n return new LookupNode(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 {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 * Start optimization path from the root. Useful for removing nodes.\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 {hasIntersection, keys} from '../../util';\nimport {DataFlowNode, OutputNode} from './dataflow';\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 nodes.\n * The reason is that we don't need subtrees that don't have any output nodes.\n */\nexport function removeUnusedSubtrees(node: DataFlowNode) {\n if (node instanceof OutputNode || node.numChildren() > 0) {\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 {isNumber, isString} from 'vega-util';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime, isDateTime} from '../../datetime';\nimport {isEqualFilter, isOneOfFilter, isRangeFilter} from '../../filter';\nimport * as log from '../../log';\nimport {isAggregate, isBin, isCalculate, isFilter, isLookup, isTimeUnit} 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 {IdentifierNode} from './indentifier';\nimport {DataComponent} from './index';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\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(model: Model) {\n let first: DataFlowNode = null;\n let node: DataFlowNode;\n let previous: DataFlowNode;\n let lookupCounter = 0;\n\n function insert(newNode: DataFlowNode) {\n if (!first) {\n // A parent may be inserted during node construction\n // (e.g., selection FilterNodes may add a TimeUnitNode).\n first = newNode.parent || newNode;\n } else if (newNode.parent) {\n previous.insertAsParentOf(newNode);\n } else {\n newNode.parent = previous;\n }\n\n previous = newNode;\n }\n\n model.transforms.forEach(t => {\n if (isCalculate(t)) {\n node = new CalculateNode(t);\n } else if (isFilter(t)) {\n // Automatically add a parse node for filters with filter objects\n const parse = {};\n const filter = t.filter;\n let val: string | number | boolean | DateTime = null;\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 (isEqualFilter(filter)) {\n val = filter.equal;\n } else if (isRangeFilter(filter)) {\n val = filter.range[0];\n } else if (isOneOfFilter(filter)) {\n val = (filter.oneOf || filter['in'])[0];\n } // else -- for filter expression, we can't infer anything\n\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 (keys(parse).length > 0) {\n const parseNode = new ParseNode(parse);\n insert(parseNode);\n }\n\n node = new FilterNode(model, t.filter);\n } else if (isBin(t)) {\n node = BinNode.makeFromTransform(t, {model});\n } else if (isTimeUnit(t)) {\n node = TimeUnitNode.makeFromTransform(t);\n } else if (isAggregate(t)) {\n node = AggregateNode.makeFromTransform(t);\n\n if (requiresSelectionId(model)) {\n insert(node);\n node = new IdentifierNode();\n }\n } else if (isLookup(t)) {\n node = LookupNode.make(model, t, lookupCounter++);\n } else {\n log.warn(log.message.invalidTransformIgnored(t));\n return;\n }\n\n insert(node);\n });\n\n const last = node;\n\n return {first, last};\n}\n\n/*\nDescription of the dataflow (http://asciiflow.com/):\n +--------+\n | Source |\n +---+----+\n |\n v\n Transforms\n(Filter, Calculate, ...)\n |\n v\n FormatParse\n |\n v\n Binning\n |\n v\n Timeunit\n |\n v\n +--+--+\n | Raw |\n +-----+\n |\n v\n Aggregate\n |\n v\n Stack\n |\n v\n Path Order\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 const root = parseRoot(model, model.component.data.sources);\n\n const outputNodes = model.component.data.outputNodes;\n const outputNodeRefCounts = model.component.data.outputNodeRefCounts;\n\n // the current head of the tree that we are appending to\n let head = root;\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) && !model.parent) {\n const ident = new IdentifierNode();\n ident.parent = head;\n head = ident;\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 const bin = BinNode.makeBinFromEncoding(model);\n if (bin) {\n bin.parent = head;\n head = bin;\n }\n }\n }\n\n if (model.transforms.length > 0) {\n const {first, last} = parseTransformArray(model);\n first.parent = head;\n head = last;\n }\n\n const parse = ParseNode.make(model);\n if (parse) {\n parse.parent = head;\n head = parse;\n }\n\n if (isUnitModel(model) || isFacetModel(model)) {\n\n if (!parentIsLayer) {\n const bin = BinNode.makeBinFromEncoding(model);\n if (bin) {\n bin.parent = head;\n head = bin;\n }\n }\n\n const tu = TimeUnitNode.makeFromEncoding(model);\n if (tu) {\n tu.parent = head;\n head = tu;\n }\n }\n\n // add an output node pre aggregation\n const rawName = model.getName(RAW);\n const raw = new OutputNode(rawName, RAW, outputNodeRefCounts);\n outputNodes[rawName] = raw;\n raw.parent = head;\n head = raw;\n\n if (isUnitModel(model)) {\n const agg = AggregateNode.makeFromEncoding(model);\n if (agg) {\n agg.parent = head;\n head = agg;\n\n if (requiresSelectionId(model)) {\n const ident = new IdentifierNode();\n ident.parent = head;\n head = ident;\n }\n }\n\n const stack = StackNode.make(model);\n if (stack) {\n stack.parent = head;\n head = stack;\n }\n }\n\n if (isUnitModel(model)) {\n const filter = FilterInvalidNode.make(model);\n if (filter) {\n filter.parent = head;\n head = filter;\n }\n }\n\n // output node for marks\n const mainName = model.getName(MAIN);\n const main = new OutputNode(mainName, MAIN, outputNodeRefCounts);\n outputNodes[mainName] = main;\n main.parent = head;\n head = main;\n\n // add facet marker\n let facetRoot = null;\n if (isFacetModel(model)) {\n const facetName = model.getName('facet');\n facetRoot = new FacetNode(model, facetName, main.getSource());\n outputNodes[facetName] = facetRoot;\n facetRoot.parent = head;\n head = facetRoot;\n }\n\n // add the format parse from this model so that children don't parse the same field again\n const ancestorParse = {...model.component.data.ancestorParse, ...(parse ? parse.parse : {})};\n\n return {\n ...model.component.data,\n outputNodes,\n outputNodeRefCounts,\n raw,\n main,\n facetRoot,\n ancestorParse\n };\n}\n","import {Data, DataFormat, DataFormatType, isInlineData, isNamedData, isUrlData} from '../../data';\nimport {contains, duplicate, hash, keys} 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();\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', '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._name = data.name;\n this._data = {};\n }\n\n if (!isNamedData(data) && 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 {isArray} from 'vega-util';\nimport {field, FieldDef} from '../../fielddef';\nimport {StackOffset} from '../../stack';\nimport {duplicate} from '../../util';\nimport {VgSort, VgTransform} from '../../vega.schema';\nimport {sortParams} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\n\nfunction getStackByFields(model: UnitModel): string[] {\n return model.stack.stackBy.reduce((fields, by) => {\n const fieldDef = by.fieldDef;\n\n const _field = field(fieldDef);\n if (_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\nexport interface StackComponent {\n /**\n * Faceted field.\n */\n facetby: string[];\n\n dimensionFieldDef: FieldDef;\n\n /**\n * Stack measure's field\n */\n field: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n */\n stackby: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n */\n sort: VgSort;\n\n /** Mode for stacking marks. */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking.\n */\n impute: boolean;\n}\n\nexport class StackNode extends DataFlowNode {\n private _stack: StackComponent;\n\n public clone() {\n return new StackNode(duplicate(this._stack));\n }\n\n constructor(stack: StackComponent) {\n super();\n\n this._stack = stack;\n }\n\n public static make(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 (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\n return new StackNode({\n dimensionFieldDef,\n field: model.field(stackProperties.fieldChannel),\n facetby: [],\n stackby,\n sort,\n offset: stackProperties.offset,\n impute: stackProperties.impute,\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.field] = 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 const out = {};\n\n out[this._stack.field + '_start'] = true;\n out[this._stack.field + '_end'] = true;\n\n return out;\n }\n\n private getGroupbyFields() {\n const {dimensionFieldDef, impute} = 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 [field(dimensionFieldDef, {binSuffix: 'mid'})];\n }\n return [\n // For binned group by field without impute, we need both bin (start) and bin_end\n field(dimensionFieldDef, {}),\n field(dimensionFieldDef, {binSuffix: 'end'})\n ];\n }\n return [field(dimensionFieldDef)];\n }\n return [];\n }\n\n public assemble(): VgTransform[] {\n const transform: VgTransform[] = [];\n\n const {facetby, field: stackField, dimensionFieldDef, impute, offset, sort, stackby} = this._stack;\n\n // Impute\n if (impute && dimensionFieldDef) {\n const dimensionField = dimensionFieldDef ? field(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 field(dimensionFieldDef, {expr: 'datum'}) +\n '+' +\n field(dimensionFieldDef, {expr: 'datum', binSuffix: 'end'}) +\n ')/2',\n as: dimensionField\n });\n }\n\n transform.push({\n type: 'impute',\n field: stackField,\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: stackField,\n sort,\n as: [\n stackField + '_start',\n stackField + '_end'\n ],\n offset\n });\n\n return transform;\n }\n}\n","import {field} 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(duplicate(this.formula));\n }\n\n constructor(private formula: Dict) {\n super();\n }\n\n public static makeFromEncoding(model: ModelWithField) {\n const formula = model.reduceFieldDef((timeUnitComponent: TimeUnitComponent, fieldDef) => {\n if (fieldDef.timeUnit) {\n const f = field(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(formula);\n }\n\n public static makeFromTransform(t: TimeUnitTransform) {\n return new TimeUnitNode({\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 {AggregateOp} from '../aggregate';\nimport {Channel, COLUMN, ROW, ScaleChannel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {field, FieldDef, normalize, title as fieldDefTitle} from '../fielddef';\nimport * as log from '../log';\nimport {hasDiscreteDomain} from '../scale';\nimport {FacetSpec} from '../spec';\nimport {contains} from '../util';\nimport {isVgRangeStep, RowCol, VgAxis, VgData, VgLayout, VgMarkGroup, VgScale, VgSignal} from '../vega.schema';\nimport {buildModel} from './buildmodel';\nimport {assembleFacetData} from './data/assemble';\nimport {parseData} from './data/parse';\nimport {getHeaderType, HeaderChannel, HeaderComponent} from './layout/header';\nimport {parseChildrenLayoutSize} from './layoutsize/parse';\nimport {Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInFacet} from './repeater';\nimport {parseGuideResolve} from './resolve';\nimport {assembleScalesForModel} from './scale/assemble';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\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: FacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, 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 = 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 mainAxis = axisComponent.main;\n const headerType = getHeaderType(mainAxis.get('orient'));\n layoutHeader[headerType] = layoutHeader[headerType] ||\n [this.makeHeaderComponent(headerChannel, false)];\n\n // LayoutHeader no longer keep track of property precedence, thus let's combine.\n layoutHeader[headerType][0].axes.push(mainAxis.combine() as VgAxis);\n delete axisComponent.main;\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 getLayoutBandMixins(headerType: 'header' | 'footer'): {\n headerBand?: RowCol,\n footerBand?: RowCol\n } {\n const bandMixins = {};\n\n const bandType = headerType === 'header' ? 'headerBand' : 'footerBand';\n\n for (const channel of ['row', 'column'] as ('row' | 'column')[]) {\n const layoutHeaderComponent = this.component.layoutHeaders[channel];\n const headerComponent = layoutHeaderComponent[headerType];\n if (headerComponent && headerComponent[0]) {\n const sizeType = channel === 'row' ? 'height' : 'width';\n\n if (!this.child.component.layoutSize.get(sizeType)) {\n // If facet child does not have size signal, then apply headerBand\n bandMixins[bandType] = bandMixins[bandType] || {};\n bandMixins[bandType][channel] = 0.5;\n }\n }\n }\n return bandMixins;\n }\n\n public assembleLayout(): 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 padding: {row: 10, column: 10},\n ...this.getLayoutBandMixins('header'),\n ...this.getLayoutBandMixins('footer'),\n\n // TODO: support offset for rowHeader/rowFooter/rowTitle/columnHeader/columnFooter/columnTitle\n offset: 10,\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: field(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 if (this.child instanceof FacetModel) {\n if (this.child.channelHasField('column')) {\n fields.push(field(this.child.facet.column));\n ops.push('distinct');\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 } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n }\n return fields.length ? {fields, ops} : undefined;\n }\n\n public assembleMarks(): VgMarkGroup[] {\n const {child, facet} = 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 hasRow = this.channelHasField(ROW);\n const hasColumn = this.channelHasField(COLUMN);\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n\n const aggregateMixins: any = {};\n if (hasRow && hasColumn) {\n aggregateMixins.aggregate = {cross: true};\n }\n const cardinalityAggregateForChild = this.getCardinalityAggregateForChild();\n if (cardinalityAggregateForChild) {\n aggregateMixins.aggregate = {\n ...aggregateMixins.aggregate,\n ...cardinalityAggregateForChild\n };\n }\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: {\n name: facetRoot.name,\n data: facetRoot.data,\n groupby: [].concat(\n hasRow ? [this.field(ROW)] : [],\n hasColumn ? [this.field(COLUMN)] : []\n ),\n ...aggregateMixins\n }\n },\n sort: {\n field: [].concat(\n hasRow ? [this.field(ROW, {expr: 'datum',})] : [],\n hasColumn ? [this.field(COLUMN, {expr: 'datum'})] : []\n ),\n order: [].concat(\n hasRow ? [ (facet.row.sort) || 'ascending'] : [],\n hasColumn ? [ (facet.column.sort) || 'ascending'] : []\n )\n },\n ...(data.length > 0 ? {data: data} : {}),\n ...(layoutSizeEncodeEntry ? {encode: {update: layoutSizeEncodeEntry}} : {}),\n ...child.assembleGroup()\n };\n\n return [markGroup];\n }\n\n protected getMapping() {\n return this.facet;\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayerSpec, LayoutSizeMixins} 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: LayerSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean) {\n\n super(spec, parent, parentGivenName, config, 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), []);\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","/**\n * Utility for generating row / column headers\n */\nimport {FacetFieldDef} from '../../facet';\nimport {field} from '../../fielddef';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis} 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 getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent) {\n if (headerCmpt) {\n let title = null;\n if (layoutHeader.facetFieldDef && headerCmpt.labels) {\n const {facetFieldDef} = layoutHeader;\n const {header = {}} = facetFieldDef;\n const {format, labelAngle} = header;\n\n const update = {\n ...(\n labelAngle ? {angle: {value: labelAngle}} : {}\n )\n\n // TODO(https://github.com/vega/vega-lite/issues/2446): apply label* (e.g, labelAlign, labelBaseline) here\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 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: {\n field: field(layoutHeader.facetFieldDef, {expr: 'datum'}),\n order: (layoutHeader.facetFieldDef.header && layoutHeader.facetFieldDef.sort) || 'ascending'\n }\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","\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 {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 {\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 * as stringify from 'json-stable-stringify';\n\nimport {flatten, keys, 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 {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';\nimport {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE} from '../../channel';\nimport {FieldDef, FieldDefWithCondition, hasConditionalValueDef, isTimeFieldDef, isValueDef, MarkPropFieldDef, ValueDefWithCondition} from '../../fielddef';\nimport {AREA, BAR, CIRCLE, FILL_STROKE_CONFIG, LINE, POINT, SQUARE, TEXT, TICK} from '../../mark';\nimport {ScaleType} from '../../scale';\nimport {keys, without} from '../../util';\nimport {LegendType} 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) {\n if (type === 'gradient') {\n return undefined;\n }\n\n let symbols:any = {};\n const mark = model.mark();\n\n switch (mark) {\n case BAR:\n case TICK:\n case TEXT:\n symbols.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n symbols.shape = {value: mark};\n break;\n case POINT:\n case LINE:\n case AREA:\n // use default circle\n break;\n }\n\n const filled = model.markDef.filled;\n\n let config = channel === COLOR ?\n /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */\n without(FILL_STROKE_CONFIG, [ filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) :\n /* For other legend, no need to omit. */\n FILL_STROKE_CONFIG;\n\n config = without(config, ['strokeDash', 'strokeDashOffset']);\n\n applyMarkConfig(symbols, model, config);\n\n if (channel !== COLOR) {\n const colorMixins = mixins.color(model);\n\n // If there are field for fill or stroke, remove them as we already apply channels.\n if (colorMixins.fill && (colorMixins.fill['field'] || colorMixins.fill['value'] === 'transparent')) {\n delete colorMixins.fill;\n }\n if (colorMixins.stroke && (colorMixins.stroke['field'] || colorMixins.stroke['value'] === 'transparent')) {\n delete colorMixins.stroke;\n }\n symbols = {...symbols, ...colorMixins};\n }\n\n if (channel !== SHAPE) {\n const shapeDef = model.encoding.shape;\n if (isValueDef(shapeDef)) {\n symbols.shape = {value: shapeDef.value};\n }\n }\n\n if (channel !== OPACITY) {\n const opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n symbols.opacity = {value: opacity};\n }\n }\n\n symbols = {...symbols, ...symbolsSpec};\n\n return keys(symbols).length > 0 ? symbols : undefined;\n}\n\nexport function gradient(fieldDef: FieldDef, gradientSpec: any, model: UnitModel, channel: Channel, type: LegendType) {\n let gradient:any = {};\n\n if (type === 'gradient') {\n const opacity = getOpacityValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n gradient.opacity = {value: opacity};\n }\n }\n\n gradient = {...gradient, ...gradientSpec};\n return keys(gradient).length > 0 ? gradient : 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 labels: any = {};\n\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n labelsSpec = {\n text: {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale)\n },\n ...labelsSpec,\n };\n }\n\n labels = {...labels, ...labelsSpec};\n\n return keys(labels).length > 0 ? labels : undefined;\n}\n\nfunction getOpacityValue(opacityDef: FieldDefWithCondition> | ValueDefWithCondition>): number {\n if (isValueDef(opacityDef)) {\n if (hasConditionalValueDef(opacityDef)) {\n const values = isArray(opacityDef.condition) ? opacityDef.condition.map(c => c.value) : [opacityDef.condition.value];\n return Math.max.apply(null, [opacityDef.value].concat(values));\n } else {\n return opacityDef.value as number;\n }\n }\n return undefined;\n}\n","import {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE, SIZE} from '../../channel';\nimport {title as fieldDefTitle} from '../../fielddef';\nimport {Legend, LEGEND_PROPERTIES, VG_LEGEND_PROPERTIES} from '../../legend';\nimport {deleteNestedProperty, keys} from '../../util';\nimport {VgLegend, VgLegendEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, numberFormat, titleMerger} from '../common';\nimport {isUnitModel, Model} from '../model';\nimport {parseGuideResolve} from '../resolve';\nimport {Explicit, makeImplicit} from '../split';\nimport {defaultTieBreaker, 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 return [COLOR, SIZE, SHAPE, OPACITY].reduce(function(legendComponent, channel) {\n if (model.legend(channel)) {\n legendComponent[channel] = parseLegendForChannel(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: Channel): 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 SIZE:\n return {size: model.scaleName(SIZE)};\n case SHAPE:\n return {shape: model.scaleName(SHAPE)};\n case OPACITY:\n return {opacity: model.scaleName(OPACITY)};\n }\n return null;\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 = property === 'values' ?\n !!legend.values : // specified legend.values is already respected, but may get transformed.\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 value = encode[part] ?\n // TODO: replace legendCmpt with type is sufficient\n encode[part](fieldDef, legendEncoding[part], model, channel, legendCmpt.get('type')) : // apply rule\n legendEncoding[part]; // 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 return getSpecifiedOrDefaultValue(specifiedLegend.title, fieldDefTitle(fieldDef, model.config));\n case 'values':\n return properties.values(specifiedLegend);\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) {\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 titleMerger(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, COLOR} from '../../channel';\nimport {DateTime, dateTimeExpr, isDateTime} from '../../datetime';\nimport {Legend} from '../../legend';\nimport {isBinScale, ScaleType} from '../../scale';\nimport {Type} from '../../type';\nimport {contains} from '../../util';\n\nexport function values(legend: Legend) {\n const vals = legend.values;\n if (vals && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return {signal: dateTimeExpr(dt, true)};\n });\n }\n return vals;\n}\n\nexport function type(type: Type, channel: Channel, scaleType: ScaleType): 'gradient' {\n if (\n channel === COLOR && (\n (type === 'quantitative' && !isBinScale(scaleType)) ||\n (type === 'temporal' && contains(['time', 'utc'], scaleType))\n )\n ) {\n return 'gradient';\n }\n return undefined;\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.markDefProperties(model.markDef),\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', 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 {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {VgValueRef} from '../../vega.schema';\nimport {isVgRangeStep, VgEncodeEntry} 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 const stack = model.stack;\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...x(model, stack),\n ...y(model, stack),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model)\n };\n }\n};\n\nfunction x(model: UnitModel, stack: StackProperties): VgEncodeEntry {\n const {config, width} = model;\n const orient = model.markDef.orient;\n const sizeDef = model.encoding.size;\n\n const xDef = model.encoding.x;\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') {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\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'), config.bar.binSpacing, 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(xScaleName, xScale, config)\n );\n }\n}\n\nfunction y(model: UnitModel, stack: StackProperties) {\n const {config, encoding, height} = model;\n const orient = model.markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const yScaleName = model.scaleName(Y);\n const yScale = model.getScaleComponent(Y);\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical') {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\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'), config.bar.binSpacing, 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(yScaleName, yScale, config)\n );\n }\n}\n\nfunction defaultSizeRef(scaleName: string, scale: ScaleComponent, config: Config): VgValueRef {\n if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n }\n\n 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.band(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n }\n if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n return {value: 20};\n}\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 {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 || getMarkConfig('opacity', markDef, config);\n if (specifiedOpacity === undefined) {\n markDef.opacity = defaultOpacity(markDef.type, encoding);\n }\n\n const specifiedFilled = markDef.filled;\n if (specifiedFilled === undefined) {\n markDef.filled = filled(markDef, config);\n }\n return markDef;\n}\n\nfunction defaultOpacity(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 RULE:\n case BAR:\n case AREA:\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 /* tslint:disable */\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 if (!(mark === LINE && encoding.order)) {\n // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots.\n log.warn(log.message.unclearOrientContinuous(mark));\n }\n return 'vertical';\n } else {\n // For Discrete x Discrete case, return undefined.\n log.warn(log.message.unclearOrientDiscreteOrEmpty(mark));\n return undefined;\n }\n }\n return 'vertical';\n}\n\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n })\n };\n }\n};\n","import {isArray} from 'vega-util';\nimport {MAIN} from '../../data';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {field, getFieldDef} from '../../fielddef';\nimport {AREA, LINE} 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 {line} 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: {[type: string]: MarkCompiler} = {\n area: area,\n bar: bar,\n line: line,\n point: point,\n text: text,\n tick: tick,\n rect: rect,\n rule: rule,\n circle: circle,\n square: square\n};\n\n\nexport function parseMarkGroup(model: UnitModel): any[] {\n if (contains([LINE, AREA], model.mark())) {\n return parsePathMark(model);\n } else {\n return parseNonPathMark(model);\n }\n}\n\nconst FACETED_PATH_PREFIX = 'faceted_path_';\n\nfunction parsePathMark(model: UnitModel) {\n const mark = model.mark();\n const details = pathGroupingFields(model.encoding);\n\n const clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model);\n const style = getStyles(model.markDef);\n const sort = getPathSort(model);\n\n const pathMarks: any = [\n {\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style? {style} : {}),\n ...(sort? {sort} : {}),\n // If has subfacet for line/area group, need to use faceted data from below.\n // FIXME: support sorting path order (in connected scatterplot)\n from: {data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + model.requestDataName(MAIN)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n }\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 getPathSort(model: UnitModel) {\n if (model.mark() === 'line' && model.channelHasField('order')) {\n // For only line, sort by the order field if it is specified.\n return sortParams(model.encoding.order, {expr: 'datum'});\n } else {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannel: 'x' | 'y' = model.markDef.orient === 'horizontal' ? 'y' : 'x';\n const s = model.sort(dimensionChannel);\n const sortField = isSortField(s) ?\n field({\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 model.field(dimensionChannel, {\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 sortField ?\n {\n field: sortField,\n order: 'descending'\n } :\n undefined;\n }\n}\n\nfunction parseNonPathMark(model: UnitModel) {\n const mark = model.mark();\n\n const style = getStyles(model.markDef);\n const clip = model.markDef.clip !== undefined ? !!model.markDef.clip : scaleClip(model);\n\n const marks: any[] = []; // TODO: vgMarks\n\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n marks.push({\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style? {style} : {}),\n from: {data: model.requestDataName(MAIN)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n });\n\n return marks;\n}\n\n/**\n * Returns list of path grouping fields\n * that the model's spec contains.\n */\nexport function pathGroupingFields(encoding: Encoding): string[] {\n return keys(encoding).reduce((details, channel) => {\n switch (channel) {\n // x, y, x2, y2, order, tooltip, href, cursor should not cause lines to group\n case 'x':\n case 'y':\n case 'order':\n case 'tooltip':\n case 'x2':\n case 'y2':\n // TODO: case 'href', 'cursor':\n\n // text, shape, shouldn't be a part of line/area\n case 'text':\n case 'shape':\n return details;\n\n case 'detail':\n const channelDef = encoding[channel];\n if (channelDef) {\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (!fieldDef.aggregate) {\n details.push(field(fieldDef, {}));\n }\n });\n }\n return details;\n case 'color':\n case 'size':\n case 'opacity':\n // TODO strokeDashOffset:\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && !fieldDef.aggregate) {\n details.push(field(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 {isArray} from 'vega-util';\nimport {NONPOSITION_SCALE_CHANNELS} from '../../channel';\nimport {ChannelDef, FieldDef, getFieldDef, isValueDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport * as util from '../../util';\nimport {VG_MARK_CONFIGS, VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {predicate} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport * as ref from './valueref';\n\n\nexport function color(model: UnitModel) {\n const config = model.config;\n const filled = model.markDef.filled;\n const vgChannel = filled ? 'fill' : 'stroke';\n const e = nonPosition('color', model, {\n vgChannel,\n // Mark definition has higher predecence than config;\n // fill/stroke has higher precedence than color.\n defaultValue: model.markDef[vgChannel] ||\n model.markDef.color ||\n getMarkConfig(vgChannel, model.markDef, config) ||\n getMarkConfig('color', model.markDef, config)\n });\n\n // If there is no fill, always fill symbols\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) {\n e.fill = {value: 'transparent'};\n }\n return e;\n}\n\nexport function markDefProperties(mark: MarkDef, ignoreOrient?: boolean) {\n return VG_MARK_CONFIGS.reduce((m, prop) => {\n if (mark[prop] && (!ignoreOrient || prop !== 'orient')) {\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\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 // TODO: refactor how we refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\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 */\nfunction 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 return {\n test: predicate(model, c.selection),\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 text(model: UnitModel, channel: 'text' | 'tooltip' = 'text') {\n const channelDef = model.encoding[channel];\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) {\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 log.warn(log.message.cannotUseSizeFieldWithBandSize(channel));\n // TODO: apply size to band and set scale range to some values between 0-1.\n // return {\n // ...centeredBandPositionMixins,\n // ...bandSize('size', model, {vgChannel: sizeChannel})\n // };\n } else if (isValueDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\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.band(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 * 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, stack} = model;\n const valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.getScaleComponent(channel), stack, defaultRef);\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, markDef, stack} = model;\n channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2');\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n\n const valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.getScaleComponent(baseChannel), stack, defaultRef);\n return {[channel]: valueRef};\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.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n ...mixins.nonPosition('opacity', model),\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 {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...x(model),\n ...y(model),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction x(model: UnitModel) {\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\nfunction y(model: UnitModel) {\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\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) {\n // if we have neither x or y, show nothing\n return {};\n }\n\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)),\n ...mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)),\n ...mixins.pointPosition2(model, 'zeroOrMax'),\n\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's rule size is strokeWidth\n })\n };\n }\n};\n","import {X} from '../../channel';\nimport {Config} from '../../config';\nimport {channelHasField, Encoding} from '../../encoding';\nimport {ChannelDef, isFieldDef} from '../../fielddef';\nimport {MarkDef} from '../../mark';\nimport {QUANTITATIVE} from '../../type';\nimport {VgValueRef} 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\nexport const text: MarkCompiler = {\n vgMark: 'text',\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding, height} = model;\n const textDef = encoding.text;\n\n return {\n ...mixins.markDefProperties(model.markDef, true),\n ...mixins.pointPosition('x', model, xDefault(config, textDef)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.text(model),\n ...mixins.color(model),\n ...mixins.text(model, 'tooltip'),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(model.markDef, encoding, config))\n };\n }\n};\n\nfunction xDefault(config: Config, textDef: ChannelDef): VgValueRef {\n if (isFieldDef(textDef) && textDef.type === QUANTITATIVE) {\n return {field: {group: 'width'}, offset: -5};\n }\n // TODO: allow this to fit (Be consistent with ref.midX())\n return {value: config.scale.textXRangeStep / 2};\n}\n\nfunction align(markDef: MarkDef, encoding: Encoding, config: Config) {\n const align = markDef.align || getMarkConfig('align', markDef, config);\n if (align === undefined) {\n return channelHasField(encoding, X) ? 'center' : 'right';\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.markDefProperties(model.markDef, true),\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: config.tick.thickness},\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config} = model;\n const orient = model.markDef.orient;\n const scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y');\n\n 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","/**\n * Utility files for producing Vega ValueRef for marks\n */\nimport {Channel, X, X2, Y, Y2} from '../../channel';\nimport {Config} from '../../config';\nimport {\n ChannelDef,\n ChannelDefWithCondition,\n field,\n FieldDef,\n FieldRefOption,\n isFieldDef,\n isValueDef,\n TextFieldDef,\n} from '../../fielddef';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {contains} 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 stackable x or y\n */\nexport function stackable(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): 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 stackable x2 or y2\n */\nexport function stackable2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): 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 * 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 const ref: VgValueRef = {\n scale: scaleName,\n field: field(fieldDef, opt),\n };\n if (mixins) {\n return {\n ...ref,\n ...mixins\n };\n }\n return ref;\n}\n\nexport function band(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}\", ${field(fieldDef, {expr: 'datum'})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${field(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(channel: Channel, channelDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties,\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax',): 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 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 } else {\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n }\n } else if (isValueDef(channelDef)) {\n return {value: channelDef.value};\n } else {\n return undefined;\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMinX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMinY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n } else if (defaultRef === 'zeroOrMax') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMaxX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMaxY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n }\n return 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\nfunction zeroOrMinX(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the x-axis\n return {value: 0};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxX(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n return {field: {group: 'width'}};\n}\n\nfunction zeroOrMinY(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {field: {group: 'height'}};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxY(scaleName: string, scale: ScaleComponent): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.get('type')) &&\n scale.get('zero') !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {value: 0};\n}\n","import {isString} from 'vega-util';\n\nimport {Channel, isChannel, isScaleChannel, ScaleChannel, SingleDefChannel} from '../channel';\nimport {Config} from '../config';\nimport {Data, DataSourceType} from '../data';\nimport {forEach, reduce} from '../encoding';\nimport {ChannelDef, field, FieldDef, FieldRefOption, getFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {Resolve} from '../resolve';\nimport {hasDiscreteDomain} from '../scale';\nimport {BaseSpec} from '../spec';\nimport {extractTitleConfig, TitleParams} from '../title';\nimport {normalizeTransform, Transform} from '../transform';\nimport {contains, Dict, keys, varName} from '../util';\nimport {\n isVgRangeStep,\n VgAxis,\n VgData,\n VgEncodeEntry,\n VgLayout,\n VgLegend,\n VgMarkGroup,\n VgSignal,\n VgSignalRef,\n VgTitle,\n} from '../vega.schema';\nimport {assembleAxes} from './axis/assemble';\nimport {AxisComponentIndex} from './axis/component';\nimport {ConcatModel} from './concat';\nimport {DataComponent} from './data/index';\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {getHeaderGroup, getTitleGroup, HEADER_CHANNELS, HEADER_TYPES, LayoutHeaderComponent} from './layout/header';\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 {RepeatModel} from './repeat';\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/**\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 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\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\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected layoutSizeNameMap: NameMapInterface;\n\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, resolve: Resolve) {\n this.parent = parent;\n this.config = config;\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.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\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 ancestorParse: parent ? {...parent.component.data.ancestorParse} : {}\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 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.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections.\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 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 abstract assembleLayout(): VgLayout;\n\n public abstract assembleLayoutSignals(): VgSignal[];\n\n public assembleHeaderMarks(): VgMarkGroup[] {\n const {layoutHeaders} = this.component;\n const 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 const layoutHeader = layoutHeaders[channel];\n for (const headerType of HEADER_TYPES) {\n if (layoutHeader[headerType]) {\n for (const header of layoutHeader[headerType]) {\n const headerGroup = getHeaderGroup(this, channel, headerType, layoutHeader, header);\n if (headerGroup) {\n headerMarks.push(headerGroup);\n }\n }\n }\n }\n }\n return headerMarks;\n }\n\n public abstract assembleMarks(): VgMarkGroup[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return assembleAxes(this.component.axes);\n }\n\n public assembleLegends(): VgLegend[] {\n return assembleLegends(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 fieldName = getFieldFromDomain(domain);\n if (fieldName) {\n const fieldRef = field({aggregate: 'distinct', field: fieldName}, {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 /**\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 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 * 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(varName: string, origName: string): SelectionComponent {\n let sel = this.component.selection[varName];\n if (!sel && this.parent) {\n sel = this.parent.getSelectionComponent(varName, 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 field(channel: SingleDefChannel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (!fieldDef) {\n return undefined;\n }\n\n return field(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","\nimport {Config} from '../config';\nimport * as log from '../log';\nimport {Repeat} from '../repeat';\nimport {RepeatSpec} 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: RepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, 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: RepeatSpec, 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 public assembleLayout(): VgLayout {\n // TODO: allow customization\n return {\n padding: {row: 10, column: 10},\n offset: 10,\n columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1,\n bounds: 'full',\n align: 'all'\n };\n }\n}\n","import {Encoding} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {Field, FieldDef, hasConditionalFieldDef, isConditionalDef, isFieldDef, isRepeatRef, ValueDef} from '../fielddef';\nimport {ChannelDef, ScaleFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {isSortField} from '../sort';\nimport {isArray} from '../util';\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 {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 {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 = Partial>;\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 {SHARED_DOMAIN_OP_INDEX} from '../../aggregate';\nimport {binToString} from '../../bin';\nimport {isScaleChannel, ScaleChannel} from '../../channel';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime, dateTimeExpr, isDateTime} from '../../datetime';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Domain, hasDiscreteDomain, isBinScale, isSelectionDomain, ScaleConfig, ScaleType} from '../../scale';\nimport {isSortField, SortField} from '../../sort';\nimport * as util from '../../util';\nimport {\n isDataRefDomain,\n VgDataRef,\n VgDomain,\n VgFieldRefUnionDomain,\n VgNonUnionDomain,\n VgSortField,\n VgUnionSortField\n} from '../../vega.schema';\nimport {isDataRefUnionedDomain, isFieldRefUnionDomain} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\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 + JSON.stringify(specifiedDomain)\n }, true);\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 // FIXME: Arvind -- Please revise logic for merging selectionDomain / domainRaw\n\n let domains: VgNonUnionDomain[];\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 }\n\n if (isFacetModel(model)) {\n domains.forEach((domain) => {\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 localScaleComponents[channel].domains = domains;\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 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 if (fieldDef.bin) {\n log.warn(log.message.conflictedDomain(channel));\n } else {\n if (isDateTime(domain[0])) {\n return (domain as DateTime[]).map((dt) => {\n return {signal: `{data: ${dateTimeExpr(dt, true)}}`};\n });\n }\n return [domain];\n }\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.field(channel, {suffix: 'start'})\n }, {\n data,\n field: model.field(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 return [{\n data,\n field: model.field(channel, {aggregate: 'min'})\n }, {\n data,\n field: model.field(channel, {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.field(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.field(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 // 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.field(channel, {})\n }, {\n data,\n field: model.field(channel, {binSuffix: 'end'})\n }];\n } else {\n // TODO: use bin_mid\n return [{\n data: model.requestDataName(MAIN),\n field: model.field(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.field(channel),\n sort: sort\n }];\n } else {\n return [{\n data: model.requestDataName(MAIN),\n field: model.field(channel)\n }];\n }\n}\n\n\nexport function domainSort(model: UnitModel, channel: ScaleChannel, scaleType: ScaleType): true | SortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const sort = model.sort(channel);\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n return sort;\n }\n\n if (sort === 'descending') {\n return {\n op: 'min',\n field: model.field(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) && util.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) && util.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 util.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 {SCALE_CHANNELS, ScaleChannel} from '../../channel';\nimport {FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../../fielddef';\nimport {\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES,\n Scale,\n scaleCompatible,\n ScaleType,\n scaleTypePrecedence,\n} from '../../scale';\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} = model;\n const mark = model.mark();\n\n return SCALE_CHANNELS.reduce((scaleComponents: ScaleComponentIndex, channel: ScaleChannel) => {\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'] || {}; // 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) {\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 scaleType = scaleTypeWithExplicitIndex[channel];\n const childScaleType = child.component.scales[channel].getWithExplicit('type');\n\n if (scaleType) {\n if (scaleCompatible(scaleType.value, childScaleType.value)) {\n // merge scale component if type are compatible\n scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(\n scaleType, 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 {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef} 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 {SortField, SortOrder} from '../../sort';\nimport {keys} from '../../util';\nimport * as util from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponent, 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 sort = model.sort(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, sort,\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: FieldDef, sort: SortOrder | SortField,\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, sort);\n case 'zero':\n return zero(channel, fieldDef, specifiedDomain);\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(padding: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (padding !== 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(padding: number, channel: Channel, scaleType: ScaleType, paddingInner: number, scaleConfig: ScaleConfig) {\n if (padding !== 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 paddingInner / 2;\n }\n }\n return undefined;\n}\n\nexport function reverse(scaleType: ScaleType, sort: SortOrder | SortField) {\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) {\n // By default, 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 if no custom domain is provided.\n // (For binning, we should not include zero by default because binning are calculated without zero.\n // Similar, 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 && !fieldDef.bin && util.contains([X, Y], channel)) {\n return true;\n }\n return false;\n}\n","import {isNumber} from 'vega-util';\n\nimport {Channel, COLOR, OPACITY, SCALE_CHANNELS, ScaleChannel, SHAPE, SIZE, 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 if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' ? '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 '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 // TODO(#1168): make max size scale based on rangeStep / overall plot size\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 '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, isScaleChannel, rangeType} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, ScaleConfig, ScaleType} from '../../scale';\nimport {hasDiscreteDomain} from '../../scale';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {contains} from '../../util';\n\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 (!fieldDefMatchScaleType(specifiedType, fieldDef)) {\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 (channel === 'color' || 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 (mark === 'rect') {\n // The rect mark should fit into a band.\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 (channel === 'color') {\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 (channel === 'color') {\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\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function fieldDefMatchScaleType(specifiedType: ScaleType, fieldDef: FieldDef):boolean {\n const type: Type = fieldDef.type;\n if (contains([Type.ORDINAL, Type.NOMINAL], type)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (type === Type.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType);\n } else if (type === Type.QUANTITATIVE) {\n if (fieldDef.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","import {X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {hasContinuousDomain, isBinScale} from '../../scale';\nimport {keys, stringValue} 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] = {value: stroke[k]};\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 ...vgStroke\n },\n update: update\n }\n });\n }\n};\nexport {interval as default};\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 {accessPath, stringValue} from '../../util';\nimport {SelectionCompiler, TUPLE, unitName} from './selection';\nimport nearest from './transforms/nearest';\n\n\nconst multi:SelectionCompiler = {\n predicate: 'vlMulti',\n scaleDomain: 'vlMultiDomain',\n\n signals: function(model, selCmpt) {\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 `[${datum}${accessPath(model.field(channel, {}))}, ` +\n `${datum}${accessPath(model.field(channel, {binSuffix: 'end'}))}]`) :\n `${datum}${accessPath(p.field)}`;\n }).join(', ');\n\n // Only add a discrete selection to the store if a datum is present _and_\n // the interaction isn't occuring 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\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 {multi as default};\n","import {selector as parseSelector} from 'vega-event-selector';\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 {accessPath, Dict, isString, logicalExpr, stringValue, 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 // 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 predicate(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 ? ` + '_' + facet${accessPath(facet.field('row'))}` : '')\n + (facet.facet.column ? ` + '_' + facet${accessPath(facet.field('column'))}` : '');\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 return varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel]));\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 {stringValue} from '../../util';\nimport multi from './multi';\nimport {SelectionCompiler, STORE, TUPLE, unitName} from './selection';\n\n\nconst single:SelectionCompiler = {\n predicate: 'vlSingle',\n scaleDomain: 'vlSingleDomain',\n\n signals: multi.signals,\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 {single as default};\n","import {accessPath, stringValue, 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' ? ${datum}${accessPath(p.field)} : 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 signal.update = `${values.join(' && ')} ? {fields: [${fields}], values: [${values.join(', ')}]} : null`;\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport {inputBindings as default};\n","import * as log from '../../../log';\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 (markType === 'line' || markType === 'area') {\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: (x || (!x && !y)) ? 'datum.x' : {expr: '0'},\n y: (y || (!x && !y)) ? 'datum.y' : {expr: '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 {nearest as default};\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.field(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(timeUnits);\n }\n }\n};\n\nexport {project as default};\n","import {Channel} from '../../../channel';\nimport * as log from '../../../log';\nimport {hasContinuousDomain, isBinScale} from '../../../scale';\nimport {stringValue} from '../../../util';\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 },\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 {scaleBindings as default};\n\nexport function domain(model: UnitModel, channel: Channel) {\n const scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\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 {toggle as default};\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 {ScaleChannel, X, Y} from '../../../channel';\nimport {VgEventHandler, 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 = '_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 {translate as default};\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 {ScaleChannel, X, Y} from '../../../channel';\nimport {stringValue} from '../../../util';\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 {zoom as default};\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","\nimport * as log from '../log';\nimport {duplicate} from '../util';\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(public readonly explicit: T = {} as T, public readonly implicit: T = {} as T) {}\n\n public clone() {\n return new Split(duplicate(this.explicit), duplicate(this.implicit));\n }\n\n public combine(): T {\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: K, 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: K, s: S) {\n // Explicit has higher precedence\n if (s[key] !== undefined) {\n this.set(key, s[key], true);\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): 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) {\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 (v1.value === v2.value) {\n return v1;\n } else {\n return tieBreaker(v1, v2, property, propertyOf);\n }\n}\n","import {Axis} from '../axis';\nimport {Channel, 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 {isMarkDef, Mark, MarkDef} from '../mark';\nimport {Domain, Scale} from '../scale';\nimport {SelectionDef} from '../selection';\nimport {SortField, SortOrder} from '../sort';\nimport {LayoutSizeMixins, UnitSpec} 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 {\n assembleTopLevelSignals,\n assembleUnitSelectionData,\n assembleUnitSelectionMarks,\n assembleUnitSelectionSignals,\n parseUnitSelection,\n} 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 readonly selection: Dict = {};\n public children: Model[] = [];\n\n constructor(spec: UnitSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins = {}, repeater: RepeaterValue, config: Config, public fit: boolean) {\n\n super(spec, parent, parentGivenName, config, 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\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\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 sort(channel: Channel): SortField | SortOrder {\n return (this.getMapping()[channel] || {}).sort;\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 compatability.\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 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 {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, Field, FieldDef, isContinuous, isFieldDef, PositionFieldDef} from './../fielddef';\nimport * as log from './../log';\nimport {MarkConfig} from './../mark';\nimport {GenericUnitSpec, LayerSpec} 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](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 * - `\"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 * __Default value:__ `\"min-max\"`.\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}\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'],\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): LayerSpec {\n spec = filterUnsupportedChannels(spec);\n // TODO: use selection\n const {mark, encoding, selection, ...outerSpec} = spec;\n\n let kIQRScalar: number = undefined;\n if (isBoxPlotDef(mark)) {\n if (mark.extent) {\n if(isNumber(mark.extent)) {\n kIQRScalar = mark.extent;\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, ..._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, ..._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 continous 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 continous 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: field(channelDef)\n });\n } else if (channelDef.aggregate === undefined) {\n const transformedField = field(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: field(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 {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 {Field} from '../fielddef';\nimport {Encoding} from './../encoding';\nimport {GenericUnitSpec, LayerSpec} from './../spec';\n\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): LayerSpec {\n // TODO: use selection\n const {mark: _m, selection: _sel, 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, LayerSpec} from './../spec';\nimport {BOXPLOT, BOXPLOT_STYLES, BoxPlotConfigMixins, BoxPlotDef, normalizeBoxPlot, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX} from './boxplot';\nimport {ERRORBAR, normalizeErrorBar} from './errorbar';\n\n\nexport {BoxPlotConfig} from './boxplot';\nexport type UnitNormalizer = (spec: GenericUnitSpec, config: Config)=> LayerSpec;\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_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 ): LayerSpec {\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(`Unregistered composite mark ${mark}`);\n}\n","import {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 {defaultLegendConfig, LegendConfig} from './legend';\nimport {Mark, MarkConfigMixins, PRIMITIVE_MARKS, VL_ONLY_MARK_CONFIG_PROPERTIES, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './mark';\nimport * as mark from './mark';\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, isObject, keys, mergeDeep} from './util';\nimport {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\nexport const defaultViewConfig: ViewConfig = {\n width: 200,\n height: 200\n};\n\nexport type RangeConfigValue = (number|string)[] | VgScheme | {step: number};\n\nexport interface RangeConfig {\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 [name: string]: RangeConfigValue;\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 are filtered.\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:__ `'%b %d, %Y'`.\n *\n */\n timeFormat?: string;\n\n\n /** Default properties for [single view plots](spec.html#single). */\n view?: ViewConfig;\n\n /**\n * Scale configuration determines default properties for all [scales](scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](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\nexport type AreaOverlay = 'line' | 'linepoint' | 'none';\n\nexport interface OverlayConfig {\n /**\n * Whether to overlay line with point.\n */\n line?: boolean;\n\n /**\n * Type of overlay for area mark (line or linepoint)\n */\n area?: AreaOverlay;\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](scale.html#config).\n */\n range?: RangeConfig;\n\n /**\n * Legend configuration, which determines default properties for all [legends](legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](legend.html#config).\n */\n legend?: LegendConfig;\n\n /**\n * Title configuration, which determines default properties for all [titles](title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](title.html#config).\n */\n title?: VgTitleConfig;\n\n /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](mark.html#mark-def). The keys represent styles names; the value are valid [mark configuration objects](mark.html#config). */\n style?: StyleConfigIndex;\n\n /**\n * @hide\n */\n overlay?: OverlayConfig;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n timeFormat: '%b %d, %Y',\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 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\n box: {size: 14},\n boxWhisker: {},\n boxMid: {color: 'white'},\n\n scale: defaultScaleConfig,\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 mark of MARK_STYLES) {\n // Remove Vega-Lite-only mark config\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config[mark][prop];\n }\n\n // Remove Vega-Lite only mark-specific config\n const vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[mark];\n if (vlOnlyMarkSpecificConfigs) {\n for (const prop of vlOnlyMarkSpecificConfigs) {\n delete config[mark][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, mark);\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 {VgData} from './vega.schema';\n/*\n * Constants and utilities for data.\n */\n\nexport interface DataFormatBase {\n /**\n * If set to auto (the default), perform automatic type inference to determine the desired data types.\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\"` or `\"date\"`).\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](timeunit.html#utc)\n */\n parse?: 'auto' | object;\n}\n\nexport interface CsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`.\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 JsonDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`.\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\"`.\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 | JsonDataFormat | TopoDataFormat;\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport interface UrlData {\n /**\n * An object that specifies the format for parsing the data file.\n */\n format?: DataFormat;\n\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 {\n /**\n * An object that specifies the format for parsing the data values.\n */\n format?: DataFormat;\n /**\n * The full data set, included inline. This can be an array of objects or primitive values 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: number[] | string[] | boolean[] | object[] | string | object;\n}\n\nexport interface NamedData {\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 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'];\n}\n\nexport type DataSourceType = 'raw' | 'main' | 'row' | 'column' | 'lookup';\n\nexport const MAIN: 'main' = 'main';\nexport const RAW: 'raw' = 'raw';\n","// DateTime definition object\n\nimport * as log from './log';\nimport {duplicate, isNumber, 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","\nimport {Channel, CHANNELS, 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 {isArray, 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 * Color of the marks – either fill or stroke color based on mark type.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](config.html#mark)'s `color` property.\n *\n * _Note:_ See the scale documentation for more information about customizing [color scheme](scale.html#scheme).\n */\n color?: FieldDefWithCondition> | ValueDefWithCondition>;\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](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 currently unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`.\n */\n size?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * The symbol's shape (only 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 * __Default value:__ If undefined, the default shape depends on [mark config](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 and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | 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>;\n\n /**\n * Stack order for stacked marks or order of data points in line marks for connected scatter plots.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[];\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) => {\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.incompatibleChannel(channel, mark, 'when the field is aggregated.'));\n return normalizedEncoding;\n }\n }\n\n if (channel === 'detail' || channel === 'order') {\n const channelDef = encoding[channel];\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef])\n .reduce((fieldDefs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n fieldDefs.push(normalizeFieldDef(fieldDef, channel));\n }\n return fieldDefs;\n }, []);\n }\n } else {\n // FIXME: remove this casting. (I don't know why Typescript doesn't infer this correctly here.)\n const channelDef = encoding[channel] as ChannelDef;\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, 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","// Declaration and utility for variants of a field definition object\nimport {AggregateOp, 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 {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Scale} from './scale';\nimport {SortField, SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {getTimeUnitParts, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {getFullName, Type} from './type';\nimport {accessPath, isArray, isBoolean, isNumber, isString, 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\n\nexport type Conditional = {\n /**\n * A [selection name](selection.html), or a series of [composed selections](selection.html#compose).\n */\n selection: LogicalOperand;\n} & T;\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\nexport type FieldDefWithCondition> = F & {\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](encoding.html#value-def)\n * since Vega-Lite only allows at mosty one encoded field per encoding channel.\n */\n condition?: Conditional | Conditional[];\n};\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`](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](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](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](bin.html#params).\n * If `true`, default [binning parameters](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 */\n aggregate?: Aggregate;\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef extends FieldDefBase {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\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 ScaleFieldDef extends FieldDef {\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 * __Default value:__ If undefined, default [scale properties](scale.html) are applied.\n */\n scale?: Scale;\n\n /**\n * Sort order for the encoded field.\n * Supported `sort` values include `\"ascending\"`, `\"descending\"` and `null` (no sorting).\n * For fields with discrete domains, `sort` can also be a [sort field definition object](sort.html#sort-field).\n *\n * __Default value:__ `\"ascending\"`\n */\n sort?: SortOrder | SortField | 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](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](stack.html#bar) and [area](stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](stack.html#streamgraph)).\n * - `null` - No-stacking. This will produce layered [bar](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](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](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 | 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 /** Overrride which aggregate to use. Needed for unaggregated domain. */\n aggregate?: AggregateOp;\n}\n\nexport function field(fieldDef: FieldDefBase, 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 (fieldDef.bin) {\n fn = binToString(fieldDef.bin);\n suffix = opt.binSuffix || '';\n } else if (fieldDef.aggregate) {\n fn = String(opt.aggregate || fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (fn) {\n field = `${fn}_${field}`;\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 field = `${opt.expr}${accessPath(field)}`;\n }\n\n return field;\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\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: FieldDef, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDef, config: Config) {\n const {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: FieldDef, 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: FieldDef, 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: (fieldDef: FieldDef, config: Config) => string) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(fieldDef: FieldDef, 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 switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef) && !fieldDef.timeUnit) {\n // TODO:(https://github.com/vega/vega-lite/issues/2011):\n // with timeUnit it's not always strictly continuous\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 'text':\n case 'detail':\n case 'tooltip':\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if (isDiscrete(fieldDef) && !fieldDef.bin) {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with nominal data only'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal') {\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","import {DataFlowNode} from './compile/data/dataflow';\nimport {Model} from './compile/model';\nimport {predicate} from './compile/selection/selection';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {field} from './fielddef';\nimport {LogicalOperand} from './logical';\nimport {fieldExpr as timeUnitFieldExpr, getLocalTimeUnit, isLocalSingleTimeUnit, isUtcSingleTimeUnit, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {isArray, isString, logicalExpr} from './util';\n\n\nexport type Filter =\n // FieldFilter (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 EqualFilter | RangeFilter | OneOfFilter |\n SelectionFilter | string;\n\nexport type FieldFilter = EqualFilter | RangeFilter | OneOfFilter;\n\nexport interface SelectionFilter {\n /**\n * Filter using a selection name.\n */\n selection: LogicalOperand;\n}\n\nexport function isSelectionFilter(filter: LogicalOperand): filter is SelectionFilter {\n return filter && filter['selection'];\n}\n\nexport interface EqualFilter {\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 /**\n * The value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isEqualFilter(filter: any): filter is EqualFilter {\n return filter && !!filter.field && filter.equal!==undefined;\n}\n\nexport interface RangeFilter {\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 /**\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)[];\n\n}\n\nexport function isRangeFilter(filter: any): filter is RangeFilter {\n if (filter && filter.field) {\n if (isArray(filter.range) && filter.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface OneOfFilter {\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 /**\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 isOneOfFilter(filter: any): filter is OneOfFilter {\n return filter && !!filter.field && (\n isArray(filter.oneOf) ||\n isArray(filter.in) // backward compatibility\n );\n}\n\nexport function isFieldFilter(filter: Filter): filter is OneOfFilter | EqualFilter | RangeFilter {\n return isOneOfFilter(filter) || isEqualFilter(filter) || isRangeFilter(filter);\n}\n\n/**\n * Converts a filter 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, (filter: Filter) => {\n if (isString(filter)) {\n return filter;\n } else if (isSelectionFilter(filter)) {\n return predicate(model, filter.selection, node);\n } else { // Filter Object\n return fieldFilterExpression(filter);\n }\n });\n}\n\n// This method is used by Voyager. Do not change its behavior without changing Voyager.\nexport function fieldFilterExpression(filter: FieldFilter, useInRange=true) {\n const fieldExpr = filter.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(filter.timeUnit, filter.field) + ')') :\n field(filter, {expr: 'datum'});\n\n if (isEqualFilter(filter)) {\n return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit);\n } else if (isOneOfFilter(filter)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n const oneOf: OneOfFilter[] = filter.oneOf || filter['in'];\n return 'indexof([' +\n oneOf.map((v) => valueExpr(v, filter.timeUnit)).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isRangeFilter(filter)) {\n const lower = filter.range[0];\n const upper = filter.range[1];\n\n if (lower !== null && upper !== null && useInRange) {\n return 'inrange(' + fieldExpr + ', [' +\n valueExpr(lower, filter.timeUnit) + ', ' +\n valueExpr(upper, filter.timeUnit) + '])';\n }\n\n const exprs = [];\n if (lower !== null) {\n exprs.push(`${fieldExpr} >= ${valueExpr(lower, filter.timeUnit)}`);\n }\n if (upper !== null) {\n exprs.push(`${fieldExpr} <= ${valueExpr(upper, filter.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 filter: ${JSON.stringify(filter)}`);\n}\n\nfunction valueExpr(v: any, timeUnit: TimeUnit): string {\n if (isDateTime(v)) {\n const expr = dateTimeExpr(v, true);\n return 'time(' + expr + ')';\n }\n if (isLocalSingleTimeUnit(timeUnit)) {\n const datetime: DateTime = {};\n datetime[timeUnit] = v;\n const expr = dateTimeExpr(datetime, true);\n return 'time(' + expr + ')';\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n return valueExpr(v, getLocalTimeUnit(timeUnit));\n }\n return JSON.stringify(v);\n}\n\nexport function normalizeFilter(f: Filter): Filter {\n if (isFieldFilter(f) && f.timeUnit) {\n return {\n ...f,\n timeUnit: normalizeTimeUnit(f.timeUnit)\n };\n }\n return f;\n}\n","import {ValueDef} from './fielddef';\nimport {VgEncodeChannel} from './vega.schema';\n\n\nexport interface Guide {\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](format.html) for more information.\n *\n * __Default value:__ derived from [numberFormat](config.html#format) config for quantitative fields and from [timeFormat](config.html#format) config for temporal fields.\n */\n format?: string;\n\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 a part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function will be denoted in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n *\n * __Note__: You can customize the default field title format by providing the [`fieldTitle` property in the [config](config.html) or [`fieldTitle` function via the `compile` function's options](compile.html#field-title).\n */\n title?: string | null;\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;\n};\n\nexport const VL_ONLY_GUIDE_CONFIG: (keyof VlOnlyGuideConfig)[] = ['shortTimeLabels'];\n","export import axis = require('./axis');\nexport import aggregate = require('./aggregate');\nexport import bin = require('./bin');\nexport import channel = require('./channel');\nexport import compositeMark = require('./compositemark');\nexport {compile} from './compile/compile';\nexport import config = require('./config');\nexport import data = require('./data');\nexport import datetime = require('./datetime');\nexport import encoding = require('./encoding');\nexport import facet = require('./facet');\nexport import fieldDef = require('./fielddef');\nexport import legend = require('./legend');\nexport import mark = require('./mark');\nexport import scale = require('./scale');\nexport import sort = require('./sort');\nexport import spec = require('./spec');\nexport import stack = require('./stack');\nexport import timeUnit = require('./timeunit');\nexport import transform = require('./transform');\nexport import type = require('./type');\nexport import util = require('./util');\nexport import validate = require('./validate');\n\nexport const version: string = require('../package.json').version;\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[] | 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","/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport {AggregateOp} from './aggregate';\nimport {Channel} from './channel';\nimport {CompositeMark} from './compositemark';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {ScaleType} from './scale';\nimport {Type} from './type';\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 const logger = current = new LocalLogger();\n f(logger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(logger: LoggerInterface) {\n current = logger;\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: ${JSON.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 the data from the secondary source.';\n\n // ENCODING & FACET\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: ${value}}.`;\n }\n\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\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\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${JSON.stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n }\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 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 unclearOrientContinuous(mark: Mark) {\n return `Cannot clearly determine orientation for \"${mark}\" since both x and y channel encode continous fields. In this case, we use vertical by default`;\n }\n\n export function unclearOrientDiscreteOrEmpty(mark: Mark) {\n return `Cannot clearly determine orientation for \"${mark}\" since both x and y channel encode discrete or empty fields.`;\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 (${JSON.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 (${JSON.stringify(fieldDef)}).`;\n }\n\n export function cannotUseSizeFieldWithBandSize(positionChannel: 'x'|'y') {\n return `Using size field when ${positionChannel}-channel has a band scale is not supported.`;\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, propertyOf: string, v1: T, v2: T) {\n return `Conflicting ${propertyOf} property \"${property}\" (\"${v1}\" and \"${v2}\"). Using \"${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 conflictedDomain(channel: Channel) {\n return `Cannot set ${channel}-scale's \"domain\" as it is binned. Please use \"bin\"'s \"extent\" instead.`;\n }\n\n export function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property \"${JSON.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}: \"${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 ${JSON.stringify(d)} as day cannot be combined with other units.`;\n }\n}\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 forEachLeave(op: LogicalOperand, fn: (op: T) => void) {\n if (isLogicalNot(op)) {\n forEachLeave(op.not, fn);\n } else if (isLogicalAnd(op)) {\n for (const subop of op.and) {\n forEachLeave(subop, fn);\n }\n } else if (isLogicalOr(op)) {\n for (const subop of op.or) {\n forEachLeave(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 {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {flagKeys, toSet} 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 CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE;\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 RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\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 rect: 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 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](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](mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface MarkDef extends MarkConfig {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n\n /**\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](mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](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\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'];\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 bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\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?: MarkConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: MarkConfig;\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\nexport interface BarConfig extends MarkConfig {\n /**\n * Offset between bar 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 * 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 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 {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 2/3 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n","import {Channel} from './channel';\nimport {ScaleComponentProps} from './compile/scale/component';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport {contains, Flag, flagKeys, keys, toSet} from './util';\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 predecence -- 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 strokeWidth (or rule/line's size) scale with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for strokeWidth (or rule/line's size) scale.\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 scheme, 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](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](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**](scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](scale.html#linear), [`\"pow\"`](scale.html#pow), [`\"sqrt\"`](scale.html#sqrt), [`\"log\"`](scale.html#log), [`\"time\"`](scale.html#time), [`\"utc\"`](scale.html#utc), [`\"sequential\"`](scale.html#sequential)).\n *\n * 2) [**Discrete Scales**](scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](scale.html#ordinal)) or continuous ([`\"band\"`](scale.html#band) and [`\"point\"`](scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`\"bin-linear\"`](scale.html#bin-linear) and [`\"bin-ordinal\"`](scale.html#bin-ordinal)).\n *\n * __Default value:__ please see the [scale type table](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](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](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](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](scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](scale.html#piecewise).\n *\n * - For [discrete](scale.html#discrete) and [discretizing](scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For [sequential](scale.html#sequential), [ordinal](scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](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](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](scale.html#band) and [point](scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](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](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](scale.html#scheme) name (e.g., `\"category10\"` or `\"viridis\"`) or a [scheme parameter object](scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](scale.html#discrete) or [discretizing](scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](scales.html#sequential) scales.\n *\n * For the full list of supported scheme, 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](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](scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](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](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](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](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?: Interpolate | InterpolateParams;\n}\n\nexport type Interpolate = 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n\nexport interface InterpolateParams {\n type: 'rgb' | 'cubehelix' | 'cubehelix-long';\n gamma?: number;\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 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 (channel !== 'color') {\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 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 case Channel.COLOR:\n return scaleType !== 'band'; // band does not make sense with color\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","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](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](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](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](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`](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`](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`](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 {AggregateOp} from './aggregate';\n\n\nexport type SortOrder = 'ascending' | 'descending' | null;\n\nexport interface SortField {\n /**\n * The data [field](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](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](aggregate.html#ops).\n */\n op: AggregateOp;\n\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n order?: SortOrder;\n}\n\nexport function isSortField(sort: SortOrder | SortField): sort is SortField {\n return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op'];\n}\n","import {COLUMN, ROW, X, X2, Y, Y2} from './channel';\nimport * as compositeMark from './compositemark';\nimport {Config, OverlayConfig} from './config';\nimport {Data} from './data';\nimport {channelHasField, Encoding, EncodingWithFacet, isRanged} from './encoding';\nimport * as vlEncoding from './encoding';\nimport {FacetMapping} from './facet';\nimport {Field, FieldDef, RepeatRef} from './fielddef';\nimport * as log from './log';\nimport {AnyMark, AREA, isPrimitiveMark, LINE, Mark, MarkDef} from './mark';\nimport {Repeat} from './repeat';\nimport {Resolve} from './resolve';\nimport {SelectionDef} from './selection';\nimport {stack} from './stack';\nimport {TitleParams} from './title';\nimport {TopLevelProperties} from './toplevelprops';\nimport {Transform} from './transform';\nimport {contains, Dict, duplicate, hash, 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 interface BaseSpec {\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\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`](size.html#autosize) type is `\"fit\"` or its x-channel has a [continuous scale](scale.html#continuous), the width will be the value of [`config.view.width`](spec.html#config).\n * - For x-axis with a band or point scale: if [`rangeStep`](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](scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](spec.html#config).\n * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](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](encoding.html#facet), this represents the width of a single view.\n *\n * __See also:__ The documentation for [width and height](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`](size.html#autosize) type is `\"fit\"` or its y-channel has a [continuous scale](scale.html#continuous), the height will be the value of [`config.view.height`](spec.html#config).\n * - For y-axis with a band or point scale: if [`rangeStep`](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](scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](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](encoding.html#facet), this represents the height of a single view.\n *\n * __See also:__ The documentation for [width and height](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\"`, and `\"text\"`) or a [mark definition object](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 * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type UnitSpec = 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\nexport type LayerSpec = GenericLayerSpec;\n\nexport interface GenericFacetSpec> extends BaseSpec {\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: GenericLayerSpec | 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 FacetSpec = GenericFacetSpec;\n\nexport interface GenericRepeatSpec> extends BaseSpec {\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 RepeatSpec = GenericRepeatSpec;\n\nexport interface GenericVConcatSpec> extends BaseSpec {\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> extends BaseSpec {\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 ConcatSpec = GenericVConcatSpec | GenericHConcatSpec;\n\nexport type GenericSpec> = U | GenericLayerSpec | GenericFacetSpec | GenericRepeatSpec | GenericVConcatSpec | GenericHConcatSpec;\n\nexport type Spec = GenericSpec;\n\nexport type TopLevelExtendedSpec = TopLevel | TopLevel> | TopLevel> | TopLevel> | TopLevel> | TopLevel>;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: GenericSpec>): spec is GenericFacetSpec> {\n return spec['facet'] !== undefined;\n}\n\nexport function isUnitSpec(spec: GenericSpec>): spec is FacetedCompositeUnitSpec | UnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: GenericSpec>): spec is GenericLayerSpec> {\n return spec['layer'] !== undefined;\n}\n\nexport function isRepeatSpec(spec: GenericSpec>): spec is GenericRepeatSpec> {\n return spec['repeat'] !== undefined;\n}\n\nexport function isConcatSpec(spec: GenericSpec>): spec is GenericVConcatSpec> | GenericHConcatSpec> {\n return isVConcatSpec(spec) || isHConcatSpec(spec);\n}\n\nexport function isVConcatSpec(spec: GenericSpec>): spec is GenericVConcatSpec> {\n return spec['vconcat'] !== undefined;\n}\n\nexport function isHConcatSpec(spec: GenericSpec>): 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: TopLevelExtendedSpec, config: Config): Spec {\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): FacetSpec {\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 normalizeLayer(spec: GenericLayerSpec, config: Config): LayerSpec {\n const {layer: layer, ...rest} = spec;\n return {\n ...rest,\n layer: layer.map((subspec) => isLayerSpec(subspec) ? normalizeLayer(subspec, config) : normalizeNonFacetUnit(subspec, config))\n };\n}\n\nfunction normalizeRepeat(spec: GenericRepeatSpec, config: Config): RepeatSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalize(subspec, config)\n };\n}\n\nfunction normalizeVConcat(spec: GenericVConcatSpec, config: Config): ConcatSpec {\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): ConcatSpec {\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): FacetSpec {\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, height, selection, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\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\n\nfunction normalizeNonFacetUnit(spec: GenericUnitSpec, AnyMark>, config: Config) {\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(spec.encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n const overlayConfig: OverlayConfig = config && config.overlay;\n const overlayWithLine = overlayConfig && spec.mark === AREA &&\n contains(['linepoint', 'line'], overlayConfig.area);\n const overlayWithPoint = overlayConfig && (\n (overlayConfig.line && spec.mark === LINE) ||\n (overlayConfig.area === 'linepoint' && spec.mark === AREA)\n );\n // TODO: consider moving this to become another case of compositeMark\n if (overlayWithPoint || overlayWithLine) {\n return normalizeOverlay(spec, overlayWithPoint, overlayWithLine, config);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec, config);\n }\n}\n\nfunction normalizeRangedUnit(spec: UnitSpec) {\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\n\n// FIXME(#1804): re-design this\nfunction normalizeOverlay(spec: UnitSpec, overlayWithPoint: boolean, overlayWithLine: boolean, config: Config): LayerSpec {\n const {mark, selection, encoding, ...outerSpec} = spec;\n const layer = [{mark, encoding}];\n\n // Need to copy stack config to overlayed layer\n const stackProps = stack(mark, 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 (overlayWithLine) {\n layer.push({\n mark: {\n type: 'line',\n style: 'lineOverlay'\n },\n ...(selection ? {selection} : {}),\n encoding: overlayEncoding\n });\n }\n if (overlayWithPoint) {\n layer.push({\n mark: {\n type: 'point',\n filled: true,\n style: 'pointOverlay'\n },\n ...(selection ? {selection} : {}),\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, fieldDefs: FieldDef[]): any {\n fieldDefs.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 {SUM_OPS} from './aggregate';\nimport {NONPOSITION_CHANNELS, NonPositionChannel, X, X2, Y2} from './channel';\nimport {channelHasField, Encoding} from './encoding';\nimport {Field, field, FieldDef, getFieldDef, isFieldDef, isStringFieldDef, PositionFieldDef} from './fielddef';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag, isArray} 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(stack: string): stack is StackOffset {\n return !!STACK_OFFSET_INDEX[stack];\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) ? field(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? field(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) ? field(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 // If stacked, check scale type if it is linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n return null;\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\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: contains(['area', 'line'], mark),\n stackBy,\n offset\n };\n}\n","import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPath, 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 = `datum${accessPath(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 {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](spec.html) and [layered](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](spec.html) and [layered](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](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 {isString} from 'util';\nimport * as log from './log';\n\n/**\n * @minimum 0\n */\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\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\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\"`) inteprets 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'\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","import {AggregateOp} from './aggregate';\nimport {BinParams} from './bin';\nimport {Data} from './data';\nimport {Filter, normalizeFilter} from './filter';\nimport {LogicalOperand, normalizeLogicalOperand} from './logical';\nimport {TimeUnit} from './timeunit';\n\n\nexport interface FilterTransform {\n /**\n * The `filter` property must be either (1) a filter object for [equal-filters](filter.html#equalfilter),\n * [range-filters](filter.html#rangefilter), [one-of filters](filter.html#oneoffilter), or [selection filters](filter.html#selectionfilter);\n * (2) a [Vega Expression](filter.html#expression) string,\n * where `datum` can be used to refer to the current data object; or (3) an array of filters (either objects or expression strings) that must all be true for a datum to pass the filter and be included.\n */\n filter: LogicalOperand;\n}\n\nexport function isFilter(t: Transform): t is FilterTransform {\n return t['filter'] !== undefined;\n}\n\n\nexport interface CalculateTransform {\n /**\n * A string containing a Vega Expression. Use the variable `datum` to refer to the current data object.\n */\n calculate: string;\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;\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.\n */\n field: string;\n\n /**\n * The output field names to use for each aggregated field.\n */\n as: string;\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 specificied, 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\nexport function isLookup(t: Transform): t is LookupTransform {\n return t['lookup'] !== 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 type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform;\n\nexport function normalizeTransform(transform: Transform[]) {\n return transform.map(t => {\n if (isFilter(t)) {\n return {\n filter: normalizeLogicalOperand(t.filter, normalizeFilter)\n };\n }\n return t;\n });\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}\nexport type Type = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\n\nconst TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 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\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 }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n","import * as stringify from 'json-stable-stringify';\nimport {isArray, isNumber, isString, splitAccessPath, stringValue} from 'vega-util';\nimport {isLogicalAnd, isLogicalNot, isLogicalOr, LogicalOperand} from './logical';\n\n\nexport {isArray, isObject, isNumber, isString, truncate, toSet, stringValue, splitAccessPath} from 'vega-util';\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: object, props: string[]) {\n const copy = {};\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: object, props: string[]) {\n const copy = duplicate(obj);\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\nexport function hash(a: any) {\n if (isString(a) || isNumber(a) || isBoolean(a)) {\n return String(a);\n }\n\n const str = stringify(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) => (keyof T)[];\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\n// Omit from http://ideasintosoftware.com/typescript-advanced-tricks/\nexport type Diff = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];\nexport type Omit = {[P in Diff]: T[P]};\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 let isEmpty = true;\n while (orderedProps.length > 0 && isEmpty) {\n let o = obj;\n for (let i=0; i < orderedProps.length-1; i++) {\n o = o[orderedProps[i]];\n }\n delete o[orderedProps.pop()];\n if (keys(o).length !== 0) {\n isEmpty = false;\n }\n }\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.\n */\nexport function accessPath(path: string) {\n return `[${splitAccessPath(path).map(stringValue).join('][')}]`;\n}\n","import {isMarkDef} from './mark';\nimport {BAR} from './mark';\nimport {FacetedCompositeUnitSpec} from './spec';\nimport {toSet} from './util';\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 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', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'detail']), // TODO: add size when Vega supports\n area: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', '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 {AggregateOp} from './aggregate';\nimport {BaseBin} from './bin';\nimport {NiceTime, ScaleType} from './scale';\nimport {SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {Flag, flagKeys, isArray} 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 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?: 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n nice?: boolean | NiceTime;\n padding?: number;\n paddingInner?: number;\n paddingOuter?: number;\n reverse?: boolean;\n round?: boolean;\n zero?: boolean;\n}\n\nexport type VgLayoutAlign = 'none' | 'each' | 'all';\n\nexport type RowCol = {\n row?: T,\n column?: T\n};\n\nexport interface VgLayout {\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 | {\n row: VgLayoutAlign,\n column: VgLayoutAlign\n };\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'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'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';\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;\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?: 'ascending' | 'descending';\n} | {\n field: string[];\n order?: ('ascending' | 'descending')[];\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](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. (e.g., `\"bold\"`).\n */\n titleFontWeight?: string | number;\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 */\n titleFontWeight?: string | number;\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';\nexport type FontWeight = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\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';\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 * 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 // ---------- 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, 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 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 (default 0, indicating no limit). The text value will be automatically truncated if the rendered size exceeds the limit.\n */\n limit?: number;\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 (e.g., `\"bold\"`).\n */\n fontWeight?: FontWeight | FontWeightNumber;\n\n /**\n * Placeholder text if the `text` channel is not specified\n */\n text?: string;\n}\n\nconst VG_MARK_CONFIG_INDEX: Flag = {\n opacity: 1,\n fill: 1,\n fillOpacity: 1,\n stroke: 1,\n strokeWidth: 1,\n strokeOpacity: 1,\n strokeDash: 1,\n strokeDashOffset: 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 limit: 1,\n dx: 1,\n dy: 1,\n radius: 1,\n theta: 1,\n angle: 1,\n font: 1,\n fontSize: 1,\n fontWeight: 1,\n fontStyle: 1\n // commented below are vg channel that do not have mark config.\n // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'\n // cursor: 1,\n // clip: 1,\n // dir: 1,\n // ellipsis: 1,\n // endAngle: 1,\n // path: 1,\n // innerRadius: 1,\n // outerRadius: 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](spec.html) and [layered](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](spec.html) and [layered](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 */\n fontWeight?: FontWeight | FontWeightNumber;\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"]} \ No newline at end of file