(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.vega = {})); }(this, (function (exports) { 'use strict'; function accessor(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; } function error(message) { throw Error(message); } function splitAccessPath(p) { var path = [], q = null, b = 0, n = p.length, s = '', i, j, c; p = p + ''; function push() { path.push(s + p.substring(i, j)); s = ''; i = j + 1; } for (i=j=0; j i) { push(); } else { i = j + 1; } } else if (c === '[') { if (j > i) push(); b = i = j + 1; } else if (c === ']') { if (!b) error('Access path missing open bracket: ' + p); if (b > 0) push(); b = 0; i = j + 1; } } if (b) error('Access path missing closing bracket: ' + p); if (q) error('Access path missing closing quote: ' + p); if (j > i) { j++; push(); } return path; } var isArray = Array.isArray; function isObject(_) { return _ === Object(_); } function isString(_) { return typeof _ === 'string'; } function $(x) { return isArray(x) ? '[' + x.map($) + ']' : isObject(x) || isString(x) ? // Output valid JSON and JS source strings. // See http://timelessrepo.com/json-isnt-a-javascript-subset JSON.stringify(x).replace('\u2028','\\u2028').replace('\u2029', '\\u2029') : x; } function field(field, name) { var path = splitAccessPath(field), code = 'return _[' + path.map($).join('][') + '];'; return accessor( Function('_', code), [(field = path.length===1 ? path[0] : field)], name || field ); } var empty = []; var id = field('id'); var identity = accessor(function(_) { return _; }, empty, 'identity'); var zero = accessor(function() { return 0; }, empty, 'zero'); var one = accessor(function() { return 1; }, empty, 'one'); var truthy = accessor(function() { return true; }, empty, 'true'); var falsy = accessor(function() { return false; }, empty, 'false'); function log(method, level, input) { var args = [level].concat([].slice.call(input)); console[method].apply(console, args); // eslint-disable-line no-console } var None = 0; var Error$1 = 1; var Warn = 2; var Info = 3; var Debug = 4; function logger(_, method) { var level = _ || None; return { level: function(_) { if (arguments.length) { level = +_; return this; } else { return level; } }, error: function() { if (level >= Error$1) log(method || 'error', 'ERROR', arguments); return this; }, warn: function() { if (level >= Warn) log(method || 'warn', 'WARN', arguments); return this; }, info: function() { if (level >= Info) log(method || 'log', 'INFO', arguments); return this; }, debug: function() { if (level >= Debug) log(method || 'log', 'DEBUG', arguments); return this; } } } function mergeConfig(...configs) { return configs.reduce((out, source) => { for (var key in source) { if (key === 'signals') { // for signals, we merge the signals arrays // source signals take precedence over // existing signals with the same name out.signals = mergeNamed(out.signals, source.signals); } else { // otherwise, merge objects subject to recursion constraints // for legend block, recurse for the layout entry only // for style block, recurse for all properties // otherwise, no recursion: objects overwrite, no merging var r = key === 'legend' ? {'layout': 1} : key === 'style' ? true : null; writeConfig(out, key, source[key], r); } } return out; }, {}); } function writeConfig(output, key, value, recurse) { var k, o; if (isObject(value) && !isArray(value)) { o = isObject(output[key]) ? output[key] : (output[key] = {}); for (k in value) { if (recurse && (recurse === true || recurse[k])) { writeConfig(o, k, value[k]); } else { o[k] = value[k]; } } } else { output[key] = value; } } function mergeNamed(a, b) { if (a == null) return b; const map = {}, out = []; function add(_) { if (!map[_.name]) { map[_.name] = 1; out.push(_); } } b.forEach(add); a.forEach(add); return out; } function peek(array) { return array[array.length - 1]; } function toNumber(_) { 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 symlog(c) { return function(x) { return Math.sign(x) * Math.log1p(Math.abs(x / c)); }; } function symexp(c) { return function(x) { return Math.sign(x) * Math.expm1(Math.abs(x)) * c; }; } 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 panSymlog(domain, delta, constant) { return pan(domain, delta, symlog(constant), symexp(constant)); } 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)); } function zoomSymlog(domain, anchor, scale, constant) { return zoom(domain, anchor, scale, symlog(constant), symexp(constant)); } function quarter(date) { return 1 + ~~(new Date(date).getMonth() / 3); } function utcquarter(date) { return 1 + ~~(new Date(date).getUTCMonth() / 3); } function array(_) { return _ != null ? (isArray(_) ? _ : [_]) : []; } /** * Span-preserving range clamp. If the span of the input range is less * than (max - min) and an endpoint exceeds either the min or max value, * the range is translated such that the span is preserved and one * endpoint touches the boundary of the min/max range. * If the span exceeds (max - min), the range [min, max] is returned. */ function clampRange(range, min, max) { var lo = range[0], hi = range[1], span; if (hi < lo) { span = hi; hi = lo; lo = span; } span = hi - lo; return span >= (max - min) ? [min, max] : [ (lo = Math.min(Math.max(lo, min), max - span)), lo + span ]; } function isFunction(_) { return typeof _ === 'function'; } function compare(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)); } function constant(_) { return isFunction(_) ? _ : function() { return _; }; } function debounce(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); }; } function extend(_) { for (var x, k, i=1, len=arguments.length; i max) max = v; } } } else { // find first valid value for (v = f(array[i]); i < n && (v == null || v !== v); v = f(array[++i])); min = max = v; // visit all other values for (; i max) max = v; } } } } return [min, max]; } function extentIndex(array, f) { var i = -1, n = array.length, a, b, c, u, v; if (f == null) { while (++i < n) { b = array[i]; if (b != null && b >= b) { a = c = b; break; } } if (i === n) return [-1, -1]; 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; } } if (i === n) return [-1, -1]; 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]; } const hop = Object.prototype.hasOwnProperty; function hasOwnProperty(object, property) { return hop.call(object, property); } var NULL = {}; function fastmap(input) { var obj = {}, map, test; function has(key) { return hasOwnProperty(obj, 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; } function flush(range, value, threshold, left, right, center) { if (!threshold && threshold !== 0) return center; var a = range[0], b = peek(range), t = +threshold, l, r; // swap endpoints if range is reversed if (b < a) { l = a; a = b; b = l; } // compare value to endpoints l = Math.abs(value - a); r = Math.abs(b - value); // adjust if value is within threshold distance of endpoint return l < r && l <= t ? left : r <= t ? right : center; } function inherits(child, parent) { var proto = (child.prototype = Object.create(parent.prototype)); proto.constructor = child; return proto; } /** * Predicate that returns true if the value lies within the span * of the given range. The left and right flags control the use * of inclusive (true) or exclusive (false) comparisons. */ function inrange(value, range, left, right) { var r0 = range[0], r1 = range[range.length-1], t; if (r0 > r1) { t = r0; r0 = r1; r1 = t; } left = left === undefined || left; right = right === undefined || right; return (left ? r0 <= value : r0 < value) && (right ? value <= r1 : value < r1); } function isBoolean(_) { return typeof _ === 'boolean'; } function isDate(_) { return Object.prototype.toString.call(_) === '[object Date]'; } function isNumber(_) { return typeof _ === 'number'; } function isRegExp(_) { return Object.prototype.toString.call(_) === '[object RegExp]'; } function key(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'); } function lerp(array, frac) { const lo = array[0], hi = peek(array), f = +frac; return !f ? lo : f === 1 ? hi : lo + f * (hi - lo); } function merge(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; } function pad(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); } /** * Return the numerical span of an array: the difference between * the last and first values. */ function span(array) { return array && (peek(array) - array[0]) || 0; } function toBoolean(_) { return _ == null || _ === '' ? null : !_ || _ === 'false' || _ === '0' ? false : !!_; } function defaultParser(_) { return isNumber(_) ? _ : isDate(_) ? _ : Date.parse(_); } function toDate(_, parser) { parser = parser || defaultParser; return _ == null || _ === '' ? null : parser(_); } function toString(_) { return _ == null || _ === '' ? null : _ + ''; } function toSet(_) { for (var s={}, i=0, n=_.length; i