{"version":3,"file":"tangram.debug.js","sources":["../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","../src/utils/thread.js","../node_modules/@babel/runtime/helpers/esm/typeof.js","../node_modules/@babel/runtime/helpers/esm/toPrimitive.js","../node_modules/@babel/runtime/helpers/esm/toPropertyKey.js","../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","../node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","../node_modules/@babel/runtime/helpers/esm/createClass.js","../src/utils/version.js","../node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js","../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/construct.js","../src/utils/worker_broker.js","../src/utils/log.js","../src/utils/utils.js","../src/utils/debug_settings.js","../src/utils/urls.js","../src/utils/task.js","../src/utils/subscribe.js","../src/utils/slice.js","../src/gl/texture.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","../src/utils/merge.js","../src/utils/geo.js","../src/utils/functions.js","../node_modules/csscolorparser/csscolorparser.js","../src/styles/style_parser.js","../src/selection/selection.js","../src/gl/constants.js","../src/gl/vbo_mesh.js","../src/lights/material.js","../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/superPropBase.js","../node_modules/@babel/runtime/helpers/esm/get.js","../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","../node_modules/@babel/runtime/helpers/esm/inherits.js","../src/utils/vector.js","../src/lights/light.js","../node_modules/@babel/runtime/helpers/esm/isNativeFunction.js","../node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js","../src/utils/errors.js","../src/sources/data_source.js","../src/tile/tile_id.js","../src/sources/raster.js","../src/builders/wireframe.js","../src/styles/style.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","../node_modules/quickselect/index.js","../src/builders/polygons.js","../src/styles/polygons/polygons.js","../src/builders/polylines.js","../src/styles/lines/dasharray.js","../src/styles/lines/lines.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_grid.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/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","../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/clip.js","../node_modules/geojson-vt/src/wrap.js","../node_modules/geojson-vt/src/transform.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","../src/utils/props.js","../src/scene/globals.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/process-es6/browser.js","../node_modules/jszip/dist/jszip.min.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/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","../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.mjs"],"sourcesContent":["function _arrayWithHoles(r) {\n if (Array.isArray(r)) return r;\n}\nexport { _arrayWithHoles as default };","function _iterableToArrayLimit(r, l) {\n var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"];\n if (null != t) {\n var e,\n n,\n i,\n u,\n a = [],\n f = !0,\n o = !1;\n try {\n if (i = (t = t.call(r)).next, 0 === l) {\n if (Object(t) !== t) return;\n f = !1;\n } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);\n } catch (r) {\n o = !0, n = r;\n } finally {\n try {\n if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return;\n } finally {\n if (o) throw n;\n }\n }\n return a;\n }\n}\nexport { _iterableToArrayLimit as default };","function _arrayLikeToArray(r, a) {\n (null == a || a > r.length) && (a = r.length);\n for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];\n return n;\n}\nexport { _arrayLikeToArray as default };","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nfunction _unsupportedIterableToArray(r, a) {\n if (r) {\n if (\"string\" == typeof r) return arrayLikeToArray(r, a);\n var t = {}.toString.call(r).slice(8, -1);\n return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? arrayLikeToArray(r, a) : void 0;\n }\n}\nexport { _unsupportedIterableToArray as default };","function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\nexport { _nonIterableRest as default };","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nfunction _slicedToArray(r, e) {\n return arrayWithHoles(r) || iterableToArrayLimit(r, e) || unsupportedIterableToArray(r, e) || nonIterableRest();\n}\nexport { _slicedToArray as default };","/*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","function _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\n}\nexport { _typeof as default };","import _typeof from \"./typeof.js\";\nfunction toPrimitive(t, r) {\n if (\"object\" != _typeof(t) || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != _typeof(i)) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\nexport { toPrimitive as default };","import _typeof from \"./typeof.js\";\nimport toPrimitive from \"./toPrimitive.js\";\nfunction toPropertyKey(t) {\n var i = toPrimitive(t, \"string\");\n return \"symbol\" == _typeof(i) ? i : i + \"\";\n}\nexport { toPropertyKey as default };","import toPropertyKey from \"./toPropertyKey.js\";\nfunction _defineProperty(e, r, t) {\n return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {\n value: t,\n enumerable: !0,\n configurable: !0,\n writable: !0\n }) : e[r] = t, e;\n}\nexport { _defineProperty as default };","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nfunction _arrayWithoutHoles(r) {\n if (Array.isArray(r)) return arrayLikeToArray(r);\n}\nexport { _arrayWithoutHoles as default };","function _iterableToArray(r) {\n if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r);\n}\nexport { _iterableToArray as default };","function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\nexport { _nonIterableSpread as default };","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nfunction _toConsumableArray(r) {\n return arrayWithoutHoles(r) || iterableToArray(r) || unsupportedIterableToArray(r) || nonIterableSpread();\n}\nexport { _toConsumableArray as default };","function _classCallCheck(a, n) {\n if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\");\n}\nexport { _classCallCheck as default };","import toPropertyKey from \"./toPropertyKey.js\";\nfunction _defineProperties(e, r) {\n for (var t = 0; t < r.length; t++) {\n var o = r[t];\n o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, toPropertyKey(o.key), o);\n }\n}\nfunction _createClass(e, r, t) {\n return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", {\n writable: !1\n }), e;\n}\nexport { _createClass as default };","import {version} from '../../package.json';\n\nexport default 'v' + version;\n","function _isNativeReflectConstruct() {\n try {\n var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n } catch (t) {}\n return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {\n return !!t;\n })();\n}\nexport { _isNativeReflectConstruct as default };","function _setPrototypeOf(t, e) {\n return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {\n return t.__proto__ = e, t;\n }, _setPrototypeOf(t, e);\n}\nexport { _setPrototypeOf as default };","import isNativeReflectConstruct from \"./isNativeReflectConstruct.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nfunction _construct(t, e, r) {\n if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);\n var o = [null];\n o.push.apply(o, e);\n var p = new (t.bind.apply(t, o))();\n return r && setPrototypeOf(p, r.prototype), p;\n}\nexport { _construct as default };","/*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","// Miscellaneous utilities\n/*jshint worker: true*/\n\nimport log from './log';\nimport Thread from './thread';\nimport WorkerBroker from './worker_broker';\n\nconst Utils = {};\n\nexport default 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({ body: request.responseText, status: request.status });\n }\n else {\n resolve({ body: request.response, status: request.status });\n }\n }\n else if (request.status === 204) { // No Content\n resolve({ body: null, status: request.status });\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 != null) {\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};\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 // draw scene in wireframe mode\n wireframe: false\n};\n\nexport function mergeDebugSettings (settings) {\n Object.assign(debugSettings, settings);\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