diff --git a/dist/tangram.debug.js b/dist/tangram.debug.js index a1a73c3e2..ccd9ee09f 100644 --- a/dist/tangram.debug.js +++ b/dist/tangram.debug.js @@ -519,7 +519,7 @@ var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORC // Set @@toStringTag to native iterators _setToStringTag(IteratorPrototype, TAG, true); // fix for some old engines - if (typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis); + if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis); } } // fix Array#{values, @@iterator}.name in V8 / FF @@ -528,7 +528,7 @@ var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORC $default = function values() { return $native.call(this); }; } // Define iterator - if (BUGGY || VALUES_BUG || !proto[ITERATOR]) { + if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { _hide(proto, ITERATOR, $default); } // Plug for library @@ -1068,6 +1068,100 @@ _export(_export.P + _export.F * (_fails(function () { } }); +var _meta = createCommonjsModule(function (module) { +var META = _uid('meta'); + + +var setDesc = _objectDp.f; +var id = 0; +var isExtensible = Object.isExtensible || function () { + return true; +}; +var FREEZE = !_fails(function () { + return isExtensible(Object.preventExtensions({})); +}); +var setMeta = function (it) { + setDesc(it, META, { value: { + i: 'O' + ++id, // object ID + w: {} // weak collections IDs + } }); +}; +var fastKey = function (it, create) { + // return primitive with prefix + if (!_isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if (!_has(it, META)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return 'F'; + // not necessary to add metadata + if (!create) return 'E'; + // add missing metadata + setMeta(it); + // return object ID + } return it[META].i; +}; +var getWeak = function (it, create) { + if (!_has(it, META)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return true; + // not necessary to add metadata + if (!create) return false; + // add missing metadata + setMeta(it); + // return hash weak collections IDs + } return it[META].w; +}; +// add metadata on freeze-family methods calling +var onFreeze = function (it) { + if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it); + return it; +}; +var meta = module.exports = { + KEY: META, + NEED: false, + fastKey: fastKey, + getWeak: getWeak, + onFreeze: onFreeze +}; +}); +var _meta_1 = _meta.KEY; +var _meta_2 = _meta.NEED; +var _meta_3 = _meta.fastKey; +var _meta_4 = _meta.getWeak; +var _meta_5 = _meta.onFreeze; + +// 7.2.2 IsArray(argument) + +var _isArray = Array.isArray || function isArray(arg) { + return _cof(arg) == 'Array'; +}; + +// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) + +var hiddenKeys = _enumBugKeys.concat('length', 'prototype'); + +var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return _objectKeysInternal(O, hiddenKeys); +}; + +var _objectGopn = { + f: f$3 +}; + +var gOPD = Object.getOwnPropertyDescriptor; + +var f$4 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) { + O = _toIobject(O); + P = _toPrimitive(P, true); + if (_ie8DomDefine) try { + return gOPD(O, P); + } catch (e) { /* empty */ } + if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]); +}; + +var _objectGopd = { + f: f$4 +}; + var $at = _stringAt(true); // 21.1.3.27 String.prototype[@@iterator]() @@ -1333,12 +1427,12 @@ function PromiseCapability(C) { this.reject = _aFunction(reject); } -var f$3 = function (C) { +var f$5 = function (C) { return new PromiseCapability(C); }; var _newPromiseCapability = { - f: f$3 + f: f$5 }; var _perform = function (exec) { @@ -1818,7 +1912,7 @@ function _wrapNativeSuper(Class) { return _wrapNativeSuper(Class); } -var version = "0.17.5"; +var version = "0.18.0"; var version$1 = 'v' + version; @@ -3221,21 +3315,6 @@ function mergeDebugSettings(settings) { Object.assign(debugSettings, settings); } -var gOPD = Object.getOwnPropertyDescriptor; - -var f$4 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) { - O = _toIobject(O); - P = _toPrimitive(P, true); - if (_ie8DomDefine) try { - return gOPD(O, P); - } catch (e) { /* empty */ } - if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]); -}; - -var _objectGopd = { - f: f$4 -}; - // Works with __proto__ only. Old v8 can't work with null proto objects. /* eslint-disable no-proto */ @@ -3271,18 +3350,6 @@ var _inheritIfRequired = function (that, target, C) { } return that; }; -// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) - -var hiddenKeys = _enumBugKeys.concat('length', 'prototype'); - -var f$5 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { - return _objectKeysInternal(O, hiddenKeys); -}; - -var _objectGopn = { - f: f$5 -}; - var dP$2 = _objectDp.f; var gOPN = _objectGopn.f; @@ -4040,12 +4107,6 @@ exports[ARRAY_BUFFER] = $ArrayBuffer; exports[DATA_VIEW] = $DataView; }); -// 7.2.2 IsArray(argument) - -var _isArray = Array.isArray || function isArray(arg) { - return _cof(arg) == 'Array'; -}; - var SPECIES$3 = _wks('species'); var _arraySpeciesConstructor = function (original) { @@ -6286,7 +6347,14 @@ ShaderProgram.updateProgram = function (gl, program, vertex_shader_source, fragm } gl.attachShader(program, vertex_shader); - gl.attachShader(program, fragment_shader); + gl.attachShader(program, fragment_shader); // Require position to be at attribute location 0 + // Attribute 0 should never be disabled (per GL best practices). All of our shader programs have an `a_position` + // attribute, and it's customary for the vertex position to be the first attribute, so we enforce that here. + // This can avoid unexpected/undefined interaction between static and dynamic attributes in Safari, and + // possible warnings/errors in other browsers. + // See https://stackoverflow.com/questions/20305231/webgl-warning-attribute-0-is-disabled-this-has-significant-performance-penalt/20923946 + + gl.bindAttribLocation(program, 0, 'a_position'); gl.linkProgram(program); // TODO: reference count and delete shader objects when no programs reference them if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { @@ -6351,11 +6419,16 @@ var VertexArrayObject = { log('warn', 'Vertex Array Object extension force disabled'); } }, + getExtension: function getExtension$$1(gl, ext_name) { + if (this.disabled !== true) { + return getExtension(gl, ext_name); + } + }, create: function create(gl, setup, teardown) { var vao = {}; vao.setup = setup; vao.teardown = teardown; - var ext = getExtension(gl, 'OES_vertex_array_object'); + var ext = this.getExtension(gl, 'OES_vertex_array_object'); if (ext != null) { vao._vao = ext.createVertexArrayOES(); @@ -6384,7 +6457,7 @@ var VertexArrayObject = { } }, bind: function bind(gl, vao) { - var ext = getExtension(gl, 'OES_vertex_array_object'); + var ext = this.getExtension(gl, 'OES_vertex_array_object'); if (vao != null) { if (ext != null && vao._vao != null) { @@ -6406,7 +6479,7 @@ var VertexArrayObject = { } }, destroy: function destroy(gl, vao) { - var ext = getExtension(gl, 'OES_vertex_array_object'); + var ext = this.getExtension(gl, 'OES_vertex_array_object'); if (ext != null && vao != null && vao._vao != null) { ext.deleteVertexArrayOES(vao._vao); @@ -6426,6 +6499,20 @@ _export(_export.S, 'Object', { } }); +// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined) + +var $find = _arrayMethods(6); +var KEY = 'findIndex'; +var forced = true; +// Shouldn't skip holes +if (KEY in []) Array(1)[KEY](function () { forced = false; }); +_export(_export.P + _export.F * forced, 'Array', { + findIndex: function findIndex(callbackfn /* , that = undefined */) { + return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); +_addToUnscopables(KEY); + // Deep/recursive merge of one or more source objects into a destination object function mergeObjects(dest) { for (var s = 0; s < (arguments.length <= 1 ? 0 : arguments.length - 1); s++) { @@ -6458,66 +6545,103 @@ function mergeObjects(dest) { return dest; } -var _meta = createCommonjsModule(function (module) { -var META = _uid('meta'); +var _stringWs = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; +var space = '[' + _stringWs + ']'; +var non = '\u200b\u0085'; +var ltrim = RegExp('^' + space + space + '*'); +var rtrim = RegExp(space + space + '*$'); -var setDesc = _objectDp.f; -var id = 0; -var isExtensible = Object.isExtensible || function () { - return true; -}; -var FREEZE = !_fails(function () { - return isExtensible(Object.preventExtensions({})); -}); -var setMeta = function (it) { - setDesc(it, META, { value: { - i: 'O' + ++id, // object ID - w: {} // weak collections IDs - } }); -}; -var fastKey = function (it, create) { - // return primitive with prefix - if (!_isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; - if (!_has(it, META)) { - // can't set metadata to uncaught frozen object - if (!isExtensible(it)) return 'F'; - // not necessary to add metadata - if (!create) return 'E'; - // add missing metadata - setMeta(it); - // return object ID - } return it[META].i; -}; -var getWeak = function (it, create) { - if (!_has(it, META)) { - // can't set metadata to uncaught frozen object - if (!isExtensible(it)) return true; - // not necessary to add metadata - if (!create) return false; - // add missing metadata - setMeta(it); - // return hash weak collections IDs - } return it[META].w; -}; -// add metadata on freeze-family methods calling -var onFreeze = function (it) { - if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it); - return it; -}; -var meta = module.exports = { - KEY: META, - NEED: false, - fastKey: fastKey, - getWeak: getWeak, - onFreeze: onFreeze -}; -}); -var _meta_1 = _meta.KEY; -var _meta_2 = _meta.NEED; -var _meta_3 = _meta.fastKey; -var _meta_4 = _meta.getWeak; -var _meta_5 = _meta.onFreeze; +var exporter = function (KEY, exec, ALIAS) { + var exp = {}; + var FORCE = _fails(function () { + return !!_stringWs[KEY]() || non[KEY]() != non; + }); + var fn = exp[KEY] = FORCE ? exec(trim) : _stringWs[KEY]; + if (ALIAS) exp[ALIAS] = fn; + _export(_export.P + _export.F * FORCE, 'String', exp); +}; + +// 1 -> String#trimLeft +// 2 -> String#trimRight +// 3 -> String#trim +var trim = exporter.trim = function (string, TYPE) { + string = String(_defined(string)); + if (TYPE & 1) string = string.replace(ltrim, ''); + if (TYPE & 2) string = string.replace(rtrim, ''); + return string; +}; + +var _stringTrim = exporter; + +var gOPN$1 = _objectGopn.f; +var gOPD$1 = _objectGopd.f; +var dP$3 = _objectDp.f; +var $trim = _stringTrim.trim; +var NUMBER = 'Number'; +var $Number = _global[NUMBER]; +var Base$1 = $Number; +var proto$2 = $Number.prototype; +// Opera ~12 has broken Object#toString +var BROKEN_COF = _cof(_objectCreate(proto$2)) == NUMBER; +var TRIM = 'trim' in String.prototype; + +// 7.1.3 ToNumber(argument) +var toNumber = function (argument) { + var it = _toPrimitive(argument, false); + if (typeof it == 'string' && it.length > 2) { + it = TRIM ? it.trim() : $trim(it, 3); + var first = it.charCodeAt(0); + var third, radix, maxCode; + if (first === 43 || first === 45) { + third = it.charCodeAt(2); + if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix + } else if (first === 48) { + switch (it.charCodeAt(1)) { + case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i + case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i + default: return +it; + } + for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) { + code = digits.charCodeAt(i); + // parseInt parses a string to a first unavailable symbol + // but ToNumber should return NaN if a string contains unavailable symbols + if (code < 48 || code > maxCode) return NaN; + } return parseInt(digits, radix); + } + } return +it; +}; + +if (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) { + $Number = function Number(value) { + var it = arguments.length < 1 ? 0 : value; + var that = this; + return that instanceof $Number + // check on 1..constructor(foo) case + && (BROKEN_COF ? _fails(function () { proto$2.valueOf.call(that); }) : _cof(that) != NUMBER) + ? _inheritIfRequired(new Base$1(toNumber(it)), that, $Number) : toNumber(it); + }; + for (var keys$1 = _descriptors ? gOPN$1(Base$1) : ( + // ES3: + 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + + // ES6 (in case, if modules with ES6 Number statics required before): + 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' + + 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger' + ).split(','), j = 0, key$1; keys$1.length > j; j++) { + if (_has(Base$1, key$1 = keys$1[j]) && !_has($Number, key$1)) { + dP$3($Number, key$1, gOPD$1(Base$1, key$1)); + } + } + $Number.prototype = proto$2; + proto$2.constructor = $Number; + _redefine(_global, NUMBER, $Number); +} + +// 20.1.2.10 Number.MIN_SAFE_INTEGER + + +_export(_export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff }); // 19.1.2.5 Object.freeze(O) @@ -8779,9 +8903,9 @@ function () { this.extra_data = config.extra_data; // Optional additional scripts made available to the transform function // NOTE: these are loaded alongside the library when the workers are instantiated - this.scripts = config.scripts; // overzoom will apply for zooms higher than this + this.scripts = config.scripts; // Configure zoom ranges at which new data will be loaded - this.max_zoom = config.max_zoom != null ? config.max_zoom : Geo$1.default_source_max_zoom; // set a custom extra overzoom adjustment factor to load consistently lower zoom levels + this.setZooms(config); // set a custom extra overzoom adjustment factor to load consistently lower zoom levels // than the current map zoom level – eg a zoom_offset of 1 would load z3 data at z4 this.zoom_offset = config.zoom_offset != null ? config.zoom_offset : 0; @@ -8797,7 +8921,7 @@ function () { this.setTileSize(config.tile_size); // no tiles will be requested or displayed outside of these min/max values - this.min_display_zoom = config.min_display_zoom != null ? config.min_display_zoom : 0; + this.min_display_zoom = Math.max(config.min_display_zoom || 0, this.zooms[0]); this.max_display_zoom = config.max_display_zoom != null ? config.max_display_zoom : null; } // Register a new data source type name, providing a function that returns the class name // to instantiate based on the source definition in the scene @@ -8830,7 +8954,7 @@ function () { } // subset of parameters that affect tile layout - var rebuild_params = ['max_zoom', 'min_display_zoom', 'max_display_zoom', 'bounds', 'tile_size', 'zoom_offset']; + var rebuild_params = ['max_zoom', 'zooms', 'min_display_zoom', 'max_display_zoom', 'bounds', 'tile_size', 'zoom_offset']; var cur = sliceObject(source.config, rebuild_params); var prev = sliceObject(prev_source.config, rebuild_params); return JSON.stringify(cur) !== JSON.stringify(prev); @@ -8937,6 +9061,27 @@ function () { dest.pad_scale = source.pad_scale; dest.default_winding = source.default_winding; return dest; + } // Configure zoom ranges at which new data will be loaded + // e.g. can be used to skip fetching data for some zooms, reusing data from next lowest available zoom instead + ; + + _proto.setZooms = function setZooms(_ref2) { + var max_zoom = _ref2.max_zoom, + zooms = _ref2.zooms; + // overzoom will apply for zooms higher than this + this.max_zoom = max_zoom != null ? max_zoom : Geo$1.default_source_max_zoom; + + if (Array.isArray(zooms)) { + this.zooms = zooms; // TODO: support range parsing, e.g. [0-4, 6-7, 12]? + + this.max_zoom = this.zooms[this.zooms.length - 1]; // overrides `max_zoom` when both are present + } else { + this.zooms = []; + + for (var i = 0; i <= this.max_zoom; i++) { + this.zooms[i] = i; + } + } } // Set the internal tile size in pixels, e.g. '256px' (default), '512px', etc. // Must be a power of 2, and greater than or equal to 256 ; @@ -8956,12 +9101,7 @@ function () { // 1024px tiles are 2 levels bigger - this.zoom_bias = Math.log2(this.tile_size) - 8 + this.zoom_offset; // the max/min coordinate zoom level at which tiles will be loaded from server - // (but tiles can be styled at other zooms) - // zoom_bias adjusts for tile sizes > than 256px, and manual zoom_offset - - this.max_coord_zoom = this.max_zoom + this.zoom_bias; - this.min_coord_zoom = this.zoom_bias; + this.zoom_bias = Math.log2(this.tile_size) - 8 + this.zoom_offset; } // Infer winding for data source from first ring of provided geometry ; @@ -9025,9 +9165,9 @@ function (_DataSource) { dupes = _URLs$addParamsToURL[1]; _this3.url = url; - dupes.forEach(function (_ref2) { - var param = _ref2[0], - value = _ref2[1]; + dupes.forEach(function (_ref3) { + var param = _ref3[0], + value = _ref3[1]; log({ level: 'warn', once: true @@ -9229,7 +9369,8 @@ function (_NetworkSource) { } // tile URL template replacement - var url = url_template.replace('{x}', coords.x).replace('{y}', coords.y).replace('{z}', coords.z).replace('{r}', this.getDensityModifier()); // modify URL by display density (e.g. @2x) + var url = url_template.replace('{x}', coords.x).replace('{y}', coords.y).replace('{z}', coords.z).replace('{r}', this.getDensityModifier()) // modify URL by display density (e.g. @2x) + .replace('{q}', this.toQuadKey(coords)); // quadkey for tile coordinates if (this.url_subdomains != null) { url = url.replace('{s}', this.url_subdomains[this.next_url_subdomain]); @@ -9258,18 +9399,33 @@ function (_NetworkSource) { } return ''; // for 1x (or less) displays, no URL modifier is used (following @2x URL convention) + }; + + _proto3.toQuadKey = function toQuadKey(_ref4) { + var x = _ref4.x, + y = _ref4.y, + z = _ref4.z; + var quadkey = ''; + + for (var i = z; i > 0; i--) { + var b = 0; + var mask = 1 << i - 1; + if ((x & mask) !== 0) b++; + if ((y & mask) !== 0) b += 2; + quadkey += b.toString(); + } + + return quadkey; } // Checks for the x/y/z tile pattern in URL template ; NetworkTileSource.urlHasTilePattern = function urlHasTilePattern(url) { - return url && url.search('{x}') > -1 && url.search('{y}') > -1 && url.search('{z}') > -1; + return url && (url.search('{x}') > -1 && url.search('{y}') > -1 && url.search('{z}') > -1 || url.search('{q}') > -1); }; return NetworkTileSource; }(NetworkSource); -var COORD_CHILDREN = {}; // only allocate children coords once per coord - var TileID = { coord: function coord(c) { return { @@ -9297,10 +9453,10 @@ var TileID = { }, normalizedCoord: function normalizedCoord(coords, source) { if (source.zoom_bias) { - coords = this.coordAtZoom(coords, coords.z - source.zoom_bias); + coords = this.coordAtZoom(coords, Math.max(coords.z - source.zoom_bias, source.zooms[0])); } - return this.coordWithMaxZoom(coords, source.max_zoom); + return this.coordForTileZooms(coords, source.zooms); }, coordAtZoom: function coordAtZoom(_ref2, zoom) { var x = _ref2.x, @@ -9321,17 +9477,18 @@ var TileID = { z: z }); }, - coordWithMaxZoom: function coordWithMaxZoom(_ref3, max_zoom) { + coordForTileZooms: function coordForTileZooms(_ref3, zooms) { var x = _ref3.x, y = _ref3.y, z = _ref3.z; + var nz = this.findZoomInRange(z, zooms); - if (max_zoom != null && z > max_zoom) { + if (nz !== z) { return this.coordAtZoom({ x: x, y: y, z: z - }, max_zoom); + }, nz); } return this.coord({ @@ -9340,36 +9497,10 @@ var TileID = { z: z }); }, - childrenForCoord: function childrenForCoord(_ref4) { - var x = _ref4.x, - y = _ref4.y, - z = _ref4.z, - key = _ref4.key; - - if (!COORD_CHILDREN[key]) { - z++; - x *= 2; - y *= 2; - COORD_CHILDREN[key] = [this.coord({ - x: x, - y: y, - z: z - }), this.coord({ - x: x + 1, - y: y, - z: z - }), this.coord({ - x: x, - y: y + 1, - z: z - }), this.coord({ - x: x + 1, - y: y + 1, - z: z - })]; - } - - return COORD_CHILDREN[key]; + findZoomInRange: function findZoomInRange(z, zooms) { + return zooms.filter(function (s) { + return z >= s; + }).reverse()[0] || zooms[0]; }, isDescendant: function isDescendant(parent, descendant) { if (descendant.z > parent.z) { @@ -9383,60 +9514,83 @@ var TileID = { return false; }, // Return identifying info for tile's parent tile - parent: function parent(_ref5) { - var coords = _ref5.coords, - source = _ref5.source, - style_z = _ref5.style_z; + parent: function parent(_ref4) { + var coords = _ref4.coords, + source = _ref4.source, + style_z = _ref4.style_z; - if (style_z > source.max_coord_zoom || style_z <= source.min_coord_zoom) { - if (style_z > 0) { - // no more tiles above style zoom 0 - return { - key: this.key(coords, source, style_z - 1), - coords: coords, - style_z: style_z - 1, - source: source - }; + if (style_z > 0) { + // no more tiles above style zoom 0 + style_z--; + var sz = Math.max(style_z - source.zoom_bias, source.zooms[0]); // z can't be lower than tile source + + var c = this.coordForTileZooms(this.coordAtZoom(coords, sz), source.zooms); + + if (c.z > style_z) { + return null; } - return; - } else if (style_z > 0) { - // no more tiles above style zoom 0 - var c = this.coordAtZoom(coords, coords.z - 1); return { - key: this.key(c, source, style_z - 1), + key: this.key(c, source, style_z), coords: c, - style_z: style_z - 1, + style_z: style_z, source: source }; } }, // Return identifying info for tile's child tiles - children: function children(_ref6) { - var _this = this; + children: function children(_ref5, CACHE) { + var coords = _ref5.coords, + source = _ref5.source, + style_z = _ref5.style_z; + + if (CACHE === void 0) { + CACHE = {}; + } - var coords = _ref6.coords, - source = _ref6.source, - style_z = _ref6.style_z; + style_z++; + var c = this.coordForTileZooms(this.coordAtZoom(coords, style_z - source.zoom_bias), source.zooms); - if (style_z >= source.max_coord_zoom || style_z < source.min_coord_zoom) { + if (c.z === coords.z) { + // same coord zoom for next level down return [{ - key: this.key(coords, source, style_z + 1), - coords: coords, - style_z: style_z + 1, + key: this.key(c, source, style_z), + coords: c, + style_z: style_z, source: source }]; - } + } else { + // coord zoom advanced down + var key = this.key(c, source, style_z); + CACHE[source.id] = CACHE[source.id] || {}; + + if (CACHE[source.id][key] == null) { + var span = Math.pow(2, c.z - coords.z); + var x = coords.x * span; + var y = coords.y * span; + var children = []; + + for (var nx = x; nx < x + span; nx++) { + for (var ny = y; ny < y + span; ny++) { + var nc = this.coord({ + x: nx, + y: ny, + z: c.z + }); + children.push({ + key: this.key(nc, source, style_z), + coords: nc, + style_z: style_z, + source: source + }); + } + } - var children = this.childrenForCoord(coords); - return children.map(function (c) { - return { - key: _this.key(c, source, style_z + 1), - coords: c, - style_z: style_z + 1, - source: source - }; - }); + CACHE[source.id][key] = children; + } + + return CACHE[source.id][key]; + } } }; @@ -9532,7 +9686,7 @@ function (_NetworkTileSource) { // do extra zoom adjustment and apply this raster source's max zoom coords = TileID.normalizedCoord(tile.coords, { zoom_bias: zdiff, - max_zoom: this.max_zoom + zooms: this.zooms }); } else { // raster source supports higher detail, but was downsampled to match (the downsampling already @@ -9545,7 +9699,7 @@ function (_NetworkTileSource) { } // no extra zoom adjustment needed, but still need to apply this raster source's max zoom - coords = TileID.coordWithMaxZoom(coords, this.max_zoom); + coords = TileID.coordForTileZooms(coords, this.zooms); } } @@ -9819,19 +9973,27 @@ var Style = { this.vertex_template = []; // shared single-vertex template, filled out by each style - this.tile_data = {}; // Default world coords to wrap every 100,000 meters, can turn off by setting this to 'false' + this.tile_data = {}; + this.stencil_proxy_tiles = true; // applied to proxy tiles w/non-opaque blend mode to avoid compounding alpha + // Default world coords to wrap every 100,000 meters, can turn off by setting this to 'false' this.defines.TANGRAM_WORLD_POSITION_WRAP = 100000; // Blending + // `opaque` styles are drawn first/under other styles, without alpha blending - this.blend = this.blend || 'opaque'; // default: opaque styles are drawn first, without blending + this.blend = this.blend || 'opaque'; // default to opaque - this.defines["TANGRAM_BLEND_" + this.blend.toUpperCase()] = true; - - if (this.blend_order == null) { - // controls order of rendering for styles w/non-opaque blending - this.blend_order = -1; // defaults to first + if (this.blend !== 'opaque') { + // non-opaque styles can customize their blend order, which will determine which features + // are drawn first/under each other + if (this.blend_order == null) { + this.blend_order = this.default_blend_orders[this.blend]; + } + } else { + // `opaque` ignores blend order, always render first/under + this.blend_order = this.default_blend_orders[this.blend]; } + this.defines["TANGRAM_BLEND_" + this.blend.toUpperCase()] = true; this.removeShaderBlock('setup'); // clear before material injection // If the style defines its own material, replace the inherited material instance @@ -10580,42 +10742,16 @@ var Style = { }, // Default sort order for blend modes default_blend_orders: { - opaque: 0, + opaque: Number.MIN_SAFE_INTEGER, add: 1, multiply: 2, inlay: 3, translucent: 4, overlay: 5 }, - // Comparison function for sorting styles by blend - blendOrderSort: function blendOrderSort(a, b) { - // opaque always comes first - if (a.blend === 'opaque' || b.blend === 'opaque') { - if (a.blend === 'opaque' && b.blend === 'opaque') { - // if both are opaque - return a.name < b.name ? -1 : 1; // use name as tie breaker - } else if (a.blend === 'opaque') { - return -1; // only `a` was opaque - } else { - return 1; // only `b` was opaque - } - } // use explicit blend order if possible - - - if (a.blend_order < b.blend_order) { - return -1; - } else if (a.blend_order > b.blend_order) { - return 1; - } // if blend orders are equal, use default order by blend mode - - - if (Style.default_blend_orders[a.blend] < Style.default_blend_orders[b.blend]) { - return -1; - } else if (Style.default_blend_orders[a.blend] > Style.default_blend_orders[b.blend]) { - return 1; - } - - return a.name < b.name ? -1 : 1; // use name as tie breaker + getBlendOrderForDraw: function getBlendOrderForDraw(draw) { + // Allow draw block to override blend_order for non-opaque blend styles + return this.blend !== 'opaque' && draw.blend_order != null ? draw.blend_order : this.blend_order; } }; // add feature and geometry counts for a single layer @@ -11882,7 +12018,7 @@ function triangulatePolygon(data) { return earcut_1(data.vertices, data.holes, data.dimensions); } -var polygons_vs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_tile_proxy_depth;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\n\nuniform mat4 u_model;\nuniform mat4 u_modelView;\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nattribute vec4 a_position;\nattribute vec4 a_color;\n\n// Optional normal attribute, otherwise default to up\n#ifdef TANGRAM_NORMAL_ATTRIBUTE\n attribute vec3 a_normal;\n #define TANGRAM_NORMAL a_normal\n#else\n #define TANGRAM_NORMAL vec3(0., 0., 1.)\n#endif\n\n// Optional dynamic line extrusion\n#ifdef TANGRAM_EXTRUDE_LINES\n attribute vec2 a_extrude; // extrusion direction in xy plane\n attribute vec2 a_offset; // offset direction in xy plane\n\n // Polygon and line styles have slightly different VBO layouts, saving memory by optimizing vertex packing.\n // All lines have a width scaling factor, but only some have a height (position.z) or offset.\n // The vertex height is stored in different attributes to account for this.\n attribute vec2 a_z_and_offset_scale; // stores vertex height in x, and offset scaling factor in y\n #define TANGRAM_POSITION_Z a_z_and_offset_scale.x // vertex height is stored in separate line-specific attrib\n #define TANGRAM_OFFSET_SCALING a_z_and_offset_scale.y // zoom scaling factor for line offset\n #define TANGRAM_WIDTH_SCALING a_position.z // zoom scaling factor for line width (stored in position attrib)\n\n uniform float u_v_scale_adjust; // scales texture UVs for line dash patterns w/fractional pixel width\n#else\n #define TANGRAM_POSITION_Z a_position.z // vertex height\n#endif\n\nvarying vec4 v_position;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvarying vec4 v_world_position;\n\n// Optional texture UVs\n#if defined(TANGRAM_TEXTURE_COORDS) || defined(TANGRAM_EXTRUDE_LINES)\n attribute vec2 a_texcoord;\n varying vec2 v_texcoord;\n#endif\n\n// Optional model position varying for tile coordinate zoom\n#ifdef TANGRAM_MODEL_POSITION_BASE_ZOOM_VARYING\n varying vec4 v_modelpos_base_zoom;\n#endif\n\n#if defined(TANGRAM_LIGHTING_VERTEX)\n varying vec4 v_lighting;\n#endif\n\n#define TANGRAM_UNPACK_SCALING(x) (x / 1024.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvoid main() {\n // Initialize globals\n #pragma tangram: setup\n\n // Texture UVs\n #ifdef TANGRAM_TEXTURE_COORDS\n v_texcoord = a_texcoord;\n #ifdef TANGRAM_EXTRUDE_LINES\n v_texcoord.y *= u_v_scale_adjust;\n #endif\n #endif\n\n // Pass model position to fragment shader\n #ifdef TANGRAM_MODEL_POSITION_BASE_ZOOM_VARYING\n v_modelpos_base_zoom = modelPositionBaseZoom();\n #endif\n\n // Position\n vec4 position = vec4(a_position.xy, TANGRAM_POSITION_Z / TANGRAM_HEIGHT_SCALE, 1.); // convert height back to meters\n\n #ifdef TANGRAM_EXTRUDE_LINES\n vec2 extrude = a_extrude.xy;\n vec2 offset = a_offset.xy;\n\n // Adjust line width based on zoom level, to prevent proxied lines\n // from being either too small or too big.\n // \"Flattens\" the zoom between 1-2 to peg it to 1 (keeps lines from\n // prematurely shrinking), then interpolate and clamp to 4 (keeps lines\n // from becoming too small when far away).\n float dz = clamp(u_map_position.z - u_tile_origin.z, 0., 4.);\n dz += step(1., dz) * (1. - dz) + mix(0., 2., clamp((dz - 2.) / 2., 0., 1.));\n\n // Interpolate line width between zooms\n float mdz = (dz - 0.5) * 2.; // zoom from mid-point\n extrude -= extrude * TANGRAM_UNPACK_SCALING(TANGRAM_WIDTH_SCALING) * mdz;\n\n // Interpolate line offset between zooms\n // Scales from the larger value to the smaller one\n float dwdz = TANGRAM_UNPACK_SCALING(TANGRAM_OFFSET_SCALING);\n float sdwdz = sign(step(0., dwdz) - 0.5); // sign indicates \"direction\" of scaling\n offset -= offset * abs(dwdz) * ((1.-step(0., sdwdz)) - (dz * -sdwdz)); // scale \"up\" or \"down\"\n\n // Scale line width and offset to be consistent in screen space\n float ssz = exp2(-dz - (u_tile_origin.z - u_tile_origin.w));\n extrude *= ssz;\n offset *= ssz;\n\n // Modify line width before extrusion\n #ifdef TANGRAM_BLOCK_WIDTH\n float width = 1.;\n #pragma tangram: width\n extrude *= width;\n #endif\n\n position.xy += extrude + offset;\n #endif\n\n // World coordinates for 3d procedural textures\n v_world_position = wrapWorldPosition(u_model * position);\n\n // Adjust for tile and view position\n position = u_modelView * position;\n\n // Modify position before camera projection\n #pragma tangram: position\n\n // Setup varyings\n v_position = position;\n v_normal = normalize(u_normalMatrix * TANGRAM_NORMAL);\n v_color = a_color;\n\n #if defined(TANGRAM_LIGHTING_VERTEX)\n // Vertex lighting\n vec3 normal = v_normal;\n\n // Modify normal before lighting\n #pragma tangram: normal\n\n // Pass lighting intensity to fragment shader\n v_lighting = calculateLighting(position.xyz - u_eye, normal, vec4(1.));\n #endif\n\n // Camera\n cameraProjection(position);\n\n // +1 is to keep all layers including proxies > 0\n applyLayerOrder(a_position.w + u_tile_proxy_depth + 1., position);\n\n gl_Position = position;\n}\n"; +var polygons_vs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_tile_proxy_order_offset;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\n\nuniform mat4 u_model;\nuniform mat4 u_modelView;\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nattribute vec4 a_position;\nattribute vec4 a_color;\n\n// Optional normal attribute, otherwise default to up\n#ifdef TANGRAM_NORMAL_ATTRIBUTE\n attribute vec3 a_normal;\n #define TANGRAM_NORMAL a_normal\n#else\n #define TANGRAM_NORMAL vec3(0., 0., 1.)\n#endif\n\n// Optional dynamic line extrusion\n#ifdef TANGRAM_EXTRUDE_LINES\n attribute vec2 a_extrude; // extrusion direction in xy plane\n attribute vec2 a_offset; // offset direction in xy plane\n\n // Polygon and line styles have slightly different VBO layouts, saving memory by optimizing vertex packing.\n // All lines have a width scaling factor, but only some have a height (position.z) or offset.\n // The vertex height is stored in different attributes to account for this.\n attribute vec2 a_z_and_offset_scale; // stores vertex height in x, and offset scaling factor in y\n #define TANGRAM_POSITION_Z a_z_and_offset_scale.x // vertex height is stored in separate line-specific attrib\n #define TANGRAM_OFFSET_SCALING a_z_and_offset_scale.y // zoom scaling factor for line offset\n #define TANGRAM_WIDTH_SCALING a_position.z // zoom scaling factor for line width (stored in position attrib)\n\n uniform float u_v_scale_adjust; // scales texture UVs for line dash patterns w/fractional pixel width\n#else\n #define TANGRAM_POSITION_Z a_position.z // vertex height\n#endif\n\nvarying vec4 v_position;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvarying vec4 v_world_position;\n\n// Optional texture UVs\n#if defined(TANGRAM_TEXTURE_COORDS) || defined(TANGRAM_EXTRUDE_LINES)\n attribute vec2 a_texcoord;\n varying vec2 v_texcoord;\n#endif\n\n// Optional model position varying for tile coordinate zoom\n#ifdef TANGRAM_MODEL_POSITION_BASE_ZOOM_VARYING\n varying vec4 v_modelpos_base_zoom;\n#endif\n\n#if defined(TANGRAM_LIGHTING_VERTEX)\n varying vec4 v_lighting;\n#endif\n\n#define TANGRAM_UNPACK_SCALING(x) (x / 1024.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvoid main() {\n // Initialize globals\n #pragma tangram: setup\n\n // Texture UVs\n #ifdef TANGRAM_TEXTURE_COORDS\n v_texcoord = a_texcoord;\n #ifdef TANGRAM_EXTRUDE_LINES\n v_texcoord.y *= u_v_scale_adjust;\n #endif\n #endif\n\n // Pass model position to fragment shader\n #ifdef TANGRAM_MODEL_POSITION_BASE_ZOOM_VARYING\n v_modelpos_base_zoom = modelPositionBaseZoom();\n #endif\n\n // Position\n vec4 position = vec4(a_position.xy, TANGRAM_POSITION_Z / TANGRAM_HEIGHT_SCALE, 1.); // convert height back to meters\n\n #ifdef TANGRAM_EXTRUDE_LINES\n vec2 extrude = a_extrude.xy;\n vec2 offset = a_offset.xy;\n\n // Adjust line width based on zoom level, to prevent proxied lines\n // from being either too small or too big.\n // \"Flattens\" the zoom between 1-2 to peg it to 1 (keeps lines from\n // prematurely shrinking), then interpolate and clamp to 4 (keeps lines\n // from becoming too small when far away).\n float dz = clamp(u_map_position.z - u_tile_origin.z, 0., 4.);\n dz += step(1., dz) * (1. - dz) + mix(0., 2., clamp((dz - 2.) / 2., 0., 1.));\n\n // Interpolate line width between zooms\n float mdz = (dz - 0.5) * 2.; // zoom from mid-point\n extrude -= extrude * TANGRAM_UNPACK_SCALING(TANGRAM_WIDTH_SCALING) * mdz;\n\n // Interpolate line offset between zooms\n // Scales from the larger value to the smaller one\n float dwdz = TANGRAM_UNPACK_SCALING(TANGRAM_OFFSET_SCALING);\n float sdwdz = sign(step(0., dwdz) - 0.5); // sign indicates \"direction\" of scaling\n offset -= offset * abs(dwdz) * ((1.-step(0., sdwdz)) - (dz * -sdwdz)); // scale \"up\" or \"down\"\n\n // Scale line width and offset to be consistent in screen space\n float ssz = exp2(-dz - (u_tile_origin.z - u_tile_origin.w));\n extrude *= ssz;\n offset *= ssz;\n\n // Modify line width before extrusion\n #ifdef TANGRAM_BLOCK_WIDTH\n float width = 1.;\n #pragma tangram: width\n extrude *= width;\n #endif\n\n position.xy += extrude + offset;\n #endif\n\n // World coordinates for 3d procedural textures\n v_world_position = wrapWorldPosition(u_model * position);\n\n // Adjust for tile and view position\n position = u_modelView * position;\n\n // Modify position before camera projection\n #pragma tangram: position\n\n // Setup varyings\n v_position = position;\n v_normal = normalize(u_normalMatrix * TANGRAM_NORMAL);\n v_color = a_color;\n\n #if defined(TANGRAM_LIGHTING_VERTEX)\n // Vertex lighting\n vec3 normal = v_normal;\n\n // Modify normal before lighting\n #pragma tangram: normal\n\n // Pass lighting intensity to fragment shader\n v_lighting = calculateLighting(position.xyz - u_eye, normal, vec4(1.));\n #endif\n\n // Camera\n cameraProjection(position);\n\n // +1 is to keep all layers including proxies > 0\n applyLayerOrder(a_position.w + u_tile_proxy_order_offset + 1., position);\n\n gl_Position = position;\n}\n"; var polygons_fs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\n\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nvarying vec4 v_position;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvarying vec4 v_world_position;\n\n#ifdef TANGRAM_EXTRUDE_LINES\n uniform bool u_has_line_texture;\n uniform sampler2D u_texture;\n uniform float u_texture_ratio;\n uniform vec4 u_dash_background_color;\n#endif\n\n#define TANGRAM_NORMAL v_normal\n\n#if defined(TANGRAM_TEXTURE_COORDS) || defined(TANGRAM_EXTRUDE_LINES)\n varying vec2 v_texcoord;\n#endif\n\n#ifdef TANGRAM_MODEL_POSITION_BASE_ZOOM_VARYING\n varying vec4 v_modelpos_base_zoom;\n#endif\n\n#if defined(TANGRAM_LIGHTING_VERTEX)\n varying vec4 v_lighting;\n#endif\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvoid main (void) {\n // Initialize globals\n #pragma tangram: setup\n\n vec4 color = v_color;\n vec3 normal = TANGRAM_NORMAL;\n\n // Apply raster to vertex color\n #ifdef TANGRAM_RASTER_TEXTURE_COLOR\n { // enclose in scope to avoid leakage of internal variables\n vec4 raster_color = sampleRaster(0);\n\n #if defined(TANGRAM_BLEND_OPAQUE) || defined(TANGRAM_BLEND_TRANSLUCENT) || defined(TANGRAM_BLEND_MULTIPLY)\n // Raster sources can optionally mask by the alpha channel, which will render with only full or no alpha.\n // This is used for handling transparency outside the raster image in some blend modes,\n // which either don't support alpha, or would cause transparent pixels to write to the depth buffer,\n // obscuring geometry underneath.\n #ifdef TANGRAM_HAS_MASKED_RASTERS // skip masking logic if no masked raster sources\n #ifndef TANGRAM_ALL_MASKED_RASTERS // skip conditional if *only* masked raster sources (always true)\n if (u_raster_mask_alpha) {\n #else\n {\n #endif\n #if defined(TANGRAM_BLEND_TRANSLUCENT) || defined(TANGRAM_BLEND_MULTIPLY)\n if (raster_color.a < TANGRAM_EPSILON) {\n discard;\n }\n #else // TANGRAM_BLEND_OPAQUE\n if (raster_color.a < 1. - TANGRAM_EPSILON) {\n discard;\n }\n // only allow full alpha in opaque blend mode (avoids artifacts blending w/canvas tile background)\n raster_color.a = 1.;\n #endif\n }\n #endif\n #endif\n\n color *= raster_color; // multiplied to tint texture color\n }\n #endif\n\n // Apply line texture\n #ifdef TANGRAM_EXTRUDE_LINES\n { // enclose in scope to avoid leakage of internal variables\n if (u_has_line_texture) {\n vec2 _line_st = vec2(v_texcoord.x, fract(v_texcoord.y / u_texture_ratio));\n vec4 _line_color = texture2D(u_texture, _line_st);\n\n if (_line_color.a < TANGRAM_ALPHA_TEST) {\n #if defined(TANGRAM_BLEND_OPAQUE)\n // use discard when alpha blending is unavailable\n if (u_dash_background_color.a < 1. - TANGRAM_EPSILON) {\n discard;\n }\n color = vec4(u_dash_background_color.rgb, 1.); // only allow full alpha in opaque blend mode\n #else\n // use alpha channel when blending is available\n color = vec4(u_dash_background_color.rgb, color.a * step(TANGRAM_EPSILON, u_dash_background_color.a));\n #endif\n }\n else {\n color *= _line_color;\n }\n }\n }\n #endif\n\n // First, get normal from raster tile (if applicable)\n #ifdef TANGRAM_RASTER_TEXTURE_NORMAL\n normal = normalize(sampleRaster(0).rgb * 2. - 1.);\n #endif\n\n // Second, alter normal with normal map texture (if applicable)\n #if defined(TANGRAM_LIGHTING_FRAGMENT) && defined(TANGRAM_MATERIAL_NORMAL_TEXTURE)\n calculateNormal(normal);\n #endif\n\n // Normal modification applied here for fragment lighting or no lighting,\n // and in vertex shader for vertex lighting\n #if !defined(TANGRAM_LIGHTING_VERTEX)\n #pragma tangram: normal\n #endif\n\n // Color modification before lighting is applied\n #pragma tangram: color\n\n #if defined(TANGRAM_LIGHTING_FRAGMENT)\n // Calculate per-fragment lighting\n color = calculateLighting(v_position.xyz - u_eye, normal, color);\n #elif defined(TANGRAM_LIGHTING_VERTEX)\n // Apply lighting intensity interpolated from vertex shader\n color *= v_lighting;\n #endif\n\n // Post-processing effects (modify color after lighting)\n #pragma tangram: filter\n\n gl_FragColor = color;\n}\n"; @@ -11958,13 +12094,15 @@ Object.assign(Polygons, { var texcoords = this.texcoords ? 1 : 0; // whether feature has texture UVs - var key = [selection, normal, texcoords].join('/'); + var blend_order = this.getBlendOrderForDraw(draw); + var key = [selection, normal, texcoords, blend_order].join('/'); draw.variant = key; if (Polygons.variants[key] == null) { Polygons.variants[key] = { key: key, - order: 0, + blend_order: blend_order, + mesh_order: 0, selection: selection, normal: normal, texcoords: texcoords @@ -13098,8 +13236,13 @@ Object.assign(Lines, { draw.outline.dash_background_color = draw.outline.dash_background_color !== undefined ? draw.outline.dash_background_color : outline_style.dash_background_color; draw.outline.dash_background_color = draw.outline.dash_background_color !== undefined ? draw.outline.dash_background_color : draw.dash_background_color; draw.outline.dash_background_color = draw.outline.dash_background_color && StyleParser.parseColor(draw.outline.dash_background_color); - draw.outline.texcoords = outline_style.texcoords || draw.outline.texture_merged ? 1 : 0; - this.computeVariant(draw.outline); + draw.outline.texcoords = outline_style.texcoords || draw.outline.texture_merged ? 1 : 0; // outline inherits draw blend order from parent inline, unless explicitly turned off with null + + if (draw.outline.blend_order === undefined && draw.blend_order != null) { + draw.outline.blend_order = draw.blend_order; + } + + this.computeVariant(draw.outline, outline_style); } else { log({ level: 'warn', @@ -13284,7 +13427,11 @@ Object.assign(Lines, { }.bind(this)); }, // Calculate and store mesh variant (unique by draw group but not feature) - computeVariant: function computeVariant(draw) { + computeVariant: function computeVariant(draw, style) { + if (style === void 0) { + style = this; + } + // Factors that determine a unique mesh rendering variant var key = draw.offset ? 1 : 0; // whether feature has a line offset @@ -13308,8 +13455,10 @@ Object.assign(Lines, { if (draw.texture_merged) { // whether feature has a line texture key += draw.texture_merged; - } // Create unique key + } + var blend_order = style.getBlendOrderForDraw(draw); + key += '/' + blend_order; // Create unique key key = hashString(key); draw.variant = key; @@ -13317,7 +13466,8 @@ Object.assign(Lines, { if (Lines.variants[key] == null) { Lines.variants[key] = { key: key, - order: draw.is_outline ? 0 : 1, + blend_order: blend_order, + mesh_order: draw.is_outline ? 0 : 1, // outlines should be drawn first, so inline is on top selection: draw.interactive ? 1 : 0, offset: draw.offset ? 1 : 0, @@ -17298,7 +17448,7 @@ function () { return View; }(); -var points_vs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_tile_proxy_depth;\nuniform bool u_tile_fade_in;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\nuniform bool u_view_panning;\nuniform float u_view_pan_snap_timer;\n\nuniform mat4 u_model;\nuniform mat4 u_modelView;\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nattribute vec4 a_position;\nattribute vec4 a_shape;\nattribute vec4 a_color;\nattribute vec2 a_texcoord;\nattribute vec2 a_offset;\n\nuniform float u_point_type;\n\n#ifdef TANGRAM_CURVED_LABEL\n attribute vec4 a_offsets;\n attribute vec4 a_pre_angles;\n attribute vec4 a_angles;\n#endif\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n attribute float a_outline_edge;\n attribute vec4 a_outline_color;\n\n varying float v_outline_edge;\n varying vec4 v_outline_color;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_PI 3.14159265359\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvec2 rotate2D(vec2 _st, float _angle) {\n return mat2(cos(_angle),-sin(_angle),\n sin(_angle),cos(_angle)) * _st;\n}\n\n#ifdef TANGRAM_CURVED_LABEL\n // Assumes stops are [0, 0.33, 0.66, 0.99];\n float mix4linear(float a, float b, float c, float d, float x) {\n return mix(mix(a, b, 3. * x),\n mix(b,\n mix(c, d, 3. * (max(x, .66) - .66)),\n 3. * (clamp(x, .33, .66) - .33)),\n step(0.33, x)\n );\n }\n#endif\n\nvoid main() {\n // Initialize globals\n #pragma tangram: setup\n\n // discard hidden labels by collapsing into degenerate triangle\n #ifndef TANGRAM_SHOW_HIDDEN_LABELS\n if (a_shape.w == 0.) {\n gl_Position = vec4(0., 0., 0., 1.);\n return;\n }\n #else\n // highlight hidden label in fragment shader for debugging\n if (a_shape.w == 0.) {\n v_label_hidden = 1.; // label debug testing\n }\n else {\n v_label_hidden = 0.;\n }\n #endif\n\n\n v_alpha_factor = 1.0;\n v_color = a_color;\n v_texcoord = a_texcoord; // UV from vertex\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n float size = abs(a_shape.x/128.); // radius in pixels\n v_texcoord = sign(a_shape.xy)*(size+1.)/(size);\n size+=2.;\n v_aa_offset=2./size;\n }\n #endif\n\n // Position\n vec4 position = u_modelView * vec4(a_position.xyz, 1.);\n\n // Apply positioning and scaling in screen space\n vec2 shape = a_shape.xy / 256.; // values have an 8-bit fraction\n vec2 offset = vec2(a_offset.x, -a_offset.y); // flip y to make it point down\n\n float zoom = clamp(u_map_position.z - u_tile_origin.z, 0., 1.); //fract(u_map_position.z);\n float theta = a_shape.z / 4096.;\n\n #ifdef TANGRAM_CURVED_LABEL\n //TODO: potential bug? null is passed in for non-curved labels, otherwise the first offset will be 0\n if (a_offsets[0] != 0.){\n vec4 angles_scaled = (TANGRAM_PI / 16384.) * a_angles;\n vec4 pre_angles_scaled = (TANGRAM_PI / 128.) * a_pre_angles;\n vec4 offsets_scaled = (1. / 64.) * a_offsets;\n\n float pre_angle = mix4linear(pre_angles_scaled[0], pre_angles_scaled[1], pre_angles_scaled[2], pre_angles_scaled[3], zoom);\n float angle = mix4linear(angles_scaled[0], angles_scaled[1], angles_scaled[2], angles_scaled[3], zoom);\n float offset_curve = mix4linear(offsets_scaled[0], offsets_scaled[1], offsets_scaled[2], offsets_scaled[3], zoom);\n\n shape = rotate2D(shape, pre_angle); // rotate in place\n shape.x += offset_curve; // offset for curved label segment\n shape = rotate2D(shape, angle); // rotate relative to curved label anchor\n shape += rotate2D(offset, theta); // offset if specified in the scene file\n }\n else {\n shape = rotate2D(shape + offset, theta);\n }\n #else\n shape = rotate2D(shape + offset, theta);\n #endif\n\n // Fade in (if requested) based on time mesh has been visible.\n // Value passed to fragment shader in the v_alpha_factor varying\n #ifdef TANGRAM_FADE_IN_RATE\n if (u_tile_fade_in) {\n v_alpha_factor *= clamp(u_visible_time * TANGRAM_FADE_IN_RATE, 0., 1.);\n }\n #endif\n\n // Fade out when tile is zooming out, e.g. acting as proxy tiles\n // NB: this is mostly done to compensate for text label collision happening at the label's 1x zoom. As labels\n // in proxy tiles are scaled down, they begin to overlap, and the fade is a simple way to ease the transition.\n // Value passed to fragment shader in the v_alpha_factor varying\n #ifdef TANGRAM_FADE_ON_ZOOM_OUT\n v_alpha_factor *= clamp(1. + TANGRAM_FADE_ON_ZOOM_OUT_RATE * (u_map_position.z - u_tile_origin.z), 0., 1.);\n #endif\n\n // World coordinates for 3d procedural textures\n v_world_position = u_model * position;\n v_world_position.xy += shape * u_meters_per_pixel;\n v_world_position = wrapWorldPosition(v_world_position);\n\n // Modify position before camera projection\n #pragma tangram: position\n\n cameraProjection(position);\n\n #ifdef TANGRAM_LAYER_ORDER\n // +1 is to keep all layers including proxies > 0\n applyLayerOrder(a_position.w + u_tile_proxy_depth + 1., position);\n #endif\n\n // Apply pixel offset in screen-space\n // Multiply by 2 is because screen is 2 units wide Normalized Device Coords (and u_resolution device pixels wide)\n // Device pixel ratio adjustment is because shape is in logical pixels\n position.xy += shape * position.w * 2. * u_device_pixel_ratio / u_resolution;\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // enlarge by 1px to catch missed MSAA fragments\n position.xy += sign(shape) * position.w * u_device_pixel_ratio / u_resolution;\n }\n #endif\n\n // Snap to pixel grid\n // Only applied to fully upright sprites/labels (not shader-drawn points), while panning is not active\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON) && u_point_type != TANGRAM_POINT_TYPE_SHADER) {\n #else\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON)) {\n #endif\n vec2 position_fract = fract((((position.xy / position.w) + 1.) * .5) * u_resolution);\n vec2 position_snap = position.xy + ((step(0.5, position_fract) - position_fract) * position.w * 2. / u_resolution);\n\n // Animate the snapping to smooth the transition and make it less noticeable\n #ifdef TANGRAM_VIEW_PAN_SNAP_RATE\n position.xy = mix(position.xy, position_snap, clamp(u_view_pan_snap_timer * TANGRAM_VIEW_PAN_SNAP_RATE, 0., 1.));\n #else\n position.xy = position_snap;\n #endif\n }\n\n gl_Position = position;\n}\n"; +var points_vs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_tile_proxy_order_offset;\nuniform bool u_tile_fade_in;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\nuniform bool u_view_panning;\nuniform float u_view_pan_snap_timer;\n\nuniform mat4 u_model;\nuniform mat4 u_modelView;\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nattribute vec4 a_position;\nattribute vec4 a_shape;\nattribute vec4 a_color;\nattribute vec2 a_texcoord;\nattribute vec2 a_offset;\n\nuniform float u_point_type;\n\n#ifdef TANGRAM_CURVED_LABEL\n attribute vec4 a_offsets;\n attribute vec4 a_pre_angles;\n attribute vec4 a_angles;\n#endif\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n attribute float a_outline_edge;\n attribute vec4 a_outline_color;\n\n varying float v_outline_edge;\n varying vec4 v_outline_color;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_PI 3.14159265359\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvec2 rotate2D(vec2 _st, float _angle) {\n return mat2(cos(_angle),-sin(_angle),\n sin(_angle),cos(_angle)) * _st;\n}\n\n#ifdef TANGRAM_CURVED_LABEL\n // Assumes stops are [0, 0.33, 0.66, 0.99];\n float mix4linear(float a, float b, float c, float d, float x) {\n x = clamp(x, 0., 1.);\n return mix(mix(a, b, 3. * x),\n mix(b,\n mix(c, d, 3. * (max(x, .66) - .66)),\n 3. * (clamp(x, .33, .66) - .33)),\n step(0.33, x)\n );\n }\n#endif\n\nvoid main() {\n // Initialize globals\n #pragma tangram: setup\n\n // discard hidden labels by collapsing into degenerate triangle\n #ifndef TANGRAM_SHOW_HIDDEN_LABELS\n if (a_shape.w == 0.) {\n gl_Position = vec4(0., 0., 0., 1.);\n return;\n }\n #else\n // highlight hidden label in fragment shader for debugging\n if (a_shape.w == 0.) {\n v_label_hidden = 1.; // label debug testing\n }\n else {\n v_label_hidden = 0.;\n }\n #endif\n\n\n v_alpha_factor = 1.0;\n v_color = a_color;\n v_texcoord = a_texcoord; // UV from vertex\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n float size = abs(a_shape.x/128.); // radius in pixels\n v_texcoord = sign(a_shape.xy)*(size+1.)/(size);\n size+=2.;\n v_aa_offset=2./size;\n }\n #endif\n\n // Position\n vec4 position = u_modelView * vec4(a_position.xyz, 1.);\n\n // Apply positioning and scaling in screen space\n vec2 shape = a_shape.xy / 256.; // values have an 8-bit fraction\n vec2 offset = vec2(a_offset.x, -a_offset.y); // flip y to make it point down\n\n float zoom = clamp(u_map_position.z - u_tile_origin.z, 0., 1.); //fract(u_map_position.z);\n float theta = a_shape.z / 4096.;\n\n #ifdef TANGRAM_CURVED_LABEL\n //TODO: potential bug? null is passed in for non-curved labels, otherwise the first offset will be 0\n if (a_offsets[0] != 0.){\n vec4 angles_scaled = (TANGRAM_PI / 16384.) * a_angles;\n vec4 pre_angles_scaled = (TANGRAM_PI / 128.) * a_pre_angles;\n vec4 offsets_scaled = (1. / 64.) * a_offsets;\n\n float pre_angle = mix4linear(pre_angles_scaled[0], pre_angles_scaled[1], pre_angles_scaled[2], pre_angles_scaled[3], zoom);\n float angle = mix4linear(angles_scaled[0], angles_scaled[1], angles_scaled[2], angles_scaled[3], zoom);\n float offset_curve = mix4linear(offsets_scaled[0], offsets_scaled[1], offsets_scaled[2], offsets_scaled[3], zoom);\n\n shape = rotate2D(shape, pre_angle); // rotate in place\n shape.x += offset_curve; // offset for curved label segment\n shape = rotate2D(shape, angle); // rotate relative to curved label anchor\n shape += rotate2D(offset, theta); // offset if specified in the scene file\n }\n else {\n shape = rotate2D(shape + offset, theta);\n }\n #else\n shape = rotate2D(shape + offset, theta);\n #endif\n\n // Fade in (if requested) based on time mesh has been visible.\n // Value passed to fragment shader in the v_alpha_factor varying\n #ifdef TANGRAM_FADE_IN_RATE\n if (u_tile_fade_in) {\n v_alpha_factor *= clamp(u_visible_time * TANGRAM_FADE_IN_RATE, 0., 1.);\n }\n #endif\n\n // World coordinates for 3d procedural textures\n v_world_position = u_model * position;\n v_world_position.xy += shape * u_meters_per_pixel;\n v_world_position = wrapWorldPosition(v_world_position);\n\n // Modify position before camera projection\n #pragma tangram: position\n\n cameraProjection(position);\n\n #ifdef TANGRAM_LAYER_ORDER\n // +1 is to keep all layers including proxies > 0\n applyLayerOrder(a_position.w + u_tile_proxy_order_offset + 1., position);\n #endif\n\n // Apply pixel offset in screen-space\n // Multiply by 2 is because screen is 2 units wide Normalized Device Coords (and u_resolution device pixels wide)\n // Device pixel ratio adjustment is because shape is in logical pixels\n position.xy += shape * position.w * 2. * u_device_pixel_ratio / u_resolution;\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // enlarge by 1px to catch missed MSAA fragments\n position.xy += sign(shape) * position.w * u_device_pixel_ratio / u_resolution;\n }\n #endif\n\n // Snap to pixel grid\n // Only applied to fully upright sprites/labels (not shader-drawn points), while panning is not active\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON) && u_point_type != TANGRAM_POINT_TYPE_SHADER) {\n #else\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON)) {\n #endif\n vec2 position_fract = fract((((position.xy / position.w) + 1.) * .5) * u_resolution);\n vec2 position_snap = position.xy + ((step(0.5, position_fract) - position_fract) * position.w * 2. / u_resolution);\n\n // Animate the snapping to smooth the transition and make it less noticeable\n #ifdef TANGRAM_VIEW_PAN_SNAP_RATE\n position.xy = mix(position.xy, position_snap, clamp(u_view_pan_snap_timer * TANGRAM_VIEW_PAN_SNAP_RATE, 0., 1.));\n #else\n position.xy = position_snap;\n #endif\n }\n\n gl_Position = position;\n}\n"; var points_fs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\n\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nuniform sampler2D u_texture;\nuniform float u_point_type;\nuniform bool u_apply_color_blocks;\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n varying vec4 v_outline_color;\n varying float v_outline_edge;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n //l is the distance from the center to the fragment, R is the radius of the drawn point\n float _tangram_antialias(float l, float R){\n float low = R - v_aa_offset;\n float high = R + v_aa_offset;\n return 1. - smoothstep(low, high, l);\n }\n#endif\n\nvoid main (void) {\n // Initialize globals\n #pragma tangram: setup\n\n vec4 color = v_color;\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n // Only apply shader blocks to point, not to attached text (N.B.: for compatibility with ES)\n if (u_point_type == TANGRAM_POINT_TYPE_TEXTURE) { // sprite texture\n color *= texture2D(u_texture, v_texcoord);\n }\n else if (u_point_type == TANGRAM_POINT_TYPE_LABEL) { // label texture\n color = texture2D(u_texture, v_texcoord);\n color.rgb /= max(color.a, 0.001); // un-multiply canvas texture\n }\n else if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n float outline_edge = v_outline_edge;\n vec4 outlineColor = v_outline_color;\n // Distance to this fragment from the center.\n float l = length(v_texcoord);\n // Mask of outermost circle, either outline or point boundary.\n float outer_alpha = _tangram_antialias(l, 1.);\n float fill_alpha = _tangram_antialias(l, 1.-v_outline_edge*0.5) * color.a;\n float stroke_alpha = (outer_alpha - _tangram_antialias(l, 1.-v_outline_edge)) * outlineColor.a;\n\n // Apply alpha compositing with stroke 'over' fill.\n #ifdef TANGRAM_BLEND_ADD\n color.a = stroke_alpha + fill_alpha;\n color.rgb = color.rgb * fill_alpha + outlineColor.rgb * stroke_alpha;\n #else // TANGRAM_BLEND_OVERLAY (and fallback for not implemented blending modes)\n color.a = stroke_alpha + fill_alpha * (1. - stroke_alpha);\n color.rgb = mix(color.rgb * fill_alpha, outlineColor.rgb, stroke_alpha) / max(color.a, 0.001); // avoid divide by zero\n #endif\n }\n #else\n // If shader points not supported, assume label texture\n color = texture2D(u_texture, v_texcoord);\n color.rgb /= max(color.a, 0.001); // un-multiply canvas texture\n #endif\n\n // Shader blocks for color/filter are only applied for sprites, shader points, and standalone text,\n // NOT for text attached to a point (N.B.: for compatibility with ES)\n if (u_apply_color_blocks) {\n #pragma tangram: color\n #pragma tangram: filter\n }\n\n color.a *= v_alpha_factor;\n\n // highlight hidden label in fragment shader for debugging\n #ifdef TANGRAM_SHOW_HIDDEN_LABELS\n if (v_label_hidden > 0.) {\n color.a *= 0.5;\n color.rgb = vec3(1., 0., 0.);\n }\n #endif\n\n // Use alpha test as a lower-quality substitute\n // For opaque and translucent: avoid transparent pixels writing to depth buffer, obscuring geometry underneath\n // For multiply: avoid transparent pixels multiplying geometry underneath to zero/full black\n #if defined(TANGRAM_BLEND_OPAQUE) || defined(TANGRAM_BLEND_TRANSLUCENT) || defined(TANGRAM_BLEND_MULTIPLY)\n if (color.a < TANGRAM_ALPHA_TEST) {\n discard;\n }\n #endif\n\n gl_FragColor = color;\n}\n"; @@ -17312,7 +17462,7 @@ Points.variants = {}; // mesh variants by variant key Points.vertex_layouts = {}; // vertex layouts by variant key -var SHADER_POINT_VARIANT_KEY = 'shader_point'; // texture types +var SHADER_POINT_VARIANT = '__shader_point'; // texture types var TANGRAM_POINT_TYPE_TEXTURE = 1; // style texture/sprites (assigned by user) @@ -17350,7 +17500,12 @@ Object.assign(Points, { this.defines.TANGRAM_POINT_TYPE_LABEL = TANGRAM_POINT_TYPE_LABEL; this.defines.TANGRAM_POINT_TYPE_SHADER = TANGRAM_POINT_TYPE_SHADER; this.collision_group_points = this.name + '-points'; - this.collision_group_text = this.name + '-text'; + this.collision_group_text = this.name + '-text'; // Stenciling proxy tiles (to avoid compounding alpha artifacts) doesn't work well with + // points/text labels, which have pure transparent pixels that interfere with the stencil buffer, + // causing a "cut-out"/"x-ray" effect (preventing pixels that would usually be covered by proxy tiles + // underneath from being rendered). + + this.stencil_proxy_tiles = false; this.reset(); }, // Setup defines common to points base and child (text) styles @@ -17358,13 +17513,9 @@ Object.assign(Points, { // If we're not rendering as overlay, we need a layer attribute if (this.blend !== 'overlay') { this.defines.TANGRAM_LAYER_ORDER = true; - } // Fade out when tile is zooming out, e.g. acting as proxy tiles + } // Fade in labels - this.defines.TANGRAM_FADE_ON_ZOOM_OUT = true; - this.defines.TANGRAM_FADE_ON_ZOOM_OUT_RATE = 2; // fade at 2x, e.g. fully transparent at 0.5 zoom level away - // Fade in (depending on tile proxy status) - if (debugSettings$1.suppress_label_fade_in === true) { this.fade_in_time = 0; this.defines.TANGRAM_FADE_IN_RATE = null; @@ -17403,6 +17554,8 @@ Object.assign(Points, { style.texture = draw.texture; // optional point texture, specified in `draw` or at style level style.label_texture = null; // assigned by labelling code if needed + + style.blend_order = draw.blend_order; // copy pre-computed blend order // require color or texture if (!style.color && !style.texture) { @@ -17659,6 +17812,8 @@ Object.assign(Points, { style.texcoords = text_info.align[q.label.align].texcoords; style.label_texture = textures[text_info.align[q.label.align].texture_id]; + style.blend_order = q.draw.blend_order; // copy blend order from parent point + Style.addFeature.call(_this, q.feature, q.draw, q.context); }); } @@ -17692,6 +17847,8 @@ Object.assign(Points, { draw.color = StyleParser.createColorPropertyCache(draw.color); draw.texture = draw.texture !== undefined ? draw.texture : this.texture; // optional or default texture + draw.blend_order = this.getBlendOrderForDraw(draw); // from draw block, or fall back on default style blend order + if (draw.outline) { draw.outline.color = StyleParser.createColorPropertyCache(draw.outline.color); draw.outline.width = StyleParser.createPropertyCache(draw.outline.width, StyleParser.parsePositiveNumber); @@ -17754,6 +17911,7 @@ Object.assign(Points, { draw.text.group = draw.group; draw.text.layers = draw.layers; draw.text.order = draw.order; + draw.text.blend_order = draw.blend_order; draw.text.repeat_group = draw.text.repeat_group != null ? draw.text.repeat_group : draw.repeat_group; draw.text.anchor = draw.text.anchor || this.default_anchor; draw.text.optional = typeof draw.text.optional === 'boolean' ? draw.text.optional : false; // default text to required @@ -18235,14 +18393,17 @@ Object.assign(Points, { }, // Override meshVariantTypeForDraw: function meshVariantTypeForDraw(draw) { - var key = draw.label_texture || draw.texture || SHADER_POINT_VARIANT_KEY; // unique key by texture name + var texture = draw.label_texture || draw.texture || SHADER_POINT_VARIANT; // unique key by texture name + + var key = texture + '/' + draw.blend_order; if (Points.variants[key] == null) { Points.variants[key] = { key: key, - shader_point: key === SHADER_POINT_VARIANT_KEY, + shader_point: texture === SHADER_POINT_VARIANT, // is shader point - order: draw.label_texture ? 1 : 0 // put text on top of points (e.g. for highway shields, etc.) + blend_order: draw.blend_order, + mesh_order: draw.label_texture ? 1 : 0 // put text on top of points (e.g. for highway shields, etc.) }; } @@ -19207,6 +19368,8 @@ Object.assign(TextStyle, { style.label_texture = textures[text_info.align[q.label.align].texture_id]; } + style.blend_order = q.draw.blend_order; // copy pre-computed blend order + Style.addFeature.call(_this2, q.feature, q.draw, q.context); }); } @@ -19243,6 +19406,8 @@ Object.assign(TextStyle, { }, // Sets up caching for draw properties _preprocess: function _preprocess(draw) { + draw.blend_order = this.getBlendOrderForDraw(draw); // from draw block, or fall back on default style blend order + return this.preprocessText(draw); }, // Implements label building for TextLabels mixin @@ -19436,7 +19601,9 @@ var StyleManager = function () { function StyleManager() { this.styles = {}; - this.base_styles = {}; // Add built-in rendering styles + this.base_styles = {}; + this.active_styles = []; + this.active_blend_orders = []; // Add built-in rendering styles this.register(Object.create(Polygons)); this.register(Object.create(Lines)); @@ -19501,6 +19668,56 @@ function () { delete this.styles[name]; }; + _proto.getActiveStyles = function getActiveStyles() { + return this.active_styles; + } // Get list of active styles based on a set of tiles + ; + + _proto.updateActiveStyles = function updateActiveStyles(tiles) { + this.active_styles = Object.keys(tiles.reduce(function (active, tile) { + Object.keys(tile.meshes).forEach(function (s) { + return active[s] = true; + }); + return active; + }, {})); + return this.active_styles; + }; + + _proto.getActiveBlendOrders = function getActiveBlendOrders() { + return this.active_blend_orders; + }; + + _proto.updateActiveBlendOrders = function updateActiveBlendOrders(tiles) { + var orders = []; + tiles.forEach(function (tile) { + Object.entries(tile.meshes).forEach(function (_ref) { + var style = _ref[0], + style_meshes = _ref[1]; + // for each tile's set of meshes, keyed by style name + style_meshes.forEach(function (mesh) { + // for each style's list of meshes + // find entry for this mesh's blend order, insert if first entry + var blend_order = mesh.variant.blend_order; + var oi = orders.findIndex(function (x) { + return x.blend_order === blend_order; + }); + oi = oi > -1 ? oi : orders.push({ + blend_order: blend_order, + styles: [] + }) - 1; // add style to list for this blend order + + if (orders[oi].styles.indexOf(style) === -1) { + orders[oi].styles.push(style); + } + }); + }); + }); // sort ascending by blend order + + this.active_blend_orders = orders.sort(function (a, b) { + return a.blend_order - b.blend_order; + }); + }; + _proto.mix = function mix(style, styles) { // Exit early if we have already applied mixins to this style if (style.mixed) { @@ -19879,6 +20096,11 @@ function () { return StyleManager; }(); +// 20.1.2.6 Number.MAX_SAFE_INTEGER + + +_export(_export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff }); + function notNull(x) { return x != null; } @@ -20030,7 +20252,7 @@ function buildFilter(filter, options) { return new Function('context', 'return ' + filterToString(parseFilter(filter, options)) + ';'); } -var reserved = ['filter', 'draw', 'visible', 'enabled', 'data']; +var reserved = ['filter', 'draw', 'visible', 'enabled', 'data', 'exclusive', 'priority']; var layer_cache = {}; function layerCache() { return layer_cache; @@ -20083,18 +20305,10 @@ function mergeTrees(matchingTrees, group) { if (draws.length === 0) { return "continue"; - } // Sort by layer name before merging, so layers are applied deterministically - // when multiple layers modify the same properties + } // Merge draw objects - draws.sort(function (a, b) { - return (a && a.layer_name) > (b && b.layer_name) ? 1 : -1; - }); // Merge draw objects - - mergeObjects.apply(void 0, [draw].concat(draws)); // Remove layer names, they were only used transiently to sort and calculate final layer - // (final merged names will not be accurate since only one tree can win) - - delete draw.layer_name; + mergeObjects.apply(void 0, [draw].concat(draws)); }; for (var x = 0; x < treeDepth; x++) { @@ -20123,6 +20337,8 @@ function () { visible = _ref.visible, enabled = _ref.enabled, filter = _ref.filter, + exclusive = _ref.exclusive, + priority = _ref.priority, styles = _ref.styles; this.id = Layer.id++; this.config_data = layer.data; @@ -20131,6 +20347,8 @@ function () { this.full_name = this.parent ? this.parent.full_name + ':' + this.name : this.name; this.draw = draw; this.filter = filter; + this.exclusive = exclusive === true; + this.priority = priority != null ? priority : Number.MAX_SAFE_INTEGER; this.styles = styles; this.is_built = false; enabled = enabled === undefined ? visible : enabled; // `visible` property is backwards compatible for `enabled` @@ -20149,8 +20367,6 @@ function () { log('warn', msg); // TODO: fire external event that clients to subscribe to delete this.draw[group]; - } else { - this.draw[group].layer_name = this.full_name; } } } @@ -20537,7 +20753,25 @@ function parseLayerChildren(parent, children, styles) { log('warn', msg); // TODO: fire external event that clients to subscribe to } - } + } // Sort sub-layers so they are applied deterministically when multiple layers modify the same properties + // Sort order is: exclusive layers first, then by explicit layer priority, then by layer name + + + parent.layers.sort(function (a, b) { + // Exclusive layers come first + // If an exclusive layer matches, no further sibling layers are matched + if (a.exclusive < b.exclusive) return 1;else if (a.exclusive > b.exclusive) return -1; // When sub-sorting exclusive layers, sort the higher priority layers first, since only one exlcusive layer + // can match and the first one that matches should be the highest priority. + // When sub-sorting non-exclusive layers, sort the lower priority layers first, since multiple layers may + // match, and when they are merged in order, the later layers will overwrite the earlier ones -- so we want + // the higher priority ones to match last so that they "win". + + var direction = a.exclusive ? 1 : -1; // Sub-sort by explicit priority + + if (a.priority > b.priority) return direction;else if (a.priority < b.priority) return -direction; // Sub-sort by layer name as last resort + + if (a.full_name < b.full_name) return direction;else if (a.full_name > b.full_name) return -direction; + }); } function parseLayers(layers, styles) { @@ -20557,7 +20791,7 @@ function parseLayers(layers, styles) { } function matchFeature(context, layers, collected_layers, collected_layers_ids) { var matched = false; - var childMatched = false; + var child_matched = false; if (layers.length === 0) { return; @@ -20571,16 +20805,24 @@ function matchFeature(context, layers, collected_layers, collected_layers_ids) { matched = true; collected_layers.push(current); collected_layers_ids.push(current.id); + + if (current.exclusive) { + break; // only one exclusive layer can match, stop matching further sibling layers + } } } else if (current.is_tree) { if (current.doesMatch(context)) { matched = true; - childMatched = matchFeature(context, current.layers, collected_layers, collected_layers_ids); + child_matched = matchFeature(context, current.layers, collected_layers, collected_layers_ids); - if (!childMatched) { + if (!child_matched) { collected_layers.push(current); collected_layers_ids.push(current.id); } + + if (current.exclusive) { + break; // only one exclusive layer can match, stop matching further sibling layers + } } } } @@ -20615,8 +20857,9 @@ function () { this.valid = true; this.visible = false; this.proxy_for = null; - this.proxy_depth = 0; this.proxied_as = null; + this.proxy_level = 0; + this.proxy_order_offset = 0; this.fade_in = true; this.loading = false; this.loaded = false; @@ -21057,8 +21300,8 @@ function () { meshes[s] = meshes[s] || []; meshes[s].push(mesh); - if (mesh.variant.order == null) { - mesh.variant.order = meshes[s].length - 1; // assign default variant render order + if (mesh.variant.mesh_order == null) { + mesh.variant.mesh_order = meshes[s].length - 1; // assign default variant render order } this.debug.buffer_size += mesh.buffer_size; @@ -21070,8 +21313,8 @@ function () { if (meshes[s]) { meshes[s].sort(function (a, b) { // Sort variant order ascending if present, then all null values (where order is unspecified) - var ao = a.variant.order, - bo = b.variant.order; + var ao = a.variant.mesh_order, + bo = b.variant.mesh_order; return ao == null ? 1 : bo == null ? -1 : ao < bo ? -1 : 1; }); } @@ -21176,12 +21419,14 @@ function () { this.visible = true; this.proxy_for = this.proxy_for || []; this.proxy_for.push(tile); - this.proxy_depth = 1; // draw proxies a half-layer back (order is scaled 2x to avoid integer truncation) + this.proxy_order_offset = 1; // draw proxies a half-layer back (order is scaled 2x to avoid integer truncation) tile.proxied_as = tile.style_z > this.style_z ? 'child' : 'parent'; + this.proxy_level = Math.abs(tile.style_z - this.style_z); // # of zoom levels proxy is above/below target tile } else { this.proxy_for = null; - this.proxy_depth = 0; + this.proxy_order_offset = 0; + this.proxy_level = 0; } }; @@ -21204,7 +21449,7 @@ function () { model32 = _ref5.model32; // Tile origin program.uniform('4fv', 'u_tile_origin', [this.min.x, this.min.y, this.style_z, this.coords.z]); - program.uniform('1f', 'u_tile_proxy_depth', this.proxy_depth); // Model - transform tile space into world space (meters, absolute mercator position) + program.uniform('1f', 'u_tile_proxy_order_offset', this.proxy_order_offset); // Model - transform tile space into world space (meters, absolute mercator position) mat4.identity(model); mat4.translate(model, model, vec3.fromValues(this.min.x, this.min.y, 0)); @@ -23605,8 +23850,6 @@ function (_NetworkSource) { _this.load_data = null; _this.tile_indexes = {}; // geojson-vt tile indices, by layer name - _this.max_zoom = Math.max(_this.max_zoom || 0, 15); // TODO: max zoom < 15 causes artifacts/no-draw at 20, investigate - _this.setTileSize(512); // auto-tile to 512px tiles for fewer internal tiles @@ -24086,6 +24329,33 @@ DataSource.register('TopoJSON', function (source) { // add all data source types +exports.require$$0 = _wks; +exports.require$$1 = _core; +exports.global = _global; +exports.require$$1$1 = _objectDp; +exports.getKeys = _objectKeys; +exports.gOPS = _objectGops; +exports.require$$0$1 = _objectPie; +exports.toIObject = _toIobject; +exports.require$$0$2 = _objectGopn; +exports.require$$0$3 = _meta; +exports.require$$0$4 = _shared; +exports.DESCRIPTORS = _descriptors; +exports.fails = _fails; +exports.require$$22 = _objectCreate; +exports.uid = _uid; +exports.redefine = _redefine; +exports.LIBRARY = _library; +exports.$export = _export; +exports.require$$17 = _has; +exports.isObject = _isObject; +exports.isArray = _isArray; +exports.hide = _hide; +exports.setToStringTag = _setToStringTag; +exports.require$$1$2 = _objectGopd; +exports.anObject = _anObject; +exports.require$$16 = _toPrimitive; +exports.require$$9 = _propertyDesc; exports.createCommonjsModule = createCommonjsModule; exports.commonjsRequire = commonjsRequire; exports.Utils = Utils; @@ -24112,22 +24382,22 @@ exports.Label = Label; exports.WorkerBroker = WorkerBroker$1; exports.Task = Task; exports.Tile = Tile; -exports.require$$0 = _typedArray; +exports._createClass = _createClass; +exports.require$$0$5 = _typedArray; exports.StyleParser = StyleParser; exports.Texture = Texture; exports.debugSettings = debugSettings$1; exports.debugSumLayerStats = debugSumLayerStats; exports.ShaderProgram = ShaderProgram; exports.VertexArrayObject = VertexArrayObject; -exports.Style = Style; exports.TextCanvas = TextCanvas; exports.DataSource = DataSource; exports.Light = Light; exports.FontManager = FontManager; exports.FeatureSelection = FeatureSelection; -exports._createClass = _createClass; exports.View = View; exports.StyleManager = StyleManager; +exports.Style = Style; exports.sliceObject = sliceObject; exports.Thread = Thread; exports.mergeDebugSettings = mergeDebugSettings; @@ -24509,6 +24779,294 @@ __chunk_1.WorkerBroker.addTarget('self', SceneWorker); define(['./shared.js'], function (__chunk_1) { 'use strict'; +var f = __chunk_1.require$$0; + +var _wksExt = { + f: f +}; + +var defineProperty = __chunk_1.require$$1$1.f; +var _wksDefine = function (name) { + var $Symbol = __chunk_1.require$$1.Symbol || (__chunk_1.require$$1.Symbol = __chunk_1.global.Symbol || {}); + if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: _wksExt.f(name) }); +}; + +_wksDefine('asyncIterator'); + +// all enumerable object keys, includes symbols + + + +var _enumKeys = function (it) { + var result = __chunk_1.getKeys(it); + var getSymbols = __chunk_1.gOPS.f; + if (getSymbols) { + var symbols = getSymbols(it); + var isEnum = __chunk_1.require$$0$1.f; + var i = 0; + var key; + while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key); + } return result; +}; + +// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window + +var gOPN = __chunk_1.require$$0$2.f; +var toString = {}.toString; + +var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames + ? Object.getOwnPropertyNames(window) : []; + +var getWindowNames = function (it) { + try { + return gOPN(it); + } catch (e) { + return windowNames.slice(); + } +}; + +var f$1 = function getOwnPropertyNames(it) { + return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(__chunk_1.toIObject(it)); +}; + +var _objectGopnExt = { + f: f$1 +}; + +// ECMAScript 6 symbols shim + + + + + +var META = __chunk_1.require$$0$3.KEY; + + + + + + + + + + + + + + + + + + + +var gOPD = __chunk_1.require$$1$2.f; +var dP = __chunk_1.require$$1$1.f; +var gOPN$1 = _objectGopnExt.f; +var $Symbol = __chunk_1.global.Symbol; +var $JSON = __chunk_1.global.JSON; +var _stringify = $JSON && $JSON.stringify; +var PROTOTYPE = 'prototype'; +var HIDDEN = __chunk_1.require$$0('_hidden'); +var TO_PRIMITIVE = __chunk_1.require$$0('toPrimitive'); +var isEnum = {}.propertyIsEnumerable; +var SymbolRegistry = __chunk_1.require$$0$4('symbol-registry'); +var AllSymbols = __chunk_1.require$$0$4('symbols'); +var OPSymbols = __chunk_1.require$$0$4('op-symbols'); +var ObjectProto = Object[PROTOTYPE]; +var USE_NATIVE = typeof $Symbol == 'function'; +var QObject = __chunk_1.global.QObject; +// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 +var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; + +// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 +var setSymbolDesc = __chunk_1.DESCRIPTORS && __chunk_1.fails(function () { + return __chunk_1.require$$22(dP({}, 'a', { + get: function () { return dP(this, 'a', { value: 7 }).a; } + })).a != 7; +}) ? function (it, key, D) { + var protoDesc = gOPD(ObjectProto, key); + if (protoDesc) delete ObjectProto[key]; + dP(it, key, D); + if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc); +} : dP; + +var wrap = function (tag) { + var sym = AllSymbols[tag] = __chunk_1.require$$22($Symbol[PROTOTYPE]); + sym._k = tag; + return sym; +}; + +var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + return it instanceof $Symbol; +}; + +var $defineProperty = function defineProperty(it, key, D) { + if (it === ObjectProto) $defineProperty(OPSymbols, key, D); + __chunk_1.anObject(it); + key = __chunk_1.require$$16(key, true); + __chunk_1.anObject(D); + if (__chunk_1.require$$17(AllSymbols, key)) { + if (!D.enumerable) { + if (!__chunk_1.require$$17(it, HIDDEN)) dP(it, HIDDEN, __chunk_1.require$$9(1, {})); + it[HIDDEN][key] = true; + } else { + if (__chunk_1.require$$17(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false; + D = __chunk_1.require$$22(D, { enumerable: __chunk_1.require$$9(0, false) }); + } return setSymbolDesc(it, key, D); + } return dP(it, key, D); +}; +var $defineProperties = function defineProperties(it, P) { + __chunk_1.anObject(it); + var keys = _enumKeys(P = __chunk_1.toIObject(P)); + var i = 0; + var l = keys.length; + var key; + while (l > i) $defineProperty(it, key = keys[i++], P[key]); + return it; +}; +var $create = function create(it, P) { + return P === undefined ? __chunk_1.require$$22(it) : $defineProperties(__chunk_1.require$$22(it), P); +}; +var $propertyIsEnumerable = function propertyIsEnumerable(key) { + var E = isEnum.call(this, key = __chunk_1.require$$16(key, true)); + if (this === ObjectProto && __chunk_1.require$$17(AllSymbols, key) && !__chunk_1.require$$17(OPSymbols, key)) return false; + return E || !__chunk_1.require$$17(this, key) || !__chunk_1.require$$17(AllSymbols, key) || __chunk_1.require$$17(this, HIDDEN) && this[HIDDEN][key] ? E : true; +}; +var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) { + it = __chunk_1.toIObject(it); + key = __chunk_1.require$$16(key, true); + if (it === ObjectProto && __chunk_1.require$$17(AllSymbols, key) && !__chunk_1.require$$17(OPSymbols, key)) return; + var D = gOPD(it, key); + if (D && __chunk_1.require$$17(AllSymbols, key) && !(__chunk_1.require$$17(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true; + return D; +}; +var $getOwnPropertyNames = function getOwnPropertyNames(it) { + var names = gOPN$1(__chunk_1.toIObject(it)); + var result = []; + var i = 0; + var key; + while (names.length > i) { + if (!__chunk_1.require$$17(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key); + } return result; +}; +var $getOwnPropertySymbols = function getOwnPropertySymbols(it) { + var IS_OP = it === ObjectProto; + var names = gOPN$1(IS_OP ? OPSymbols : __chunk_1.toIObject(it)); + var result = []; + var i = 0; + var key; + while (names.length > i) { + if (__chunk_1.require$$17(AllSymbols, key = names[i++]) && (IS_OP ? __chunk_1.require$$17(ObjectProto, key) : true)) result.push(AllSymbols[key]); + } return result; +}; + +// 19.4.1.1 Symbol([description]) +if (!USE_NATIVE) { + $Symbol = function Symbol() { + if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!'); + var tag = __chunk_1.uid(arguments.length > 0 ? arguments[0] : undefined); + var $set = function (value) { + if (this === ObjectProto) $set.call(OPSymbols, value); + if (__chunk_1.require$$17(this, HIDDEN) && __chunk_1.require$$17(this[HIDDEN], tag)) this[HIDDEN][tag] = false; + setSymbolDesc(this, tag, __chunk_1.require$$9(1, value)); + }; + if (__chunk_1.DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set }); + return wrap(tag); + }; + __chunk_1.redefine($Symbol[PROTOTYPE], 'toString', function toString() { + return this._k; + }); + + __chunk_1.require$$1$2.f = $getOwnPropertyDescriptor; + __chunk_1.require$$1$1.f = $defineProperty; + __chunk_1.require$$0$2.f = _objectGopnExt.f = $getOwnPropertyNames; + __chunk_1.require$$0$1.f = $propertyIsEnumerable; + __chunk_1.gOPS.f = $getOwnPropertySymbols; + + if (__chunk_1.DESCRIPTORS && !__chunk_1.LIBRARY) { + __chunk_1.redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); + } + + _wksExt.f = function (name) { + return wrap(__chunk_1.require$$0(name)); + }; +} + +__chunk_1.$export(__chunk_1.$export.G + __chunk_1.$export.W + __chunk_1.$export.F * !USE_NATIVE, { Symbol: $Symbol }); + +for (var es6Symbols = ( + // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 + 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' +).split(','), j = 0; es6Symbols.length > j;)__chunk_1.require$$0(es6Symbols[j++]); + +for (var wellKnownSymbols = __chunk_1.getKeys(__chunk_1.require$$0.store), k = 0; wellKnownSymbols.length > k;) _wksDefine(wellKnownSymbols[k++]); + +__chunk_1.$export(__chunk_1.$export.S + __chunk_1.$export.F * !USE_NATIVE, 'Symbol', { + // 19.4.2.1 Symbol.for(key) + 'for': function (key) { + return __chunk_1.require$$17(SymbolRegistry, key += '') + ? SymbolRegistry[key] + : SymbolRegistry[key] = $Symbol(key); + }, + // 19.4.2.5 Symbol.keyFor(sym) + keyFor: function keyFor(sym) { + if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!'); + for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key; + }, + useSetter: function () { setter = true; }, + useSimple: function () { setter = false; } +}); + +__chunk_1.$export(__chunk_1.$export.S + __chunk_1.$export.F * !USE_NATIVE, 'Object', { + // 19.1.2.2 Object.create(O [, Properties]) + create: $create, + // 19.1.2.4 Object.defineProperty(O, P, Attributes) + defineProperty: $defineProperty, + // 19.1.2.3 Object.defineProperties(O, Properties) + defineProperties: $defineProperties, + // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) + getOwnPropertyDescriptor: $getOwnPropertyDescriptor, + // 19.1.2.7 Object.getOwnPropertyNames(O) + getOwnPropertyNames: $getOwnPropertyNames, + // 19.1.2.8 Object.getOwnPropertySymbols(O) + getOwnPropertySymbols: $getOwnPropertySymbols +}); + +// 24.3.2 JSON.stringify(value [, replacer [, space]]) +$JSON && __chunk_1.$export(__chunk_1.$export.S + __chunk_1.$export.F * (!USE_NATIVE || __chunk_1.fails(function () { + var S = $Symbol(); + // MS Edge converts symbol values to JSON as {} + // WebKit converts symbol values to JSON as null + // V8 throws on boxed symbols + return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}'; +})), 'JSON', { + stringify: function stringify(it) { + var args = [it]; + var i = 1; + var replacer, $replacer; + while (arguments.length > i) args.push(arguments[i++]); + $replacer = replacer = args[1]; + if (!__chunk_1.isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined + if (!__chunk_1.isArray(replacer)) replacer = function (key, value) { + if (typeof $replacer == 'function') value = $replacer.call(this, key, value); + if (!isSymbol(value)) return value; + }; + args[1] = replacer; + return _stringify.apply($JSON, args); + } +}); + +// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) +$Symbol[PROTOTYPE][TO_PRIMITIVE] || __chunk_1.hide($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); +// 19.4.3.5 Symbol.prototype[@@toStringTag] +__chunk_1.setToStringTag($Symbol, 'Symbol'); +// 20.2.1.9 Math[@@toStringTag] +__chunk_1.setToStringTag(Math, 'Math', true); +// 24.3.3 JSON[@@toStringTag] +__chunk_1.setToStringTag(__chunk_1.global.JSON, 'JSON', true); + // WebGL context wrapper var Context; var Context$1 = Context = {}; @@ -24757,10 +25315,10 @@ function write (buffer, value, offset, isLE, mLen, nBytes) { buffer[offset + i - d] |= s * 128; } -var toString = {}.toString; +var toString$1 = {}.toString; var isArray = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; + return toString$1.call(arr) == '[object Array]'; }; var INSPECT_MAX_BYTES = 50; @@ -30197,14 +30755,14 @@ var _toPrimitive = function(it, S){ throw TypeError("Can't convert object to primitive value"); }; -var dP = Object.defineProperty; +var dP$1 = Object.defineProperty; -var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes){ +var f$2 = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes){ _anObject(O); P = _toPrimitive(P, true); _anObject(Attributes); if(_ie8DomDefine)try { - return dP(O, P, Attributes); + return dP$1(O, P, Attributes); } catch(e){ /* empty */ } if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); if('value' in Attributes)O[P] = Attributes.value; @@ -30212,7 +30770,7 @@ var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Att }; var _objectDp = { - f: f + f: f$2 }; var _propertyDesc = function(bitmap, value){ @@ -30231,7 +30789,7 @@ var _hide = _descriptors ? function(object, key, value){ return object; }; -var PROTOTYPE = 'prototype'; +var PROTOTYPE$1 = 'prototype'; var $export = function(type, name, source){ var IS_FORCED = type & $export.F @@ -30241,8 +30799,8 @@ var $export = function(type, name, source){ , IS_BIND = type & $export.B , IS_WRAP = type & $export.W , exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {}) - , expProto = exports[PROTOTYPE] - , target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] : (_global[name] || {})[PROTOTYPE] + , expProto = exports[PROTOTYPE$1] + , target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] : (_global[name] || {})[PROTOTYPE$1] , key, own, out; if(IS_GLOBAL)source = name; for(key in source){ @@ -30266,7 +30824,7 @@ var $export = function(type, name, source){ } return new C(a, b, c); } return C.apply(this, arguments); }; - F[PROTOTYPE] = C[PROTOTYPE]; + F[PROTOTYPE$1] = C[PROTOTYPE$1]; return F; // make static versions for prototype methods })(out) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; @@ -30308,10 +30866,10 @@ var _invoke = function(fn, args, that){ var _html = _global.document && document.documentElement; -var toString$1 = {}.toString; +var toString$2 = {}.toString; var _cof = function(it){ - return toString$1.call(it).slice(8, -1); + return toString$2.call(it).slice(8, -1); }; var process$1 = _global.process @@ -36073,7 +36631,7 @@ function ZStream() { var zstream = ZStream; -var toString$2 = Object.prototype.toString; +var toString$3 = Object.prototype.toString; /* Public constants ==========================================================*/ /* ===========================================================================*/ @@ -36237,7 +36795,7 @@ function Deflate(options) { if (typeof opt.dictionary === 'string') { // If we need to compress text, change encoding to utf8. dict = strings.string2buf(opt.dictionary); - } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') { + } else if (toString$3.call(opt.dictionary) === '[object ArrayBuffer]') { dict = new Uint8Array(opt.dictionary); } else { dict = opt.dictionary; @@ -36295,7 +36853,7 @@ Deflate.prototype.push = function (data, mode) { if (typeof data === 'string') { // If we need to compress text, change encoding to utf8. strm.input = strings.string2buf(data); - } else if (toString$2.call(data) === '[object ArrayBuffer]') { + } else if (toString$3.call(data) === '[object ArrayBuffer]') { strm.input = new Uint8Array(data); } else { strm.input = data; @@ -38847,7 +39405,7 @@ function GZheader() { var gzheader = GZheader; -var toString$3 = Object.prototype.toString; +var toString$4 = Object.prototype.toString; /** * class Inflate @@ -39031,7 +39589,7 @@ Inflate.prototype.push = function (data, mode) { if (typeof data === 'string') { // Only binary strings can be decompressed on practice strm.input = strings.binstring2buf(data); - } else if (toString$3.call(data) === '[object ArrayBuffer]') { + } else if (toString$4.call(data) === '[object ArrayBuffer]') { strm.input = new Uint8Array(data); } else { strm.input = data; @@ -39053,7 +39611,7 @@ Inflate.prototype.push = function (data, mode) { // Convert data if needed if (typeof dictionary === 'string') { dict = strings.string2buf(dictionary); - } else if (toString$3.call(dictionary) === '[object ArrayBuffer]') { + } else if (toString$4.call(dictionary) === '[object ArrayBuffer]') { dict = new Uint8Array(dictionary); } else { dict = dictionary; @@ -45033,6 +45591,7 @@ function () { this.max_proxy_descendant_depth = 6; // # of levels to search up/down for proxy tiles this.max_proxy_ancestor_depth = 7; + this.children_cache = {}; // cache for children of coordinates } var _proto = TilePyramid.prototype; @@ -45094,7 +45653,6 @@ function () { var level = 0; while (level < this.max_proxy_ancestor_depth) { - var last_z = tile.coords.z; tile = __chunk_1.TileID.parent(tile); if (!tile) { @@ -45105,9 +45663,7 @@ function () { return this.tiles[tile.key].tile; } - if (tile.coords.z !== last_z) { - level++; - } + level++; } } // Find the descendant tiles for a given tile and style zoom level ; @@ -45122,7 +45678,7 @@ function () { var descendants = []; if (level < this.max_proxy_descendant_depth) { - var tiles = __chunk_1.TileID.children(tile); + var tiles = __chunk_1.TileID.children(tile, this.children_cache); if (!tiles) { return; @@ -45134,7 +45690,7 @@ function () { descendants.push(_this.tiles[t.key].tile); } else if (_this.tiles[t.key].descendants > 0) { // didn't find any children, try next level - descendants.push.apply(descendants, _this.getDescendants(t, level + (t.coords.z !== tile.coords.z))); + descendants.push.apply(descendants, _this.getDescendants(t, level + 1)); } } }); @@ -45179,66 +45735,72 @@ function mainThreadLabelCollisionPass(tiles, view_zoom, hide_breach) { meshes.forEach(function (mesh) { if (mesh.labels) { for (var label_id in mesh.labels) { - if (!labels[label_id]) { - var params = mesh.labels[label_id].container.label; - var linked = mesh.labels[label_id].container.linked; - var ranges = mesh.labels[label_id].ranges; - var debug = Object.assign({}, mesh.labels[label_id].debug, { - tile: tile, - params: params, - label_id: label_id - }); - var label = labels[label_id] = {}; - label.discard = discard.bind(label); - label.build_id = tile.build_id; // original order in which tiles were built - - Object.assign(label, params); - label.layout = Object.assign({}, params.layout); // TODO: ideally remove need to copy props here - - label.layout.repeat_scale = 0.75; // looser second pass on repeat groups, to weed out repeats near tile edges - - label.layout.repeat_distance = label.layout.repeat_distance || 0; - label.layout.repeat_distance /= size_scale; // TODO: where should this be scaled? - - label.position = [// don't overwrite referenced values - label.position[0] / units_per_meter + tile.min.x, label.position[1] / units_per_meter + tile.min.y]; - label.unit_scale = meters_per_pixel; // if (params.obb) { - - if (label.type === 'point') { - // TODO: move to integer constants to avoid excess string copies - __chunk_1.LabelPoint.prototype.updateBBoxes.call(label); - } else if (label.type === 'straight') { - __chunk_1.LabelLineStraight.prototype.updateBBoxes.call(label, label.position, label.size, label.angle, label.angle, label.offset); - } else if (params.obbs) { - // NB: this is a very rough approximation of curved label collision at intermediate zooms, - // becuase the position/scale of each collision box isn't correctly updated; however, - // it's good enough to provide some additional label coverage, with less overhead - var obbs = params.obbs.map(function (o) { - var x = o.x, - y = o.y, - a = o.a, - w = o.w, - h = o.h; - x = x / units_per_meter + tile.min.x; - y = y / units_per_meter + tile.min.y; - w /= size_scale; - h /= size_scale; - return new __chunk_1.OBB(x, y, a, w, h); - }); - label.obbs = obbs; - label.aabbs = obbs.map(function (o) { - return o.getExtent(); - }); - } + // For proxy tiles, only allow visible labels to be *hidden* by further collisions, + // don't allow new ones to appear. Promotes label stability and prevents thrash + // from different labels (often not thematically relevant given the different zoom level of + // the proxy tile content, e.g. random POIs popping in/out when zooming out to city-wide view). + if (tile.isProxy() && !prev_visible[label_id]) { + continue; + } - containers[label_id] = { - label: label, - linked: linked, - ranges: ranges, - mesh: mesh, - debug: debug - }; + var params = mesh.labels[label_id].container.label; + var linked = mesh.labels[label_id].container.linked; + var ranges = mesh.labels[label_id].ranges; + var debug = Object.assign({}, mesh.labels[label_id].debug, { + tile: tile, + params: params, + label_id: label_id + }); + var label = labels[label_id] = {}; + label.discard = discard.bind(label); + label.build_id = tile.build_id; // original order in which tiles were built + + Object.assign(label, params); + label.layout = Object.assign({}, params.layout); // TODO: ideally remove need to copy props here + + label.layout.repeat_scale = 0.75; // looser second pass on repeat groups, to weed out repeats near tile edges + + label.layout.repeat_distance = label.layout.repeat_distance || 0; + label.layout.repeat_distance /= size_scale; // TODO: where should this be scaled? + + label.position = [// don't overwrite referenced values + label.position[0] / units_per_meter + tile.min.x, label.position[1] / units_per_meter + tile.min.y]; + label.unit_scale = meters_per_pixel; + + if (label.type === 'point') { + // TODO: move to integer constants to avoid excess string copies + __chunk_1.LabelPoint.prototype.updateBBoxes.call(label); + } else if (label.type === 'straight') { + __chunk_1.LabelLineStraight.prototype.updateBBoxes.call(label, label.position, label.size, label.angle, label.angle, label.offset); + } else if (params.obbs) { + // NB: this is a very rough approximation of curved label collision at intermediate zooms, + // becuase the position/scale of each collision box isn't correctly updated; however, + // it's good enough to provide some additional label coverage, with less overhead + var obbs = params.obbs.map(function (o) { + var x = o.x, + y = o.y, + a = o.a, + w = o.w, + h = o.h; + x = x / units_per_meter + tile.min.x; + y = y / units_per_meter + tile.min.y; + w /= size_scale; + h /= size_scale; + return new __chunk_1.OBB(x, y, a, w, h); + }); + label.obbs = obbs; + label.aabbs = obbs.map(function (o) { + return o.getExtent(); + }); } + + containers[label_id] = { + label: label, + linked: linked, + ranges: ranges, + mesh: mesh, + debug: debug + }; } } }); @@ -45359,17 +45921,14 @@ var TileManager = /*#__PURE__*/ function () { function TileManager(_ref) { - var scene = _ref.scene, - view = _ref.view; + var scene = _ref.scene; this.scene = scene; - this.view = view; this.tiles = {}; this.pyramid = new TilePyramid(); this.visible_coords = {}; this.queued_coords = []; this.building_tiles = null; this.renderable_tiles = []; - this.active_styles = []; this.collision = { tile_keys: null, mesh_set: null, @@ -45393,7 +45952,6 @@ function () { this.visible_coords = {}; this.queued_coords = []; this.scene = null; - this.view = null; __chunk_1.WorkerBroker.removeTarget(this.main_thread_target); }; @@ -45478,7 +46036,8 @@ function () { this.updateProxyTiles(); this.view.pruneTilesForView(); this.updateRenderableTiles(); - this.updateActiveStyles(); + this.style_manager.updateActiveStyles(this.renderable_tiles); + this.style_manager.updateActiveBlendOrders(this.renderable_tiles); return this.updateLabels(); }; @@ -45539,9 +46098,7 @@ function () { return _this2.scene.immediateRedraw(); }); }); - }, - user_moving_view: false // don't run task when user is moving view - + } }; __chunk_1.Task.add(this.collision.task); } // else { @@ -45634,25 +46191,6 @@ function () { return this.renderable_tiles; }; - _proto.getActiveStyles = function getActiveStyles() { - return this.active_styles; - }; - - _proto.updateActiveStyles = function updateActiveStyles() { - var tiles = this.renderable_tiles; - var active = {}; - - for (var t = 0; t < tiles.length; t++) { - var tile = tiles[t]; - Object.keys(tile.meshes).forEach(function (s) { - return active[s] = true; - }); - } - - this.active_styles = Object.keys(active); - return this.active_styles; - }; - _proto.isLoadingVisibleTiles = function isLoadingVisibleTiles() { var _this4 = this; @@ -45845,6 +46383,18 @@ function () { return this.getDebugSum(prop, filter) / Object.keys(this.tiles).length; }; + __chunk_1._createClass(TileManager, [{ + key: "view", + get: function get() { + return this.scene.view; + } + }, { + key: "style_manager", + get: function get() { + return this.scene.style_manager; + } + }]); + return TileManager; }(); // Round a number to given number of decimal divisions @@ -45958,7 +46508,7 @@ var RenderStateManager = function RenderStateManager(gl) { }); }; -__chunk_1.require$$0('Uint8', 1, function (init) { +__chunk_1.require$$0$5('Uint8', 1, function (init) { return function Uint8ClampedArray(data, byteOffset, length) { return init(this, data, byteOffset, length); }; @@ -46326,8 +46876,7 @@ function () { this.sources = {}; this.view = new __chunk_1.View(this, options); this.tile_manager = new TileManager({ - scene: this, - view: this.view + scene: this }); this.num_workers = options.numWorkers || 2; @@ -46875,99 +47424,204 @@ function () { // optionally force alpha off (e.g. for selection pass) allow_blend = allow_blend == null ? true : allow_blend; - this.clearFrame(); // Sort styles by blend order + this.clearFrame(); + var count = 0; // how many primitives were rendered - var styles = this.tile_manager.getActiveStyles().map(function (s) { - return _this6.styles[s]; - }).filter(function (s) { - return s; - }). // guard against missing styles, such as while loading a new scene - sort(__chunk_1.Style.blendOrderSort); // Render styles + var last_blend; // blend mode active in last render pass + // Get sorted list of current blend orders, with accompanying list of styles to render for each - var count = 0; // how many primitives were rendered + var blend_orders = this.style_manager.getActiveBlendOrders(); - var last_blend; + for (var _iterator = blend_orders, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref3; - for (var s = 0; s < styles.length; s++) { - var style = styles[s]; // Only update render state when blend mode changes + if (_isArray) { + if (_i >= _iterator.length) break; + _ref3 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref3 = _i.value; + } - if (style.blend !== last_blend) { - var state = Object.assign({}, __chunk_1.Style.render_states[style.blend], // render state for blend mode - { - blend: allow_blend && style.blend // enable/disable blending (e.g. no blend for selection) + var _ref4 = _ref3, + blend_order = _ref4.blend_order, + styles = _ref4.styles; - }); - this.setRenderState(state); - } // Depth pre-pass for translucency + var _loop2 = function _loop2(s) { + var style = _this6.styles[styles[s]]; + if (style == null) { + return "continue"; + } // Only update render state when blend mode changes - var translucent = style.blend === 'translucent' && program_key === 'program'; // skip for selection buffer render pass - if (translucent) { - this.gl.colorMask(false, false, false, false); - this.renderStyle(style.name, program_key); - this.gl.colorMask(true, true, true, true); - this.gl.depthFunc(this.gl.EQUAL); // stencil buffer prevents compounding alpha from overlapping polys + if (style.blend !== last_blend) { + var state = Object.assign({}, __chunk_1.Style.render_states[style.blend], // render state for blend mode + { + blend: allow_blend && style.blend // enable/disable blending (e.g. no blend for selection) - this.gl.enable(this.gl.STENCIL_TEST); - this.gl.clear(this.gl.STENCIL_BUFFER_BIT); - this.gl.stencilFunc(this.gl.EQUAL, this.gl.ZERO, 0xFF); - this.gl.stencilOp(this.gl.KEEP, this.gl.KEEP, this.gl.INCR); - } // Main render pass + }); + _this6.setRenderState(state); + } - count += this.renderStyle(style.name, program_key); + var blend = allow_blend && style.blend; - if (translucent) { - // disable translucency-specific settings - this.gl.disable(this.gl.STENCIL_TEST); - this.gl.depthFunc(this.gl.LESS); - } + if (blend === 'translucent') { + // Depth pre-pass for translucency + _this6.gl.colorMask(false, false, false, false); + + _this6.renderStyle(style.name, program_key, blend_order); + + _this6.gl.colorMask(true, true, true, true); + + _this6.gl.depthFunc(_this6.gl.EQUAL); // Stencil buffer mask prevents overlap/flicker from compounding alpha of overlapping polys + + + _this6.gl.enable(_this6.gl.STENCIL_TEST); + + _this6.gl.clearStencil(0); + + _this6.gl.clear(_this6.gl.STENCIL_BUFFER_BIT); + + _this6.gl.stencilFunc(_this6.gl.EQUAL, _this6.gl.ZERO, 0xFF); + + _this6.gl.stencilOp(_this6.gl.KEEP, _this6.gl.KEEP, _this6.gl.INCR); // Main render pass + + + count += _this6.renderStyle(style.name, program_key, blend_order); // Disable translucency-specific settings - last_blend = style.blend; + _this6.gl.disable(_this6.gl.STENCIL_TEST); + + _this6.gl.depthFunc(_this6.gl.LESS); + } else if (blend !== 'opaque' && style.stencil_proxy_tiles === true) { + // Mask proxy tiles to with stencil buffer to avoid overlap/flicker from compounding alpha + // Find unique levels of proxy tiles to render for this style + var proxy_levels = _this6.tile_manager.getRenderableTiles().filter(function (t) { + return t.meshes[style.name]; + }) // must have meshes for this style + .map(function (t) { + return t.proxy_level; + }) // get the proxy depth + .reduce(function (levels, level) { + // count unique proxy depths + levels.indexOf(level) > -1 || levels.push(level); + return levels; + }, []).sort(); // sort by lower depth first + + + if (proxy_levels.length > 1) { + // When there are multiple "levels" of tiles to render (e.g. non-proxy and one or more proxy + // tile levels, or multiple proxy tile levels but no non-proxy tiles, etc.): + // Render each proxy tile level to stencil buffer, masking each level such that it will not + // render over any pixel rendered by a previous proxy tile level. + _this6.gl.enable(_this6.gl.STENCIL_TEST); + + _this6.gl.clearStencil(0); + + _this6.gl.clear(_this6.gl.STENCIL_BUFFER_BIT); + + _this6.gl.stencilOp(_this6.gl.KEEP, _this6.gl.KEEP, _this6.gl.REPLACE); + + for (var i = 0; i < proxy_levels.length; i++) { + // stencil test passes either for zero (not-yet-rendered), + // or for other pixels at this proxy level (but not previous proxy levels) + _this6.gl.stencilFunc(_this6.gl.GEQUAL, proxy_levels.length - i, 0xFF); + + count += _this6.renderStyle(style.name, program_key, blend_order, proxy_levels[i]); + } + + _this6.gl.disable(_this6.gl.STENCIL_TEST); + } else { + // No special render handling needed when there are no proxy tiles, + // or if there is ONLY a single proxy tile level (e.g. with no non-proxy tiles) + count += _this6.renderStyle(style.name, program_key, blend_order); + } + } else { + // Regular render pass (no special blend handling, or selection buffer pass) + count += _this6.renderStyle(style.name, program_key, blend_order); + } + + last_blend = style.blend; + }; + + // Render each style + for (var s = 0; s < styles.length; s++) { + var _ret = _loop2(s); + + if (_ret === "continue") continue; + } } return count; }; - _proto.renderStyle = function renderStyle(style_name, program_key) { + _proto.renderStyle = function renderStyle(style_name, program_key, blend_order, proxy_level) { var _this7 = this; + if (proxy_level === void 0) { + proxy_level = null; + } + var style = this.styles[style_name]; - var first_for_style = true; + var first_for_style = true; // TODO: allow this state to be passed in (for multilpe blend orders, stencil tests, etc) + var render_count = 0; var program; // Render tile GL geometries - var renderable_tiles = this.tile_manager.getRenderableTiles(); // Mesh variants must be rendered in requested order across tiles, to prevent labels that cross + var renderable_tiles = this.tile_manager.getRenderableTiles(); // For each tile, only include meshes for the blend order currently being rendered + // Builds an array tiles and their associated meshes, each as a [tile, meshes] 2-element array + + var tile_meshes = renderable_tiles.filter(function (t) { + return typeof proxy_level !== 'number' || t.proxy_level === proxy_level; + }) // optional filter by proxy level + .map(function (t) { + if (t.meshes[style_name]) { + return [t, t.meshes[style_name].filter(function (m) { + return m.variant.blend_order === blend_order; + })]; + } + }).filter(function (x) { + return x; + }); // skip tiles with no meshes for this blend order + // Mesh variants must be rendered in requested order across tiles, to prevent labels that cross // tile boundaries from rendering over adjacent tile features meant to be underneath - var max_mesh_variant_order = Math.max.apply(Math, renderable_tiles.map(function (t) { - return t.meshes[style_name] ? Math.max.apply(Math, t.meshes[style_name].map(function (m) { - return m.variant.order; - })) : -1; + var max_mesh_order = Math.max.apply(Math, tile_meshes.map(function (_ref5) { + var meshes = _ref5[1]; + return Math.max.apply(Math, meshes.map(function (m) { + return m.variant.mesh_order; + })); })); // One pass per mesh variant order (loop goes to max value +1 because 0 is a valid order value) - var _loop2 = function _loop2(mo) { - var _loop3 = function _loop3(t) { - var tile = renderable_tiles[t]; - var first_for_tile = true; - - if (tile.meshes[style_name] == null) { - return "continue"; - } // Skip proxy tiles if new tiles have finished loading this style + var _loop3 = function _loop3(mo) { + var _loop5 = function _loop5() { + if (_isArray2) { + if (_i2 >= _iterator2.length) return "break"; + _ref6 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) return "break"; + _ref6 = _i2.value; + } + var _ref7 = _ref6, + tile = _ref7[0], + meshes = _ref7[1]; + var first_for_tile = true; // Skip proxy tiles if new tiles have finished loading this style if (!tile.shouldProxyForStyle(style_name)) { // log('trace', `Scene.renderStyle(): Skip proxy tile for style '${style_name}' `, tile, tile.proxy_for); return "continue"; - } // Get meshes for current variant order, current style, and current tile + } // Filter meshes further by current variant order - var meshes = tile.meshes[style_name].filter(function (m) { - return m.variant.order === mo; - }); // find meshes by variant order + var order_meshes = meshes.filter(function (m) { + return m.variant.mesh_order === mo; + }); - if (meshes.length === 0) { + if (order_meshes.length === 0) { return "continue"; } // Style-specific state // Only setup style if rendering for first time this frame @@ -46989,7 +47643,7 @@ function () { } // Render each mesh (for current variant order) - meshes.forEach(function (mesh) { + order_meshes.forEach(function (mesh) { // Tile-specific state if (first_for_tile === true) { first_for_tile = false; @@ -47006,23 +47660,29 @@ function () { }); }; - for (var t = 0; t < renderable_tiles.length; t++) { - var _ret2 = _loop3(t); + // Loop over tiles, with meshes pre-filtered by current blend order + _loop4: for (var _iterator2 = tile_meshes, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref6; + + var _ret3 = _loop5(); + + switch (_ret3) { + case "break": + break _loop4; - switch (_ret2) { case "continue": continue; default: - if (typeof _ret2 === "object") return _ret2.v; + if (typeof _ret3 === "object") return _ret3.v; } } }; - for (var mo = 0; mo < max_mesh_variant_order + 1; mo++) { - var _ret = _loop2(mo); + for (var mo = 0; mo < max_mesh_order + 1; mo++) { + var _ret2 = _loop3(mo); - if (typeof _ret === "object") return _ret.v; + if (typeof _ret2 === "object") return _ret2.v; } return render_count; @@ -47072,11 +47732,11 @@ function () { }; _proto.setRenderState = function setRenderState(_temp2) { - var _ref3 = _temp2 === void 0 ? {} : _temp2, - depth_test = _ref3.depth_test, - depth_write = _ref3.depth_write, - cull_face = _ref3.cull_face, - blend = _ref3.blend; + var _ref8 = _temp2 === void 0 ? {} : _temp2, + depth_test = _ref8.depth_test, + depth_write = _ref8.depth_write, + cull_face = _ref8.cull_face, + blend = _ref8.blend; if (!this.initialized) { return; @@ -47147,8 +47807,8 @@ function () { ; _proto.getFeatureAt = function getFeatureAt(pixel, _temp3) { - var _ref4 = _temp3 === void 0 ? {} : _temp3, - radius = _ref4.radius; + var _ref9 = _temp3 === void 0 ? {} : _temp3, + radius = _ref9.radius; if (!this.initialized) { __chunk_1.log('debug', 'Scene.getFeatureAt() called before scene was initialized'); @@ -47196,9 +47856,9 @@ function () { _proto.queryFeatures = function queryFeatures(_temp4) { return new Promise(function ($return, $error) { - var _ref5, filter, _ref5$unique, unique, _ref5$group_by, group_by, _ref5$visible, visible, _ref5$geometry, geometry, uniqueify, group, tile_keys, results, features, keys, groups; + var _ref10, filter, _ref10$unique, unique, _ref10$group_by, group_by, _ref10$visible, visible, _ref10$geometry, geometry, uniqueify, group, tile_keys, results, features, keys, groups; - _ref5 = _temp4 === void 0 ? {} : _temp4, filter = _ref5.filter, _ref5$unique = _ref5.unique, unique = _ref5$unique === void 0 ? true : _ref5$unique, _ref5$group_by = _ref5.group_by, group_by = _ref5$group_by === void 0 ? null : _ref5$group_by, _ref5$visible = _ref5.visible, visible = _ref5$visible === void 0 ? null : _ref5$visible, _ref5$geometry = _ref5.geometry, geometry = _ref5$geometry === void 0 ? false : _ref5$geometry; + _ref10 = _temp4 === void 0 ? {} : _temp4, filter = _ref10.filter, _ref10$unique = _ref10.unique, unique = _ref10$unique === void 0 ? true : _ref10$unique, _ref10$group_by = _ref10.group_by, group_by = _ref10$group_by === void 0 ? null : _ref10$group_by, _ref10$visible = _ref10.visible, visible = _ref10$visible === void 0 ? null : _ref10$visible, _ref10$geometry = _ref10.geometry, geometry = _ref10$geometry === void 0 ? false : _ref10$geometry; if (!this.initialized) { return $return([]); @@ -47282,18 +47942,18 @@ function () { _proto.rebuild = function rebuild(_temp5) { var _this8 = this; - var _ref6 = _temp5 === void 0 ? {} : _temp5, - _ref6$initial = _ref6.initial, - initial = _ref6$initial === void 0 ? false : _ref6$initial, - _ref6$new_generation = _ref6.new_generation, - new_generation = _ref6$new_generation === void 0 ? true : _ref6$new_generation, - _ref6$sources = _ref6.sources, - sources = _ref6$sources === void 0 ? null : _ref6$sources, - serialize_funcs = _ref6.serialize_funcs, - _ref6$profile = _ref6.profile, - profile = _ref6$profile === void 0 ? false : _ref6$profile, - _ref6$fade_in = _ref6.fade_in, - fade_in = _ref6$fade_in === void 0 ? false : _ref6$fade_in; + var _ref11 = _temp5 === void 0 ? {} : _temp5, + _ref11$initial = _ref11.initial, + initial = _ref11$initial === void 0 ? false : _ref11$initial, + _ref11$new_generation = _ref11.new_generation, + new_generation = _ref11$new_generation === void 0 ? true : _ref11$new_generation, + _ref11$sources = _ref11.sources, + sources = _ref11$sources === void 0 ? null : _ref11$sources, + serialize_funcs = _ref11.serialize_funcs, + _ref11$profile = _ref11.profile, + profile = _ref11$profile === void 0 ? false : _ref11$profile, + _ref11$fade_in = _ref11.fade_in, + fade_in = _ref11$fade_in === void 0 ? false : _ref11$fade_in; return new Promise(function (resolve, reject) { // Skip rebuild if already in progress @@ -47417,9 +48077,9 @@ function () { config_source = null; } - var _ref7 = _temp6 === void 0 ? {} : _temp6, - base_path = _ref7.base_path, - file_type = _ref7.file_type; + var _ref12 = _temp6 === void 0 ? {} : _temp6, + base_path = _ref12.base_path, + file_type = _ref12.file_type; this.config_source = config_source || this.config_source; @@ -47435,9 +48095,9 @@ function () { return SceneLoader$1.loadScene(this.config_source, { path: this.base_path, type: file_type - }).then(function (_ref8) { - var config = _ref8.config, - bundle = _ref8.bundle; + }).then(function (_ref13) { + var config = _ref13.config, + bundle = _ref13.bundle; _this9.config = config; _this9.config_bundle = bundle; return _this9.config; @@ -47693,16 +48353,16 @@ function () { _proto.updateConfig = function updateConfig(_temp7) { var _this14 = this; - var _ref9 = _temp7 === void 0 ? {} : _temp7, - _ref9$loading = _ref9.loading, - loading = _ref9$loading === void 0 ? false : _ref9$loading, - _ref9$rebuild = _ref9.rebuild, - rebuild = _ref9$rebuild === void 0 ? true : _ref9$rebuild, - serialize_funcs = _ref9.serialize_funcs, - _ref9$normalize = _ref9.normalize, - normalize = _ref9$normalize === void 0 ? true : _ref9$normalize, - _ref9$fade_in = _ref9.fade_in, - fade_in = _ref9$fade_in === void 0 ? false : _ref9$fade_in; + var _ref14 = _temp7 === void 0 ? {} : _temp7, + _ref14$loading = _ref14.loading, + loading = _ref14$loading === void 0 ? false : _ref14$loading, + _ref14$rebuild = _ref14.rebuild, + rebuild = _ref14$rebuild === void 0 ? true : _ref14$rebuild, + serialize_funcs = _ref14.serialize_funcs, + _ref14$normalize = _ref14.normalize, + normalize = _ref14$normalize === void 0 ? true : _ref14$normalize, + _ref14$fade_in = _ref14.fade_in, + fade_in = _ref14$fade_in === void 0 ? false : _ref14$fade_in; this.generation = ++Scene.generation; this.updating++; @@ -47755,9 +48415,9 @@ function () { ; _proto.syncConfigToWorker = function syncConfigToWorker(_temp8) { - var _ref10 = _temp8 === void 0 ? {} : _temp8, - _ref10$serialize_func = _ref10.serialize_funcs, - serialize_funcs = _ref10$serialize_func === void 0 ? true : _ref10$serialize_func; + var _ref15 = _temp8 === void 0 ? {} : _temp8, + _ref15$serialize_func = _ref15.serialize_funcs, + serialize_funcs = _ref15$serialize_func === void 0 ? true : _ref15$serialize_func; // Tell workers we're about to rebuild (so they can update styles, etc.) var config_serialized = serialize_funcs ? __chunk_1.Utils.serializeWithFunctions(this.config) : JSON.stringify(this.config); @@ -47876,9 +48536,9 @@ function () { ; _proto.screenshot = function screenshot(_temp9) { - var _ref11 = _temp9 === void 0 ? {} : _temp9, - _ref11$background = _ref11.background, - background = _ref11$background === void 0 ? 'white' : _ref11$background; + var _ref16 = _temp9 === void 0 ? {} : _temp9, + _ref16$background = _ref16.background, + background = _ref16$background === void 0 ? 'white' : _ref16$background; this.requestRedraw(); return this.media_capture.screenshot({ @@ -47917,7 +48577,7 @@ function () { var _this18 = this; // Disable animation is scene flag requests it, otherwise enable animation if any animated styles are in view - return this.config.scene.animated === false ? false : this.tile_manager.getActiveStyles().some(function (s) { + return this.config.scene.animated === false ? false : this.style_manager.getActiveStyles().some(function (s) { return _this18.styles[s].animated; }); } @@ -48559,6 +49219,7 @@ var debug$1 = { Task: __chunk_1.Task, StyleManager: __chunk_1.StyleManager, StyleParser: __chunk_1.StyleParser, + TileID: __chunk_1.TileID, Collision: __chunk_1.Collision, FeatureSelection: __chunk_1.FeatureSelection, TextCanvas: __chunk_1.TextCanvas, @@ -48580,7 +49241,7 @@ return index; // Script modules can't expose exports try { Tangram.debug.ESM = false; // mark build as ES module - Tangram.debug.SHA = '2601a1fb6864e05bb4f865aebd6904ff195fd3e0'; + Tangram.debug.SHA = 'f4235dbb2a13111efbbb66b24ab2f8258922885c'; if (false === true && typeof window === 'object') { window.Tangram = Tangram; } diff --git a/dist/tangram.debug.js.map b/dist/tangram.debug.js.map index 4dca35932..a9386be8a 100644 --- a/dist/tangram.debug.js.map +++ b/dist/tangram.debug.js.map @@ -1 +1 @@ -{"version":3,"file":"tangram.debug.js","sources":["../node_modules/core-js/modules/_core.js","../node_modules/core-js/modules/_global.js","../node_modules/core-js/modules/_library.js","../node_modules/core-js/modules/_shared.js","../node_modules/core-js/modules/_uid.js","../node_modules/core-js/modules/_wks.js","../node_modules/core-js/modules/_is-object.js","../node_modules/core-js/modules/_an-object.js","../node_modules/core-js/modules/_fails.js","../node_modules/core-js/modules/_descriptors.js","../node_modules/core-js/modules/_dom-create.js","../node_modules/core-js/modules/_ie8-dom-define.js","../node_modules/core-js/modules/_to-primitive.js","../node_modules/core-js/modules/_object-dp.js","../node_modules/core-js/modules/_property-desc.js","../node_modules/core-js/modules/_hide.js","../node_modules/core-js/modules/_add-to-unscopables.js","../node_modules/core-js/modules/_iter-step.js","../node_modules/core-js/modules/_iterators.js","../node_modules/core-js/modules/_cof.js","../node_modules/core-js/modules/_iobject.js","../node_modules/core-js/modules/_defined.js","../node_modules/core-js/modules/_to-iobject.js","../node_modules/core-js/modules/_has.js","../node_modules/core-js/modules/_redefine.js","../node_modules/core-js/modules/_a-function.js","../node_modules/core-js/modules/_ctx.js","../node_modules/core-js/modules/_export.js","../node_modules/core-js/modules/_to-integer.js","../node_modules/core-js/modules/_to-length.js","../node_modules/core-js/modules/_to-absolute-index.js","../node_modules/core-js/modules/_array-includes.js","../node_modules/core-js/modules/_shared-key.js","../node_modules/core-js/modules/_object-keys-internal.js","../node_modules/core-js/modules/_enum-bug-keys.js","../node_modules/core-js/modules/_object-keys.js","../node_modules/core-js/modules/_object-dps.js","../node_modules/core-js/modules/_html.js","../node_modules/core-js/modules/_object-create.js","../node_modules/core-js/modules/_set-to-string-tag.js","../node_modules/core-js/modules/_iter-create.js","../node_modules/core-js/modules/_to-object.js","../node_modules/core-js/modules/_object-gpo.js","../node_modules/core-js/modules/_iter-define.js","../node_modules/core-js/modules/es6.array.iterator.js","../node_modules/core-js/modules/web.dom.iterable.js","../node_modules/core-js/modules/_object-gops.js","../node_modules/core-js/modules/_object-pie.js","../node_modules/core-js/modules/_object-assign.js","../node_modules/core-js/modules/es6.object.assign.js","../src/utils/thread.js","../node_modules/core-js/modules/_string-at.js","../node_modules/core-js/modules/_advance-string-index.js","../node_modules/core-js/modules/_classof.js","../node_modules/core-js/modules/_regexp-exec-abstract.js","../node_modules/core-js/modules/_flags.js","../node_modules/core-js/modules/_regexp-exec.js","../node_modules/core-js/modules/es6.regexp.exec.js","../node_modules/core-js/modules/_fix-re-wks.js","../node_modules/core-js/modules/es6.regexp.replace.js","../node_modules/core-js/modules/_strict-method.js","../node_modules/core-js/modules/es6.array.sort.js","../node_modules/core-js/modules/es6.string.iterator.js","../node_modules/core-js/modules/_an-instance.js","../node_modules/core-js/modules/_iter-call.js","../node_modules/core-js/modules/_is-array-iter.js","../node_modules/core-js/modules/core.get-iterator-method.js","../node_modules/core-js/modules/_for-of.js","../node_modules/core-js/modules/_species-constructor.js","../node_modules/core-js/modules/_invoke.js","../node_modules/core-js/modules/_task.js","../node_modules/core-js/modules/_microtask.js","../node_modules/core-js/modules/_new-promise-capability.js","../node_modules/core-js/modules/_perform.js","../node_modules/core-js/modules/_user-agent.js","../node_modules/core-js/modules/_promise-resolve.js","../node_modules/core-js/modules/_redefine-all.js","../node_modules/core-js/modules/_set-species.js","../node_modules/core-js/modules/_iter-detect.js","../node_modules/core-js/modules/es6.promise.js","../node_modules/core-js/modules/es6.function.name.js","../node_modules/core-js/modules/_object-sap.js","../node_modules/core-js/modules/es6.object.keys.js","../src/utils/version.js","../node_modules/core-js/modules/_is-regexp.js","../node_modules/core-js/modules/es6.regexp.split.js","../src/utils/worker_broker.js","../src/utils/log.js","../node_modules/core-js/modules/es6.regexp.flags.js","../node_modules/core-js/modules/es6.regexp.to-string.js","../src/utils/geo.js","../src/utils/utils.js","../src/utils/debug_settings.js","../node_modules/core-js/modules/_object-gopd.js","../node_modules/core-js/modules/_set-proto.js","../node_modules/core-js/modules/_inherit-if-required.js","../node_modules/core-js/modules/_object-gopn.js","../node_modules/core-js/modules/es6.regexp.constructor.js","../node_modules/core-js/modules/_same-value.js","../node_modules/core-js/modules/es6.regexp.search.js","../src/utils/urls.js","../src/utils/task.js","../src/utils/subscribe.js","../src/utils/slice.js","../node_modules/core-js/modules/_string-repeat.js","../node_modules/core-js/modules/es6.string.repeat.js","../node_modules/core-js/modules/_typed.js","../node_modules/core-js/modules/_to-index.js","../node_modules/core-js/modules/_array-fill.js","../node_modules/core-js/modules/_typed-buffer.js","../node_modules/core-js/modules/_is-array.js","../node_modules/core-js/modules/_array-species-constructor.js","../node_modules/core-js/modules/_array-species-create.js","../node_modules/core-js/modules/_array-methods.js","../node_modules/core-js/modules/_array-copy-within.js","../node_modules/core-js/modules/_typed-array.js","../node_modules/core-js/modules/es6.typed.uint8-array.js","../src/gl/texture.js","../node_modules/core-js/modules/_object-to-array.js","../node_modules/core-js/modules/es7.object.entries.js","../node_modules/core-js/modules/es6.regexp.match.js","../src/gl/glsl.js","../src/gl/extensions.js","../src/utils/hash.js","../node_modules/gl-shader-errors/index.js","../src/gl/shader_program.js","../src/gl/vao.js","../node_modules/core-js/modules/es7.object.values.js","../src/utils/merge.js","../node_modules/core-js/modules/_meta.js","../node_modules/core-js/modules/es6.object.freeze.js","../src/utils/functions.js","../node_modules/csscolorparser/csscolorparser.js","../src/styles/style_parser.js","../node_modules/core-js/modules/es6.array.fill.js","../src/selection/selection.js","../node_modules/core-js/modules/es6.typed.uint16-array.js","../src/gl/vbo_mesh.js","../src/lights/material.js","../src/utils/vector.js","../src/lights/light.js","../node_modules/core-js/modules/es6.math.log2.js","../src/utils/errors.js","../src/sources/data_source.js","../src/tile/tile_id.js","../src/sources/raster.js","../src/styles/style.js","../src/gl/constants.js","../node_modules/core-js/modules/es6.typed.int16-array.js","../node_modules/core-js/modules/es6.typed.uint32-array.js","../node_modules/core-js/modules/es6.typed.int32-array.js","../node_modules/core-js/modules/es6.typed.int8-array.js","../node_modules/core-js/modules/es6.typed.float32-array.js","../src/gl/vertex_elements.js","../src/gl/vertex_data.js","../src/gl/vertex_layout.js","../src/builders/common.js","../node_modules/earcut/src/earcut.js","../src/builders/polygons.js","../src/styles/polygons/polygons.js","../node_modules/core-js/modules/_string-html.js","../node_modules/core-js/modules/es6.string.sub.js","../src/builders/polylines.js","../src/styles/lines/dasharray.js","../src/styles/lines/lines.js","../node_modules/core-js/modules/es6.date.to-json.js","../node_modules/core-js/modules/es6.string.anchor.js","../src/builders/points.js","../src/labels/point_anchor.js","../src/labels/intersect.js","../src/utils/obb.js","../src/labels/label.js","../src/labels/repeat_group.js","../src/labels/collision.js","../src/labels/label_point.js","../src/labels/point_placement.js","../src/styles/text/text_settings.js","../node_modules/fontfaceobserver/fontfaceobserver.standalone.js","../src/styles/text/font_manager.js","../src/styles/text/text_segments.js","../src/styles/text/text_wrap.js","../src/styles/text/text_canvas.js","../src/styles/text/text_labels.js","../node_modules/core-js/modules/es6.typed.float64-array.js","../node_modules/gl-mat3/normal-from-mat4.js","../node_modules/gl-mat3/invert.js","../node_modules/gl-mat4/multiply.js","../node_modules/gl-mat4/translate.js","../node_modules/gl-mat4/scale.js","../node_modules/gl-mat4/perspective.js","../node_modules/gl-mat4/identity.js","../node_modules/gl-mat4/lookAt.js","../node_modules/gl-mat4/copy.js","../src/utils/gl-matrix.js","../src/scene/camera.js","../src/scene/view.js","../src/styles/points/points.js","../node_modules/core-js/modules/es6.math.hypot.js","../src/labels/label_line.js","../src/styles/text/text.js","../src/styles/raster/raster.js","../src/styles/style_manager.js","../src/styles/filter.js","../src/styles/layer.js","../src/tile/tile.js","../node_modules/ieee754/index.js","../node_modules/pbf/index.js","../node_modules/@mapbox/point-geometry/index.js","../node_modules/@mapbox/vector-tile/lib/vectortilefeature.js","../node_modules/@mapbox/vector-tile/lib/vectortilelayer.js","../node_modules/@mapbox/vector-tile/lib/vectortile.js","../node_modules/@mapbox/vector-tile/index.js","../src/sources/mvt.js","../node_modules/geojson-vt/src/simplify.js","../node_modules/geojson-vt/src/feature.js","../node_modules/geojson-vt/src/convert.js","../node_modules/geojson-vt/src/transform.js","../node_modules/geojson-vt/src/clip.js","../node_modules/geojson-vt/src/wrap.js","../node_modules/geojson-vt/src/tile.js","../node_modules/geojson-vt/src/index.js","../src/sources/geojson.js","../node_modules/topojson-client/src/reverse.js","../node_modules/topojson-client/src/identity.js","../node_modules/topojson-client/src/transform.js","../node_modules/topojson-client/src/feature.js","../src/sources/topojson.js","../src/scene/scene_worker.js","../src/gl/context.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/buffer-es6/base64.js","../node_modules/buffer-es6/ieee754.js","../node_modules/buffer-es6/isArray.js","../node_modules/buffer-es6/index.js","../node_modules/rollup-plugin-node-builtins/src/es6/events.js","../node_modules/process-es6/browser.js","../node_modules/util/support/isBufferBrowser.js","../node_modules/util/node_modules/inherits/inherits_browser.js","../node_modules/util/util.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/buffer-list.js","../node_modules/safe-buffer/index.js","../node_modules/string_decoder/lib/string_decoder.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/readable.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/writable.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/duplex.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/transform.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/passthrough.js","../node_modules/rollup-plugin-node-builtins/src/es6/stream.js","../node_modules/jszip/lib/readable-stream-browser.js","../node_modules/jszip/lib/support.js","../node_modules/jszip/lib/base64.js","../node_modules/jszip/lib/nodejsUtils.js","../node_modules/jszip/node_modules/core-js/library/modules/_global.js","../node_modules/jszip/node_modules/core-js/library/modules/_core.js","../node_modules/jszip/node_modules/core-js/library/modules/_a-function.js","../node_modules/jszip/node_modules/core-js/library/modules/_ctx.js","../node_modules/jszip/node_modules/core-js/library/modules/_is-object.js","../node_modules/jszip/node_modules/core-js/library/modules/_an-object.js","../node_modules/jszip/node_modules/core-js/library/modules/_fails.js","../node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js","../node_modules/jszip/node_modules/core-js/library/modules/_dom-create.js","../node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js","../node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js","../node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js","../node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js","../node_modules/jszip/node_modules/core-js/library/modules/_hide.js","../node_modules/jszip/node_modules/core-js/library/modules/_export.js","../node_modules/jszip/node_modules/core-js/library/modules/_invoke.js","../node_modules/jszip/node_modules/core-js/library/modules/_html.js","../node_modules/jszip/node_modules/core-js/library/modules/_cof.js","../node_modules/jszip/node_modules/core-js/library/modules/_task.js","../node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js","../node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js","../node_modules/immediate/lib/browser.js","../node_modules/lie/lib/browser.js","../node_modules/jszip/lib/external.js","../node_modules/jszip/lib/utils.js","../node_modules/jszip/lib/stream/GenericWorker.js","../node_modules/jszip/lib/utf8.js","../node_modules/jszip/lib/stream/ConvertWorker.js","../node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js","../node_modules/jszip/lib/stream/StreamHelper.js","../node_modules/jszip/lib/defaults.js","../node_modules/jszip/lib/stream/DataWorker.js","../node_modules/jszip/lib/stream/DataLengthProbe.js","../node_modules/jszip/lib/crc32.js","../node_modules/jszip/lib/stream/Crc32Probe.js","../node_modules/jszip/lib/compressedObject.js","../node_modules/jszip/lib/zipObject.js","../node_modules/pako/lib/utils/common.js","../node_modules/pako/lib/zlib/trees.js","../node_modules/pako/lib/zlib/adler32.js","../node_modules/pako/lib/zlib/crc32.js","../node_modules/pako/lib/zlib/messages.js","../node_modules/pako/lib/zlib/deflate.js","../node_modules/pako/lib/utils/strings.js","../node_modules/pako/lib/zlib/zstream.js","../node_modules/pako/lib/deflate.js","../node_modules/pako/lib/zlib/inffast.js","../node_modules/pako/lib/zlib/inftrees.js","../node_modules/pako/lib/zlib/inflate.js","../node_modules/pako/lib/zlib/constants.js","../node_modules/pako/lib/zlib/gzheader.js","../node_modules/pako/lib/inflate.js","../node_modules/pako/index.js","../node_modules/jszip/lib/flate.js","../node_modules/jszip/lib/compressions.js","../node_modules/jszip/lib/signature.js","../node_modules/jszip/lib/generate/ZipFileWorker.js","../node_modules/jszip/lib/generate/index.js","../node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js","../node_modules/jszip/lib/object.js","../node_modules/jszip/lib/reader/DataReader.js","../node_modules/jszip/lib/reader/ArrayReader.js","../node_modules/jszip/lib/reader/StringReader.js","../node_modules/jszip/lib/reader/Uint8ArrayReader.js","../node_modules/jszip/lib/reader/NodeBufferReader.js","../node_modules/jszip/lib/reader/readerFor.js","../node_modules/jszip/lib/zipEntry.js","../node_modules/jszip/lib/zipEntries.js","../node_modules/jszip/lib/load.js","../node_modules/jszip/lib/index.js","../node_modules/js-yaml/lib/js-yaml/common.js","../node_modules/js-yaml/lib/js-yaml/exception.js","../node_modules/js-yaml/lib/js-yaml/mark.js","../node_modules/js-yaml/lib/js-yaml/type.js","../node_modules/js-yaml/lib/js-yaml/schema.js","../node_modules/js-yaml/lib/js-yaml/type/str.js","../node_modules/js-yaml/lib/js-yaml/type/seq.js","../node_modules/js-yaml/lib/js-yaml/type/map.js","../node_modules/js-yaml/lib/js-yaml/schema/failsafe.js","../node_modules/js-yaml/lib/js-yaml/type/null.js","../node_modules/js-yaml/lib/js-yaml/type/bool.js","../node_modules/js-yaml/lib/js-yaml/type/int.js","../node_modules/js-yaml/lib/js-yaml/type/float.js","../node_modules/js-yaml/lib/js-yaml/schema/json.js","../node_modules/js-yaml/lib/js-yaml/schema/core.js","../node_modules/js-yaml/lib/js-yaml/type/timestamp.js","../node_modules/js-yaml/lib/js-yaml/type/merge.js","../node_modules/rollup-plugin-node-resolve/src/empty.js","../node_modules/js-yaml/lib/js-yaml/type/binary.js","../node_modules/js-yaml/lib/js-yaml/type/omap.js","../node_modules/js-yaml/lib/js-yaml/type/pairs.js","../node_modules/js-yaml/lib/js-yaml/type/set.js","../node_modules/js-yaml/lib/js-yaml/schema/default_safe.js","../node_modules/js-yaml/lib/js-yaml/type/js/undefined.js","../node_modules/js-yaml/lib/js-yaml/type/js/regexp.js","../node_modules/js-yaml/lib/js-yaml/type/js/function.js","../node_modules/js-yaml/lib/js-yaml/schema/default_full.js","../node_modules/js-yaml/lib/js-yaml/loader.js","../node_modules/js-yaml/lib/js-yaml.js","../node_modules/js-yaml/index.js","../src/scene/scene_bundle.js","../src/scene/scene_loader.js","../src/tile/tile_pyramid.js","../src/labels/main_pass.js","../src/tile/tile_manager.js","../src/gl/render_state.js","../node_modules/core-js/modules/es6.typed.uint8-clamped-array.js","../src/utils/media_capture.js","../src/scene/scene_debug.js","../src/scene/scene.js","../src/utils/debounce.js","../src/leaflet_layer.js","../src/index.js","../build/bundle.js"],"sourcesContent":["var core = module.exports = { version: '2.6.3' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self\n // eslint-disable-next-line no-new-func\n : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n","module.exports = false;\n","var core = require('./_core');\nvar global = require('./_global');\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: core.version,\n mode: require('./_library') ? 'pure' : 'global',\n copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n","var id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n","var store = require('./_shared')('wks');\nvar uid = require('./_uid');\nvar Symbol = require('./_global').Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n","module.exports = function (exec) {\n try {\n return !!exec();\n } catch (e) {\n return true;\n }\n};\n","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n","var isObject = require('./_is-object');\nvar document = require('./_global').document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n return is ? document.createElement(it) : {};\n};\n","module.exports = !require('./_descriptors') && !require('./_fails')(function () {\n return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n if (!isObject(it)) return it;\n var fn, val;\n if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n","var anObject = require('./_an-object');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar toPrimitive = require('./_to-primitive');\nvar dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return dP(O, P, Attributes);\n } catch (e) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","var dP = require('./_object-dp');\nvar createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function (object, key, value) {\n return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = require('./_wks')('unscopables');\nvar ArrayProto = Array.prototype;\nif (ArrayProto[UNSCOPABLES] == undefined) require('./_hide')(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function (key) {\n ArrayProto[UNSCOPABLES][key] = true;\n};\n","module.exports = function (done, value) {\n return { value: value, done: !!done };\n};\n","module.exports = {};\n","var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject');\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return IObject(defined(it));\n};\n","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n","var global = require('./_global');\nvar hide = require('./_hide');\nvar has = require('./_has');\nvar SRC = require('./_uid')('src');\nvar TO_STRING = 'toString';\nvar $toString = Function[TO_STRING];\nvar TPL = ('' + $toString).split(TO_STRING);\n\nrequire('./_core').inspectSource = function (it) {\n return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n var isFunction = typeof val == 'function';\n if (isFunction) has(val, 'name') || hide(val, 'name', key);\n if (O[key] === val) return;\n if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n if (O === global) {\n O[key] = val;\n } else if (!safe) {\n delete O[key];\n hide(O, key, val);\n } else if (O[key]) {\n O[key] = val;\n } else {\n hide(O, key, val);\n }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n","module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","var global = require('./_global');\nvar core = require('./_core');\nvar hide = require('./_hide');\nvar redefine = require('./_redefine');\nvar ctx = require('./_ctx');\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n var IS_FORCED = type & $export.F;\n var IS_GLOBAL = type & $export.G;\n var IS_STATIC = type & $export.S;\n var IS_PROTO = type & $export.P;\n var IS_BIND = type & $export.B;\n var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n var key, own, out, exp;\n if (IS_GLOBAL) source = name;\n for (key in source) {\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n // export native or passed\n out = (own ? target : source)[key];\n // bind timers to global for call from export context\n exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // extend global\n if (target) redefine(target, key, out, type & $export.U);\n // export\n if (exports[key] != out) hide(exports, key, exp);\n if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n","// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n","var toInteger = require('./_to-integer');\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject');\nvar toLength = require('./_to-length');\nvar toAbsoluteIndex = require('./_to-absolute-index');\nmodule.exports = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n if (O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n","var shared = require('./_shared')('keys');\nvar uid = require('./_uid');\nmodule.exports = function (key) {\n return shared[key] || (shared[key] = uid(key));\n};\n","var has = require('./_has');\nvar toIObject = require('./_to-iobject');\nvar arrayIndexOf = require('./_array-includes')(false);\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function (object, names) {\n var O = toIObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal');\nvar enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O) {\n return $keys(O, enumBugKeys);\n};\n","var dP = require('./_object-dp');\nvar anObject = require('./_an-object');\nvar getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var keys = getKeys(Properties);\n var length = keys.length;\n var i = 0;\n var P;\n while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n","var document = require('./_global').document;\nmodule.exports = document && document.documentElement;\n","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object');\nvar dPs = require('./_object-dps');\nvar enumBugKeys = require('./_enum-bug-keys');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe');\n var i = enumBugKeys.length;\n var lt = '<';\n var gt = '>';\n var iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n","var def = require('./_object-dp').f;\nvar has = require('./_has');\nvar TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n","'use strict';\nvar create = require('./_object-create');\nvar descriptor = require('./_property-desc');\nvar setToStringTag = require('./_set-to-string-tag');\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return Object(defined(it));\n};\n","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has');\nvar toObject = require('./_to-object');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n O = toObject(O);\n if (has(O, IE_PROTO)) return O[IE_PROTO];\n if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n","'use strict';\nvar LIBRARY = require('./_library');\nvar $export = require('./_export');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar $iterCreate = require('./_iter-create');\nvar setToStringTag = require('./_set-to-string-tag');\nvar getPrototypeOf = require('./_object-gpo');\nvar ITERATOR = require('./_wks')('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n $iterCreate(Constructor, NAME, next);\n var getMethod = function (kind) {\n if (!BUGGY && kind in proto) return proto[kind];\n switch (kind) {\n case KEYS: return function keys() { return new Constructor(this, kind); };\n case VALUES: return function values() { return new Constructor(this, kind); };\n } return function entries() { return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator';\n var DEF_VALUES = DEFAULT == VALUES;\n var VALUES_BUG = false;\n var proto = Base.prototype;\n var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n var $default = $native || getMethod(DEFAULT);\n var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n var methods, key, IteratorPrototype;\n // Fix native\n if ($anyNative) {\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if (DEF_VALUES && $native && $native.name !== VALUES) {\n VALUES_BUG = true;\n $default = function values() { return $native.call(this); };\n }\n // Define iterator\n if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if (DEFAULT) {\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if (FORCED) for (key in methods) {\n if (!(key in proto)) redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n","'use strict';\nvar addToUnscopables = require('./_add-to-unscopables');\nvar step = require('./_iter-step');\nvar Iterators = require('./_iterators');\nvar toIObject = require('./_to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {\n this._t = toIObject(iterated); // target\n this._i = 0; // next index\n this._k = kind; // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var kind = this._k;\n var index = this._i++;\n if (!O || index >= O.length) {\n this._t = undefined;\n return step(1);\n }\n if (kind == 'keys') return step(0, index);\n if (kind == 'values') return step(0, O[index]);\n return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n","var $iterators = require('./es6.array.iterator');\nvar getKeys = require('./_object-keys');\nvar redefine = require('./_redefine');\nvar global = require('./_global');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar wks = require('./_wks');\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n CSSRuleList: true, // TODO: Not spec compliant, should be false.\n CSSStyleDeclaration: false,\n CSSValueList: false,\n ClientRectList: false,\n DOMRectList: false,\n DOMStringList: false,\n DOMTokenList: true,\n DataTransferItemList: false,\n FileList: false,\n HTMLAllCollection: false,\n HTMLCollection: false,\n HTMLFormElement: false,\n HTMLSelectElement: false,\n MediaList: true, // TODO: Not spec compliant, should be false.\n MimeTypeArray: false,\n NamedNodeMap: false,\n NodeList: true,\n PaintRequestList: false,\n Plugin: false,\n PluginArray: false,\n SVGLengthList: false,\n SVGNumberList: false,\n SVGPathSegList: false,\n SVGPointList: false,\n SVGStringList: false,\n SVGTransformList: false,\n SourceBufferList: false,\n StyleSheetList: true, // TODO: Not spec compliant, should be false.\n TextTrackCueList: false,\n TextTrackList: false,\n TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n var NAME = collections[i];\n var explicit = DOMIterables[NAME];\n var Collection = global[NAME];\n var proto = Collection && Collection.prototype;\n var key;\n if (proto) {\n if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = ArrayValues;\n if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n }\n}\n","exports.f = Object.getOwnPropertySymbols;\n","exports.f = {}.propertyIsEnumerable;\n","'use strict';\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = require('./_object-keys');\nvar gOPS = require('./_object-gops');\nvar pIE = require('./_object-pie');\nvar toObject = require('./_to-object');\nvar IObject = require('./_iobject');\nvar $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || require('./_fails')(function () {\n var A = {};\n var B = {};\n // eslint-disable-next-line no-undef\n var S = Symbol();\n var K = 'abcdefghijklmnopqrst';\n A[S] = 7;\n K.split('').forEach(function (k) { B[k] = k; });\n return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n var T = toObject(target);\n var aLen = arguments.length;\n var index = 1;\n var getSymbols = gOPS.f;\n var isEnum = pIE.f;\n while (aLen > index) {\n var S = IObject(arguments[index++]);\n var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);\n var length = keys.length;\n var j = 0;\n var key;\n while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];\n } return T;\n} : $assign;\n","// 19.1.3.1 Object.assign(target, source)\nvar $export = require('./_export');\n\n$export($export.S + $export.F, 'Object', { assign: require('./_object-assign') });\n","/*jshint worker: true*/\n\n// Mark thread as main or worker\nconst Thread = {};\n\ntry {\n if (window instanceof Window && window.document instanceof HTMLDocument) { // jshint ignore:line\n Thread.is_worker = false;\n Thread.is_main = true;\n }\n}\ncatch(e) {\n Thread.is_worker = true;\n Thread.is_main = false;\n\n // Patch for 3rd party libs that require these globals to be present. Specifically, FontFaceObserver.\n // Brittle solution but allows that library to load on worker threads.\n self.window = { document: {} };\n self.document = self.window.document;\n}\n\nexport default Thread;\n","var toInteger = require('./_to-integer');\nvar defined = require('./_defined');\n// true -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n return function (that, pos) {\n var s = String(defined(that));\n var i = toInteger(pos);\n var l = s.length;\n var a, b;\n if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n a = s.charCodeAt(i);\n return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n ? TO_STRING ? s.charAt(i) : a\n : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n };\n};\n","'use strict';\nvar at = require('./_string-at')(true);\n\n // `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n return index + (unicode ? at(S, index).length : 1);\n};\n","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof');\nvar TAG = require('./_wks')('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n","'use strict';\n\nvar classof = require('./_classof');\nvar builtinExec = RegExp.prototype.exec;\n\n // `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n var exec = R.exec;\n if (typeof exec === 'function') {\n var result = exec.call(R, S);\n if (typeof result !== 'object') {\n throw new TypeError('RegExp exec method returned something other than an Object or null');\n }\n return result;\n }\n if (classof(R) !== 'RegExp') {\n throw new TypeError('RegExp#exec called on incompatible receiver');\n }\n return builtinExec.call(R, S);\n};\n","'use strict';\n// 21.2.5.3 get RegExp.prototype.flags\nvar anObject = require('./_an-object');\nmodule.exports = function () {\n var that = anObject(this);\n var result = '';\n if (that.global) result += 'g';\n if (that.ignoreCase) result += 'i';\n if (that.multiline) result += 'm';\n if (that.unicode) result += 'u';\n if (that.sticky) result += 'y';\n return result;\n};\n","'use strict';\n\nvar regexpFlags = require('./_flags');\n\nvar nativeExec = RegExp.prototype.exec;\n// This always refers to the native implementation, because the\n// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,\n// which loads this file before patching the method.\nvar nativeReplace = String.prototype.replace;\n\nvar patchedExec = nativeExec;\n\nvar LAST_INDEX = 'lastIndex';\n\nvar UPDATES_LAST_INDEX_WRONG = (function () {\n var re1 = /a/,\n re2 = /b*/g;\n nativeExec.call(re1, 'a');\n nativeExec.call(re2, 'a');\n return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;\n})();\n\n// nonparticipating capturing group, copied from es5-shim's String#split patch.\nvar NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;\n\nvar PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;\n\nif (PATCH) {\n patchedExec = function exec(str) {\n var re = this;\n var lastIndex, reCopy, match, i;\n\n if (NPCG_INCLUDED) {\n reCopy = new RegExp('^' + re.source + '$(?!\\\\s)', regexpFlags.call(re));\n }\n if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];\n\n match = nativeExec.call(re, str);\n\n if (UPDATES_LAST_INDEX_WRONG && match) {\n re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;\n }\n if (NPCG_INCLUDED && match && match.length > 1) {\n // Fix browsers whose `exec` methods don't consistently return `undefined`\n // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/\n // eslint-disable-next-line no-loop-func\n nativeReplace.call(match[0], reCopy, function () {\n for (i = 1; i < arguments.length - 2; i++) {\n if (arguments[i] === undefined) match[i] = undefined;\n }\n });\n }\n\n return match;\n };\n}\n\nmodule.exports = patchedExec;\n","'use strict';\nvar regexpExec = require('./_regexp-exec');\nrequire('./_export')({\n target: 'RegExp',\n proto: true,\n forced: regexpExec !== /./.exec\n}, {\n exec: regexpExec\n});\n","'use strict';\nrequire('./es6.regexp.exec');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar fails = require('./_fails');\nvar defined = require('./_defined');\nvar wks = require('./_wks');\nvar regexpExec = require('./_regexp-exec');\n\nvar SPECIES = wks('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n // #replace needs built-in support for named groups.\n // #match works fine because it just return the exec results, even if it has\n // a \"grops\" property.\n var re = /./;\n re.exec = function () {\n var result = [];\n result.groups = { a: '7' };\n return result;\n };\n return ''.replace(re, '$') !== '7';\n});\n\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {\n // Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n var re = /(?:)/;\n var originalExec = re.exec;\n re.exec = function () { return originalExec.apply(this, arguments); };\n var result = 'ab'.split(re);\n return result.length === 2 && result[0] === 'a' && result[1] === 'b';\n})();\n\nmodule.exports = function (KEY, length, exec) {\n var SYMBOL = wks(KEY);\n\n var DELEGATES_TO_SYMBOL = !fails(function () {\n // String methods call symbol-named RegEp methods\n var O = {};\n O[SYMBOL] = function () { return 7; };\n return ''[KEY](O) != 7;\n });\n\n var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !fails(function () {\n // Symbol-named RegExp methods call .exec\n var execCalled = false;\n var re = /a/;\n re.exec = function () { execCalled = true; return null; };\n if (KEY === 'split') {\n // RegExp[@@split] doesn't call the regex's exec method, but first creates\n // a new one. We need to return the patched regex when creating the new one.\n re.constructor = {};\n re.constructor[SPECIES] = function () { return re; };\n }\n re[SYMBOL]('');\n return !execCalled;\n }) : undefined;\n\n if (\n !DELEGATES_TO_SYMBOL ||\n !DELEGATES_TO_EXEC ||\n (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||\n (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n ) {\n var nativeRegExpMethod = /./[SYMBOL];\n var fns = exec(\n defined,\n SYMBOL,\n ''[KEY],\n function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {\n if (regexp.exec === regexpExec) {\n if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n // The native String method already delegates to @@method (this\n // polyfilled function), leasing to infinite recursion.\n // We avoid it by directly calling the native @@method method.\n return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n }\n return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n }\n return { done: false };\n }\n );\n var strfn = fns[0];\n var rxfn = fns[1];\n\n redefine(String.prototype, KEY, strfn);\n hide(RegExp.prototype, SYMBOL, length == 2\n // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n ? function (string, arg) { return rxfn.call(string, this, arg); }\n // 21.2.5.6 RegExp.prototype[@@match](string)\n // 21.2.5.9 RegExp.prototype[@@search](string)\n : function (string) { return rxfn.call(string, this); }\n );\n }\n};\n","'use strict';\n\nvar anObject = require('./_an-object');\nvar toObject = require('./_to-object');\nvar toLength = require('./_to-length');\nvar toInteger = require('./_to-integer');\nvar advanceStringIndex = require('./_advance-string-index');\nvar regExpExec = require('./_regexp-exec-abstract');\nvar max = Math.max;\nvar min = Math.min;\nvar floor = Math.floor;\nvar SUBSTITUTION_SYMBOLS = /\\$([$&`']|\\d\\d?|<[^>]*>)/g;\nvar SUBSTITUTION_SYMBOLS_NO_NAMED = /\\$([$&`']|\\d\\d?)/g;\n\nvar maybeToString = function (it) {\n return it === undefined ? it : String(it);\n};\n\n// @@replace logic\nrequire('./_fix-re-wks')('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {\n return [\n // `String.prototype.replace` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.replace\n function replace(searchValue, replaceValue) {\n var O = defined(this);\n var fn = searchValue == undefined ? undefined : searchValue[REPLACE];\n return fn !== undefined\n ? fn.call(searchValue, O, replaceValue)\n : $replace.call(String(O), searchValue, replaceValue);\n },\n // `RegExp.prototype[@@replace]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace\n function (regexp, replaceValue) {\n var res = maybeCallNative($replace, regexp, this, replaceValue);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n var functionalReplace = typeof replaceValue === 'function';\n if (!functionalReplace) replaceValue = String(replaceValue);\n var global = rx.global;\n if (global) {\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n }\n var results = [];\n while (true) {\n var result = regExpExec(rx, S);\n if (result === null) break;\n results.push(result);\n if (!global) break;\n var matchStr = String(result[0]);\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n }\n var accumulatedResult = '';\n var nextSourcePosition = 0;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n var matched = String(result[0]);\n var position = max(min(toInteger(result.index), S.length), 0);\n var captures = [];\n // NOTE: This is equivalent to\n // captures = result.slice(1).map(maybeToString)\n // but for some reason `nativeSlice.call(result, 1, result.length)` (called in\n // the slice polyfill when slicing native arrays) \"doesn't work\" in safari 9 and\n // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.\n for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));\n var namedCaptures = result.groups;\n if (functionalReplace) {\n var replacerArgs = [matched].concat(captures, position, S);\n if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);\n var replacement = String(replaceValue.apply(undefined, replacerArgs));\n } else {\n replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);\n }\n if (position >= nextSourcePosition) {\n accumulatedResult += S.slice(nextSourcePosition, position) + replacement;\n nextSourcePosition = position + matched.length;\n }\n }\n return accumulatedResult + S.slice(nextSourcePosition);\n }\n ];\n\n // https://tc39.github.io/ecma262/#sec-getsubstitution\n function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {\n var tailPos = position + matched.length;\n var m = captures.length;\n var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;\n if (namedCaptures !== undefined) {\n namedCaptures = toObject(namedCaptures);\n symbols = SUBSTITUTION_SYMBOLS;\n }\n return $replace.call(replacement, symbols, function (match, ch) {\n var capture;\n switch (ch.charAt(0)) {\n case '$': return '$';\n case '&': return matched;\n case '`': return str.slice(0, position);\n case \"'\": return str.slice(tailPos);\n case '<':\n capture = namedCaptures[ch.slice(1, -1)];\n break;\n default: // \\d\\d?\n var n = +ch;\n if (n === 0) return match;\n if (n > m) {\n var f = floor(n / 10);\n if (f === 0) return match;\n if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);\n return match;\n }\n capture = captures[n - 1];\n }\n return capture === undefined ? '' : capture;\n });\n }\n});\n","'use strict';\nvar fails = require('./_fails');\n\nmodule.exports = function (method, arg) {\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call\n arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);\n });\n};\n","'use strict';\nvar $export = require('./_export');\nvar aFunction = require('./_a-function');\nvar toObject = require('./_to-object');\nvar fails = require('./_fails');\nvar $sort = [].sort;\nvar test = [1, 2, 3];\n\n$export($export.P + $export.F * (fails(function () {\n // IE8-\n test.sort(undefined);\n}) || !fails(function () {\n // V8 bug\n test.sort(null);\n // Old WebKit\n}) || !require('./_strict-method')($sort)), 'Array', {\n // 22.1.3.25 Array.prototype.sort(comparefn)\n sort: function sort(comparefn) {\n return comparefn === undefined\n ? $sort.call(toObject(this))\n : $sort.call(toObject(this), aFunction(comparefn));\n }\n});\n","'use strict';\nvar $at = require('./_string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./_iter-define')(String, 'String', function (iterated) {\n this._t = String(iterated); // target\n this._i = 0; // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var index = this._i;\n var point;\n if (index >= O.length) return { value: undefined, done: true };\n point = $at(O, index);\n this._i += point.length;\n return { value: point, done: false };\n});\n","module.exports = function (it, Constructor, name, forbiddenField) {\n if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n throw TypeError(name + ': incorrect invocation!');\n } return it;\n};\n","// call something on iterator step with safe closing on error\nvar anObject = require('./_an-object');\nmodule.exports = function (iterator, fn, value, entries) {\n try {\n return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch (e) {\n var ret = iterator['return'];\n if (ret !== undefined) anObject(ret.call(iterator));\n throw e;\n }\n};\n","// check on default Array iterator\nvar Iterators = require('./_iterators');\nvar ITERATOR = require('./_wks')('iterator');\nvar ArrayProto = Array.prototype;\n\nmodule.exports = function (it) {\n return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n","var classof = require('./_classof');\nvar ITERATOR = require('./_wks')('iterator');\nvar Iterators = require('./_iterators');\nmodule.exports = require('./_core').getIteratorMethod = function (it) {\n if (it != undefined) return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n","var ctx = require('./_ctx');\nvar call = require('./_iter-call');\nvar isArrayIter = require('./_is-array-iter');\nvar anObject = require('./_an-object');\nvar toLength = require('./_to-length');\nvar getIterFn = require('./core.get-iterator-method');\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n var f = ctx(fn, that, entries ? 2 : 1);\n var index = 0;\n var length, step, iterator, result;\n if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n // fast case for arrays with default iterator\n if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n if (result === BREAK || result === RETURN) return result;\n } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n result = call(iterator, f, step.value, entries);\n if (result === BREAK || result === RETURN) return result;\n }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n","// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = require('./_an-object');\nvar aFunction = require('./_a-function');\nvar SPECIES = require('./_wks')('species');\nmodule.exports = function (O, D) {\n var C = anObject(O).constructor;\n var S;\n return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function (fn, args, that) {\n var un = that === undefined;\n switch (args.length) {\n case 0: return un ? fn()\n : fn.call(that);\n case 1: return un ? fn(args[0])\n : fn.call(that, args[0]);\n case 2: return un ? fn(args[0], args[1])\n : fn.call(that, args[0], args[1]);\n case 3: return un ? fn(args[0], args[1], args[2])\n : fn.call(that, args[0], args[1], args[2]);\n case 4: return un ? fn(args[0], args[1], args[2], args[3])\n : fn.call(that, args[0], args[1], args[2], args[3]);\n } return fn.apply(that, args);\n};\n","var ctx = require('./_ctx');\nvar invoke = require('./_invoke');\nvar html = require('./_html');\nvar cel = require('./_dom-create');\nvar global = require('./_global');\nvar process = global.process;\nvar setTask = global.setImmediate;\nvar clearTask = global.clearImmediate;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\nvar run = function () {\n var id = +this;\n // eslint-disable-next-line no-prototype-builtins\n if (queue.hasOwnProperty(id)) {\n var fn = queue[id];\n delete queue[id];\n fn();\n }\n};\nvar listener = function (event) {\n run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!setTask || !clearTask) {\n setTask = function setImmediate(fn) {\n var args = [];\n var i = 1;\n while (arguments.length > i) args.push(arguments[i++]);\n queue[++counter] = function () {\n // eslint-disable-next-line no-new-func\n invoke(typeof fn == 'function' ? fn : Function(fn), args);\n };\n defer(counter);\n return counter;\n };\n clearTask = function clearImmediate(id) {\n delete queue[id];\n };\n // Node.js 0.8-\n if (require('./_cof')(process) == 'process') {\n defer = function (id) {\n process.nextTick(ctx(run, id, 1));\n };\n // Sphere (JS game engine) Dispatch API\n } else if (Dispatch && Dispatch.now) {\n defer = function (id) {\n Dispatch.now(ctx(run, id, 1));\n };\n // Browsers with MessageChannel, includes WebWorkers\n } else if (MessageChannel) {\n channel = new MessageChannel();\n port = channel.port2;\n channel.port1.onmessage = listener;\n defer = ctx(port.postMessage, port, 1);\n // Browsers with postMessage, skip WebWorkers\n // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {\n defer = function (id) {\n global.postMessage(id + '', '*');\n };\n global.addEventListener('message', listener, false);\n // IE8-\n } else if (ONREADYSTATECHANGE in cel('script')) {\n defer = function (id) {\n html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {\n html.removeChild(this);\n run.call(id);\n };\n };\n // Rest old browsers\n } else {\n defer = function (id) {\n setTimeout(ctx(run, id, 1), 0);\n };\n }\n}\nmodule.exports = {\n set: setTask,\n clear: clearTask\n};\n","var global = require('./_global');\nvar macrotask = require('./_task').set;\nvar Observer = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar isNode = require('./_cof')(process) == 'process';\n\nmodule.exports = function () {\n var head, last, notify;\n\n var flush = function () {\n var parent, fn;\n if (isNode && (parent = process.domain)) parent.exit();\n while (head) {\n fn = head.fn;\n head = head.next;\n try {\n fn();\n } catch (e) {\n if (head) notify();\n else last = undefined;\n throw e;\n }\n } last = undefined;\n if (parent) parent.enter();\n };\n\n // Node.js\n if (isNode) {\n notify = function () {\n process.nextTick(flush);\n };\n // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339\n } else if (Observer && !(global.navigator && global.navigator.standalone)) {\n var toggle = true;\n var node = document.createTextNode('');\n new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n notify = function () {\n node.data = toggle = !toggle;\n };\n // environments with maybe non-completely correct, but existent Promise\n } else if (Promise && Promise.resolve) {\n // Promise.resolve without an argument throws an error in LG WebOS 2\n var promise = Promise.resolve(undefined);\n notify = function () {\n promise.then(flush);\n };\n // for other environments - macrotask based on:\n // - setImmediate\n // - MessageChannel\n // - window.postMessag\n // - onreadystatechange\n // - setTimeout\n } else {\n notify = function () {\n // strange IE + webpack dev server bug - use .call(global)\n macrotask.call(global, flush);\n };\n }\n\n return function (fn) {\n var task = { fn: fn, next: undefined };\n if (last) last.next = task;\n if (!head) {\n head = task;\n notify();\n } last = task;\n };\n};\n","'use strict';\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = require('./_a-function');\n\nfunction PromiseCapability(C) {\n var resolve, reject;\n this.promise = new C(function ($$resolve, $$reject) {\n if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n resolve = $$resolve;\n reject = $$reject;\n });\n this.resolve = aFunction(resolve);\n this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n return new PromiseCapability(C);\n};\n","module.exports = function (exec) {\n try {\n return { e: false, v: exec() };\n } catch (e) {\n return { e: true, v: e };\n }\n};\n","var global = require('./_global');\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n","var anObject = require('./_an-object');\nvar isObject = require('./_is-object');\nvar newPromiseCapability = require('./_new-promise-capability');\n\nmodule.exports = function (C, x) {\n anObject(C);\n if (isObject(x) && x.constructor === C) return x;\n var promiseCapability = newPromiseCapability.f(C);\n var resolve = promiseCapability.resolve;\n resolve(x);\n return promiseCapability.promise;\n};\n","var redefine = require('./_redefine');\nmodule.exports = function (target, src, safe) {\n for (var key in src) redefine(target, key, src[key], safe);\n return target;\n};\n","'use strict';\nvar global = require('./_global');\nvar dP = require('./_object-dp');\nvar DESCRIPTORS = require('./_descriptors');\nvar SPECIES = require('./_wks')('species');\n\nmodule.exports = function (KEY) {\n var C = global[KEY];\n if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {\n configurable: true,\n get: function () { return this; }\n });\n};\n","var ITERATOR = require('./_wks')('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n var riter = [7][ITERATOR]();\n riter['return'] = function () { SAFE_CLOSING = true; };\n // eslint-disable-next-line no-throw-literal\n Array.from(riter, function () { throw 2; });\n} catch (e) { /* empty */ }\n\nmodule.exports = function (exec, skipClosing) {\n if (!skipClosing && !SAFE_CLOSING) return false;\n var safe = false;\n try {\n var arr = [7];\n var iter = arr[ITERATOR]();\n iter.next = function () { return { done: safe = true }; };\n arr[ITERATOR] = function () { return iter; };\n exec(arr);\n } catch (e) { /* empty */ }\n return safe;\n};\n","'use strict';\nvar LIBRARY = require('./_library');\nvar global = require('./_global');\nvar ctx = require('./_ctx');\nvar classof = require('./_classof');\nvar $export = require('./_export');\nvar isObject = require('./_is-object');\nvar aFunction = require('./_a-function');\nvar anInstance = require('./_an-instance');\nvar forOf = require('./_for-of');\nvar speciesConstructor = require('./_species-constructor');\nvar task = require('./_task').set;\nvar microtask = require('./_microtask')();\nvar newPromiseCapabilityModule = require('./_new-promise-capability');\nvar perform = require('./_perform');\nvar userAgent = require('./_user-agent');\nvar promiseResolve = require('./_promise-resolve');\nvar PROMISE = 'Promise';\nvar TypeError = global.TypeError;\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar $Promise = global[PROMISE];\nvar isNode = classof(process) == 'process';\nvar empty = function () { /* empty */ };\nvar Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;\nvar newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;\n\nvar USE_NATIVE = !!function () {\n try {\n // correct subclassing with @@species support\n var promise = $Promise.resolve(1);\n var FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function (exec) {\n exec(empty, empty);\n };\n // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n return (isNode || typeof PromiseRejectionEvent == 'function')\n && promise.then(empty) instanceof FakePromise\n // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n // we can't detect it synchronously, so just check versions\n && v8.indexOf('6.6') !== 0\n && userAgent.indexOf('Chrome/66') === -1;\n } catch (e) { /* empty */ }\n}();\n\n// helpers\nvar isThenable = function (it) {\n var then;\n return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar notify = function (promise, isReject) {\n if (promise._n) return;\n promise._n = true;\n var chain = promise._c;\n microtask(function () {\n var value = promise._v;\n var ok = promise._s == 1;\n var i = 0;\n var run = function (reaction) {\n var handler = ok ? reaction.ok : reaction.fail;\n var resolve = reaction.resolve;\n var reject = reaction.reject;\n var domain = reaction.domain;\n var result, then, exited;\n try {\n if (handler) {\n if (!ok) {\n if (promise._h == 2) onHandleUnhandled(promise);\n promise._h = 1;\n }\n if (handler === true) result = value;\n else {\n if (domain) domain.enter();\n result = handler(value); // may throw\n if (domain) {\n domain.exit();\n exited = true;\n }\n }\n if (result === reaction.promise) {\n reject(TypeError('Promise-chain cycle'));\n } else if (then = isThenable(result)) {\n then.call(result, resolve, reject);\n } else resolve(result);\n } else reject(value);\n } catch (e) {\n if (domain && !exited) domain.exit();\n reject(e);\n }\n };\n while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n promise._c = [];\n promise._n = false;\n if (isReject && !promise._h) onUnhandled(promise);\n });\n};\nvar onUnhandled = function (promise) {\n task.call(global, function () {\n var value = promise._v;\n var unhandled = isUnhandled(promise);\n var result, handler, console;\n if (unhandled) {\n result = perform(function () {\n if (isNode) {\n process.emit('unhandledRejection', value, promise);\n } else if (handler = global.onunhandledrejection) {\n handler({ promise: promise, reason: value });\n } else if ((console = global.console) && console.error) {\n console.error('Unhandled promise rejection', value);\n }\n });\n // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n } promise._a = undefined;\n if (unhandled && result.e) throw result.v;\n });\n};\nvar isUnhandled = function (promise) {\n return promise._h !== 1 && (promise._a || promise._c).length === 0;\n};\nvar onHandleUnhandled = function (promise) {\n task.call(global, function () {\n var handler;\n if (isNode) {\n process.emit('rejectionHandled', promise);\n } else if (handler = global.onrejectionhandled) {\n handler({ promise: promise, reason: promise._v });\n }\n });\n};\nvar $reject = function (value) {\n var promise = this;\n if (promise._d) return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n promise._v = value;\n promise._s = 2;\n if (!promise._a) promise._a = promise._c.slice();\n notify(promise, true);\n};\nvar $resolve = function (value) {\n var promise = this;\n var then;\n if (promise._d) return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n try {\n if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n if (then = isThenable(value)) {\n microtask(function () {\n var wrapper = { _w: promise, _d: false }; // wrap\n try {\n then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n } catch (e) {\n $reject.call(wrapper, e);\n }\n });\n } else {\n promise._v = value;\n promise._s = 1;\n notify(promise, false);\n }\n } catch (e) {\n $reject.call({ _w: promise, _d: false }, e); // wrap\n }\n};\n\n// constructor polyfill\nif (!USE_NATIVE) {\n // 25.4.3.1 Promise(executor)\n $Promise = function Promise(executor) {\n anInstance(this, $Promise, PROMISE, '_h');\n aFunction(executor);\n Internal.call(this);\n try {\n executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n } catch (err) {\n $reject.call(this, err);\n }\n };\n // eslint-disable-next-line no-unused-vars\n Internal = function Promise(executor) {\n this._c = []; // <- awaiting reactions\n this._a = undefined; // <- checked in isUnhandled reactions\n this._s = 0; // <- state\n this._d = false; // <- done\n this._v = undefined; // <- value\n this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n this._n = false; // <- notify\n };\n Internal.prototype = require('./_redefine-all')($Promise.prototype, {\n // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n then: function then(onFulfilled, onRejected) {\n var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n reaction.fail = typeof onRejected == 'function' && onRejected;\n reaction.domain = isNode ? process.domain : undefined;\n this._c.push(reaction);\n if (this._a) this._a.push(reaction);\n if (this._s) notify(this, false);\n return reaction.promise;\n },\n // 25.4.5.1 Promise.prototype.catch(onRejected)\n 'catch': function (onRejected) {\n return this.then(undefined, onRejected);\n }\n });\n OwnPromiseCapability = function () {\n var promise = new Internal();\n this.promise = promise;\n this.resolve = ctx($resolve, promise, 1);\n this.reject = ctx($reject, promise, 1);\n };\n newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n return C === $Promise || C === Wrapper\n ? new OwnPromiseCapability(C)\n : newGenericPromiseCapability(C);\n };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });\nrequire('./_set-to-string-tag')($Promise, PROMISE);\nrequire('./_set-species')(PROMISE);\nWrapper = require('./_core')[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n // 25.4.4.5 Promise.reject(r)\n reject: function reject(r) {\n var capability = newPromiseCapability(this);\n var $$reject = capability.reject;\n $$reject(r);\n return capability.promise;\n }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n // 25.4.4.6 Promise.resolve(x)\n resolve: function resolve(x) {\n return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);\n }\n});\n$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function (iter) {\n $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n // 25.4.4.1 Promise.all(iterable)\n all: function all(iterable) {\n var C = this;\n var capability = newPromiseCapability(C);\n var resolve = capability.resolve;\n var reject = capability.reject;\n var result = perform(function () {\n var values = [];\n var index = 0;\n var remaining = 1;\n forOf(iterable, false, function (promise) {\n var $index = index++;\n var alreadyCalled = false;\n values.push(undefined);\n remaining++;\n C.resolve(promise).then(function (value) {\n if (alreadyCalled) return;\n alreadyCalled = true;\n values[$index] = value;\n --remaining || resolve(values);\n }, reject);\n });\n --remaining || resolve(values);\n });\n if (result.e) reject(result.v);\n return capability.promise;\n },\n // 25.4.4.4 Promise.race(iterable)\n race: function race(iterable) {\n var C = this;\n var capability = newPromiseCapability(C);\n var reject = capability.reject;\n var result = perform(function () {\n forOf(iterable, false, function (promise) {\n C.resolve(promise).then(capability.resolve, reject);\n });\n });\n if (result.e) reject(result.v);\n return capability.promise;\n }\n});\n","var dP = require('./_object-dp').f;\nvar FProto = Function.prototype;\nvar nameRE = /^\\s*function ([^ (]*)/;\nvar NAME = 'name';\n\n// 19.2.4.2 name\nNAME in FProto || require('./_descriptors') && dP(FProto, NAME, {\n configurable: true,\n get: function () {\n try {\n return ('' + this).match(nameRE)[1];\n } catch (e) {\n return '';\n }\n }\n});\n","// most Object methods by ES6 should accept primitives\nvar $export = require('./_export');\nvar core = require('./_core');\nvar fails = require('./_fails');\nmodule.exports = function (KEY, exec) {\n var fn = (core.Object || {})[KEY] || Object[KEY];\n var exp = {};\n exp[KEY] = exec(fn);\n $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp);\n};\n","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./_to-object');\nvar $keys = require('./_object-keys');\n\nrequire('./_object-sap')('keys', function () {\n return function keys(it) {\n return $keys(toObject(it));\n };\n});\n","import {version} from '../../package.json';\n\nexport default 'v' + version;\n","// 7.2.8 IsRegExp(argument)\nvar isObject = require('./_is-object');\nvar cof = require('./_cof');\nvar MATCH = require('./_wks')('match');\nmodule.exports = function (it) {\n var isRegExp;\n return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');\n};\n","'use strict';\n\nvar isRegExp = require('./_is-regexp');\nvar anObject = require('./_an-object');\nvar speciesConstructor = require('./_species-constructor');\nvar advanceStringIndex = require('./_advance-string-index');\nvar toLength = require('./_to-length');\nvar callRegExpExec = require('./_regexp-exec-abstract');\nvar regexpExec = require('./_regexp-exec');\nvar fails = require('./_fails');\nvar $min = Math.min;\nvar $push = [].push;\nvar $SPLIT = 'split';\nvar LENGTH = 'length';\nvar LAST_INDEX = 'lastIndex';\nvar MAX_UINT32 = 0xffffffff;\n\n// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError\nvar SUPPORTS_Y = !fails(function () { RegExp(MAX_UINT32, 'y'); });\n\n// @@split logic\nrequire('./_fix-re-wks')('split', 2, function (defined, SPLIT, $split, maybeCallNative) {\n var internalSplit;\n if (\n 'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||\n 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||\n 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||\n '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||\n '.'[$SPLIT](/()()/)[LENGTH] > 1 ||\n ''[$SPLIT](/.?/)[LENGTH]\n ) {\n // based on es5-shim implementation, need to rework it\n internalSplit = function (separator, limit) {\n var string = String(this);\n if (separator === undefined && limit === 0) return [];\n // If `separator` is not a regex, use native split\n if (!isRegExp(separator)) return $split.call(string, separator, limit);\n var output = [];\n var flags = (separator.ignoreCase ? 'i' : '') +\n (separator.multiline ? 'm' : '') +\n (separator.unicode ? 'u' : '') +\n (separator.sticky ? 'y' : '');\n var lastLastIndex = 0;\n var splitLimit = limit === undefined ? MAX_UINT32 : limit >>> 0;\n // Make `global` and avoid `lastIndex` issues by working with a copy\n var separatorCopy = new RegExp(separator.source, flags + 'g');\n var match, lastIndex, lastLength;\n while (match = regexpExec.call(separatorCopy, string)) {\n lastIndex = separatorCopy[LAST_INDEX];\n if (lastIndex > lastLastIndex) {\n output.push(string.slice(lastLastIndex, match.index));\n if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));\n lastLength = match[0][LENGTH];\n lastLastIndex = lastIndex;\n if (output[LENGTH] >= splitLimit) break;\n }\n if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop\n }\n if (lastLastIndex === string[LENGTH]) {\n if (lastLength || !separatorCopy.test('')) output.push('');\n } else output.push(string.slice(lastLastIndex));\n return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;\n };\n // Chakra, V8\n } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {\n internalSplit = function (separator, limit) {\n return separator === undefined && limit === 0 ? [] : $split.call(this, separator, limit);\n };\n } else {\n internalSplit = $split;\n }\n\n return [\n // `String.prototype.split` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.split\n function split(separator, limit) {\n var O = defined(this);\n var splitter = separator == undefined ? undefined : separator[SPLIT];\n return splitter !== undefined\n ? splitter.call(separator, O, limit)\n : internalSplit.call(String(O), separator, limit);\n },\n // `RegExp.prototype[@@split]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split\n //\n // NOTE: This cannot be properly polyfilled in engines that don't support\n // the 'y' flag.\n function (regexp, limit) {\n var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== $split);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n var C = speciesConstructor(rx, RegExp);\n\n var unicodeMatching = rx.unicode;\n var flags = (rx.ignoreCase ? 'i' : '') +\n (rx.multiline ? 'm' : '') +\n (rx.unicode ? 'u' : '') +\n (SUPPORTS_Y ? 'y' : 'g');\n\n // ^(? + rx + ) is needed, in combination with some S slicing, to\n // simulate the 'y' flag.\n var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);\n var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n if (lim === 0) return [];\n if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];\n var p = 0;\n var q = 0;\n var A = [];\n while (q < S.length) {\n splitter.lastIndex = SUPPORTS_Y ? q : 0;\n var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));\n var e;\n if (\n z === null ||\n (e = $min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p\n ) {\n q = advanceStringIndex(S, q, unicodeMatching);\n } else {\n A.push(S.slice(p, q));\n if (A.length === lim) return A;\n for (var i = 1; i <= z.length - 1; i++) {\n A.push(z[i]);\n if (A.length === lim) return A;\n }\n q = p = e;\n }\n }\n A.push(S.slice(p));\n return A;\n }\n ];\n});\n","/*jshint worker: true*/\n\n// WorkerBroker routes messages between web workers and the main thread, allowing for simpler\n// async code via promises. Example usage:\n//\n// In web worker, register self as a callable \"target\", and define a method:\n//\n// WorkerBroker.addTarget('self', self);\n//\n// self.square = function (x) {\n// return x * x;\n// };\n//\n// In main thread, invoke that method and receive the result (if any) as a promise.\n//\n// worker = new Worker(...);\n// WorkerBroker.addWorker(worker);\n//\n// WorkerBroker.postMessage(worker, 'self.square', 5).then(function(y) {\n// console.log(y);\n// });\n//\n// -> prints 25\n//\n// Async code:\n//\n// For synchronous code that must pass a return value to the main thread, the function can simply\n// return an immediate value (see example above). For cases where the worker method needs to run\n// asynchronous code, the function can return a promise, and the resolved or rejected value will\n// be sent back to the main thread when the promise is fulfilled.\n//\n// Error handling:\n//\n// If the worker method either throws an error, or returns a promise that is rejected, it will be\n// sent back to the main thread as a promise rejection. These two examples are equivalent:\n//\n// In worker, throwing an error:\n//\n// self.broken = function () {\n// throw new Error('error in worker!');\n// };\n//\n// In worker, returning a rejected promise:\n//\n// self.broken = function () {\n// return Promise.reject(new Error('error in worker!'));\n// };\n//\n// In main thread, both errors are received as a promise rejection:\n//\n// WorkerBroker.postMessage(worker, 'self.broken').then(\n// // Promise resolved\n// function() {\n// console.log('success!');\n// },\n// // Promise rejected\n// function(error) {\n// console.log('error!', error);\n// });\n//\n// -> prints 'error! error in worker'\n//\n// Calling from worker to main thread:\n//\n// The same style of calls can be made *from* a web worker, to the main thread. The API is the same\n// with the exception that the first argument, 'worker', is not needed for WorkerBroker.postMessage(),\n// since the main thread is the implicit target.\n//\n// In main thread, define a method and register it:\n//\n// var geometry = {\n// length: function(x, y) {\n// return Math.sqrt(x * x + y * y);\n// }\n// };\n//\n// WorkerBroker.addTarget('geometry', geometry);\n//\n// In worker thread):\n//\n// WorkerBroker.postMessage('geometry.length', 3, 4).then(function(d) {\n// console.log(d);\n// });\n//\n// -> prints 5\n//\n\nimport Thread from './thread';\nimport log from './log';\n\nvar WorkerBroker;\nexport default WorkerBroker = {};\n\n// Global list of all worker messages\n// Uniquely tracks every call made between main thread and a worker\nvar message_id = 0;\nvar messages = {};\n\n// Register an object to receive calls from other thread\nWorkerBroker.targets = {};\nWorkerBroker.addTarget = function (name, target) {\n WorkerBroker.targets[name] = target;\n};\n\nWorkerBroker.removeTarget = function (name) {\n if (name) {\n delete WorkerBroker.targets[name];\n }\n};\n\n// Given a dot-notation-style method name, e.g. 'Object.object.method',\n// find the object to call the method on from the list of registered targets\nfunction findTarget (method) {\n var chain = [];\n if (typeof method === 'string') {\n chain = method.split('.');\n method = chain.pop();\n }\n\n var target = WorkerBroker.targets;\n\n for (let m=0; m < chain.length; m++) {\n if (target[chain[m]]) {\n target = target[chain[m]];\n }\n else {\n return [];\n }\n }\n\n return [method, target];\n}\n\n// Main thread:\n// - Send messages to workers, and optionally receive an async response as a promise\n// - Receive messages from workers, and optionally send an async response back as a promise\nfunction setupMainThread () {\n\n // Send a message to a worker, and optionally get an async response\n // Arguments:\n // - worker: one or more web worker instances to send the message to (single value or array)\n // - method: the method with this name, specified with dot-notation, will be invoked in the worker\n // - message: spread of arguments to call the method with\n // Returns:\n // - a promise that will be fulfilled if the worker method returns a value (could be immediately, or async)\n //\n WorkerBroker.postMessage = function (worker, method, ...message) {\n // If more than one worker specified, post to multiple\n if (Array.isArray(worker)) {\n return Promise.all(\n worker.map(w => WorkerBroker.postMessage(w, method, ...message))\n );\n }\n\n // Parse options\n let options = {};\n if (typeof method === 'object') {\n options = method;\n method = method.method;\n }\n\n // Track state of this message\n var promise = new Promise((resolve, reject) => {\n messages[message_id] = { method, message, resolve, reject };\n });\n\n\n let payload, transferables = [];\n\n if (message && message.length === 1 && message[0] instanceof WorkerBroker.withTransferables) {\n transferables = message[0].transferables;\n message = message[0].value;\n }\n\n payload = {\n type: 'main_send', // mark message as method invocation from main thread\n message_id, // unique id for this message, for life of program\n method, // will dispatch to a function of this name within the worker\n message // message payload\n };\n\n if (options.stringify) {\n payload = JSON.stringify(payload);\n }\n\n worker.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method}' transferred ${transferables.length} objects to worker thread`);\n }\n\n message_id++;\n return promise;\n };\n\n // Add a worker to communicate with - each worker must be registered from the main thread\n WorkerBroker.addWorker = function (worker) {\n if (!(worker instanceof Worker)) {\n throw Error('Worker broker could not add non-Worker object', worker);\n }\n\n worker.addEventListener('message', function WorkerBrokerMainThreadHandler(event) {\n let data = ((typeof event.data === 'string') ? JSON.parse(event.data) : event.data);\n let id = data.message_id;\n\n // Listen for messages coming back from the worker, and fulfill that message's promise\n if (data.type === 'worker_reply') {\n // Pass the result to the promise\n if (messages[id]) {\n if (data.error) {\n messages[id].reject(data.error);\n }\n else {\n messages[id].resolve(data.message);\n }\n delete messages[id];\n }\n }\n // Listen for messages initiating a call from the worker, dispatch them,\n // and send any return value back to the worker\n // Unique id for this message & return call to main thread\n else if (data.type === 'worker_send' && id != null) {\n // Call the requested method and save the return value\n let result, error, target, method_name, method;\n try {\n [method_name, target] = findTarget(data.method);\n if (!target) {\n throw Error(`Worker broker could not dispatch message type ${data.method} on target ${data.target} because no object with that name is registered on main thread`);\n }\n\n method = (typeof target[method_name] === 'function') && target[method_name];\n if (!method) {\n throw Error(`Worker broker could not dispatch message type ${data.method} on target ${data.target} because object has no method with that name`);\n }\n\n result = method.apply(target, data.message);\n }\n catch(e) {\n // Thrown errors will be passed back (in string form) to worker\n error = e;\n\n }\n // Send return value to worker\n let payload, transferables = [];\n\n // Async result\n if (result instanceof Promise) {\n result.then((value) => {\n if (value instanceof WorkerBroker.withTransferables) {\n transferables = value.transferables;\n value = value.value[0];\n }\n\n payload = {\n type: 'main_reply',\n message_id: id,\n message: value\n };\n worker.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to worker thread`);\n }\n\n }, (error) => {\n worker.postMessage({\n type: 'main_reply',\n message_id: id,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n });\n });\n }\n // Immediate result\n else {\n if (result instanceof WorkerBroker.withTransferables) {\n transferables = result.transferables;\n result = result.value[0];\n }\n\n payload = {\n type: 'main_reply',\n message_id: id,\n message: result,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n };\n worker.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to worker thread`);\n }\n }\n }\n });\n\n };\n\n // Expose for debugging\n WorkerBroker.getMessages = function () {\n return messages;\n };\n\n WorkerBroker.getMessageId = function () {\n return message_id;\n };\n\n}\n\n// Worker threads:\n// - Receive messages from main thread, and optionally send an async response back as a promise\n// - Send messages to main thread, and optionally receive an async response as a promise\nfunction setupWorkerThread () {\n\n // Send a message to the main thread, and optionally get an async response as a promise\n // Arguments:\n // - method: the method with this name, specified with dot-notation, will be invoked on the main thread\n // - message: array of arguments to call the method with\n // Returns:\n // - a promise that will be fulfilled if the main thread method returns a value (could be immediately, or async)\n //\n WorkerBroker.postMessage = function (method, ...message) {\n // Parse options\n let options = {};\n if (typeof method === 'object') {\n options = method;\n method = method.method;\n }\n\n // Track state of this message\n var promise = new Promise((resolve, reject) => {\n messages[message_id] = { method, message, resolve, reject };\n });\n\n let payload, transferables = [];\n\n if (message && message.length === 1 && message[0] instanceof WorkerBroker.withTransferables) {\n transferables = message[0].transferables;\n message = message[0].value;\n }\n\n payload = {\n type: 'worker_send', // mark message as method invocation from worker\n message_id, // unique id for this message, for life of program\n method, // will dispatch to a method of this name on the main thread\n message // message payload\n };\n\n if (options.stringify) {\n payload = JSON.stringify(payload);\n }\n\n self.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method}' transferred ${transferables.length} objects to main thread`);\n }\n\n message_id++;\n return promise;\n };\n\n self.addEventListener('message', function WorkerBrokerWorkerThreadHandler(event) {\n let data = ((typeof event.data === 'string') ? JSON.parse(event.data) : event.data);\n let id = data.message_id;\n\n // Listen for messages coming back from the main thread, and fulfill that message's promise\n if (data.type === 'main_reply') {\n // Pass the result to the promise\n if (messages[id]) {\n if (data.error) {\n messages[id].reject(data.error);\n }\n else {\n messages[id].resolve(data.message);\n }\n delete messages[id];\n }\n }\n // Receive messages from main thread, dispatch them, and send back a reply\n // Unique id for this message & return call to main thread\n else if (data.type === 'main_send' && id != null) {\n // Call the requested worker method and save the return value\n let result, error, target, method_name, method;\n try {\n [method_name, target] = findTarget(data.method);\n if (!target) {\n throw Error(`Worker broker could not dispatch message type ${data.method} on target ${data.target} because no object with that name is registered on main thread`);\n }\n\n method = (typeof target[method_name] === 'function') && target[method_name];\n\n if (!method) {\n throw Error(`Worker broker could not dispatch message type ${data.method} because worker has no method with that name`);\n }\n\n result = method.apply(target, data.message);\n }\n catch(e) {\n // Thrown errors will be passed back (in string form) to main thread\n error = e;\n }\n\n // Send return value to main thread\n let payload, transferables = [];\n\n // Async result\n if (result instanceof Promise) {\n result.then((value) => {\n if (value instanceof WorkerBroker.withTransferables) {\n transferables = value.transferables;\n value = value.value[0];\n }\n\n payload = {\n type: 'worker_reply',\n message_id: id,\n message: value\n };\n self.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to main thread`);\n }\n }, (error) => {\n self.postMessage({\n type: 'worker_reply',\n message_id: id,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n });\n });\n }\n // Immediate result\n else {\n if (result instanceof WorkerBroker.withTransferables) {\n transferables = result.transferables;\n result = result.value[0];\n }\n\n payload = {\n type: 'worker_reply',\n message_id: id,\n message: result,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n };\n self.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to main thread`);\n }\n }\n }\n });\n\n}\n\n// Special value wrapper, to indicate that we want to find and include transferable objects in the message\nWorkerBroker.withTransferables = function (...value) {\n if (!(this instanceof WorkerBroker.withTransferables)) {\n return new WorkerBroker.withTransferables(...value);\n }\n\n this.value = value;\n this.transferables = findTransferables(this.value);\n};\n\n// Build a list of transferable objects from a source object\n// Returns a list of info about each transferable:\n// - object: the actual transferable object\n// - parent: the parent object that the transferable is a property of (if any)\n// - property: the property name of the transferable on the parent object (if any)\n// TODO: add option in case you DON'T want to transfer objects\nfunction findTransferables(source, parent = null, property = null, list = []) {\n if (!source) {\n return list;\n }\n\n if (Array.isArray(source)) {\n // Check each array element\n source.forEach((x, i) => findTransferables(x, source, i, list));\n }\n else if (typeof source === 'object') {\n // Is the object a transferable array buffer?\n if (source instanceof ArrayBuffer) {\n list.push({ object: source, parent, property });\n }\n // Or looks like a typed array (has an array buffer property)?\n else if (source.buffer instanceof ArrayBuffer) {\n list.push({ object: source.buffer, parent, property });\n }\n // Otherwise check each property\n else {\n for (let prop in source) {\n findTransferables(source[prop], source, prop, list);\n }\n }\n }\n return list;\n}\n\n// Remove neutered transferables from parent objects, as they should no longer be accessed after transfer\nfunction freeTransferables(transferables) {\n if (!Array.isArray(transferables)) {\n return;\n }\n transferables.filter(t => t.parent && t.property).forEach(t => delete t.parent[t.property]);\n}\n\n// Setup this thread as appropriate\nif (Thread.is_main) {\n setupMainThread();\n}\n\nif (Thread.is_worker) {\n setupWorkerThread();\n}\n","import version from './version';\nimport Thread from './thread';\nimport WorkerBroker from './worker_broker';\n\nconst LEVELS = {\n silent: -1,\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4\n};\n\nconst methods = {};\nlet logged_once = {};\n\nfunction methodForLevel (level) {\n if (Thread.is_main) {\n methods[level] = methods[level] || (console[level] ? console[level] : console.log).bind(console); // eslint-disable-line no-console\n return methods[level];\n }\n}\n\n// Logs message, proxying any log requests from worker threads back to the main thread.\n// Returns (asynchronously, due to proxying) a boolean indicating if the message was logged.\n// Option `once: true` can be used to only log each unique log message once (e.g. for warnings\n// that would otherwise be repetitive or possibly logged thousands of times, such as per feature).\nexport default function log (opts, ...msg) {\n let level = (typeof opts === 'object') ? opts.level : opts;\n if (LEVELS[level] <= LEVELS[log.level]) {\n if (Thread.is_worker) {\n // Proxy to main thread\n return WorkerBroker.postMessage({ method: '_logProxy', stringify: true }, opts, ...msg);\n }\n else {\n // Only log message once?\n if (typeof opts === 'object' && opts.once === true) {\n if (logged_once[JSON.stringify(msg)]) {\n return Promise.resolve(false);\n }\n logged_once[JSON.stringify(msg)] = true;\n }\n\n // Write to console (on main thread)\n let logger = methodForLevel(level);\n if (msg.length > 1) {\n logger(`Tangram ${version} [${level}]: ${msg[0]}`, ...msg.slice(1));\n }\n else {\n logger(`Tangram ${version} [${level}]: ${msg[0]}`);\n }\n }\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n}\n\nlog.level = 'info';\nlog.workers = null;\n\nlog.setLevel = function (level) {\n log.level = level;\n\n if (Thread.is_main && Array.isArray(log.workers)) {\n WorkerBroker.postMessage(log.workers, '_logSetLevelProxy', level);\n }\n};\n\nif (Thread.is_main) {\n log.setWorkers = function (workers) {\n log.workers = workers;\n };\n\n log.reset = function () {\n logged_once = {};\n };\n}\n\nWorkerBroker.addTarget('_logProxy', log); // proxy log messages from worker to main thread\nWorkerBroker.addTarget('_logSetLevelProxy', log.setLevel); // proxy log level setting from main to worker thread\n","// 21.2.5.3 get RegExp.prototype.flags()\nif (require('./_descriptors') && /./g.flags != 'g') require('./_object-dp').f(RegExp.prototype, 'flags', {\n configurable: true,\n get: require('./_flags')\n});\n","'use strict';\nrequire('./es6.regexp.flags');\nvar anObject = require('./_an-object');\nvar $flags = require('./_flags');\nvar DESCRIPTORS = require('./_descriptors');\nvar TO_STRING = 'toString';\nvar $toString = /./[TO_STRING];\n\nvar define = function (fn) {\n require('./_redefine')(RegExp.prototype, TO_STRING, fn, true);\n};\n\n// 21.2.5.14 RegExp.prototype.toString()\nif (require('./_fails')(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) {\n define(function toString() {\n var R = anObject(this);\n return '/'.concat(R.source, '/',\n 'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);\n });\n// FF44- RegExp#toString has a wrong name\n} else if ($toString.name != TO_STRING) {\n define(function toString() {\n return $toString.call(this);\n });\n}\n","// Miscellaneous geo functions\n\nvar Geo;\nexport default Geo = {};\n\n// Projection constants\nGeo.default_source_max_zoom = 18;\nGeo.default_view_max_zoom = 20;\nGeo.max_style_zoom = 25; // max zoom at which styles will be evaluated\nGeo.tile_size = 256;\nGeo.half_circumference_meters = 20037508.342789244;\nGeo.circumference_meters = Geo.half_circumference_meters * 2;\nGeo.min_zoom_meters_per_pixel = Geo.circumference_meters / Geo.tile_size; // min zoom draws world as 2 tiles wide\n\nlet meters_per_pixel = [];\nGeo.metersPerPixel = function (z) {\n meters_per_pixel[z] = meters_per_pixel[z] || Geo.min_zoom_meters_per_pixel / Math.pow(2, z);\n return meters_per_pixel[z];\n};\n\nlet meters_per_tile = [];\nGeo.metersPerTile = function (z) {\n meters_per_tile[z] = meters_per_tile[z] || Geo.circumference_meters / Math.pow(2, z);\n return meters_per_tile[z];\n};\n\n// Conversion functions based on an defined tile scale\nGeo.tile_scale = 4096; // coordinates are locally scaled to the range [0, tile_scale]\nGeo.units_per_pixel = Geo.tile_scale / Geo.tile_size;\nGeo.height_scale = 16; // provides sub-meter precision for height values (16ths of a meters)\n\nlet units_per_meter = [];\nGeo.unitsPerMeter = function (z) {\n units_per_meter[z] = units_per_meter[z] || Geo.tile_scale / (Geo.tile_size * Geo.metersPerPixel(z));\n return units_per_meter[z];\n};\n\n// Convert tile location to mercator meters - multiply by pixels per tile, then by meters per pixel, adjust for map origin\nGeo.metersForTile = function (tile) {\n return {\n x: tile.x * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters,\n y: -(tile.y * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters)\n };\n};\n\n/**\n Given a point in mercator meters and a zoom level, return the tile X/Y/Z that the point lies in\n*/\nGeo.tileForMeters = function ([x, y], zoom) {\n return {\n x: Math.floor((x + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))),\n y: Math.floor((-y + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))),\n z: zoom\n };\n};\n\n// Wrap a tile to positive #s for zoom\n// Optionally specify the axes to wrap\nGeo.wrapTile = function({ x, y, z }, mask = { x: true, y: false }) {\n var m = (1 << z) - 1;\n if (mask.x) {\n x = x & m;\n }\n if (mask.y) {\n y = y & m;\n }\n return { x, y, z };\n};\n\n/**\n Convert mercator meters to lat-lng\n*/\nGeo.metersToLatLng = function ([x, y]) {\n\n x /= Geo.half_circumference_meters;\n y /= Geo.half_circumference_meters;\n\n y = (2 * Math.atan(Math.exp(y * Math.PI)) - (Math.PI / 2)) / Math.PI;\n\n x *= 180;\n y *= 180;\n\n return [x, y];\n};\n\n/**\n Convert lat-lng to mercator meters\n*/\nGeo.latLngToMeters = function([x, y]) {\n\n // Latitude\n y = Math.log(Math.tan(y*Math.PI/360 + Math.PI/4)) / Math.PI;\n y *= Geo.half_circumference_meters;\n\n // Longitude\n x *= Geo.half_circumference_meters / 180;\n\n return [x, y];\n};\n\n// Transform from local tile coordinats to lat lng\nGeo.tileSpaceToLatlng = function (geometry, z, min) {\n const units_per_meter = Geo.unitsPerMeter(z);\n Geo.transformGeometry(geometry, coord => {\n coord[0] = (coord[0] / units_per_meter) + min.x;\n coord[1] = (coord[1] / units_per_meter) + min.y;\n\n let [x, y] = Geo.metersToLatLng(coord);\n coord[0] = x;\n coord[1] = y;\n });\n return geometry;\n};\n\n// Copy GeoJSON geometry\nGeo.copyGeometry = function (geometry) {\n if (geometry == null) {\n return; // skip if missing geometry (valid GeoJSON)\n }\n\n let copy = { type: geometry.type };\n\n if (geometry.type === 'Point') {\n copy.coordinates = [geometry.coordinates[0], geometry.coordinates[1]];\n }\n else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') {\n copy.coordinates = geometry.coordinates.map(c => [c[0], c[1]]);\n }\n else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') {\n copy.coordinates = geometry.coordinates.map(ring => ring.map(c => [c[0], c[1]]));\n }\n else if (geometry.type === 'MultiPolygon') {\n copy.coordinates = geometry.coordinates.map(polygon => {\n return polygon.map(ring => ring.map(c => [c[0], c[1]]));\n });\n }\n // TODO: support GeometryCollection\n return copy;\n};\n\n// Run an in-place transform function on each cooordinate in a GeoJSON geometry\nGeo.transformGeometry = function (geometry, transform) {\n if (geometry == null) {\n return; // skip if missing geometry (valid GeoJSON)\n }\n\n if (geometry.type === 'Point') {\n transform(geometry.coordinates);\n }\n else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') {\n geometry.coordinates.forEach(transform);\n }\n else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') {\n geometry.coordinates.forEach(ring => ring.forEach(transform));\n }\n else if (geometry.type === 'MultiPolygon') {\n geometry.coordinates.forEach(polygon => {\n polygon.forEach(ring => ring.forEach(transform));\n });\n }\n // TODO: support GeometryCollection\n};\n\nGeo.boxIntersect = function (b1, b2) {\n return !(\n b2.sw.x > b1.ne.x ||\n b2.ne.x < b1.sw.x ||\n b2.sw.y > b1.ne.y ||\n b2.ne.y < b1.sw.y\n );\n};\n\n// Finds the axis-aligned bounding box for a polygon\nGeo.findBoundingBox = function (polygon) {\n var min_x = Infinity,\n max_x = -Infinity,\n min_y = Infinity,\n max_y = -Infinity;\n\n // Only need to examine outer ring (polygon[0])\n var num_coords = polygon[0].length;\n for (var c=0; c < num_coords; c++) {\n var coord = polygon[0][c];\n\n if (coord[0] < min_x) {\n min_x = coord[0];\n }\n if (coord[1] < min_y) {\n min_y = coord[1];\n }\n if (coord[0] > max_x) {\n max_x = coord[0];\n }\n if (coord[1] > max_y) {\n max_y = coord[1];\n }\n }\n\n return [min_x, min_y, max_x, max_y];\n};\n\n// Convert geometry type to one of: 'point', 'line', 'polygon'\nGeo.geometryType = function(type) {\n if (type === 'Polygon' || type === 'MultiPolygon') {\n return 'polygon';\n }\n else if (type === 'LineString' || type === 'MultiLineString') {\n return 'line';\n }\n if (type === 'Point' || type === 'MultiPoint') {\n return 'point';\n }\n};\n\n// Geometric / weighted centroid of polygon\n// Adapted from https://github.com/Leaflet/Leaflet/blob/c10f405a112142b19785967ce0e142132a6095ad/src/layer/vector/Polygon.js#L57\nGeo.centroid = function (polygon, relative = true) {\n if (!polygon || polygon.length === 0) {\n return;\n }\n\n let x = 0, y = 0, area = 0;\n let ring = polygon[0]; // only use first ring for now\n let len = ring.length;\n\n // optionally calculate relative to first coordinate to avoid precision issues w/small polygons\n let origin;\n if (relative) {\n origin = ring[0];\n ring = ring.map(v => [v[0] - origin[0], v[1] - origin[1]]);\n }\n\n for (let i = 0, j = len - 1; i < len; j = i, i++) {\n let p0 = ring[i];\n let p1 = ring[j];\n let f = p0[1] * p1[0] - p1[1] * p0[0];\n\n x += (p0[0] + p1[0]) * f;\n y += (p0[1] + p1[1]) * f;\n area += f * 3;\n }\n\n if (!area) {\n return; // skip degenerate polygons\n }\n\n let c = [x / area, y / area];\n if (relative) {\n c[0] += origin[0];\n c[1] += origin[1];\n }\n return c;\n};\n\nGeo.multiCentroid = function (polygons) {\n let n = 0;\n let centroid = null;\n\n for (let p=0; p < polygons.length; p++) {\n let c = Geo.centroid(polygons[p]);\n if (c) { // skip degenerate polygons\n centroid = centroid || [0, 0];\n centroid[0] += c[0];\n centroid[1] += c[1];\n n++;\n }\n }\n\n if (n > 0) {\n centroid[0] /= n;\n centroid[1] /= n;\n }\n\n return centroid; // will return null if all polygons were degenerate\n};\n\nGeo.signedPolygonRingAreaSum = function (ring) {\n let area = 0;\n let n = ring.length;\n\n for (let i = 0; i < n - 1; i++) {\n let p0 = ring[i];\n let p1 = ring[i+1];\n\n area += p0[0] * p1[1] - p1[0] * p0[1];\n }\n\n area += ring[n - 1][0] * ring[0][1] - ring[0][0] * ring[n - 1][1];\n return area;\n};\n\nGeo.polygonRingArea = function (ring) {\n return Math.abs(Geo.signedPolygonRingAreaSum(ring)) / 2;\n};\n\n// TODO: subtract inner rings\nGeo.polygonArea = function (polygon) {\n if (!polygon) {\n return;\n }\n return Geo.polygonRingArea(polygon[0]);\n};\n\nGeo.multiPolygonArea = function (polygons) {\n let area = 0;\n\n for (let p=0; p < polygons.length; p++) {\n area += Geo.polygonArea(polygons[p]);\n }\n\n return area;\n};\n\nGeo.ringWinding = function (ring) {\n let area = Geo.signedPolygonRingAreaSum(ring);\n if (area > 0) {\n return 'CW';\n }\n else if (area < 0) {\n return 'CCW';\n }\n // return undefined on zero area polygon\n};\n","// Miscellaneous utilities\n/*jshint worker: true*/\n\nimport log from './log';\nimport Thread from './thread';\nimport WorkerBroker from './worker_broker';\nimport Geo from './geo';\n\nexport default Utils;\n\nconst Utils = {};\n\nWorkerBroker.addTarget('Utils', Utils);\n\n// Basic Safari detection\n// http://stackoverflow.com/questions/7944460/detect-safari-browser\nUtils.isSafari = function () {\n return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n};\n\n// Basic IE11 or Edge detection\nUtils.isMicrosoft = function () {\n return /(Trident\\/7.0|Edge[ /](\\d+[.\\d]+))/i.test(navigator.userAgent);\n};\n\nUtils._requests = {}; // XHR requests on current thread\nUtils._proxy_requests = {}; // XHR requests proxied to main thread\n\n// `request_key` is a user-provided key that can be later used to cancel the request\nUtils.io = function (url, timeout = 60000, responseType = 'text', method = 'GET', headers = {}, request_key = null, proxy = false) {\n if (Thread.is_worker && Utils.isMicrosoft()) {\n // Some versions of IE11 and Edge will hang web workers when performing XHR requests\n // These requests can be proxied through the main thread\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9545866/\n log('debug', 'Proxying request for URL to worker', url);\n\n if (request_key) {\n Utils._proxy_requests[request_key] = true; // mark as proxied\n }\n return WorkerBroker.postMessage('Utils.io', url, timeout, responseType, method, headers, request_key, true);\n }\n else {\n var request = new XMLHttpRequest();\n var promise = new Promise((resolve, reject) => {\n request.open(method, url, true);\n request.timeout = timeout;\n request.responseType = responseType;\n\n // Attach optional request headers\n if (headers && typeof headers === 'object') {\n for (let key in headers) {\n request.setRequestHeader(key, headers[key]);\n }\n }\n\n request.onload = () => {\n if (request.status === 200) {\n if (['text', 'json'].indexOf(request.responseType) > -1) {\n resolve(request.responseText);\n }\n else {\n resolve(request.response);\n }\n } else {\n reject(Error('Request error with a status of ' + request.statusText));\n }\n };\n request.onerror = (evt) => {\n reject(Error('There was a network error' + evt.toString()));\n };\n request.ontimeout = (evt) => {\n reject(Error('timeout '+ evt.toString()));\n };\n request.send();\n });\n\n promise = promise.then(response => {\n if (request_key) {\n delete Utils._requests[request_key];\n }\n\n if (proxy) {\n return WorkerBroker.withTransferables(response);\n }\n return response;\n });\n\n if (request_key) {\n Utils._requests[request_key] = request;\n }\n\n return promise;\n }\n};\n\n// Çancel a pending network request by user-provided request key\nUtils.cancelRequest = function (key) {\n // Check for a request that was proxied to the main thread\n if (Thread.is_worker && Utils._proxy_requests[key]) {\n return WorkerBroker.postMessage('Utils.cancelRequest', key); // forward to main thread\n }\n\n let req = Utils._requests[key];\n if (req) {\n log('trace', `Cancelling network request key '${key}'`);\n Utils._requests[key].abort();\n delete Utils._requests[key];\n }\n else {\n log('trace', `Could not find network request key '${key}'`);\n }\n};\n\n// Stringify an object into JSON, but convert functions to strings\nUtils.serializeWithFunctions = function (obj) {\n if (typeof obj === 'function') {\n return obj.toString();\n }\n\n let serialized = JSON.stringify(obj, function(k, v) {\n // Convert functions to strings\n if (typeof v === 'function') {\n return v.toString();\n }\n return v;\n });\n\n return serialized;\n};\n\n// Default to allowing high pixel density\n// Returns true if display density changed\nUtils.use_high_density_display = true;\nUtils.updateDevicePixelRatio = function () {\n let prev = Utils.device_pixel_ratio;\n Utils.device_pixel_ratio = (Utils.use_high_density_display && window.devicePixelRatio) || 1;\n return Utils.device_pixel_ratio !== prev;\n};\n\nif (Thread.is_main) {\n Utils.updateDevicePixelRatio();\n}\n\n// Used for differentiating between power-of-2 and non-power-of-2 textures\n// Via: http://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load\nUtils.isPowerOf2 = function(value) {\n return (value & (value - 1)) === 0;\n};\n\n// Interpolate 'x' along a series of control points\n// 'points' is an array of control points in the form [x, y]\n//\n// Example:\n// Control points:\n// [0, 5]: when x=0, y=5\n// [4, 10]: when x=4, y=10\n//\n// Utils.interpolate(2, [[0, 5], [4, 10]]);\n// -> computes x=2, halfway between x=0 and x=4: (10 - 5) / 2 +5\n// -> returns 7.5\n//\n// TODO: add other interpolation methods besides linear\n//\nUtils.interpolate = function(x, points, transform) {\n // If this doesn't resemble a list of control points, just return the original value\n if (!Array.isArray(points) || !Array.isArray(points[0])) {\n return points;\n }\n else if (points.length < 1) {\n return points;\n }\n\n var x1, x2, d, y, y1, y2;\n\n // Min bounds\n if (x <= points[0][0]) {\n y = points[0][1];\n if (typeof transform === 'function') {\n y = transform(y);\n }\n }\n // Max bounds\n else if (x >= points[points.length-1][0]) {\n y = points[points.length-1][1];\n if (typeof transform === 'function') {\n y = transform(y);\n }\n }\n // Find which control points x is between\n else {\n for (var i=0; i < points.length - 1; i++) {\n if (x >= points[i][0] && x < points[i+1][0]) {\n // Linear interpolation\n x1 = points[i][0];\n x2 = points[i+1][0];\n\n // Multiple values\n if (Array.isArray(points[i][1])) {\n y = [];\n for (var c=0; c < points[i][1].length; c++) {\n if (typeof transform === 'function') {\n y1 = transform(points[i][1][c]);\n y2 = transform(points[i+1][1][c]);\n d = y2 - y1;\n y[c] = d * (x - x1) / (x2 - x1) + y1;\n }\n else {\n d = points[i+1][1][c] - points[i][1][c];\n y[c] = d * (x - x1) / (x2 - x1) + points[i][1][c];\n }\n }\n }\n // Single value\n else {\n if (typeof transform === 'function') {\n y1 = transform(points[i][1]);\n y2 = transform(points[i+1][1]);\n d = y2 - y1;\n y = d * (x - x1) / (x2 - x1) + y1;\n }\n else {\n d = points[i+1][1] - points[i][1];\n y = d * (x - x1) / (x2 - x1) + points[i][1];\n }\n }\n break;\n }\n }\n }\n return y;\n};\n\nUtils.toCSSColor = function (color) {\n if (color[3] === 1) { // full opacity\n return `rgb(${color.slice(0, 3).map(c => Math.round(c * 255)).join(', ')})`;\n }\n // RGB is between [0, 255] opacity is between [0, 1]\n return `rgba(${color.map((c, i) => (i < 3 && Math.round(c * 255)) || c).join(', ')})`;\n};\n\nUtils.pointInTile = function (point) {\n return point[0] >= 0 && point[1] > -Geo.tile_scale && point[0] < Geo.tile_scale && point[1] <= 0;\n};\n","let debugSettings;\n\nexport default debugSettings = {\n // draws a blue rectangle border around the collision box of a label\n draw_label_collision_boxes: false,\n\n // draws a green rectangle border within the texture box of a label\n draw_label_texture_boxes: false,\n\n // suppreses fade-in of labels\n suppress_label_fade_in: false,\n\n // suppress animaton of label snap to pixel grid\n suppress_label_snap_animation: false,\n\n // show hidden labels for debugging\n show_hidden_labels: false,\n\n // collect feature/geometry stats on styling layers\n layer_stats: false\n};\n\nexport function mergeDebugSettings (settings) {\n Object.assign(debugSettings, settings);\n}\n","var pIE = require('./_object-pie');\nvar createDesc = require('./_property-desc');\nvar toIObject = require('./_to-iobject');\nvar toPrimitive = require('./_to-primitive');\nvar has = require('./_has');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {\n O = toIObject(O);\n P = toPrimitive(P, true);\n if (IE8_DOM_DEFINE) try {\n return gOPD(O, P);\n } catch (e) { /* empty */ }\n if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);\n};\n","// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar isObject = require('./_is-object');\nvar anObject = require('./_an-object');\nvar check = function (O, proto) {\n anObject(O);\n if (!isObject(proto) && proto !== null) throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n function (test, buggy, set) {\n try {\n set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);\n set(test, []);\n buggy = !(test instanceof Array);\n } catch (e) { buggy = true; }\n return function setPrototypeOf(O, proto) {\n check(O, proto);\n if (buggy) O.__proto__ = proto;\n else set(O, proto);\n return O;\n };\n }({}, false) : undefined),\n check: check\n};\n","var isObject = require('./_is-object');\nvar setPrototypeOf = require('./_set-proto').set;\nmodule.exports = function (that, target, C) {\n var S = target.constructor;\n var P;\n if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {\n setPrototypeOf(that, P);\n } return that;\n};\n","// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = require('./_object-keys-internal');\nvar hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return $keys(O, hiddenKeys);\n};\n","var global = require('./_global');\nvar inheritIfRequired = require('./_inherit-if-required');\nvar dP = require('./_object-dp').f;\nvar gOPN = require('./_object-gopn').f;\nvar isRegExp = require('./_is-regexp');\nvar $flags = require('./_flags');\nvar $RegExp = global.RegExp;\nvar Base = $RegExp;\nvar proto = $RegExp.prototype;\nvar re1 = /a/g;\nvar re2 = /a/g;\n// \"new\" creates a new object, old webkit buggy here\nvar CORRECT_NEW = new $RegExp(re1) !== re1;\n\nif (require('./_descriptors') && (!CORRECT_NEW || require('./_fails')(function () {\n re2[require('./_wks')('match')] = false;\n // RegExp constructor can alter flags and IsRegExp works correct with @@match\n return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';\n}))) {\n $RegExp = function RegExp(p, f) {\n var tiRE = this instanceof $RegExp;\n var piRE = isRegExp(p);\n var fiU = f === undefined;\n return !tiRE && piRE && p.constructor === $RegExp && fiU ? p\n : inheritIfRequired(CORRECT_NEW\n ? new Base(piRE && !fiU ? p.source : p, f)\n : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)\n , tiRE ? this : proto, $RegExp);\n };\n var proxy = function (key) {\n key in $RegExp || dP($RegExp, key, {\n configurable: true,\n get: function () { return Base[key]; },\n set: function (it) { Base[key] = it; }\n });\n };\n for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]);\n proto.constructor = $RegExp;\n $RegExp.prototype = proto;\n require('./_redefine')(global, 'RegExp', $RegExp);\n}\n\nrequire('./_set-species')('RegExp');\n","// 7.2.9 SameValue(x, y)\nmodule.exports = Object.is || function is(x, y) {\n // eslint-disable-next-line no-self-compare\n return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n","'use strict';\n\nvar anObject = require('./_an-object');\nvar sameValue = require('./_same-value');\nvar regExpExec = require('./_regexp-exec-abstract');\n\n// @@search logic\nrequire('./_fix-re-wks')('search', 1, function (defined, SEARCH, $search, maybeCallNative) {\n return [\n // `String.prototype.search` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.search\n function search(regexp) {\n var O = defined(this);\n var fn = regexp == undefined ? undefined : regexp[SEARCH];\n return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n },\n // `RegExp.prototype[@@search]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search\n function (regexp) {\n var res = maybeCallNative($search, regexp, this);\n if (res.done) return res.value;\n var rx = anObject(regexp);\n var S = String(this);\n var previousLastIndex = rx.lastIndex;\n if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;\n var result = regExpExec(rx, S);\n if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;\n return result === null ? -1 : result.index;\n }\n ];\n});\n","import log from './log';\n\n// Adds a base origin to relative URLs\nexport function addBaseURL (url, base) {\n if (!url || !isRelativeURL(url)) {\n return url;\n }\n\n var relative_path = (url[0] !== '/');\n var base_info;\n if (base) {\n base_info = document.createElement('a'); // use a temporary element to parse URL\n base_info.href = base;\n }\n else {\n base_info = window.location;\n }\n\n if (relative_path) {\n let path = pathForURL(base_info.href);\n url = path + url;\n }\n else {\n let origin = base_info.origin;\n if (!origin) {\n origin = base_info.protocol + '//' + base_info.host; // IE11 doesn't have origin property\n }\n url = origin + url;\n }\n\n return url;\n}\n\nexport function pathForURL (url) {\n if (typeof url === 'string' && url.search(/^(data|blob):/) === -1) {\n let qs = url.indexOf('?');\n if (qs > -1) {\n url = url.substr(0, qs);\n }\n\n let hash = url.indexOf('#');\n if (hash > -1) {\n url = url.substr(0, hash);\n }\n\n return url.substr(0, url.lastIndexOf('/') + 1) || '';\n }\n return '';\n}\n\nexport function extensionForURL (url) {\n url = url.split('/').pop();\n let last_dot = url.lastIndexOf('.');\n if (last_dot > -1) {\n return url.substring(last_dot + 1);\n }\n}\n\nexport function isLocalURL (url) {\n if (typeof url !== 'string') {\n return;\n }\n return (url.search(/^(data|blob):/) > -1);\n}\n\nexport function isRelativeURL (url) {\n if (typeof url !== 'string') {\n return;\n }\n return !(url.search(/^(http|https|data|blob):/) > -1 || url.substr(0, 2) === '//');\n}\n\n// Resolves './' and '../' components from relative path, to get a \"flattened\" path\nexport function flattenRelativeURL (url) {\n let dirs = (url || '').split('/');\n for (let d = 1; d < dirs.length; d++) {\n if (dirs[d] === '.') {\n dirs.splice(d, 1);\n d--;\n }\n else if (dirs[d] === '..') {\n d = d + 0;\n dirs.splice(d-1, 2);\n d--;\n }\n }\n return dirs.join('/');\n}\n\n// Add a set of query string params to a URL\n// params: hash of key/value pairs of query string parameters\n// returns array of: [modified URL, array of duplicate param name and values]\nexport function addParamsToURL (url, params) {\n if (!params || Object.keys(params).length === 0) {\n return [url, []];\n }\n\n var qs_index = url.indexOf('?');\n var hash_index = url.indexOf('#');\n\n // Save and trim hash\n var hash = '';\n if (hash_index > -1) {\n hash = url.slice(hash_index);\n url = url.slice(0, hash_index);\n }\n\n // Start query string\n if (qs_index === -1) {\n qs_index = url.length;\n url += '?';\n }\n qs_index++; // advanced past '?'\n\n // Build query string params\n var url_params = '';\n var dupes = [];\n for (var p in params) {\n if (getURLParameter(p, url) !== '') {\n dupes.push([p, params[p]]);\n continue;\n }\n url_params += `${p}=${params[p]}&`;\n }\n\n // Insert new query string params and restore hash\n url = url.slice(0, qs_index) + url_params + url.slice(qs_index) + hash;\n\n return [url, dupes];\n}\n\n// Polyfill (for Safari compatibility)\nlet _createObjectURL;\nexport function createObjectURL (url) {\n if (_createObjectURL === undefined) {\n _createObjectURL = (window.URL && window.URL.createObjectURL) || (window.webkitURL && window.webkitURL.createObjectURL);\n\n if (typeof _createObjectURL !== 'function') {\n _createObjectURL = null;\n log('warn', 'window.URL.createObjectURL (or vendor prefix) not found, unable to create local blob URLs');\n }\n }\n\n if (_createObjectURL) {\n return _createObjectURL(url);\n }\n else {\n return url;\n }\n}\n\nlet _revokeObjectURL;\nexport function revokeObjectURL (url) {\n if (_revokeObjectURL === undefined) {\n _revokeObjectURL = (window.URL && window.URL.revokeObjectURL) || (window.webkitURL && window.webkitURL.revokeObjectURL);\n\n if (typeof _revokeObjectURL !== 'function') {\n _revokeObjectURL = null;\n log('warn', 'window.URL.revokeObjectURL (or vendor prefix) not found, unable to create local blob URLs');\n }\n }\n\n if (_revokeObjectURL) {\n return _revokeObjectURL(url);\n }\n else {\n return url;\n }\n}\n\n// Get URL that the current script was loaded from\n// If currentScript is not available, loops through