From 4306d6ab2963afca307c81a39ac95d105d2e96c1 Mon Sep 17 00:00:00 2001 From: Brett Camper Date: Fri, 3 Jan 2020 22:07:16 -0800 Subject: [PATCH] v0.20.0 --- dist/tangram.debug.js | 328 +++++++++++++++++++++++++----------- dist/tangram.debug.js.map | 2 +- dist/tangram.debug.mjs | 333 ++++++++++++++++++++++++++----------- dist/tangram.debug.mjs.map | 2 +- dist/tangram.min.js | 6 +- dist/tangram.min.mjs | 6 +- package.json | 2 +- 7 files changed, 475 insertions(+), 204 deletions(-) diff --git a/dist/tangram.debug.js b/dist/tangram.debug.js index d4d64f869..129cdb67b 100644 --- a/dist/tangram.debug.js +++ b/dist/tangram.debug.js @@ -1914,7 +1914,7 @@ function _wrapNativeSuper(Class) { return _wrapNativeSuper(Class); } -var version = "0.19.1"; +var version = "0.20.0"; var version$1 = 'v' + version; @@ -7957,6 +7957,19 @@ FeatureSelection.map_prefix = 0; // set by worker to worker id # FeatureSelection.defaultColor = [0, 0, 0, 1]; +// WebGL constants - need to import these separately to make them available in the web worker +var gl; +var gl$1 = gl = {}; +/* DataType */ + +gl.BYTE = 0x1400; +gl.UNSIGNED_BYTE = 0x1401; +gl.SHORT = 0x1402; +gl.UNSIGNED_SHORT = 0x1403; +gl.INT = 0x1404; +gl.UNSIGNED_INT = 0x1405; +gl.FLOAT = 0x1406; + _typedArray('Uint16', 2, function (init) { return function Uint16Array(data, byteOffset, length) { return init(this, data, byteOffset, length); @@ -10002,6 +10015,10 @@ var Style = { this.tile_data = {}; this.stencil_proxy_tiles = true; // applied to proxy tiles w/non-opaque blend mode to avoid compounding alpha + + this.variants = {}; // mesh variants by variant key + + this.vertex_layouts = {}; // vertex layouts by variant key // 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 @@ -10036,7 +10053,9 @@ var Style = { Light.setMode(this.lighting, this); // Setup raster samplers if needed - this.setupRasters(); + this.setupRasters(); // Setup shader definitions for custom attributes + + this.setupCustomAttributes(); this.initialized = true; }, destroy: function destroy() { @@ -10249,6 +10268,19 @@ var Style = { if (!style) { return; // skip feature + } // Custom attributes + + + if (this.shaders.attributes) { + style.attributes = style.attributes || {}; + + for (var aname in this.shaders.attributes) { + style.attributes[aname] = StyleParser.evalCachedProperty(draw.attributes && draw.attributes[aname], context); // set attribute value to zero for null/undefined/non-numeric values + + if (typeof style.attributes[aname] !== 'number') { + style.attributes[aname] = 0; + } + } } // Feature selection (only if feature is marked as interactive, and style supports it) @@ -10262,8 +10294,10 @@ var Style = { style.selection_color = FeatureSelection.makeColor(feature, context.tile, context); } else { style.selection_color = FeatureSelection.defaultColor; - } + } // Subclass implementation + + style = this._parseFeature(feature, draw, context); return style; } catch (error) { log('error', 'Style.parseFeature: style parsing error', feature, style, error.stack); @@ -10303,6 +10337,15 @@ var Style = { if (!draw) { return; + } // Custom attributes + + + if (this.shaders.attributes) { + draw.attributes = draw.attributes || {}; + + for (var aname in this.shaders.attributes) { + draw.attributes[aname] = StyleParser.createPropertyCache(draw.attributes[aname] != null ? draw.attributes[aname] : 0); + } } draw.preprocessed = true; @@ -10383,6 +10426,7 @@ var Style = { program.compile(); } catch (e) { log('error', "Style: error compiling program for style '" + this.name + "' (program key '" + key + "')", this, e.stack, e.type, e.shader_errors); + throw e; // re-throw so users can be notified via event subscriptions } } @@ -10709,6 +10753,60 @@ var Style = { }.bind(this), $error); }.bind(this)); }, + // Setup shader definitions for custom attributes + setupCustomAttributes: function setupCustomAttributes() { + if (this.shaders.attributes) { + var _arr = Object.entries(this.shaders.attributes); + + for (var _i = 0; _i < _arr.length; _i++) { + var _arr$_i = _arr[_i], + aname = _arr$_i[0], + attrib = _arr$_i[1]; + + // alias each custom attribute to the internal attribute name in vertex shader, + // and internal varying name in fragment shader (if varying is enabled) + if (attrib.type === 'float') { + if (attrib.varying !== false) { + this.addShaderBlock('attributes', "\n #ifdef TANGRAM_VERTEX_SHADER\n attribute float a_" + aname + ";\n varying float v_" + aname + ";\n #define " + aname + " a_" + aname + "\n #else\n varying float v_" + aname + ";\n #define " + aname + " v_" + aname + "\n #endif\n "); + this.addShaderBlock('setup', "#ifdef TANGRAM_VERTEX_SHADER\nv_" + aname + " = a_" + aname + ";\n#endif"); + } else { + this.addShaderBlock('attributes', "\n #ifdef TANGRAM_VERTEX_SHADER\n attribute float a_" + aname + ";\n #define " + aname + " a_" + aname + "\n #endif\n "); + } + } + } + } + }, + // Add custom attributes to a list of attributes for initializing a vertex layout + addCustomAttributesToAttributeList: function addCustomAttributesToAttributeList(attribs) { + if (this.shaders.attributes) { + var _arr2 = Object.entries(this.shaders.attributes); + + for (var _i2 = 0; _i2 < _arr2.length; _i2++) { + var _arr2$_i = _arr2[_i2], + aname = _arr2$_i[0], + attrib = _arr2$_i[1]; + + if (attrib.type === 'float') { + attribs.push({ + name: "a_" + aname, + size: 1, + type: gl$1.FLOAT, + normalized: false + }); + } + } + } + + return attribs; + }, + // Add current feature values for custom attributes to vertex template + addCustomAttributesToVertexTemplate: function addCustomAttributesToVertexTemplate(draw, index) { + if (this.shaders.attributes) { + for (var aname in this.shaders.attributes) { + this.vertex_template[index++] = draw.attributes[aname] != null ? draw.attributes[aname] : 0; + } + } + }, // Setup any GL state for rendering setup: function setup() { this.setUniforms(); @@ -10790,19 +10888,6 @@ function addLayerDebugEntry(target, layer, faeture_count, geom_count, styles, ba } } -// WebGL constants - need to import these separately to make them available in the web worker -var gl; -var gl$1 = gl = {}; -/* DataType */ - -gl.BYTE = 0x1400; -gl.UNSIGNED_BYTE = 0x1401; -gl.SHORT = 0x1402; -gl.UNSIGNED_SHORT = 0x1403; -gl.INT = 0x1404; -gl.UNSIGNED_INT = 0x1405; -gl.FLOAT = 0x1406; - _typedArray('Int16', 2, function (init) { return function Int16Array(data, byteOffset, length) { return init(this, data, byteOffset, length); @@ -12029,15 +12114,11 @@ 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_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_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: attributes\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 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 #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"; +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: attributes\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 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 #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"; var Polygons = Object.create(Style); -Polygons.variants = {}; // mesh variants by variant key - -Polygons.vertex_layouts = {}; // vertex layouts by variant key - Object.assign(Polygons, { name: 'polygons', built_in: true, @@ -12059,6 +12140,8 @@ Object.assign(Polygons, { return null; } + style.alpha = StyleParser.evalCachedProperty(draw.alpha, context); // optional alpha override + style.variant = draw.variant; // pre-calculated mesh variant style.z = StyleParser.evalCachedDistanceProperty(draw.z, context) || StyleParser.defaults.z; @@ -12092,6 +12175,7 @@ Object.assign(Polygons, { }, _preprocess: function _preprocess(draw) { draw.color = StyleParser.createColorPropertyCache(draw.color); + draw.alpha = StyleParser.createPropertyCache(draw.alpha); draw.z = StyleParser.createPropertyCache(draw.z, StyleParser.parseUnits); this.computeVariant(draw); return draw; @@ -12109,8 +12193,8 @@ Object.assign(Polygons, { var key = [selection, normal, texcoords, blend_order].join('/'); draw.variant = key; - if (Polygons.variants[key] == null) { - Polygons.variants[key] = { + if (this.variants[key] == null) { + this.variants[key] = { key: key, blend_order: blend_order, mesh_order: 0, @@ -12123,7 +12207,7 @@ Object.assign(Polygons, { // Override // Create or return desired vertex layout permutation based on flags vertexLayoutForMeshVariant: function vertexLayoutForMeshVariant(variant) { - if (Polygons.vertex_layouts[variant.key] == null) { + if (this.vertex_layouts[variant.key] == null) { // Attributes for this mesh variant // Optional attributes have placeholder values assigned with `static` parameter var attribs = [{ @@ -12156,10 +12240,11 @@ Object.assign(Polygons, { normalized: true, static: variant.texcoords ? null : [0, 0] }]; - Polygons.vertex_layouts[variant.key] = new VertexLayout(attribs); + this.addCustomAttributesToAttributeList(attribs); + this.vertex_layouts[variant.key] = new VertexLayout(attribs); } - return Polygons.vertex_layouts[variant.key]; + return this.vertex_layouts[variant.key]; }, // Override meshVariantTypeForDraw: function meshVariantTypeForDraw(draw) { @@ -12190,7 +12275,7 @@ Object.assign(Polygons, { this.vertex_template[i++] = style.color[0] * 255; this.vertex_template[i++] = style.color[1] * 255; this.vertex_template[i++] = style.color[2] * 255; - this.vertex_template[i++] = style.color[3] * 255; // a_selection_color.rgba - selection color + this.vertex_template[i++] = (style.alpha != null ? style.alpha : style.color[3]) * 255; // a_selection_color.rgba - selection color if (mesh.variant.selection) { this.vertex_template[i++] = style.selection_color[0] * 255; @@ -12205,6 +12290,7 @@ Object.assign(Polygons, { this.vertex_template[i++] = 0; } + this.addCustomAttributesToVertexTemplate(style, i); return this.vertex_template; }, buildPolygons: function buildPolygons$1(polygons, style, context) { @@ -12926,10 +13012,6 @@ function renderDashArray(pattern, options) { } var Lines = Object.create(Style); -Lines.variants = {}; // mesh variants by variant key - -Lines.vertex_layouts = {}; // vertex layouts by variant key - var DASH_SCALE = 20; // adjustment factor for UV scale to for line dash patterns w/fractional pixel width Object.assign(Lines, { @@ -13073,6 +13155,8 @@ Object.assign(Lines, { return; } + style.alpha = StyleParser.evalCachedProperty(draw.alpha, context); // optional alpha override + style.variant = draw.variant; // pre-calculated mesh variant // height defaults to feature height, but extrude style can dynamically adjust height by returning a number or array (instead of a boolean) @@ -13128,9 +13212,9 @@ Object.assign(Lines, { style.outline.inline_texcoord_width = style.texcoord_width; // Offset is directly copied from fill to outline, no need to re-calculate it style.outline.offset_precalc = style.offset; - style.outline.offset_scale_precalc = style.offset_scale; // Inherited properties - + style.outline.offset_scale_precalc = style.offset_scale; style.outline.color = draw.outline.color; + style.outline.alpha = draw.outline.alpha; style.outline.interactive = draw.outline.interactive; style.outline.cap = draw.outline.cap; style.outline.join = draw.outline.join; @@ -13164,6 +13248,7 @@ Object.assign(Lines, { }, _preprocess: function _preprocess(draw) { draw.color = StyleParser.createColorPropertyCache(draw.color); + draw.alpha = StyleParser.createPropertyCache(draw.alpha); draw.width = StyleParser.createPropertyCache(draw.width, StyleParser.parseUnits); if (draw.width && draw.width.type !== StyleParser.CACHE_TYPE.STATIC) { @@ -13190,6 +13275,7 @@ Object.assign(Lines, { draw.outline.style = draw.outline.style || this.name; draw.outline.color = StyleParser.createColorPropertyCache(draw.outline.color); + draw.outline.alpha = StyleParser.createPropertyCache(draw.outline.alpha); draw.outline.width = StyleParser.createPropertyCache(draw.outline.width, StyleParser.parseUnits); draw.outline.next_width = StyleParser.createPropertyCache(draw.outline.width, StyleParser.parseUnits); // width re-computed for next zoom @@ -13235,7 +13321,7 @@ Object.assign(Lines, { draw.outline.blend_order = draw.blend_order; } - this.computeVariant(draw.outline, outline_style); + outline_style.computeVariant(draw.outline); } else { log({ level: 'warn', @@ -13420,11 +13506,7 @@ Object.assign(Lines, { }.bind(this)); }, // Calculate and store mesh variant (unique by draw group but not feature) - computeVariant: function computeVariant(draw, style) { - if (style === void 0) { - style = this; - } - + computeVariant: function computeVariant(draw) { // Factors that determine a unique mesh rendering variant var key = draw.offset ? 1 : 0; // whether feature has a line offset @@ -13450,14 +13532,14 @@ Object.assign(Lines, { key += draw.texture_merged; } - var blend_order = style.getBlendOrderForDraw(draw); + var blend_order = this.getBlendOrderForDraw(draw); key += '/' + blend_order; // Create unique key key = hashString(key); draw.variant = key; - if (Lines.variants[key] == null) { - Lines.variants[key] = { + if (this.variants[key] == null) { + this.variants[key] = { key: key, blend_order: blend_order, mesh_order: draw.is_outline ? 0 : 1, @@ -13476,7 +13558,7 @@ Object.assign(Lines, { // Override // Create or return desired vertex layout permutation based on flags vertexLayoutForMeshVariant: function vertexLayoutForMeshVariant(variant) { - if (Lines.vertex_layouts[variant.key] == null) { + if (this.vertex_layouts[variant.key] == null) { // Attributes for this mesh variant // Optional attributes have placeholder values assigned with `static` parameter var attribs = [{ @@ -13519,14 +13601,15 @@ Object.assign(Lines, { normalized: true, static: variant.selection ? null : [0, 0, 0, 0] }]; - Lines.vertex_layouts[variant.key] = new VertexLayout(attribs); + this.addCustomAttributesToAttributeList(attribs); + this.vertex_layouts[variant.key] = new VertexLayout(attribs); } - return Lines.vertex_layouts[variant.key]; + return this.vertex_layouts[variant.key]; }, // Override meshVariantTypeForDraw: function meshVariantTypeForDraw(draw) { - return Lines.variants[draw.variant]; // return pre-calculated mesh variant + return this.variants[draw.variant]; // return pre-calculated mesh variant }, /** @@ -13569,7 +13652,7 @@ Object.assign(Lines, { this.vertex_template[i++] = style.color[0] * 255; this.vertex_template[i++] = style.color[1] * 255; this.vertex_template[i++] = style.color[2] * 255; - this.vertex_template[i++] = style.color[3] * 255; // a_selection_color.rgba - selection color + this.vertex_template[i++] = (style.alpha != null ? style.alpha : style.color[3]) * 255; // a_selection_color.rgba - selection color if (mesh.variant.selection) { this.vertex_template[i++] = style.selection_color[0] * 255; @@ -13578,6 +13661,7 @@ Object.assign(Lines, { this.vertex_template[i++] = style.selection_color[3] * 255; } + this.addCustomAttributesToVertexTemplate(style, i); return this.vertex_template; }, buildLines: function buildLines(lines, style, context, options) { @@ -14781,11 +14865,10 @@ var TextSettings = { px_size: 12, family: 'Helvetica', fill: 'white', + fill_array: [1, 1, 1, 1], text_wrap: 15, max_lines: 5, - align: 'center', - stroke: null, - stroke_width: 0 + align: 'center' }, compute: function compute(feature, draw, context) { var style = {}; @@ -14793,7 +14876,18 @@ var TextSettings = { style.can_articulate = draw.can_articulate; // Use fill if specified, or default - style.fill = draw.font.fill && Utils.toCSSColor(StyleParser.evalCachedColorProperty(draw.font.fill, context)) || this.defaults.fill; // Font properties are modeled after CSS names: + style.fill = draw.font.fill && StyleParser.evalCachedColorProperty(draw.font.fill, context); // optional alpha override + + var alpha = StyleParser.evalCachedProperty(draw.font.alpha, context); + + if (alpha != null) { + style.fill = [].concat(style.fill ? style.fill : this.defaults.fill_array); // copy to avoid modifying underlying object + + style.fill[3] = alpha; + } + + style.fill = style.fill && Utils.toCSSColor(style.fill) || this.defaults.fill; // convert to CSS for Canvas + // Font properties are modeled after CSS names: // - family: Helvetica, Futura, etc. // - size: in pt, px, or em // - style: normal, italic, oblique @@ -14820,8 +14914,22 @@ var TextSettings = { style.px_size = StyleParser.evalCachedProperty(draw.font.px_size, context) * style.supersample; // Use stroke if specified if (draw.font.stroke && draw.font.stroke.color) { - style.stroke = Utils.toCSSColor(StyleParser.evalCachedColorProperty(draw.font.stroke.color, context) || this.defaults.stroke); - style.stroke_width = StyleParser.evalCachedProperty(draw.font.stroke.width, context) || this.defaults.stroke_width; + style.stroke = StyleParser.evalCachedColorProperty(draw.font.stroke.color, context); + + if (style.stroke) { + // optional alpha override + var stroke_alpha = StyleParser.evalCachedProperty(draw.font.stroke.alpha, context); + + if (stroke_alpha != null) { + style.stroke = [].concat(style.stroke); // copy to avoid modifying underlying object + + style.stroke[3] = stroke_alpha; + } + + style.stroke = Utils.toCSSColor(style.stroke); // convert to CSS for Canvas + } + + style.stroke_width = StyleParser.evalCachedProperty(draw.font.stroke.width, context); } style.font_css = this.fontCSS(style); // Word wrap and text alignment @@ -16418,9 +16526,11 @@ var TextLabels = { draw.font.fill = StyleParser.createPropertyCache(draw.font.fill); + draw.font.alpha = StyleParser.createPropertyCache(draw.font.alpha); if (draw.font.stroke) { draw.font.stroke.color = StyleParser.createPropertyCache(draw.font.stroke.color); + draw.font.stroke.alpha = StyleParser.createPropertyCache(draw.font.stroke.alpha); } // Convert font and text stroke sizes @@ -17569,16 +17679,12 @@ 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_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(vec4 v, float x) {\n x = clamp(x, 0., 1.);\n return mix(mix(v[0], v[1], 3. * x),\n mix(v[1],\n mix(v[2], v[3], 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 v_alpha_factor = 1.0;\n v_color = a_color;\n v_texcoord = a_texcoord; // UV from vertex attribute\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // use point dimensions for UVs instead (ignore attribute), add antialiasing info for fragment shader\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 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 _zoom = clamp(u_map_position.z - u_tile_origin.z, 0., 1.); //fract(u_map_position.z);\n float _pre_angle = mix4linear(_pre_angles_scaled, _zoom);\n float _angle = mix4linear(_angles_scaled, _zoom);\n float _offset_curve = mix4linear(_offsets_scaled, _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_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: attributes\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(vec4 v, float x) {\n x = clamp(x, 0., 1.);\n return mix(mix(v[0], v[1], 3. * x),\n mix(v[1],\n mix(v[2], v[3], 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 v_alpha_factor = 1.0;\n v_color = a_color;\n v_texcoord = a_texcoord; // UV from vertex attribute\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // use point dimensions for UVs instead (ignore attribute), add antialiasing info for fragment shader\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 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 _zoom = clamp(u_map_position.z - u_tile_origin.z, 0., 1.); //fract(u_map_position.z);\n float _pre_angle = mix4linear(_pre_angles_scaled, _zoom);\n float _angle = mix4linear(_angles_scaled, _zoom);\n float _offset_curve = mix4linear(_offsets_scaled, _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 // Mask of outermost circle, either outline or point boundary\n float _d = length(v_texcoord); // distance to this fragment from the point center\n float _outer_alpha = _tangram_antialias(_d, 1.);\n float _fill_alpha = _tangram_antialias(_d, 1. - (v_outline_edge * 0.5)) * color.a;\n float _stroke_alpha = (_outer_alpha - _tangram_antialias(_d, 1. - v_outline_edge)) * v_outline_color.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 + v_outline_color.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, v_outline_color.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"; +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: attributes\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 // Mask of outermost circle, either outline or point boundary\n float _d = length(v_texcoord); // distance to this fragment from the point center\n float _outer_alpha = _tangram_antialias(_d, 1.);\n float _fill_alpha = _tangram_antialias(_d, 1. - (v_outline_edge * 0.5)) * color.a;\n float _stroke_alpha = (_outer_alpha - _tangram_antialias(_d, 1. - v_outline_edge)) * v_outline_color.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 + v_outline_color.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, v_outline_color.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"; var PLACEMENT$1 = LabelPoint.PLACEMENT; var Points = Object.create(Style); -Points.variants = {}; // mesh variants by variant key - -Points.vertex_layouts = {}; // vertex layouts by variant key - var SHADER_POINT_VARIANT = '__shader_point'; // texture types var TANGRAM_POINT_TYPE_TEXTURE = 1; // style texture/sprites (assigned by user) @@ -17677,8 +17783,10 @@ Object.assign(Points, { if (!style.color && !style.texture) { return; - } // optional sprite and texture + } + style.alpha = StyleParser.evalCachedProperty(draw.alpha, context); // optional alpha override + // optional sprite and texture var sprite_info; @@ -17719,10 +17827,13 @@ Object.assign(Points, { style.outline_edge_pct = 0; if (style.outline_width && style.outline_color) { + // adjust size and UVs for outline var outline_width = style.outline_width; style.size[0] += outline_width; style.size[1] += outline_width; style.outline_edge_pct = outline_width / Math.min(style.size[0], style.size[1]) * 2; // UV distance at which outline starts + + style.outline_alpha = StyleParser.evalCachedProperty(draw.outline.alpha, context); // optional alpha override } // size will be scaled to 16-bit signed int, so max allowed width + height of 256 pixels @@ -17957,12 +18068,14 @@ Object.assign(Points, { }, _preprocess: function _preprocess(draw) { draw.color = StyleParser.createColorPropertyCache(draw.color); + draw.alpha = StyleParser.createPropertyCache(draw.alpha); 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.alpha = StyleParser.createPropertyCache(draw.outline.alpha); draw.outline.width = StyleParser.createPropertyCache(draw.outline.width, StyleParser.parsePositiveNumber); } @@ -18178,7 +18291,11 @@ Object.assign(Points, { * A "template" that sets constant attibutes for each vertex, which is then modified per vertex or per feature. * A plain JS array matching the order of the vertex layout. */ - makeVertexTemplate: function makeVertexTemplate(style, mesh) { + makeVertexTemplate: function makeVertexTemplate(style, mesh, add_custom_attribs) { + if (add_custom_attribs === void 0) { + add_custom_attribs = true; + } + var i = 0; // a_position.xyz - vertex position // a_position.w - layer order @@ -18208,7 +18325,7 @@ Object.assign(Points, { this.vertex_template[i++] = color[0] * 255; this.vertex_template[i++] = color[1] * 255; this.vertex_template[i++] = color[2] * 255; - this.vertex_template[i++] = color[3] * 255; // a_selection_color.rgba - selection color + this.vertex_template[i++] = (style.alpha != null ? style.alpha : color[3]) * 255; // a_selection_color.rgba - selection color if (mesh.variant.selection) { this.vertex_template[i++] = style.selection_color[0] * 255; @@ -18224,11 +18341,15 @@ Object.assign(Points, { this.vertex_template[i++] = outline_color[0] * 255; this.vertex_template[i++] = outline_color[1] * 255; this.vertex_template[i++] = outline_color[2] * 255; - this.vertex_template[i++] = outline_color[3] * 255; // a_outline_edge - point outline edge (as % of point size where outline begins) + this.vertex_template[i++] = (style.outline_alpha != null ? style.outline_alpha : outline_color[3]) * 255; // a_outline_edge - point outline edge (as % of point size where outline begins) this.vertex_template[i++] = style.outline_edge_pct || StyleParser.defaults.outline.width; } + if (add_custom_attribs) { + this.addCustomAttributesToVertexTemplate(style, i); + } + return this.vertex_template; }, buildQuad: function buildQuad(point, size, angle, angles, pre_angles, offset, offsets, texcoords, curve, vertex_data, vertex_template) { @@ -18424,7 +18545,7 @@ Object.assign(Points, { // Create or return desired vertex layout permutation based on flags vertexLayoutForMeshVariant: function vertexLayoutForMeshVariant(variant) { // Vertex layout only depends on shader point flag, so using it as layout key to avoid duplicate layouts - if (Points.vertex_layouts[variant.shader_point] == null) { + if (this.vertex_layouts[variant.shader_point] == null) { // Attributes for this mesh variant // Optional attributes have placeholder values assigned with `static` parameter // TODO: could support optional attributes for selection and offset, but may not be worth it @@ -18474,10 +18595,11 @@ Object.assign(Points, { normalized: false, static: variant.shader_point ? null : 0 }]; - Points.vertex_layouts[variant.shader_point] = new VertexLayout(attribs); + this.addCustomAttributesToAttributeList(attribs); + this.vertex_layouts[variant.shader_point] = new VertexLayout(attribs); } - return Points.vertex_layouts[variant.shader_point]; + return this.vertex_layouts[variant.shader_point]; }, // Override meshVariantTypeForDraw: function meshVariantTypeForDraw(draw) { @@ -18485,8 +18607,8 @@ Object.assign(Points, { var key = texture + '/' + draw.blend_order; - if (Points.variants[key] == null) { - Points.variants[key] = { + if (this.variants[key] == null) { + this.variants[key] = { key: key, selection: 1, // TODO: make this vary by draw params @@ -18498,7 +18620,7 @@ Object.assign(Points, { }; } - return Points.variants[key]; // return pre-calculated mesh variant + return this.variants[key]; // return pre-calculated mesh variant }, // Override makeMesh: function makeMesh(vertex_data, vertex_elements, options) { @@ -19328,8 +19450,6 @@ function getAbsAngleDiff(angle1, angle2) { } var TextStyle = Object.create(Points); -TextStyle.vertex_layouts = {}; // vertex layouts by variant key - Object.assign(TextStyle, { name: 'text', super: Points, @@ -19354,7 +19474,9 @@ Object.assign(TextStyle, { * A plain JS array matching the order of the vertex layout. */ makeVertexTemplate: function makeVertexTemplate(style, mesh) { - this.super.makeVertexTemplate.apply(this, arguments); + this.super.makeVertexTemplate.call(this, style, mesh, + /* add_custom_attribs */ + false); var vertex_layout = mesh.vertex_data.vertex_layout; var i = vertex_layout.index.a_pre_angles; // a_pre_angles.xyzw - rotation of entire curved label // a_angles.xyzw - angle of each curved label segment @@ -19364,6 +19486,7 @@ Object.assign(TextStyle, { this.vertex_template[i++] = 0; } + this.addCustomAttributesToVertexTemplate(style, i); return this.vertex_template; }, reset: function reset() { @@ -19607,7 +19730,7 @@ Object.assign(TextStyle, { // Create or return vertex layout vertexLayoutForMeshVariant: function vertexLayoutForMeshVariant(variant) { // Vertex layout only depends on shader point flag, so using it as layout key to avoid duplicate layouts - if (TextStyle.vertex_layouts[variant.shader_point] == null) { + if (this.vertex_layouts[variant.shader_point] == null) { // TODO: could make selection, offset, and curved label attribs optional, but may not be worth it // since text points generally don't consume much memory anyway var attribs = [{ @@ -19657,10 +19780,11 @@ Object.assign(TextStyle, { type: gl$1.UNSIGNED_SHORT, normalized: false }]; - TextStyle.vertex_layouts[variant.shader_point] = new VertexLayout(attribs); + this.addCustomAttributesToAttributeList(attribs); + this.vertex_layouts[variant.shader_point] = new VertexLayout(attribs); } - return TextStyle.vertex_layouts[variant.shader_point]; + return this.vertex_layouts[variant.shader_point]; } }); TextStyle.texture_id = 0; // namespaces per-tile label textures @@ -19941,6 +20065,12 @@ function () { return x.defines; }).filter(function (x) { return x; + }))); // Attributes + + shaders.attributes = Object.assign.apply(Object, [{}].concat(shader_merges.map(function (x) { + return x.attributes; + }).filter(function (x) { + return x; }))); // Uniforms shaders.uniforms = {}; // uniforms for this style, both explicitly defined, and mixed from other styles @@ -20096,14 +20226,36 @@ function () { } // Called to create and initialize styles ; - _proto.build = function build(styles) { + _proto.build = function build(styles_defs) { var _this2 = this; + var styles = Object.assign({}, styles_defs); // copy to avoid modifying underlying object // Un-register existing styles from cross-thread communication + if (this.styles) { Object.values(this.styles).forEach(function (s) { return WorkerBroker$1.removeTarget(s.main_thread_target); }); + } // Add default blend/base style pairs as needed + + + var blends = ['opaque', 'add', 'multiply', 'overlay', 'inlay', 'translucent']; + var bases = ['polygons', 'lines', 'points', 'text', 'raster']; + + for (var _i = 0; _i < blends.length; _i++) { + var blend = blends[_i]; + + for (var _i2 = 0; _i2 < bases.length; _i2++) { + var base = bases[_i2]; + var style = blend + '_' + base; + + if (styles[style] == null) { + styles[style] = { + base: base, + blend: blend + }; + } + } } // Sort styles by dependency, then build them @@ -45826,26 +45978,6 @@ var SceneLoader$1 = SceneLoader = { config.lights.default_light = { type: 'directional' }; - } // Add default blend/base style pairs as needed - - - var blends = ['opaque', 'add', 'multiply', 'overlay', 'inlay', 'translucent']; - var bases = ['polygons', 'lines', 'points', 'text']; - - for (var _i = 0; _i < blends.length; _i++) { - var blend = blends[_i]; - - for (var _i2 = 0; _i2 < bases.length; _i2++) { - var base = bases[_i2]; - var style = blend + '_' + base; - - if (config.styles[style] == null) { - config.styles[style] = { - base: base, - blend: blend - }; - } - } } return { @@ -49600,7 +49732,7 @@ return index; // Script modules can't expose exports try { Tangram.debug.ESM = false; // mark build as ES module - Tangram.debug.SHA = '998cb95f28e17a511e2991fe6c08a9e0c044aceb'; + Tangram.debug.SHA = 'e76e4fd4278c18dccb19ec07d7550bbb76bdd8f7'; if (false === true && typeof window === 'object') { window.Tangram = Tangram; } diff --git a/dist/tangram.debug.js.map b/dist/tangram.debug.js.map index a3132b76c..331f1f9b2 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/_meta.js","../node_modules/core-js/modules/_is-array.js","../node_modules/core-js/modules/_object-gopn.js","../node_modules/core-js/modules/_object-gopd.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/utils.js","../src/utils/debug_settings.js","../node_modules/core-js/modules/_set-proto.js","../node_modules/core-js/modules/_inherit-if-required.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/_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","../node_modules/core-js/modules/es6.array.find-index.js","../src/utils/merge.js","../src/utils/geo.js","../node_modules/core-js/modules/_string-ws.js","../node_modules/core-js/modules/_string-trim.js","../node_modules/core-js/modules/es6.number.constructor.js","../node_modules/core-js/modules/es6.number.min-safe-integer.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_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/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","../node_modules/core-js/modules/es6.number.max-safe-integer.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","../node_modules/core-js/modules/_wks-ext.js","../node_modules/core-js/modules/_wks-define.js","../node_modules/core-js/modules/es7.symbol.async-iterator.js","../node_modules/core-js/modules/_enum-keys.js","../node_modules/core-js/modules/_object-gopn-ext.js","../node_modules/core-js/modules/es6.symbol.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","var META = require('./_uid')('meta');\nvar isObject = require('./_is-object');\nvar has = require('./_has');\nvar setDesc = require('./_object-dp').f;\nvar id = 0;\nvar isExtensible = Object.isExtensible || function () {\n return true;\n};\nvar FREEZE = !require('./_fails')(function () {\n return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function (it) {\n setDesc(it, META, { value: {\n i: 'O' + ++id, // object ID\n w: {} // weak collections IDs\n } });\n};\nvar fastKey = function (it, create) {\n // return primitive with prefix\n if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if (!has(it, META)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return 'F';\n // not necessary to add metadata\n if (!create) return 'E';\n // add missing metadata\n setMeta(it);\n // return object ID\n } return it[META].i;\n};\nvar getWeak = function (it, create) {\n if (!has(it, META)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return true;\n // not necessary to add metadata\n if (!create) return false;\n // add missing metadata\n setMeta(it);\n // return hash weak collections IDs\n } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function (it) {\n if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);\n return it;\n};\nvar meta = module.exports = {\n KEY: META,\n NEED: false,\n fastKey: fastKey,\n getWeak: getWeak,\n onFreeze: onFreeze\n};\n","// 7.2.2 IsArray(argument)\nvar cof = require('./_cof');\nmodule.exports = Array.isArray || function isArray(arg) {\n return cof(arg) == 'Array';\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 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","'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 utilities\n/*jshint worker: true*/\n\nimport log from './log';\nimport Thread from './thread';\nimport WorkerBroker from './worker_broker';\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({ 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[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","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","// 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","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