From 2c7f8c9959c701adfb82e8f4b98e0d82d2eaf6d7 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 2 Jun 2021 08:07:12 +0200 Subject: [PATCH 001/138] A working prototype, which adds 3d-terrain to maplibre-gl. Sadly, during the development i did no intermediate commits, so in this first commit all the following functionality is included: * allow MTK terrainRGB-tiles encoding with parameters: [6553.6, 25.6, 0.03, 10000.0]. In our opinion 0.1 for height-steps is to rough. * create a TerrainSourceCache.js class which is similar to SourceCache.js and holds all the terrain-tiles used for the 3D-mesh. If a terrainRGB tile is used in both, terrain & hillshading, it is loaded twice. This makes the whole process much more easy. * create a 3d-mesh in raster_dem_tile_worker_source.js with the martini library. * rewrite the draw logic to render all layers, except symbols, into a framebuffer. This framebuffer a later used as a texture onto the 3d-mesh. * rewrite symbol rendering to use 3d-coordinates. This is done with an extra a_ele shader parameter, because the z-value of the a_pos variable is already used for other things. * add the third dimension into the collision index. * create a terrain.html test-page. --- build/generate-struct-arrays.js | 2 + debug/terrain.html | 3989 ++++++++++++++++++ package.json | 3 +- src/data/array_types.js | 2 + src/data/bucket/symbol_attributes.js | 4 + src/data/bucket/symbol_bucket.js | 26 +- src/data/dem_data.js | 26 +- src/data/pos3d_attributes.js | 6 + src/geo/transform.js | 2 + src/render/draw_background.js | 4 +- src/render/draw_fill.js | 5 +- src/render/draw_hillshade.js | 6 +- src/render/draw_line.js | 10 +- src/render/draw_raster.js | 5 +- src/render/draw_symbol.js | 38 +- src/render/draw_terrain.js | 61 + src/render/painter.js | 40 + src/render/program.js | 6 +- src/render/program/hillshade_program.js | 7 +- src/render/program/line_program.js | 24 +- src/render/program/program_uniforms.js | 4 +- src/render/program/terrain_program.js | 25 + src/render/vertex_array_object.js | 24 +- src/shaders/collision_box.vertex.glsl | 1 + src/shaders/line.vertex.glsl | 6 +- src/shaders/line_gradient.vertex.glsl | 6 +- src/shaders/line_pattern.vertex.glsl | 6 +- src/shaders/line_sdf.vertex.glsl | 7 +- src/shaders/shaders.js | 3 + src/shaders/symbol_icon.vertex.glsl | 10 +- src/shaders/symbol_sdf.vertex.glsl | 10 +- src/shaders/symbol_text_and_icon.vertex.glsl | 10 +- src/shaders/terrain.fragment.glsl | 8 + src/shaders/terrain.vertex.glsl | 9 + src/source/raster_dem_tile_source.js | 9 +- src/source/raster_dem_tile_worker_source.js | 28 +- src/source/terrain_source_cache.js | 118 + src/source/worker_source.js | 5 +- src/style-spec/reference/v8.json | 3 + src/style-spec/types.js | 5 +- src/style/style.js | 10 + src/symbol/collision_index.js | 24 +- src/symbol/placement.js | 28 +- src/symbol/projection.js | 48 +- 44 files changed, 4545 insertions(+), 128 deletions(-) create mode 100644 debug/terrain.html create mode 100644 src/data/pos3d_attributes.js create mode 100644 src/render/draw_terrain.js create mode 100644 src/render/program/terrain_program.js create mode 100644 src/shaders/terrain.fragment.glsl create mode 100644 src/shaders/terrain.vertex.glsl create mode 100644 src/source/terrain_source_cache.js diff --git a/build/generate-struct-arrays.js b/build/generate-struct-arrays.js index 439af9d65ba..8a1c0659f35 100644 --- a/build/generate-struct-arrays.js +++ b/build/generate-struct-arrays.js @@ -151,6 +151,7 @@ const { symbolLayoutAttributes, dynamicLayoutAttributes, placementOpacityAttributes, + elevationAttributes, collisionBox, collisionBoxLayout, collisionCircleLayout, @@ -165,6 +166,7 @@ const { createStructArrayType(`symbol_layout`, symbolLayoutAttributes); createStructArrayType(`symbol_dynamic_layout`, dynamicLayoutAttributes); createStructArrayType(`symbol_opacity`, placementOpacityAttributes); +createStructArrayType(`symbol_elevation`, elevationAttributes); createStructArrayType('collision_box', collisionBox, true); createStructArrayType(`collision_box_layout`, collisionBoxLayout); createStructArrayType(`collision_circle_layout`, collisionCircleLayout); diff --git a/debug/terrain.html b/debug/terrain.html new file mode 100644 index 00000000000..266eecffbdd --- /dev/null +++ b/debug/terrain.html @@ -0,0 +1,3989 @@ + + + + MapLibre GL JS debug page + + + + + + + +
+ + + + + + diff --git a/package.json b/package.json index c3c3435b428..df0e3461f7a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ "rw": "^1.3.3", "supercluster": "^7.1.0", "tinyqueue": "^2.0.3", - "vt-pbf": "^3.1.1" + "vt-pbf": "^3.1.1", + "@mapbox/martini": "^0.2.0" }, "devDependencies": { "@babel/core": "^7.9.0", diff --git a/src/data/array_types.js b/src/data/array_types.js index bc15e318b2d..f77987a667d 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -1114,6 +1114,7 @@ export { StructArrayLayout1ui2, StructArrayLayout4f16, StructArrayLayout2i4 as PosArray, + StructArrayLayout3i6 as Pos3DArray, StructArrayLayout4i8 as RasterBoundsArray, StructArrayLayout2i4 as CircleLayoutArray, StructArrayLayout2i4 as FillLayoutArray, @@ -1125,6 +1126,7 @@ export { StructArrayLayout4i4ui4i24 as SymbolLayoutArray, StructArrayLayout3f12 as SymbolDynamicLayoutArray, StructArrayLayout1ul4 as SymbolOpacityArray, + StructArrayLayout1f4 as SymbolElevationArray, StructArrayLayout2i2i2i12 as CollisionBoxLayoutArray, StructArrayLayout2f1f2i16 as CollisionCircleLayoutArray, StructArrayLayout2ub2f12 as CollisionVertexArray, diff --git a/src/data/bucket/symbol_attributes.js b/src/data/bucket/symbol_attributes.js index 5d307d2ada6..87ab9c2fa20 100644 --- a/src/data/bucket/symbol_attributes.js +++ b/src/data/bucket/symbol_attributes.js @@ -12,6 +12,10 @@ export const dynamicLayoutAttributes = createLayout([ {name: 'a_projected_pos', components: 3, type: 'Float32'} ], 4); +export const elevationAttributes = createLayout([ + {name: 'a_ele', components: 1, type: 'Float32'} +], 4); + export const placementOpacityAttributes = createLayout([ {name: 'a_fade_opacity', components: 1, type: 'Uint32'} ], 4); diff --git a/src/data/bucket/symbol_bucket.js b/src/data/bucket/symbol_bucket.js index 89d67230054..4de8f6732c8 100644 --- a/src/data/bucket/symbol_bucket.js +++ b/src/data/bucket/symbol_bucket.js @@ -3,12 +3,14 @@ import {symbolLayoutAttributes, collisionVertexAttributes, collisionBoxLayout, - dynamicLayoutAttributes + dynamicLayoutAttributes, + elevationAttributes } from './symbol_attributes'; import {SymbolLayoutArray, SymbolDynamicLayoutArray, SymbolOpacityArray, + SymbolElevationArray, CollisionBoxLayoutArray, CollisionVertexArray, PlacedSymbolArray, @@ -65,6 +67,7 @@ export type SingleCollisionBox = { y2: number; anchorPointX: number; anchorPointY: number; + elevation: number; }; export type CollisionArrays = { @@ -137,6 +140,13 @@ function addDynamicAttributes(dynamicLayoutVertexArray: StructArray, p: Point, a dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle); } +function addElevation(elevationVertexArray: StructArray, elevation: number = 0.0) { + elevationVertexArray.emplaceBack(elevation); + elevationVertexArray.emplaceBack(elevation); + elevationVertexArray.emplaceBack(elevation); + elevationVertexArray.emplaceBack(elevation); +} + function containsRTLText(formattedText: Formatted): boolean { for (const section of formattedText.sections) { if (stringContainsRTLText(section.text)) { @@ -159,6 +169,9 @@ export class SymbolBuffers { dynamicLayoutVertexArray: SymbolDynamicLayoutArray; dynamicLayoutVertexBuffer: VertexBuffer; + elevationVertexArray: SymbolElevationArray; + elevationVertexBuffer: VertexBuffer; + opacityVertexArray: SymbolOpacityArray; opacityVertexBuffer: VertexBuffer; @@ -173,6 +186,7 @@ export class SymbolBuffers { this.programConfigurations = programConfigurations; this.segments = new SegmentVector(); this.dynamicLayoutVertexArray = new SymbolDynamicLayoutArray(); + this.elevationVertexArray = new SymbolElevationArray(); this.opacityVertexArray = new SymbolOpacityArray(); this.placedSymbolArray = new PlacedSymbolArray(); } @@ -181,6 +195,7 @@ export class SymbolBuffers { return this.layoutVertexArray.length === 0 && this.indexArray.length === 0 && this.dynamicLayoutVertexArray.length === 0 && + this.elevationVertexArray.length === 0 && this.opacityVertexArray.length === 0; } @@ -193,6 +208,7 @@ export class SymbolBuffers { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, symbolLayoutAttributes.members); this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer); this.dynamicLayoutVertexBuffer = context.createVertexBuffer(this.dynamicLayoutVertexArray, dynamicLayoutAttributes.members, true); + this.elevationVertexBuffer = context.createVertexBuffer(this.elevationVertexArray, elevationAttributes.members, true); this.opacityVertexBuffer = context.createVertexBuffer(this.opacityVertexArray, shaderOpacityAttributes, true); // This is a performance hack so that we can write to opacityVertexArray with uint32s // even though the shaders read uint8s @@ -211,6 +227,7 @@ export class SymbolBuffers { this.segments.destroy(); this.dynamicLayoutVertexBuffer.destroy(); this.opacityVertexBuffer.destroy(); + this.elevationVertexBuffer.destroy(); } } @@ -291,6 +308,7 @@ register('CollisionBuffers', CollisionBuffers); class SymbolBucket implements Bucket { static MAX_GLYPHS: number; static addDynamicAttributes: typeof addDynamicAttributes; + static addElevation: typeof addElevation; collisionBoxArray: CollisionBoxArray; zoom: number; @@ -619,6 +637,7 @@ class SymbolBucket implements Bucket { canonical: CanonicalTileID) { const indexArray = arrays.indexArray; const layoutVertexArray = arrays.layoutVertexArray; + const elevationVertexArray = arrays.elevationVertexArray; const segment = arrays.segments.prepareSegment(4 * quads.length, layoutVertexArray, indexArray, this.canOverlap ? feature.sortKey : undefined); const glyphOffsetArrayStart = this.glyphOffsetArray.length; @@ -640,6 +659,8 @@ class SymbolBucket implements Bucket { addDynamicAttributes(arrays.dynamicLayoutVertexArray, labelAnchor, angle); + addElevation(elevationVertexArray, 0); // elevation is calculated in a later step + indexArray.emplaceBack(index, index + 1, index + 2); indexArray.emplaceBack(index + 1, index + 2, index + 3); @@ -932,6 +953,7 @@ register('SymbolBucket', SymbolBucket, { SymbolBucket.MAX_GLYPHS = 65535; SymbolBucket.addDynamicAttributes = addDynamicAttributes; +SymbolBucket.addElevation = addElevation; export default SymbolBucket; -export {addDynamicAttributes}; +export {addDynamicAttributes,addElevation}; diff --git a/src/data/dem_data.js b/src/data/dem_data.js index fcbf98ad830..25ad9e092b7 100644 --- a/src/data/dem_data.js +++ b/src/data/dem_data.js @@ -19,15 +19,15 @@ export default class DEMData { data: Uint32Array; stride: number; dim: number; - encoding: "mapbox" | "terrarium"; + encoding: "mapbox" | "terrarium" | "mtk"; // RGBAImage data has uniform 1px padding on all sides: square tile edge size defines stride // and dim is calculated as stride - 2. - constructor(uid: string, data: RGBAImage, encoding: "mapbox" | "terrarium") { + constructor(uid: string, data: RGBAImage, encoding: "mapbox" | "terrarium" | "mtk") { this.uid = uid; if (data.height !== data.width) throw new RangeError('DEM tiles must be square'); - if (encoding && encoding !== "mapbox" && encoding !== "terrarium") return warnOnce( - `"${encoding}" is not a valid encoding type. Valid types include "mapbox" and "terrarium".` + if (encoding && encoding !== "mapbox" && encoding !== "terrarium" && encoding !== "mtk") return warnOnce( + `"${encoding}" is not a valid encoding type. Valid types include "mapbox", "mtk" and "terrarium".` ); this.stride = data.height; const dim = this.dim = data.height - 2; @@ -57,12 +57,22 @@ export default class DEMData { get(x: number, y: number) { const pixels = new Uint8Array(this.data.buffer); const index = this._idx(x, y) * 4; - const unpack = this.encoding === "terrarium" ? this._unpackTerrarium : this._unpackMapbox; + let unpack = this._unpackMapbox; + if (this.encoding === "terrarium") unpack = this._unpackTerrarium; + if (this.encoding === "mtk") unpack = this._unpackMTK; return unpack(pixels[index], pixels[index + 1], pixels[index + 2]); } + // when using MTK encoding the hillshading looks ugly, so still use mapbox encoding + getHillshadingUnpackVector() { + if (this.encoding === "terrarium") return [256.0, 1.0, 1.0 / 256.0, 32768.0]; + return [6553.6, 25.6, 0.1, 10000.0]; + } + getUnpackVector() { - return this.encoding === "terrarium" ? [256.0, 1.0, 1.0 / 256.0, 32768.0] : [6553.6, 25.6, 0.1, 10000.0]; + if (this.encoding === "terrarium") return [256.0, 1.0, 1.0 / 256.0, 32768.0]; + if (this.encoding === "mtk") return [6553.6, 25.6, 0.03, 10000.0]; + return [6553.6, 25.6, 0.1, 10000.0]; } _idx(x: number, y: number) { @@ -76,6 +86,10 @@ export default class DEMData { return ((r * 256 * 256 + g * 256.0 + b) / 10.0 - 10000.0); } + _unpackMTK(r: number, g: number, b: number) { + return ((r * 256 * 256 + g * 256.0 + b) * 0.03 - 10000.0); + } + _unpackTerrarium(r: number, g: number, b: number) { // unpacking formula for mapzen terrarium: // https://aws.amazon.com/public-datasets/terrain/ diff --git a/src/data/pos3d_attributes.js b/src/data/pos3d_attributes.js new file mode 100644 index 00000000000..a6c17f3904e --- /dev/null +++ b/src/data/pos3d_attributes.js @@ -0,0 +1,6 @@ +// @flow +import {createLayout} from '../util/struct_array'; + +export default createLayout([ + { name: 'a_pos', type: 'Int16', components: 3 } +]); \ No newline at end of file diff --git a/src/geo/transform.js b/src/geo/transform.js index 997e3f00386..cbfa911230c 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -41,6 +41,7 @@ class Transform { pixelMatrixInverse: Float64Array; glCoordMatrix: Float32Array; labelPlaneMatrix: Float32Array; + terrainSourceCache: any; _fov: number; _pitch: number; _zoom: number; @@ -95,6 +96,7 @@ class Transform { clone._pitch = this._pitch; clone._unmodified = this._unmodified; clone._edgeInsets = this._edgeInsets.clone(); + clone.terrainSourceCache = this.terrainSourceCache; clone._calcMatrices(); return clone; } diff --git a/src/render/draw_background.js b/src/render/draw_background.js index 3855b519dab..b80a036d6de 100644 --- a/src/render/draw_background.js +++ b/src/render/draw_background.js @@ -45,7 +45,8 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const crossfade = layer.getCrossfadeParameters(); for (const tileID of tileIDs) { - const matrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped()); + const matrix = painter.prepareFramebuffer(tileID, "background") + || painter.transform.calculatePosMatrix(tileID.toUnwrapped()); const uniformValues = image ? backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}, crossfade) : backgroundUniformValues(matrix, opacity, color); @@ -53,5 +54,6 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.tileExtentBuffer, painter.quadTriangleIndexBuffer, painter.tileExtentSegments); + painter.finishFramebuffer(tileID, "background"); } } diff --git a/src/render/draw_fill.js b/src/render/draw_fill.js index 7f673f944d4..82242544daf 100644 --- a/src/render/draw_fill.js +++ b/src/render/draw_fill.js @@ -98,7 +98,8 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const tileMatrix = painter.translatePosMatrix(coord.posMatrix, tile, + let posMatrix = painter.prepareFramebuffer(coord, "fill") || coord.posMatrix; + const tileMatrix = painter.translatePosMatrix(posMatrix, tile, layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor')); if (!isOutline) { @@ -120,5 +121,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration); + + painter.finishFramebuffer(tile.tileID, "fill"); } } diff --git a/src/render/draw_hillshade.js b/src/render/draw_hillshade.js index 25519fce4b8..c78c44237e2 100644 --- a/src/render/draw_hillshade.js +++ b/src/render/draw_hillshade.js @@ -50,11 +50,13 @@ function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); - const uniformValues = hillshadeUniformValues(painter, tile, layer); + let posMatrix = painter.prepareFramebuffer(tile.tileID, "hillshade"); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - uniformValues, layer.id, painter.rasterBoundsBuffer, + hillshadeUniformValues(painter, tile, layer, posMatrix), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); + + painter.finishFramebuffer(tile.tileID, "hillshade"); } // hillshade rendering is done in two steps. the prepare step first calculates the slope of the terrain in the x and y diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 48c2813b01c..97dbb8cb002 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -67,10 +67,11 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade) : - dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade) : - gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length) : - lineUniformValues(painter, tile, layer); + const posMatrix = painter.prepareFramebuffer(tile.tileID, "line"); + const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade, posMatrix) : + dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade, posMatrix) : + gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length, posMatrix) : + lineUniformValues(painter, tile, layer, posMatrix); if (image) { context.activeTexture.set(gl.TEXTURE0); @@ -119,6 +120,7 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration, bucket.layoutVertexBuffer2); + painter.finishFramebuffer(tile.tileID, "line"); firstTile = false; // once refactored so that bound texture state is managed, we'll also be able to remove this firstTile/programChanged logic } diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index d65cffaa900..1517ecdd341 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -41,7 +41,6 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty layer.paint.get('raster-opacity') === 1 ? DepthMode.ReadWrite : DepthMode.ReadOnly, gl.LESS); const tile = sourceCache.getTile(coord); - const posMatrix = painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); tile.registerFadeDuration(layer.paint.get('raster-fade-duration')); @@ -66,6 +65,8 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); } + const posMatrix = painter.prepareFramebuffer(tile.tileID, "raster") + || painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); if (source instanceof ImageSource) { @@ -77,6 +78,8 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } + + painter.finishFramebuffer(tile.tileID, "raster"); } } diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 9160cd8c826..50c4aaad2ae 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -12,7 +12,7 @@ const identityMat4 = mat4.identity(new Float32Array(16)); import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; import CullFaceMode from '../gl/cull_face_mode'; -import {addDynamicAttributes} from '../data/bucket/symbol_bucket'; +import {addDynamicAttributes, addElevation} from '../data/bucket/symbol_bucket'; import {getAnchorAlignment, WritingMode} from '../symbol/shaping'; import ONE_EM from '../symbol/one_em'; @@ -60,6 +60,8 @@ function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolSt const colorMode = painter.colorModeForRenderPass(); const variablePlacement = layer.layout.get('text-variable-anchor'); + updateElevation(coords, painter, layer, sourceCache); + //Compute variable-offsets before painting since icons and text data positioning //depend on each other in this case. if (variablePlacement) { @@ -111,6 +113,35 @@ function calculateVariableRenderShift(anchor, width, height, textOffset, textBox ); } +function updateElevation(coords, painter, layer, sourceCache) { + for (const coord of coords) { + const tile = sourceCache.getTile(coord); + // FIXME-3D! normally the calculation of elevation has to be done only once, + // but there is a race-condition if vector tiles loads faster than terrain-tiles + // so recalculte elevation every rendering. Suprisingly it seems there is no + // performance issue. + // if (tile.hasElevation) continue; + const bucket: SymbolBucket = (tile.getBucket(layer): any); + for (const type of ['text', 'icon']) { + const placedSymbols = bucket && bucket[type] && bucket[type].placedSymbolArray; + if (placedSymbols) { + const elevationVertexArray = bucket[type].elevationVertexArray; + elevationVertexArray.clear(); + for (let s = 0; s < placedSymbols.length; s++) { + const symbol: any = placedSymbols.get(s); + const elevation = painter.style.terrainSourceCache.getElevation(coord, symbol.anchorX, symbol.anchorY); + for (let g = 0; g < symbol.numGlyphs; g++) { + addElevation(elevationVertexArray, elevation); + } + } + if (bucket[type].elevationVertexBuffer) + bucket[type].elevationVertexBuffer.updateData(elevationVertexArray); + } + } + tile.hasElevation = true; + } +} + function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlignment, pitchAlignment, variableOffsets) { const tr = painter.transform; const rotateWithMap = rotationAlignment === 'map'; @@ -296,7 +327,8 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate bucket.hasIconData(); if (alongLine) { - symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright); + const getElevation = (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y); + symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } const matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor), @@ -388,5 +420,5 @@ function drawSymbolElements(buffers, segments, layer, painter, program, depthMod uniformValues, layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, segments, layer.paint, painter.transform.zoom, buffers.programConfigurations.get(layer.id), - buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer); + buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer, buffers.elevationVertexBuffer); } diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js new file mode 100644 index 00000000000..57f4d90ba0f --- /dev/null +++ b/src/render/draw_terrain.js @@ -0,0 +1,61 @@ +// @flow + +import StencilMode from '../gl/stencil_mode'; +import DepthMode from '../gl/depth_mode'; +import SegmentVector from '../data/segment'; +import {terrainUniformValues} from './program/terrain_program'; +import type Painter from './painter'; +import type TerranSourceCache from '../source/terrain_source_cache'; +import CullFaceMode from '../gl/cull_face_mode'; +import pos3DAttributes from '../data/pos3d_attributes'; +import Texture from './texture'; +import Color from '../style-spec/util/color'; + +function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { + const tiles = Object.values(sourceCache._tiles).filter(t => t.needsRedraw); + if (!tiles.length) return; + + const context = painter.context; + const gl = context.gl; + const colorMode = painter.colorModeForRenderPass(); + const program = painter.useProgram('terrain'); + + for (const tile of tiles) { + tile.needsRedraw = false; + context.activeTexture.set(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tile.fbo.colorAttachment.get()); + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); + const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, + terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); + } +} + +function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { + const context = painter.context; + for (const tileID of sourceCache.getRenderableTileIDs(painter.transform)) { + const tile = sourceCache.getTileByID(tileID); + if (!tile.fbo) { + // FIXME! adjust size for overzooming + context.activeTexture.set(context.gl.TEXTURE0); + tile.texture = new Texture(context, {width: 1024, height: 1024, data: null}, context.gl.RGBA); + tile.texture.bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); + tile.fbo = context.createFramebuffer(1024, 1024, false); + tile.fbo.colorAttachment.set(tile.texture.texture); + } + if (!tile.segments) { + tile.indexBuffer = context.createIndexBuffer(tile.mesh.indexArray); + tile.vertexBuffer = context.createVertexBuffer(tile.mesh.vertexArray, pos3DAttributes.members); + tile.segments = SegmentVector.simpleSegment(0, 0, tile.mesh.vertexArray.length, tile.mesh.indexArray.length); + } + // empty framebuffer + context.bindFramebuffer.set(tile.fbo.framebuffer); + context.clear({ color: Color.transparent }); + painter.finishFramebuffer(); + } +} + +export { + prepareTerrain, + drawTerrain +}; diff --git a/src/render/painter.js b/src/render/painter.js index 56507434800..dbecc93ba01 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -36,6 +36,7 @@ import raster from './draw_raster'; import background from './draw_background'; import debug, {drawDebugPadding} from './draw_debug'; import custom from './draw_custom'; +import {prepareTerrain, drawTerrain} from './draw_terrain'; const draw = { symbol, @@ -323,6 +324,33 @@ class Painter { return [{[minTileZ]: StencilMode.disabled}, coords]; } + // start drawing into the framebuffer, which is drawn on terrain-mesh + prepareFramebuffer(tileID: OverscaledTileID, layerType: string) { + // dz is the tileSize difference of the layer-source and the 512px terrain-source + // so if dz > 0 the frameport's viewbuffer is located to the currect subtile + let z = Math.floor(this.transform.zoom), dz = tileID.canonical.z - z; + const tile = dz >= 0 + ? this.style.terrainSourceCache.getTileByCanonical(tileID.scaledTo(z).canonical) + : this.style.terrainSourceCache.getTileByCanonical(tileID); + if (dz < 0) dz = 0; // draw in parent tile + if (tile) { + const x = tileID.canonical.x - (tile.tileID.canonical.x << dz); + const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); + let size = dz ? tile.fbo.width / (dz * 2) : tile.fbo.width; + tile.needsRedraw = true; + this.context.bindFramebuffer.set(tile.fbo.framebuffer); + this.context.viewport.set([size * x, size * y, size, size]); + return tile.tileID.posMatrix; + } + return null; + } + + // draw onto the screen + finishFramebuffer(tileID: OverscaledTileID, note: string) { + this.context.bindFramebuffer.set(null); + this.context.viewport.set([0, 0, this.width, this.height]); + } + colorModeForRenderPass(): $ReadOnly { const gl = this.context.gl; if (this._showOverdrawInspector) { @@ -388,6 +416,7 @@ class Painter { } this.opaquePassCutoff = Infinity; + this.opaquePassCutoff = 0; // FIXME-3D! disbaled for Terrain3D, but with this setting heatmap no longer work for (let i = 0; i < layerIds.length; i++) { const layerId = layerIds[i]; if (this.style._layers[layerId].is3D()) { @@ -396,6 +425,8 @@ class Painter { } } + prepareTerrain(this, this.style.terrainSourceCache); + // Offscreen pass =============================================== // We first do all rendering that requires rendering to a separate // framebuffer, and then save those for rendering back to the map @@ -443,6 +474,13 @@ class Painter { const layer = this.style._layers[layerIds[this.currentLayer]]; const sourceCache = sourceCaches[layer.source]; + // symbols are renderd directly onto the screen + // so draw the current terrain-framebuffer below the symbols + if (layer.type == 'symbol') { + drawTerrain(this, this.style.terrainSourceCache); + prepareTerrain(this, this.style.terrainSourceCache); + } + // For symbol layers in the translucent pass, we add extra tiles to the renderable set // for cross-tile symbol fading. Symbol layers don't use tile clipping, so no need to render // separate clipping masks @@ -452,6 +490,8 @@ class Painter { this.renderLayer(this, sourceCache, layer, coords); } + drawTerrain(this, this.style.terrainSourceCache); + if (this.options.showTileBoundaries) { //Use source with highest maxzoom let selectedSource; diff --git a/src/render/program.js b/src/render/program.js index 7e273c0a339..7468bc55afb 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -135,7 +135,8 @@ class Program { zoom: ?number, configuration: ?ProgramConfiguration, dynamicLayoutBuffer: ?VertexBuffer, - dynamicLayoutBuffer2: ?VertexBuffer) { + dynamicLayoutBuffer2: ?VertexBuffer, + dynamicLayoutBuffer3: ?VertexBuffer) { const gl = context.gl; @@ -173,7 +174,8 @@ class Program { indexBuffer, segment.vertexOffset, dynamicLayoutBuffer, - dynamicLayoutBuffer2 + dynamicLayoutBuffer2, + dynamicLayoutBuffer3 ); gl.drawElements( diff --git a/src/render/program/hillshade_program.js b/src/render/program/hillshade_program.js index b843970ff15..7a44188262a 100644 --- a/src/render/program/hillshade_program.js +++ b/src/render/program/hillshade_program.js @@ -60,7 +60,8 @@ const hillshadePrepareUniforms = (context: Context, locations: UniformLocations) const hillshadeUniformValues = ( painter: Painter, tile: Tile, - layer: HillshadeStyleLayer + layer: HillshadeStyleLayer, + matrix: ?Float32Array ): UniformValues => { const shadow = layer.paint.get("hillshade-shadow-color"); const highlight = layer.paint.get("hillshade-highlight-color"); @@ -73,7 +74,7 @@ const hillshadeUniformValues = ( } const align = !painter.options.moving; return { - 'u_matrix': painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), + 'u_matrix': matrix || painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), 'u_image': 0, 'u_latrange': getTileLatRange(painter, tile.tileID), 'u_light': [layer.paint.get('hillshade-exaggeration'), azimuthal], @@ -98,7 +99,7 @@ const hillshadeUniformPrepareValues = ( 'u_image': 1, 'u_dimension': [stride, stride], 'u_zoom': tileID.overscaledZ, - 'u_unpack': dem.getUnpackVector() + 'u_unpack': dem.getHillshadingUnpackVector() }; }; diff --git a/src/render/program/line_program.js b/src/render/program/line_program.js index 79fa83c2340..0c12f203a5e 100644 --- a/src/render/program/line_program.js +++ b/src/render/program/line_program.js @@ -105,12 +105,13 @@ const lineSDFUniforms = (context: Context, locations: UniformLocations): LineSDF const lineUniformValues = ( painter: Painter, tile: Tile, - layer: LineStyleLayer + layer: LineStyleLayer, + matrix: ?Float32Array ): UniformValues => { const transform = painter.transform; return { - 'u_matrix': calculateMatrix(painter, tile, layer), + 'u_matrix': calculateMatrix(painter, tile, layer, matrix), 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), 'u_device_pixel_ratio': browser.devicePixelRatio, 'u_units_to_pixels': [ @@ -124,9 +125,10 @@ const lineGradientUniformValues = ( painter: Painter, tile: Tile, layer: LineStyleLayer, - imageHeight: number + imageHeight: number, + matrix: ?Float32Array ): UniformValues => { - return extend(lineUniformValues(painter, tile, layer), { + return extend(lineUniformValues(painter, tile, layer, matrix), { 'u_image': 0, 'u_image_height': imageHeight, }); @@ -136,12 +138,13 @@ const linePatternUniformValues = ( painter: Painter, tile: Tile, layer: LineStyleLayer, - crossfade: CrossfadeParameters + crossfade: CrossfadeParameters, + matrix: ?Float32Array ): UniformValues => { const transform = painter.transform; const tileZoomRatio = calculateTileRatio(tile, transform); return { - 'u_matrix': calculateMatrix(painter, tile, layer), + 'u_matrix': calculateMatrix(painter, tile, layer, matrix), 'u_texsize': tile.imageAtlasTexture.size, // camera zoom ratio 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), @@ -161,7 +164,8 @@ const lineSDFUniformValues = ( tile: Tile, layer: LineStyleLayer, dasharray: CrossFaded>, - crossfade: CrossfadeParameters + crossfade: CrossfadeParameters, + matrix: ?Float32Array ): UniformValues => { const transform = painter.transform; const lineAtlas = painter.lineAtlas; @@ -175,7 +179,7 @@ const lineSDFUniformValues = ( const widthA = posA.width * crossfade.fromScale; const widthB = posB.width * crossfade.toScale; - return extend(lineUniformValues(painter, tile, layer), { + return extend(lineUniformValues(painter, tile, layer, matrix), { 'u_patternscale_a': [tileRatio / widthA, -posA.height / 2], 'u_patternscale_b': [tileRatio / widthB, -posB.height / 2], 'u_sdfgamma': lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2, @@ -190,9 +194,9 @@ function calculateTileRatio(tile: Tile, transform: Transform) { return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom); } -function calculateMatrix(painter, tile, layer) { +function calculateMatrix(painter, tile, layer, posMatrix) { return painter.translatePosMatrix( - tile.tileID.posMatrix, + posMatrix || tile.tileID.posMatrix, tile, layer.paint.get('line-translate'), layer.paint.get('line-translate-anchor') diff --git a/src/render/program/program_uniforms.js b/src/render/program/program_uniforms.js index e36ec6f6e83..1496cbd4f83 100644 --- a/src/render/program/program_uniforms.js +++ b/src/render/program/program_uniforms.js @@ -12,6 +12,7 @@ import {lineUniforms, lineGradientUniforms, linePatternUniforms, lineSDFUniforms import {rasterUniforms} from './raster_program'; import {symbolIconUniforms, symbolSDFUniforms, symbolTextAndIconUniforms} from './symbol_program'; import {backgroundUniforms, backgroundPatternUniforms} from './background_program'; +import {terrainUniforms} from './terrain_program'; export const programUniforms = { fillExtrusion: fillExtrusionUniforms, @@ -38,5 +39,6 @@ export const programUniforms = { symbolSDF: symbolSDFUniforms, symbolTextAndIcon: symbolTextAndIconUniforms, background: backgroundUniforms, - backgroundPattern: backgroundPatternUniforms + backgroundPattern: backgroundPatternUniforms, + terrain: terrainUniforms }; diff --git a/src/render/program/terrain_program.js b/src/render/program/terrain_program.js new file mode 100644 index 00000000000..79bd9e8529e --- /dev/null +++ b/src/render/program/terrain_program.js @@ -0,0 +1,25 @@ +// @flow + +import { + Uniform1i, + UniformMatrix4f +} from '../uniform_binding'; +import type Context from '../gl/context'; +import type {UniformValues, UniformLocations} from '../render/uniform_binding'; + +export type TerrainUniformsType = {| + 'u_matrix': UniformMatrix4f, + 'u_texture': Uniform1i +|}; + +const terrainUniforms = (context: Context, locations: UniformLocations): TerrainRasterUniformsType => ({ + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_texture': new Uniform1i(context, locations.u_image0) +}); + +const terrainUniformValues = (matrix: Float32Array): UniformValues => ({ + 'u_matrix': matrix, + 'u_texture': 0 +}); + +export {terrainUniforms, terrainUniformValues}; diff --git a/src/render/vertex_array_object.js b/src/render/vertex_array_object.js index fab9aee0a1b..473f9d88994 100644 --- a/src/render/vertex_array_object.js +++ b/src/render/vertex_array_object.js @@ -16,6 +16,7 @@ class VertexArrayObject { boundVertexOffset: ?number; boundDynamicVertexBuffer: ?VertexBuffer; boundDynamicVertexBuffer2: ?VertexBuffer; + boundDynamicVertexBuffer3: ?VertexBuffer; vao: any; constructor() { @@ -35,7 +36,8 @@ class VertexArrayObject { indexBuffer: ?IndexBuffer, vertexOffset: ?number, dynamicVertexBuffer: ?VertexBuffer, - dynamicVertexBuffer2: ?VertexBuffer) { + dynamicVertexBuffer2: ?VertexBuffer, + dynamicVertexBuffer3: ?VertexBuffer) { this.context = context; @@ -54,11 +56,12 @@ class VertexArrayObject { this.boundIndexBuffer !== indexBuffer || this.boundVertexOffset !== vertexOffset || this.boundDynamicVertexBuffer !== dynamicVertexBuffer || - this.boundDynamicVertexBuffer2 !== dynamicVertexBuffer2 + this.boundDynamicVertexBuffer2 !== dynamicVertexBuffer2 || + this.boundDynamicVertexBuffer3 !== dynamicVertexBuffer3 ); if (!context.extVertexArrayObject || isFreshBindRequired) { - this.freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2); + this.freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2, dynamicVertexBuffer3); } else { context.bindVertexArrayOES.set(this.vao); @@ -74,6 +77,10 @@ class VertexArrayObject { if (dynamicVertexBuffer2) { dynamicVertexBuffer2.bind(); } + + if (dynamicVertexBuffer3) { + dynamicVertexBuffer3.bind(); + } } } @@ -83,7 +90,8 @@ class VertexArrayObject { indexBuffer: ?IndexBuffer, vertexOffset: ?number, dynamicVertexBuffer: ?VertexBuffer, - dynamicVertexBuffer2: ?VertexBuffer) { + dynamicVertexBuffer2: ?VertexBuffer, + dynamicVertexBuffer3: ?VertexBuffer) { let numPrevAttributes; const numNextAttributes = program.numAttributes; @@ -104,6 +112,7 @@ class VertexArrayObject { this.boundVertexOffset = vertexOffset; this.boundDynamicVertexBuffer = dynamicVertexBuffer; this.boundDynamicVertexBuffer2 = dynamicVertexBuffer2; + this.boundDynamicVertexBuffer3 = dynamicVertexBuffer3; } else { numPrevAttributes = context.currentNumAttributes || 0; @@ -129,6 +138,9 @@ class VertexArrayObject { if (dynamicVertexBuffer2) { dynamicVertexBuffer2.enableAttributes(gl, program); } + if (dynamicVertexBuffer3) { + dynamicVertexBuffer3.enableAttributes(gl, program); + } layoutVertexBuffer.bind(); layoutVertexBuffer.setVertexAttribPointers(gl, program, vertexOffset); @@ -148,6 +160,10 @@ class VertexArrayObject { dynamicVertexBuffer2.bind(); dynamicVertexBuffer2.setVertexAttribPointers(gl, program, vertexOffset); } + if (dynamicVertexBuffer3) { + dynamicVertexBuffer3.bind(); + dynamicVertexBuffer3.setVertexAttribPointers(gl, program, vertexOffset); + } context.currentNumAttributes = numNextAttributes; } diff --git a/src/shaders/collision_box.vertex.glsl b/src/shaders/collision_box.vertex.glsl index 8fa4bfc025d..568d0235f3a 100644 --- a/src/shaders/collision_box.vertex.glsl +++ b/src/shaders/collision_box.vertex.glsl @@ -1,3 +1,4 @@ +// FIXME-3D! use 3d coordinates attribute vec2 a_pos; attribute vec2 a_anchor_pos; attribute vec2 a_extrude; diff --git a/src/shaders/line.vertex.glsl b/src/shaders/line.vertex.glsl index 9334e2b72e1..c55fab14605 100644 --- a/src/shaders/line.vertex.glsl +++ b/src/shaders/line.vertex.glsl @@ -76,10 +76,6 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - // calculate how much the perspective view squishes or stretches the extrude - float extrude_length_without_perspective = length(dist); - float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); - v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; - + v_gamma_scale = 1.0; v_width2 = vec2(outset, inset); } diff --git a/src/shaders/line_gradient.vertex.glsl b/src/shaders/line_gradient.vertex.glsl index 4b02ba5337e..f6b69765022 100644 --- a/src/shaders/line_gradient.vertex.glsl +++ b/src/shaders/line_gradient.vertex.glsl @@ -79,10 +79,6 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - // calculate how much the perspective view squishes or stretches the extrude - float extrude_length_without_perspective = length(dist); - float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); - v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; - + v_gamma_scale = 1.0; v_width2 = vec2(outset, inset); } diff --git a/src/shaders/line_pattern.vertex.glsl b/src/shaders/line_pattern.vertex.glsl index fff2daa110a..21f9581b24e 100644 --- a/src/shaders/line_pattern.vertex.glsl +++ b/src/shaders/line_pattern.vertex.glsl @@ -88,11 +88,7 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - // calculate how much the perspective view squishes or stretches the extrude - float extrude_length_without_perspective = length(dist); - float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); - v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; - + v_gamma_scale = 1.0; v_linesofar = a_linesofar; v_width2 = vec2(outset, inset); v_width = floorwidth; diff --git a/src/shaders/line_sdf.vertex.glsl b/src/shaders/line_sdf.vertex.glsl index c85140ef7c4..e4f0eb52361 100644 --- a/src/shaders/line_sdf.vertex.glsl +++ b/src/shaders/line_sdf.vertex.glsl @@ -86,13 +86,8 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - // calculate how much the perspective view squishes or stretches the extrude - float extrude_length_without_perspective = length(dist); - float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); - v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; - + v_gamma_scale = 1.0; v_tex_a = vec2(a_linesofar * u_patternscale_a.x / floorwidth, normal.y * u_patternscale_a.y + u_tex_y_a); v_tex_b = vec2(a_linesofar * u_patternscale_b.x / floorwidth, normal.y * u_patternscale_b.y + u_tex_y_b); - v_width2 = vec2(outset, inset); } diff --git a/src/shaders/shaders.js b/src/shaders/shaders.js index 25f1fabdbcb..7cd19ced73a 100644 --- a/src/shaders/shaders.js +++ b/src/shaders/shaders.js @@ -54,6 +54,8 @@ import symbolSDFFrag from './symbol_sdf.fragment.glsl'; import symbolSDFVert from './symbol_sdf.vertex.glsl'; import symbolTextAndIconFrag from './symbol_text_and_icon.fragment.glsl'; import symbolTextAndIconVert from './symbol_text_and_icon.vertex.glsl'; +import terrainFrag from './terrain.fragment.glsl'; +import terrainVert from './terrain.vertex.glsl'; export const prelude = compile(preludeFrag, preludeVert); export const background = compile(backgroundFrag, backgroundVert); @@ -81,6 +83,7 @@ export const raster = compile(rasterFrag, rasterVert); export const symbolIcon = compile(symbolIconFrag, symbolIconVert); export const symbolSDF = compile(symbolSDFFrag, symbolSDFVert); export const symbolTextAndIcon = compile(symbolTextAndIconFrag, symbolTextAndIconVert); +export const terrain = compile(terrainFrag, terrainVert); // Expand #pragmas to #ifdefs. diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 16ab111429c..8751010c494 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -5,6 +5,7 @@ attribute vec4 a_data; attribute vec4 a_pixeloffset; attribute vec3 a_projected_pos; attribute float a_fade_opacity; +attribute float a_ele; uniform bool u_is_size_zoom_constant; uniform bool u_is_size_feature_constant; @@ -54,7 +55,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele, 1); highp float camera_to_anchor_distance = projectedPoint.w; // See comments in symbol_sdf.vertex highp float distance_ratio = u_pitch_with_map ? @@ -72,7 +73,7 @@ void main() { highp float symbol_rotation = 0.0; if (u_rotate_symbol) { // See comments in symbol_sdf.vertex - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -84,8 +85,9 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); - gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), 0.0, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele, 1.0); + float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. + gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), z, 1.0); v_tex = a_tex / u_texsize; vec2 fade_opacity = unpack_opacity(a_fade_opacity); diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index 71ccf3c81d7..5a0bf8a1325 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -5,6 +5,7 @@ attribute vec4 a_data; attribute vec4 a_pixeloffset; attribute vec3 a_projected_pos; attribute float a_fade_opacity; +attribute float a_ele; // contents of a_size vary based on the type of property value // used for {text,icon}-size. @@ -65,7 +66,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -90,7 +91,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -102,8 +103,9 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); - gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), 0.0, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele, 1.0); + float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. + gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), z, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index 647310fc9c9..c0340a3f871 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -4,6 +4,7 @@ attribute vec4 a_pos_offset; attribute vec4 a_data; attribute vec3 a_projected_pos; attribute float a_fade_opacity; +attribute float a_ele; // contents of a_size vary based on the type of property value // used for {text,icon}-size. @@ -65,7 +66,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -90,7 +91,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -102,8 +103,9 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); - gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele, 1.0); + float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. + gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), z, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); diff --git a/src/shaders/terrain.fragment.glsl b/src/shaders/terrain.fragment.glsl new file mode 100644 index 00000000000..fb615811aa9 --- /dev/null +++ b/src/shaders/terrain.fragment.glsl @@ -0,0 +1,8 @@ +precision mediump float; + +uniform sampler2D u_texture; +varying vec2 v_texture_pos; + +void main() { + gl_FragColor = vec4(texture2D(u_texture, v_texture_pos).xyz, 1.0); +} diff --git a/src/shaders/terrain.vertex.glsl b/src/shaders/terrain.vertex.glsl new file mode 100644 index 00000000000..fa5a67062d5 --- /dev/null +++ b/src/shaders/terrain.vertex.glsl @@ -0,0 +1,9 @@ +attribute vec3 a_pos; + +uniform mat4 u_matrix; +varying vec2 v_texture_pos; + +void main() { + v_texture_pos = a_pos.xy / 8192.0; + gl_Position = u_matrix * vec4((a_pos), 1.0); +} diff --git a/src/source/raster_dem_tile_source.js b/src/source/raster_dem_tile_source.js index bd36edfdda7..edd64c34c1b 100644 --- a/src/source/raster_dem_tile_source.js +++ b/src/source/raster_dem_tile_source.js @@ -18,7 +18,7 @@ import type {Callback} from '../types/callback'; import type {RasterDEMSourceSpecification} from '../style-spec/types'; class RasterDEMTileSource extends RasterTileSource implements Source { - encoding: "mapbox" | "terrarium"; + encoding: "mapbox" | "terrarium" | "mtk"; constructor(id: string, options: RasterDEMSourceSpecification, dispatcher: Dispatcher, eventedParent: Evented) { super(id, options, dispatcher, eventedParent); @@ -73,14 +73,15 @@ class RasterDEMTileSource extends RasterTileSource implements Source { } } - function done(err, dem) { + function done(err, data) { if (err) { tile.state = 'errored'; callback(err); } - if (dem) { - tile.dem = dem; + if (data) { + tile.dem = data.dem; + tile.mesh = data.mesh; tile.needsHillshadePrepare = true; tile.state = 'loaded'; callback(null); diff --git a/src/source/raster_dem_tile_worker_source.js b/src/source/raster_dem_tile_worker_source.js index 416462ea169..be84ccaefe8 100644 --- a/src/source/raster_dem_tile_worker_source.js +++ b/src/source/raster_dem_tile_worker_source.js @@ -1,9 +1,11 @@ // @flow +import Martini from '@mapbox/martini'; import DEMData from '../data/dem_data'; import {RGBAImage} from '../util/image'; import window from '../util/window'; - +import EXTENT from '../data/extent'; +import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; import type Actor from '../util/actor'; import type { WorkerDEMTileParameters, @@ -29,7 +31,7 @@ class RasterDEMTileWorkerSource { const dem = new DEMData(uid, imagePixels, encoding); this.loaded = this.loaded || {}; this.loaded[uid] = dem; - callback(null, dem); + callback(null, { dem: dem, mesh: this.createTerrainMesh(dem) }); } getImageData(imgBitmap: ImageBitmap): RGBAImage { @@ -50,6 +52,28 @@ class RasterDEMTileWorkerSource { return new RGBAImage({width: imgData.width, height: imgData.height}, imgData.data); } + createTerrainMesh(dem) { + // load terrain from dem data + const dim = dem.dim, dim1 = dim + 1; // add right/bottom overlap + const terrain = new Array(dim1 * dim1); + for (let y=0; y this._loadQueue.forEach(tile => { + this._source.loadTile(tile, () => this._tileLoaded(tile)); + })); + } + + /** + * Removes tiles that are outside the viewport and adds new tiles that are inside the viewport. + * @private + */ + update(transform: Transform, context: Context) { + let idealTileIDs = this.getRenderableTileIDs(transform).filter(id => !this._tiles[id.key]); + for (const tileID of idealTileIDs) { + let tile = this._tiles[tileID.key] = this._createEmptyTile(tileID); + if (this._source && this._source.loaded()) { + this._source.loadTile(tile, () => this._tileLoaded(tile)); + } else { + this._loadQueue.push(tile); // remember for loading later + } + } + } + + getRenderableTileIDs(transform: Transform) { + return transform.coveringTiles({ tileSize: 512, minzoom: this.minzoom, maxzoom: this.maxzoom }); + } + + /** + * get terrain tile by the x/y/z coordinate. + * FIXME-3D! may speedup with separate lookup-table + * @private + */ + getTileByCanonical(tileID: CanonicalTileID): Tile { + for (let key in this._tiles) + if (tileID.equals(this._tiles[key].tileID.canonical)) + return this._tiles[key]; + return null; + } + + /** + * get terrain tile by the TileID key + * @private + */ + getTileByID(tileID: OverscaledTileID): Tile { + return this._tiles[tileID.key]; + } + + /** + * get the Elevation for given coordinate + * FIXME-3D: make linear interpolation + * @param {OverscaledTileID} tileID + * @param {number} x between 0 .. EXTENT + * @param {number} y between 0 .. EXTENT + */ + getElevation(tileID: OverscaledTileID, x: number, y: number): number { + let dz = tileID.overscaledZ > this.maxzoom ? tileID.overscaledZ - this.maxzoom : 0; + let tile = this.getTileByCanonical(tileID.scaledTo(tileID.overscaledZ - dz).canonical); + return tile && tile.dem && x > 0 && y > 0 //FIXME-3D handle negative coordinates + ? tile.dem.get(Math.floor(x / EXTENT * tile.dem.dim), Math.floor(y / EXTENT * tile.dem.dim)) + : 0; + } + + /** + * after a tile is loaded: + * - recreate terrain-mesh webgl segments + * - recalculate elevation of all symbols of all tiles + * @param {Tile} tile + */ + _tileLoaded(tile: Tile) { + if (tile.state == "loaded") tile.segments = null; + for (let s in this._style.sourceCaches) { + for (let key in this._style.sourceCaches[s]._tiles) { + let t = this._style.sourceCaches[s]._tiles[key]; + if (t && t.hasSymbolBuckets) t.hasElevation = false; + } + } + } + + _createEmptyTile(tileID: OverscaledTileID) { + tileID.posMatrix = mat4.create(); + mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + let tile = new Tile(tileID, this.tileSize * tileID.overscaleFactor()); + const vertexArray = new Pos3DArray(), indexArray = new TriangleIndexArray(); + // create an empty terrain-mesh. (e.g. 2 flat triangles) + // FIXME-3D: get elevation from parent/children or surrounding tiles + [[1, 1, 0], [0, 0, 0], [0, 1, 0], [1, 0, 0]].forEach(xy => vertexArray.emplaceBack(...xy.map(c => c * EXTENT))); + [[1, 0, 3], [0, 1, 2]].forEach(xyz => indexArray.emplaceBack(...xyz)) + tile.mesh = { indexArray: indexArray, vertexArray: vertexArray }; + return tile; + } + +} +export default TerrainSourceCache; diff --git a/src/source/worker_source.js b/src/source/worker_source.js index c800049e3b3..29e31955179 100644 --- a/src/source/worker_source.js +++ b/src/source/worker_source.js @@ -8,7 +8,6 @@ import type {OverscaledTileID} from './tile_id'; import type {Bucket} from '../data/bucket'; import type FeatureIndex from '../data/feature_index'; import type {CollisionBoxArray} from '../data/array_types'; -import type DEMData from '../data/dem_data'; import type {StyleGlyph} from '../style/style_glyph'; import type {StyleImage} from '../style/style_image'; import type {PromoteIdSpecification} from '../style-spec/types'; @@ -36,7 +35,7 @@ export type WorkerTileParameters = TileParameters & { export type WorkerDEMTileParameters = TileParameters & { coord: { z: number, x: number, y: number, w: number }, rawImageData: RGBAImage | ImageBitmap, - encoding: "mapbox" | "terrarium" + encoding: "mapbox" | "terrarium" | "mtk" }; export type WorkerTileResult = { @@ -54,7 +53,7 @@ export type WorkerTileResult = { }; export type WorkerTileCallback = (error: ?Error, result: ?WorkerTileResult) => void; -export type WorkerDEMTileCallback = (err: ?Error, result: ?DEMData) => void; +export type WorkerDEMTileCallback = (err: ?Error, result: ?any) => void; /** * May be implemented by custom source types to provide code that can be run on diff --git a/src/style-spec/reference/v8.json b/src/style-spec/reference/v8.json index 0a29e67b372..0917222b8c2 100644 --- a/src/style-spec/reference/v8.json +++ b/src/style-spec/reference/v8.json @@ -336,6 +336,9 @@ "terrarium": { "doc": "Terrarium format PNG tiles. See https://aws.amazon.com/es/public-datasets/terrain/ for more info." }, + "mtk": { + "doc": "MTK format PNG tiles." + }, "mapbox": { "doc": "Mapbox Terrain RGB tiles. See https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb for more info." } diff --git a/src/style-spec/types.js b/src/style-spec/types.js index 34a380e1ba0..69ba407f0f9 100644 --- a/src/style-spec/types.js +++ b/src/style-spec/types.js @@ -115,8 +115,9 @@ export type RasterDEMSourceSpecification = { "maxzoom"?: number, "tileSize"?: number, "attribution"?: string, - "encoding"?: "terrarium" | "mapbox", - "volatile"?: boolean + "encoding"?: "terrarium" | "mapbox" | "mtk", + "volatile"?: boolean, + "useForTerrain"?: boolean } export type GeoJSONSourceSpecification = {| diff --git a/src/style/style.js b/src/style/style.js index 70523941871..4e9f2786610 100644 --- a/src/style/style.js +++ b/src/style/style.js @@ -23,6 +23,7 @@ import { } from '../source/source'; import {queryRenderedFeatures, queryRenderedSymbols, querySourceFeatures} from '../source/query_features'; import SourceCache from '../source/source_cache'; +import TerrainSourceCache from '../source/terrain_source_cache'; import GeoJSONSource from '../source/geojson_source'; import styleSpec from '../style-spec/reference/latest'; import getWorkerPool from '../util/global_worker_pool'; @@ -117,6 +118,7 @@ class Style extends Evented { _serializedLayers: {[_: string]: Object}; _order: Array; sourceCaches: {[_: string]: SourceCache}; + terrainSourceCaches: TerrainSourceCache; zoomHistory: ZoomHistory; _loaded: boolean; _rtlTextPluginCallback: Function; @@ -154,10 +156,15 @@ class Style extends Evented { this._serializedLayers = {}; this._order = []; this.sourceCaches = {}; + this.terrainSourceCache = new TerrainSourceCache(this); this.zoomHistory = new ZoomHistory(); this._loaded = false; this._availableImages = []; + // make elevtaion accessible from map.transform + // FIXME-3D! refactor this hack + map.transform.terrainSourceCache = this.terrainSourceCache; + this._resetUpdates(); this.dispatcher.broadcast('setReferrer', getReferrer()); @@ -576,6 +583,8 @@ class Style extends Evented { if (this.map && this.map._collectResourceTiming) (source: any).collectResourceTiming = true; const sourceCache = this.sourceCaches[id] = new SourceCache(id, source, this.dispatcher); + // FIXME-3D: is is may be ugly. Should we use map.setTerrain like mapbox does it? + if (source.useForTerrain) this.terrainSourceCache.setSourceCache(sourceCache); sourceCache.style = this; sourceCache.setEventedParent(this, () => ({ isSourceLoaded: this.loaded(), @@ -1252,6 +1261,7 @@ class Style extends Evented { for (const id in this.sourceCaches) { this.sourceCaches[id].update(transform); } + this.terrainSourceCache.update(transform); } _generateCollisionBoxes() { diff --git a/src/symbol/collision_index.js b/src/symbol/collision_index.js index f553e610761..3c200c4b7fb 100644 --- a/src/symbol/collision_index.js +++ b/src/symbol/collision_index.js @@ -6,7 +6,7 @@ import PathInterpolator from './path_interpolator'; import * as intersectionTests from '../util/intersection_tests'; import Grid from './grid_index'; -import {mat4} from 'gl-matrix'; +import {mat4, vec4} from 'gl-matrix'; import ONE_EM from '../symbol/one_em'; import assert from 'assert'; @@ -66,8 +66,8 @@ class CollisionIndex { this.gridBottomBoundary = transform.height + 2 * viewportPadding; } - placeCollisionBox(collisionBox: SingleCollisionBox, allowOverlap: boolean, textPixelRatio: number, posMatrix: mat4, collisionGroupPredicate?: any): { box: Array, offscreen: boolean } { - const projectedPoint = this.projectAndGetPerspectiveRatio(posMatrix, collisionBox.anchorPointX, collisionBox.anchorPointY); + placeCollisionBox(collisionBox: SingleCollisionBox, allowOverlap: boolean, textPixelRatio: number, posMatrix: mat4, collisionGroupPredicate?: any, getElevation: any): { box: Array, offscreen: boolean } { + const projectedPoint = this.projectAndGetPerspectiveRatio(posMatrix, collisionBox.anchorPointX, collisionBox.anchorPointY, getElevation); const tileToViewport = textPixelRatio * projectedPoint.perspectiveRatio; const tlX = collisionBox.x1 * tileToViewport + projectedPoint.point.x; const tlY = collisionBox.y1 * tileToViewport + projectedPoint.point.y; @@ -100,16 +100,17 @@ class CollisionIndex { pitchWithMap: boolean, collisionGroupPredicate?: any, circlePixelDiameter: number, - textPixelPadding: number): { circles: Array, offscreen: boolean, collisionDetected: boolean } { + textPixelPadding: number, + getElevation: any): { circles: Array, offscreen: boolean, collisionDetected: boolean } { const placedCollisionCircles = []; const tileUnitAnchorPoint = new Point(symbol.anchorX, symbol.anchorY); - const screenAnchorPoint = projection.project(tileUnitAnchorPoint, posMatrix); + const screenAnchorPoint = projection.project(tileUnitAnchorPoint, posMatrix, getElevation); const perspectiveRatio = projection.getPerspectiveRatio(this.transform.cameraToCenterDistance, screenAnchorPoint.signedDistanceFromCamera); const labelPlaneFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio; const labelPlaneFontScale = labelPlaneFontSize / ONE_EM; - const labelPlaneAnchorPoint = projection.project(tileUnitAnchorPoint, labelPlaneMatrix).point; + const labelPlaneAnchorPoint = projection.project(tileUnitAnchorPoint, labelPlaneMatrix, getElevation).point; const projectionCache = {}; const lineOffsetX = symbol.lineOffsetX * labelPlaneFontScale; @@ -126,7 +127,8 @@ class CollisionIndex { symbol, lineVertexArray, labelPlaneMatrix, - projectionCache); + projectionCache, + getElevation); let collisionDetected = false; let inGrid = false; @@ -156,7 +158,7 @@ class CollisionIndex { // The path might need to be converted into screen space if a pitched map is used as the label space if (labelToScreenMatrix) { - const screenSpacePath = projectedPath.map(p => projection.project(p, labelToScreenMatrix)); + const screenSpacePath = projectedPath.map(p => projection.project(p, labelToScreenMatrix, getElevation)); // Do not try to place collision circles if even of the points is behind the camera. // This is a plausible scenario with big camera pitch angles @@ -334,9 +336,9 @@ class CollisionIndex { } } - projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number) { - const p = [x, y, 0, 1]; - projection.xyTransformMat4(p, p, posMatrix); + projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number, getElevation: any) { + const p = [x, y, getElevation(x, y), 1]; + vec4.transformMat4(p, p, posMatrix); const a = new Point( (((p[0] / p[3] + 1) / 2) * this.transform.width) + viewportPadding, (((-p[1] / p[3] + 1) / 2) * this.transform.height) + viewportPadding diff --git a/src/symbol/placement.js b/src/symbol/placement.js index b7e06fb865a..ae0fcfd65b0 100644 --- a/src/symbol/placement.js +++ b/src/symbol/placement.js @@ -145,7 +145,7 @@ function shiftVariableCollisionBox(collisionBox: SingleCollisionBox, shiftX: number, shiftY: number, rotateWithMap: boolean, pitchWithMap: boolean, angle: number) { - const {x1, x2, y1, y2, anchorPointX, anchorPointY} = collisionBox; + const {x1, x2, y1, y2, anchorPointX, anchorPointY, elevation} = collisionBox; const rotatedOffset = new Point(shiftX, shiftY); if (rotateWithMap) { rotatedOffset._rotate(pitchWithMap ? angle : -angle); @@ -157,7 +157,8 @@ function shiftVariableCollisionBox(collisionBox: SingleCollisionBox, y2: y2 + rotatedOffset.y, // symbol anchor point stays the same regardless of text-anchor anchorPointX, - anchorPointY + anchorPointY, + elevation }; } @@ -311,7 +312,7 @@ export class Placement { attemptAnchorPlacement(anchor: TextAnchor, textBox: SingleCollisionBox, width: number, height: number, textBoxScale: number, rotateWithMap: boolean, pitchWithMap: boolean, textPixelRatio: number, posMatrix: mat4, collisionGroup: CollisionGroup, - textAllowOverlap: boolean, symbolInstance: SymbolInstance, bucket: SymbolBucket, orientation: number, iconBox: ?SingleCollisionBox): ?{ shift: Point, placedGlyphBoxes: { box: Array, offscreen: boolean } } { + textAllowOverlap: boolean, symbolInstance: SymbolInstance, bucket: SymbolBucket, orientation: number, iconBox: ?SingleCollisionBox, getElevation: any): ?{ shift: Point, placedGlyphBoxes: { box: Array, offscreen: boolean } } { const textOffset = [symbolInstance.textOffset0, symbolInstance.textOffset1]; const shift = calculateVariableLayoutShift(anchor, width, height, textOffset, textBoxScale); @@ -320,14 +321,14 @@ export class Placement { shiftVariableCollisionBox( textBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle), - textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); + textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate, getElevation); if (iconBox) { const placedIconBoxes = this.collisionIndex.placeCollisionBox( shiftVariableCollisionBox( iconBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle), - textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); + textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate, getElevation); if (placedIconBoxes.box.length === 0) return; } @@ -439,6 +440,14 @@ export class Placement { verticalTextFeatureIndex = collisionArrays.verticalTextFeatureIndex; } + // update elevtaion of collisionArrays + let tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; + let getElevation = (x: number, y: number) => this.transform.terrainSourceCache.getElevation(tileID, x, y); + for (let boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { + const box = collisionArrays[boxType]; + if (box) box.elevation = getElevation(box.anchorPointX, box.anchorPointY); + } + const textBox = collisionArrays.textBox; if (textBox) { @@ -474,7 +483,7 @@ export class Placement { if (!layout.get('text-variable-anchor')) { const placeBox = (collisionTextBox, orientation) => { const placedFeature = this.collisionIndex.placeCollisionBox(collisionTextBox, textAllowOverlap, - textPixelRatio, posMatrix, collisionGroup.predicate); + textPixelRatio, posMatrix, collisionGroup.predicate, getElevation); if (placedFeature && placedFeature.box && placedFeature.box.length) { this.markUsedOrientation(bucket, orientation, symbolInstance); this.placedOrientations[symbolInstance.crossTileID] = orientation; @@ -526,7 +535,7 @@ export class Placement { const result = this.attemptAnchorPlacement( anchor, collisionTextBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, - collisionGroup, allowOverlap, symbolInstance, bucket, orientation, variableIconBox); + collisionGroup, allowOverlap, symbolInstance, bucket, orientation, variableIconBox, getElevation); if (result) { placedBox = result.placedGlyphBoxes; @@ -600,7 +609,8 @@ export class Placement { pitchWithMap, collisionGroup.predicate, circlePixelDiameter, - textPixelPadding); + textPixelPadding, + getElevation); assert(!placedGlyphCircles.circles.length || (!placedGlyphCircles.collisionDetected || showCollisionBoxes)); // If text-allow-overlap is set, force "placedCircles" to true @@ -624,7 +634,7 @@ export class Placement { rotateWithMap, pitchWithMap, this.transform.angle) : iconBox; return this.collisionIndex.placeCollisionBox(shiftedIconBox, - iconAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); + iconAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate, getElevation); }; if (placedVerticalText && placedVerticalText.box && placedVerticalText.box.length && collisionArrays.verticalIconBox) { diff --git a/src/symbol/projection.js b/src/symbol/projection.js index e0c16142989..965fb60cb16 100644 --- a/src/symbol/projection.js +++ b/src/symbol/projection.js @@ -103,9 +103,9 @@ function getGlCoordMatrix(posMatrix: mat4, } } -function project(point: Point, matrix: mat4) { - const pos = [point.x, point.y, 0, 1]; - xyTransformMat4(pos, pos, matrix); +function project(point: Point, matrix: mat4, getElevation: any) { + const pos = [point.x, point.y, getElevation(point.x, point.y), 1]; + vec4.transformMat4(pos, pos, matrix); const w = pos[3]; return { point: new Point(pos[0] / w, pos[1] / w), @@ -140,7 +140,8 @@ function updateLineLabels(bucket: SymbolBucket, labelPlaneMatrix: mat4, glCoordMatrix: mat4, pitchWithMap: boolean, - keepUpright: boolean) { + keepUpright: boolean, + getElevation: any) { const sizeData = isText ? bucket.textSizeData : bucket.iconSizeData; const partiallyEvaluatedSize = symbolSize.evaluateSizeForZoom(sizeData, painter.transform.zoom); @@ -172,7 +173,7 @@ function updateLineLabels(bucket: SymbolBucket, // Awkward... but we're counting on the paired "vertical" symbol coming immediately after its horizontal counterpart useVertical = false; - const anchorPos = [symbol.anchorX, symbol.anchorY, 0, 1]; + const anchorPos = [symbol.anchorX, symbol.anchorY, getElevation(symbol.anchorX, symbol.anchorY), 1]; vec4.transformMat4(anchorPos, anchorPos, posMatrix); // Don't bother calculating the correct point for invisible labels. @@ -188,18 +189,18 @@ function updateLineLabels(bucket: SymbolBucket, const pitchScaledFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio; const tileAnchorPoint = new Point(symbol.anchorX, symbol.anchorY); - const anchorPoint = project(tileAnchorPoint, labelPlaneMatrix).point; + const anchorPoint = project(tileAnchorPoint, labelPlaneMatrix, getElevation).point; const projectionCache = {}; const placeUnflipped: any = placeGlyphsAlongLine(symbol, pitchScaledFontSize, false /*unflipped*/, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, - bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio); + bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevation); useVertical = placeUnflipped.useVertical; if (placeUnflipped.notEnoughRoom || useVertical || (placeUnflipped.needsFlipping && placeGlyphsAlongLine(symbol, pitchScaledFontSize, true /*flipped*/, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, - bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio).notEnoughRoom)) { + bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevation).notEnoughRoom)) { hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); } } @@ -211,7 +212,7 @@ function updateLineLabels(bucket: SymbolBucket, } } -function placeFirstAndLastGlyph(fontScale: number, glyphOffsetArray: GlyphOffsetArray, lineOffsetX: number, lineOffsetY: number, flip: boolean, anchorPoint: Point, tileAnchorPoint: Point, symbol: any, lineVertexArray: SymbolLineVertexArray, labelPlaneMatrix: mat4, projectionCache: any) { +function placeFirstAndLastGlyph(fontScale: number, glyphOffsetArray: GlyphOffsetArray, lineOffsetX: number, lineOffsetY: number, flip: boolean, anchorPoint: Point, tileAnchorPoint: Point, symbol: any, lineVertexArray: SymbolLineVertexArray, labelPlaneMatrix: mat4, projectionCache: any, getElevation: any) { const glyphEndIndex = symbol.glyphStartIndex + symbol.numGlyphs; const lineStartIndex = symbol.lineStartIndex; const lineEndIndex = symbol.lineStartIndex + symbol.lineLength; @@ -220,12 +221,12 @@ function placeFirstAndLastGlyph(fontScale: number, glyphOffsetArray: GlyphOffset const lastGlyphOffset = glyphOffsetArray.getoffsetX(glyphEndIndex - 1); const firstPlacedGlyph = placeGlyphAlongLine(fontScale * firstGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, - lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache); + lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation); if (!firstPlacedGlyph) return null; const lastPlacedGlyph = placeGlyphAlongLine(fontScale * lastGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, - lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache); + lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation); if (!lastPlacedGlyph) return null; @@ -253,7 +254,7 @@ function requiresOrientationChange(writingMode, firstPoint, lastPoint, aspectRat return null; } -function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio) { +function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevation) { const fontScale = fontSize / 24; const lineOffsetX = symbol.lineOffsetX * fontScale; const lineOffsetY = symbol.lineOffsetY * fontScale; @@ -266,12 +267,12 @@ function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, la // Place the first and the last glyph in the label first, so we can figure out // the overall orientation of the label and determine whether it needs to be flipped in keepUpright mode - const firstAndLastGlyph = placeFirstAndLastGlyph(fontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache); + const firstAndLastGlyph = placeFirstAndLastGlyph(fontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation); if (!firstAndLastGlyph) { return {notEnoughRoom: true}; } - const firstPoint = project(firstAndLastGlyph.first.point, glCoordMatrix).point; - const lastPoint = project(firstAndLastGlyph.last.point, glCoordMatrix).point; + const firstPoint = project(firstAndLastGlyph.first.point, glCoordMatrix, getElevation).point; + const lastPoint = project(firstAndLastGlyph.last.point, glCoordMatrix, getElevation).point; if (keepUpright && !flip) { const orientationChange = requiresOrientationChange(symbol.writingMode, firstPoint, lastPoint, aspectRatio); @@ -292,17 +293,17 @@ function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, la // Only a single glyph to place // So, determine whether to flip based on projected angle of the line segment it's on if (keepUpright && !flip) { - const a = project(tileAnchorPoint, posMatrix).point; + const a = project(tileAnchorPoint, posMatrix, getElevation).point; const tileVertexIndex = (symbol.lineStartIndex + symbol.segment + 1); // $FlowFixMe const tileSegmentEnd = new Point(lineVertexArray.getx(tileVertexIndex), lineVertexArray.gety(tileVertexIndex)); - const projectedVertex = project(tileSegmentEnd, posMatrix); + const projectedVertex = project(tileSegmentEnd, posMatrix, getElevation); // We know the anchor will be in the viewport, but the end of the line segment may be // behind the plane of the camera, in which case we can use a point at any arbitrary (closer) // point on the segment. const b = (projectedVertex.signedDistanceFromCamera > 0) ? projectedVertex.point : - projectTruncatedLineSegment(tileAnchorPoint, tileSegmentEnd, a, 1, posMatrix); + projectTruncatedLineSegment(tileAnchorPoint, tileSegmentEnd, a, 1, posMatrix, getElevation); const orientationChange = requiresOrientationChange(symbol.writingMode, a, b, aspectRatio); if (orientationChange) { @@ -324,12 +325,12 @@ function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, la return {}; } -function projectTruncatedLineSegment(previousTilePoint: Point, currentTilePoint: Point, previousProjectedPoint: Point, minimumLength: number, projectionMatrix: mat4) { +function projectTruncatedLineSegment(previousTilePoint: Point, currentTilePoint: Point, previousProjectedPoint: Point, minimumLength: number, projectionMatrix: mat4, getElevation: any) { // We are assuming "previousTilePoint" won't project to a point within one unit of the camera plane // If it did, that would mean our label extended all the way out from within the viewport to a (very distant) // point near the plane of the camera. We wouldn't be able to render the label anyway once it crossed the // plane of the camera. - const projectedUnitVertex = project(previousTilePoint.add(previousTilePoint.sub(currentTilePoint)._unit()), projectionMatrix).point; + const projectedUnitVertex = project(previousTilePoint.add(previousTilePoint.sub(currentTilePoint)._unit()), projectionMatrix, getElevation).point; const projectedUnitSegment = previousProjectedPoint.sub(projectedUnitVertex); return previousProjectedPoint.add(projectedUnitSegment._mult(minimumLength / projectedUnitSegment.mag())); @@ -346,7 +347,8 @@ function placeGlyphAlongLine(offsetX: number, lineEndIndex: number, lineVertexArray: SymbolLineVertexArray, labelPlaneMatrix: mat4, - projectionCache: {[_: number]: Point}) { + projectionCache: {[_: number]: Point}, + getElevation: any) { const combinedOffsetX = flip ? offsetX - lineOffsetX : @@ -388,7 +390,7 @@ function placeGlyphAlongLine(offsetX: number, current = projectionCache[currentIndex]; if (current === undefined) { const currentVertex = new Point(lineVertexArray.getx(currentIndex), lineVertexArray.gety(currentIndex)); - const projection = project(currentVertex, labelPlaneMatrix); + const projection = project(currentVertex, labelPlaneMatrix, getElevation); if (projection.signedDistanceFromCamera > 0) { current = projectionCache[currentIndex] = projection.point; } else { @@ -399,7 +401,7 @@ function placeGlyphAlongLine(offsetX: number, tileAnchorPoint : new Point(lineVertexArray.getx(previousLineVertexIndex), lineVertexArray.gety(previousLineVertexIndex)); // Don't cache because the new vertex might not be far enough out for future glyphs on the same segment - current = projectTruncatedLineSegment(previousTilePoint, currentVertex, prev, absOffsetX - distanceToPrev + 1, labelPlaneMatrix); + current = projectTruncatedLineSegment(previousTilePoint, currentVertex, prev, absOffsetX - distanceToPrev + 1, labelPlaneMatrix, getElevation); } } From abed6841fabba2c66ecbcb0047477a3c76ead360 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 2 Jun 2021 08:14:20 +0200 Subject: [PATCH 002/138] render more tiles to avoid wholes on tiled maps at canvas bottom --- src/geo/transform.js | 6 ++++-- src/util/primitives.js | 16 +++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/geo/transform.js b/src/geo/transform.js index cbfa911230c..af12b2ec21e 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -346,8 +346,10 @@ class Transform { const newRootTile = (wrap: number): any => { return { - // All tiles are on zero elevation plane => z difference is zero - aabb: new Aabb([wrap * numTiles, 0, 0], [(wrap + 1) * numTiles, numTiles, 0]), + // FIXME-3D! -5 .. 5 is enough for rendering front elevation tiles, dont know why + // but with this simple hack, there a rendered to many tiles outside the viewport, + // which is a performance issue + aabb: new Aabb([wrap * numTiles, 0, -5], [(wrap + 1) * numTiles, numTiles, 5]), zoom: 0, x: 0, y: 0, diff --git a/src/util/primitives.js b/src/util/primitives.js index b1cd69e6fe3..c3bd55b65f6 100644 --- a/src/util/primitives.js +++ b/src/util/primitives.js @@ -91,15 +91,17 @@ class Aabb { intersects(frustum: Frustum): number { // Execute separating axis test between two convex objects to find intersections // Each frustum plane together with 3 major axes define the separating axes - // Note: test only 4 points as both min and max points have equal elevation - assert(this.min[2] === 0 && this.max[2] === 0); const aabbPoints = [ - [this.min[0], this.min[1], 0.0, 1], - [this.max[0], this.min[1], 0.0, 1], - [this.max[0], this.max[1], 0.0, 1], - [this.min[0], this.max[1], 0.0, 1] - ]; + [this.min[0], this.min[1], this.min[2], 1], + [this.max[0], this.min[1], this.min[2], 1], + [this.max[0], this.max[1], this.min[2], 1], + [this.min[0], this.max[1], this.min[2], 1], + [this.min[0], this.min[1], this.max[2], 1], + [this.max[0], this.min[1], this.max[2], 1], + [this.max[0], this.max[1], this.max[2], 1], + [this.min[0], this.max[1], this.max[2], 1] + ]; let fullyInside = true; From 5f77f5c08607f4b17dda56e50074db2ad98fe3ab Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 2 Jun 2021 08:33:05 +0200 Subject: [PATCH 003/138] Proof of concept! to get mercator-coords from the 3d-mesh on screen. This is done with an extra framebuffer in which all tile coordinates are rendered in an encoded rgb value. Dont know why, but this framebuffer looks very inperformant. As advantage, grabbing coordinates from screen is very fast. It may help to render the framebuffer only every 100ms instead of every requestAnimationFrame? This logic is currently used in * map.project * map.unproject. Other usecases are: * elevate camera over terrain * use in mouse-events * use in queryRenderedFeatures --- src/geo/transform.js | 55 ++++++++++++++++++++++++++++-- src/render/draw_terrain.js | 33 +++++++++++++++++- src/render/painter.js | 4 ++- src/shaders/terrain.fragment.glsl | 2 +- src/source/terrain_source_cache.js | 40 +++++++++++++++++++++- src/ui/map.js | 4 +-- src/util/primitives.js | 18 +++++----- 7 files changed, 139 insertions(+), 17 deletions(-) diff --git a/src/geo/transform.js b/src/geo/transform.js index af12b2ec21e..5b407d44823 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -10,6 +10,8 @@ import EXTENT from '../data/extent'; import {vec4, mat4, mat2, vec2} from 'gl-matrix'; import {Aabb, Frustum} from '../util/primitives.js'; import EdgeInsets from './edge_insets'; +import Texture from '../render/texture'; +import browser from '../util/browser'; import {UnwrappedTileID, OverscaledTileID, CanonicalTileID} from '../source/tile_id'; import type {PaddingOptions} from './edge_insets'; @@ -471,6 +473,22 @@ class Transform { return this.coordinatePoint(this.locationCoordinate(lnglat)); } + /** + * Given a location, return the screen point that corresponds to it + * @param {LngLat} lnglat location + * @returns {Point} screen point + * @private + */ + locationPoint3D(lnglat: LngLat) { + const merc = this.locationCoordinate(lnglat); + const tileSize = this.terrainSourceCache.tileSize, worldSize = (1 << this.tileZoom) * tileSize; + const mercX = merc.x * worldSize, mercY = merc.y * worldSize; + const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); + const tileID = new OverscaledTileID(this.tileZoom, 1, this.tileZoom, tileX, tileY); + const elevation = this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize); + return this.coordinatePoint(this.locationCoordinate(lnglat), elevation); + } + /** * Given a point on screen, return its lnglat * @param {Point} p screen point @@ -481,6 +499,16 @@ class Transform { return this.coordinateLocation(this.pointCoordinate(p)); } + /** + * Given a point on screen, return its lnglat + * @param {Point} p screen point + * @returns {LngLat} lnglat location + * @private + */ + pointLocation3D(p: Point) { + return this.coordinateLocation(this.pointCoordinate3D(p)); + } + /** * Given a geographical lnglat, return an unrounded * coordinate that represents it at this transform's zoom level. @@ -530,14 +558,37 @@ class Transform { interpolate(y0, y1, t) / this.worldSize); } + // FIXME-3D! mouseout events may contains coordinates outside the coords-framebuffer + pointCoordinate3D(p: Point) { + const rgba = new Uint8Array(4); + const painter = this.terrainSourceCache._style.map.painter, context = painter.context, gl = context.gl; + // grab coordinate pixel from coordinates framebuffer + context.bindFramebuffer.set(this.terrainSourceCache.getCoordsFramebuffer(context).framebuffer); + gl.readPixels(p.x, painter.height / browser.devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); + context.bindFramebuffer.set(null); + // decode coordinates (encoding see terrain-source-cache) + let y = (rgba[3] >> 1) | ((rgba[2] & 3) << 7); + let x = (rgba[2] >> 2) | ((rgba[1] & 7) << 6); + let i = (rgba[1] >> 3) | (rgba[0] << 5); + let tile = this.terrainSourceCache._coordsIndex[i]; + if (!tile) return this.pointCoordinate(p); // FIXME! remove this hack + let worldSize = (1 << tile.tileID.canonical.z) * tile.tileSize; + return new MercatorCoordinate( + (tile.tileID.canonical.x * tile.tileSize + x) / worldSize, + (tile.tileID.canonical.y * tile.tileSize + y) / worldSize, + this.terrainSourceCache.getElevation(tile.tileID, x, y) + ); + } + /** * Given a coordinate, return the screen point that corresponds to it * @param {Coordinate} coord * @returns {Point} screen point + * @returns {number} elevation, default 0 * @private */ - coordinatePoint(coord: MercatorCoordinate) { - const p = [coord.x * this.worldSize, coord.y * this.worldSize, 0, 1]; + coordinatePoint(coord: MercatorCoordinate, elevation: number=0) { + const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1]; vec4.transformMat4(p, p, this.pixelMatrix); return new Point(p[0] / p[3], p[1] / p[3]); } diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index 57f4d90ba0f..279ea0c102b 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -10,6 +10,32 @@ import CullFaceMode from '../gl/cull_face_mode'; import pos3DAttributes from '../data/pos3d_attributes'; import Texture from './texture'; import Color from '../style-spec/util/color'; +import ColorMode from '../gl/color_mode'; +import browser from '../util/browser'; + +function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { + const tiles = Object.values(sourceCache._tiles).filter(t => t.unprojectTileID && t.coordsTexture); + if (!tiles.length) return; + + const context = painter.context; + const gl = context.gl; + const colorMode = ColorMode.unblended; + const program = painter.useProgram('terrain'); + + // draw tile-coords into framebuffer + context.bindFramebuffer.set(sourceCache.getCoordsFramebuffer(painter.context).framebuffer); + context.viewport.set([0, 0, painter.width / browser.devicePixelRatio, painter.height / browser.devicePixelRatio]); + + for (const tile of tiles) { + context.activeTexture.set(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tile.coordsTexture.texture); + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); + const posMatrix = painter.transform.calculatePosMatrix(tile.unprojectTileID.toUnwrapped()); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, + terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); + tile.unprojectTileID = null; + } +} function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { const tiles = Object.values(sourceCache._tiles).filter(t => t.needsRedraw); @@ -48,6 +74,10 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { tile.vertexBuffer = context.createVertexBuffer(tile.mesh.vertexArray, pos3DAttributes.members); tile.segments = SegmentVector.simpleSegment(0, 0, tile.mesh.vertexArray.length, tile.mesh.indexArray.length); } + if (!tile.coordsTexture) { + tile.coordsTexture = new Texture(context, tile.coords, context.gl.RGBA, {premultiply: false}); + tile.coordsTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + } // empty framebuffer context.bindFramebuffer.set(tile.fbo.framebuffer); context.clear({ color: Color.transparent }); @@ -57,5 +87,6 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { export { prepareTerrain, - drawTerrain + drawTerrain, + drawTerrainCoords }; diff --git a/src/render/painter.js b/src/render/painter.js index dbecc93ba01..bdfe4a60947 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -36,7 +36,7 @@ import raster from './draw_raster'; import background from './draw_background'; import debug, {drawDebugPadding} from './draw_debug'; import custom from './draw_custom'; -import {prepareTerrain, drawTerrain} from './draw_terrain'; +import {prepareTerrain, drawTerrain, drawTerrainCoords} from './draw_terrain'; const draw = { symbol, @@ -338,6 +338,7 @@ class Painter { const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); let size = dz ? tile.fbo.width / (dz * 2) : tile.fbo.width; tile.needsRedraw = true; + tile.unprojectTileID = tileID; this.context.bindFramebuffer.set(tile.fbo.framebuffer); this.context.viewport.set([size * x, size * y, size, size]); return tile.tileID.posMatrix; @@ -491,6 +492,7 @@ class Painter { } drawTerrain(this, this.style.terrainSourceCache); + drawTerrainCoords(this, this.style.terrainSourceCache); if (this.options.showTileBoundaries) { //Use source with highest maxzoom diff --git a/src/shaders/terrain.fragment.glsl b/src/shaders/terrain.fragment.glsl index fb615811aa9..8ae6592e782 100644 --- a/src/shaders/terrain.fragment.glsl +++ b/src/shaders/terrain.fragment.glsl @@ -4,5 +4,5 @@ uniform sampler2D u_texture; varying vec2 v_texture_pos; void main() { - gl_FragColor = vec4(texture2D(u_texture, v_texture_pos).xyz, 1.0); + gl_FragColor = texture2D(u_texture, v_texture_pos); } diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 16ff4e4e909..a2865031ebb 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -8,6 +8,8 @@ import EXTENT from '../data/extent'; import {mat4} from 'gl-matrix'; import {Evented} from '../util/evented'; import Style from '../style/style'; +import Texture from '../render/texture'; +import {RGBAImage} from '../util/image'; class TerrainSourceCache extends Evented { @@ -16,7 +18,9 @@ class TerrainSourceCache extends Evented { this._sourceCache = null; this._source = null; this._tiles = []; + this._coordsIndex = {}; this._loadQueue = []; + this._coordsFramebuffer = null; this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; @@ -38,6 +42,7 @@ class TerrainSourceCache extends Evented { let idealTileIDs = this.getRenderableTileIDs(transform).filter(id => !this._tiles[id.key]); for (const tileID of idealTileIDs) { let tile = this._tiles[tileID.key] = this._createEmptyTile(tileID); + this._coordsIndex[tile._coordsIndex] = tile; if (this._source && this._source.loaded()) { this._source.loadTile(tile, () => this._tileLoaded(tile)); } else { @@ -72,7 +77,10 @@ class TerrainSourceCache extends Evented { /** * get the Elevation for given coordinate - * FIXME-3D: make linear interpolation + * FIXME-3D: + * - make linear interpolation + * - handle negative coordinates + * - interploate below ZL 14 * @param {OverscaledTileID} tileID * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT @@ -85,6 +93,21 @@ class TerrainSourceCache extends Evented { : 0; } + /** + * store all tile-coords in a framebuffer for unprojecting pixel coordinates + * FIXME-3D resize texture on window-resize + */ + getCoordsFramebuffer(context: Context) { + if (! this.fbo) { + context.activeTexture.set(context.gl.TEXTURE0); + let texture = new Texture(context, { width: 2024, height: 2024, data: null }, context.gl.RGBA, {premultiply: false}); + texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + this.fbo = context.createFramebuffer(2024, 2024, false); + this.fbo.colorAttachment.set(texture.texture); + } + return this.fbo; + } + /** * after a tile is loaded: * - recreate terrain-mesh webgl segments @@ -111,6 +134,21 @@ class TerrainSourceCache extends Evented { [[1, 1, 0], [0, 0, 0], [0, 1, 0], [1, 0, 0]].forEach(xy => vertexArray.emplaceBack(...xy.map(c => c * EXTENT))); [[1, 0, 3], [0, 1, 2]].forEach(xyz => indexArray.emplaceBack(...xyz)) tile.mesh = { indexArray: indexArray, vertexArray: vertexArray }; + // create coords texture, needed to grab coordianates from canvas + // encode coords coordinate into 4 bytes: + // - 13 bits for coordsIndex (0 .. 8191) (= number of loaded terraintile) + // - 9 bits for y (0 .. 511) + // - 9 bits for x (0 .. 511) + // - 1 bit for always true in alpha channel, because webgl do not render for opacity 0 + tile._coordsIndex = Object.keys(this._coordsIndex).length + 1; // create unique coords index + const data = new Uint8Array(this.tileSize * this.tileSize * 4); + for (let x=0, i=0; x> 7); + data[i + 1] = ((tile._coordsIndex & 31) << 3) | (y >> 6); + data[i + 0] = tile._coordsIndex >> 5; + } + tile.coords = new RGBAImage({width: this.tileSize, height: this.tileSize}, new Uint8Array(data.buffer)); return tile; } diff --git a/src/ui/map.js b/src/ui/map.js index 2fb5152bdfe..356979d0e46 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -849,7 +849,7 @@ class Map extends Camera { * var point = map.project(coordinate); */ project(lnglat: LngLatLike) { - return this.transform.locationPoint(LngLat.convert(lnglat)); + return this.transform.locationPoint3D(LngLat.convert(lnglat)); } /** @@ -865,7 +865,7 @@ class Map extends Camera { * }); */ unproject(point: PointLike) { - return this.transform.pointLocation(Point.convert(point)); + return this.transform.pointLocation3D(Point.convert(point)); } /** diff --git a/src/util/primitives.js b/src/util/primitives.js index c3bd55b65f6..adf2c59293b 100644 --- a/src/util/primitives.js +++ b/src/util/primitives.js @@ -93,15 +93,15 @@ class Aabb { // Each frustum plane together with 3 major axes define the separating axes const aabbPoints = [ - [this.min[0], this.min[1], this.min[2], 1], - [this.max[0], this.min[1], this.min[2], 1], - [this.max[0], this.max[1], this.min[2], 1], - [this.min[0], this.max[1], this.min[2], 1], - [this.min[0], this.min[1], this.max[2], 1], - [this.max[0], this.min[1], this.max[2], 1], - [this.max[0], this.max[1], this.max[2], 1], - [this.min[0], this.max[1], this.max[2], 1] - ]; + [this.min[0], this.min[1], this.min[2], 1], + [this.max[0], this.min[1], this.min[2], 1], + [this.max[0], this.max[1], this.min[2], 1], + [this.min[0], this.max[1], this.min[2], 1], + [this.min[0], this.min[1], this.max[2], 1], + [this.max[0], this.min[1], this.max[2], 1], + [this.max[0], this.max[1], this.max[2], 1], + [this.min[0], this.max[1], this.max[2], 1] + ]; let fullyInside = true; From 6f3278cdbadee3d000f0debc4df8f451bca67946 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 4 Jun 2021 16:34:35 +0200 Subject: [PATCH 004/138] fix bug in picking correct coords from coordsFramebuffer --- src/geo/transform.js | 4 ++-- src/source/terrain_source_cache.js | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/geo/transform.js b/src/geo/transform.js index 5b407d44823..1bbe0e0df29 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -485,7 +485,7 @@ class Transform { const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); const tileID = new OverscaledTileID(this.tileZoom, 1, this.tileZoom, tileX, tileY); - const elevation = this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize); + const elevation = this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); return this.coordinatePoint(this.locationCoordinate(lnglat), elevation); } @@ -576,7 +576,7 @@ class Transform { return new MercatorCoordinate( (tile.tileID.canonical.x * tile.tileSize + x) / worldSize, (tile.tileID.canonical.y * tile.tileSize + y) / worldSize, - this.terrainSourceCache.getElevation(tile.tileID, x, y) + this.terrainSourceCache.getElevation(tile.tileID, x, y, tile.tileSize) ); } diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index a2865031ebb..33e571f05c2 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -84,12 +84,13 @@ class TerrainSourceCache extends Evented { * @param {OverscaledTileID} tileID * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT + * @param {number} extent optional, default 8192 */ - getElevation(tileID: OverscaledTileID, x: number, y: number): number { + getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { let dz = tileID.overscaledZ > this.maxzoom ? tileID.overscaledZ - this.maxzoom : 0; let tile = this.getTileByCanonical(tileID.scaledTo(tileID.overscaledZ - dz).canonical); return tile && tile.dem && x > 0 && y > 0 //FIXME-3D handle negative coordinates - ? tile.dem.get(Math.floor(x / EXTENT * tile.dem.dim), Math.floor(y / EXTENT * tile.dem.dim)) + ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; } From 341ef2f2399709d51ea30429a5460de80cf1c487 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 4 Jun 2021 16:35:34 +0200 Subject: [PATCH 005/138] Add Depthbuffer to RTT Framebuffer --- src/render/draw_terrain.js | 7 ++++--- src/render/painter.js | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index 279ea0c102b..5691c233609 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -57,7 +57,7 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { } } -function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { +function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth: number=1) { const context = painter.context; for (const tileID of sourceCache.getRenderableTileIDs(painter.transform)) { const tile = sourceCache.getTileByID(tileID); @@ -66,8 +66,9 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { context.activeTexture.set(context.gl.TEXTURE0); tile.texture = new Texture(context, {width: 1024, height: 1024, data: null}, context.gl.RGBA); tile.texture.bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); - tile.fbo = context.createFramebuffer(1024, 1024, false); + tile.fbo = context.createFramebuffer(1024, 1024, true); tile.fbo.colorAttachment.set(tile.texture.texture); + tile.fbo.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, 1024, 1024)); } if (!tile.segments) { tile.indexBuffer = context.createIndexBuffer(tile.mesh.indexArray); @@ -80,7 +81,7 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { } // empty framebuffer context.bindFramebuffer.set(tile.fbo.framebuffer); - context.clear({ color: Color.transparent }); + context.clear({ color: Color.transparent, depth: depth }); painter.finishFramebuffer(); } } diff --git a/src/render/painter.js b/src/render/painter.js index bdfe4a60947..ffec10ac7ec 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -417,7 +417,6 @@ class Painter { } this.opaquePassCutoff = Infinity; - this.opaquePassCutoff = 0; // FIXME-3D! disbaled for Terrain3D, but with this setting heatmap no longer work for (let i = 0; i < layerIds.length; i++) { const layerId = layerIds[i]; if (this.style._layers[layerId].is3D()) { @@ -479,7 +478,7 @@ class Painter { // so draw the current terrain-framebuffer below the symbols if (layer.type == 'symbol') { drawTerrain(this, this.style.terrainSourceCache); - prepareTerrain(this, this.style.terrainSourceCache); + prepareTerrain(this, this.style.terrainSourceCache, 0); } // For symbol layers in the translucent pass, we add extra tiles to the renderable set From 2a2a35ded59f0c3cd01bf4c1a81eceb2eb9c5689 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 16 Jun 2021 08:16:49 +0200 Subject: [PATCH 006/138] add z-dimension to circle layers --- src/data/array_types.js | 1 + src/data/bucket/circle_attributes.js | 4 ++++ src/data/bucket/circle_bucket.js | 20 +++++++++++++++++--- src/render/draw_circle.js | 17 +++++++++++++++-- src/shaders/circle.vertex.glsl | 5 +++-- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/data/array_types.js b/src/data/array_types.js index f77987a667d..7ed9b5331c4 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -1117,6 +1117,7 @@ export { StructArrayLayout3i6 as Pos3DArray, StructArrayLayout4i8 as RasterBoundsArray, StructArrayLayout2i4 as CircleLayoutArray, + StructArrayLayout1f4 as CircleElevationArray, StructArrayLayout2i4 as FillLayoutArray, StructArrayLayout2i4i12 as FillExtrusionLayoutArray, StructArrayLayout2i4 as HeatmapLayoutArray, diff --git a/src/data/bucket/circle_attributes.js b/src/data/bucket/circle_attributes.js index e2334a28e50..d706865493b 100644 --- a/src/data/bucket/circle_attributes.js +++ b/src/data/bucket/circle_attributes.js @@ -5,5 +5,9 @@ const layout = createLayout([ {name: 'a_pos', components: 2, type: 'Int16'} ], 4); +export const elevationAttributes = createLayout([ + {name: 'a_ele', components: 1, type: 'Float32'} +], 4); + export default layout; export const {members, size, alignment} = layout; diff --git a/src/data/bucket/circle_bucket.js b/src/data/bucket/circle_bucket.js index 235eeb09a8a..755c1c7b0ae 100644 --- a/src/data/bucket/circle_bucket.js +++ b/src/data/bucket/circle_bucket.js @@ -1,8 +1,8 @@ // @flow -import {CircleLayoutArray} from '../array_types'; +import {CircleLayoutArray, CircleElevationArray} from '../array_types'; -import {members as layoutAttributes} from './circle_attributes'; +import layout, {members as layoutAttributes, elevationAttributes} from './circle_attributes'; import SegmentVector from '../segment'; import {ProgramConfigurationSet} from '../program_configuration'; import {TriangleIndexArray} from '../index_array_type'; @@ -28,6 +28,7 @@ import type VertexBuffer from '../../gl/vertex_buffer'; import type Point from '@mapbox/point-geometry'; import type {FeatureStates} from '../../source/source_state'; import type {ImagePosition} from '../../render/image_atlas'; +import { addElevation } from './symbol_bucket'; function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) { layoutVertexArray.emplaceBack( @@ -54,6 +55,9 @@ class CircleBucket implements Bucke layoutVertexArray: CircleLayoutArray; layoutVertexBuffer: VertexBuffer; + elevationVertexArray: CircleElevationArray; + elevationVertexBuffer: VertexBuffer; + indexArray: TriangleIndexArray; indexBuffer: IndexBuffer; @@ -62,6 +66,8 @@ class CircleBucket implements Bucke segments: SegmentVector; uploaded: boolean; + points: any; + constructor(options: BucketParameters) { this.zoom = options.zoom; this.overscaling = options.overscaling; @@ -71,10 +77,12 @@ class CircleBucket implements Bucke this.hasPattern = false; this.layoutVertexArray = new CircleLayoutArray(); + this.elevationVertexArray = new CircleElevationArray(); this.indexArray = new TriangleIndexArray(); this.segments = new SegmentVector(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id); + this.points = []; } populate(features: Array, options: PopulateParameters, canonical: CanonicalTileID) { @@ -137,7 +145,7 @@ class CircleBucket implements Bucke } isEmpty() { - return this.layoutVertexArray.length === 0; + return this.layoutVertexArray.length === 0 && this.elevationVertexArray.length === 0; } uploadPending() { @@ -147,6 +155,7 @@ class CircleBucket implements Bucke upload(context: Context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, layoutAttributes); + this.elevationVertexBuffer = context.createVertexBuffer(this.elevationVertexArray, elevationAttributes.members, true); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); @@ -159,6 +168,7 @@ class CircleBucket implements Bucke this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); + this.elevationVertexBuffer.destroy(); } addFeature(feature: BucketFeature, geometry: Array>, index: number, canonical: CanonicalTileID) { @@ -187,9 +197,13 @@ class CircleBucket implements Bucke addCircleVertex(this.layoutVertexArray, x, y, 1, 1); addCircleVertex(this.layoutVertexArray, x, y, -1, 1); + addElevation(this.elevationVertexArray, 0); + this.indexArray.emplaceBack(index, index + 1, index + 2); this.indexArray.emplaceBack(index, index + 3, index + 2); + this.points.push([x, y]); + segment.vertexLength += 4; segment.primitiveLength += 2; } diff --git a/src/render/draw_circle.js b/src/render/draw_circle.js index d0d152bcacd..3feb6005523 100644 --- a/src/render/draw_circle.js +++ b/src/render/draw_circle.js @@ -17,6 +17,7 @@ import type VertexBuffer from '../gl/vertex_buffer'; import type IndexBuffer from '../gl/index_buffer'; import type {UniformValues} from './uniform_binding'; import type {CircleUniformsType} from './program/circle_program'; +import {addElevation} from '../data/bucket/symbol_bucket'; export default drawCircles; @@ -24,6 +25,7 @@ type TileRenderState = { programConfiguration: ProgramConfiguration, program: Program<*>, layoutVertexBuffer: VertexBuffer, + elevationVertexBuffer: VertexBuffer, indexBuffer: IndexBuffer, uniformValues: UniformValues }; @@ -64,6 +66,15 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const bucket: ?CircleBucket<*> = (tile.getBucket(layer): any); if (!bucket) continue; + const elevationVertexArray = bucket.elevationVertexArray + const elevationVertexBuffer = bucket.elevationVertexBuffer; + elevationVertexArray.clear(); + for (const point of bucket.points) { + const elevation = painter.style.terrainSourceCache.getElevation(coord, ...point); + addElevation(elevationVertexArray, elevation); + } + elevationVertexBuffer.updateData(elevationVertexArray); + const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('circle', programConfiguration); const layoutVertexBuffer = bucket.layoutVertexBuffer; @@ -74,6 +85,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt programConfiguration, program, layoutVertexBuffer, + elevationVertexBuffer, indexBuffer, uniformValues, }; @@ -102,12 +114,13 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt } for (const segmentsState of segmentsRenderStates) { - const {programConfiguration, program, layoutVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; + const {programConfiguration, program, layoutVertexBuffer, elevationVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; const segments = segmentsState.segments; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, layoutVertexBuffer, indexBuffer, segments, - layer.paint, painter.transform.zoom, programConfiguration); + layer.paint, painter.transform.zoom, programConfiguration, + elevationVertexBuffer); } } diff --git a/src/shaders/circle.vertex.glsl b/src/shaders/circle.vertex.glsl index 1f084104174..89332a1e018 100644 --- a/src/shaders/circle.vertex.glsl +++ b/src/shaders/circle.vertex.glsl @@ -6,6 +6,7 @@ uniform lowp float u_device_pixel_ratio; uniform highp float u_camera_to_center_distance; attribute vec2 a_pos; +attribute float a_ele; varying vec3 v_data; @@ -44,9 +45,9 @@ void main(void) { corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance); } - gl_Position = u_matrix * vec4(corner_position, 0, 1); + gl_Position = u_matrix * vec4(corner_position, a_ele, 1); } else { - gl_Position = u_matrix * vec4(circle_center, 0, 1); + gl_Position = u_matrix * vec4(circle_center, a_ele, 1); if (u_scale_with_map) { gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance; From 71fa7a548428c6f692e80bff41e4ae4f4f9a099b Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 18 Jun 2021 14:53:05 +0200 Subject: [PATCH 007/138] switch to regular grid, correct rendering below ZL14, remove visible tile-boundaries --- src/geo/transform.js | 24 +++++----- src/render/draw_terrain.js | 29 ++++++++---- src/render/painter.js | 20 ++++---- src/source/raster_dem_tile_source.js | 1 - src/source/raster_dem_tile_worker_source.js | 7 +-- src/source/terrain_source_cache.js | 51 ++++++++++----------- src/symbol/projection.js | 4 +- 7 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/geo/transform.js b/src/geo/transform.js index 1bbe0e0df29..92c85c03328 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -480,11 +480,12 @@ class Transform { * @private */ locationPoint3D(lnglat: LngLat) { - const merc = this.locationCoordinate(lnglat); - const tileSize = this.terrainSourceCache.tileSize, worldSize = (1 << this.tileZoom) * tileSize; + const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; + const tileZ = tsc.maxzoom < this.tileZoom ? tsc.maxzoom : this.tileZoom; + const tileSize = tsc.tileSize, worldSize = (1 << tileZ) * tileSize; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); - const tileID = new OverscaledTileID(this.tileZoom, 1, this.tileZoom, tileX, tileY); + const tileID = new OverscaledTileID(this.tileZoom, 0, tileZ, tileX, tileY); const elevation = this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); return this.coordinatePoint(this.locationCoordinate(lnglat), elevation); } @@ -567,16 +568,17 @@ class Transform { gl.readPixels(p.x, painter.height / browser.devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); context.bindFramebuffer.set(null); // decode coordinates (encoding see terrain-source-cache) - let y = (rgba[3] >> 1) | ((rgba[2] & 3) << 7); - let x = (rgba[2] >> 2) | ((rgba[1] & 7) << 6); - let i = (rgba[1] >> 3) | (rgba[0] << 5); - let tile = this.terrainSourceCache._coordsIndex[i]; + const y = (rgba[3] >> 1) | ((rgba[2] & 3) << 7); + const x = (rgba[2] >> 2) | ((rgba[1] & 7) << 6); + const i = (rgba[1] >> 3) | (rgba[0] << 5); + const tile = this.terrainSourceCache._coordsIndex[i]; if (!tile) return this.pointCoordinate(p); // FIXME! remove this hack - let worldSize = (1 << tile.tileID.canonical.z) * tile.tileSize; + const tileSize = this.terrainSourceCache.tileSize; + const worldSize = (1 << tile.tileID.canonical.z) * tileSize; return new MercatorCoordinate( - (tile.tileID.canonical.x * tile.tileSize + x) / worldSize, - (tile.tileID.canonical.y * tile.tileSize + y) / worldSize, - this.terrainSourceCache.getElevation(tile.tileID, x, y, tile.tileSize) + (tile.tileID.canonical.x * tileSize + x) / worldSize, + (tile.tileID.canonical.y * tileSize + y) / worldSize, + this.terrainSourceCache.getElevation(tile.tileID, x, y, tileSize) ); } diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index 5691c233609..ce8d120cd51 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -12,6 +12,8 @@ import Texture from './texture'; import Color from '../style-spec/util/color'; import ColorMode from '../gl/color_mode'; import browser from '../util/browser'; +import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; +import EXTENT from '../data/extent'; function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { const tiles = Object.values(sourceCache._tiles).filter(t => t.unprojectTileID && t.coordsTexture); @@ -59,21 +61,30 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth: number=1) { const context = painter.context; - for (const tileID of sourceCache.getRenderableTileIDs(painter.transform)) { - const tile = sourceCache.getTileByID(tileID); + for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { + const tile = sourceCache.getTileByID(tileID.key); if (!tile.fbo) { - // FIXME! adjust size for overzooming + const tileSize = tile.tileSize * 2; context.activeTexture.set(context.gl.TEXTURE0); - tile.texture = new Texture(context, {width: 1024, height: 1024, data: null}, context.gl.RGBA); + tile.texture = new Texture(context, {width: tileSize, height: tileSize, data: null}, context.gl.RGBA); tile.texture.bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); - tile.fbo = context.createFramebuffer(1024, 1024, true); + tile.fbo = context.createFramebuffer(tileSize, tileSize, true); tile.fbo.colorAttachment.set(tile.texture.texture); - tile.fbo.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, 1024, 1024)); + tile.fbo.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, tileSize, tileSize)); } if (!tile.segments) { - tile.indexBuffer = context.createIndexBuffer(tile.mesh.indexArray); - tile.vertexBuffer = context.createVertexBuffer(tile.mesh.vertexArray, pos3DAttributes.members); - tile.segments = SegmentVector.simpleSegment(0, 0, tile.mesh.vertexArray.length, tile.mesh.indexArray.length); + const vertexArray = new Pos3DArray(), indexArray = new TriangleIndexArray(); + // create regular terrain-mesh. (e.g. 32 * 32 * 2 flat triangles) + const meshSize = sourceCache.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; + for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) + vertexArray.emplaceBack(x * delta, y * delta, Math.floor(sourceCache.getElevation(tileID, x, y, meshSize))); + for (let y=0; y<=meshSize2; y+=meshSize) for (let x=0; x 0 the frameport's viewbuffer is located to the currect subtile - let z = Math.floor(this.transform.zoom), dz = tileID.canonical.z - z; - const tile = dz >= 0 - ? this.style.terrainSourceCache.getTileByCanonical(tileID.scaledTo(z).canonical) - : this.style.terrainSourceCache.getTileByCanonical(tileID); - if (dz < 0) dz = 0; // draw in parent tile + const z = Math.floor(this.transform.zoom); + const canonical = tileID.canonical.z > this.style.terrainSourceCache.maxzoom + ? tileID.scaledTo(this.style.terrainSourceCache.maxzoom).canonical + : tileID.canonical; + const id = new OverscaledTileID(z, tileID.wrap, canonical.z, canonical.x, canonical.y).key; + const tile = this.style.terrainSourceCache.getTileByID(id); if (tile) { + const dz = tileID.canonical.z - canonical.z; const x = tileID.canonical.x - (tile.tileID.canonical.x << dz); const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); - let size = dz ? tile.fbo.width / (dz * 2) : tile.fbo.width; + const size = tile.fbo.width / (1 << dz); tile.needsRedraw = true; tile.unprojectTileID = tileID; this.context.bindFramebuffer.set(tile.fbo.framebuffer); @@ -470,16 +472,18 @@ class Painter { // Draw all other layers bottom-to-top. this.renderPass = 'translucent'; + let prevLayerType = ""; for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; const sourceCache = sourceCaches[layer.source]; // symbols are renderd directly onto the screen // so draw the current terrain-framebuffer below the symbols - if (layer.type == 'symbol') { + if (layer.type == 'symbol' && prevLayerType != "symbol") { drawTerrain(this, this.style.terrainSourceCache); prepareTerrain(this, this.style.terrainSourceCache, 0); } + prevLayerType = layer.type; // For symbol layers in the translucent pass, we add extra tiles to the renderable set // for cross-tile symbol fading. Symbol layers don't use tile clipping, so no need to render diff --git a/src/source/raster_dem_tile_source.js b/src/source/raster_dem_tile_source.js index edd64c34c1b..a6b9a314df2 100644 --- a/src/source/raster_dem_tile_source.js +++ b/src/source/raster_dem_tile_source.js @@ -81,7 +81,6 @@ class RasterDEMTileSource extends RasterTileSource implements Source { if (data) { tile.dem = data.dem; - tile.mesh = data.mesh; tile.needsHillshadePrepare = true; tile.state = 'loaded'; callback(null); diff --git a/src/source/raster_dem_tile_worker_source.js b/src/source/raster_dem_tile_worker_source.js index be84ccaefe8..a6d31eb67dc 100644 --- a/src/source/raster_dem_tile_worker_source.js +++ b/src/source/raster_dem_tile_worker_source.js @@ -31,7 +31,7 @@ class RasterDEMTileWorkerSource { const dem = new DEMData(uid, imagePixels, encoding); this.loaded = this.loaded || {}; this.loaded[uid] = dem; - callback(null, { dem: dem, mesh: this.createTerrainMesh(dem) }); + callback(null, { dem: dem, mesh: null }); } getImageData(imgBitmap: ImageBitmap): RGBAImage { @@ -52,7 +52,7 @@ class RasterDEMTileWorkerSource { return new RGBAImage({width: imgData.width, height: imgData.height}, imgData.data); } - createTerrainMesh(dem) { + createTerrainMesh(dem, resolution) { // load terrain from dem data const dim = dem.dim, dim1 = dim + 1; // add right/bottom overlap const terrain = new Array(dim1 * dim1); @@ -60,9 +60,10 @@ class RasterDEMTileWorkerSource { for (let x=0; x !this._tiles[id.key]); + let idealTileIDs = this.getRenderableTileIds(transform).filter(id => !this._tiles[id.key]); for (const tileID of idealTileIDs) { let tile = this._tiles[tileID.key] = this._createEmptyTile(tileID); this._coordsIndex[tile._coordsIndex] = tile; @@ -51,28 +53,25 @@ class TerrainSourceCache extends Evented { } } - getRenderableTileIDs(transform: Transform) { - return transform.coveringTiles({ tileSize: 512, minzoom: this.minzoom, maxzoom: this.maxzoom }); + getRenderableTileIds(transform: Transform) { + return transform.coveringTiles({ + tileSize: this.tileSize, + minzoom: this._source ? this._source.minzoom : this.minzoom, + maxzoom: 14, + reparseOverscaled: true + }); } - /** - * get terrain tile by the x/y/z coordinate. - * FIXME-3D! may speedup with separate lookup-table - * @private - */ - getTileByCanonical(tileID: CanonicalTileID): Tile { - for (let key in this._tiles) - if (tileID.equals(this._tiles[key].tileID.canonical)) - return this._tiles[key]; - return null; + getRenderableIds() { + return Object.values(this._tiles).map(t => t.tileID.key); } /** * get terrain tile by the TileID key * @private */ - getTileByID(tileID: OverscaledTileID): Tile { - return this._tiles[tileID.key]; + getTileByID(id: string): Tile { + return this._tiles[id]; } /** @@ -87,9 +86,8 @@ class TerrainSourceCache extends Evented { * @param {number} extent optional, default 8192 */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { - let dz = tileID.overscaledZ > this.maxzoom ? tileID.overscaledZ - this.maxzoom : 0; - let tile = this.getTileByCanonical(tileID.scaledTo(tileID.overscaledZ - dz).canonical); - return tile && tile.dem && x > 0 && y > 0 //FIXME-3D handle negative coordinates + let tile = this.getTileByID(tileID.key); + return tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; } @@ -116,7 +114,14 @@ class TerrainSourceCache extends Evented { * @param {Tile} tile */ _tileLoaded(tile: Tile) { - if (tile.state == "loaded") tile.segments = null; + if (tile.state == "loaded") { + if (this._sourceCache) this._sourceCache._backfillDEM.call(this, tile); + // rerender tile incl. neighboring tiles + tile.segments = null; + Object.keys(tile.neighboringTiles) + .map(id => this.getTileByID(id)) + .forEach(tile => { if (tile) tile.segments = null }); + } for (let s in this._style.sourceCaches) { for (let key in this._style.sourceCaches[s]._tiles) { let t = this._style.sourceCaches[s]._tiles[key]; @@ -129,12 +134,6 @@ class TerrainSourceCache extends Evented { tileID.posMatrix = mat4.create(); mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); let tile = new Tile(tileID, this.tileSize * tileID.overscaleFactor()); - const vertexArray = new Pos3DArray(), indexArray = new TriangleIndexArray(); - // create an empty terrain-mesh. (e.g. 2 flat triangles) - // FIXME-3D: get elevation from parent/children or surrounding tiles - [[1, 1, 0], [0, 0, 0], [0, 1, 0], [1, 0, 0]].forEach(xy => vertexArray.emplaceBack(...xy.map(c => c * EXTENT))); - [[1, 0, 3], [0, 1, 2]].forEach(xyz => indexArray.emplaceBack(...xyz)) - tile.mesh = { indexArray: indexArray, vertexArray: vertexArray }; // create coords texture, needed to grab coordianates from canvas // encode coords coordinate into 4 bytes: // - 13 bits for coordsIndex (0 .. 8191) (= number of loaded terraintile) diff --git a/src/symbol/projection.js b/src/symbol/projection.js index 965fb60cb16..5d9886e0b72 100644 --- a/src/symbol/projection.js +++ b/src/symbol/projection.js @@ -286,7 +286,7 @@ function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, la // Since first and last glyph fit on the line, we're sure that the rest of the glyphs can be placed // $FlowFixMe placedGlyphs.push(placeGlyphAlongLine(fontScale * glyphOffsetArray.getoffsetX(glyphIndex), lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, - lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache)); + lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation)); } placedGlyphs.push(firstAndLastGlyph.last); } else { @@ -312,7 +312,7 @@ function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, la } // $FlowFixMe const singleGlyph = placeGlyphAlongLine(fontScale * glyphOffsetArray.getoffsetX(symbol.glyphStartIndex), lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, - symbol.lineStartIndex, symbol.lineStartIndex + symbol.lineLength, lineVertexArray, labelPlaneMatrix, projectionCache); + symbol.lineStartIndex, symbol.lineStartIndex + symbol.lineLength, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation); if (!singleGlyph) return {notEnoughRoom: true}; From 2ae33e32c27ca695e8ef0107e434d9c9888e253c Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 21 Jun 2021 09:33:37 +0200 Subject: [PATCH 008/138] fix raster-rendering, hacky performance improvement --- src/render/draw_terrain.js | 2 +- src/render/painter.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index ce8d120cd51..a41406eb955 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -16,7 +16,7 @@ import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; import EXTENT from '../data/extent'; function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { - const tiles = Object.values(sourceCache._tiles).filter(t => t.unprojectTileID && t.coordsTexture); + const tiles = Object.values(sourceCache._tiles).filter(t => t.unprojectTileID && t.coordsTexture && t.segments); if (!tiles.length) return; const context = painter.context; diff --git a/src/render/painter.js b/src/render/painter.js index 24f69cef3af..4ba04228815 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -332,10 +332,10 @@ class Painter { const canonical = tileID.canonical.z > this.style.terrainSourceCache.maxzoom ? tileID.scaledTo(this.style.terrainSourceCache.maxzoom).canonical : tileID.canonical; - const id = new OverscaledTileID(z, tileID.wrap, canonical.z, canonical.x, canonical.y).key; - const tile = this.style.terrainSourceCache.getTileByID(id); + const id = new OverscaledTileID(canonical.z > z ? canonical.z : z, tileID.wrap, canonical.z, canonical.x, canonical.y); + const tile = this.style.terrainSourceCache.getTileByID(id.scaledTo(z).key); if (tile) { - const dz = tileID.canonical.z - canonical.z; + const dz = tileID.canonical.z - (z < canonical.z ? z : canonical.z); const x = tileID.canonical.x - (tile.tileID.canonical.x << dz); const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); const size = tile.fbo.width / (1 << dz); @@ -495,7 +495,12 @@ class Painter { } drawTerrain(this, this.style.terrainSourceCache); - drawTerrainCoords(this, this.style.terrainSourceCache); + + // redraw coords every 100ms for performance + if (this._drawTerrainCoordsTimeout) clearTimeout(this._drawTerrainCoordsTimeout); + this._drawTerrainCoordsTimeout = setTimeout(() => { + drawTerrainCoords(this, this.style.terrainSourceCache); + }, 100); if (this.options.showTileBoundaries) { //Use source with highest maxzoom From ebf5ea4bd7e683f41bcead76d0bc823481293941 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 22 Jun 2021 10:06:40 +0200 Subject: [PATCH 009/138] add z-dimension to fill-extrusion --- src/data/array_types.js | 1 + src/data/bucket/fill_extrusion_attributes.js | 4 ++ src/data/bucket/fill_extrusion_bucket.js | 41 +++++++++++++++++-- src/render/draw_fill_extrusion.js | 11 ++++- src/shaders/fill_extrusion.vertex.glsl | 5 ++- .../fill_extrusion_pattern.vertex.glsl | 5 ++- 6 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/data/array_types.js b/src/data/array_types.js index 7ed9b5331c4..1c138e228ab 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -1120,6 +1120,7 @@ export { StructArrayLayout1f4 as CircleElevationArray, StructArrayLayout2i4 as FillLayoutArray, StructArrayLayout2i4i12 as FillExtrusionLayoutArray, + StructArrayLayout1f4 as FillExtrusionElevationArray, StructArrayLayout2i4 as HeatmapLayoutArray, StructArrayLayout2i4ub8 as LineLayoutArray, StructArrayLayout2f8 as LineExtLayoutArray, diff --git a/src/data/bucket/fill_extrusion_attributes.js b/src/data/bucket/fill_extrusion_attributes.js index f8c6d70afd0..4745c1731ce 100644 --- a/src/data/bucket/fill_extrusion_attributes.js +++ b/src/data/bucket/fill_extrusion_attributes.js @@ -6,5 +6,9 @@ const layout = createLayout([ {name: 'a_normal_ed', components: 4, type: 'Int16'}, ], 4); +export const elevationAttributes = createLayout([ + {name: 'a_ele', components: 1, type: 'Float32'} +], 4); + export default layout; export const {members, size, alignment} = layout; diff --git a/src/data/bucket/fill_extrusion_bucket.js b/src/data/bucket/fill_extrusion_bucket.js index b45ba4b2ce9..b0670c509bc 100644 --- a/src/data/bucket/fill_extrusion_bucket.js +++ b/src/data/bucket/fill_extrusion_bucket.js @@ -1,8 +1,8 @@ // @flow -import {FillExtrusionLayoutArray} from '../array_types'; +import {FillExtrusionLayoutArray, FillExtrusionElevationArray} from '../array_types'; -import {members as layoutAttributes} from './fill_extrusion_attributes'; +import {members as layoutAttributes, elevationAttributes} from './fill_extrusion_attributes'; import SegmentVector from '../segment'; import {ProgramConfigurationSet} from '../program_configuration'; import {TriangleIndexArray} from '../index_array_type'; @@ -64,6 +64,9 @@ class FillExtrusionBucket implements Bucket { layoutVertexArray: FillExtrusionLayoutArray; layoutVertexBuffer: VertexBuffer; + elevationVertexArray: FillExtrusionElevationArray; + elevationVertexBuffer: VertexBuffer; + indexArray: TriangleIndexArray; indexBuffer: IndexBuffer; @@ -72,6 +75,7 @@ class FillExtrusionBucket implements Bucket { segments: SegmentVector; uploaded: boolean; features: Array; + points: any; constructor(options: BucketParameters) { this.zoom = options.zoom; @@ -82,11 +86,12 @@ class FillExtrusionBucket implements Bucket { this.hasPattern = false; this.layoutVertexArray = new FillExtrusionLayoutArray(); + this.elevationVertexArray = new FillExtrusionElevationArray(); this.indexArray = new TriangleIndexArray(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.segments = new SegmentVector(); this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id); - + this.points = []; } populate(features: Array, options: PopulateParameters, canonical: CanonicalTileID) { @@ -132,7 +137,7 @@ class FillExtrusionBucket implements Bucket { } isEmpty() { - return this.layoutVertexArray.length === 0; + return this.layoutVertexArray.length === 0 && this.elevationVertexArray.length === 0; } uploadPending() { @@ -142,6 +147,7 @@ class FillExtrusionBucket implements Bucket { upload(context: Context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, layoutAttributes); + this.elevationVertexBuffer = context.createVertexBuffer(this.elevationVertexArray, elevationAttributes.members, true); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); @@ -154,9 +160,11 @@ class FillExtrusionBucket implements Bucket { this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); + this.elevationVertexBuffer.destroy(); } addFeature(feature: BucketFeature, geometry: Array>, index: number, canonical: CanonicalTileID, imagePositions: {[_: string]: ImagePosition}) { + const points = []; for (const polygon of classifyRings(geometry, EARCUT_MAX_RINGS)) { let numVertices = 0; for (const ring of polygon) { @@ -174,6 +182,7 @@ class FillExtrusionBucket implements Bucket { } let edgeDistance = 0; + let point = { x: 0, y: 0, size: 0 }; for (let p = 0; p < ring.length; p++) { const p1 = ring[p]; @@ -192,11 +201,13 @@ class FillExtrusionBucket implements Bucket { addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); + point.x += 2 * p1.x; point.y += 2 * p1.y; point.size += 2; edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); + point.x += 2 * p2.x; point.y += 2 * p2.y; point.size += 2; const bottomRight = segment.vertexLength; @@ -213,6 +224,14 @@ class FillExtrusionBucket implements Bucket { } } } + + // reduce polygon to centroid and set elevation for it + points.push({ + x: Math.floor(point.x / point.size), + y: Math.floor(point.y / point.size), + size: point.size + }); + } if (segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) { @@ -233,6 +252,8 @@ class FillExtrusionBucket implements Bucket { continue; } + let point = { x: 0, y: 0, size: 0 }; + if (ring !== polygon[0]) { holeIndices.push(flattened.length / 2); } @@ -241,10 +262,18 @@ class FillExtrusionBucket implements Bucket { const p = ring[i]; addVertex(this.layoutVertexArray, p.x, p.y, 0, 0, 1, 1, 0); + point.x += p.x; point.y += p.y; point.size += 1; flattened.push(p.x); flattened.push(p.y); } + + // reduce polygon to centroid and set elevation for it + points.push({ + x: Math.floor(point.x / point.size), + y: Math.floor(point.y / point.size), + size: point.size + }); } const indices = earcut(flattened, holeIndices); @@ -262,6 +291,10 @@ class FillExtrusionBucket implements Bucket { segment.vertexLength += numVertices; } + let pointSize = points.map(p => p.size).reduce((a, b) => a + b, 0); + for (let i=0; i 0.0 ? height : base; From bdf3eeacf3db7a3c187f58bf8330d7d07743b0f5 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 23 Jun 2021 11:15:34 +0200 Subject: [PATCH 010/138] fix regular grid --- src/render/draw_terrain.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index a41406eb955..ec6dcadc816 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -78,9 +78,9 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth const meshSize = sourceCache.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) vertexArray.emplaceBack(x * delta, y * delta, Math.floor(sourceCache.getElevation(tileID, x, y, meshSize))); - for (let y=0; y<=meshSize2; y+=meshSize) for (let x=0; x Date: Fri, 25 Jun 2021 08:56:38 +0200 Subject: [PATCH 011/138] hide symbols behind terrain --- src/geo/transform.js | 2 +- src/render/draw_circle.js | 3 +++ src/render/draw_symbol.js | 3 +++ src/render/draw_terrain.js | 22 ++++++++-------- src/render/painter.js | 8 +----- src/render/program/circle_program.js | 9 ++++--- src/render/program/symbol_program.js | 21 ++++++++++------ src/render/program/terrain_program.js | 2 +- src/shaders/_prelude.vertex.glsl | 25 +++++++++++++++++++ src/shaders/circle.fragment.glsl | 3 ++- src/shaders/circle.vertex.glsl | 4 +++ src/shaders/symbol_icon.fragment.glsl | 1 + src/shaders/symbol_icon.vertex.glsl | 7 +++--- src/shaders/symbol_sdf.fragment.glsl | 1 + src/shaders/symbol_sdf.vertex.glsl | 4 ++- .../symbol_text_and_icon.fragment.glsl | 1 + src/shaders/symbol_text_and_icon.vertex.glsl | 4 ++- src/source/terrain_source_cache.js | 22 ++++++++++------ 18 files changed, 98 insertions(+), 44 deletions(-) diff --git a/src/geo/transform.js b/src/geo/transform.js index 92c85c03328..76120637b24 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -564,7 +564,7 @@ class Transform { const rgba = new Uint8Array(4); const painter = this.terrainSourceCache._style.map.painter, context = painter.context, gl = context.gl; // grab coordinate pixel from coordinates framebuffer - context.bindFramebuffer.set(this.terrainSourceCache.getCoordsFramebuffer(context).framebuffer); + context.bindFramebuffer.set(this.terrainSourceCache.getCoordsFramebuffer(painter).framebuffer); gl.readPixels(p.x, painter.height / browser.devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); context.bindFramebuffer.set(null); // decode coordinates (encoding see terrain-source-cache) diff --git a/src/render/draw_circle.js b/src/render/draw_circle.js index 3feb6005523..92788f2fa49 100644 --- a/src/render/draw_circle.js +++ b/src/render/draw_circle.js @@ -113,6 +113,9 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt segmentsRenderStates.sort((a, b) => a.sortKey - b.sortKey); } + context.activeTexture.set(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getCoordsFramebuffer(painter).colorAttachment.get()); + for (const segmentsState of segmentsRenderStates) { const {programConfiguration, program, layoutVertexBuffer, elevationVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; const segments = segmentsState.segments; diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 50c4aaad2ae..a6221c597a6 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -401,6 +401,9 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate } } + context.activeTexture.set(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getCoordsFramebuffer(painter).colorAttachment.get()); + if (state.isSDF) { const uniformValues = ((state.uniformValues: any): UniformValues); if (state.hasHalo) { diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index ec6dcadc816..fc1f609811e 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -16,27 +16,27 @@ import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; import EXTENT from '../data/extent'; function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { - const tiles = Object.values(sourceCache._tiles).filter(t => t.unprojectTileID && t.coordsTexture && t.segments); - if (!tiles.length) return; - + // FIXME-3D! update only when camera changes const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; const program = painter.useProgram('terrain'); + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); // draw tile-coords into framebuffer - context.bindFramebuffer.set(sourceCache.getCoordsFramebuffer(painter.context).framebuffer); - context.viewport.set([0, 0, painter.width / browser.devicePixelRatio, painter.height / browser.devicePixelRatio]); + context.bindFramebuffer.set(sourceCache.getCoordsFramebuffer(painter).framebuffer); + context.viewport.set([0, 0, painter.width / browser.devicePixelRatio, painter.height / browser.devicePixelRatio]); + context.clear({ color: Color.transparent, depth: 1 }); - for (const tile of tiles) { + for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { + const tile = sourceCache.getTileByID(tileID.key); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, tile.coordsTexture.texture); - const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); - const posMatrix = painter.transform.calculatePosMatrix(tile.unprojectTileID.toUnwrapped()); + const posMatrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); - tile.unprojectTileID = null; } + painter.finishFramebuffer(); } function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { @@ -46,13 +46,15 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { const context = painter.context; const gl = context.gl; const colorMode = painter.colorModeForRenderPass(); + // const colorMode = ColorMode.unblended; + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); const program = painter.useProgram('terrain'); for (const tile of tiles) { tile.needsRedraw = false; context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, tile.fbo.colorAttachment.get()); - const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); + // gl.bindTexture(gl.TEXTURE_2D, tile.coordsTexture.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); diff --git a/src/render/painter.js b/src/render/painter.js index 4ba04228815..d14b9a4e4ee 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -340,7 +340,6 @@ class Painter { const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); const size = tile.fbo.width / (1 << dz); tile.needsRedraw = true; - tile.unprojectTileID = tileID; this.context.bindFramebuffer.set(tile.fbo.framebuffer); this.context.viewport.set([size * x, size * y, size, size]); return tile.tileID.posMatrix; @@ -428,6 +427,7 @@ class Painter { } prepareTerrain(this, this.style.terrainSourceCache); + drawTerrainCoords(this, this.style.terrainSourceCache); // Offscreen pass =============================================== // We first do all rendering that requires rendering to a separate @@ -496,12 +496,6 @@ class Painter { drawTerrain(this, this.style.terrainSourceCache); - // redraw coords every 100ms for performance - if (this._drawTerrainCoordsTimeout) clearTimeout(this._drawTerrainCoordsTimeout); - this._drawTerrainCoordsTimeout = setTimeout(() => { - drawTerrainCoords(this, this.style.terrainSourceCache); - }, 100); - if (this.options.showTileBoundaries) { //Use source with highest maxzoom let selectedSource; diff --git a/src/render/program/circle_program.js b/src/render/program/circle_program.js index afde54051ee..79f38cf44d7 100644 --- a/src/render/program/circle_program.js +++ b/src/render/program/circle_program.js @@ -22,7 +22,8 @@ export type CircleUniformsType = {| 'u_pitch_with_map': Uniform1i, 'u_extrude_scale': Uniform2f, 'u_device_pixel_ratio': Uniform1f, - 'u_matrix': UniformMatrix4f + 'u_matrix': UniformMatrix4f, + 'u_coords': Uniform1i |}; const circleUniforms = (context: Context, locations: UniformLocations): CircleUniformsType => ({ @@ -31,7 +32,8 @@ const circleUniforms = (context: Context, locations: UniformLocations): CircleUn 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), 'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), - 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_coords': new Uniform1i(context, locations.u_coords) }); const circleUniformValues = ( @@ -62,7 +64,8 @@ const circleUniformValues = ( layer.paint.get('circle-translate-anchor')), 'u_pitch_with_map': +(pitchWithMap), 'u_device_pixel_ratio': browser.devicePixelRatio, - 'u_extrude_scale': extrudeScale + 'u_extrude_scale': extrudeScale, + 'u_coords': 0 }; }; diff --git a/src/render/program/symbol_program.js b/src/render/program/symbol_program.js index 6b082119205..50de9c3c7bf 100644 --- a/src/render/program/symbol_program.js +++ b/src/render/program/symbol_program.js @@ -29,7 +29,8 @@ export type SymbolIconUniformsType = {| 'u_is_text': Uniform1i, 'u_pitch_with_map': Uniform1i, 'u_texsize': Uniform2f, - 'u_texture': Uniform1i + 'u_texture': Uniform1i, + 'u_coords': Uniform1i |}; export type SymbolSDFUniformsType = {| @@ -51,7 +52,8 @@ export type SymbolSDFUniformsType = {| 'u_texture': Uniform1i, 'u_gamma_scale': Uniform1f, 'u_device_pixel_ratio': Uniform1f, - 'u_is_halo': Uniform1i + 'u_is_halo': Uniform1i, + 'u_coords': Uniform1i |}; export type symbolTextAndIconUniformsType = {| @@ -75,7 +77,8 @@ export type symbolTextAndIconUniformsType = {| 'u_texture_icon': Uniform1i, 'u_gamma_scale': Uniform1f, 'u_device_pixel_ratio': Uniform1f, - 'u_is_halo': Uniform1i + 'u_is_halo': Uniform1i, + 'u_coords': Uniform1i |}; const symbolIconUniforms = (context: Context, locations: UniformLocations): SymbolIconUniformsType => ({ @@ -94,7 +97,8 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb 'u_is_text': new Uniform1i(context, locations.u_is_text), 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new Uniform2f(context, locations.u_texsize), - 'u_texture': new Uniform1i(context, locations.u_texture) + 'u_texture': new Uniform1i(context, locations.u_texture), + 'u_coords': new Uniform1i(context, locations.u_coords) }); const symbolSDFUniforms = (context: Context, locations: UniformLocations): SymbolSDFUniformsType => ({ @@ -116,7 +120,8 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo 'u_texture': new Uniform1i(context, locations.u_texture), 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), - 'u_is_halo': new Uniform1i(context, locations.u_is_halo) + 'u_is_halo': new Uniform1i(context, locations.u_is_halo), + 'u_coords': new Uniform1i(context, locations.u_coords) }); const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations): symbolTextAndIconUniformsType => ({ @@ -140,7 +145,8 @@ const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations 'u_texture_icon': new Uniform1i(context, locations.u_texture_icon), 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), - 'u_is_halo': new Uniform1i(context, locations.u_is_halo) + 'u_is_halo': new Uniform1i(context, locations.u_is_halo), + 'u_coords': new Uniform1i(context, locations.u_coords) }); const symbolIconUniformValues = ( @@ -173,7 +179,8 @@ const symbolIconUniformValues = ( 'u_is_text': +isText, 'u_pitch_with_map': +pitchWithMap, 'u_texsize': texSize, - 'u_texture': 0 + 'u_texture': 0, + 'u_coords': 2 }; }; diff --git a/src/render/program/terrain_program.js b/src/render/program/terrain_program.js index 79bd9e8529e..421e224cb96 100644 --- a/src/render/program/terrain_program.js +++ b/src/render/program/terrain_program.js @@ -14,7 +14,7 @@ export type TerrainUniformsType = {| const terrainUniforms = (context: Context, locations: UniformLocations): TerrainRasterUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_texture': new Uniform1i(context, locations.u_image0) + 'u_texture': new Uniform1i(context, locations.u_texture) }); const terrainUniformValues = (matrix: Float32Array): UniformValues => ({ diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 9cd030e4eb9..4ed1c8e7e96 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -71,3 +71,28 @@ vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); return (tile_units_to_pixels * pos + offset) / pattern_size; } + +float hasBit(float value, int pos) { + return floor(mod(floor(value / pow(2.0, float(pos))), 2.0)); +} + +// unpack a RGBA value from the the coords framebuffer into a vec2 in the range from 0 .. 8191 +vec2 unpackCoord(vec4 rgba) { + float r = floor(rgba.x * 255.0); + float g = floor(rgba.y * 255.0); + float b = floor(rgba.z * 255.0); + float a = floor(rgba.w * 255.0); + float x = hasBit(b, 2) * 1.0 + hasBit(b, 3) * 2.0 + hasBit(b, 4) * 4.0 + hasBit(b, 5) * 8.0 + hasBit(b, 6) * 16.0 + hasBit(b, 7) * 32.0 + hasBit(g, 0) * 64.0 + hasBit(g, 1) * 128.0 + hasBit(g, 2) * 258.0; + float y = hasBit(a, 1) * 1.0 + hasBit(a, 2) * 2.0 + hasBit(a, 3) * 4.0 + hasBit(a, 4) * 8.0 + hasBit(a, 5) * 16.0 + hasBit(a, 6) * 32.0 + hasBit(a, 7) * 64.0 + hasBit(b, 0) * 128.0 + hasBit(b, 1) * 258.0; + return vec2(x, y) / 511.0 * 8191.0; +} + +// unpack a coord RGBA to vec2 +float calculate_visibility(sampler2D u_coords, vec4 pos, vec2 tilePos) { + vec3 frag = pos.xyz / pos.w; + vec2 coord = unpackCoord(texture2D(u_coords, frag.xy * 0.5 + 0.5)); + vec2 delta = tilePos - coord; + float distance = sqrt(delta.x * delta.x + delta.y * delta.y); + if (distance < 100.0) return 1.0; + return 0.2; +} \ No newline at end of file diff --git a/src/shaders/circle.fragment.glsl b/src/shaders/circle.fragment.glsl index 14081450b09..a9f972539fb 100644 --- a/src/shaders/circle.fragment.glsl +++ b/src/shaders/circle.fragment.glsl @@ -1,4 +1,5 @@ varying vec3 v_data; +varying float v_visibility; #pragma mapbox: define highp vec4 color #pragma mapbox: define mediump float radius @@ -31,7 +32,7 @@ void main() { extrude_length - radius / (radius + stroke_width) ); - gl_FragColor = opacity_t * mix(color * opacity, stroke_color * stroke_opacity, color_t); + gl_FragColor = v_visibility * opacity_t * mix(color * opacity, stroke_color * stroke_opacity, color_t); #ifdef OVERDRAW_INSPECTOR gl_FragColor = vec4(1.0); diff --git a/src/shaders/circle.vertex.glsl b/src/shaders/circle.vertex.glsl index 89332a1e018..2566a73285d 100644 --- a/src/shaders/circle.vertex.glsl +++ b/src/shaders/circle.vertex.glsl @@ -4,11 +4,13 @@ uniform bool u_pitch_with_map; uniform vec2 u_extrude_scale; uniform lowp float u_device_pixel_ratio; uniform highp float u_camera_to_center_distance; +uniform highp sampler2D u_coords; attribute vec2 a_pos; attribute float a_ele; varying vec3 v_data; +varying float v_visibility; #pragma mapbox: define highp vec4 color #pragma mapbox: define mediump float radius @@ -33,6 +35,8 @@ void main(void) { // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data vec2 circle_center = floor(a_pos * 0.5); + v_visibility = calculate_visibility(u_coords, u_matrix * vec4(circle_center, a_ele, 1.0), circle_center); + if (u_pitch_with_map) { vec2 corner_position = circle_center; if (u_scale_with_map) { diff --git a/src/shaders/symbol_icon.fragment.glsl b/src/shaders/symbol_icon.fragment.glsl index 4f6d75e70fb..5892ec8c1df 100644 --- a/src/shaders/symbol_icon.fragment.glsl +++ b/src/shaders/symbol_icon.fragment.glsl @@ -2,6 +2,7 @@ uniform sampler2D u_texture; varying vec2 v_tex; varying float v_fade_opacity; +varying float v_visibility; #pragma mapbox: define lowp float opacity diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 8751010c494..20fa7e7afeb 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -16,15 +16,13 @@ uniform highp float u_pitch; uniform bool u_rotate_symbol; uniform highp float u_aspect_ratio; uniform float u_fade_change; - uniform mat4 u_matrix; uniform mat4 u_label_plane_matrix; uniform mat4 u_coord_matrix; - uniform bool u_is_text; uniform bool u_pitch_with_map; - uniform vec2 u_texsize; +uniform highp sampler2D u_coords; varying vec2 v_tex; varying float v_fade_opacity; @@ -92,5 +90,6 @@ void main() { v_tex = a_tex / u_texsize; vec2 fade_opacity = unpack_opacity(a_fade_opacity); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; - v_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change)); + float visibility = calculate_visibility(u_coords, projectedPoint, a_pos); + v_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); } diff --git a/src/shaders/symbol_sdf.fragment.glsl b/src/shaders/symbol_sdf.fragment.glsl index 6b077543069..ba2c9756dfb 100644 --- a/src/shaders/symbol_sdf.fragment.glsl +++ b/src/shaders/symbol_sdf.fragment.glsl @@ -8,6 +8,7 @@ uniform bool u_is_text; varying vec2 v_data0; varying vec3 v_data1; +varying float v_visibility; #pragma mapbox: define highp vec4 fill_color #pragma mapbox: define highp vec4 halo_color diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index 5a0bf8a1325..05285d0de9e 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -29,6 +29,7 @@ uniform highp float u_aspect_ratio; uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; +uniform highp sampler2D u_coords; varying vec2 v_data0; varying vec3 v_data1; @@ -109,8 +110,9 @@ void main() { float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); + float visibility = calculate_visibility(u_coords, projectedPoint, a_pos); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; - float interpolated_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change)); + float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); v_data0 = a_tex / u_texsize; v_data1 = vec3(gamma_scale, size, interpolated_fade_opacity); diff --git a/src/shaders/symbol_text_and_icon.fragment.glsl b/src/shaders/symbol_text_and_icon.fragment.glsl index 6220563c415..a3c2e408d19 100644 --- a/src/shaders/symbol_text_and_icon.fragment.glsl +++ b/src/shaders/symbol_text_and_icon.fragment.glsl @@ -11,6 +11,7 @@ uniform lowp float u_device_pixel_ratio; varying vec4 v_data0; varying vec4 v_data1; +varying float v_visibility; #pragma mapbox: define highp vec4 fill_color #pragma mapbox: define highp vec4 halo_color diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index c0340a3f871..3e2818409d6 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -29,6 +29,7 @@ uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; uniform vec2 u_texsize_icon; +uniform highp sampler2D u_coords; varying vec4 v_data0; varying vec4 v_data1; @@ -109,8 +110,9 @@ void main() { float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); + float visibility = calculate_visibility(u_coords, projectedPoint, a_pos); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; - float interpolated_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change)); + float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); v_data0.xy = a_tex / u_texsize; v_data0.zw = a_tex / u_texsize_icon; diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 49dda2ee677..bf604c1d300 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -9,8 +9,7 @@ import {Evented} from '../util/evented'; import Style from '../style/style'; import Texture from '../render/texture'; import {RGBAImage} from '../util/image'; -import { extent } from 'd3'; -import DEMData from '../data/dem_data'; +import browser from '../util/browser'; class TerrainSourceCache extends Evented { @@ -25,7 +24,7 @@ class TerrainSourceCache extends Evented { this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; - this.meshSize = 32; + this.meshSize = 64; } setSourceCache(sourceCache: Source) { @@ -96,13 +95,20 @@ class TerrainSourceCache extends Evented { * store all tile-coords in a framebuffer for unprojecting pixel coordinates * FIXME-3D resize texture on window-resize */ - getCoordsFramebuffer(context: Context) { + getCoordsFramebuffer(painter: Painter) { + const width = painter.width / browser.devicePixelRatio; + const height = painter.height / browser.devicePixelRatio; + if (this.fbo && (this.fbo.width != width || this.fbo.height != height)) { + this.fbo.destroy(); + delete this.fbo; + } if (! this.fbo) { - context.activeTexture.set(context.gl.TEXTURE0); - let texture = new Texture(context, { width: 2024, height: 2024, data: null }, context.gl.RGBA, {premultiply: false}); - texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - this.fbo = context.createFramebuffer(2024, 2024, false); + painter.context.activeTexture.set(painter.context.gl.TEXTURE0); + let texture = new Texture(painter.context, { width: width, height: height, data: null }, painter.context.gl.RGBA, {premultiply: false}); + texture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); + this.fbo = painter.context.createFramebuffer(width, height, true); this.fbo.colorAttachment.set(texture.texture); + this.fbo.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, width, height)); } return this.fbo; } From ac2f0ee98130e0f355f697b7c0d497e231256947 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 29 Jun 2021 15:09:38 +0200 Subject: [PATCH 012/138] calculate elevation of symbol/circle/extrusion only once --- src/render/draw_circle.js | 13 ++++++++----- src/render/draw_fill_extrusion.js | 13 ++++++++----- src/render/draw_symbol.js | 8 ++------ src/render/draw_terrain.js | 2 +- src/source/terrain_source_cache.js | 5 +++-- src/source/tile.js | 2 ++ 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/render/draw_circle.js b/src/render/draw_circle.js index 92788f2fa49..afefe36f781 100644 --- a/src/render/draw_circle.js +++ b/src/render/draw_circle.js @@ -68,12 +68,15 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const elevationVertexArray = bucket.elevationVertexArray const elevationVertexBuffer = bucket.elevationVertexBuffer; - elevationVertexArray.clear(); - for (const point of bucket.points) { - const elevation = painter.style.terrainSourceCache.getElevation(coord, ...point); - addElevation(elevationVertexArray, elevation); + if (bucket && tile.state == "loaded" && !tile.elevation[layer.id]) { + elevationVertexArray.clear(); + for (const point of bucket.points) { + const elevation = painter.style.terrainSourceCache.getElevation(coord, ...point); + addElevation(elevationVertexArray, elevation); + } + elevationVertexBuffer.updateData(elevationVertexArray); + tile.elevation[layer.id] = true; } - elevationVertexBuffer.updateData(elevationVertexArray); const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('circle', programConfiguration); diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index 322eaabc327..f2d9f0bea89 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -62,12 +62,15 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo const elevationVertexArray = bucket.elevationVertexArray const elevationVertexBuffer = bucket.elevationVertexBuffer; - elevationVertexArray.clear(); - for (const point of bucket.points) { - const elevation = painter.style.terrainSourceCache.getElevation(coord, point.x, point.y); - for (let i=0; i this.getTileByID(id)) .forEach(tile => { if (tile) tile.segments = null }); } + // mark all tiles to refetch elevation-data + // FIXME! only mark necessary tiles for (let s in this._style.sourceCaches) { for (let key in this._style.sourceCaches[s]._tiles) { - let t = this._style.sourceCaches[s]._tiles[key]; - if (t && t.hasSymbolBuckets) t.hasElevation = false; + this._style.sourceCaches[s]._tiles[key].elevation = {}; } } } diff --git a/src/source/tile.js b/src/source/tile.js index 419059b7ac2..95e280553be 100644 --- a/src/source/tile.js +++ b/src/source/tile.js @@ -88,6 +88,7 @@ class Tile { hasSymbolBuckets: boolean; hasRTLText: boolean; dependencies: Object; + elevation: Object; /** * @param {OverscaledTileID} tileID @@ -105,6 +106,7 @@ class Tile { this.hasSymbolBuckets = false; this.hasRTLText = false; this.dependencies = {}; + this.elevation = {}; // Counts the number of times a response was already expired when // received. We're using this to add a delay when making a new request From 5c21371da2bb670472d4e1b1a6cc8a16479799b4 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 29 Jun 2021 16:04:05 +0200 Subject: [PATCH 013/138] render coords-framebuffer only on camera movement --- src/render/painter.js | 11 ++++++++++- src/source/terrain_source_cache.js | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/render/painter.js b/src/render/painter.js index d14b9a4e4ee..caf67179e33 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -126,11 +126,13 @@ class Painter { emptyTexture: Texture; debugOverlayTexture: Texture; debugOverlayCanvas: HTMLCanvasElement; + coordsBuffer: Object; constructor(gl: WebGLRenderingContext, transform: Transform) { this.context = new Context(gl); this.transform = transform; this._tileTextures = {}; + this.coordsBuffer = { matrix: new Float64Array(16), renderTime: 0 }; this.setup(); @@ -427,7 +429,14 @@ class Painter { } prepareTerrain(this, this.style.terrainSourceCache); - drawTerrainCoords(this, this.style.terrainSourceCache); + + // update coords-framebuffer only on camera movement + const newTiles = this.style.terrainSourceCache.tilesForTime(this.coordsBuffer.renderTime); + if (!mat4.equals(this.coordsBuffer.matrix, this.transform.projMatrix) || newTiles.length) { + mat4.copy(this.coordsBuffer.matrix, this.transform.projMatrix); + this.coordsBuffer.renderTime = Date.now(); + drawTerrainCoords(this, this.style.terrainSourceCache); + } // Offscreen pass =============================================== // We first do all rendering that requires rendering to a separate diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index f733fb5789d..4a9fd5117f8 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -113,13 +113,22 @@ class TerrainSourceCache extends Evented { return this.fbo; } + /** + * get a list of tiles, loaded after a spezific time + * @param {Date} time + */ + tilesForTime(time=Date.now()) { + return Object.values(this._tiles).filter(t => t.loadTime >= time); + } + /** * after a tile is loaded: * - recreate terrain-mesh webgl segments - * - recalculate elevation of all symbols of all tiles + * - recalculate elevation of all symbols/circles/buildings of all tiles * @param {Tile} tile */ _tileLoaded(tile: Tile) { + tile.loadTime = Date.now(); if (tile.state == "loaded") { if (this._sourceCache) this._sourceCache._backfillDEM.call(this, tile); // rerender tile incl. neighboring tiles From 9e4c74e423730d03789a059d7ac9c80f4df72512 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 2 Jul 2021 14:44:37 +0200 Subject: [PATCH 014/138] improve performacne: render layers to texture only once --- src/render/draw_terrain.js | 32 +++++++------- src/render/painter.js | 67 ++++++++++++++++++++---------- src/source/terrain_source_cache.js | 5 ++- 3 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index 5fe28136503..da5eab5b9cc 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -16,7 +16,6 @@ import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; import EXTENT from '../data/extent'; function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { - // FIXME-3D! update only when camera changes const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; @@ -40,21 +39,16 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { } function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { - const tiles = Object.values(sourceCache._tiles).filter(t => t.needsRedraw); - if (!tiles.length) return; - const context = painter.context; const gl = context.gl; const colorMode = painter.colorModeForRenderPass(); - // const colorMode = ColorMode.unblended; const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); const program = painter.useProgram('terrain'); - for (const tile of tiles) { - tile.needsRedraw = false; + for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { + const tile = sourceCache.getTileByID(tileID.key); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, tile.fbo.colorAttachment.get()); - // gl.bindTexture(gl.TEXTURE_2D, tile.coordsTexture.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); @@ -65,13 +59,13 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth const context = painter.context; for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { const tile = sourceCache.getTileByID(tileID.key); + const tileSize = tile.tileSize * 2; + if (!tile.textures[painter.batch]) { + tile.textures[painter.batch] = new Texture(context, {width: tileSize, height: tileSize, data: null}, context.gl.RGBA); + tile.textures[painter.batch].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); + } if (!tile.fbo) { - const tileSize = tile.tileSize * 2; - context.activeTexture.set(context.gl.TEXTURE0); - tile.texture = new Texture(context, {width: tileSize, height: tileSize, data: null}, context.gl.RGBA); - tile.texture.bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); tile.fbo = context.createFramebuffer(tileSize, tileSize, true); - tile.fbo.colorAttachment.set(tile.texture.texture); tile.fbo.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, tileSize, tileSize)); } if (!tile.segments) { @@ -92,7 +86,16 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth tile.coordsTexture = new Texture(context, tile.coords, context.gl.RGBA, {premultiply: false}); tile.coordsTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); } - // empty framebuffer + // set current batch-texture to framebuffer + tile.fbo.colorAttachment.set(tile.textures[painter.batch].texture); + context.bindFramebuffer.set(null); + } +} + +function clearTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth: number=1) { + const context = painter.context; + for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { + const tile = sourceCache.getTileByID(tileID.key); context.bindFramebuffer.set(tile.fbo.framebuffer); context.clear({ color: Color.transparent, depth: depth }); painter.finishFramebuffer(); @@ -100,6 +103,7 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth } export { + clearTerrain, prepareTerrain, drawTerrain, drawTerrainCoords diff --git a/src/render/painter.js b/src/render/painter.js index caf67179e33..d023ddfef29 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -36,7 +36,7 @@ import raster from './draw_raster'; import background from './draw_background'; import debug, {drawDebugPadding} from './draw_debug'; import custom from './draw_custom'; -import {prepareTerrain, drawTerrain, drawTerrainCoords} from './draw_terrain'; +import {clearTerrain, prepareTerrain, drawTerrain, drawTerrainCoords} from './draw_terrain'; import {OverscaledTileID} from '../source/tile_id'; const draw = { @@ -341,7 +341,6 @@ class Painter { const x = tileID.canonical.x - (tile.tileID.canonical.x << dz); const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); const size = tile.fbo.width / (1 << dz); - tile.needsRedraw = true; this.context.bindFramebuffer.set(tile.fbo.framebuffer); this.context.viewport.set([size * x, size * y, size, size]); return tile.tileID.posMatrix; @@ -427,7 +426,10 @@ class Painter { break; } } + // disable opaque rendering until terrain is disable + this.opaquePassCutoff = 0; + this.batch = 0; prepareTerrain(this, this.style.terrainSourceCache); // update coords-framebuffer only on camera movement @@ -466,44 +468,67 @@ class Painter { // Opaque pass =============================================== // Draw opaque layers top-to-bottom first. - this.renderPass = 'opaque'; + if (this.opaquePassCutoff > 0) { + this.renderPass = 'opaque'; - for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) { - const layer = this.style._layers[layerIds[this.currentLayer]]; - const sourceCache = sourceCaches[layer.source]; - const coords = coordsAscending[layer.source]; + for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) { + const layer = this.style._layers[layerIds[this.currentLayer]]; + const sourceCache = sourceCaches[layer.source]; + const coords = coordsAscending[layer.source]; - this._renderTileClippingMasks(layer, coords); - this.renderLayer(this, sourceCache, layer, coords); + this._renderTileClippingMasks(layer, coords); + this.renderLayer(this, sourceCache, layer, coords); + } } // Translucent pass =============================================== // Draw all other layers bottom-to-top. this.renderPass = 'translucent'; - - let prevLayerType = ""; + let prevType = null; + const rerender = this.style.terrainSourceCache._rerender || this.style._modified; + let renderToTexture = { background: true, fill: true, line: true, raster: true }; for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; const sourceCache = sourceCaches[layer.source]; - - // symbols are renderd directly onto the screen - // so draw the current terrain-framebuffer below the symbols - if (layer.type == 'symbol' && prevLayerType != "symbol") { - drawTerrain(this, this.style.terrainSourceCache); - prepareTerrain(this, this.style.terrainSourceCache, 0); - } - prevLayerType = layer.type; + const type = layer.type; // For symbol layers in the translucent pass, we add extra tiles to the renderable set // for cross-tile symbol fading. Symbol layers don't use tile clipping, so no need to render // separate clipping masks - const coords = (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer.source]; + let coords = (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer.source]; + + // render background, fill, line & raster layer into texture + if (renderToTexture[type]) { + if (prevType == 'hillshade') drawTerrain(this, this.style.terrainSourceCache); + if (prevType && !renderToTexture[prevType]) { + this.batch++; + prepareTerrain(this, this.style.terrainSourceCache); + if (rerender) clearTerrain(this, this.style.terrainSourceCache); + } + prevType = type; + if (!rerender) continue; + + // render hillshading-texture to separate mesh-texture + // FIXME-3D! render hillshading-texture direct to screen for performance + } else if (type == 'hillshade') { + if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); + this.batch++; + prepareTerrain(this, this.style.terrainSourceCache); + clearTerrain(this, this.style.terrainSourceCache); + prevType = type; + + // render all other layers direct to screen + } else { + if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); + prevType = type; + } this._renderTileClippingMasks(layer, coordsAscending[layer.source]); this.renderLayer(this, sourceCache, layer, coords); } - drawTerrain(this, this.style.terrainSourceCache); + if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); + this.style.terrainSourceCache._rerender = false; if (this.options.showTileBoundaries) { //Use source with highest maxzoom diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 4a9fd5117f8..15c2688798a 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -21,10 +21,12 @@ class TerrainSourceCache extends Evented { this._coordsIndex = {}; this._loadQueue = []; this._coordsFramebuffer = null; + this._rerender = true; this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; - this.meshSize = 64; + this.meshSize = 32; + style.on("data", () => this._rerender = true); } setSourceCache(sourceCache: Source) { @@ -165,6 +167,7 @@ class TerrainSourceCache extends Evented { data[i + 0] = tile._coordsIndex >> 5; } tile.coords = new RGBAImage({width: this.tileSize, height: this.tileSize}, new Uint8Array(data.buffer)); + tile.textures = []; return tile; } From 2a3f99a0b2be4ee10d7c7fcebee105c7718ac53c Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 14 Jul 2021 10:24:40 +0200 Subject: [PATCH 015/138] * raise camera to correct zoomlevel-distance over terrain * add exaggeration setting in TerrainSourceCache * fix farZ clipping-plane * set points: any declaration to Array --- src/data/bucket/circle_bucket.js | 2 +- src/data/bucket/fill_extrusion_bucket.js | 31 ++++-------- src/geo/transform.js | 60 ++++++++++++++---------- src/source/terrain_source_cache.js | 9 ++-- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/data/bucket/circle_bucket.js b/src/data/bucket/circle_bucket.js index 755c1c7b0ae..e68492d03c2 100644 --- a/src/data/bucket/circle_bucket.js +++ b/src/data/bucket/circle_bucket.js @@ -66,7 +66,7 @@ class CircleBucket implements Bucke segments: SegmentVector; uploaded: boolean; - points: any; + points: Array; constructor(options: BucketParameters) { this.zoom = options.zoom; diff --git a/src/data/bucket/fill_extrusion_bucket.js b/src/data/bucket/fill_extrusion_bucket.js index b0670c509bc..72efcb11032 100644 --- a/src/data/bucket/fill_extrusion_bucket.js +++ b/src/data/bucket/fill_extrusion_bucket.js @@ -75,7 +75,7 @@ class FillExtrusionBucket implements Bucket { segments: SegmentVector; uploaded: boolean; features: Array; - points: any; + points: Array; constructor(options: BucketParameters) { this.zoom = options.zoom; @@ -164,7 +164,7 @@ class FillExtrusionBucket implements Bucket { } addFeature(feature: BucketFeature, geometry: Array>, index: number, canonical: CanonicalTileID, imagePositions: {[_: string]: ImagePosition}) { - const points = []; + const point = { x: 0, y: 0, size: 0 }; for (const polygon of classifyRings(geometry, EARCUT_MAX_RINGS)) { let numVertices = 0; for (const ring of polygon) { @@ -182,7 +182,6 @@ class FillExtrusionBucket implements Bucket { } let edgeDistance = 0; - let point = { x: 0, y: 0, size: 0 }; for (let p = 0; p < ring.length; p++) { const p1 = ring[p]; @@ -225,13 +224,6 @@ class FillExtrusionBucket implements Bucket { } } - // reduce polygon to centroid and set elevation for it - points.push({ - x: Math.floor(point.x / point.size), - y: Math.floor(point.y / point.size), - size: point.size - }); - } if (segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) { @@ -252,8 +244,6 @@ class FillExtrusionBucket implements Bucket { continue; } - let point = { x: 0, y: 0, size: 0 }; - if (ring !== polygon[0]) { holeIndices.push(flattened.length / 2); } @@ -268,12 +258,6 @@ class FillExtrusionBucket implements Bucket { flattened.push(p.y); } - // reduce polygon to centroid and set elevation for it - points.push({ - x: Math.floor(point.x / point.size), - y: Math.floor(point.y / point.size), - size: point.size - }); } const indices = earcut(flattened, holeIndices); @@ -291,9 +275,14 @@ class FillExtrusionBucket implements Bucket { segment.vertexLength += numVertices; } - let pointSize = points.map(p => p.size).reduce((a, b) => a + b, 0); - for (let i=0; i 0.5 ? dx - 1 : dx, dy > 0.5 ? dy - 1 : dy, 0 ]); this.alignedProjMatrix = alignedM; - m = mat4.create(); - mat4.scale(m, m, [this.width / 2, -this.height / 2, 1]); - mat4.translate(m, m, [1, -1, 0]); - this.labelPlaneMatrix = m; - - m = mat4.create(); - mat4.scale(m, m, [1, -1, 1]); - mat4.translate(m, m, [-1, -1, 0]); - mat4.scale(m, m, [2 / this.width, 2 / this.height, 1]); - this.glCoordMatrix = m; - - // matrix for conversion from location to screen coordinates - this.pixelMatrix = mat4.multiply(new Float64Array(16), this.labelPlaneMatrix, this.projMatrix); - // inverse matrix for conversion from screen coordinaes to location m = mat4.invert(new Float64Array(16), this.pixelMatrix); if (!m) throw new Error("failed to invert matrix"); diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 15c2688798a..00c9b3430fb 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -25,7 +25,8 @@ class TerrainSourceCache extends Evented { this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; - this.meshSize = 32; + this.meshSize = 64; + this.exaggeration = 1; style.on("data", () => this._rerender = true); } @@ -42,6 +43,7 @@ class TerrainSourceCache extends Evented { * @private */ update(transform: Transform, context: Context) { + transform._calcMatrices(); let idealTileIDs = this.getRenderableTileIds(transform).filter(id => !this._tiles[id.key]); for (const tileID of idealTileIDs) { let tile = this._tiles[tileID.key] = this._createEmptyTile(tileID); @@ -87,10 +89,11 @@ class TerrainSourceCache extends Evented { * @param {number} extent optional, default 8192 */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { - let tile = this.getTileByID(tileID.key); - return tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates + const tile = this.getTileByID(tileID.key); + const elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; + return elevation * this.exaggeration; } /** From d95a197d7b07e7a73f09d90a21dcb9e233d472a9 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 14 Jul 2021 11:35:23 +0200 Subject: [PATCH 016/138] Add an elevation offset of 450m to put the dead sea into positive values --- src/source/terrain_source_cache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 00c9b3430fb..589b3ef09f8 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -93,7 +93,7 @@ class TerrainSourceCache extends Evented { const elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; - return elevation * this.exaggeration; + return (elevation + 450) * this.exaggeration; // add a global offset of 450m to put the dead-sea into positive values. } /** From 0ff2e33c8f75a7dff08ae39df7e316ac54bca843 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 14 Jul 2021 11:45:42 +0200 Subject: [PATCH 017/138] add yarn.lock file with martini entries --- yarn.lock | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/yarn.lock b/yarn.lock index 4128c627ba2..13bf9981937 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1081,6 +1081,11 @@ resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e" integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg== +"@mapbox/martini@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@mapbox/martini/-/martini-0.2.0.tgz#1af70211fbe994abf26e37f1388ca69c02cd43b4" + integrity sha512-7hFhtkb0KTLEls+TRw/rWayq5EeHtTaErgm/NskVoXmtgAQu/9D299aeyj6mzAR/6XUnYRp2lU+4IcrYRFjVsQ== + "@mapbox/mvt-fixtures@^3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@mapbox/mvt-fixtures/-/mvt-fixtures-3.6.0.tgz#0d359c1eca9499db8b5b57292b1f986921ef0fbd" From fe3b92a5d7297b9cc1620ad4d69d7400fcc2ee95 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 26 Jul 2021 19:00:15 +0200 Subject: [PATCH 018/138] render tiles only if terrain is loaded --- src/render/painter.js | 23 +++++++++++++++++------ src/source/terrain_source_cache.js | 22 +++++++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/render/painter.js b/src/render/painter.js index d023ddfef29..55926dd0364 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -326,18 +326,23 @@ class Painter { return [{[minTileZ]: StencilMode.disabled}, coords]; } - // start drawing into the framebuffer, which is drawn on terrain-mesh - prepareFramebuffer(tileID: OverscaledTileID, layerType: string) { - // dz is the tileSize difference of the layer-source and the 512px terrain-source - // so if dz > 0 the frameport's viewbuffer is located to the currect subtile + getTerrainTile(tileID: OverscaledTileID) { const z = Math.floor(this.transform.zoom); const canonical = tileID.canonical.z > this.style.terrainSourceCache.maxzoom ? tileID.scaledTo(this.style.terrainSourceCache.maxzoom).canonical : tileID.canonical; const id = new OverscaledTileID(canonical.z > z ? canonical.z : z, tileID.wrap, canonical.z, canonical.x, canonical.y); - const tile = this.style.terrainSourceCache.getTileByID(id.scaledTo(z).key); + return this.style.terrainSourceCache.getTileByID(id.scaledTo(z).key); + } + + // start drawing into the framebuffer, which is drawn on terrain-mesh + prepareFramebuffer(tileID: OverscaledTileID, layerType: string) { + const tile = this.getTerrainTile(tileID); if (tile) { - const dz = tileID.canonical.z - (z < canonical.z ? z : canonical.z); + const z = Math.floor(this.transform.zoom); + // dz is the tileSize difference of the layer-source and the 512px terrain-source + // so if dz > 0 the frameport's viewbuffer is located to the currect subtile + const dz = tileID.canonical.z - (z < tile.tileID.canonical.z ? z : tile.tileID.canonical.z); const x = tileID.canonical.x - (tile.tileID.canonical.x << dz); const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); const size = tile.fbo.width / (1 << dz); @@ -497,6 +502,12 @@ class Painter { // separate clipping masks let coords = (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer.source]; + // render only tiles which has loaded terrain + if (coords) coords = coords.filter(tileID => { + const tile = this.getTerrainTile(tileID); + return tile && tile.state == "loaded"; + }); + // render background, fill, line & raster layer into texture if (renderToTexture[type]) { if (prevType == 'hillshade') drawTerrain(this, this.style.terrainSourceCache); diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 589b3ef09f8..88ed5eb06f5 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -33,9 +33,10 @@ class TerrainSourceCache extends Evented { setSourceCache(sourceCache: Source) { this._sourceCache = sourceCache; this._source = sourceCache._source; - if (! this._source.loaded()) this._source.once("data", () => this._loadQueue.forEach(tile => { - this._source.loadTile(tile, () => this._tileLoaded(tile)); - })); + if (! this._source.loaded()) this._source.once("data", () => { + this._loadQueue.forEach(tile => this._source.loadTile(tile, () => this._tileLoaded(tile))); + this._loadQueue = []; + }); } /** @@ -44,8 +45,12 @@ class TerrainSourceCache extends Evented { */ update(transform: Transform, context: Context) { transform._calcMatrices(); - let idealTileIDs = this.getRenderableTileIds(transform).filter(id => !this._tiles[id.key]); + let idealTileIDs = this.getRenderableTileIds(transform); + let outdated = {}; + Object.keys(this._tiles).forEach(key => outdated[key] = true); for (const tileID of idealTileIDs) { + delete(outdated[tileID.key]); + if (this._tiles[tileID.key]) continue; let tile = this._tiles[tileID.key] = this._createEmptyTile(tileID); this._coordsIndex[tile._coordsIndex] = tile; if (this._source && this._source.loaded()) { @@ -54,13 +59,20 @@ class TerrainSourceCache extends Evented { this._loadQueue.push(tile); // remember for loading later } } + for (const key in outdated) { + let tile = this._tiles[key]; + tile.textures.forEach(t => t.destroy()); + tile.textures = []; + tile.coordsTexture && tile.coordsTexture.destroy(); + tile.coordsTexture = null; + } } getRenderableTileIds(transform: Transform) { return transform.coveringTiles({ tileSize: this.tileSize, minzoom: this._source ? this._source.minzoom : this.minzoom, - maxzoom: 14, + maxzoom: this.maxzoom, reparseOverscaled: true }); } From 5d24943d7122fe6a05e1729dd4c709fb3c8995dc Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 26 Jul 2021 19:01:01 +0200 Subject: [PATCH 019/138] reuse framebuffer objects during rtt rendering --- src/render/draw_terrain.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index da5eab5b9cc..31f3f664e22 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -15,6 +15,8 @@ import browser from '../util/browser'; import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; import EXTENT from '../data/extent'; +const FBOs = {}; + function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { const context = painter.context; const gl = context.gl; @@ -57,6 +59,7 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth: number=1) { const context = painter.context; + let fbo = 0; for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { const tile = sourceCache.getTileByID(tileID.key); const tileSize = tile.tileSize * 2; @@ -64,10 +67,6 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth tile.textures[painter.batch] = new Texture(context, {width: tileSize, height: tileSize, data: null}, context.gl.RGBA); tile.textures[painter.batch].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); } - if (!tile.fbo) { - tile.fbo = context.createFramebuffer(tileSize, tileSize, true); - tile.fbo.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, tileSize, tileSize)); - } if (!tile.segments) { const vertexArray = new Pos3DArray(), indexArray = new TriangleIndexArray(); // create regular terrain-mesh. @@ -86,7 +85,13 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth tile.coordsTexture = new Texture(context, tile.coords, context.gl.RGBA, {premultiply: false}); tile.coordsTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); } - // set current batch-texture to framebuffer + // reuse a framebuffer from the framebuffer-stack and attach active batch-texture + if (!FBOs[tileSize]) FBOs[tileSize] = {}; + if (!FBOs[tileSize][fbo]) { + FBOs[tileSize][fbo] = context.createFramebuffer(tileSize, tileSize, true); + FBOs[tileSize][fbo].depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, tileSize, tileSize)); + } + tile.fbo = FBOs[tileSize][fbo++]; tile.fbo.colorAttachment.set(tile.textures[painter.batch].texture); context.bindFramebuffer.set(null); } From 7aaff8f2917fecd56a94e45e9cb340cfd4fa4904 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 26 Jul 2021 20:16:29 +0200 Subject: [PATCH 020/138] reuse regular-mesh in all tiles --- src/render/draw_terrain.js | 35 ++++++++++----------- src/shaders/terrain.vertex.glsl | 7 +++-- src/source/raster_dem_tile_worker_source.js | 25 --------------- src/source/terrain_source_cache.js | 24 ++++++++++++-- 4 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index 31f3f664e22..12d5dae7df1 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -2,18 +2,20 @@ import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; -import SegmentVector from '../data/segment'; import {terrainUniformValues} from './program/terrain_program'; import type Painter from './painter'; import type TerranSourceCache from '../source/terrain_source_cache'; import CullFaceMode from '../gl/cull_face_mode'; -import pos3DAttributes from '../data/pos3d_attributes'; import Texture from './texture'; import Color from '../style-spec/util/color'; import ColorMode from '../gl/color_mode'; import browser from '../util/browser'; -import {Pos3DArray, TriangleIndexArray} from '../data/array_types'; -import EXTENT from '../data/extent'; +import {TerrainElevationArray} from '../data/array_types'; +import {createLayout} from '../util/struct_array'; + +const elevationAttributes = createLayout([ + {name: 'a_ele', components: 1, type: 'Float32'} +], 4); const FBOs = {}; @@ -35,7 +37,9 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { gl.bindTexture(gl.TEXTURE_2D, tile.coordsTexture.texture); const posMatrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); + terrainUniformValues(posMatrix), "terrain", + sourceCache.mesh.vertexBuffer, sourceCache.mesh.indexBuffer, sourceCache.mesh.segments, + null, null, null, tile.elevationVertexBuffer); } painter.finishFramebuffer(); } @@ -53,7 +57,9 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { gl.bindTexture(gl.TEXTURE_2D, tile.fbo.colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainUniformValues(posMatrix), "terrain", tile.vertexBuffer, tile.indexBuffer, tile.segments); + terrainUniformValues(posMatrix), "terrain", + sourceCache.mesh.vertexBuffer, sourceCache.mesh.indexBuffer, sourceCache.mesh.segments, + null, null, null, tile.elevationVertexBuffer); } } @@ -67,19 +73,12 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth tile.textures[painter.batch] = new Texture(context, {width: tileSize, height: tileSize, data: null}, context.gl.RGBA); tile.textures[painter.batch].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); } - if (!tile.segments) { - const vertexArray = new Pos3DArray(), indexArray = new TriangleIndexArray(); - // create regular terrain-mesh. - const meshSize = sourceCache.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; - for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) - vertexArray.emplaceBack(x * delta, y * delta, Math.floor(sourceCache.getElevation(tileID, x, y, meshSize))); - for (let y=0; y this.getTileByID(id)) - .forEach(tile => { if (tile) tile.segments = null }); + .forEach(tile => { if (tile) tile.elevationVertexBuffer = null }); } // mark all tiles to refetch elevation-data // FIXME! only mark necessary tiles From 87e820587ab9a47fbce75eab64853a4183faa5da Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 27 Jul 2021 11:54:34 +0200 Subject: [PATCH 021/138] add transform.elevation --- src/data/array_types.js | 1 + src/geo/transform.js | 23 ++++++++++++++++++++--- src/source/terrain_source_cache.js | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/data/array_types.js b/src/data/array_types.js index 1c138e228ab..bf1d95473dd 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -1118,6 +1118,7 @@ export { StructArrayLayout4i8 as RasterBoundsArray, StructArrayLayout2i4 as CircleLayoutArray, StructArrayLayout1f4 as CircleElevationArray, + StructArrayLayout1f4 as TerrainElevationArray, StructArrayLayout2i4 as FillLayoutArray, StructArrayLayout2i4i12 as FillExtrusionLayoutArray, StructArrayLayout1f4 as FillExtrusionElevationArray, diff --git a/src/geo/transform.js b/src/geo/transform.js index 1f5266ab425..d76f661da00 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -54,6 +54,7 @@ class Transform { _minPitch: number; _maxPitch: number; _center: LngLat; + _elevation: number; _edgeInsets: EdgeInsets; _constraining: boolean; _posMatrixCache: {[_: string]: Float32Array}; @@ -75,6 +76,7 @@ class Transform { this.width = 0; this.height = 0; this._center = new LngLat(0, 0); + this._elevation = 0; this.zoom = 0; this.angle = 0; this._fov = 0.6435011087932844; @@ -92,6 +94,7 @@ class Transform { clone.width = this.width; clone.height = this.height; clone._center = this._center; + clone._elevation = this._elevation; clone.zoom = this.zoom; clone.angle = this.angle; clone._fov = this._fov; @@ -213,6 +216,15 @@ class Transform { this._calcMatrices(); } + get elevation(): LngLat { return this._elevation; } + set elevation(elevation: number) { + if (elevation === this._elevation) return; + this._unmodified = false; + this._elevation = elevation; + this._constrain(); + this._calcMatrices(); + } + get padding(): PaddingOptions { return this._edgeInsets.toJSON(); } set padding(padding: PaddingOptions) { if (this._edgeInsets.equals(padding)) return; @@ -352,7 +364,7 @@ class Transform { // FIXME-3D! -5 .. 5 is enough for rendering front elevation tiles, dont know why // but with this simple hack, there a rendered to many tiles outside the viewport, // which is a performance issue - aabb: new Aabb([wrap * numTiles, 0, -5], [(wrap + 1) * numTiles, numTiles, 5]), + aabb: new Aabb([wrap * numTiles, 0, 0], [(wrap + 1) * numTiles, numTiles, 5]), zoom: 0, x: 0, y: 0, @@ -451,6 +463,10 @@ class Transform { get point(): Point { return this.project(this.center); } + updateElevation() { + this.elevation = this.getElevation(this._center); + } + getElevation(lnglat: LngLat) { const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; if (!tsc) return 0; @@ -596,7 +612,7 @@ class Transform { */ coordinatePoint(coord: MercatorCoordinate, elevation: number=0) { const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1]; - vec4.transformMat4(p, p, this.pixelMatrix); + vec4.transformMat4(p, p, this.pixelMatrix2); return new Point(p[0] / p[3], p[1] / p[3]); } @@ -740,7 +756,7 @@ class Transform { _calcMatrices() { if (!this.height) return; - const elevation = this.getElevation(this._center); + const elevation = this._elevation; const halfFov = this._fov / 2; const offset = this.centerOffset; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; @@ -809,6 +825,7 @@ class Transform { mat4.translate(m, m, [0, 0, -elevation]); this.projMatrix = m; this.invProjMatrix = mat4.invert([], this.projMatrix); + this.pixelMatrix2 = mat4.multiply(new Float64Array(16), this.labelPlaneMatrix, m); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 871f6e1ffd2..8b1fcd259f4 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -64,7 +64,7 @@ class TerrainSourceCache extends Evented { segments: SegmentVector.simpleSegment(0, 0, vertexArray.length, indexArray.length) }; } - transform._calcMatrices(); + transform.updateElevation(); let idealTileIDs = this.getRenderableTileIds(transform); let outdated = {}; Object.keys(this._tiles).forEach(key => outdated[key] = true); From ba9bd36fdfa55bccdec60cf59c9bc9a0def26175 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 28 Jul 2021 12:18:52 +0200 Subject: [PATCH 022/138] create transform.invProjMatrix before elevation correcture --- src/geo/transform.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/geo/transform.js b/src/geo/transform.js index d76f661da00..654ab6dd93f 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -822,9 +822,9 @@ class Transform { this.pixelMatrix = mat4.multiply(new Float64Array(16), this.labelPlaneMatrix, m); // matrix for conversion from location to GL coordinates (-1 .. 1) - mat4.translate(m, m, [0, 0, -elevation]); + this.invProjMatrix = mat4.invert([], m); + mat4.translate(m, m, [0, 0, -elevation]); // elevate camera over terrain this.projMatrix = m; - this.invProjMatrix = mat4.invert([], this.projMatrix); this.pixelMatrix2 = mat4.multiply(new Float64Array(16), this.labelPlaneMatrix, m); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. From 55ad06ad9513dab926a88698074295372f5a3ab1 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 10 Aug 2021 13:14:56 +0200 Subject: [PATCH 023/138] * move exaggeration calculation into shaders * new more performant encoding of the coords-framebuffer --- src/geo/transform.js | 20 ++-- src/render/draw_symbol.js | 2 +- src/render/draw_terrain.js | 23 ++--- src/render/program/circle_program.js | 9 +- src/render/program/fill_extrusion_program.js | 15 ++- src/render/program/program_uniforms.js | 5 +- src/render/program/symbol_program.js | 21 ++-- src/render/program/terrain_program.js | 38 ++++++-- src/shaders/_prelude.vertex.glsl | 13 ++- src/shaders/circle.vertex.glsl | 7 +- src/shaders/fill_extrusion.vertex.glsl | 5 +- .../fill_extrusion_pattern.vertex.glsl | 5 +- src/shaders/shaders.js | 2 + src/shaders/symbol_icon.vertex.glsl | 7 +- src/shaders/symbol_sdf.vertex.glsl | 7 +- src/shaders/symbol_text_and_icon.vertex.glsl | 7 +- src/shaders/terrain.vertex.glsl | 4 +- src/shaders/terrain_coords.fragment.glsl | 11 +++ src/source/terrain_source_cache.js | 95 +++++++++++-------- src/symbol/placement.js | 2 +- 20 files changed, 190 insertions(+), 108 deletions(-) create mode 100644 src/shaders/terrain_coords.fragment.glsl diff --git a/src/geo/transform.js b/src/geo/transform.js index 654ab6dd93f..c5e0aad3511 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -348,7 +348,7 @@ class Transform { const centerCoord = MercatorCoordinate.fromLngLat(this.center); const numTiles = Math.pow(2, z); const centerPoint = [numTiles * centerCoord.x, numTiles * centerCoord.y, 0]; - const cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix, this.worldSize, z); + const cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix2, this.worldSize, z); // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level let minZoom = options.minzoom || 0; @@ -589,17 +589,17 @@ class Transform { gl.readPixels(p.x, painter.height / browser.devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); context.bindFramebuffer.set(null); // decode coordinates (encoding see terrain-source-cache) - const y = (rgba[3] >> 1) | ((rgba[2] & 3) << 7); - const x = (rgba[2] >> 2) | ((rgba[1] & 7) << 6); - const i = (rgba[1] >> 3) | (rgba[0] << 5); - const tile = this.terrainSourceCache._coordsIndex[i]; + const x = rgba[0] + ((rgba[2] >> 4) << 8); + const y = rgba[1] + ((rgba[2] & 15) << 8); + const tileID = this.terrainSourceCache.coordsIndex[255 - rgba[3]]; + const tile = tileID && this.terrainSourceCache.getTileByID(tileID); if (!tile) return this.pointCoordinate(p); // FIXME! remove this hack const tileSize = this.terrainSourceCache.tileSize; const worldSize = (1 << tile.tileID.canonical.z) * tileSize; return new MercatorCoordinate( - (tile.tileID.canonical.x * tileSize + x) / worldSize, - (tile.tileID.canonical.y * tileSize + y) / worldSize, - this.terrainSourceCache.getElevation(tile.tileID, x, y, tileSize) + (tile.tileID.canonical.x * tileSize + x / 8) / worldSize, + (tile.tileID.canonical.y * tileSize + y / 8) / worldSize, + this.terrainSourceCache.getElevation(tile.tileID, x, y, 4096) ); } @@ -756,7 +756,8 @@ class Transform { _calcMatrices() { if (!this.height) return; - const elevation = this._elevation; + const exaggeration = this.terrainSourceCache ? this.terrainSourceCache.exaggeration : 1.0; + const elevation = this._elevation * exaggeration; const halfFov = this._fov / 2; const offset = this.centerOffset; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; @@ -826,6 +827,7 @@ class Transform { mat4.translate(m, m, [0, 0, -elevation]); // elevate camera over terrain this.projMatrix = m; this.pixelMatrix2 = mat4.multiply(new Float64Array(16), this.labelPlaneMatrix, m); + this.invProjMatrix2 = mat4.invert(new Float64Array(16), m); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 8809d640dbf..c7e778fc721 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -323,7 +323,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate bucket.hasIconData(); if (alongLine) { - const getElevation = (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y); + const getElevation = (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y); symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } diff --git a/src/render/draw_terrain.js b/src/render/draw_terrain.js index 12d5dae7df1..0a6b372aa5b 100644 --- a/src/render/draw_terrain.js +++ b/src/render/draw_terrain.js @@ -2,7 +2,7 @@ import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; -import {terrainUniformValues} from './program/terrain_program'; +import {terrainUniformValues, terrainCoordsUniformValues} from './program/terrain_program'; import type Painter from './painter'; import type TerranSourceCache from '../source/terrain_source_cache'; import CullFaceMode from '../gl/cull_face_mode'; @@ -23,23 +23,27 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; - const program = painter.useProgram('terrain'); + const program = painter.useProgram('terrainCoords'); const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); + const mesh = sourceCache.getTerrainMesh(context); + const coords = sourceCache.getCoordsTexture(context); // draw tile-coords into framebuffer context.bindFramebuffer.set(sourceCache.getCoordsFramebuffer(painter).framebuffer); context.viewport.set([0, 0, painter.width / browser.devicePixelRatio, painter.height / browser.devicePixelRatio]); context.clear({ color: Color.transparent, depth: 1 }); + sourceCache.coordsIndex = []; for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { const tile = sourceCache.getTileByID(tileID.key); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, tile.coordsTexture.texture); + gl.bindTexture(gl.TEXTURE_2D, coords.texture); const posMatrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainUniformValues(posMatrix), "terrain", - sourceCache.mesh.vertexBuffer, sourceCache.mesh.indexBuffer, sourceCache.mesh.segments, + terrainCoordsUniformValues(painter, posMatrix, 255 - sourceCache.coordsIndex.length), "terrain", + mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, null, null, null, tile.elevationVertexBuffer); + sourceCache.coordsIndex.push(tileID.key); } painter.finishFramebuffer(); } @@ -50,6 +54,7 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { const colorMode = painter.colorModeForRenderPass(); const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); const program = painter.useProgram('terrain'); + const mesh = sourceCache.getTerrainMesh(context); for (const tileID of sourceCache.getRenderableTileIds(painter.transform)) { const tile = sourceCache.getTileByID(tileID.key); @@ -57,8 +62,8 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { gl.bindTexture(gl.TEXTURE_2D, tile.fbo.colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainUniformValues(posMatrix), "terrain", - sourceCache.mesh.vertexBuffer, sourceCache.mesh.indexBuffer, sourceCache.mesh.segments, + terrainUniformValues(painter, posMatrix), "terrain", + mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, null, null, null, tile.elevationVertexBuffer); } } @@ -80,10 +85,6 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth } tile.elevationVertexBuffer = context.createVertexBuffer(vertexArray, elevationAttributes.members, true); } - if (!tile.coordsTexture) { - tile.coordsTexture = new Texture(context, tile.coords, context.gl.RGBA, {premultiply: false}); - tile.coordsTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - } // reuse a framebuffer from the framebuffer-stack and attach active batch-texture if (!FBOs[tileSize]) FBOs[tileSize] = {}; if (!FBOs[tileSize][fbo]) { diff --git a/src/render/program/circle_program.js b/src/render/program/circle_program.js index 79f38cf44d7..03991c61912 100644 --- a/src/render/program/circle_program.js +++ b/src/render/program/circle_program.js @@ -23,7 +23,8 @@ export type CircleUniformsType = {| 'u_extrude_scale': Uniform2f, 'u_device_pixel_ratio': Uniform1f, 'u_matrix': UniformMatrix4f, - 'u_coords': Uniform1i + 'u_coords': Uniform1i, + 'u_ele_exaggeration': Uniform1f |}; const circleUniforms = (context: Context, locations: UniformLocations): CircleUniformsType => ({ @@ -33,7 +34,8 @@ const circleUniforms = (context: Context, locations: UniformLocations): CircleUn 'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_coords': new Uniform1i(context, locations.u_coords) + 'u_coords': new Uniform1i(context, locations.u_coords), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) }); const circleUniformValues = ( @@ -65,7 +67,8 @@ const circleUniformValues = ( 'u_pitch_with_map': +(pitchWithMap), 'u_device_pixel_ratio': browser.devicePixelRatio, 'u_extrude_scale': extrudeScale, - 'u_coords': 0 + 'u_coords': 0, + 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/fill_extrusion_program.js b/src/render/program/fill_extrusion_program.js index 39dec5cf055..c29d24f82c6 100644 --- a/src/render/program/fill_extrusion_program.js +++ b/src/render/program/fill_extrusion_program.js @@ -25,7 +25,8 @@ export type FillExtrusionUniformsType = {| 'u_lightintensity': Uniform1f, 'u_lightcolor': Uniform3f, 'u_vertical_gradient': Uniform1f, - 'u_opacity': Uniform1f + 'u_opacity': Uniform1f, + 'u_ele_exaggeration': Uniform1f |}; export type FillExtrusionPatternUniformsType = {| @@ -42,7 +43,8 @@ export type FillExtrusionPatternUniformsType = {| 'u_pixel_coord_lower': Uniform2f, 'u_scale': Uniform3f, 'u_fade': Uniform1f, - 'u_opacity': Uniform1f + 'u_opacity': Uniform1f, + 'u_ele_exaggeration': Uniform1f |}; const fillExtrusionUniforms = (context: Context, locations: UniformLocations): FillExtrusionUniformsType => ({ @@ -51,7 +53,8 @@ const fillExtrusionUniforms = (context: Context, locations: UniformLocations): F 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), 'u_lightcolor': new Uniform3f(context, locations.u_lightcolor), 'u_vertical_gradient': new Uniform1f(context, locations.u_vertical_gradient), - 'u_opacity': new Uniform1f(context, locations.u_opacity) + 'u_opacity': new Uniform1f(context, locations.u_opacity), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) }); const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): FillExtrusionPatternUniformsType => ({ @@ -68,7 +71,8 @@ const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocati 'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower), 'u_scale': new Uniform3f(context, locations.u_scale), 'u_fade': new Uniform1f(context, locations.u_fade), - 'u_opacity': new Uniform1f(context, locations.u_opacity) + 'u_opacity': new Uniform1f(context, locations.u_opacity), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) }); const fillExtrusionUniformValues = ( @@ -94,7 +98,8 @@ const fillExtrusionUniformValues = ( 'u_lightintensity': light.properties.get('intensity'), 'u_lightcolor': [lightColor.r, lightColor.g, lightColor.b], 'u_vertical_gradient': +shouldUseVerticalGradient, - 'u_opacity': opacity + 'u_opacity': opacity, + 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/program_uniforms.js b/src/render/program/program_uniforms.js index 1496cbd4f83..d428f17e06b 100644 --- a/src/render/program/program_uniforms.js +++ b/src/render/program/program_uniforms.js @@ -12,7 +12,7 @@ import {lineUniforms, lineGradientUniforms, linePatternUniforms, lineSDFUniforms import {rasterUniforms} from './raster_program'; import {symbolIconUniforms, symbolSDFUniforms, symbolTextAndIconUniforms} from './symbol_program'; import {backgroundUniforms, backgroundPatternUniforms} from './background_program'; -import {terrainUniforms} from './terrain_program'; +import {terrainUniforms, terrainCoordsUniforms} from './terrain_program'; export const programUniforms = { fillExtrusion: fillExtrusionUniforms, @@ -40,5 +40,6 @@ export const programUniforms = { symbolTextAndIcon: symbolTextAndIconUniforms, background: backgroundUniforms, backgroundPattern: backgroundPatternUniforms, - terrain: terrainUniforms + terrain: terrainUniforms, + terrainCoords: terrainCoordsUniforms }; diff --git a/src/render/program/symbol_program.js b/src/render/program/symbol_program.js index 50de9c3c7bf..358732d7a59 100644 --- a/src/render/program/symbol_program.js +++ b/src/render/program/symbol_program.js @@ -30,7 +30,8 @@ export type SymbolIconUniformsType = {| 'u_pitch_with_map': Uniform1i, 'u_texsize': Uniform2f, 'u_texture': Uniform1i, - 'u_coords': Uniform1i + 'u_coords': Uniform1i, + 'u_ele_exaggeration': Uniform1f |}; export type SymbolSDFUniformsType = {| @@ -53,7 +54,8 @@ export type SymbolSDFUniformsType = {| 'u_gamma_scale': Uniform1f, 'u_device_pixel_ratio': Uniform1f, 'u_is_halo': Uniform1i, - 'u_coords': Uniform1i + 'u_coords': Uniform1i, + 'u_ele_exaggeration': Uniform1f |}; export type symbolTextAndIconUniformsType = {| @@ -78,7 +80,8 @@ export type symbolTextAndIconUniformsType = {| 'u_gamma_scale': Uniform1f, 'u_device_pixel_ratio': Uniform1f, 'u_is_halo': Uniform1i, - 'u_coords': Uniform1i + 'u_coords': Uniform1i, + 'u_ele_exaggeration': Uniform1f |}; const symbolIconUniforms = (context: Context, locations: UniformLocations): SymbolIconUniformsType => ({ @@ -98,7 +101,8 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_texture': new Uniform1i(context, locations.u_texture), - 'u_coords': new Uniform1i(context, locations.u_coords) + 'u_coords': new Uniform1i(context, locations.u_coords), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) }); const symbolSDFUniforms = (context: Context, locations: UniformLocations): SymbolSDFUniformsType => ({ @@ -121,7 +125,8 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new Uniform1i(context, locations.u_is_halo), - 'u_coords': new Uniform1i(context, locations.u_coords) + 'u_coords': new Uniform1i(context, locations.u_coords), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) }); const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations): symbolTextAndIconUniformsType => ({ @@ -146,7 +151,8 @@ const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new Uniform1i(context, locations.u_is_halo), - 'u_coords': new Uniform1i(context, locations.u_coords) + 'u_coords': new Uniform1i(context, locations.u_coords), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) }); const symbolIconUniformValues = ( @@ -180,7 +186,8 @@ const symbolIconUniformValues = ( 'u_pitch_with_map': +pitchWithMap, 'u_texsize': texSize, 'u_texture': 0, - 'u_coords': 2 + 'u_coords': 2, + 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/terrain_program.js b/src/render/program/terrain_program.js index 421e224cb96..9404aea75f6 100644 --- a/src/render/program/terrain_program.js +++ b/src/render/program/terrain_program.js @@ -2,24 +2,50 @@ import { Uniform1i, + Uniform1f, UniformMatrix4f } from '../uniform_binding'; import type Context from '../gl/context'; +import type Painter from '../painter'; import type {UniformValues, UniformLocations} from '../render/uniform_binding'; export type TerrainUniformsType = {| 'u_matrix': UniformMatrix4f, - 'u_texture': Uniform1i + 'u_texture': Uniform1i, + 'u_ele_exaggeration': Uniform1f |}; -const terrainUniforms = (context: Context, locations: UniformLocations): TerrainRasterUniformsType => ({ +export type TerrainCoordsUniformsType = {| + 'u_matrix': UniformMatrix4f, + 'u_texture': Uniform1i, + 'u_terrain_coords_id': Uniform1f, + 'u_ele_exaggeration': Uniform1f +|}; + +const terrainUniforms = (context: Context, locations: UniformLocations): TerrainUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_texture': new Uniform1i(context, locations.u_texture) + 'u_texture': new Uniform1i(context, locations.u_texture), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) +}); + +const terrainCoordsUniforms = (context: Context, locations: UniformLocations): TerrainCoordsUniformsType => ({ + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_texture': new Uniform1i(context, locations.u_texture), + 'u_terrain_coords_id': new Uniform1f(context, locations.u_terrain_coords_id), + 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) +}); + +const terrainUniformValues = (painter: Painter, matrix: Float32Array): UniformValues => ({ + 'u_matrix': matrix, + 'u_texture': 0, + 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration }); -const terrainUniformValues = (matrix: Float32Array): UniformValues => ({ +const terrainCoordsUniformValues = (painter: Painter, matrix: Float32Array, coordsId: number): UniformValues => ({ 'u_matrix': matrix, - 'u_texture': 0 + 'u_texture': 0, + 'u_terrain_coords_id': coordsId / 255, + 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration }); -export {terrainUniforms, terrainUniformValues}; +export {terrainUniforms, terrainCoordsUniforms, terrainUniformValues, terrainCoordsUniformValues}; diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 4ed1c8e7e96..d7b45bd716c 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -78,13 +78,12 @@ float hasBit(float value, int pos) { // unpack a RGBA value from the the coords framebuffer into a vec2 in the range from 0 .. 8191 vec2 unpackCoord(vec4 rgba) { - float r = floor(rgba.x * 255.0); - float g = floor(rgba.y * 255.0); - float b = floor(rgba.z * 255.0); - float a = floor(rgba.w * 255.0); - float x = hasBit(b, 2) * 1.0 + hasBit(b, 3) * 2.0 + hasBit(b, 4) * 4.0 + hasBit(b, 5) * 8.0 + hasBit(b, 6) * 16.0 + hasBit(b, 7) * 32.0 + hasBit(g, 0) * 64.0 + hasBit(g, 1) * 128.0 + hasBit(g, 2) * 258.0; - float y = hasBit(a, 1) * 1.0 + hasBit(a, 2) * 2.0 + hasBit(a, 3) * 4.0 + hasBit(a, 4) * 8.0 + hasBit(a, 5) * 16.0 + hasBit(a, 6) * 32.0 + hasBit(a, 7) * 64.0 + hasBit(b, 0) * 128.0 + hasBit(b, 1) * 258.0; - return vec2(x, y) / 511.0 * 8191.0; + float r = floor(rgba.r * 255.0); + float g = floor(rgba.g * 255.0); + float b = floor(rgba.b * 255.0); + float x = r + hasBit(b, 4) * 256.0 + hasBit(b, 5) * 512.0 + hasBit(b, 6) * 1024.0 + hasBit(b, 7) * 2048.0; + float y = g + hasBit(b, 0) * 256.0 + hasBit(b, 1) * 512.0 + hasBit(b, 2) * 1024.0 + hasBit(b, 3) * 2048.0; + return vec2(x, y) * 2.0; } // unpack a coord RGBA to vec2 diff --git a/src/shaders/circle.vertex.glsl b/src/shaders/circle.vertex.glsl index 2566a73285d..a2b31989ce4 100644 --- a/src/shaders/circle.vertex.glsl +++ b/src/shaders/circle.vertex.glsl @@ -5,6 +5,7 @@ uniform vec2 u_extrude_scale; uniform lowp float u_device_pixel_ratio; uniform highp float u_camera_to_center_distance; uniform highp sampler2D u_coords; +uniform lowp float u_ele_exaggeration; attribute vec2 a_pos; attribute float a_ele; @@ -35,7 +36,7 @@ void main(void) { // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data vec2 circle_center = floor(a_pos * 0.5); - v_visibility = calculate_visibility(u_coords, u_matrix * vec4(circle_center, a_ele, 1.0), circle_center); + v_visibility = calculate_visibility(u_coords, u_matrix * vec4(circle_center, a_ele * u_ele_exaggeration, 1.0), circle_center); if (u_pitch_with_map) { vec2 corner_position = circle_center; @@ -49,9 +50,9 @@ void main(void) { corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance); } - gl_Position = u_matrix * vec4(corner_position, a_ele, 1); + gl_Position = u_matrix * vec4(corner_position, a_ele * u_ele_exaggeration, 1); } else { - gl_Position = u_matrix * vec4(circle_center, a_ele, 1); + gl_Position = u_matrix * vec4(circle_center, a_ele * u_ele_exaggeration, 1); if (u_scale_with_map) { gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance; diff --git a/src/shaders/fill_extrusion.vertex.glsl b/src/shaders/fill_extrusion.vertex.glsl index 017dd0cd74f..b4ce53ebafa 100644 --- a/src/shaders/fill_extrusion.vertex.glsl +++ b/src/shaders/fill_extrusion.vertex.glsl @@ -4,6 +4,7 @@ uniform lowp vec3 u_lightpos; uniform lowp float u_lightintensity; uniform float u_vertical_gradient; uniform lowp float u_opacity; +uniform lowp float u_ele_exaggeration; attribute vec2 a_pos; attribute vec4 a_normal_ed; @@ -23,8 +24,8 @@ void main() { vec3 normal = a_normal_ed.xyz; - base = max(0.0, a_ele + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation - height = max(0.0, a_ele + height); + base = max(0.0, a_ele * u_ele_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + height = max(0.0, a_ele * u_ele_exaggeration + height); float t = mod(normal.x, 2.0); diff --git a/src/shaders/fill_extrusion_pattern.vertex.glsl b/src/shaders/fill_extrusion_pattern.vertex.glsl index 2c384aaeea3..9f8d88186c6 100644 --- a/src/shaders/fill_extrusion_pattern.vertex.glsl +++ b/src/shaders/fill_extrusion_pattern.vertex.glsl @@ -9,6 +9,7 @@ uniform lowp float u_opacity; uniform vec3 u_lightcolor; uniform lowp vec3 u_lightpos; uniform lowp float u_lightintensity; +uniform lowp float u_ele_exaggeration; attribute vec2 a_pos; attribute vec4 a_normal_ed; @@ -48,8 +49,8 @@ void main() { vec2 display_size_a = (pattern_br_a - pattern_tl_a) / pixel_ratio_from; vec2 display_size_b = (pattern_br_b - pattern_tl_b) / pixel_ratio_to; - base = max(0.0, a_ele + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation - height = max(0.0, a_ele + height); + base = max(0.0, a_ele * u_ele_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + height = max(0.0, a_ele * u_ele_exaggeration + height); float t = mod(normal.x, 2.0); float z = t > 0.0 ? height : base; diff --git a/src/shaders/shaders.js b/src/shaders/shaders.js index 7cd19ced73a..a5ccdaf37a5 100644 --- a/src/shaders/shaders.js +++ b/src/shaders/shaders.js @@ -54,6 +54,7 @@ import symbolSDFFrag from './symbol_sdf.fragment.glsl'; import symbolSDFVert from './symbol_sdf.vertex.glsl'; import symbolTextAndIconFrag from './symbol_text_and_icon.fragment.glsl'; import symbolTextAndIconVert from './symbol_text_and_icon.vertex.glsl'; +import terrainCoordsFrag from './terrain_coords.fragment.glsl'; import terrainFrag from './terrain.fragment.glsl'; import terrainVert from './terrain.vertex.glsl'; @@ -84,6 +85,7 @@ export const symbolIcon = compile(symbolIconFrag, symbolIconVert); export const symbolSDF = compile(symbolSDFFrag, symbolSDFVert); export const symbolTextAndIcon = compile(symbolTextAndIconFrag, symbolTextAndIconVert); export const terrain = compile(terrainFrag, terrainVert); +export const terrainCoords = compile(terrainCoordsFrag, terrainVert); // Expand #pragmas to #ifdefs. diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 20fa7e7afeb..f51ea9c6cc4 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -23,6 +23,7 @@ uniform bool u_is_text; uniform bool u_pitch_with_map; uniform vec2 u_texsize; uniform highp sampler2D u_coords; +uniform lowp float u_ele_exaggeration; varying vec2 v_tex; varying float v_fade_opacity; @@ -53,7 +54,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1); highp float camera_to_anchor_distance = projectedPoint.w; // See comments in symbol_sdf.vertex highp float distance_ratio = u_pitch_with_map ? @@ -71,7 +72,7 @@ void main() { highp float symbol_rotation = 0.0; if (u_rotate_symbol) { // See comments in symbol_sdf.vertex - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_ele_exaggeration, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -83,7 +84,7 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_ele_exaggeration, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), z, 1.0); diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index 05285d0de9e..d22ce22b015 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -30,6 +30,7 @@ uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; uniform highp sampler2D u_coords; +uniform lowp float u_ele_exaggeration; varying vec2 v_data0; varying vec3 v_data1; @@ -67,7 +68,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -92,7 +93,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_ele_exaggeration, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -104,7 +105,7 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_ele_exaggeration, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), z, 1.0); float gamma_scale = gl_Position.w; diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index 3e2818409d6..b0997155a53 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -30,6 +30,7 @@ uniform float u_fade_change; uniform vec2 u_texsize; uniform vec2 u_texsize_icon; uniform highp sampler2D u_coords; +uniform lowp float u_ele_exaggeration; varying vec4 v_data0; varying vec4 v_data1; @@ -67,7 +68,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -92,7 +93,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_ele_exaggeration, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -104,7 +105,7 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_ele_exaggeration, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), z, 1.0); float gamma_scale = gl_Position.w; diff --git a/src/shaders/terrain.vertex.glsl b/src/shaders/terrain.vertex.glsl index 1e9b35cfb81..ac52e6790e4 100644 --- a/src/shaders/terrain.vertex.glsl +++ b/src/shaders/terrain.vertex.glsl @@ -2,9 +2,11 @@ attribute vec2 a_pos; attribute float a_ele; uniform mat4 u_matrix; +uniform lowp float u_ele_exaggeration; + varying vec2 v_texture_pos; void main() { v_texture_pos = a_pos / 8192.0; - gl_Position = u_matrix * vec4(a_pos, a_ele, 1.0); + gl_Position = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1.0); } diff --git a/src/shaders/terrain_coords.fragment.glsl b/src/shaders/terrain_coords.fragment.glsl new file mode 100644 index 00000000000..c4d8c7815be --- /dev/null +++ b/src/shaders/terrain_coords.fragment.glsl @@ -0,0 +1,11 @@ +precision mediump float; + +uniform sampler2D u_texture; +uniform float u_terrain_coords_id; + +varying vec2 v_texture_pos; + +void main() { + vec4 rgba = texture2D(u_texture, v_texture_pos); + gl_FragColor = vec4(rgba.r, rgba.g, rgba.b, u_terrain_coords_id); +} diff --git a/src/source/terrain_source_cache.js b/src/source/terrain_source_cache.js index 8b1fcd259f4..22241652f82 100644 --- a/src/source/terrain_source_cache.js +++ b/src/source/terrain_source_cache.js @@ -21,15 +21,15 @@ class TerrainSourceCache extends Evented { this._sourceCache = null; this._source = null; this._tiles = []; - this._coordsIndex = {}; this._loadQueue = []; this._coordsFramebuffer = null; this._rerender = true; this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; - this.meshSize = 64; - this.exaggeration = 1; + this.meshSize = 128; + this.exaggeration = 1.0; + this.coordsIndex = []; style.on("data", () => this._rerender = true); } @@ -48,22 +48,6 @@ class TerrainSourceCache extends Evented { * @private */ update(transform: Transform, context: Context) { - if (!this.mesh) { - // create a regular mesh which will be used by all terrain-tiles - const vertexArray = new PosArray(), indexArray = new TriangleIndexArray(); - const meshSize = this.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; - for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) - vertexArray.emplaceBack(x * delta, y * delta); - for (let y=0; y this._tileLoaded(tile)); } else { @@ -83,8 +66,6 @@ class TerrainSourceCache extends Evented { let tile = this._tiles[key]; tile.textures.forEach(t => t.destroy()); tile.textures = []; - tile.coordsTexture && tile.coordsTexture.destroy(); - tile.coordsTexture = null; } } @@ -98,7 +79,7 @@ class TerrainSourceCache extends Evented { } getRenderableIds() { - return Object.values(this._tiles).map(t => t.tileID.key); + return Object.values(this._tiles).map(t => t.tileID.key); } /** @@ -125,7 +106,18 @@ class TerrainSourceCache extends Evented { const elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; - return (elevation + 450) * this.exaggeration; // add a global offset of 450m to put the dead-sea into positive values. + return (elevation + 450); // add a global offset of 450m to put the dead-sea into positive values. + } + + /** + * get the Elevation for given coordinate multiplied by exaggeration. + * @param {OverscaledTileID} tileID + * @param {number} x between 0 .. EXTENT + * @param {number} y between 0 .. EXTENT + * @param {number} extent optional, default 8192 + */ + getElevationWithExaggeration(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { + return this.getElevation(tileID, x, y, extent) * this.exaggeration; } /** @@ -158,6 +150,46 @@ class TerrainSourceCache extends Evented { return Object.values(this._tiles).filter(t => t.loadTime >= time); } + // create a regular mesh which will be used by all terrain-tiles + getTerrainMesh(context: Context) { + if (this.mesh) return this.mesh; + const vertexArray = new PosArray(), indexArray = new TriangleIndexArray(); + const meshSize = this.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; + for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) + vertexArray.emplaceBack(x * delta, y * delta); + for (let y=0; y> 8) << 4) | (y >> 8); + data[i + 3] = 0; + } + let image = new RGBAImage({width: 4096, height: 4096}, new Uint8Array(data.buffer)); + let texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); + texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + return this.coords = texture; + } + /** * after a tile is loaded: * - recreate terrain-mesh webgl segments @@ -187,21 +219,6 @@ class TerrainSourceCache extends Evented { tileID.posMatrix = mat4.create(); mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); let tile = new Tile(tileID, this.tileSize * tileID.overscaleFactor()); - // create coords texture, needed to grab coordianates from canvas - // encode coords coordinate into 4 bytes: - // - 13 bits for coordsIndex (0 .. 8191) (= number of loaded terraintile) - // - 9 bits for y (0 .. 511) - // - 9 bits for x (0 .. 511) - // - 1 bit for always true in alpha channel, because webgl do not render for opacity 0 - tile._coordsIndex = Object.keys(this._coordsIndex).length + 1; // create unique coords index - const data = new Uint8Array(this.tileSize * this.tileSize * 4); - for (let x=0, i=0; x> 7); - data[i + 1] = ((tile._coordsIndex & 31) << 3) | (y >> 6); - data[i + 0] = tile._coordsIndex >> 5; - } - tile.coords = new RGBAImage({width: this.tileSize, height: this.tileSize}, new Uint8Array(data.buffer)); tile.textures = []; return tile; } diff --git a/src/symbol/placement.js b/src/symbol/placement.js index ae0fcfd65b0..773291a1c03 100644 --- a/src/symbol/placement.js +++ b/src/symbol/placement.js @@ -442,7 +442,7 @@ export class Placement { // update elevtaion of collisionArrays let tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; - let getElevation = (x: number, y: number) => this.transform.terrainSourceCache.getElevation(tileID, x, y); + let getElevation = (x: number, y: number) => this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y); for (let boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { const box = collisionArrays[boxType]; if (box) box.elevation = getElevation(box.anchorPointX, box.anchorPointY); From 1875f51b740eebd2dfb71f6b495fa4e579a00bb3 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 10 Sep 2021 09:19:08 +0200 Subject: [PATCH 024/138] some minor fixes, add map.addTerrain and map.removeTerrain --- debug/terrain.html | 3976 +--------------------- src/data/bucket/circle_bucket.ts | 6 +- src/data/bucket/fill_extrusion_bucket.ts | 25 +- src/geo/transform.ts | 11 +- src/render/draw_background.ts | 8 +- src/render/draw_circle.ts | 4 +- src/render/draw_fill.ts | 7 +- src/render/draw_fill_extrusion.ts | 6 +- src/render/draw_hillshade.ts | 7 +- src/render/draw_line.ts | 14 +- src/render/draw_raster.ts | 8 +- src/render/draw_terrain.ts | 20 +- src/render/painter.ts | 135 +- src/render/program.ts | 7 +- src/render/program/hillshade_program.ts | 4 +- src/render/program/line_program.ts | 21 +- src/shaders/_prelude.vertex.glsl | 26 +- src/shaders/line.vertex.glsl | 10 +- src/shaders/line_gradient.vertex.glsl | 10 +- src/shaders/line_pattern.vertex.glsl | 10 +- src/shaders/line_sdf.vertex.glsl | 10 +- src/source/terrain_source_cache.ts | 54 +- src/style/style.ts | 7 +- src/symbol/placement.ts | 2 +- src/ui/map.ts | 40 +- 25 files changed, 308 insertions(+), 4120 deletions(-) diff --git a/debug/terrain.html b/debug/terrain.html index 266eecffbdd..3b456fd5891 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -22,3967 +22,23 @@ container: 'map', zoom: 12.5, center: [11.40416, 47.26475], - style: { - "version": 8, - "name": "dev3d", - "light": {"anchor": "viewport", "color": "white", "intensity": 0.1}, - "center": [13.255, 47.723], - "zoom": 7, - "sprite": "https://static.maptoolkit.net/sprites/toursprung", - "glyphs": "https://static.maptoolkit.net/fonts/{fontstack}/{range}.pbf", - "sources": { - "mtk": { - "type": "vector", - "url": "https://vtc-cdn.maptoolkit.net/mtk-contours-bathymetry.json" - }, - "terrain": { - "type": "raster-dem", - "tileSize": 512, - "tiles": ["https://vtc-cdn.maptoolkit.net/terrainrgb/{z}/{x}/{y}.png"], - "encoding": "mtk", - "useForTerrain": true, - "maxzoom": 15 - }, - "basemap": { - "type": "raster", - "url": "https://vtc.maptoolkit.net/basemap_orthophoto.json" - }, - "naturalearth": { - "type": "raster", - "url": "https://vdata.maptoolkit.net/toursprung/naturalearth.json" - } - }, - "layers": [ - { - "id": "background_", - "type": "background", - "minzoom": 0, - "maxzoom": 22, - "paint": { - "background-color": { - "base": 1, - "stops": [[11, "#f7f9ee"], [14, "#fefefa"]] - } - } - }, // background_ - { - "id": "naturalearth", - "type": "raster", - "source": "naturalearth", - "maxzoom": 7, - "layout": {"visibility": "visible"}, - "paint": {"raster-opacity": {"base": 1.5, "stops": [[5, 0.6], [7, 0.1]]}} - }, // naturalearth - { - "id": "greenland", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 5, - "maxzoom": 9, - "filter": ["all", ["in", "type", "wood", "farmland", "grass"]], - "paint": { - "fill-color": "#a3cf61", - "fill-opacity": {"base": 1.2, "stops": [[6, 0.15], [9, 0.3]]}, - "fill-antialias": false - } - }, // greenland - { - "id": "landuse_builtup_residential", - "type": "fill", - "source": "mtk", - "source-layer": "landuse", - "metadata": {"maptoolkit:category": "Buildings"}, - "minzoom": 5, - "maxzoom": 22, - "filter": ["==", "type", "residential"], - "layout": {"visibility": "visible"}, - "paint": { - "fill-color": {"stops": [[12.9, "#e8e8e8"], [13, "#F4F4F4"]]}, - "fill-opacity": {"base": 1.4, "stops": [[5, 0.3], [9, 0.8]]} - } - }, // landuse_builtup_residential - { - "id": "natural_wetland", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 8, - "maxzoom": 22, - "filter": ["==", "type", "wetland"], - "layout": {"visibility": "visible"}, - "paint": { - "fill-pattern": "wetland", - "fill-opacity": {"base": 1, "stops": [[10, 0.9], [11, 1]]} - } - }, // natural_wetland - { - "id": "natural_nationalpark", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "minzoom": 5, - "maxzoom": 22, - "filter": [ - "in", - "type", - "nature_reserve", - "protected_area", - "national_park" - ], - "paint": { - "fill-color": "#cff092", - "fill-opacity": {"base": 1, "stops": [[8, 0.6], [11, 0.3]]} - }, - "metadata": { - "maptoolkit:category": "Nature Reserve", - "mtk:states": { - "nationalparks": { - "paint": { - "fill-color": "#bbea65", - "fill-opacity": {"base": 1, "stops": [[8, 0.7], [11, 0.7]]} - } - } - } - } - }, // natural_nationalpark - { - "id": "landuse_park", - "type": "fill", - "source": "mtk", - "source-layer": "landuse", - "metadata": {"maptoolkit:category": "Park"}, - "minzoom": 5, - "maxzoom": 22, - "filter": ["in", "type", "park"], - "paint": {"fill-color": "#c7e78d", "fill-opacity": 0.9} - }, // landuse_park - { - "id": "landuse_cemetery", - "type": "fill", - "source": "mtk", - "source-layer": "landuse", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 9, - "maxzoom": 22, - "filter": ["==", "type", "cemetery"], - "paint": {"fill-color": "#cff092"} - }, // landuse_cemetery - { - "id": "landuse_hospital", - "type": "fill", - "source": "mtk", - "source-layer": "landuse", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["in", "type", "hospital", "college"], - "paint": {"fill-color": "#e8e3d9"} - }, // landuse_hospital - { - "id": "landuse_school", - "type": "fill", - "source": "mtk", - "source-layer": "landuse", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 14, - "maxzoom": 22, - "filter": ["==", "type", "school"], - "paint": {"fill-color": "#e8e3d9"} - }, // landuse_school - { - "id": "natural_wood", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Wood"}, - "minzoom": 9, - "maxzoom": 22, - "filter": ["all", ["==", "type", "wood"]], - "paint": { - "fill-color": "#a3cf61", - "fill-opacity": 0.6, - "fill-antialias": false - } - }, // natural_wood - { - "id": "natural_grass", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Grass"}, - "minzoom": 9, - "maxzoom": 22, - "filter": [ - "all", - ["in", "type", "grass", "farmland"], - ["!=", "subtype", "park"] - ], - "paint": {"fill-color": "#ebf9c2", "fill-opacity": 0.7} - }, // natural_grass - { - "id": "poi_label_garden", - "type": "fill", - "source": "mtk", - "source-layer": "poi_label", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["==", "type", "garden"], - "paint": {"fill-color": "#ddecb1", "fill-opacity": 1} - }, // poi_label_garden - { - "id": "natural_glacier", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 9, - "maxzoom": 22, - "filter": ["==", "subtype", "glacier"], - "paint": { - "fill-color": "#e1ecf2", - "fill-opacity": {"base": 1, "stops": [[9, 0.1], [10, 1]]} - } - }, // natural_glacier - { - "id": "natural_sand", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 5, - "maxzoom": 22, - "filter": ["==", "type", "sand"], - "paint": {"fill-color": "hsl(60, 46%, 87%)"} - }, // natural_sand - { - "id": "natural_pitch", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["==", "subtype", "pitch"], - "paint": {"fill-color": "hsl(100, 57%, 72%)", "fill-opacity": 0.2} - }, // natural_pitch - { - "id": "poi_label_pitch", - "type": "fill", - "source": "mtk", - "source-layer": "poi_label", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["in", "type", "stadium", "sports_centre", "athletics"], - "paint": {"fill-color": "hsl(100, 57%, 72%)", "fill-opacity": 0.2} - }, // poi_label_pitch - { - "id": "natural_bare_rock", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["==", "subtype", "bare_rock"], - "paint": { - "fill-pattern": "bare_rock", - "fill-opacity": {"base": 1, "stops": [[15, 0.6], [17, 0.3]]} - } - }, // natural_bare_rock - { - "id": "natural_bare_scree", - "type": "fill", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["in", "subtype", "bare_scree", "scree"], - "paint": { - "fill-pattern": "scree", - "fill-opacity": { - "base": 1, - "stops": [[13, 0.2], [14, 0.3], [15, 0.3], [17, 0.2]] - } - } - }, // natural_bare_scree - { - "id": "contours_20", - "type": "line", - "source": "mtk", - "source-layer": "contours", - "metadata": {"maptoolkit:category": "Contour Lines"}, - "minzoom": 5, - "maxzoom": 22, - "filter": ["==", "divisor", 20], - "layout": { - "line-join": "round", - "line-cap": "round", - "visibility": "visible" - }, - "paint": { - "line-color": "#e1c26e", - "line-width": { - "stops": [[11, 0.2], [12, 0.4], [14, 0.6], [16, 0.8]], - "base": 1 - }, - "line-opacity": {"base": 1, "stops": [[16, 0.5], [17, 0.2]]} - } - }, // contours_20 - { - "id": "contours_50", - "type": "line", - "source": "mtk", - "source-layer": "contours", - "metadata": {"maptoolkit:category": "Contour Lines"}, - "minzoom": 5, - "maxzoom": 22, - "filter": ["==", "divisor", 50], - "layout": { - "line-join": "round", - "line-cap": "round", - "visibility": "visible" - }, - "paint": { - "line-color": "#e1c26e", - "line-width": { - "stops": [[11, 0.4], [12, 0.6], [14, 0.8], [16, 1]], - "base": 1 - }, - "line-opacity": {"base": 1, "stops": [[16, 0.5], [17, 0.2]]} - } - }, // contours_50 - { - "id": "contours_100", - "type": "line", - "source": "mtk", - "source-layer": "contours", - "metadata": {"maptoolkit:category": "Contour Lines"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["==", "divisor", 100], - "layout": { - "line-join": "round", - "line-cap": "round", - "visibility": "visible" - }, - "paint": { - "line-width": { - "stops": [[11, 0.6], [12, 0.8], [14, 1], [16, 1.2]], - "base": 1 - }, - "line-color": "#e1c26e", - "line-opacity": {"base": 1, "stops": [[16, 0.5], [17, 0.2]]} - } - }, // contours_100 - { - "id": "contours_500", - "type": "line", - "source": "mtk", - "source-layer": "contours", - "metadata": {"maptoolkit:category": "Contour Lines"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["all", ["==", "divisor", 500], ["!=", "ele", 0]], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-color": "#e1c26e", - "line-width": { - "stops": [[11, 0.8], [12, 1], [14, 1.2], [16, 1.5]], - "base": 1 - }, - "line-opacity": {"base": 1, "stops": [[16, 0.5], [17, 0.2]]} - } - }, // contours_500 - { - "id": "mtk-terrain-rgb", - "type": "hillshade", - "source": "terrain", - "layout": {"visibility": "visible"}, - "paint": { - "hillshade-exaggeration": {"stops": [[5, 0.3], [16, 0.45]]}, - "hillshade-highlight-color": "rgba(255, 255, 255, 1)", - "hillshade-shadow-color": "rgba(0,0,0,1)", - "hillshade-accent-color": "rgba(204,204,204,1)" - } - }, // hillshading - { - "id": "natural_cliff", - "type": "line", - "source": "mtk", - "source-layer": "natural", - "metadata": {"maptoolkit:category": "Landuse"}, - "minzoom": 13, - "filter": ["==", "type", "cliff"], - "paint": { - "line-width": 8, - "line-opacity": {"base": 1, "stops": [[13, 0.5], [15, 1]]}, - "line-pattern": "cliff" - } - }, // natural_cliff - { - "id": "water_other", - "type": "line", - "source": "mtk", - "source-layer": "water", - "metadata": {"maptoolkit:category": "Water"}, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["!=", "type", "river"], - ["!=", "type", "stream"], - ["!=", "type", "canal"] - ], - "layout": {"line-cap": "round"}, - "paint": { - "line-color": "#b7d6ff", - "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 2]]} - } - }, // water_other - { - "id": "water_river", - "type": "line", - "source": "mtk", - "source-layer": "water", - "metadata": {"maptoolkit:category": "Water"}, - "filter": ["all", ["==", "$type", "LineString"], ["==", "type", "river"]], - "layout": {"line-cap": "round"}, - "paint": { - "line-color": "#b7d6ff", - "line-width": {"base": 1.2, "stops": [[11, 0.5], [20, 6]]} - } - }, // water_river - { - "id": "water_stream", - "type": "line", - "source": "mtk", - "source-layer": "water", - "metadata": {"maptoolkit:category": "Water"}, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["in", "type", "stream", "canal"] - ], - "layout": {"line-cap": "round"}, - "paint": { - "line-color": "#b7d6ff", - "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 6]]} - } - }, // water_stream - { - "id": "water", - "type": "fill", - "source": "mtk", - "source-layer": "water", - "metadata": {"maptoolkit:category": "Water"}, - "filter": ["==", "$type", "Polygon"], - "paint": {"fill-color": "#ADD1FF"} - }, // water - { - "id": "bathymetry", - "type": "fill", - "source": "mtk", - "source-layer": "bathymetry", - "metadata": {"maptoolkit:category": "Water"}, - "filter": ["==", "$type", "Polygon"], - "paint": {"fill-color": "#61a6ff", "fill-opacity": 0.12} - }, // bathymetry - { - "id": "landuse_pedestrian", - "type": "fill", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Pedestrian"}, - "minzoom": 12, - "maxzoom": 22, - "filter": [ - "all", - ["==", "$type", "Polygon"], - ["==", "subtype", "pedestrian"] - ], - "layout": {"visibility": "visible"}, - "paint": { - "fill-color": "#dce2e5", - "fill-opacity": {"base": 1, "stops": [[12, 0.3], [15, 0.9]]} - } - }, // landuse_pedestrian - { - "id": "landuse_aeroway_fill", - "type": "fill", - "source": "mtk", - "source-layer": "landuse", - "metadata": {"maptoolkit:category": "Airport"}, - "minzoom": 11, - "filter": ["all", ["==", "type", "aeroway"], ["==", "$type", "Polygon"]], - "paint": {"fill-color": "#f0ede9", "fill-opacity": 0.6} - }, // landuse_aeroway_fill - { - "id": "aeroway_runway", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Airport"}, - "minzoom": 11, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["==", "subtype", "runway"] - ], - "paint": { - "line-color": "#f0ede9", - "line-width": {"base": 1.2, "stops": [[11, 3], [20, 16]]} - } - }, // aeroway_runway - { - "id": "road_aeroway_taxiway", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Airport"}, - "minzoom": 11, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["==", "subtype", "taxiway"] - ], - "paint": { - "line-color": "#f0ede9", - "line-width": {"base": 1.2, "stops": [[11, 0.5], [20, 6]]} - } - }, // road_aeroway_taxiway - { - "id": "road_tunnel_motorway_ramp_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["==", "type", "motorway"], - ["==", "ramp", 1] - ], - "layout": {"line-join": "round", "visibility": "visible"}, - "paint": { - "line-color": "#bfbfbf", - "line-dasharray": [0.5, 0.25], - "line-opacity": 1, - "line-width": { - "base": 1.2, - "stops": [[12, 1], [13, 3], [14, 4], [20, 15]] - } - } - }, // road_tunnel_motorway_ramp_casing - { - "id": "road_tunnel_service_track_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["in", "type", "service", "track"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#cfcdca", - "line-dasharray": [0.5, 0.25], - "line-width": {"base": 1.2, "stops": [[15, 1], [16, 4], [20, 11]]} - } - }, // road_tunnel_service_track_casing - { - "id": "road_tunnel_ramp_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["==", "ramp", 1], - ["!=", "indoor", 1], - ["!=", "type", "path"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": { - "base": 1.2, - "stops": [[12, 1], [13, 3], [14, 4], [20, 15]] - } - } - }, // road_tunnel_ramp_casing - { - "id": "road_tunnel_minor_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": ["all", ["==", "structure", "tunnel"], ["==", "type", "minor"]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#cfcdca", - "line-opacity": {"stops": [[12, 0], [12.5, 1]]}, - "line-width": { - "base": 1.2, - "stops": [[12, 0.5], [13, 1], [14, 4], [20, 15]] - } - } - }, // road_tunnel_minor_casing - { - "id": "road_tunnel_secondary_tertiary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["in", "type", "secondary", "tertiary"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_tunnel_secondary_tertiary_casing - { - "id": "road_tunnel_trunk_primary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["in", "type", "trunk", "primary"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_tunnel_trunk_primary_casing - { - "id": "road_tunnel_motorway_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["==", "type", "motorway"] - ], - "layout": {"line-join": "round", "visibility": "visible"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-dasharray": [0.5, 0.25], - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_tunnel_motorway_casing - { - "id": "road_tunnel_path", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": ["all", ["==", "brunnel", "tunnel"], ["==", "type", "path"]], - "layout": {"visibility": "none"}, - "paint": { - "line-color": "#cba", - "line-dasharray": [1.5, 0.75], - "line-width": {"base": 1.2, "stops": [[15, 1.2], [20, 4]]} - } - }, // road_tunnel_path - { - "id": "road_tunnel_motorway_ramp", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["==", "type", "motorway"], - ["==", "ramp", 1] - ], - "layout": {"line-join": "round", "visibility": "visible"}, - "paint": { - "line-color": "#ffc345", - "line-width": { - "base": 1.2, - "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] - } - } - }, // road_tunnel_motorway_ramp - { - "id": "road_tunnel_service_track", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["in", "type", "service", "track"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-width": {"base": 1.2, "stops": [[15.5, 0], [16, 2], [20, 7.5]]} - } - }, // road_tunnel_service_track - { - "id": "road_tunnel_link", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["==", "ramp", 1], - ["!=", "indoor", 1], - ["!=", "type", "path"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff4c6", - "line-width": { - "base": 1.2, - "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] - } - } - }, // road_tunnel_link - { - "id": "road_tunnel_minor", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": ["all", ["==", "structure", "tunnel"], ["==", "type", "minor"]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-opacity": 1, - "line-width": {"base": 1.2, "stops": [[13.5, 0], [14, 2.5], [20, 11.5]]} - } - }, // road_tunnel_minor - { - "id": "road_tunnel_secondary_tertiary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["in", "type", "secondary", "tertiary"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff4c6", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_tunnel_secondary_tertiary - { - "id": "road_tunnel_trunk_primary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["in", "type", "trunk", "primary"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff4c6", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_tunnel_trunk_primary - { - "id": "road_tunnel_motorway", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "brunnel", "tunnel"], - ["==", "type", "motorway"] - ], - "layout": {"line-join": "round", "visibility": "visible"}, - "paint": { - "line-color": "#ffdaa6", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_tunnel_motorway - { - "id": "road_tunnel_rail", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Railway"}, - "filter": ["all", ["==", "brunnel", "tunnel"], ["==", "type", "rail"]], - "paint": { - "line-color": "#bbb", - "line-opacity": 0.6, - "line-width": {"base": 1.4, "stops": [[14, 0.4], [15, 0.75], [20, 2]]} - } - }, // road_tunnel_rail - { - "id": "road_tunnel_rail_hatching", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Railway"}, - "filter": ["all", ["==", "brunnel", "tunnel"], ["==", "type", "rail"]], - "paint": { - "line-color": "#bbb", - "line-dasharray": [0.2, 8], - "line-opacity": 0.6, - "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 3], [20, 8]]} - } - }, // road_tunnel_rail_hatching - { - "id": "road_motorway_ramp_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 7, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "motorway"], - ["==", "ramp", 1], - ["!in", "structure", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_motorway_ramp_casing - { - "id": "road_track_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 12, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "track"], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-color": "#a6a6a6", - "line-dasharray": [1, 2], - "line-width": {"base": 1.4, "stops": [[12, 1], [16, 4], [20, 11]]}, - "line-opacity": 0.9 - } - }, // road_track_casing - { - "id": "road_service_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 12, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "service"], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-gap-width": {"base": 1.5, "stops": [[13, 0], [14, 2], [18, 18]]}, - "line-color": "#cfcdca", - "line-opacity": 1, - "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]} - } - }, // road_service_casing - { - "id": "road_ramp_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 13, - "maxzoom": 22, - "filter": [ - "all", - ["==", "ramp", 1], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "none" - }, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_ramp_casing - { - "id": "road_minor_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 11, - "maxzoom": 22, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["==", "type", "minor"], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-gap-width": {"base": 1.5, "stops": [[13, 0], [14, 2], [18, 18]]}, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.5, "stops": [[11, 0.75], [20, 2]]} - } - }, // road_minor_casing - { - "id": "road_secondary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 9, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["in", "type", "secondary"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": {"base": 1, "stops": [[9, 0.1], [10, 1]]}, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_secondary_casing - { - "id": "road_tertiary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 9, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["in", "type", "tertiary"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": {"base": 1, "stops": [[9, 0.1], [10, 1]]}, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_tertiary_casing - { - "id": "road_trunk_primary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 10, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["in", "type", "trunk", "primary"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[7, 0.05], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": {"base": 1, "stops": [[7, 0.1], [10, 1]]}, - "line-width": {"stops": [[10, 0.75], [18, 2]], "base": 1.2} - } - }, // road_trunk_primary_casing - { - "id": "road_motorway_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "minzoom": 9, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["==", "type", "motorway"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-width": {"stops": [[10, 0.75], [18, 2]], "base": 1.2} - } - }, // road_motorway_casing - { - "id": "road_path_pedestrian", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Pedestrian"}, - "minzoom": 15, - "maxzoom": 22, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["==", "type", "path"], - ["!in", "brunnel", "bridge", "tunnel"], - ["!in", "subtype", "platform"] - ], - "paint": { - "line-color": "#c3c3c3", - "line-dasharray": [1.5, 0.75], - "line-width": {"base": 1.2, "stops": [[15, 1.1], [20, 2.5]]}, - "line-opacity": 0.7 - } - }, // road_path_pedestrian - { - "id": "road_motorway_ramp", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 7, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "motorway"], - ["==", "ramp", 1], - ["!in", "structure", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-color": "#ffc345", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_motorway_ramp - { - "id": "road_track", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 12, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "track"], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-width": {"base": 1.2, "stops": [[12, 0], [16, 2], [20, 7.5]]}, - "line-opacity": 0.9 - } - }, // road_track - { - "id": "road_service", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 12, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "service"], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-width": {"base": 1.5, "stops": [[12.5, 0.5], [14, 2], [18, 18]]} - } - }, // road_service - { - "id": "road_ramp", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 13, - "maxzoom": 22, - "filter": [ - "all", - ["==", "ramp", 1], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "none" - }, - "paint": { - "line-color": "#fff", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_ramp - { - "id": "road_minor", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 11, - "maxzoom": 22, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["==", "type", "minor"], - ["!in", "brunnel", "bridge", "tunnel"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-opacity": 1, - "line-width": {"base": 1.5, "stops": [[12.5, 0.5], [14, 2], [18, 18]]} - } - }, // road_minor - { - "id": "road_secondary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 9, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["in", "type", "secondary"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-color": {"stops": [[9, "#fff"], [22, "#fff"]]}, - "line-opacity": {"stops": [[8, 0.1], [10, 1]]}, - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_secondary - { - "id": "road_tertiary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 9, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["in", "type", "tertiary"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-color": "#fff", - "line-opacity": {"stops": [[8, 0.1], [10, 1]]}, - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_tertiary - { - "id": "road_trunk_primary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 7, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["in", "type", "trunk", "primary"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-color": { - "stops": [ - [7.9, "#fff"], - [8, "#fffd8b"], - [11, "#fffd00"], - [22, "#fffd00"] - ] - }, - "line-opacity": {"stops": [[7, 0.8], [10, 1]]}, - "line-width": {"base": 1.5, "stops": [[7, 1], [10, 2], [18, 26]]} - } - }, // road_trunk_primary - { - "id": "road_motorway", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 6, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["==", "type", "motorway"] - ], - "layout": { - "line-cap": "round", - "line-join": "round", - "visibility": "visible" - }, - "paint": { - "line-color": {"stops": [[6.9, "#fff"], [7, "#ffc345"]]}, - "line-width": { - "base": 1.5, - "stops": [[6, 0.3], [8.5, 0.5], [10, 0.75], [18, 26]] - } - } - }, // road_motorway - { - "id": "road_rail", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Railway"}, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["==", "type", "railway"], - ["in", "subtype", "rail", "light_rail"] - ], - "paint": { - "line-color": "#bbb", - "line-width": {"base": 1.4, "stops": [[14, 0.4], [15, 0.75], [20, 2]]} - } - }, // road_rail - { - "id": "road_rail_hatching", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Railway"}, - "filter": [ - "all", - ["!in", "brunnel", "bridge", "tunnel"], - ["==", "type", "railway"], - ["in", "subtype", "rail", "light_rail"] - ], - "paint": { - "line-color": "#bbb", - "line-dasharray": [0.2, 8], - "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 3], [20, 8]]} - } - }, // road_rail_hatching - { - "id": "road_bridge_motorway_ramp_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "type", "motorway"], - ["==", "ramp", 1], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_bridge_motorway_ramp_casing - { - "id": "road_bridge_service_track_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["in", "type", "service", "track"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-gap-width": {"base": 1.5, "stops": [[13, 0], [14, 2], [18, 18]]}, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]} - } - }, // road_bridge_service_track_casing - { - "id": "road_bridge_ramp_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": ["all", ["==", "ramp", 1], ["==", "brunnel", "bridge"]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.4, "stops": [[10, 1.25], [12, 1.25], [18, 16]]} - } - }, // road_bridge_ramp_casing - { - "id": "road_bridge_minor_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": ["all", ["in", "type", "minor"], ["==", "brunnel", "bridge"]], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": {"base": 1.5, "stops": [[13, 0], [14, 2], [18, 18]]}, - "line-color": "#bfbfbf", - "line-opacity": 1, - "line-width": {"base": 1.5, "stops": [[12, 0.75], [20, 2]]} - } - }, // road_bridge_minor_casing - { - "id": "road_bridge_secondary_tertiary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["in", "type", "secondary", "tertiary"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-opacity": {"base": 1, "stops": [[9, 0.1], [10, 1]]}, - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_bridge_secondary_tertiary_casing - { - "id": "road_bridge_trunk_primary_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["in", "type", "trunk", "primary"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_bridge_trunk_primary_casing - { - "id": "road_bridge_motorway_casing", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Road Casings"}, - "filter": [ - "all", - ["==", "type", "motorway"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-gap-width": { - "base": 1.5, - "stops": [[8.5, 0.5], [10, 0.75], [18, 26]] - }, - "line-color": "#bfbfbf", - "line-width": {"base": 1.2, "stops": [[10, 0.75], [18, 2]]} - } - }, // road_bridge_motorway_casing - { - "id": "road_bridge_path", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "minzoom": 16.5, - "filter": ["all", ["==", "brunnel", "bridge"], ["==", "type", "path"]], - "paint": { - "line-color": "#cba", - "line-dasharray": [1.5, 0.75], - "line-width": {"base": 1.2, "stops": [[15, 1.2], [20, 4]]} - } - }, // road_bridge_path - { - "id": "road_bridge_motorway_link", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "type", "motorway"], - ["==", "ramp", 1], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#ffc345", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_bridge_motorway_link - { - "id": "road_bridge_service_track", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["in", "type", "service", "track"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-cap": "round", "line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-width": {"base": 1.5, "stops": [[12.5, 0.5], [14, 2], [18, 18]]} - } - }, // road_bridge_service_track - { - "id": "road_bridge_link", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": ["all", ["==", "ramp", 1], ["==", "brunnel", "bridge"]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fffd8b", - "line-width": { - "base": 1.2, - "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] - } - } - }, // road_bridge_link - { - "id": "road_bridge_minor", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": ["all", ["in", "type", "minor"], ["==", "brunnel", "bridge"]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-opacity": 1, - "line-width": {"base": 1.5, "stops": [[12.5, 0.5], [14, 2], [18, 18]]} - } - }, // road_bridge_minor - { - "id": "road_bridge_secondary_tertiary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["in", "type", "secondary", "tertiary"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": {"stops": [[8, "#666"], [9, "#fff"], [22, "#fff"]]}, - "line-opacity": {"stops": [[8, 0.1], [10, 1]]}, - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_bridge_secondary_tertiary - { - "id": "road_bridge_trunk_primary", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["in", "type", "trunk", "primary"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fffd8b", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_bridge_trunk_primary - { - "id": "road_bridge_motorway", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Roads"}, - "filter": [ - "all", - ["==", "type", "motorway"], - ["==", "brunnel", "bridge"] - ], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#ffc345", - "line-width": {"base": 1.5, "stops": [[8.5, 0.5], [10, 0.75], [18, 26]]} - } - }, // road_bridge_motorway - { - "id": "road_bridge_rail", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Railway"}, - "filter": ["all", ["==", "type", "rail"], ["==", "brunnel", "bridge"]], - "paint": { - "line-color": "#bbb", - "line-width": {"base": 1.4, "stops": [[14, 0.4], [15, 0.75], [20, 2]]} - } - }, // road_bridge_rail - { - "id": "road_bridge_rail_hatching", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Railway"}, - "filter": ["all", ["==", "type", "rail"], ["==", "brunnel", "bridge"]], - "paint": { - "line-color": "#bbb", - "line-dasharray": [0.2, 8], - "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 3], [20, 8]]} - } - }, // road_bridge_rail_hatching - { - "id": "road_walking_local", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Hiking"}, - "minzoom": 14, - "maxzoom": 22, - "filter": ["==", "network", "lwn"], - "paint": { - "line-color": "#990000", - "line-dasharray": [1.5, 0.75], - "line-width": {"base": 1.2, "stops": [[13, 1], [20, 3]]} - } - }, // road_walking_local - { - "id": "road_walking_regional", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Hiking"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["==", "network", "rwn"], - "paint": { - "line-color": "#990000", - "line-dasharray": [1.5, 0.75], - "line-width": {"base": 1.2, "stops": [[13, 1], [20, 3]]}, - "line-opacity": 0.5 - } - }, // road_walking_regional - { - "id": "road_hiking_international", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Hiking"}, - "minzoom": 12, - "maxzoom": 22, - "filter": ["in", "network", "iwn", "nwn"], - "paint": { - "line-color": "#990000", - "line-width": {"base": 1.2, "stops": [[8, 1], [20, 4]]}, - "line-opacity": 0.5 - } - }, // road_hiking_international - { - "id": "road_cycling_local", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Cycling"}, - "minzoom": 14, - "maxzoom": 22, - "filter": ["in", "network", "lcn"], - "paint": { - "line-color": "#6dad3e", - "line-dasharray": [1.5, 0.75], - "line-width": {"base": 1.2, "stops": [[13, 1], [20, 3]]}, - "line-opacity": 0.7 - } - }, // road_cycling_local - { - "id": "road_cycling_regional", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Cycling"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["in", "network", "rcn"], - "paint": { - "line-color": "#6dad3e", - "line-width": {"base": 1.2, "stops": [[8, 1], [20, 4]]}, - "line-opacity": 0.7 - } - }, // road_cycling_regional - { - "id": "road_cycling_international", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Cycling"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["in", "network", "icn", "ncn"], - "paint": { - "line-color": "#6dad3e", - "line-width": {"base": 1.2, "stops": [[8, 1], [20, 4]]}, - "line-opacity": 0.7 - } - }, // road_cycling_international - { - "id": "road_transit_tram", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Public Transport"}, - "minzoom": 16, - "maxzoom": 22, - "filter": ["all", ["==", "type", "transit"], ["==", "subtype", "tram"]], - "paint": { - "line-color": "#acacac", - "line-width": {"base": 1.2, "stops": [[16, 1], [20, 4]]}, - "line-opacity": 0.7 - } - }, // road_transit_tram - { - "id": "road_ferry", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Ferry"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["in", "type", "ferry"], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#fff", - "line-dasharray": [1, 2], - "line-width": {"base": 1.2, "stops": [[10, 0.3], [14, 1]]} - } - }, // road_ferry - { - "id": "admin_level_3", - "type": "line", - "source": "mtk", - "source-layer": "admin", - "metadata": {"maptoolkit:category": "Borders"}, - "minzoom": 4, - "maxzoom": 22, - "filter": ["all", ["in", "admin_level", 3, 4], ["==", "maritime", 0]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#9e9cab", - "line-dasharray": [3, 1, 1, 1], - "line-opacity": 0.8, - "line-width": {"base": 1, "stops": [[4, 0.4], [5, 1], [12, 3]]} - } - }, // admin_level_3 - { - "id": "admin_level_2", - "type": "line", - "source": "mtk", - "source-layer": "admin", - "metadata": {"maptoolkit:category": "Borders"}, - "minzoom": 0, - "maxzoom": 22, - "filter": [ - "all", - ["==", "admin_level", 2], - ["==", "disputed", 0], - ["==", "maritime", 0] - ], - "layout": {"line-join": "round", "line-cap": "round"}, - "paint": { - "line-color": "hsl(230, 8%, 51%)", - "line-width": {"base": 1, "stops": [[3, 0.5], [10, 2]]} - } - }, // admin_level_2 - { - "id": "admin_level_2_disputed", - "type": "line", - "source": "mtk", - "source-layer": "admin", - "metadata": {"maptoolkit:category": "Borders"}, - "minzoom": 4, - "maxzoom": 22, - "filter": [ - "all", - ["==", "admin_level", 2], - ["==", "disputed", 1], - ["==", "maritime", 0] - ], - "layout": {"line-cap": "round"}, - "paint": { - "line-color": "#9e9cab", - "line-dasharray": [2, 2], - "line-width": {"base": 1, "stops": [[4, 1.4], [5, 2], [12, 8]]} - } - }, // admin_level_2_disputed - { - "id": "admin_level_3_maritime", - "type": "line", - "source": "mtk", - "source-layer": "admin", - "metadata": {"maptoolkit:category": "Borders"}, - "minzoom": 4, - "maxzoom": 22, - "filter": ["all", [">=", "admin_level", 3], ["==", "maritime", 1]], - "layout": {"line-join": "round"}, - "paint": { - "line-color": "#a0c8f0", - "line-dasharray": [3, 1, 1, 1], - "line-opacity": 0.5, - "line-width": {"base": 1, "stops": [[4, 0.4], [5, 1], [12, 3]]} - } - }, // admin_level_3_maritime - { - "id": "admin_level_2_maritime", - "type": "line", - "source": "mtk", - "source-layer": "admin", - "metadata": {"maptoolkit:category": "Borders"}, - "minzoom": 4, - "maxzoom": 22, - "filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 1]], - "layout": {"line-cap": "round", "visibility": "none"}, - "paint": { - "line-color": "#a0c8f0", - "line-opacity": 0.5, - "line-width": {"base": 1, "stops": [[4, 1.4], [5, 2], [12, 8]]} - } - }, // admin_level_2_maritime - { - "id": "road_aerialway", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 10, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "aerialway"], - ["!in", "subtype", "t-bar", "drag_lift", "magic_carpet", "rope_tow"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "visible" - }, - "paint": { - "line-color": "#666", - "line-width": {"stops": [[10, 0.5], [12, 1.4]]}, - "line-opacity": {"stops": [[11, 0.35], [14, 0.5]]} - } - }, // road_aerialway - { - "id": "road_aerialway_patterns", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 10, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "aerialway"], - ["!in", "subtype", "t-bar", "drag_lift", "magic_carpet", "rope_tow"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "visible" - }, - "paint": { - "line-dasharray": [1, 6], - "line-color": "#666", - "line-width": {"stops": [[10, 0.5], [12, 2.8]]}, - "line-opacity": {"stops": [[11, 0.35], [14, 0.5]]} - } - }, // road_aerialway_patterns - { - "id": "road_piste_easy_outline", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-easy"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#0969B3", - "line-blur": {"base": 1, "stops": [[12, 4], [13, 6], [22, 7]]}, - "line-opacity": {"base": 1, "stops": [[11, 0.8], [14, 1]]}, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-width": {"base": 1, "stops": [[11, 2], [13, 5], [14, 7], [16, 9]]} - } - }, // road_piste_easy_outline - { - "id": "road_piste_easy", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-easy"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#0969B3", - "line-opacity": {"stops": [[11, 0.3], [13, 0.6]]}, - "line-blur": 0, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-dasharray": [1, 1], - "line-width": {"base": 1.2, "stops": [[13, 1], [20, 3]]} - } - }, // road_piste_easy - { - "id": "road_pistes_intermediate_outline", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-intermediate"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#EF2021", - "line-blur": {"base": 1, "stops": [[12, 4], [13, 6], [22, 7]]}, - "line-opacity": {"base": 1, "stops": [[11, 0.8], [14, 1]]}, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-width": {"base": 1, "stops": [[11, 2], [13, 5], [14, 7], [16, 9]]} - } - }, // road_pistes_intermediate_outline - { - "id": "road_pistes_intermediate", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-intermediate"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#EF2021", - "line-opacity": {"stops": [[11, 0.3], [13, 0.6]]}, - "line-blur": 0, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-dasharray": [1, 1], - "line-width": {"base": 1.2, "stops": [[13, 1], [20, 3]]} - } - }, // road_pistes_intermediate - { - "id": "road_pistes_difficult_outline", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-advanced"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#000", - "line-blur": {"base": 1, "stops": [[12, 4], [13, 6], [22, 7]]}, - "line-opacity": {"base": 1, "stops": [[11, 0.8], [14, 1]]}, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-width": {"base": 1, "stops": [[11, 2], [13, 5], [14, 7], [16, 9]]} - } - }, // road_pistes_difficult_outline - { - "id": "road_pistes_difficult", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-advanced"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#000", - "line-opacity": {"stops": [[11, 0.3], [13, 0.6]]}, - "line-blur": 0, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-dasharray": [1, 1], - "line-width": {"base": 1.2, "stops": [[13, 1], [20, 3]]} - } - }, // road_pistes_difficult - { - "id": "road_pistes_nordic", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "nordic"], - ["==", "subtype", "nordic-easy"], - ["==", "subtype", "nordic-intermediate"], - ["==", "subtype", "nordic-advaned"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#606060", - "line-opacity": {"stops": [[11, 0.3], [13, 0.6]]}, - "line-blur": 0, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-dasharray": [1, 1], - "line-width": {"base": 1.2, "stops": [[13, 1.2], [15, 3], [22, 2]]} - } - }, // road_pistes_nordic - { - "id": "road_pistes_skiroutes", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "downhill-freeride"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#EF2021", - "line-opacity": {"stops": [[11, 0.3], [13, 0.6]]}, - "line-blur": 0, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-dasharray": [3, 2], - "line-width": {"base": 1.2, "stops": [[13, 1.2], [15, 3], [22, 2]]} - } - }, // road_pistes_skiroutes - { - "id": "road_piste_connection_outline", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "connection"], - ["==", "subtype", "connection-easy"], - ["==", "subtype", "connection-intermediate"], - ["==", "subtype", "connection-advaned"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#0969B3", - "line-blur": {"base": 1, "stops": [[12, 4], [13, 6], [22, 7]]}, - "line-opacity": {"base": 1, "stops": [[11, 0.8], [14, 1]]}, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-width": {"base": 1, "stops": [[11, 4], [13, 7], [14, 9], [22, 9]]} - } - }, // road_piste_connection_outline - { - "id": "road_piste_connection", - "type": "line", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "piste"], - ["==", "subtype", "connection"], - ["==", "subtype", "connection-easy"], - ["==", "subtype", "connection-intermediate"], - ["==", "subtype", "connection-advaned"] - ], - "layout": { - "line-join": "round", - "line-cap": "square", - "visibility": "none" - }, - "paint": { - "line-color": "#0969B3", - "line-opacity": {"stops": [[11, 0.3], [13, 0.6]]}, - "line-blur": 0, - "line-translate-anchor": "map", - "line-translate": [0, 0], - "line-dasharray": [1, 1], - "line-width": {"base": 1.2, "stops": [[13, 1.2], [15, 3], [22, 2]]} - } - }, // road_piste_connection - { - "id": "building", - "type": "fill", - "source": "mtk", - "source-layer": "building", - "metadata": {"maptoolkit:category": "Buildings"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["any", ["!has", "level"], [">=", "level", 0]], - "layout": {"visibility": "visible"}, - "paint": { - "fill-color": {"stops": [[13, "#E8E8E8"], [15, "#E8E8E8"]]}, - "fill-outline-color": "#c5c5c5", - "fill-opacity": 0.5 - } - }, // building - { - "id": "building_public", - "type": "fill", - "source": "mtk", - "source-layer": "building", - "metadata": {"maptoolkit:category": "Buildings"}, - "minzoom": 13, - "maxzoom": 22, - "filter": [ - "all", - ["any", ["!has", "level"], [">=", "level", 0]], - [ - "any", - ["in", "building", "church", "school", "public", "train_station"], - ["in", "type", "library"] - ] - ], - "paint": { - "fill-opacity": 0.5, - "fill-outline-color": "#efbebe", - "fill-color": "#F9E7E7" - } - }, // building_public - { - "id": "building_3D", - "type": "fill-extrusion", - "source": "mtk", - "source-layer": "building", - "metadata": {"maptoolkit:category": "Buildings"}, - "minzoom": 15, - "maxzoom": 22, - "filter": ["==", "extrude", true], - "layout": {"visibility": "visible"}, - "paint": { - "fill-extrusion-color": "#E8E8E8", - "fill-extrusion-height": [ - "interpolate", - ["linear"], - ["zoom"], - 15, - 0, - 15.05, - ["get", "height"] - ], - "fill-extrusion-base": [ - "interpolate", - ["linear"], - ["zoom"], - 15, - 0, - 15.05, - ["get", "min_height"] - ], - "fill-extrusion-opacity": 0.6 - } - }, // building_3D - { - "id": "building_3D_public", - "type": "fill-extrusion", - "source": "mtk", - "source-layer": "building", - "metadata": {"maptoolkit:category": "Buildings"}, - "minzoom": 15, - "maxzoom": 22, - "filter": [ - "all", - ["==", "extrude", true], - [ - "any", - ["in", "building", "church", "school", "public", "train_station"], - ["in", "type", "library"] - ] - ], - "layout": {"visibility": "visible"}, - "paint": { - "fill-extrusion-color": "#efbebe", - "fill-extrusion-height": [ - "interpolate", - ["linear"], - ["zoom"], - 15, - 0, - 15.05, - ["get", "height"] - ], - "fill-extrusion-base": [ - "interpolate", - ["linear"], - ["zoom"], - 15, - 0, - 15.05, - ["get", "min_height"] - ], - "fill-extrusion-opacity": 0.6 - } - }, // building_3D_public - { - "id": "road_oneway_arrows", - "type": "symbol", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Oneway Arrows"}, - "minzoom": 15, - "maxzoom": 22, - "filter": [ - "all", - ["==", "oneway", 1], - ["!=", "type", "transit"], - ["!in", "cycleway", "opposite", "opposite_lane"] - ], - "layout": { - "symbol-placement": "line", - "icon-size": 0.7, - "icon-padding": 2, - "icon-image": {"base": 1, "stops": [[15, "oneway"]]}, - "icon-rotation-alignment": "map", - "symbol-spacing": 250 - }, - "paint": {"text-color": "#334"} - }, // road_oneway_arrows - { - "id": "road_oneway_arrows_except_cycles", - "type": "symbol", - "source": "mtk", - "source-layer": "road", - "metadata": {"maptoolkit:category": "Oneway Arrows"}, - "minzoom": 15, - "maxzoom": 22, - "filter": [ - "all", - ["==", "oneway", 1], - ["!=", "type", "transit"], - ["in", "cycleway", "opposite", "opposite_lane"] - ], - "layout": { - "symbol-placement": "line", - "icon-size": 0.7, - "icon-padding": 2, - "icon-image": {"base": 1, "stops": [[15, "oneway-except-cycles"]]}, - "icon-rotation-alignment": "map", - "symbol-spacing": 250 - }, - "paint": {"text-color": "#334"} - }, // road_oneway_arrows_except_cycles - { - "id": "housenum_label", - "type": "symbol", - "source": "mtk", - "source-layer": "housenum_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "House Numbers" - }, - "minzoom": 17, - "maxzoom": 22, - "layout": { - "text-font": ["Noto Sans Regular"], - "text-size": 9.5, - "text-field": "{housenumber}", - "text-max-width": 7, - "text-pitch-alignment": "viewport", - "visibility": "visible" - }, - "paint": { - "text-color": "hsl(35, 2%, 69%)", - "text-halo-width": 0.5, - "text-halo-color": "hsl(35, 8%, 85%)", - "text-opacity": {"base": 1, "stops": [[16, 0], [16.5, 1]]} - } - }, // housenum_label - { - "id": "contours_100_label", - "type": "symbol", - "source": "mtk", - "source-layer": "contours", - "metadata": {"maptoolkit:category": "Contour Lines"}, - "minzoom": 14, - "maxzoom": 22, - "filter": ["==", "divisor", 100], - "layout": { - "text-letter-spacing": 0.1, - "symbol-placement": "line", - "text-size": 8, - "text-font": ["Noto Sans Regular"], - "text-field": "{ele}", - "text-line-height": 1.6, - "text-max-width": 5, - "symbol-spacing": 200, - "text-pitch-alignment": "viewport" - }, - "paint": {"text-color": "#e1c26e"} - }, // contours_100_label - { - "id": "contours_500_label", - "type": "symbol", - "source": "mtk", - "source-layer": "contours", - "metadata": {"maptoolkit:category": "Contour Lines"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["all", ["==", "divisor", 500], ["!=", "ele", 0]], - "layout": { - "text-letter-spacing": 0.1, - "symbol-placement": "line", - "text-size": 10, - "text-font": ["Noto Sans Regular"], - "text-field": "{ele}", - "text-line-height": 1.6, - "text-max-width": 5, - "symbol-spacing": 200, - "text-pitch-alignment": "viewport" - }, - "paint": {"text-color": "#e1c26e"} - }, // contours_500_label - { - "id": "poi_label_3", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 17, - "maxzoom": 22, - "filter": [ - "all", - [ - "!in", - "subtype", - "subway_entrance", - "board", - "map", - "guidepost", - "drag_lift", - "station", - "pitch" - ], - ["!in", "type", "information"] - ], - "layout": { - "icon-image": "{type}-11", - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": {"icon-opacity": 0.4} - }, // poi_label_3 - { - "id": "poi_label_2", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 15, - "maxzoom": 22, - "filter": [ - "all", - ["<=", "rank", 50], - [ - "!in", - "subtype", - "subway_entrance", - "board", - "map", - "guidepost", - "drag_lift", - "station", - "pitch" - ], - ["!in", "type", "information"] - ], - "layout": { - "text-padding": 2, - "text-font": ["Noto Sans Bold"], - "text-anchor": "top", - "icon-image": "{type}-11", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-offset": [0, 0.6], - "text-size": 12, - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#666", - "text-halo-width": 1, - "text-halo-color": "#ffffff" - } - }, // poi_label_2 - { - "id": "poi_label_1", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["<=", "rank", 8], - [ - "!in", - "subtype", - "subway_entrance", - "board", - "map", - "guidepost", - "drag_lift", - "station", - "pitch", - "dog_park", - "playground", - "garden", - "picnic_site" - ], - ["!in", "type", "information"] - ], - "layout": { - "text-padding": {"base": 1, "stops": [[14, 20], [20, 2]]}, - "text-font": ["Noto Sans Bold"], - "text-anchor": "top", - "icon-image": "{type}-11", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-offset": [0, 0.6], - "text-size": 10, - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#666", - "text-halo-width": 0.9, - "text-halo-color": "hsla(0, 0%, 100%, 0.8)", - "icon-opacity": 0.6 - } - }, // poi_label_1 - { - "id": "poi_label_bank", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 14, - "maxzoom": 22, - "filter": ["==", "type", "bank"], - "layout": { - "text-padding": {"base": 1, "stops": [[14, 20], [20, 2]]}, - "text-font": ["Noto Sans Bold"], - "text-anchor": "top", - "icon-image": "{type}", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-offset": [0, 0.6], - "text-size": 10, - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#666", - "text-halo-width": 1, - "text-halo-color": "#ffffff", - "icon-opacity": 0.6 - } - }, // poi_label_bank - { - "id": "poi_label_rail_station", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 15, - "filter": [ - "all", - ["==", "type", "station"], - [ - "!in", - "subtype", - "t-bar", - "magic_carpet", - "rope_tow", - "drag_lift", - "gondola", - "cable_car", - "chair_lift" - ] - ], - "layout": { - "text-padding": {"base": 1, "stops": [[14, 20], [20, 2]]}, - "text-font": ["Noto Sans Bold"], - "icon-image": "{maki}-11", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-anchor": "top", - "text-offset": [0, 0.6], - "text-size": 12, - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport", - "visibility": "visible" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#666", - "text-halo-width": 1, - "text-halo-color": "#ffffff" - } - }, // poi_label_rail_station - { - "id": "poi_label_aerialway_station_icon", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 10, - "maxzoom": 22, - "filter": [ - "all", - ["==", "type", "station"], - ["in", "subtype", "gondola", "cable_car", "chair_lift"], - ["!in", "subtype", "t-bar", "magic_carpet", "rope_tow", "drag_lift"] - ], - "layout": { - "icon-image": "{subtype}", - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - } - }, // poi_label_aerialway_station_icon - { - "id": "road_label_walking_shied", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Hiking"}, - "minzoom": 12, - "maxzoom": 22, - "filter": ["all", ["in", "network", "iwn"], ["has", "ref"]], - "layout": { - "icon-size": 0.7, - "symbol-placement": {"base": 1, "stops": [[10, "point"], [11, "line"]]}, - "text-font": ["Open Sans Bold"], - "icon-image": "motorway_{ref_length}", - "text-field": "{ref}", - "icon-rotation-alignment": "viewport", - "text-rotation-alignment": "viewport", - "text-size": 8, - "symbol-spacing": 500, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": {"text-color": "#990000"} - }, // road_label_walking_shied - { - "id": "road_label_cycling_shied", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Cycling" - }, - "minzoom": 11, - "maxzoom": 22, - "filter": ["all", ["in", "network", "icn"], ["has", "ref"]], - "layout": { - "icon-size": 0.7, - "symbol-placement": {"base": 1, "stops": [[10, "point"], [11, "line"]]}, - "text-font": ["Open Sans Bold"], - "icon-image": "motorway_{ref_length}", - "text-field": "{ref}", - "icon-rotation-alignment": "viewport", - "text-rotation-alignment": "viewport", - "text-size": 8, - "symbol-spacing": 500, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": {"text-color": "#6dad3e"} - }, // road_label_cycling_shied - { - "id": "place_label_other", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Other Places" - }, - "minzoom": 11, - "maxzoom": 22, - "filter": [ - "in", - "type", - "neighbourhood", - "valley", - "glacier", - "locality", - "wetland", - "cliff", - "wineyard", - "ridge", - "wood" - ], - "layout": { - "text-letter-spacing": 0.1, - "text-size": {"base": 1.2, "stops": [[12, 10], [15, 14]]}, - "text-font": ["Noto Sans Regular"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "hsla(0, 0%, 33%, 1)", - "text-halo-width": 1.1, - "text-halo-color": "hsla(0, 0%, 100%, 0.6)" - } - }, // place_label_other - { - "id": "poi_label_peaks", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Peaks"}, - "minzoom": 9, - "maxzoom": 22, - "filter": ["==", "type", "peak"], - "layout": { - "text-padding": {"base": 1, "stops": [[9, 35], [12, 15]]}, - "icon-size": 0.4, - "text-font": ["Noto Sans Regular"], - "icon-image": "triangle-15", - "text-field": "{name}\n{ele}", - "text-anchor": "top", - "text-optional": false, - "text-offset": [0, 0.5], - "text-size": {"base": 1, "stops": [[10, 8], [16, 15]]}, - "text-pitch-alignment": "viewport", - "visibility": "visible" - }, - "paint": {"text-color": "#333", "text-opacity": 0.9, "icon-opacity": 0.8} - }, // poi_label_peaks - { - "id": "road_label_pistes", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": {"maptoolkit:category": "Mountain Sports"}, - "minzoom": 13, - "maxzoom": 22, - "filter": ["==", "type", "piste"], - "layout": { - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-font": ["Noto Sans Regular"], - "symbol-spacing": 400, - "text-size": {"stops": [[8, 8], [20, 20]], "base": 1.2}, - "text-padding": 2, - "text-letter-spacing": 0.05, - "symbol-placement": "line", - "text-max-angle": 40, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport", - "visibility": "none" - }, - "paint": { - "text-halo-width": {"stops": [[13, 1], [20, 2]]}, - "text-halo-color": "hsla(0, 0%, 100%, 1)", - "text-color": "hsla(0, 0%, 0%, 0.8)" - } - }, // road_label_pistes - { - "id": "poi_label_mountain_pass", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Peaks"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["==", "type", "moutain_pass"], - "layout": { - "icon-size": 1, - "icon-padding": 20, - "text-padding": 20, - "text-font": ["Noto Sans Regular"], - "icon-image": "triangle-stroked-15", - "text-field": "{name}\n{ele}", - "text-anchor": "top", - "text-optional": false, - "text-offset": [0, 0.5], - "text-size": {"base": 1, "stops": [[10, 8], [16, 13]]}, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport", - "visibility": "visible" - }, - "paint": {"text-color": "#333"} - }, // poi_label_mountain_pass - { - "id": "poi_label_alpine_hut", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Peaks"}, - "minzoom": 11, - "maxzoom": 22, - "filter": ["==", "subtype", "alpine_hut"], - "layout": { - "icon-size": 1, - "icon-padding": 20, - "text-padding": 20, - "text-font": ["Noto Sans Regular"], - "icon-image": "alpine_hut", - "text-field": "{name}\n{ele}", - "text-anchor": "top", - "text-optional": false, - "text-offset": [0, 0.5], - "text-size": {"base": 1, "stops": [[10, 8], [16, 13]]}, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport", - "visibility": "visible" - }, - "paint": {"text-color": "#333"} - }, // poi_label_alpine_hut - { - "id": "road_label_walking", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Road Labels" - }, - "minzoom": 13, - "maxzoom": 22, - "filter": ["in", "network", "iwn", "nwn", "rwn"], - "layout": { - "text-font": ["Noto Sans Regular"], - "text-size": {"base": 1, "stops": [[8, 8], [20, 14]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "symbol-placement": "line", - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#990000", - "text-halo-color": "hsla(0, 0%, 100%, 0.8)", - "text-halo-width": 0.9 - } - }, // road_label_walking - { - "id": "road_label_cycling", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Cycling" - }, - "minzoom": 11, - "maxzoom": 22, - "filter": ["in", "network", "icn", "ncn", "rcn"], - "layout": { - "text-font": ["Noto Sans Regular"], - "text-size": {"base": 1, "stops": [[8, 8], [20, 14]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "symbol-placement": "line", - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#6dad3e", - "text-halo-color": "#ffffff", - "text-halo-width": 1 - } - }, // road_label_cycling - { - "id": "road_label_2", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Road Labels" - }, - "minzoom": 14, - "maxzoom": 22, - "filter": [ - "all", - ["!in", "type", "ferry", "motorway", "primary", "secondary", "piste"], - [ - "!in", - "subtype", - "t-bar", - "drag_lift", - "magic_carpet", - "rope_tow", - "downhill", - "nordic" - ], - ["!has", "network"] - ], - "layout": { - "text-font": ["Noto Sans Regular"], - "text-size": {"base": 1, "stops": [[10, 8], [16, 14]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "symbol-placement": "line", - "symbol-spacing": 200, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "hsla(0, 0%, 0%, 0.6)", - "text-halo-color": "#ffffff", - "text-halo-width": 1 - } - }, // road_label_2 - { - "id": "road_label_1", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Road Labels" - }, - "minzoom": 8, - "maxzoom": 22, - "filter": [ - "all", - ["in", "type", "motorway", "primary", "secondary"], - [ - "!in", - "network", - "ncn", - "rcn", - "icn", - "lcn", - "iwn", - "nwn", - "rwn", - "lwn" - ] - ], - "layout": { - "text-font": ["Noto Sans Regular"], - "text-size": {"base": 1, "stops": [[13, 10], [16, 14]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "symbol-placement": "line", - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "hsla(0, 0%, 0%, 0.7)", - "text-halo-color": "#ffffff", - "text-halo-width": 1 - } - }, // road_label_1 - { - "id": "road_label_highway_shield_primary", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Road Shields" - }, - "minzoom": 11, - "maxzoom": 22, - "filter": ["==", "type", "primary"], - "layout": { - "symbol-placement": {"base": 1, "stops": [[10, "point"], [11, "line"]]}, - "text-font": ["Open Sans Bold"], - "icon-image": "motorway_{ref_length}", - "text-field": "{ref}", - "icon-rotation-alignment": "viewport", - "text-rotation-alignment": "viewport", - "text-size": 10, - "symbol-spacing": 500, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - } - }, // road_label_highway_shield_primary - { - "id": "road_label_highway_shield_motorway", - "type": "symbol", - "source": "mtk", - "source-layer": "road_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Road Shields" - }, - "minzoom": 9, - "maxzoom": 22, - "filter": ["==", "type", "motorway"], - "layout": { - "symbol-placement": {"base": 1, "stops": [[10, "point"], [11, "line"]]}, - "text-font": ["Open Sans Bold"], - "icon-image": "motorway_{ref_length}", - "icon-size": 1, - "text-field": "{ref}", - "icon-rotation-alignment": "viewport", - "text-rotation-alignment": "viewport", - "text-size": 10, - "symbol-spacing": 500, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - } - }, // road_label_highway_shield_motorway - { - "id": "place_label_hamlet_suburb", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Other Places" - }, - "minzoom": 11, - "maxzoom": 22, - "filter": ["in", "type", "hamlet", "suburb"], - "layout": { - "text-letter-spacing": 0.1, - "text-size": {"base": 1.2, "stops": [[12, 10], [15, 14]]}, - "text-font": ["Noto Sans Regular"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "hsla(0, 0%, 33%, 1)", - "text-halo-width": 1.1, - "text-halo-color": "hsla(0, 0%, 100%, 0.6)" - } - }, // place_label_hamlet_suburb - { - "id": "poi_label_subway_label", - "type": "symbol", - "source": "mtk", - "source-layer": "poi_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "POI Labels" - }, - "minzoom": 14, - "maxzoom": 22, - "filter": ["all", ["==", "subtype", "subway"], ["==", "agg_stop", 1]], - "layout": { - "text-padding": 2, - "text-font": ["Noto Sans Bold"], - "text-anchor": "top", - "icon-image": "rail_metro", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-offset": [0, 0.6], - "text-size": 12, - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-halo-blur": 0.5, - "text-color": "#666", - "text-halo-width": 1, - "text-halo-color": "#ffffff" - } - }, // poi_label_subway_label - { - "id": "place_label_piste", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Villages" - }, - "minzoom": 8, - "maxzoom": 14, - "filter": ["==", "type", "piste"], - "layout": { - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"base": 1, "stops": [[8, 12], [14, 18]]}, - "text-font": ["Noto Sans Regular"], - "text-max-width": 8, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport", - "visibility": "none" - }, - "paint": { - "text-color": "#0069a3", - "text-halo-width": 1, - "text-opacity": 0.6, - "text-halo-color": "hsl(0, 0%, 100%)" - } - }, // place_label_piste - { - "id": "place_label_village", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Villages" - }, - "minzoom": 8, - "maxzoom": 22, - "filter": ["==", "type", "village"], - "layout": { - "text-padding": {"base": 1, "stops": [[8, 10], [11, 2]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"base": 1, "stops": [[8, 9.5], [16, 18]]}, - "text-font": ["Noto Sans Regular"], - "text-max-width": 8, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": { - "base": 1, - "stops": [[8, "hsla(0, 0%, 33%, 1)"], [16, "hsla(0, 0%, 0%, 1)"]] - }, - "text-halo-width": 1, - "text-halo-color": "hsla(0, 0%, 100%, 0.7)" - } - }, // place_label_village - { - "id": "water_label_lakeline", - "type": "symbol", - "source": "mtk", - "source-layer": "water_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Water Labels" - }, - "minzoom": 3, - "maxzoom": 22, - "filter": [ - "all", - ["in", "type", "water", "lake"], - ["==", "$type", "LineString"] - ], - "layout": { - "text-letter-spacing": 0.2, - "symbol-placement": "line", - "text-font": ["Noto Sans Italic"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"stops": [[9, 12], [20, 18]]}, - "text-max-width": 5, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#74aee9", - "text-halo-width": 1.5, - "text-halo-color": "rgba(255,255,255,0.7)" - } - }, // water_label_lakeline - { - "id": "water_label_point", - "type": "symbol", - "source": "mtk", - "source-layer": "water_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Water Labels" - }, - "minzoom": 3, - "maxzoom": 22, - "filter": [ - "all", - ["in", "type", "water", "lake"], - ["==", "$type", "Point"], - ["<=", "rank", 15] - ], - "layout": { - "text-letter-spacing": 0.2, - "symbol-placement": "point", - "text-font": ["Noto Sans Italic"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"stops": [[9, 10], [20, 18]]}, - "text-max-width": 5, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#74aee9", - "text-halo-width": 1.5, - "text-halo-color": "rgba(255,255,255,0.7)" - } - }, // water_label_point - { - "id": "water_label_stream", - "type": "symbol", - "source": "mtk", - "source-layer": "water_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Water Labels" - }, - "minzoom": 12, - "maxzoom": 22, - "filter": [ - "all", - ["==", "$type", "LineString"], - ["in", "type", "stream"] - ], - "layout": { - "text-letter-spacing": 0.1, - "symbol-placement": "line", - "text-size": {"stops": [[12, 8], [18, 14]]}, - "text-font": ["Noto Sans Italic"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-line-height": 1.6, - "text-max-width": 5, - "symbol-spacing": 350, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#74aee9", - "text-halo-width": 1.5, - "text-halo-color": "rgba(255,255,255,0.7)" - } - }, // water_label_stream - { - "id": "water_label_river", - "type": "symbol", - "source": "mtk", - "source-layer": "water_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Water Labels" - }, - "minzoom": 12, - "maxzoom": 22, - "filter": ["all", ["==", "$type", "LineString"], ["in", "type", "river"]], - "layout": { - "text-letter-spacing": 0.1, - "symbol-placement": "line", - "text-size": {"stops": [[3, 10], [13, 14], [18, 20]]}, - "text-font": ["Noto Sans Italic"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-line-height": 1.6, - "text-max-width": 5, - "symbol-spacing": 350, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#74aee9", - "text-halo-width": 1.4, - "text-halo-color": "hsla(0, 0%, 100%, 0.7)" - } - }, // water_label_river - { - "id": "natural_label_nationalpark", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "minzoom": 5, - "maxzoom": 22, - "filter": [ - "in", - "type", - "nature_reserve", - "protected_area", - "national_park" - ], - "layout": { - "text-letter-spacing": 0.1, - "text-size": {"base": 1.2, "stops": [[12, 12], [15, 16]]}, - "text-font": ["Noto Sans Regular"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "hsla(0, 0%, 33%, 1)", - "text-halo-width": 1.1, - "text-halo-color": "hsla(0, 0%, 100%, 0.6)" - }, - "metadata": { - "maptoolkit:category": "Nature Reserve", - "mtk:states": { - "nationalparks": { - "layout": { - "text-size": {"base": 1.2, "stops": [[12, 12], [15, 16]]} - } - } - } - } - }, // natural_label_nationalpark - { - "id": "place_label_town_small", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Towns"}, - "minzoom": 6, - "maxzoom": 22, - "filter": ["all", ["==", "type", "town"], [">", "rank", 5]], - "layout": { - "text-padding": {"base": 1, "stops": [[6, 10], [10, 2]]}, - "icon-size": 0.4, - "icon-padding": 0, - "text-size": { - "base": 1.2, - "stops": [[6, 11], [12, 15], [19, 32], [20, 48]] - }, - "text-font": { - "base": 1, - "stops": [ - [7, ["Noto Sans Regular"]], - [12, ["Noto Sans Bold"]], - [22, ["Noto Sans Bold"]] - ] - }, - "text-anchor": {"base": 1, "stops": [[7.99, "bottom"], [8, "center"]]}, - "text-offset": { - "base": 1, - "stops": [[7.99, [0, -0.2]], [8, [0, -0.2]]] - }, - "icon-image": {"base": 1, "stops": [[0, "circle-11"], [8, ""]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-line-height": {"base": 1, "stops": [[8, 1], [20, 1.3]]}, - "text-max-width": 8, - "icon-offset": [0, 5], - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": { - "base": 1, - "stops": [ - [7, "hsl(0, 0%, 0%)"], - [18.9, "hsl(0, 0%, 0%)"], - [19, "hsla(0, 0%, 100%, 0.4)"] - ] - }, - "text-halo-width": {"base": 1.4, "stops": [[18.9, 1], [19, 0.5]]}, - "text-halo-color": { - "base": 1, - "stops": [ - [18.9, "hsla(0, 0%, 100%, 0.6)"], - [19, "hsla(0, 0%, 2%, 0.4)"] - ] - } - } - }, // place_label_town_small - { - "id": "place_label_town_large", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Towns"}, - "minzoom": 5, - "maxzoom": 22, - "filter": ["all", ["==", "type", "town"], ["<=", "rank", 5]], - "layout": { - "icon-size": 0.4, - "icon-padding": 0, - "text-size": { - "base": 1.2, - "stops": [[6, 12], [11, 16], [18, 32], [19, 48], [19.9, 48], [20, 0]] - }, - "text-font": { - "base": 1, - "stops": [ - [6, ["Noto Sans Regular"]], - [11, ["Noto Sans Bold"]], - [22, ["Noto Sans Bold"]] - ] - }, - "text-anchor": {"base": 1, "stops": [[7.99, "bottom"], [8, "center"]]}, - "text-offset": { - "base": 1, - "stops": [[7.99, [0, -0.2]], [8, [0, -0.2]]] - }, - "icon-image": {"base": 1, "stops": [[0, "circle-11"], [8, ""]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-line-height": {"base": 1, "stops": [[8, 1], [20, 1.3]]}, - "text-max-width": 8, - "icon-offset": [0, 5], - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": { - "base": 1, - "stops": [ - [6, "hsl(0, 0%, 0%)"], - [17.9, "hsl(0, 0%, 0%)"], - [18, "hsla(0, 0%, 100%, 0.4)"] - ] - }, - "text-halo-width": { - "base": 1.4, - "stops": [[6, 1], [17.9, 1], [18, 0.5]] - }, - "text-halo-color": { - "base": 1, - "stops": [ - [6, "hsla(0, 0%, 100%, 0.5)"], - [17.9, "hsla(0, 0%, 100%, 0.5)"], - [18, "hsla(0, 0%, 2%, 0.4)"] - ] - } - } - }, // place_label_town_large - { - "id": "place_label_island_small", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Other Places" - }, - "minzoom": 8, - "maxzoom": 22, - "filter": ["all", ["==", "type", "island"], [">", "rank", 3]], - "layout": { - "text-letter-spacing": 0.1, - "text-size": {"base": 1.2, "stops": [[12, 12], [15, 16]]}, - "text-font": ["Noto Sans Regular"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#666", - "text-halo-width": 1.2, - "text-halo-color": "rgba(255,255,255,0.8)" - } - }, // place_label_island_small - { - "id": "place_label_island_large", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Other Places" - }, - "minzoom": 7, - "maxzoom": 22, - "filter": ["all", ["==", "type", "island"], ["<", "rank", 4]], - "layout": { - "text-letter-spacing": 0.1, - "text-size": {"base": 1.2, "stops": [[12, 12], [15, 16]]}, - "text-font": ["Noto Sans Regular"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-max-width": 9, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#666", - "text-halo-width": 1.2, - "text-halo-color": "rgba(255,255,255,0.8)" - } - }, // place_label_island_large - { - "id": "place_label_city_small", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Cities"}, - "minzoom": 4, - "maxzoom": 15.9, - "filter": [ - "all", - ["==", "type", "city"], - ["!in", "rank", 0, 1, 2, 3, 4, 5] - ], - "layout": { - "icon-size": 0.5, - "text-line-height": 1.1, - "text-font": { - "base": 1, - "stops": [[0, ["Noto Sans Regular"]], [9, ["Noto Sans Bold"]]] - }, - "text-anchor": {"base": 1, "stops": [[7.99, "bottom"], [8, "center"]]}, - "text-offset": { - "base": 1, - "stops": [[7.99, [0, -0.2]], [8, [0, -0.2]]] - }, - "icon-image": {"base": 1, "stops": [[0, "circle-11"], [8, ""]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": { - "base": 1.2, - "stops": [ - [5, 12], - [8, 15], - [9, 18], - [15, 32], - [16, 48], - [16.9, 48], - [17, 0] - ] - }, - "text-max-width": 8, - "icon-offset": [0, 5], - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": { - "base": 1, - "stops": [ - [0, "hsl(0, 0%, 0%)"], - [13.9, "hsl(0, 0%, 0%)"], - [14, "hsla(0, 0%, 100%, 0.4)"] - ] - }, - "text-halo-width": {"base": 1.4, "stops": [[5, 1], [14, 1], [15, 0.5]]}, - "text-halo-color": { - "base": 1, - "stops": [ - [5, "hsla(0, 0%, 100%, 0.5)"], - [13, "hsla(0, 0%, 100%, 0.5)"], - [14, "hsla(0, 0%, 2%, 0.4)"] - ] - } - } - }, // place_label_city_small - { - "id": "place_label_city_medium", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Cities"}, - "minzoom": 4, - "maxzoom": 15.9, - "filter": ["all", ["==", "type", "city"], ["in", "rank", 3, 4, 5]], - "layout": { - "icon-size": 0.5, - "text-size": { - "base": 1.2, - "stops": [ - [5, 15], - [7, 18], - [9, 22], - [14, 48], - [15, 64], - [15.9, 64], - [16, 0] - ] - }, - "text-font": { - "base": 1, - "stops": [[0, ["Noto Sans Regular"]], [9, ["Noto Sans Bold"]]] - }, - "text-anchor": {"base": 1, "stops": [[7.99, "bottom"], [8, "center"]]}, - "text-offset": { - "base": 1, - "stops": [[7.99, [0, -0.2]], [8, [0, -0.2]]] - }, - "icon-image": {"base": 1, "stops": [[0, "circle-11"], [8, ""]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-line-height": 1.1, - "text-max-width": 8, - "icon-offset": [0, 5], - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": { - "base": 1, - "stops": [ - [0, "hsl(0, 0%, 0%)"], - [13.9, "hsl(0, 0%, 0%)"], - [14, "hsla(0, 0%, 100%, 0.4)"] - ] - }, - "text-halo-width": { - "base": 1.4, - "stops": [[5, 1], [13.9, 1], [14, 0.5]] - }, - "text-halo-color": { - "base": 1, - "stops": [ - [5, "hsla(0, 0%, 100%, 0.5)"], - [13.9, "hsla(0, 0%, 100%, 0.5)"], - [14, "hsla(0, 0%, 2%, 0.4)"] - ] - } - } - }, // place_label_city_medium - { - "id": "place_label_city_large", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": {"maptoolkit:type": "label", "maptoolkit:category": "Cities"}, - "minzoom": 4, - "maxzoom": 15.9, - "filter": ["all", ["==", "type", "city"], ["in", "rank", 0, 1, 2]], - "layout": { - "icon-size": 0.6, - "text-padding": {"base": 1, "stops": [[7, 20], [8, 5]]}, - "text-font": ["Noto Sans Bold"], - "text-anchor": {"base": 1, "stops": [[7.99, "bottom"], [8, "center"]]}, - "text-offset": { - "base": 1, - "stops": [[7.99, [0, -0.2]], [8, [0, -0.2]]] - }, - "icon-image": {"base": 1, "stops": [[0, "circle-11"], [8, ""]]}, - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": { - "base": 1.2, - "stops": [[5, 15], [9, 24], [13, 48], [15, 64], [17.9, 64], [18, 0]] - }, - "text-max-width": 8, - "icon-offset": [0, 5], - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": { - "base": 1, - "stops": [ - [0, "hsl(0, 0%, 0%)"], - [13.5, "hsl(0, 0%, 0%)"], - [14, "hsla(0, 0%, 100%, 0.4)"] - ] - }, - "text-halo-width": { - "base": 1.4, - "stops": [[5, 1], [13.5, 1], [14, 0.5]] - }, - "text-halo-color": { - "base": 1, - "stops": [ - [5, "hsla(0, 0%, 100%, 0.5)"], - [13.5, "hsla(0, 0%, 100%, 0.5)"], - [14, "hsla(0, 0%, 2%, 0.4)"] - ] - } - } - }, // place_label_city_large - { - "id": "water_label_ocean", - "type": "symbol", - "source": "mtk", - "source-layer": "water_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Water Labels" - }, - "minzoom": 1, - "maxzoom": 22, - "filter": ["in", "type", "sea", "ocean"], - "layout": { - "text-letter-spacing": 0.2, - "symbol-placement": "point", - "text-size": {"stops": [[3, 12], [4, 16]]}, - "text-font": ["Noto Sans Italic"], - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-offset": [0, 1], - "text-line-height": 1.6, - "text-max-width": 5, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#74aee9", - "text-halo-width": 1.5, - "text-halo-color": "rgba(255,255,255,0.7)" - } - }, // water_label_ocean - { - "id": "place_label_country_4", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Country Labels" - }, - "minzoom": 3, - "maxzoom": 22, - "filter": ["all", ["==", "type", "country"], ["==", "rank", 4]], - "layout": { - "text-transform": "uppercase", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"stops": [[4, 11], [6, 15]]}, - "text-font": ["Noto Sans Regular"], - "text-max-width": 6.25, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#334", - "text-halo-color": "rgba(255,255,255,0.8)", - "text-halo-width": 1.4, - "text-halo-blur": 1 - } - }, // place_label_country_4 - { - "id": "place_label_country_3", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Country Labels" - }, - "minzoom": 3, - "maxzoom": 22, - "filter": ["all", ["==", "type", "country"], ["==", "rank", 3]], - "layout": { - "text-transform": "uppercase", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"stops": [[3, 11], [7, 17]]}, - "text-font": ["Noto Sans Regular"], - "text-max-width": 6.25, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#334", - "text-halo-color": "rgba(255,255,255,0.8)", - "text-halo-width": 1.4, - "text-halo-blur": 1 - } - }, // place_label_country_3 - { - "id": "place_label_country_2", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Country Labels" - }, - "minzoom": 2, - "maxzoom": 22, - "filter": ["all", ["==", "type", "country"], ["==", "rank", 2]], - "layout": { - "text-transform": "uppercase", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"stops": [[2, 11], [5, 18]]}, - "text-font": ["Noto Sans Regular"], - "text-max-width": 6.25, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#334", - "text-halo-color": "rgba(255,255,255,0.8)", - "text-halo-width": 1.4, - "text-halo-blur": 1 - } - }, // place_label_country_2 - { - "id": "place_label_country_1", - "type": "symbol", - "source": "mtk", - "source-layer": "place_label", - "metadata": { - "maptoolkit:type": "label", - "maptoolkit:category": "Country Labels" - }, - "minzoom": 1, - "maxzoom": 22, - "filter": ["all", ["==", "type", "country"], ["==", "rank", 1]], - "layout": { - "text-transform": "uppercase", - "text-field": [ - "case", - ["has", "is_nonlatin"], - ["concat", ["get", "name"], "\n", ["get", "name_en"]], - ["get", "name"] - ], - "text-size": {"stops": [[1, 11], [4, 17]]}, - "text-font": ["Noto Sans Regular"], - "text-max-width": 6.25, - "symbol-avoid-edges": false, - "text-pitch-alignment": "viewport" - }, - "paint": { - "text-color": "#334", - "text-halo-color": "rgba(255,255,255,0.8)", - "text-halo-width": 1.4, - "text-halo-blur": 1 - } - } // place_label_country_1 - ] - }, - hash: true + hash: true, + style: "https://static.maptoolkit.net/styles/toursprung/terrain.json" +}); + +map.on("load", () => { + map.addSource("terrain", { + "type": "raster-dem", + "tiles": ["https://vtc-cdn.maptoolkit.net/terrainrgb/{z}/{x}/{y}.webp"], + "encoding": "mtk", + "maxzoom": 15 + }); + map.addTerrain("terrain"); +}); + +map.on("click", e => { + new maplibregl.Marker().setLngLat(e.lngLat).addTo(map); }); -map.showTileBoundaries=false; diff --git a/src/data/bucket/circle_bucket.ts b/src/data/bucket/circle_bucket.ts index ca17e77698c..dbbbc3246e9 100644 --- a/src/data/bucket/circle_bucket.ts +++ b/src/data/bucket/circle_bucket.ts @@ -63,7 +63,7 @@ class CircleBucket implement segments: SegmentVector; uploaded: boolean; - points: Array; + centroids: Array<{ x: number; y: number; }>; constructor(options: BucketParameters) { this.zoom = options.zoom; @@ -79,7 +79,7 @@ class CircleBucket implement this.segments = new SegmentVector(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id); - this.points = []; + this.centroids = []; } populate(features: Array, options: PopulateParameters, canonical: CanonicalTileID) { @@ -195,7 +195,7 @@ class CircleBucket implement this.indexArray.emplaceBack(index, index + 1, index + 2); this.indexArray.emplaceBack(index, index + 3, index + 2); - this.points.push([x, y]); + this.centroids.push({ x: x, y: y }); segment.vertexLength += 4; segment.primitiveLength += 2; diff --git a/src/data/bucket/fill_extrusion_bucket.ts b/src/data/bucket/fill_extrusion_bucket.ts index 2e3e1e463e1..99df2d7b869 100644 --- a/src/data/bucket/fill_extrusion_bucket.ts +++ b/src/data/bucket/fill_extrusion_bucket.ts @@ -72,7 +72,7 @@ class FillExtrusionBucket implements Bucket { segments: SegmentVector; uploaded: boolean; features: Array; - points: Array<{x: number; y: number; size: number;}>; + centroids: Array<{ x: number; y: number; vertexCount: number; }>; constructor(options: BucketParameters) { this.zoom = options.zoom; @@ -88,7 +88,7 @@ class FillExtrusionBucket implements Bucket { this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.segments = new SegmentVector(); this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id); - this.points = []; + this.centroids = []; } populate(features: Array, options: PopulateParameters, canonical: CanonicalTileID) { @@ -161,7 +161,7 @@ class FillExtrusionBucket implements Bucket { } addFeature(feature: BucketFeature, geometry: Array>, index: number, canonical: CanonicalTileID, imagePositions: {[_: string]: ImagePosition}) { - const point = { x: 0, y: 0, size: 0 }; + const centroid = { x: 0, y: 0, vertexCount: 0 }; for (const polygon of classifyRings(geometry, EARCUT_MAX_RINGS)) { let numVertices = 0; for (const ring of polygon) { @@ -197,13 +197,13 @@ class FillExtrusionBucket implements Bucket { addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); - point.x += 2 * p1.x; point.y += 2 * p1.y; point.size += 2; + centroid.x += 2 * p1.x; centroid.y += 2 * p1.y; centroid.vertexCount +=2; edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); - point.x += 2 * p2.x; point.y += 2 * p2.y; point.size += 2; + centroid.x += 2 * p2.x; centroid.y += 2 * p2.y; centroid.vertexCount +=2; const bottomRight = segment.vertexLength; @@ -249,7 +249,7 @@ class FillExtrusionBucket implements Bucket { const p = ring[i]; addVertex(this.layoutVertexArray, p.x, p.y, 0, 0, 1, 1, 0); - point.x += p.x; point.y += p.y; point.size += 1; + centroid.x += p.x; centroid.y += p.y; centroid.vertexCount += 1; flattened.push(p.x); flattened.push(p.y); @@ -272,14 +272,13 @@ class FillExtrusionBucket implements Bucket { segment.vertexLength += numVertices; } - - // remember polygon centroid to calculate elevation later - this.points.push({ - x: Math.floor(point.x / point.size), - y: Math.floor(point.y / point.size), - size: point.size + // remember polygon centroid to calculate elevation in a later step + this.centroids.push({ + x: Math.floor(centroid.x / centroid.vertexCount), + y: Math.floor(centroid.y / centroid.vertexCount), + vertexCount: centroid.vertexCount }); - for (let i=0; i 0 the frameport's viewbuffer is located to the currect subtile - const dz = tileID.canonical.z - (z < tile.tileID.canonical.z ? z : tile.tileID.canonical.z); - const x = tileID.canonical.x - (tile.tileID.canonical.x << dz); - const y = tileID.canonical.y - (tile.tileID.canonical.y << dz); - const size = tile.fbo.width / (1 << dz); - this.context.bindFramebuffer.set(tile.fbo.framebuffer); - this.context.viewport.set([size * x, size * y, size, size]); - return tile.tileID.posMatrix; - } - return null; + prepareFramebuffer(tileID: OverscaledTileID, terrainTile: Tile) { + const z = Math.floor(this.transform.zoom); + // dz is the tileSize difference of the layer-source and the 512px terrain-source + // so if dz > 0 the frameport's viewbuffer is located to the currect subtile + const dz = tileID.canonical.z - (z < terrainTile.tileID.canonical.z ? z : terrainTile.tileID.canonical.z); + const x = tileID.canonical.x - (terrainTile.tileID.canonical.x << dz); + const y = tileID.canonical.y - (terrainTile.tileID.canonical.y << dz); + const size = terrainTile.fbo.width / (1 << dz); + this.context.bindFramebuffer.set(terrainTile.fbo.framebuffer); + this.context.viewport.set([size * x, size * y, size, size]); } // draw onto the screen - finishFramebuffer(tileID?: OverscaledTileID | null, note?: string | null) { + finishFramebuffer() { this.context.bindFramebuffer.set(null); this.context.viewport.set([0, 0, this.width, this.height]); } @@ -432,18 +428,20 @@ class Painter { break; } } - // disable opaque rendering until terrain is disable - this.opaquePassCutoff = 0; - - this.batch = 0; - prepareTerrain(this, this.style.terrainSourceCache); - - // update coords-framebuffer only on camera movement - const newTiles = this.style.terrainSourceCache.tilesForTime(this.coordsBuffer.renderTime); - if (!mat4.equals(this.coordsBuffer.matrix, this.transform.projMatrix) || newTiles.length) { - mat4.copy(this.coordsBuffer.matrix, this.transform.projMatrix); - this.coordsBuffer.renderTime = Date.now(); - drawTerrainCoords(this, this.style.terrainSourceCache); + + const isTerrainEnabled = this.style.terrainSourceCache.isEnabled(); + if (isTerrainEnabled) { + this.opaquePassCutoff = 0; + this.batch = 0; + prepareTerrain(this, this.style.terrainSourceCache); + + // update coords-framebuffer on camera movement + const newTiles = this.style.terrainSourceCache.tilesAfterTime(this.coordsBuffer.renderTime); + if (!mat4.equals(this.coordsBuffer.matrix, this.transform.projMatrix) || newTiles.length) { + mat4.copy(this.coordsBuffer.matrix, this.transform.projMatrix); + this.coordsBuffer.renderTime = Date.now(); + drawTerrainCoords(this, this.style.terrainSourceCache); + } } // Offscreen pass =============================================== @@ -474,7 +472,7 @@ class Painter { // Opaque pass =============================================== // Draw opaque layers top-to-bottom first. - if (this.opaquePassCutoff > 0) { + if (!isTerrainEnabled) { this.renderPass = 'opaque'; for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) { @@ -490,9 +488,11 @@ class Painter { // Translucent pass =============================================== // Draw all other layers bottom-to-top. this.renderPass = 'translucent'; + // the following variables only used when terrain-3d is enabled let prevType = null; - const rerender = this.style.terrainSourceCache._rerender || this.style._modified; + const rerender = this.style.terrainSourceCache._rerender; let renderToTexture = { background: true, fill: true, line: true, raster: true }; + for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; const sourceCache = sourceCaches[layer.source]; @@ -503,44 +503,48 @@ class Painter { // separate clipping masks let coords = (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer.source]; - // render only tiles which has loaded terrain - if (coords) coords = coords.filter(tileID => { - const tile = this.getTerrainTile(tileID); - return tile && tile.state == "loaded"; - }); + if (isTerrainEnabled) { + // render only tiles which has loaded terrain + if (coords) coords = coords.filter(tileID => { + const tile = this.getTerrainTile(tileID); + return tile && tile.state == "loaded"; + }); + + // render background, fill, line & raster layer into texture + if (renderToTexture[type]) { + if (prevType == 'hillshade') drawTerrain(this, this.style.terrainSourceCache); + if (prevType && !renderToTexture[prevType]) { + this.batch++; + prepareTerrain(this, this.style.terrainSourceCache); + if (rerender) clearTerrain(this, this.style.terrainSourceCache); + } + prevType = type; + if (!rerender) continue; - // render background, fill, line & raster layer into texture - if (renderToTexture[type]) { - if (prevType == 'hillshade') drawTerrain(this, this.style.terrainSourceCache); - if (prevType && !renderToTexture[prevType]) { + // render hillshading-texture to separate mesh-texture + // FIXME-3D! render hillshading-texture direct to screen for performance + } else if (type == 'hillshade') { + if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); this.batch++; prepareTerrain(this, this.style.terrainSourceCache); - if (rerender) clearTerrain(this, this.style.terrainSourceCache); + clearTerrain(this, this.style.terrainSourceCache); + prevType = type; + + // render all other layers direct to screen + } else { + if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); + prevType = type; } - prevType = type; - if (!rerender) continue; - - // render hillshading-texture to separate mesh-texture - // FIXME-3D! render hillshading-texture direct to screen for performance - } else if (type == 'hillshade') { - if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); - this.batch++; - prepareTerrain(this, this.style.terrainSourceCache); - clearTerrain(this, this.style.terrainSourceCache); - prevType = type; - - // render all other layers direct to screen - } else { - if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); - prevType = type; } this._renderTileClippingMasks(layer, coordsAscending[layer.source]); this.renderLayer(this, sourceCache, layer, coords); } - if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); - this.style.terrainSourceCache._rerender = false; + if (isTerrainEnabled) { + if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); + this.style.terrainSourceCache._rerender = false; + } if (this.options.showTileBoundaries) { //Use source with highest maxzoom @@ -687,9 +691,20 @@ class Painter { useProgram(name: string, programConfiguration?: ProgramConfiguration | null): Program { this.cache = this.cache || {}; - const key = `${name}${programConfiguration ? programConfiguration.cacheKey : ''}${this._showOverdrawInspector ? '/overdraw' : ''}`; + const key = name + + (programConfiguration ? programConfiguration.cacheKey : '') + + (this._showOverdrawInspector ? '/overdraw' : '') + + (this.style.terrainSourceCache.isEnabled() ? '/terrain' : ''); if (!this.cache[key]) { - this.cache[key] = new Program(this.context, name, shaders[name], programConfiguration, programUniforms[name], this._showOverdrawInspector); + this.cache[key] = new Program( + this.context, + name, + shaders[name], + programConfiguration, + programUniforms[name], + this._showOverdrawInspector, + this.style.terrainSourceCache.isEnabled() + ); } return this.cache[key]; } diff --git a/src/render/program.ts b/src/render/program.ts index 2335f1444ad..154717c2f02 100644 --- a/src/render/program.ts +++ b/src/render/program.ts @@ -44,7 +44,8 @@ class Program { }, configuration: ProgramConfiguration | undefined | null, fixedUniforms: (b: Context, a: UniformLocations) => Us, - showOverdrawInspector: boolean) { + showOverdrawInspector: boolean, + useTerrain: boolean) { const gl = context.gl; this.program = gl.createProgram(); @@ -65,7 +66,9 @@ class Program { if (showOverdrawInspector) { defines.push('#define OVERDRAW_INSPECTOR;'); } - + if (useTerrain) { + defines.push('#define TERRAIN3D;'); + } const fragmentSource = defines.concat(shaders.prelude.fragmentSource, source.fragmentSource).join('\n'); const vertexSource = defines.concat(shaders.prelude.vertexSource, source.vertexSource).join('\n'); const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); diff --git a/src/render/program/hillshade_program.ts b/src/render/program/hillshade_program.ts index 1cbf88cefcd..df516fa3de2 100644 --- a/src/render/program/hillshade_program.ts +++ b/src/render/program/hillshade_program.ts @@ -59,7 +59,7 @@ const hillshadeUniformValues = ( painter: Painter, tile: Tile, layer: HillshadeStyleLayer, - matrix?: mat4 + terrainTile: Tile ): UniformValues => { const shadow = layer.paint.get('hillshade-shadow-color'); const highlight = layer.paint.get('hillshade-highlight-color'); @@ -72,7 +72,7 @@ const hillshadeUniformValues = ( } const align = !painter.options.moving; return { - 'u_matrix': matrix || painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), + 'u_matrix': terrainTile ? terrainTile.tileID.posMatrix : painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), 'u_image': 0, 'u_latrange': getTileLatRange(painter, tile.tileID), 'u_light': [layer.paint.get('hillshade-exaggeration'), azimuthal], diff --git a/src/render/program/line_program.ts b/src/render/program/line_program.ts index d37bf0d1b01..95d5adf83c6 100644 --- a/src/render/program/line_program.ts +++ b/src/render/program/line_program.ts @@ -1,7 +1,6 @@ import {Uniform1i, Uniform1f, Uniform2f, Uniform3f, UniformMatrix4f} from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import {extend} from '../../util/util'; -import {mat4} from 'gl-matrix'; import type Context from '../../gl/context'; import type {UniformValues, UniformLocations} from '../uniform_binding'; @@ -98,12 +97,12 @@ const lineUniformValues = ( painter: Painter, tile: Tile, layer: LineStyleLayer, - matrix?: mat4 + terrainTile: Tile ): UniformValues => { const transform = painter.transform; return { - 'u_matrix': calculateMatrix(painter, tile, layer, matrix), + 'u_matrix': calculateMatrix(painter, tile, layer, terrainTile), 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), 'u_device_pixel_ratio': devicePixelRatio, 'u_units_to_pixels': [ @@ -118,9 +117,9 @@ const lineGradientUniformValues = ( tile: Tile, layer: LineStyleLayer, imageHeight: number, - matrix?: mat4 + terrainTile: Tile ): UniformValues => { - return extend(lineUniformValues(painter, tile, layer, matrix), { + return extend(lineUniformValues(painter, tile, layer, terrainTile), { 'u_image': 0, 'u_image_height': imageHeight, }); @@ -131,12 +130,12 @@ const linePatternUniformValues = ( tile: Tile, layer: LineStyleLayer, crossfade: CrossfadeParameters, - matrix?: mat4 + terrainTile: Tile ): UniformValues => { const transform = painter.transform; const tileZoomRatio = calculateTileRatio(tile, transform); return { - 'u_matrix': calculateMatrix(painter, tile, layer, matrix), + 'u_matrix': calculateMatrix(painter, tile, layer, terrainTile), 'u_texsize': tile.imageAtlasTexture.size, // camera zoom ratio 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), @@ -157,7 +156,7 @@ const lineSDFUniformValues = ( layer: LineStyleLayer, dasharray: CrossFaded>, crossfade: CrossfadeParameters, - matrix?: mat4 + terrainTile: Tile ): UniformValues => { const transform = painter.transform; const lineAtlas = painter.lineAtlas; @@ -171,7 +170,7 @@ const lineSDFUniformValues = ( const widthA = posA.width * crossfade.fromScale; const widthB = posB.width * crossfade.toScale; - return extend(lineUniformValues(painter, tile, layer, matrix), { + return extend(lineUniformValues(painter, tile, layer, terrainTile), { 'u_patternscale_a': [tileRatio / widthA, -posA.height / 2], 'u_patternscale_b': [tileRatio / widthB, -posB.height / 2], 'u_sdfgamma': lineAtlas.width / (Math.min(widthA, widthB) * 256 * devicePixelRatio) / 2, @@ -186,9 +185,9 @@ function calculateTileRatio(tile: Tile, transform: Transform) { return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom); } -function calculateMatrix(painter, tile, layer, posMatrix) { +function calculateMatrix(painter, tile, layer, terrainTile) { return painter.translatePosMatrix( - posMatrix || tile.tileID.posMatrix, + terrainTile ? terrainTile.tileID.posMatrix : tile.tileID.posMatrix, tile, layer.paint.get('line-translate'), layer.paint.get('line-translate-anchor') diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index d7b45bd716c..32fdd174788 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -76,22 +76,30 @@ float hasBit(float value, int pos) { return floor(mod(floor(value / pow(2.0, float(pos))), 2.0)); } -// unpack a RGBA value from the the coords framebuffer into a vec2 in the range from 0 .. 8191 +// unpack a RGBA value from the coords framebuffer into a vec2 in the range from 0 .. 8191 vec2 unpackCoord(vec4 rgba) { float r = floor(rgba.r * 255.0); float g = floor(rgba.g * 255.0); float b = floor(rgba.b * 255.0); float x = r + hasBit(b, 4) * 256.0 + hasBit(b, 5) * 512.0 + hasBit(b, 6) * 1024.0 + hasBit(b, 7) * 2048.0; float y = g + hasBit(b, 0) * 256.0 + hasBit(b, 1) * 512.0 + hasBit(b, 2) * 1024.0 + hasBit(b, 3) * 2048.0; - return vec2(x, y) * 2.0; + return vec2(x, y) * 2.0; // multiply by 2 is necesarry because the coords-texture has only 4096x4096 pixels. } -// unpack a coord RGBA to vec2 +// calculate the visibility of a coordinate in terrain and return an opacity value. +// if a coordinate is behind the terrain reduce its opacity float calculate_visibility(sampler2D u_coords, vec4 pos, vec2 tilePos) { - vec3 frag = pos.xyz / pos.w; - vec2 coord = unpackCoord(texture2D(u_coords, frag.xy * 0.5 + 0.5)); - vec2 delta = tilePos - coord; - float distance = sqrt(delta.x * delta.x + delta.y * delta.y); - if (distance < 100.0) return 1.0; - return 0.2; + #ifdef TERRAIN3D + vec3 frag = pos.xyz / pos.w; + vec2 coord = unpackCoord(texture2D(u_coords, frag.xy * 0.5 + 0.5)); + // distance is in vector-tile coordinate-space. e.g. 0 .. 8191 + // e.g. the distance of the pos.coordinate to the tile.coordinate on the same screen-pixel. + float distance = length(tilePos - coord); + if (distance < 100.0) return 1.0; // assume fully visible on terrain + return 0.2; // opacity 0.2 behind terrain + // FIXME-3D: to get a correct fadeout effect it is necesarry to grab more + // pixels around pos to find the exact screen-pixel distance behind the terrain. + #else + return 1.0; + #endif } \ No newline at end of file diff --git a/src/shaders/line.vertex.glsl b/src/shaders/line.vertex.glsl index c55fab14605..13edbbe3864 100644 --- a/src/shaders/line.vertex.glsl +++ b/src/shaders/line.vertex.glsl @@ -76,6 +76,14 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - v_gamma_scale = 1.0; + // calculate how much the perspective view squishes or stretches the extrude + #ifdef TERRAIN3D + v_gamma_scale = 1.0; // not needed, because this is done automatically via the mesh + #else + float extrude_length_without_perspective = length(dist); + float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); + v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; + #endif + v_width2 = vec2(outset, inset); } diff --git a/src/shaders/line_gradient.vertex.glsl b/src/shaders/line_gradient.vertex.glsl index f6b69765022..244ddaea891 100644 --- a/src/shaders/line_gradient.vertex.glsl +++ b/src/shaders/line_gradient.vertex.glsl @@ -79,6 +79,14 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - v_gamma_scale = 1.0; + // calculate how much the perspective view squishes or stretches the extrude + #ifdef TERRAIN3D + v_gamma_scale = 1.0; // not needed, because this is done automatically via the mesh + #else + float extrude_length_without_perspective = length(dist); + float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); + v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; + #endif + v_width2 = vec2(outset, inset); } diff --git a/src/shaders/line_pattern.vertex.glsl b/src/shaders/line_pattern.vertex.glsl index 21f9581b24e..c1abacbab91 100644 --- a/src/shaders/line_pattern.vertex.glsl +++ b/src/shaders/line_pattern.vertex.glsl @@ -88,7 +88,15 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - v_gamma_scale = 1.0; + // calculate how much the perspective view squishes or stretches the extrude + #ifdef TERRAIN3D + v_gamma_scale = 1.0; // not needed, because this is done automatically via the mesh + #else + float extrude_length_without_perspective = length(dist); + float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); + v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; + #endif + v_linesofar = a_linesofar; v_width2 = vec2(outset, inset); v_width = floorwidth; diff --git a/src/shaders/line_sdf.vertex.glsl b/src/shaders/line_sdf.vertex.glsl index e4f0eb52361..3dcb1e914c5 100644 --- a/src/shaders/line_sdf.vertex.glsl +++ b/src/shaders/line_sdf.vertex.glsl @@ -86,7 +86,15 @@ void main() { vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; - v_gamma_scale = 1.0; + // calculate how much the perspective view squishes or stretches the extrude + #ifdef TERRAIN3D + v_gamma_scale = 1.0; // not needed, because this is done automatically via the mesh + #else + float extrude_length_without_perspective = length(dist); + float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); + v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; + #endif + v_tex_a = vec2(a_linesofar * u_patternscale_a.x / floorwidth, normal.y * u_patternscale_a.y + u_tex_y_a); v_tex_b = vec2(a_linesofar * u_patternscale_b.x / floorwidth, normal.y * u_patternscale_b.y + u_tex_y_b); v_width2 = vec2(outset, inset); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 85eebe45109..3cf4fca82cd 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -6,6 +6,7 @@ import EXTENT from '../data/extent'; import {mat4} from 'gl-matrix'; import {Evented} from '../util/evented'; import Style from '../style/style'; +import Color from '../style-spec/util/color'; import Texture from '../render/texture'; import {RGBAImage} from '../util/image'; import {PosArray, TriangleIndexArray} from '../data/array_types'; @@ -21,15 +22,17 @@ class TerrainSourceCache extends Evented { _style: Style; _source: RasterDEMTileSource; _sourceCache: SourceCache; - _tiles: Array; + _tiles: {[_: string]: Tile}; _loadQueue: Array; _coordsFramebuffer: any; _rerender: boolean; minzoom: number; maxzoom: number; tileSize: number; + maxOverscaleFactor: number; // limit tileSize on overzooming for performant rendering meshSize: number; exaggeration: number; + elevationOffset: number; coordsIndex: Array; fbo: any; mesh: any; @@ -40,29 +43,54 @@ class TerrainSourceCache extends Evented { this._style = style; this._sourceCache = null; this._source = null; - this._tiles = []; + this._tiles = {}; this._loadQueue = []; this._coordsFramebuffer = null; this._rerender = true; this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; + this.maxOverscaleFactor = 3; // e.g. maximal tileSize will be 2048 this.meshSize = 128; this.exaggeration = 1.0; this.coordsIndex = []; this.fbo = null; this.mesh = null; this.coords = null; + this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. style.on("data", () => this._rerender = true); } - setSourceCache(sourceCache: SourceCache) { + enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number; maxOverscaleFactor:number}) { + this._rerender = true; this._sourceCache = sourceCache; + ['exaggeration', 'elevationOffset', 'meshSize', 'maxOverscaleFactor'].forEach(key => { + if (options && options[key] != undefined) this[key] = options[key] + }); this._source = sourceCache._source as RasterDEMTileSource; if (! this._source.loaded()) this._source.once("data", () => { this._loadQueue.forEach(tile => this._source.loadTile(tile, () => this._tileLoaded(tile))); this._loadQueue = []; }); + } + + disable() { + this._sourceCache = this._source = null; + for (const key in this._tiles) { + let tile = this._tiles[key]; + tile.textures.forEach(t => t.destroy()); + tile.textures = []; + } + for (let s in this._style.sourceCaches) { + for (let key in this._style.sourceCaches[s]._tiles) { + this._style.sourceCaches[s]._tiles[key].elevation = {}; + } + } + this._tiles = {}; + } + + isEnabled() { + return this._sourceCache ? true : false; } /** @@ -71,6 +99,7 @@ class TerrainSourceCache extends Evented { * @private */ update(transform: Transform) { + if (! this.isEnabled()) return; transform.updateElevation(); let idealTileIDs = this.getRenderableTileIds(transform); let outdated = {}; @@ -101,6 +130,10 @@ class TerrainSourceCache extends Evented { }); } + getRenderableTiles(transform: Transform) { + return this.getRenderableTileIds(transform).map(tileID => this.getTileByID(tileID.key)).filter(t => t); + } + getRenderableIds() { return Object.values(this._tiles).map(t => t.tileID.key); } @@ -125,11 +158,12 @@ class TerrainSourceCache extends Evented { * @param {number} extent optional, default 8192 */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { + if (!this.isEnabled()) return 0; const tile = this.getTileByID(tileID.key); const elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; - return (elevation + 450); // add a global offset of 450m to put the dead-sea into positive values. + return (elevation + this.elevationOffset); } /** @@ -148,8 +182,8 @@ class TerrainSourceCache extends Evented { * FIXME-3D resize texture on window-resize */ getCoordsFramebuffer(painter: Painter) { - const width = painter.width / devicePixelRatio; - const height = painter.height / devicePixelRatio; + const width = this.isEnabled() ? painter.width / devicePixelRatio : 10; + const height = this.isEnabled() ? painter.height / devicePixelRatio : 10; if (this.fbo && (this.fbo.width != width || this.fbo.height != height)) { this.fbo.destroy(); delete this.fbo; @@ -169,7 +203,7 @@ class TerrainSourceCache extends Evented { * get a list of tiles, loaded after a spezific time * @param {Date} time */ - tilesForTime(time=Date.now()) { + tilesAfterTime(time=Date.now()) { return Object.values(this._tiles).filter(t => t.timeLoaded >= time); } @@ -191,7 +225,7 @@ class TerrainSourceCache extends Evented { }; } - // create coords texture, needed to grab coordianates from canvas + // create coords texture, needed to grab coordinates from canvas // encode coords coordinate into 4 bytes: // - 8 lower bits for x // - 8 lower bits for y @@ -236,12 +270,14 @@ class TerrainSourceCache extends Evented { this._style.sourceCaches[s]._tiles[key].elevation = {}; } } + this._rerender = true; } _createEmptyTile(tileID: OverscaledTileID) { tileID.posMatrix = mat4.create(); mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); - let tile = new Tile(tileID, this.tileSize * tileID.overscaleFactor()); + let tileSize = this.tileSize * Math.min(this.maxOverscaleFactor, tileID.overscaleFactor()); + let tile = new Tile(tileID, tileSize); tile.textures = []; return tile; } diff --git a/src/style/style.ts b/src/style/style.ts index 462e8e26f9f..f378f135cde 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -119,7 +119,6 @@ class Style extends Evented { _loaded: boolean; _rtlTextPluginCallback: (a: any) => any; _changed: boolean; - _modified: boolean; _updatedSources: {[_: string]: 'clear' | 'reload'}; _updatedLayers: {[_: string]: true}; _removedLayers: {[_: string]: StyleLayer}; @@ -158,8 +157,8 @@ class Style extends Evented { this._loaded = false; this._availableImages = []; - // make elevtaion accessible from map.transform - // FIXME-3D! refactor this hack + // make elevation accessible from map.transform + // FIXME-3D! is this the right place to assign this? map.transform.terrainSourceCache = this.terrainSourceCache; this._resetUpdates(); @@ -578,8 +577,6 @@ class Style extends Evented { if (this.map && this.map._collectResourceTiming) (source as any).collectResourceTiming = true; const sourceCache = this.sourceCaches[id] = new SourceCache(id, source, this.dispatcher); - // FIXME-3D: is is may be ugly. Should we use map.setTerrain like mapbox does it? - if (source.type == "raster-dem") this.terrainSourceCache.setSourceCache(sourceCache); sourceCache.style = this; sourceCache.setEventedParent(this, () => ({ isSourceLoaded: this.loaded(), diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index b7f9c335d06..0967cd42f7f 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -481,7 +481,7 @@ export class Placement { verticalTextFeatureIndex = collisionArrays.verticalTextFeatureIndex; } - // update elevtaion of collisionArrays + // update elevation of collisionArrays let tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; let getElevation = (x: number, y: number) => this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y); for (let boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { diff --git a/src/ui/map.ts b/src/ui/map.ts index 9a60c4d74ac..7cbbecff969 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -851,7 +851,9 @@ class Map extends Camera { * var point = map.project(coordinate); */ project(lnglat: LngLatLike) { - return this.transform.locationPoint3D(LngLat.convert(lnglat)); + return this.style.terrainSourceCache.isEnabled() + ? this.transform.locationPoint3D(LngLat.convert(lnglat)) + : this.transform.locationPoint(LngLat.convert(lnglat)); } /** @@ -867,7 +869,9 @@ class Map extends Camera { * }); */ unproject(point: PointLike) { - return this.transform.pointLocation3D(Point.convert(point)); + return this.style.terrainSourceCache.isEnabled() + ? this.transform.pointLocation3D(Point.convert(point)) + : this.transform.pointLocation(Point.convert(point)); } /** @@ -1528,6 +1532,38 @@ class Map extends Camera { return source.loaded(); } + /** + * Loads a 3D terrain mesh, based on a "raster-dem" source. + * + * @param {string} id The ID of the raster-dem source to use. + * @returns {Map} `this` + * @example + * map.addTerrain('my-data'); + */ + addTerrain(id: string, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number; maxOverscaleFactor:number}) { + this.isSourceLoaded(id); + this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); + this.style.terrainSourceCache.update(this.transform); + this._sourcesDirty = true; + this._styleDirty = true; + this.triggerRepaint(); + return this; + } + + /** + * Removes the 3D terrain mesh from the map. + * + * @returns {Map} `this` + * @example + * map.removeTerrain(); + */ + removeTerrain() { + this.style.terrainSourceCache.disable(); + this.transform.updateElevation(); + this.triggerRepaint(); + return this; + } + /** * Returns a Boolean indicating whether all tiles in the viewport from all sources on * the style are loaded. From 7c6903a1fd0b5aa517c0449b931a23f09fddfa2b Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 14 Sep 2021 20:20:44 +0200 Subject: [PATCH 025/138] refactor texture rendering * decrease the number of framebuffers * decrease the number of framebuffer/texture switches * more caching and less re-rendering the old render-pipeline renders layer by layer, which is ok to render on display framebuffer, but when rendering into a textures it is more performant to render all necessary layers at once. --- src/render/draw_background.ts | 5 +- src/render/draw_fill.ts | 6 +- src/render/draw_hillshade.ts | 5 +- src/render/draw_line.ts | 5 +- src/render/draw_raster.ts | 6 +- src/render/draw_terrain.ts | 92 ++++++------- src/render/painter.ts | 120 ++++++++-------- src/source/terrain_source_cache.ts | 214 ++++++++++++++++++----------- src/source/tile.ts | 2 + src/ui/map.ts | 14 +- 10 files changed, 253 insertions(+), 216 deletions(-) diff --git a/src/render/draw_background.ts b/src/render/draw_background.ts index d1d2b696274..5b3e5fe620f 100644 --- a/src/render/draw_background.ts +++ b/src/render/draw_background.ts @@ -43,8 +43,8 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const crossfade = layer.getCrossfadeParameters(); for (const tileID of tileIDs) { - const terrainTile = painter.getTerrainTile(tileID); - if (terrainTile) painter.prepareFramebuffer(tileID, terrainTile); + const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tileID, painter.transform.zoom); + if (terrainTile) painter.setTextureViewport(tileID, terrainTile); const matrix = terrainTile ? terrainTile.tileID.posMatrix : painter.transform.calculatePosMatrix(tileID.toUnwrapped()); const uniformValues = image ? @@ -54,6 +54,5 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.tileExtentBuffer, painter.quadTriangleIndexBuffer, painter.tileExtentSegments); - if (terrainTile) painter.finishFramebuffer(); } } diff --git a/src/render/draw_fill.ts b/src/render/draw_fill.ts index 14e99fe1f86..fe5de471bca 100644 --- a/src/render/draw_fill.ts +++ b/src/render/draw_fill.ts @@ -96,8 +96,8 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const terrainTile = painter.getTerrainTile(coord); - if (terrainTile) painter.prepareFramebuffer(coord, terrainTile); + const terrainTile = painter.style.terrainSourceCache.getTerrainTile(coord, painter.transform.zoom); + if (terrainTile) painter.setTextureViewport(coord, terrainTile); let posMatrix = terrainTile ? terrainTile.tileID.posMatrix : coord.posMatrix; const tileMatrix = painter.translatePosMatrix(posMatrix, tile, @@ -122,7 +122,5 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration); - - if (terrainTile) painter.finishFramebuffer(); } } diff --git a/src/render/draw_hillshade.ts b/src/render/draw_hillshade.ts index 10c6660cd24..95d3a84c906 100644 --- a/src/render/draw_hillshade.ts +++ b/src/render/draw_hillshade.ts @@ -48,14 +48,13 @@ function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); - const terrainTile = painter.getTerrainTile(tile.tileID); - if (terrainTile) painter.prepareFramebuffer(tile.tileID, terrainTile); + const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tile.tileID, painter.transform.zoom); + if (terrainTile) painter.setTextureViewport(tile.tileID, terrainTile); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, hillshadeUniformValues(painter, tile, layer, terrainTile), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); - if (terrainTile) painter.finishFramebuffer(); } // hillshade rendering is done in two steps. the prepare step first calculates the slope of the terrain in the x and y diff --git a/src/render/draw_line.ts b/src/render/draw_line.ts index c8ccf22c0e5..0cdc44840d6 100644 --- a/src/render/draw_line.ts +++ b/src/render/draw_line.ts @@ -65,8 +65,8 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const terrainTile = painter.getTerrainTile(tile.tileID); - if (terrainTile) painter.prepareFramebuffer(tile.tileID, terrainTile); + const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tile.tileID, painter.transform.zoom); + if (terrainTile) painter.setTextureViewport(tile.tileID, terrainTile); const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade, terrainTile) : dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade, terrainTile) : @@ -120,7 +120,6 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration, bucket.layoutVertexBuffer2); - if (terrainTile) painter.finishFramebuffer(); firstTile = false; // once refactored so that bound texture state is managed, we'll also be able to remove this firstTile/programChanged logic } diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index 586a99c5d71..731a34cb792 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -63,8 +63,8 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); } - const terrainTile = painter.getTerrainTile(tile.tileID); - if (terrainTile) painter.prepareFramebuffer(tile.tileID, terrainTile); + const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tile.tileID, painter.transform.zoom); + if (terrainTile) painter.setTextureViewport(tile.tileID, terrainTile); const posMatrix = terrainTile ? terrainTile.tileID.posMatrix : painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); @@ -78,8 +78,6 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } - - if (terrainTile) painter.finishFramebuffer(); } } diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index df575d8bf39..0148f4faed8 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -3,6 +3,7 @@ import DepthMode from '../gl/depth_mode'; import {terrainUniformValues, terrainCoordsUniformValues} from './program/terrain_program'; import type Painter from './painter'; import type TerrainSourceCache from '../source/terrain_source_cache'; +import type Tile from '../source/tile'; import CullFaceMode from '../gl/cull_face_mode'; import Texture from './texture'; import Color from '../style-spec/util/color'; @@ -36,72 +37,59 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { gl.bindTexture(gl.TEXTURE_2D, coords.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainCoordsUniformValues(painter, posMatrix, 255 - sourceCache.coordsIndex.length), "terrain", - mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, - null, null, null, tile.elevationVertexBuffer); + terrainCoordsUniformValues(painter, posMatrix, 255 - sourceCache.coordsIndex.length), "terrain", + mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, + null, null, null, tile.elevationVertexBuffer); sourceCache.coordsIndex.push(tile.tileID.key); } - painter.finishFramebuffer(); + + context.bindFramebuffer.set(null); + context.viewport.set([0, 0, painter.width, painter.height]); } -function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache) { - const context = painter.context; - const gl = context.gl; - const colorMode = painter.colorModeForRenderPass(); - const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); - const program = painter.useProgram('terrain'); - const mesh = sourceCache.getTerrainMesh(context); +function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile) { + const context = painter.context; + const gl = context.gl; + const colorMode = painter.colorModeForRenderPass(); + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); + const program = painter.useProgram('terrain'); + const mesh = sourceCache.getTerrainMesh(context); - for (const tile of sourceCache.getRenderableTiles(painter.transform)) { - context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, tile.fbo.colorAttachment.get()); - const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainUniformValues(painter, posMatrix), "terrain", - mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, - null, null, null, tile.elevationVertexBuffer); - } + context.bindFramebuffer.set(null); + context.viewport.set([0, 0, painter.width, painter.height]); + context.activeTexture.set(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, FBOs[tile.tileSize].colorAttachment.get()); + const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, + terrainUniformValues(painter, posMatrix), "terrain", + mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, + null, null, null, tile.elevationVertexBuffer); } -function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache) { +function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile, stack: number) { const context = painter.context; - let fbo = 0; - for (const tile of sourceCache.getRenderableTiles(painter.transform)) { - const tileSize = tile.tileSize * 2; - if (!tile.textures[painter.batch]) { - tile.textures[painter.batch] = new Texture(context, {width: tileSize, height: tileSize, data: null}, context.gl.RGBA); - tile.textures[painter.batch].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); - } - if (!tile.elevationVertexBuffer) { - const meshSize = sourceCache.meshSize, vertexArray = new TerrainElevationArray(); - for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) { - vertexArray.emplaceBack(sourceCache.getElevation(tile.tileID, x, y, meshSize)); - } - tile.elevationVertexBuffer = context.createVertexBuffer(vertexArray, elevationAttributes.members, true); - } - // reuse a framebuffer from the framebuffer-stack and attach active batch-texture - if (!FBOs[tileSize]) FBOs[tileSize] = {}; - if (!FBOs[tileSize][fbo]) { - FBOs[tileSize][fbo] = context.createFramebuffer(tileSize, tileSize, true); - FBOs[tileSize][fbo].depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, tileSize, tileSize)); + const size = tile.tileSize * sourceCache.qualityFactor; // may increase rendering-size for better quality + if (!tile.textures[stack]) { + tile.textures[stack] = new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); + tile.textures[stack].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); + } + if (!tile.elevationVertexBuffer) { + const meshSize = sourceCache.meshSize, vertexArray = new TerrainElevationArray(); + for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) { + vertexArray.emplaceBack(sourceCache.getElevation(tile.tileID, x, y, meshSize)); } - tile.fbo = FBOs[tileSize][fbo++]; - tile.fbo.colorAttachment.set(tile.textures[painter.batch].texture); - context.bindFramebuffer.set(null); + tile.elevationVertexBuffer = context.createVertexBuffer(vertexArray, elevationAttributes.members, true); } -} - -function clearTerrain(painter: Painter, sourceCache: TerrainSourceCache, depth: number=1) { - const context = painter.context; - for (const tile of sourceCache.getRenderableTiles(painter.transform)) { - context.bindFramebuffer.set(tile.fbo.framebuffer); - context.clear({ color: Color.transparent, depth: depth }); - painter.finishFramebuffer(); + // reuse a framebuffer from the framebuffer-stack and attach active texture + if (!FBOs[tile.tileSize]) { + FBOs[tile.tileSize] = context.createFramebuffer(size, size, true); + FBOs[tile.tileSize].depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, size, size)); } + FBOs[tile.tileSize].colorAttachment.set(tile.textures[stack].texture); + context.bindFramebuffer.set(FBOs[tile.tileSize].framebuffer); } export { - clearTerrain, prepareTerrain, drawTerrain, drawTerrainCoords diff --git a/src/render/painter.ts b/src/render/painter.ts index 2f596c3a991..f41d4d9eaf5 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -31,7 +31,7 @@ import raster from './draw_raster'; import background from './draw_background'; import debug, {drawDebugPadding} from './draw_debug'; import custom from './draw_custom'; -import {clearTerrain, prepareTerrain, drawTerrain, drawTerrainCoords} from './draw_terrain'; +import {prepareTerrain, drawTerrain, drawTerrainCoords} from './draw_terrain'; import {OverscaledTileID} from '../source/tile_id'; const draw = { @@ -61,7 +61,6 @@ import type IndexBuffer from '../gl/index_buffer'; import type {DepthRangeType, DepthMaskType, DepthFuncType} from '../gl/types'; import type ResolvedImage from '../style-spec/expression/types/resolved_image'; import type {RGBAImage} from '../util/image'; -import { console } from 'window-or-global'; export type RenderPass = 'offscreen' | 'opaque' | 'translucent'; @@ -126,7 +125,6 @@ class Painter { debugOverlayTexture: Texture; debugOverlayCanvas: HTMLCanvasElement; coordsBuffer: { matrix: mat4; renderTime: number; }; - batch: number; constructor(gl: WebGLRenderingContext, transform: Transform) { this.context = new Context(gl); @@ -328,34 +326,18 @@ class Painter { return [{[minTileZ]: StencilMode.disabled}, coords]; } - getTerrainTile(tileID: OverscaledTileID) { - const z = Math.floor(this.transform.zoom); - const canonical = tileID.canonical.z > this.style.terrainSourceCache.maxzoom - ? tileID.scaledTo(this.style.terrainSourceCache.maxzoom).canonical - : tileID.canonical; - const id = new OverscaledTileID(canonical.z > z ? canonical.z : z, tileID.wrap, canonical.z, canonical.x, canonical.y); - return this.style.terrainSourceCache.getTileByID(id.scaledTo(z).key); - } - - // start drawing into the framebuffer, which is drawn on terrain-mesh - prepareFramebuffer(tileID: OverscaledTileID, terrainTile: Tile) { + // calculate the correct viewport when rendering it to texture + setTextureViewport(tileID: OverscaledTileID, terrainTile: Tile) { const z = Math.floor(this.transform.zoom); // dz is the tileSize difference of the layer-source and the 512px terrain-source // so if dz > 0 the frameport's viewbuffer is located to the currect subtile const dz = tileID.canonical.z - (z < terrainTile.tileID.canonical.z ? z : terrainTile.tileID.canonical.z); const x = tileID.canonical.x - (terrainTile.tileID.canonical.x << dz); const y = tileID.canonical.y - (terrainTile.tileID.canonical.y << dz); - const size = terrainTile.fbo.width / (1 << dz); - this.context.bindFramebuffer.set(terrainTile.fbo.framebuffer); + const size = terrainTile.tileSize * this.style.terrainSourceCache.qualityFactor / (1 << dz); this.context.viewport.set([size * x, size * y, size, size]); } - // draw onto the screen - finishFramebuffer() { - this.context.bindFramebuffer.set(null); - this.context.viewport.set([0, 0, this.width, this.height]); - } - colorModeForRenderPass(): Readonly { const gl = this.context.gl; if (this._showOverdrawInspector) { @@ -401,6 +383,8 @@ class Painter { const layerIds = this.style._order; const sourceCaches = this.style.sourceCaches; + const renderToTexture = { background: true, fill: true, line: true, raster: true }; + const isTerrainEnabled = this.style.terrainSourceCache.isEnabled(); for (const id in sourceCaches) { const sourceCache = sourceCaches[id]; @@ -410,6 +394,7 @@ class Painter { } const coordsAscending: {[_: string]: Array} = {}; + const coordsAscendingInv: {[_: string]: {[_:string]: Array}} = {}; const coordsDescending: {[_: string]: Array} = {}; const coordsDescendingSymbol: {[_: string]: Array} = {}; @@ -418,6 +403,16 @@ class Painter { coordsAscending[id] = sourceCache.getVisibleCoordinates(); coordsDescending[id] = coordsAscending[id].slice().reverse(); coordsDescendingSymbol[id] = sourceCache.getVisibleCoordinates(true).reverse(); + if (isTerrainEnabled) { + coordsAscendingInv[id] = {}; + for (let c=0; c { - const tile = this.getTerrainTile(tileID); - return tile && tile.state == "loaded"; - }); - // render background, fill, line & raster layer into texture + // remember background, fill, line & raster layer to render into texture-batch if (renderToTexture[type]) { - if (prevType == 'hillshade') drawTerrain(this, this.style.terrainSourceCache); - if (prevType && !renderToTexture[prevType]) { - this.batch++; - prepareTerrain(this, this.style.terrainSourceCache); - if (rerender) clearTerrain(this, this.style.terrainSourceCache); - } - prevType = type; - if (!rerender) continue; - - // render hillshading-texture to separate mesh-texture - // FIXME-3D! render hillshading-texture direct to screen for performance - } else if (type == 'hillshade') { - if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); - this.batch++; - prepareTerrain(this, this.style.terrainSourceCache); - clearTerrain(this, this.style.terrainSourceCache); + if (!prevType || !renderToTexture[prevType]) stacks.push([]); prevType = type; + stacks[stacks.length-1].push(layerIds[this.currentLayer]); + continue; // rendering is done later, all in once - // render all other layers direct to screen - } else { - if (renderToTexture[prevType]) drawTerrain(this, this.style.terrainSourceCache); + // render all stack-layers into a texture + } else if (renderToTexture[prevType] || type == "hillshade") { prevType = type; + const stack = stacks.length - 1, layers = stacks[stack]; + for (const tile of this.style.terrainSourceCache.getRenderableTiles(this.transform)) { + const render = tile.rerender || !tile.textures[stack]; + prepareTerrain(this, this.style.terrainSourceCache, tile, stack); + if (render) { + this.context.clear({ color: Color.transparent }); + for (let l=0; l) { if (layer.isHidden(this.transform.zoom)) return; - if (layer.type !== 'background' && layer.type !== 'custom' && !coords.length) return; + if (layer.type !== 'background' && layer.type !== 'custom' && !(coords || []).length) return; this.id = layer.id; this.gpuTimingStart(layer); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 3cf4fca82cd..82e28cdde75 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -6,7 +6,6 @@ import EXTENT from '../data/extent'; import {mat4} from 'gl-matrix'; import {Evented} from '../util/evented'; import Style from '../style/style'; -import Color from '../style-spec/util/color'; import Texture from '../render/texture'; import {RGBAImage} from '../util/image'; import {PosArray, TriangleIndexArray} from '../data/array_types'; @@ -17,6 +16,7 @@ import type SourceCache from '../source/source_cache'; import type Context from '../gl/context'; import type Painter from '../render/painter'; import type RasterDEMTileSource from '../source/raster_dem_tile_source'; +import type Framebuffer from '../gl/framebuffer'; class TerrainSourceCache extends Evented { _style: Style; @@ -25,19 +25,22 @@ class TerrainSourceCache extends Evented { _tiles: {[_: string]: Tile}; _loadQueue: Array; _coordsFramebuffer: any; - _rerender: boolean; + _fbo: any; + _mesh: any; + _coords: Texture; minzoom: number; maxzoom: number; tileSize: number; - maxOverscaleFactor: number; // limit tileSize on overzooming for performant rendering meshSize: number; exaggeration: number; elevationOffset: number; coordsIndex: Array; - fbo: any; - mesh: any; - coords: Texture; + qualityFactor: number; + terrainTileCache: {[_: string]: string}; + /** + * @param {Style} style + */ constructor(style: Style) { super(); this._style = style; @@ -46,35 +49,47 @@ class TerrainSourceCache extends Evented { this._tiles = {}; this._loadQueue = []; this._coordsFramebuffer = null; - this._rerender = true; + this._fbo = null; + this._coords = null; + this._mesh = null; this.minzoom = 5; this.maxzoom = 14; this.tileSize = 512; - this.maxOverscaleFactor = 3; // e.g. maximal tileSize will be 2048 this.meshSize = 128; this.exaggeration = 1.0; - this.coordsIndex = []; - this.fbo = null; - this.mesh = null; - this.coords = null; this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. - style.on("data", () => this._rerender = true); + this.coordsIndex = []; + this.qualityFactor = 2; + this.terrainTileCache = {}; + style.on("data", e => { + let tile = e.coord && this.getTerrainTile(e.coord, this._style.map.transform.zoom); + if (tile) tile.rerender = true; + }); } - enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number; maxOverscaleFactor:number}) { - this._rerender = true; + /** + * + * @param {SourceCache} sourceCache + * @param options Allowed options are exaggeration, elevationOffset & meshSize + */ + enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}): void { this._sourceCache = sourceCache; - ['exaggeration', 'elevationOffset', 'meshSize', 'maxOverscaleFactor'].forEach(key => { - if (options && options[key] != undefined) this[key] = options[key] + ['exaggeration', 'elevationOffset', 'meshSize'].forEach(key => { + if (options && options[key] != undefined) this[key] = options[key] }); this._source = sourceCache._source as RasterDEMTileSource; + this.minzoom = this._source.minzoom; + this.maxzoom = this._source.maxzoom; if (! this._source.loaded()) this._source.once("data", () => { - this._loadQueue.forEach(tile => this._source.loadTile(tile, () => this._tileLoaded(tile))); - this._loadQueue = []; + this._loadQueue.forEach(tile => this._source.loadTile(tile, () => this._tileLoaded(tile))); + this._loadQueue = []; }); - } + } - disable() { + /** + * remove the the 3d terrain from map. + */ + disable(): void { this._sourceCache = this._source = null; for (const key in this._tiles) { let tile = this._tiles[key]; @@ -83,22 +98,24 @@ class TerrainSourceCache extends Evented { } for (let s in this._style.sourceCaches) { for (let key in this._style.sourceCaches[s]._tiles) { - this._style.sourceCaches[s]._tiles[key].elevation = {}; + this._style.sourceCaches[s]._tiles[key].elevation = {}; } } this._tiles = {}; } - isEnabled() { + /** + * check if terrain is currently activated + * @return {boolean} + */ + isEnabled(): boolean { return this._sourceCache ? true : false; } /** - * Creates a singletop terrain-mesh - * Removes tiles that are outside the viewport and adds new tiles that are inside the viewport. - * @private + * Load Terrain Tiles, removes outdated Tiles and update camera elevation. */ - update(transform: Transform) { + update(transform: Transform): void { if (! this.isEnabled()) return; transform.updateElevation(); let idealTileIDs = this.getRenderableTileIds(transform); @@ -115,13 +132,18 @@ class TerrainSourceCache extends Evented { } } for (const key in outdated) { - let tile = this._tiles[key]; - tile.textures.forEach(t => t.destroy()); - tile.textures = []; + let tile = this._tiles[key]; + tile.textures.forEach(t => t.destroy()); + tile.textures = []; } } - getRenderableTileIds(transform: Transform) { + /** + * get a list of tileIds, which should be rendered in the current scene + * @param {Transform} transform + * @return {Array} + */ + getRenderableTileIds(transform: Transform): Array { return transform.coveringTiles({ tileSize: this.tileSize, minzoom: this._source ? this._source.minzoom : this.minzoom, @@ -130,22 +152,47 @@ class TerrainSourceCache extends Evented { }); } - getRenderableTiles(transform: Transform) { + /** + * get a list of tiles, which are loaded and should be rendered in the current scene + * @param {Transform} transform + * @returns {Array} + */ + getRenderableTiles(transform: Transform): Array { return this.getRenderableTileIds(transform).map(tileID => this.getTileByID(tileID.key)).filter(t => t); } - getRenderableIds() { + /** + * get a list of tile-keys which are available in cache + * @param {Transform} transform + * @returns {Array} + */ + getRenderableIds(): Array { return Object.values(this._tiles).map(t => t.tileID.key); } /** * get terrain tile by the TileID key - * @private + * @returns {Tile} */ getTileByID(id: string): Tile { return this._tiles[id]; } + /** + * searches for the corresponding terrain-tile at a given zoomlevel + * @param {OverscaledTileID} tileID + * @param {number} zoom + * @returns {Tile} + */ + getTerrainTile(tileID: OverscaledTileID, zoom: number): Tile { + if (this.terrainTileCache[tileID.key]) this.getTileByID(this.terrainTileCache[tileID.key]); + const z = Math.floor(zoom); + const canonical = tileID.canonical.z > this.maxzoom ? tileID.scaledTo(this.maxzoom).canonical : tileID.canonical; + const id = new OverscaledTileID(canonical.z > z ? canonical.z : z, tileID.wrap, canonical.z, canonical.x, canonical.y); + this.terrainTileCache[tileID.key] = id.scaledTo(z).key; + return this.getTileByID(this.terrainTileCache[tileID.key]); + } + /** * get the Elevation for given coordinate * FIXME-3D: @@ -156,13 +203,15 @@ class TerrainSourceCache extends Evented { * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT * @param {number} extent optional, default 8192 + * @returns {number} */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { if (!this.isEnabled()) return 0; const tile = this.getTileByID(tileID.key); - const elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates - ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) - : 0; + let elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates + ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) + : 0; + if (elevation > 8191) elevation = 0; // REMOVE: this hack is for MTK data, because of false nodata values return (elevation + this.elevationOffset); } @@ -172,6 +221,7 @@ class TerrainSourceCache extends Evented { * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT * @param {number} extent optional, default 8192 + * @returns {number} */ getElevationWithExaggeration(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { return this.getElevation(tileID, x, y, extent) * this.exaggeration; @@ -179,37 +229,43 @@ class TerrainSourceCache extends Evented { /** * store all tile-coords in a framebuffer for unprojecting pixel coordinates - * FIXME-3D resize texture on window-resize + * @param {Painter} painter + * @returns {Framebuffer} */ - getCoordsFramebuffer(painter: Painter) { + getCoordsFramebuffer(painter: Painter): Framebuffer { const width = this.isEnabled() ? painter.width / devicePixelRatio : 10; const height = this.isEnabled() ? painter.height / devicePixelRatio : 10; - if (this.fbo && (this.fbo.width != width || this.fbo.height != height)) { - this.fbo.destroy(); - delete this.fbo; + if (this._fbo && (this._fbo.width != width || this._fbo.height != height)) { + this._fbo.destroy(); + delete this._fbo; } - if (! this.fbo) { + if (! this._fbo) { painter.context.activeTexture.set(painter.context.gl.TEXTURE0); let texture = new Texture(painter.context, { width: width, height: height, data: null }, painter.context.gl.RGBA, {premultiply: false}); texture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); - this.fbo = painter.context.createFramebuffer(width, height, true); - this.fbo.colorAttachment.set(texture.texture); - this.fbo.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, width, height)); + this._fbo = painter.context.createFramebuffer(width, height, true); + this._fbo.colorAttachment.set(texture.texture); + this._fbo.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, width, height)); } - return this.fbo; + return this._fbo; } /** * get a list of tiles, loaded after a spezific time * @param {Date} time + * @returns {Array} */ - tilesAfterTime(time=Date.now()) { + tilesAfterTime(time=Date.now()): Array { return Object.values(this._tiles).filter(t => t.timeLoaded >= time); } - // create a regular mesh which will be used by all terrain-tiles + /** + * create a regular mesh which will be used by all terrain-tiles + * @param {Context} context + * @returns {Object} + */ getTerrainMesh(context: Context) { - if (this.mesh) return this.mesh; + if (this._mesh) return this._mesh; const vertexArray = new PosArray(), indexArray = new TriangleIndexArray(); const meshSize = this.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) @@ -218,33 +274,37 @@ class TerrainSourceCache extends Evented { indexArray.emplaceBack(x+y, meshSize+x+y+1, meshSize+x+y+2); indexArray.emplaceBack(x+y, meshSize+x+y+2, x+y+1); } - return this.mesh = { + return this._mesh = { indexBuffer: context.createIndexBuffer(indexArray), vertexBuffer: context.createVertexBuffer(vertexArray, posAttributes.members), segments: SegmentVector.simpleSegment(0, 0, vertexArray.length, indexArray.length) }; } - // create coords texture, needed to grab coordinates from canvas - // encode coords coordinate into 4 bytes: - // - 8 lower bits for x - // - 8 lower bits for y - // - 4 higher bits for x - // - 4 higher bits for y - // - 8 bits for coordsIndex (1 .. 256) (= number of terraintile), is later setted in draw_terrain uniform value - getCoordsTexture(context: Context) { - if (this.coords) return this.coords; + /** + * create coords texture, needed to grab coordinates from canvas + * encode coords coordinate into 4 bytes: + * - 8 lower bits for x + * - 8 lower bits for y + * - 4 higher bits for x + * - 4 higher bits for y + * - 8 bits for coordsIndex (1 .. 255) (= number of terraintile), is later setted in draw_terrain uniform value + * @param {Context} context + * @returns {Texture} + */ + getCoordsTexture(context: Context): Texture { + if (this._coords) return this._coords; const data = new Uint8Array(4096 * 4096 * 4); for (let y=0, i=0; y<4096; y++) for (let x=0; x<4096; x++, i+=4) { - data[i + 0] = x & 255; - data[i + 1] = y & 255; - data[i + 2] = ((x >> 8) << 4) | (y >> 8); - data[i + 3] = 0; + data[i + 0] = x & 255; + data[i + 1] = y & 255; + data[i + 2] = ((x >> 8) << 4) | (y >> 8); + data[i + 3] = 0; } let image = new RGBAImage({width: 4096, height: 4096}, new Uint8Array(data.buffer)); let texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - return this.coords = texture; + return this._coords = texture; } /** @@ -253,31 +313,31 @@ class TerrainSourceCache extends Evented { * - recalculate elevation of all symbols/circles/buildings of all tiles * @param {Tile} tile */ - _tileLoaded(tile: Tile) { + _tileLoaded(tile: Tile): void { tile.timeLoaded = Date.now(); + this._style.map.transform.updateElevation(); if (tile.state == "loaded") { if (this._sourceCache) this._sourceCache._backfillDEM.call(this, tile); // rerender tile incl. neighboring tiles tile.elevationVertexBuffer = null; Object.keys(tile.neighboringTiles) - .map(id => this.getTileByID(id)) - .forEach(tile => { if (tile) tile.elevationVertexBuffer = null }); + .map(id => this.getTileByID(id)) + .forEach(tile => { if (tile) tile.elevationVertexBuffer = null }); } - // mark all tiles to refetch elevation-data - // FIXME! only mark necessary tiles + // delete elevationdata from coresponding tile, so that they can be reloaded on next rendering + // FIXME-3D! only delete data from necessary tiles for (let s in this._style.sourceCaches) { - for (let key in this._style.sourceCaches[s]._tiles) { - this._style.sourceCaches[s]._tiles[key].elevation = {}; - } + for (let key in this._style.sourceCaches[s]._tiles) { + this._style.sourceCaches[s]._tiles[key].elevation = {}; + } } - this._rerender = true; } - _createEmptyTile(tileID: OverscaledTileID) { + // FIXME-3D! copy terrain-data from parent tile if available + _createEmptyTile(tileID: OverscaledTileID): Tile { tileID.posMatrix = mat4.create(); mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); - let tileSize = this.tileSize * Math.min(this.maxOverscaleFactor, tileID.overscaleFactor()); - let tile = new Tile(tileID, tileSize); + let tile = new Tile(tileID, this.tileSize * tileID.overscaleFactor()); tile.textures = []; return tile; } diff --git a/src/source/tile.ts b/src/source/tile.ts index 40403b7e1cf..9b219bbe50f 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -85,6 +85,7 @@ class Tile { reloadCallback: any; resourceTiming: Array | undefined | null; queryPadding: number; + rerender: boolean; symbolFadeHoldUntil: number | undefined | null; hasSymbolBuckets: boolean; @@ -111,6 +112,7 @@ class Tile { this.hasRTLText = false; this.dependencies = {}; this.elevation = {}; + this.rerender = false; // Counts the number of times a response was already expired when // received. We're using this to add a delay when making a new request diff --git a/src/ui/map.ts b/src/ui/map.ts index 7cbbecff969..35bffbf03e7 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -1536,11 +1536,12 @@ class Map extends Camera { * Loads a 3D terrain mesh, based on a "raster-dem" source. * * @param {string} id The ID of the raster-dem source to use. + * @param options Allowed options are exaggeration, elevationOffset & meshSize * @returns {Map} `this` * @example * map.addTerrain('my-data'); */ - addTerrain(id: string, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number; maxOverscaleFactor:number}) { + addTerrain(id: string, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}) { this.isSourceLoaded(id); this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); this.style.terrainSourceCache.update(this.transform); @@ -1558,11 +1559,11 @@ class Map extends Camera { * map.removeTerrain(); */ removeTerrain() { - this.style.terrainSourceCache.disable(); - this.transform.updateElevation(); - this.triggerRepaint(); - return this; - } + this.style.terrainSourceCache.disable(); + this.transform.updateElevation(); + this.triggerRepaint(); + return this; + } /** * Returns a Boolean indicating whether all tiles in the viewport from all sources on @@ -1572,7 +1573,6 @@ class Map extends Camera { * @example * var tilesLoaded = map.areTilesLoaded(); */ - areTilesLoaded() { const sources = this.style && this.style.sourceCaches; for (const id in sources) { From 35a5e1bb661eb60943b05234540d5dfaa32fd1ae Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 24 Sep 2021 20:27:39 +0200 Subject: [PATCH 026/138] moved elevation-calculation to GPU This checkin is only for backup, so do not test! * changed elevation calculation from CPU to GPU This change had a big impact in performacne. To calculate the hight in CPU sometimes about 100ms per tile was needed. When loading a lot of tiles the framerate was really bad. This works now much better. NOTE: Currently only the Mesh elevation is moved to GPU, symbols are still calculated via the CPU. * refactor render to texture workflow below ZL 14 Until now, below ZL 14 (e.g. our Vector-Tile maxzoom) the tile-size increased with ZL, so ZL 1-14 had 1024px, ZL 15 2048px, ZL 16 4096px, and so on. This was very easy to program, but needed also a lot of GPU performacne and RAM. So now, the TerrainSourceCache holds tiles for each zoomlevel of the size 1024, and below ZL 14 in each is renderd a sub-region of ZL 14. * refactor the coords-framebuffer. Also the coords-framebuffer use a textures with 1024px in size. To avoid bluring the texture below ZL 14 an additional small texture is needed (u_coords_index) which holds in its RGBA values the tile quadrants of the sub-regions. NOTE: This is currently a work in progress! --- src/data/dem_data.ts | 13 +- src/geo/transform.ts | 16 +- src/render/draw_background.ts | 13 +- src/render/draw_circle.ts | 2 + src/render/draw_fill.ts | 6 +- src/render/draw_hillshade.ts | 10 +- src/render/draw_line.ts | 12 +- src/render/draw_raster.ts | 6 +- src/render/draw_symbol.ts | 2 + src/render/draw_terrain.ts | 39 +-- src/render/painter.ts | 49 ++-- src/render/program/circle_program.ts | 9 +- src/render/program/fill_extrusion_program.ts | 10 +- src/render/program/hillshade_program.ts | 4 +- src/render/program/line_program.ts | 21 +- src/render/program/symbol_program.ts | 21 +- src/render/program/terrain_program.ts | 55 +++- src/shaders/_prelude.vertex.glsl | 4 +- src/shaders/circle.vertex.glsl | 9 +- src/shaders/fill_extrusion.vertex.glsl | 6 +- .../fill_extrusion_pattern.vertex.glsl | 6 +- src/shaders/symbol_icon.vertex.glsl | 11 +- src/shaders/symbol_sdf.vertex.glsl | 11 +- src/shaders/symbol_text_and_icon.vertex.glsl | 11 +- src/shaders/terrain.fragment.glsl | 4 +- src/shaders/terrain.vertex.glsl | 19 +- src/source/source_cache.ts | 3 +- src/source/terrain_source_cache.ts | 258 +++++++++++++----- src/source/tile.ts | 5 +- src/source/tile_id.ts | 9 + 30 files changed, 423 insertions(+), 221 deletions(-) diff --git a/src/data/dem_data.ts b/src/data/dem_data.ts index a18c8f65ad4..c224ef129d0 100644 --- a/src/data/dem_data.ts +++ b/src/data/dem_data.ts @@ -18,6 +18,8 @@ export default class DEMData { data: Uint32Array; stride: number; dim: number; + min: number; + max: number; encoding: "mapbox" | "terrarium" | "mtk"; // RGBAImage data has uniform 1px padding on all sides: square tile edge size defines stride @@ -52,6 +54,15 @@ export default class DEMData { this.data[this._idx(dim, -1)] = this.data[this._idx(dim - 1, 0)]; this.data[this._idx(-1, dim)] = this.data[this._idx(0, dim - 1)]; this.data[this._idx(dim, dim)] = this.data[this._idx(dim - 1, dim - 1)]; + + // calculate min/max values + this.min = Number.MAX_SAFE_INTEGER; + this.max = Number.MIN_SAFE_INTEGER; + for (let x=0; x this.max) this.max = ele; + if (ele < this.min) this.min = ele; + } } get(x: number, y: number) { @@ -71,7 +82,7 @@ export default class DEMData { getUnpackVector() { if (this.encoding === "terrarium") return [256.0, 1.0, 1.0 / 256.0, 32768.0]; - if (this.encoding === "mtk") return [6553.6, 25.6, 0.03, 10000.0]; + if (this.encoding === "mtk") return [65536.0 * 0.03, 256.0 * 0.03, 0.03, 10000.0]; return [6553.6, 25.6, 0.1, 10000.0]; } diff --git a/src/geo/transform.ts b/src/geo/transform.ts index acfc79655a5..5919a8edab6 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -352,7 +352,7 @@ class Transform { const centerCoord = MercatorCoordinate.fromLngLat(this.center); const numTiles = Math.pow(2, z); const centerPoint = [numTiles * centerCoord.x, numTiles * centerCoord.y, 0]; - const cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix2, this.worldSize, z); + const cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix, this.worldSize, z); // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level let minZoom = options.minzoom || 0; @@ -365,10 +365,7 @@ class Transform { const newRootTile = (wrap: number): any => { return { - // FIXME-3D! -5 .. 5 is enough for rendering front elevation tiles, dont know why - // but with this simple hack, there a rendered to many tiles outside the viewport, - // which is a performance issue - aabb: new Aabb([wrap * numTiles, 0, 0], [(wrap + 1) * numTiles, numTiles, 5]), + aabb: new Aabb([wrap * numTiles, 0, 0], [(wrap + 1) * numTiles, numTiles, 0]), zoom: 0, x: 0, y: 0, @@ -473,12 +470,13 @@ class Transform { getElevation(lnglat: LngLat) { const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; - if (!tsc) return 0; - const tileZ = tsc.maxzoom < this.tileZoom ? tsc.maxzoom : this.tileZoom; + if (!tsc.isEnabled()) return 0; + const maxzoom = tsc._sourceCache._source.maxzoom; + const tileZ = maxzoom < this.tileZoom ? maxzoom : this.tileZoom; const tileSize = tsc.tileSize, worldSize = (1 << tileZ) * tileSize; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); - const tileID = new OverscaledTileID(this.tileZoom, 0, tileZ, tileX, tileY); + const tileID = new OverscaledTileID(tileZ, 0, tileZ, tileX, tileY); return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); } @@ -595,7 +593,7 @@ class Transform { // decode coordinates (encoding see terrain-source-cache) const x = rgba[0] + ((rgba[2] >> 4) << 8); const y = rgba[1] + ((rgba[2] & 15) << 8); - const tileID = this.terrainSourceCache.coordsIndex[255 - rgba[3]]; + const tileID = this.terrainSourceCache._coordsIndex[255 - rgba[3]]; const tile = tileID && this.terrainSourceCache.getTileByID(tileID); if (!tile) return this.pointCoordinate(p); // FIXME! remove this hack const tileSize = this.terrainSourceCache.tileSize; diff --git a/src/render/draw_background.ts b/src/render/draw_background.ts index 5b3e5fe620f..05c3a770a6a 100644 --- a/src/render/draw_background.ts +++ b/src/render/draw_background.ts @@ -9,10 +9,11 @@ import { import type Painter from './painter'; import type SourceCache from '../source/source_cache'; import type BackgroundStyleLayer from '../style/style_layer/background_style_layer'; +import { OverscaledTileID } from '../source/tile_id'; export default drawBackground; -function drawBackground(painter: Painter, sourceCache: SourceCache, layer: BackgroundStyleLayer) { +function drawBackground(painter: Painter, sourceCache: SourceCache, layer: BackgroundStyleLayer, coords?: Array) { const color = layer.paint.get('background-color'); const opacity = layer.paint.get('background-opacity'); @@ -31,10 +32,8 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const stencilMode = StencilMode.disabled; const depthMode = painter.depthModeForSublayer(0, pass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly); const colorMode = painter.colorModeForRenderPass(); - const program = painter.useProgram(image ? 'backgroundPattern' : 'background'); - - const tileIDs = transform.coveringTiles({tileSize}); + const tileIDs = coords ? coords : transform.coveringTiles({tileSize}); if (image) { context.activeTexture.set(gl.TEXTURE0); @@ -43,10 +42,8 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const crossfade = layer.getCrossfadeParameters(); for (const tileID of tileIDs) { - const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tileID, painter.transform.zoom); - if (terrainTile) painter.setTextureViewport(tileID, terrainTile); - - const matrix = terrainTile ? terrainTile.tileID.posMatrix : painter.transform.calculatePosMatrix(tileID.toUnwrapped()); + if (coords) painter.setTextureViewport(tileID); + const matrix = coords ? tileID.posMatrix : painter.transform.calculatePosMatrix(tileID.toUnwrapped()); const uniformValues = image ? backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}, crossfade) : backgroundUniformValues(matrix, opacity, color); diff --git a/src/render/draw_circle.ts b/src/render/draw_circle.ts index da3127b9fe6..687db690e13 100644 --- a/src/render/draw_circle.ts +++ b/src/render/draw_circle.ts @@ -116,6 +116,8 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getCoordsFramebuffer(painter).colorAttachment.get()); + context.activeTexture.set(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache._coordsIndexTexture.texture); for (const segmentsState of segmentsRenderStates) { const {programConfiguration, program, layoutVertexBuffer, elevationVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; diff --git a/src/render/draw_fill.ts b/src/render/draw_fill.ts index fe5de471bca..0cb597695df 100644 --- a/src/render/draw_fill.ts +++ b/src/render/draw_fill.ts @@ -96,10 +96,10 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const terrainTile = painter.style.terrainSourceCache.getTerrainTile(coord, painter.transform.zoom); - if (terrainTile) painter.setTextureViewport(coord, terrainTile); + const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + if (terrainCoord) painter.setTextureViewport(terrainCoord); - let posMatrix = terrainTile ? terrainTile.tileID.posMatrix : coord.posMatrix; + let posMatrix = terrainCoord ? terrainCoord.posMatrix : coord.posMatrix; const tileMatrix = painter.translatePosMatrix(posMatrix, tile, layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor')); diff --git a/src/render/draw_hillshade.ts b/src/render/draw_hillshade.ts index 95d3a84c906..7cbe769955e 100644 --- a/src/render/draw_hillshade.ts +++ b/src/render/draw_hillshade.ts @@ -30,14 +30,14 @@ function drawHillshade(painter: Painter, sourceCache: SourceCache, layer: Hillsh if (tile.needsHillshadePrepare && painter.renderPass === 'offscreen') { prepareHillshade(painter, tile, layer, depthMode, StencilMode.disabled, colorMode); } else if (painter.renderPass === 'translucent') { - renderHillshade(painter, tile, layer, depthMode, stencilModes[coord.overscaledZ], colorMode); + renderHillshade(painter, coord, tile, layer, depthMode, stencilModes[coord.overscaledZ], colorMode); } } context.viewport.set([0, 0, painter.width, painter.height]); } -function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode) { +function renderHillshade(painter, coord, tile, layer, depthMode, stencilMode, colorMode) { const context = painter.context; const gl = context.gl; const fbo = tile.fbo; @@ -48,11 +48,11 @@ function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); - const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tile.tileID, painter.transform.zoom); - if (terrainTile) painter.setTextureViewport(tile.tileID, terrainTile); + const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + if (terrainCoord) painter.setTextureViewport(terrainCoord); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - hillshadeUniformValues(painter, tile, layer, terrainTile), layer.id, painter.rasterBoundsBuffer, + hillshadeUniformValues(painter, tile, layer, terrainCoord), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } diff --git a/src/render/draw_line.ts b/src/render/draw_line.ts index 0cdc44840d6..c4534e5d824 100644 --- a/src/render/draw_line.ts +++ b/src/render/draw_line.ts @@ -65,13 +65,13 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tile.tileID, painter.transform.zoom); - if (terrainTile) painter.setTextureViewport(tile.tileID, terrainTile); + const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + if (terrainCoord) painter.setTextureViewport(terrainCoord); - const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade, terrainTile) : - dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade, terrainTile) : - gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length, terrainTile) : - lineUniformValues(painter, tile, layer, terrainTile); + const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade, terrainCoord) : + dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade, terrainCoord) : + gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length, terrainCoord) : + lineUniformValues(painter, tile, layer, terrainCoord); if (image) { context.activeTexture.set(gl.TEXTURE0); diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index 731a34cb792..fe6a5af346c 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -63,10 +63,10 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); } - const terrainTile = painter.style.terrainSourceCache.getTerrainTile(tile.tileID, painter.transform.zoom); - if (terrainTile) painter.setTextureViewport(tile.tileID, terrainTile); + const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + if (terrainCoord) painter.setTextureViewport(terrainCoord); - const posMatrix = terrainTile ? terrainTile.tileID.posMatrix : painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); + const posMatrix = terrainCoord ? terrainCoord.posMatrix : painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); if (source instanceof ImageSource) { diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index 36b5ec63e7b..1d8cca3beb4 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -404,6 +404,8 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate context.activeTexture.set(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getCoordsFramebuffer(painter).colorAttachment.get()); + context.activeTexture.set(gl.TEXTURE3); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache._coordsIndexTexture.texture); if (state.isSDF) { const uniformValues = (state.uniformValues as any as UniformValues); diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 0148f4faed8..35c94af465c 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -8,12 +8,6 @@ import CullFaceMode from '../gl/cull_face_mode'; import Texture from './texture'; import Color from '../style-spec/util/color'; import ColorMode from '../gl/color_mode'; -import {TerrainElevationArray} from '../data/array_types'; -import {createLayout} from '../util/struct_array'; - -const elevationAttributes = createLayout([ - {name: 'a_ele', components: 1, type: 'Float32'} -], 4); const FBOs = {}; @@ -31,20 +25,22 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); context.clear({ color: Color.transparent, depth: 1 }); - sourceCache.coordsIndex = []; + sourceCache._coordsIndex = []; for (const tile of sourceCache.getRenderableTiles(painter.transform)) { + const dem = sourceCache.getDem(tile.tileID); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, coords.texture); + context.activeTexture.set(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, dem.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainCoordsUniformValues(painter, posMatrix, 255 - sourceCache.coordsIndex.length), "terrain", - mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, - null, null, null, tile.elevationVertexBuffer); - sourceCache.coordsIndex.push(tile.tileID.key); + const uniformValues = terrainCoordsUniformValues(painter, posMatrix, dem.matrix, 255 - sourceCache._coordsIndex.length, dem.unpackVector, sourceCache.elevationOffset); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + sourceCache._coordsIndex.push(tile.tileID.key); } context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); + sourceCache.updateCoordsIndexTexture(context); } function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile) { @@ -54,32 +50,27 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Ti const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); const program = painter.useProgram('terrain'); const mesh = sourceCache.getTerrainMesh(context); + const dem = sourceCache.getDem(tile.tileID); context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, FBOs[tile.tileSize].colorAttachment.get()); + context.activeTexture.set(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, dem.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, - terrainUniformValues(painter, posMatrix), "terrain", - mesh.vertexBuffer, mesh.indexBuffer, mesh.segments, - null, null, null, tile.elevationVertexBuffer); + const uniformValues = terrainUniformValues(painter, posMatrix, dem.matrix, dem.unpackVector, sourceCache.elevationOffset); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); } function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile, stack: number) { const context = painter.context; const size = tile.tileSize * sourceCache.qualityFactor; // may increase rendering-size for better quality if (!tile.textures[stack]) { - tile.textures[stack] = new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); + tile.textures[stack] = painter.getTileTexture(size) + || new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); tile.textures[stack].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); } - if (!tile.elevationVertexBuffer) { - const meshSize = sourceCache.meshSize, vertexArray = new TerrainElevationArray(); - for (let y=0; y<=meshSize; y++) for (let x=0; x<=meshSize; x++) { - vertexArray.emplaceBack(sourceCache.getElevation(tile.tileID, x, y, meshSize)); - } - tile.elevationVertexBuffer = context.createVertexBuffer(vertexArray, elevationAttributes.members, true); - } // reuse a framebuffer from the framebuffer-stack and attach active texture if (!FBOs[tile.tileSize]) { FBOs[tile.tileSize] = context.createFramebuffer(size, size, true); diff --git a/src/render/painter.ts b/src/render/painter.ts index f41d4d9eaf5..a6687912b1b 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -61,6 +61,7 @@ import type IndexBuffer from '../gl/index_buffer'; import type {DepthRangeType, DepthMaskType, DepthFuncType} from '../gl/types'; import type ResolvedImage from '../style-spec/expression/types/resolved_image'; import type {RGBAImage} from '../util/image'; +import Match from '../style-spec/expression/definitions/match'; export type RenderPass = 'offscreen' | 'opaque' | 'translucent'; @@ -326,15 +327,15 @@ class Painter { return [{[minTileZ]: StencilMode.disabled}, coords]; } - // calculate the correct viewport when rendering it to texture - setTextureViewport(tileID: OverscaledTileID, terrainTile: Tile) { - const z = Math.floor(this.transform.zoom); - // dz is the tileSize difference of the layer-source and the 512px terrain-source - // so if dz > 0 the frameport's viewbuffer is located to the currect subtile - const dz = tileID.canonical.z - (z < terrainTile.tileID.canonical.z ? z : terrainTile.tileID.canonical.z); - const x = tileID.canonical.x - (terrainTile.tileID.canonical.x << dz); - const y = tileID.canonical.y - (terrainTile.tileID.canonical.y << dz); - const size = terrainTile.tileSize * this.style.terrainSourceCache.qualityFactor / (1 << dz); + // calculate the correct tiles-viewport when rendering to texture + setTextureViewport(tileID: OverscaledTileID) { + let x = 0, y = 0, size = this.style.terrainSourceCache.tileSize * this.style.terrainSourceCache.qualityFactor; + const z = Math.floor(this.transform.zoom), dz = tileID.canonical.z - z; + if (dz > 0) { + x = tileID.canonical.x - (tileID.canonical.x >> dz << dz); + y = tileID.canonical.y - (tileID.canonical.y >> dz << dz); + size /= 1 << dz; + } this.context.viewport.set([size * x, size * y, size, size]); } @@ -394,8 +395,8 @@ class Painter { } const coordsAscending: {[_: string]: Array} = {}; - const coordsAscendingInv: {[_: string]: {[_:string]: Array}} = {}; const coordsDescending: {[_: string]: Array} = {}; + const coordsDescendingInv: {[_: string]: {[_:string]: Array}} = {}; const coordsDescendingSymbol: {[_: string]: Array} = {}; for (const id in sourceCaches) { @@ -404,13 +405,13 @@ class Painter { coordsDescending[id] = coordsAscending[id].slice().reverse(); coordsDescendingSymbol[id] = sourceCache.getVisibleCoordinates(true).reverse(); if (isTerrainEnabled) { - coordsAscendingInv[id] = {}; - for (let c=0; c ({ @@ -27,7 +28,8 @@ const circleUniforms = (context: Context, locations: UniformLocations): CircleUn 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const circleUniformValues = ( @@ -60,7 +62,8 @@ const circleUniformValues = ( 'u_device_pixel_ratio': devicePixelRatio, 'u_extrude_scale': extrudeScale, 'u_coords': 0, - 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_coords_index': 1, + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/fill_extrusion_program.ts b/src/render/program/fill_extrusion_program.ts index 06100cf7923..5d9835cd901 100644 --- a/src/render/program/fill_extrusion_program.ts +++ b/src/render/program/fill_extrusion_program.ts @@ -24,7 +24,7 @@ export type FillExtrusionUniformsType = { 'u_lightcolor': Uniform3f; 'u_vertical_gradient': Uniform1f; 'u_opacity': Uniform1f; - 'u_ele_exaggeration': Uniform1f; + 'u_terrain_exaggeration': Uniform1f; }; export type FillExtrusionPatternUniformsType = { @@ -42,7 +42,7 @@ export type FillExtrusionPatternUniformsType = { 'u_scale': Uniform3f; 'u_fade': Uniform1f; 'u_opacity': Uniform1f; - 'u_ele_exaggeration': Uniform1f; + 'u_terrain_exaggeration': Uniform1f; }; const fillExtrusionUniforms = (context: Context, locations: UniformLocations): FillExtrusionUniformsType => ({ @@ -52,7 +52,7 @@ const fillExtrusionUniforms = (context: Context, locations: UniformLocations): F 'u_lightcolor': new Uniform3f(context, locations.u_lightcolor), 'u_vertical_gradient': new Uniform1f(context, locations.u_vertical_gradient), 'u_opacity': new Uniform1f(context, locations.u_opacity), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): FillExtrusionPatternUniformsType => ({ @@ -70,7 +70,7 @@ const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocati 'u_scale': new Uniform3f(context, locations.u_scale), 'u_fade': new Uniform1f(context, locations.u_fade), 'u_opacity': new Uniform1f(context, locations.u_opacity), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const fillExtrusionUniformValues = ( @@ -97,7 +97,7 @@ const fillExtrusionUniformValues = ( 'u_lightcolor': [lightColor.r, lightColor.g, lightColor.b], 'u_vertical_gradient': +shouldUseVerticalGradient, 'u_opacity': opacity, - 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/hillshade_program.ts b/src/render/program/hillshade_program.ts index df516fa3de2..34c9d97ffd6 100644 --- a/src/render/program/hillshade_program.ts +++ b/src/render/program/hillshade_program.ts @@ -59,7 +59,7 @@ const hillshadeUniformValues = ( painter: Painter, tile: Tile, layer: HillshadeStyleLayer, - terrainTile: Tile + coord: OverscaledTileID ): UniformValues => { const shadow = layer.paint.get('hillshade-shadow-color'); const highlight = layer.paint.get('hillshade-highlight-color'); @@ -72,7 +72,7 @@ const hillshadeUniformValues = ( } const align = !painter.options.moving; return { - 'u_matrix': terrainTile ? terrainTile.tileID.posMatrix : painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), + 'u_matrix': coord ? coord.posMatrix : painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), 'u_image': 0, 'u_latrange': getTileLatRange(painter, tile.tileID), 'u_light': [layer.paint.get('hillshade-exaggeration'), azimuthal], diff --git a/src/render/program/line_program.ts b/src/render/program/line_program.ts index 95d5adf83c6..b53bdc09e15 100644 --- a/src/render/program/line_program.ts +++ b/src/render/program/line_program.ts @@ -10,6 +10,7 @@ import type {CrossFaded} from '../../style/properties'; import type LineStyleLayer from '../../style/style_layer/line_style_layer'; import type Painter from '../painter'; import type {CrossfadeParameters} from '../../style/evaluation_parameters'; +import { OverscaledTileID } from '../../source/tile_id'; export type LineUniformsType = { 'u_matrix': UniformMatrix4f; @@ -97,12 +98,12 @@ const lineUniformValues = ( painter: Painter, tile: Tile, layer: LineStyleLayer, - terrainTile: Tile + coord: OverscaledTileID ): UniformValues => { const transform = painter.transform; return { - 'u_matrix': calculateMatrix(painter, tile, layer, terrainTile), + 'u_matrix': calculateMatrix(painter, tile, layer, coord), 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), 'u_device_pixel_ratio': devicePixelRatio, 'u_units_to_pixels': [ @@ -117,9 +118,9 @@ const lineGradientUniformValues = ( tile: Tile, layer: LineStyleLayer, imageHeight: number, - terrainTile: Tile + coord: OverscaledTileID ): UniformValues => { - return extend(lineUniformValues(painter, tile, layer, terrainTile), { + return extend(lineUniformValues(painter, tile, layer, coord), { 'u_image': 0, 'u_image_height': imageHeight, }); @@ -130,12 +131,12 @@ const linePatternUniformValues = ( tile: Tile, layer: LineStyleLayer, crossfade: CrossfadeParameters, - terrainTile: Tile + coord: OverscaledTileID ): UniformValues => { const transform = painter.transform; const tileZoomRatio = calculateTileRatio(tile, transform); return { - 'u_matrix': calculateMatrix(painter, tile, layer, terrainTile), + 'u_matrix': calculateMatrix(painter, tile, layer, coord), 'u_texsize': tile.imageAtlasTexture.size, // camera zoom ratio 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), @@ -156,7 +157,7 @@ const lineSDFUniformValues = ( layer: LineStyleLayer, dasharray: CrossFaded>, crossfade: CrossfadeParameters, - terrainTile: Tile + coord: OverscaledTileID ): UniformValues => { const transform = painter.transform; const lineAtlas = painter.lineAtlas; @@ -170,7 +171,7 @@ const lineSDFUniformValues = ( const widthA = posA.width * crossfade.fromScale; const widthB = posB.width * crossfade.toScale; - return extend(lineUniformValues(painter, tile, layer, terrainTile), { + return extend(lineUniformValues(painter, tile, layer, coord), { 'u_patternscale_a': [tileRatio / widthA, -posA.height / 2], 'u_patternscale_b': [tileRatio / widthB, -posB.height / 2], 'u_sdfgamma': lineAtlas.width / (Math.min(widthA, widthB) * 256 * devicePixelRatio) / 2, @@ -185,9 +186,9 @@ function calculateTileRatio(tile: Tile, transform: Transform) { return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom); } -function calculateMatrix(painter, tile, layer, terrainTile) { +function calculateMatrix(painter, tile, layer, coord) { return painter.translatePosMatrix( - terrainTile ? terrainTile.tileID.posMatrix : tile.tileID.posMatrix, + coord ? coord.posMatrix : tile.tileID.posMatrix, tile, layer.paint.get('line-translate'), layer.paint.get('line-translate-anchor') diff --git a/src/render/program/symbol_program.ts b/src/render/program/symbol_program.ts index a41cca1969f..66bce1616d8 100644 --- a/src/render/program/symbol_program.ts +++ b/src/render/program/symbol_program.ts @@ -24,7 +24,8 @@ export type SymbolIconUniformsType = { 'u_texsize': Uniform2f; 'u_texture': Uniform1i; 'u_coords': Uniform1i; - 'u_ele_exaggeration': Uniform1f; + 'u_coords_index': Uniform1i; + 'u_terrain_exaggeration': Uniform1f; }; export type SymbolSDFUniformsType = { @@ -48,7 +49,8 @@ export type SymbolSDFUniformsType = { 'u_device_pixel_ratio': Uniform1f; 'u_is_halo': Uniform1i; 'u_coords': Uniform1i; - 'u_ele_exaggeration': Uniform1f; + 'u_coords_index': Uniform1i; + 'u_terrain_exaggeration': Uniform1f; }; export type symbolTextAndIconUniformsType = { @@ -74,7 +76,8 @@ export type symbolTextAndIconUniformsType = { 'u_device_pixel_ratio': Uniform1f; 'u_is_halo': Uniform1i; 'u_coords': Uniform1i; - 'u_ele_exaggeration': Uniform1f; + 'u_coords_index': Uniform1i; + 'u_terrain_exaggeration': Uniform1f; }; const symbolIconUniforms = (context: Context, locations: UniformLocations): SymbolIconUniformsType => ({ @@ -95,7 +98,8 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_texture': new Uniform1i(context, locations.u_texture), 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const symbolSDFUniforms = (context: Context, locations: UniformLocations): SymbolSDFUniformsType => ({ @@ -119,7 +123,8 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new Uniform1i(context, locations.u_is_halo), 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations): symbolTextAndIconUniformsType => ({ @@ -145,7 +150,8 @@ const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new Uniform1i(context, locations.u_is_halo), 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const symbolIconUniformValues = ( @@ -183,7 +189,8 @@ const symbolIconUniformValues = ( 'u_texsize': texSize, 'u_texture': 0, 'u_coords': 2, - 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_coords_index': 3, + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/terrain_program.ts b/src/render/program/terrain_program.ts index 45e3b98d30e..12bdeb4ed1f 100644 --- a/src/render/program/terrain_program.ts +++ b/src/render/program/terrain_program.ts @@ -1,50 +1,89 @@ import { Uniform1i, Uniform1f, + Uniform4f, UniformMatrix4f } from '../uniform_binding'; import type Context from '../../gl/context'; import type Painter from '../painter'; import type {UniformValues, UniformLocations} from '../../render/uniform_binding'; import {mat4} from 'gl-matrix'; +import { GlyphOffsetArray } from '../../data/array_types'; export type TerrainUniformsType = { 'u_matrix': UniformMatrix4f; 'u_texture': Uniform1i; - 'u_ele_exaggeration': Uniform1f; + 'u_terrain': Uniform1i; + 'u_terrain_matrix': UniformMatrix4f; + 'u_terrain_unpack': Uniform4f; + 'u_terrain_offset': Uniform1f; + 'u_terrain_exaggeration': Uniform1f; }; export type TerrainCoordsUniformsType = { 'u_matrix': UniformMatrix4f; 'u_texture': Uniform1i; + 'u_terrain': Uniform1i; + 'u_terrain_matrix': UniformMatrix4f; + 'u_terrain_unpack': Uniform4f; + 'u_terrain_offset': Uniform1f; 'u_terrain_coords_id': Uniform1f; - 'u_ele_exaggeration': Uniform1f; + 'u_terrain_exaggeration': Uniform1f; }; const terrainUniforms = (context: Context, locations: UniformLocations): TerrainUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_texture': new Uniform1i(context, locations.u_texture), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_terrain': new Uniform1i(context, locations.u_terrain), + 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), + 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), + 'u_terrain_offset': new Uniform1f(context, locations.u_terrain_offset), + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); const terrainCoordsUniforms = (context: Context, locations: UniformLocations): TerrainCoordsUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_texture': new Uniform1i(context, locations.u_texture), + 'u_terrain': new Uniform1i(context, locations.u_terrain), + 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), + 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), + 'u_terrain_offset': new Uniform1f(context, locations.u_terrain_offset), 'u_terrain_coords_id': new Uniform1f(context, locations.u_terrain_coords_id), - 'u_ele_exaggeration': new Uniform1f(context, locations.u_ele_exaggeration) + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); -const terrainUniformValues = (painter: Painter, matrix: mat4): UniformValues => ({ +const terrainUniformValues = ( + painter: Painter, + matrix: mat4, + terrainMatrix: mat4, + unpackVector: Array, + offset: number +): UniformValues => ({ 'u_matrix': matrix, 'u_texture': 0, - 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_terrain': 1, + 'u_terrain_matrix': terrainMatrix, + 'u_terrain_unpack': unpackVector, + 'u_terrain_offset': offset, + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }); -const terrainCoordsUniformValues = (painter: Painter, matrix: mat4, coordsId: number): UniformValues => ({ +const terrainCoordsUniformValues = ( + painter: Painter, + matrix: mat4, + terrainMatrix: mat4, + coordsId: number, + unpackVector: Array, + offset: number +): UniformValues => ({ 'u_matrix': matrix, 'u_texture': 0, + 'u_terrain': 1, + 'u_terrain_matrix': terrainMatrix, + 'u_terrain_unpack': unpackVector, + 'u_terrain_offset': offset, 'u_terrain_coords_id': coordsId / 255, - 'u_ele_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }); export {terrainUniforms, terrainCoordsUniforms, terrainUniformValues, terrainCoordsUniformValues}; diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 32fdd174788..e0a8c6c197c 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -83,12 +83,12 @@ vec2 unpackCoord(vec4 rgba) { float b = floor(rgba.b * 255.0); float x = r + hasBit(b, 4) * 256.0 + hasBit(b, 5) * 512.0 + hasBit(b, 6) * 1024.0 + hasBit(b, 7) * 2048.0; float y = g + hasBit(b, 0) * 256.0 + hasBit(b, 1) * 512.0 + hasBit(b, 2) * 1024.0 + hasBit(b, 3) * 2048.0; - return vec2(x, y) * 2.0; // multiply by 2 is necesarry because the coords-texture has only 4096x4096 pixels. + return vec2(x, y) * 8.0; // multiply by 8 is necesarry because the coords-texture has only 1024x1024 pixels. } // calculate the visibility of a coordinate in terrain and return an opacity value. // if a coordinate is behind the terrain reduce its opacity -float calculate_visibility(sampler2D u_coords, vec4 pos, vec2 tilePos) { +float calculate_visibility(sampler2D u_coords, sampler2D u_coords_index, vec4 pos, vec2 tilePos) { #ifdef TERRAIN3D vec3 frag = pos.xyz / pos.w; vec2 coord = unpackCoord(texture2D(u_coords, frag.xy * 0.5 + 0.5)); diff --git a/src/shaders/circle.vertex.glsl b/src/shaders/circle.vertex.glsl index a2b31989ce4..836505f28b2 100644 --- a/src/shaders/circle.vertex.glsl +++ b/src/shaders/circle.vertex.glsl @@ -5,7 +5,8 @@ uniform vec2 u_extrude_scale; uniform lowp float u_device_pixel_ratio; uniform highp float u_camera_to_center_distance; uniform highp sampler2D u_coords; -uniform lowp float u_ele_exaggeration; +uniform highp sampler2D u_coords_index; +uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; attribute float a_ele; @@ -36,7 +37,7 @@ void main(void) { // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data vec2 circle_center = floor(a_pos * 0.5); - v_visibility = calculate_visibility(u_coords, u_matrix * vec4(circle_center, a_ele * u_ele_exaggeration, 1.0), circle_center); + v_visibility = calculate_visibility(u_coords, u_coords_index, u_matrix * vec4(circle_center, a_ele * u_terrain_exaggeration, 1.0), circle_center); if (u_pitch_with_map) { vec2 corner_position = circle_center; @@ -50,9 +51,9 @@ void main(void) { corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance); } - gl_Position = u_matrix * vec4(corner_position, a_ele * u_ele_exaggeration, 1); + gl_Position = u_matrix * vec4(corner_position, a_ele * u_terrain_exaggeration, 1); } else { - gl_Position = u_matrix * vec4(circle_center, a_ele * u_ele_exaggeration, 1); + gl_Position = u_matrix * vec4(circle_center, a_ele * u_terrain_exaggeration, 1); if (u_scale_with_map) { gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance; diff --git a/src/shaders/fill_extrusion.vertex.glsl b/src/shaders/fill_extrusion.vertex.glsl index b4ce53ebafa..bfe18025f2e 100644 --- a/src/shaders/fill_extrusion.vertex.glsl +++ b/src/shaders/fill_extrusion.vertex.glsl @@ -4,7 +4,7 @@ uniform lowp vec3 u_lightpos; uniform lowp float u_lightintensity; uniform float u_vertical_gradient; uniform lowp float u_opacity; -uniform lowp float u_ele_exaggeration; +uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; attribute vec4 a_normal_ed; @@ -24,8 +24,8 @@ void main() { vec3 normal = a_normal_ed.xyz; - base = max(0.0, a_ele * u_ele_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation - height = max(0.0, a_ele * u_ele_exaggeration + height); + base = max(0.0, a_ele * u_terrain_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + height = max(0.0, a_ele * u_terrain_exaggeration + height); float t = mod(normal.x, 2.0); diff --git a/src/shaders/fill_extrusion_pattern.vertex.glsl b/src/shaders/fill_extrusion_pattern.vertex.glsl index 9f8d88186c6..f6e667e1852 100644 --- a/src/shaders/fill_extrusion_pattern.vertex.glsl +++ b/src/shaders/fill_extrusion_pattern.vertex.glsl @@ -9,7 +9,7 @@ uniform lowp float u_opacity; uniform vec3 u_lightcolor; uniform lowp vec3 u_lightpos; uniform lowp float u_lightintensity; -uniform lowp float u_ele_exaggeration; +uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; attribute vec4 a_normal_ed; @@ -49,8 +49,8 @@ void main() { vec2 display_size_a = (pattern_br_a - pattern_tl_a) / pixel_ratio_from; vec2 display_size_b = (pattern_br_b - pattern_tl_b) / pixel_ratio_to; - base = max(0.0, a_ele * u_ele_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation - height = max(0.0, a_ele * u_ele_exaggeration + height); + base = max(0.0, a_ele * u_terrain_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + height = max(0.0, a_ele * u_terrain_exaggeration + height); float t = mod(normal.x, 2.0); float z = t > 0.0 ? height : base; diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index f51ea9c6cc4..734b35fc954 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -23,7 +23,8 @@ uniform bool u_is_text; uniform bool u_pitch_with_map; uniform vec2 u_texsize; uniform highp sampler2D u_coords; -uniform lowp float u_ele_exaggeration; +uniform highp sampler2D u_coords_index; +uniform lowp float u_terrain_exaggeration; varying vec2 v_tex; varying float v_fade_opacity; @@ -54,7 +55,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_terrain_exaggeration, 1); highp float camera_to_anchor_distance = projectedPoint.w; // See comments in symbol_sdf.vertex highp float distance_ratio = u_pitch_with_map ? @@ -72,7 +73,7 @@ void main() { highp float symbol_rotation = 0.0; if (u_rotate_symbol) { // See comments in symbol_sdf.vertex - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_ele_exaggeration, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_terrain_exaggeration, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -84,13 +85,13 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_ele_exaggeration, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_terrain_exaggeration, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), z, 1.0); v_tex = a_tex / u_texsize; vec2 fade_opacity = unpack_opacity(a_fade_opacity); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; - float visibility = calculate_visibility(u_coords, projectedPoint, a_pos); + float visibility = calculate_visibility(u_coords, u_coords_index, projectedPoint, a_pos); v_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); } diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index d22ce22b015..d7bcdded305 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -30,7 +30,8 @@ uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; uniform highp sampler2D u_coords; -uniform lowp float u_ele_exaggeration; +uniform highp sampler2D u_coords_index; +uniform lowp float u_terrain_exaggeration; varying vec2 v_data0; varying vec3 v_data1; @@ -68,7 +69,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_terrain_exaggeration, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -93,7 +94,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_ele_exaggeration, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_terrain_exaggeration, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -105,13 +106,13 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_ele_exaggeration, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_terrain_exaggeration, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), z, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); - float visibility = calculate_visibility(u_coords, projectedPoint, a_pos); + float visibility = calculate_visibility(u_coords, u_coords_index, projectedPoint, a_pos); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index b0997155a53..83d28fd0b73 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -30,7 +30,8 @@ uniform float u_fade_change; uniform vec2 u_texsize; uniform vec2 u_texsize_icon; uniform highp sampler2D u_coords; -uniform lowp float u_ele_exaggeration; +uniform highp sampler2D u_coords_index; +uniform lowp float u_terrain_exaggeration; varying vec4 v_data0; varying vec4 v_data1; @@ -68,7 +69,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_terrain_exaggeration, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -93,7 +94,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_ele_exaggeration, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_terrain_exaggeration, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -105,13 +106,13 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_ele_exaggeration, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_terrain_exaggeration, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), z, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); - float visibility = calculate_visibility(u_coords, projectedPoint, a_pos); + float visibility = calculate_visibility(u_coords, u_coords_index, projectedPoint, a_pos); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); diff --git a/src/shaders/terrain.fragment.glsl b/src/shaders/terrain.fragment.glsl index 8ae6592e782..2f5223260d3 100644 --- a/src/shaders/terrain.fragment.glsl +++ b/src/shaders/terrain.fragment.glsl @@ -1,8 +1,10 @@ precision mediump float; uniform sampler2D u_texture; +uniform sampler2D u_terrain; varying vec2 v_texture_pos; +varying vec2 v_terrain_pos; void main() { - gl_FragColor = texture2D(u_texture, v_texture_pos); + gl_FragColor = texture2D(u_texture, v_texture_pos); } diff --git a/src/shaders/terrain.vertex.glsl b/src/shaders/terrain.vertex.glsl index ac52e6790e4..0bf5032c211 100644 --- a/src/shaders/terrain.vertex.glsl +++ b/src/shaders/terrain.vertex.glsl @@ -1,12 +1,23 @@ attribute vec2 a_pos; -attribute float a_ele; uniform mat4 u_matrix; -uniform lowp float u_ele_exaggeration; +uniform sampler2D u_terrain; +uniform mat4 u_terrain_matrix; +uniform vec4 u_terrain_unpack; +uniform float u_terrain_exaggeration; +uniform float u_terrain_offset; varying vec2 v_texture_pos; +varying vec2 v_terrain_pos; + +float getElevation(vec2 coord) { + vec4 rgb = (texture2D(u_terrain, coord) * 255.0) * u_terrain_unpack; + float ele = rgb.r + rgb.g + rgb.b - u_terrain_unpack.a; + return (ele + u_terrain_offset) * u_terrain_exaggeration; +} void main() { - v_texture_pos = a_pos / 8192.0; - gl_Position = u_matrix * vec4(a_pos, a_ele * u_ele_exaggeration, 1.0); + v_texture_pos = a_pos / 8192.0; + v_terrain_pos = (u_terrain_matrix * vec4(a_pos, 0.0, 1.0)).xy * 0.5 + 0.5; + gl_Position = u_matrix * vec4(a_pos, getElevation(v_terrain_pos), 1.0); } diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index d1c7cf24191..87ea6d518e7 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -57,6 +57,7 @@ class SourceCache extends Evented { _coveredTiles: {[_: string]: boolean}; transform: Transform; used: boolean; + usedForTerrain: boolean; _state: SourceFeatureState; _loadedParentTiles: {[_: string]: Tile | undefined | null}; @@ -488,7 +489,7 @@ class SourceCache extends Evented { this._coveredTiles = {}; let idealTileIDs; - if (!this.used) { + if (!this.used && !this.usedForTerrain) { idealTileIDs = []; } else if (this._source.tileID) { idealTileIDs = transform.getVisibleUnwrappedCoordinates(this._source.tileID) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 82e28cdde75..bc2d3370c7f 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -11,6 +11,7 @@ import {RGBAImage} from '../util/image'; import {PosArray, TriangleIndexArray} from '../data/array_types'; import posAttributes from '../data/pos_attributes'; import SegmentVector from '../data/segment'; +import DEMData from '../data/dem_data'; import type Transform from '../geo/transform'; import type SourceCache from '../source/source_cache'; import type Context from '../gl/context'; @@ -27,16 +28,22 @@ class TerrainSourceCache extends Evented { _coordsFramebuffer: any; _fbo: any; _mesh: any; - _coords: Texture; + _coordsIndex: Array; + _coordsTexture: Texture; + _coordsTextureSize: number; + _coordsIndexTexture: Texture; + _terrainTileCache: {[_: string]: string}; + _sourceTileIDs: {[_: string]: OverscaledTileID}; + _emptyDem: any; + _emptyDemTexture: Texture; + _emptyDemMatrix: mat4; minzoom: number; maxzoom: number; tileSize: number; meshSize: number; exaggeration: number; elevationOffset: number; - coordsIndex: Array; qualityFactor: number; - terrainTileCache: {[_: string]: string}; /** * @param {Style} style @@ -50,20 +57,69 @@ class TerrainSourceCache extends Evented { this._loadQueue = []; this._coordsFramebuffer = null; this._fbo = null; - this._coords = null; this._mesh = null; - this.minzoom = 5; - this.maxzoom = 14; + this._terrainTileCache = {}; + this._sourceTileIDs = {}; + this._coordsIndex = []; + this._coordsTextureSize = 1024; + this.minzoom = 0; + this.maxzoom = 22; this.tileSize = 512; this.meshSize = 128; this.exaggeration = 1.0; this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. - this.coordsIndex = []; this.qualityFactor = 2; - this.terrainTileCache = {}; + + // create empty DEM Obejcts + const context = style.map.painter.context; + this._emptyDem = new DEMData("0", new RGBAImage({width: 4, height: 4}), "mapbox"); + this._emptyDemTexture = new Texture(context, this._emptyDem.getPixels(), context.gl.RGBA, {premultiply: false}); + this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + this._emptyDemMatrix = mat4.create(); + mat4.ortho(this._emptyDemMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + + // create empty coordsIndexTexture + const image = new RGBAImage({width: 256, height: 1}, new Uint8Array(256 * 4)); + const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); + this._coordsIndexTexture = texture; + + // rerender corresponding tiles on source-tile updates style.on("data", e => { - let tile = e.coord && this.getTerrainTile(e.coord, this._style.map.transform.zoom); - if (tile) tile.rerender = true; + if (e.dataType == "source" && e.tile && this.isEnabled()) { + const transform = style.map.transform; + if (e.sourceId == this._sourceCache.id) { + for (const key in this._tiles) { + const tile = this._tiles[key]; + if (tile.tileID.equals(e.coord) || tile.tileID.isChildOf(e.coord)) { + tile.timeLoaded = Date.now(); + tile.rerender = true; + } + } + const tile = this.getTileByID(e.coord.key); + transform.updateElevation(); + // delete elevationdata from coresponding tile, so that they can be reloaded on next rendering + // FIXME-3D! when symbol-occlusion is moved to GPU, this lines can be removed + for (let s in style.sourceCaches) { + for (let key in style.sourceCaches[s]._tiles) + style.sourceCaches[s]._tiles[key].elevation = {}; + } + } else if (e.coord) { + // FIXME! mark only necessary tiles to rerender + for (let key in this._tiles) this.getTileByID(key).rerender = true; + // let dz = e.coord.canonical.z - transform.tileZoom; + // let x = e.coord.canonical.x, y = e.coord.canonical.y, wrap = e.coord.wrap, z = transform.tileZoom; + // const sourceTile = this.getSourceTile(dz > 0 ? new OverscaledTileID(z, wrap, z, x >> dz, y >> dz) : e.coord); + // const tile = sourceTile && this.getTileByID(sourceTile.tileID.key); + // if (tile) { + // tile.rerender = true; + // } else if (sourceTile) { + // for (let key in this._tiles) { + // let _tile = this.getTileByID(key); + // if (_tile.tileID.isChildOf(sourceTile.tileID)) _tile.rerender = true; + // } + // } + } + } }); } @@ -73,24 +129,22 @@ class TerrainSourceCache extends Evented { * @param options Allowed options are exaggeration, elevationOffset & meshSize */ enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}): void { + sourceCache.usedForTerrain = true; + sourceCache._source.roundZoom = false; this._sourceCache = sourceCache; ['exaggeration', 'elevationOffset', 'meshSize'].forEach(key => { if (options && options[key] != undefined) this[key] = options[key] }); - this._source = sourceCache._source as RasterDEMTileSource; - this.minzoom = this._source.minzoom; - this.maxzoom = this._source.maxzoom; - if (! this._source.loaded()) this._source.once("data", () => { - this._loadQueue.forEach(tile => this._source.loadTile(tile, () => this._tileLoaded(tile))); - this._loadQueue = []; - }); } /** * remove the the 3d terrain from map. */ disable(): void { - this._sourceCache = this._source = null; + if (!this._sourceCache) return; + this._sourceCache.usedForTerrain = false; + this._sourceCache._source.roundZoom = true; + this._sourceCache = null; for (const key in this._tiles) { let tile = this._tiles[key]; tile.textures.forEach(t => t.destroy()); @@ -116,25 +170,45 @@ class TerrainSourceCache extends Evented { * Load Terrain Tiles, removes outdated Tiles and update camera elevation. */ update(transform: Transform): void { - if (! this.isEnabled()) return; + if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; + this._sourceCache.update(transform); transform.updateElevation(); - let idealTileIDs = this.getRenderableTileIds(transform); let outdated = {}; - Object.keys(this._tiles).forEach(key => outdated[key] = true); - for (const tileID of idealTileIDs) { + for (let key in this._tiles) outdated[key] = true; + // create tiles for current view + for (const tileID of this.getRenderableTileIds(transform)) { delete(outdated[tileID.key]); if (this._tiles[tileID.key]) continue; - let tile = this._tiles[tileID.key] = this._createEmptyTile(tileID); - if (this._source && this._source.loaded()) { - this._source.loadTile(tile, () => this._tileLoaded(tile)); + // find parent source tile + const maxzoom = this._sourceCache._source.maxzoom; + const sourceTileID = this._sourceTileIDs[tileID.key] = tileID.overscaledZ > maxzoom ? tileID.scaledTo(maxzoom) : tileID; + // create pos matrix in relation to source tile + tileID.posMatrix = mat4.create(); + const demMatrix = mat4.create(); + if (tileID.canonical.z == sourceTileID.canonical.z) { + mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + mat4.ortho(demMatrix, 0, EXTENT, 0, EXTENT, 0, 1); } else { - this._loadQueue.push(tile); // remember for loading later + const dz = tileID.canonical.z - sourceTileID.canonical.z; + const dx = tileID.canonical.x - (sourceTileID.canonical.x << dz); + const dy = tileID.canonical.y - (sourceTileID.canonical.y << dz); + const size = EXTENT >> dz + mat4.ortho(tileID.posMatrix, 0, size, 0, size, 0, 1); + mat4.translate(tileID.posMatrix, tileID.posMatrix, [-dx * size, -dy * size, 0]); + mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); + mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); } + // create new tile + this._tiles[tileID.key] = new Tile(tileID, this.tileSize); + this._tiles[tileID.key].demMatrix = demMatrix; } + // free GPU memory from outdated tiles for (const key in outdated) { let tile = this._tiles[key]; - tile.textures.forEach(t => t.destroy()); + tile.textures.forEach(t => this._style.map.painter.saveTileTexture(t)); + if (tile.demTexture) this._style.map.painter.saveTileTexture(tile.demTexture); tile.textures = []; + tile.demTexture = null; } } @@ -146,9 +220,9 @@ class TerrainSourceCache extends Evented { getRenderableTileIds(transform: Transform): Array { return transform.coveringTiles({ tileSize: this.tileSize, - minzoom: this._source ? this._source.minzoom : this.minzoom, + minzoom: this.minzoom, maxzoom: this.maxzoom, - reparseOverscaled: true + reparseOverscaled: false }); } @@ -185,12 +259,45 @@ class TerrainSourceCache extends Evented { * @returns {Tile} */ getTerrainTile(tileID: OverscaledTileID, zoom: number): Tile { - if (this.terrainTileCache[tileID.key]) this.getTileByID(this.terrainTileCache[tileID.key]); - const z = Math.floor(zoom); + const z = Math.floor(zoom), cacheKey = z + ":" + tileID.key; + if (this._terrainTileCache[cacheKey]) return this.getTileByID(this._terrainTileCache[cacheKey]); const canonical = tileID.canonical.z > this.maxzoom ? tileID.scaledTo(this.maxzoom).canonical : tileID.canonical; const id = new OverscaledTileID(canonical.z > z ? canonical.z : z, tileID.wrap, canonical.z, canonical.x, canonical.y); - this.terrainTileCache[tileID.key] = id.scaledTo(z).key; - return this.getTileByID(this.terrainTileCache[tileID.key]); + this._terrainTileCache[cacheKey] = id.scaledTo(z).key; + return this.getTileByID(this._terrainTileCache[cacheKey]); + } + + /** + * searches for the corresponding terrain-tiles at a given zoomlevel + * @param {OverscaledTileID} tileID + * @param {number} zoom + * @returns {Tile} + */ + getTerrainCoords(tileID: OverscaledTileID): {[_: string]: OverscaledTileID} { + const coords = {}; + for (let key in this._tiles) { + const _tileID = this._tiles[key].tileID; + // handle reparseOverscaled tilesources + if (_tileID.equals(tileID) + || _tileID.canonical.isChildOf(tileID.canonical) + || tileID.canonical.isChildOf(_tileID.canonical) + ) { + const coord = tileID.clone(); + coord.posMatrix = mat4.clone(_tileID.posMatrix); + coords[key] = coord; + } + } + return coords; + } + + /** + * find the sourcetile + * @param {OverscaledTileID} tileID + * @returns {Tile} + */ + getSourceTile(tileID: OverscaledTileID): Tile { + const coord = this._sourceTileIDs[tileID.key]; + return coord && this._sourceCache.getTileByID(coord.key); } /** @@ -198,7 +305,7 @@ class TerrainSourceCache extends Evented { * FIXME-3D: * - make linear interpolation * - handle negative coordinates - * - interploate below ZL 14 + * - interploate below ZL this.maxzoom * @param {OverscaledTileID} tileID * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT @@ -207,11 +314,12 @@ class TerrainSourceCache extends Evented { */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { if (!this.isEnabled()) return 0; - const tile = this.getTileByID(tileID.key); + const maxzoom = this._sourceCache._source.maxzoom, shouldScale = tileID.overscaledZ > maxzoom; + const tile = this._sourceCache.getTileByID(shouldScale ? tileID.scaledTo(maxzoom).key : tileID.key); let elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; - if (elevation > 8191) elevation = 0; // REMOVE: this hack is for MTK data, because of false nodata values + if (elevation > 8191) elevation = 0; // REMOVEME: this hack is for MTK data, because of false nodata values return (elevation + this.elevationOffset); } @@ -281,6 +389,27 @@ class TerrainSourceCache extends Evented { }; } + /** + * returns a DEM Object for a tile. Unless the tile has data, return an flat dem object + * @param {OverscaledTileID} tileID + */ + getDem(tileID: OverscaledTileID): any { + const tile = this.getTileByID(tileID.key); + const sourceTile = this.getSourceTile(tileID); + if (sourceTile && sourceTile.dem && !sourceTile.demTexture) { + let context = this._style.map.painter.context; + sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.dim); + if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); + else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); + sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + } + return { + unpackVector: (sourceTile && sourceTile.dem || this._emptyDem).getUnpackVector(), + texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, + matrix: tile && tile.demMatrix || this._emptyDemMatrix, + }; + } + /** * create coords texture, needed to grab coordinates from canvas * encode coords coordinate into 4 bytes: @@ -293,53 +422,40 @@ class TerrainSourceCache extends Evented { * @returns {Texture} */ getCoordsTexture(context: Context): Texture { - if (this._coords) return this._coords; - const data = new Uint8Array(4096 * 4096 * 4); - for (let y=0, i=0; y<4096; y++) for (let x=0; x<4096; x++, i+=4) { + if (this._coordsTexture) return this._coordsTexture; + const data = new Uint8Array(this._coordsTextureSize * this._coordsTextureSize * 4); + for (let y=0, i=0; y> 8) << 4) | (y >> 8); data[i + 3] = 0; } - let image = new RGBAImage({width: 4096, height: 4096}, new Uint8Array(data.buffer)); + let image = new RGBAImage({width: this._coordsTextureSize, height: this._coordsTextureSize}, new Uint8Array(data.buffer)); let texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - return this._coords = texture; + return this._coordsTexture = texture; } /** - * after a tile is loaded: - * - recreate terrain-mesh webgl segments - * - recalculate elevation of all symbols/circles/buildings of all tiles - * @param {Tile} tile + * create texture, with informations about the coords-index + * e.g. for each coords tile, size & quadrant + * @param {Context} context + * @returns {Texture} */ - _tileLoaded(tile: Tile): void { - tile.timeLoaded = Date.now(); - this._style.map.transform.updateElevation(); - if (tile.state == "loaded") { - if (this._sourceCache) this._sourceCache._backfillDEM.call(this, tile); - // rerender tile incl. neighboring tiles - tile.elevationVertexBuffer = null; - Object.keys(tile.neighboringTiles) - .map(id => this.getTileByID(id)) - .forEach(tile => { if (tile) tile.elevationVertexBuffer = null }); - } - // delete elevationdata from coresponding tile, so that they can be reloaded on next rendering - // FIXME-3D! only delete data from necessary tiles - for (let s in this._style.sourceCaches) { - for (let key in this._style.sourceCaches[s]._tiles) { - this._style.sourceCaches[s]._tiles[key].elevation = {}; - } + updateCoordsIndexTexture(context: Context) { + const data = new Uint8Array(256 * 4); + for (let i=0; i> dz << dz; + data[i + 1] = tile.tileID.canonical.y - tile.tileID.canonical.y >> dz << dz; + data[i + 2] = tile.tileID.canonical.z; + data[i + 3] = dz; } - } - - // FIXME-3D! copy terrain-data from parent tile if available - _createEmptyTile(tileID: OverscaledTileID): Tile { - tileID.posMatrix = mat4.create(); - mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); - let tile = new Tile(tileID, this.tileSize * tileID.overscaleFactor()); - tile.textures = []; - return tile; + const image = new RGBAImage({width: 256, height: 1}, data); + this._coordsIndexTexture.update(image, {premultiply: false}); + this._coordsIndexTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); } } diff --git a/src/source/tile.ts b/src/source/tile.ts index 9b219bbe50f..f6ba9b04d1e 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -75,6 +75,7 @@ class Tile { neighboringTiles: any; dem: DEMData | undefined | null; + demMatrix: mat4; aborted: boolean | undefined | null; needsHillshadePrepare: boolean | undefined | null; request: Cancelable | undefined | null; @@ -92,8 +93,8 @@ class Tile { hasRTLText: boolean; dependencies: any; elevation: any; + elevationMax: number; textures: Array; - elevationVertexBuffer: VertexBuffer; /** * @param {OverscaledTileID} tileID @@ -112,7 +113,9 @@ class Tile { this.hasRTLText = false; this.dependencies = {}; this.elevation = {}; + this.elevationMax = 0; this.rerender = false; + this.textures = []; // Counts the number of times a response was already expired when // received. We're using this to add a delay when making a new request diff --git a/src/source/tile_id.ts b/src/source/tile_id.ts index e3ec2c60f90..d648e8de140 100644 --- a/src/source/tile_id.ts +++ b/src/source/tile_id.ts @@ -41,6 +41,11 @@ export class CanonicalTileID { .replace('{bbox-epsg-3857}', bbox); } + isChildOf(parent: CanonicalTileID) { + const dz = this.z - parent.z; + return dz > 0 && parent.x === (this.x >> dz) && parent.y === (this.y >> dz); + } + getTilePoint(coord: MercatorCoordinate) { const tilesAtZoom = Math.pow(2, this.z); return new Point( @@ -80,6 +85,10 @@ export class OverscaledTileID { this.key = calculateKey(wrap, overscaledZ, z, x, y); } + clone() { + return new OverscaledTileID(this.overscaledZ, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y); + } + equals(id: OverscaledTileID) { return this.overscaledZ === id.overscaledZ && this.wrap === id.wrap && this.canonical.equals(id.canonical); } From 7ecbc8abdb888313dbc966facde311fc08e9f914 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 28 Sep 2021 11:31:47 +0200 Subject: [PATCH 027/138] fix calculate_visibility in overzoomed terrain-tiles --- src/geo/transform.ts | 2 -- src/shaders/_prelude.vertex.glsl | 12 ++++++++++-- src/source/raster_dem_tile_source.ts | 2 ++ src/source/terrain_source_cache.ts | 14 +++++++------- src/source/tile.ts | 2 ++ 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 5919a8edab6..6ea882b1625 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -8,8 +8,6 @@ import EXTENT from '../data/extent'; import {vec4, mat4, mat2, vec2, vec3} from 'gl-matrix'; import {Aabb, Frustum} from '../util/primitives'; import EdgeInsets from './edge_insets'; -import Texture from '../render/texture'; -import browser from '../util/browser'; import {UnwrappedTileID, OverscaledTileID, CanonicalTileID} from '../source/tile_id'; import type {PaddingOptions} from './edge_insets'; diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index e0a8c6c197c..7680e1537fc 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -90,11 +90,19 @@ vec2 unpackCoord(vec4 rgba) { // if a coordinate is behind the terrain reduce its opacity float calculate_visibility(sampler2D u_coords, sampler2D u_coords_index, vec4 pos, vec2 tilePos) { #ifdef TERRAIN3D + // get pixel from coords framebuffer vec3 frag = pos.xyz / pos.w; - vec2 coord = unpackCoord(texture2D(u_coords, frag.xy * 0.5 + 0.5)); + vec4 coord_color = texture2D(u_coords, frag.xy * 0.5 + 0.5); + vec2 coord = unpackCoord(coord_color); + // ask coords_index for sub-regions. + // HINT: '1.0 - coord_color.a' is because coords-index is stored in reverse order + // because web-gl do not render pixels with zero opacity + vec4 coords_index = texture2D(u_coords_index, vec2(1.0 - coord_color.a, 0.0)); + float q = 8192.0 / pow(2.0, floor(coords_index.a * 255.0)); + vec2 xy = coords_index.xy * 255.0 * q + coord / 8192.0 * q; // distance is in vector-tile coordinate-space. e.g. 0 .. 8191 // e.g. the distance of the pos.coordinate to the tile.coordinate on the same screen-pixel. - float distance = length(tilePos - coord); + float distance = length(tilePos - xy); if (distance < 100.0) return 1.0; // assume fully visible on terrain return 0.2; // opacity 0.2 behind terrain // FIXME-3D: to get a correct fadeout effect it is necesarry to grab more diff --git a/src/source/raster_dem_tile_source.ts b/src/source/raster_dem_tile_source.ts index 3baea9a1ab4..2d99e6e3c15 100644 --- a/src/source/raster_dem_tile_source.ts +++ b/src/source/raster_dem_tile_source.ts @@ -78,6 +78,8 @@ class RasterDEMTileSource extends RasterTileSource implements Source { if (data) { tile.dem = data.dem; + tile.elevationMin = data.dem.min; + tile.elevationMax = data.dem.max; tile.needsHillshadePrepare = true; tile.state = 'loaded'; callback(null); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index bc2d3370c7f..d2c290762cb 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -75,7 +75,7 @@ class TerrainSourceCache extends Evented { this._emptyDem = new DEMData("0", new RGBAImage({width: 4, height: 4}), "mapbox"); this._emptyDemTexture = new Texture(context, this._emptyDem.getPixels(), context.gl.RGBA, {premultiply: false}); this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - this._emptyDemMatrix = mat4.create(); + this._emptyDemMatrix = new Float64Array(16) as any; mat4.ortho(this._emptyDemMatrix, 0, EXTENT, 0, EXTENT, 0, 1); // create empty coordsIndexTexture @@ -183,8 +183,8 @@ class TerrainSourceCache extends Evented { const maxzoom = this._sourceCache._source.maxzoom; const sourceTileID = this._sourceTileIDs[tileID.key] = tileID.overscaledZ > maxzoom ? tileID.scaledTo(maxzoom) : tileID; // create pos matrix in relation to source tile - tileID.posMatrix = mat4.create(); - const demMatrix = mat4.create(); + tileID.posMatrix = new Float64Array(16) as any; + const demMatrix = new Float64Array(16) as any; if (tileID.canonical.z == sourceTileID.canonical.z) { mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); mat4.ortho(demMatrix, 0, EXTENT, 0, EXTENT, 0, 1); @@ -296,6 +296,7 @@ class TerrainSourceCache extends Evented { * @returns {Tile} */ getSourceTile(tileID: OverscaledTileID): Tile { + if (!this.isEnabled()) return null; const coord = this._sourceTileIDs[tileID.key]; return coord && this._sourceCache.getTileByID(coord.key); } @@ -445,11 +446,11 @@ class TerrainSourceCache extends Evented { updateCoordsIndexTexture(context: Context) { const data = new Uint8Array(256 * 4); for (let i=0; i> dz << dz; - data[i + 1] = tile.tileID.canonical.y - tile.tileID.canonical.y >> dz << dz; + data[i + 0] = tile.tileID.canonical.x - (tile.tileID.canonical.x >> dz << dz); + data[i + 1] = tile.tileID.canonical.y - (tile.tileID.canonical.y >> dz << dz); data[i + 2] = tile.tileID.canonical.z; data[i + 3] = dz; } @@ -457,7 +458,6 @@ class TerrainSourceCache extends Evented { this._coordsIndexTexture.update(image, {premultiply: false}); this._coordsIndexTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); } - } export default TerrainSourceCache; diff --git a/src/source/tile.ts b/src/source/tile.ts index f6ba9b04d1e..3d928ab9a13 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -93,6 +93,7 @@ class Tile { hasRTLText: boolean; dependencies: any; elevation: any; + elevationMin: number; elevationMax: number; textures: Array; @@ -113,6 +114,7 @@ class Tile { this.hasRTLText = false; this.dependencies = {}; this.elevation = {}; + this.elevationMin = 0; this.elevationMax = 0; this.rerender = false; this.textures = []; From 6b395d16c11e36091e4a45581da93bd4cdea6138 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 29 Sep 2021 09:27:30 +0200 Subject: [PATCH 028/138] add very basic logic of loading tiles in respect of their elevation --- src/geo/transform.ts | 12 ++++++++++-- src/util/primitives.ts | 12 +++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 03ff963d61d..85681e5c252 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -427,8 +427,16 @@ class Transform { for (let i = 0; i < 4; i++) { const childX = (x << 1) + (i % 2); const childY = (y << 1) + (i >> 1); - - stack.push({aabb: it.aabb.quadrant(i), zoom: it.zoom + 1, x: childX, y: childY, wrap: it.wrap, fullyVisible}); + const childZ = it.zoom + 1; + let quadrant = it.aabb.quadrant(i); + if (this.terrainSourceCache.isEnabled()) { + let tile = this.terrainSourceCache.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY)); + quadrant = new Aabb( + vec3.fromValues(quadrant.min[0], quadrant.min[1], tile && tile.dem ? tile.dem.min - this.elevation : -this.elevation), + vec3.fromValues(quadrant.max[0], quadrant.max[1], tile && tile.dem ? Math.max(0, tile.dem.max - this.elevation) : 0) + ); + } + stack.push({aabb: quadrant, zoom: childZ, x: childX, y: childY, wrap: it.wrap, fullyVisible}); } } diff --git a/src/util/primitives.ts b/src/util/primitives.ts index 4e033965adf..dc55c7572ad 100644 --- a/src/util/primitives.ts +++ b/src/util/primitives.ts @@ -19,10 +19,12 @@ class Frustum { const scale = Math.pow(2, zoom); - // Transform frustum corner points from clip space to tile space - const frustumCoords = clipSpaceCorners - .map(v => vec4.transformMat4([] as any, v as any, invProj)) - .map(v => vec4.scale([] as any, v, 1.0 / v[3] / worldSize * scale)); + // Transform frustum corner points from clip space to tile space, Z to meters + const frustumCoords = clipSpaceCorners.map(v => { + v = vec4.transformMat4([] as any, v as any, invProj) as any; + const s = 1.0 / v[3] / worldSize * scale; + return vec4.mul(v as any, v as any, vec4.fromValues(s, s, 1.0 / v[3], s)); + }); const frustumPlanePointIndices = [ [0, 1, 2], // near @@ -89,7 +91,7 @@ class Aabb { [this.min[0], this.min[1], this.min[2], 1], [this.max[0], this.min[1], this.min[2], 1], [this.max[0], this.max[1], this.min[2], 1], - [this.min[0], this.max[1], this.min[2], 1] + [this.min[0], this.max[1], this.min[2], 1], [this.min[0], this.min[1], this.max[2], 1], [this.max[0], this.min[1], this.max[2], 1], [this.max[0], this.max[1], this.max[2], 1], From 7df734dbc07c793b992244fae3b360a67c64a90d Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 5 Oct 2021 09:10:46 +0200 Subject: [PATCH 029/138] correct unprojecting coordinates --- src/geo/transform.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 85681e5c252..7b0d6d5f2a5 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -602,12 +602,12 @@ class Transform { const tileID = this.terrainSourceCache._coordsIndex[255 - rgba[3]]; const tile = tileID && this.terrainSourceCache.getTileByID(tileID); if (!tile) return this.pointCoordinate(p); // FIXME! remove this hack - const tileSize = this.terrainSourceCache.tileSize; - const worldSize = (1 << tile.tileID.canonical.z) * tileSize; + const coordsSize = this.terrainSourceCache._coordsTextureSize; + const worldSize = (1 << tile.tileID.canonical.z) * coordsSize; return new MercatorCoordinate( - (tile.tileID.canonical.x * tileSize + x / 8) / worldSize, - (tile.tileID.canonical.y * tileSize + y / 8) / worldSize, - this.terrainSourceCache.getElevation(tile.tileID, x, y, 4096) + (tile.tileID.canonical.x * coordsSize + x) / worldSize, + (tile.tileID.canonical.y * coordsSize + y) / worldSize, + this.terrainSourceCache.getElevation(tile.tileID, x, y, coordsSize) ); } @@ -770,12 +770,12 @@ class Transform { const offset = this.centerOffset; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; - let m = mat4.create(); + let m = mat4.identity(new Float64Array(16) as any); mat4.scale(m, m, [this.width / 2, -this.height / 2, 1]); mat4.translate(m, m, [1, -1, 0]); this.labelPlaneMatrix = m; - m = mat4.create(); + m = mat4.identity(new Float64Array(16) as any); mat4.scale(m, m, [1, -1, 1]); mat4.translate(m, m, [-1, -1, 0]); mat4.scale(m, m, [2 / this.width, 2 / this.height, 1]); @@ -822,7 +822,7 @@ class Transform { // The mercatorMatrix can be used to transform points from mercator coordinates // ([0, 0] nw, [1, 1] se) to GL coordinates. - this.mercatorMatrix = mat4.scale([] as any, m, vec3.fromValues(this.worldSize, this.worldSize, this.worldSize)); + this.mercatorMatrix = mat4.scale(new Float64Array(16) as any, m, vec3.fromValues(this.worldSize, this.worldSize, this.worldSize)); // scale vertically to meters per pixel (inverse of ground resolution): mat4.scale(m, m, vec3.fromValues(1, 1, metersPerPixel)); From e6447910725fa76f9d2cdbed27d059a9425d3845 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 6 Oct 2021 12:07:33 +0200 Subject: [PATCH 030/138] correct calculation of elevation in CPU for different maxzoom settings --- src/geo/transform.ts | 6 +-- src/render/draw_background.ts | 1 - src/render/draw_fill.ts | 2 - src/render/draw_hillshade.ts | 2 - src/render/draw_line.ts | 2 - src/render/draw_raster.ts | 2 - src/render/draw_terrain.ts | 1 + src/render/painter.ts | 12 ----- src/source/terrain_source_cache.ts | 70 +++++++++++++++++++++++------- 9 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 7b0d6d5f2a5..74972e006f8 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -790,12 +790,12 @@ class Transform { const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * this.cameraToCenterDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); const point = this.point; const x = point.x, y = point.y; - const metersPerPixel = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; + const pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; // Calculate z distance of the farthest fragment that should be rendered. const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToCenterDistance; // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` - const farZ = (furthestDistance + elevation * metersPerPixel / Math.cos(this._pitch)) * 1.01; + const farZ = (furthestDistance + elevation * pixelPerMeter / Math.cos(this._pitch)) * 1.01; // The larger the value of nearZ is // - the more depth precision is available for features (good) @@ -825,7 +825,7 @@ class Transform { this.mercatorMatrix = mat4.scale(new Float64Array(16) as any, m, vec3.fromValues(this.worldSize, this.worldSize, this.worldSize)); // scale vertically to meters per pixel (inverse of ground resolution): - mat4.scale(m, m, vec3.fromValues(1, 1, metersPerPixel)); + mat4.scale(m, m, vec3.fromValues(1, 1, pixelPerMeter)); // matrix for conversion from location to screen coordinates this.pixelMatrix = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); diff --git a/src/render/draw_background.ts b/src/render/draw_background.ts index 05c3a770a6a..c9ba5d263ec 100644 --- a/src/render/draw_background.ts +++ b/src/render/draw_background.ts @@ -42,7 +42,6 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const crossfade = layer.getCrossfadeParameters(); for (const tileID of tileIDs) { - if (coords) painter.setTextureViewport(tileID); const matrix = coords ? tileID.posMatrix : painter.transform.calculatePosMatrix(tileID.toUnwrapped()); const uniformValues = image ? backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}, crossfade) : diff --git a/src/render/draw_fill.ts b/src/render/draw_fill.ts index 2e0d3535f61..4d4a398612b 100644 --- a/src/render/draw_fill.ts +++ b/src/render/draw_fill.ts @@ -97,8 +97,6 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode } const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; - if (terrainCoord) painter.setTextureViewport(terrainCoord); - let posMatrix = terrainCoord ? terrainCoord.posMatrix : coord.posMatrix; const tileMatrix = painter.translatePosMatrix(posMatrix, tile, layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor')); diff --git a/src/render/draw_hillshade.ts b/src/render/draw_hillshade.ts index 7cbe769955e..004fd92a6ec 100644 --- a/src/render/draw_hillshade.ts +++ b/src/render/draw_hillshade.ts @@ -49,8 +49,6 @@ function renderHillshade(painter, coord, tile, layer, depthMode, stencilMode, co gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; - if (terrainCoord) painter.setTextureViewport(terrainCoord); - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, hillshadeUniformValues(painter, tile, layer, terrainCoord), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); diff --git a/src/render/draw_line.ts b/src/render/draw_line.ts index 458fc6ad4a6..8561ee22a8f 100644 --- a/src/render/draw_line.ts +++ b/src/render/draw_line.ts @@ -66,8 +66,6 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay } const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; - if (terrainCoord) painter.setTextureViewport(terrainCoord); - const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade, terrainCoord) : dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade, terrainCoord) : gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length, terrainCoord) : diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index fe6a5af346c..5eaede1d117 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -64,8 +64,6 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty } const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; - if (terrainCoord) painter.setTextureViewport(terrainCoord); - const posMatrix = terrainCoord ? terrainCoord.posMatrix : painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 35c94af465c..e0276f08763 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -78,6 +78,7 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: } FBOs[tile.tileSize].colorAttachment.set(tile.textures[stack].texture); context.bindFramebuffer.set(FBOs[tile.tileSize].framebuffer); + context.viewport.set([0, 0, size, size]); } export { diff --git a/src/render/painter.ts b/src/render/painter.ts index 175624f9e0f..bd805c09cd0 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -327,18 +327,6 @@ class Painter { return [{[minTileZ]: StencilMode.disabled}, coords]; } - // calculate the correct tiles-viewport when rendering to texture - setTextureViewport(tileID: OverscaledTileID) { - let x = 0, y = 0, size = this.style.terrainSourceCache.tileSize * this.style.terrainSourceCache.qualityFactor; - const z = Math.floor(this.transform.zoom), dz = tileID.canonical.z - z; - if (dz > 0) { - x = tileID.canonical.x - (tileID.canonical.x >> dz << dz); - y = tileID.canonical.y - (tileID.canonical.y >> dz << dz); - size /= 1 << dz; - } - this.context.viewport.set([size * x, size * y, size, size]); - } - colorModeForRenderPass(): Readonly { const gl = this.context.gl; if (this._showOverdrawInspector) { diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index d2c290762cb..c89c07657c8 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -24,6 +24,7 @@ class TerrainSourceCache extends Evented { _source: RasterDEMTileSource; _sourceCache: SourceCache; _tiles: {[_: string]: Tile}; + _renderableTiles: Array; _loadQueue: Array; _coordsFramebuffer: any; _fbo: any; @@ -54,6 +55,7 @@ class TerrainSourceCache extends Evented { this._sourceCache = null; this._source = null; this._tiles = {}; + this._renderableTiles = []; this._loadQueue = []; this._coordsFramebuffer = null; this._fbo = null; @@ -175,8 +177,10 @@ class TerrainSourceCache extends Evented { transform.updateElevation(); let outdated = {}; for (let key in this._tiles) outdated[key] = true; + this._renderableTiles = []; // create tiles for current view for (const tileID of this.getRenderableTileIds(transform)) { + this._renderableTiles.push(tileID.key); delete(outdated[tileID.key]); if (this._tiles[tileID.key]) continue; // find parent source tile @@ -184,17 +188,14 @@ class TerrainSourceCache extends Evented { const sourceTileID = this._sourceTileIDs[tileID.key] = tileID.overscaledZ > maxzoom ? tileID.scaledTo(maxzoom) : tileID; // create pos matrix in relation to source tile tileID.posMatrix = new Float64Array(16) as any; + mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); const demMatrix = new Float64Array(16) as any; if (tileID.canonical.z == sourceTileID.canonical.z) { - mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); mat4.ortho(demMatrix, 0, EXTENT, 0, EXTENT, 0, 1); } else { const dz = tileID.canonical.z - sourceTileID.canonical.z; const dx = tileID.canonical.x - (sourceTileID.canonical.x << dz); const dy = tileID.canonical.y - (sourceTileID.canonical.y << dz); - const size = EXTENT >> dz - mat4.ortho(tileID.posMatrix, 0, size, 0, size, 0, 1); - mat4.translate(tileID.posMatrix, tileID.posMatrix, [-dx * size, -dy * size, 0]); mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); } @@ -275,15 +276,33 @@ class TerrainSourceCache extends Evented { */ getTerrainCoords(tileID: OverscaledTileID): {[_: string]: OverscaledTileID} { const coords = {}; - for (let key in this._tiles) { + for (let key of this._renderableTiles) { const _tileID = this._tiles[key].tileID; - // handle reparseOverscaled tilesources - if (_tileID.equals(tileID) - || _tileID.canonical.isChildOf(tileID.canonical) - || tileID.canonical.isChildOf(_tileID.canonical) - ) { + if (_tileID.equals(tileID)) { const coord = tileID.clone(); - coord.posMatrix = mat4.clone(_tileID.posMatrix); + coord.posMatrix = new Float64Array(16) as any; + mat4.ortho(coord.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + coords[key] = coord; + } else if (_tileID.canonical.isChildOf(tileID.canonical)) { + const coord = tileID.clone(); + coord.posMatrix = new Float64Array(16) as any; + const dz = _tileID.canonical.z - tileID.canonical.z; + const dx = _tileID.canonical.x - (_tileID.canonical.x >> dz << dz); + const dy = _tileID.canonical.y - (_tileID.canonical.y >> dz << dz); + const size = EXTENT >> dz; + mat4.ortho(coord.posMatrix, 0, size, 0, size, 0, 1); + mat4.translate(coord.posMatrix, coord.posMatrix, [-dx * size, -dy * size, 0]); + coords[key] = coord; + } else if (tileID.canonical.isChildOf(_tileID.canonical)) { + const coord = tileID.clone(); + coord.posMatrix = new Float64Array(16) as any; + const dz = tileID.canonical.z - _tileID.canonical.z; + const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); + const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); + const size = EXTENT >> dz; + mat4.ortho(coord.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + mat4.translate(coord.posMatrix, coord.posMatrix, [dx * size, dy * size, 0]); + mat4.scale(coord.posMatrix, coord.posMatrix, [1 / (2 ** dz), 1 / (2 ** dz), 0]); coords[key] = coord; } } @@ -314,10 +333,31 @@ class TerrainSourceCache extends Evented { * @returns {number} */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { - if (!this.isEnabled()) return 0; - const maxzoom = this._sourceCache._source.maxzoom, shouldScale = tileID.overscaledZ > maxzoom; - const tile = this._sourceCache.getTileByID(shouldScale ? tileID.scaledTo(maxzoom).key : tileID.key); - let elevation = tile && tile.dem && x >= 0 && y >= 0 && x <= extent && y <= extent //FIXME-3D handle negative coordinates + if (!this.isEnabled()) return this.elevationOffset; + if (!(x >= 0 && x <= extent && y >= 0 && y <= extent)) return this.elevationOffset; + // convert tileID to tileID.overscaledZ level + let dz = tileID.overscaledZ - tileID.canonical.z; + if (dz > 0) { + const size = extent >> dz; + const tx = (tileID.canonical.x << dz) + Math.floor(x / size); + const ty = (tileID.canonical.y << dz) + Math.floor(y / size); + tileID = new OverscaledTileID(tileID.overscaledZ, tileID.wrap, tileID.overscaledZ, tx, ty); + x = (x % size) / size * extent; + y = (y % size) / size * extent; + } + // search for sourceTile + dz = tileID.overscaledZ - this._sourceCache._source.maxzoom; + if (dz > 0) { + const size = extent >> dz; + const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); + const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); + tileID = tileID.scaledTo(tileID.overscaledZ - dz); + x = dx * size + x / extent * size; + y = dy * size + y / extent * size; + } + const tile = this._sourceCache.getTileByID(tileID.key); + // get elevation from dem + let elevation = tile && tile.dem ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) : 0; if (elevation > 8191) elevation = 0; // REMOVEME: this hack is for MTK data, because of false nodata values From 1b368307bb088360fe65164a6025799fab46b0a9 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Oct 2021 14:18:45 +0200 Subject: [PATCH 031/138] calcuate symbol visibility via a depth-framebuffer, because the coords-framebuffer visibility calculation gets to wired if terrain-tiles & vector-tiles has different maxzoom settings --- src/geo/transform.ts | 2 +- src/render/draw_circle.ts | 4 +- src/render/draw_symbol.ts | 4 +- src/render/draw_terrain.ts | 33 ++++++++++---- src/render/program/circle_program.ts | 9 ++-- src/render/program/program_uniforms.ts | 3 +- src/render/program/symbol_program.ts | 21 +++------ src/render/program/terrain_program.ts | 45 +++++++++++++++--- src/shaders/_prelude.vertex.glsl | 39 +++++----------- src/shaders/circle.vertex.glsl | 5 +- src/shaders/shaders.ts | 2 + src/shaders/symbol_icon.vertex.glsl | 5 +- src/shaders/symbol_sdf.vertex.glsl | 5 +- src/shaders/symbol_text_and_icon.vertex.glsl | 5 +- src/shaders/terrain.fragment.glsl | 2 - src/shaders/terrain.vertex.glsl | 7 +-- src/shaders/terrain_depth.fragment.glsl | 15 ++++++ src/source/terrain_source_cache.ts | 48 +++++++------------- 18 files changed, 133 insertions(+), 121 deletions(-) create mode 100644 src/shaders/terrain_depth.fragment.glsl diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 74972e006f8..bf55c6b0b7c 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -593,7 +593,7 @@ class Transform { const rgba = new Uint8Array(4); const painter = this.terrainSourceCache._style.map.painter, context = painter.context, gl = context.gl; // grab coordinate pixel from coordinates framebuffer - context.bindFramebuffer.set(this.terrainSourceCache.getCoordsFramebuffer(painter).framebuffer); + context.bindFramebuffer.set(this.terrainSourceCache.getFramebuffer(painter, "coords").framebuffer); gl.readPixels(p.x, painter.height / devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); context.bindFramebuffer.set(null); // decode coordinates (encoding see terrain-source-cache) diff --git a/src/render/draw_circle.ts b/src/render/draw_circle.ts index a30c8965ac6..7c617a8ccdb 100644 --- a/src/render/draw_circle.ts +++ b/src/render/draw_circle.ts @@ -115,9 +115,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt } context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getCoordsFramebuffer(painter).colorAttachment.get()); - context.activeTexture.set(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache._coordsIndexTexture.texture); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getFramebuffer(painter, "depth").colorAttachment.get()); for (const segmentsState of segmentsRenderStates) { const {programConfiguration, program, layoutVertexBuffer, elevationVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index b709a2ebc73..32f08b05e03 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -402,9 +402,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate } context.activeTexture.set(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getCoordsFramebuffer(painter).colorAttachment.get()); - context.activeTexture.set(gl.TEXTURE3); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache._coordsIndexTexture.texture); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getFramebuffer(painter, "depth").colorAttachment.get()); if (state.isSDF) { const uniformValues = (state.uniformValues as any as UniformValues); diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index e0276f08763..acc8b1c354e 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -1,6 +1,6 @@ import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; -import {terrainUniformValues, terrainCoordsUniformValues} from './program/terrain_program'; +import {terrainUniformValues, terrainDepthUniformValues, terrainCoordsUniformValues} from './program/terrain_program'; import type Painter from './painter'; import type TerrainSourceCache from '../source/terrain_source_cache'; import type Tile from '../source/tile'; @@ -15,32 +15,45 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; - const program = painter.useProgram('terrainCoords'); const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); const mesh = sourceCache.getTerrainMesh(context); const coords = sourceCache.getCoordsTexture(context); + const tiles = sourceCache.getRenderableTiles(painter.transform); // draw tile-coords into framebuffer - context.bindFramebuffer.set(sourceCache.getCoordsFramebuffer(painter).framebuffer); + let program = painter.useProgram('terrainCoords'); + context.bindFramebuffer.set(sourceCache.getFramebuffer(painter, "coords").framebuffer); context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); context.clear({ color: Color.transparent, depth: 1 }); - sourceCache._coordsIndex = []; - for (const tile of sourceCache.getRenderableTiles(painter.transform)) { + for (const tile of tiles) { const dem = sourceCache.getDem(tile.tileID); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, coords.texture); - context.activeTexture.set(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, dem.texture); + context.activeTexture.set(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, coords.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); const uniformValues = terrainCoordsUniformValues(painter, posMatrix, dem.matrix, 255 - sourceCache._coordsIndex.length, dem.unpackVector, sourceCache.elevationOffset); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); sourceCache._coordsIndex.push(tile.tileID.key); } + // draw depth into framebuffer + program = painter.useProgram('terrainDepth'); + context.bindFramebuffer.set(sourceCache.getFramebuffer(painter, "depth").framebuffer); + context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); + context.clear({ color: Color.transparent, depth: 1 }); + for (const tile of tiles) { + const dem = sourceCache.getDem(tile.tileID); + context.activeTexture.set(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, dem.texture); + const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); + const uniformValues = terrainDepthUniformValues(painter, posMatrix, dem.matrix, dem.unpackVector, sourceCache.elevationOffset); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + } + context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); - sourceCache.updateCoordsIndexTexture(context); } function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile) { @@ -55,9 +68,9 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Ti context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, FBOs[tile.tileSize].colorAttachment.get()); - context.activeTexture.set(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, dem.texture); + context.activeTexture.set(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, FBOs[tile.tileSize].colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); const uniformValues = terrainUniformValues(painter, posMatrix, dem.matrix, dem.unpackVector, sourceCache.elevationOffset); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); diff --git a/src/render/program/circle_program.ts b/src/render/program/circle_program.ts index 6d234d11034..202016c3c4d 100644 --- a/src/render/program/circle_program.ts +++ b/src/render/program/circle_program.ts @@ -15,8 +15,7 @@ export type CircleUniformsType = { 'u_extrude_scale': Uniform2f; 'u_device_pixel_ratio': Uniform1f; 'u_matrix': UniformMatrix4f; - 'u_coords': Uniform1i; - 'u_coords_index': Uniform1i; + 'u_depth': Uniform1i; 'u_terrain_exaggeration': Uniform1f; }; @@ -27,8 +26,7 @@ const circleUniforms = (context: Context, locations: UniformLocations): CircleUn 'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_depth': new Uniform1i(context, locations.u_depth), 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); @@ -61,8 +59,7 @@ const circleUniformValues = ( 'u_pitch_with_map': +(pitchWithMap), 'u_device_pixel_ratio': devicePixelRatio, 'u_extrude_scale': extrudeScale, - 'u_coords': 0, - 'u_coords_index': 1, + 'u_depth': 0, 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/program_uniforms.ts b/src/render/program/program_uniforms.ts index 2f0cb509d97..f1723ccac78 100644 --- a/src/render/program/program_uniforms.ts +++ b/src/render/program/program_uniforms.ts @@ -10,7 +10,7 @@ import {lineUniforms, lineGradientUniforms, linePatternUniforms, lineSDFUniforms import {rasterUniforms} from './raster_program'; import {symbolIconUniforms, symbolSDFUniforms, symbolTextAndIconUniforms} from './symbol_program'; import {backgroundUniforms, backgroundPatternUniforms} from './background_program'; -import {terrainUniforms, terrainCoordsUniforms} from './terrain_program'; +import {terrainUniforms, terrainDepthUniforms, terrainCoordsUniforms} from './terrain_program'; export const programUniforms = { fillExtrusion: fillExtrusionUniforms, @@ -39,5 +39,6 @@ export const programUniforms = { background: backgroundUniforms, backgroundPattern: backgroundPatternUniforms, terrain: terrainUniforms, + terrainDepth: terrainDepthUniforms, terrainCoords: terrainCoordsUniforms }; diff --git a/src/render/program/symbol_program.ts b/src/render/program/symbol_program.ts index 0228b17f930..f4b579802df 100644 --- a/src/render/program/symbol_program.ts +++ b/src/render/program/symbol_program.ts @@ -23,8 +23,7 @@ export type SymbolIconUniformsType = { 'u_pitch_with_map': Uniform1i; 'u_texsize': Uniform2f; 'u_texture': Uniform1i; - 'u_coords': Uniform1i; - 'u_coords_index': Uniform1i; + 'u_depth': Uniform1i; 'u_terrain_exaggeration': Uniform1f; }; @@ -48,8 +47,7 @@ export type SymbolSDFUniformsType = { 'u_gamma_scale': Uniform1f; 'u_device_pixel_ratio': Uniform1f; 'u_is_halo': Uniform1i; - 'u_coords': Uniform1i; - 'u_coords_index': Uniform1i; + 'u_depth': Uniform1i; 'u_terrain_exaggeration': Uniform1f; }; @@ -75,8 +73,7 @@ export type symbolTextAndIconUniformsType = { 'u_gamma_scale': Uniform1f; 'u_device_pixel_ratio': Uniform1f; 'u_is_halo': Uniform1i; - 'u_coords': Uniform1i; - 'u_coords_index': Uniform1i; + 'u_depth': Uniform1i; 'u_terrain_exaggeration': Uniform1f; }; @@ -97,8 +94,7 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_texture': new Uniform1i(context, locations.u_texture), - 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_depth': new Uniform1i(context, locations.u_depth), 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); @@ -122,8 +118,7 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new Uniform1i(context, locations.u_is_halo), - 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_depth': new Uniform1i(context, locations.u_depth), 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); @@ -149,8 +144,7 @@ const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new Uniform1i(context, locations.u_is_halo), - 'u_coords': new Uniform1i(context, locations.u_coords), - 'u_coords_index': new Uniform1i(context, locations.u_coords_index), + 'u_depth': new Uniform1i(context, locations.u_depth), 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); @@ -188,8 +182,7 @@ const symbolIconUniformValues = ( 'u_pitch_with_map': +pitchWithMap, 'u_texsize': texSize, 'u_texture': 0, - 'u_coords': 2, - 'u_coords_index': 3, + 'u_depth': 2, 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration }; }; diff --git a/src/render/program/terrain_program.ts b/src/render/program/terrain_program.ts index 12bdeb4ed1f..732cb9d335a 100644 --- a/src/render/program/terrain_program.ts +++ b/src/render/program/terrain_program.ts @@ -20,6 +20,15 @@ export type TerrainUniformsType = { 'u_terrain_exaggeration': Uniform1f; }; +export type TerrainDepthUniformsType = { + 'u_matrix': UniformMatrix4f; + 'u_terrain': Uniform1i; + 'u_terrain_matrix': UniformMatrix4f; + 'u_terrain_unpack': Uniform4f; + 'u_terrain_offset': Uniform1f; + 'u_terrain_exaggeration': Uniform1f; +}; + export type TerrainCoordsUniformsType = { 'u_matrix': UniformMatrix4f; 'u_texture': Uniform1i; @@ -41,6 +50,15 @@ const terrainUniforms = (context: Context, locations: UniformLocations): Terrain 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); +const terrainDepthUniforms = (context: Context, locations: UniformLocations): TerrainDepthUniformsType => ({ + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_terrain': new Uniform1i(context, locations.u_terrain), + 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), + 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), + 'u_terrain_offset': new Uniform1f(context, locations.u_terrain_offset), + 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) +}); + const terrainCoordsUniforms = (context: Context, locations: UniformLocations): TerrainCoordsUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_texture': new Uniform1i(context, locations.u_texture), @@ -60,8 +78,23 @@ const terrainUniformValues = ( offset: number ): UniformValues => ({ 'u_matrix': matrix, - 'u_texture': 0, - 'u_terrain': 1, + 'u_terrain': 0, + 'u_terrain_matrix': terrainMatrix, + 'u_terrain_unpack': unpackVector, + 'u_terrain_offset': offset, + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration, + 'u_texture': 1 +}); + +const terrainDepthUniformValues = ( + painter: Painter, + matrix: mat4, + terrainMatrix: mat4, + unpackVector: Array, + offset: number +): UniformValues => ({ + 'u_matrix': matrix, + 'u_terrain': 0, 'u_terrain_matrix': terrainMatrix, 'u_terrain_unpack': unpackVector, 'u_terrain_offset': offset, @@ -77,13 +110,13 @@ const terrainCoordsUniformValues = ( offset: number ): UniformValues => ({ 'u_matrix': matrix, - 'u_texture': 0, - 'u_terrain': 1, + 'u_terrain': 0, 'u_terrain_matrix': terrainMatrix, 'u_terrain_unpack': unpackVector, 'u_terrain_offset': offset, 'u_terrain_coords_id': coordsId / 255, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration, + 'u_texture': 1 }); -export {terrainUniforms, terrainCoordsUniforms, terrainUniformValues, terrainCoordsUniformValues}; +export {terrainUniforms, terrainDepthUniforms, terrainCoordsUniforms, terrainUniformValues, terrainDepthUniformValues, terrainCoordsUniformValues}; diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 7680e1537fc..45aca504658 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -72,41 +72,24 @@ vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, return (tile_units_to_pixels * pos + offset) / pattern_size; } -float hasBit(float value, int pos) { - return floor(mod(floor(value / pow(2.0, float(pos))), 2.0)); -} +// methods for pack/unpack depth value to texture rgba +// https://stackoverflow.com/questions/34963366/encode-floating-point-data-in-a-rgba-texture +const highp vec4 bitSh = vec4(256. * 256. * 256., 256. * 256., 256., 1.); +const highp vec4 bitShifts = vec4(1.) / bitSh; -// unpack a RGBA value from the coords framebuffer into a vec2 in the range from 0 .. 8191 -vec2 unpackCoord(vec4 rgba) { - float r = floor(rgba.r * 255.0); - float g = floor(rgba.g * 255.0); - float b = floor(rgba.b * 255.0); - float x = r + hasBit(b, 4) * 256.0 + hasBit(b, 5) * 512.0 + hasBit(b, 6) * 1024.0 + hasBit(b, 7) * 2048.0; - float y = g + hasBit(b, 0) * 256.0 + hasBit(b, 1) * 512.0 + hasBit(b, 2) * 1024.0 + hasBit(b, 3) * 2048.0; - return vec2(x, y) * 8.0; // multiply by 8 is necesarry because the coords-texture has only 1024x1024 pixels. +highp float unpack(highp vec4 color) { + return dot(color , bitShifts); } // calculate the visibility of a coordinate in terrain and return an opacity value. // if a coordinate is behind the terrain reduce its opacity -float calculate_visibility(sampler2D u_coords, sampler2D u_coords_index, vec4 pos, vec2 tilePos) { +float calculate_visibility(sampler2D u_depth, vec4 pos) { #ifdef TERRAIN3D - // get pixel from coords framebuffer vec3 frag = pos.xyz / pos.w; - vec4 coord_color = texture2D(u_coords, frag.xy * 0.5 + 0.5); - vec2 coord = unpackCoord(coord_color); - // ask coords_index for sub-regions. - // HINT: '1.0 - coord_color.a' is because coords-index is stored in reverse order - // because web-gl do not render pixels with zero opacity - vec4 coords_index = texture2D(u_coords_index, vec2(1.0 - coord_color.a, 0.0)); - float q = 8192.0 / pow(2.0, floor(coords_index.a * 255.0)); - vec2 xy = coords_index.xy * 255.0 * q + coord / 8192.0 * q; - // distance is in vector-tile coordinate-space. e.g. 0 .. 8191 - // e.g. the distance of the pos.coordinate to the tile.coordinate on the same screen-pixel. - float distance = length(tilePos - xy); - if (distance < 100.0) return 1.0; // assume fully visible on terrain - return 0.2; // opacity 0.2 behind terrain - // FIXME-3D: to get a correct fadeout effect it is necesarry to grab more - // pixels around pos to find the exact screen-pixel distance behind the terrain. + vec4 rgba = texture2D(u_depth, frag.xy * 0.5 + 0.5); + highp float depth = unpack(rgba); + if ((depth + 0.001) < frag.z) return 0.2; + return 1.0; #else return 1.0; #endif diff --git a/src/shaders/circle.vertex.glsl b/src/shaders/circle.vertex.glsl index 836505f28b2..03d678eb640 100644 --- a/src/shaders/circle.vertex.glsl +++ b/src/shaders/circle.vertex.glsl @@ -4,8 +4,7 @@ uniform bool u_pitch_with_map; uniform vec2 u_extrude_scale; uniform lowp float u_device_pixel_ratio; uniform highp float u_camera_to_center_distance; -uniform highp sampler2D u_coords; -uniform highp sampler2D u_coords_index; +uniform highp sampler2D u_depth; uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; @@ -37,7 +36,7 @@ void main(void) { // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data vec2 circle_center = floor(a_pos * 0.5); - v_visibility = calculate_visibility(u_coords, u_coords_index, u_matrix * vec4(circle_center, a_ele * u_terrain_exaggeration, 1.0), circle_center); + v_visibility = calculate_visibility(u_depth, u_matrix * vec4(circle_center, a_ele * u_terrain_exaggeration, 1.0)); if (u_pitch_with_map) { vec2 corner_position = circle_center; diff --git a/src/shaders/shaders.ts b/src/shaders/shaders.ts index e36f65a5e1c..22466711dd8 100644 --- a/src/shaders/shaders.ts +++ b/src/shaders/shaders.ts @@ -53,6 +53,7 @@ import symbolSDFFrag from './symbol_sdf.fragment.glsl'; import symbolSDFVert from './symbol_sdf.vertex.glsl'; import symbolTextAndIconFrag from './symbol_text_and_icon.fragment.glsl'; import symbolTextAndIconVert from './symbol_text_and_icon.vertex.glsl'; +import terrainDepthFrag from './terrain_depth.fragment.glsl'; import terrainCoordsFrag from './terrain_coords.fragment.glsl'; import terrainFrag from './terrain.fragment.glsl'; import terrainVert from './terrain.vertex.glsl'; @@ -85,6 +86,7 @@ export default { symbolSDF: compile(symbolSDFFrag, symbolSDFVert), symbolTextAndIcon: compile(symbolTextAndIconFrag, symbolTextAndIconVert), terrain: compile(terrainFrag, terrainVert), + terrainDepth: compile(terrainDepthFrag, terrainVert), terrainCoords: compile(terrainCoordsFrag, terrainVert) }; diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 734b35fc954..1b7cc9cfbb5 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -22,8 +22,7 @@ uniform mat4 u_coord_matrix; uniform bool u_is_text; uniform bool u_pitch_with_map; uniform vec2 u_texsize; -uniform highp sampler2D u_coords; -uniform highp sampler2D u_coords_index; +uniform highp sampler2D u_depth; uniform lowp float u_terrain_exaggeration; varying vec2 v_tex; @@ -92,6 +91,6 @@ void main() { v_tex = a_tex / u_texsize; vec2 fade_opacity = unpack_opacity(a_fade_opacity); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; - float visibility = calculate_visibility(u_coords, u_coords_index, projectedPoint, a_pos); + float visibility = calculate_visibility(u_depth, projectedPoint); v_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); } diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index d7bcdded305..6972e15f60e 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -29,8 +29,7 @@ uniform highp float u_aspect_ratio; uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; -uniform highp sampler2D u_coords; -uniform highp sampler2D u_coords_index; +uniform highp sampler2D u_depth; uniform lowp float u_terrain_exaggeration; varying vec2 v_data0; @@ -112,7 +111,7 @@ void main() { float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); - float visibility = calculate_visibility(u_coords, u_coords_index, projectedPoint, a_pos); + float visibility = calculate_visibility(u_depth, projectedPoint); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index 83d28fd0b73..40800c1ac73 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -29,8 +29,7 @@ uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; uniform vec2 u_texsize_icon; -uniform highp sampler2D u_coords; -uniform highp sampler2D u_coords_index; +uniform highp sampler2D u_depth; uniform lowp float u_terrain_exaggeration; varying vec4 v_data0; @@ -112,7 +111,7 @@ void main() { float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); - float visibility = calculate_visibility(u_coords, u_coords_index, projectedPoint, a_pos); + float visibility = calculate_visibility(u_depth, projectedPoint); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); diff --git a/src/shaders/terrain.fragment.glsl b/src/shaders/terrain.fragment.glsl index 2f5223260d3..6d20bb4a9de 100644 --- a/src/shaders/terrain.fragment.glsl +++ b/src/shaders/terrain.fragment.glsl @@ -1,9 +1,7 @@ precision mediump float; uniform sampler2D u_texture; -uniform sampler2D u_terrain; varying vec2 v_texture_pos; -varying vec2 v_terrain_pos; void main() { gl_FragColor = texture2D(u_texture, v_texture_pos); diff --git a/src/shaders/terrain.vertex.glsl b/src/shaders/terrain.vertex.glsl index 0bf5032c211..f30ee54700c 100644 --- a/src/shaders/terrain.vertex.glsl +++ b/src/shaders/terrain.vertex.glsl @@ -8,7 +8,7 @@ uniform float u_terrain_exaggeration; uniform float u_terrain_offset; varying vec2 v_texture_pos; -varying vec2 v_terrain_pos; +varying float v_depth; float getElevation(vec2 coord) { vec4 rgb = (texture2D(u_terrain, coord) * 255.0) * u_terrain_unpack; @@ -18,6 +18,7 @@ float getElevation(vec2 coord) { void main() { v_texture_pos = a_pos / 8192.0; - v_terrain_pos = (u_terrain_matrix * vec4(a_pos, 0.0, 1.0)).xy * 0.5 + 0.5; - gl_Position = u_matrix * vec4(a_pos, getElevation(v_terrain_pos), 1.0); + vec2 terrain_pos = (u_terrain_matrix * vec4(a_pos, 0.0, 1.0)).xy * 0.5 + 0.5; + gl_Position = u_matrix * vec4(a_pos, getElevation(terrain_pos), 1.0); + v_depth = gl_Position.z / gl_Position.w; } diff --git a/src/shaders/terrain_depth.fragment.glsl b/src/shaders/terrain_depth.fragment.glsl new file mode 100644 index 00000000000..ff5cf76d8c1 --- /dev/null +++ b/src/shaders/terrain_depth.fragment.glsl @@ -0,0 +1,15 @@ +varying float v_depth; + +// methods for pack/unpack depth value to texture rgba +// https://stackoverflow.com/questions/34963366/encode-floating-point-data-in-a-rgba-texture +const highp vec4 bitSh = vec4(256. * 256. * 256., 256. * 256., 256., 1.); +const highp vec4 bitMsk = vec4(0.,vec3(1./256.0)); +highp vec4 pack(highp float value) { + highp vec4 comp = fract(value * bitSh); + comp -= comp.xxyz * bitMsk; + return comp; +} + +void main() { + gl_FragColor = pack(v_depth); +} diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index c89c07657c8..eebbfdffcce 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -28,6 +28,8 @@ class TerrainSourceCache extends Evented { _loadQueue: Array; _coordsFramebuffer: any; _fbo: any; + _fboCoordsTexture: Texture; + _fboDepthTexture: Texture; _mesh: any; _coordsIndex: Array; _coordsTexture: Texture; @@ -52,14 +54,9 @@ class TerrainSourceCache extends Evented { constructor(style: Style) { super(); this._style = style; - this._sourceCache = null; - this._source = null; this._tiles = {}; this._renderableTiles = []; this._loadQueue = []; - this._coordsFramebuffer = null; - this._fbo = null; - this._mesh = null; this._terrainTileCache = {}; this._sourceTileIDs = {}; this._coordsIndex = []; @@ -381,21 +378,30 @@ class TerrainSourceCache extends Evented { * @param {Painter} painter * @returns {Framebuffer} */ - getCoordsFramebuffer(painter: Painter): Framebuffer { + getFramebuffer(painter: Painter, texture: string): Framebuffer { const width = this.isEnabled() ? painter.width / devicePixelRatio : 10; const height = this.isEnabled() ? painter.height / devicePixelRatio : 10; if (this._fbo && (this._fbo.width != width || this._fbo.height != height)) { this._fbo.destroy(); + this._fboCoordsTexture.destroy(); + this._fboDepthTexture.destroy(); delete this._fbo; + delete this._fboDepthTexture; + delete this._fboCoordsTexture; + } + if (!this._fboCoordsTexture) { + this._fboCoordsTexture = new Texture(painter.context, { width: width, height: height, data: null }, painter.context.gl.RGBA, {premultiply: false}); + this._fboCoordsTexture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); + } + if (!this._fboDepthTexture) { + this._fboDepthTexture = new Texture(painter.context, { width: width, height: height, data: null }, painter.context.gl.RGBA, {premultiply: false}); + this._fboDepthTexture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); } if (! this._fbo) { - painter.context.activeTexture.set(painter.context.gl.TEXTURE0); - let texture = new Texture(painter.context, { width: width, height: height, data: null }, painter.context.gl.RGBA, {premultiply: false}); - texture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); this._fbo = painter.context.createFramebuffer(width, height, true); - this._fbo.colorAttachment.set(texture.texture); this._fbo.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, width, height)); } + this._fbo.colorAttachment.set(texture == "coords" ? this._fboCoordsTexture.texture : this._fboDepthTexture.texture); return this._fbo; } @@ -476,28 +482,6 @@ class TerrainSourceCache extends Evented { texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); return this._coordsTexture = texture; } - - /** - * create texture, with informations about the coords-index - * e.g. for each coords tile, size & quadrant - * @param {Context} context - * @returns {Texture} - */ - updateCoordsIndexTexture(context: Context) { - const data = new Uint8Array(256 * 4); - for (let i=0; i> dz << dz); - data[i + 1] = tile.tileID.canonical.y - (tile.tileID.canonical.y >> dz << dz); - data[i + 2] = tile.tileID.canonical.z; - data[i + 3] = dz; - } - const image = new RGBAImage({width: 256, height: 1}, data); - this._coordsIndexTexture.update(image, {premultiply: false}); - this._coordsIndexTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - } } export default TerrainSourceCache; From cd34a3a8a7b28b54199a05a48dc0abbd6cd458a3 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Oct 2021 15:49:08 +0200 Subject: [PATCH 032/138] fix symbol flickering --- src/render/draw_circle.ts | 2 +- src/render/draw_symbol.ts | 2 +- src/source/terrain_source_cache.ts | 14 +++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/render/draw_circle.ts b/src/render/draw_circle.ts index 7c617a8ccdb..1299ba444ef 100644 --- a/src/render/draw_circle.ts +++ b/src/render/draw_circle.ts @@ -115,7 +115,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt } context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getFramebuffer(painter, "depth").colorAttachment.get()); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getDepthTexture().texture); for (const segmentsState of segmentsRenderStates) { const {programConfiguration, program, layoutVertexBuffer, elevationVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index 32f08b05e03..25faaefe59d 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -402,7 +402,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate } context.activeTexture.set(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getFramebuffer(painter, "depth").colorAttachment.get()); + gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getDepthTexture().texture); if (state.isSDF) { const uniformValues = (state.uniformValues as any as UniformValues); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index eebbfdffcce..09af5b7a3f5 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -30,11 +30,11 @@ class TerrainSourceCache extends Evented { _fbo: any; _fboCoordsTexture: Texture; _fboDepthTexture: Texture; + _emptyDepthTexture: Texture; _mesh: any; _coordsIndex: Array; _coordsTexture: Texture; _coordsTextureSize: number; - _coordsIndexTexture: Texture; _terrainTileCache: {[_: string]: string}; _sourceTileIDs: {[_: string]: OverscaledTileID}; _emptyDem: any; @@ -78,9 +78,9 @@ class TerrainSourceCache extends Evented { mat4.ortho(this._emptyDemMatrix, 0, EXTENT, 0, EXTENT, 0, 1); // create empty coordsIndexTexture - const image = new RGBAImage({width: 256, height: 1}, new Uint8Array(256 * 4)); + const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); - this._coordsIndexTexture = texture; + this._emptyDepthTexture = texture; // rerender corresponding tiles on source-tile updates style.on("data", e => { @@ -379,8 +379,8 @@ class TerrainSourceCache extends Evented { * @returns {Framebuffer} */ getFramebuffer(painter: Painter, texture: string): Framebuffer { - const width = this.isEnabled() ? painter.width / devicePixelRatio : 10; - const height = this.isEnabled() ? painter.height / devicePixelRatio : 10; + const width = painter.width / devicePixelRatio; + const height = painter.height / devicePixelRatio; if (this._fbo && (this._fbo.width != width || this._fbo.height != height)) { this._fbo.destroy(); this._fboCoordsTexture.destroy(); @@ -482,6 +482,10 @@ class TerrainSourceCache extends Evented { texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); return this._coordsTexture = texture; } + + getDepthTexture(): Texture { + return this._fboCoordsTexture || this._emptyDepthTexture; + } } export default TerrainSourceCache; From b838fcd2e29ed57c2bcfff1b8a35a1c07d43cf6e Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Oct 2021 16:06:42 +0200 Subject: [PATCH 033/138] typo --- src/source/terrain_source_cache.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 09af5b7a3f5..e66219784df 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -105,18 +105,18 @@ class TerrainSourceCache extends Evented { } else if (e.coord) { // FIXME! mark only necessary tiles to rerender for (let key in this._tiles) this.getTileByID(key).rerender = true; - // let dz = e.coord.canonical.z - transform.tileZoom; - // let x = e.coord.canonical.x, y = e.coord.canonical.y, wrap = e.coord.wrap, z = transform.tileZoom; - // const sourceTile = this.getSourceTile(dz > 0 ? new OverscaledTileID(z, wrap, z, x >> dz, y >> dz) : e.coord); - // const tile = sourceTile && this.getTileByID(sourceTile.tileID.key); - // if (tile) { - // tile.rerender = true; - // } else if (sourceTile) { - // for (let key in this._tiles) { - // let _tile = this.getTileByID(key); - // if (_tile.tileID.isChildOf(sourceTile.tileID)) _tile.rerender = true; - // } - // } + // let dz = e.coord.canonical.z - transform.tileZoom; + // let x = e.coord.canonical.x, y = e.coord.canonical.y, wrap = e.coord.wrap, z = transform.tileZoom; + // const sourceTile = this.getSourceTile(dz > 0 ? new OverscaledTileID(z, wrap, z, x >> dz, y >> dz) : e.coord); + // const tile = sourceTile && this.getTileByID(sourceTile.tileID.key); + // if (tile) { + // tile.rerender = true; + // } else if (sourceTile) { + // for (let key in this._tiles) { + // let _tile = this.getTileByID(key); + // if (_tile.tileID.isChildOf(sourceTile.tileID)) _tile.rerender = true; + // } + // } } } }); @@ -484,7 +484,7 @@ class TerrainSourceCache extends Evented { } getDepthTexture(): Texture { - return this._fboCoordsTexture || this._emptyDepthTexture; + return this._fboDepthTexture || this._emptyDepthTexture; } } From 3d75e2ffd4cebc53bec122549fa621a7e3ef0da1 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 15 Oct 2021 12:27:05 +0200 Subject: [PATCH 034/138] move symbol/circle/fill_extrusion height calculation to GPU --- src/data/array_types.ts | 1 - src/data/bucket/circle_attributes.ts | 4 - src/data/bucket/circle_bucket.ts | 20 +-- src/data/bucket/fill_extrusion_attributes.ts | 4 +- src/data/bucket/fill_extrusion_bucket.ts | 30 ++-- src/data/bucket/symbol_attributes.ts | 4 - src/data/bucket/symbol_bucket.ts | 23 +-- src/render/draw_background.ts | 3 +- src/render/draw_circle.ts | 28 +--- src/render/draw_collision_debug.ts | 6 +- src/render/draw_debug.ts | 5 +- src/render/draw_fill.ts | 3 +- src/render/draw_fill_extrusion.ts | 17 +-- src/render/draw_heatmap.ts | 6 +- src/render/draw_hillshade.ts | 6 +- src/render/draw_line.ts | 3 +- src/render/draw_raster.ts | 5 +- src/render/draw_symbol.ts | 50 ++----- src/render/draw_terrain.ts | 24 ++- src/render/painter.ts | 5 +- src/render/program.ts | 17 ++- src/render/program/circle_program.ts | 14 +- src/render/program/fill_extrusion_program.ts | 12 +- src/render/program/symbol_program.ts | 22 +-- src/render/program/terrain_program.ts | 87 +++-------- src/shaders/_prelude.vertex.glsl | 26 +++- src/shaders/circle.vertex.glsl | 10 +- src/shaders/fill_extrusion.vertex.glsl | 8 +- .../fill_extrusion_pattern.vertex.glsl | 8 +- src/shaders/symbol_icon.vertex.glsl | 12 +- src/shaders/symbol_sdf.vertex.glsl | 12 +- src/shaders/symbol_text_and_icon.vertex.glsl | 12 +- src/shaders/terrain.fragment.glsl | 3 +- src/shaders/terrain.vertex.glsl | 14 +- src/source/raster_dem_tile_source.ts | 2 - src/source/terrain_source_cache.ts | 140 ++++++++---------- src/source/tile.ts | 6 - 37 files changed, 240 insertions(+), 412 deletions(-) diff --git a/src/data/array_types.ts b/src/data/array_types.ts index 6564ac7e7e2..ff9831ab88f 100644 --- a/src/data/array_types.ts +++ b/src/data/array_types.ts @@ -1061,7 +1061,6 @@ export { StructArrayLayout1f4 as TerrainElevationArray, StructArrayLayout2i4 as FillLayoutArray, StructArrayLayout2i4i12 as FillExtrusionLayoutArray, - StructArrayLayout1f4 as FillExtrusionElevationArray, StructArrayLayout2i4 as HeatmapLayoutArray, StructArrayLayout2i4ub8 as LineLayoutArray, StructArrayLayout2f8 as LineExtLayoutArray, diff --git a/src/data/bucket/circle_attributes.ts b/src/data/bucket/circle_attributes.ts index f37658d6d8f..ed9ebcefa84 100644 --- a/src/data/bucket/circle_attributes.ts +++ b/src/data/bucket/circle_attributes.ts @@ -4,9 +4,5 @@ const layout = createLayout([ {name: 'a_pos', components: 2, type: 'Int16'} ], 4); -export const elevationAttributes = createLayout([ - {name: 'a_ele', components: 1, type: 'Float32'} -], 4); - export default layout; export const {members, size, alignment} = layout; diff --git a/src/data/bucket/circle_bucket.ts b/src/data/bucket/circle_bucket.ts index dbbbc3246e9..71616d40397 100644 --- a/src/data/bucket/circle_bucket.ts +++ b/src/data/bucket/circle_bucket.ts @@ -1,5 +1,5 @@ -import {CircleLayoutArray, CircleElevationArray} from '../array_types'; -import layout, {members as layoutAttributes, elevationAttributes} from './circle_attributes'; +import {CircleLayoutArray} from '../array_types'; +import {members as layoutAttributes} from './circle_attributes'; import SegmentVector from '../segment'; import {ProgramConfigurationSet} from '../program_configuration'; import {TriangleIndexArray} from '../index_array_type'; @@ -25,7 +25,6 @@ import type VertexBuffer from '../../gl/vertex_buffer'; import type Point from '../../util/point'; import type {FeatureStates} from '../../source/source_state'; import type {ImagePosition} from '../../render/image_atlas'; -import { addElevation } from './symbol_bucket'; function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) { layoutVertexArray.emplaceBack( @@ -52,9 +51,6 @@ class CircleBucket implement layoutVertexArray: CircleLayoutArray; layoutVertexBuffer: VertexBuffer; - elevationVertexArray: CircleElevationArray; - elevationVertexBuffer: VertexBuffer; - indexArray: TriangleIndexArray; indexBuffer: IndexBuffer; @@ -63,8 +59,6 @@ class CircleBucket implement segments: SegmentVector; uploaded: boolean; - centroids: Array<{ x: number; y: number; }>; - constructor(options: BucketParameters) { this.zoom = options.zoom; this.overscaling = options.overscaling; @@ -74,12 +68,10 @@ class CircleBucket implement this.hasPattern = false; this.layoutVertexArray = new CircleLayoutArray(); - this.elevationVertexArray = new CircleElevationArray(); this.indexArray = new TriangleIndexArray(); this.segments = new SegmentVector(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id); - this.centroids = []; } populate(features: Array, options: PopulateParameters, canonical: CanonicalTileID) { @@ -138,7 +130,7 @@ class CircleBucket implement } isEmpty() { - return this.layoutVertexArray.length === 0 && this.elevationVertexArray.length === 0; + return this.layoutVertexArray.length === 0; } uploadPending() { @@ -148,7 +140,6 @@ class CircleBucket implement upload(context: Context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, layoutAttributes); - this.elevationVertexBuffer = context.createVertexBuffer(this.elevationVertexArray, elevationAttributes.members, true); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); @@ -161,7 +152,6 @@ class CircleBucket implement this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); - this.elevationVertexBuffer.destroy(); } addFeature(feature: BucketFeature, geometry: Array>, index: number, canonical: CanonicalTileID) { @@ -190,13 +180,9 @@ class CircleBucket implement addCircleVertex(this.layoutVertexArray, x, y, 1, 1); addCircleVertex(this.layoutVertexArray, x, y, -1, 1); - addElevation(this.elevationVertexArray, 0); - this.indexArray.emplaceBack(index, index + 1, index + 2); this.indexArray.emplaceBack(index, index + 3, index + 2); - this.centroids.push({ x: x, y: y }); - segment.vertexLength += 4; segment.primitiveLength += 2; } diff --git a/src/data/bucket/fill_extrusion_attributes.ts b/src/data/bucket/fill_extrusion_attributes.ts index 9ddef2aa7f8..5e3c8fcbdc4 100644 --- a/src/data/bucket/fill_extrusion_attributes.ts +++ b/src/data/bucket/fill_extrusion_attributes.ts @@ -5,8 +5,8 @@ const layout = createLayout([ {name: 'a_normal_ed', components: 4, type: 'Int16'}, ], 4); -export const elevationAttributes = createLayout([ - {name: 'a_ele', components: 1, type: 'Float32'} +export const centroidAttributes = createLayout([ + {name: 'a_centroid', components: 2, type: 'Int16'} ], 4); export default layout; diff --git a/src/data/bucket/fill_extrusion_bucket.ts b/src/data/bucket/fill_extrusion_bucket.ts index 99df2d7b869..7d5ac8a0c8e 100644 --- a/src/data/bucket/fill_extrusion_bucket.ts +++ b/src/data/bucket/fill_extrusion_bucket.ts @@ -1,5 +1,5 @@ -import {FillExtrusionLayoutArray, FillExtrusionElevationArray} from '../array_types'; -import {members as layoutAttributes, elevationAttributes} from './fill_extrusion_attributes'; +import {FillExtrusionLayoutArray, PosArray} from '../array_types'; +import {members as layoutAttributes, centroidAttributes} from './fill_extrusion_attributes'; import SegmentVector from '../segment'; import {ProgramConfigurationSet} from '../program_configuration'; import {TriangleIndexArray} from '../index_array_type'; @@ -61,8 +61,8 @@ class FillExtrusionBucket implements Bucket { layoutVertexArray: FillExtrusionLayoutArray; layoutVertexBuffer: VertexBuffer; - elevationVertexArray: FillExtrusionElevationArray; - elevationVertexBuffer: VertexBuffer; + centroidVertexArray: PosArray; + centroidVertexBuffer: VertexBuffer; indexArray: TriangleIndexArray; indexBuffer: IndexBuffer; @@ -72,7 +72,6 @@ class FillExtrusionBucket implements Bucket { segments: SegmentVector; uploaded: boolean; features: Array; - centroids: Array<{ x: number; y: number; vertexCount: number; }>; constructor(options: BucketParameters) { this.zoom = options.zoom; @@ -83,12 +82,11 @@ class FillExtrusionBucket implements Bucket { this.hasPattern = false; this.layoutVertexArray = new FillExtrusionLayoutArray(); - this.elevationVertexArray = new FillExtrusionElevationArray(); + this.centroidVertexArray = new PosArray(); this.indexArray = new TriangleIndexArray(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.segments = new SegmentVector(); this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id); - this.centroids = []; } populate(features: Array, options: PopulateParameters, canonical: CanonicalTileID) { @@ -134,7 +132,7 @@ class FillExtrusionBucket implements Bucket { } isEmpty() { - return this.layoutVertexArray.length === 0 && this.elevationVertexArray.length === 0; + return this.layoutVertexArray.length === 0 && this.centroidVertexArray.length === 0; } uploadPending() { @@ -144,7 +142,7 @@ class FillExtrusionBucket implements Bucket { upload(context: Context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, layoutAttributes); - this.elevationVertexBuffer = context.createVertexBuffer(this.elevationVertexArray, elevationAttributes.members, true); + this.centroidVertexBuffer = context.createVertexBuffer(this.centroidVertexArray, centroidAttributes.members, true); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); @@ -157,7 +155,7 @@ class FillExtrusionBucket implements Bucket { this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); - this.elevationVertexBuffer.destroy(); + this.centroidVertexBuffer.destroy(); } addFeature(feature: BucketFeature, geometry: Array>, index: number, canonical: CanonicalTileID, imagePositions: {[_: string]: ImagePosition}) { @@ -272,13 +270,11 @@ class FillExtrusionBucket implements Bucket { segment.vertexLength += numVertices; } - // remember polygon centroid to calculate elevation in a later step - this.centroids.push({ - x: Math.floor(centroid.x / centroid.vertexCount), - y: Math.floor(centroid.y / centroid.vertexCount), - vertexCount: centroid.vertexCount - }); - for (let i=0; i; layoutVertexBuffer: VertexBuffer; - elevationVertexBuffer: VertexBuffer; indexBuffer: IndexBuffer; uniformValues: UniformValues; + terrain: any; }; type SegmentsTileRenderState = { @@ -64,31 +63,20 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const bucket: CircleBucket = (tile.getBucket(layer) as any); if (!bucket) continue; - const elevationVertexArray = bucket.elevationVertexArray - const elevationVertexBuffer = bucket.elevationVertexBuffer; - if (bucket && tile.state == "loaded" && !tile.elevation[layer.id]) { - elevationVertexArray.clear(); - for (const centroid of bucket.centroids) { - const elevation = painter.style.terrainSourceCache.getElevation(coord, centroid.x, centroid.y); - addElevation(elevationVertexArray, elevation); - } - elevationVertexBuffer.updateData(elevationVertexArray); - tile.elevation[layer.id] = true; - } - const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('circle', programConfiguration); const layoutVertexBuffer = bucket.layoutVertexBuffer; const indexBuffer = bucket.indexBuffer; + const terrain = painter.style.terrainSourceCache.getTerrain(coord); const uniformValues = circleUniformValues(painter, coord, tile, layer); const state: TileRenderState = { programConfiguration, program, layoutVertexBuffer, - elevationVertexBuffer, indexBuffer, uniformValues, + terrain }; if (sortFeaturesByKey) { @@ -114,17 +102,13 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt segmentsRenderStates.sort((a, b) => a.sortKey - b.sortKey); } - context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, painter.style.terrainSourceCache.getDepthTexture().texture); - for (const segmentsState of segmentsRenderStates) { - const {programConfiguration, program, layoutVertexBuffer, elevationVertexBuffer, indexBuffer, uniformValues} = segmentsState.state; + const {programConfiguration, program, layoutVertexBuffer, indexBuffer, uniformValues, terrain} = segmentsState.state; const segments = segmentsState.segments; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - uniformValues, layer.id, + uniformValues, terrain, layer.id, layoutVertexBuffer, indexBuffer, segments, - layer.paint, painter.transform.zoom, programConfiguration, - elevationVertexBuffer); + layer.paint, painter.transform.zoom, programConfiguration); } } diff --git a/src/render/draw_collision_debug.ts b/src/render/draw_collision_debug.ts index 66c39e77ef6..c1b118957d1 100644 --- a/src/render/draw_collision_debug.ts +++ b/src/render/draw_collision_debug.ts @@ -22,6 +22,7 @@ type TileBatch = { circleOffset: number; transform: mat4; invTransform: mat4; + coord: OverscaledTileID; }; let quadTriangles: QuadTriangleArray; @@ -60,7 +61,8 @@ function drawCollisionDebug(painter: Painter, sourceCache: SourceCache, layer: S circleArray, circleOffset, transform, - invTransform + invTransform, + coord }); circleCount += circleArray.length / 4; // 4 values per circle @@ -75,6 +77,7 @@ function drawCollisionDebug(painter: Painter, sourceCache: SourceCache, layer: S posMatrix, painter.transform, tile), + painter.style.terrainSourceCache.getTerrain(coord), layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, buffers.segments, null, painter.transform.zoom, null, null, buffers.collisionVertexBuffer); @@ -132,6 +135,7 @@ function drawCollisionDebug(painter: Painter, sourceCache: SourceCache, layer: S painter.colorModeForRenderPass(), CullFaceMode.disabled, uniforms, + painter.style.terrainSourceCache.getTerrain(batch.coord), layer.id, vertexBuffer, indexBuffer, diff --git a/src/render/draw_debug.ts b/src/render/draw_debug.ts index 1a76fcacda9..e76b512f20b 100644 --- a/src/render/draw_debug.ts +++ b/src/render/draw_debug.ts @@ -77,13 +77,14 @@ function drawDebugTile(painter, sourceCache, coord: OverscaledTileID) { const stencilMode = StencilMode.disabled; const colorMode = painter.colorModeForRenderPass(); const id = '$debug'; + const terrain = painter.style.terrainSourceCache.getTerrain(coord); context.activeTexture.set(gl.TEXTURE0); // Bind the empty texture for drawing outlines painter.emptyTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - debugUniformValues(posMatrix, Color.red), id, + debugUniformValues(posMatrix, Color.red), terrain, id, painter.debugBuffer, painter.tileBorderIndexBuffer, painter.debugSegments); const tileRawData = sourceCache.getTileByID(coord.key).latestRawTileData; @@ -99,7 +100,7 @@ function drawDebugTile(painter, sourceCache, coord: OverscaledTileID) { drawTextToOverlay(painter, tileLabel); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, ColorMode.alphaBlended, CullFaceMode.disabled, - debugUniformValues(posMatrix, Color.transparent, scaleRatio), id, + debugUniformValues(posMatrix, Color.transparent, scaleRatio), terrain, id, painter.debugBuffer, painter.quadTriangleIndexBuffer, painter.debugSegments); } diff --git a/src/render/draw_fill.ts b/src/render/draw_fill.ts index 4d4a398612b..8abd8e81145 100644 --- a/src/render/draw_fill.ts +++ b/src/render/draw_fill.ts @@ -81,6 +81,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram(programName, programConfiguration); + const terrain = painter.style.terrainSourceCache.getTerrain(coord); if (image) { painter.context.activeTexture.set(gl.TEXTURE0); @@ -117,7 +118,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode } program.draw(painter.context, drawMode, depthMode, - painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, + painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, terrain, layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration); } diff --git a/src/render/draw_fill_extrusion.ts b/src/render/draw_fill_extrusion.ts index 5f057169f4a..969323a6fd6 100644 --- a/src/render/draw_fill_extrusion.ts +++ b/src/render/draw_fill_extrusion.ts @@ -58,18 +58,7 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo const bucket: FillExtrusionBucket = (tile.getBucket(layer) as any); if (!bucket) continue; - const elevationVertexArray = bucket.elevationVertexArray - const elevationVertexBuffer = bucket.elevationVertexBuffer; - if (tile.state == "loaded" && !tile.elevation[layer.id]) { - elevationVertexArray.clear(); - for (const centroid of bucket.centroids) { - const elevation = painter.style.terrainSourceCache.getElevation(coord, centroid.x, centroid.y); - for (let i=0; i); if (state.hasHalo) { uniformValues['u_is_halo'] = 1; - drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, uniformValues); + drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, uniformValues, segmentState.terrain); } uniformValues['u_is_halo'] = 0; } - drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, state.uniformValues); + drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, state.uniformValues, segmentState.terrain); } } -function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues) { +function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues, terrain) { const context = painter.context; const gl = context.gl; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - uniformValues, layer.id, buffers.layoutVertexBuffer, + uniformValues, terrain, layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, segments, layer.paint, painter.transform.zoom, buffers.programConfigurations.get(layer.id), - buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer, buffers.elevationVertexBuffer); + buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer); } diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index acc8b1c354e..e7fd14cf36f 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -27,14 +27,12 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { context.clear({ color: Color.transparent, depth: 1 }); sourceCache._coordsIndex = []; for (const tile of tiles) { - const dem = sourceCache.getDem(tile.tileID); + const terrain = sourceCache.getTerrain(tile.tileID); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, dem.texture); - context.activeTexture.set(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, coords.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainCoordsUniformValues(painter, posMatrix, dem.matrix, 255 - sourceCache._coordsIndex.length, dem.unpackVector, sourceCache.elevationOffset); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + const uniformValues = terrainCoordsUniformValues(posMatrix, 255 - sourceCache._coordsIndex.length); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); sourceCache._coordsIndex.push(tile.tileID.key); } @@ -44,12 +42,10 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); context.clear({ color: Color.transparent, depth: 1 }); for (const tile of tiles) { - const dem = sourceCache.getDem(tile.tileID); - context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, dem.texture); + const terrain = sourceCache.getTerrain(tile.tileID); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainDepthUniformValues(painter, posMatrix, dem.matrix, dem.unpackVector, sourceCache.elevationOffset); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + const uniformValues = terrainDepthUniformValues(posMatrix); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); } context.bindFramebuffer.set(null); @@ -63,17 +59,15 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Ti const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); const program = painter.useProgram('terrain'); const mesh = sourceCache.getTerrainMesh(context); - const dem = sourceCache.getDem(tile.tileID); + const terrain = sourceCache.getTerrain(tile.tileID); context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, dem.texture); - context.activeTexture.set(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, FBOs[tile.tileSize].colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainUniformValues(painter, posMatrix, dem.matrix, dem.unpackVector, sourceCache.elevationOffset); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + const uniformValues = terrainUniformValues(posMatrix); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); } function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile, stack: number) { diff --git a/src/render/painter.ts b/src/render/painter.ts index bd805c09cd0..6af4ba873c0 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -241,7 +241,7 @@ class Painter { this.useProgram('clippingMask').draw(context, gl.TRIANGLES, DepthMode.disabled, this.stencilClearMode, ColorMode.disabled, CullFaceMode.disabled, - clippingMaskUniformValues(matrix), + clippingMaskUniformValues(matrix), this.style.terrainSourceCache.getTerrain(), '$clipping', this.viewportBuffer, this.quadTriangleIndexBuffer, this.viewportSegments); } @@ -268,12 +268,13 @@ class Painter { for (const tileID of tileIDs) { const id = this._tileClippingMaskIDs[tileID.key] = this.nextStencilID++; + const terrain = this.style.terrainSourceCache.getTerrain(tileID); program.draw(context, gl.TRIANGLES, DepthMode.disabled, // Tests will always pass, and ref value will be written to stencil buffer. new StencilMode({func: gl.ALWAYS, mask: 0}, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE), ColorMode.disabled, CullFaceMode.disabled, clippingMaskUniformValues(tileID.posMatrix), - '$clipping', this.tileExtentBuffer, + terrain, '$clipping', this.tileExtentBuffer, this.quadTriangleIndexBuffer, this.tileExtentSegments); } } diff --git a/src/render/program.ts b/src/render/program.ts index e797a6fb169..04b6b7e0fd5 100644 --- a/src/render/program.ts +++ b/src/render/program.ts @@ -13,6 +13,7 @@ import type ColorMode from '../gl/color_mode'; import type CullFaceMode from '../gl/cull_face_mode'; import type {UniformBindings, UniformValues, UniformLocations} from './uniform_binding'; import type {BinderUniform} from '../data/program_configuration'; +import {terrainPreludeUniforms} from './program/terrain_program'; export type DrawMode = WebGLRenderingContext['LINES'] | WebGLRenderingContext['TRIANGLES'] | WebGLRenderingContext['LINE_STRIP']; @@ -31,6 +32,7 @@ class Program { attributes: {[_: string]: number}; numAttributes: number; fixedUniforms: Us; + terrainUniforms: any; binderUniforms: Array; failedToCreate: boolean; @@ -53,10 +55,11 @@ class Program { const dynamicAttrInfo = configuration ? configuration.getBinderAttributes() : []; const allAttrInfo = staticAttrInfo.concat(dynamicAttrInfo); + const preludeUniformsInfo = shaders.prelude.staticUniforms ? getTokenizedAttributesAndUniforms(shaders.prelude.staticUniforms) : []; const staticUniformsInfo = source.staticUniforms ? getTokenizedAttributesAndUniforms(source.staticUniforms) : []; const dynamicUniformsInfo = configuration ? configuration.getBinderUniforms() : []; // remove duplicate uniforms - const uniformList = staticUniformsInfo.concat(dynamicUniformsInfo); + const uniformList = preludeUniformsInfo.concat(staticUniformsInfo).concat(dynamicUniformsInfo); const allUniformsInfo = []; for (const uniform of uniformList) { if (allUniformsInfo.indexOf(uniform) < 0) allUniformsInfo.push(uniform); @@ -120,6 +123,7 @@ class Program { } this.fixedUniforms = fixedUniforms(context, uniformLocations); + this.terrainUniforms = terrainPreludeUniforms(context, uniformLocations); this.binderUniforms = configuration ? configuration.getUniforms(context, uniformLocations) : []; } @@ -130,6 +134,7 @@ class Program { colorMode: Readonly, cullFaceMode: Readonly, uniformValues: UniformValues, + terrain: any, layerID: string, layoutVertexBuffer: VertexBuffer, indexBuffer: IndexBuffer, @@ -151,6 +156,16 @@ class Program { context.setColorMode(colorMode); context.setCullFace(cullFaceMode); + if (terrain) { + context.activeTexture.set(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, terrain.depthTexture); + context.activeTexture.set(gl.TEXTURE3); + gl.bindTexture(gl.TEXTURE_2D, terrain.texture); + for (const name in this.terrainUniforms) { + this.terrainUniforms[name].set(terrain[name]); + } + } + for (const name in this.fixedUniforms) { this.fixedUniforms[name].set(uniformValues[name]); } diff --git a/src/render/program/circle_program.ts b/src/render/program/circle_program.ts index 202016c3c4d..8282a7ba17a 100644 --- a/src/render/program/circle_program.ts +++ b/src/render/program/circle_program.ts @@ -1,4 +1,4 @@ -import {Uniform1i, Uniform1f, Uniform2f, UniformMatrix4f} from '../uniform_binding'; +import {Uniform1i, Uniform1f, Uniform2f, Uniform4f, UniformMatrix4f} from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import type Context from '../../gl/context'; @@ -15,8 +15,6 @@ export type CircleUniformsType = { 'u_extrude_scale': Uniform2f; 'u_device_pixel_ratio': Uniform1f; 'u_matrix': UniformMatrix4f; - 'u_depth': Uniform1i; - 'u_terrain_exaggeration': Uniform1f; }; const circleUniforms = (context: Context, locations: UniformLocations): CircleUniformsType => ({ @@ -25,16 +23,14 @@ const circleUniforms = (context: Context, locations: UniformLocations): CircleUn 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), 'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), - 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_depth': new Uniform1i(context, locations.u_depth), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const circleUniformValues = ( painter: Painter, coord: OverscaledTileID, tile: Tile, - layer: CircleStyleLayer + layer: CircleStyleLayer, ): UniformValues => { const transform = painter.transform; @@ -58,9 +54,7 @@ const circleUniformValues = ( layer.paint.get('circle-translate-anchor')), 'u_pitch_with_map': +(pitchWithMap), 'u_device_pixel_ratio': devicePixelRatio, - 'u_extrude_scale': extrudeScale, - 'u_depth': 0, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_extrude_scale': extrudeScale }; }; diff --git a/src/render/program/fill_extrusion_program.ts b/src/render/program/fill_extrusion_program.ts index 5d9835cd901..8679862681f 100644 --- a/src/render/program/fill_extrusion_program.ts +++ b/src/render/program/fill_extrusion_program.ts @@ -4,6 +4,7 @@ import { Uniform1f, Uniform2f, Uniform3f, + Uniform4f, UniformMatrix4f } from '../uniform_binding'; @@ -24,7 +25,6 @@ export type FillExtrusionUniformsType = { 'u_lightcolor': Uniform3f; 'u_vertical_gradient': Uniform1f; 'u_opacity': Uniform1f; - 'u_terrain_exaggeration': Uniform1f; }; export type FillExtrusionPatternUniformsType = { @@ -42,7 +42,6 @@ export type FillExtrusionPatternUniformsType = { 'u_scale': Uniform3f; 'u_fade': Uniform1f; 'u_opacity': Uniform1f; - 'u_terrain_exaggeration': Uniform1f; }; const fillExtrusionUniforms = (context: Context, locations: UniformLocations): FillExtrusionUniformsType => ({ @@ -51,8 +50,7 @@ const fillExtrusionUniforms = (context: Context, locations: UniformLocations): F 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), 'u_lightcolor': new Uniform3f(context, locations.u_lightcolor), 'u_vertical_gradient': new Uniform1f(context, locations.u_vertical_gradient), - 'u_opacity': new Uniform1f(context, locations.u_opacity), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_opacity': new Uniform1f(context, locations.u_opacity) }); const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): FillExtrusionPatternUniformsType => ({ @@ -69,8 +67,7 @@ const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocati 'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower), 'u_scale': new Uniform3f(context, locations.u_scale), 'u_fade': new Uniform1f(context, locations.u_fade), - 'u_opacity': new Uniform1f(context, locations.u_opacity), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_opacity': new Uniform1f(context, locations.u_opacity) }); const fillExtrusionUniformValues = ( @@ -96,8 +93,7 @@ const fillExtrusionUniformValues = ( 'u_lightintensity': light.properties.get('intensity'), 'u_lightcolor': [lightColor.r, lightColor.g, lightColor.b], 'u_vertical_gradient': +shouldUseVerticalGradient, - 'u_opacity': opacity, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_opacity': opacity }; }; diff --git a/src/render/program/symbol_program.ts b/src/render/program/symbol_program.ts index f4b579802df..d8318c9aa3c 100644 --- a/src/render/program/symbol_program.ts +++ b/src/render/program/symbol_program.ts @@ -23,8 +23,6 @@ export type SymbolIconUniformsType = { 'u_pitch_with_map': Uniform1i; 'u_texsize': Uniform2f; 'u_texture': Uniform1i; - 'u_depth': Uniform1i; - 'u_terrain_exaggeration': Uniform1f; }; export type SymbolSDFUniformsType = { @@ -47,8 +45,6 @@ export type SymbolSDFUniformsType = { 'u_gamma_scale': Uniform1f; 'u_device_pixel_ratio': Uniform1f; 'u_is_halo': Uniform1i; - 'u_depth': Uniform1i; - 'u_terrain_exaggeration': Uniform1f; }; export type symbolTextAndIconUniformsType = { @@ -73,8 +69,6 @@ export type symbolTextAndIconUniformsType = { 'u_gamma_scale': Uniform1f; 'u_device_pixel_ratio': Uniform1f; 'u_is_halo': Uniform1i; - 'u_depth': Uniform1i; - 'u_terrain_exaggeration': Uniform1f; }; const symbolIconUniforms = (context: Context, locations: UniformLocations): SymbolIconUniformsType => ({ @@ -93,9 +87,7 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb 'u_is_text': new Uniform1i(context, locations.u_is_text), 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new Uniform2f(context, locations.u_texsize), - 'u_texture': new Uniform1i(context, locations.u_texture), - 'u_depth': new Uniform1i(context, locations.u_depth), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_texture': new Uniform1i(context, locations.u_texture) }); const symbolSDFUniforms = (context: Context, locations: UniformLocations): SymbolSDFUniformsType => ({ @@ -117,9 +109,7 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo 'u_texture': new Uniform1i(context, locations.u_texture), 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), - 'u_is_halo': new Uniform1i(context, locations.u_is_halo), - 'u_depth': new Uniform1i(context, locations.u_depth), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_is_halo': new Uniform1i(context, locations.u_is_halo) }); const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations): symbolTextAndIconUniformsType => ({ @@ -143,9 +133,7 @@ const symbolTextAndIconUniforms = (context: Context, locations: UniformLocations 'u_texture_icon': new Uniform1i(context, locations.u_texture_icon), 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio), - 'u_is_halo': new Uniform1i(context, locations.u_is_halo), - 'u_depth': new Uniform1i(context, locations.u_depth), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_is_halo': new Uniform1i(context, locations.u_is_halo) }); const symbolIconUniformValues = ( @@ -181,9 +169,7 @@ const symbolIconUniformValues = ( 'u_is_text': +isText, 'u_pitch_with_map': +pitchWithMap, 'u_texsize': texSize, - 'u_texture': 0, - 'u_depth': 2, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_texture': 0 }; }; diff --git a/src/render/program/terrain_program.ts b/src/render/program/terrain_program.ts index 732cb9d335a..67902118f6c 100644 --- a/src/render/program/terrain_program.ts +++ b/src/render/program/terrain_program.ts @@ -5,14 +5,11 @@ import { UniformMatrix4f } from '../uniform_binding'; import type Context from '../../gl/context'; -import type Painter from '../painter'; import type {UniformValues, UniformLocations} from '../../render/uniform_binding'; import {mat4} from 'gl-matrix'; -import { GlyphOffsetArray } from '../../data/array_types'; -export type TerrainUniformsType = { - 'u_matrix': UniformMatrix4f; - 'u_texture': Uniform1i; +export type TerrainPreludeUniformsType = { + 'u_depth': Uniform1i; 'u_terrain': Uniform1i; 'u_terrain_matrix': UniformMatrix4f; 'u_terrain_unpack': Uniform4f; @@ -20,29 +17,23 @@ export type TerrainUniformsType = { 'u_terrain_exaggeration': Uniform1f; }; +export type TerrainUniformsType = { + 'u_matrix': UniformMatrix4f; + 'u_texture': Uniform1i; +}; + export type TerrainDepthUniformsType = { 'u_matrix': UniformMatrix4f; - 'u_terrain': Uniform1i; - 'u_terrain_matrix': UniformMatrix4f; - 'u_terrain_unpack': Uniform4f; - 'u_terrain_offset': Uniform1f; - 'u_terrain_exaggeration': Uniform1f; }; export type TerrainCoordsUniformsType = { 'u_matrix': UniformMatrix4f; 'u_texture': Uniform1i; - 'u_terrain': Uniform1i; - 'u_terrain_matrix': UniformMatrix4f; - 'u_terrain_unpack': Uniform4f; - 'u_terrain_offset': Uniform1f; 'u_terrain_coords_id': Uniform1f; - 'u_terrain_exaggeration': Uniform1f; }; -const terrainUniforms = (context: Context, locations: UniformLocations): TerrainUniformsType => ({ - 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_texture': new Uniform1i(context, locations.u_texture), +const terrainPreludeUniforms = (context: Context, locations: UniformLocations): TerrainPreludeUniformsType => ({ + 'u_depth': new Uniform1i(context, locations.u_depth), 'u_terrain': new Uniform1i(context, locations.u_terrain), 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), @@ -50,73 +41,41 @@ const terrainUniforms = (context: Context, locations: UniformLocations): Terrain 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) }); -const terrainDepthUniforms = (context: Context, locations: UniformLocations): TerrainDepthUniformsType => ({ +const terrainUniforms = (context: Context, locations: UniformLocations): TerrainUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), - 'u_terrain': new Uniform1i(context, locations.u_terrain), - 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), - 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), - 'u_terrain_offset': new Uniform1f(context, locations.u_terrain_offset), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_texture': new Uniform1i(context, locations.u_texture) +}); + +const terrainDepthUniforms = (context: Context, locations: UniformLocations): TerrainDepthUniformsType => ({ + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const terrainCoordsUniforms = (context: Context, locations: UniformLocations): TerrainCoordsUniformsType => ({ 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_texture': new Uniform1i(context, locations.u_texture), - 'u_terrain': new Uniform1i(context, locations.u_terrain), - 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), - 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), - 'u_terrain_offset': new Uniform1f(context, locations.u_terrain_offset), - 'u_terrain_coords_id': new Uniform1f(context, locations.u_terrain_coords_id), - 'u_terrain_exaggeration': new Uniform1f(context, locations.u_terrain_exaggeration) + 'u_terrain_coords_id': new Uniform1f(context, locations.u_terrain_coords_id) }); const terrainUniformValues = ( - painter: Painter, - matrix: mat4, - terrainMatrix: mat4, - unpackVector: Array, - offset: number + matrix: mat4 ): UniformValues => ({ 'u_matrix': matrix, - 'u_terrain': 0, - 'u_terrain_matrix': terrainMatrix, - 'u_terrain_unpack': unpackVector, - 'u_terrain_offset': offset, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration, - 'u_texture': 1 + 'u_texture': 0 }); const terrainDepthUniformValues = ( - painter: Painter, - matrix: mat4, - terrainMatrix: mat4, - unpackVector: Array, - offset: number + matrix: mat4 ): UniformValues => ({ - 'u_matrix': matrix, - 'u_terrain': 0, - 'u_terrain_matrix': terrainMatrix, - 'u_terrain_unpack': unpackVector, - 'u_terrain_offset': offset, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration + 'u_matrix': matrix }); const terrainCoordsUniformValues = ( - painter: Painter, matrix: mat4, - terrainMatrix: mat4, - coordsId: number, - unpackVector: Array, - offset: number + coordsId: number ): UniformValues => ({ 'u_matrix': matrix, - 'u_terrain': 0, - 'u_terrain_matrix': terrainMatrix, - 'u_terrain_unpack': unpackVector, - 'u_terrain_offset': offset, 'u_terrain_coords_id': coordsId / 255, - 'u_terrain_exaggeration': painter.style.terrainSourceCache.exaggeration, - 'u_texture': 1 + 'u_texture': 0 }); -export {terrainUniforms, terrainDepthUniforms, terrainCoordsUniforms, terrainUniformValues, terrainDepthUniformValues, terrainCoordsUniformValues}; +export {terrainUniforms, terrainDepthUniforms, terrainCoordsUniforms, terrainPreludeUniforms, terrainUniformValues, terrainDepthUniformValues, terrainCoordsUniformValues}; diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 45aca504658..b0f79659691 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -72,6 +72,17 @@ vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, return (tile_units_to_pixels * pos + offset) / pattern_size; } +// logic for terrain 3d + +#ifdef TERRAIN3D +uniform sampler2D u_terrain; +uniform mat4 u_terrain_matrix; +uniform vec4 u_terrain_unpack; +uniform float u_terrain_offset; +uniform float u_terrain_exaggeration; +uniform highp sampler2D u_depth; +#endif + // methods for pack/unpack depth value to texture rgba // https://stackoverflow.com/questions/34963366/encode-floating-point-data-in-a-rgba-texture const highp vec4 bitSh = vec4(256. * 256. * 256., 256. * 256., 256., 1.); @@ -83,7 +94,7 @@ highp float unpack(highp vec4 color) { // calculate the visibility of a coordinate in terrain and return an opacity value. // if a coordinate is behind the terrain reduce its opacity -float calculate_visibility(sampler2D u_depth, vec4 pos) { +float calculate_visibility(vec4 pos) { #ifdef TERRAIN3D vec3 frag = pos.xyz / pos.w; vec4 rgba = texture2D(u_depth, frag.xy * 0.5 + 0.5); @@ -93,4 +104,15 @@ float calculate_visibility(sampler2D u_depth, vec4 pos) { #else return 1.0; #endif -} \ No newline at end of file +} + +float get_elevation(vec2 pos) { + #ifdef TERRAIN3D + vec2 coord = (u_terrain_matrix * vec4(pos, 0.0, 1.0)).xy * 0.5 + 0.5; + vec4 rgb = (texture2D(u_terrain, coord) * 255.0) * u_terrain_unpack; + float ele = rgb.r + rgb.g + rgb.b - u_terrain_unpack.a; + return (ele + u_terrain_offset) * u_terrain_exaggeration; + #else + return 0.0; + #endif +} diff --git a/src/shaders/circle.vertex.glsl b/src/shaders/circle.vertex.glsl index 03d678eb640..32f0ad2ee74 100644 --- a/src/shaders/circle.vertex.glsl +++ b/src/shaders/circle.vertex.glsl @@ -4,11 +4,8 @@ uniform bool u_pitch_with_map; uniform vec2 u_extrude_scale; uniform lowp float u_device_pixel_ratio; uniform highp float u_camera_to_center_distance; -uniform highp sampler2D u_depth; -uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; -attribute float a_ele; varying vec3 v_data; varying float v_visibility; @@ -36,7 +33,8 @@ void main(void) { // multiply a_pos by 0.5, since we had it * 2 in order to sneak // in extrusion data vec2 circle_center = floor(a_pos * 0.5); - v_visibility = calculate_visibility(u_depth, u_matrix * vec4(circle_center, a_ele * u_terrain_exaggeration, 1.0)); + float ele = get_elevation(circle_center); + v_visibility = calculate_visibility(u_matrix * vec4(circle_center, ele, 1.0)); if (u_pitch_with_map) { vec2 corner_position = circle_center; @@ -50,9 +48,9 @@ void main(void) { corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance); } - gl_Position = u_matrix * vec4(corner_position, a_ele * u_terrain_exaggeration, 1); + gl_Position = u_matrix * vec4(corner_position, ele, 1); } else { - gl_Position = u_matrix * vec4(circle_center, a_ele * u_terrain_exaggeration, 1); + gl_Position = u_matrix * vec4(circle_center, ele, 1); if (u_scale_with_map) { gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance; diff --git a/src/shaders/fill_extrusion.vertex.glsl b/src/shaders/fill_extrusion.vertex.glsl index bfe18025f2e..be8841fe524 100644 --- a/src/shaders/fill_extrusion.vertex.glsl +++ b/src/shaders/fill_extrusion.vertex.glsl @@ -4,11 +4,10 @@ uniform lowp vec3 u_lightpos; uniform lowp float u_lightintensity; uniform float u_vertical_gradient; uniform lowp float u_opacity; -uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; attribute vec4 a_normal_ed; -attribute float a_ele; +attribute vec2 a_centroid; varying vec4 v_color; @@ -24,8 +23,9 @@ void main() { vec3 normal = a_normal_ed.xyz; - base = max(0.0, a_ele * u_terrain_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation - height = max(0.0, a_ele * u_terrain_exaggeration + height); + float ele = get_elevation(a_centroid); + base = max(0.0, ele + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + height = max(0.0, ele + height); float t = mod(normal.x, 2.0); diff --git a/src/shaders/fill_extrusion_pattern.vertex.glsl b/src/shaders/fill_extrusion_pattern.vertex.glsl index f6e667e1852..248357ab3a8 100644 --- a/src/shaders/fill_extrusion_pattern.vertex.glsl +++ b/src/shaders/fill_extrusion_pattern.vertex.glsl @@ -9,11 +9,10 @@ uniform lowp float u_opacity; uniform vec3 u_lightcolor; uniform lowp vec3 u_lightpos; uniform lowp float u_lightintensity; -uniform lowp float u_terrain_exaggeration; attribute vec2 a_pos; attribute vec4 a_normal_ed; -attribute float a_ele; +attribute vec2 a_centroid; varying vec2 v_pos_a; varying vec2 v_pos_b; @@ -49,8 +48,9 @@ void main() { vec2 display_size_a = (pattern_br_a - pattern_tl_a) / pixel_ratio_from; vec2 display_size_b = (pattern_br_b - pattern_tl_b) / pixel_ratio_to; - base = max(0.0, a_ele * u_terrain_exaggeration + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation - height = max(0.0, a_ele * u_terrain_exaggeration + height); + float ele = get_elevation(a_centroid); + base = max(0.0, ele + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + height = max(0.0, ele + height); float t = mod(normal.x, 2.0); float z = t > 0.0 ? height : base; diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 1b7cc9cfbb5..836e82401d6 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -5,7 +5,6 @@ attribute vec4 a_data; attribute vec4 a_pixeloffset; attribute vec3 a_projected_pos; attribute float a_fade_opacity; -attribute float a_ele; uniform bool u_is_size_zoom_constant; uniform bool u_is_size_feature_constant; @@ -22,8 +21,6 @@ uniform mat4 u_coord_matrix; uniform bool u_is_text; uniform bool u_pitch_with_map; uniform vec2 u_texsize; -uniform highp sampler2D u_depth; -uniform lowp float u_terrain_exaggeration; varying vec2 v_tex; varying float v_fade_opacity; @@ -43,6 +40,7 @@ void main() { vec2 a_pxoffset = a_pixeloffset.xy; vec2 a_minFontScale = a_pixeloffset.zw / 256.0; + float ele = get_elevation(a_pos); highp float segment_angle = -a_projected_pos[2]; float size; @@ -54,7 +52,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_terrain_exaggeration, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, ele, 1); highp float camera_to_anchor_distance = projectedPoint.w; // See comments in symbol_sdf.vertex highp float distance_ratio = u_pitch_with_map ? @@ -72,7 +70,7 @@ void main() { highp float symbol_rotation = 0.0; if (u_rotate_symbol) { // See comments in symbol_sdf.vertex - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_terrain_exaggeration, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), ele, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -84,13 +82,13 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_terrain_exaggeration, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, ele, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), z, 1.0); v_tex = a_tex / u_texsize; vec2 fade_opacity = unpack_opacity(a_fade_opacity); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; - float visibility = calculate_visibility(u_depth, projectedPoint); + float visibility = calculate_visibility(projectedPoint); v_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); } diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index 6972e15f60e..2288b98810b 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -5,7 +5,6 @@ attribute vec4 a_data; attribute vec4 a_pixeloffset; attribute vec3 a_projected_pos; attribute float a_fade_opacity; -attribute float a_ele; // contents of a_size vary based on the type of property value // used for {text,icon}-size. @@ -29,8 +28,6 @@ uniform highp float u_aspect_ratio; uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; -uniform highp sampler2D u_depth; -uniform lowp float u_terrain_exaggeration; varying vec2 v_data0; varying vec3 v_data1; @@ -57,6 +54,7 @@ void main() { float a_size_min = floor(a_size[0] * 0.5); vec2 a_pxoffset = a_pixeloffset.xy; + float ele = get_elevation(a_pos); highp float segment_angle = -a_projected_pos[2]; float size; @@ -68,7 +66,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_terrain_exaggeration, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, ele, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -93,7 +91,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_terrain_exaggeration, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), ele, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -105,13 +103,13 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_terrain_exaggeration, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, ele, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), z, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); - float visibility = calculate_visibility(u_depth, projectedPoint); + float visibility = calculate_visibility(projectedPoint); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index 40800c1ac73..25f1a5d5477 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -4,7 +4,6 @@ attribute vec4 a_pos_offset; attribute vec4 a_data; attribute vec3 a_projected_pos; attribute float a_fade_opacity; -attribute float a_ele; // contents of a_size vary based on the type of property value // used for {text,icon}-size. @@ -29,8 +28,6 @@ uniform highp float u_camera_to_center_distance; uniform float u_fade_change; uniform vec2 u_texsize; uniform vec2 u_texsize_icon; -uniform highp sampler2D u_depth; -uniform lowp float u_terrain_exaggeration; varying vec4 v_data0; varying vec4 v_data1; @@ -57,6 +54,7 @@ void main() { float a_size_min = floor(a_size[0] * 0.5); float is_sdf = a_size[0] - 2.0 * a_size_min; + float ele = get_elevation(a_pos); highp float segment_angle = -a_projected_pos[2]; float size; @@ -68,7 +66,7 @@ void main() { size = u_size; } - vec4 projectedPoint = u_matrix * vec4(a_pos, a_ele * u_terrain_exaggeration, 1); + vec4 projectedPoint = u_matrix * vec4(a_pos, ele, 1); highp float camera_to_anchor_distance = projectedPoint.w; // If the label is pitched with the map, layout is done in pitched space, // which makes labels in the distance smaller relative to viewport space. @@ -93,7 +91,7 @@ void main() { // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units // To figure out that angle in projected space, we draw a short horizontal line in tile // space, project it, and measure its angle in projected space. - vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), a_ele * u_terrain_exaggeration, 1); + vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), ele, 1); vec2 a = projectedPoint.xy / projectedPoint.w; vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w; @@ -105,13 +103,13 @@ void main() { highp float angle_cos = cos(segment_angle + symbol_rotation); mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, a_ele * u_terrain_exaggeration, 1.0); + vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, ele, 1.0); float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), z, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); - float visibility = calculate_visibility(u_depth, projectedPoint); + float visibility = calculate_visibility(projectedPoint); float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change; float interpolated_fade_opacity = max(0.0, min(visibility, fade_opacity[0] + fade_change)); diff --git a/src/shaders/terrain.fragment.glsl b/src/shaders/terrain.fragment.glsl index 6d20bb4a9de..14e2517dab8 100644 --- a/src/shaders/terrain.fragment.glsl +++ b/src/shaders/terrain.fragment.glsl @@ -1,6 +1,5 @@ -precision mediump float; - uniform sampler2D u_texture; + varying vec2 v_texture_pos; void main() { diff --git a/src/shaders/terrain.vertex.glsl b/src/shaders/terrain.vertex.glsl index f30ee54700c..a5a6b00fde5 100644 --- a/src/shaders/terrain.vertex.glsl +++ b/src/shaders/terrain.vertex.glsl @@ -1,24 +1,12 @@ attribute vec2 a_pos; uniform mat4 u_matrix; -uniform sampler2D u_terrain; -uniform mat4 u_terrain_matrix; -uniform vec4 u_terrain_unpack; -uniform float u_terrain_exaggeration; -uniform float u_terrain_offset; varying vec2 v_texture_pos; varying float v_depth; -float getElevation(vec2 coord) { - vec4 rgb = (texture2D(u_terrain, coord) * 255.0) * u_terrain_unpack; - float ele = rgb.r + rgb.g + rgb.b - u_terrain_unpack.a; - return (ele + u_terrain_offset) * u_terrain_exaggeration; -} - void main() { v_texture_pos = a_pos / 8192.0; - vec2 terrain_pos = (u_terrain_matrix * vec4(a_pos, 0.0, 1.0)).xy * 0.5 + 0.5; - gl_Position = u_matrix * vec4(a_pos, getElevation(terrain_pos), 1.0); + gl_Position = u_matrix * vec4(a_pos, get_elevation(a_pos), 1.0); v_depth = gl_Position.z / gl_Position.w; } diff --git a/src/source/raster_dem_tile_source.ts b/src/source/raster_dem_tile_source.ts index d3cf3e68c28..7db9a1ecbee 100644 --- a/src/source/raster_dem_tile_source.ts +++ b/src/source/raster_dem_tile_source.ts @@ -78,8 +78,6 @@ class RasterDEMTileSource extends RasterTileSource implements Source { if (data) { tile.dem = data.dem; - tile.elevationMin = data.dem.min; - tile.elevationMax = data.dem.max; tile.needsHillshadePrepare = true; tile.state = 'loaded'; callback(null); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index e66219784df..8fe64574422 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -35,11 +35,10 @@ class TerrainSourceCache extends Evented { _coordsIndex: Array; _coordsTexture: Texture; _coordsTextureSize: number; - _terrainTileCache: {[_: string]: string}; - _sourceTileIDs: {[_: string]: OverscaledTileID}; _emptyDem: any; _emptyDemTexture: Texture; - _emptyDemMatrix: mat4; + _demMatrixCache: {[_: string]: mat4} + _sourceTileCache: {[_: string]: string}; minzoom: number; maxzoom: number; tileSize: number; @@ -57,8 +56,8 @@ class TerrainSourceCache extends Evented { this._tiles = {}; this._renderableTiles = []; this._loadQueue = []; - this._terrainTileCache = {}; - this._sourceTileIDs = {}; + this._demMatrixCache = {}; + this._sourceTileCache = {}; this._coordsIndex = []; this._coordsTextureSize = 1024; this.minzoom = 0; @@ -74,8 +73,6 @@ class TerrainSourceCache extends Evented { this._emptyDem = new DEMData("0", new RGBAImage({width: 4, height: 4}), "mapbox"); this._emptyDemTexture = new Texture(context, this._emptyDem.getPixels(), context.gl.RGBA, {premultiply: false}); this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - this._emptyDemMatrix = new Float64Array(16) as any; - mat4.ortho(this._emptyDemMatrix, 0, EXTENT, 0, EXTENT, 0, 1); // create empty coordsIndexTexture const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); @@ -96,12 +93,6 @@ class TerrainSourceCache extends Evented { } const tile = this.getTileByID(e.coord.key); transform.updateElevation(); - // delete elevationdata from coresponding tile, so that they can be reloaded on next rendering - // FIXME-3D! when symbol-occlusion is moved to GPU, this lines can be removed - for (let s in style.sourceCaches) { - for (let key in style.sourceCaches[s]._tiles) - style.sourceCaches[s]._tiles[key].elevation = {}; - } } else if (e.coord) { // FIXME! mark only necessary tiles to rerender for (let key in this._tiles) this.getTileByID(key).rerender = true; @@ -149,11 +140,6 @@ class TerrainSourceCache extends Evented { tile.textures.forEach(t => t.destroy()); tile.textures = []; } - for (let s in this._style.sourceCaches) { - for (let key in this._style.sourceCaches[s]._tiles) { - this._style.sourceCaches[s]._tiles[key].elevation = {}; - } - } this._tiles = {}; } @@ -179,26 +165,11 @@ class TerrainSourceCache extends Evented { for (const tileID of this.getRenderableTileIds(transform)) { this._renderableTiles.push(tileID.key); delete(outdated[tileID.key]); - if (this._tiles[tileID.key]) continue; - // find parent source tile - const maxzoom = this._sourceCache._source.maxzoom; - const sourceTileID = this._sourceTileIDs[tileID.key] = tileID.overscaledZ > maxzoom ? tileID.scaledTo(maxzoom) : tileID; - // create pos matrix in relation to source tile - tileID.posMatrix = new Float64Array(16) as any; - mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); - const demMatrix = new Float64Array(16) as any; - if (tileID.canonical.z == sourceTileID.canonical.z) { - mat4.ortho(demMatrix, 0, EXTENT, 0, EXTENT, 0, 1); - } else { - const dz = tileID.canonical.z - sourceTileID.canonical.z; - const dx = tileID.canonical.x - (sourceTileID.canonical.x << dz); - const dy = tileID.canonical.y - (sourceTileID.canonical.y << dz); - mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); - mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); + if (! this._tiles[tileID.key]) { + tileID.posMatrix = new Float64Array(16) as any; + mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + this._tiles[tileID.key] = new Tile(tileID, this.tileSize); } - // create new tile - this._tiles[tileID.key] = new Tile(tileID, this.tileSize); - this._tiles[tileID.key].demMatrix = demMatrix; } // free GPU memory from outdated tiles for (const key in outdated) { @@ -250,21 +221,6 @@ class TerrainSourceCache extends Evented { return this._tiles[id]; } - /** - * searches for the corresponding terrain-tile at a given zoomlevel - * @param {OverscaledTileID} tileID - * @param {number} zoom - * @returns {Tile} - */ - getTerrainTile(tileID: OverscaledTileID, zoom: number): Tile { - const z = Math.floor(zoom), cacheKey = z + ":" + tileID.key; - if (this._terrainTileCache[cacheKey]) return this.getTileByID(this._terrainTileCache[cacheKey]); - const canonical = tileID.canonical.z > this.maxzoom ? tileID.scaledTo(this.maxzoom).canonical : tileID.canonical; - const id = new OverscaledTileID(canonical.z > z ? canonical.z : z, tileID.wrap, canonical.z, canonical.x, canonical.y); - this._terrainTileCache[cacheKey] = id.scaledTo(z).key; - return this.getTileByID(this._terrainTileCache[cacheKey]); - } - /** * searches for the corresponding terrain-tiles at a given zoomlevel * @param {OverscaledTileID} tileID @@ -307,14 +263,63 @@ class TerrainSourceCache extends Evented { } /** - * find the sourcetile + * find the covering terrain-dem tile * @param {OverscaledTileID} tileID * @returns {Tile} */ getSourceTile(tileID: OverscaledTileID): Tile { if (!this.isEnabled()) return null; - const coord = this._sourceTileIDs[tileID.key]; - return coord && this._sourceCache.getTileByID(coord.key); + if (!this._sourceTileCache[tileID.key]) { + const maxzoom = this._sourceCache._source.maxzoom; + const sourceTileID = tileID.overscaledZ > maxzoom ? tileID.scaledTo(maxzoom) : tileID; + this._sourceTileCache[tileID.key] = sourceTileID.key; + } + return this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); + } + + /** + * returns a Terrain Object for a tile. Unless the tile corresponds to data, return an flat dem object + * @param {OverscaledTileID} tileID + */ + getTerrain(tileID?: OverscaledTileID): any { + if (!this.isEnabled() || !tileID) return null; + + // find covering dem tile and prepare demTexture + const sourceTile = this.getSourceTile(tileID); + if (sourceTile && sourceTile.dem && !sourceTile.demTexture) { + let context = this._style.map.painter.context; + sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.dim); + if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); + else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); + sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + } + + // create matrix for lookup in dem data + if (!this._demMatrixCache[tileID.key]) { + const dz = tileID.canonical.z - this._sourceCache._source.maxzoom; + const demMatrix = new Float64Array(16) as any; + if (dz > 0) { + const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); + const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); + mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); + mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); + } else { + mat4.ortho(demMatrix, 0, EXTENT, 0, EXTENT, 0, 1); + } + this._demMatrixCache[tileID.key] = demMatrix; + } + + // return uniform values & textures + return { + u_depth: 2, + u_terrain: 3, + u_terrain_matrix: this._demMatrixCache[tileID.key], + u_terrain_unpack: (sourceTile && sourceTile.dem || this._emptyDem).getUnpackVector(), + u_terrain_offset: this.elevationOffset, + u_terrain_exaggeration: this.exaggeration, + texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, + depthTexture: (this._fboDepthTexture || this._emptyDepthTexture).texture, + }; } /** @@ -436,27 +441,6 @@ class TerrainSourceCache extends Evented { }; } - /** - * returns a DEM Object for a tile. Unless the tile has data, return an flat dem object - * @param {OverscaledTileID} tileID - */ - getDem(tileID: OverscaledTileID): any { - const tile = this.getTileByID(tileID.key); - const sourceTile = this.getSourceTile(tileID); - if (sourceTile && sourceTile.dem && !sourceTile.demTexture) { - let context = this._style.map.painter.context; - sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.dim); - if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); - else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); - sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - } - return { - unpackVector: (sourceTile && sourceTile.dem || this._emptyDem).getUnpackVector(), - texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, - matrix: tile && tile.demMatrix || this._emptyDemMatrix, - }; - } - /** * create coords texture, needed to grab coordinates from canvas * encode coords coordinate into 4 bytes: @@ -482,10 +466,6 @@ class TerrainSourceCache extends Evented { texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); return this._coordsTexture = texture; } - - getDepthTexture(): Texture { - return this._fboDepthTexture || this._emptyDepthTexture; - } } export default TerrainSourceCache; diff --git a/src/source/tile.ts b/src/source/tile.ts index 4c453a9a943..9589b95460b 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -92,9 +92,6 @@ class Tile { hasSymbolBuckets: boolean; hasRTLText: boolean; dependencies: any; - elevation: any; - elevationMin: number; - elevationMax: number; textures: Array; /** @@ -113,9 +110,6 @@ class Tile { this.hasSymbolBuckets = false; this.hasRTLText = false; this.dependencies = {}; - this.elevation = {}; - this.elevationMin = 0; - this.elevationMax = 0; this.rerender = false; this.textures = []; From 10c733212c913e5f4d4d0d6084eb6b211970dff3 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 19 Oct 2021 12:30:12 +0200 Subject: [PATCH 035/138] bugfix when rerender tiles, closes #24 --- src/render/painter.ts | 8 +++----- src/source/terrain_source_cache.ts | 9 ++++----- src/source/tile.ts | 7 +++++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/render/painter.ts b/src/render/painter.ts index 6af4ba873c0..bfcfe69f366 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -417,7 +417,7 @@ class Painter { if (isTerrainEnabled) { this.opaquePassCutoff = 0; - // update coords-framebuffer on camera movement + // update coords/depth-framebuffer on camera movement const newTiles = this.style.terrainSourceCache.tilesAfterTime(this.coordsBuffer.renderTime); if (!mat4.equals(this.coordsBuffer.matrix, this.transform.projMatrix) || newTiles.length) { mat4.copy(this.coordsBuffer.matrix, this.transform.projMatrix); @@ -493,18 +493,16 @@ class Painter { prevType = type; const stack = stacks.length - 1, layers = stacks[stack]; for (const tile of this.style.terrainSourceCache.getRenderableTiles(this.transform)) { - const render = tile.rerender || !tile.textures[stack]; prepareTerrain(this, this.style.terrainSourceCache, tile, stack); - if (render) { + if (tile.textures[stack]) { this.context.clear({ color: Color.transparent }); for (let l=0; l 0 ? new OverscaledTileID(z, wrap, z, x >> dz, y >> dz) : e.coord); // const tile = sourceTile && this.getTileByID(sourceTile.tileID.key); // if (tile) { - // tile.rerender = true; + // tile.clearTextures(this._style.map.painter); // } else if (sourceTile) { // for (let key in this._tiles) { // let _tile = this.getTileByID(key); - // if (_tile.tileID.isChildOf(sourceTile.tileID)) _tile.rerender = true; + // if (_tile.tileID.isChildOf(sourceTile.tileID)) _tile.clearTextures(this._style.map.painter); // } // } } diff --git a/src/source/tile.ts b/src/source/tile.ts index 9589b95460b..be109487e55 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -86,7 +86,6 @@ class Tile { reloadCallback: any; resourceTiming: Array; queryPadding: number; - rerender: boolean; symbolFadeHoldUntil: number; hasSymbolBuckets: boolean; @@ -110,7 +109,6 @@ class Tile { this.hasSymbolBuckets = false; this.hasRTLText = false; this.dependencies = {}; - this.rerender = false; this.textures = []; // Counts the number of times a response was already expired when @@ -134,6 +132,11 @@ class Tile { return this.state === 'errored' || this.state === 'loaded' || this.state === 'reloading'; } + clearTextures(painter: any) { + this.textures.forEach(t => painter.saveTileTexture(t)); + this.textures = []; + } + /** * Given a data object with a 'buffers' property, load it into * this tile's elementGroups and buffers properties and set loaded From 11a133b46868672b72f1c5f7a587b82623c1ad9f Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 21 Oct 2021 19:29:46 +0200 Subject: [PATCH 036/138] * free GPU less aggressive * add deltaZoom setting to load less detailed terraintiles * fix bug in _emptyDemTexture * redraw only necesarry tiles (this still has bugs!) --- src/render/draw_terrain.ts | 4 +- src/render/painter.ts | 11 +-- src/source/terrain_source_cache.ts | 111 +++++++++++------------------ src/source/tile.ts | 2 + src/style/style.ts | 2 +- 5 files changed, 51 insertions(+), 79 deletions(-) diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index e7fd14cf36f..3b42f99aa89 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -74,9 +74,9 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: const context = painter.context; const size = tile.tileSize * sourceCache.qualityFactor; // may increase rendering-size for better quality if (!tile.textures[stack]) { - tile.textures[stack] = painter.getTileTexture(size) - || new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); + tile.textures[stack] = painter.getTileTexture(size) || new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); tile.textures[stack].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); + if (stack == 0) sourceCache._renderHistory.push(tile.tileID.key); } // reuse a framebuffer from the framebuffer-stack and attach active texture if (!FBOs[tile.tileSize]) { diff --git a/src/render/painter.ts b/src/render/painter.ts index bfcfe69f366..f875be17d82 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -61,7 +61,6 @@ import type IndexBuffer from '../gl/index_buffer'; import type {DepthRangeType, DepthMaskType, DepthFuncType} from '../gl/types'; import type ResolvedImage from '../style-spec/expression/types/resolved_image'; import type {RGBAImage} from '../util/image'; -import Match from '../style-spec/expression/definitions/match'; export type RenderPass = 'offscreen' | 'opaque' | 'translucent'; @@ -472,7 +471,9 @@ class Painter { this.renderPass = 'translucent'; // the following variables only used when terrain-3d is enabled let prevType = null; - const stacks = []; + const stacks = [], rerender = {}; + const renderableTiles = this.style.terrainSourceCache.getRenderableTiles(this.transform); + renderableTiles.forEach(t => rerender[t.tileID.key] = !t.textures.length); for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; @@ -492,9 +493,9 @@ class Painter { } else if (renderToTexture[prevType] || type == "hillshade") { prevType = type; const stack = stacks.length - 1, layers = stacks[stack]; - for (const tile of this.style.terrainSourceCache.getRenderableTiles(this.transform)) { + for (const tile of renderableTiles) { prepareTerrain(this, this.style.terrainSourceCache, tile, stack); - if (tile.textures[stack]) { + if (rerender[tile.tileID.key]) { this.context.clear({ color: Color.transparent }); for (let l=0; l; _loadQueue: Array; + _renderHistory: Array; _coordsFramebuffer: any; _fbo: any; _fboCoordsTexture: Texture; @@ -35,7 +35,7 @@ class TerrainSourceCache extends Evented { _coordsIndex: Array; _coordsTexture: Texture; _coordsTextureSize: number; - _emptyDem: any; + _emptyDemUnpack: any; _emptyDemTexture: Texture; _demMatrixCache: {[_: string]: mat4} _sourceTileCache: {[_: string]: string}; @@ -46,6 +46,7 @@ class TerrainSourceCache extends Evented { exaggeration: number; elevationOffset: number; qualityFactor: number; + deltaZoom: number; /** * @param {Style} style @@ -56,6 +57,7 @@ class TerrainSourceCache extends Evented { this._tiles = {}; this._renderableTiles = []; this._loadQueue = []; + this._renderHistory = []; this._demMatrixCache = {}; this._sourceTileCache = {}; this._coordsIndex = []; @@ -66,12 +68,13 @@ class TerrainSourceCache extends Evented { this.meshSize = 128; this.exaggeration = 1.0; this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. - this.qualityFactor = 2; + this.qualityFactor = 2; // render more pixels per tile, value must be a power of two + this.deltaZoom = 1; // set to a value between 0 and 2 // create empty DEM Obejcts const context = style.map.painter.context; - this._emptyDem = new DEMData("0", new RGBAImage({width: 4, height: 4}), "mapbox"); - this._emptyDemTexture = new Texture(context, this._emptyDem.getPixels(), context.gl.RGBA, {premultiply: false}); + this._emptyDemUnpack = [0, 0, 0, 0]; + this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); // create empty coordsIndexTexture @@ -81,32 +84,25 @@ class TerrainSourceCache extends Evented { // rerender corresponding tiles on source-tile updates style.on("data", e => { - if (e.dataType == "source" && e.tile && this.isEnabled()) { + if (e.dataType == "source" && e.coord && this.isEnabled()) { const transform = style.map.transform; if (e.sourceId == this._sourceCache.id) { for (const key in this._tiles) { const tile = this._tiles[key]; + // redraw current and overscaled tiles if (tile.tileID.equals(e.coord) || tile.tileID.isChildOf(e.coord)) { tile.timeLoaded = Date.now(); tile.clearTextures(this._style.map.painter); } } transform.updateElevation(); - } else if (e.coord) { - // FIXME! mark only necessary tiles to rerender - for (let key in this._tiles) this.getTileByID(key).clearTextures(this._style.map.painter); - // let dz = e.coord.canonical.z - transform.tileZoom; - // let x = e.coord.canonical.x, y = e.coord.canonical.y, wrap = e.coord.wrap, z = transform.tileZoom; - // const sourceTile = this.getSourceTile(dz > 0 ? new OverscaledTileID(z, wrap, z, x >> dz, y >> dz) : e.coord); - // const tile = sourceTile && this.getTileByID(sourceTile.tileID.key); - // if (tile) { - // tile.clearTextures(this._style.map.painter); - // } else if (sourceTile) { - // for (let key in this._tiles) { - // let _tile = this.getTileByID(key); - // if (_tile.tileID.isChildOf(sourceTile.tileID)) _tile.clearTextures(this._style.map.painter); - // } - // } + } else { + for (let key in this._tiles) { + const tile = this._tiles[key], coord = tile.tileID; + if (coord.equals(e.coord) || coord.isChildOf(e.coord) || e.coord.isChildOf(coord)) { + tile.clearTextures(this._style.map.painter); + } + } } } }); @@ -120,6 +116,7 @@ class TerrainSourceCache extends Evented { enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}): void { sourceCache.usedForTerrain = true; sourceCache._source.roundZoom = false; + sourceCache._source.tileSize = this.tileSize * 2 ** this.deltaZoom; this._sourceCache = sourceCache; ['exaggeration', 'elevationOffset', 'meshSize'].forEach(key => { if (options && options[key] != undefined) this[key] = options[key] @@ -132,7 +129,6 @@ class TerrainSourceCache extends Evented { disable(): void { if (!this._sourceCache) return; this._sourceCache.usedForTerrain = false; - this._sourceCache._source.roundZoom = true; this._sourceCache = null; for (const key in this._tiles) { let tile = this._tiles[key]; @@ -157,26 +153,21 @@ class TerrainSourceCache extends Evented { if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; this._sourceCache.update(transform); transform.updateElevation(); - let outdated = {}; - for (let key in this._tiles) outdated[key] = true; this._renderableTiles = []; // create tiles for current view for (const tileID of this.getRenderableTileIds(transform)) { this._renderableTiles.push(tileID.key); - delete(outdated[tileID.key]); if (! this._tiles[tileID.key]) { tileID.posMatrix = new Float64Array(16) as any; mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); this._tiles[tileID.key] = new Tile(tileID, this.tileSize); } } - // free GPU memory from outdated tiles - for (const key in outdated) { - let tile = this._tiles[key]; - tile.textures.forEach(t => this._style.map.painter.saveTileTexture(t)); - if (tile.demTexture) this._style.map.painter.saveTileTexture(tile.demTexture); - tile.textures = []; - tile.demTexture = null; + // free GPU memory from old tiles (e.g. remove ) + this._renderHistory = this._renderHistory.filter((i, p) => this._renderHistory.indexOf(i) == p); // remove duplicates + while (this._renderHistory.length > 100) { + let tile = this._tiles[this._renderHistory.shift()]; + if (tile) tile.clearTextures(this._style.map.painter); } } @@ -270,8 +261,8 @@ class TerrainSourceCache extends Evented { if (!this.isEnabled()) return null; if (!this._sourceTileCache[tileID.key]) { const maxzoom = this._sourceCache._source.maxzoom; - const sourceTileID = tileID.overscaledZ > maxzoom ? tileID.scaledTo(maxzoom) : tileID; - this._sourceTileCache[tileID.key] = sourceTileID.key; + const z = Math.max(0, tileID.overscaledZ - this.deltaZoom > maxzoom ? maxzoom : tileID.overscaledZ - this.deltaZoom); + this._sourceTileCache[tileID.key] = tileID.scaledTo(z).key; } return this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); } @@ -282,7 +273,6 @@ class TerrainSourceCache extends Evented { */ getTerrain(tileID?: OverscaledTileID): any { if (!this.isEnabled() || !tileID) return null; - // find covering dem tile and prepare demTexture const sourceTile = this.getSourceTile(tileID); if (sourceTile && sourceTile.dem && !sourceTile.demTexture) { @@ -292,32 +282,28 @@ class TerrainSourceCache extends Evented { else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); } - // create matrix for lookup in dem data if (!this._demMatrixCache[tileID.key]) { - const dz = tileID.canonical.z - this._sourceCache._source.maxzoom; const demMatrix = new Float64Array(16) as any; - if (dz > 0) { - const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); - const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); - mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); - mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); - } else { - mat4.ortho(demMatrix, 0, EXTENT, 0, EXTENT, 0, 1); - } + const maxzoom = this._sourceCache._source.maxzoom; + const dz = Math.max(this.deltaZoom, tileID.overscaledZ - 2 - maxzoom); + const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); + const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); + mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); + mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); this._demMatrixCache[tileID.key] = demMatrix; } - // return uniform values & textures return { u_depth: 2, u_terrain: 3, u_terrain_matrix: this._demMatrixCache[tileID.key], - u_terrain_unpack: (sourceTile && sourceTile.dem || this._emptyDem).getUnpackVector(), + u_terrain_unpack: sourceTile && sourceTile.dem && sourceTile.dem.getUnpackVector() || this._emptyDemUnpack, u_terrain_offset: this.elevationOffset, u_terrain_exaggeration: this.exaggeration, texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, depthTexture: (this._fboDepthTexture || this._emptyDepthTexture).texture, + tile: sourceTile }; } @@ -336,30 +322,13 @@ class TerrainSourceCache extends Evented { getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { if (!this.isEnabled()) return this.elevationOffset; if (!(x >= 0 && x <= extent && y >= 0 && y <= extent)) return this.elevationOffset; - // convert tileID to tileID.overscaledZ level - let dz = tileID.overscaledZ - tileID.canonical.z; - if (dz > 0) { - const size = extent >> dz; - const tx = (tileID.canonical.x << dz) + Math.floor(x / size); - const ty = (tileID.canonical.y << dz) + Math.floor(y / size); - tileID = new OverscaledTileID(tileID.overscaledZ, tileID.wrap, tileID.overscaledZ, tx, ty); - x = (x % size) / size * extent; - y = (y % size) / size * extent; - } - // search for sourceTile - dz = tileID.overscaledZ - this._sourceCache._source.maxzoom; - if (dz > 0) { - const size = extent >> dz; - const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); - const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); - tileID = tileID.scaledTo(tileID.overscaledZ - dz); - x = dx * size + x / extent * size; - y = dy * size + y / extent * size; - } - const tile = this._sourceCache.getTileByID(tileID.key); + const terrain = this.getTerrain(tileID); + const pos = vec2.transformMat4([] as any, [x / extent * EXTENT, y / extent * EXTENT], terrain.u_terrain_matrix); + pos[0] = pos[0] * 0.5 + 0.5; + pos[1] = pos[1] * 0.5 + 0.5; // get elevation from dem - let elevation = tile && tile.dem - ? tile.dem.get(Math.floor(x / extent * tile.dem.dim), Math.floor(y / extent * tile.dem.dim)) + let elevation = terrain.tile && terrain.tile.dem + ? terrain.tile.dem.get(Math.floor(pos[0] * terrain.tile.dem.dim), Math.floor(pos[1] * terrain.tile.dem.dim)) : 0; if (elevation > 8191) elevation = 0; // REMOVEME: this hack is for MTK data, because of false nodata values return (elevation + this.elevationOffset); diff --git a/src/source/tile.ts b/src/source/tile.ts index be109487e55..a0dad69a5a9 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -133,7 +133,9 @@ class Tile { } clearTextures(painter: any) { + this.demTexture && painter.saveTileTexture(this.demTexture); this.textures.forEach(t => painter.saveTileTexture(t)); + this.demTexture = null; this.textures = []; } diff --git a/src/style/style.ts b/src/style/style.ts index fc7623116ab..799443cff14 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -1271,10 +1271,10 @@ class Style extends Evented { } _updateSources(transform: Transform) { + this.terrainSourceCache.update(transform); for (const id in this.sourceCaches) { this.sourceCaches[id].update(transform); } - this.terrainSourceCache.update(transform); } _generateCollisionBoxes() { From f819944e8245098ce2bb4cf619714ce52d5229ce Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 3 Nov 2021 08:30:09 +0100 Subject: [PATCH 037/138] bugfix with TerrainSourceCache.deltaZoom --- src/geo/transform.ts | 2 +- src/source/terrain_source_cache.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index bf55c6b0b7c..37308542167 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -477,7 +477,7 @@ class Transform { getElevation(lnglat: LngLat) { const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; if (!tsc.isEnabled()) return 0; - const maxzoom = tsc._sourceCache._source.maxzoom; + const maxzoom = tsc._sourceCache._source.maxzoom + tsc.deltaZoom; const tileZ = maxzoom < this.tileZoom ? maxzoom : this.tileZoom; const tileSize = tsc.tileSize, worldSize = (1 << tileZ) * tileSize; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 246b5d9b29a..ffd11795f00 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -286,7 +286,7 @@ class TerrainSourceCache extends Evented { if (!this._demMatrixCache[tileID.key]) { const demMatrix = new Float64Array(16) as any; const maxzoom = this._sourceCache._source.maxzoom; - const dz = Math.max(this.deltaZoom, tileID.overscaledZ - 2 - maxzoom); + const dz = this.deltaZoom + Math.max(0, tileID.overscaledZ - this.deltaZoom - maxzoom); const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); From eb595ce426c21e769e2371e0c4e8a0604546e16d Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 3 Nov 2021 18:38:12 +0100 Subject: [PATCH 038/138] * bugfix in u_terrain_matrix * remember texture-coords to know which tile has to rerender * disable raster fading if 3d is enabled --- src/render/draw_raster.ts | 1 + src/render/painter.ts | 27 ++++++++++++++++++++++++--- src/source/terrain_source_cache.ts | 9 +-------- src/source/tile.ts | 3 +++ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index 702f66b6336..c33ed88f11b 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -44,6 +44,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty const parentTile = sourceCache.findLoadedParent(coord, 0), fade = getFadeValues(tile, parentTile, sourceCache, layer, painter.transform); + if (painter.style.terrainSourceCache.isEnabled()) fade.opacity = 1; let parentScaleBy, parentTL; diff --git a/src/render/painter.ts b/src/render/painter.ts index f875be17d82..6147b57ffb3 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -385,6 +385,7 @@ class Painter { const coordsAscending: {[_: string]: Array} = {}; const coordsDescending: {[_: string]: Array} = {}; const coordsDescendingInv: {[_: string]: {[_:string]: Array}} = {}; + const coordsDescendingInvStr: {[_: string]: {[_:string]: string}} = {}; const coordsDescendingSymbol: {[_: string]: Array} = {}; for (const id in sourceCaches) { @@ -393,7 +394,7 @@ class Painter { coordsDescending[id] = coordsAscending[id].slice().reverse(); coordsDescendingSymbol[id] = sourceCache.getVisibleCoordinates(true).reverse(); if (isTerrainEnabled) { - coordsDescendingInv[id] = {}; + coordsDescendingInv[id] = {}; for (let c=0; c c.key).sort().join(); + } + } + } this.opaquePassCutoff = Infinity; for (let i = 0; i < layerIds.length; i++) { @@ -473,7 +485,15 @@ class Painter { let prevType = null; const stacks = [], rerender = {}; const renderableTiles = this.style.terrainSourceCache.getRenderableTiles(this.transform); - renderableTiles.forEach(t => rerender[t.tileID.key] = !t.textures.length); + renderableTiles.forEach(tile => { + // rerender if there are more coords to render than in the last rendering + for (let source in coordsDescendingInvStr) { + const coords = coordsDescendingInvStr[source][tile.tileID.key]; + if (coords && coords != tile.textureCoords[source]) tile.clearTextures(this); + } + // rerender if there are no previous renderings + rerender[tile.tileID.key] = !tile.textures.length; + }); for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; @@ -501,7 +521,8 @@ class Painter { const layer = this.style._layers[layers[l]]; const coords = layer.source ? coordsDescendingInv[layer.source][tile.tileID.key] : [tile.tileID]; this._renderTileClippingMasks(layer, coords); - this.renderLayer(this, this.style.sourceCaches[layer.source], layer, coords) + this.renderLayer(this, this.style.sourceCaches[layer.source], layer, coords); + if (layer.source) tile.textureCoords[layer.source] = coordsDescendingInvStr[layer.source][tile.tileID.key]; } } drawTerrain(this, this.style.terrainSourceCache, tile); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index ffd11795f00..5ebcb104f53 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -96,13 +96,6 @@ class TerrainSourceCache extends Evented { } } transform.updateElevation(); - } else { - for (let key in this._tiles) { - const tile = this._tiles[key], coord = tile.tileID; - if (coord.equals(e.coord) || coord.isChildOf(e.coord) || e.coord.isChildOf(coord)) { - tile.clearTextures(this._style.map.painter); - } - } } } }); @@ -286,7 +279,7 @@ class TerrainSourceCache extends Evented { if (!this._demMatrixCache[tileID.key]) { const demMatrix = new Float64Array(16) as any; const maxzoom = this._sourceCache._source.maxzoom; - const dz = this.deltaZoom + Math.max(0, tileID.overscaledZ - this.deltaZoom - maxzoom); + const dz = this.deltaZoom + Math.max(0, tileID.canonical.z - this.deltaZoom - maxzoom); const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); diff --git a/src/source/tile.ts b/src/source/tile.ts index a0dad69a5a9..001bb54c0df 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -92,6 +92,7 @@ class Tile { hasRTLText: boolean; dependencies: any; textures: Array; + textureCoords: {[_: string]: string}; // remeber all coords rendered to textures /** * @param {OverscaledTileID} tileID @@ -110,6 +111,7 @@ class Tile { this.hasRTLText = false; this.dependencies = {}; this.textures = []; + this.textureCoords = {}; // Counts the number of times a response was already expired when // received. We're using this to add a delay when making a new request @@ -137,6 +139,7 @@ class Tile { this.textures.forEach(t => painter.saveTileTexture(t)); this.demTexture = null; this.textures = []; + this.textureCoords = {}; } /** From e8fad6e364214986d14ac38186d87b29dd40ffb5 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 5 Nov 2021 11:16:28 +0100 Subject: [PATCH 039/138] add linear interpolation --- src/geo/transform.ts | 6 ++-- src/render/program/terrain_program.ts | 2 ++ src/shaders/_prelude.vertex.glsl | 24 +++++++++++--- src/source/terrain_source_cache.ts | 46 +++++++++++++-------------- 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 37308542167..d8d6f7eb499 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -477,12 +477,10 @@ class Transform { getElevation(lnglat: LngLat) { const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; if (!tsc.isEnabled()) return 0; - const maxzoom = tsc._sourceCache._source.maxzoom + tsc.deltaZoom; - const tileZ = maxzoom < this.tileZoom ? maxzoom : this.tileZoom; - const tileSize = tsc.tileSize, worldSize = (1 << tileZ) * tileSize; + const tileSize = tsc.tileSize, worldSize = (1 << this.tileZoom) * tileSize; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); - const tileID = new OverscaledTileID(tileZ, 0, tileZ, tileX, tileY); + const tileID = new OverscaledTileID(this.tileZoom, 0, this.tileZoom, tileX, tileY); return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); } diff --git a/src/render/program/terrain_program.ts b/src/render/program/terrain_program.ts index 67902118f6c..9f4c581be27 100644 --- a/src/render/program/terrain_program.ts +++ b/src/render/program/terrain_program.ts @@ -11,6 +11,7 @@ import {mat4} from 'gl-matrix'; export type TerrainPreludeUniformsType = { 'u_depth': Uniform1i; 'u_terrain': Uniform1i; + 'u_terrain_dim': Uniform1f; 'u_terrain_matrix': UniformMatrix4f; 'u_terrain_unpack': Uniform4f; 'u_terrain_offset': Uniform1f; @@ -35,6 +36,7 @@ export type TerrainCoordsUniformsType = { const terrainPreludeUniforms = (context: Context, locations: UniformLocations): TerrainPreludeUniformsType => ({ 'u_depth': new Uniform1i(context, locations.u_depth), 'u_terrain': new Uniform1i(context, locations.u_terrain), + 'u_terrain_dim': new Uniform1f(context, locations.u_terrain_dim), 'u_terrain_matrix': new UniformMatrix4f(context, locations.u_terrain_matrix), 'u_terrain_unpack': new Uniform4f(context, locations.u_terrain_unpack), 'u_terrain_offset': new Uniform1f(context, locations.u_terrain_offset), diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index b0f79659691..ccdbcf9f696 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -76,6 +76,7 @@ vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, #ifdef TERRAIN3D uniform sampler2D u_terrain; +uniform float u_terrain_dim; uniform mat4 u_terrain_matrix; uniform vec4 u_terrain_unpack; uniform float u_terrain_offset; @@ -106,12 +107,27 @@ float calculate_visibility(vec4 pos) { #endif } +float ele(vec2 pos) { + #ifdef TERRAIN3D + vec4 rgb = (texture2D(u_terrain, pos) * 255.0) * u_terrain_unpack; + return rgb.r + rgb.g + rgb.b - u_terrain_unpack.a; + #else + return 0.0; + #endif +} + float get_elevation(vec2 pos) { #ifdef TERRAIN3D - vec2 coord = (u_terrain_matrix * vec4(pos, 0.0, 1.0)).xy * 0.5 + 0.5; - vec4 rgb = (texture2D(u_terrain, coord) * 255.0) * u_terrain_unpack; - float ele = rgb.r + rgb.g + rgb.b - u_terrain_unpack.a; - return (ele + u_terrain_offset) * u_terrain_exaggeration; + vec2 coord = (u_terrain_matrix * vec4(pos, 0.0, 1.0)).xy * u_terrain_dim + 1.0; + vec2 f = fract(coord); + vec2 c = (floor(coord) + 0.5) / (u_terrain_dim + 2.0); // get the pixel center + float d = 1.0 / (u_terrain_dim + 2.0); + float tl = ele(c); + float tr = ele(c + vec2(d, 0.0)); + float bl = ele(c + vec2(0.0, d)); + float br = ele(c + vec2(d, d)); + float elevation = mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y); + return (elevation + u_terrain_offset) * u_terrain_exaggeration; #else return 0.0; #endif diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 5ebcb104f53..37b36f24806 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -9,6 +9,7 @@ import Style from '../style/style'; import Texture from '../render/texture'; import {RGBAImage} from '../util/image'; import {PosArray, TriangleIndexArray} from '../data/array_types'; +import {number as mix} from '../style-spec/util/interpolate.js'; import posAttributes from '../data/pos_attributes'; import SegmentVector from '../data/segment'; import type Transform from '../geo/transform'; @@ -37,7 +38,7 @@ class TerrainSourceCache extends Evented { _coordsTextureSize: number; _emptyDemUnpack: any; _emptyDemTexture: Texture; - _demMatrixCache: {[_: string]: mat4} + _demMatrixCache: {[_: string]: mat4}; _sourceTileCache: {[_: string]: string}; minzoom: number; maxzoom: number; @@ -46,7 +47,6 @@ class TerrainSourceCache extends Evented { exaggeration: number; elevationOffset: number; qualityFactor: number; - deltaZoom: number; /** * @param {Style} style @@ -69,7 +69,6 @@ class TerrainSourceCache extends Evented { this.exaggeration = 1.0; this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. this.qualityFactor = 2; // render more pixels per tile, value must be a power of two - this.deltaZoom = 1; // set to a value between 0 and 2 // create empty DEM Obejcts const context = style.map.painter.context; @@ -108,8 +107,7 @@ class TerrainSourceCache extends Evented { */ enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}): void { sourceCache.usedForTerrain = true; - sourceCache._source.roundZoom = false; - sourceCache._source.tileSize = this.tileSize * 2 ** this.deltaZoom; + sourceCache.tileSize = this.tileSize; this._sourceCache = sourceCache; ['exaggeration', 'elevationOffset', 'meshSize'].forEach(key => { if (options && options[key] != undefined) this[key] = options[key] @@ -254,7 +252,7 @@ class TerrainSourceCache extends Evented { if (!this.isEnabled()) return null; if (!this._sourceTileCache[tileID.key]) { const maxzoom = this._sourceCache._source.maxzoom; - const z = Math.max(0, tileID.overscaledZ - this.deltaZoom > maxzoom ? maxzoom : tileID.overscaledZ - this.deltaZoom); + const z = Math.max(0, tileID.overscaledZ > maxzoom ? maxzoom : tileID.overscaledZ); this._sourceTileCache[tileID.key] = tileID.scaledTo(z).key; } return this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); @@ -270,26 +268,25 @@ class TerrainSourceCache extends Evented { const sourceTile = this.getSourceTile(tileID); if (sourceTile && sourceTile.dem && !sourceTile.demTexture) { let context = this._style.map.painter.context; - sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.dim); + sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.stride); if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); } // create matrix for lookup in dem data if (!this._demMatrixCache[tileID.key]) { - const demMatrix = new Float64Array(16) as any; - const maxzoom = this._sourceCache._source.maxzoom; - const dz = this.deltaZoom + Math.max(0, tileID.canonical.z - this.deltaZoom - maxzoom); + const dz = Math.max(0, tileID.canonical.z - this._sourceCache._source.maxzoom); const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); - mat4.ortho(demMatrix, 0, EXTENT << dz, 0, EXTENT << dz, 0, 1); + const demMatrix = mat4.fromScaling(new Float64Array(16) as any, [1 / (EXTENT << dz), 1 / (EXTENT << dz), 0]); mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); this._demMatrixCache[tileID.key] = demMatrix; - } + } // return uniform values & textures return { u_depth: 2, u_terrain: 3, + u_terrain_dim: sourceTile && sourceTile.dem && sourceTile.dem.dim || 1, u_terrain_matrix: this._demMatrixCache[tileID.key], u_terrain_unpack: sourceTile && sourceTile.dem && sourceTile.dem.getUnpackVector() || this._emptyDemUnpack, u_terrain_offset: this.elevationOffset, @@ -302,10 +299,7 @@ class TerrainSourceCache extends Evented { /** * get the Elevation for given coordinate - * FIXME-3D: - * - make linear interpolation - * - handle negative coordinates - * - interploate below ZL this.maxzoom + * FIXME-3D: handle coordinates outside bounds, e.g. use neighbouring tiles * @param {OverscaledTileID} tileID * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT @@ -314,15 +308,19 @@ class TerrainSourceCache extends Evented { */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { if (!this.isEnabled()) return this.elevationOffset; - if (!(x >= 0 && x <= extent && y >= 0 && y <= extent)) return this.elevationOffset; + if (!(x >= 0 && x < extent && y >= 0 && y < extent)) return this.elevationOffset; + let elevation = 0; const terrain = this.getTerrain(tileID); - const pos = vec2.transformMat4([] as any, [x / extent * EXTENT, y / extent * EXTENT], terrain.u_terrain_matrix); - pos[0] = pos[0] * 0.5 + 0.5; - pos[1] = pos[1] * 0.5 + 0.5; - // get elevation from dem - let elevation = terrain.tile && terrain.tile.dem - ? terrain.tile.dem.get(Math.floor(pos[0] * terrain.tile.dem.dim), Math.floor(pos[1] * terrain.tile.dem.dim)) - : 0; + if (terrain.tile && terrain.tile.dem) { + const pos = vec2.transformMat4([] as any, [x / extent * EXTENT, y / extent * EXTENT], terrain.u_terrain_matrix); + const coord = [ pos[0] * terrain.tile.dem.dim, pos[1] * terrain.tile.dem.dim ]; + const c = [ Math.floor(coord[0]), Math.floor(coord[1]) ]; + const tl = terrain.tile.dem.get(c[0], c[1]); + const tr = terrain.tile.dem.get(c[0], c[1] + 1); + const bl = terrain.tile.dem.get(c[0] + 1, c[1]); + const br = terrain.tile.dem.get(c[0] + 1, c[1] + 1); + elevation = mix(mix(tl, tr, coord[0] - c[0]), mix(bl, br, coord[0] - c[0]), coord[1] - c[1]); + } if (elevation > 8191) elevation = 0; // REMOVEME: this hack is for MTK data, because of false nodata values return (elevation + this.elevationOffset); } From e41daac4a5628698103040b2251ad2930fce624e Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 5 Nov 2021 12:04:38 +0100 Subject: [PATCH 040/138] remove visible tile-boundaries --- src/render/draw_raster.ts | 9 ++++----- src/source/raster_dem_tile_source.ts | 1 + src/source/source_cache.ts | 6 ++++-- src/source/terrain_source_cache.ts | 3 ++- src/source/tile.ts | 1 + 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index c33ed88f11b..c783b1e77e5 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -43,8 +43,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.registerFadeDuration(layer.paint.get('raster-fade-duration')); const parentTile = sourceCache.findLoadedParent(coord, 0), - fade = getFadeValues(tile, parentTile, sourceCache, layer, painter.transform); - if (painter.style.terrainSourceCache.isEnabled()) fade.opacity = 1; + fade = getFadeValues(tile, parentTile, sourceCache, layer, painter); let parentScaleBy, parentTL; @@ -81,16 +80,16 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty } } -function getFadeValues(tile, parentTile, sourceCache, layer, transform) { +function getFadeValues(tile, parentTile, sourceCache, layer, painter) { const fadeDuration = layer.paint.get('raster-fade-duration'); - if (fadeDuration > 0) { + if (!painter.style.terrainSourceCache.isEnabled() && fadeDuration > 0) { const now = browser.now(); const sinceTile = (now - tile.timeAdded) / fadeDuration; const sinceParent = parentTile ? (now - parentTile.timeAdded) / fadeDuration : -1; const source = sourceCache.getSource(); - const idealZ = transform.coveringZoomLevel({ + const idealZ = painter.transform.coveringZoomLevel({ tileSize: source.tileSize, roundZoom: source.roundZoom }); diff --git a/src/source/raster_dem_tile_source.ts b/src/source/raster_dem_tile_source.ts index 7db9a1ecbee..b9a35d70794 100644 --- a/src/source/raster_dem_tile_source.ts +++ b/src/source/raster_dem_tile_source.ts @@ -79,6 +79,7 @@ class RasterDEMTileSource extends RasterTileSource implements Source { if (data) { tile.dem = data.dem; tile.needsHillshadePrepare = true; + tile.needsTerrainPrepare = true; tile.state = 'loaded'; callback(null); } diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 6f398424427..2bd70788e41 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -58,6 +58,7 @@ class SourceCache extends Evented { transform: Transform; used: boolean; usedForTerrain: boolean; + tileSize: number; _state: SourceFeatureState; _loadedParentTiles: {[_: string]: Tile}; @@ -286,6 +287,7 @@ class SourceCache extends Evented { function fillBorder(tile, borderTile) { tile.needsHillshadePrepare = true; + tile.needsTerrainPrepare = true; let dx = borderTile.tileID.canonical.x - tile.tileID.canonical.x; const dy = borderTile.tileID.canonical.y - tile.tileID.canonical.y; const dim = Math.pow(2, tile.tileID.canonical.z); @@ -496,10 +498,10 @@ class SourceCache extends Evented { .map((unwrapped) => new OverscaledTileID(unwrapped.canonical.z, unwrapped.wrap, unwrapped.canonical.z, unwrapped.canonical.x, unwrapped.canonical.y)); } else { idealTileIDs = transform.coveringTiles({ - tileSize: this._source.tileSize, + tileSize: this.usedForTerrain ? this.tileSize : this._source.tileSize, minzoom: this._source.minzoom, maxzoom: this._source.maxzoom, - roundZoom: this._source.roundZoom, + roundZoom: this.usedForTerrain ? false : this._source.roundZoom, reparseOverscaled: this._source.reparseOverscaled }); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 37b36f24806..2e24fe6f79a 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -266,12 +266,13 @@ class TerrainSourceCache extends Evented { if (!this.isEnabled() || !tileID) return null; // find covering dem tile and prepare demTexture const sourceTile = this.getSourceTile(tileID); - if (sourceTile && sourceTile.dem && !sourceTile.demTexture) { + if (sourceTile && sourceTile.dem && (!sourceTile.demTexture || sourceTile.needsTerrainPrepare)) { let context = this._style.map.painter.context; sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.stride); if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + sourceTile.needsTerrainPrepare = false; } // create matrix for lookup in dem data if (!this._demMatrixCache[tileID.key]) { diff --git a/src/source/tile.ts b/src/source/tile.ts index 001bb54c0df..0a53a6c0674 100644 --- a/src/source/tile.ts +++ b/src/source/tile.ts @@ -78,6 +78,7 @@ class Tile { demMatrix: mat4; aborted: boolean; needsHillshadePrepare: boolean; + needsTerrainPrepare: boolean; request: Cancelable; texture: any; fbo: Framebuffer; From 68cad1e079955c790ec76e07c893e9933de03673 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 5 Nov 2021 13:06:58 +0100 Subject: [PATCH 041/138] reimplement deltaZoom --- src/source/terrain_source_cache.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 2e24fe6f79a..74a46555cc9 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -18,6 +18,7 @@ import type Context from '../gl/context'; import type Painter from '../render/painter'; import type RasterDEMTileSource from '../source/raster_dem_tile_source'; import type Framebuffer from '../gl/framebuffer'; +import { warnOnce } from '../util/util'; class TerrainSourceCache extends Evented { _style: Style; @@ -47,6 +48,7 @@ class TerrainSourceCache extends Evented { exaggeration: number; elevationOffset: number; qualityFactor: number; + deltaZoom: number; /** * @param {Style} style @@ -69,6 +71,7 @@ class TerrainSourceCache extends Evented { this.exaggeration = 1.0; this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. this.qualityFactor = 2; // render more pixels per tile, value must be a power of two + this.deltaZoom = 1; // set to a value between 0 and 2 (load load terraintiles in less quality) // create empty DEM Obejcts const context = style.map.painter.context; @@ -107,7 +110,7 @@ class TerrainSourceCache extends Evented { */ enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}): void { sourceCache.usedForTerrain = true; - sourceCache.tileSize = this.tileSize; + sourceCache.tileSize = this.tileSize * 2 ** this.deltaZoom; this._sourceCache = sourceCache; ['exaggeration', 'elevationOffset', 'meshSize'].forEach(key => { if (options && options[key] != undefined) this[key] = options[key] @@ -252,7 +255,8 @@ class TerrainSourceCache extends Evented { if (!this.isEnabled()) return null; if (!this._sourceTileCache[tileID.key]) { const maxzoom = this._sourceCache._source.maxzoom; - const z = Math.max(0, tileID.overscaledZ > maxzoom ? maxzoom : tileID.overscaledZ); + const tilezoom = tileID.overscaledZ - this.deltaZoom; + const z = Math.max(0, tilezoom > maxzoom ? maxzoom : tilezoom); this._sourceTileCache[tileID.key] = tileID.scaledTo(z).key; } return this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); @@ -276,7 +280,14 @@ class TerrainSourceCache extends Evented { } // create matrix for lookup in dem data if (!this._demMatrixCache[tileID.key]) { - const dz = Math.max(0, tileID.canonical.z - this._sourceCache._source.maxzoom); + const maxzoom = this._sourceCache._source.maxzoom; + let dz = tileID.canonical.z - this.deltaZoom <= maxzoom + ? this.deltaZoom + : Math.max(0, tileID.canonical.z - maxzoom); + if (tileID.overscaledZ > tileID.canonical.z) { + if (tileID.canonical.z >= maxzoom) dz = tileID.canonical.z - maxzoom; + else warnOnce("cannot calculate elevation if elevation maxzoom > source.maxzoom") + } const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); const demMatrix = mat4.fromScaling(new Float64Array(16) as any, [1 / (EXTENT << dz), 1 / (EXTENT << dz), 0]); From fa57d70b0f8cce6510b8cd312a159958610bd90c Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 5 Nov 2021 16:35:08 +0100 Subject: [PATCH 042/138] fix marker wobbling & check visibility --- src/geo/transform.ts | 3 ++- src/ui/marker.ts | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index d8d6f7eb499..2a51026f052 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -211,6 +211,7 @@ class Transform { if (center.lat === this._center.lat && center.lng === this._center.lng) return; this._unmodified = false; this._center = center; + this._elevation = this.getElevation(center); this._constrain(); this._calcMatrices(); } @@ -476,7 +477,7 @@ class Transform { getElevation(lnglat: LngLat) { const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; - if (!tsc.isEnabled()) return 0; + if (!(tsc && tsc.isEnabled())) return 0; const tileSize = tsc.tileSize, worldSize = (1 << this.tileZoom) * tileSize; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); diff --git a/src/ui/marker.ts b/src/ui/marker.ts index 11ff376359e..860629bfedb 100644 --- a/src/ui/marker.ts +++ b/src/ui/marker.ts @@ -73,6 +73,7 @@ export default class Marker extends Evented { _pitchAlignment: string; _rotationAlignment: string; _originalTabIndex: string; // original tabindex of _element + _opacityTimeout: any; constructor(options?: Options, legacyOptions?: Options) { super(); @@ -468,6 +469,15 @@ export default class Marker extends Evented { } DOM.setTransform(this._element, `${anchorTranslate[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${pitch} ${rotation}`); + + // in case of 3D, ask the the terrain coords-framebuffer for this pos and check if the marker is visible + const tsc = this._map.style.terrainSourceCache; + if (tsc && tsc.isEnabled() && !this._opacityTimeout) this._opacityTimeout = setTimeout(() => { + const lnglat = this._map.unproject(this._pos); + const metresPerPixel = 40075016.686 * Math.abs(Math.cos(this._lngLat.lat * Math.PI/180)) / Math.pow(2, this._map.transform.tileZoom+8); + this._element.style.opacity = lnglat.distanceTo(this._lngLat) > metresPerPixel * 20 ? "0.2" : "1.0"; + this._opacityTimeout = null; + }, 100); } /** From 939a9248b4c8224ebf9b7f87f2881e367cb2565c Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 9 Nov 2021 12:08:49 +0100 Subject: [PATCH 043/138] some code cleanup --- src/data/array_types.ts | 4 -- src/data/bucket/fill_attributes.ts | 4 -- src/data/bucket/symbol_bucket.ts | 12 +++--- src/data/pos3d_attributes.ts | 6 --- src/geo/transform.ts | 2 - src/render/draw_circle.ts | 12 +++--- src/render/painter.ts | 2 +- src/render/program/circle_program.ts | 2 +- src/render/program/fill_extrusion_program.ts | 1 - src/render/program/line_program.ts | 40 ++++++++++---------- src/source/tile_id.ts | 2 +- src/source/worker_source.ts | 3 +- src/style-spec/types.ts | 20 +++++----- src/style/style.ts | 1 - src/util/primitives.ts | 5 +++ 15 files changed, 52 insertions(+), 64 deletions(-) delete mode 100644 src/data/pos3d_attributes.ts diff --git a/src/data/array_types.ts b/src/data/array_types.ts index 1063f64aee8..d46f31e0fd9 100644 --- a/src/data/array_types.ts +++ b/src/data/array_types.ts @@ -1055,11 +1055,8 @@ export { StructArrayLayout1ui2, StructArrayLayout4f16, StructArrayLayout2i4 as PosArray, - StructArrayLayout3i6 as Pos3DArray, StructArrayLayout4i8 as RasterBoundsArray, StructArrayLayout2i4 as CircleLayoutArray, - StructArrayLayout1f4 as CircleElevationArray, - StructArrayLayout1f4 as TerrainElevationArray, StructArrayLayout2i4 as FillLayoutArray, StructArrayLayout2i4i12 as FillExtrusionLayoutArray, StructArrayLayout2i4 as HeatmapLayoutArray, @@ -1069,7 +1066,6 @@ export { StructArrayLayout4i4ui4i24 as SymbolLayoutArray, StructArrayLayout3f12 as SymbolDynamicLayoutArray, StructArrayLayout1ul4 as SymbolOpacityArray, - StructArrayLayout1f4 as SymbolElevationArray, StructArrayLayout2i2i2i12 as CollisionBoxLayoutArray, StructArrayLayout2f1f2i16 as CollisionCircleLayoutArray, StructArrayLayout2ub2f12 as CollisionVertexArray, diff --git a/src/data/bucket/fill_attributes.ts b/src/data/bucket/fill_attributes.ts index f37658d6d8f..ed9ebcefa84 100644 --- a/src/data/bucket/fill_attributes.ts +++ b/src/data/bucket/fill_attributes.ts @@ -4,9 +4,5 @@ const layout = createLayout([ {name: 'a_pos', components: 2, type: 'Int16'} ], 4); -export const elevationAttributes = createLayout([ - {name: 'a_ele', components: 1, type: 'Float32'} -], 4); - export default layout; export const {members, size, alignment} = layout; diff --git a/src/data/bucket/symbol_bucket.ts b/src/data/bucket/symbol_bucket.ts index ecf9a56b066..0d9dd090a88 100644 --- a/src/data/bucket/symbol_bucket.ts +++ b/src/data/bucket/symbol_bucket.ts @@ -58,12 +58,12 @@ import type {FeatureStates} from '../../source/source_state'; import type {ImagePosition} from '../../render/image_atlas'; export type SingleCollisionBox = { - x1: number; - y1: number; - x2: number; - y2: number; - anchorPointX: number; - anchorPointY: number; + x1: number; + y1: number; + x2: number; + y2: number; + anchorPointX: number; + anchorPointY: number; }; export type CollisionArrays = { diff --git a/src/data/pos3d_attributes.ts b/src/data/pos3d_attributes.ts deleted file mode 100644 index a6c17f3904e..00000000000 --- a/src/data/pos3d_attributes.ts +++ /dev/null @@ -1,6 +0,0 @@ -// @flow -import {createLayout} from '../util/struct_array'; - -export default createLayout([ - { name: 'a_pos', type: 'Int16', components: 3 } -]); \ No newline at end of file diff --git a/src/geo/transform.ts b/src/geo/transform.ts index c4969bce054..d892b3e568f 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -35,7 +35,6 @@ class Transform { mercatorMatrix: mat4; projMatrix: mat4; invProjMatrix: mat4; - invProjMatrix2: mat4; alignedProjMatrix: mat4; pixelMatrix: mat4; pixelMatrix2: mat4; @@ -834,7 +833,6 @@ class Transform { mat4.translate(m, m, [0, 0, -elevation]); // elevate camera over terrain this.projMatrix = m; this.pixelMatrix2 = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); - this.invProjMatrix2 = mat4.invert(new Float64Array(16) as any, m); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional diff --git a/src/render/draw_circle.ts b/src/render/draw_circle.ts index b2d96819406..4ffcfbe571b 100644 --- a/src/render/draw_circle.ts +++ b/src/render/draw_circle.ts @@ -19,12 +19,12 @@ import type {CircleUniformsType} from './program/circle_program'; export default drawCircles; type TileRenderState = { - programConfiguration: ProgramConfiguration; - program: Program; - layoutVertexBuffer: VertexBuffer; - indexBuffer: IndexBuffer; - uniformValues: UniformValues; - terrain: any; + programConfiguration: ProgramConfiguration; + program: Program; + layoutVertexBuffer: VertexBuffer; + indexBuffer: IndexBuffer; + uniformValues: UniformValues; + terrain: any; }; type SegmentsTileRenderState = { diff --git a/src/render/painter.ts b/src/render/painter.ts index 6147b57ffb3..edca3fdf42d 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -548,7 +548,7 @@ class Painter { // For symbol layers in the translucent pass, we add extra tiles to the renderable set // for cross-tile symbol fading. Symbol layers don't use tile clipping, so no need to render // separate clipping masks - let coords = (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer.source]; + const coords = (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer.source]; this._renderTileClippingMasks(layer, coordsAscending[layer.source]); this.renderLayer(this, sourceCache, layer, coords); diff --git a/src/render/program/circle_program.ts b/src/render/program/circle_program.ts index 8282a7ba17a..bcbf840fb83 100644 --- a/src/render/program/circle_program.ts +++ b/src/render/program/circle_program.ts @@ -30,7 +30,7 @@ const circleUniformValues = ( painter: Painter, coord: OverscaledTileID, tile: Tile, - layer: CircleStyleLayer, + layer: CircleStyleLayer ): UniformValues => { const transform = painter.transform; diff --git a/src/render/program/fill_extrusion_program.ts b/src/render/program/fill_extrusion_program.ts index 8679862681f..0983128494c 100644 --- a/src/render/program/fill_extrusion_program.ts +++ b/src/render/program/fill_extrusion_program.ts @@ -4,7 +4,6 @@ import { Uniform1f, Uniform2f, Uniform3f, - Uniform4f, UniformMatrix4f } from '../uniform_binding'; diff --git a/src/render/program/line_program.ts b/src/render/program/line_program.ts index b53bdc09e15..e923199e3a2 100644 --- a/src/render/program/line_program.ts +++ b/src/render/program/line_program.ts @@ -95,10 +95,10 @@ const lineSDFUniforms = (context: Context, locations: UniformLocations): LineSDF }); const lineUniformValues = ( - painter: Painter, - tile: Tile, - layer: LineStyleLayer, - coord: OverscaledTileID + painter: Painter, + tile: Tile, + layer: LineStyleLayer, + coord: OverscaledTileID ): UniformValues => { const transform = painter.transform; @@ -114,11 +114,11 @@ const lineUniformValues = ( }; const lineGradientUniformValues = ( - painter: Painter, - tile: Tile, - layer: LineStyleLayer, - imageHeight: number, - coord: OverscaledTileID + painter: Painter, + tile: Tile, + layer: LineStyleLayer, + imageHeight: number, + coord: OverscaledTileID ): UniformValues => { return extend(lineUniformValues(painter, tile, layer, coord), { 'u_image': 0, @@ -127,11 +127,11 @@ const lineGradientUniformValues = ( }; const linePatternUniformValues = ( - painter: Painter, - tile: Tile, - layer: LineStyleLayer, - crossfade: CrossfadeParameters, - coord: OverscaledTileID + painter: Painter, + tile: Tile, + layer: LineStyleLayer, + crossfade: CrossfadeParameters, + coord: OverscaledTileID ): UniformValues => { const transform = painter.transform; const tileZoomRatio = calculateTileRatio(tile, transform); @@ -152,12 +152,12 @@ const linePatternUniformValues = ( }; const lineSDFUniformValues = ( - painter: Painter, - tile: Tile, - layer: LineStyleLayer, - dasharray: CrossFaded>, - crossfade: CrossfadeParameters, - coord: OverscaledTileID + painter: Painter, + tile: Tile, + layer: LineStyleLayer, + dasharray: CrossFaded>, + crossfade: CrossfadeParameters, + coord: OverscaledTileID ): UniformValues => { const transform = painter.transform; const lineAtlas = painter.lineAtlas; diff --git a/src/source/tile_id.ts b/src/source/tile_id.ts index 572857ba14d..980b8dbd645 100644 --- a/src/source/tile_id.ts +++ b/src/source/tile_id.ts @@ -86,7 +86,7 @@ export class OverscaledTileID { } clone() { - return new OverscaledTileID(this.overscaledZ, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y); + return new OverscaledTileID(this.overscaledZ, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y); } equals(id: OverscaledTileID) { diff --git a/src/source/worker_source.ts b/src/source/worker_source.ts index c177c1aa2ce..0b10650251a 100644 --- a/src/source/worker_source.ts +++ b/src/source/worker_source.ts @@ -6,6 +6,7 @@ import type {OverscaledTileID} from './tile_id'; import type {Bucket} from '../data/bucket'; import type FeatureIndex from '../data/feature_index'; import type {CollisionBoxArray} from '../data/array_types'; +import type DEMData from '../data/dem_data'; import type {StyleGlyph} from '../style/style_glyph'; import type {StyleImage} from '../style/style_image'; import type {PromoteIdSpecification} from '../style-spec/types'; @@ -60,7 +61,7 @@ export type WorkerTileResult = { }; export type WorkerTileCallback = (error?: Error | null, result?: WorkerTileResult | null) => void; -export type WorkerDEMTileCallback = (err?: Error | null, result?: any) => void; +export type WorkerDEMTileCallback = (err?: Error | null, result?: DEMData | null) => void; /** * May be implemented by custom source types to provide code that can be run on diff --git a/src/style-spec/types.ts b/src/style-spec/types.ts index f46c2773681..0b9fa657b40 100644 --- a/src/style-spec/types.ts +++ b/src/style-spec/types.ts @@ -106,16 +106,16 @@ export type RasterSourceSpecification = { }; export type RasterDEMSourceSpecification = { - "type": "raster-dem", - "url"?: string, - "tiles"?: Array, - "bounds"?: [number, number, number, number], - "minzoom"?: number, - "maxzoom"?: number, - "tileSize"?: number, - "attribution"?: string, - "encoding"?: "terrarium" | "mapbox" | "mtk", - "volatile"?: boolean + "type": "raster-dem", + "url"?: string, + "tiles"?: Array, + "bounds"?: [number, number, number, number], + "minzoom"?: number, + "maxzoom"?: number, + "tileSize"?: number, + "attribution"?: string, + "encoding"?: "terrarium" | "mapbox" | "mtk", + "volatile"?: boolean }; export type GeoJSONSourceSpecification = { diff --git a/src/style/style.ts b/src/style/style.ts index 3af7e7f969a..4f43fab7696 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -158,7 +158,6 @@ class Style extends Evented { this._availableImages = []; // make elevation accessible from map.transform - // FIXME-3D! is this the right place to assign this? map.transform.terrainSourceCache = this.terrainSourceCache; this._resetUpdates(); diff --git a/src/util/primitives.ts b/src/util/primitives.ts index dc55c7572ad..7a9d4f6ba44 100644 --- a/src/util/primitives.ts +++ b/src/util/primitives.ts @@ -81,6 +81,11 @@ class Aabb { return pointOnAabb - point[1]; } + distanceZ(point: Array): number { + const pointOnAabb = Math.max(Math.min(this.max[2], point[2]), this.min[2]); + return pointOnAabb - point[2]; + } + // Performs a frustum-aabb intersection test. Returns 0 if there's no intersection, // 1 if shapes are intersecting and 2 if the aabb if fully inside the frustum. intersects(frustum: Frustum): number { From 86b7dbd5f8d01f47927e1b4c214cf318f3d3e682 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 9 Nov 2021 15:34:27 +0100 Subject: [PATCH 044/138] ... --- src/source/raster_dem_tile_worker_source.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source/raster_dem_tile_worker_source.ts b/src/source/raster_dem_tile_worker_source.ts index a2c57eb3594..f08fb1780cd 100644 --- a/src/source/raster_dem_tile_worker_source.ts +++ b/src/source/raster_dem_tile_worker_source.ts @@ -25,7 +25,7 @@ class RasterDEMTileWorkerSource { const dem = new DEMData(uid, imagePixels, encoding); this.loaded = this.loaded || {}; this.loaded[uid] = dem; - callback(null, { dem: dem, mesh: null }); + callback(null, dem); } getImageData(imgBitmap: ImageBitmap): RGBAImage { From 4efafc0846ee290e86de935e6442e9dcd94a2c4e Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 10 Nov 2021 10:09:08 +0100 Subject: [PATCH 045/138] use preloaded terraintiles when zooming in and out --- debug/terrain.html | 5 ++- src/source/raster_dem_tile_source.ts | 2 +- src/source/source_cache.ts | 12 ++++++ src/source/terrain_source_cache.ts | 57 +++++++++++++++++----------- src/ui/map.ts | 4 +- 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/debug/terrain.html b/debug/terrain.html index fd8e9b697ef..9411332ace0 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -23,7 +23,8 @@ zoom: 12.5, center: [11.40416, 47.26475], hash: true, - style: "https://static.maptoolkit.net/styles/toursprung/terrain.json" + style: "https://static.maptoolkit.net/styles/toursprung/terrain.json", + maxZoom: 16 }); map.on("load", () => { @@ -40,6 +41,8 @@ new maplibregl.Marker().setLngLat(e.lngLat).addTo(map); }); +map.addControl(new maplibregl.NavigationControl()); + diff --git a/src/source/raster_dem_tile_source.ts b/src/source/raster_dem_tile_source.ts index b9a35d70794..1185819a516 100644 --- a/src/source/raster_dem_tile_source.ts +++ b/src/source/raster_dem_tile_source.ts @@ -77,7 +77,7 @@ class RasterDEMTileSource extends RasterTileSource implements Source { } if (data) { - tile.dem = data.dem; + tile.dem = data; tile.needsHillshadePrepare = true; tile.needsTerrainPrepare = true; tile.state = 'loaded'; diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 2bd70788e41..446347f4ef3 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -515,6 +515,18 @@ class SourceCache extends Evented { const minCoveringZoom = Math.max(zoom - SourceCache.maxOverzooming, this._source.minzoom); const maxCoveringZoom = Math.max(zoom + SourceCache.maxUnderzooming, this._source.minzoom); + // When sourcecache is used for terrain also load parent tiles to avoid flickering when zooming out + if (this.usedForTerrain) { + const parents = {}; + for (const tileID of idealTileIDs) { + if (tileID.canonical.z > this._source.minzoom) { + const parent = tileID.scaledTo(tileID.canonical.z - 1); + parents[parent.key] = parent; + } + } + idealTileIDs = idealTileIDs.concat(Object.values(parents)); + } + // Retain is a list of tiles that we shouldn't delete, even if they are not // the most ideal tile for the current viewport. This may include tiles like // parent or child tiles that are *already* loaded. diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 74a46555cc9..1523b247dd9 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -39,7 +39,7 @@ class TerrainSourceCache extends Evented { _coordsTextureSize: number; _emptyDemUnpack: any; _emptyDemTexture: Texture; - _demMatrixCache: {[_: string]: mat4}; + _demMatrixCache: {[_: string]: { matrix: mat4, coord: OverscaledTileID }}; _sourceTileCache: {[_: string]: string}; minzoom: number; maxzoom: number; @@ -70,28 +70,32 @@ class TerrainSourceCache extends Evented { this.meshSize = 128; this.exaggeration = 1.0; this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. - this.qualityFactor = 2; // render more pixels per tile, value must be a power of two - this.deltaZoom = 1; // set to a value between 0 and 2 (load load terraintiles in less quality) + this.qualityFactor = 2; // render more pixels per tile (e.g. texture is greater than tileSize), value must be a power of two. + this.deltaZoom = 1; // set to a value between 0 and 2. Load tiles for actual zoomlevel - deltaZoom, which leads in faster 3d rendering with less quality. - // create empty DEM Obejcts + // create empty DEM Obejcts. During the elevation-tiles loading use this objects. const context = style.map.painter.context; this._emptyDemUnpack = [0, 0, 0, 0]; this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - // create empty coordsIndexTexture + // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); this._emptyDepthTexture = texture; - // rerender corresponding tiles on source-tile updates + // rerender corresponding tiles on terrain-dem source-tile updates style.on("data", e => { if (e.dataType == "source" && e.coord && this.isEnabled()) { const transform = style.map.transform; if (e.sourceId == this._sourceCache.id) { + // clean demMatrixCache for all subtiles. This is needed because parent-tiles are used during child loading. + for (const key in this._demMatrixCache) { + if (this._demMatrixCache[key].coord.isChildOf(e.coord)) delete this._demMatrixCache[key]; + } + // redraw current and overscaled terrain-tiles for (const key in this._tiles) { const tile = this._tiles[key]; - // redraw current and overscaled tiles if (tile.tileID.equals(e.coord) || tile.tileID.isChildOf(e.coord)) { tile.timeLoaded = Date.now(); tile.clearTextures(this._style.map.painter); @@ -106,13 +110,13 @@ class TerrainSourceCache extends Evented { /** * * @param {SourceCache} sourceCache - * @param options Allowed options are exaggeration, elevationOffset & meshSize + * @param options Allowed options are exaggeration, elevationOffset */ - enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}): void { + enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number}): void { sourceCache.usedForTerrain = true; sourceCache.tileSize = this.tileSize * 2 ** this.deltaZoom; this._sourceCache = sourceCache; - ['exaggeration', 'elevationOffset', 'meshSize'].forEach(key => { + ['exaggeration', 'elevationOffset'].forEach(key => { if (options && options[key] != undefined) this[key] = options[key] }); } @@ -249,17 +253,24 @@ class TerrainSourceCache extends Evented { /** * find the covering terrain-dem tile * @param {OverscaledTileID} tileID + * @param {boolean} searchForDEM Optinal parameter to search for (parent) souretiles with loaded dem. * @returns {Tile} */ - getSourceTile(tileID: OverscaledTileID): Tile { + getSourceTile(tileID: OverscaledTileID, searchForDEM?: boolean): Tile { if (!this.isEnabled()) return null; - if (!this._sourceTileCache[tileID.key]) { - const maxzoom = this._sourceCache._source.maxzoom; - const tilezoom = tileID.overscaledZ - this.deltaZoom; - const z = Math.max(0, tilezoom > maxzoom ? maxzoom : tilezoom); + const source = this._sourceCache._source; + let z = tileID.overscaledZ - this.deltaZoom; + if (z > source.maxzoom) z = source.maxzoom; + if (z < source.minzoom) return null; + // cache for tileID to terrain-tileID + if (!this._sourceTileCache[tileID.key]) this._sourceTileCache[tileID.key] = tileID.scaledTo(z).key; - } - return this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); + let tile = this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); + // during tile-loading phase look if parent tiles (with loaded dem) are available. + if (!(tile && tile.dem) && searchForDEM) + while (z > source.minzoom && !(tile && tile.dem)) + tile = this._sourceCache.getTileByID(tileID.scaledTo(z--).key); + return tile; } /** @@ -269,7 +280,7 @@ class TerrainSourceCache extends Evented { getTerrain(tileID?: OverscaledTileID): any { if (!this.isEnabled() || !tileID) return null; // find covering dem tile and prepare demTexture - const sourceTile = this.getSourceTile(tileID); + const sourceTile = this.getSourceTile(tileID, true); if (sourceTile && sourceTile.dem && (!sourceTile.demTexture || sourceTile.needsTerrainPrepare)) { let context = this._style.map.painter.context; sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.stride); @@ -281,9 +292,9 @@ class TerrainSourceCache extends Evented { // create matrix for lookup in dem data if (!this._demMatrixCache[tileID.key]) { const maxzoom = this._sourceCache._source.maxzoom; - let dz = tileID.canonical.z - this.deltaZoom <= maxzoom - ? this.deltaZoom - : Math.max(0, tileID.canonical.z - maxzoom); + let dz = sourceTile + ? tileID.canonical.z - sourceTile.tileID.canonical.z + : tileID.canonical.z - this.deltaZoom <= maxzoom ? this.deltaZoom : Math.max(0, tileID.canonical.z - maxzoom); if (tileID.overscaledZ > tileID.canonical.z) { if (tileID.canonical.z >= maxzoom) dz = tileID.canonical.z - maxzoom; else warnOnce("cannot calculate elevation if elevation maxzoom > source.maxzoom") @@ -292,14 +303,14 @@ class TerrainSourceCache extends Evented { const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); const demMatrix = mat4.fromScaling(new Float64Array(16) as any, [1 / (EXTENT << dz), 1 / (EXTENT << dz), 0]); mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); - this._demMatrixCache[tileID.key] = demMatrix; + this._demMatrixCache[tileID.key] = { matrix: demMatrix, coord: tileID }; } // return uniform values & textures return { u_depth: 2, u_terrain: 3, u_terrain_dim: sourceTile && sourceTile.dem && sourceTile.dem.dim || 1, - u_terrain_matrix: this._demMatrixCache[tileID.key], + u_terrain_matrix: this._demMatrixCache[tileID.key].matrix, u_terrain_unpack: sourceTile && sourceTile.dem && sourceTile.dem.getUnpackVector() || this._emptyDemUnpack, u_terrain_offset: this.elevationOffset, u_terrain_exaggeration: this.exaggeration, diff --git a/src/ui/map.ts b/src/ui/map.ts index eff92170c64..7a9cb8809da 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -1539,12 +1539,12 @@ class Map extends Camera { * Loads a 3D terrain mesh, based on a "raster-dem" source. * * @param {string} id The ID of the raster-dem source to use. - * @param options Allowed options are exaggeration, elevationOffset & meshSize + * @param options Allowed options are exaggeration, elevationOffset * @returns {Map} `this` * @example * map.addTerrain('my-data'); */ - addTerrain(id: string, options?: {exaggeration: boolean; elevationOffset: number; meshSize: number}) { + addTerrain(id: string, options?: {exaggeration: boolean; elevationOffset: number}) { this.isSourceLoaded(id); this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); this.style.terrainSourceCache.update(this.transform); From 6e8beabc90834395ddf023ce9b5561257780b7be Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 10 Nov 2021 14:42:14 +0100 Subject: [PATCH 046/138] ... --- src/source/terrain_source_cache.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 1523b247dd9..4b9307a71a3 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -39,6 +39,7 @@ class TerrainSourceCache extends Evented { _coordsTextureSize: number; _emptyDemUnpack: any; _emptyDemTexture: Texture; + _emptyDemMatrix: mat4; _demMatrixCache: {[_: string]: { matrix: mat4, coord: OverscaledTileID }}; _sourceTileCache: {[_: string]: string}; minzoom: number; @@ -78,6 +79,7 @@ class TerrainSourceCache extends Evented { this._emptyDemUnpack = [0, 0, 0, 0]; this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + this._emptyDemMatrix = mat4.identity([] as any); // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); @@ -89,10 +91,6 @@ class TerrainSourceCache extends Evented { if (e.dataType == "source" && e.coord && this.isEnabled()) { const transform = style.map.transform; if (e.sourceId == this._sourceCache.id) { - // clean demMatrixCache for all subtiles. This is needed because parent-tiles are used during child loading. - for (const key in this._demMatrixCache) { - if (this._demMatrixCache[key].coord.isChildOf(e.coord)) delete this._demMatrixCache[key]; - } // redraw current and overscaled terrain-tiles for (const key in this._tiles) { const tile = this._tiles[key]; @@ -290,11 +288,10 @@ class TerrainSourceCache extends Evented { sourceTile.needsTerrainPrepare = false; } // create matrix for lookup in dem data - if (!this._demMatrixCache[tileID.key]) { + const matrixKey = sourceTile && (sourceTile + sourceTile.tileID.key) + tileID.key; + if (matrixKey && !this._demMatrixCache[matrixKey]) { const maxzoom = this._sourceCache._source.maxzoom; - let dz = sourceTile - ? tileID.canonical.z - sourceTile.tileID.canonical.z - : tileID.canonical.z - this.deltaZoom <= maxzoom ? this.deltaZoom : Math.max(0, tileID.canonical.z - maxzoom); + let dz = tileID.canonical.z - sourceTile.tileID.canonical.z; if (tileID.overscaledZ > tileID.canonical.z) { if (tileID.canonical.z >= maxzoom) dz = tileID.canonical.z - maxzoom; else warnOnce("cannot calculate elevation if elevation maxzoom > source.maxzoom") @@ -310,7 +307,7 @@ class TerrainSourceCache extends Evented { u_depth: 2, u_terrain: 3, u_terrain_dim: sourceTile && sourceTile.dem && sourceTile.dem.dim || 1, - u_terrain_matrix: this._demMatrixCache[tileID.key].matrix, + u_terrain_matrix: matrixKey ? this._demMatrixCache[tileID.key].matrix : this._emptyDemMatrix, u_terrain_unpack: sourceTile && sourceTile.dem && sourceTile.dem.getUnpackVector() || this._emptyDemUnpack, u_terrain_offset: this.elevationOffset, u_terrain_exaggeration: this.exaggeration, From 4b76529245f07728ec3a97e853e7471c723367c4 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 10 Nov 2021 14:56:51 +0100 Subject: [PATCH 047/138] bugfix for empty render-to-texture stack --- src/render/painter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/painter.ts b/src/render/painter.ts index edca3fdf42d..01c8480492d 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -512,7 +512,7 @@ class Painter { // render all stack-layers into a texture } else if (renderToTexture[prevType] || type == "hillshade") { prevType = type; - const stack = stacks.length - 1, layers = stacks[stack]; + const stack = stacks.length - 1, layers = stacks[stack] || []; for (const tile of renderableTiles) { prepareTerrain(this, this.style.terrainSourceCache, tile, stack); if (rerender[tile.tileID.key]) { From 9f02eba1fe164a30147aa81c12e155daa00c1050 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 12 Nov 2021 07:39:11 +0100 Subject: [PATCH 048/138] set LOD tile-loading in case of terrain3d --- src/geo/transform.ts | 11 +++++++---- src/util/primitives.ts | 5 ----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index d892b3e568f..3ddfc1428ff 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -343,11 +343,14 @@ class Transform { ): Array { let z = this.coveringZoomLevel(options); const actualZ = z; + const tsc = this.terrainSourceCache; if (options.minzoom !== undefined && z < options.minzoom) return []; if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom; - const centerCoord = MercatorCoordinate.fromLngLat(this.center); + const centerCoord = tsc.isEnabled() + ? this.pointCoordinate(this.getCameraPoint()) + : MercatorCoordinate.fromLngLat(this.center); const numTiles = Math.pow(2, z); const centerPoint = [numTiles * centerCoord.x, numTiles * centerCoord.y, 0]; const cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix, this.worldSize, z); @@ -355,7 +358,7 @@ class Transform { // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level let minZoom = options.minzoom || 0; // Use 0.1 as an epsilon to avoid for explicit == 0.0 floating point checks - if (this.pitch <= 60.0 && this._edgeInsets.top < 0.1) + if (!tsc.isEnabled() && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) minZoom = z; // There should always be a certain number of maximum zoom level tiles surrounding the center location @@ -429,8 +432,8 @@ class Transform { const childY = (y << 1) + (i >> 1); const childZ = it.zoom + 1; let quadrant = it.aabb.quadrant(i); - if (this.terrainSourceCache.isEnabled()) { - let tile = this.terrainSourceCache.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY)); + if (tsc.isEnabled()) { + let tile = tsc.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY)); quadrant = new Aabb( vec3.fromValues(quadrant.min[0], quadrant.min[1], tile && tile.dem ? tile.dem.min - this.elevation : -this.elevation), vec3.fromValues(quadrant.max[0], quadrant.max[1], tile && tile.dem ? Math.max(0, tile.dem.max - this.elevation) : 0) diff --git a/src/util/primitives.ts b/src/util/primitives.ts index 7a9d4f6ba44..dc55c7572ad 100644 --- a/src/util/primitives.ts +++ b/src/util/primitives.ts @@ -81,11 +81,6 @@ class Aabb { return pointOnAabb - point[1]; } - distanceZ(point: Array): number { - const pointOnAabb = Math.max(Math.min(this.max[2], point[2]), this.min[2]); - return pointOnAabb - point[2]; - } - // Performs a frustum-aabb intersection test. Returns 0 if there's no intersection, // 1 if shapes are intersecting and 2 if the aabb if fully inside the frustum. intersects(frustum: Frustum): number { From b490d1a5ec93e9b6b0584c9e5119b241f5265a09 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 17 Nov 2021 12:50:51 +0100 Subject: [PATCH 049/138] avoid double-rendering (because of fading logic) of raster tiles --- src/source/source_cache.ts | 39 ++++++++++++++++++++++++++++++ src/source/terrain_source_cache.ts | 1 - src/ui/map.ts | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 446347f4ef3..d957ed6e986 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -563,6 +563,45 @@ class SourceCache extends Evented { retain[id] = parentsForFading[id]; } } + + // disable fading logic in renderToTexture (e.g. 3D) mode + // e.g. avoid rendering two tiles on the same place + if (this.style.terrainSourceCache && this.style.terrainSourceCache.isEnabled()) { + const idealRasterTileIDs: {[_: string]: OverscaledTileID} = {}; + const missingTileIDs: {[_: string]: OverscaledTileID} = {}; + for (const tileID of idealTileIDs) { + if (this._tiles[tileID.key].hasData()) + idealRasterTileIDs[tileID.key] = tileID; + else + missingTileIDs[tileID.key] = tileID; + } + // search for a complete set of children for each missing tile + for (const key in missingTileIDs) { + const children = missingTileIDs[key].children(this._source.maxzoom); + if (this._tiles[children[0].key] && this._tiles[children[1].key] && this._tiles[children[2].key] && this._tiles[children[3].key]) { + idealRasterTileIDs[children[0].key] = retain[children[0].key] = children[0]; + idealRasterTileIDs[children[1].key] = retain[children[1].key] = children[1]; + idealRasterTileIDs[children[2].key] = retain[children[2].key] = children[2]; + idealRasterTileIDs[children[3].key] = retain[children[3].key] = children[3]; + delete(missingTileIDs[key]); + } + } + // search for parent for each missing tile + for (const key in missingTileIDs) { + const parent = this.findLoadedParent(missingTileIDs[key], this._source.minzoom); + if (parent) { + idealRasterTileIDs[parent.tileID.key] = retain[parent.tileID.key] = parent.tileID; + // remove idealTiles which would be rendered twice + for (const key in idealRasterTileIDs) { + if (idealRasterTileIDs[key].isChildOf(parent.tileID)) delete(idealRasterTileIDs[key]); + } + } + } + // cover all tiles which are not needed + for (const key in this._tiles) { + if (!idealRasterTileIDs[key]) this._coveredTiles[key] = true; + } + } } for (const retainedId in retain) { diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 4b9307a71a3..b7eb52862c8 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -148,7 +148,6 @@ class TerrainSourceCache extends Evented { update(transform: Transform): void { if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; this._sourceCache.update(transform); - transform.updateElevation(); this._renderableTiles = []; // create tiles for current view for (const tileID of this.getRenderableTileIds(transform)) { diff --git a/src/ui/map.ts b/src/ui/map.ts index 7a9cb8809da..1492ff13ca7 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -115,7 +115,7 @@ const defaultMaxZoom = 22; // the default values, but also the valid range const defaultMinPitch = 0; -const defaultMaxPitch = 60; +const defaultMaxPitch = 75; // use this variable to check maxPitch for validity const maxPitchThreshold = 85; From be076a635817697f885ebb1e2a7b5b6d237fdbf1 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 19 Nov 2021 10:07:14 +0100 Subject: [PATCH 050/138] calculate_visibility now checks visibility also some pixels above --- src/shaders/_prelude.vertex.glsl | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index ccdbcf9f696..64a69908ae4 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -93,15 +93,28 @@ highp float unpack(highp vec4 color) { return dot(color , bitShifts); } +// calculate the opacity behind terrain, returns a value between 0 and 1. +highp float depthOpacity(vec3 frag) { + #ifdef TERRAIN3D + // create the delta between frag.z + terrain.z. + highp float d = (unpack(texture2D(u_depth, frag.xy * 0.5 + 0.5)) + 0.0001 - frag.z); + // visibility range is between 0 and 0.002. 0 is visible, 0.002 is fully invisible. + return 1.0 - max(0.0, min(1.0, -d * 500.0)); + #else + return 1.0; + #endif +} + // calculate the visibility of a coordinate in terrain and return an opacity value. // if a coordinate is behind the terrain reduce its opacity float calculate_visibility(vec4 pos) { #ifdef TERRAIN3D vec3 frag = pos.xyz / pos.w; - vec4 rgba = texture2D(u_depth, frag.xy * 0.5 + 0.5); - highp float depth = unpack(rgba); - if ((depth + 0.001) < frag.z) return 0.2; - return 1.0; + // check if coordingate is fully visible + highp float d = depthOpacity(frag); + if (d > 0.95) return 1.0; + // if not, go some pixel above and check it this point is visible + return (d + depthOpacity(frag + vec3(0.0, 0.01, 0.0))) / 2.0; #else return 1.0; #endif From ab0d337b39229b202acb50b9e913b4e5f95f91ca Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 19 Nov 2021 10:10:49 +0100 Subject: [PATCH 051/138] ... --- src/shaders/_prelude.vertex.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 64a69908ae4..6cb130fab50 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -97,7 +97,7 @@ highp float unpack(highp vec4 color) { highp float depthOpacity(vec3 frag) { #ifdef TERRAIN3D // create the delta between frag.z + terrain.z. - highp float d = (unpack(texture2D(u_depth, frag.xy * 0.5 + 0.5)) + 0.0001 - frag.z); + highp float d = unpack(texture2D(u_depth, frag.xy * 0.5 + 0.5)) + 0.0001 - frag.z; // visibility range is between 0 and 0.002. 0 is visible, 0.002 is fully invisible. return 1.0 - max(0.0, min(1.0, -d * 500.0)); #else From 4c4ff8fa45bcdb725d400dc2f0b6efcd2b362dbe Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 25 Nov 2021 15:49:19 +0100 Subject: [PATCH 052/138] add code-documentation --- src/render/draw_terrain.ts | 40 ++++-- src/render/painter.ts | 49 ++++--- src/render/program.ts | 1 + src/shaders/_prelude.vertex.glsl | 2 + src/shaders/symbol_icon.vertex.glsl | 2 +- src/shaders/symbol_sdf.vertex.glsl | 2 +- src/shaders/symbol_text_and_icon.vertex.glsl | 2 +- src/source/terrain_source_cache.ts | 138 ++++++++++++------- 8 files changed, 151 insertions(+), 85 deletions(-) diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 3b42f99aa89..d86631b291f 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -9,16 +9,19 @@ import Texture from './texture'; import Color from '../style-spec/util/color'; import ColorMode from '../gl/color_mode'; -const FBOs = {}; - -function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { +/** + * Redraw the Coords & Depth Framebuffers + * @param {Painter} painter + * @param {sourceCache} sourceCache + */ +function updateTerrainFacilitators(painter, sourceCache: TerrainSourceCache) { const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); const mesh = sourceCache.getTerrainMesh(context); const coords = sourceCache.getCoordsTexture(context); - const tiles = sourceCache.getRenderableTiles(painter.transform); + const tiles = sourceCache.getRenderableTiles(); // draw tile-coords into framebuffer let program = painter.useProgram('terrainCoords'); @@ -52,6 +55,12 @@ function drawTerrainCoords(painter, sourceCache: TerrainSourceCache) { context.viewport.set([0, 0, painter.width, painter.height]); } +/** + * Render, e.g. drape, a render-to-texture tile onto the 3d mesh on screen. + * @param {Painter} painter + * @param {TerrainSourceCache} sourceCache + * @param {Tile} tile + */ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile) { const context = painter.context; const gl = context.gl; @@ -64,32 +73,35 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Ti context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, FBOs[tile.tileSize].colorAttachment.get()); + gl.bindTexture(gl.TEXTURE_2D, sourceCache.rttFramebuffer.colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); const uniformValues = terrainUniformValues(posMatrix); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, "terrain", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); } +/** + * prepare the render-to-texture tile. + * E.g. creates the necessary textures and attach them to the render-to-texture-framebuffer. + * @param {Painter} painter + * @param {TerrainSourceCache} sourceCache + * @param {Tile} tile + * @param {number} stack number of a layer-groop. see painter.ts + */ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile, stack: number) { const context = painter.context; - const size = tile.tileSize * sourceCache.qualityFactor; // may increase rendering-size for better quality + const size = tile.tileSize * sourceCache.qualityFactor; if (!tile.textures[stack]) { tile.textures[stack] = painter.getTileTexture(size) || new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); tile.textures[stack].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); if (stack == 0) sourceCache._renderHistory.push(tile.tileID.key); } - // reuse a framebuffer from the framebuffer-stack and attach active texture - if (!FBOs[tile.tileSize]) { - FBOs[tile.tileSize] = context.createFramebuffer(size, size, true); - FBOs[tile.tileSize].depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, size, size)); - } - FBOs[tile.tileSize].colorAttachment.set(tile.textures[stack].texture); - context.bindFramebuffer.set(FBOs[tile.tileSize].framebuffer); + sourceCache.rttFramebuffer.colorAttachment.set(tile.textures[stack].texture); + context.bindFramebuffer.set(sourceCache.rttFramebuffer.framebuffer); context.viewport.set([0, 0, size, size]); } export { prepareTerrain, drawTerrain, - drawTerrainCoords + updateTerrainFacilitators }; diff --git a/src/render/painter.ts b/src/render/painter.ts index 01c8480492d..d632907660e 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -31,7 +31,7 @@ import raster from './draw_raster'; import background from './draw_background'; import debug, {drawDebugPadding} from './draw_debug'; import custom from './draw_custom'; -import {prepareTerrain, drawTerrain, drawTerrainCoords} from './draw_terrain'; +import {prepareTerrain, drawTerrain, updateTerrainFacilitators} from './draw_terrain'; import {OverscaledTileID} from '../source/tile_id'; const draw = { @@ -124,13 +124,15 @@ class Painter { emptyTexture: Texture; debugOverlayTexture: Texture; debugOverlayCanvas: HTMLCanvasElement; - coordsBuffer: { matrix: mat4; renderTime: number; }; + // this object stores the current camera-matrix and the last render time of + // of the terrain-acilitators. e.g. depth & coords framebuffers + terrainFacilitator: { matrix: mat4; renderTime: number; }; constructor(gl: WebGLRenderingContext, transform: Transform) { this.context = new Context(gl); this.transform = transform; this._tileTextures = {}; - this.coordsBuffer = { matrix: mat4.create(), renderTime: 0 }; + this.terrainFacilitator = { matrix: mat4.create(), renderTime: 0 }; this.setup(); @@ -384,9 +386,12 @@ class Painter { const coordsAscending: {[_: string]: Array} = {}; const coordsDescending: {[_: string]: Array} = {}; + const coordsDescendingSymbol: {[_: string]: Array} = {}; + // this is used for 3d-terrain + // coordsDescendingInv contains a list of all tiles which should be rendered for one render-to-texture tile + // e.g. render 4 raster-tiles with size 256px to the 512px render-to-texture tile const coordsDescendingInv: {[_: string]: {[_:string]: Array}} = {}; const coordsDescendingInvStr: {[_: string]: {[_:string]: string}} = {}; - const coordsDescendingSymbol: {[_: string]: Array} = {}; for (const id in sourceCaches) { const sourceCache = sourceCaches[id]; @@ -404,7 +409,9 @@ class Painter { } } } - // create a string representation of all to render coords for all renderToTexture layers + + // create a string representation of all to tiles rendered to render-to-texture tiles + // this string representation is used to check if tile should be re-rendered. for (const id of layerIds) { const layer = this.style._layers[id], source = layer.source; if (renderToTexture[layer.type]) { @@ -426,14 +433,15 @@ class Painter { } if (isTerrainEnabled) { + // this is disabled, because render-to-texture is rendering all layers from bottom to top. this.opaquePassCutoff = 0; - // update coords/depth-framebuffer on camera movement - const newTiles = this.style.terrainSourceCache.tilesAfterTime(this.coordsBuffer.renderTime); - if (!mat4.equals(this.coordsBuffer.matrix, this.transform.projMatrix) || newTiles.length) { - mat4.copy(this.coordsBuffer.matrix, this.transform.projMatrix); - this.coordsBuffer.renderTime = Date.now(); - drawTerrainCoords(this, this.style.terrainSourceCache); + // update coords/depth-framebuffer on camera movement, ore tile reloading + const newTiles = this.style.terrainSourceCache.tilesAfterTime(this.terrainFacilitator.renderTime); + if (!mat4.equals(this.terrainFacilitator.matrix, this.transform.projMatrix) || newTiles.length) { + mat4.copy(this.terrainFacilitator.matrix, this.transform.projMatrix); + this.terrainFacilitator.renderTime = Date.now(); + updateTerrainFacilitators(this, this.style.terrainSourceCache); } } @@ -484,7 +492,7 @@ class Painter { // the following variables only used when terrain-3d is enabled let prevType = null; const stacks = [], rerender = {}; - const renderableTiles = this.style.terrainSourceCache.getRenderableTiles(this.transform); + const renderableTiles = this.style.terrainSourceCache.getRenderableTiles(); renderableTiles.forEach(tile => { // rerender if there are more coords to render than in the last rendering for (let source in coordsDescendingInvStr) { @@ -501,15 +509,21 @@ class Painter { const type = layer.type; if (isTerrainEnabled) { - - // remember background, fill, line & raster layer to render into texture-batch + // due that switching textures is relatively slow, the render + // layer-by-layer context here is not practicable. To bypass this problem + // this lines of code stack all layers and later render all at once. + // Because of the stylesheet possibility to mixing render-to-texture layers and 'live'-layers + // and 'live'-layers it is necessary to create more stacks. For example + // a symbol-layer is in between of fill-layers. + + // remember background, fill, line & raster layer to render into a stack if (renderToTexture[type]) { if (!prevType || !renderToTexture[prevType]) stacks.push([]); prevType = type; stacks[stacks.length-1].push(layerIds[this.currentLayer]); continue; // rendering is done later, all in once - // render all stack-layers into a texture + // in case a stack is finished render all collected stack-layers into a texture } else if (renderToTexture[prevType] || type == "hillshade") { prevType = type; const stack = stacks.length - 1, layers = stacks[stack] || []; @@ -528,11 +542,14 @@ class Painter { drawTerrain(this, this.style.terrainSourceCache, tile); } + // the hillshading layer is a special case because it changes on every camera-movement + // so rerender it in eny case. + // FIXME-3D! check if rerendering is really necessary, depending on hillshade-illumination-anchor if (type == "hillshade") { stacks.push([layerIds[this.currentLayer]]); for (const tile of renderableTiles) { const coords = coordsDescendingInv[layer.source][tile.tileID.key]; - // FIXME! replace prepareTerrain with hillshading texture from prepareHillshading directly + // FIXME-3D! replace prepareTerrain with hillshading texture from prepareHillshading directly prepareTerrain(this, this.style.terrainSourceCache, tile, stacks.length - 1); this.context.clear({ color: Color.transparent }); this._renderTileClippingMasks(layer, coords); diff --git a/src/render/program.ts b/src/render/program.ts index 04b6b7e0fd5..0a24efb31de 100644 --- a/src/render/program.ts +++ b/src/render/program.ts @@ -156,6 +156,7 @@ class Program { context.setColorMode(colorMode); context.setCullFace(cullFaceMode); + // set varaibles used by the 3d functions defined in _prelude.vertex.glsl if (terrain) { context.activeTexture.set(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, terrain.depthTexture); diff --git a/src/shaders/_prelude.vertex.glsl b/src/shaders/_prelude.vertex.glsl index 6cb130fab50..2ae1de99624 100644 --- a/src/shaders/_prelude.vertex.glsl +++ b/src/shaders/_prelude.vertex.glsl @@ -120,6 +120,7 @@ float calculate_visibility(vec4 pos) { #endif } +// grab an elevation value from a raster-dem texture float ele(vec2 pos) { #ifdef TERRAIN3D vec4 rgb = (texture2D(u_terrain, pos) * 255.0) * u_terrain_unpack; @@ -129,6 +130,7 @@ float ele(vec2 pos) { #endif } +// calculate the elevation with linear interpolation for a coordinate float get_elevation(vec2 pos) { #ifdef TERRAIN3D vec2 coord = (u_terrain_matrix * vec4(pos, 0.0, 1.0)).xy * u_terrain_dim + 1.0; diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 836e82401d6..964cebc3dda 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -83,7 +83,7 @@ void main() { mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, ele, 1.0); - float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. + float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), z, 1.0); v_tex = a_tex / u_texsize; diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index 2288b98810b..3776cb6a3dc 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -104,7 +104,7 @@ void main() { mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, ele, 1.0); - float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. + float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), z, 1.0); float gamma_scale = gl_Position.w; diff --git a/src/shaders/symbol_text_and_icon.vertex.glsl b/src/shaders/symbol_text_and_icon.vertex.glsl index 25f1a5d5477..4d85246acc8 100644 --- a/src/shaders/symbol_text_and_icon.vertex.glsl +++ b/src/shaders/symbol_text_and_icon.vertex.glsl @@ -104,7 +104,7 @@ void main() { mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, ele, 1.0); - float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; // After draping them to texture, no need for this. + float z = float(u_pitch_with_map) * projected_pos.z / projected_pos.w; gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), z, 1.0); float gamma_scale = gl_Position.w; diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index b7eb52862c8..e98369f2f61 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -1,5 +1,3 @@ -// @flow - import {OverscaledTileID} from './tile_id'; import Tile from './tile'; import EXTENT from '../data/extent'; @@ -19,37 +17,81 @@ import type Painter from '../render/painter'; import type RasterDEMTileSource from '../source/raster_dem_tile_source'; import type Framebuffer from '../gl/framebuffer'; import { warnOnce } from '../util/util'; +import VertexBuffer from '../gl/vertex_buffer'; +import IndexBuffer from '../gl/index_buffer'; + + +/** + * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: + * 1) loads raster-dem tiles via the internal sourceCache this._source + * 2) creates a depth-framebuffer, which is used to calculate the visibility of coordinates + * 3) creates a coords-framebuffer, which is used the get to tile-coordinate for a screen-pixel + * 4) stores all render-to-texture tiles in the this._tiles variable + * 5) calculates the elevation for a spezific tile-coordinate + * 6) creates a terrain-mesh + */ class TerrainSourceCache extends Evented { _style: Style; _source: RasterDEMTileSource; + // source-cache for the raster-dem source. _sourceCache: SourceCache; + // stores all render-to-texture tiles. _tiles: {[_: string]: Tile}; + // because _tiles holds, for performance, also previous rendered tiles + // this variable contains a list of tiles for the current scene. _renderableTiles: Array; - _loadQueue: Array; + // each time a render-to-texture tile is rendered, its tileID.key is stored into this array + // each time a screen is rendered, the last 100 rendered tiles will be kept in cache (e.g. this._tiles). _renderHistory: Array; - _coordsFramebuffer: any; + // holds the framebuffer object in size of the screen to render the coords & depth into a texture. _fbo: any; _fboCoordsTexture: Texture; _fboDepthTexture: Texture; _emptyDepthTexture: Texture; - _mesh: any; - _coordsIndex: Array; + // GL Objects for the terrain-mesh + // The mesh is a regular mesh, which has the advantage that it can be reused for all tiles. + _mesh: { indexBuffer: IndexBuffer, vertexBuffer: VertexBuffer, segments: SegmentVector }; + // coords index contains a list of tileID.keys. This index is used to identify + // the tile via the alpha-cannel in the coords-texture. + // As the alpha-channel has 1 Byte a max of 255 tiles can rendered without an error. + _coordsIndex: Array; + // tile-coords encoded in the rgb channel, _coordsIndex is in the alpha-channel. _coordsTexture: Texture; + // accuracy of the coords. 2 * tileSize should be enoughth. _coordsTextureSize: number; + // variables for an empty dem texture, which is used while the raster-dem tile is loading. _emptyDemUnpack: any; _emptyDemTexture: Texture; _emptyDemMatrix: mat4; + // as of overzooming of raster-dem tiles in high zoomlevels, this cache contains + // matrices to transform from vector-tile coords to raster-dem-tile coords. _demMatrixCache: {[_: string]: { matrix: mat4, coord: OverscaledTileID }}; + // because of overzooming raster-dem tiles this cache holds the corresponding + // raster-dem-tile for a vector-tile. _sourceTileCache: {[_: string]: string}; + // minimum zoomlevel to render the terrain. minzoom: number; + // maximum zoomlevel to render the terrain. maxzoom: number; + // render-to-texture tileSize in scene. tileSize: number; + // define the meshSize per tile. meshSize: number; + // multiplicator for the elevation. Used to make terrain more "extrem". exaggeration: number; + // defines the global offset of putting negative elevations (e.g. dead-sea) into positive values. elevationOffset: number; + // to not see pixels in the render-to-texture tiles it is good to render them bigger + // this number is the multiplicator (must be a power of 2) for the current tileSize. + // So to get good results with not too much memory footprint a value of 2 should be fine. qualityFactor: number; + // loading raster-dem tiles foreach render-to-texture tile results in loading + // a lot of terrain-dem tiles with very low visual advantage. So with this setting + // the raster-dem tiles will load for the actualZoom - deltaZoom zoom-level. deltaZoom: number; + // framebuffer-object to render tiles to texture + rttFramebuffer: Framebuffer; /** * @param {Style} style @@ -59,7 +101,6 @@ class TerrainSourceCache extends Evented { this._style = style; this._tiles = {}; this._renderableTiles = []; - this._loadQueue = []; this._renderHistory = []; this._demMatrixCache = {}; this._sourceTileCache = {}; @@ -70,11 +111,11 @@ class TerrainSourceCache extends Evented { this.tileSize = 512; this.meshSize = 128; this.exaggeration = 1.0; - this.elevationOffset = 450; // add a global offset of 450m to put the dead-sea into positive values. - this.qualityFactor = 2; // render more pixels per tile (e.g. texture is greater than tileSize), value must be a power of two. - this.deltaZoom = 1; // set to a value between 0 and 2. Load tiles for actual zoomlevel - deltaZoom, which leads in faster 3d rendering with less quality. + this.elevationOffset = 450; // ~ dead-sea + this.qualityFactor = 2; + this.deltaZoom = 1; - // create empty DEM Obejcts. During the elevation-tiles loading use this objects. + // create empty DEM Obejcts, which will used while raster-dem tiles will load. const context = style.map.painter.context; this._emptyDemUnpack = [0, 0, 0, 0]; this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); @@ -86,6 +127,11 @@ class TerrainSourceCache extends Evented { const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); this._emptyDepthTexture = texture; + // create the render-to-texture framebuffer + const size = this.tileSize * this.qualityFactor; + this.rttFramebuffer = context.createFramebuffer(size, size, true); + this.rttFramebuffer.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, size, size)); + // rerender corresponding tiles on terrain-dem source-tile updates style.on("data", e => { if (e.dataType == "source" && e.coord && this.isEnabled()) { @@ -106,9 +152,9 @@ class TerrainSourceCache extends Evented { } /** - * + * Loads a 3D terrain-mesh * @param {SourceCache} sourceCache - * @param options Allowed options are exaggeration, elevationOffset + * @param options Allowed options are exaggeration & elevationOffset */ enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number}): void { sourceCache.usedForTerrain = true; @@ -143,59 +189,48 @@ class TerrainSourceCache extends Evented { } /** - * Load Terrain Tiles, removes outdated Tiles and update camera elevation. + * Load Terrain Tiles, create internal render-to-texture tiles, free GPU memory. + * @param {Transform} transform */ update(transform: Transform): void { if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; + // load raster-dem tiles for the current scene. this._sourceCache.update(transform); this._renderableTiles = []; - // create tiles for current view - for (const tileID of this.getRenderableTileIds(transform)) { + const tileIDs = {}; + // create internal render-to-texture tiles for the current scene. + for (const tileID of transform.coveringTiles({ + tileSize: this.tileSize, + minzoom: this.minzoom, + maxzoom: this.maxzoom, + reparseOverscaled: false + })) { this._renderableTiles.push(tileID.key); + tileIDs[tileID.key] = true; if (! this._tiles[tileID.key]) { tileID.posMatrix = new Float64Array(16) as any; mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); this._tiles[tileID.key] = new Tile(tileID, this.tileSize); } } - // free GPU memory from old tiles (e.g. remove ) - this._renderHistory = this._renderHistory.filter((i, p) => this._renderHistory.indexOf(i) == p); // remove duplicates - while (this._renderHistory.length > 100) { + // remove duplicates from _renderHistory + this._renderHistory = this._renderHistory.filter((i, p) => this._renderHistory.indexOf(i) == p); + // free (GPU) memory from previously rendered not needed tiles + while (this._renderHistory.length > 150) { let tile = this._tiles[this._renderHistory.shift()]; - if (tile) tile.clearTextures(this._style.map.painter); + if (tile && !tileIDs[tile.tileID.key]) { + tile.clearTextures(this._style.map.painter); + delete(this._tiles[tile.tileID.key]); + } } } - /** - * get a list of tileIds, which should be rendered in the current scene - * @param {Transform} transform - * @return {Array} - */ - getRenderableTileIds(transform: Transform): Array { - return transform.coveringTiles({ - tileSize: this.tileSize, - minzoom: this.minzoom, - maxzoom: this.maxzoom, - reparseOverscaled: false - }); - } - /** * get a list of tiles, which are loaded and should be rendered in the current scene - * @param {Transform} transform * @returns {Array} */ - getRenderableTiles(transform: Transform): Array { - return this.getRenderableTileIds(transform).map(tileID => this.getTileByID(tileID.key)).filter(t => t); - } - - /** - * get a list of tile-keys which are available in cache - * @param {Transform} transform - * @returns {Array} - */ - getRenderableIds(): Array { - return Object.values(this._tiles).map(t => t.tileID.key); + getRenderableTiles(): Array { + return this._renderableTiles.map(key => this.getTileByID(key)); } /** @@ -207,10 +242,9 @@ class TerrainSourceCache extends Evented { } /** - * searches for the corresponding terrain-tiles at a given zoomlevel + * searches for the corresponding current rendered terrain-tiles * @param {OverscaledTileID} tileID - * @param {number} zoom - * @returns {Tile} + * @returns {[_:string]: Tile} */ getTerrainCoords(tileID: OverscaledTileID): {[_: string]: OverscaledTileID} { const coords = {}; @@ -248,7 +282,7 @@ class TerrainSourceCache extends Evented { } /** - * find the covering terrain-dem tile + * find the covering raster-dem tile * @param {OverscaledTileID} tileID * @param {boolean} searchForDEM Optinal parameter to search for (parent) souretiles with loaded dem. * @returns {Tile} @@ -357,7 +391,7 @@ class TerrainSourceCache extends Evented { } /** - * store all tile-coords in a framebuffer for unprojecting pixel coordinates + * get a framebuffer as big as the map-div, which will be used to render depth & coords into a texture * @param {Painter} painter * @returns {Framebuffer} */ @@ -389,7 +423,7 @@ class TerrainSourceCache extends Evented { } /** - * get a list of tiles, loaded after a spezific time + * get a list of tiles, loaded after a spezific time. This is used to update depth & coords framebuffers. * @param {Date} time * @returns {Array} */ From 7d5d217729ce13c33e4c7cb9d983eb51e8ab8c6d Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 25 Nov 2021 15:53:06 +0100 Subject: [PATCH 053/138] remove mtk raster-dem tiles hack --- src/source/terrain_source_cache.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index e98369f2f61..ac7280dc341 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -374,7 +374,6 @@ class TerrainSourceCache extends Evented { const br = terrain.tile.dem.get(c[0] + 1, c[1] + 1); elevation = mix(mix(tl, tr, coord[0] - c[0]), mix(bl, br, coord[0] - c[0]), coord[1] - c[1]); } - if (elevation > 8191) elevation = 0; // REMOVEME: this hack is for MTK data, because of false nodata values return (elevation + this.elevationOffset); } From bc2ec6a15fd62d906e93355de4113e8b3eb51bf5 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 26 Nov 2021 08:14:54 +0100 Subject: [PATCH 054/138] add more minor fixes and add some comments --- src/data/bucket/fill_extrusion_bucket.ts | 6 +++--- src/shaders/fill_extrusion.vertex.glsl | 9 ++++++++- src/shaders/terrain.vertex.glsl | 2 +- src/source/terrain_source_cache.ts | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/data/bucket/fill_extrusion_bucket.ts b/src/data/bucket/fill_extrusion_bucket.ts index 7d5ac8a0c8e..123255e3864 100644 --- a/src/data/bucket/fill_extrusion_bucket.ts +++ b/src/data/bucket/fill_extrusion_bucket.ts @@ -195,13 +195,13 @@ class FillExtrusionBucket implements Bucket { addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += 2 * p1.x; centroid.y += 2 * p1.y; centroid.vertexCount +=2; + centroid.x += p1.x; centroid.y += p1.y; centroid.vertexCount++; edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += 2 * p2.x; centroid.y += 2 * p2.y; centroid.vertexCount +=2; + centroid.x += p2.x; centroid.y += p2.y; centroid.vertexCount++; const bottomRight = segment.vertexLength; @@ -247,7 +247,7 @@ class FillExtrusionBucket implements Bucket { const p = ring[i]; addVertex(this.layoutVertexArray, p.x, p.y, 0, 0, 1, 1, 0); - centroid.x += p.x; centroid.y += p.y; centroid.vertexCount += 1; + // centroid.x += p.x; centroid.y += p.y; centroid.vertexCount += 1; flattened.push(p.x); flattened.push(p.y); diff --git a/src/shaders/fill_extrusion.vertex.glsl b/src/shaders/fill_extrusion.vertex.glsl index be8841fe524..dcdd80987fc 100644 --- a/src/shaders/fill_extrusion.vertex.glsl +++ b/src/shaders/fill_extrusion.vertex.glsl @@ -24,7 +24,14 @@ void main() { vec3 normal = a_normal_ed.xyz; float ele = get_elevation(a_centroid); - base = max(0.0, ele + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + #ifdef TERRAIN3D + // To avoid floating buildings in 3d-terrain, especially in heavy terrain, + // render the buildings a little below terrain. The unit is meter. + float baseDelta = 10.0; + #else + float baseDelta = 0.0; + #endif + base = max(0.0, ele + base - baseDelta); height = max(0.0, ele + height); float t = mod(normal.x, 2.0); diff --git a/src/shaders/terrain.vertex.glsl b/src/shaders/terrain.vertex.glsl index a5a6b00fde5..05b4d378d28 100644 --- a/src/shaders/terrain.vertex.glsl +++ b/src/shaders/terrain.vertex.glsl @@ -6,7 +6,7 @@ varying vec2 v_texture_pos; varying float v_depth; void main() { - v_texture_pos = a_pos / 8192.0; + v_texture_pos = a_pos / 8192.0; // 8192.0 is the hardcoded vector-tiles coordinates resolution gl_Position = u_matrix * vec4(a_pos, get_elevation(a_pos), 1.0); v_depth = gl_Position.z / gl_Position.w; } diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index ac7280dc341..a8d4481b278 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -29,6 +29,24 @@ import IndexBuffer from '../gl/index_buffer'; * 4) stores all render-to-texture tiles in the this._tiles variable * 5) calculates the elevation for a spezific tile-coordinate * 6) creates a terrain-mesh + * + * A note about the GPU resource-usage: + * Framebuffers: + * - one for the depth & coords framebuffer with the size of the map-div. + * - one for rendering a tile to texture with the size of tileSize (= 512x512). + * Textures: + * - one texture for an empty raster-dem tile with size 1x1 + * - one texture for an empty depth-buffer, when terrain is disabled with size 1x1 + * - one texture for an each loaded raster-dem with size of the source.tileSize + * - one texture for the coords-framebuffer with the size of the map-div. + * - one texture for the depth-framebuffer with the size of the map-div. + * - one texture for the encoded tile-coords with the size 2*tileSize (=1024x1024) + * - finally for each render-to-texture tile (= this._tiles) a set of textures + * for each render stack (The stack-concept is documented in painter.ts). + * Normally there exists 1-3 Textures per tile, depending on the stylesheet. + * Each Textures has the size 2*tileSize (= 1024x1024). Also there exists a + * cache of the last 150 newest rendered tiles. + * */ class TerrainSourceCache extends Evented { From 53865a892a21d3c5b37c9ab2ae65e38e9f2162a1 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 26 Nov 2021 09:03:16 +0100 Subject: [PATCH 055/138] bugfix for collision-index calculation with disabled 3d, fixes #38 --- src/source/terrain_source_cache.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index a8d4481b278..f8ada5d57eb 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -378,7 +378,7 @@ class TerrainSourceCache extends Evented { * @returns {number} */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { - if (!this.isEnabled()) return this.elevationOffset; + if (!this.isEnabled()) return 0.0; if (!(x >= 0 && x < extent && y >= 0 && y < extent)) return this.elevationOffset; let elevation = 0; const terrain = this.getTerrain(tileID); @@ -404,6 +404,7 @@ class TerrainSourceCache extends Evented { * @returns {number} */ getElevationWithExaggeration(tileID: OverscaledTileID, x: number, y: number, extent: number=EXTENT): number { + if (!this.isEnabled()) return 0.0; return this.getElevation(tileID, x, y, extent) * this.exaggeration; } From 2299f304c82165d121157ac12edc2f9a94e89356 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 26 Nov 2021 09:20:24 +0100 Subject: [PATCH 056/138] revert old fill_extrusion_bucket centroid code, because new logic had bugs --- src/data/bucket/fill_extrusion_bucket.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/bucket/fill_extrusion_bucket.ts b/src/data/bucket/fill_extrusion_bucket.ts index 61fa851a46f..20f8d85add7 100644 --- a/src/data/bucket/fill_extrusion_bucket.ts +++ b/src/data/bucket/fill_extrusion_bucket.ts @@ -196,13 +196,13 @@ class FillExtrusionBucket implements Bucket { addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += p1.x; centroid.y += p1.y; centroid.vertexCount++; + centroid.x += 2 * p1.x; centroid.y += 2 * p1.y; centroid.vertexCount += 2; edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += p2.x; centroid.y += p2.y; centroid.vertexCount++; + centroid.x += 2 * p2.x; centroid.y += 2 * p2.y; centroid.vertexCount += 2; const bottomRight = segment.vertexLength; @@ -248,7 +248,7 @@ class FillExtrusionBucket implements Bucket { const p = ring[i]; addVertex(this.layoutVertexArray, p.x, p.y, 0, 0, 1, 1, 0); - // centroid.x += p.x; centroid.y += p.y; centroid.vertexCount += 1; + centroid.x += p.x; centroid.y += p.y; centroid.vertexCount += 1; flattened.push(p.x); flattened.push(p.y); From 98137d3cb1839488fae657027cfb968028fe3bbc Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 29 Nov 2021 12:38:17 +0100 Subject: [PATCH 057/138] fixes #36 --- src/render/painter.ts | 29 +++++++++++++++++------------ src/ui/map.ts | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/render/painter.ts b/src/render/painter.ts index 28e7881df80..af1a927871f 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -489,19 +489,24 @@ class Painter { // Translucent pass =============================================== // Draw all other layers bottom-to-top. this.renderPass = 'translucent'; + // the following variables only used when terrain-3d is enabled - let prevType = null; - const stacks = [], rerender = {}; - const renderableTiles = this.style.terrainSourceCache.getRenderableTiles(); - renderableTiles.forEach(tile => { - // rerender if there are more coords to render than in the last rendering - for (let source in coordsDescendingInvStr) { - const coords = coordsDescendingInvStr[source][tile.tileID.key]; - if (coords && coords != tile.textureCoords[source]) tile.clearTextures(this); - } - // rerender if there are no previous renderings - rerender[tile.tileID.key] = !tile.textures.length; - }); + const stacks = []; // render layers not one by one, instead group into stacks + let prevType = null; // remember the type of the last layer when render to a stack + const rerender = {}; // create a lookup which tiles should rendered to texture + let renderableTiles = []; // all terrain-tiles for the current scene + if (isTerrainEnabled) { + renderableTiles = this.style.terrainSourceCache.getRenderableTiles(); + renderableTiles.forEach(tile => { + // rerender if there are more coords to render than in the last rendering + for (let source in coordsDescendingInvStr) { + const coords = coordsDescendingInvStr[source][tile.tileID.key]; + if (coords && coords != tile.textureCoords[source]) tile.clearTextures(this); + } + // rerender if there are no previous renderings + rerender[tile.tileID.key] = !tile.textures.length; + }); + } for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; diff --git a/src/ui/map.ts b/src/ui/map.ts index 595ec7e70fc..a68ab8cedd0 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -855,7 +855,7 @@ class Map extends Camera { * var point = map.project(coordinate); */ project(lnglat: LngLatLike) { - return this.style.terrainSourceCache.isEnabled() + return this.style && this.style.terrainSourceCache.isEnabled() ? this.transform.locationPoint3D(LngLat.convert(lnglat)) : this.transform.locationPoint(LngLat.convert(lnglat)); } @@ -873,7 +873,7 @@ class Map extends Camera { * }); */ unproject(point: PointLike) { - return this.style.terrainSourceCache.isEnabled() + return this.style && this.style.terrainSourceCache.isEnabled() ? this.transform.pointLocation3D(Point.convert(point)) : this.transform.pointLocation(Point.convert(point)); } From 0b81a4189f2f2426318dbc39e58da76ee0086cc4 Mon Sep 17 00:00:00 2001 From: Andrew Calcutt Date: Mon, 6 Dec 2021 11:34:44 -0500 Subject: [PATCH 058/138] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7a841b2906..f2a01f733e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ - Migrated the production code to typescript - ** Breaking Change ** removed `version` from the public API -- ** Breaking Change ** stopped supporting IE (internet explorer) - ** Breaking Change ** removed all code related to `accessToken` and mapbox specific urls, including telemetry etc. Please do not use mapbox servers with this library. - ** Breaking Change ** removed `baseApiUrl` as it was used only for mapbox related urls - ** Breaking Change ** typescript typings have changed: From 2192c1d5046a1d69445f3cb570de60c78c64d22c Mon Sep 17 00:00:00 2001 From: acalcutt Date: Mon, 6 Dec 2021 11:37:17 -0500 Subject: [PATCH 059/138] Revert "Update CHANGELOG.md" This reverts commit 0b81a4189f2f2426318dbc39e58da76ee0086cc4. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2a01f733e3..d7a841b2906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Migrated the production code to typescript - ** Breaking Change ** removed `version` from the public API +- ** Breaking Change ** stopped supporting IE (internet explorer) - ** Breaking Change ** removed all code related to `accessToken` and mapbox specific urls, including telemetry etc. Please do not use mapbox servers with this library. - ** Breaking Change ** removed `baseApiUrl` as it was used only for mapbox related urls - ** Breaking Change ** typescript typings have changed: From 2031d8e68185407fca72640a73ec8334734161fe Mon Sep 17 00:00:00 2001 From: acalcutt Date: Mon, 6 Dec 2021 11:55:32 -0500 Subject: [PATCH 060/138] attribution fixes (from astridx) https://github.com/maplibre/maplibre-gl-js/pull/668/commits/a1272d9f569057fed6ce3b163fc0602f824e7653 https://github.com/maplibre/maplibre-gl-js/pull/668/commits/b9b03707fd07b0eaba276703eb1a3626f05bbb64 --- src/ui/control/attribution_control.test.ts | 507 +++++++++++++++++++-- src/ui/control/attribution_control.ts | 16 +- 2 files changed, 476 insertions(+), 47 deletions(-) diff --git a/src/ui/control/attribution_control.test.ts b/src/ui/control/attribution_control.test.ts index bcb7e3a537c..31da4478b95 100644 --- a/src/ui/control/attribution_control.test.ts +++ b/src/ui/control/attribution_control.test.ts @@ -10,27 +10,27 @@ function createMap() { version: 8, sources: {}, layers: [], - owner: 'mapbox', - id: 'streets-v10', + owner: 'mapblibre', + id: 'demotiles', }, hash: true }, undefined); } -describe('AttributionControl', () => { - let map; +let map; - beforeEach(() => { - setWebGlContext(); - setPerformance(); - setMatchMedia(); - map = createMap(); - }); +beforeEach(() => { + setWebGlContext(); + setPerformance(); + setMatchMedia(); + map = createMap(); +}); - afterEach(() => { - map.remove(); - }); +afterEach(() => { + map.remove(); +}); +describe('AttributionControl', () => { test('appears in bottom-right by default', () => { map.addControl(new AttributionControl()); @@ -264,13 +264,75 @@ describe('AttributionControl', () => { }); }); - test('details is set correct for compact view after map load. In particular, it should NOT contain the attribute open="".', () => { - const attributionControl = new AttributionControl({ - compact: true +}); + +describe('AttributionControl Snapshot Tests', () => { + describe('Details is set correct for compact view', () => { + test('It should NOT contain the attribute open="" on first load.', () => { + const attributionControl = new AttributionControl({ + compact: true + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); }); - map.addControl(attributionControl); - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + test('It SHOULD contain the attribute open="" after click on summary.', () => { + const attributionControl = new AttributionControl({ + compact: true + }); + map.addControl(attributionControl); + const container = map.getContainer(); + const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); + + simulate.click(toggle); + + expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + }); + + test('It should NOT contain the attribute open="" after two clicks on summary.', () => { + const attributionControl = new AttributionControl({ + compact: true + }); + map.addControl(attributionControl); + const container = map.getContainer(); + const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); + + simulate.click(toggle); + simulate.click(toggle); + + expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); + }); }); - test('details is set correct for compact view after click on summary. In particular, it SHOULD contain the attribute open="".', () => { - const attributionControl = new AttributionControl({ - compact: true + describe('Details is set correct for default view (compact === undefined)', () => { + test('It should NOT contain the attribute open="" if offsetWidth <= 640.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + const attributionControl = new AttributionControl({ + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); }); - map.addControl(attributionControl); - const container = map.getContainer(); - const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); - simulate.click(toggle); + test('It SHOULD contain the attribute open="" if offsetWidth > 640.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); + const attributionControl = new AttributionControl({ + }); + map.addControl(attributionControl); - expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); - }); + }); - test('details is set correct for compact view after two clicks on summary. In particular, it should NOT contain the attribute open="".', () => { - const attributionControl = new AttributionControl({ - compact: true + test('The attribute open="" SHOULD change on resize from size > 640 to <= 640 and and vice versa.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + const attributionControl = new AttributionControl({ + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); }); - map.addControl(attributionControl); - const container = map.getContainer(); - const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); - simulate.click(toggle); - simulate.click(toggle); + test('The attribute open="" should NOT change on resize from > 640 to another > 640.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); + const attributionControl = new AttributionControl({ + }); + map.addControl(attributionControl); - expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); - }); - test('details is set correct for default view. In particular, it SHOULD contain the attribute open="".', () => { - const attributionControl = new AttributionControl({ + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 650, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); }); - map.addControl(attributionControl); - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + test('The attribute open="" should NOT change on resize from <= 640 to another <= 640 if it is closed.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + const attributionControl = new AttributionControl({ + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 630, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + }); + + test('The attribute open="" should NOT change on resize from <= 640 to another <= 640 if it is open.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + const attributionControl = new AttributionControl({ + }); + map.addControl(attributionControl); + const toggle = map.getContainer().querySelector('.maplibregl-ctrl-attrib-button'); + simulate.click(toggle); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 630, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
, ] `); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + }); }); -}); + + describe('Details is set correct for default view (compact === false)', () => { + test('It SHOULD contain the attribute open="" if offsetWidth <= 640.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + const attributionControl = new AttributionControl({ + compact: false + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + }); + + test('It SHOULD contain the attribute open="" if offsetWidth > 640.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); + const attributionControl = new AttributionControl({ + compact: false + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + }); + + test('The attribute open="" should NOT change on resize.', () => { + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + const attributionControl = new AttributionControl({ + compact: false + }); + map.addControl(attributionControl); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + + Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); + map.resize(); + + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` +NodeList [ +
+ +
+
, +] +`); + }); + }); +}); \ No newline at end of file diff --git a/src/ui/control/attribution_control.ts b/src/ui/control/attribution_control.ts index 27aa152d213..6a1c2ed25b9 100644 --- a/src/ui/control/attribution_control.ts +++ b/src/ui/control/attribution_control.ts @@ -53,13 +53,19 @@ class AttributionControl implements IControl { this._map = map; this._container = DOM.create('details', 'maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib'); this._compactButton = DOM.create('summary', 'maplibregl-ctrl-attrib-button mapboxgl-ctrl-attrib-button', this._container); - this._compactButton.addEventListener('click', this._toggleAttribution); + + if (compact !== false) { + this._compactButton.addEventListener('click', this._toggleAttribution); + } + this._setElementTitle(this._compactButton, 'ToggleAttribution'); this._innerContainer = DOM.create('div', 'maplibregl-ctrl-attrib-inner mapboxgl-ctrl-attrib-inner', this._container); if (compact) { this._container.classList.add('maplibregl-compact', 'mapboxgl-compact'); - } else { + } + + if (!compact) { this._container.setAttribute('open', ''); } @@ -168,12 +174,16 @@ class AttributionControl implements IControl { _updateCompact() { if (this._map.getCanvasContainer().offsetWidth <= 640) { + if (!this._container.classList.contains('maplibregl-compact')) { + this._container.removeAttribute('open'); + } this._container.classList.add('maplibregl-compact', 'mapboxgl-compact'); } else { + this._container.setAttribute('open', ''); this._container.classList.remove('maplibregl-compact', 'maplibregl-compact-show', 'mapboxgl-compact', 'mapboxgl-compact-show'); } } } -export default AttributionControl; +export default AttributionControl; \ No newline at end of file From 032b16e5707ec0e95086a4f6d87f5df12961333e Mon Sep 17 00:00:00 2001 From: Andrew Calcutt Date: Mon, 6 Dec 2021 22:47:31 -0500 Subject: [PATCH 061/138] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 715d1ee3fd1..734e2216b86 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ /dist/ /dist_type/ *.es.js -*.js.map node_modules *.sublime-* coverage From 711436a93abebcdc2539d1494a370ee3ca827af5 Mon Sep 17 00:00:00 2001 From: acalcutt Date: Tue, 7 Dec 2021 07:49:42 -0500 Subject: [PATCH 062/138] fix missing new line lint complained about --- src/ui/control/attribution_control.test.ts | 2 +- src/ui/control/attribution_control.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/control/attribution_control.test.ts b/src/ui/control/attribution_control.test.ts index 31da4478b95..7302687916b 100644 --- a/src/ui/control/attribution_control.test.ts +++ b/src/ui/control/attribution_control.test.ts @@ -788,4 +788,4 @@ NodeList [ `); }); }); -}); \ No newline at end of file +}); diff --git a/src/ui/control/attribution_control.ts b/src/ui/control/attribution_control.ts index 6a1c2ed25b9..097602727df 100644 --- a/src/ui/control/attribution_control.ts +++ b/src/ui/control/attribution_control.ts @@ -186,4 +186,4 @@ class AttributionControl implements IControl { } -export default AttributionControl; \ No newline at end of file +export default AttributionControl; From 7895d045996107f576374cd1066ac2aa88b8bf7b Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 9 Dec 2021 08:47:03 +0100 Subject: [PATCH 063/138] first try (not finished) to leave the camera at the same height when dragging map. --- src/geo/transform.ts | 30 ++++++++++++++++++++++++++++-- src/ui/handler_manager.ts | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 3ddfc1428ff..7801ce88914 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -42,6 +42,7 @@ class Transform { glCoordMatrix: mat4; labelPlaneMatrix: mat4; terrainSourceCache: TerrainSourceCache; + freezeElevation: boolean; _fov: number; _pitch: number; _zoom: number; @@ -61,6 +62,7 @@ class Transform { constructor(minZoom?: number, maxZoom?: number, minPitch?: number, maxPitch?: number, renderWorldCopies?: boolean) { this.tileSize = 512; // constant this.maxValidLatitude = 85.051129; // constant + this.freezeElevation = false; this._renderWorldCopies = renderWorldCopies === undefined ? true : !!renderWorldCopies; this._minZoom = minZoom || 0; @@ -210,13 +212,13 @@ class Transform { if (center.lat === this._center.lat && center.lng === this._center.lng) return; this._unmodified = false; this._center = center; - this._elevation = this.getElevation(center); this._constrain(); this._calcMatrices(); } get elevation(): number { return this._elevation; } set elevation(elevation: number) { + if (this.freezeElevation) return; if (elevation === this._elevation) return; this._unmodified = false; this._elevation = elevation; @@ -474,7 +476,7 @@ class Transform { get point(): Point { return this.project(this.center); } updateElevation() { - this.elevation = this.getElevation(this._center); + this.elevation = this.getElevation(this._center); } getElevation(lnglat: LngLat) { @@ -487,6 +489,30 @@ class Transform { return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); } + // this method only works in combination with freezeElevation, because in this case + // this.elevation holds the old elevation value. + // FIMXE! currently this logic only works for camera pitch = 0 + recalculateZoom() { + const elevation = this.getElevation(this.center); + const deltaElevation = + this.elevation - elevation; + if (!deltaElevation) return; + + const mercatorZPerMeter = mercatorZfromAltitude(1, this.center.lat); + // to calculate the elevation in meters for the current zoomlevel the formular from + // https://github.com/mapbox/mapbox-gl-js/pull/8830/files is used + const zoomElevation = this.cameraToCenterDistance / this.worldSize / mercatorZPerMeter; + // calculate the current total height of the camera, e.g. zoom-elevation + terrain-elevation in meters + // elevation1 = zoomElevation + this.elevation + // to get the same total camera height for a different terrain-elevation do + // elevation2 = cameraToCenterDistance / (2^zoom * tilesize) / mercatorZPerMeter + // now do + // elevation1 = elevation2 + // then solve the formular for zoom + const zoom = this.scaleZoom(this.cameraToCenterDistance / (zoomElevation + deltaElevation) / mercatorZPerMeter / this.tileSize); + this._elevation = elevation; + this.zoom = zoom; + } + setLocationAtPoint(lnglat: LngLat, point: Point) { const a = this.pointCoordinate(point); const b = this.pointCoordinate(this.centerPoint); diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index b41b3effe45..f8fdec071f8 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -18,6 +18,7 @@ import DragRotateHandler from './handler/shim/drag_rotate'; import TouchZoomRotateHandler from './handler/shim/touch_zoom_rotate'; import {bindAll, extend} from '../util/util'; import Point from '../util/point'; +import LngLat from '../geo/lng_lat'; import assert from 'assert'; export type InputEvent = MouseEvent | TouchEvent | KeyboardEvent | WheelEvent; @@ -100,6 +101,7 @@ class HandlerManager { _handlersById: {[x: string]: Handler}; _updatingCamera: boolean; _changes: Array<[HandlerResult, any, any]>; + _drag: {center: Point, lngLat: LngLat, point: Point, delta: Point, handlerName: string}; _previousActiveHandlers: {[x: string]: Handler}; _listeners: Array<[Window | Document | HTMLElement, string, { passive?: boolean; @@ -411,11 +413,10 @@ class HandlerManager { } _updateMapTransform(combinedResult: any, combinedEventsInProgress: any, deactivatedHandlers: any) { - const map = this._map; const tr = map.transform; - if (!hasChange(combinedResult)) { + if (!hasChange(combinedResult) && !this._drag) { return this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); } @@ -429,11 +430,39 @@ class HandlerManager { map._stop(true); around = around || map.transform.centerPoint; - const loc = tr.pointLocation(panDelta ? around.sub(panDelta) : around); if (bearingDelta) tr.bearing += bearingDelta; if (pitchDelta) tr.pitch += pitchDelta; if (zoomDelta) tr.zoom += zoomDelta; - tr.setLocationAtPoint(loc, around); + + // when dragging starts, remember mousedown-location and panDelta from this point + if (combinedEventsInProgress.drag && !this._drag) { + this._drag = { + center: tr.centerPoint, + lngLat: tr.pointLocation(around), + point: around, + delta: panDelta, + handlerName: combinedEventsInProgress.drag.handlerName + }; + tr.freezeElevation = true; + // when dragging ends, recalcuate the zoomlevel for the new center coordinate + } else if (this._drag && deactivatedHandlers[this._drag.handlerName]) { + tr.freezeElevation = false; + tr.recalculateZoom(); + this._drag = null; + // drag map + } else if (combinedEventsInProgress.drag && this._drag) { + this._drag.delta = this._drag.delta.add(panDelta); + // in terrain-mode do not drag the picked point itself, instead only drag the pixel delta + // of the picked point. With this approach it is no longer possible to pick a point from + // from somewhere near the horizon to the center in one move. + // So this logic avoids the problem, that in such cases you easily loose orientation. + if (map.style.terrainSourceCache.isEnabled()) { + tr.center = tr.pointLocation(tr.centerPoint.sub(panDelta)); + // in flat mode leave all es it is. e.g. drag the picked point directly to the new posistion. + } else { + tr.setLocationAtPoint(this._drag.lngLat, this._drag.point.add(this._drag.delta)); + } + } this._map._update(); if (!combinedResult.noInertia) this._inertia.record(combinedResult); From 53d97eb54cc52f1b0d07456604c0f1de44798d3d Mon Sep 17 00:00:00 2001 From: acalcutt Date: Sat, 11 Dec 2021 13:47:27 -0500 Subject: [PATCH 064/138] Revert "attribution fixes (from astridx)" This reverts commit 2031d8e68185407fca72640a73ec8334734161fe. --- src/ui/control/attribution_control.test.ts | 505 ++------------------- src/ui/control/attribution_control.ts | 14 +- 2 files changed, 45 insertions(+), 474 deletions(-) diff --git a/src/ui/control/attribution_control.test.ts b/src/ui/control/attribution_control.test.ts index 7302687916b..bcb7e3a537c 100644 --- a/src/ui/control/attribution_control.test.ts +++ b/src/ui/control/attribution_control.test.ts @@ -10,27 +10,27 @@ function createMap() { version: 8, sources: {}, layers: [], - owner: 'mapblibre', - id: 'demotiles', + owner: 'mapbox', + id: 'streets-v10', }, hash: true }, undefined); } -let map; +describe('AttributionControl', () => { + let map; -beforeEach(() => { - setWebGlContext(); - setPerformance(); - setMatchMedia(); - map = createMap(); -}); + beforeEach(() => { + setWebGlContext(); + setPerformance(); + setMatchMedia(); + map = createMap(); + }); -afterEach(() => { - map.remove(); -}); + afterEach(() => { + map.remove(); + }); -describe('AttributionControl', () => { test('appears in bottom-right by default', () => { map.addControl(new AttributionControl()); @@ -264,75 +264,13 @@ describe('AttributionControl', () => { }); }); -}); - -describe('AttributionControl Snapshot Tests', () => { - describe('Details is set correct for compact view', () => { - test('It should NOT contain the attribute open="" on first load.', () => { - const attributionControl = new AttributionControl({ - compact: true - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - }); - - test('It SHOULD contain the attribute open="" after click on summary.', () => { - const attributionControl = new AttributionControl({ - compact: true - }); - map.addControl(attributionControl); - const container = map.getContainer(); - const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); - - simulate.click(toggle); - - expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); + test('details is set correct for compact view after map load. In particular, it should NOT contain the attribute open="".', () => { + const attributionControl = new AttributionControl({ + compact: true }); + map.addControl(attributionControl); - test('It should NOT contain the attribute open="" after two clicks on summary.', () => { - const attributionControl = new AttributionControl({ - compact: true - }); - map.addControl(attributionControl); - const container = map.getContainer(); - const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); - - simulate.click(toggle); - simulate.click(toggle); - - expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); - }); }); - describe('Details is set correct for default view (compact === undefined)', () => { - test('It should NOT contain the attribute open="" if offsetWidth <= 640.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - const attributionControl = new AttributionControl({ - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - }); - - test('It SHOULD contain the attribute open="" if offsetWidth > 640.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); - const attributionControl = new AttributionControl({ - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - }); - - test('The attribute open="" SHOULD change on resize from size > 640 to <= 640 and and vice versa.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - const attributionControl = new AttributionControl({ - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); + test('details is set correct for compact view after click on summary. In particular, it SHOULD contain the attribute open="".', () => { + const attributionControl = new AttributionControl({ + compact: true }); + map.addControl(attributionControl); + const container = map.getContainer(); + const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); - test('The attribute open="" should NOT change on resize from > 640 to another > 640.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); - const attributionControl = new AttributionControl({ - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 650, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); - map.resize(); + simulate.click(toggle); - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); - }); - - test('The attribute open="" should NOT change on resize from <= 640 to another <= 640 if it is closed.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - const attributionControl = new AttributionControl({ - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 630, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - map.resize(); + }); - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); + test('details is set correct for compact view after two clicks on summary. In particular, it should NOT contain the attribute open="".', () => { + const attributionControl = new AttributionControl({ + compact: true }); + map.addControl(attributionControl); + const container = map.getContainer(); + const toggle = container.querySelector('.maplibregl-ctrl-attrib-button'); - test('The attribute open="" should NOT change on resize from <= 640 to another <= 640 if it is open.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - const attributionControl = new AttributionControl({ - }); - map.addControl(attributionControl); - const toggle = map.getContainer().querySelector('.maplibregl-ctrl-attrib-button'); - simulate.click(toggle); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 630, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - map.resize(); + simulate.click(toggle); + simulate.click(toggle); - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); - }); }); - describe('Details is set correct for default view (compact === false)', () => { - test('It SHOULD contain the attribute open="" if offsetWidth <= 640.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - const attributionControl = new AttributionControl({ - compact: false - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - }); - - test('It SHOULD contain the attribute open="" if offsetWidth > 640.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); - const attributionControl = new AttributionControl({ - compact: false - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); + test('details is set correct for default view. In particular, it SHOULD contain the attribute open="".', () => { + const attributionControl = new AttributionControl({ }); + map.addControl(attributionControl); - test('The attribute open="" should NOT change on resize.', () => { - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - const attributionControl = new AttributionControl({ - compact: false - }); - map.addControl(attributionControl); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` -NodeList [ -
- -
-
, -] -`); - - Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true}); - map.resize(); - - expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` + expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(` NodeList [
, ] `); - }); }); }); diff --git a/src/ui/control/attribution_control.ts b/src/ui/control/attribution_control.ts index 097602727df..27aa152d213 100644 --- a/src/ui/control/attribution_control.ts +++ b/src/ui/control/attribution_control.ts @@ -53,19 +53,13 @@ class AttributionControl implements IControl { this._map = map; this._container = DOM.create('details', 'maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib'); this._compactButton = DOM.create('summary', 'maplibregl-ctrl-attrib-button mapboxgl-ctrl-attrib-button', this._container); - - if (compact !== false) { - this._compactButton.addEventListener('click', this._toggleAttribution); - } - + this._compactButton.addEventListener('click', this._toggleAttribution); this._setElementTitle(this._compactButton, 'ToggleAttribution'); this._innerContainer = DOM.create('div', 'maplibregl-ctrl-attrib-inner mapboxgl-ctrl-attrib-inner', this._container); if (compact) { this._container.classList.add('maplibregl-compact', 'mapboxgl-compact'); - } - - if (!compact) { + } else { this._container.setAttribute('open', ''); } @@ -174,12 +168,8 @@ class AttributionControl implements IControl { _updateCompact() { if (this._map.getCanvasContainer().offsetWidth <= 640) { - if (!this._container.classList.contains('maplibregl-compact')) { - this._container.removeAttribute('open'); - } this._container.classList.add('maplibregl-compact', 'mapboxgl-compact'); } else { - this._container.setAttribute('open', ''); this._container.classList.remove('maplibregl-compact', 'maplibregl-compact-show', 'mapboxgl-compact', 'mapboxgl-compact-show'); } } From 466f964a98a8188cff40caaac1030bc089cf9e5a Mon Sep 17 00:00:00 2001 From: acalcutt Date: Fri, 17 Dec 2021 15:09:58 -0500 Subject: [PATCH 065/138] Create a TerrainControl to toggle terrain --- debug/terrain_button.html | 51 ++++++++++++ src/css/maplibre-gl.css | 20 +++++ .../svg/maplibregl-ctrl-terrain-enabled.svg | 6 ++ src/css/svg/maplibregl-ctrl-terrain.svg | 7 ++ src/index.ts | 2 + src/ui/control/terrain_control.ts | 77 +++++++++++++++++++ 6 files changed, 163 insertions(+) create mode 100644 debug/terrain_button.html create mode 100644 src/css/svg/maplibregl-ctrl-terrain-enabled.svg create mode 100644 src/css/svg/maplibregl-ctrl-terrain.svg create mode 100644 src/ui/control/terrain_control.ts diff --git a/debug/terrain_button.html b/debug/terrain_button.html new file mode 100644 index 00000000000..1e9dee48008 --- /dev/null +++ b/debug/terrain_button.html @@ -0,0 +1,51 @@ + + + + MapLibre GL JS debug page + + + + + + + +
+ + + + + + diff --git a/src/css/maplibre-gl.css b/src/css/maplibre-gl.css index 9c89c02cf02..f19c473c61b 100644 --- a/src/css/maplibre-gl.css +++ b/src/css/maplibre-gl.css @@ -314,6 +314,26 @@ } } +@svg-load ctrl-terrain url(svg/maplibregl-ctrl-terrain.svg) { + fill: #333; + #stroke { display: none; } +} + +.maplibregl-ctrl button.maplibregl-ctrl-terrain .maplibregl-ctrl-icon, +.mapboxgl-ctrl button.mapboxgl-ctrl-terrain .mapboxgl-ctrl-icon { + background-image: svg-inline(ctrl-terrain); +} + +@svg-load ctrl-terrain-enabled url(svg/maplibregl-ctrl-terrain-enabled.svg) { + fill: #333; + #stroke { display: none; } +} + +.maplibregl-ctrl button.maplibregl-ctrl-terrain-enabled .maplibregl-ctrl-icon, +.mapboxgl-ctrl button.mapboxgl-ctrl-terrain-enabled .mapboxgl-ctrl-icon { + background-image: svg-inline(ctrl-terrain-enabled); +} + @svg-load ctrl-geolocate url(svg/maplibregl-ctrl-geolocate.svg) { fill: #333; #stroke { display: none; } diff --git a/src/css/svg/maplibregl-ctrl-terrain-enabled.svg b/src/css/svg/maplibregl-ctrl-terrain-enabled.svg new file mode 100644 index 00000000000..a0dbeeeee59 --- /dev/null +++ b/src/css/svg/maplibregl-ctrl-terrain-enabled.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/css/svg/maplibregl-ctrl-terrain.svg b/src/css/svg/maplibregl-ctrl-terrain.svg new file mode 100644 index 00000000000..1e23d4e5e6e --- /dev/null +++ b/src/css/svg/maplibregl-ctrl-terrain.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/index.ts b/src/index.ts index 91fd6b08171..5262a20979d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import GeolocateControl from './ui/control/geolocate_control'; import AttributionControl from './ui/control/attribution_control'; import ScaleControl from './ui/control/scale_control'; import FullscreenControl from './ui/control/fullscreen_control'; +import TerrainControl from './ui/control/terrain_control'; import Popup from './ui/popup'; import Marker from './ui/marker'; import Style from './style/style'; @@ -38,6 +39,7 @@ const exported = { AttributionControl, ScaleControl, FullscreenControl, + TerrainControl, Popup, Marker, Style, diff --git a/src/ui/control/terrain_control.ts b/src/ui/control/terrain_control.ts new file mode 100644 index 00000000000..975db1ff3a1 --- /dev/null +++ b/src/ui/control/terrain_control.ts @@ -0,0 +1,77 @@ +import DOM from '../../util/dom'; +import {bindAll} from '../../util/util'; + +import type Map from '../map'; +import type {ControlPosition, IControl} from './control'; + +type TerrainOptions = { + id?: string; + options?: {exaggeration: boolean; elevationOffset: number} +}; + +/** + * An `TerrainControl` control adds a button to turn terrain on and off. + * + * @implements {IControl} + * @param {Object} [options] + * @param {string} [options.id] The ID of the raster-dem source to use. + * @param {exaggeration: boolean; elevationOffset: number} [options.options] Allowed options are exaggeration: boolean; elevationOffset: number + * @example + * var map = new maplibregl.Map({TerrainControl: false}) + * .addControl(new maplibregl.TerrainControl({ + * compact: true + * })); + */ +class TerrainControl implements IControl { + options: TerrainOptions; + _map: Map; + _container: HTMLElement; + _terrainButton: HTMLButtonElement; + + constructor(options: TerrainOptions = {}) { + this.options = options; + + bindAll([ + '_toggleTerrain', + '_toggleTerrainIcon', + ], this); + } + + onAdd(map: Map) { + this._map = map; + this._container = DOM.create('div', 'maplibregl-ctrl maplibregl-ctrl-group mapboxgl-ctrl mapboxgl-ctrl-group'); + this._terrainButton = DOM.create('button', 'maplibregl-ctrl-terrain mapboxgl-ctrl-terrain', this._container); + DOM.create('span', 'maplibregl-ctrl-icon mapboxgl-ctrl-icon', this._terrainButton).setAttribute('aria-hidden', 'true'); + this._terrainButton.type = 'button'; + this._terrainButton.addEventListener('click', this._toggleTerrain); + + this._toggleTerrainIcon + return this._container; + } + + onRemove() { + DOM.remove(this._container); + this._map = undefined; + } + + _toggleTerrain() { + if (this._map.style.terrainSourceCache.isEnabled()) { + this._map.removeTerrain() + } else { + this._map.addTerrain(this.options.id, this.options.options) + } + this._toggleTerrainIcon() + } + + _toggleTerrainIcon() { + if (this._map.style.terrainSourceCache.isEnabled()) { + this._terrainButton.classList.add('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + this._terrainButton.classList.remove('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + } else { + this._terrainButton.classList.add('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + this._terrainButton.classList.remove('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + } + } +} + +export default TerrainControl; From c1b695d4d222e1810a86a07dba42230ac7d15622 Mon Sep 17 00:00:00 2001 From: acalcutt Date: Fri, 17 Dec 2021 16:16:05 -0500 Subject: [PATCH 066/138] fix tabs and comment --- src/ui/control/terrain_control.ts | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ui/control/terrain_control.ts b/src/ui/control/terrain_control.ts index 975db1ff3a1..7dd89eb3dd5 100644 --- a/src/ui/control/terrain_control.ts +++ b/src/ui/control/terrain_control.ts @@ -19,7 +19,7 @@ type TerrainOptions = { * @example * var map = new maplibregl.Map({TerrainControl: false}) * .addControl(new maplibregl.TerrainControl({ - * compact: true + * id: "terrain" * })); */ class TerrainControl implements IControl { @@ -43,9 +43,9 @@ class TerrainControl implements IControl { this._terrainButton = DOM.create('button', 'maplibregl-ctrl-terrain mapboxgl-ctrl-terrain', this._container); DOM.create('span', 'maplibregl-ctrl-icon mapboxgl-ctrl-icon', this._terrainButton).setAttribute('aria-hidden', 'true'); this._terrainButton.type = 'button'; - this._terrainButton.addEventListener('click', this._toggleTerrain); - - this._toggleTerrainIcon + this._terrainButton.addEventListener('click', this._toggleTerrain); + + this._toggleTerrainIcon return this._container; } @@ -55,22 +55,22 @@ class TerrainControl implements IControl { } _toggleTerrain() { - if (this._map.style.terrainSourceCache.isEnabled()) { - this._map.removeTerrain() - } else { - this._map.addTerrain(this.options.id, this.options.options) - } - this._toggleTerrainIcon() + if (this._map.style.terrainSourceCache.isEnabled()) { + this._map.removeTerrain() + } else { + this._map.addTerrain(this.options.id, this.options.options) + } + this._toggleTerrainIcon() } _toggleTerrainIcon() { - if (this._map.style.terrainSourceCache.isEnabled()) { - this._terrainButton.classList.add('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); - this._terrainButton.classList.remove('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); - } else { - this._terrainButton.classList.add('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); - this._terrainButton.classList.remove('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); - } + if (this._map.style.terrainSourceCache.isEnabled()) { + this._terrainButton.classList.add('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + this._terrainButton.classList.remove('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + } else { + this._terrainButton.classList.add('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + this._terrainButton.classList.remove('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + } } } From f967ea801471911588e77efd00f432dce3d1491b Mon Sep 17 00:00:00 2001 From: acalcutt Date: Sat, 18 Dec 2021 23:51:34 -0500 Subject: [PATCH 067/138] change exaggeration type to number. add options to control example --- debug/{terrain_button.html => terrain_control.html} | 4 ++++ src/source/terrain_source_cache.ts | 2 +- src/ui/control/terrain_control.ts | 4 ++-- src/ui/map.ts | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) rename debug/{terrain_button.html => terrain_control.html} (93%) diff --git a/debug/terrain_button.html b/debug/terrain_control.html similarity index 93% rename from debug/terrain_button.html rename to debug/terrain_control.html index 1e9dee48008..31fd37f34bb 100644 --- a/debug/terrain_button.html +++ b/debug/terrain_control.html @@ -37,6 +37,10 @@ map.addControl( new maplibregl.TerrainControl({ id: "terrain" + options: { + exaggeration: 2, + elevationOffset: 0 + } }) ); }); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index f8ada5d57eb..84f96dc02b9 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -174,7 +174,7 @@ class TerrainSourceCache extends Evented { * @param {SourceCache} sourceCache * @param options Allowed options are exaggeration & elevationOffset */ - enable(sourceCache: SourceCache, options?: {exaggeration: boolean; elevationOffset: number}): void { + enable(sourceCache: SourceCache, options?: {exaggeration: number; elevationOffset: number}): void { sourceCache.usedForTerrain = true; sourceCache.tileSize = this.tileSize * 2 ** this.deltaZoom; this._sourceCache = sourceCache; diff --git a/src/ui/control/terrain_control.ts b/src/ui/control/terrain_control.ts index 7dd89eb3dd5..c2b47fa1a8c 100644 --- a/src/ui/control/terrain_control.ts +++ b/src/ui/control/terrain_control.ts @@ -6,7 +6,7 @@ import type {ControlPosition, IControl} from './control'; type TerrainOptions = { id?: string; - options?: {exaggeration: boolean; elevationOffset: number} + options?: {exaggeration: number; elevationOffset: number} }; /** @@ -15,7 +15,7 @@ type TerrainOptions = { * @implements {IControl} * @param {Object} [options] * @param {string} [options.id] The ID of the raster-dem source to use. - * @param {exaggeration: boolean; elevationOffset: number} [options.options] Allowed options are exaggeration: boolean; elevationOffset: number + * @param {exaggeration: number; elevationOffset: number} [options.options] Allowed options are exaggeration: number; elevationOffset: number * @example * var map = new maplibregl.Map({TerrainControl: false}) * .addControl(new maplibregl.TerrainControl({ diff --git a/src/ui/map.ts b/src/ui/map.ts index 52118e95863..1e8788bf309 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -1563,7 +1563,7 @@ class Map extends Camera { * @example * map.addTerrain('my-data'); */ - addTerrain(id: string, options?: {exaggeration: boolean; elevationOffset: number}) { + addTerrain(id: string, options?: {exaggeration: number; elevationOffset: number}) { this.isSourceLoaded(id); this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); this.style.terrainSourceCache.update(this.transform); From b263230722b7b3278bb6bb81f92789cbfc5d7eb8 Mon Sep 17 00:00:00 2001 From: acalcutt Date: Sun, 19 Dec 2021 09:29:14 -0500 Subject: [PATCH 068/138] change terrain icon fill color when enabled remove second "flat/enabled" svg. used color from gps location button. --- src/css/maplibre-gl.css | 10 +++++----- src/css/svg/maplibregl-ctrl-terrain-enabled.svg | 6 ------ src/css/svg/maplibregl-ctrl-terrain.svg | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) delete mode 100644 src/css/svg/maplibregl-ctrl-terrain-enabled.svg diff --git a/src/css/maplibre-gl.css b/src/css/maplibre-gl.css index f19c473c61b..661b46197e4 100644 --- a/src/css/maplibre-gl.css +++ b/src/css/maplibre-gl.css @@ -319,16 +319,16 @@ #stroke { display: none; } } +@svg-load ctrl-terrain-enabled url(svg/maplibregl-ctrl-terrain.svg) { + fill: #33b5e5; + #stroke { display: none; } +} + .maplibregl-ctrl button.maplibregl-ctrl-terrain .maplibregl-ctrl-icon, .mapboxgl-ctrl button.mapboxgl-ctrl-terrain .mapboxgl-ctrl-icon { background-image: svg-inline(ctrl-terrain); } -@svg-load ctrl-terrain-enabled url(svg/maplibregl-ctrl-terrain-enabled.svg) { - fill: #333; - #stroke { display: none; } -} - .maplibregl-ctrl button.maplibregl-ctrl-terrain-enabled .maplibregl-ctrl-icon, .mapboxgl-ctrl button.mapboxgl-ctrl-terrain-enabled .mapboxgl-ctrl-icon { background-image: svg-inline(ctrl-terrain-enabled); diff --git a/src/css/svg/maplibregl-ctrl-terrain-enabled.svg b/src/css/svg/maplibregl-ctrl-terrain-enabled.svg deleted file mode 100644 index a0dbeeeee59..00000000000 --- a/src/css/svg/maplibregl-ctrl-terrain-enabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/css/svg/maplibregl-ctrl-terrain.svg b/src/css/svg/maplibregl-ctrl-terrain.svg index 1e23d4e5e6e..af8fefe7a58 100644 --- a/src/css/svg/maplibregl-ctrl-terrain.svg +++ b/src/css/svg/maplibregl-ctrl-terrain.svg @@ -1,7 +1,7 @@ - - + + From 8ab66b0d06c8e8da6af1e485bee5788104870ea8 Mon Sep 17 00:00:00 2001 From: acalcutt Date: Sun, 26 Dec 2021 13:25:19 -0500 Subject: [PATCH 069/138] revert some merge changes --- .gitignore | 1 + package-lock.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 734e2216b86..715d1ee3fd1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /dist/ /dist_type/ *.es.js +*.js.map node_modules *.sublime-* coverage diff --git a/package-lock.json b/package-lock.json index c1361c6d48b..34a96c0153a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24151,4 +24151,4 @@ "dev": true } } -} +} \ No newline at end of file From be5e0e915314218e26533251969256aab3d50c12 Mon Sep 17 00:00:00 2001 From: acalcutt Date: Sun, 26 Dec 2021 13:28:36 -0500 Subject: [PATCH 070/138] Revert package-lock.json for pull request --- package-lock.json | 33866 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 28452 insertions(+), 5414 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34a96c0153a..9ea43f540eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,28205 @@ { "name": "maplibre-gl", "version": "2.0.0-pre.6", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "maplibre-gl", + "version": "2.0.0-pre.6", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.0", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^2.0.1", + "@mapbox/tiny-sdf": "^2.0.4", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.2.1", + "grid-index": "^1.1.0", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "supercluster": "^7.1.0", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + }, + "devDependencies": { + "@babel/core": "^7.16.0", + "@mapbox/gazetteer": "^5.1.0", + "@mapbox/mapbox-gl-rtl-text": "^0.2.1", + "@mapbox/mvt-fixtures": "^3.6.0", + "@octokit/rest": "^18.10.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.6", + "@rollup/plugin-replace": "^3.0.0", + "@rollup/plugin-strip": "^2.1.0", + "@rollup/plugin-typescript": "^8.3.0", + "@types/babel__core": "^7.1.12", + "@types/babelify": "^7.3.6", + "@types/benchmark": "^2.1.0", + "@types/browserify": "^12.0.36", + "@types/cssnano": "^4.0.0", + "@types/d3": "^4.13.12", + "@types/diff": "^4.0.2", + "@types/earcut": "^2.1.1", + "@types/ejs": "^3.1.0", + "@types/eslint": "^7.28.2", + "@types/geojson": "^7946.0.7", + "@types/gl": "^4.1.0", + "@types/glob": "^7.1.3", + "@types/jest": "^27.0.2", + "@types/jsdom": "^16.2.5", + "@types/jsonwebtoken": "^8.5.5", + "@types/lodash.template": "^4.5.0", + "@types/minimist": "^1.2.1", + "@types/murmurhash-js": "^1.0.3", + "@types/node-notifier": "^8.0.0", + "@types/npm-packlist": "^1.1.1", + "@types/offscreencanvas": "^2019.6.3", + "@types/pbf": "^3.0.2", + "@types/pixelmatch": "^5.2.2", + "@types/pngjs": "^6.0.1", + "@types/puppeteer": "^5.4.4", + "@types/react": "^17.0.19", + "@types/react-dom": "^17.0.9", + "@types/request": "^2.48.7", + "@types/rollup-plugin-json": "^3.0.2", + "@types/selenium-webdriver": "^4.0.16", + "@types/shuffle-seed": "^1.1.0", + "@types/sinon": "^10.0.2", + "@types/stylelint": "^13.13.2", + "@types/supercluster": "^5.0.2", + "@types/tape": "^4.13.2", + "@types/window-or-global": "^1.0.4", + "@typescript-eslint/eslint-plugin": "^4.30.0", + "@typescript-eslint/parser": "^4.30.0", + "address": "^1.1.2", + "babel-eslint": "^10.0.1", + "babel-jest": "^27.2.5", + "babelify": "^10.0.0", + "benchmark": "^2.1.4", + "browserify": "^17.0.0", + "canvas": "^2.6.1", + "chalk": "^4.1.2", + "chokidar": "^3.0.2", + "cssnano": "^5.0.8", + "d3": "^4.12.0", + "diff": "^4.0.1", + "documentation": "~12.1.1", + "dts-bundle-generator": "^6.0.0", + "ejs": "^3.1.6", + "eslint": "^7.32.0", + "eslint-config-mourner": "^3.0.0", + "eslint-plugin-html": "^6.1.2", + "eslint-plugin-import": "^2.24.2", + "eslint-plugin-jest": "^25.2.2", + "eslint-plugin-jsdoc": "^37.0.3", + "eslint-plugin-react": "^7.25.1", + "gl": "^4.5.3", + "glob": "^7.1.4", + "is-builtin-module": "^3.0.0", + "jest": "^27.2.4", + "jest-canvas-mock": "^2.3.1", + "jest-codemods": "^0.24.0", + "jest-raw-loader": "^1.0.1", + "jscodeshift": "^0.13.0", + "jsdom": "^13.0.0", + "json-stringify-pretty-compact": "^3.0.0", + "jsonwebtoken": "^8.3.0", + "list-npm-contents": "^1.0.2", + "lodash": "^4.17.19", + "lodash.template": "^4.5.0", + "mapbox-gl-styles": "^2.0.2", + "minimist": "^1.2.5", + "mock-geolocation": "^1.0.11", + "node-notifier": "^10.0.0", + "node-plantuml": "^0.9.0", + "npm-font-open-sans": "^1.1.0", + "npm-packlist": "^3.0.0", + "npm-run-all": "^4.1.5", + "nyc": "^15.1.0", + "pirates": "^4.0.1", + "pixelmatch": "^5.1.0", + "pngjs": "^6.0.0", + "postcss": "^8.3.11", + "postcss-cli": "^9.0.2", + "postcss-inline-svg": "^5.0.0", + "pretty-bytes": "^5.1.0", + "puppeteer": "^11.0.0", + "qrcode-terminal": "^0.12.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "replace-in-file": "^6.2.0", + "request": "^2.88.0", + "rollup": "^2.56.3", + "rollup-plugin-buble": "^0.19.8", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-replace": "^2.2.0", + "rollup-plugin-sourcemaps": "^0.6.3", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-unassert": "^0.3.0", + "rollup-pluginutils": "^2.8.2", + "rw": "^1.3.3", + "selenium-webdriver": "^4.0.0-rc-1", + "semver": "^7.3.5", + "shuffle-seed": "^1.1.6", + "sinon": "^12.0.1", + "source-map-explorer": "^2.5.1", + "st": "^3.0.0", + "stylelint": "^13.13.1", + "stylelint-config-standard": "^22.0.0", + "tap": "~12.4.1", + "tap-parser": "^10.0.1", + "tape": "^5.3.1", + "tape-filter": "^1.0.4", + "testem": "^3.5.0", + "ts-jest": "^27.0.5", + "ts-node": "^10.2.1", + "typescript": "^4.4.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.15.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/compat-data": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-compilation-targets": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.16.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-function-name": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-get-function-arity": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-hoist-variables": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-module-imports": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-module-transforms": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-optimise-call-expression": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-replace-supers": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-simple-access": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/highlight": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/parser": { + "version": "7.16.2", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/template": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/traverse": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.14.9", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-wrap-function": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/code-frame": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/generator": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-get-function-arity": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-hoist-variables": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/highlight": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/parser": { + "version": "7.16.2", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/template": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/traverse": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.15.6", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.15.4", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-decorators": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-do-expressions": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-do-expressions": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-default-from": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-default-from": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-function-bind": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-function-bind": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-function-sent": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-wrap-function": "^7.14.5", + "@babel/plugin-syntax-function-sent": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.15.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-pipeline-operator": { + "version": "7.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-pipeline-operator": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-throw-expressions": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-throw-expressions": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-do-expressions": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-default-from": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-function-bind": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-function-sent": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-pipeline-operator": { + "version": "7.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-throw-expressions": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.15.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.14.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-flow": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.15.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.14.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.15.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.14.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.14.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/code-frame": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/generator": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-function-name": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-get-function-arity": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-hoist-variables": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-optimise-call-expression": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-replace-supers": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/highlight": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/parser": { + "version": "7.16.2", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/template": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/traverse": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/@babel/types": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-typescript/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.15.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", + "@babel/plugin-proposal-async-generator-functions": "^7.15.4", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.15.4", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.15.6", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.15.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.15.3", + "@babel/plugin-transform-classes": "^7.15.4", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.7", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.15.4", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.15.4", + "@babel/plugin-transform-modules-systemjs": "^7.15.4", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.15.4", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.14.6", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.15.6", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.16.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-flow": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-flow-strip-types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-react-display-name": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.5", + "@babel/plugin-transform-react-jsx-development": "^7.14.5", + "@babel/plugin-transform-react-pure-annotations": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-stage-0": { + "version": "7.8.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/preset-typescript": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/register": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/register/node_modules/find-cache-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/pkg-dir": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/runtime": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.15.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.15.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.2.4", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "2.0.0" + }, + "engines": { + "node": "^12 || ^14 || ^16 || ^17" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hapi/address": { + "version": "2.1.4", + "deprecated": "Moved to 'npm install @sideway/address'", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/bourne": { + "version": "1.3.2", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/hoek": { + "version": "8.5.1", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/joi": { + "version": "15.1.1", + "deprecated": "Switch to 'npm install joi'", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "node_modules/@hapi/topo": { + "version": "3.1.6", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^8.3.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.3.1", + "jest-util": "^27.3.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.3.1", + "@jest/reporters": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.3.0", + "jest-config": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-resolve-dependencies": "^27.3.1", + "jest-runner": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "jest-watcher": "^27.3.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.3.1", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.3.1", + "@jest/types": "^27.2.5", + "expect": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/jest-worker": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@jest/source-map": { + "version": "27.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^27.3.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-runtime": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.2.5", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.3.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "27.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@mapbox/gazetteer": { + "version": "5.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@hapi/joi": "^15.0.3", + "@mapbox/geojsonhint": "^2.2.0" + } + }, + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.1", + "license": "ISC", + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojsonhint": { + "version": "2.2.0", + "deprecated": "Please make plans to check GeoJSON in some other way", + "dev": true, + "license": "ISC", + "dependencies": { + "concat-stream": "^1.6.1", + "jsonlint-lines": "1.7.1", + "minimist": "1.2.0", + "vfile": "^4.0.0", + "vfile-reporter": "^5.1.1" + }, + "bin": { + "geojsonhint": "bin/geojsonhint" + } + }, + "node_modules/@mapbox/geojsonhint/node_modules/minimist": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/mapbox-gl-rtl-text": { + "version": "0.2.3", + "dev": true, + "license": "BSD-2-Clause", + "peerDependencies": { + "mapbox-gl": ">=0.32.1 <2.0.0" + } + }, + "node_modules/@mapbox/mapbox-gl-supported": { + "version": "2.0.1", + "license": "BSD-3-Clause" + }, + "node_modules/@mapbox/mvt-fixtures": { + "version": "3.6.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@mapbox/sphericalmercator": "^1.0.5", + "@mapbox/vector-tile": "^1.3.0", + "d3-queue": "^3.0.7", + "pbf": "^3.0.5", + "protocol-buffers-schema": "^3.3.2" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "license": "ISC" + }, + "node_modules/@mapbox/sphericalmercator": { + "version": "1.1.0", + "dev": true, + "bin": { + "bbox": "bin/bbox.js", + "to4326": "bin/to4326.js", + "to900913": "bin/to900913.js", + "xyz": "bin/xyz.js" + } + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "2.0.4", + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "license": "ISC", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.4.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "10.1.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.16.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.27.2" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.10.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.27.2", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.0", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.9.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^10.1.5" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "21.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^2.38.3" + } + }, + "node_modules/@rollup/plugin-json": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.0.8" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "13.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^2.42.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-strip": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "estree-walker": "^2.0.1", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-typescript": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", + "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0", + "tslib": "*", + "typescript": ">=3.7.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "7.1.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "dev": true, + "license": "(Unlicense OR Apache-2.0)" + }, + "node_modules/@stylelint/postcss-css-in-js": { + "version": "0.37.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": ">=7.9.0" + }, + "peerDependencies": { + "postcss": ">=7.0.0", + "postcss-syntax": ">=0.36.2" + } + }, + "node_modules/@stylelint/postcss-markdown": { + "version": "0.36.2", + "dev": true, + "license": "MIT", + "dependencies": { + "remark": "^13.0.0", + "unist-util-find-all-after": "^3.0.2" + }, + "peerDependencies": { + "postcss": ">=7.0.0", + "postcss-syntax": ">=0.36.2" + } + }, + "node_modules/@stylelint/postcss-markdown/node_modules/is-plain-obj": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@stylelint/postcss-markdown/node_modules/remark": { + "version": "13.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@stylelint/postcss-markdown/node_modules/remark-parse": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@stylelint/postcss-markdown/node_modules/remark-stringify": { + "version": "9.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@stylelint/postcss-markdown/node_modules/unified": { + "version": "9.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.1.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/babel-core": { + "version": "6.25.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel-generator": "*", + "@types/babel-template": "*", + "@types/babel-traverse": "*", + "@types/babel-types": "*", + "@types/babylon": "*" + } + }, + "node_modules/@types/babel-generator": { + "version": "6.25.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel-types": "*" + } + }, + "node_modules/@types/babel-template": { + "version": "6.25.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel-types": "*", + "@types/babylon": "*" + } + }, + "node_modules/@types/babel-traverse": { + "version": "6.25.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel-types": "*" + } + }, + "node_modules/@types/babel-types": { + "version": "7.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babelify": { + "version": "7.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/babylon": { + "version": "6.16.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel-types": "*" + } + }, + "node_modules/@types/benchmark": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/browserify": { + "version": "12.0.37", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/insert-module-globals": "*", + "@types/node": "*" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/component-emitter": { + "version": "1.2.10", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cssnano": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "5 - 7" + } + }, + "node_modules/@types/cssnano/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/cssnano/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/cssnano/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/@types/cssnano/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@types/cssnano/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/d3": { + "version": "4.13.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-array": "^1", + "@types/d3-axis": "^1", + "@types/d3-brush": "^1", + "@types/d3-chord": "^1", + "@types/d3-collection": "*", + "@types/d3-color": "^1", + "@types/d3-dispatch": "^1", + "@types/d3-drag": "^1", + "@types/d3-dsv": "^1", + "@types/d3-ease": "^1", + "@types/d3-force": "^1", + "@types/d3-format": "^1", + "@types/d3-geo": "^1", + "@types/d3-hierarchy": "^1", + "@types/d3-interpolate": "^1", + "@types/d3-path": "^1", + "@types/d3-polygon": "^1", + "@types/d3-quadtree": "^1", + "@types/d3-queue": "*", + "@types/d3-random": "^1", + "@types/d3-request": "*", + "@types/d3-scale": "^1", + "@types/d3-selection": "^1", + "@types/d3-shape": "^1", + "@types/d3-time": "^1", + "@types/d3-time-format": "^2", + "@types/d3-timer": "^1", + "@types/d3-transition": "^1", + "@types/d3-voronoi": "*", + "@types/d3-zoom": "^1" + } + }, + "node_modules/@types/d3-array": { + "version": "1.2.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "1.0.16", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-brush": { + "version": "1.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-chord": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-collection": { + "version": "1.0.10", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-dsv": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "1.0.10", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-force": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "1.12.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "1.1.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "1.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-color": "^1" + } + }, + "node_modules/@types/d3-path": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-queue": { + "version": "3.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-request": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "^1" + } + }, + "node_modules/@types/d3-scale": { + "version": "1.0.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-time": "^1" + } + }, + "node_modules/@types/d3-selection": { + "version": "1.4.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-path": "^1" + } + }, + "node_modules/@types/d3-time": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "1.0.10", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-voronoi": { + "version": "1.1.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-zoom": { + "version": "1.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "^1", + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/diff": { + "version": "4.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/earcut": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ejs": { + "version": "3.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "7.28.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.39", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/gl": { + "version": "4.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/insert-module-globals": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/jsdom": { + "version": "16.2.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/parse5": "*", + "@types/tough-cookie": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "8.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.172", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash.template": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/mdast": { + "version": "3.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/murmurhash-js": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "16.9.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node-notifier": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/npm-packlist": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/webgl2": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse5": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/pbf": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/pixelmatch": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/pngjs": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/puppeteer": { + "version": "5.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/react": { + "version": "17.0.19", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "17.0.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/request": { + "version": "2.48.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/rollup-plugin-json": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "rollup": "^0.63.4" + } + }, + "node_modules/@types/rollup-plugin-json/node_modules/rollup": { + "version": "0.63.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "@types/node": "*" + }, + "bin": { + "rollup": "bin/rollup" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/selenium-webdriver": { + "version": "4.0.16", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/shuffle-seed": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sinon": { + "version": "10.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinonjs/fake-timers": "^7.1.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/stylelint": { + "version": "13.13.2", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "11.x.x", + "postcss": "7.x.x" + } + }, + "node_modules/@types/stylelint/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/stylelint/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/stylelint/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/@types/stylelint/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@types/stylelint/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/supercluster": { + "version": "5.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/tape": { + "version": "4.13.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/webgl2": { + "version": "0.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/window-or-global": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.30.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/experimental-utils": "4.30.0", + "@typescript-eslint/scope-manager": "4.30.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.30.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.30.0", + "@typescript-eslint/types": "4.30.0", + "@typescript-eslint/typescript-estree": "4.30.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.30.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "4.30.0", + "@typescript-eslint/types": "4.30.0", + "@typescript-eslint/typescript-estree": "4.30.0", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.30.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "4.30.0", + "@typescript-eslint/visitor-keys": "4.30.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.30.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.30.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "4.30.0", + "@typescript-eslint/visitor-keys": "4.30.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.30.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "4.30.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abab": { + "version": "2.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/accepts": { + "version": "1.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-dynamic-import": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0" + } + }, + "node_modules/acorn-globals": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals/node_modules/acorn-walk": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-node": { + "version": "1.8.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/amdefine": { + "version": "1.0.1", + "dev": true, + "license": "BSD-3-Clause OR MIT", + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html": { + "version": "0.0.7", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-buffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/archy": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-differ": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-equal": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/assert": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-types": { + "version": "0.14.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types/node_modules/tslib": { + "version": "2.3.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "0.9.2", + "dev": true, + "license": "MIT" + }, + "node_modules/async-cache": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^4.0.0" + } + }, + "node_modules/async-cache/node_modules/lru-cache": { + "version": "4.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/async-cache/node_modules/yallist": { + "version": "2.1.2", + "dev": true, + "license": "ISC" + }, + "node_modules/async-each": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/atob": { + "version": "2.1.2", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.6", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/autoprefixer/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/autoprefixer/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/autoprefixer/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-core": { + "version": "7.0.0-bridge.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-eslint": { + "version": "10.1.0", + "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "eslint": ">= 4.12.1" + } + }, + "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-jest": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.14.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^27.2.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babelify": { + "version": "10.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/backbone": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "underscore": ">=1.8.3" + } + }, + "node_modules/backbone/node_modules/underscore": { + "version": "1.13.1", + "dev": true, + "license": "MIT" + }, + "node_modules/bail": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base": { + "version": "0.11.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.4", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/benchmark": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/bind-obj-methods": { + "version": "2.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/bindings": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bit-twiddle": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/block-stream": { + "version": "0.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "inherits": "~2.0.0" + }, + "engines": { + "node": "0.4 || >=0.5.8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/body": { + "version": "5.1.0", + "dev": true, + "dependencies": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, + "node_modules/body-parser": { + "version": "1.19.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/boxen": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/browser-pack": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "JSONStream": "^1.0.3", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + }, + "bin": { + "browser-pack": "bin/cmd.js" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/browser-resolve": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.17.0" + } + }, + "node_modules/browserify": { + "version": "17.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^2.0.0", + "browserify-zlib": "~0.2.0", + "buffer": "~5.2.1", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.1", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^3.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.2.1", + "JSONStream": "^1.0.3", + "labeled-stream-splicer": "^2.0.0", + "mkdirp-classic": "^0.5.2", + "module-deps": "^6.2.3", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "^1.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum-object": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^3.0.0", + "stream-http": "^3.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.12.0", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "browserify": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001254", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.830", + "escalade": "^3.1.1", + "node-releases": "^1.1.75" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/btoa": { + "version": "1.2.1", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "btoa": "bin/btoa.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/buble": { + "version": "0.19.8", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^6.1.1", + "acorn-dynamic-import": "^4.0.0", + "acorn-jsx": "^5.0.1", + "chalk": "^2.4.2", + "magic-string": "^0.25.3", + "minimist": "^1.2.0", + "os-homedir": "^2.0.0", + "regexpu-core": "^4.5.4" + }, + "bin": { + "buble": "bin/buble" + } + }, + "node_modules/buble/node_modules/acorn": { + "version": "6.4.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buble/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/buble/node_modules/os-homedir": { + "version": "2.0.0", + "deprecated": "This is not needed anymore. Use `require('os').homedir()` instead.", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/buffer": { + "version": "5.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-shims": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "1.0.0", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "4.5.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/cached-path-relative": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-matcher": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-equal": "^1.0.0", + "espurify": "^2.0.0", + "estraverse": "^4.0.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-api/node_modules/lodash.memoize": { + "version": "4.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001257", + "dev": true, + "license": "CC-BY-4.0", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/canvas": { + "version": "2.8.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.14.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/capture-stack-trace": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ccount": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/charm": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/class-utils": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/clean-yaml-object": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clone-regexp": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/clone-stats": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cloneable-readable": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "node_modules/co": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collapse-white-space": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colord": { + "version": "2.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "0.6.2", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combine-source-map": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "node_modules/combine-source-map/node_modules/convert-source-map": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/comment-parser": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/configstore": { + "version": "5.0.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/consolidate": { + "version": "0.15.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/continuable-cache": { + "version": "0.3.1", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.17.3", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.17.0", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/coveralls": { + "version": "3.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + }, + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/create-error-class": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "capture-stack-trace": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn-async": { + "version": "2.2.5", + "deprecated": "cross-spawn no longer requires a build toolchain, use it instead", + "dev": true, + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "node_modules/cross-spawn-async/node_modules/lru-cache": { + "version": "4.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/cross-spawn-async/node_modules/yallist": { + "version": "2.1.2", + "dev": true, + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-color-names": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "timsort": "^0.3.0" + }, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-select": { + "version": "4.1.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "5.0.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csscolorparser": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssfontparser": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cssnano": { + "version": "5.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^5.1.4", + "is-resolvable": "^1.1.0", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "css-declaration-sorter": "^6.0.3", + "cssnano-utils": "^2.0.1", + "postcss-calc": "^8.0.0", + "postcss-colormin": "^5.2.0", + "postcss-convert-values": "^5.0.1", + "postcss-discard-comments": "^5.0.1", + "postcss-discard-duplicates": "^5.0.1", + "postcss-discard-empty": "^5.0.1", + "postcss-discard-overridden": "^5.0.1", + "postcss-merge-longhand": "^5.0.2", + "postcss-merge-rules": "^5.0.2", + "postcss-minify-font-values": "^5.0.1", + "postcss-minify-gradients": "^5.0.2", + "postcss-minify-params": "^5.0.1", + "postcss-minify-selectors": "^5.1.0", + "postcss-normalize-charset": "^5.0.1", + "postcss-normalize-display-values": "^5.0.1", + "postcss-normalize-positions": "^5.0.1", + "postcss-normalize-repeat-style": "^5.0.1", + "postcss-normalize-string": "^5.0.1", + "postcss-normalize-timing-functions": "^5.0.1", + "postcss-normalize-unicode": "^5.0.1", + "postcss-normalize-url": "^5.0.2", + "postcss-normalize-whitespace": "^5.0.1", + "postcss-ordered-values": "^5.0.2", + "postcss-reduce-initial": "^5.0.1", + "postcss-reduce-transforms": "^5.0.1", + "postcss-svgo": "^5.0.2", + "postcss-unique-selectors": "^5.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/cssom": { + "version": "0.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "0.3.x" + } + }, + "node_modules/csstype": { + "version": "3.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3": { + "version": "4.13.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1.2.1", + "d3-axis": "1.0.8", + "d3-brush": "1.0.4", + "d3-chord": "1.0.4", + "d3-collection": "1.0.4", + "d3-color": "1.0.3", + "d3-dispatch": "1.0.3", + "d3-drag": "1.2.1", + "d3-dsv": "1.0.8", + "d3-ease": "1.0.3", + "d3-force": "1.1.0", + "d3-format": "1.2.2", + "d3-geo": "1.9.1", + "d3-hierarchy": "1.1.5", + "d3-interpolate": "1.1.6", + "d3-path": "1.0.5", + "d3-polygon": "1.0.3", + "d3-quadtree": "1.0.3", + "d3-queue": "3.0.7", + "d3-random": "1.1.0", + "d3-request": "1.0.6", + "d3-scale": "1.0.7", + "d3-selection": "1.3.0", + "d3-shape": "1.2.0", + "d3-time": "1.0.8", + "d3-time-format": "2.1.1", + "d3-timer": "1.0.7", + "d3-transition": "1.1.1", + "d3-voronoi": "1.1.2", + "d3-zoom": "1.7.1" + } + }, + "node_modules/d3-array": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-axis": { + "version": "1.0.8", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-brush": { + "version": "1.0.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "node_modules/d3-chord": { + "version": "1.0.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1", + "d3-path": "1" + } + }, + "node_modules/d3-collection": { + "version": "1.0.4", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-color": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-dispatch": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-drag": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "node_modules/d3-dsv": { + "version": "1.0.8", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json", + "csv2tsv": "bin/dsv2dsv", + "dsv2dsv": "bin/dsv2dsv", + "dsv2json": "bin/dsv2json", + "json2csv": "bin/json2dsv", + "json2dsv": "bin/json2dsv", + "json2tsv": "bin/json2dsv", + "tsv2csv": "bin/dsv2dsv", + "tsv2json": "bin/dsv2json" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/d3-ease": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-force": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "node_modules/d3-format": { + "version": "1.2.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-geo": { + "version": "1.9.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1" + } + }, + "node_modules/d3-hierarchy": { + "version": "1.1.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-interpolate": { + "version": "1.1.6", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-color": "1" + } + }, + "node_modules/d3-path": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-polygon": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-quadtree": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-queue": { + "version": "3.0.7", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-random": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-request": { + "version": "1.0.6", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-dsv": "1", + "xmlhttprequest": "1" + } + }, + "node_modules/d3-scale": { + "version": "1.0.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "^1.2.0", + "d3-collection": "1", + "d3-color": "1", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "node_modules/d3-selection": { + "version": "1.3.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-shape": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-time": { + "version": "1.0.8", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-time-format": { + "version": "2.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-time": "1" + } + }, + "node_modules/d3-timer": { + "version": "1.0.7", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-transition": { + "version": "1.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "node_modules/d3-voronoi": { + "version": "1.1.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-zoom": { + "version": "1.7.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "node_modules/dash-ast": { + "version": "1.0.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "node_modules/de-indent": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-require-extensions": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/define-properties": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/deps-sort": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "JSONStream": "^1.0.3", + "shasum-object": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + }, + "bin": { + "deps-sort": "bin/cmd.js" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/detab": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.5.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detective": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.901419", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/diff": { + "version": "4.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/doctrine-temporary-fork": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation": { + "version": "12.1.4", + "dev": true, + "license": "ISC", + "dependencies": { + "@babel/core": "^7.1.2", + "@babel/generator": "^7.1.3", + "@babel/parser": "7.1.3", + "@babel/plugin-proposal-class-properties": "^7.1.0", + "@babel/plugin-proposal-decorators": "^7.1.2", + "@babel/plugin-proposal-do-expressions": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-export-namespace-from": "^7.0.0", + "@babel/plugin-proposal-function-bind": "^7.0.0", + "@babel/plugin-proposal-function-sent": "^7.1.0", + "@babel/plugin-proposal-json-strings": "^7.0.0", + "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-numeric-separator": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-proposal-pipeline-operator": "^7.0.0", + "@babel/plugin-proposal-throw-expressions": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-import-meta": "^7.0.0", + "@babel/preset-env": "^7.1.0", + "@babel/preset-flow": "^7.0.0", + "@babel/preset-react": "^7.0.0", + "@babel/preset-stage-0": "^7.0.0", + "@babel/traverse": "^7.1.4", + "@babel/types": "^7.1.3", + "ansi-html": "^0.0.7", + "babelify": "^10.0.0", + "chalk": "^2.3.0", + "chokidar": "^2.0.4", + "concat-stream": "^1.6.0", + "diff": "^4.0.1", + "doctrine-temporary-fork": "2.1.0", + "get-port": "^4.0.0", + "git-url-parse": "^11.1.2", + "github-slugger": "1.2.0", + "glob": "^7.1.2", + "globals-docs": "^2.4.0", + "highlight.js": "^9.15.5", + "ini": "^1.3.5", + "js-yaml": "^3.10.0", + "lodash": "^4.17.10", + "mdast-util-inject": "^1.1.0", + "micromatch": "^3.1.5", + "mime": "^2.2.0", + "module-deps-sortable": "5.0.0", + "parse-filepath": "^1.0.2", + "pify": "^4.0.0", + "read-pkg-up": "^4.0.0", + "remark": "^9.0.0", + "remark-html": "^8.0.0", + "remark-reference-links": "^4.0.1", + "remark-toc": "^5.0.0", + "resolve": "^1.8.1", + "stream-array": "^1.1.2", + "strip-json-comments": "^2.0.1", + "tiny-lr": "^1.1.0", + "unist-builder": "^1.0.2", + "unist-util-visit": "^1.3.0", + "vfile": "^4.0.0", + "vfile-reporter": "^6.0.0", + "vfile-sort": "^2.1.0", + "vinyl": "^2.1.0", + "vinyl-fs": "^3.0.2", + "vue-template-compiler": "^2.5.16", + "yargs": "^12.0.2" + }, + "bin": { + "documentation": "bin/documentation.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/documentation/node_modules/@babel/parser": { + "version": "7.1.3", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/documentation/node_modules/acorn": { + "version": "5.7.4", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/documentation/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/documentation/node_modules/anymatch": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/documentation/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/binary-extensions": { + "version": "1.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/braces": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/browser-resolve": { + "version": "1.11.3", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/documentation/node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/documentation/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/documentation/node_modules/chokidar": { + "version": "2.1.8", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/documentation/node_modules/detective": { + "version": "4.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^5.2.1", + "defined": "^1.0.0" + } + }, + "node_modules/documentation/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/documentation/node_modules/fill-range": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/glob-parent": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/documentation/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/is-binary-path": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/documentation/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/documentation/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/micromatch": { + "version": "3.1.10", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/module-deps-sortable": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.5.0", + "defined": "^1.0.0", + "detective": "^4.0.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "JSONStream": "^1.0.3", + "readable-stream": "^2.0.2", + "resolve": "^1.1.3", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "module-deps": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/documentation/node_modules/module-deps-sortable/node_modules/concat-stream": { + "version": "1.5.2", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + } + }, + "node_modules/documentation/node_modules/module-deps-sortable/node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/documentation/node_modules/process-nextick-args": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/documentation/node_modules/readdirp": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/documentation/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/documentation/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/documentation/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/documentation/node_modules/to-regex-range": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/documentation/node_modules/vfile-reporter": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.5.0", + "string-width": "^4.0.0", + "supports-color": "^6.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-sort": "^2.1.2", + "vfile-statistics": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/documentation/node_modules/vfile-reporter/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domexception": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/domhandler": { + "version": "4.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotignore": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" + } + }, + "node_modules/dts-bundle-generator": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "typescript": ">=3.0.1", + "yargs": "^17.2.1" + }, + "bin": { + "dts-bundle-generator": "dist/bin/dts-bundle-generator.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/dts-bundle-generator/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dts-bundle-generator/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/dts-bundle-generator/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/dts-bundle-generator/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/dts-bundle-generator/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/dts-bundle-generator/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dts-bundle-generator/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/dts-bundle-generator/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dts-bundle-generator/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dts-bundle-generator/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dts-bundle-generator/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/dts-bundle-generator/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/dts-bundle-generator/node_modules/yargs": { + "version": "17.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dts-bundle-generator/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/duplexify": { + "version": "3.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/earcut": { + "version": "2.2.3", + "license": "ISC" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.6.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.838", + "dev": true, + "license": "ISC" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emittery": { + "version": "0.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "6.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.0", + "ws": "~7.4.2" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "0.1.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "7.4.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error": { + "version": "7.2.1", + "dev": true, + "dependencies": { + "string-template": "~0.2.1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.0", + "has-symbols": "^1.0.1", + "is-arguments": "^1.1.0", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-mourner": { + "version": "3.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-html": { + "version": "6.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "htmlparser2": "^6.0.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.24.2", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.6.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/find-up": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/locate-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-import/node_modules/p-limit": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/p-locate": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/p-try": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/read-pkg-up": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/experimental-utils": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.3.0", + "@typescript-eslint/types": "5.3.0", + "@typescript-eslint/typescript-estree": "5.3.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.3.0", + "@typescript-eslint/visitor-keys": "5.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.3.0", + "@typescript-eslint/visitor-keys": "5.3.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.3.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/eslint-visitor-keys": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "37.0.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "0.12.0", + "comment-parser": "1.2.4", + "debug": "^4.3.2", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "^2.0.0", + "lodash": "^4.17.21", + "regextras": "^0.8.0", + "semver": "^7.3.5", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": "^12 || ^14 || ^16 || ^17" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.25.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", + "doctrine": "^2.1.0", + "estraverse": "^5.2.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.4", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/estraverse": { + "version": "5.2.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/espurify": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/esquery": { + "version": "1.4.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-to-array": { + "version": "1.1.2", + "dev": true, + "license": "ISC" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/execall": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/expand-template": { + "version": "2.0.3", + "dev": true, + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-regex-util": "^27.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/extract-zip/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.13.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd": { + "version": "0.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/filelist": { + "version": "1.0.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/filter-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/fireworm": { + "version": "0.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "~0.2.9", + "is-type": "0.0.1", + "lodash.debounce": "^3.1.1", + "lodash.flatten": "^3.0.2", + "minimatch": "^3.0.2" + } + }, + "node_modules/fireworm/node_modules/async": { + "version": "0.2.10", + "dev": true + }, + "node_modules/fireworm/node_modules/lodash.debounce": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._getnative": "^3.0.0" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.2", + "dev": true, + "license": "ISC" + }, + "node_modules/flow-parser": { + "version": "0.163.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.14.3", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreach": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/foreground-child/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/foreground-child/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-exists-cached": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-extra": { + "version": "10.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fstream": { + "version": "1.0.12", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/function-loop": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/gauge": { + "version": "2.7.4", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/geojson-vt": { + "version": "3.2.1", + "license": "ISC" + }, + "node_modules/get-assigned-identifiers": { + "version": "1.2.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/get-caller-file": { + "version": "1.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-npm-tarball-url": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "normalize-registry-url": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-port": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-stdin": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-up": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.3.0", + "parse-url": "^6.0.0" + } + }, + "node_modules/git-url-parse": { + "version": "11.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^4.0.0" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/github-slugger": { + "version": "1.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "emoji-regex": ">=6.0.0 <=6.1.1" + } + }, + "node_modules/gl": { + "version": "4.9.0", + "dev": true, + "hasInstallScript": true, + "license": "BSD-2-Clause", + "dependencies": { + "bindings": "^1.5.0", + "bit-twiddle": "^1.0.2", + "glsl-tokenizer": "^2.0.2", + "nan": "^2.14.1", + "node-abi": "^2.18.0", + "node-gyp": "^7.1.0", + "prebuild-install": "^5.3.5" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/gl-matrix": { + "version": "3.3.0", + "license": "MIT" + }, + "node_modules/glob": { + "version": "7.1.7", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-stream": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/glob-stream/node_modules/glob-parent": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-stream/node_modules/is-glob": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-dirs": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "1.3.7" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "1.3.7", + "dev": true, + "license": "ISC" + }, + "node_modules/global-modules": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globals-docs": { + "version": "2.4.1", + "dev": true, + "license": "ISC" + }, + "node_modules/globby": { + "version": "11.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/glsl-tokenizer": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "through2": "^0.6.3" + } + }, + "node_modules/glsl-tokenizer/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/glsl-tokenizer/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/glsl-tokenizer/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/glsl-tokenizer/node_modules/through2": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/got": { + "version": "6.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "dev": true, + "license": "ISC" + }, + "node_modules/grid-index": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/growly": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "deprecated": "this library is no longer supported", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-color": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-dynamic-import": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/has-value": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/hast-util-is-element": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-sanitize": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.1" + } + }, + "node_modules/hast-util-to-html": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ccount": "^1.0.0", + "comma-separated-tokens": "^1.0.1", + "hast-util-is-element": "^1.0.0", + "hast-util-whitespace": "^1.0.0", + "html-void-elements": "^1.0.0", + "property-information": "^4.0.0", + "space-separated-tokens": "^1.0.0", + "stringify-entities": "^1.0.1", + "unist-util-is": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/hast-util-to-html/node_modules/unist-util-is": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/hast-util-whitespace": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "9.18.5", + "deprecated": "Support has ended for 9.x series. Upgrade to @latest", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "dev": true, + "license": "ISC" + }, + "node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/html-tags": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-void-elements": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/htmlescape": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/http-parser-js": { + "version": "0.5.3", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.1.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "4.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/import-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "import-from": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-from": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-from/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "dev": true, + "license": "ISC" + }, + "node_modules/inline-source-map": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.5.3" + } + }, + "node_modules/inquirer": { + "version": "7.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/insert-module-globals": { + "version": "7.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "JSONStream": "^1.0.3", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + }, + "bin": { + "insert-module-globals": "bin/cmd.js" + } + }, + "node_modules/insert-module-globals/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/invert-kv": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-absolute-url": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumeric": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-builtin-module": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-git-clean": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^0.4.0", + "is-obj": "^1.0.1", + "multimatch": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-git-clean/node_modules/execa": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn-async": "^2.1.1", + "is-stream": "^1.1.0", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/is-git-clean/node_modules/npm-run-path": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-git-clean/node_modules/path-key": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-npm": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-redirect": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^1.1.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-type": { + "version": "0.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-whitespace-character": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-word-character": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.8.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^27.3.1", + "import-local": "^3.0.2", + "jest-cli": "^27.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-canvas-mock": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cssfontparser": "^1.2.1", + "moo-color": "^1.0.2" + } + }, + "node_modules/jest-changed-files": { + "version": "27.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-changed-files/node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-circus": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.3.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/stack-utils": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-codemods": { + "version": "0.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.4.5", + "@babel/preset-env": "^7.1.6", + "chalk": "^4.0.0", + "execa": "^4.0.2", + "globby": "^11.0.1", + "inquirer": "^7.1.0", + "is-git-clean": "^1.1.0", + "jscodeshift": "^0.13.0", + "meow": "^7.0.1", + "update-notifier": "^4.1.0" + }, + "bin": { + "jest-codemods": "bin/jest-codemods.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-codemods/node_modules/@babel/core": { + "version": "7.4.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helpers": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.5", + "@babel/types": "^7.4.4", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-codemods/node_modules/camelcase-keys": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-codemods/node_modules/execa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-codemods/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/human-signals": { + "version": "1.1.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/jest-codemods/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/map-obj": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/meow": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/jest-codemods/node_modules/read-pkg": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/read-pkg-up": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/redent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/jest-codemods/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/strip-indent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/trim-newlines": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-codemods/node_modules/type-fest": { + "version": "0.13.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-codemods/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-codemods/node_modules/yargs-parser": { + "version": "18.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-config": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.3.1", + "@jest/types": "^27.2.5", + "babel-jest": "^27.3.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.3.1", + "jest-environment-jsdom": "^27.3.1", + "jest-environment-node": "^27.3.1", + "jest-get-type": "^27.3.1", + "jest-jasmine2": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-runner": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "27.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "jest-get-type": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.3.1", + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn": { + "version": "8.5.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn-globals": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssom": { + "version": "0.4.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/domexception": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/escodegen": { + "version": "2.0.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/form-data": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "16.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/levn": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/optionator": { + "version": "0.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/parse5": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/prelude-ls": { + "version": "1.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/saxes": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tough-cookie": { + "version": "4.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/type-check": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "8.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/ws": { + "version": "7.5.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/jest-environment-node": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.3.1", + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-haste-map/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-haste-map/node_modules/jest-worker": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-haste-map/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.3.1", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.3.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.3.1", + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/stack-utils": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-mock": { + "version": "27.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-raw-loader": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-regex-util": { + "version": "27.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.3.1", + "@jest/environment": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.3.1", + "jest-environment-node": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-leak-detector": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/jest-worker": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-runtime": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.3.1", + "@jest/environment": "^27.3.1", + "@jest/globals": "^27.3.1", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-mock": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runtime/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-runtime/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runtime/node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/jest-runtime/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runtime/node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-runtime/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-serializer": { + "version": "27.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.3.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.3.1", + "jest-get-type": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-util": "^27.3.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.3.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.3.1", + "leven": "^3.1.0", + "pretty-format": "^27.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.3.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jest/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jest/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/jest/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/jest-cli": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/jest/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/jest/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/jscodeshift": { + "version": "0.13.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.13.16", + "@babel/parser": "^7.13.16", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/preset-flow": "^7.13.13", + "@babel/preset-typescript": "^7.13.0", + "@babel/register": "^7.13.16", + "babel-core": "^7.0.0-bridge.0", + "colors": "^1.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^3.1.10", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.20.4", + "temp": "^0.8.4", + "write-file-atomic": "^2.3.0" + }, + "bin": { + "jscodeshift": "bin/jscodeshift.js" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + } + }, + "node_modules/jscodeshift/node_modules/braces": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/colors": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/jscodeshift/node_modules/fill-range": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/jscodeshift/node_modules/is-number": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/micromatch": { + "version": "3.1.10", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/jscodeshift/node_modules/temp": { + "version": "0.8.4", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/jscodeshift/node_modules/to-regex-range": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/write-file-atomic": { + "version": "2.4.3", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdom": { + "version": "13.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.0.9", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.5", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "6.4.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.2.3", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-pretty-compact": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonlint-lines": { + "version": "1.7.1", + "dev": true, + "dependencies": { + "JSV": ">= 4.0.x", + "nomnom": ">= 1.5.x" + }, + "bin": { + "jsonlint": "lib/cli.js" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/JSV": { + "version": "4.0.2", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jszip": { + "version": "3.7.1", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/jwa": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kdbush": { + "version": "3.0.0", + "license": "ISC" + }, + "node_modules/keyv": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.21.0", + "dev": true, + "license": "MIT" + }, + "node_modules/labeled-stream-splicer": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "stream-splicer": "^2.0.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lazystream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lcid": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "invert-kv": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lcov-parse": { + "version": "1.0.0", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "lcov-parse": "bin/cli.js" + } + }, + "node_modules/lead": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/list-npm-contents": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.5.0", + "get-npm-tarball-url": "^2.0.0", + "got": "^6.7.1", + "is-url": "^1.2.2", + "ls-archive": "^1.2.3", + "meow": "^3.3.0", + "registry-url": "^4.0.0", + "tmp": "0.0.31" + }, + "bin": { + "list-npm-contents": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/livereload-js": { + "version": "2.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._baseflatten": { + "version": "3.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.castarray": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.find": { + "version": "4.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._baseflatten": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.forown": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "3.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/log-driver": { + "version": "1.2.7", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=0.8.6" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/longest-streak": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ls-archive": { + "version": "1.3.4", + "dev": true, + "dependencies": { + "async": "~0.2.9", + "colors": "~0.6.2", + "optimist": "~0.5.2", + "rimraf": "~2.2.6", + "tar": "^2.2.1", + "yauzl": "^2.9.1" + }, + "bin": { + "lsa": "bin/lsa" + } + }, + "node_modules/ls-archive/node_modules/async": { + "version": "0.2.10", + "dev": true + }, + "node_modules/ls-archive/node_modules/rimraf": { + "version": "2.2.8", + "dev": true, + "license": "MIT", + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ls-archive/node_modules/tar": { + "version": "2.2.2", + "deprecated": "This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.", + "dev": true, + "license": "ISC", + "dependencies": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "node_modules/magic-string": { + "version": "0.25.7", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mapbox-gl-styles": { + "version": "2.0.2", + "deprecated": "This package has moved to the @mapbox namespace. All new version are available via @mapbox/mapbox-gl-styles", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^5.0.14" + } + }, + "node_modules/mapbox-gl-styles/node_modules/glob": { + "version": "5.0.15", + "dev": true, + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/markdown-escapes": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdast-util-compact": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-visit": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/parse-entities": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-inject": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-to-string": "^1.0.0" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "collapse-white-space": "^1.0.0", + "detab": "^2.0.0", + "mdast-util-definitions": "^1.2.0", + "mdurl": "^1.0.1", + "trim": "0.0.1", + "trim-lines": "^1.0.0", + "unist-builder": "^1.0.1", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.0", + "xtend": "^4.0.1" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/parse-entities": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-to-string": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-toc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "github-slugger": "^1.2.1", + "mdast-util-to-string": "^1.0.5", + "unist-util-is": "^2.1.2", + "unist-util-visit": "^1.1.0" + } + }, + "node_modules/mdast-util-toc/node_modules/github-slugger": { + "version": "1.4.0", + "dev": true, + "license": "ISC" + }, + "node_modules/mdast-util-toc/node_modules/unist-util-is": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/meow": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/load-json-file": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/parse-json": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/path-exists": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/path-type": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/strip-bom": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/parse-entities": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/mime": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.49.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.32", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.49.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "license": "MIT" + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mock-geolocation": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/module-deps": { + "version": "6.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-resolve": "^2.0.0", + "cached-path-relative": "^1.0.2", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.2.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "JSONStream": "^1.0.3", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "module-deps": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/moo-color": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.1.4" + } + }, + "node_modules/moo-color/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/multi-stage-sourcemap": { + "version": "0.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.1.34" + } + }, + "node_modules/multi-stage-sourcemap/node_modules/source-map": { + "version": "0.1.43", + "dev": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/multimatch": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/multimatch/node_modules/array-union": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/mustache": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + }, + "engines": { + "npm": ">=1.4.0" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "license": "ISC" + }, + "node_modules/nan": { + "version": "2.15.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.1.30", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/nise": { + "version": "5.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/node-abi": { + "version": "2.30.1", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-dir": { + "version": "0.1.17", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.2" + }, + "engines": { + "node": ">= 0.10.5" + } + }, + "node_modules/node-fetch": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-nailgun-client": { + "version": "0.1.2", + "dev": true, + "license": "Apache v2", + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "node-nailgun-client": "index.js" + } + }, + "node_modules/node-nailgun-client/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/node-nailgun-server": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "node-nailgun-server": "index.js" + } + }, + "node_modules/node-nailgun-server/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/node-notifier": { + "version": "10.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.5", + "shellwords": "^0.1.1", + "uuid": "^8.3.2", + "which": "^2.0.2" + } + }, + "node_modules/node-notifier/node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/node-notifier/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/node-plantuml": { + "version": "0.9.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "commander": "^2.8.1", + "node-nailgun-client": "^0.1.0", + "node-nailgun-server": "^0.1.4", + "plantuml-encoder": "^1.2.5" + }, + "bin": { + "puml": "index.js" + }, + "engines": { + "node": ">= 6.x" + } + }, + "node_modules/node-plantuml/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/node-preload": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "1.1.75", + "dev": true, + "license": "MIT" + }, + "node_modules/nomnom": { + "version": "1.8.1", + "deprecated": "Package no longer supported. Contact support@npmjs.com for more info.", + "dev": true, + "dependencies": { + "chalk": "~0.4.0", + "underscore": "~1.6.0" + } + }, + "node_modules/nomnom/node_modules/ansi-styles": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nomnom/node_modules/chalk": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/noop-logger": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "5.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-registry-url": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-selector": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/now-and-later": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-font-open-sans": { + "version": "1.1.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/npm-packlist": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.6", + "ignore-walk": "^4.0.1", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.0.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc": { + "version": "15.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/nyc/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/require-main-filename": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "7.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optimist": { + "version": "0.5.2", + "dev": true, + "license": "MIT/X11", + "dependencies": { + "wordwrap": "~0.0.2" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/own-or": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/own-or-env": { + "version": "1.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "own-or": "^1.0.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/decompress-response": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json/node_modules/got": { + "version": "9.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/package-json/node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json/node_modules/prepend-http": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/package-json/node_modules/registry-url": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/package-json/node_modules/url-parse-lax": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parents": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-platform": "~0.11.15" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-entities": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-path": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0", + "qs": "^6.9.4", + "query-string": "^6.13.8" + } + }, + "node_modules/parse-url": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.3.0", + "normalize-url": "^6.1.0", + "parse-path": "^4.0.0", + "protocols": "^1.4.0" + } + }, + "node_modules/parse5": { + "version": "5.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-platform": { + "version": "0.11.15", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/path-root": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pbf": { + "version": "3.2.1", + "license": "BSD-3-Clause", + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pixelmatch": { + "version": "5.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "pngjs": "^4.0.1" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pixelmatch/node_modules/pngjs": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/p-try": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/plantuml-encoder": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/platform": { + "version": "1.3.6", + "dev": true, + "license": "MIT" + }, + "node_modules/pn": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pngjs": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "8.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-calc": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-cli": { + "version": "9.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.3.0", + "dependency-graph": "^0.11.0", + "fs-extra": "^10.0.0", + "get-stdin": "^9.0.0", + "globby": "^12.0.0", + "picocolors": "^1.0.0", + "postcss-load-config": "^3.0.0", + "postcss-reporter": "^7.0.0", + "pretty-hrtime": "^1.0.3", + "read-cache": "^1.0.0", + "slash": "^4.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "postcss": "index.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-cli/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/postcss-cli/node_modules/array-union": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/postcss-cli/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/postcss-cli/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-cli/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-cli/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/postcss-cli/node_modules/get-stdin": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/globby": { + "version": "12.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^3.0.1", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.7", + "ignore": "^5.1.8", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-cli/node_modules/slash": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-cli/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/postcss-cli/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/postcss-cli/node_modules/yargs": { + "version": "17.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/postcss-cli/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/postcss-colormin": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-html": { + "version": "0.36.0", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^3.10.0" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-html/node_modules/dom-serializer": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/postcss-html/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/postcss-html/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/postcss-html/node_modules/domelementtype": { + "version": "1.3.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/postcss-html/node_modules/domhandler": { + "version": "2.4.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/postcss-html/node_modules/domutils": { + "version": "1.7.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/postcss-html/node_modules/entities": { + "version": "1.1.2", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/postcss-html/node_modules/htmlparser2": { + "version": "3.10.1", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/postcss-html/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-inline-svg": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^3.1.0", + "dom-serializer": "^1.1.0", + "htmlparser2": "^5.0.1", + "postcss-value-parser": "^4.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-inline-svg/node_modules/css-select": { + "version": "3.1.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/postcss-inline-svg/node_modules/css-what": { + "version": "4.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/postcss-inline-svg/node_modules/htmlparser2": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.3.0", + "domutils": "^2.4.2", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/fb55/htmlparser2?sponsor=1" + } + }, + "node_modules/postcss-inline-svg/node_modules/htmlparser2/node_modules/domhandler": { + "version": "3.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/postcss-less": { + "version": "3.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/postcss-less/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-less/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-less/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-less/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-less/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "import-cwd": "^3.0.0", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-merge-longhand": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "css-color-names": "^1.0.1", + "postcss-value-parser": "^4.1.0", + "stylehacks": "^5.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^2.0.1", + "postcss-selector-parser": "^6.0.5", + "vendors": "^1.0.3" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "colord": "^2.6", + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "alphanum-sort": "^1.0.2", + "browserslist": "^4.16.0", + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-absolute-url": "^3.0.3", + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reporter": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.difference": "^4.5.0", + "lodash.forown": "^4.4.0", + "lodash.get": "^4.4.2", + "lodash.groupby": "^4.6.0", + "lodash.sortby": "^4.7.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "^7.0.26" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-safe-parser/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-safe-parser/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-safe-parser/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-safe-parser/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-safe-parser/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-sass": { + "version": "0.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "postcss": "^7.0.21" + } + }, + "node_modules/postcss-sass/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sass/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sass/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-sass/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-sass/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-scss": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "^7.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-scss/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-scss/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-scss/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-scss/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-scss/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.1.0", + "svgo": "^2.3.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-syntax": { + "version": "0.36.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "postcss": ">=5.0.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.5", + "uniqs": "^2.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/potpack": { + "version": "1.0.1", + "license": "ISC" + }, + "node_modules/prebuild-install": { + "version": "5.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prebuild-install/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "27.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/printf": { + "version": "0.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.9.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/property-information": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.1" + } + }, + "node_modules/protocol-buffers-schema": { + "version": "3.5.1", + "license": "MIT" + }, + "node_modules/protocols": { + "version": "1.4.8", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/psl": { + "version": "1.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/pupa": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer": { + "version": "11.0.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "4.3.2", + "devtools-protocol": "0.0.901419", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.5", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/puppeteer/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/node-fetch": { + "version": "2.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/puppeteer/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/tr46": { + "version": "0.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/puppeteer/node_modules/webidl-conversions": { + "version": "3.0.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/puppeteer/node_modules/whatwg-url": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/puppeteer/node_modules/ws": { + "version": "8.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/qs": { + "version": "6.10.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-string": { + "version": "6.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.0", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/quickselect": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "1", + "string_decoder": "0.10" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/raw-body/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/rc": { + "version": "1.2.8", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/react": { + "version": "17.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "dev": true, + "license": "MIT" + }, + "node_modules/read-cache": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-only-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recast": { + "version": "0.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "0.14.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/recast/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/recast/node_modules/tslib": { + "version": "2.3.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/redent": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "8.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "4.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regextras": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.2.7" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/regjsgen": { + "version": "0.5.2", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.6.9", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/remark": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-parse": "^5.0.0", + "remark-stringify": "^5.0.0", + "unified": "^6.0.0" + } + }, + "node_modules/remark-html": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "hast-util-sanitize": "^1.0.0", + "hast-util-to-html": "^4.0.0", + "mdast-util-to-hast": "^3.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/remark-parse": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/remark-reference-links": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-visit": "^1.0.0" + } + }, + "node_modules/remark-slug": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "github-slugger": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^1.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "node_modules/remark-toc": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-toc": "^3.0.0", + "remark-slug": "^5.0.0" + } + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-buffer/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/replace-ext": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/replace-in-file": { + "version": "6.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "glob": "^7.2.0", + "yargs": "^17.2.1" + }, + "bin": { + "replace-in-file": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/replace-in-file/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/replace-in-file/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/replace-in-file/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/replace-in-file/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/replace-in-file/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/replace-in-file/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/replace-in-file/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/replace-in-file/node_modules/glob": { + "version": "7.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/replace-in-file/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/replace-in-file/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace-in-file/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace-in-file/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/replace-in-file/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/replace-in-file/node_modules/yargs": { + "version": "17.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/replace-in-file/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "license": "ISC", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-options": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resumer": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "~2.3.4" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rollup": { + "version": "2.56.3", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-buble": { + "version": "0.19.8", + "deprecated": "This module has been deprecated and is no longer maintained. Please use @rollup/plugin-buble.", + "dev": true, + "license": "MIT", + "dependencies": { + "buble": "^0.19.8", + "rollup-pluginutils": "^2.3.3" + } + }, + "node_modules/rollup-plugin-commonjs": { + "version": "10.1.0", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs.", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^0.6.1", + "is-reference": "^1.1.2", + "magic-string": "^0.25.2", + "resolve": "^1.11.0", + "rollup-pluginutils": "^2.8.1" + }, + "peerDependencies": { + "rollup": ">=1.12.0" + } + }, + "node_modules/rollup-plugin-commonjs/node_modules/estree-walker": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/rollup-plugin-node-resolve": { + "version": "5.2.0", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve.", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.11.1", + "rollup-pluginutils": "^2.8.1" + }, + "peerDependencies": { + "rollup": ">=1.11.0" + } + }, + "node_modules/rollup-plugin-node-resolve/node_modules/@types/resolve": { + "version": "0.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/rollup-plugin-replace": { + "version": "2.2.0", + "deprecated": "This module has moved and is now available at @rollup/plugin-replace. Please update your dependencies. This version is no longer maintained.", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.25.2", + "rollup-pluginutils": "^2.6.0" + } + }, + "node_modules/rollup-plugin-sourcemaps": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.0.9", + "source-map-resolve": "^0.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "@types/node": ">=10.0.0", + "rollup": ">=0.31.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/rollup-plugin-sourcemaps/node_modules/source-map-resolve": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-unassert": { + "version": "0.3.0", + "dev": true, + "license": "Beerware", + "dependencies": { + "acorn": "^6.1.1", + "convert-source-map": "^1.6.0", + "escodegen": "^1.11.1", + "multi-stage-sourcemap": "^0.3.1", + "rollup-pluginutils": "^2.5.0", + "unassert": "^1.5.1" + } + }, + "node_modules/rollup-plugin-unassert/node_modules/acorn": { + "version": "6.4.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/run-async": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/rxjs": { + "version": "6.6.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-json-parse": { + "version": "1.0.1", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "3.1.11", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scheduler": { + "version": "0.20.2", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/seedrandom": { + "version": "2.4.4", + "dev": true, + "license": "MIT" + }, + "node_modules/selenium-webdriver": { + "version": "4.0.0-rc-1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jszip": "^3.6.0", + "rimraf": "^3.0.2", + "tmp": "^0.2.1", + "ws": ">=7.4.6" + }, + "engines": { + "node": ">= 10.15.0" + } + }, + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/selenium-webdriver/node_modules/ws": { + "version": "8.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/semver": { + "version": "7.3.5", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/set-immediate-shim": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shasum-object": { + "version": "1.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/shellwords": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/shuffle-seed": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "seedrandom": "^2.4.2" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sinon": { + "version": "12.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^8.1.0", + "@sinonjs/samsam": "^6.0.2", + "diff": "^5.0.0", + "nise": "^5.1.0", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.0.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~5.2.0", + "socket.io-adapter": "~2.3.2", + "socket.io-parser": "~4.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io-parser": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-explorer": { + "version": "2.5.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "btoa": "^1.2.1", + "chalk": "^4.1.0", + "convert-source-map": "^1.7.0", + "ejs": "^3.1.5", + "escape-html": "^1.0.3", + "glob": "^7.1.6", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "open": "^7.3.1", + "source-map": "^0.7.3", + "temp": "^0.9.4", + "yargs": "^16.2.0" + }, + "bin": { + "sme": "bin/cli.js", + "source-map-explorer": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map-explorer/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-explorer/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/source-map-explorer/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/source-map-explorer/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/source-map-explorer/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map-explorer/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map-explorer/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/source-map-explorer/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-explorer/node_modules/source-map": { + "version": "0.7.3", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-explorer/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-explorer/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-explorer/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/source-map-explorer/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map-explorer/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map-explorer/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map-js": { + "version": "1.0.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "dev": true, + "license": "MIT" + }, + "node_modules/space-separated-tokens": { + "version": "1.1.5", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spawn-args": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/specificity": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "bin": { + "specificity": "bin/specificity" + } + }, + "node_modules/split-on-first": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sshpk": { + "version": "1.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/st": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "async-cache": "^1.1.0", + "bl": "^5.0.0", + "fd": "~0.0.3", + "mime": "^2.5.2", + "negotiator": "~0.6.2" + }, + "bin": { + "st": "bin/server.js" + }, + "optionalDependencies": { + "graceful-fs": "^4.2.3" + } + }, + "node_modules/st/node_modules/bl": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/st/node_modules/buffer": { + "version": "6.0.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/st/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "dev": true, + "license": "MIT" + }, + "node_modules/stack-utils": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/state-toggle": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-array/node_modules/process-nextick-args": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-array/node_modules/readable-stream": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-array/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-splicer": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-template": { + "version": "0.2.1", + "dev": true + }, + "node_modules/string-width": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "node_modules/strip-ansi": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "bin": { + "strip-ansi": "cli.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/styled_string": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/stylehacks": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.0", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/stylelint": { + "version": "13.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@stylelint/postcss-css-in-js": "^0.37.2", + "@stylelint/postcss-markdown": "^0.36.2", + "autoprefixer": "^9.8.6", + "balanced-match": "^2.0.0", + "chalk": "^4.1.1", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "execall": "^2.0.0", + "fast-glob": "^3.2.5", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.0.3", + "globjoin": "^0.1.4", + "html-tags": "^3.1.0", + "ignore": "^5.1.8", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.21.0", + "lodash": "^4.17.21", + "log-symbols": "^4.1.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.4", + "normalize-selector": "^0.2.0", + "postcss": "^7.0.35", + "postcss-html": "^0.36.0", + "postcss-less": "^3.1.4", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.2", + "postcss-sass": "^0.4.4", + "postcss-scss": "^2.1.1", + "postcss-selector-parser": "^6.0.5", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^4.1.0", + "resolve-from": "^5.0.0", + "slash": "^3.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.2", + "strip-ansi": "^6.0.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^6.6.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^3.0.3" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "stylelint": "^13.13.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "22.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "stylelint-config-recommended": "^5.0.0" + }, + "peerDependencies": { + "stylelint": "^13.13.0" + } + }, + "node_modules/stylelint/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/camelcase-keys": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/get-stdin": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/hosted-git-info": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/map-obj": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/meow": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/normalize-package-data": { + "version": "3.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/stylelint/node_modules/postcss/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/postcss/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/read-pkg": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/read-pkg-up": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "dev": true, + "license": "ISC" + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/redent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/strip-indent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/trim-newlines": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/type-fest": { + "version": "0.18.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/subarg": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.1.0" + } + }, + "node_modules/sugarss": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/sugarss/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sugarss/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sugarss/node_modules/postcss": { + "version": "7.0.36", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/sugarss/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sugarss/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/supercluster": { + "version": "7.1.3", + "license": "ISC", + "dependencies": { + "kdbush": "^3.0.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "dev": true + }, + "node_modules/svgo": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "colorette": "^1.3.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/syntax-error": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn-node": "^1.2.0" + } + }, + "node_modules/table": { + "version": "6.7.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap": { + "version": "12.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "bind-obj-methods": "^2.0.0", + "browser-process-hrtime": "^1.0.0", + "capture-stack-trace": "^1.0.0", + "clean-yaml-object": "^0.1.0", + "color-support": "^1.1.0", + "coveralls": "^3.0.2", + "domain-browser": "^1.2.0", + "foreground-child": "^1.3.3", + "fs-exists-cached": "^1.0.0", + "function-loop": "^1.0.1", + "glob": "^7.1.3", + "isexe": "^2.0.0", + "js-yaml": "^3.12.1", + "minipass": "^2.3.5", + "mkdirp": "^0.5.1", + "nyc": "^13.1.0", + "opener": "^1.5.1", + "os-homedir": "^1.0.2", + "own-or": "^1.0.0", + "own-or-env": "^1.0.1", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.0", + "source-map-support": "^0.5.10", + "stack-utils": "^1.0.2", + "tap-mocha-reporter": "^3.0.7", + "tap-parser": "^7.0.0", + "tmatch": "^4.0.0", + "trivial-deferred": "^1.0.1", + "ts-node": "^8.0.1", + "tsame": "^2.0.1", + "typescript": "^3.2.4", + "write-file-atomic": "^2.3.0", + "yapool": "^1.0.0" + }, + "bin": { + "tap": "bin/run.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap-mocha-reporter": { + "version": "3.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "color-support": "^1.1.0", + "debug": "^2.1.3", + "diff": "^1.3.2", + "escape-string-regexp": "^1.0.3", + "glob": "^7.0.5", + "js-yaml": "^3.3.1", + "tap-parser": "^5.1.0", + "unicode-length": "^1.0.0" + }, + "bin": { + "tap-mocha-reporter": "index.js" + }, + "optionalDependencies": { + "readable-stream": "^2.1.5" + } + }, + "node_modules/tap-mocha-reporter/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/tap-mocha-reporter/node_modules/diff": { + "version": "1.4.0", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tap-mocha-reporter/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tap-mocha-reporter/node_modules/tap-parser": { + "version": "5.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "events-to-array": "^1.0.1", + "js-yaml": "^3.2.7" + }, + "bin": { + "tap-parser": "bin/cmd.js" + }, + "optionalDependencies": { + "readable-stream": "^2" + } + }, + "node_modules/tap-parser": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "events-to-array": "^1.0.1", + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" + }, + "bin": { + "tap-parser": "bin/cmd.js" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tap-yaml": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yaml": "^1.5.0" + } + }, + "node_modules/tap/node_modules/cross-spawn": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/tap/node_modules/foreground-child": { + "version": "1.5.6", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "node_modules/tap/node_modules/istanbul-lib-coverage": { + "version": "2.0.5", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/istanbul-lib-instrument": { + "version": "3.3.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/lru-cache": { + "version": "4.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/tap/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/tap/node_modules/minipass/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/tap/node_modules/nyc": { + "version": "13.3.0", + "bundleDependencies": [ + "archy", + "arrify", + "caching-transform", + "convert-source-map", + "find-cache-dir", + "find-up", + "foreground-child", + "glob", + "istanbul-lib-coverage", + "istanbul-lib-hook", + "istanbul-lib-report", + "istanbul-lib-source-maps", + "istanbul-reports", + "make-dir", + "merge-source-map", + "resolve-from", + "rimraf", + "signal-exit", + "spawn-wrap", + "test-exclude", + "uuid", + "yargs", + "yargs-parser" + ], + "dev": true, + "license": "ISC", + "dependencies": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.1.0", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.1", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/ansi-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/append-transform": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "default-require-extensions": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/arrify": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/async": { + "version": "2.6.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/caching-transform": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/camelcase": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/cliui": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/commander": { + "version": "2.17.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/tap/node_modules/nyc/node_modules/commondir": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/convert-source-map": { + "version": "1.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/cross-spawn": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/debug": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/default-require-extensions": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/end-of-stream": { + "version": "1.4.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/es6-error": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/execa": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/find-cache-dir": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/foreground-child": { + "version": "1.5.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/get-caller-file": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/glob": { + "version": "7.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/graceful-fs": { + "version": "4.1.15", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/handlebars": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/hasha": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-stream": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/hosted-git-info": { + "version": "2.7.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/invert-kv": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-lib-coverage": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-lib-hook": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "append-transform": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-lib-report": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "6.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-lib-source-maps": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/istanbul-reports": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "handlebars": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/json-parse-better-errors": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/lcid": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "invert-kv": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/load-json-file": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/lodash": { + "version": "4.17.11", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/lodash.flattendeep": { + "version": "4.4.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/lru-cache": { + "version": "4.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/make-dir": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/map-age-cleaner": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/mem": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/merge-source-map": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/merge-source-map/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/mimic-fn": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/minimist": { + "version": "0.0.10", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/mkdirp": { + "version": "0.5.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/mkdirp/node_modules/minimist": { + "version": "0.0.8", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/npm-run-path": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/optimist": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "MIT/X11", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/os-locale": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/p-defer": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/p-is-promise": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/p-limit": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/p-try": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/package-hash": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/parse-json": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/path-parse": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/path-type": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/pify": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/pkg-dir": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/pseudomap": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/read-pkg": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/read-pkg-up": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/release-zalgo": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/require-main-filename": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/resolve": { + "version": "1.10.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/nyc/node_modules/semver": { + "version": "5.6.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/signal-exit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/spawn-wrap": { + "version": "1.4.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/spdx-correct": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/spdx-exceptions": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/tap/node_modules/nyc/node_modules/spdx-expression-parse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/spdx-license-ids": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/tap/node_modules/nyc/node_modules/string-width": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/strip-eof": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/test-exclude": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/uglify-js": { + "version": "3.4.9", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/uuid": { + "version": "3.3.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/which": { + "version": "1.3.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/which-module": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/wordwrap": { + "version": "0.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/wrap-ansi": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/wrap-ansi/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/write-file-atomic": { + "version": "2.4.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/y18n": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/yallist": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/nyc/node_modules/yargs": { + "version": "12.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "node_modules/tap/node_modules/nyc/node_modules/yargs-parser": { + "version": "11.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/tap/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tap/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/tap/node_modules/tap-parser": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "events-to-array": "^1.0.1", + "js-yaml": "^3.2.7", + "minipass": "^2.2.0" + }, + "bin": { + "tap-parser": "bin/cmd.js" + } + }, + "node_modules/tap/node_modules/ts-node": { + "version": "8.10.2", + "dev": true, + "license": "MIT", + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/tap/node_modules/typescript": { + "version": "3.9.10", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/tap/node_modules/write-file-atomic": { + "version": "2.4.3", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/tap/node_modules/yallist": { + "version": "2.1.2", + "dev": true, + "license": "ISC" + }, + "node_modules/tape": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "deep-equal": "^2.0.5", + "defined": "^1.0.0", + "dotignore": "^0.1.2", + "for-each": "^0.3.3", + "get-package-type": "^0.1.0", + "glob": "^7.1.7", + "has": "^1.0.3", + "has-dynamic-import": "^2.0.0", + "inherits": "^2.0.4", + "is-regex": "^1.1.4", + "minimist": "^1.2.5", + "object-inspect": "^1.11.0", + "object-is": "^1.1.5", + "object.assign": "^4.1.2", + "resolve": "^2.0.0-next.3", + "resumer": "^0.0.0", + "string.prototype.trim": "^1.2.4", + "through": "^2.3.8" + }, + "bin": { + "tape": "bin/tape" + } + }, + "node_modules/tape-filter": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + } + }, + "node_modules/tape/node_modules/deep-equal": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "es-get-iterator": "^1.1.1", + "get-intrinsic": "^1.0.1", + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.2", + "is-regex": "^1.1.1", + "isarray": "^2.0.5", + "object-is": "^1.1.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.3", + "which-boxed-primitive": "^1.0.1", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tape/node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/tape/node_modules/resolve": { + "version": "2.0.0-next.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.1.11", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "license": "ISC" + }, + "node_modules/tar-fs/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.8.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/testem": { + "version": "3.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.7.1", + "backbone": "^1.1.2", + "bluebird": "^3.4.6", + "charm": "^1.0.0", + "commander": "^2.6.0", + "compression": "^1.7.4", + "consolidate": "^0.15.1", + "execa": "^1.0.0", + "express": "^4.10.7", + "fireworm": "^0.7.0", + "glob": "^7.0.4", + "http-proxy": "^1.13.1", + "js-yaml": "^3.2.5", + "lodash.assignin": "^4.1.0", + "lodash.castarray": "^4.4.0", + "lodash.clonedeep": "^4.4.1", + "lodash.find": "^4.5.1", + "lodash.uniqby": "^4.7.0", + "mkdirp": "^0.5.1", + "mustache": "^3.0.0", + "node-notifier": "^9.0.1", + "npmlog": "^4.0.0", + "printf": "^0.6.1", + "rimraf": "^2.4.4", + "socket.io": "^4.1.2", + "spawn-args": "^0.2.0", + "styled_string": "0.0.1", + "tap-parser": "^7.0.0", + "tmp": "0.0.33" + }, + "bin": { + "testem": "testem.js" + }, + "engines": { + "node": ">= 7.*" + } + }, + "node_modules/testem/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/testem/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/testem/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/testem/node_modules/node-notifier": { + "version": "9.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "node_modules/testem/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/testem/node_modules/tap-parser": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "events-to-array": "^1.0.1", + "js-yaml": "^3.2.7", + "minipass": "^2.2.0" + }, + "bin": { + "tap-parser": "bin/cmd.js" + } + }, + "node_modules/testem/node_modules/tmp": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/testem/node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/testem/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/testem/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/throat": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timers-browserify": { + "version": "1.4.2", + "dev": true, + "dependencies": { + "process": "~0.11.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-lr": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "body": "^5.1.0", + "debug": "^3.1.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + } + }, + "node_modules/tiny-lr/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/tinyqueue": { + "version": "2.0.3", + "license": "ISC" + }, + "node_modules/tmatch": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/tmp": { + "version": "0.0.31", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tr46/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/trim": { + "version": "0.0.1", + "dev": true + }, + "node_modules/trim-lines": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-trailing-lines": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trivial-deferred": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/trough": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-jest": { + "version": "27.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", + "jest": "^27.0.0", + "typescript": ">=3.8 <5.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/lodash.memoize": { + "version": "4.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.5.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tsame": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/tsconfig-paths": { + "version": "3.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.4.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/umd": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "bin": { + "umd": "bin/cli.js" + } + }, + "node_modules/unassert": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.0.0", + "call-matcher": "^2.0.0", + "deep-equal": "^1.0.0", + "espurify": "^2.0.1", + "estraverse": "^4.1.0", + "esutils": "^2.0.2", + "object-assign": "^4.1.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undeclared-identifiers": { + "version": "1.1.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + }, + "bin": { + "undeclared-identifiers": "bin.js" + } + }, + "node_modules/underscore": { + "version": "1.6.0", + "dev": true + }, + "node_modules/unherit": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-length": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.3.2", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/unicode-length/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unicode-length/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + } + }, + "node_modules/unified/node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/unified/node_modules/unist-util-stringify-position": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/unified/node_modules/vfile": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "node_modules/unified/node_modules/vfile-message": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniqs": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unist-builder": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0" + } + }, + "node_modules/unist-util-find-all-after": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-all-after/node_modules/unist-util-is": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-generated": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-position": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unzip-response": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-notifier": { + "version": "4.1.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/update-notifier/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/update-notifier/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/import-lazy": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-notifier/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true, + "license": "MIT" + }, + "node_modules/url": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse-lax": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/use": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.12.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/value-or-function": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.5.0", + "string-width": "^2.0.0", + "supports-color": "^5.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-sort": "^2.1.2", + "vfile-statistics": "^1.1.0" + } + }, + "node_modules/vfile-sort": { + "version": "2.2.2", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-statistics": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vinyl": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/normalize-path": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "license": "MIT", + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.6.14", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/which-pm-runs": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/which-typed-array": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/widest-line/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "0.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/x-is-string": { + "version": "0.1.0", + "dev": true + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yapool": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "12.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "node_modules/yargs-parser": { + "version": "11.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/zwitch": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { "@babel/highlight": "^7.14.5" @@ -15,14 +28207,10 @@ }, "@babel/compat-data": { "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", "dev": true }, "@babel/core": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.0.tgz", - "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -44,8 +28232,6 @@ "dependencies": { "@babel/code-frame": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "requires": { "@babel/highlight": "^7.16.0" @@ -53,14 +28239,10 @@ }, "@babel/compat-data": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.0.tgz", - "integrity": "sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew==", "dev": true }, "@babel/generator": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz", - "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", "dev": true, "requires": { "@babel/types": "^7.16.0", @@ -70,8 +28252,6 @@ }, "@babel/helper-compilation-targets": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz", - "integrity": "sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==", "dev": true, "requires": { "@babel/compat-data": "^7.16.0", @@ -82,8 +28262,6 @@ }, "@babel/helper-function-name": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.16.0", @@ -93,8 +28271,6 @@ }, "@babel/helper-get-function-arity": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -102,8 +28278,6 @@ }, "@babel/helper-hoist-variables": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -111,8 +28285,6 @@ }, "@babel/helper-member-expression-to-functions": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz", - "integrity": "sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -120,8 +28292,6 @@ }, "@babel/helper-module-imports": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -129,8 +28299,6 @@ }, "@babel/helper-module-transforms": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz", - "integrity": "sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.16.0", @@ -145,8 +28313,6 @@ }, "@babel/helper-optimise-call-expression": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -154,8 +28320,6 @@ }, "@babel/helper-replace-supers": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz", - "integrity": "sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.16.0", @@ -166,8 +28330,6 @@ }, "@babel/helper-simple-access": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -175,8 +28337,6 @@ }, "@babel/helper-split-export-declaration": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -184,14 +28344,10 @@ }, "@babel/helper-validator-identifier": { "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, "@babel/highlight": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -201,14 +28357,10 @@ }, "@babel/parser": { "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", - "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", "dev": true }, "@babel/template": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -218,8 +28370,6 @@ }, "@babel/traverse": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz", - "integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -235,8 +28385,6 @@ }, "@babel/types": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -245,8 +28393,6 @@ }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -256,16 +28402,12 @@ }, "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/generator": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", - "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", "dev": true, "requires": { "@babel/types": "^7.15.4", @@ -275,8 +28417,6 @@ }, "@babel/helper-annotate-as-pure": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -284,8 +28424,6 @@ }, "@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", - "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.15.4", @@ -294,8 +28432,6 @@ }, "@babel/helper-compilation-targets": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "requires": { "@babel/compat-data": "^7.15.0", @@ -306,16 +28442,12 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/helper-create-class-features-plugin": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", - "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.15.4", @@ -328,8 +28460,6 @@ }, "@babel/helper-create-regexp-features-plugin": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.14.5", @@ -338,8 +28468,6 @@ }, "@babel/helper-define-polyfill-provider": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", - "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", @@ -354,16 +28482,12 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/helper-explode-assignable-expression": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", - "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -371,8 +28495,6 @@ }, "@babel/helper-function-name": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.15.4", @@ -382,8 +28504,6 @@ }, "@babel/helper-get-function-arity": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -391,8 +28511,6 @@ }, "@babel/helper-hoist-variables": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -400,8 +28518,6 @@ }, "@babel/helper-member-expression-to-functions": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -409,8 +28525,6 @@ }, "@babel/helper-module-imports": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -418,8 +28532,6 @@ }, "@babel/helper-module-transforms": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.4.tgz", - "integrity": "sha512-9fHHSGE9zTC++KuXLZcB5FKgvlV83Ox+NLUmQTawovwlJ85+QMhk1CnVk406CQVj97LaWod6KVjl2Sfgw9Aktw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.15.4", @@ -434,8 +28546,6 @@ }, "@babel/helper-optimise-call-expression": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -443,14 +28553,10 @@ }, "@babel/helper-plugin-utils": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true }, "@babel/helper-remap-async-to-generator": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", - "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.15.4", @@ -460,8 +28566,6 @@ }, "@babel/helper-replace-supers": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.15.4", @@ -472,8 +28576,6 @@ }, "@babel/helper-simple-access": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -481,8 +28583,6 @@ }, "@babel/helper-skip-transparent-expression-wrappers": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", - "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -490,8 +28590,6 @@ }, "@babel/helper-split-export-declaration": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "requires": { "@babel/types": "^7.15.4" @@ -499,20 +28597,14 @@ }, "@babel/helper-validator-identifier": { "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", "dev": true }, "@babel/helper-validator-option": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, "@babel/helper-wrap-function": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", - "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", "dev": true, "requires": { "@babel/helper-function-name": "^7.15.4", @@ -523,8 +28615,6 @@ }, "@babel/helpers": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.0.tgz", - "integrity": "sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==", "dev": true, "requires": { "@babel/template": "^7.16.0", @@ -534,8 +28624,6 @@ "dependencies": { "@babel/code-frame": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "requires": { "@babel/highlight": "^7.16.0" @@ -543,8 +28631,6 @@ }, "@babel/generator": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz", - "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", "dev": true, "requires": { "@babel/types": "^7.16.0", @@ -554,8 +28640,6 @@ }, "@babel/helper-function-name": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.16.0", @@ -565,8 +28649,6 @@ }, "@babel/helper-get-function-arity": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -574,8 +28656,6 @@ }, "@babel/helper-hoist-variables": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -583,8 +28663,6 @@ }, "@babel/helper-split-export-declaration": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -592,14 +28670,10 @@ }, "@babel/helper-validator-identifier": { "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, "@babel/highlight": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -609,14 +28683,10 @@ }, "@babel/parser": { "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", - "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", "dev": true }, "@babel/template": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -626,8 +28696,6 @@ }, "@babel/traverse": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz", - "integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -643,8 +28711,6 @@ }, "@babel/types": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -653,8 +28719,6 @@ }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -666,8 +28730,6 @@ }, "@babel/highlight": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.5", @@ -677,8 +28739,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -690,14 +28750,10 @@ }, "@babel/parser": { "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.6.tgz", - "integrity": "sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q==", "dev": true }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", - "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -707,8 +28763,6 @@ }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.4.tgz", - "integrity": "sha512-2zt2g5vTXpMC3OmK6uyjvdXptbhBXfA77XGrd3gh93zwG8lZYBLOBImiGBEG0RANu3JqKEACCz5CGk73OJROBw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -718,8 +28772,6 @@ }, "@babel/plugin-proposal-class-properties": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", - "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.14.5", @@ -728,8 +28780,6 @@ }, "@babel/plugin-proposal-class-static-block": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", - "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.15.4", @@ -739,8 +28789,6 @@ }, "@babel/plugin-proposal-decorators": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.15.4.tgz", - "integrity": "sha512-WNER+YLs7avvRukEddhu5PSfSaMMimX2xBFgLQS7Bw16yrUxJGWidO9nQp+yLy9MVybg5Ba3BlhAw+BkdhpDmg==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.15.4", @@ -750,8 +28798,6 @@ }, "@babel/plugin-proposal-do-expressions": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-do-expressions/-/plugin-proposal-do-expressions-7.14.5.tgz", - "integrity": "sha512-i40m/CLe5WBGYMZL/SC3xtjJ/B0i+XblaonSsinumgfNIqmBOf4LEcZJXijoQeQbQVl55PyM0siWSWWJ9lV7cA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -760,8 +28806,6 @@ }, "@babel/plugin-proposal-dynamic-import": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -770,8 +28814,6 @@ }, "@babel/plugin-proposal-export-default-from": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", - "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -780,8 +28822,6 @@ }, "@babel/plugin-proposal-export-namespace-from": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", - "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -790,8 +28830,6 @@ }, "@babel/plugin-proposal-function-bind": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.14.5.tgz", - "integrity": "sha512-PSQk5JImi81nFAzIebCEqkd0aiP9LDVKLCIH+0yR66JV8cQ1oZ8IRK9NNaA5nw9sjo0cPXxuBPCqgqcpugR8tA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -800,8 +28838,6 @@ }, "@babel/plugin-proposal-function-sent": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.14.5.tgz", - "integrity": "sha512-3Hvb9m1dvFK1cor9kObPCPK8q0xlcakm+haBwHQy7V5BN1As6iys9oOKyWpHVbop+tW8JYs0v9Ahcp1BOxC3Ng==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -811,8 +28847,6 @@ }, "@babel/plugin-proposal-json-strings": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -821,8 +28855,6 @@ }, "@babel/plugin-proposal-logical-assignment-operators": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", - "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -831,8 +28863,6 @@ }, "@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -841,8 +28871,6 @@ }, "@babel/plugin-proposal-numeric-separator": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -851,8 +28879,6 @@ }, "@babel/plugin-proposal-object-rest-spread": { "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", - "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", "dev": true, "requires": { "@babel/compat-data": "^7.15.0", @@ -864,8 +28890,6 @@ }, "@babel/plugin-proposal-optional-catch-binding": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -874,8 +28898,6 @@ }, "@babel/plugin-proposal-optional-chaining": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -885,8 +28907,6 @@ }, "@babel/plugin-proposal-pipeline-operator": { "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.15.0.tgz", - "integrity": "sha512-/XNBV8GmMxl7icZ0G5o4f3aGXHDKuhS8xHhbdusjE/ZDrsqtLq5kUiw/i7J6ZnlS/ngM0IQTN2CPlrPTb6GKVw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -895,8 +28915,6 @@ }, "@babel/plugin-proposal-private-methods": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", - "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.14.5", @@ -905,8 +28923,6 @@ }, "@babel/plugin-proposal-private-property-in-object": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", - "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.15.4", @@ -917,8 +28933,6 @@ }, "@babel/plugin-proposal-throw-expressions": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.14.5.tgz", - "integrity": "sha512-Db2JCIPhe409U3qy0sWpDun6Xa1k77TfNsKTzUY0PDRTpiho7e2uIhYMJVwGrHOkHRH03D6yQLZRosNahnpi1Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -927,8 +28941,6 @@ }, "@babel/plugin-proposal-unicode-property-regex": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.14.5", @@ -937,8 +28949,6 @@ }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -946,8 +28956,6 @@ }, "@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -955,8 +28963,6 @@ }, "@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.12.13" @@ -964,8 +28970,6 @@ }, "@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -973,8 +28977,6 @@ }, "@babel/plugin-syntax-decorators": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.14.5.tgz", - "integrity": "sha512-c4sZMRWL4GSvP1EXy0woIP7m4jkVcEuG8R1TOZxPBPtp4FSM/kiPZub9UIs/Jrb5ZAOzvTUSGYrWsrSu1JvoPw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -982,8 +28984,6 @@ }, "@babel/plugin-syntax-do-expressions": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-do-expressions/-/plugin-syntax-do-expressions-7.14.5.tgz", - "integrity": "sha512-IpVyxRlfFCU2emBiq2OxUX10PD6FoGZ30yWwGt1qdkIPUDhAodG5Il1LStODgATndKRhQgqT21ksqA5fd39AwA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -991,8 +28991,6 @@ }, "@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1000,8 +28998,6 @@ }, "@babel/plugin-syntax-export-default-from": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", - "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1009,8 +29005,6 @@ }, "@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -1018,8 +29012,6 @@ }, "@babel/plugin-syntax-flow": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", - "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1027,8 +29019,6 @@ }, "@babel/plugin-syntax-function-bind": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.14.5.tgz", - "integrity": "sha512-gstAIrKtlPwrQaRz4uK+kT7zI2p5MQqX41SeO+kZKH1XGO1jL0nLZBWznRigPpkem6LfIoG2EduQZmPBcUwEmg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1036,8 +29026,6 @@ }, "@babel/plugin-syntax-function-sent": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.14.5.tgz", - "integrity": "sha512-FNN0Ve2/6yxCa0xMG7wUlM81t+HOPu8HNWk683Xav1B+vjHKQQujX82NEKYdDYNUX7/ky8pUCHfRUYVmigs69Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1045,8 +29033,6 @@ }, "@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1054,8 +29040,6 @@ }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1063,8 +29047,6 @@ }, "@babel/plugin-syntax-jsx": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", - "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1072,8 +29054,6 @@ }, "@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1081,8 +29061,6 @@ }, "@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1090,8 +29068,6 @@ }, "@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1099,8 +29075,6 @@ }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1108,8 +29082,6 @@ }, "@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1117,8 +29089,6 @@ }, "@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" @@ -1126,8 +29096,6 @@ }, "@babel/plugin-syntax-pipeline-operator": { "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.15.0.tgz", - "integrity": "sha512-APuEsBJFWgLasnPi3XS4o7AW24Z8hsX1odmCl9it1fpIA38E2+rSWk6zy1MpFQYKGyphlh84dJB4MtDwI0XN5w==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1135,8 +29103,6 @@ }, "@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1144,8 +29110,6 @@ }, "@babel/plugin-syntax-throw-expressions": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.14.5.tgz", - "integrity": "sha512-4aFC2goA9+JceXayipcSY017nGspvcAkzR+sdsT6hN4DUuHWvM88wdjf/Nxja5sTE7oYPmfuN84ViREdgjingw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1153,8 +29117,6 @@ }, "@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1162,8 +29124,6 @@ }, "@babel/plugin-syntax-typescript": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz", - "integrity": "sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1171,8 +29131,6 @@ }, "@babel/plugin-transform-arrow-functions": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1180,8 +29138,6 @@ }, "@babel/plugin-transform-async-to-generator": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.14.5", @@ -1191,8 +29147,6 @@ }, "@babel/plugin-transform-block-scoped-functions": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1200,8 +29154,6 @@ }, "@babel/plugin-transform-block-scoping": { "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1209,8 +29161,6 @@ }, "@babel/plugin-transform-classes": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", - "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.15.4", @@ -1224,8 +29174,6 @@ }, "@babel/plugin-transform-computed-properties": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1233,8 +29181,6 @@ }, "@babel/plugin-transform-destructuring": { "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1242,8 +29188,6 @@ }, "@babel/plugin-transform-dotall-regex": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.14.5", @@ -1252,8 +29196,6 @@ }, "@babel/plugin-transform-duplicate-keys": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1261,8 +29203,6 @@ }, "@babel/plugin-transform-exponentiation-operator": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", @@ -1271,8 +29211,6 @@ }, "@babel/plugin-transform-flow-strip-types": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", - "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -1281,8 +29219,6 @@ }, "@babel/plugin-transform-for-of": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", - "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1290,8 +29226,6 @@ }, "@babel/plugin-transform-function-name": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", "dev": true, "requires": { "@babel/helper-function-name": "^7.14.5", @@ -1300,8 +29234,6 @@ }, "@babel/plugin-transform-literals": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1309,8 +29241,6 @@ }, "@babel/plugin-transform-member-expression-literals": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1318,8 +29248,6 @@ }, "@babel/plugin-transform-modules-amd": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.14.5", @@ -1329,8 +29257,6 @@ }, "@babel/plugin-transform-modules-commonjs": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", - "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.15.4", @@ -1341,8 +29267,6 @@ }, "@babel/plugin-transform-modules-systemjs": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.15.4", @@ -1354,8 +29278,6 @@ }, "@babel/plugin-transform-modules-umd": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.14.5", @@ -1364,8 +29286,6 @@ }, "@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.14.5" @@ -1373,8 +29293,6 @@ }, "@babel/plugin-transform-new-target": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1382,8 +29300,6 @@ }, "@babel/plugin-transform-object-super": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -1392,8 +29308,6 @@ }, "@babel/plugin-transform-parameters": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", - "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1401,8 +29315,6 @@ }, "@babel/plugin-transform-property-literals": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1410,8 +29322,6 @@ }, "@babel/plugin-transform-react-display-name": { "version": "7.15.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.15.1.tgz", - "integrity": "sha512-yQZ/i/pUCJAHI/LbtZr413S3VT26qNrEm0M5RRxQJA947/YNYwbZbBaXGDrq6CG5QsZycI1VIP6d7pQaBfP+8Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1419,8 +29329,6 @@ }, "@babel/plugin-transform-react-jsx": { "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.9.tgz", - "integrity": "sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.14.5", @@ -1432,8 +29340,6 @@ }, "@babel/plugin-transform-react-jsx-development": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.14.5.tgz", - "integrity": "sha512-rdwG/9jC6QybWxVe2UVOa7q6cnTpw8JRRHOxntG/h6g/guAOe6AhtQHJuJh5FwmnXIT1bdm5vC2/5huV8ZOorQ==", "dev": true, "requires": { "@babel/plugin-transform-react-jsx": "^7.14.5" @@ -1441,8 +29347,6 @@ }, "@babel/plugin-transform-react-pure-annotations": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.14.5.tgz", - "integrity": "sha512-3X4HpBJimNxW4rhUy/SONPyNQHp5YRr0HhJdT2OH1BRp0of7u3Dkirc7x9FRJMKMqTBI079VZ1hzv7Ouuz///g==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.14.5", @@ -1451,8 +29355,6 @@ }, "@babel/plugin-transform-regenerator": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" @@ -1460,8 +29362,6 @@ }, "@babel/plugin-transform-reserved-words": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1469,8 +29369,6 @@ }, "@babel/plugin-transform-shorthand-properties": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1478,8 +29376,6 @@ }, "@babel/plugin-transform-spread": { "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", - "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -1488,8 +29384,6 @@ }, "@babel/plugin-transform-sticky-regex": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1497,8 +29391,6 @@ }, "@babel/plugin-transform-template-literals": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1506,8 +29398,6 @@ }, "@babel/plugin-transform-typeof-symbol": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1515,8 +29405,6 @@ }, "@babel/plugin-transform-typescript": { "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.16.0", @@ -1526,8 +29414,6 @@ "dependencies": { "@babel/code-frame": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "requires": { "@babel/highlight": "^7.16.0" @@ -1535,8 +29421,6 @@ }, "@babel/generator": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz", - "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", "dev": true, "requires": { "@babel/types": "^7.16.0", @@ -1546,8 +29430,6 @@ }, "@babel/helper-annotate-as-pure": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -1555,8 +29437,6 @@ }, "@babel/helper-create-class-features-plugin": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz", - "integrity": "sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.0", @@ -1569,8 +29449,6 @@ }, "@babel/helper-function-name": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.16.0", @@ -1580,8 +29458,6 @@ }, "@babel/helper-get-function-arity": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -1589,8 +29465,6 @@ }, "@babel/helper-hoist-variables": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -1598,8 +29472,6 @@ }, "@babel/helper-member-expression-to-functions": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz", - "integrity": "sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -1607,8 +29479,6 @@ }, "@babel/helper-optimise-call-expression": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -1616,8 +29486,6 @@ }, "@babel/helper-replace-supers": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz", - "integrity": "sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.16.0", @@ -1628,8 +29496,6 @@ }, "@babel/helper-split-export-declaration": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, "requires": { "@babel/types": "^7.16.0" @@ -1637,14 +29503,10 @@ }, "@babel/helper-validator-identifier": { "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, "@babel/highlight": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -1654,14 +29516,10 @@ }, "@babel/parser": { "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", - "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", "dev": true }, "@babel/template": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -1671,8 +29529,6 @@ }, "@babel/traverse": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz", - "integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==", "dev": true, "requires": { "@babel/code-frame": "^7.16.0", @@ -1688,8 +29544,6 @@ }, "@babel/types": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -1698,8 +29552,6 @@ }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -1711,8 +29563,6 @@ }, "@babel/plugin-transform-unicode-escapes": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", - "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" @@ -1720,8 +29570,6 @@ }, "@babel/plugin-transform-unicode-regex": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.14.5", @@ -1730,8 +29578,6 @@ }, "@babel/preset-env": { "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.6.tgz", - "integrity": "sha512-L+6jcGn7EWu7zqaO2uoTDjjMBW+88FXzV8KvrBl2z6MtRNxlsmUNRlZPaNNPUTgqhyC5DHNFk/2Jmra+ublZWw==", "dev": true, "requires": { "@babel/compat-data": "^7.15.0", @@ -1811,16 +29657,12 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/preset-flow": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", - "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -1830,8 +29672,6 @@ }, "@babel/preset-modules": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1843,8 +29683,6 @@ }, "@babel/preset-react": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.14.5.tgz", - "integrity": "sha512-XFxBkjyObLvBaAvkx1Ie95Iaq4S/GUEIrejyrntQ/VCMKUYvKLoyKxOBzJ2kjA3b6rC9/KL6KXfDC2GqvLiNqQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -1857,14 +29695,10 @@ }, "@babel/preset-stage-0": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/preset-stage-0/-/preset-stage-0-7.8.3.tgz", - "integrity": "sha512-+l6FlG1j73t4wh78W41StbcCz0/9a1/y+vxfnjtHl060kSmcgMfGzK9MEkLvrCOXfhp9RCX+d88sm6rOqxEIEQ==", "dev": true }, "@babel/preset-typescript": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz", - "integrity": "sha512-txegdrZYgO9DlPbv+9QOVpMnKbOtezsLHWsnsRF4AjbSIsVaujrq1qg8HK0mxQpWv0jnejt0yEoW1uWpvbrDTg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", @@ -1874,8 +29708,6 @@ }, "@babel/register": { "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.0.tgz", - "integrity": "sha512-lzl4yfs0zVXnooeLE0AAfYaT7F3SPA8yB2Bj4W1BiZwLbMS3MZH35ZvCWSRHvneUugwuM+Wsnrj7h0F7UmU3NQ==", "dev": true, "requires": { "clone-deep": "^4.0.1", @@ -1887,8 +29719,6 @@ "dependencies": { "find-cache-dir": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", @@ -1898,8 +29728,6 @@ }, "make-dir": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { "pify": "^4.0.1", @@ -1908,8 +29736,6 @@ }, "pkg-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { "find-up": "^3.0.0" @@ -1917,16 +29743,12 @@ }, "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "@babel/runtime": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -1934,8 +29756,6 @@ }, "@babel/template": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", @@ -1945,8 +29765,6 @@ }, "@babel/traverse": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", @@ -1962,8 +29780,6 @@ }, "@babel/types": { "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.9", @@ -1972,20 +29788,14 @@ }, "@bcoe/v8-coverage": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, "@cspotcode/source-map-consumer": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", "dev": true }, "@cspotcode/source-map-support": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", "dev": true, "requires": { "@cspotcode/source-map-consumer": "0.8.0" @@ -1993,8 +29803,6 @@ }, "@es-joy/jsdoccomment": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.12.0.tgz", - "integrity": "sha512-Gw4/j9v36IKY8ET+W0GoOzrRw17xjf21EIFFRL3zx21fF5MnqmeNpNi+PU/LKjqLpPb2Pw2XdlJbYM31VVo/PQ==", "dev": true, "requires": { "comment-parser": "1.2.4", @@ -2004,8 +29812,6 @@ }, "@eslint/eslintrc": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -2021,8 +29827,6 @@ "dependencies": { "globals": { "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -2030,40 +29834,28 @@ }, "ignore": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true } } }, "@hapi/address": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", "dev": true }, "@hapi/bourne": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", "dev": true }, "@hapi/hoek": { "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", "dev": true }, "@hapi/joi": { "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", "dev": true, "requires": { "@hapi/address": "2.x.x", @@ -2074,8 +29866,6 @@ }, "@hapi/topo": { "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", "dev": true, "requires": { "@hapi/hoek": "^8.3.0" @@ -2083,8 +29873,6 @@ }, "@humanwhocodes/config-array": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", @@ -2094,14 +29882,10 @@ }, "@humanwhocodes/object-schema": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", "dev": true }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -2113,8 +29897,6 @@ "dependencies": { "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -2123,8 +29905,6 @@ }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -2132,8 +29912,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -2141,28 +29919,20 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true } } }, "@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, "@jest/console": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", - "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -2175,8 +29945,6 @@ }, "@jest/core": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", - "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", "dev": true, "requires": { "@jest/console": "^27.3.1", @@ -2211,14 +29979,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -2228,8 +29992,6 @@ }, "@jest/environment": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", - "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", "dev": true, "requires": { "@jest/fake-timers": "^27.3.1", @@ -2240,8 +30002,6 @@ }, "@jest/fake-timers": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", - "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -2254,8 +30014,6 @@ "dependencies": { "@sinonjs/fake-timers": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -2265,8 +30023,6 @@ }, "@jest/globals": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", - "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", "dev": true, "requires": { "@jest/environment": "^27.3.1", @@ -2276,8 +30032,6 @@ }, "@jest/reporters": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", - "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", @@ -2309,14 +30063,10 @@ "dependencies": { "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "jest-worker": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", "dev": true, "requires": { "@types/node": "*", @@ -2326,14 +30076,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -2343,8 +30089,6 @@ }, "@jest/source-map": { "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -2354,16 +30098,12 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "@jest/test-result": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", - "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", "dev": true, "requires": { "@jest/console": "^27.3.1", @@ -2374,8 +30114,6 @@ }, "@jest/test-sequencer": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", - "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", "dev": true, "requires": { "@jest/test-result": "^27.3.1", @@ -2386,8 +30124,6 @@ }, "@jest/transform": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", - "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", "dev": true, "requires": { "@babel/core": "^7.1.0", @@ -2409,16 +30145,12 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "@jest/types": { "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -2430,8 +30162,6 @@ }, "@mapbox/gazetteer": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/gazetteer/-/gazetteer-5.1.0.tgz", - "integrity": "sha512-AYI4bJkgB/rJkSXnXRrAzL3ssinMUP/nqowhtnPU5O/uNCzwk8TOh6fTgoB2Wsy1c1GqbNb9EHy0aDbnwy9LEw==", "dev": true, "requires": { "@hapi/joi": "^15.0.3", @@ -2440,8 +30170,6 @@ }, "@mapbox/geojson-rewind": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.1.tgz", - "integrity": "sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA==", "requires": { "get-stream": "^6.0.1", "minimist": "^1.2.5" @@ -2449,8 +30177,6 @@ }, "@mapbox/geojsonhint": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@mapbox/geojsonhint/-/geojsonhint-2.2.0.tgz", - "integrity": "sha512-8qQYRB+/2z2JsN5s6D0WAnpo69+3V3nvJsSFLwMB1dsaWz1V4oZeuoje9srbYAxxL8PXCwIywfhYa3GxOkBv5Q==", "dev": true, "requires": { "concat-stream": "^1.6.1", @@ -2462,32 +30188,23 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, "@mapbox/jsonlint-lines-primitives": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", - "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=" + "version": "2.0.2" }, "@mapbox/mapbox-gl-rtl-text": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-rtl-text/-/mapbox-gl-rtl-text-0.2.3.tgz", - "integrity": "sha512-RaCYfnxULUUUxNwcUimV9C/o2295ktTyLEUzD/+VWkqXqvaVfFcZ5slytGzb2Sd/Jj4MlbxD0DCZbfa6CzcmMw==", - "dev": true + "dev": true, + "requires": {} }, "@mapbox/mapbox-gl-supported": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz", - "integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ==" + "version": "2.0.1" }, "@mapbox/mvt-fixtures": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@mapbox/mvt-fixtures/-/mvt-fixtures-3.6.0.tgz", - "integrity": "sha512-YgaODBQdutOcCnOiRJzbJO3lRejuaeuwfYk0XxfVlAi6L+UDXVHzi7NlpAa6GAYGzQm1V1KLk+2Io8+aSv8I+w==", "dev": true, "requires": { "@mapbox/sphericalmercator": "^1.0.5", @@ -2499,8 +30216,6 @@ }, "@mapbox/node-pre-gyp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", "dev": true, "requires": { "detect-libc": "^1.0.3", @@ -2515,43 +30230,29 @@ } }, "@mapbox/point-geometry": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", - "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" + "version": "0.1.0" }, "@mapbox/sphericalmercator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.1.0.tgz", - "integrity": "sha512-pEsfZyG4OMThlfFQbCte4gegvHUjxXCjz0KZ4Xk8NdOYTQBLflj6U8PL05RPAiuRAMAQNUUKJuL6qYZ5Y4kAWA==", "dev": true }, "@mapbox/tiny-sdf": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.4.tgz", - "integrity": "sha512-CBtL2rhZiYmdIryksp0zh4Mmx54iClYfNb0mpYeHrZnq4z84lVjre7LBWGPEjWspEn6AiF0lxC1HaZDye89m3g==" + "version": "2.0.4" }, "@mapbox/unitbezier": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", - "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==" + "version": "0.0.1" }, "@mapbox/vector-tile": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", - "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", "requires": { "@mapbox/point-geometry": "~0.1.0" } }, "@mapbox/whoots-js": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", - "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==" + "version": "3.1.0" }, "@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", @@ -2560,14 +30261,10 @@ }, "@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", @@ -2576,8 +30273,6 @@ }, "@octokit/auth-token": { "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz", - "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==", "dev": true, "requires": { "@octokit/types": "^6.0.3" @@ -2585,8 +30280,6 @@ }, "@octokit/core": { "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", - "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.4", @@ -2600,8 +30293,6 @@ }, "@octokit/endpoint": { "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", "dev": true, "requires": { "@octokit/types": "^6.0.3", @@ -2611,8 +30302,6 @@ }, "@octokit/graphql": { "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", "dev": true, "requires": { "@octokit/request": "^5.6.0", @@ -2622,14 +30311,10 @@ }, "@octokit/openapi-types": { "version": "10.1.5", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-10.1.5.tgz", - "integrity": "sha512-OoShNYzhAU8p8JbGHe1rRs1GIErRtmN2230AQCJAjL5lc0AUU5OhppVe6693HIZ2eCBLUhoLPhnnnmQ5ASH7Wg==", "dev": true }, "@octokit/plugin-paginate-rest": { "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.2.tgz", - "integrity": "sha512-WF5/MTPnFgYH6rMGuxBvbxX2S/3ygNWylakgD7njKES0Qwk5e+d/L6r/BYXSw7B6xJJ3hlwIAmUmOxxYrR+Q8A==", "dev": true, "requires": { "@octokit/types": "^6.27.2" @@ -2637,14 +30322,11 @@ }, "@octokit/plugin-request-log": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true + "dev": true, + "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { "version": "5.10.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.10.3.tgz", - "integrity": "sha512-eAT4gje+VR9xdSlhuHWNXsNLpiODqdqz8jqShMgaxRH82Le2nS6EV6LAo3QPZ05Fso5oGmDfJF6eq9vs1cEhdA==", "dev": true, "requires": { "@octokit/types": "^6.27.2", @@ -2653,8 +30335,6 @@ }, "@octokit/request": { "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.1.tgz", - "integrity": "sha512-Ls2cfs1OfXaOKzkcxnqw5MR6drMA/zWX/LIS/p8Yjdz7QKTPQLMsB3R+OvoxE6XnXeXEE2X7xe4G4l4X0gRiKQ==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", @@ -2667,8 +30347,6 @@ }, "@octokit/request-error": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", "dev": true, "requires": { "@octokit/types": "^6.0.3", @@ -2678,8 +30356,6 @@ }, "@octokit/rest": { "version": "18.10.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.10.0.tgz", - "integrity": "sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw==", "dev": true, "requires": { "@octokit/core": "^3.5.1", @@ -2690,8 +30366,6 @@ }, "@octokit/types": { "version": "6.27.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.27.2.tgz", - "integrity": "sha512-AgajmAJh7LhStgaEaNoY1N7znst2q07CKZVdnVB/V4tmitMbk+qijmD0IkkSKulXE5RVLbJjQikJF9+XLqhsVA==", "dev": true, "requires": { "@octokit/openapi-types": "^10.1.5" @@ -2699,8 +30373,6 @@ }, "@rollup/plugin-commonjs": { "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", - "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -2714,8 +30386,6 @@ }, "@rollup/plugin-json": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", "dev": true, "requires": { "@rollup/pluginutils": "^3.0.8" @@ -2723,8 +30393,6 @@ }, "@rollup/plugin-node-resolve": { "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.6.tgz", - "integrity": "sha512-sFsPDMPd4gMqnh2gS0uIxELnoRUp5kBl5knxD2EO0778G1oOJv4G1vyT2cpWz75OU2jDVcXhjVUuTAczGyFNKA==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -2737,8 +30405,6 @@ }, "@rollup/plugin-replace": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-3.0.0.tgz", - "integrity": "sha512-3c7JCbMuYXM4PbPWT4+m/4Y6U60SgsnDT/cCyAyUKwFHg7pTSfsSQzIpETha3a3ig6OdOKzZz87D9ZXIK3qsDg==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -2747,8 +30413,6 @@ }, "@rollup/plugin-strip": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-strip/-/plugin-strip-2.1.0.tgz", - "integrity": "sha512-OKlIlXMFlH4nVxq0beNSIKVw0LkpNUpVjjvfzH5OAOAR5dhLZgLZBzwYX4ifIAs18YDrreMcZH4xnKmW9fI2AQ==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -2768,8 +30432,6 @@ }, "@rollup/pluginutils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "dev": true, "requires": { "@types/estree": "0.0.39", @@ -2779,22 +30441,16 @@ "dependencies": { "estree-walker": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true } } }, "@sindresorhus/is": { "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, "@sinonjs/commons": { "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -2802,8 +30458,6 @@ }, "@sinonjs/fake-timers": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -2811,8 +30465,6 @@ }, "@sinonjs/samsam": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -2822,14 +30474,10 @@ }, "@sinonjs/text-encoding": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, "@stylelint/postcss-css-in-js": { "version": "0.37.2", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", - "integrity": "sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==", "dev": true, "requires": { "@babel/core": ">=7.9.0" @@ -2837,8 +30485,6 @@ }, "@stylelint/postcss-markdown": { "version": "0.36.2", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz", - "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==", "dev": true, "requires": { "remark": "^13.0.0", @@ -2847,14 +30493,10 @@ "dependencies": { "is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "remark": { "version": "13.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", - "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", "dev": true, "requires": { "remark-parse": "^9.0.0", @@ -2864,8 +30506,6 @@ }, "remark-parse": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", "dev": true, "requires": { "mdast-util-from-markdown": "^0.8.0" @@ -2873,8 +30513,6 @@ }, "remark-stringify": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", - "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", "dev": true, "requires": { "mdast-util-to-markdown": "^0.6.0" @@ -2882,8 +30520,6 @@ }, "unified": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", "dev": true, "requires": { "bail": "^1.0.0", @@ -2898,8 +30534,6 @@ }, "@szmarczak/http-timer": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", "dev": true, "requires": { "defer-to-connect": "^1.0.1" @@ -2907,44 +30541,63 @@ }, "@tootallnate/once": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, "@trysound/sax": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true }, "@tsconfig/node10": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", "dev": true }, "@tsconfig/node12": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", "dev": true }, "@tsconfig/node14": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", "dev": true }, "@tsconfig/node16": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "@types/babel__core": { + "version": "7.1.15", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.3", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.14.2", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, "@types/babel-core": { "version": "6.25.7", - "resolved": "https://registry.npmjs.org/@types/babel-core/-/babel-core-6.25.7.tgz", - "integrity": "sha512-WPnyzNFVRo6bxpr7bcL27qXtNKNQ3iToziNBpibaXHyKGWQA0+tTLt73QQxC/5zzbM544ih6Ni5L5xrck6rGwg==", "dev": true, "requires": { "@types/babel-generator": "*", @@ -2956,8 +30609,6 @@ }, "@types/babel-generator": { "version": "6.25.4", - "resolved": "https://registry.npmjs.org/@types/babel-generator/-/babel-generator-6.25.4.tgz", - "integrity": "sha512-Rnsen+ckop5mbl9d43bempS7i9wdTN1vytiTlmQla/YiNm6kH8kEVABVSXmp1UbnpkUV44nUCPeDQoa+Mu7ALA==", "dev": true, "requires": { "@types/babel-types": "*" @@ -2965,8 +30616,6 @@ }, "@types/babel-template": { "version": "6.25.2", - "resolved": "https://registry.npmjs.org/@types/babel-template/-/babel-template-6.25.2.tgz", - "integrity": "sha512-QKtDQRJmAz3Y1HSxfMl0syIHebMc/NnOeH/8qeD0zjgU2juD0uyC922biMxCy5xjTNvHinigML2l8kxE8eEBmw==", "dev": true, "requires": { "@types/babel-types": "*", @@ -2975,8 +30624,6 @@ }, "@types/babel-traverse": { "version": "6.25.7", - "resolved": "https://registry.npmjs.org/@types/babel-traverse/-/babel-traverse-6.25.7.tgz", - "integrity": "sha512-BeQiEGLnVzypzBdsexEpZAHUx+WucOMXW6srEWDkl4SegBlaCy+iBvRO+4vz6EZ+BNQg22G4MCdDdvZxf+jW5A==", "dev": true, "requires": { "@types/babel-types": "*" @@ -2984,55 +30631,10 @@ }, "@types/babel-types": { "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.11.tgz", - "integrity": "sha512-pkPtJUUY+Vwv6B1inAz55rQvivClHJxc9aVEPPmaq2cbyeMLCiDpbKpcKyX4LAwpNGi+SHBv0tHv6+0gXv0P2A==", "dev": true }, - "@types/babel__core": { - "version": "7.1.15", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", - "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, "@types/babelify": { "version": "7.3.7", - "resolved": "https://registry.npmjs.org/@types/babelify/-/babelify-7.3.7.tgz", - "integrity": "sha512-OjGe1SBi3M7I/uk5+x4mNhVNymJNyK4RqeStCL5U/H2pB+K1FhC0PYbLJiPTyZpWs/8eVmQJKWoF4hGgqIdYhA==", "dev": true, "requires": { "@types/babel-core": "*", @@ -3041,8 +30643,6 @@ }, "@types/babylon": { "version": "6.16.6", - "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.6.tgz", - "integrity": "sha512-G4yqdVlhr6YhzLXFKy5F7HtRBU8Y23+iWy7UKthMq/OSQnL1hbsoeXESQ2LY8zEDlknipDG3nRGhUC9tkwvy/w==", "dev": true, "requires": { "@types/babel-types": "*" @@ -3050,14 +30650,10 @@ }, "@types/benchmark": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-2.1.1.tgz", - "integrity": "sha512-XmdNOarpSSxnb3DE2rRFOFsEyoqXLUL+7H8nSGS25vs+JS0018bd+cW5Ma9vdlkPmoTHSQ6e8EUFMFMxeE4l+g==", "dev": true }, "@types/browserify": { "version": "12.0.37", - "resolved": "https://registry.npmjs.org/@types/browserify/-/browserify-12.0.37.tgz", - "integrity": "sha512-rGVZQhqlBMdnU0Wcq/RDO6+I1tppM42SqVq5ZEXiw2ft/A55Ro+dz4aKTy28gniwOIxZhRFqb5N+qnbg7J040g==", "dev": true, "requires": { "@types/insert-module-globals": "*", @@ -3066,32 +30662,22 @@ }, "@types/caseless": { "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", "dev": true }, "@types/component-emitter": { "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", - "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", "dev": true }, "@types/cookie": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", "dev": true }, "@types/cors": { "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, "@types/cssnano": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/cssnano/-/cssnano-4.0.1.tgz", - "integrity": "sha512-hGOroxRTBkYl5gSBRJOffhV4+io+Y2bFX1VP7LgKEVHJt/LPPJaWUIuDAz74Vlp7l7hCDZfaDi7iPxwNwuVA4Q==", "dev": true, "requires": { "postcss": "5 - 7" @@ -3099,8 +30685,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -3110,8 +30694,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -3121,8 +30703,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -3132,14 +30712,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -3149,8 +30725,6 @@ }, "@types/d3": { "version": "4.13.12", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-4.13.12.tgz", - "integrity": "sha512-/bbFtkOBc04gGGN8N9rMG5ps3T0eIj5I8bnYe9iIyeM5qoOrydPCbFYlEPUnj2h9ibc2i+QZfDam9jY5XTrTxQ==", "dev": true, "requires": { "@types/d3-array": "^1", @@ -3187,14 +30761,10 @@ }, "@types/d3-array": { "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.9.tgz", - "integrity": "sha512-E/7RgPr2ylT5dWG0CswMi9NpFcjIEDqLcUSBgNHe/EMahfqYaTx4zhcggG3khqoEB/leY4Vl6nTSbwLUPjXceA==", "dev": true }, "@types/d3-axis": { "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.16.tgz", - "integrity": "sha512-p7085weOmo4W+DzlRRVC/7OI/jugaKbVa6WMQGCQscaMylcbuaVEGk7abJLNyGVFLeCBNrHTdDiqRGnzvL0nXQ==", "dev": true, "requires": { "@types/d3-selection": "^1" @@ -3202,8 +30772,6 @@ }, "@types/d3-brush": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-1.1.5.tgz", - "integrity": "sha512-4zGkBafJf5zCsBtLtvDj/pNMo5X9+Ii/1hUz0GvQ+wEwelUBm2AbIDAzJnp2hLDFF307o0fhxmmocHclhXC+tw==", "dev": true, "requires": { "@types/d3-selection": "^1" @@ -3211,32 +30779,22 @@ }, "@types/d3-chord": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-1.0.11.tgz", - "integrity": "sha512-0DdfJ//bxyW3G9Nefwq/LDgazSKNN8NU0lBT3Cza6uVuInC2awMNsAcv1oKyRFLn9z7kXClH5XjwpveZjuz2eg==", "dev": true }, "@types/d3-collection": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-collection/-/d3-collection-1.0.10.tgz", - "integrity": "sha512-54Fdv8u5JbuXymtmXm2SYzi1x/Svt+jfWBU5junkhrCewL92VjqtCBDn97coBRVwVFmYNnVTNDyV8gQyPYfm+A==", "dev": true }, "@types/d3-color": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz", - "integrity": "sha512-fYtiVLBYy7VQX+Kx7wU/uOIkGQn8aAEY8oWMoyja3N4dLd8Yf6XgSIR/4yWvMuveNOH5VShnqCgRqqh/UNanBA==", "dev": true }, "@types/d3-dispatch": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-1.0.9.tgz", - "integrity": "sha512-zJ44YgjqALmyps+II7b1mZLhrtfV/FOxw9owT87mrweGWcg+WK5oiJX2M3SYJ0XUAExBduarysfgbR11YxzojQ==", "dev": true }, "@types/d3-drag": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.5.tgz", - "integrity": "sha512-7NeTnfolst1Js3Vs7myctBkmJWu6DMI3k597AaHUX98saHjHWJ6vouT83UrpE+xfbSceHV+8A0JgxuwgqgmqWw==", "dev": true, "requires": { "@types/d3-selection": "^1" @@ -3244,32 +30802,22 @@ }, "@types/d3-dsv": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-1.2.1.tgz", - "integrity": "sha512-LLmJmjiqp/fTNEdij5bIwUJ6P6TVNk5hKM9/uk5RPO2YNgEu9XvKO0dJ7Iqd3psEdmZN1m7gB1bOsjr4HmO2BA==", "dev": true }, "@types/d3-ease": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-1.0.10.tgz", - "integrity": "sha512-fMFTCzd8DOwruE9zlu2O8ci5ct+U5jkGcDS+cH+HCidnJlDs0MZ+TuSVCFtEzh4E5MasItwy+HvgoFtxPHa5Cw==", "dev": true }, "@types/d3-force": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-1.2.4.tgz", - "integrity": "sha512-fkorLTKvt6AQbFBQwn4aq7h9rJ4c7ZVcPMGB8X6eFFveAyMZcv7t7m6wgF4Eg93rkPgPORU7sAho1QSHNcZu6w==", "dev": true }, "@types/d3-format": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.2.tgz", - "integrity": "sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ==", "dev": true }, "@types/d3-geo": { "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-1.12.3.tgz", - "integrity": "sha512-yZbPb7/5DyL/pXkeOmZ7L5ySpuGr4H48t1cuALjnJy5sXQqmSSAYBiwa6Ya/XpWKX2rJqGDDubmh3nOaopOpeA==", "dev": true, "requires": { "@types/geojson": "*" @@ -3277,14 +30825,10 @@ }, "@types/d3-hierarchy": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", - "integrity": "sha512-AbStKxNyWiMDQPGDguG2Kuhlq1Sv539pZSxYbx4UZeYkutpPwXCcgyiRrlV4YH64nIOsKx7XVnOMy9O7rJsXkg==", "dev": true }, "@types/d3-interpolate": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz", - "integrity": "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==", "dev": true, "requires": { "@types/d3-color": "^1" @@ -3292,38 +30836,26 @@ }, "@types/d3-path": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==", "dev": true }, "@types/d3-polygon": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-1.0.8.tgz", - "integrity": "sha512-1TOJPXCBJC9V3+K3tGbTqD/CsqLyv/YkTXAcwdsZzxqw5cvpdnCuDl42M4Dvi8XzMxZNCT9pL4ibrK2n4VmAcw==", "dev": true }, "@types/d3-quadtree": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-1.0.9.tgz", - "integrity": "sha512-5E0OJJn2QVavITFEc1AQlI8gLcIoDZcTKOD3feKFckQVmFV4CXhqRFt83tYNVNIN4ZzRkjlAMavJa1ldMhf5rA==", "dev": true }, "@types/d3-queue": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-queue/-/d3-queue-3.0.8.tgz", - "integrity": "sha512-1FWOiI/MYwS5Z1Sa9EvS1Xet3isiVIIX5ozD6iGnwHonGcqL+RcC1eThXN5VfDmAiYt9Me9EWNEv/9J9k9RIKQ==", "dev": true }, "@types/d3-random": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-1.1.3.tgz", - "integrity": "sha512-XXR+ZbFCoOd4peXSMYJzwk0/elP37WWAzS/DG+90eilzVbUSsgKhBcWqylGWe+lA2ubgr7afWAOBaBxRgMUrBQ==", "dev": true }, "@types/d3-request": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-request/-/d3-request-1.0.6.tgz", - "integrity": "sha512-4nRKDUBg3EBx8VowpMvM3NAVMiMMI1qFUOYv3OJsclGjHX6xjtu09nsWhRQ0fvSUla3MEjb5Ch4IeaYarMEi1w==", "dev": true, "requires": { "@types/d3-dsv": "^1" @@ -3331,8 +30863,6 @@ }, "@types/d3-scale": { "version": "1.0.17", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-1.0.17.tgz", - "integrity": "sha512-baIP5/gw+PS8Axs1lfZCeIjcOXen/jxQmgFEjbYThwaj2drvivOIrJMh2Ig4MeenrogCH6zkhiOxCPRkvN1scA==", "dev": true, "requires": { "@types/d3-time": "^1" @@ -3340,14 +30870,10 @@ }, "@types/d3-selection": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.3.tgz", - "integrity": "sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==", "dev": true }, "@types/d3-shape": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.8.tgz", - "integrity": "sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg==", "dev": true, "requires": { "@types/d3-path": "^1" @@ -3355,26 +30881,18 @@ }, "@types/d3-time": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.1.1.tgz", - "integrity": "sha512-ULX7LoqXTCYtM+tLYOaeAJK7IwCT+4Gxlm2MaH0ErKLi07R5lh8NHCAyWcDkCCmx1AfRcBEV6H9QE9R25uP7jw==", "dev": true }, "@types/d3-time-format": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.1.tgz", - "integrity": "sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA==", "dev": true }, "@types/d3-timer": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.10.tgz", - "integrity": "sha512-ZnAbquVqy+4ZjdW0cY6URp+qF/AzTVNda2jYyOzpR2cPT35FTXl78s15Bomph9+ckOiI1TtkljnWkwbIGAb6rg==", "dev": true }, "@types/d3-transition": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.2.tgz", - "integrity": "sha512-J+a3SuF/E7wXbOSN19p8ZieQSFIm5hU2Egqtndbc54LXaAEOpLfDx4sBu/PKAKzHOdgKK1wkMhINKqNh4aoZAg==", "dev": true, "requires": { "@types/d3-selection": "^1" @@ -3382,14 +30900,10 @@ }, "@types/d3-voronoi": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.9.tgz", - "integrity": "sha512-DExNQkaHd1F3dFPvGA/Aw2NGyjMln6E9QzsiqOcBgnE+VInYnFBHBBySbZQts6z6xD+5jTfKCP7M4OqMyVjdwQ==", "dev": true }, "@types/d3-zoom": { "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.3.tgz", - "integrity": "sha512-3kHkL6sPiDdbfGhzlp5gIHyu3kULhtnHTTAl3UBZVtWB1PzcLL8vdmz5mTx7plLiUqOA2Y+yT2GKjt/TdA2p7Q==", "dev": true, "requires": { "@types/d3-interpolate": "^1", @@ -3398,26 +30912,18 @@ }, "@types/diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-mIenTfsIe586/yzsyfql69KRnA75S8SVXQbTLpDejRrjH0QSJcpu3AUOi/Vjnt9IOsXKxPhJfGpQUNMueIU1fQ==", "dev": true }, "@types/earcut": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.1.tgz", - "integrity": "sha512-w8oigUCDjElRHRRrMvn/spybSMyX8MTkKA5Dv+tS1IE/TgmNZPqUYtvYBXGY8cieSE66gm+szeK+bnbxC2xHTQ==", "dev": true }, "@types/ejs": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.0.tgz", - "integrity": "sha512-DCg+Ka+uDQ31lJ/UtEXVlaeV3d6t81gifaVWKJy4MYVVgvJttyX/viREy+If7fz+tK/gVxTGMtyrFPnm4gjrVA==", "dev": true }, "@types/eslint": { "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz", - "integrity": "sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==", "dev": true, "requires": { "@types/estree": "*", @@ -3426,26 +30932,18 @@ }, "@types/estree": { "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, "@types/geojson": { "version": "7946.0.8", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", - "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", "dev": true }, "@types/gl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/gl/-/gl-4.1.0.tgz", - "integrity": "sha512-XdyM2/Q+XAsdw69t23YD812fY3KDw9dYmULZTOGMFM2tLaweBtcVzUnOwsMzF7i0dvFDL0GnawYwEq/+hvUZtw==", "dev": true }, "@types/glob": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, "requires": { "@types/minimatch": "*", @@ -3454,8 +30952,6 @@ }, "@types/graceful-fs": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, "requires": { "@types/node": "*" @@ -3463,8 +30959,6 @@ }, "@types/insert-module-globals": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/insert-module-globals/-/insert-module-globals-7.0.2.tgz", - "integrity": "sha512-b+XCUBUioZoveg4e8+D/wGVIvQcuV6TNHPy53aeY0YBydOOZhAtX2Sdr4x97uWKKy9Xrt0SUKsPxbT9e0u/x9Q==", "dev": true, "requires": { "@types/node": "*" @@ -3472,14 +30966,10 @@ }, "@types/istanbul-lib-coverage": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, "@types/istanbul-lib-report": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" @@ -3487,8 +30977,6 @@ }, "@types/istanbul-reports": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -3496,8 +30984,6 @@ }, "@types/jest": { "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", - "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", "dev": true, "requires": { "jest-diff": "^27.0.0", @@ -3506,8 +30992,6 @@ }, "@types/jsdom": { "version": "16.2.13", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-16.2.13.tgz", - "integrity": "sha512-8JQCjdeAidptSsOcRWk2iTm9wCcwn9l+kRG6k5bzUacrnm1ezV4forq0kWjUih/tumAeoG+OspOvQEbbRucBTw==", "dev": true, "requires": { "@types/node": "*", @@ -3517,20 +31001,14 @@ }, "@types/json-schema": { "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, "@types/json5": { "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, "@types/jsonwebtoken": { "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.5.tgz", - "integrity": "sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw==", "dev": true, "requires": { "@types/node": "*" @@ -3538,14 +31016,10 @@ }, "@types/lodash": { "version": "4.14.172", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", - "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==", "dev": true }, "@types/lodash.template": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@types/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-4LgHxK16IPbGR7TmXpPvNT7iNGsLCdQY6Rc0mi1a/JECt8et/D4hx6NMVAJej/d932sj1mJsg0QYHKL189O0Qw==", "dev": true, "requires": { "@types/lodash": "*" @@ -3553,8 +31027,6 @@ }, "@types/mdast": { "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", - "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", "dev": true, "requires": { "@types/unist": "*" @@ -3562,32 +31034,22 @@ }, "@types/minimatch": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, "@types/minimist": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, "@types/murmurhash-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/murmurhash-js/-/murmurhash-js-1.0.3.tgz", - "integrity": "sha512-PxJwTlcFOBRPqv9pSoC3O1FpKN8GnM5hMJIkG6U3omH8b4GAh28fO1c+TMR4oxj0BG43/ICbrIK3KBfzad2heg==", "dev": true }, "@types/node": { "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", "dev": true }, "@types/node-notifier": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-oEaec3j6vw1u0xT/rEniM0yarkV5dZsZvjgTX3IlgekpjDGlv8EGD+Pnpbt3D9IMkoosprPeRtvYc/1t9XBduw==", "dev": true, "requires": { "@types/node": "*" @@ -3595,20 +31057,14 @@ }, "@types/normalize-package-data": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/npm-packlist": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/npm-packlist/-/npm-packlist-1.1.2.tgz", - "integrity": "sha512-9NYoEH87t90e6dkaQOuUTY/R1xUE0a67sXzJBuAB+b+/z4FysHFD19g/O154ToGjyWqKYkezVUtuBdtfd4hyfw==", "dev": true }, "@types/offscreencanvas": { "version": "2019.6.3", - "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.6.3.tgz", - "integrity": "sha512-957DsU187Y90EmlXneuqrqnwmwCkC9oPyQ/IEGwmDRpMfuhcGtjIz72Me7HvdK04ZC16A0VWmv0TSNLwC9ZvXw==", "dev": true, "requires": { "@types/webgl2": "*" @@ -3616,26 +31072,18 @@ }, "@types/parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, "@types/parse5": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-ARATsLdrGPUnaBvxLhUlnltcMgn7pQG312S8ccdYlnyijabrX9RN/KN/iGj9Am96CoW8e/K9628BA7Bv4XHdrA==", "dev": true }, "@types/pbf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", - "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==", "dev": true }, "@types/pixelmatch": { "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.4.tgz", - "integrity": "sha512-HDaSHIAv9kwpMN7zlmwfTv6gax0PiporJOipcrGsVNF3Ba+kryOZc0Pio5pn6NhisgWr7TaajlPEKTbTAypIBQ==", "dev": true, "requires": { "@types/node": "*" @@ -3643,8 +31091,6 @@ }, "@types/pngjs": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/pngjs/-/pngjs-6.0.1.tgz", - "integrity": "sha512-J39njbdW1U/6YyVXvC9+1iflZghP8jgRf2ndYghdJb5xL49LYDB+1EuAxfbuJ2IBbWIL3AjHPQhgaTxT3YaYeg==", "dev": true, "requires": { "@types/node": "*" @@ -3652,20 +31098,14 @@ }, "@types/prettier": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, "@types/prop-types": { "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", "dev": true }, "@types/puppeteer": { "version": "5.4.4", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.4.tgz", - "integrity": "sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==", "dev": true, "requires": { "@types/node": "*" @@ -3673,8 +31113,6 @@ }, "@types/react": { "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.19.tgz", - "integrity": "sha512-sX1HisdB1/ZESixMTGnMxH9TDe8Sk709734fEQZzCV/4lSu9kJCPbo2PbTRoZM+53Pp0P10hYVyReUueGwUi4A==", "dev": true, "requires": { "@types/prop-types": "*", @@ -3684,8 +31122,6 @@ }, "@types/react-dom": { "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", - "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", "dev": true, "requires": { "@types/react": "*" @@ -3693,8 +31129,6 @@ }, "@types/request": { "version": "2.48.7", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.7.tgz", - "integrity": "sha512-GWP9AZW7foLd4YQxyFZDBepl0lPsWLMEXDZUjQ/c1gqVPDPECrRZyEzuhJdnPWioFCq3Tv0qoGpMD6U+ygd4ZA==", "dev": true, "requires": { "@types/caseless": "*", @@ -3705,8 +31139,6 @@ }, "@types/resolve": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "dev": true, "requires": { "@types/node": "*" @@ -3714,8 +31146,6 @@ }, "@types/rollup-plugin-json": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/rollup-plugin-json/-/rollup-plugin-json-3.0.3.tgz", - "integrity": "sha512-5Y5fTYRCXS1llyLzQ3X1XhDRpw/31jkfWOMpDRgz000d9ABOsdLWDg/f6mqwT8BKGYV/+6tje4uGQnuebuk7dg==", "dev": true, "requires": { "@types/node": "*", @@ -3724,8 +31154,6 @@ "dependencies": { "rollup": { "version": "0.63.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.63.5.tgz", - "integrity": "sha512-dFf8LpUNzIj3oE0vCvobX6rqOzHzLBoblyFp+3znPbjiSmSvOoK2kMKx+Fv9jYduG1rvcCfCveSgEaQHjWRF6g==", "dev": true, "requires": { "@types/estree": "0.0.39", @@ -3736,26 +31164,18 @@ }, "@types/scheduler": { "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, "@types/selenium-webdriver": { "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.0.16.tgz", - "integrity": "sha512-0UAzu2lFXpLK4lU4yhgUtM/KxoN8hIpyI+q22KAwzIDHNk4kLJ/Ut5mJZLFSxfQx58OBQ9SJXZkSL065fe/WdQ==", "dev": true }, "@types/shuffle-seed": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/shuffle-seed/-/shuffle-seed-1.1.0.tgz", - "integrity": "sha512-h6UW72XuE07bSDVTkNjMMapFj6ERJmvf+RajssOoEIVhuU53/+zyCSBjBrSpDJSzVYjGr4CYxW3ABrY0C6s8qA==", "dev": true }, "@types/sinon": { "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.2.tgz", - "integrity": "sha512-BHn8Bpkapj8Wdfxvh2jWIUoaYB/9/XhsL0oOvBfRagJtKlSl9NWPcFOz2lRukI9szwGxFtYZCTejJSqsGDbdmw==", "dev": true, "requires": { "@sinonjs/fake-timers": "^7.1.0" @@ -3763,14 +31183,10 @@ }, "@types/stack-utils": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/stylelint": { "version": "13.13.2", - "resolved": "https://registry.npmjs.org/@types/stylelint/-/stylelint-13.13.2.tgz", - "integrity": "sha512-5Yt1LQenR7uk+efCydQmN7ubOtO2qJ8Z9K/qqnlW87X1zkIQ8RkMCZbaOgZj/aBrR/h5Q738mJU6CYhXOj9sEg==", "dev": true, "requires": { "globby": "11.x.x", @@ -3779,8 +31195,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -3790,8 +31204,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -3801,8 +31213,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -3812,14 +31222,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -3829,8 +31235,6 @@ }, "@types/supercluster": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-5.0.3.tgz", - "integrity": "sha512-XMSqQEr7YDuNtFwSgaHHOjsbi0ZGL62V9Js4CW45RBuRYlNWSW/KDqN+RFFE7HdHcGhJPtN0klKvw06r9Kg7rg==", "dev": true, "requires": { "@types/geojson": "*" @@ -3838,8 +31242,6 @@ }, "@types/tape": { "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.13.2.tgz", - "integrity": "sha512-V1ez/RtYRGN9cNYApw5xf27DpMkTB0033X6a2i3KUmKhSojBfbWN0i3EgZxboUG96WJLHLdOyZ01aiZwVW5aSA==", "dev": true, "requires": { "@types/node": "*" @@ -3847,26 +31249,18 @@ }, "@types/tough-cookie": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==", "dev": true }, "@types/unist": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", "dev": true }, "@types/webgl2": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/webgl2/-/webgl2-0.0.6.tgz", - "integrity": "sha512-50GQhDVTq/herLMiqSQkdtRu+d5q/cWHn4VvKJtrj4DJAjo1MNkWYa2MA41BaBO1q1HgsUjuQvEOk0QHvlnAaQ==", "dev": true }, "@types/window-or-global": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/window-or-global/-/window-or-global-1.0.4.tgz", - "integrity": "sha512-+tJmApNoyWOxINwhTuMD8b9UegcB8HUSoLzBHPKIxq2XMnmUKCwPV2/+n8qkjkabx2diA68hDSAohESC9uC2kg==", "dev": true, "requires": { "@types/node": "*" @@ -3874,8 +31268,6 @@ }, "@types/yargs": { "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -3883,14 +31275,10 @@ }, "@types/yargs-parser": { "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@types/yauzl": { "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", "dev": true, "optional": true, "requires": { @@ -3899,8 +31287,6 @@ }, "@typescript-eslint/eslint-plugin": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.30.0.tgz", - "integrity": "sha512-NgAnqk55RQ/SD+tZFD9aPwNSeHmDHHe5rtUyhIq0ZeCWZEvo4DK9rYz7v9HDuQZFvn320Ot+AikaCKMFKLlD0g==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "4.30.0", @@ -3914,8 +31300,6 @@ }, "@typescript-eslint/experimental-utils": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.30.0.tgz", - "integrity": "sha512-K8RNIX9GnBsv5v4TjtwkKtqMSzYpjqAQg/oSphtxf3xxdt6T0owqnpojztjjTcatSteH3hLj3t/kklKx87NPqw==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", @@ -3928,8 +31312,6 @@ }, "@typescript-eslint/parser": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.30.0.tgz", - "integrity": "sha512-HJ0XuluSZSxeboLU7Q2VQ6eLlCwXPBOGnA7CqgBnz2Db3JRQYyBDJgQnop6TZ+rsbSx5gEdWhw4rE4mDa1FnZg==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "4.30.0", @@ -3940,8 +31322,6 @@ }, "@typescript-eslint/scope-manager": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.30.0.tgz", - "integrity": "sha512-VJ/jAXovxNh7rIXCQbYhkyV2Y3Ac/0cVHP/FruTJSAUUm4Oacmn/nkN5zfWmWFEanN4ggP0vJSHOeajtHq3f8A==", "dev": true, "requires": { "@typescript-eslint/types": "4.30.0", @@ -3950,14 +31330,10 @@ }, "@typescript-eslint/types": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.30.0.tgz", - "integrity": "sha512-YKldqbNU9K4WpTNwBqtAerQKLLW/X2A/j4yw92e3ZJYLx+BpKLeheyzoPfzIXHfM8BXfoleTdiYwpsvVPvHrDw==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.30.0.tgz", - "integrity": "sha512-6WN7UFYvykr/U0Qgy4kz48iGPWILvYL34xXJxvDQeiRE018B7POspNRVtAZscWntEPZpFCx4hcz/XBT+erenfg==", "dev": true, "requires": { "@typescript-eslint/types": "4.30.0", @@ -3971,8 +31347,6 @@ }, "@typescript-eslint/visitor-keys": { "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.30.0.tgz", - "integrity": "sha512-pNaaxDt/Ol/+JZwzP7MqWc8PJQTUhZwoee/PVlQ+iYoYhagccvoHnC9e4l+C/krQYYkENxznhVSDwClIbZVxRw==", "dev": true, "requires": { "@typescript-eslint/types": "4.30.0", @@ -3981,42 +31355,18 @@ }, "@xmldom/xmldom": { "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", - "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "JSV": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", - "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=", "dev": true }, "abab": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, "abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, "accepts": { "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { "mime-types": "~2.1.24", @@ -4025,20 +31375,15 @@ }, "acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-dynamic-import": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true + "dev": true, + "requires": {} }, "acorn-globals": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { "acorn": "^6.0.1", @@ -4047,28 +31392,21 @@ "dependencies": { "acorn": { "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, "acorn-walk": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true } } }, "acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-node": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", "dev": true, "requires": { "acorn": "^7.0.0", @@ -4078,20 +31416,14 @@ }, "acorn-walk": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, "address": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, "agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { "debug": "4" @@ -4099,8 +31431,6 @@ }, "aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { "clean-stack": "^2.0.0", @@ -4109,16 +31439,12 @@ "dependencies": { "indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true } } }, "ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -4129,20 +31455,14 @@ }, "alphanum-sort": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, "amdefine": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi-align": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, "requires": { "string-width": "^4.1.0" @@ -4150,26 +31470,18 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -4179,8 +31491,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -4190,14 +31500,10 @@ }, "ansi-colors": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { "type-fest": "^0.21.3" @@ -4205,28 +31511,20 @@ "dependencies": { "type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true } } }, "ansi-html": { "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", "dev": true }, "ansi-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -4234,8 +31532,6 @@ }, "anymatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -4244,8 +31540,6 @@ }, "append-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", "dev": true, "requires": { "buffer-equal": "^1.0.0" @@ -4253,8 +31547,6 @@ }, "append-transform": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, "requires": { "default-require-extensions": "^3.0.0" @@ -4262,20 +31554,14 @@ }, "aproba": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, "archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "are-we-there-yet": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "dev": true, "requires": { "delegates": "^1.0.0", @@ -4284,14 +31570,10 @@ }, "arg": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" @@ -4299,50 +31581,34 @@ }, "arr-diff": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "arr-flatten": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-union": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, "array-differ": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", "dev": true }, "array-equal": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, "array-find-index": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, "array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, "array-includes": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -4354,26 +31620,18 @@ }, "array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "array-uniq": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", "dev": true }, "array-unique": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "array.prototype.flat": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "requires": { "call-bind": "^1.0.0", @@ -4383,8 +31641,6 @@ }, "array.prototype.flatmap": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", "dev": true, "requires": { "call-bind": "^1.0.0", @@ -4395,14 +31651,10 @@ }, "arrify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "asn1": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { "safer-buffer": "~2.1.0" @@ -4410,8 +31662,6 @@ }, "asn1.js": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -4422,16 +31672,12 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "assert": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, "requires": { "object-assign": "^4.1.1", @@ -4440,14 +31686,10 @@ "dependencies": { "inherits": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { "inherits": "2.0.1" @@ -4457,20 +31699,14 @@ }, "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "assign-symbols": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "ast-types": { "version": "0.14.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", - "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", "dev": true, "requires": { "tslib": "^2.0.1" @@ -4478,28 +31714,20 @@ "dependencies": { "tslib": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true } } }, "astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true }, "async-cache": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/async-cache/-/async-cache-1.1.0.tgz", - "integrity": "sha1-SppaidBl7F2OUlS9nulrp2xTK1o=", "dev": true, "requires": { "lru-cache": "^4.0.0" @@ -4507,8 +31735,6 @@ "dependencies": { "lru-cache": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -4517,40 +31743,28 @@ }, "yallist": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } }, "async-each": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "async-limiter": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, "asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, "atob": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, "autoprefixer": { "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", "dev": true, "requires": { "browserslist": "^4.12.0", @@ -4564,8 +31778,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -4575,8 +31787,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -4586,8 +31796,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -4597,14 +31805,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -4614,32 +31818,23 @@ }, "available-typed-arrays": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, "aws-sign2": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "babel-core": { "version": "7.0.0-bridge.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", - "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "dev": true + "dev": true, + "requires": {} }, "babel-eslint": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -4652,16 +31847,12 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "babel-jest": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", - "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", "dev": true, "requires": { "@jest/transform": "^27.3.1", @@ -4676,8 +31867,6 @@ }, "babel-plugin-dynamic-import-node": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dev": true, "requires": { "object.assign": "^4.1.0" @@ -4685,8 +31874,6 @@ }, "babel-plugin-istanbul": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -4698,14 +31885,10 @@ "dependencies": { "istanbul-lib-coverage": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, "istanbul-lib-instrument": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "requires": { "@babel/core": "^7.12.3", @@ -4717,16 +31900,12 @@ }, "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "babel-plugin-jest-hoist": { "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -4737,8 +31916,6 @@ }, "babel-plugin-polyfill-corejs2": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", - "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", "dev": true, "requires": { "@babel/compat-data": "^7.13.11", @@ -4748,16 +31925,12 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "babel-plugin-polyfill-corejs3": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.4.tgz", - "integrity": "sha512-z3HnJE5TY/j4EFEa/qpQMSbcUJZ5JQi+3UFjXzn6pQCmIKc5Ug5j98SuYyH+m4xQnvKlMDIW4plLfgyVnd0IcQ==", "dev": true, "requires": { "@babel/helper-define-polyfill-provider": "^0.2.2", @@ -4766,8 +31939,6 @@ }, "babel-plugin-polyfill-regenerator": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", - "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", "dev": true, "requires": { "@babel/helper-define-polyfill-provider": "^0.2.2" @@ -4775,8 +31946,6 @@ }, "babel-preset-current-node-syntax": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -4795,8 +31964,6 @@ }, "babel-preset-jest": { "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, "requires": { "babel-plugin-jest-hoist": "^27.2.0", @@ -4805,14 +31972,11 @@ }, "babelify": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz", - "integrity": "sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==", - "dev": true + "dev": true, + "requires": {} }, "backbone": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", - "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", "dev": true, "requires": { "underscore": ">=1.8.3" @@ -4820,28 +31984,20 @@ "dependencies": { "underscore": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", "dev": true } } }, "bail": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", "dev": true }, "balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base": { "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { "cache-base": "^1.0.1", @@ -4855,8 +32011,6 @@ "dependencies": { "define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -4864,8 +32018,6 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -4873,8 +32025,6 @@ }, "is-data-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -4882,8 +32032,6 @@ }, "is-descriptor": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -4895,26 +32043,18 @@ }, "base64-arraybuffer": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", "dev": true }, "base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, "base64id": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "dev": true }, "bcrypt-pbkdf": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { "tweetnacl": "^0.14.3" @@ -4922,14 +32062,10 @@ }, "before-after-hook": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", "dev": true }, "benchmark": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", "dev": true, "requires": { "lodash": "^4.17.4", @@ -4938,20 +32074,14 @@ }, "binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bind-obj-methods": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.2.tgz", - "integrity": "sha512-bUkRdEOppT1Xg/jG0+bp0JSjUD9U0r7skxb/42WeBUjfBpW6COQTIgQmKX5J2Z3aMXcORKgN2N+d7IQwTK3pag==", "dev": true }, "bindings": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, "requires": { "file-uri-to-path": "1.0.0" @@ -4959,14 +32089,10 @@ }, "bit-twiddle": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", - "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=", "dev": true }, "bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "requires": { "buffer": "^5.5.0", @@ -4976,8 +32102,6 @@ "dependencies": { "buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "requires": { "base64-js": "^1.3.1", @@ -4986,8 +32110,6 @@ }, "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -4999,8 +32121,6 @@ }, "block-stream": { "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "requires": { "inherits": "~2.0.0" @@ -5008,20 +32128,14 @@ }, "bluebird": { "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, "bn.js": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", "dev": true }, "body": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", - "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { "continuable-cache": "^0.3.1", @@ -5032,8 +32146,6 @@ }, "body-parser": { "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "requires": { "bytes": "3.1.0", @@ -5050,14 +32162,10 @@ "dependencies": { "bytes": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -5065,20 +32173,14 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "qs": { "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, "raw-body": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "dev": true, "requires": { "bytes": "3.1.0", @@ -5091,14 +32193,10 @@ }, "boolbase": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, "boxen": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "dev": true, "requires": { "ansi-align": "^3.0.0", @@ -5113,14 +32211,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -5128,8 +32222,6 @@ }, "chalk": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -5138,8 +32230,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -5147,32 +32237,22 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -5182,8 +32262,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -5191,8 +32269,6 @@ }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -5200,16 +32276,12 @@ }, "type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -5218,8 +32290,6 @@ }, "braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.0.1" @@ -5227,19 +32297,15 @@ }, "brorand": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, "browser-pack": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "requires": { - "JSONStream": "^1.0.3", "combine-source-map": "~0.8.0", "defined": "^1.0.0", + "JSONStream": "^1.0.3", "safe-buffer": "^5.1.1", "through2": "^2.0.0", "umd": "^3.0.0" @@ -5247,14 +32313,10 @@ }, "browser-process-hrtime": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, "browser-resolve": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", "dev": true, "requires": { "resolve": "^1.17.0" @@ -5262,11 +32324,8 @@ }, "browserify": { "version": "17.0.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz", - "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==", "dev": true, "requires": { - "JSONStream": "^1.0.3", "assert": "^1.4.0", "browser-pack": "^6.0.1", "browser-resolve": "^2.0.0", @@ -5288,6 +32347,7 @@ "https-browserify": "^1.0.0", "inherits": "~2.0.1", "insert-module-globals": "^7.2.1", + "JSONStream": "^1.0.3", "labeled-stream-splicer": "^2.0.0", "mkdirp-classic": "^0.5.2", "module-deps": "^6.2.3", @@ -5318,8 +32378,6 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { "buffer-xor": "^1.0.3", @@ -5332,8 +32390,6 @@ }, "browserify-cipher": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { "browserify-aes": "^1.0.4", @@ -5343,8 +32399,6 @@ }, "browserify-des": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -5355,8 +32409,6 @@ }, "browserify-rsa": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { "bn.js": "^5.0.0", @@ -5365,8 +32417,6 @@ }, "browserify-sign": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", "dev": true, "requires": { "bn.js": "^5.1.1", @@ -5382,8 +32432,6 @@ "dependencies": { "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -5393,16 +32441,12 @@ }, "safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } } }, "browserify-zlib": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { "pako": "~1.0.5" @@ -5410,8 +32454,6 @@ }, "browserslist": { "version": "4.17.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.0.tgz", - "integrity": "sha512-g2BJ2a0nEYvEFQC208q8mVAhfNwpZ5Mu8BwgtCdZKO3qx98HChmeg448fPdUzld8aFmfLgVh7yymqV+q1lJZ5g==", "dev": true, "requires": { "caniuse-lite": "^1.0.30001254", @@ -5423,8 +32465,6 @@ }, "bs-logger": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "requires": { "fast-json-stable-stringify": "2.x" @@ -5432,8 +32472,6 @@ }, "bser": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "requires": { "node-int64": "^0.4.0" @@ -5441,14 +32479,10 @@ }, "btoa": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", - "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", "dev": true }, "buble": { "version": "0.19.8", - "resolved": "https://registry.npmjs.org/buble/-/buble-0.19.8.tgz", - "integrity": "sha512-IoGZzrUTY5fKXVkgGHw3QeXFMUNBFv+9l8a4QJKG1JhG3nCMHTdEX1DCOg8568E2Q9qvAQIiSokv6Jsgx8p2cA==", "dev": true, "requires": { "acorn": "^6.1.1", @@ -5463,14 +32497,10 @@ "dependencies": { "acorn": { "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -5480,16 +32510,12 @@ }, "os-homedir": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-2.0.0.tgz", - "integrity": "sha512-saRNz0DSC5C/I++gFIaJTXoFJMRwiP5zHar5vV3xQ2TkgEw6hDCcU5F272JjUylpiVgBrZNQHnfjkLabTfb92Q==", "dev": true } } }, "buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", "dev": true, "requires": { "base64-js": "^1.0.2", @@ -5498,62 +32524,42 @@ }, "buffer-crc32": { "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, "buffer-equal": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", "dev": true }, "buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", "dev": true }, "buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "buffer-shims": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, "buffer-xor": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, "builtin-modules": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, "builtin-status-codes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, "bytes": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, "cache-base": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { "collection-visit": "^1.0.0", @@ -5569,8 +32575,6 @@ }, "cacheable-request": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "dev": true, "requires": { "clone-response": "^1.0.2", @@ -5584,8 +32588,6 @@ "dependencies": { "get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -5593,20 +32595,14 @@ }, "lowercase-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true }, "normalize-url": { "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -5617,14 +32613,10 @@ }, "cached-path-relative": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", - "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", "dev": true }, "caching-transform": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, "requires": { "hasha": "^5.0.0", @@ -5635,8 +32627,6 @@ }, "call-bind": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -5645,8 +32635,6 @@ }, "call-matcher": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-2.0.0.tgz", - "integrity": "sha512-CIDC5wZZfZ2VjZu849WQckS58Z3pJXFfRaSjNjgo/q3in5zxkhTwVL83vttgtmvyLG7TuDlLlBya7SKP6CjDIA==", "dev": true, "requires": { "deep-equal": "^1.0.0", @@ -5656,20 +32644,14 @@ }, "callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "camelcase-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { "camelcase": "^2.0.0", @@ -5678,16 +32660,12 @@ "dependencies": { "camelcase": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true } } }, "caniuse-api": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dev": true, "requires": { "browserslist": "^4.0.0", @@ -5698,22 +32676,16 @@ "dependencies": { "lodash.memoize": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true } } }, "caniuse-lite": { "version": "1.0.30001257", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001257.tgz", - "integrity": "sha512-JN49KplOgHSXpIsVSF+LUyhD8PUp6xPpAXeRrrcBh4KBeP7W864jHn6RvzJgDlrReyeVjMFJL3PLpPvKIxlIHA==", "dev": true }, "canvas": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz", - "integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==", "dev": true, "requires": { "@mapbox/node-pre-gyp": "^1.0.0", @@ -5723,26 +32695,18 @@ }, "capture-stack-trace": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", "dev": true }, "caseless": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "ccount": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", "dev": true }, "chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -5751,8 +32715,6 @@ "dependencies": { "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -5760,8 +32722,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -5769,20 +32729,14 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -5792,44 +32746,30 @@ }, "char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, "character-entities": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", "dev": true }, "character-entities-html4": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", "dev": true }, "character-entities-legacy": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", "dev": true }, "character-reference-invalid": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", "dev": true }, "chardet": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "charm": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", - "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", "dev": true, "requires": { "inherits": "^2.0.1" @@ -5837,8 +32777,6 @@ }, "chokidar": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -5853,20 +32791,14 @@ }, "chownr": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, "ci-info": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", "dev": true }, "cipher-base": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -5875,14 +32807,10 @@ }, "cjs-module-lexer": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "class-utils": { "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -5893,8 +32821,6 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -5904,26 +32830,18 @@ }, "clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, "clean-yaml-object": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", "dev": true }, "cli-boxes": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, "cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { "restore-cursor": "^3.1.0" @@ -5931,14 +32849,10 @@ }, "cli-width": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true }, "cliui": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { "string-width": "^2.1.1", @@ -5948,8 +32862,6 @@ "dependencies": { "strip-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -5959,20 +32871,14 @@ }, "clone": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, "clone-buffer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", "dev": true }, "clone-deep": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "requires": { "is-plain-object": "^2.0.4", @@ -5982,8 +32888,6 @@ "dependencies": { "is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -5993,8 +32897,6 @@ }, "clone-regexp": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", "dev": true, "requires": { "is-regexp": "^2.0.0" @@ -6002,8 +32904,6 @@ }, "clone-response": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", "dev": true, "requires": { "mimic-response": "^1.0.0" @@ -6011,22 +32911,16 @@ "dependencies": { "mimic-response": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true } } }, "clone-stats": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, "cloneable-readable": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -6036,32 +32930,22 @@ }, "co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "collapse-white-space": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", "dev": true }, "collect-v8-coverage": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, "collection-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { "map-visit": "^1.0.0", @@ -6070,8 +32954,6 @@ }, "color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" @@ -6079,38 +32961,26 @@ }, "color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "color-support": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, "colord": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.7.0.tgz", - "integrity": "sha512-pZJBqsHz+pYyw3zpX6ZRXWoCHM1/cvFikY9TV8G3zcejCaKE0lhankoj8iScyrrePA8C7yJ5FStfA9zbcOnw7Q==", "dev": true }, "colorette": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", "dev": true }, "colors": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", "dev": true }, "combine-source-map": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "requires": { "convert-source-map": "~1.1.0", @@ -6121,16 +32991,12 @@ "dependencies": { "convert-source-map": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", "dev": true } } }, "combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" @@ -6138,38 +33004,26 @@ }, "comma-separated-tokens": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "dev": true }, "commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true }, "comment-parser": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", - "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true }, "commondir": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "component-emitter": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "compressible": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "requires": { "mime-db": ">= 1.43.0 < 2" @@ -6177,8 +33031,6 @@ }, "compression": { "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "requires": { "accepts": "~1.3.5", @@ -6192,14 +33044,10 @@ "dependencies": { "bytes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -6207,22 +33055,16 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -6233,8 +33075,6 @@ }, "configstore": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dev": true, "requires": { "dot-prop": "^5.2.0", @@ -6247,20 +33087,14 @@ }, "console-browserify": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, "consolidate": { "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", "dev": true, "requires": { "bluebird": "^3.1.1" @@ -6268,14 +33102,10 @@ }, "constants-browserify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, "content-disposition": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "dev": true, "requires": { "safe-buffer": "5.1.2" @@ -6283,20 +33113,14 @@ }, "content-type": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, "continuable-cache": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", "dev": true }, "convert-source-map": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -6304,26 +33128,18 @@ }, "cookie": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true }, "cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, "copy-descriptor": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, "core-js-compat": { "version": "3.17.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.17.3.tgz", - "integrity": "sha512-+in61CKYs4hQERiADCJsdgewpdl/X0GhEX77pjKgbeibXviIt2oxEjTc8O2fqHX8mDdBrDvX8MYD/RYsBv4OiA==", "dev": true, "requires": { "browserslist": "^4.17.0", @@ -6332,22 +33148,16 @@ "dependencies": { "semver": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true } } }, "core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, "cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, "requires": { "object-assign": "^4", @@ -6356,8 +33166,6 @@ }, "cosmiconfig": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", @@ -6369,8 +33177,6 @@ "dependencies": { "parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -6383,8 +33189,6 @@ }, "coveralls": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", - "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, "requires": { "js-yaml": "^3.13.1", @@ -6396,8 +33200,6 @@ }, "create-ecdh": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -6406,16 +33208,12 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "create-error-class": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", "dev": true, "requires": { "capture-stack-trace": "^1.0.0" @@ -6423,8 +33221,6 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -6436,8 +33232,6 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { "cipher-base": "^1.0.3", @@ -6450,14 +33244,10 @@ }, "create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, "cross-spawn": { "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { "nice-try": "^1.0.4", @@ -6469,16 +33259,12 @@ "dependencies": { "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "cross-spawn-async": { "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", "dev": true, "requires": { "lru-cache": "^4.0.0", @@ -6487,8 +33273,6 @@ "dependencies": { "lru-cache": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -6497,16 +33281,12 @@ }, "yallist": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } }, "crypto-browserify": { "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { "browserify-cipher": "^1.0.0", @@ -6524,20 +33304,14 @@ }, "crypto-random-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, "css-color-names": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", - "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", "dev": true }, "css-declaration-sorter": { "version": "6.1.3", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz", - "integrity": "sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA==", "dev": true, "requires": { "timsort": "^0.3.0" @@ -6545,8 +33319,6 @@ }, "css-select": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", "dev": true, "requires": { "boolbase": "^1.0.0", @@ -6558,8 +33330,6 @@ }, "css-tree": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dev": true, "requires": { "mdn-data": "2.0.14", @@ -6568,39 +33338,27 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "css-what": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", - "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", "dev": true }, "csscolorparser": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", - "integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs=" + "version": "1.0.3" }, "cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, "cssfontparser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", - "integrity": "sha1-9AIvyPlwDGgCnVQghK+69CWj8+M=", "dev": true }, "cssnano": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.8.tgz", - "integrity": "sha512-Lda7geZU0Yu+RZi2SGpjYuQz4HI4/1Y+BhdD0jL7NXAQ5larCzVn+PUGuZbDMYz904AXXCOgO5L1teSvgu7aFg==", "dev": true, "requires": { "cssnano-preset-default": "^5.1.4", @@ -6611,8 +33369,6 @@ }, "cssnano-preset-default": { "version": "5.1.4", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.4.tgz", - "integrity": "sha512-sPpQNDQBI3R/QsYxQvfB4mXeEcWuw0wGtKtmS5eg8wudyStYMgKOQT39G07EbW1LB56AOYrinRS9f0ig4Y3MhQ==", "dev": true, "requires": { "css-declaration-sorter": "^6.0.3", @@ -6648,14 +33404,11 @@ }, "cssnano-utils": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", - "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", - "dev": true + "dev": true, + "requires": {} }, "csso": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dev": true, "requires": { "css-tree": "^1.1.2" @@ -6663,14 +33416,10 @@ }, "cssom": { "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, "cssstyle": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "dev": true, "requires": { "cssom": "0.3.x" @@ -6678,14 +33427,10 @@ }, "csstype": { "version": "3.0.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", - "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==", "dev": true }, "currently-unhandled": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { "array-find-index": "^1.0.1" @@ -6693,8 +33438,6 @@ }, "d3": { "version": "4.13.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-4.13.0.tgz", - "integrity": "sha512-l8c4+0SldjVKLaE2WG++EQlqD7mh/dmQjvi2L2lKPadAVC+TbJC4ci7Uk9bRi+To0+ansgsS0iWfPjD7DBy+FQ==", "dev": true, "requires": { "d3-array": "1.2.1", @@ -6731,20 +33474,14 @@ }, "d3-array": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==", "dev": true }, "d3-axis": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", - "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=", "dev": true }, "d3-brush": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", - "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=", "dev": true, "requires": { "d3-dispatch": "1", @@ -6756,8 +33493,6 @@ }, "d3-chord": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", - "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=", "dev": true, "requires": { "d3-array": "1", @@ -6766,26 +33501,18 @@ }, "d3-collection": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", - "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=", "dev": true }, "d3-color": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", - "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=", "dev": true }, "d3-dispatch": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", - "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=", "dev": true }, "d3-drag": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==", "dev": true, "requires": { "d3-dispatch": "1", @@ -6794,8 +33521,6 @@ }, "d3-dsv": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.8.tgz", - "integrity": "sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==", "dev": true, "requires": { "commander": "2", @@ -6805,22 +33530,16 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true } } }, "d3-ease": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", - "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=", "dev": true }, "d3-force": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.0.tgz", - "integrity": "sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==", "dev": true, "requires": { "d3-collection": "1", @@ -6831,14 +33550,10 @@ }, "d3-format": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.2.2.tgz", - "integrity": "sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==", "dev": true }, "d3-geo": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.9.1.tgz", - "integrity": "sha512-l9wL/cEQkyZQYXw3xbmLsH3eQ5ij+icNfo4r0GrLa5rOCZR/e/3am45IQ0FvQ5uMsv+77zBRunLc9ufTWSQYFA==", "dev": true, "requires": { "d3-array": "1" @@ -6846,14 +33561,10 @@ }, "d3-hierarchy": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", - "integrity": "sha1-ochFxC+Eoga88cAcAQmOpN2qeiY=", "dev": true }, "d3-interpolate": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.6.tgz", - "integrity": "sha512-mOnv5a+pZzkNIHtw/V6I+w9Lqm9L5bG3OTXPM5A+QO0yyVMQ4W1uZhR+VOJmazaOZXri2ppbiZ5BUNWT0pFM9A==", "dev": true, "requires": { "d3-color": "1" @@ -6861,38 +33572,26 @@ }, "d3-path": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", - "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=", "dev": true }, "d3-polygon": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", - "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=", "dev": true }, "d3-quadtree": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", - "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=", "dev": true }, "d3-queue": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/d3-queue/-/d3-queue-3.0.7.tgz", - "integrity": "sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=", "dev": true }, "d3-random": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", - "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=", "dev": true }, "d3-request": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-request/-/d3-request-1.0.6.tgz", - "integrity": "sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==", "dev": true, "requires": { "d3-collection": "1", @@ -6903,8 +33602,6 @@ }, "d3-scale": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.7.tgz", - "integrity": "sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==", "dev": true, "requires": { "d3-array": "^1.2.0", @@ -6918,14 +33615,10 @@ }, "d3-selection": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.0.tgz", - "integrity": "sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==", "dev": true }, "d3-shape": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", - "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=", "dev": true, "requires": { "d3-path": "1" @@ -6933,14 +33626,10 @@ }, "d3-time": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz", - "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==", "dev": true }, "d3-time-format": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz", - "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==", "dev": true, "requires": { "d3-time": "1" @@ -6948,14 +33637,10 @@ }, "d3-timer": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==", "dev": true }, "d3-transition": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==", "dev": true, "requires": { "d3-color": "1", @@ -6968,14 +33653,10 @@ }, "d3-voronoi": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", - "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=", "dev": true }, "d3-zoom": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.1.tgz", - "integrity": "sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==", "dev": true, "requires": { "d3-dispatch": "1", @@ -6987,14 +33668,10 @@ }, "dash-ast": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", "dev": true }, "dashdash": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -7002,8 +33679,6 @@ }, "data-urls": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { "abab": "^2.0.0", @@ -7013,14 +33688,10 @@ }, "de-indent": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", "dev": true }, "debug": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -7028,14 +33699,10 @@ }, "decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decamelize-keys": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -7044,20 +33711,14 @@ }, "decimal.js": { "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "decode-uri-component": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "decompress-response": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", "dev": true, "requires": { "mimic-response": "^2.0.0" @@ -7065,14 +33726,10 @@ }, "dedent": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, "deep-equal": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", "dev": true, "requires": { "is-arguments": "^1.0.4", @@ -7085,26 +33742,18 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, "deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "deepmerge": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, "default-require-extensions": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", "dev": true, "requires": { "strip-bom": "^4.0.0" @@ -7112,22 +33761,16 @@ "dependencies": { "strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true } } }, "defer-to-connect": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, "define-properties": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { "object-keys": "^1.0.12" @@ -7135,8 +33778,6 @@ }, "define-property": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { "is-descriptor": "^1.0.2", @@ -7145,8 +33786,6 @@ "dependencies": { "is-accessor-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -7154,8 +33793,6 @@ }, "is-data-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -7163,8 +33800,6 @@ }, "is-descriptor": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -7176,44 +33811,30 @@ }, "defined": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, "delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, "depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, "dependency-graph": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true }, "deprecation": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "dev": true }, "deps-sort": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", - "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", "dev": true, "requires": { "JSONStream": "^1.0.3", @@ -7224,8 +33845,6 @@ }, "des.js": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -7234,14 +33853,10 @@ }, "destroy": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, "detab": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", - "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", "dev": true, "requires": { "repeat-string": "^1.5.4" @@ -7249,20 +33864,14 @@ }, "detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true }, "detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, "detective": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", - "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", "dev": true, "requires": { "acorn-node": "^1.6.1", @@ -7272,26 +33881,18 @@ }, "devtools-protocol": { "version": "0.0.901419", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.901419.tgz", - "integrity": "sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ==", "dev": true }, "diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "diff-sequences": { "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -7301,16 +33902,12 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" @@ -7318,8 +33915,6 @@ }, "doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -7327,8 +33922,6 @@ }, "doctrine-temporary-fork": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine-temporary-fork/-/doctrine-temporary-fork-2.1.0.tgz", - "integrity": "sha512-nliqOv5NkE4zMON4UA6AMJE6As35afs8aYXATpU4pTUdIKiARZwrJVEP1boA3Rx1ZXHVkwxkhcq4VkqvsuRLsA==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -7336,8 +33929,6 @@ }, "documentation": { "version": "12.1.4", - "resolved": "https://registry.npmjs.org/documentation/-/documentation-12.1.4.tgz", - "integrity": "sha512-GGS635tR8bBR/m/AuUZ6MCZmFXZA25Wk9S/TTHNe+EMkTCoDdlcft56dZCjF7voCmfnMqKRo8sXAukf/ciA5IA==", "dev": true, "requires": { "@babel/core": "^7.1.2", @@ -7409,26 +34000,18 @@ "dependencies": { "@babel/parser": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.1.3.tgz", - "integrity": "sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w==", "dev": true }, "acorn": { "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "anymatch": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -7437,8 +34020,6 @@ "dependencies": { "normalize-path": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -7448,14 +34029,10 @@ }, "binary-extensions": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "braces": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -7472,8 +34049,6 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -7483,8 +34058,6 @@ }, "browser-resolve": { "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", "dev": true, "requires": { "resolve": "1.1.7" @@ -7492,16 +34065,12 @@ "dependencies": { "resolve": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } } }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -7511,8 +34080,6 @@ }, "chokidar": { "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -7531,8 +34098,6 @@ }, "detective": { "version": "4.7.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", - "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", "dev": true, "requires": { "acorn": "^5.2.1", @@ -7541,14 +34106,10 @@ }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "fill-range": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -7559,8 +34120,6 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -7568,21 +34127,8 @@ } } }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, "glob-parent": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { "is-glob": "^3.1.0", @@ -7591,8 +34137,6 @@ "dependencies": { "is-glob": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { "is-extglob": "^2.1.0" @@ -7602,8 +34146,6 @@ }, "is-binary-path": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { "binary-extensions": "^1.0.0" @@ -7611,20 +34153,14 @@ }, "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -7632,8 +34168,6 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -7643,8 +34177,6 @@ }, "micromatch": { "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -7664,11 +34196,8 @@ }, "module-deps-sortable": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/module-deps-sortable/-/module-deps-sortable-5.0.0.tgz", - "integrity": "sha512-bnGGeghQmz/t/6771/KC4FmxpVm126iR6AAzzq4N6hVZQVl4+ZZBv+VF3PJmDyxXtVtgcgTSSP7NL+jq1QAHrg==", "dev": true, "requires": { - "JSONStream": "^1.0.3", "browser-resolve": "^1.7.0", "cached-path-relative": "^1.0.0", "concat-stream": "~1.5.0", @@ -7676,6 +34205,7 @@ "detective": "^4.0.0", "duplexer2": "^0.1.2", "inherits": "^2.0.1", + "JSONStream": "^1.0.3", "readable-stream": "^2.0.2", "resolve": "^1.1.3", "stream-combiner2": "^1.1.1", @@ -7686,8 +34216,6 @@ "dependencies": { "concat-stream": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", "dev": true, "requires": { "inherits": "~2.0.1", @@ -7697,8 +34225,6 @@ "dependencies": { "readable-stream": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -7715,14 +34241,10 @@ }, "process-nextick-args": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "readdirp": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -7730,10 +34252,12 @@ "readable-stream": "^2.0.2" } }, + "string_decoder": { + "version": "0.10.31", + "dev": true + }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -7741,16 +34265,8 @@ "strip-ansi": "^6.0.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" @@ -7758,8 +34274,6 @@ }, "to-regex-range": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -7768,8 +34282,6 @@ }, "vfile-reporter": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-6.0.2.tgz", - "integrity": "sha512-GN2bH2gs4eLnw/4jPSgfBjo+XCuvnX9elHICJZjVD4+NM0nsUrMTvdjGY5Sc/XG69XVTgLwj7hknQVc6M9FukA==", "dev": true, "requires": { "repeat-string": "^1.5.0", @@ -7782,8 +34294,6 @@ "dependencies": { "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -7795,8 +34305,6 @@ }, "dom-serializer": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "dev": true, "requires": { "domelementtype": "^2.0.1", @@ -7806,20 +34314,14 @@ }, "domain-browser": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, "domelementtype": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, "domexception": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", "dev": true, "requires": { "webidl-conversions": "^4.0.2" @@ -7827,8 +34329,6 @@ }, "domhandler": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", "dev": true, "requires": { "domelementtype": "^2.2.0" @@ -7836,8 +34336,6 @@ }, "domutils": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, "requires": { "dom-serializer": "^1.0.1", @@ -7847,8 +34345,6 @@ }, "dot-prop": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { "is-obj": "^2.0.0" @@ -7856,16 +34352,12 @@ "dependencies": { "is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true } } }, "dotignore": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", - "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", "dev": true, "requires": { "minimatch": "^3.0.4" @@ -7873,8 +34365,6 @@ }, "dts-bundle-generator": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/dts-bundle-generator/-/dts-bundle-generator-6.1.0.tgz", - "integrity": "sha512-9MGbhZExuN75zq8ImoM7iVeGUavjtGw+UIfbaNRWZ+Jq4Nw2MN5OLuSrA1EnWlmZakTZRCx1CMo1zqBQ9+HP9g==", "dev": true, "requires": { "typescript": ">=3.0.1", @@ -7883,14 +34373,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -7898,8 +34384,6 @@ }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -7909,8 +34393,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -7918,32 +34400,22 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -7953,8 +34425,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -7962,8 +34432,6 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -7973,14 +34441,10 @@ }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -7994,22 +34458,16 @@ }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "duplexer": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, "duplexer2": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { "readable-stream": "^2.0.2" @@ -8017,14 +34475,10 @@ }, "duplexer3": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, "duplexify": { "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, "requires": { "end-of-stream": "^1.0.0", @@ -8034,14 +34488,10 @@ } }, "earcut": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.3.tgz", - "integrity": "sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==" + "version": "2.2.3" }, "ecc-jsbn": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { "jsbn": "~0.1.0", @@ -8050,8 +34500,6 @@ }, "ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "dev": true, "requires": { "safe-buffer": "^5.0.1" @@ -8059,14 +34507,10 @@ }, "ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, "ejs": { "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", "dev": true, "requires": { "jake": "^10.6.1" @@ -8074,14 +34518,10 @@ }, "electron-to-chromium": { "version": "1.3.838", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.838.tgz", - "integrity": "sha512-65O6UJiyohFAdX/nc6KJ0xG/4zOn7XCO03kQNNbCeMRGxlWTLzc6Uyi0tFNQuuGWqySZJi8CD2KXPXySVYmzMA==", "dev": true }, "elliptic": { "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "requires": { "bn.js": "^4.11.9", @@ -8095,34 +34535,24 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "emittery": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true }, "emoji-regex": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", "dev": true }, "encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, "end-of-stream": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { "once": "^1.4.0" @@ -8130,8 +34560,6 @@ }, "engine.io": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.2.0.tgz", - "integrity": "sha512-d1DexkQx87IFr1FLuV+0f5kAm1Hk1uOVijLOb+D1sDO2QMb7YjE02VHtZtxo7xIXMgcWLb+vl3HRT0rI9tr4jQ==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -8145,22 +34573,17 @@ "dependencies": { "cookie": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", "dev": true }, "ws": { "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true + "dev": true, + "requires": {} } } }, "engine.io-parser": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", - "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", "dev": true, "requires": { "base64-arraybuffer": "0.1.4" @@ -8168,8 +34591,6 @@ }, "enquirer": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { "ansi-colors": "^4.1.1" @@ -8177,20 +34598,14 @@ }, "entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true }, "env-paths": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, "error": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", - "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", "dev": true, "requires": { "string-template": "~0.2.1" @@ -8198,8 +34613,6 @@ }, "error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -8207,8 +34620,6 @@ }, "es-abstract": { "version": "1.18.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", - "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -8233,8 +34644,6 @@ }, "es-get-iterator": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", - "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -8249,16 +34658,12 @@ "dependencies": { "isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true } } }, "es-to-primitive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", @@ -8268,38 +34673,26 @@ }, "es6-error": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, "escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-goat": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "dev": true }, "escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "escodegen": { "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { "esprima": "^4.0.1", @@ -8311,8 +34704,6 @@ "dependencies": { "levn": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -8321,8 +34712,6 @@ }, "optionator": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", @@ -8335,21 +34724,15 @@ }, "prelude-ls": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true }, "type-check": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" @@ -8359,8 +34742,6 @@ }, "eslint": { "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", @@ -8407,8 +34788,6 @@ "dependencies": { "@babel/code-frame": { "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" @@ -8416,14 +34795,10 @@ }, "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -8433,14 +34808,10 @@ }, "escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "eslint-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -8448,16 +34819,12 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "globals": { "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8465,20 +34832,14 @@ }, "ignore": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -8486,14 +34847,10 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" @@ -8501,14 +34858,10 @@ }, "strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -8518,14 +34871,10 @@ }, "eslint-config-mourner": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-mourner/-/eslint-config-mourner-3.0.0.tgz", - "integrity": "sha512-QWMt3Cbqkhg/73fZ2UrTNa/p27nF3JhI1Ej2Jg7qSBri88Y0bg4LFzz0/6I5IrvFR10c6UPwDS+DsV9Ec42aVQ==", "dev": true }, "eslint-import-resolver-node": { "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "requires": { "debug": "^3.2.7", @@ -8534,8 +34883,6 @@ "dependencies": { "debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -8545,8 +34892,6 @@ }, "eslint-module-utils": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", - "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, "requires": { "debug": "^3.2.7", @@ -8555,8 +34900,6 @@ "dependencies": { "debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -8566,8 +34909,6 @@ }, "eslint-plugin-html": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.1.2.tgz", - "integrity": "sha512-bhBIRyZFqI4EoF12lGDHAmgfff8eLXx6R52/K3ESQhsxzCzIE6hdebS7Py651f7U3RBotqroUnC3L29bR7qJWQ==", "dev": true, "requires": { "htmlparser2": "^6.0.1" @@ -8575,8 +34916,6 @@ }, "eslint-plugin-import": { "version": "2.24.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", - "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "requires": { "array-includes": "^3.1.3", @@ -8598,8 +34937,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -8607,8 +34944,6 @@ }, "doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -8616,8 +34951,6 @@ }, "find-up": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -8625,8 +34958,6 @@ }, "locate-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -8635,14 +34966,10 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "p-limit": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { "p-try": "^1.0.0" @@ -8650,8 +34977,6 @@ }, "p-locate": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -8659,14 +34984,10 @@ }, "p-try": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "read-pkg-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { "find-up": "^2.0.0", @@ -8677,8 +34998,6 @@ }, "eslint-plugin-jest": { "version": "25.2.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.2.4.tgz", - "integrity": "sha512-HRyinpgmEdkVr7pNPaYPHCoGqEzpgk79X8pg/xCeoAdurbyQjntJQ4pTzHl7BiVEBlam/F1Qsn+Dk0HtJO7Aaw==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^5.0.0" @@ -8686,8 +35005,6 @@ "dependencies": { "@typescript-eslint/experimental-utils": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz", - "integrity": "sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", @@ -8700,8 +35017,6 @@ }, "@typescript-eslint/scope-manager": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz", - "integrity": "sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A==", "dev": true, "requires": { "@typescript-eslint/types": "5.3.0", @@ -8710,14 +35025,10 @@ }, "@typescript-eslint/types": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.0.tgz", - "integrity": "sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz", - "integrity": "sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug==", "dev": true, "requires": { "@typescript-eslint/types": "5.3.0", @@ -8731,8 +35042,6 @@ }, "@typescript-eslint/visitor-keys": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz", - "integrity": "sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw==", "dev": true, "requires": { "@typescript-eslint/types": "5.3.0", @@ -8741,14 +35050,10 @@ }, "eslint-visitor-keys": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", "dev": true }, "is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -8758,8 +35063,6 @@ }, "eslint-plugin-jsdoc": { "version": "37.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.0.3.tgz", - "integrity": "sha512-Qg/gIZAfcrM4Qu/JzcnxPGD45Je6wPLFzMZQboeqit/CL4aY6wuzBTkgUMiWXfw/PaPl+sb0GF1XdBlV23ReDA==", "dev": true, "requires": { "@es-joy/jsdoccomment": "0.12.0", @@ -8775,8 +35078,6 @@ }, "eslint-plugin-react": { "version": "7.25.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.1.tgz", - "integrity": "sha512-P4j9K1dHoFXxDNP05AtixcJEvIT6ht8FhYKsrkY0MPCPaUMYijhpWwNiRDZVtA8KFuZOkGSeft6QwH8KuVpJug==", "dev": true, "requires": { "array-includes": "^3.1.3", @@ -8796,8 +35097,6 @@ "dependencies": { "doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -8805,14 +35104,10 @@ }, "estraverse": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true }, "resolve": { "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", "dev": true, "requires": { "is-core-module": "^2.2.0", @@ -8823,8 +35118,6 @@ }, "eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -8833,8 +35126,6 @@ }, "eslint-utils": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" @@ -8842,14 +35133,10 @@ }, "eslint-visitor-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", @@ -8859,28 +35146,20 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "espurify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/espurify/-/espurify-2.1.1.tgz", - "integrity": "sha512-zttWvnkhcDyGOhSH4vO2qCBILpdCMv/MX8lp4cqgRkQoDRGK2oZxi2GfWhlP2dIXmk7BaKeOTuzbHhyC68o8XQ==", "dev": true }, "esquery": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -8888,16 +35167,12 @@ "dependencies": { "estraverse": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" @@ -8905,58 +35180,40 @@ "dependencies": { "estraverse": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "estree-walker": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, "eventemitter3": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, "events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, "events-to-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, "evp_bytestokey": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { "md5.js": "^1.3.4", @@ -8965,8 +35222,6 @@ }, "execa": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { "cross-spawn": "^6.0.0", @@ -8980,8 +35235,6 @@ "dependencies": { "get-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -8989,8 +35242,6 @@ }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -9001,8 +35252,6 @@ }, "execall": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", "dev": true, "requires": { "clone-regexp": "^2.1.0" @@ -9010,14 +35259,10 @@ }, "exit": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, "expand-brackets": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { "debug": "^2.3.3", @@ -9031,8 +35276,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -9040,8 +35283,6 @@ }, "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -9049,8 +35290,6 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -9058,22 +35297,16 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "expand-template": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "dev": true }, "expect": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", - "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -9086,16 +35319,12 @@ "dependencies": { "ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true } } }, "express": { "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { "accepts": "~1.3.7", @@ -9132,8 +35361,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -9141,34 +35368,24 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "path-to-regexp": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, "qs": { "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true } } }, "extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "extend-shallow": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { "assign-symbols": "^1.0.0", @@ -9177,8 +35394,6 @@ "dependencies": { "is-extendable": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -9186,8 +35401,6 @@ }, "is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -9197,8 +35410,6 @@ }, "external-editor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -9208,8 +35419,6 @@ "dependencies": { "tmp": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -9219,8 +35428,6 @@ }, "extglob": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { "array-unique": "^0.3.2", @@ -9235,8 +35442,6 @@ "dependencies": { "define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -9244,8 +35449,6 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -9253,8 +35456,6 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -9262,8 +35463,6 @@ }, "is-data-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -9271,8 +35470,6 @@ }, "is-descriptor": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -9284,8 +35481,6 @@ }, "extract-zip": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { "@types/yauzl": "^2.9.1", @@ -9296,8 +35491,6 @@ "dependencies": { "get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -9305,8 +35498,6 @@ }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -9317,20 +35508,14 @@ }, "extsprintf": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, "fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -9342,32 +35527,22 @@ }, "fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "fast-safe-stringify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, "fastest-levenshtein": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, "fastq": { "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -9375,8 +35550,6 @@ }, "faye-websocket": { "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -9384,8 +35557,6 @@ }, "fb-watchman": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, "requires": { "bser": "2.1.1" @@ -9393,14 +35564,10 @@ }, "fd": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/fd/-/fd-0.0.3.tgz", - "integrity": "sha512-iAHrIslQb3U68OcMSP0kkNWabp7sSN6d2TBSb2JO3gcLJVDd4owr/hKM4SFJovFOUeeXeItjYgouEDTMWiVAnA==", "dev": true }, "fd-slicer": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "~1.2.0" @@ -9408,8 +35575,6 @@ }, "figures": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -9417,8 +35582,6 @@ }, "file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -9426,14 +35589,10 @@ }, "file-uri-to-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true }, "filelist": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", - "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", "dev": true, "requires": { "minimatch": "^3.0.4" @@ -9441,8 +35600,6 @@ }, "fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -9450,14 +35607,10 @@ }, "filter-obj": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=", "dev": true }, "finalhandler": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { "debug": "2.6.9", @@ -9471,8 +35624,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -9480,16 +35631,12 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "find-cache-dir": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", @@ -9499,8 +35646,6 @@ "dependencies": { "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -9509,8 +35654,6 @@ }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -9518,8 +35661,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -9527,14 +35668,10 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { "find-up": "^4.0.0" @@ -9544,8 +35681,6 @@ }, "find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" @@ -9553,8 +35688,6 @@ }, "fireworm": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/fireworm/-/fireworm-0.7.1.tgz", - "integrity": "sha1-zPIPeUHxCIg/zduZOD2+bhhhx1g=", "dev": true, "requires": { "async": "~0.2.9", @@ -9566,14 +35699,10 @@ "dependencies": { "async": { "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true }, "lodash.debounce": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", - "integrity": "sha1-gSIRw3ipTMKdWqTjNGzwv846ffU=", "dev": true, "requires": { "lodash._getnative": "^3.0.0" @@ -9583,8 +35712,6 @@ }, "flat-cache": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { "flatted": "^3.1.0", @@ -9593,20 +35720,14 @@ }, "flatted": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, "flow-parser": { "version": "0.163.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.163.0.tgz", - "integrity": "sha512-txOsBcZ1nKsKtoAsBFnArFdq0cnPCmEHI5S2jQIgU1ZO1xtWpg64TsZSRktsaOyoWLpAvVxPap4Qbdd/TCJ3FQ==", "dev": true }, "flush-write-stream": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -9615,14 +35736,10 @@ }, "follow-redirects": { "version": "1.14.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", - "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==", "dev": true }, "for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "requires": { "is-callable": "^1.1.3" @@ -9630,20 +35747,14 @@ }, "for-in": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "foreach": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, "foreground-child": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -9652,8 +35763,6 @@ "dependencies": { "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -9663,14 +35772,10 @@ }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -9678,14 +35783,10 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -9695,14 +35796,10 @@ }, "forever-agent": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, "form-data": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -9712,14 +35809,10 @@ }, "forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true }, "fragment-cache": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { "map-cache": "^0.2.2" @@ -9727,32 +35820,22 @@ }, "fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, "fromentries": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true }, "fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true }, "fs-exists-cached": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", - "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, "fs-extra": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -9762,8 +35845,6 @@ }, "fs-minipass": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "requires": { "minipass": "^3.0.0" @@ -9771,8 +35852,6 @@ }, "fs-mkdirp-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -9781,21 +35860,10 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "fstream": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -9806,8 +35874,6 @@ "dependencies": { "mkdirp": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -9815,8 +35881,6 @@ }, "rimraf": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -9826,26 +35890,18 @@ }, "function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "function-loop": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz", - "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", "dev": true }, "functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "requires": { "aproba": "^1.0.3", @@ -9860,14 +35916,10 @@ "dependencies": { "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -9875,8 +35927,6 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -9886,8 +35936,6 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -9897,31 +35945,21 @@ }, "gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "geojson-vt": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", - "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" + "version": "3.2.1" }, "get-assigned-identifiers": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", "dev": true }, "get-caller-file": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, "get-intrinsic": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -9931,8 +35969,6 @@ }, "get-npm-tarball-url": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-npm-tarball-url/-/get-npm-tarball-url-2.0.2.tgz", - "integrity": "sha512-2dPhgT0K4pVyciTqdS0gr9nEwyCQwt9ql1/t5MCUMvcjWjAysjGJgT7Sx4n6oq3tFBjBN238mxX4RfTjT3838Q==", "dev": true, "requires": { "normalize-registry-url": "^1.0.0" @@ -9940,31 +35976,21 @@ }, "get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, "get-port": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", "dev": true }, "get-stdin": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + "version": "6.0.1" }, "get-symbol-description": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -9973,14 +35999,10 @@ }, "get-value": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, "getpass": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -9988,8 +36010,6 @@ }, "git-up": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.5.tgz", - "integrity": "sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA==", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -9998,8 +36018,6 @@ }, "git-url-parse": { "version": "11.6.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.6.0.tgz", - "integrity": "sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g==", "dev": true, "requires": { "git-up": "^4.0.0" @@ -10007,14 +36025,10 @@ }, "github-from-package": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", "dev": true }, "github-slugger": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.0.tgz", - "integrity": "sha512-wIaa75k1vZhyPm9yWrD08A5Xnx/V+RmzGrpjQuLemGKSb77Qukiaei58Bogrl/LZSADDfPzKJX8jhLs4CRTl7Q==", "dev": true, "requires": { "emoji-regex": ">=6.0.0 <=6.1.1" @@ -10022,8 +36036,6 @@ }, "gl": { "version": "4.9.0", - "resolved": "https://registry.npmjs.org/gl/-/gl-4.9.0.tgz", - "integrity": "sha512-5Qz8fM4kO4xTo/Ofv80hq/iXEGNlMxOCSo1+9cvT9CX/j84tIFBsbFLXkBVFZiKulA3H2VPQGSs0qZIMwv3KEA==", "dev": true, "requires": { "bindings": "^1.5.0", @@ -10036,14 +36048,10 @@ } }, "gl-matrix": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.3.0.tgz", - "integrity": "sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA==" + "version": "3.3.0" }, "glob": { "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -10056,8 +36064,6 @@ }, "glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -10065,8 +36071,6 @@ }, "glob-stream": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", "dev": true, "requires": { "extend": "^3.0.0", @@ -10083,8 +36087,6 @@ "dependencies": { "glob-parent": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { "is-glob": "^3.1.0", @@ -10093,8 +36095,6 @@ }, "is-glob": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { "is-extglob": "^2.1.0" @@ -10104,8 +36104,6 @@ }, "global-dirs": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", "dev": true, "requires": { "ini": "1.3.7" @@ -10113,16 +36111,12 @@ "dependencies": { "ini": { "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true } } }, "global-modules": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, "requires": { "global-prefix": "^3.0.0" @@ -10130,8 +36124,6 @@ }, "global-prefix": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, "requires": { "ini": "^1.3.5", @@ -10141,20 +36133,14 @@ }, "globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "globals-docs": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/globals-docs/-/globals-docs-2.4.1.tgz", - "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==", "dev": true }, "globby": { "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -10167,14 +36153,10 @@ }, "globjoin": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", "dev": true }, "glsl-tokenizer": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz", - "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==", "dev": true, "requires": { "through2": "^0.6.3" @@ -10182,14 +36164,10 @@ "dependencies": { "isarray": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10200,14 +36178,10 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "through2": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", @@ -10218,8 +36192,6 @@ }, "gonzales-pe": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", - "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -10227,8 +36199,6 @@ }, "got": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { "create-error-class": "^3.0.0", @@ -10246,33 +36216,23 @@ "dependencies": { "get-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true } } }, "graceful-fs": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "grid-index": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", - "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==" + "version": "1.1.0" }, "growly": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, "gzip-size": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dev": true, "requires": { "duplexer": "^0.1.2" @@ -10280,14 +36240,10 @@ }, "har-schema": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { "ajv": "^6.12.3", @@ -10296,14 +36252,10 @@ }, "hard-rejection": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, "has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { "function-bind": "^1.1.1" @@ -10311,20 +36263,14 @@ }, "has-bigints": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true }, "has-color": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", "dev": true }, "has-dynamic-import": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.0.tgz", - "integrity": "sha512-GYPi/aZmACJVrVfEhP1rNUFmtCuK+SQ96mn8Bs7mXiGZRAJiI4VjaMmjj4uuvW8qaF085uWJvyJk9UNYUIYn0A==", "dev": true, "requires": { "call-bind": "^1.0.2" @@ -10332,20 +36278,14 @@ }, "has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-symbols": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, "has-tostringtag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, "requires": { "has-symbols": "^1.0.2" @@ -10353,14 +36293,10 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, "has-value": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { "get-value": "^2.0.6", @@ -10370,8 +36306,6 @@ }, "has-values": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -10380,14 +36314,10 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -10395,8 +36325,6 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -10406,8 +36334,6 @@ }, "kind-of": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -10417,14 +36343,10 @@ }, "has-yarn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, "hash-base": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "dev": true, "requires": { "inherits": "^2.0.4", @@ -10434,8 +36356,6 @@ "dependencies": { "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -10445,16 +36365,12 @@ }, "safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true } } }, "hash.js": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -10463,8 +36379,6 @@ }, "hasha": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, "requires": { "is-stream": "^2.0.0", @@ -10473,28 +36387,20 @@ "dependencies": { "is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, "hast-util-is-element": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", - "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", "dev": true }, "hast-util-sanitize": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.3.1.tgz", - "integrity": "sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==", "dev": true, "requires": { "xtend": "^4.0.1" @@ -10502,8 +36408,6 @@ }, "hast-util-to-html": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-4.0.1.tgz", - "integrity": "sha512-2emzwyf0xEsc4TBIPmDJmBttIw8R4SXAJiJZoiRR/s47ODYWgOqNoDbf2SJAbMbfNdFWMiCSOrI3OVnX6Qq2Mg==", "dev": true, "requires": { "ccount": "^1.0.0", @@ -10520,34 +36424,24 @@ "dependencies": { "unist-util-is": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", - "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", "dev": true } } }, "hast-util-whitespace": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", - "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", "dev": true }, "he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "highlight.js": { "version": "9.18.5", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz", - "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==", "dev": true }, "hmac-drbg": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { "hash.js": "^1.0.3", @@ -10557,14 +36451,10 @@ }, "hosted-git-info": { "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-encoding-sniffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { "whatwg-encoding": "^1.0.1" @@ -10572,32 +36462,22 @@ }, "html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "html-tags": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", - "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true }, "html-void-elements": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", - "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", "dev": true }, "htmlescape": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", "dev": true }, "htmlparser2": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, "requires": { "domelementtype": "^2.0.1", @@ -10608,14 +36488,10 @@ }, "http-cache-semantics": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, "http-errors": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { "depd": "~1.1.2", @@ -10627,22 +36503,16 @@ "dependencies": { "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true } } }, "http-parser-js": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", "dev": true }, "http-proxy": { "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { "eventemitter3": "^4.0.0", @@ -10652,8 +36522,6 @@ }, "http-proxy-agent": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, "requires": { "@tootallnate/once": "1", @@ -10663,8 +36531,6 @@ }, "http-signature": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -10674,14 +36540,10 @@ }, "https-browserify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "https-proxy-agent": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "requires": { "agent-base": "6", @@ -10690,34 +36552,24 @@ }, "human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, "iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "version": "1.2.1" }, "ignore": { "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, "ignore-walk": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-4.0.1.tgz", - "integrity": "sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw==", "dev": true, "requires": { "minimatch": "^3.0.4" @@ -10725,14 +36577,10 @@ }, "immediate": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", "dev": true }, "import-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz", - "integrity": "sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==", "dev": true, "requires": { "import-from": "^3.0.0" @@ -10740,8 +36588,6 @@ }, "import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -10750,8 +36596,6 @@ }, "import-from": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", - "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", "dev": true, "requires": { "resolve-from": "^5.0.0" @@ -10759,22 +36603,16 @@ "dependencies": { "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true } } }, "import-lazy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true }, "import-local": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", "dev": true, "requires": { "pkg-dir": "^4.2.0", @@ -10783,8 +36621,6 @@ "dependencies": { "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -10793,8 +36629,6 @@ }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -10802,8 +36636,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -10811,14 +36643,10 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { "find-up": "^4.0.0" @@ -10828,14 +36656,10 @@ }, "imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "indent-string": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { "repeating": "^2.0.0" @@ -10843,8 +36667,6 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", @@ -10853,20 +36675,14 @@ }, "inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "inline-source-map": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "dev": true, "requires": { "source-map": "~0.5.3" @@ -10874,8 +36690,6 @@ }, "inquirer": { "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -10895,26 +36709,18 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -10924,8 +36730,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -10935,15 +36739,13 @@ }, "insert-module-globals": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", - "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", "dev": true, "requires": { - "JSONStream": "^1.0.3", "acorn-node": "^1.5.2", "combine-source-map": "^0.8.0", "concat-stream": "^1.6.1", "is-buffer": "^1.1.0", + "JSONStream": "^1.0.3", "path-is-absolute": "^1.0.1", "process": "~0.11.0", "through2": "^2.0.0", @@ -10953,16 +36755,12 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true } } }, "internal-slot": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "requires": { "get-intrinsic": "^1.1.0", @@ -10972,20 +36770,14 @@ }, "invert-kv": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, "ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, "is-absolute": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { "is-relative": "^1.0.0", @@ -10994,14 +36786,10 @@ }, "is-absolute-url": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11009,14 +36797,10 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11026,20 +36810,14 @@ }, "is-alphabetical": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "dev": true }, "is-alphanumeric": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", "dev": true }, "is-alphanumerical": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", "dev": true, "requires": { "is-alphabetical": "^1.0.0", @@ -11048,8 +36826,6 @@ }, "is-arguments": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -11058,14 +36834,10 @@ }, "is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-bigint": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "requires": { "has-bigints": "^1.0.1" @@ -11073,8 +36845,6 @@ }, "is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" @@ -11082,8 +36852,6 @@ }, "is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -11092,14 +36860,10 @@ }, "is-buffer": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true }, "is-builtin-module": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", "dev": true, "requires": { "builtin-modules": "^3.0.0" @@ -11107,14 +36871,10 @@ }, "is-callable": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-ci": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { "ci-info": "^2.0.0" @@ -11122,16 +36882,12 @@ "dependencies": { "ci-info": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true } } }, "is-core-module": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dev": true, "requires": { "has": "^1.0.3" @@ -11139,8 +36895,6 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -11148,14 +36902,10 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -11165,8 +36915,6 @@ }, "is-date-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" @@ -11174,14 +36922,10 @@ }, "is-decimal": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", "dev": true }, "is-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", @@ -11191,52 +36935,36 @@ "dependencies": { "kind-of": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } }, "is-docker": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true }, "is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, "is-generator-function": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" @@ -11244,8 +36972,6 @@ }, "is-git-clean": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-git-clean/-/is-git-clean-1.1.0.tgz", - "integrity": "sha1-E6vW3acRuwiq/UJgTaSHhF3c+I0=", "dev": true, "requires": { "execa": "^0.4.0", @@ -11255,8 +36981,6 @@ "dependencies": { "execa": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.4.0.tgz", - "integrity": "sha1-TrZGejaglfq7KXD/nV4/t7zm68M=", "dev": true, "requires": { "cross-spawn-async": "^2.1.1", @@ -11269,8 +36993,6 @@ }, "npm-run-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", "dev": true, "requires": { "path-key": "^1.0.0" @@ -11278,16 +37000,12 @@ }, "path-key": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", "dev": true } } }, "is-glob": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -11295,14 +37013,10 @@ }, "is-hexadecimal": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "dev": true }, "is-installed-globally": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", "dev": true, "requires": { "global-dirs": "^2.0.1", @@ -11311,44 +37025,30 @@ }, "is-map": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true }, "is-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, "is-negated-glob": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", "dev": true }, "is-negative-zero": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true }, "is-npm": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, "is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-number-object": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" @@ -11356,44 +37056,30 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, "is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, "is-plain-obj": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, "is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, "is-potential-custom-element-name": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, "is-redirect": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", "dev": true }, "is-reference": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "requires": { "@types/estree": "*" @@ -11401,8 +37087,6 @@ }, "is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -11411,14 +37095,10 @@ }, "is-regexp": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", "dev": true }, "is-relative": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { "is-unc-path": "^1.0.0" @@ -11426,26 +37106,18 @@ }, "is-resolvable": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-retry-allowed": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", "dev": true }, "is-set": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true }, "is-ssh": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz", - "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==", "dev": true, "requires": { "protocols": "^1.1.0" @@ -11453,14 +37125,10 @@ }, "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-string": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" @@ -11468,8 +37136,6 @@ }, "is-symbol": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { "has-symbols": "^1.0.2" @@ -11477,8 +37143,6 @@ }, "is-type": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/is-type/-/is-type-0.0.1.tgz", - "integrity": "sha1-9lHYXDZdRJVdFKUdjXBh8/a0d5w=", "dev": true, "requires": { "core-util-is": "~1.0.0" @@ -11486,8 +37150,6 @@ }, "is-typed-array": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", "dev": true, "requires": { "available-typed-arrays": "^1.0.5", @@ -11499,14 +37161,10 @@ }, "is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "is-unc-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "^0.1.2" @@ -11514,62 +37172,42 @@ }, "is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "is-url": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", "dev": true }, "is-utf8": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-valid-glob": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", "dev": true }, "is-weakmap": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "dev": true }, "is-weakset": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz", - "integrity": "sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==", "dev": true }, "is-whitespace-character": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", "dev": true }, "is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "is-word-character": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", "dev": true }, "is-wsl": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "requires": { "is-docker": "^2.0.0" @@ -11577,44 +37215,30 @@ }, "is-yarn-global": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "isstream": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "istanbul-lib-coverage": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true }, "istanbul-lib-hook": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, "requires": { "append-transform": "^2.0.0" @@ -11622,8 +37246,6 @@ }, "istanbul-lib-instrument": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "requires": { "@babel/core": "^7.7.5", @@ -11634,16 +37256,12 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "istanbul-lib-processinfo": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", "dev": true, "requires": { "archy": "^1.0.0", @@ -11657,8 +37275,6 @@ "dependencies": { "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -11668,14 +37284,10 @@ }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -11683,14 +37295,10 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -11700,8 +37308,6 @@ }, "istanbul-lib-report": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", @@ -11711,14 +37317,10 @@ "dependencies": { "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -11728,8 +37330,6 @@ }, "istanbul-lib-source-maps": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", "dev": true, "requires": { "debug": "^4.1.1", @@ -11739,16 +37339,12 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "istanbul-reports": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -11757,8 +37353,6 @@ }, "jake": { "version": "10.8.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", - "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", "dev": true, "requires": { "async": "0.9.x", @@ -11769,8 +37363,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -11782,8 +37374,6 @@ }, "jest": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz", - "integrity": "sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng==", "dev": true, "requires": { "@jest/core": "^27.3.1", @@ -11793,14 +37383,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -11808,8 +37394,6 @@ }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -11819,8 +37403,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -11828,32 +37410,22 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "jest-cli": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", - "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", "dev": true, "requires": { "@jest/core": "^27.3.1", @@ -11872,8 +37444,6 @@ }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -11883,8 +37453,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -11892,8 +37460,6 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -11903,14 +37469,10 @@ }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -11924,16 +37486,12 @@ }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "jest-canvas-mock": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.3.1.tgz", - "integrity": "sha512-5FnSZPrX3Q2ZfsbYNE3wqKR3+XorN8qFzDzB5o0golWgt6EOX1+emBnpOc9IAQ+NXFj8Nzm3h7ZdE/9H0ylBcg==", "dev": true, "requires": { "cssfontparser": "^1.2.1", @@ -11942,8 +37500,6 @@ }, "jest-changed-files": { "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -11953,8 +37509,6 @@ "dependencies": { "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -11964,8 +37518,6 @@ }, "execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -11981,14 +37533,10 @@ }, "is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { "path-key": "^3.0.0" @@ -11996,14 +37544,10 @@ }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -12011,14 +37555,10 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -12028,8 +37568,6 @@ }, "jest-circus": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", - "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", "dev": true, "requires": { "@jest/environment": "^27.3.1", @@ -12055,14 +37593,10 @@ "dependencies": { "escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, "stack-utils": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12072,8 +37606,6 @@ }, "jest-codemods": { "version": "0.24.0", - "resolved": "https://registry.npmjs.org/jest-codemods/-/jest-codemods-0.24.0.tgz", - "integrity": "sha512-xausWHSLvUVc7eJlONJgM6HIoRRy8WPt+MBRgKZsGqOtzXtpydbMt6XsClvSBLxaoyj7VoBU9BLcSfYc1CjkzA==", "dev": true, "requires": { "@babel/core": "7.4.5", @@ -12090,8 +37622,6 @@ "dependencies": { "@babel/core": { "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", - "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -12112,8 +37642,6 @@ }, "camelcase-keys": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -12123,8 +37651,6 @@ }, "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -12134,8 +37660,6 @@ }, "execa": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -12151,8 +37675,6 @@ }, "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -12161,8 +37683,6 @@ }, "get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -12170,26 +37690,18 @@ }, "human-signals": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, "indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -12197,14 +37709,10 @@ }, "map-obj": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, "meow": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", - "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -12222,8 +37730,6 @@ }, "npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { "path-key": "^3.0.0" @@ -12231,8 +37737,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -12240,8 +37744,6 @@ }, "parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -12252,20 +37754,14 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -12274,8 +37770,6 @@ }, "read-pkg": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", @@ -12286,16 +37780,12 @@ "dependencies": { "type-fest": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true } } }, "read-pkg-up": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { "find-up": "^4.1.0", @@ -12305,16 +37795,12 @@ "dependencies": { "type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, "redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { "indent-string": "^4.0.0", @@ -12323,14 +37809,10 @@ }, "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -12338,14 +37820,10 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "strip-indent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { "min-indent": "^1.0.0" @@ -12353,20 +37831,14 @@ }, "trim-newlines": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "type-fest": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -12374,8 +37846,6 @@ }, "yargs-parser": { "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -12386,8 +37856,6 @@ }, "jest-config": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", - "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", "dev": true, "requires": { "@babel/core": "^7.1.0", @@ -12415,8 +37883,6 @@ }, "jest-diff": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", - "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -12427,8 +37893,6 @@ }, "jest-docblock": { "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "requires": { "detect-newline": "^3.0.0" @@ -12436,8 +37900,6 @@ }, "jest-each": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", - "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -12449,8 +37911,6 @@ }, "jest-environment-jsdom": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", - "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", "dev": true, "requires": { "@jest/environment": "^27.3.1", @@ -12464,14 +37924,10 @@ "dependencies": { "acorn": { "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true }, "acorn-globals": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, "requires": { "acorn": "^7.1.1", @@ -12480,22 +37936,16 @@ "dependencies": { "acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true } } }, "cssom": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "dev": true }, "cssstyle": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, "requires": { "cssom": "~0.3.6" @@ -12503,16 +37953,12 @@ "dependencies": { "cssom": { "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true } } }, "data-urls": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, "requires": { "abab": "^2.0.3", @@ -12522,8 +37968,6 @@ }, "domexception": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, "requires": { "webidl-conversions": "^5.0.0" @@ -12531,16 +37975,12 @@ "dependencies": { "webidl-conversions": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", "dev": true } } }, "escodegen": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "requires": { "esprima": "^4.0.1", @@ -12552,14 +37992,10 @@ }, "estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "form-data": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -12569,8 +38005,6 @@ }, "html-encoding-sniffer": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, "requires": { "whatwg-encoding": "^1.0.5" @@ -12578,8 +38012,6 @@ }, "jsdom": { "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { "abab": "^2.0.5", @@ -12613,8 +38045,6 @@ }, "levn": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -12623,8 +38053,6 @@ }, "optionator": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", @@ -12637,26 +38065,18 @@ }, "parse5": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, "prelude-ls": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "punycode": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "saxes": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, "requires": { "xmlchars": "^2.2.0" @@ -12664,15 +38084,11 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true }, "tough-cookie": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, "requires": { "psl": "^1.1.33", @@ -12682,8 +38098,6 @@ }, "tr46": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "requires": { "punycode": "^2.1.1" @@ -12691,8 +38105,6 @@ }, "type-check": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" @@ -12700,14 +38112,10 @@ }, "universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, "w3c-xmlserializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", "dev": true, "requires": { "xml-name-validator": "^3.0.0" @@ -12715,14 +38123,10 @@ }, "webidl-conversions": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "dev": true }, "whatwg-url": { "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { "lodash": "^4.7.0", @@ -12732,16 +38136,13 @@ }, "ws": { "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true + "dev": true, + "requires": {} } } }, "jest-environment-node": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", - "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", "dev": true, "requires": { "@jest/environment": "^27.3.1", @@ -12754,14 +38155,10 @@ }, "jest-get-type": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", - "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", "dev": true }, "jest-haste-map": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", - "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -12781,14 +38178,10 @@ "dependencies": { "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "jest-worker": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", "dev": true, "requires": { "@types/node": "*", @@ -12798,8 +38191,6 @@ }, "supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -12809,8 +38200,6 @@ }, "jest-jasmine2": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", - "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", @@ -12835,8 +38224,6 @@ }, "jest-leak-detector": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", - "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", "dev": true, "requires": { "jest-get-type": "^27.3.1", @@ -12845,8 +38232,6 @@ }, "jest-matcher-utils": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", - "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -12857,8 +38242,6 @@ }, "jest-message-util": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", - "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", @@ -12874,14 +38257,10 @@ "dependencies": { "escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, "stack-utils": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12891,8 +38270,6 @@ }, "jest-mock": { "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -12901,26 +38278,19 @@ }, "jest-pnp-resolver": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-raw-loader": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jest-raw-loader/-/jest-raw-loader-1.0.1.tgz", - "integrity": "sha1-zp9W1UZQ8VfEp9FtIkul1hO81iY=", "dev": true }, "jest-regex-util": { "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true }, "jest-resolve": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", - "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -12937,8 +38307,6 @@ }, "jest-resolve-dependencies": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", - "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -12948,8 +38316,6 @@ }, "jest-runner": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", - "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", "dev": true, "requires": { "@jest/console": "^27.3.1", @@ -12978,14 +38344,10 @@ "dependencies": { "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "jest-worker": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", "dev": true, "requires": { "@types/node": "*", @@ -12995,8 +38357,6 @@ }, "supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -13006,8 +38366,6 @@ }, "jest-runtime": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", - "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", "dev": true, "requires": { "@jest/console": "^27.3.1", @@ -13040,14 +38398,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -13055,8 +38409,6 @@ }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -13066,8 +38418,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -13075,14 +38425,10 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -13092,14 +38438,10 @@ }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -13115,26 +38457,18 @@ }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { "path-key": "^3.0.0" @@ -13142,14 +38476,10 @@ }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -13157,14 +38487,10 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -13174,8 +38500,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -13183,14 +38507,10 @@ }, "strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -13198,8 +38518,6 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -13209,14 +38527,10 @@ }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -13230,16 +38544,12 @@ }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "jest-serializer": { "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "requires": { "@types/node": "*", @@ -13248,8 +38558,6 @@ }, "jest-snapshot": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", - "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -13280,8 +38588,6 @@ }, "jest-util": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", - "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -13294,8 +38600,6 @@ }, "jest-validate": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", - "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -13308,16 +38612,12 @@ "dependencies": { "camelcase": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true } } }, "jest-watcher": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", - "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", "dev": true, "requires": { "@jest/test-result": "^27.3.1", @@ -13331,8 +38631,6 @@ }, "jest-worker": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { "@types/node": "*", @@ -13342,14 +38640,10 @@ "dependencies": { "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -13359,14 +38653,10 @@ }, "js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -13375,14 +38665,10 @@ }, "jsbn": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "jscodeshift": { "version": "0.13.0", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.13.0.tgz", - "integrity": "sha512-FNHLuwh7TeI0F4EzNVIRwUSxSqsGWM5nTv596FK4NfBnEEKFpIcyFeG559DMFGHSTIYA5AY4Fqh2cBrJx0EAwg==", "dev": true, "requires": { "@babel/core": "^7.13.16", @@ -13408,8 +38694,6 @@ "dependencies": { "braces": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -13426,8 +38710,6 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -13437,14 +38719,10 @@ }, "colors": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true }, "fill-range": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -13455,8 +38733,6 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -13466,14 +38742,10 @@ }, "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -13481,8 +38753,6 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -13492,8 +38762,6 @@ }, "micromatch": { "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -13513,8 +38781,6 @@ }, "rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -13522,8 +38788,6 @@ }, "temp": { "version": "0.8.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", - "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", "dev": true, "requires": { "rimraf": "~2.6.2" @@ -13531,8 +38795,6 @@ }, "to-regex-range": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -13541,8 +38803,6 @@ }, "write-file-atomic": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -13554,14 +38814,10 @@ }, "jsdoc-type-pratt-parser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.0.tgz", - "integrity": "sha512-sUuj2j48wxrEpbFjDp1sAesAxPiLT+z0SWVmMafyIINs6Lj5gIPKh3VrkBZu4E/Dv+wHpOot0m6H8zlHQjwqeQ==", "dev": true }, "jsdom": { "version": "13.2.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-13.2.0.tgz", - "integrity": "sha512-cG1NtMWO9hWpqRNRR3dSvEQa8bFI6iLlqU2x4kwX51FQjp0qus8T9aBaAO6iGp3DeBrhdwuKxckknohkmfvsFw==", "dev": true, "requires": { "abab": "^2.0.0", @@ -13594,70 +38850,48 @@ "dependencies": { "acorn": { "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true } } }, "jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "json-buffer": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, "json-parse-better-errors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, "json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "json-stringify-pretty-compact": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", - "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==", "dev": true }, "json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "json5": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -13665,8 +38899,6 @@ }, "jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", @@ -13675,8 +38907,6 @@ }, "jsonlint-lines": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/jsonlint-lines/-/jsonlint-lines-1.7.1.tgz", - "integrity": "sha1-UH3mgNP7jEvhZBzFfW9nnynxeP8=", "dev": true, "requires": { "JSV": ">= 4.0.x", @@ -13685,14 +38915,18 @@ }, "jsonparse": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "JSONStream": { + "version": "1.3.5", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "jsonwebtoken": { "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", "dev": true, "requires": { "jws": "^3.2.2", @@ -13709,16 +38943,12 @@ "dependencies": { "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "jsprim": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { "assert-plus": "1.0.0", @@ -13727,10 +38957,12 @@ "verror": "1.10.0" } }, + "JSV": { + "version": "4.0.2", + "dev": true + }, "jsx-ast-utils": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", "dev": true, "requires": { "array-includes": "^3.1.2", @@ -13739,8 +38971,6 @@ }, "jszip": { "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", - "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", "dev": true, "requires": { "lie": "~3.3.0", @@ -13751,14 +38981,10 @@ }, "just-extend": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "jwa": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "dev": true, "requires": { "buffer-equal-constant-time": "1.0.1", @@ -13768,8 +38994,6 @@ }, "jws": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "dev": true, "requires": { "jwa": "^1.4.1", @@ -13777,14 +39001,10 @@ } }, "kdbush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz", - "integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==" + "version": "3.0.0" }, "keyv": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "dev": true, "requires": { "json-buffer": "3.0.0" @@ -13792,26 +39012,18 @@ }, "kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "kleur": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, "known-css-properties": { "version": "0.21.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz", - "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==", "dev": true }, "labeled-stream-splicer": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -13820,8 +39032,6 @@ }, "latest-version": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "dev": true, "requires": { "package-json": "^6.3.0" @@ -13829,8 +39039,6 @@ }, "lazystream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { "readable-stream": "^2.0.5" @@ -13838,8 +39046,6 @@ }, "lcid": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { "invert-kv": "^2.0.0" @@ -13847,14 +39053,10 @@ }, "lcov-parse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", "dev": true }, "lead": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", "dev": true, "requires": { "flush-write-stream": "^1.0.2" @@ -13862,14 +39064,10 @@ }, "leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, "levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { "prelude-ls": "^1.2.1", @@ -13878,8 +39076,6 @@ }, "lie": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, "requires": { "immediate": "~3.0.5" @@ -13887,20 +39083,14 @@ }, "lilconfig": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.3.tgz", - "integrity": "sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg==", "dev": true }, "lines-and-columns": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, "list-npm-contents": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/list-npm-contents/-/list-npm-contents-1.0.2.tgz", - "integrity": "sha512-cpAkA9+ioEqHnxTuh3UDRewX+obC3mTr9dlYRVnTt0riggK+0IdKIed7BPn1BgkBQP+TVHiso4Rj0ZxGaXzh1Q==", "dev": true, "requires": { "bluebird": "^3.5.0", @@ -13915,14 +39105,10 @@ }, "livereload-js": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", - "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", "dev": true }, "load-json-file": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -13933,16 +39119,12 @@ "dependencies": { "pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", @@ -13951,14 +39133,10 @@ }, "lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash._baseflatten": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz", - "integrity": "sha1-B3D/gBMa9uNPO1EXlqe6UhTmX/c=", "dev": true, "requires": { "lodash.isarguments": "^3.0.0", @@ -13967,62 +39145,42 @@ }, "lodash._getnative": { "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", "dev": true }, "lodash._isiterateecall": { "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, "lodash._reinterpolate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, "lodash.assignin": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", - "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", "dev": true }, "lodash.castarray": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=", "dev": true }, "lodash.clonedeep": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, "lodash.debounce": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, "lodash.difference": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", "dev": true }, "lodash.find": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", - "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=", "dev": true }, "lodash.flatten": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-3.0.2.tgz", - "integrity": "sha1-3hz1d1j49EeTGdNcPpzGDEUBk4w=", "dev": true, "requires": { "lodash._baseflatten": "^3.0.0", @@ -14031,104 +39189,70 @@ }, "lodash.flattendeep": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lodash.forown": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", - "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=", "dev": true }, "lodash.get": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, "lodash.groupby": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", - "integrity": "sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=", "dev": true }, "lodash.includes": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=", "dev": true }, "lodash.isarguments": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", "dev": true }, "lodash.isarray": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", "dev": true }, "lodash.isboolean": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=", "dev": true }, "lodash.isinteger": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=", "dev": true }, "lodash.isnumber": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=", "dev": true }, "lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, "lodash.isstring": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", "dev": true }, "lodash.memoize": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, "lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.once": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", "dev": true }, "lodash.sortby": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, "lodash.template": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0", @@ -14137,8 +39261,6 @@ }, "lodash.templatesettings": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0" @@ -14146,32 +39268,22 @@ }, "lodash.truncate": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, "lodash.uniq": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, "lodash.uniqby": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=", "dev": true }, "log-driver": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, "log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -14180,14 +39292,10 @@ }, "longest-streak": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", "dev": true }, "loose-envify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -14195,8 +39303,6 @@ }, "loud-rejection": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { "currently-unhandled": "^0.4.1", @@ -14205,14 +39311,10 @@ }, "lowercase-keys": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, "lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -14220,8 +39322,6 @@ }, "ls-archive": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ls-archive/-/ls-archive-1.3.4.tgz", - "integrity": "sha512-7GmjZOckV+gzm4PM1/LcWIsZIRsSkAVmIchoEf5xjquNKU0Ti5KUvGQ3dl/7VsbZIduMOPwRDXrvpo3LVJ0Pmg==", "dev": true, "requires": { "async": "~0.2.9", @@ -14234,20 +39334,14 @@ "dependencies": { "async": { "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true }, "rimraf": { "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", "dev": true }, "tar": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", @@ -14259,8 +39353,6 @@ }, "magic-string": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, "requires": { "sourcemap-codec": "^1.4.4" @@ -14268,8 +39360,6 @@ }, "make-dir": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { "semver": "^6.0.0" @@ -14277,22 +39367,16 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "makeerror": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { "tmpl": "1.0.5" @@ -14300,8 +39384,6 @@ }, "map-age-cleaner": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { "p-defer": "^1.0.0" @@ -14309,20 +39391,14 @@ }, "map-cache": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, "map-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { "object-visit": "^1.0.0" @@ -14330,8 +39406,6 @@ }, "mapbox-gl-styles": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mapbox-gl-styles/-/mapbox-gl-styles-2.0.2.tgz", - "integrity": "sha1-u1Jbd+oNwrBBu4BRZFF283g+KUo=", "dev": true, "requires": { "glob": "^5.0.14" @@ -14339,8 +39413,6 @@ "dependencies": { "glob": { "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { "inflight": "^1.0.4", @@ -14354,26 +39426,18 @@ }, "markdown-escapes": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", "dev": true }, "markdown-table": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", "dev": true }, "mathml-tag-names": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true }, "md5.js": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "requires": { "hash-base": "^3.0.0", @@ -14383,8 +39447,6 @@ }, "mdast-util-compact": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", "dev": true, "requires": { "unist-util-visit": "^1.1.0" @@ -14392,8 +39454,6 @@ }, "mdast-util-definitions": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz", - "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==", "dev": true, "requires": { "unist-util-visit": "^1.0.0" @@ -14401,8 +39461,6 @@ }, "mdast-util-from-markdown": { "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -14414,14 +39472,10 @@ "dependencies": { "mdast-util-to-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", "dev": true }, "parse-entities": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { "character-entities": "^1.0.0", @@ -14436,8 +39490,6 @@ }, "mdast-util-inject": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz", - "integrity": "sha1-2wa4tYW+lZotzS+H9HK6m3VvNnU=", "dev": true, "requires": { "mdast-util-to-string": "^1.0.0" @@ -14445,8 +39497,6 @@ }, "mdast-util-to-hast": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-3.0.4.tgz", - "integrity": "sha512-/eIbly2YmyVgpJNo+bFLLMCI1XgolO/Ffowhf+pHDq3X4/V6FntC9sGQCDLM147eTS+uSXv5dRzJyFn+o0tazA==", "dev": true, "requires": { "collapse-white-space": "^1.0.0", @@ -14464,8 +39514,6 @@ }, "mdast-util-to-markdown": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", - "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -14478,14 +39526,10 @@ "dependencies": { "mdast-util-to-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", "dev": true }, "parse-entities": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { "character-entities": "^1.0.0", @@ -14500,14 +39544,10 @@ }, "mdast-util-to-string": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", "dev": true }, "mdast-util-toc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz", - "integrity": "sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==", "dev": true, "requires": { "github-slugger": "^1.2.1", @@ -14518,40 +39558,28 @@ "dependencies": { "github-slugger": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz", - "integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==", "dev": true }, "unist-util-is": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", - "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", "dev": true } } }, "mdn-data": { "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, "mdurl": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, "mem": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", @@ -14561,14 +39589,10 @@ }, "memorystream": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "dev": true }, "meow": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { "camelcase-keys": "^2.0.0", @@ -14585,8 +39609,6 @@ "dependencies": { "find-up": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -14595,8 +39617,6 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -14608,8 +39628,6 @@ }, "parse-json": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -14617,8 +39635,6 @@ }, "path-exists": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -14626,8 +39642,6 @@ }, "path-type": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -14637,14 +39651,10 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "read-pkg": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -14654,8 +39664,6 @@ }, "read-pkg-up": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", @@ -14664,8 +39672,6 @@ }, "strip-bom": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -14675,32 +39681,22 @@ }, "merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, "merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, "merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true }, "micromark": { "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", "dev": true, "requires": { "debug": "^4.0.0", @@ -14709,8 +39705,6 @@ "dependencies": { "parse-entities": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { "character-entities": "^1.0.0", @@ -14725,8 +39719,6 @@ }, "micromatch": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", @@ -14735,8 +39727,6 @@ }, "miller-rabin": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -14745,28 +39735,20 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "mime": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "dev": true }, "mime-db": { "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true }, "mime-types": { "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "requires": { "mime-db": "1.49.0" @@ -14774,52 +39756,36 @@ }, "mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "mimic-response": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", "dev": true }, "min-indent": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, "minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, "minimalistic-crypto-utils": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", "dev": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.5" }, "minimist-options": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -14829,8 +39795,6 @@ }, "minipass": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -14838,8 +39802,6 @@ }, "minizlib": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "requires": { "minipass": "^3.0.0", @@ -14848,8 +39810,6 @@ }, "mixin-deep": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -14858,8 +39818,6 @@ "dependencies": { "is-extendable": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -14867,8 +39825,6 @@ }, "is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -14878,29 +39834,20 @@ }, "mkdirp": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, "mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, "mock-geolocation": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/mock-geolocation/-/mock-geolocation-1.0.11.tgz", - "integrity": "sha1-LHuZJCoscNvs0xezkrMDEXIpksg=", "dev": true }, "module-deps": { "version": "6.2.3", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", - "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", "dev": true, "requires": { - "JSONStream": "^1.0.3", "browser-resolve": "^2.0.0", "cached-path-relative": "^1.0.2", "concat-stream": "~1.6.0", @@ -14908,6 +39855,7 @@ "detective": "^5.2.0", "duplexer2": "^0.1.2", "inherits": "^2.0.1", + "JSONStream": "^1.0.3", "parents": "^1.0.0", "readable-stream": "^2.0.2", "resolve": "^1.4.0", @@ -14919,8 +39867,6 @@ }, "moo-color": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.2.tgz", - "integrity": "sha512-5iXz5n9LWQzx/C2WesGFfpE6RLamzdHwsn3KpfzShwbfIqs7stnoEpaNErf/7+3mbxwZ4s8Foq7I0tPxw7BWHg==", "dev": true, "requires": { "color-name": "^1.1.4" @@ -14928,22 +39874,16 @@ "dependencies": { "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true } } }, "ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "multi-stage-sourcemap": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/multi-stage-sourcemap/-/multi-stage-sourcemap-0.3.1.tgz", - "integrity": "sha512-UiTLYjqeIoVnJHyWGskwMKIhtZKK9uXUjSTWuwatarrc0d2H/6MAVFdwvEA/aKOHamIn7z4tfvxjz+FYucFpNQ==", "dev": true, "requires": { "source-map": "^0.1.34" @@ -14951,8 +39891,6 @@ "dependencies": { "source-map": { "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { "amdefine": ">=0.0.4" @@ -14962,8 +39900,6 @@ }, "multimatch": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", "dev": true, "requires": { "array-differ": "^1.0.0", @@ -14974,8 +39910,6 @@ "dependencies": { "array-union": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { "array-uniq": "^1.0.1" @@ -14984,38 +39918,26 @@ } }, "murmurhash-js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", - "integrity": "sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E=" + "version": "1.0.0" }, "mustache": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz", - "integrity": "sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==", "dev": true }, "mute-stream": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, "nan": { "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", "dev": true }, "nanoid": { "version": "3.1.30", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", - "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", "dev": true }, "nanomatch": { "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -15033,38 +39955,26 @@ }, "napi-build-utils": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", "dev": true }, "natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "negotiator": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, "neo-async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "nice-try": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, "nise": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", @@ -15076,8 +39986,6 @@ }, "node-abi": { "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", "dev": true, "requires": { "semver": "^5.4.1" @@ -15085,16 +39993,12 @@ "dependencies": { "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "node-dir": { "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", "dev": true, "requires": { "minimatch": "^3.0.2" @@ -15102,14 +40006,10 @@ }, "node-fetch": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==", "dev": true }, "node-gyp": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", - "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "dev": true, "requires": { "env-paths": "^2.2.0", @@ -15126,8 +40026,6 @@ "dependencies": { "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -15137,20 +40035,14 @@ }, "node-int64": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, "node-modules-regexp": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true }, "node-nailgun-client": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/node-nailgun-client/-/node-nailgun-client-0.1.2.tgz", - "integrity": "sha512-OC611lR0fsDUSptwnhBf8d3sj4DZ5fiRKfS2QaGPe0kR3Dt9YoZr1MY7utK0scFPTbXuQdSBBbeoKYVbME1q5g==", "dev": true, "requires": { "commander": "^2.8.1" @@ -15158,16 +40050,12 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true } } }, "node-nailgun-server": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-nailgun-server/-/node-nailgun-server-0.1.4.tgz", - "integrity": "sha512-e0Hbh6XPb/7GqATJ45BePaUEO5AwR7InRW/pGeMKHH1cqPMBFCeqdBNfvi+bkVLnsbYOOQE+pAek9nmNoD8sYw==", "dev": true, "requires": { "commander": "^2.8.1" @@ -15175,16 +40063,12 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true } } }, "node-notifier": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.0.tgz", - "integrity": "sha512-ZTqP90y1eyb2xAZTa7j4AlAayTwh6cL8mn0nlJhLDq8itXGnJUmQGYOnpaMUvqZVfGo0vhU7KZ3HtDW6CT2SiQ==", "dev": true, "requires": { "growly": "^1.3.0", @@ -15197,14 +40081,10 @@ "dependencies": { "uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -15214,8 +40094,6 @@ }, "node-plantuml": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-plantuml/-/node-plantuml-0.9.0.tgz", - "integrity": "sha512-bUnntTGjbpYu1pvXZI/GS6ctcXf3AOMqJxBMO8vFzTT5RwH8Cj/J5Ca6Dy+PEfMiMDdSBCFKSGnvYyBvYnucXg==", "dev": true, "requires": { "commander": "^2.8.1", @@ -15226,16 +40104,12 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true } } }, "node-preload": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", "dev": true, "requires": { "process-on-spawn": "^1.0.0" @@ -15243,14 +40117,10 @@ }, "node-releases": { "version": "1.1.75", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", - "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", "dev": true }, "nomnom": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", "dev": true, "requires": { "chalk": "~0.4.0", @@ -15259,14 +40129,10 @@ "dependencies": { "ansi-styles": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", "dev": true }, "chalk": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", "dev": true, "requires": { "ansi-styles": "~1.0.0", @@ -15278,14 +40144,10 @@ }, "noop-logger": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", "dev": true }, "nopt": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, "requires": { "abbrev": "1" @@ -15293,8 +40155,6 @@ }, "normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -15305,46 +40165,32 @@ "dependencies": { "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "normalize-range": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, "normalize-registry-url": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/normalize-registry-url/-/normalize-registry-url-1.0.0.tgz", - "integrity": "sha512-0v6T4851b72ykk5zEtFoN4QX/Fqyk7pouIj9xZyAvAe9jlDhAwT4z6FlwsoQCHjeuK2EGUoAwy/F4y4B1uZq9A==", "dev": true }, "normalize-selector": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", - "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", "dev": true }, "normalize-url": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true }, "now-and-later": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", "dev": true, "requires": { "once": "^1.3.2" @@ -15352,8 +40198,6 @@ }, "npm-bundled": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", - "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", "dev": true, "requires": { "npm-normalize-package-bin": "^1.0.1" @@ -15361,20 +40205,14 @@ }, "npm-font-open-sans": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/npm-font-open-sans/-/npm-font-open-sans-1.1.0.tgz", - "integrity": "sha512-t1y5ShWm6a8FSLwBdINT47XYMcuKY2rkTBsTdz/76YB2MtX0YD89RUkY2eSS2/XOmlZfBe1HFBAwD+b9+/UfmQ==", "dev": true }, "npm-normalize-package-bin": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", "dev": true }, "npm-packlist": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-3.0.0.tgz", - "integrity": "sha512-L/cbzmutAwII5glUcf2DBRNY/d0TFd4e/FnaZigJV6JD85RHZXJFGwCndjMWiiViiWSsWt3tiOLpI3ByTnIdFQ==", "dev": true, "requires": { "glob": "^7.1.6", @@ -15385,8 +40223,6 @@ }, "npm-run-all": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -15402,8 +40238,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -15415,8 +40249,6 @@ }, "npm-run-path": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" @@ -15424,8 +40256,6 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "requires": { "are-we-there-yet": "~1.1.2", @@ -15436,8 +40266,6 @@ }, "nth-check": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", - "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", "dev": true, "requires": { "boolbase": "^1.0.0" @@ -15445,26 +40273,18 @@ }, "num2fraction": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", "dev": true }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "nwsapi": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, "nyc": { "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, "requires": { "@istanbuljs/load-nyc-config": "^1.0.0", @@ -15498,14 +40318,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -15513,8 +40329,6 @@ }, "cliui": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -15524,8 +40338,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -15533,20 +40345,14 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -15555,20 +40361,14 @@ }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -15576,8 +40376,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -15585,26 +40383,18 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -15614,8 +40404,6 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" @@ -15623,8 +40411,6 @@ }, "wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -15634,8 +40420,6 @@ }, "yargs": { "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -15653,8 +40437,6 @@ }, "yargs-parser": { "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -15665,20 +40447,14 @@ }, "oauth-sign": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-copy": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { "copy-descriptor": "^0.1.0", @@ -15688,8 +40464,6 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -15697,14 +40471,10 @@ }, "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -15714,14 +40484,10 @@ }, "object-inspect": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true }, "object-is": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -15730,14 +40496,10 @@ }, "object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, "object-visit": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { "isobject": "^3.0.0" @@ -15745,8 +40507,6 @@ }, "object.assign": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { "call-bind": "^1.0.0", @@ -15757,8 +40517,6 @@ }, "object.entries": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -15768,8 +40526,6 @@ }, "object.fromentries": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -15780,8 +40536,6 @@ }, "object.pick": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -15789,8 +40543,6 @@ }, "object.values": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -15800,8 +40552,6 @@ }, "on-finished": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "requires": { "ee-first": "1.1.1" @@ -15809,14 +40559,10 @@ }, "on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" @@ -15824,8 +40570,6 @@ }, "onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -15833,8 +40577,6 @@ }, "open": { "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dev": true, "requires": { "is-docker": "^2.0.0", @@ -15843,14 +40585,10 @@ }, "opener": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, "optimist": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.5.2.tgz", - "integrity": "sha1-hcjBRUszFeSniUfoV7HfAzRQv7w=", "dev": true, "requires": { "wordwrap": "~0.0.2" @@ -15858,8 +40596,6 @@ }, "optionator": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -15872,8 +40608,6 @@ }, "ordered-read-streams": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", "dev": true, "requires": { "readable-stream": "^2.0.1" @@ -15881,20 +40615,14 @@ }, "os-browserify": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { "execa": "^1.0.0", @@ -15904,20 +40632,14 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "own-or": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", "dev": true }, "own-or-env": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz", - "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==", "dev": true, "requires": { "own-or": "^1.0.0" @@ -15925,32 +40647,22 @@ }, "p-cancelable": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, "p-defer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, "p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, "p-is-promise": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -15958,8 +40670,6 @@ }, "p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" @@ -15967,8 +40677,6 @@ }, "p-map": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "requires": { "aggregate-error": "^3.0.0" @@ -15976,14 +40684,10 @@ }, "p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "package-hash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -15994,8 +40698,6 @@ }, "package-json": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dev": true, "requires": { "got": "^9.6.0", @@ -16006,8 +40708,6 @@ "dependencies": { "decompress-response": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "dev": true, "requires": { "mimic-response": "^1.0.0" @@ -16015,8 +40715,6 @@ }, "get-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -16024,8 +40722,6 @@ }, "got": { "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "dev": true, "requires": { "@sindresorhus/is": "^0.14.0", @@ -16043,20 +40739,14 @@ }, "mimic-response": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, "prepend-http": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -16065,8 +40755,6 @@ }, "registry-url": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "dev": true, "requires": { "rc": "^1.2.8" @@ -16074,14 +40762,10 @@ }, "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "url-parse-lax": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", "dev": true, "requires": { "prepend-http": "^2.0.0" @@ -16091,14 +40775,10 @@ }, "pako": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, "parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" @@ -16106,8 +40786,6 @@ }, "parents": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "dev": true, "requires": { "path-platform": "~0.11.15" @@ -16115,8 +40793,6 @@ }, "parse-asn1": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { "asn1.js": "^5.2.0", @@ -16128,8 +40804,6 @@ }, "parse-entities": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", "dev": true, "requires": { "character-entities": "^1.0.0", @@ -16142,8 +40816,6 @@ }, "parse-filepath": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { "is-absolute": "^1.0.0", @@ -16153,8 +40825,6 @@ }, "parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", @@ -16163,8 +40833,6 @@ }, "parse-path": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", - "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -16175,8 +40843,6 @@ }, "parse-url": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-6.0.0.tgz", - "integrity": "sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw==", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -16187,68 +40853,46 @@ }, "parse5": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", "dev": true }, "parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, "pascalcase": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, "path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "dev": true }, "path-dirname": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, "path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-platform": { "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, "path-root": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { "path-root-regex": "^0.1.0" @@ -16256,14 +40900,10 @@ }, "path-root-regex": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, "path-to-regexp": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" @@ -16271,22 +40911,16 @@ "dependencies": { "isarray": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true } } }, "path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "pbf": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", "requires": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" @@ -16294,8 +40928,6 @@ }, "pbkdf2": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -16307,50 +40939,34 @@ }, "pend": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, "performance-now": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, "picomatch": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pidtree": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true }, "pify": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "pinkie": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -16358,8 +40974,6 @@ }, "pirates": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, "requires": { "node-modules-regexp": "^1.0.0" @@ -16367,8 +40981,6 @@ }, "pixelmatch": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", - "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", "dev": true, "requires": { "pngjs": "^4.0.1" @@ -16376,16 +40988,12 @@ "dependencies": { "pngjs": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", - "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==", "dev": true } } }, "pkg-dir": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { "find-up": "^2.1.0" @@ -16393,8 +41001,6 @@ "dependencies": { "find-up": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -16402,8 +41008,6 @@ }, "locate-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -16412,8 +41016,6 @@ }, "p-limit": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { "p-try": "^1.0.0" @@ -16421,8 +41023,6 @@ }, "p-locate": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -16430,16 +41030,12 @@ }, "p-try": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true } } }, "pkg-up": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, "requires": { "find-up": "^2.1.0" @@ -16447,8 +41043,6 @@ "dependencies": { "find-up": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -16456,8 +41050,6 @@ }, "locate-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -16466,8 +41058,6 @@ }, "p-limit": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { "p-try": "^1.0.0" @@ -16475,8 +41065,6 @@ }, "p-locate": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -16484,46 +41072,32 @@ }, "p-try": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true } } }, "plantuml-encoder": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.4.0.tgz", - "integrity": "sha512-sxMwpDw/ySY1WB2CE3+IdMuEcWibJ72DDOsXLkSmEaSzwEUaYBT6DWgOfBiHGCux4q433X6+OEFWjlVqp7gL6g==", "dev": true }, "platform": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", - "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", "dev": true }, "pn": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, "pngjs": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", "dev": true }, "posix-character-classes": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, "postcss": { "version": "8.4.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.1.tgz", - "integrity": "sha512-WqLs/TTzXdG+/A4ZOOK9WDZiikrRaiA+eoEb/jz2DT9KUhMNHgP7yKPO8vwi62ZCsb703Gwb7BMZwDzI54Y2Ag==", "dev": true, "requires": { "nanoid": "^3.1.30", @@ -16533,8 +41107,6 @@ }, "postcss-calc": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", - "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", "dev": true, "requires": { "postcss-selector-parser": "^6.0.2", @@ -16543,8 +41115,6 @@ }, "postcss-cli": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.0.2.tgz", - "integrity": "sha512-08Wujoy7YGhKCFrGsT9OXqWjtHlGQ+JmyaD/4McjCiwor2IUTRVzXiJd+xmLTGdSWjceS6/TePaJQwBlkVWHiw==", "dev": true, "requires": { "chokidar": "^3.3.0", @@ -16563,14 +41133,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -16578,14 +41144,10 @@ }, "array-union": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", - "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", "dev": true }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -16595,8 +41157,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -16604,32 +41164,22 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-stdin": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true }, "globby": { "version": "12.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-12.0.2.tgz", - "integrity": "sha512-lAsmb/5Lww4r7MM9nCCliDZVIKbZTavrsunAsHLr9oHthrZP1qi7/gAnHOsUs9bLvEt2vKVJhHmxuL7QbDuPdQ==", "dev": true, "requires": { "array-union": "^3.0.1", @@ -16642,20 +41192,14 @@ }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "slash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -16665,8 +41209,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -16674,8 +41216,6 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -16685,14 +41225,10 @@ }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -16706,16 +41242,12 @@ }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "postcss-colormin": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.0.tgz", - "integrity": "sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw==", "dev": true, "requires": { "browserslist": "^4.16.6", @@ -16726,8 +41258,6 @@ }, "postcss-convert-values": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz", - "integrity": "sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" @@ -16735,32 +41265,26 @@ }, "postcss-discard-comments": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", - "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-duplicates": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", - "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-empty": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", - "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-overridden": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", - "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", - "dev": true + "dev": true, + "requires": {} }, "postcss-html": { "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", - "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", "dev": true, "requires": { "htmlparser2": "^3.10.0" @@ -16768,8 +41292,6 @@ "dependencies": { "dom-serializer": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, "requires": { "domelementtype": "^2.0.1", @@ -16778,28 +41300,20 @@ "dependencies": { "domelementtype": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, "entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true } } }, "domelementtype": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, "domhandler": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", "dev": true, "requires": { "domelementtype": "1" @@ -16807,8 +41321,6 @@ }, "domutils": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "dev": true, "requires": { "dom-serializer": "0", @@ -16817,14 +41329,10 @@ }, "entities": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, "htmlparser2": { "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", "dev": true, "requires": { "domelementtype": "^1.3.1", @@ -16837,8 +41345,6 @@ }, "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -16850,8 +41356,6 @@ }, "postcss-inline-svg": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-inline-svg/-/postcss-inline-svg-5.0.0.tgz", - "integrity": "sha512-Agqkrn91Qgi+KAO+cTvUS1IAZbHPD4sryPoG0q5U0ThokL4UGoMcmwvNV6tDoRp69B5tgD1VNkn9P09E+xpQAg==", "dev": true, "requires": { "css-select": "^3.1.0", @@ -16862,8 +41366,6 @@ "dependencies": { "css-select": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", - "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", "dev": true, "requires": { "boolbase": "^1.0.0", @@ -16875,14 +41377,10 @@ }, "css-what": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", - "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", "dev": true }, "htmlparser2": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz", - "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==", "dev": true, "requires": { "domelementtype": "^2.0.1", @@ -16893,8 +41391,6 @@ "dependencies": { "domhandler": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", - "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", "dev": true, "requires": { "domelementtype": "^2.0.1" @@ -16906,8 +41402,6 @@ }, "postcss-less": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", - "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", "dev": true, "requires": { "postcss": "^7.0.14" @@ -16915,8 +41409,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -16926,8 +41418,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -16937,8 +41427,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -16948,14 +41436,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -16965,8 +41449,6 @@ }, "postcss-load-config": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.0.tgz", - "integrity": "sha512-ipM8Ds01ZUophjDTQYSVP70slFSYg3T0/zyfII5vzhN6V57YSxMgG5syXuwi5VtS8wSf3iL30v0uBdoIVx4Q0g==", "dev": true, "requires": { "import-cwd": "^3.0.0", @@ -16976,14 +41458,10 @@ }, "postcss-media-query-parser": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", "dev": true }, "postcss-merge-longhand": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz", - "integrity": "sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==", "dev": true, "requires": { "css-color-names": "^1.0.1", @@ -16993,8 +41471,6 @@ }, "postcss-merge-rules": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz", - "integrity": "sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg==", "dev": true, "requires": { "browserslist": "^4.16.6", @@ -17006,8 +41482,6 @@ }, "postcss-minify-font-values": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz", - "integrity": "sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" @@ -17015,8 +41489,6 @@ }, "postcss-minify-gradients": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.2.tgz", - "integrity": "sha512-7Do9JP+wqSD6Prittitt2zDLrfzP9pqKs2EcLX7HJYxsxCOwrrcLt4x/ctQTsiOw+/8HYotAoqNkrzItL19SdQ==", "dev": true, "requires": { "colord": "^2.6", @@ -17026,8 +41498,6 @@ }, "postcss-minify-params": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz", - "integrity": "sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw==", "dev": true, "requires": { "alphanum-sort": "^1.0.2", @@ -17039,8 +41509,6 @@ }, "postcss-minify-selectors": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz", - "integrity": "sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==", "dev": true, "requires": { "alphanum-sort": "^1.0.2", @@ -17049,14 +41517,11 @@ }, "postcss-normalize-charset": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", - "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", - "dev": true + "dev": true, + "requires": {} }, "postcss-normalize-display-values": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz", - "integrity": "sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==", "dev": true, "requires": { "cssnano-utils": "^2.0.1", @@ -17065,8 +41530,6 @@ }, "postcss-normalize-positions": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz", - "integrity": "sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" @@ -17074,8 +41537,6 @@ }, "postcss-normalize-repeat-style": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz", - "integrity": "sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==", "dev": true, "requires": { "cssnano-utils": "^2.0.1", @@ -17084,8 +41545,6 @@ }, "postcss-normalize-string": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz", - "integrity": "sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" @@ -17093,8 +41552,6 @@ }, "postcss-normalize-timing-functions": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz", - "integrity": "sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==", "dev": true, "requires": { "cssnano-utils": "^2.0.1", @@ -17103,8 +41560,6 @@ }, "postcss-normalize-unicode": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz", - "integrity": "sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==", "dev": true, "requires": { "browserslist": "^4.16.0", @@ -17113,8 +41568,6 @@ }, "postcss-normalize-url": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz", - "integrity": "sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ==", "dev": true, "requires": { "is-absolute-url": "^3.0.3", @@ -17124,8 +41577,6 @@ }, "postcss-normalize-whitespace": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz", - "integrity": "sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" @@ -17133,8 +41584,6 @@ }, "postcss-ordered-values": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz", - "integrity": "sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ==", "dev": true, "requires": { "cssnano-utils": "^2.0.1", @@ -17143,8 +41592,6 @@ }, "postcss-reduce-initial": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", - "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", "dev": true, "requires": { "browserslist": "^4.16.0", @@ -17153,8 +41600,6 @@ }, "postcss-reduce-transforms": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz", - "integrity": "sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==", "dev": true, "requires": { "cssnano-utils": "^2.0.1", @@ -17163,8 +41608,6 @@ }, "postcss-reporter": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.4.tgz", - "integrity": "sha512-jY/fnpGSin7kwJeunXbY35STp5O3VIxSFdjee5JkoPQ+FfGH5JW3N+Xe9oAPcL9UkjWjkK+JC72o8XH4XXKdhw==", "dev": true, "requires": { "lodash.difference": "^4.5.0", @@ -17177,14 +41620,10 @@ }, "postcss-resolve-nested-selector": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", "dev": true }, "postcss-safe-parser": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", - "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", "dev": true, "requires": { "postcss": "^7.0.26" @@ -17192,8 +41631,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -17203,8 +41640,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -17214,8 +41649,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17225,14 +41658,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -17242,8 +41671,6 @@ }, "postcss-sass": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz", - "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==", "dev": true, "requires": { "gonzales-pe": "^4.3.0", @@ -17252,8 +41679,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -17263,8 +41688,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -17274,8 +41697,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17285,14 +41706,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -17302,8 +41719,6 @@ }, "postcss-scss": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", - "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", "dev": true, "requires": { "postcss": "^7.0.6" @@ -17311,8 +41726,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -17322,8 +41735,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -17333,8 +41744,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -17344,14 +41753,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -17361,8 +41766,6 @@ }, "postcss-selector-parser": { "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -17371,8 +41774,6 @@ }, "postcss-svgo": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.2.tgz", - "integrity": "sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0", @@ -17381,14 +41782,11 @@ }, "postcss-syntax": { "version": "0.36.2", - "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", - "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", - "dev": true + "dev": true, + "requires": {} }, "postcss-unique-selectors": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz", - "integrity": "sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w==", "dev": true, "requires": { "alphanum-sort": "^1.0.2", @@ -17398,19 +41796,13 @@ }, "postcss-value-parser": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, "potpack": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.1.tgz", - "integrity": "sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw==" + "version": "1.0.1" }, "prebuild-install": { "version": "5.3.6", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", - "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", "dev": true, "requires": { "detect-libc": "^1.0.3", @@ -17432,8 +41824,6 @@ "dependencies": { "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -17444,26 +41834,18 @@ }, "prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prepend-http": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, "pretty-bytes": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, "pretty-format": { "version": "27.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", - "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", "dev": true, "requires": { "@jest/types": "^27.2.5", @@ -17474,52 +41856,36 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, "react-is": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true } } }, "pretty-hrtime": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, "printf": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/printf/-/printf-0.6.1.tgz", - "integrity": "sha512-is0ctgGdPJ5951KulgfzvHGwJtZ5ck8l042vRkV6jrkpBzTmb/lueTqguWHy2JfVA+RY6gFVlaZgUS0j7S/dsw==", "dev": true }, "process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, "process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "process-on-spawn": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", "dev": true, "requires": { "fromentries": "^1.2.0" @@ -17527,14 +41893,10 @@ }, "progress": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "requires": { "kleur": "^3.0.3", @@ -17543,8 +41905,6 @@ }, "prop-types": { "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "dev": true, "requires": { "loose-envify": "^1.4.0", @@ -17554,28 +41914,20 @@ }, "property-information": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-4.2.0.tgz", - "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", "dev": true, "requires": { "xtend": "^4.0.1" } }, "protocol-buffers-schema": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz", - "integrity": "sha512-YVCvdhxWNDP8/nJDyXLuM+UFsuPk4+1PB7WGPVDzm3HTHbzFLxQYeW2iZpS4mmnXrQJGBzt230t/BbEb7PrQaw==" + "version": "3.5.1" }, "protocols": { "version": "1.4.8", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", - "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==", "dev": true }, "proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "requires": { "forwarded": "0.2.0", @@ -17584,26 +41936,18 @@ }, "proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, "pseudomap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "psl": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "public-encrypt": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -17616,16 +41960,12 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "pump": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -17634,8 +41974,6 @@ }, "pumpify": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, "requires": { "duplexify": "^3.6.0", @@ -17645,14 +41983,10 @@ }, "punycode": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, "pupa": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dev": true, "requires": { "escape-goat": "^2.0.0" @@ -17660,8 +41994,6 @@ }, "puppeteer": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-11.0.0.tgz", - "integrity": "sha512-6rPFqN1ABjn4shgOICGDBITTRV09EjXVqhDERBDKwCLz0UyBxeeBH6Ay0vQUJ84VACmlxwzOIzVEJXThcF3aNg==", "dev": true, "requires": { "debug": "4.3.2", @@ -17680,8 +42012,6 @@ "dependencies": { "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -17690,8 +42020,6 @@ }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -17699,8 +42027,6 @@ }, "node-fetch": { "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", "dev": true, "requires": { "whatwg-url": "^5.0.0" @@ -17708,8 +42034,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -17717,14 +42041,10 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { "find-up": "^4.0.0" @@ -17732,20 +42052,14 @@ }, "tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", "dev": true }, "webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", "dev": true }, "whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "dev": true, "requires": { "tr46": "~0.0.3", @@ -17754,22 +42068,17 @@ }, "ws": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true + "dev": true, + "requires": {} } } }, "qrcode-terminal": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", - "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", "dev": true }, "qs": { "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -17777,8 +42086,6 @@ }, "query-string": { "version": "6.14.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", - "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", "dev": true, "requires": { "decode-uri-component": "^0.2.0", @@ -17789,37 +42096,25 @@ }, "querystring": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "dev": true }, "querystring-es3": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, "queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "quick-lru": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + "version": "2.0.0" }, "randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -17827,8 +42122,6 @@ }, "randomfill": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { "randombytes": "^2.0.5", @@ -17837,14 +42130,10 @@ }, "range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, "raw-body": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { "bytes": "1", @@ -17853,16 +42142,12 @@ "dependencies": { "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { "deep-extend": "^0.6.0", @@ -17873,8 +42158,6 @@ }, "react": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -17883,8 +42166,6 @@ }, "react-dom": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -17894,14 +42175,10 @@ }, "react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "read-cache": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", "dev": true, "requires": { "pify": "^2.3.0" @@ -17909,16 +42186,12 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, "read-only-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { "readable-stream": "^2.0.2" @@ -17926,8 +42199,6 @@ }, "read-pkg": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", @@ -17937,8 +42208,6 @@ "dependencies": { "path-type": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" @@ -17946,16 +42215,12 @@ }, "pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "read-pkg-up": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "requires": { "find-up": "^3.0.0", @@ -17964,8 +42229,6 @@ }, "readable-stream": { "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -17979,8 +42242,6 @@ }, "readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -17988,8 +42249,6 @@ }, "recast": { "version": "0.20.5", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", - "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", "dev": true, "requires": { "ast-types": "0.14.2", @@ -18000,22 +42259,16 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "tslib": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true } } }, "redent": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { "indent-string": "^2.1.0", @@ -18024,14 +42277,10 @@ }, "regenerate": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, "regenerate-unicode-properties": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", "dev": true, "requires": { "regenerate": "^1.4.0" @@ -18039,14 +42288,10 @@ }, "regenerator-runtime": { "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, "regenerator-transform": { "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", "dev": true, "requires": { "@babel/runtime": "^7.8.4" @@ -18054,8 +42299,6 @@ }, "regex-not": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { "extend-shallow": "^3.0.2", @@ -18064,8 +42307,6 @@ }, "regexp.prototype.flags": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -18074,14 +42315,10 @@ }, "regexpp": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "regexpu-core": { "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", "dev": true, "requires": { "regenerate": "^1.4.0", @@ -18094,14 +42331,10 @@ }, "regextras": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", "dev": true }, "registry-auth-token": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { "rc": "^1.2.8" @@ -18109,8 +42342,6 @@ }, "registry-url": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-4.0.0.tgz", - "integrity": "sha512-WAfGLywivb8s2+Cfblq1UV+kOyzURHzWSJmciDvrmstr4bv/0lnVSB9jfoOfkxx5xNJ1OGlSFmZh9WYBLFJOPg==", "dev": true, "requires": { "rc": "^1.2.7" @@ -18118,14 +42349,10 @@ }, "regjsgen": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", "dev": true }, "regjsparser": { "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -18133,16 +42360,12 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } } }, "release-zalgo": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { "es6-error": "^4.0.1" @@ -18150,8 +42373,6 @@ }, "remark": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-9.0.0.tgz", - "integrity": "sha512-amw8rGdD5lHbMEakiEsllmkdBP+/KpjW/PRK6NSGPZKCQowh0BT4IWXDAkRMyG3SB9dKPXWMviFjNusXzXNn3A==", "dev": true, "requires": { "remark-parse": "^5.0.0", @@ -18161,8 +42382,6 @@ }, "remark-html": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-8.0.0.tgz", - "integrity": "sha512-3V2391GL3hxKhrkzYOyfPpxJ6taIKLCfuLVqumeWQOk3H9nTtSQ8St8kMYkBVIEAquXN1chT83qJ/2lAW+dpEg==", "dev": true, "requires": { "hast-util-sanitize": "^1.0.0", @@ -18173,8 +42392,6 @@ }, "remark-parse": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", - "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", "dev": true, "requires": { "collapse-white-space": "^1.0.2", @@ -18196,8 +42413,6 @@ }, "remark-reference-links": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/remark-reference-links/-/remark-reference-links-4.0.4.tgz", - "integrity": "sha512-+2X8hwSQqxG4tvjYZNrTcEC+bXp8shQvwRGG6J/rnFTvBoU4G0BBviZoqKGZizLh/DG+0gSYhiDDWCqyxXW1iQ==", "dev": true, "requires": { "unist-util-visit": "^1.0.0" @@ -18205,8 +42420,6 @@ }, "remark-slug": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz", - "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==", "dev": true, "requires": { "github-slugger": "^1.0.0", @@ -18216,8 +42429,6 @@ }, "remark-stringify": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-5.0.0.tgz", - "integrity": "sha512-Ws5MdA69ftqQ/yhRF9XhVV29mhxbfGhbz0Rx5bQH+oJcNhhSM6nCu1EpLod+DjrFGrU0BMPs+czVmJZU7xiS7w==", "dev": true, "requires": { "ccount": "^1.0.0", @@ -18238,8 +42449,6 @@ }, "remark-toc": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-5.1.1.tgz", - "integrity": "sha512-vCPW4YOsm2CfyuScdktM9KDnJXVHJsd/ZeRtst+dnBU3B3KKvt8bc+bs5syJjyptAHfqo7H+5Uhz+2blWBfwow==", "dev": true, "requires": { "mdast-util-toc": "^3.0.0", @@ -18248,8 +42457,6 @@ }, "remove-bom-buffer": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", "dev": true, "requires": { "is-buffer": "^1.1.5", @@ -18258,16 +42465,12 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true } } }, "remove-bom-stream": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", "dev": true, "requires": { "remove-bom-buffer": "^3.0.0", @@ -18277,26 +42480,18 @@ }, "remove-trailing-separator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, "repeat-element": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true }, "repeat-string": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "repeating": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { "is-finite": "^1.0.0" @@ -18304,14 +42499,10 @@ }, "replace-ext": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", "dev": true }, "replace-in-file": { "version": "6.3.2", - "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.3.2.tgz", - "integrity": "sha512-Dbt5pXKvFVPL3WAaEB3ZX+95yP0CeAtIPJDwYzHbPP5EAHn+0UoegH/Wg3HKflU9dYBH8UnBC2NvY3P+9EZtTg==", "dev": true, "requires": { "chalk": "^4.1.2", @@ -18321,14 +42512,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -18336,8 +42523,6 @@ }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -18347,8 +42532,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -18356,26 +42539,18 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "glob": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -18388,14 +42563,10 @@ }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -18405,8 +42576,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -18414,8 +42583,6 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -18425,14 +42592,10 @@ }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -18446,16 +42609,12 @@ }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "request": { "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { "aws-sign2": "~0.7.0", @@ -18482,8 +42641,6 @@ "dependencies": { "form-data": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -18493,16 +42650,12 @@ }, "qs": { "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true } } }, "request-promise-core": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { "lodash": "^4.17.19" @@ -18510,8 +42663,6 @@ }, "request-promise-native": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { "request-promise-core": "1.1.4", @@ -18521,32 +42672,22 @@ }, "require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, "require-main-filename": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, "resolve": { "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { "is-core-module": "^2.2.0", @@ -18555,8 +42696,6 @@ }, "resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { "resolve-from": "^5.0.0" @@ -18564,22 +42703,16 @@ "dependencies": { "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true } } }, "resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "resolve-options": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", "dev": true, "requires": { "value-or-function": "^3.0.0" @@ -18587,28 +42720,20 @@ }, "resolve-protobuf-schema": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", - "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", "requires": { "protocol-buffers-schema": "^3.3.1" } }, "resolve-url": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, "resolve.exports": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, "responselike": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "dev": true, "requires": { "lowercase-keys": "^1.0.0" @@ -18616,8 +42741,6 @@ }, "restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { "onetime": "^5.1.0", @@ -18626,8 +42749,6 @@ }, "resumer": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", "dev": true, "requires": { "through": "~2.3.4" @@ -18635,20 +42756,14 @@ }, "ret": { "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, "reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -18656,8 +42771,6 @@ }, "ripemd160": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { "hash-base": "^3.0.0", @@ -18666,8 +42779,6 @@ }, "rollup": { "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -18675,8 +42786,6 @@ }, "rollup-plugin-buble": { "version": "0.19.8", - "resolved": "https://registry.npmjs.org/rollup-plugin-buble/-/rollup-plugin-buble-0.19.8.tgz", - "integrity": "sha512-8J4zPk2DQdk3rxeZvxgzhHh/rm5nJkjwgcsUYisCQg1QbT5yagW+hehYEW7ZNns/NVbDCTv4JQ7h4fC8qKGOKw==", "dev": true, "requires": { "buble": "^0.19.8", @@ -18685,8 +42794,6 @@ }, "rollup-plugin-commonjs": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", "dev": true, "requires": { "estree-walker": "^0.6.1", @@ -18698,16 +42805,12 @@ "dependencies": { "estree-walker": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "dev": true } } }, "rollup-plugin-node-resolve": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", "dev": true, "requires": { "@types/resolve": "0.0.8", @@ -18719,8 +42822,6 @@ "dependencies": { "@types/resolve": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", "dev": true, "requires": { "@types/node": "*" @@ -18730,8 +42831,6 @@ }, "rollup-plugin-replace": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz", - "integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==", "dev": true, "requires": { "magic-string": "^0.25.2", @@ -18740,8 +42839,6 @@ }, "rollup-plugin-sourcemaps": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz", - "integrity": "sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw==", "dev": true, "requires": { "@rollup/pluginutils": "^3.0.9", @@ -18750,8 +42847,6 @@ "dependencies": { "source-map-resolve": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", "dev": true, "requires": { "atob": "^2.1.2", @@ -18762,8 +42857,6 @@ }, "rollup-plugin-terser": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", @@ -18774,8 +42867,6 @@ }, "rollup-plugin-unassert": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-unassert/-/rollup-plugin-unassert-0.3.0.tgz", - "integrity": "sha512-mdRJ8AinuNdtoS9L+CXVQcoaHLHV+eeEV5b9u76ai3yxOWp3t1oXQOuDjRmRiIjOYWYxCkSYiFQH72QoPdDfwQ==", "dev": true, "requires": { "acorn": "^6.1.1", @@ -18788,16 +42879,12 @@ "dependencies": { "acorn": { "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true } } }, "rollup-pluginutils": { "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, "requires": { "estree-walker": "^0.6.1" @@ -18805,22 +42892,16 @@ "dependencies": { "estree-walker": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "dev": true } } }, "run-async": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, "run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { "queue-microtask": "^1.2.2" @@ -18828,14 +42909,10 @@ }, "rw": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=", "dev": true }, "rxjs": { "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -18843,20 +42920,14 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "safe-json-parse": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", "dev": true }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { "ret": "~0.1.10" @@ -18864,14 +42935,10 @@ }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "saxes": { "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", "dev": true, "requires": { "xmlchars": "^2.1.1" @@ -18879,8 +42946,6 @@ }, "scheduler": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -18889,14 +42954,10 @@ }, "seedrandom": { "version": "2.4.4", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", - "integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA==", "dev": true }, "selenium-webdriver": { "version": "4.0.0-rc-1", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-1.tgz", - "integrity": "sha512-bcrwFPRax8fifRP60p7xkWDGSJJoMkPAzufMlk5K2NyLPht/YZzR2WcIk1+3gR8VOCLlst1P2PI+MXACaFzpIw==", "dev": true, "requires": { "jszip": "^3.6.0", @@ -18907,8 +42968,6 @@ "dependencies": { "tmp": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "requires": { "rimraf": "^3.0.0" @@ -18916,16 +42975,13 @@ }, "ws": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.2.tgz", - "integrity": "sha512-Q6B6H2oc8QY3llc3cB8kVmQ6pnJWVQbP7Q5algTcIxx7YEpc0oU4NBVHlztA7Ekzfhw2r0rPducMUiCGWKQRzw==", - "dev": true + "dev": true, + "requires": {} } } }, "semver": { "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -18933,8 +42989,6 @@ }, "semver-diff": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "dev": true, "requires": { "semver": "^6.3.0" @@ -18942,16 +42996,12 @@ "dependencies": { "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "send": { "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "requires": { "debug": "2.6.9", @@ -18971,8 +43021,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -18980,30 +43028,22 @@ "dependencies": { "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "ms": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true } } }, "serialize-javascript": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -19011,8 +43051,6 @@ }, "serve-static": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "requires": { "encodeurl": "~1.0.2", @@ -19023,20 +43061,14 @@ }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-immediate-shim": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", "dev": true }, "set-value": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -19047,8 +43079,6 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -19056,8 +43086,6 @@ }, "is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -19067,14 +43095,10 @@ }, "setprototypeof": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -19083,8 +43107,6 @@ }, "shallow-clone": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "requires": { "kind-of": "^6.0.2" @@ -19092,8 +43114,6 @@ }, "shasum-object": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", - "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", "dev": true, "requires": { "fast-safe-stringify": "^2.0.7" @@ -19101,8 +43121,6 @@ }, "shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -19110,26 +43128,18 @@ }, "shebang-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "shell-quote": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", "dev": true }, "shellwords": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, "shuffle-seed": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/shuffle-seed/-/shuffle-seed-1.1.6.tgz", - "integrity": "sha1-UzwSaDurO0+j6HUfxOViFGdEJgs=", "dev": true, "requires": { "seedrandom": "^2.4.2" @@ -19137,8 +43147,6 @@ }, "side-channel": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "requires": { "call-bind": "^1.0.0", @@ -19148,20 +43156,14 @@ }, "signal-exit": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "simple-concat": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "dev": true }, "simple-get": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", "dev": true, "requires": { "decompress-response": "^4.2.0", @@ -19171,8 +43173,6 @@ }, "sinon": { "version": "12.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", - "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==", "dev": true, "requires": { "@sinonjs/commons": "^1.8.3", @@ -19185,8 +43185,6 @@ "dependencies": { "@sinonjs/fake-timers": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -19194,20 +43192,14 @@ }, "diff": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -19217,20 +43209,14 @@ }, "sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, "slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -19240,8 +43226,6 @@ "dependencies": { "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -19249,8 +43233,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -19258,22 +43240,16 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true } } }, "snapdragon": { "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { "base": "^0.11.1", @@ -19288,8 +43264,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -19297,8 +43271,6 @@ }, "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -19306,8 +43278,6 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -19315,16 +43285,12 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "snapdragon-node": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { "define-property": "^1.0.0", @@ -19334,8 +43300,6 @@ "dependencies": { "define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -19343,8 +43307,6 @@ }, "is-accessor-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -19352,8 +43314,6 @@ }, "is-data-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -19361,8 +43321,6 @@ }, "is-descriptor": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -19374,8 +43332,6 @@ }, "snapdragon-util": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { "kind-of": "^3.2.0" @@ -19383,14 +43339,10 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -19400,8 +43352,6 @@ }, "socket.io": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.2.0.tgz", - "integrity": "sha512-sjlGfMmnaWvTRVxGRGWyhd9ctpg4APxWAxu85O/SxekkxHhfxmePWZbaYCkeX5QQX0z1YEnKOlNt6w82E4Nzug==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -19417,14 +43367,10 @@ }, "socket.io-adapter": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.2.tgz", - "integrity": "sha512-PBZpxUPYjmoogY0aoaTmo1643JelsaS1CiAwNjRVdrI0X9Seuc19Y2Wife8k88avW6haG8cznvwbubAZwH4Mtg==", "dev": true }, "socket.io-parser": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", - "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", "dev": true, "requires": { "@types/component-emitter": "^1.2.10", @@ -19434,14 +43380,10 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-explorer": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/source-map-explorer/-/source-map-explorer-2.5.2.tgz", - "integrity": "sha512-gBwOyCcHPHcdLbgw6Y6kgoH1uLKL6hN3zz0xJcNI2lpnElZliIlmSYAjUVwAWnc7+HscoTyh1ScR7ITtFuEnxg==", "dev": true, "requires": { "btoa": "^1.2.1", @@ -19460,14 +43402,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -19475,8 +43413,6 @@ }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -19486,8 +43422,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -19495,38 +43429,26 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "source-map": { "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -19536,8 +43458,6 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" @@ -19545,8 +43465,6 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -19556,14 +43474,10 @@ }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -19577,22 +43491,16 @@ }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "source-map-js": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", - "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", "dev": true }, "source-map-resolve": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { "atob": "^2.1.2", @@ -19604,8 +43512,6 @@ }, "source-map-support": { "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -19614,40 +43520,28 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "source-map-url": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, "sourcemap-codec": { "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, "space-separated-tokens": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", "dev": true }, "spawn-args": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/spawn-args/-/spawn-args-0.2.0.tgz", - "integrity": "sha1-+30L0dcP1DFr2ePew4nmX51jYbs=", "dev": true }, "spawn-wrap": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, "requires": { "foreground-child": "^2.0.0", @@ -19660,8 +43554,6 @@ "dependencies": { "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -19671,8 +43563,6 @@ }, "spdx-correct": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -19681,14 +43571,10 @@ }, "spdx-exceptions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -19697,26 +43583,18 @@ }, "spdx-license-ids": { "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, "specificity": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", "dev": true }, "split-on-first": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", "dev": true }, "split-string": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { "extend-shallow": "^3.0.0" @@ -19724,14 +43602,10 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -19747,8 +43621,6 @@ }, "st": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/st/-/st-3.0.0.tgz", - "integrity": "sha512-UEUi8P8Y5GOewlJbE5vrhsaQRwmbNVMUr6PLxRZHH4Cwz8CkHhnBqlqGtE3egXQd+ceUwNxdOVjsC/IsgN2Pww==", "dev": true, "requires": { "async-cache": "^1.1.0", @@ -19761,8 +43633,6 @@ "dependencies": { "bl": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.0.0.tgz", - "integrity": "sha512-8vxFNZ0pflFfi0WXA3WQXlj6CaMEwsmh63I1CNp0q+wWv8sD0ARx1KovSQd0l2GkwrMIOyedq0EF1FxI+RCZLQ==", "dev": true, "requires": { "buffer": "^6.0.3", @@ -19772,8 +43642,6 @@ }, "buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "requires": { "base64-js": "^1.3.1", @@ -19782,8 +43650,6 @@ }, "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -19795,14 +43661,10 @@ }, "stable": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "dev": true }, "stack-utils": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", - "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -19810,22 +43672,16 @@ "dependencies": { "escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true } } }, "state-toggle": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", "dev": true }, "static-extend": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { "define-property": "^0.2.5", @@ -19834,8 +43690,6 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -19845,20 +43699,14 @@ }, "statuses": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, "stealthy-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, "stream-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/stream-array/-/stream-array-1.1.2.tgz", - "integrity": "sha1-nl9zRfITfDDuO0mLkRToC1K7frU=", "dev": true, "requires": { "readable-stream": "~2.1.0" @@ -19866,14 +43714,10 @@ "dependencies": { "process-nextick-args": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "readable-stream": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", - "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", "dev": true, "requires": { "buffer-shims": "^1.0.0", @@ -19887,16 +43731,12 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "stream-browserify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", "dev": true, "requires": { "inherits": "~2.0.4", @@ -19905,8 +43745,6 @@ "dependencies": { "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -19918,8 +43756,6 @@ }, "stream-combiner2": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, "requires": { "duplexer2": "~0.1.0", @@ -19928,8 +43764,6 @@ }, "stream-http": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", "dev": true, "requires": { "builtin-status-codes": "^3.0.0", @@ -19940,8 +43774,6 @@ "dependencies": { "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -19953,14 +43785,10 @@ }, "stream-shift": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, "stream-splicer": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -19969,14 +43797,17 @@ }, "strict-uri-encode": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", "dev": true }, + "string_decoder": { + "version": "1.1.1", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { "char-regex": "^1.0.2", @@ -19985,14 +43816,10 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -20002,14 +43829,10 @@ }, "string-template": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", "dev": true }, "string-width": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -20018,8 +43841,6 @@ "dependencies": { "strip-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -20029,8 +43850,6 @@ }, "string.prototype.matchall": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", - "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -20045,8 +43864,6 @@ }, "string.prototype.padend": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz", - "integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -20056,8 +43873,6 @@ }, "string.prototype.trim": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.4.tgz", - "integrity": "sha512-hWCk/iqf7lp0/AgTF7/ddO1IWtSNPASjlzCicV5irAVdE1grjsneK26YG6xACMBEdCvO8fUST0UzDMh/2Qy+9Q==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -20067,8 +43882,6 @@ }, "string.prototype.trimend": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -20077,27 +43890,14 @@ }, "string.prototype.trimstart": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "stringify-entities": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", "dev": true, "requires": { "character-entities-html4": "^1.0.0", @@ -20108,32 +43908,22 @@ }, "strip-ansi": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", "dev": true }, "strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "strip-indent": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { "get-stdin": "^4.0.1" @@ -20141,26 +43931,18 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "style-search": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", "dev": true }, "styled_string": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/styled_string/-/styled_string-0.0.1.tgz", - "integrity": "sha1-0ieCvYEpVFm8Tx3xjEutjpTdEko=", "dev": true }, "stylehacks": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz", - "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==", "dev": true, "requires": { "browserslist": "^4.16.0", @@ -20169,8 +43951,6 @@ }, "stylelint": { "version": "13.13.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.13.1.tgz", - "integrity": "sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==", "dev": true, "requires": { "@stylelint/postcss-css-in-js": "^0.37.2", @@ -20225,20 +44005,14 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "balanced-match": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, "camelcase-keys": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -20248,14 +44022,10 @@ }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -20264,14 +44034,10 @@ }, "get-stdin": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, "hosted-git-info": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -20279,20 +44045,14 @@ }, "indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -20300,14 +44060,10 @@ }, "map-obj": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", - "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", "dev": true }, "meow": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -20326,8 +44082,6 @@ }, "normalize-package-data": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, "requires": { "hosted-git-info": "^4.0.1", @@ -20338,8 +44092,6 @@ }, "p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -20347,8 +44099,6 @@ }, "parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -20359,14 +44109,10 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20376,8 +44122,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -20387,8 +44131,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -20400,8 +44142,6 @@ }, "read-pkg": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", @@ -20412,14 +44152,10 @@ "dependencies": { "hosted-git-info": { "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -20430,22 +44166,16 @@ }, "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "type-fest": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true } } }, "read-pkg-up": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { "find-up": "^4.1.0", @@ -20455,16 +44185,12 @@ "dependencies": { "type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, "redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { "indent-string": "^4.0.0", @@ -20473,20 +44199,14 @@ }, "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -20496,8 +44216,6 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" @@ -20505,8 +44223,6 @@ }, "strip-indent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { "min-indent": "^1.0.0" @@ -20514,8 +44230,6 @@ }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -20523,34 +44237,25 @@ }, "trim-newlines": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "type-fest": { "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "stylelint-config-recommended": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-5.0.0.tgz", - "integrity": "sha512-c8aubuARSu5A3vEHLBeOSJt1udOdS+1iue7BmJDTSXoCBmfEQmmWX+59vYIj3NQdJBY6a/QRv1ozVFpaB9jaqA==", - "dev": true + "dev": true, + "requires": {} }, "stylelint-config-standard": { "version": "22.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-22.0.0.tgz", - "integrity": "sha512-uQVNi87SHjqTm8+4NIP5NMAyY/arXrBgimaaT7skvRfE9u3JKXRK9KBkbr4pVmeciuCcs64kAdjlxfq6Rur7Hw==", "dev": true, "requires": { "stylelint-config-recommended": "^5.0.0" @@ -20558,8 +44263,6 @@ }, "subarg": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "requires": { "minimist": "^1.1.0" @@ -20567,8 +44270,6 @@ }, "sugarss": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", - "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", "dev": true, "requires": { "postcss": "^7.0.2" @@ -20576,8 +44277,6 @@ "dependencies": { "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -20587,8 +44286,6 @@ "dependencies": { "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -20598,8 +44295,6 @@ }, "postcss": { "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -20609,14 +44304,10 @@ }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -20626,16 +44317,12 @@ }, "supercluster": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.3.tgz", - "integrity": "sha512-7+bR4FbF5SYsmkHfDp61QiwCKtwNDyPsddk9TzfsDA5DQr5Goii5CVD2SXjglweFCxjrzVZf945ahqYfUIk8UA==", "requires": { "kdbush": "^3.0.0" } }, "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -20643,8 +44330,6 @@ }, "supports-hyperlinks": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -20653,14 +44338,10 @@ "dependencies": { "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -20670,14 +44351,10 @@ }, "svg-tags": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", "dev": true }, "svgo": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.6.0.tgz", - "integrity": "sha512-ATpRmynNSjP/5hSM4Ij4Pg3L+BCN6IBES7wRLh1ZtVxJB7Xn8omiGttLW6v6ZbqrV5pCVB3XfdbUoY8IpgIwvw==", "dev": true, "requires": { "@trysound/sax": "0.2.0", @@ -20691,14 +44368,10 @@ }, "symbol-tree": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, "syntax-error": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "requires": { "acorn-node": "^1.2.0" @@ -20706,8 +44379,6 @@ }, "table": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -20720,8 +44391,6 @@ "dependencies": { "ajv": { "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -20732,32 +44401,22 @@ }, "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -20767,8 +44426,6 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" @@ -20778,8 +44435,6 @@ }, "tap": { "version": "12.4.1", - "resolved": "https://registry.npmjs.org/tap/-/tap-12.4.1.tgz", - "integrity": "sha512-hWh6V5cIIHwvXwmNb3fL/3athC9NyZuL4ZoiyHUHXqRAJJ6/SBmGX7IOfzj/Pf7EzFy9JwDCw/64eOyKx8XikA==", "dev": true, "requires": { "bind-obj-methods": "^2.0.0", @@ -20819,8 +44474,6 @@ "dependencies": { "cross-spawn": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -20829,8 +44482,6 @@ }, "foreground-child": { "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", @@ -20839,14 +44490,10 @@ }, "istanbul-lib-coverage": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-instrument": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { "@babel/generator": "^7.4.0", @@ -20860,8 +44507,6 @@ }, "lru-cache": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -20870,8 +44515,6 @@ }, "minipass": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "requires": { "safe-buffer": "^5.1.2", @@ -20880,16 +44523,12 @@ "dependencies": { "yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "mkdirp": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -20897,8 +44536,6 @@ }, "nyc": { "version": "13.3.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", - "integrity": "sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w==", "dev": true, "requires": { "archy": "^1.0.0", @@ -20929,14 +44566,12 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "bundled": true, "dev": true }, "append-transform": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "bundled": true, "dev": true, "requires": { "default-require-extensions": "^2.0.0" @@ -20944,20 +44579,17 @@ }, "archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "bundled": true, "dev": true }, "arrify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "bundled": true, "dev": true }, "async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "bundled": true, "dev": true, "requires": { "lodash": "^4.17.11" @@ -20965,14 +44597,12 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "bundled": true, "dev": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -20981,8 +44611,7 @@ }, "caching-transform": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.1.tgz", - "integrity": "sha512-Y1KTLNwSPd4ljsDrFOtyXVmm7Gnk42yQitNq43AhE+cwUR/e4T+rmOHs1IPtzBg8066GBJfTOj1rQYFSWSsH2g==", + "bundled": true, "dev": true, "requires": { "hasha": "^3.0.0", @@ -20993,14 +44622,12 @@ }, "camelcase": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "bundled": true, "dev": true }, "cliui": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "bundled": true, "dev": true, "requires": { "string-width": "^2.1.1", @@ -21010,33 +44637,28 @@ }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "bundled": true, "dev": true }, "commander": { "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "bundled": true, "dev": true, "optional": true }, "commondir": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "bundled": true, "dev": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "bundled": true, "dev": true }, "convert-source-map": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "bundled": true, "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -21044,8 +44666,7 @@ }, "cross-spawn": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "bundled": true, "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -21054,8 +44675,7 @@ }, "debug": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "bundled": true, "dev": true, "requires": { "ms": "^2.1.1" @@ -21063,14 +44683,12 @@ }, "decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "bundled": true, "dev": true }, "default-require-extensions": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "bundled": true, "dev": true, "requires": { "strip-bom": "^3.0.0" @@ -21078,8 +44696,7 @@ }, "end-of-stream": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "bundled": true, "dev": true, "requires": { "once": "^1.4.0" @@ -21087,8 +44704,7 @@ }, "error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "bundled": true, "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -21096,14 +44712,12 @@ }, "es6-error": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "bundled": true, "dev": true }, "execa": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "bundled": true, "dev": true, "requires": { "cross-spawn": "^6.0.0", @@ -21117,8 +44731,7 @@ "dependencies": { "cross-spawn": { "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "bundled": true, "dev": true, "requires": { "nice-try": "^1.0.4", @@ -21132,8 +44745,7 @@ }, "find-cache-dir": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", - "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "bundled": true, "dev": true, "requires": { "commondir": "^1.0.1", @@ -21143,8 +44755,7 @@ }, "find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "bundled": true, "dev": true, "requires": { "locate-path": "^3.0.0" @@ -21152,8 +44763,7 @@ }, "foreground-child": { "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "bundled": true, "dev": true, "requires": { "cross-spawn": "^4", @@ -21162,20 +44772,17 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "dev": true }, "get-caller-file": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "bundled": true, "dev": true }, "get-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "bundled": true, "dev": true, "requires": { "pump": "^3.0.0" @@ -21183,8 +44790,7 @@ }, "glob": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "bundled": true, "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -21197,14 +44803,12 @@ }, "graceful-fs": { "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "bundled": true, "dev": true }, "handlebars": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==", + "bundled": true, "dev": true, "requires": { "async": "^2.5.0", @@ -21215,22 +44819,19 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "bundled": true, "dev": true } } }, "has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "bundled": true, "dev": true }, "hasha": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "bundled": true, "dev": true, "requires": { "is-stream": "^1.0.1" @@ -21238,20 +44839,17 @@ }, "hosted-git-info": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "bundled": true, "dev": true }, "imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "bundled": true, "dev": true }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "dev": true, "requires": { "once": "^1.3.0", @@ -21260,50 +44858,42 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "bundled": true, "dev": true }, "invert-kv": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "bundled": true, "dev": true }, "is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "bundled": true, "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "bundled": true, "dev": true }, "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "bundled": true, "dev": true }, "isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "bundled": true, "dev": true }, "istanbul-lib-coverage": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "bundled": true, "dev": true }, "istanbul-lib-hook": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz", - "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==", + "bundled": true, "dev": true, "requires": { "append-transform": "^1.0.0" @@ -21311,8 +44901,7 @@ }, "istanbul-lib-report": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz", - "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==", + "bundled": true, "dev": true, "requires": { "istanbul-lib-coverage": "^2.0.3", @@ -21322,8 +44911,7 @@ "dependencies": { "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "bundled": true, "dev": true, "requires": { "has-flag": "^3.0.0" @@ -21333,8 +44921,7 @@ }, "istanbul-lib-source-maps": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz", - "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==", + "bundled": true, "dev": true, "requires": { "debug": "^4.1.1", @@ -21346,16 +44933,14 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "bundled": true, "dev": true } } }, "istanbul-reports": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz", - "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==", + "bundled": true, "dev": true, "requires": { "handlebars": "^4.1.0" @@ -21363,14 +44948,12 @@ }, "json-parse-better-errors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "bundled": true, "dev": true }, "lcid": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "bundled": true, "dev": true, "requires": { "invert-kv": "^2.0.0" @@ -21378,8 +44961,7 @@ }, "load-json-file": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "bundled": true, "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -21390,8 +44972,7 @@ }, "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "bundled": true, "dev": true, "requires": { "p-locate": "^3.0.0", @@ -21400,20 +44981,17 @@ }, "lodash": { "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "bundled": true, "dev": true }, "lodash.flattendeep": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "bundled": true, "dev": true }, "lru-cache": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "bundled": true, "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -21422,8 +45000,7 @@ }, "make-dir": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "bundled": true, "dev": true, "requires": { "pify": "^3.0.0" @@ -21431,8 +45008,7 @@ }, "map-age-cleaner": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "bundled": true, "dev": true, "requires": { "p-defer": "^1.0.0" @@ -21440,8 +45016,7 @@ }, "mem": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", - "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "bundled": true, "dev": true, "requires": { "map-age-cleaner": "^0.1.1", @@ -21451,8 +45026,7 @@ }, "merge-source-map": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "bundled": true, "dev": true, "requires": { "source-map": "^0.6.1" @@ -21460,22 +45034,19 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "bundled": true, "dev": true } } }, "mimic-fn": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "bundled": true, "dev": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -21483,14 +45054,12 @@ }, "minimist": { "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "bundled": true, "dev": true }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "dev": true, "requires": { "minimist": "0.0.8" @@ -21498,28 +45067,24 @@ "dependencies": { "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "bundled": true, "dev": true } } }, "ms": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "bundled": true, "dev": true }, "nice-try": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "bundled": true, "dev": true }, "normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "bundled": true, "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -21530,8 +45095,7 @@ }, "npm-run-path": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "bundled": true, "dev": true, "requires": { "path-key": "^2.0.0" @@ -21539,14 +45103,12 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "bundled": true, "dev": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, "requires": { "wrappy": "1" @@ -21554,8 +45116,7 @@ }, "optimist": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "bundled": true, "dev": true, "requires": { "minimist": "~0.0.1", @@ -21564,14 +45125,12 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "dev": true }, "os-locale": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "bundled": true, "dev": true, "requires": { "execa": "^1.0.0", @@ -21581,26 +45140,22 @@ }, "p-defer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "bundled": true, "dev": true }, "p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "bundled": true, "dev": true }, "p-is-promise": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", - "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "bundled": true, "dev": true }, "p-limit": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "bundled": true, "dev": true, "requires": { "p-try": "^2.0.0" @@ -21608,8 +45163,7 @@ }, "p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "bundled": true, "dev": true, "requires": { "p-limit": "^2.0.0" @@ -21617,14 +45171,12 @@ }, "p-try": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "bundled": true, "dev": true }, "package-hash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "bundled": true, "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -21635,8 +45187,7 @@ }, "parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "bundled": true, "dev": true, "requires": { "error-ex": "^1.3.1", @@ -21645,32 +45196,27 @@ }, "path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "bundled": true, "dev": true }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "dev": true }, "path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "bundled": true, "dev": true }, "path-parse": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "bundled": true, "dev": true }, "path-type": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "bundled": true, "dev": true, "requires": { "pify": "^3.0.0" @@ -21678,14 +45224,12 @@ }, "pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "bundled": true, "dev": true }, "pkg-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "bundled": true, "dev": true, "requires": { "find-up": "^3.0.0" @@ -21693,14 +45237,12 @@ }, "pseudomap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "bundled": true, "dev": true }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "bundled": true, "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -21709,8 +45251,7 @@ }, "read-pkg": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "bundled": true, "dev": true, "requires": { "load-json-file": "^4.0.0", @@ -21720,8 +45261,7 @@ }, "read-pkg-up": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "bundled": true, "dev": true, "requires": { "find-up": "^3.0.0", @@ -21730,8 +45270,7 @@ }, "release-zalgo": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "bundled": true, "dev": true, "requires": { "es6-error": "^4.0.1" @@ -21739,20 +45278,17 @@ }, "require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "bundled": true, "dev": true }, "require-main-filename": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "bundled": true, "dev": true }, "resolve": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "bundled": true, "dev": true, "requires": { "path-parse": "^1.0.6" @@ -21760,14 +45296,12 @@ }, "resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "bundled": true, "dev": true }, "rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "bundled": true, "dev": true, "requires": { "glob": "^7.1.3" @@ -21775,26 +45309,22 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "bundled": true, "dev": true }, "semver": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "bundled": true, "dev": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "dev": true }, "shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "bundled": true, "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -21802,20 +45332,17 @@ }, "shebang-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "bundled": true, "dev": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "dev": true }, "spawn-wrap": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", - "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", + "bundled": true, "dev": true, "requires": { "foreground-child": "^1.5.6", @@ -21828,8 +45355,7 @@ }, "spdx-correct": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "bundled": true, "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -21838,14 +45364,12 @@ }, "spdx-exceptions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "bundled": true, "dev": true }, "spdx-expression-parse": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "bundled": true, "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -21854,14 +45378,12 @@ }, "spdx-license-ids": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "bundled": true, "dev": true }, "string-width": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "bundled": true, "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -21870,8 +45392,7 @@ }, "strip-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "bundled": true, "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -21879,20 +45400,17 @@ }, "strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "bundled": true, "dev": true }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "bundled": true, "dev": true }, "test-exclude": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.1.0.tgz", - "integrity": "sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA==", + "bundled": true, "dev": true, "requires": { "arrify": "^1.0.1", @@ -21903,8 +45421,7 @@ }, "uglify-js": { "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -21914,8 +45431,7 @@ "dependencies": { "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "bundled": true, "dev": true, "optional": true } @@ -21923,14 +45439,12 @@ }, "uuid": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "bundled": true, "dev": true }, "validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "bundled": true, "dev": true, "requires": { "spdx-correct": "^3.0.0", @@ -21939,8 +45453,7 @@ }, "which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "bundled": true, "dev": true, "requires": { "isexe": "^2.0.0" @@ -21948,20 +45461,17 @@ }, "which-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "bundled": true, "dev": true }, "wordwrap": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "bundled": true, "dev": true }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "bundled": true, "dev": true, "requires": { "string-width": "^1.0.1", @@ -21970,14 +45480,12 @@ "dependencies": { "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "bundled": true, "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -21985,8 +45493,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -21996,8 +45503,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -22007,14 +45513,12 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "bundled": true, "dev": true }, "write-file-atomic": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", - "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "bundled": true, "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -22024,20 +45528,17 @@ }, "y18n": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "bundled": true, "dev": true }, "yallist": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "bundled": true, "dev": true }, "yargs": { "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "bundled": true, "dev": true, "requires": { "cliui": "^4.0.0", @@ -22056,8 +45557,7 @@ }, "yargs-parser": { "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "bundled": true, "dev": true, "requires": { "camelcase": "^5.0.0", @@ -22068,8 +45568,6 @@ }, "rimraf": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -22077,14 +45575,10 @@ }, "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "tap-parser": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", - "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -22094,8 +45588,6 @@ }, "ts-node": { "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", "dev": true, "requires": { "arg": "^4.1.0", @@ -22107,14 +45599,10 @@ }, "typescript": { "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true }, "write-file-atomic": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -22124,16 +45612,12 @@ }, "yallist": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } }, "tap-mocha-reporter": { "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.9.tgz", - "integrity": "sha512-VO07vhC9EG27EZdOe7bWBj1ldbK+DL9TnRadOgdQmiQOVZjFpUEQuuqO7+rNSO2kfmkq5hWeluYXDWNG/ytXTQ==", "dev": true, "requires": { "color-support": "^1.1.0", @@ -22149,8 +45633,6 @@ "dependencies": { "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -22158,20 +45640,14 @@ }, "diff": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", "dev": true }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "tap-parser": { "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz", - "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -22183,8 +45659,6 @@ }, "tap-parser": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", - "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -22194,8 +45668,6 @@ }, "tap-yaml": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", - "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", "dev": true, "requires": { "yaml": "^1.5.0" @@ -22203,8 +45675,6 @@ }, "tape": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-5.3.1.tgz", - "integrity": "sha512-Mj3h+/dgfI2xct4kTpzqZaRxhhglXcMg//xGTbB0AQisfiOYa6ZBNQIgv46xi1MqbgthuNLSS1SAySDZsb7MMA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -22230,8 +45700,6 @@ "dependencies": { "deep-equal": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz", - "integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==", "dev": true, "requires": { "call-bind": "^1.0.0", @@ -22253,14 +45721,10 @@ }, "isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, "resolve": { "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", "dev": true, "requires": { "is-core-module": "^2.2.0", @@ -22271,8 +45735,6 @@ }, "tape-filter": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tape-filter/-/tape-filter-1.0.4.tgz", - "integrity": "sha1-HWN6wGTVGSbzOa2I9kLrD4fKncc=", "dev": true, "requires": { "minimist": "^1.2.0" @@ -22280,8 +45742,6 @@ }, "tar": { "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -22294,8 +45754,6 @@ }, "tar-fs": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "requires": { "chownr": "^1.1.1", @@ -22306,14 +45764,10 @@ "dependencies": { "chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -22324,8 +45778,6 @@ }, "tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, "requires": { "bl": "^4.0.3", @@ -22337,8 +45789,6 @@ "dependencies": { "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -22350,8 +45800,6 @@ }, "temp": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", "dev": true, "requires": { "mkdirp": "^0.5.1", @@ -22360,8 +45808,6 @@ "dependencies": { "mkdirp": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -22369,8 +45815,6 @@ }, "rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -22380,14 +45824,10 @@ }, "term-size": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true }, "terminal-link": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -22396,8 +45836,6 @@ }, "terser": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.8.0.tgz", - "integrity": "sha512-f0JH+6yMpneYcRJN314lZrSwu9eKkUFEHLN/kNy8ceh8gaRiLgFPJqrB9HsXjhEGdv4e/ekjTOFxIlL6xlma8A==", "dev": true, "requires": { "commander": "^2.20.0", @@ -22407,22 +45845,16 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "source-map": { "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true } } }, "test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "requires": { "@istanbuljs/schema": "^0.1.2", @@ -22432,8 +45864,6 @@ }, "testem": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/testem/-/testem-3.5.0.tgz", - "integrity": "sha512-qucRtq6aDVrCc6aEyz15CxIpjij95B8XTHpRT7xrTdTw3iFypZw95DQjX+EnGmGIqUB7CGapv3L2OP+HAlHUBg==", "dev": true, "requires": { "@xmldom/xmldom": "^0.7.1", @@ -22469,14 +45899,10 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "minipass": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "requires": { "safe-buffer": "^5.1.2", @@ -22485,8 +45911,6 @@ }, "mkdirp": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -22494,8 +45918,6 @@ }, "node-notifier": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.1.tgz", - "integrity": "sha512-fPNFIp2hF/Dq7qLDzSg4vZ0J4e9v60gJR+Qx7RbjbWqzPDdEqeVpEx5CFeDAELIl+A/woaaNn1fQ5nEVerMxJg==", "dev": true, "requires": { "growly": "^1.3.0", @@ -22508,8 +45930,6 @@ }, "rimraf": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -22517,8 +45937,6 @@ }, "tap-parser": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", - "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -22528,8 +45946,6 @@ }, "tmp": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -22537,14 +45953,10 @@ }, "uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -22552,34 +45964,24 @@ }, "yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "throat": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "through2": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { "readable-stream": "~2.3.6", @@ -22588,8 +45990,6 @@ }, "through2-filter": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, "requires": { "through2": "~2.0.0", @@ -22598,14 +45998,10 @@ }, "timed-out": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, "timers-browserify": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true, "requires": { "process": "~0.11.0" @@ -22613,14 +46009,10 @@ }, "timsort": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, "tiny-lr": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", - "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { "body": "^5.1.0", @@ -22633,8 +46025,6 @@ "dependencies": { "debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -22643,20 +46033,14 @@ } }, "tinyqueue": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", - "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + "version": "2.0.3" }, "tmatch": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", - "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==", "dev": true }, "tmp": { "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", "dev": true, "requires": { "os-tmpdir": "~1.0.1" @@ -22664,14 +46048,10 @@ }, "tmpl": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-absolute-glob": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", "dev": true, "requires": { "is-absolute": "^1.0.0", @@ -22680,14 +46060,10 @@ }, "to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-object-path": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -22695,14 +46071,10 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -22712,14 +46084,10 @@ }, "to-readable-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, "to-regex": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { "define-property": "^2.0.2", @@ -22730,8 +46098,6 @@ }, "to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" @@ -22739,8 +46105,6 @@ }, "to-through": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", "dev": true, "requires": { "through2": "^2.0.3" @@ -22748,14 +46112,10 @@ }, "toidentifier": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, "tough-cookie": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { "psl": "^1.1.28", @@ -22764,16 +46124,12 @@ "dependencies": { "punycode": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true } } }, "tr46": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", "dev": true, "requires": { "punycode": "^2.1.0" @@ -22781,52 +46137,36 @@ "dependencies": { "punycode": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true } } }, "trim": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", "dev": true }, "trim-lines": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.3.tgz", - "integrity": "sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA==", "dev": true }, "trim-newlines": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true }, "trim-trailing-lines": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", "dev": true }, "trivial-deferred": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", - "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, "trough": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", "dev": true }, "ts-jest": { "version": "27.0.7", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", - "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", "dev": true, "requires": { "bs-logger": "0.x", @@ -22841,22 +46181,16 @@ "dependencies": { "lodash.memoize": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, "yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } }, "ts-node": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.7.0", @@ -22875,28 +46209,20 @@ "dependencies": { "acorn": { "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true }, "acorn-walk": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true } } }, "tsame": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tsame/-/tsame-2.0.1.tgz", - "integrity": "sha512-jxyxgKVKa4Bh5dPcO42TJL22lIvfd9LOVJwdovKOnJa4TLLrHxquK+DlGm4rkGmrcur+GRx+x4oW00O2pY/fFw==", "dev": true }, "tsconfig-paths": { "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "requires": { "@types/json5": "^0.0.29", @@ -22907,8 +46233,6 @@ "dependencies": { "json5": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -22918,14 +46242,10 @@ }, "tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -22933,14 +46253,10 @@ }, "tty-browserify": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true }, "tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { "safe-buffer": "^5.0.1" @@ -22948,14 +46264,10 @@ }, "tweetnacl": { "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, "type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { "prelude-ls": "^1.2.1" @@ -22963,20 +46275,14 @@ }, "type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "requires": { "media-typer": "0.3.0", @@ -22985,14 +46291,10 @@ }, "typedarray": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, "requires": { "is-typedarray": "^1.0.0" @@ -23000,20 +46302,14 @@ }, "typescript": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz", - "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==", "dev": true }, "umd": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", "dev": true }, "unassert": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/unassert/-/unassert-1.6.0.tgz", - "integrity": "sha512-GoMtWTwGSxSFuRD0NKmbjlx3VJkgvSogzDzMPpJXYmBZv6MIWButsyMqEYhMx3NI4osXACcZA9mXiBteXyJtRw==", "dev": true, "requires": { "acorn": "^7.0.0", @@ -23027,8 +46323,6 @@ }, "unbox-primitive": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -23039,8 +46333,6 @@ }, "unbzip2-stream": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "requires": { "buffer": "^5.2.1", @@ -23049,14 +46341,10 @@ }, "unc-path-regex": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, "undeclared-identifiers": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", "dev": true, "requires": { "acorn-node": "^1.3.0", @@ -23068,14 +46356,10 @@ }, "underscore": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", "dev": true }, "unherit": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", "dev": true, "requires": { "inherits": "^2.0.0", @@ -23084,14 +46368,10 @@ }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", "dev": true }, "unicode-length": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", - "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", "dev": true, "requires": { "punycode": "^1.3.2", @@ -23100,14 +46380,10 @@ "dependencies": { "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -23117,8 +46393,6 @@ }, "unicode-match-property-ecmascript": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", "dev": true, "requires": { "unicode-canonical-property-names-ecmascript": "^1.0.4", @@ -23127,20 +46401,14 @@ }, "unicode-match-property-value-ecmascript": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", "dev": true }, "unicode-property-aliases-ecmascript": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", "dev": true }, "unified": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", - "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", "dev": true, "requires": { "bail": "^1.0.0", @@ -23153,20 +46421,14 @@ "dependencies": { "is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "unist-util-stringify-position": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", "dev": true }, "vfile": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", "dev": true, "requires": { "is-buffer": "^1.1.4", @@ -23177,8 +46439,6 @@ }, "vfile-message": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", "dev": true, "requires": { "unist-util-stringify-position": "^1.1.1" @@ -23188,8 +46448,6 @@ }, "union-value": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -23200,14 +46458,10 @@ }, "uniqs": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", "dev": true }, "unique-stream": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "dev": true, "requires": { "json-stable-stringify-without-jsonify": "^1.0.1", @@ -23216,8 +46470,6 @@ }, "unique-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "requires": { "crypto-random-string": "^2.0.0" @@ -23225,8 +46477,6 @@ }, "unist-builder": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", - "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", "dev": true, "requires": { "object-assign": "^4.1.0" @@ -23234,8 +46484,6 @@ }, "unist-util-find-all-after": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", - "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==", "dev": true, "requires": { "unist-util-is": "^4.0.0" @@ -23243,34 +46491,24 @@ "dependencies": { "unist-util-is": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", "dev": true } } }, "unist-util-generated": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", - "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", "dev": true }, "unist-util-is": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", "dev": true }, "unist-util-position": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", "dev": true }, "unist-util-remove-position": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", "dev": true, "requires": { "unist-util-visit": "^1.1.0" @@ -23278,8 +46516,6 @@ }, "unist-util-stringify-position": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, "requires": { "@types/unist": "^2.0.2" @@ -23287,8 +46523,6 @@ }, "unist-util-visit": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", "dev": true, "requires": { "unist-util-visit-parents": "^2.0.0" @@ -23296,8 +46530,6 @@ }, "unist-util-visit-parents": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", "dev": true, "requires": { "unist-util-is": "^3.0.0" @@ -23305,26 +46537,18 @@ }, "universal-user-agent": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", "dev": true }, "universalify": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, "unset-value": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { "has-value": "^0.3.1", @@ -23333,8 +46557,6 @@ "dependencies": { "has-value": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { "get-value": "^2.0.3", @@ -23344,8 +46566,6 @@ "dependencies": { "isobject": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" @@ -23355,28 +46575,20 @@ }, "has-values": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true } } }, "unzip-response": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", "dev": true }, "upath": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, "update-notifier": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -23396,8 +46608,6 @@ "dependencies": { "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -23405,8 +46615,6 @@ }, "chalk": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -23415,8 +46623,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -23424,26 +46630,18 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "import-lazy": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -23453,8 +46651,6 @@ }, "uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -23462,22 +46658,16 @@ "dependencies": { "punycode": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true } } }, "urix": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "url": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, "requires": { "punycode": "1.3.2", @@ -23486,16 +46676,12 @@ "dependencies": { "punycode": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true } } }, "url-parse-lax": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "dev": true, "requires": { "prepend-http": "^1.0.1" @@ -23503,14 +46689,10 @@ }, "use": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, "util": { "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -23523,32 +46705,22 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true }, "uuid": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "v8-compile-cache": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-to-istanbul": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -23558,16 +46730,12 @@ "dependencies": { "source-map": { "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true } } }, "validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { "spdx-correct": "^3.0.0", @@ -23576,26 +46744,18 @@ }, "value-or-function": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", "dev": true }, "vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, "vendors": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", "dev": true }, "verror": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -23605,16 +46765,12 @@ "dependencies": { "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true } } }, "vfile": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -23625,14 +46781,10 @@ }, "vfile-location": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", "dev": true }, "vfile-message": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -23641,8 +46793,6 @@ }, "vfile-reporter": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-5.1.2.tgz", - "integrity": "sha512-b15sTuss1wOPWVlyWOvu+n6wGJ/eTYngz3uqMLimQvxZ+Q5oFQGYZZP1o3dR9sk58G5+wej0UPCZSwQBX/mzrQ==", "dev": true, "requires": { "repeat-string": "^1.5.0", @@ -23655,20 +46805,14 @@ }, "vfile-sort": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.2.tgz", - "integrity": "sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==", "dev": true }, "vfile-statistics": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz", - "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==", "dev": true }, "vinyl": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "dev": true, "requires": { "clone": "^2.1.1", @@ -23681,8 +46825,6 @@ }, "vinyl-fs": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", "dev": true, "requires": { "fs-mkdirp-stream": "^1.0.0", @@ -23706,8 +46848,6 @@ }, "vinyl-sourcemap": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", "dev": true, "requires": { "append-buffer": "^1.0.2", @@ -23721,8 +46861,6 @@ "dependencies": { "normalize-path": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -23732,14 +46870,10 @@ }, "vm-browserify": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, "vt-pbf": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", - "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", "requires": { "@mapbox/point-geometry": "0.1.0", "@mapbox/vector-tile": "^1.3.1", @@ -23748,8 +46882,6 @@ }, "vue-template-compiler": { "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", - "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", "dev": true, "requires": { "de-indent": "^1.0.2", @@ -23758,8 +46890,6 @@ }, "w3c-hr-time": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, "requires": { "browser-process-hrtime": "^1.0.0" @@ -23767,8 +46897,6 @@ }, "w3c-xmlserializer": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", "dev": true, "requires": { "domexception": "^1.0.1", @@ -23778,8 +46906,6 @@ }, "walker": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { "makeerror": "1.0.12" @@ -23787,14 +46913,10 @@ }, "webidl-conversions": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, "websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "requires": { "http-parser-js": ">=0.5.1", @@ -23804,14 +46926,10 @@ }, "websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, "whatwg-encoding": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "dev": true, "requires": { "iconv-lite": "0.4.24" @@ -23819,14 +46937,10 @@ }, "whatwg-mimetype": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, "whatwg-url": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -23836,8 +46950,6 @@ }, "which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -23845,8 +46957,6 @@ }, "which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, "requires": { "is-bigint": "^1.0.1", @@ -23858,8 +46968,6 @@ }, "which-collection": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "dev": true, "requires": { "is-map": "^2.0.1", @@ -23870,20 +46978,14 @@ }, "which-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "which-pm-runs": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", "dev": true }, "which-typed-array": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", "dev": true, "requires": { "available-typed-arrays": "^1.0.5", @@ -23896,8 +46998,6 @@ }, "wide-align": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "requires": { "string-width": "^1.0.2 || 2" @@ -23905,8 +47005,6 @@ }, "widest-line": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { "string-width": "^4.0.0" @@ -23914,26 +47012,18 @@ "dependencies": { "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -23943,8 +47033,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -23954,20 +47042,14 @@ }, "word-wrap": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wordwrap": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", @@ -23976,14 +47058,10 @@ "dependencies": { "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -23991,8 +47069,6 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -24002,8 +47078,6 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -24013,14 +47087,10 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write-file-atomic": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { "imurmurhash": "^0.1.4", @@ -24031,8 +47101,6 @@ }, "ws": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "dev": true, "requires": { "async-limiter": "~1.0.0" @@ -24040,68 +47108,46 @@ }, "x-is-string": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", "dev": true }, "xdg-basedir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, "xml-name-validator": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, "xmlchars": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, "xmlhttprequest": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", "dev": true }, "xtend": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, "y18n": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, "yapool": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", "dev": true }, "yargs": { "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "dev": true, "requires": { "cliui": "^4.0.0", @@ -24120,8 +47166,6 @@ }, "yargs-parser": { "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -24130,8 +47174,6 @@ }, "yauzl": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { "buffer-crc32": "~0.2.3", @@ -24140,15 +47182,11 @@ }, "yn": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true }, "zwitch": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", "dev": true } } -} \ No newline at end of file +} From a27c38771605900ceae63abee8631f51ed54b8b8 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 13 Jan 2022 09:55:14 +0100 Subject: [PATCH 071/138] some improvements leave the camera in the same height during paning --- src/geo/transform.ts | 53 ++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 7801ce88914..0f0fc06dd4b 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -54,6 +54,7 @@ class Transform { _maxPitch: number; _center: LngLat; _elevation: number; + _pixelPerMeter: number; _edgeInsets: EdgeInsets; _constraining: boolean; _posMatrixCache: {[_: string]: mat4}; @@ -489,28 +490,36 @@ class Transform { return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); } + getCameraPosition() { + const lngLat = this.pointLocation(this.getCameraPoint()); + const altitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; + return { lngLat: lngLat, altitude: altitude }; + } + // this method only works in combination with freezeElevation, because in this case // this.elevation holds the old elevation value. - // FIMXE! currently this logic only works for camera pitch = 0 recalculateZoom() { - const elevation = this.getElevation(this.center); - const deltaElevation = + this.elevation - elevation; - if (!deltaElevation) return; - - const mercatorZPerMeter = mercatorZfromAltitude(1, this.center.lat); - // to calculate the elevation in meters for the current zoomlevel the formular from - // https://github.com/mapbox/mapbox-gl-js/pull/8830/files is used - const zoomElevation = this.cameraToCenterDistance / this.worldSize / mercatorZPerMeter; - // calculate the current total height of the camera, e.g. zoom-elevation + terrain-elevation in meters - // elevation1 = zoomElevation + this.elevation - // to get the same total camera height for a different terrain-elevation do - // elevation2 = cameraToCenterDistance / (2^zoom * tilesize) / mercatorZPerMeter - // now do - // elevation1 = elevation2 - // then solve the formular for zoom - const zoom = this.scaleZoom(this.cameraToCenterDistance / (zoomElevation + deltaElevation) / mercatorZPerMeter / this.tileSize); - this._elevation = elevation; - this.zoom = zoom; + // find position the camera is looking on + const center = this.pointLocation3D(this.centerPoint); + const elevation = this.getElevation(center); + const deltaElevation = + this.elevation - elevation; + if (!deltaElevation) return; + + // calculate mercator distance between camera & target + const cameraAltitude = this.getCameraPosition().altitude + this.elevation; + const cameraLngLat = this.pointLocation(this.getCameraPoint()); + const camera = MercatorCoordinate.fromLngLat(cameraLngLat, cameraAltitude); + const target = MercatorCoordinate.fromLngLat(center, elevation); + const dx = camera.x - target.x, dy = camera.y - target.y, dz = camera.z - target.z; + const distance = Math.sqrt(dx * dx + dy * dy + dz * dz); + + // from this distance we calculate the new zoomlevel + const zoom = this.scaleZoom(this.cameraToCenterDistance / distance / this.tileSize); + + // update matrices + this._elevation = elevation; + this._center = center; + this.zoom = zoom; } setLocationAtPoint(lnglat: LngLat, point: Point) { @@ -817,12 +826,12 @@ class Transform { const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * this.cameraToCenterDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); const point = this.point; const x = point.x, y = point.y; - const pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; + this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; // Calculate z distance of the farthest fragment that should be rendered. const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToCenterDistance; // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` - const farZ = (furthestDistance + elevation * pixelPerMeter / Math.cos(this._pitch)) * 1.01; + const farZ = (furthestDistance + elevation * this._pixelPerMeter / Math.cos(this._pitch)) * 1.01; // The larger the value of nearZ is // - the more depth precision is available for features (good) @@ -852,7 +861,7 @@ class Transform { this.mercatorMatrix = mat4.scale(new Float64Array(16) as any, m, vec3.fromValues(this.worldSize, this.worldSize, this.worldSize)); // scale vertically to meters per pixel (inverse of ground resolution): - mat4.scale(m, m, vec3.fromValues(1, 1, pixelPerMeter)); + mat4.scale(m, m, vec3.fromValues(1, 1, this._pixelPerMeter)); // matrix for conversion from location to screen coordinates this.pixelMatrix = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); From 4e5f5a88da4eb216482141ed0e0bc8063a320a64 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 13 Jan 2022 12:56:02 +0100 Subject: [PATCH 072/138] set default pitch back to 65, because of too much labels & missing sky --- src/ui/map.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/map.ts b/src/ui/map.ts index 3d08ab459ec..713b6a090b4 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -116,7 +116,7 @@ const defaultMaxZoom = 22; // the default values, but also the valid range const defaultMinPitch = 0; -const defaultMaxPitch = 75; +const defaultMaxPitch = 65; // use this variable to check maxPitch for validity const maxPitchThreshold = 85; From b2a730b5314f7b2e9f27c7db9658aba7082f4468 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 14 Jan 2022 08:39:26 +0100 Subject: [PATCH 073/138] fix "mismatched image size" errors in some of our stylesheets --- src/render/glyph_manager.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/render/glyph_manager.ts b/src/render/glyph_manager.ts index 14e3dfaa447..aa00e02d77d 100644 --- a/src/render/glyph_manager.ts +++ b/src/render/glyph_manager.ts @@ -195,15 +195,16 @@ export default class GlyphManager { }); } + const char = tinySDF.draw(String.fromCharCode(id)); return { id, - bitmap: new AlphaImage({width: 30, height: 30}, tinySDF.draw(String.fromCharCode(id)).data), + bitmap: new AlphaImage({width: char.width, height: char.height}, char.data), metrics: { - width: 24, - height: 24, - left: 0, - top: -8, - advance: 24 + width: char.glyphWidth, + height: char.glyphHeight, + left: char.glyphLeft, + top: char.glyphTop, + advance: char.glyphAdvance } }; } From 136b7d417f48a4fffe0cdec7adf0600c92f6c85a Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Fri, 14 Jan 2022 13:16:07 +0100 Subject: [PATCH 074/138] add default values during tinySDF generation --- src/render/glyph_manager.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/render/glyph_manager.ts b/src/render/glyph_manager.ts index aa00e02d77d..b0938e8ac7a 100644 --- a/src/render/glyph_manager.ts +++ b/src/render/glyph_manager.ts @@ -198,13 +198,13 @@ export default class GlyphManager { const char = tinySDF.draw(String.fromCharCode(id)); return { id, - bitmap: new AlphaImage({width: char.width, height: char.height}, char.data), + bitmap: new AlphaImage({width: char.width || 30, height: char.height || 30}, char.data), metrics: { - width: char.glyphWidth, - height: char.glyphHeight, - left: char.glyphLeft, - top: char.glyphTop, - advance: char.glyphAdvance + width: char.glyphWidth || 24, + height: char.glyphHeight || 24, + left: char.glyphLeft || 0, + top: char.glyphTop || -8, + advance: char.glyphAdvance || 24 } }; } From 7cf9085fd0450f9e77a9bd919fb4b7f445af5ee1 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 19 Jan 2022 15:20:30 +0100 Subject: [PATCH 075/138] fire "terrain" events --- src/ui/map.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ui/map.ts b/src/ui/map.ts index 31f81a6a0cb..920ca4b2708 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -1566,13 +1566,23 @@ class Map extends Camera { addTerrain(id: string, options?: {exaggeration: number; elevationOffset: number}) { this.isSourceLoaded(id); this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); + this.transform.updateElevation(); this.style.terrainSourceCache.update(this.transform); this._sourcesDirty = true; this._styleDirty = true; this.triggerRepaint(); + this.fire(new Event("terrain")); return this; } + /** + * Returns a Boolean indicating whether terrain is loaded. + * @returns {boolean} + */ + isTerrainLoaded() { + return this.style.terrainSourceCache.isEnabled(); + } + /** * Removes the 3D terrain mesh from the map. * @@ -1584,6 +1594,7 @@ class Map extends Camera { this.style.terrainSourceCache.disable(); this.transform.updateElevation(); this.triggerRepaint(); + this.fire(new Event("terrain")); return this; } From 94734caf6c20d6552937029f9f7ef005e23db076 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 19 Jan 2022 17:10:40 +0100 Subject: [PATCH 076/138] let use TerrainControl use terrain-Event --- src/ui/control/terrain_control.ts | 24 ++++++++++++++---------- src/ui/default_locale.ts | 5 +++-- src/ui/events.ts | 14 +++++++++++++- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/ui/control/terrain_control.ts b/src/ui/control/terrain_control.ts index c2b47fa1a8c..b358f9f14db 100644 --- a/src/ui/control/terrain_control.ts +++ b/src/ui/control/terrain_control.ts @@ -2,7 +2,7 @@ import DOM from '../../util/dom'; import {bindAll} from '../../util/util'; import type Map from '../map'; -import type {ControlPosition, IControl} from './control'; +import type {IControl} from './control'; type TerrainOptions = { id?: string; @@ -33,7 +33,7 @@ class TerrainControl implements IControl { bindAll([ '_toggleTerrain', - '_toggleTerrainIcon', + '_updateTerrainIcon', ], this); } @@ -45,12 +45,14 @@ class TerrainControl implements IControl { this._terrainButton.type = 'button'; this._terrainButton.addEventListener('click', this._toggleTerrain); - this._toggleTerrainIcon + this._updateTerrainIcon(); + this._map.on('terrain', this._updateTerrainIcon); return this._container; } onRemove() { DOM.remove(this._container); + this._map.off('terrain', this._updateTerrainIcon); this._map = undefined; } @@ -60,16 +62,18 @@ class TerrainControl implements IControl { } else { this._map.addTerrain(this.options.id, this.options.options) } - this._toggleTerrainIcon() + this._updateTerrainIcon() } - _toggleTerrainIcon() { - if (this._map.style.terrainSourceCache.isEnabled()) { - this._terrainButton.classList.add('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); - this._terrainButton.classList.remove('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + _updateTerrainIcon() { + this._terrainButton.classList.remove('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + this._terrainButton.classList.remove('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + if (this._map.isTerrainLoaded()) { + this._terrainButton.classList.add('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + this._terrainButton.title = this._map._getUIString(`TerrainControl.disableTerrain`); } else { - this._terrainButton.classList.add('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); - this._terrainButton.classList.remove('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); + this._terrainButton.classList.add('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); + this._terrainButton.title = this._map._getUIString(`TerrainControl.enableTerrain`); } } } diff --git a/src/ui/default_locale.ts b/src/ui/default_locale.ts index 3c29809a922..a3ea2bc0176 100644 --- a/src/ui/default_locale.ts +++ b/src/ui/default_locale.ts @@ -13,8 +13,9 @@ const defaultLocale = { 'ScaleControl.Meters': 'm', 'ScaleControl.Kilometers': 'km', 'ScaleControl.Miles': 'mi', - 'ScaleControl.NauticalMiles': 'nm' - + 'ScaleControl.NauticalMiles': 'nm', + 'TerrainControl.enableTerrain': 'Enable terrain', + 'TerrainControl.disableTerrain': 'Disable terrain' }; export default defaultLocale; diff --git a/src/ui/events.ts b/src/ui/events.ts index bef42e6bf4f..a63c5947fcb 100644 --- a/src/ui/events.ts +++ b/src/ui/events.ts @@ -311,6 +311,10 @@ export type MapDataEvent = { sourceDataType: MapSourceDataType; }; +export type MapTerrainEvent = { + type: 'terrain'; +}; + export type MapContextEvent = { type: 'webglcontextlost' | 'webglcontextrestored'; originalEvent: WebGLContextEvent; @@ -384,6 +388,8 @@ export type MapEventType = { pitchend: MapLibreEvent; wheel: MapWheelEvent; + + terrain: MapTerrainEvent; }; export type MapEvent = /** @@ -1341,4 +1347,10 @@ export type MapEvent = /** * @memberof Map * @instance * @private - */ | 'style.load'; + */ | 'style.load' +/** + * @event terrain + * @memberof Map + * @instance + * @private + */ | 'terrain'; From 2fc3a576b9794f2e4dc39b2017b085738e3db061 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 20 Jan 2022 10:27:15 +0100 Subject: [PATCH 077/138] typo --- debug/terrain_control.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug/terrain_control.html b/debug/terrain_control.html index 31fd37f34bb..67f21f8c4fb 100644 --- a/debug/terrain_control.html +++ b/debug/terrain_control.html @@ -36,7 +36,7 @@ }); map.addControl( new maplibregl.TerrainControl({ - id: "terrain" + id: "terrain", options: { exaggeration: 2, elevationOffset: 0 From ffc30c9bebb2ef1d6daf973355bed863356fa64a Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 20 Jan 2022 10:27:51 +0100 Subject: [PATCH 078/138] may fix farZ clippingplane calculation --- src/geo/transform.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 0f0fc06dd4b..fed62e7c7ac 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -821,17 +821,19 @@ class Transform { // center top point [width/2 + offset.x, 0] in Z units, using the law of sines. // 1 Z unit is equivalent to 1 horizontal px at the center of the map // (the distance between[width/2, height/2] and [width/2 + 1, height/2]) + this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; const groundAngle = Math.PI / 2 + this._pitch; const fovAboveCenter = this._fov * (0.5 + offset.y / this.height); - const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * this.cameraToCenterDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); + const cameraAltitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; + const cameraToCenterDistance = (cameraAltitude + elevation) * this._pixelPerMeter / Math.cos(this._pitch); + const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToCenterDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); const point = this.point; const x = point.x, y = point.y; - this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; // Calculate z distance of the farthest fragment that should be rendered. - const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToCenterDistance; + const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + cameraToCenterDistance; // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` - const farZ = (furthestDistance + elevation * this._pixelPerMeter / Math.cos(this._pitch)) * 1.01; + const farZ = furthestDistance * 1.01; // The larger the value of nearZ is // - the more depth precision is available for features (good) From 26a325ab98559331ae58caea15053942879e076f Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 20 Jan 2022 11:30:53 +0100 Subject: [PATCH 079/138] fix TileID-order of transform.coveringTiles result --- src/geo/transform.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index fed62e7c7ac..b9c88675f34 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -351,10 +351,12 @@ class Transform { if (options.minzoom !== undefined && z < options.minzoom) return []; if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom; - const centerCoord = tsc.isEnabled() + const cameraCoord = tsc.isEnabled() ? this.pointCoordinate(this.getCameraPoint()) : MercatorCoordinate.fromLngLat(this.center); + const centerCoord = MercatorCoordinate.fromLngLat(this.center); const numTiles = Math.pow(2, z); + const cameraPoint = [numTiles * cameraCoord.x, numTiles * cameraCoord.y, 0]; const centerPoint = [numTiles * centerCoord.x, numTiles * centerCoord.y, 0]; const cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix, this.worldSize, z); @@ -410,8 +412,8 @@ class Transform { fullyVisible = intersectResult === 2; } - const distanceX = it.aabb.distanceX(centerPoint); - const distanceY = it.aabb.distanceY(centerPoint); + const distanceX = it.aabb.distanceX(cameraPoint); + const distanceY = it.aabb.distanceY(cameraPoint); const longestDim = Math.max(Math.abs(distanceX), Math.abs(distanceY)); // We're using distance based heuristics to determine if a tile should be split into quadrants or not. From 0ca71480d45615a53f7231ae7559ad52a5954058 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 20 Jan 2022 11:38:13 +0100 Subject: [PATCH 080/138] call transform.updateElevation on every rendering --- src/source/terrain_source_cache.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 84f96dc02b9..5cc2c966ee1 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -213,6 +213,7 @@ class TerrainSourceCache extends Evented { update(transform: Transform): void { if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; // load raster-dem tiles for the current scene. + transform.updateElevation(); this._sourceCache.update(transform); this._renderableTiles = []; const tileIDs = {}; From c5ef8009c3e58735bb073674def5a7086e348986 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 8 Feb 2022 08:30:30 +0100 Subject: [PATCH 081/138] rerender rtt tiles on geojson.setData --- src/geo/transform.ts | 9 +++---- src/render/painter.ts | 39 ++++++++++++++++++------------ src/source/terrain_source_cache.ts | 15 +++++++++--- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index b9c88675f34..d03c42d0b4b 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -495,7 +495,7 @@ class Transform { getCameraPosition() { const lngLat = this.pointLocation(this.getCameraPoint()); const altitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; - return { lngLat: lngLat, altitude: altitude }; + return { lngLat: lngLat, altitude: altitude + this.elevation }; } // this method only works in combination with freezeElevation, because in this case @@ -508,9 +508,8 @@ class Transform { if (!deltaElevation) return; // calculate mercator distance between camera & target - const cameraAltitude = this.getCameraPosition().altitude + this.elevation; - const cameraLngLat = this.pointLocation(this.getCameraPoint()); - const camera = MercatorCoordinate.fromLngLat(cameraLngLat, cameraAltitude); + const cameraPosition = this.getCameraPosition(); + const camera = MercatorCoordinate.fromLngLat(cameraPosition.lngLat, cameraPosition.altitude); const target = MercatorCoordinate.fromLngLat(center, elevation); const dx = camera.x - target.x, dy = camera.y - target.y, dz = camera.z - target.z; const distance = Math.sqrt(dx * dx + dy * dy + dz * dz); @@ -645,7 +644,7 @@ class Transform { return new MercatorCoordinate( (tile.tileID.canonical.x * coordsSize + x) / worldSize, (tile.tileID.canonical.y * coordsSize + y) / worldSize, - this.terrainSourceCache.getElevation(tile.tileID, x, y, coordsSize) + this.terrainSourceCache.getElevationWithExaggeration(tile.tileID, x, y, coordsSize) ); } diff --git a/src/render/painter.ts b/src/render/painter.ts index af1a927871f..d212383390f 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -375,7 +375,8 @@ class Painter { const layerIds = this.style._order; const sourceCaches = this.style.sourceCaches; const renderToTexture = { background: true, fill: true, line: true, raster: true }; - const isTerrainEnabled = this.style.terrainSourceCache.isEnabled(); + const tsc = this.style.terrainSourceCache + const isTerrainEnabled = tsc.isEnabled(); for (const id in sourceCaches) { const sourceCache = sourceCaches[id]; @@ -401,7 +402,7 @@ class Painter { if (isTerrainEnabled) { coordsDescendingInv[id] = {}; for (let c=0; c { - // rerender if there are more coords to render than in the last rendering for (let source in coordsDescendingInvStr) { + // rerender if there are more coords to render than in the last rendering const coords = coordsDescendingInvStr[source][tile.tileID.key]; if (coords && coords != tile.textureCoords[source]) tile.clearTextures(this); + // rerender if terrainSourceCache has marked tile for rerender + if (tsc.rerender[source] && tsc.rerender[source][tile.tileID.key]) tile.clearTextures(this); } // rerender if there are no previous renderings rerender[tile.tileID.key] = !tile.textures.length; }); + // reset terrainSource rerender cache + tsc.rerender = {}; } for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { @@ -517,23 +522,27 @@ class Painter { // due that switching textures is relatively slow, the render // layer-by-layer context here is not practicable. To bypass this problem // this lines of code stack all layers and later render all at once. - // Because of the stylesheet possibility to mixing render-to-texture layers and 'live'-layers - // and 'live'-layers it is necessary to create more stacks. For example + // Because of the stylesheet possibility to mixing render-to-texture layers + // and 'live'-layers (f.e. symbols) it is necessary to create more stacks. For example // a symbol-layer is in between of fill-layers. + const isLastLayer = this.currentLayer + 1 == layerIds.length; + // remember background, fill, line & raster layer to render into a stack if (renderToTexture[type]) { if (!prevType || !renderToTexture[prevType]) stacks.push([]); prevType = type; stacks[stacks.length-1].push(layerIds[this.currentLayer]); - continue; // rendering is done later, all in once + // rendering is done later, all in once + if (!isLastLayer) continue; + } // in case a stack is finished render all collected stack-layers into a texture - } else if (renderToTexture[prevType] || type == "hillshade") { + if (renderToTexture[prevType] || type == "hillshade" || (renderToTexture[type] && isLastLayer)) { prevType = type; const stack = stacks.length - 1, layers = stacks[stack] || []; for (const tile of renderableTiles) { - prepareTerrain(this, this.style.terrainSourceCache, tile, stack); + prepareTerrain(this, tsc, tile, stack); if (rerender[tile.tileID.key]) { this.context.clear({ color: Color.transparent }); for (let l=0; l { if (e.dataType == "source" && e.coord && this.isEnabled()) { - const transform = style.map.transform; + // redraw current and overscaled terrain-tiles if (e.sourceId == this._sourceCache.id) { - // redraw current and overscaled terrain-tiles for (const key in this._tiles) { const tile = this._tiles[key]; if (tile.tileID.equals(e.coord) || tile.tileID.isChildOf(e.coord)) { @@ -163,7 +165,12 @@ class TerrainSourceCache extends Evented { tile.clearTextures(this._style.map.painter); } } - transform.updateElevation(); + style.map.transform.updateElevation(); + } + // remember GeoJson tile updates in rerender cache + if (e.source.type == "geojson") { + this.rerender[e.sourceId] = this.rerender[e.sourceId] || {}; + this.rerender[e.sourceId][e.tile.tileID.key] = true; } } }); @@ -416,7 +423,7 @@ class TerrainSourceCache extends Evented { */ getFramebuffer(painter: Painter, texture: string): Framebuffer { const width = painter.width / devicePixelRatio; - const height = painter.height / devicePixelRatio; + const height = painter.height / devicePixelRatio; if (this._fbo && (this._fbo.width != width || this._fbo.height != height)) { this._fbo.destroy(); this._fboCoordsTexture.destroy(); From e1c00c72ea014bc92a577ab4fbfc847d47dc1809 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 8 Feb 2022 09:54:40 +0100 Subject: [PATCH 082/138] freezeElevation while camera-easing --- src/ui/camera.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ui/camera.ts b/src/ui/camera.ts index dd667c9822c..e50e8247a45 100644 --- a/src/ui/camera.ts +++ b/src/ui/camera.ts @@ -889,6 +889,7 @@ abstract class Camera extends Evented { _prepareEase(eventData: any, noMoveStart: boolean, currently: any = {}) { this._moving = true; + this.transform.freezeElevation = true; if (!noMoveStart && !currently.moving) { this.fire(new Event('movestart', eventData)); @@ -924,6 +925,8 @@ abstract class Camera extends Evented { return; } delete this._easeId; + this.transform.freezeElevation = false; + this.transform.recalculateZoom(); const wasZooming = this._zooming; const wasRotating = this._rotating; From 84674ef7df31c1c209404d1015b3d30cb5f7e79d Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 10 Feb 2022 16:05:45 +0100 Subject: [PATCH 083/138] make tests running --- debug/terrain.html | 4 +- debug/terrain_control.html | 4 +- src/data/dem_data.test.ts | 13 ++++- src/data/dem_data.ts | 26 +++------ src/geo/transform.ts | 28 +++++----- src/render/draw_heatmap.ts | 7 ++- src/render/draw_terrain.ts | 7 +-- src/render/program/hillshade_program.ts | 2 +- src/source/raster_dem_tile_source.ts | 2 +- src/source/source_cache.ts | 6 +-- src/source/terrain_source_cache.ts | 50 ++++++++++-------- src/source/worker_source.ts | 2 +- src/style-spec/reference/v8.json | 3 -- src/style-spec/types.ts | 2 +- src/style/style.ts | 2 +- src/symbol/placement.ts | 4 +- src/ui/camera.ts | 3 +- src/ui/handler_manager.ts | 7 +-- src/ui/map.ts | 2 +- src/ui/marker.ts | 2 +- src/util/primitives.ts | 1 - .../expected.png | Bin 2915 -> 2773 bytes .../collision-pitched-wrapped/expected.png | Bin 108681 -> 109734 bytes .../debug/collision-pitched/expected.png | Bin 32739 -> 33675 bytes .../render/tests/debug/collision/expected.png | Bin 68217 -> 68446 bytes 25 files changed, 92 insertions(+), 85 deletions(-) diff --git a/debug/terrain.html b/debug/terrain.html index 0a6d37faccb..c24f4bca0d4 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -31,10 +31,10 @@ map.addSource('terrain', { 'type': 'raster-dem', 'tiles': ['https://vtc-cdn.maptoolkit.net/terrainrgb/{z}/{x}/{y}.webp'], - 'encoding': 'mtk', + 'encoding': 'mapbox', 'maxzoom': 14 }); - map.addTerrain('terrain'); + map.addTerrain('terrain', {exaggeration: 0.33}); }); map.on('click', e => { diff --git a/debug/terrain_control.html b/debug/terrain_control.html index 8f33d1d3c09..c3e781daba0 100644 --- a/debug/terrain_control.html +++ b/debug/terrain_control.html @@ -31,14 +31,14 @@ map.addSource('terrain', { 'type': 'raster-dem', 'tiles': ['https://vtc-cdn.maptoolkit.net/terrainrgb/{z}/{x}/{y}.webp'], - 'encoding': 'mtk', + 'encoding': 'mapbox', 'maxzoom': 14 }); map.addControl( new maplibregl.TerrainControl({ id: 'terrain', options: { - exaggeration: 2, + exaggeration: 0.33, elevationOffset: 0 } }) diff --git a/src/data/dem_data.test.ts b/src/data/dem_data.test.ts index 4380c0a7c57..0101fdb5fba 100644 --- a/src/data/dem_data.test.ts +++ b/src/data/dem_data.test.ts @@ -222,13 +222,24 @@ describe('DEMData is correctly serialized and deserialized', () => { const dem0 = new DEMData('0', imageData0, 'mapbox'); const serialized = serialize(dem0); + // calculate min/max values + let min = Number.MAX_SAFE_INTEGER; + let max = Number.MIN_SAFE_INTEGER; + for (let x = 0; x < 4; x++) for (let y = 0; y < 4; y++) { + const ele = dem0.get(x, y); + if (ele > max) max = ele; + if (ele < min) min = ele; + } + expect(serialized).toEqual({ $name: 'DEMData', uid: '0', dim: 4, stride: 6, data: dem0.data, - encoding: 'mapbox' + encoding: 'mapbox', + max: max, + min: min, }); const transferrables = []; diff --git a/src/data/dem_data.ts b/src/data/dem_data.ts index 3e3ac37b2b6..d90ff34dd9a 100644 --- a/src/data/dem_data.ts +++ b/src/data/dem_data.ts @@ -20,15 +20,15 @@ export default class DEMData { dim: number; min: number; max: number; - encoding: 'mapbox' | 'terrarium' | 'mtk'; + encoding: 'mapbox' | 'terrarium'; // RGBAImage data has uniform 1px padding on all sides: square tile edge size defines stride // and dim is calculated as stride - 2. - constructor(uid: string, data: RGBAImage, encoding: 'mapbox' | 'terrarium' | 'mtk') { + constructor(uid: string, data: RGBAImage, encoding: 'mapbox' | 'terrarium') { this.uid = uid; if (data.height !== data.width) throw new RangeError('DEM tiles must be square'); - if (encoding && encoding !== 'mapbox' && encoding !== 'terrarium' && encoding !== 'mtk') { - warnOnce(`"${encoding}" is not a valid encoding type. Valid types include "mapbox", "mtk" and "terrarium".`); + if (encoding && encoding !== 'mapbox' && encoding !== 'terrarium') { + warnOnce(`"${encoding}" is not a valid encoding type. Valid types include "mapbox" and "terrarium".`); return; } this.stride = data.height; @@ -68,22 +68,12 @@ export default class DEMData { get(x: number, y: number) { const pixels = new Uint8Array(this.data.buffer); const index = this._idx(x, y) * 4; - let unpack = this._unpackMapbox; - if (this.encoding === 'terrarium') unpack = this._unpackTerrarium; - if (this.encoding === 'mtk') unpack = this._unpackMTK; + const unpack = this.encoding === 'terrarium' ? this._unpackTerrarium : this._unpackMapbox; return unpack(pixels[index], pixels[index + 1], pixels[index + 2]); } - // when using MTK encoding the hillshading looks ugly, so still use mapbox encoding - getHillshadingUnpackVector() { - if (this.encoding === 'terrarium') return [256.0, 1.0, 1.0 / 256.0, 32768.0]; - return [6553.6, 25.6, 0.1, 10000.0]; - } - getUnpackVector() { - if (this.encoding === 'terrarium') return [256.0, 1.0, 1.0 / 256.0, 32768.0]; - if (this.encoding === 'mtk') return [65536.0 * 0.03, 256.0 * 0.03, 0.03, 10000.0]; - return [6553.6, 25.6, 0.1, 10000.0]; + return this.encoding === 'terrarium' ? [256.0, 1.0, 1.0 / 256.0, 32768.0] : [6553.6, 25.6, 0.1, 10000.0]; } _idx(x: number, y: number) { @@ -97,10 +87,6 @@ export default class DEMData { return ((r * 256 * 256 + g * 256.0 + b) / 10.0 - 10000.0); } - _unpackMTK(r: number, g: number, b: number) { - return ((r * 256 * 256 + g * 256.0 + b) * 0.03 - 10000.0); - } - _unpackTerrarium(r: number, g: number, b: number) { // unpacking formula for mapzen terrarium: // https://aws.amazon.com/public-datasets/terrain/ diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 34deb4a76f4..16684d51367 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -351,7 +351,7 @@ class Transform { if (options.minzoom !== undefined && z < options.minzoom) return []; if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom; - const cameraCoord = tsc.isEnabled() ? + const cameraCoord = (tsc && tsc.isEnabled()) ? this.pointCoordinate(this.getCameraPoint()) : MercatorCoordinate.fromLngLat(this.center); const centerCoord = MercatorCoordinate.fromLngLat(this.center); @@ -363,7 +363,7 @@ class Transform { // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level let minZoom = options.minzoom || 0; // Use 0.1 as an epsilon to avoid for explicit == 0.0 floating point checks - if (!tsc.isEnabled() && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) + if (!(tsc && tsc.isEnabled()) && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) minZoom = z; // There should always be a certain number of maximum zoom level tiles surrounding the center location @@ -437,7 +437,7 @@ class Transform { const childY = (y << 1) + (i >> 1); const childZ = it.zoom + 1; let quadrant = it.aabb.quadrant(i); - if (tsc.isEnabled()) { + if (tsc && tsc.isEnabled()) { const tile = tsc.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY)); quadrant = new Aabb( vec3.fromValues(quadrant.min[0], quadrant.min[1], tile && tile.dem ? tile.dem.min - this.elevation : -this.elevation), @@ -489,7 +489,7 @@ class Transform { const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); const tileID = new OverscaledTileID(this.tileZoom, 0, this.tileZoom, tileX, tileY); - return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); + return this.terrainSourceCache.getElevationWithExaggeration(tileID, mercX % tileSize, mercY % tileSize, tileSize); } getCameraPosition() { @@ -498,9 +498,10 @@ class Transform { return {lngLat, altitude: altitude + this.elevation}; } - // this method only works in combination with freezeElevation, because in this case - // this.elevation holds the old elevation value. + // this method only works in combination with elevation enabled and freezeElevation activated, + // because only in this case this.elevation holds the old elevation value. recalculateZoom() { + if (!this.terrainSourceCache || !this.terrainSourceCache.isEnabled()) return; // find position the camera is looking on const center = this.pointLocation3D(this.centerPoint); const elevation = this.getElevation(center); @@ -627,6 +628,7 @@ class Transform { // FIX ME-3D! mouseout events may contains coordinates outside the coords-framebuffer pointCoordinate3D(p: Point) { + if (!this.terrainSourceCache) return this.pointCoordinate(p); const rgba = new Uint8Array(4); const painter = this.terrainSourceCache._style.map.painter, context = painter.context, gl = context.gl; // grab coordinate pixel from coordinates framebuffer @@ -656,7 +658,7 @@ class Transform { * @private */ coordinatePoint(coord: MercatorCoordinate, elevation: number = 0) { - const p = vec4.fromValues(coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1); + const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1] as any; vec4.transformMat4(p, p, this.pixelMatrix2); return new Point(p[0] / p[3], p[1] / p[3]); } @@ -801,8 +803,6 @@ class Transform { _calcMatrices() { if (!this.height) return; - const exaggeration = this.terrainSourceCache ? this.terrainSourceCache.exaggeration : 1.0; - const elevation = this._elevation * exaggeration; const halfFov = this._fov / 2; const offset = this.centerOffset; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; @@ -826,7 +826,9 @@ class Transform { const groundAngle = Math.PI / 2 + this._pitch; const fovAboveCenter = this._fov * (0.5 + offset.y / this.height); const cameraAltitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; - const cameraToCenterDistance = (cameraAltitude + elevation) * this._pixelPerMeter / Math.cos(this._pitch); + const cameraToCenterDistance = this.terrainSourceCache && this.terrainSourceCache.isEnabled() ? + (cameraAltitude + this._elevation) * this._pixelPerMeter / Math.cos(this._pitch) : + this.cameraToCenterDistance; const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToCenterDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); const point = this.point; const x = point.x, y = point.y; @@ -861,7 +863,7 @@ class Transform { // The mercatorMatrix can be used to transform points from mercator coordinates // ([0, 0] nw, [1, 1] se) to GL coordinates. - this.mercatorMatrix = mat4.scale(new Float64Array(16) as any, m, vec3.fromValues(this.worldSize, this.worldSize, this.worldSize)); + this.mercatorMatrix = mat4.scale([] as any, m, vec3.fromValues(this.worldSize, this.worldSize, this.worldSize)); // scale vertically to meters per pixel (inverse of ground resolution): mat4.scale(m, m, vec3.fromValues(1, 1, this._pixelPerMeter)); @@ -870,8 +872,8 @@ class Transform { this.pixelMatrix = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); // matrix for conversion from location to GL coordinates (-1 .. 1) - this.invProjMatrix = mat4.invert(new Float64Array(16) as any, m); - mat4.translate(m, m, [0, 0, -elevation]); // elevate camera over terrain + this.invProjMatrix = mat4.invert([] as any, m); + mat4.translate(m, m, [0, 0, -this.elevation]); // elevate camera over terrain this.projMatrix = m; this.pixelMatrix2 = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); diff --git a/src/render/draw_heatmap.ts b/src/render/draw_heatmap.ts index e92c3f25f57..c81572bc400 100644 --- a/src/render/draw_heatmap.ts +++ b/src/render/draw_heatmap.ts @@ -51,11 +51,10 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('heatmap', programConfiguration); const {zoom} = painter.transform; - const terrain = painter.style.terrainSourceCache.getTerrain(coord); program.draw(context, gl.TRIANGLES, DepthMode.disabled, stencilMode, colorMode, CullFaceMode.disabled, - heatmapUniformValues(coord.posMatrix, tile, zoom, layer.paint.get('heatmap-intensity')), - terrain, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, + heatmapUniformValues(coord.posMatrix, tile, zoom, layer.paint.get('heatmap-intensity')), null, + layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration); } @@ -125,7 +124,7 @@ function renderTextureToMap(painter, layer) { painter.useProgram('heatmapTexture').draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, - heatmapTextureUniformValues(painter, layer, 0, 1), + heatmapTextureUniformValues(painter, layer, 0, 1), null, // FIX ME-3D render onto terrain-mesh layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments, layer.paint, painter.transform.zoom); } diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index ca282a8eff4..5e41565ae00 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -73,7 +73,7 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Ti context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, sourceCache.rttFramebuffer.colorAttachment.get()); + gl.bindTexture(gl.TEXTURE_2D, sourceCache.getRTTFramebuffer(painter).colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); const uniformValues = terrainUniformValues(posMatrix); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); @@ -95,8 +95,9 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: tile.textures[stack].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); if (stack === 0) sourceCache._renderHistory.push(tile.tileID.key); } - sourceCache.rttFramebuffer.colorAttachment.set(tile.textures[stack].texture); - context.bindFramebuffer.set(sourceCache.rttFramebuffer.framebuffer); + const fb = sourceCache.getRTTFramebuffer(painter); + fb.colorAttachment.set(tile.textures[stack].texture); + context.bindFramebuffer.set(fb.framebuffer); context.viewport.set([0, 0, size, size]); } diff --git a/src/render/program/hillshade_program.ts b/src/render/program/hillshade_program.ts index b285ea938bf..81a29165d09 100644 --- a/src/render/program/hillshade_program.ts +++ b/src/render/program/hillshade_program.ts @@ -95,7 +95,7 @@ const hillshadeUniformPrepareValues = (tileID: OverscaledTileID, dem: DEMData): 'u_image': 1, 'u_dimension': [stride, stride], 'u_zoom': tileID.overscaledZ, - 'u_unpack': dem.getHillshadingUnpackVector() + 'u_unpack': dem.getUnpackVector() }; }; diff --git a/src/source/raster_dem_tile_source.ts b/src/source/raster_dem_tile_source.ts index 5e17e4d78d1..8b69e8dc96a 100644 --- a/src/source/raster_dem_tile_source.ts +++ b/src/source/raster_dem_tile_source.ts @@ -15,7 +15,7 @@ import type {Callback} from '../types/callback'; import type {RasterDEMSourceSpecification} from '../style-spec/types'; class RasterDEMTileSource extends RasterTileSource implements Source { - encoding: 'mapbox' | 'terrarium' | 'mtk'; + encoding: 'mapbox' | 'terrarium'; constructor(id: string, options: RasterDEMSourceSpecification, dispatcher: Dispatcher, eventedParent: Evented) { super(id, options, dispatcher, eventedParent); diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 06095c999ba..2305b732f03 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -568,7 +568,7 @@ class SourceCache extends Evented { // disable fading logic in renderToTexture (e.g. 3D) mode // e.g. avoid rendering two tiles on the same place - if (this.style.terrainSourceCache && this.style.terrainSourceCache.isEnabled()) { + if (this.style && this.style.terrainSourceCache && this.style.terrainSourceCache.isEnabled()) { const idealRasterTileIDs: {[_: string]: OverscaledTileID} = {}; const missingTileIDs: {[_: string]: OverscaledTileID} = {}; for (const tileID of idealTileIDs) { @@ -585,7 +585,7 @@ class SourceCache extends Evented { idealRasterTileIDs[children[1].key] = retain[children[1].key] = children[1]; idealRasterTileIDs[children[2].key] = retain[children[2].key] = children[2]; idealRasterTileIDs[children[3].key] = retain[children[3].key] = children[3]; - delete (missingTileIDs[key]); + delete missingTileIDs[key]; } } // search for parent for each missing tile @@ -595,7 +595,7 @@ class SourceCache extends Evented { idealRasterTileIDs[parent.tileID.key] = retain[parent.tileID.key] = parent.tileID; // remove idealTiles which would be rendered twice for (const key in idealRasterTileIDs) { - if (idealRasterTileIDs[key].isChildOf(parent.tileID)) delete (idealRasterTileIDs[key]); + if (idealRasterTileIDs[key].isChildOf(parent.tileID)) delete idealRasterTileIDs[key]; } } } diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 231376bdc77..2b849c1fea0 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -7,7 +7,7 @@ import Style from '../style/style'; import Texture from '../render/texture'; import {RGBAImage} from '../util/image'; import {PosArray, TriangleIndexArray} from '../data/array_types.g'; -import {number as mix} from '../style-spec/util/interpolate.js'; +import {number as mix} from '../style-spec/util/interpolate'; import posAttributes from '../data/pos_attributes'; import SegmentVector from '../data/segment'; import type Transform from '../geo/transform'; @@ -87,6 +87,8 @@ class TerrainSourceCache extends Evented { // because of overzooming raster-dem tiles this cache holds the corresponding // raster-dem-tile for a vector-tile. _sourceTileCache: {[_: string]: string}; + // framebuffer-object to render tiles to texture + _rttFramebuffer: Framebuffer; // minimum zoomlevel to render the terrain. minzoom: number; // maximum zoomlevel to render the terrain. @@ -107,8 +109,6 @@ class TerrainSourceCache extends Evented { // a lot of terrain-dem tiles with very low visual advantage. So with this setting // the raster-dem tiles will load for the actualZoom - deltaZoom zoom-level. deltaZoom: number; - // framebuffer-object to render tiles to texture - rttFramebuffer: Framebuffer; // remember all tiles which contains new data for a spezific source and tile-key. rerender: {[_: string]: {[_: number]: boolean}}; @@ -135,23 +135,6 @@ class TerrainSourceCache extends Evented { this.deltaZoom = 1; this.rerender = {}; - // create empty DEM Obejcts, which will used while raster-dem tiles will load. - const context = style.map.painter.context; - this._emptyDemUnpack = [0, 0, 0, 0]; - this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); - this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - this._emptyDemMatrix = mat4.identity([] as any); - - // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. - const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); - const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); - this._emptyDepthTexture = texture; - - // create the render-to-texture framebuffer - const size = this.tileSize * this.qualityFactor; - this.rttFramebuffer = context.createFramebuffer(size, size, true); - this.rttFramebuffer.depthAttachment.set(context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, size, size)); - // rerender corresponding tiles on terrain-dem source-tile updates style.on('data', e => { if (e.dataType === 'source' && e.coord && this.isEnabled()) { @@ -247,7 +230,7 @@ class TerrainSourceCache extends Evented { const tile = this._tiles[this._renderHistory.shift()]; if (tile && !tileIDs[tile.tileID.key]) { tile.clearTextures(this._style.map.painter); - delete (this._tiles[tile.tileID.key]); + delete this._tiles[tile.tileID.key]; } } } @@ -338,6 +321,17 @@ class TerrainSourceCache extends Evented { */ getTerrain(tileID?: OverscaledTileID): any { if (!this.isEnabled() || !tileID) return null; + // create empty DEM Obejcts, which will used while raster-dem tiles will load. + // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. + if (!this._emptyDemTexture) { + const context = this._style.map.painter.context; + const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); + this._emptyDepthTexture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); + this._emptyDemUnpack = [0, 0, 0, 0]; + this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); + this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + this._emptyDemMatrix = mat4.identity([] as any); + } // find covering dem tile and prepare demTexture const sourceTile = this.getSourceTile(tileID, true); if (sourceTile && sourceTile.dem && (!sourceTile.demTexture || sourceTile.needsTerrainPrepare)) { @@ -418,6 +412,20 @@ class TerrainSourceCache extends Evented { return this.getElevation(tileID, x, y, extent) * this.exaggeration; } + /** + * create the render-to-texture framebuffer + * @param {Painter} painter + * @returns {Framebuffer} + */ + getRTTFramebuffer(painter: Painter) { + if (!this._rttFramebuffer) { + const size = this.tileSize * this.qualityFactor; + this._rttFramebuffer = painter.context.createFramebuffer(size, size, true); + this._rttFramebuffer.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, size, size)); + } + return this._rttFramebuffer; + } + /** * get a framebuffer as big as the map-div, which will be used to render depth & coords into a texture * @param {Painter} painter diff --git a/src/source/worker_source.ts b/src/source/worker_source.ts index 9f4a801d7ba..8695d4ba0c4 100644 --- a/src/source/worker_source.ts +++ b/src/source/worker_source.ts @@ -37,7 +37,7 @@ export type WorkerDEMTileParameters = TileParameters & { w: number; }; rawImageData: RGBAImage | ImageBitmap; - encoding: 'mapbox' | 'terrarium' | 'mtk'; + encoding: 'mapbox' | 'terrarium'; }; export type WorkerTileResult = { diff --git a/src/style-spec/reference/v8.json b/src/style-spec/reference/v8.json index ba67645368c..bff35d4ec41 100644 --- a/src/style-spec/reference/v8.json +++ b/src/style-spec/reference/v8.json @@ -336,9 +336,6 @@ "terrarium": { "doc": "Terrarium format PNG tiles. See https://aws.amazon.com/es/public-datasets/terrain/ for more info." }, - "mtk": { - "doc": "MTK format PNG tiles." - }, "mapbox": { "doc": "Mapbox Terrain RGB tiles. See https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb for more info." } diff --git a/src/style-spec/types.ts b/src/style-spec/types.ts index a1563cf31cf..d2db980ccc5 100644 --- a/src/style-spec/types.ts +++ b/src/style-spec/types.ts @@ -134,7 +134,7 @@ export type RasterDEMSourceSpecification = { "maxzoom"?: number, "tileSize"?: number, "attribution"?: string, - "encoding"?: "terrarium" | "mtk" | "mapbox", + "encoding"?: "terrarium" | "mapbox", "volatile"?: boolean }; diff --git a/src/style/style.ts b/src/style/style.ts index 3b3afa0d756..56f204d84f2 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -158,7 +158,7 @@ class Style extends Evented { this._availableImages = []; // make elevation accessible from map.transform - map.transform.terrainSourceCache = this.terrainSourceCache; + if (map.transform) map.transform.terrainSourceCache = this.terrainSourceCache; this._resetUpdates(); diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index 330e5bcda37..e389c3946fc 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -492,7 +492,9 @@ export class Placement { // update elevation of collisionArrays const tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; - const getElevation = (x: number, y: number) => this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y); + const getElevation = (x: number, y: number) => this.transform.terrainSourceCache ? + this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y) : + 0; for (const boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { const box = collisionArrays[boxType]; if (box) box.elevation = getElevation(box.anchorPointX, box.anchorPointY); diff --git a/src/ui/camera.ts b/src/ui/camera.ts index 67b229511e0..663b7dc63fe 100644 --- a/src/ui/camera.ts +++ b/src/ui/camera.ts @@ -935,7 +935,8 @@ abstract class Camera extends Evented { } delete this._easeId; this.transform.freezeElevation = false; - this.transform.recalculateZoom(); + if (this.transform.terrainSourceCache && this.transform.terrainSourceCache.isEnabled()) + this.transform.recalculateZoom(); const wasZooming = this._zooming; const wasRotating = this._rotating; diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index 381052cd4f0..1aadb1f619e 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -415,8 +415,9 @@ class HandlerManager { _updateMapTransform(combinedResult: any, combinedEventsInProgress: any, deactivatedHandlers: any) { const map = this._map; const tr = map.transform; + const hasTerrain = map.style && map.style.terrainSourceCache && map.style.terrainSourceCache.isEnabled(); - if (!hasChange(combinedResult) && !this._drag) { + if (!hasChange(combinedResult) && !(hasTerrain && this._drag)) { return this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); } @@ -447,7 +448,7 @@ class HandlerManager { // when dragging ends, recalcuate the zoomlevel for the new center coordinate } else if (this._drag && deactivatedHandlers[this._drag.handlerName]) { tr.freezeElevation = false; - tr.recalculateZoom(); + if (hasTerrain) tr.recalculateZoom(); this._drag = null; // drag map } else if (combinedEventsInProgress.drag && this._drag) { @@ -456,7 +457,7 @@ class HandlerManager { // of the picked point. With this approach it is no longer possible to pick a point from // from somewhere near the horizon to the center in one move. // So this logic avoids the problem, that in such cases you easily loose orientation. - if (map.style.terrainSourceCache.isEnabled()) { + if (hasTerrain) { tr.center = tr.pointLocation(tr.centerPoint.sub(panDelta)); // in flat mode leave all es it is. e.g. drag the picked point directly to the new posistion. } else { diff --git a/src/ui/map.ts b/src/ui/map.ts index 85dd8a79739..478a095841b 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -117,7 +117,7 @@ const defaultMaxZoom = 22; // the default values, but also the valid range const defaultMinPitch = 0; -const defaultMaxPitch = 65; +const defaultMaxPitch = 60; // use this variable to check maxPitch for validity const maxPitchThreshold = 85; diff --git a/src/ui/marker.ts b/src/ui/marker.ts index a67a9f24f44..9eb516e526d 100644 --- a/src/ui/marker.ts +++ b/src/ui/marker.ts @@ -472,7 +472,7 @@ export default class Marker extends Evented { DOM.setTransform(this._element, `${anchorTranslate[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${pitch} ${rotation}`); // in case of 3D, ask the the terrain coords-framebuffer for this pos and check if the marker is visible - const tsc = this._map.style.terrainSourceCache; + const tsc = this._map.style && this._map.style.terrainSourceCache; if (tsc && tsc.isEnabled() && !this._opacityTimeout) this._opacityTimeout = setTimeout(() => { const lnglat = this._map.unproject(this._pos); const metresPerPixel = 40075016.686 * Math.abs(Math.cos(this._lngLat.lat * Math.PI / 180)) / Math.pow(2, this._map.transform.tileZoom + 8); diff --git a/src/util/primitives.ts b/src/util/primitives.ts index dc55c7572ad..4f9b1adbf99 100644 --- a/src/util/primitives.ts +++ b/src/util/primitives.ts @@ -1,5 +1,4 @@ import {mat4, vec3, vec4} from 'gl-matrix'; -import assert from 'assert'; class Frustum { diff --git a/test/integration/render/tests/debug/collision-icon-text-point-translate/expected.png b/test/integration/render/tests/debug/collision-icon-text-point-translate/expected.png index bb2a67c4964628b7aecc115743b8de112b6272d7..4786207deddbb11e5a10be2a0c90b2ca169f10f4 100644 GIT binary patch literal 2773 zcmd^BXH*kd77h>y1VeO1gh+8FI);w)p#>A9h`~q@lomulkS-*5K!-0S3)%zGf}*;M}YO!2HKEWLO?m$(KIp*_R! z4)b=pWC>C;poYsSumWhEJr7Yji^M-exYeT3;$e)(T~Hvd2yE->J#|hE<-qI_icK zuaFoDO=$82B9oH6`)JvY{=~Vh0AB&-oaC>Jp0+P>6LeIMg!Dk%J{215a~ z{A?kU1OiDj25<B>o;3H$nvz1>EP{{e+-fZRV9#e*$FK_qfk1;F1^P`cwKdDJb zB++VJ^E`b)xiqc6%#ObE}-UtQ<7AhiZAIB_0c7!#))zNKU#V_|3%Y>I)b57-N;sr^xa zuYUgSgzRrjdP?DbL~CfMbY(@iPcsB7r<{w$$5TzoRONTKKs@Q{=c~P?DpG7w?c*(+ z6cqC@r%3*2d3kZGg5vzaenV%+2P=v2BoH5hLxYDqx=$9{S8y5QyQa;$NiB)rz@)p@ zd{+k_6CZvPS$aEb%!yPe{Rxd0w@S^((^1l=(Bd53Wn20!UqU7GbaY~JB#w9t8GLt6Ilnyq?DG01?#XCp ztQV_;(WZ#|Hsj#W4s=mv1)qy-HB3|Y7#&oMXzY%Xbj+zrNo#qQ%B+gtQFC`?4-H@g z_$_p!FIv~{T$AbTjoF*hh(WUD@+;hLY^|60eYIgdc&FteeCaIAyDqgg-P`5s@&~cd zDY59-*zysAlzjGqj>?=>an9ZsmdgyAb$fh!x-cdl*V}!;KQL$RSOJw$V%-vq+~S(l zVC7-0jC{vXE=e?c915r+;{CZP24yGFPGB~!rF)xm`n|H;=gni90*qFlwbB3}eKg_F zBMdur*aZRLiVB9@ji!&_^>q$ouP5Zy)ENH$OEfSqr>`k<{~`Ws6#A*za^9V;`8kvp z{4X}=X|H(YnduypRFlbLebBJdGZ! zsf%k~YBCH8kd+!VM(Wf`>V-gUOT}`;+-N{8?YNBw8pNk4US(y)a*Ks;x)zU~zmr#e z)O8;NY4+A=aFr@kW`gR60U8@9Rd~B4d3%6<%y1`2@z#qjHkf#KG7?LjWEk#{3Gku_ zpj#z(dkOlB1Iu!x(~tNl((2&2O4gTc46QDSP~|NvSId)JgiedqU%h?jNZ<&>d1RnL zsp#F5z02-0vQEHxI_WO6ag4Z~OUZ$E>YhxNL^9!+}(OId@-q(KAm<$ScaZ z>U3ryC&$5Y?9@YPKa?0^b$F_1`fCDw)>_FHoUUMN$aWDF0cG$ge5TR_G`#R%&VXV0R4~%O{Nx@Nx zzFWgwn&veLlT`;QZT-6t?C9ILwgKP0R>}S8RH@$8GGgBMF4-bYskFIZdUvyN*)i9B zMg@lqv%s&S-hf#vut&V6B~Fb!^^T3a zR)=A~#6x^sHy@UhG%5aiJs!X`yl>u-M~&SVgh;?`i9IUk~I4KZ#ufa+q8n9 zz9wvSKKx+o`~ff9@TMcok|>PuL$UAVedbpsD%42W?@FGtVF2b+R@J?a@Hm?x&=l^J z@>Mfuv$souKZ24+_+vAbn4R?C*`wdG>z=4>?#h0!3s`)iv+2EA>ObS0tT@I<)4n+y z`{PFp1oYMsI;B~JvdyE+wJt#hL+vi}`4#4;@iy<#=}ooLnujhojo74CxmSzoRg1YP z0Mm#S?LPApOJDg!zfHu*zZLZg7r&F9IE5mYP1N))Rn`9e7JSWXvfM5h8g@s8p$=~+ z>EFKMsZvA)D$sc%A~cSyuhv;>jlDD)%Ly>{lkfUW=+@ezv(T)-K{il)?mmS_DMS=D zM41e`{syKOp=}!mH~1k%jT~Ug2zScJ1AiLupOb?tN6>y9-$o#IcE+#Hc4f@WjsFn5 o=l{@F{`wi_&(`(-S!10TSsgS8MO=h%##MmHMKc2$%HhF30Q}YytpET3 literal 2915 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 at^TsFVEI1Fo@K50&vX3SZr_dziuoU(HeIOz literal 108681 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⋙fho-(O%phlUA=LTV=`panK-Q+f+DNMP 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

yc(&KP^sUhFS{|;?u8<&2j%G}q9 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

uWPW}Vc3oY}Ubm)K5#Om(6aw9>6` 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 Yg`g{UB%3lLd+%A4mAyxjl`VS2pvI`l{`MIv^ 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 From b9244570ddd747a432e5e6b3b7ae36e3061ac456 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 15 Feb 2022 08:48:33 +0100 Subject: [PATCH 084/138] speedup symbol-placement in 2D mode --- src/render/draw_symbol.ts | 8 ++++++-- src/symbol/collision_index.ts | 10 ++++++++-- src/symbol/placement.ts | 8 ++++---- src/symbol/projection.ts | 20 ++++++++++++++++---- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index def84e31321..01f2e5a3b1a 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -134,7 +134,9 @@ function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlig if (size) { const tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ); - const getElevation = (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y); + const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? + (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : + null; updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, tr, labelPlaneMatrix, coord.posMatrix, tileScale, size, updateTextFitIcon, getElevation); } @@ -303,7 +305,9 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate bucket.hasIconData(); if (alongLine) { - const getElevation = (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y); + const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? + (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : + 0; symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } diff --git a/src/symbol/collision_index.ts b/src/symbol/collision_index.ts index 9c6e777be45..8d86c0b58d1 100644 --- a/src/symbol/collision_index.ts +++ b/src/symbol/collision_index.ts @@ -357,8 +357,14 @@ class CollisionIndex { } projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number, getElevation: any) { - const p = vec4.fromValues(x, y, getElevation(x, y), 1); - vec4.transformMat4(p, p, posMatrix); + let p; + if (getElevation) { // slow because of handle z-index + p = vec4.fromValues(x, y, getElevation(x, y), 1); + vec4.transformMat4(p, p, posMatrix); + } else { // fast because of ignore z-index + p = vec4.fromValues(x, y, 0, 1); + projection.xyTransformMat4(p, p, posMatrix); + } const a = new Point( (((p[0] / p[3] + 1) / 2) * this.transform.width) + viewportPadding, (((-p[1] / p[3] + 1) / 2) * this.transform.height) + viewportPadding diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index e389c3946fc..1d5ce3594bb 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -492,12 +492,12 @@ export class Placement { // update elevation of collisionArrays const tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; - const getElevation = (x: number, y: number) => this.transform.terrainSourceCache ? - this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y) : - 0; + const getElevation = this.transform.terrainSourceCache && this.transform.terrainSourceCache.isEnabled() ? + (x: number, y: number) => this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y) : + null; for (const boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { const box = collisionArrays[boxType]; - if (box) box.elevation = getElevation(box.anchorPointX, box.anchorPointY); + if (box) box.elevation = getElevation ? getElevation(box.anchorPointX, box.anchorPointY) : 0; } const textBox = collisionArrays.textBox; diff --git a/src/symbol/projection.ts b/src/symbol/projection.ts index a41ec2886f4..838906e0d2d 100644 --- a/src/symbol/projection.ts +++ b/src/symbol/projection.ts @@ -102,8 +102,14 @@ function getGlCoordMatrix(posMatrix: mat4, } function project(point: Point, matrix: mat4, getElevation: any) { - const pos = vec4.fromValues(point.x, point.y, getElevation(point.x, point.y), 1); - vec4.transformMat4(pos, pos, matrix); + let pos; + if (getElevation) { // slow because of handle z-index + pos = vec4.fromValues(point.x, point.y, getElevation(point.x, point.y), 1); + vec4.transformMat4(pos, pos, matrix); + } else { // fast because of ignore z-index + pos = vec4.fromValues(point.x, point.y, 0, 1); + xyTransformMat4(pos, pos, matrix); + } const w = pos[3]; return { point: new Point(pos[0] / w, pos[1] / w), @@ -171,8 +177,14 @@ function updateLineLabels(bucket: SymbolBucket, // Awkward... but we're counting on the paired "vertical" symbol coming immediately after its horizontal counterpart useVertical = false; - const anchorPos = vec4.fromValues(symbol.anchorX, symbol.anchorY, getElevation(symbol.anchorX, symbol.anchorY), 1); - vec4.transformMat4(anchorPos, anchorPos, posMatrix); + let anchorPos; + if (getElevation) { // slow because of handle z-index + anchorPos = vec4.fromValues(symbol.anchorX, symbol.anchorY, getElevation(symbol.anchorX, symbol.anchorY), 1); + vec4.transformMat4(anchorPos, anchorPos, posMatrix); + } else { // fast because of ignore z-index + anchorPos = vec4.fromValues(symbol.anchorX, symbol.anchorY, 0, 1); + xyTransformMat4(anchorPos, anchorPos, posMatrix); + } // Don't bother calculating the correct point for invisible labels. if (!isVisible(anchorPos, clippingBuffer)) { From daaf8cab9c07f703d4c351d3b57bedc66bf99bda Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Tue, 15 Feb 2022 08:49:42 +0100 Subject: [PATCH 085/138] ... --- src/render/draw_symbol.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index 01f2e5a3b1a..06021f009e1 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -135,8 +135,8 @@ function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlig if (size) { const tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ); const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? - (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : - null; + (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : + null; updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, tr, labelPlaneMatrix, coord.posMatrix, tileScale, size, updateTextFitIcon, getElevation); } @@ -306,8 +306,8 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate if (alongLine) { const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? - (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : - 0; + (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : + 0; symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } From 32b01dd9f1a25320bd7d3ec19717b224ba00be35 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 16 Feb 2022 10:13:58 +0100 Subject: [PATCH 086/138] add first very poor TerrainSourceCache test --- debug/terrain_control.html | 5 +- src/data/dem_data.test.ts | 4 +- src/render/draw_hillshade.ts | 3 +- src/render/painter.ts | 9 +- src/source/terrain_source_cache.test.ts | 107 ++++++++++++++++++++++++ src/source/terrain_source_cache.ts | 8 +- 6 files changed, 120 insertions(+), 16 deletions(-) create mode 100644 src/source/terrain_source_cache.test.ts diff --git a/debug/terrain_control.html b/debug/terrain_control.html index c3e781daba0..7f532f284f2 100644 --- a/debug/terrain_control.html +++ b/debug/terrain_control.html @@ -37,10 +37,7 @@ map.addControl( new maplibregl.TerrainControl({ id: 'terrain', - options: { - exaggeration: 0.33, - elevationOffset: 0 - } + options: {exaggeration: 0.33} }) ); }); diff --git a/src/data/dem_data.test.ts b/src/data/dem_data.test.ts index 0101fdb5fba..3224c0cc67e 100644 --- a/src/data/dem_data.test.ts +++ b/src/data/dem_data.test.ts @@ -238,8 +238,8 @@ describe('DEMData is correctly serialized and deserialized', () => { stride: 6, data: dem0.data, encoding: 'mapbox', - max: max, - min: min, + max, + min, }); const transferrables = []; diff --git a/src/render/draw_hillshade.ts b/src/render/draw_hillshade.ts index 0589395ed95..c0eaf7832c2 100644 --- a/src/render/draw_hillshade.ts +++ b/src/render/draw_hillshade.ts @@ -62,7 +62,6 @@ function prepareHillshade(painter, tile, layer, depthMode, stencilMode, colorMod const context = painter.context; const gl = context.gl; const dem = tile.dem; - const terrain = painter.style.terrainSourceCache.getTerrain(); if (dem && dem.data) { const tileSize = dem.dim; const textureStride = dem.stride; @@ -99,7 +98,7 @@ function prepareHillshade(painter, tile, layer, depthMode, stencilMode, colorMod painter.useProgram('hillshadePrepare').draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, hillshadeUniformPrepareValues(tile.tileID, dem), - terrain, layer.id, painter.rasterBoundsBuffer, + null, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); tile.needsHillshadePrepare = false; diff --git a/src/render/painter.ts b/src/render/painter.ts index dbc254274dc..0c18a888029 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -125,9 +125,10 @@ class Painter { emptyTexture: Texture; debugOverlayTexture: Texture; debugOverlayCanvas: HTMLCanvasElement; - // this object stores the current camera-matrix and the last render time of - // of the terrain-acilitators. e.g. depth & coords framebuffers - terrainFacilitator: { matrix: mat4; renderTime: number }; + // this object stores the current camera-matrix and the last render time + // of the terrain-facilitators. e.g. depth & coords framebuffers + // every time the camera-matrix changes the terrain-facilitators will be redrawn. + terrainFacilitator: {matrix: mat4; renderTime: number}; constructor(gl: WebGLRenderingContext, transform: Transform) { this.context = new Context(gl); @@ -244,7 +245,7 @@ class Painter { this.useProgram('clippingMask').draw(context, gl.TRIANGLES, DepthMode.disabled, this.stencilClearMode, ColorMode.disabled, CullFaceMode.disabled, - clippingMaskUniformValues(matrix), this.style.terrainSourceCache.getTerrain(), + clippingMaskUniformValues(matrix), null, '$clipping', this.viewportBuffer, this.quadTriangleIndexBuffer, this.viewportSegments); } diff --git a/src/source/terrain_source_cache.test.ts b/src/source/terrain_source_cache.test.ts new file mode 100644 index 00000000000..eccbcece2d9 --- /dev/null +++ b/src/source/terrain_source_cache.test.ts @@ -0,0 +1,107 @@ +import TerrainSourceCache from './terrain_source_cache'; +import Style from '../style/style'; +import {OverscaledTileID} from './tile_id'; +import {RequestManager} from '../util/request_manager'; +import Dispatcher from '../util/dispatcher'; +import {fakeServer, FakeServer} from 'nise'; +import Tile from './tile'; +import Transform from '../geo/transform'; +import {Evented} from '../util/evented'; +import Painter from '../render/painter'; +import Context from '../gl/context'; +import gl from 'gl'; +import RasterDEMTileSource from './raster_dem_tile_source'; + +const context = new Context(gl(10, 10)); +const transform = new Transform(); + +class StubMap extends Evented { + transform: Transform; + painter: Painter; + _requestManager: RequestManager; + + constructor() { + super(); + this.transform = transform; + this._requestManager = { + transformRequest: (url) => { + return {url}; + } + } as any as RequestManager; + } +} + +function createSource(options, transformCallback?) { + const source = new RasterDEMTileSource('id', options, {send() {}} as any as Dispatcher, null); + source.onAdd({ + transform: transform, + _getMapId: () => 1, + _requestManager: new RequestManager(transformCallback), + getPixelRatio() { return 1; } + } as any); + + source.on('error', (e) => { + throw e.error; + }); + + return source; +} + +describe('TerrainSourceCache', () => { + let server: FakeServer; + let style: Style; + let tsc: TerrainSourceCache; + + beforeAll(done => { + global.fetch = null; + server = fakeServer.create(); + server.respondWith('/source.json', JSON.stringify({ + minzoom: 0, + maxzoom: 22, + attribution: 'MapLibre', + tiles: ['http://example.com/{z}/{x}/{y}.pngraw'], + bounds: [-47, -7, -45, -5] + })); + const map = new StubMap(); + style = new Style(map as any); + style.map.painter = {style: style, context: context} as any; + style.on("style.load", () => { + const source = createSource({url: '/source.json'}); + server.respond(); + style.addSource('terrain', source as any); + tsc = new TerrainSourceCache(style); + done(); + }) + style.loadJSON({ + 'version': 8, + 'sources': {}, + 'layers': [] + }); + }); + + afterAll(() => { + server.restore(); + }); + + test('#enable', () => { + tsc.enable(style.sourceCaches['terrain']); + expect(tsc.exaggeration).toBe(1); + expect(tsc.elevationOffset).toBe(450); + expect(style.sourceCaches['terrain'].usedForTerrain).toBeTruthy(); + expect(style.sourceCaches['terrain'].tileSize).toBe(1024); + expect(tsc.isEnabled()).toBeTruthy(); + + tsc.enable(style.sourceCaches['terrain'], {exaggeration: 2, elevationOffset: 1000}); + expect(tsc.exaggeration).toBe(2); + expect(tsc.elevationOffset).toBe(1000); + }); + + test('#disable', () => { + tsc.disable(); + expect(tsc._sourceCache).toBeNull(); + expect(style.sourceCaches['terrain'].usedForTerrain).toBeFalsy(); + expect(tsc.isEnabled()).toBeFalsy(); + expect(tsc._tiles).toEqual({}); + }); + +}); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 2b849c1fea0..9b38dc503a9 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -316,12 +316,12 @@ class TerrainSourceCache extends Evented { } /** - * returns a Terrain Object for a tile. Unless the tile corresponds to data, return an flat dem object + * returns a Terrain Object for a tile. Unless the tile corresponds to data (e.g. tile is loading), return a flat dem object * @param {OverscaledTileID} tileID */ - getTerrain(tileID?: OverscaledTileID): any { - if (!this.isEnabled() || !tileID) return null; - // create empty DEM Obejcts, which will used while raster-dem tiles will load. + getTerrain(tileID: OverscaledTileID): any { + if (!this.isEnabled()) return null; + // create empty DEM Obejcts, which will used while raster-dem tiles are loading. // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. if (!this._emptyDemTexture) { const context = this._style.map.painter.context; From f146f67be746b7e7930de00f568983db0dc620c3 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 16 Feb 2022 10:16:31 +0100 Subject: [PATCH 087/138] ... --- src/source/terrain_source_cache.test.ts | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/source/terrain_source_cache.test.ts b/src/source/terrain_source_cache.test.ts index eccbcece2d9..0f9784a2d2f 100644 --- a/src/source/terrain_source_cache.test.ts +++ b/src/source/terrain_source_cache.test.ts @@ -16,25 +16,25 @@ const context = new Context(gl(10, 10)); const transform = new Transform(); class StubMap extends Evented { - transform: Transform; - painter: Painter; - _requestManager: RequestManager; + transform: Transform; + painter: Painter; + _requestManager: RequestManager; - constructor() { - super(); - this.transform = transform; - this._requestManager = { - transformRequest: (url) => { - return {url}; - } - } as any as RequestManager; - } + constructor() { + super(); + this.transform = transform; + this._requestManager = { + transformRequest: (url) => { + return {url}; + } + } as any as RequestManager; + } } function createSource(options, transformCallback?) { const source = new RasterDEMTileSource('id', options, {send() {}} as any as Dispatcher, null); source.onAdd({ - transform: transform, + transform, _getMapId: () => 1, _requestManager: new RequestManager(transformCallback), getPixelRatio() { return 1; } @@ -64,14 +64,14 @@ describe('TerrainSourceCache', () => { })); const map = new StubMap(); style = new Style(map as any); - style.map.painter = {style: style, context: context} as any; - style.on("style.load", () => { + style.map.painter = {style, context} as any; + style.on('style.load', () => { const source = createSource({url: '/source.json'}); server.respond(); style.addSource('terrain', source as any); tsc = new TerrainSourceCache(style); done(); - }) + }); style.loadJSON({ 'version': 8, 'sources': {}, From 3343d3563c4b709c3e8f9998f453e81af99599f8 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 17 Feb 2022 12:14:39 +0100 Subject: [PATCH 088/138] show correct tileBoundaries & collisionBoxes in terrain --- src/shaders/collision_box.vertex.glsl | 2 +- src/shaders/debug.vertex.glsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shaders/collision_box.vertex.glsl b/src/shaders/collision_box.vertex.glsl index 568d0235f3a..f76cc473fa1 100644 --- a/src/shaders/collision_box.vertex.glsl +++ b/src/shaders/collision_box.vertex.glsl @@ -20,7 +20,7 @@ void main() { 0.0, // Prevents oversized near-field boxes in pitched/overzoomed tiles 4.0); - gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); + gl_Position = u_matrix * vec4(a_pos, get_elevation(a_pos), 1.0); gl_Position.xy += (a_extrude + a_shift) * u_extrude_scale * gl_Position.w * collision_perspective_ratio; v_placed = a_placed.x; diff --git a/src/shaders/debug.vertex.glsl b/src/shaders/debug.vertex.glsl index c872e7fa981..f8635d8da0f 100644 --- a/src/shaders/debug.vertex.glsl +++ b/src/shaders/debug.vertex.glsl @@ -8,5 +8,5 @@ void main() { // This vertex shader expects a EXTENT x EXTENT quad, // The UV co-ordinates for the overlay texture can be calculated using that knowledge v_uv = a_pos / 8192.0; - gl_Position = u_matrix * vec4(a_pos * u_overlay_scale, 0, 1); + gl_Position = u_matrix * vec4(a_pos * u_overlay_scale, get_elevation(a_pos), 1); } From 87601e2169e3c44b09707aa95e3850cb3e8dfd67 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 17 Feb 2022 12:19:48 +0100 Subject: [PATCH 089/138] load LOD tiles in respect of terrain --- src/geo/transform.ts | 21 +++++++++++++-------- src/source/source_cache.ts | 8 +++++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 16684d51367..65116c2d160 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -351,9 +351,7 @@ class Transform { if (options.minzoom !== undefined && z < options.minzoom) return []; if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom; - const cameraCoord = (tsc && tsc.isEnabled()) ? - this.pointCoordinate(this.getCameraPoint()) : - MercatorCoordinate.fromLngLat(this.center); + const cameraCoord = this.pointCoordinate(this.getCameraPoint()); const centerCoord = MercatorCoordinate.fromLngLat(this.center); const numTiles = Math.pow(2, z); const cameraPoint = [numTiles * cameraCoord.x, numTiles * cameraCoord.y, 0]; @@ -412,8 +410,10 @@ class Transform { fullyVisible = intersectResult === 2; } - const distanceX = it.aabb.distanceX(cameraPoint); - const distanceY = it.aabb.distanceY(cameraPoint); + // FIX ME-3D. I think refPoint should in any case be the cameraPoint, this logic is only for backward-compatibliy + const refPoint = tsc && tsc.isEnabled() ? cameraPoint : centerPoint; + const distanceX = it.aabb.distanceX(refPoint); + const distanceY = it.aabb.distanceY(refPoint); const longestDim = Math.max(Math.abs(distanceX), Math.abs(distanceY)); // We're using distance based heuristics to determine if a tile should be split into quadrants or not. @@ -438,10 +438,15 @@ class Transform { const childZ = it.zoom + 1; let quadrant = it.aabb.quadrant(i); if (tsc && tsc.isEnabled()) { - const tile = tsc.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY)); + const tile = tsc.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY), true); + let minElevation = this.elevation, maxElevation = this.elevation; + if (tile && tile.dem) { + minElevation = tile.dem.min * tsc.exaggeration; + maxElevation = tile.dem.max * tsc.exaggeration; + } quadrant = new Aabb( - vec3.fromValues(quadrant.min[0], quadrant.min[1], tile && tile.dem ? tile.dem.min - this.elevation : -this.elevation), - vec3.fromValues(quadrant.max[0], quadrant.max[1], tile && tile.dem ? Math.max(0, tile.dem.max - this.elevation) : 0) + vec3.fromValues(quadrant.min[0], quadrant.min[1], minElevation), + vec3.fromValues(quadrant.max[0], quadrant.max[1], maxElevation) ); } stack.push({aabb: quadrant, zoom: childZ, x: childX, y: childY, wrap: it.wrap, fullyVisible}); diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 2305b732f03..22b860a1b70 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -521,9 +521,11 @@ class SourceCache extends Evented { if (this.usedForTerrain) { const parents = {}; for (const tileID of idealTileIDs) { - if (tileID.canonical.z > this._source.minzoom) { - const parent = tileID.scaledTo(tileID.canonical.z - 1); - parents[parent.key] = parent; + for (let dz = 1; dz <= 22; dz++) { // load all parent tiles + if (tileID.canonical.z - dz >= this._source.minzoom) { + const parent = tileID.scaledTo(tileID.canonical.z - dz); + parents[parent.key] = parent; + } } } idealTileIDs = idealTileIDs.concat(Object.values(parents)); From 2439a60b7077b4b78a5d7f33d348796616df9b24 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 17 Feb 2022 12:20:29 +0100 Subject: [PATCH 090/138] rename getElevationWithExaggeration to getElevation --- src/geo/transform.ts | 6 +++--- src/render/draw_symbol.ts | 4 ++-- src/source/terrain_source_cache.ts | 13 ++++++------- src/symbol/placement.ts | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 65116c2d160..6a40fc83891 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -494,7 +494,7 @@ class Transform { const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); const tileID = new OverscaledTileID(this.tileZoom, 0, this.tileZoom, tileX, tileY); - return this.terrainSourceCache.getElevationWithExaggeration(tileID, mercX % tileSize, mercY % tileSize, tileSize); + return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); } getCameraPosition() { @@ -651,7 +651,7 @@ class Transform { return new MercatorCoordinate( (tile.tileID.canonical.x * coordsSize + x) / worldSize, (tile.tileID.canonical.y * coordsSize + y) / worldSize, - this.terrainSourceCache.getElevationWithExaggeration(tile.tileID, x, y, coordsSize) + this.terrainSourceCache.getElevation(tile.tileID, x, y, coordsSize) ); } @@ -877,9 +877,9 @@ class Transform { this.pixelMatrix = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); // matrix for conversion from location to GL coordinates (-1 .. 1) - this.invProjMatrix = mat4.invert([] as any, m); mat4.translate(m, m, [0, 0, -this.elevation]); // elevate camera over terrain this.projMatrix = m; + this.invProjMatrix = mat4.invert([] as any, m); this.pixelMatrix2 = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index 06021f009e1..b40730cf650 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -135,7 +135,7 @@ function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlig if (size) { const tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ); const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? - (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : + (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y) : null; updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, tr, labelPlaneMatrix, coord.posMatrix, tileScale, size, updateTextFitIcon, getElevation); @@ -306,7 +306,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate if (alongLine) { const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? - (x: number, y: number) => painter.style.terrainSourceCache.getElevationWithExaggeration(coord, x, y) : + (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y) : 0; symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 9b38dc503a9..a9cb3c5625c 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -373,15 +373,14 @@ class TerrainSourceCache extends Evented { } /** - * get the Elevation for given coordinate - * FIXME-3D: handle coordinates outside bounds, e.g. use neighbouring tiles + * get the elevation-value from original dem-data for a given tile-coordinate * @param {OverscaledTileID} tileID * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT * @param {number} extent optional, default 8192 * @returns {number} */ - getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { + getDEMElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { if (!this.isEnabled()) return 0.0; if (!(x >= 0 && x < extent && y >= 0 && y < extent)) return this.elevationOffset; let elevation = 0; @@ -396,20 +395,20 @@ class TerrainSourceCache extends Evented { const br = terrain.tile.dem.get(c[0] + 1, c[1] + 1); elevation = mix(mix(tl, tr, coord[0] - c[0]), mix(bl, br, coord[0] - c[0]), coord[1] - c[1]); } - return (elevation + this.elevationOffset); + return elevation; } /** - * get the Elevation for given coordinate multiplied by exaggeration. + * get the Elevation for given coordinate in respect of elevationOffset and exaggeration. * @param {OverscaledTileID} tileID * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT * @param {number} extent optional, default 8192 * @returns {number} */ - getElevationWithExaggeration(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { + getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { if (!this.isEnabled()) return 0.0; - return this.getElevation(tileID, x, y, extent) * this.exaggeration; + return (this.getDEMElevation(tileID, x, y, extent) + this.elevationOffset) * this.exaggeration; } /** diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index 1d5ce3594bb..e7defbc18b0 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -493,7 +493,7 @@ export class Placement { // update elevation of collisionArrays const tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; const getElevation = this.transform.terrainSourceCache && this.transform.terrainSourceCache.isEnabled() ? - (x: number, y: number) => this.transform.terrainSourceCache.getElevationWithExaggeration(tileID, x, y) : + (x: number, y: number) => this.transform.terrainSourceCache.getElevation(tileID, x, y) : null; for (const boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { const box = collisionArrays[boxType]; From a2246ba47591ecb94878a8cc9261d9ab41485c12 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 21 Feb 2022 09:01:23 +0100 Subject: [PATCH 091/138] calculate tileDistanceToCamera form future-use in tile reduction algorithm --- src/geo/transform.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 6a40fc83891..7cee63579c9 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -425,9 +425,12 @@ class Transform { // Have we reached the target depth or is the tile too far away to be any split further? if (it.zoom === maxZoom || (longestDim > distToSplit && it.zoom >= minZoom)) { + const dz = maxZoom - it.zoom, dx = cameraPoint[0] - 0.5 - (x << dz), dy = cameraPoint[1] - 0.5 - (y << dz); result.push({ tileID: new OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y), - distanceSq: vec2.sqrLen([centerPoint[0] - 0.5 - x, centerPoint[1] - 0.5 - y]) + distanceSq: vec2.sqrLen([centerPoint[0] - 0.5 - x, centerPoint[1] - 0.5 - y]), + // this variable is currently not used, but may be important to reduce the amount of loaded tiles + tileDistanceToCamera: Math.sqrt(dx * dx + dy * dy) }); continue; } From 0aea4c6a53313b1ec016e80f8b4a538ac19d0844 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 21 Feb 2022 09:05:27 +0100 Subject: [PATCH 092/138] update terrain-test page to maxPitch = 85 --- debug/terrain.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debug/terrain.html b/debug/terrain.html index c24f4bca0d4..14861ec5615 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -24,7 +24,8 @@ center: [11.40416, 47.26475], hash: true, style: 'https://static.maptoolkit.net/styles/toursprung/terrain.json', - maxZoom: 16 + maxZoom: 18, + maxPitch: 85 }); map.on('load', () => { @@ -32,7 +33,8 @@ 'type': 'raster-dem', 'tiles': ['https://vtc-cdn.maptoolkit.net/terrainrgb/{z}/{x}/{y}.webp'], 'encoding': 'mapbox', - 'maxzoom': 14 + 'maxzoom': 14, + 'minzoom': 4 }); map.addTerrain('terrain', {exaggeration: 0.33}); }); From bbc1f9ce1f72a6ca06e4713fd29cf93cddfbab1b Mon Sep 17 00:00:00 2001 From: HarelM Date: Fri, 25 Feb 2022 15:56:43 +0200 Subject: [PATCH 093/138] Fix some lint warnings --- src/render/draw_terrain.ts | 18 +++++++++--------- src/render/program/circle_program.ts | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 5e41565ae00..73d90239864 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -11,10 +11,10 @@ import ColorMode from '../gl/color_mode'; /** * Redraw the Coords & Depth Framebuffers - * @param {Painter} painter - * @param {sourceCache} sourceCache + * @param {Painter} painter - the painter + * @param {TerrainSourceCache} sourceCache- the source cache */ -function updateTerrainFacilitators(painter, sourceCache: TerrainSourceCache) { +function updateTerrainFacilitators(painter: Painter, sourceCache: TerrainSourceCache) { const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; @@ -57,9 +57,9 @@ function updateTerrainFacilitators(painter, sourceCache: TerrainSourceCache) { /** * Render, e.g. drape, a render-to-texture tile onto the 3d mesh on screen. - * @param {Painter} painter - * @param {TerrainSourceCache} sourceCache - * @param {Tile} tile + * @param {Painter} painter - the painter + * @param {TerrainSourceCache} sourceCache - the source cache + * @param {Tile} tile - the tile */ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile) { const context = painter.context; @@ -82,9 +82,9 @@ function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Ti /** * prepare the render-to-texture tile. * E.g. creates the necessary textures and attach them to the render-to-texture-framebuffer. - * @param {Painter} painter - * @param {TerrainSourceCache} sourceCache - * @param {Tile} tile + * @param {Painter} painter - the painter + * @param {TerrainSourceCache} sourceCache - the source cache + * @param {Tile} tile - the tile * @param {number} stack number of a layer-groop. see painter.ts */ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile, stack: number) { diff --git a/src/render/program/circle_program.ts b/src/render/program/circle_program.ts index 0b8b7a031d0..0e5ad947d79 100644 --- a/src/render/program/circle_program.ts +++ b/src/render/program/circle_program.ts @@ -1,4 +1,4 @@ -import {Uniform1i, Uniform1f, Uniform2f, Uniform4f, UniformMatrix4f} from '../uniform_binding'; +import {Uniform1i, Uniform1f, Uniform2f, UniformMatrix4f} from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import type Context from '../../gl/context'; From c3df5a3b9bb4cd2c17344bb37ec4591bdca06844 Mon Sep 17 00:00:00 2001 From: HarelM Date: Fri, 25 Feb 2022 15:57:00 +0200 Subject: [PATCH 094/138] Fix some lint warnings --- src/source/terrain_source_cache.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/source/terrain_source_cache.test.ts b/src/source/terrain_source_cache.test.ts index 0f9784a2d2f..1fe1ce27571 100644 --- a/src/source/terrain_source_cache.test.ts +++ b/src/source/terrain_source_cache.test.ts @@ -1,10 +1,8 @@ import TerrainSourceCache from './terrain_source_cache'; import Style from '../style/style'; -import {OverscaledTileID} from './tile_id'; import {RequestManager} from '../util/request_manager'; import Dispatcher from '../util/dispatcher'; import {fakeServer, FakeServer} from 'nise'; -import Tile from './tile'; import Transform from '../geo/transform'; import {Evented} from '../util/evented'; import Painter from '../render/painter'; From 4ee0bf9c05902b80faa506b77c1fe8fa3f540d0b Mon Sep 17 00:00:00 2001 From: HarelM Date: Fri, 25 Feb 2022 16:07:57 +0200 Subject: [PATCH 095/138] lint warning fixes --- src/source/terrain_source_cache.ts | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index a9cb3c5625c..6edd2b2658a 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -113,7 +113,7 @@ class TerrainSourceCache extends Evented { rerender: {[_: string]: {[_: number]: boolean}}; /** - * @param {Style} style + * @param {Style} style - the style */ constructor(style: Style) { super(); @@ -199,7 +199,7 @@ class TerrainSourceCache extends Evented { /** * Load Terrain Tiles, create internal render-to-texture tiles, free GPU memory. - * @param {Transform} transform + * @param {Transform} transform - the operation to do */ update(transform: Transform): void { if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; @@ -237,7 +237,7 @@ class TerrainSourceCache extends Evented { /** * get a list of tiles, which are loaded and should be rendered in the current scene - * @returns {Array} + * @returns {Array} the renderable tiles */ getRenderableTiles(): Array { return this._renderableTiles.map(key => this.getTileByID(key)); @@ -245,8 +245,8 @@ class TerrainSourceCache extends Evented { /** * get terrain tile by the TileID key - * @param id - * @returns {Tile} + * @param id - the tile id + * @returns {Tile} - the tile */ getTileByID(id: string): Tile { return this._tiles[id]; @@ -254,8 +254,8 @@ class TerrainSourceCache extends Evented { /** * searches for the corresponding current rendered terrain-tiles - * @param {OverscaledTileID} tileID - * @returns {[_:string]: Tile} + * @param {OverscaledTileID} tileID - the tile to look for + * @returns {[_:string]: Tile} - the tiles that were found */ getTerrainCoords(tileID: OverscaledTileID): {[_: string]: OverscaledTileID} { const coords = {}; @@ -294,9 +294,9 @@ class TerrainSourceCache extends Evented { /** * find the covering raster-dem tile - * @param {OverscaledTileID} tileID + * @param {OverscaledTileID} tileID - the tile to look for * @param {boolean} searchForDEM Optinal parameter to search for (parent) souretiles with loaded dem. - * @returns {Tile} + * @returns {Tile} - the tile */ getSourceTile(tileID: OverscaledTileID, searchForDEM?: boolean): Tile { if (!this.isEnabled()) return null; @@ -317,7 +317,7 @@ class TerrainSourceCache extends Evented { /** * returns a Terrain Object for a tile. Unless the tile corresponds to data (e.g. tile is loading), return a flat dem object - * @param {OverscaledTileID} tileID + * @param {OverscaledTileID} tileID - the tile to get the terrain for */ getTerrain(tileID: OverscaledTileID): any { if (!this.isEnabled()) return null; @@ -374,11 +374,11 @@ class TerrainSourceCache extends Evented { /** * get the elevation-value from original dem-data for a given tile-coordinate - * @param {OverscaledTileID} tileID + * @param {OverscaledTileID} tileID - the tile to get elevation for * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT * @param {number} extent optional, default 8192 - * @returns {number} + * @returns {number} - the elevation */ getDEMElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { if (!this.isEnabled()) return 0.0; @@ -400,11 +400,11 @@ class TerrainSourceCache extends Evented { /** * get the Elevation for given coordinate in respect of elevationOffset and exaggeration. - * @param {OverscaledTileID} tileID + * @param {OverscaledTileID} tileID - the tile id * @param {number} x between 0 .. EXTENT * @param {number} y between 0 .. EXTENT * @param {number} extent optional, default 8192 - * @returns {number} + * @returns {number} - the elevation */ getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { if (!this.isEnabled()) return 0.0; @@ -413,8 +413,8 @@ class TerrainSourceCache extends Evented { /** * create the render-to-texture framebuffer - * @param {Painter} painter - * @returns {Framebuffer} + * @param {Painter} painter - the painter + * @returns {Framebuffer} - the frame buffer */ getRTTFramebuffer(painter: Painter) { if (!this._rttFramebuffer) { @@ -427,9 +427,9 @@ class TerrainSourceCache extends Evented { /** * get a framebuffer as big as the map-div, which will be used to render depth & coords into a texture - * @param {Painter} painter - * @param texture - * @returns {Framebuffer} + * @param {Painter} painter - the painter + * @param {string} texture - the texture + * @returns {Framebuffer} the frame buffer */ getFramebuffer(painter: Painter, texture: string): Framebuffer { const width = painter.width / devicePixelRatio; @@ -460,8 +460,8 @@ class TerrainSourceCache extends Evented { /** * get a list of tiles, loaded after a spezific time. This is used to update depth & coords framebuffers. - * @param {Date} time - * @returns {Array} + * @param {Date} time - the time + * @returns {Array} - the relevant tiles */ tilesAfterTime(time = Date.now()): Array { return Object.values(this._tiles).filter(t => t.timeLoaded >= time); @@ -469,7 +469,7 @@ class TerrainSourceCache extends Evented { /** * create a regular mesh which will be used by all terrain-tiles - * @param {Context} context + * @param {Context} context - the context * @returns {Object} */ getTerrainMesh(context: Context) { @@ -498,8 +498,8 @@ class TerrainSourceCache extends Evented { * - 4 higher bits for x * - 4 higher bits for y * - 8 bits for coordsIndex (1 .. 255) (= number of terraintile), is later setted in draw_terrain uniform value - * @param {Context} context - * @returns {Texture} + * @param {Context} context - the context + * @returns {Texture} - the texture */ getCoordsTexture(context: Context): Texture { if (this._coordsTexture) return this._coordsTexture; From 18d2686d058bc370f66c0eb3c348e8e1d4d940e0 Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 26 Feb 2022 22:08:58 +0200 Subject: [PATCH 096/138] Improve typings, fix lint warnings --- src/render/draw_circle.ts | 3 ++- src/render/draw_symbol.ts | 3 ++- src/render/draw_terrain.ts | 2 +- src/render/program.ts | 7 +++--- src/source/terrain_source_cache.ts | 36 +++++++++++++++++++++++------- src/ui/map.ts | 16 ++++++------- 6 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/render/draw_circle.ts b/src/render/draw_circle.ts index 8db11b52dcf..39abf9d26c0 100644 --- a/src/render/draw_circle.ts +++ b/src/render/draw_circle.ts @@ -15,6 +15,7 @@ import type VertexBuffer from '../gl/vertex_buffer'; import type IndexBuffer from '../gl/index_buffer'; import type {UniformValues} from './uniform_binding'; import type {CircleUniformsType} from './program/circle_program'; +import type {TerrainData} from '../source/terrain_source_cache'; export default drawCircles; @@ -24,7 +25,7 @@ type TileRenderState = { layoutVertexBuffer: VertexBuffer; indexBuffer: IndexBuffer; uniformValues: UniformValues; - terrain: any; + terrain: TerrainData; }; type SegmentsTileRenderState = { diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index b40730cf650..9f6bd5f0933 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -32,13 +32,14 @@ import type {SymbolSDFUniformsType} from '../render/program/symbol_program'; import type {CrossTileID, VariableOffset} from '../symbol/placement'; import type SymbolBucket from '../data/bucket/symbol_bucket'; import type {SymbolBuffers} from '../data/bucket/symbol_bucket'; +import type {TerrainData} from '../source/terrain_source_cache'; export default drawSymbols; type SymbolTileRenderState = { segments: SegmentVector; sortKey: number; - terrain: any; + terrain: TerrainData; state: { program: any; buffers: SymbolBuffers; diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 73d90239864..44e4a25498c 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -12,7 +12,7 @@ import ColorMode from '../gl/color_mode'; /** * Redraw the Coords & Depth Framebuffers * @param {Painter} painter - the painter - * @param {TerrainSourceCache} sourceCache- the source cache + * @param {TerrainSourceCache} sourceCache - the source cache */ function updateTerrainFacilitators(painter: Painter, sourceCache: TerrainSourceCache) { const context = painter.context; diff --git a/src/render/program.ts b/src/render/program.ts index f207b5c13bf..9051848730c 100644 --- a/src/render/program.ts +++ b/src/render/program.ts @@ -13,7 +13,8 @@ import type ColorMode from '../gl/color_mode'; import type CullFaceMode from '../gl/cull_face_mode'; import type {UniformBindings, UniformValues, UniformLocations} from './uniform_binding'; import type {BinderUniform} from '../data/program_configuration'; -import {terrainPreludeUniforms} from './program/terrain_program'; +import {terrainPreludeUniforms, TerrainPreludeUniformsType} from './program/terrain_program'; +import type {TerrainData} from '../source/terrain_source_cache'; export type DrawMode = WebGLRenderingContext['LINES'] | WebGLRenderingContext['TRIANGLES'] | WebGLRenderingContext['LINE_STRIP']; @@ -32,7 +33,7 @@ class Program { attributes: {[_: string]: number}; numAttributes: number; fixedUniforms: Us; - terrainUniforms: any; + terrainUniforms: TerrainPreludeUniformsType; binderUniforms: Array; failedToCreate: boolean; @@ -135,7 +136,7 @@ class Program { colorMode: Readonly, cullFaceMode: Readonly, uniformValues: UniformValues, - terrain: any, + terrain: TerrainData, layerID: string, layoutVertexBuffer: VertexBuffer, indexBuffer: IndexBuffer, diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 6edd2b2658a..d8d5bff5728 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -20,6 +20,25 @@ import {warnOnce} from '../util/util'; import VertexBuffer from '../gl/vertex_buffer'; import IndexBuffer from '../gl/index_buffer'; +export type TerrainData = { + 'u_depth': number; + 'u_terrain': number; + 'u_terrain_dim': number; + 'u_terrain_matrix': mat4; + 'u_terrain_unpack': number[]; + 'u_terrain_offset': number; + 'u_terrain_exaggeration': number; + texture: WebGLTexture; + depthTexture: WebGLTexture; + tile: Tile; +} + +export type TerrainMesh = { + indexBuffer: IndexBuffer; + vertexBuffer: VertexBuffer; + segments: SegmentVector; +} + /** * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: * 1) loads raster-dem tiles via the internal sourceCache this._source @@ -68,7 +87,7 @@ class TerrainSourceCache extends Evented { _emptyDepthTexture: Texture; // GL Objects for the terrain-mesh // The mesh is a regular mesh, which has the advantage that it can be reused for all tiles. - _mesh: { indexBuffer: IndexBuffer; vertexBuffer: VertexBuffer; segments: SegmentVector }; + _mesh: TerrainMesh; // coords index contains a list of tileID.keys. This index is used to identify // the tile via the alpha-cannel in the coords-texture. // As the alpha-channel has 1 Byte a max of 255 tiles can rendered without an error. @@ -160,10 +179,10 @@ class TerrainSourceCache extends Evented { /** * Loads a 3D terrain-mesh - * @param {SourceCache} sourceCache + * @param {SourceCache} sourceCache - the source cache * @param options Allowed options are exaggeration & elevationOffset - * @param options.exaggeration - * @param options.elevationOffset + * @param options.exaggeration - the exaggeration + * @param options.elevationOffset - the elevation offset */ enable(sourceCache: SourceCache, options?: {exaggeration: number; elevationOffset: number}): void { sourceCache.usedForTerrain = true; @@ -191,7 +210,7 @@ class TerrainSourceCache extends Evented { /** * check if terrain is currently activated - * @return {boolean} + * @returns {boolean} - true if the terrain source cache is enabled, false otherwise */ isEnabled(): boolean { return !!this._sourceCache; @@ -318,8 +337,9 @@ class TerrainSourceCache extends Evented { /** * returns a Terrain Object for a tile. Unless the tile corresponds to data (e.g. tile is loading), return a flat dem object * @param {OverscaledTileID} tileID - the tile to get the terrain for + * @returns {TerrainData} the terrain data to use in the program */ - getTerrain(tileID: OverscaledTileID): any { + getTerrain(tileID: OverscaledTileID): TerrainData { if (!this.isEnabled()) return null; // create empty DEM Obejcts, which will used while raster-dem tiles are loading. // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. @@ -470,9 +490,9 @@ class TerrainSourceCache extends Evented { /** * create a regular mesh which will be used by all terrain-tiles * @param {Context} context - the context - * @returns {Object} + * @returns {TerrainMesh} - the created regular mesh */ - getTerrainMesh(context: Context) { + getTerrainMesh(context: Context): TerrainMesh { if (this._mesh) return this._mesh; const vertexArray = new PosArray(), indexArray = new TriangleIndexArray(); const meshSize = this.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; diff --git a/src/ui/map.ts b/src/ui/map.ts index 49c28570fbb..3f88692fd0b 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -1574,13 +1574,13 @@ class Map extends Camera { * * @param {string} id The ID of the raster-dem source to use. * @param options Allowed options are exaggeration, elevationOffset - * @param options.exaggeration - * @param options.elevationOffset + * @param options.exaggeration - the exaggeration + * @param options.elevationOffset - the elevation offset * @returns {Map} `this` * @example * map.addTerrain('my-data'); */ - addTerrain(id: string, options?: {exaggeration: number; elevationOffset: number}) { + addTerrain(id: string, options?: {exaggeration: number; elevationOffset: number}): Map { this.isSourceLoaded(id); this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); this.transform.updateElevation(); @@ -1594,9 +1594,9 @@ class Map extends Camera { /** * Returns a Boolean indicating whether terrain is loaded. - * @returns {boolean} + * @returns {boolean} true if the terrain is loaded */ - isTerrainLoaded() { + isTerrainLoaded(): boolean { return this.style.terrainSourceCache.isEnabled(); } @@ -1607,7 +1607,7 @@ class Map extends Camera { * @example * map.removeTerrain(); */ - removeTerrain() { + removeTerrain(): Map { this.style.terrainSourceCache.disable(); this.transform.updateElevation(); this.triggerRepaint(); @@ -1623,7 +1623,7 @@ class Map extends Camera { * @example * var tilesLoaded = map.areTilesLoaded(); */ - areTilesLoaded() { + areTilesLoaded(): boolean { const sources = this.style && this.style.sourceCaches; for (const id in sources) { const source = sources[id]; @@ -1657,7 +1657,7 @@ class Map extends Camera { * @example * map.removeSource('bathymetry-data'); */ - removeSource(id: string) { + removeSource(id: string): Map { this.style.removeSource(id); return this._update(true); } From 7e8bdc8b3f4d0eaf3efc301bcf899ada5d103b98 Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 26 Feb 2022 22:27:47 +0200 Subject: [PATCH 097/138] Add type to getElevation parameter --- src/symbol/collision_index.ts | 6 +++--- src/symbol/projection.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/symbol/collision_index.ts b/src/symbol/collision_index.ts index 8d86c0b58d1..5bbbc47646d 100644 --- a/src/symbol/collision_index.ts +++ b/src/symbol/collision_index.ts @@ -78,7 +78,7 @@ class CollisionIndex { textPixelRatio: number, posMatrix: mat4, collisionGroupPredicate?: (key: FeatureKey) => boolean, - getElevation?: any + getElevation?: (x: number, y: number) => number ): { box: Array; offscreen: boolean; @@ -118,7 +118,7 @@ class CollisionIndex { collisionGroupPredicate: (key: FeatureKey) => boolean, circlePixelDiameter: number, textPixelPadding: number, - getElevation: any + getElevation: (x: number, y: number) => number ): { circles: Array; offscreen: boolean; @@ -356,7 +356,7 @@ class CollisionIndex { } } - projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number, getElevation: any) { + projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number, getElevation: (x: number, y: number) => number) { let p; if (getElevation) { // slow because of handle z-index p = vec4.fromValues(x, y, getElevation(x, y), 1); diff --git a/src/symbol/projection.ts b/src/symbol/projection.ts index 838906e0d2d..ea269841f3e 100644 --- a/src/symbol/projection.ts +++ b/src/symbol/projection.ts @@ -101,7 +101,7 @@ function getGlCoordMatrix(posMatrix: mat4, } } -function project(point: Point, matrix: mat4, getElevation: any) { +function project(point: Point, matrix: mat4, getElevation: (x: number, y: number) => number) { let pos; if (getElevation) { // slow because of handle z-index pos = vec4.fromValues(point.x, point.y, getElevation(point.x, point.y), 1); @@ -335,7 +335,7 @@ function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, la return {}; } -function projectTruncatedLineSegment(previousTilePoint: Point, currentTilePoint: Point, previousProjectedPoint: Point, minimumLength: number, projectionMatrix: mat4, getElevation: any) { +function projectTruncatedLineSegment(previousTilePoint: Point, currentTilePoint: Point, previousProjectedPoint: Point, minimumLength: number, projectionMatrix: mat4, getElevation: (x: number, y: number) => number) { // We are assuming "previousTilePoint" won't project to a point within one unit of the camera plane // If it did, that would mean our label extended all the way out from within the viewport to a (very distant) // point near the plane of the camera. We wouldn't be able to render the label anyway once it crossed the @@ -361,7 +361,7 @@ function placeGlyphAlongLine( projectionCache: { [_: number]: Point; }, - getElevation: any) { + getElevation: (x: number, y: number) => number) { const combinedOffsetX = flip ? offsetX - lineOffsetX : From a2962024cac1f9dcad9ae43a95704d63b2f29523 Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 26 Feb 2022 22:38:03 +0200 Subject: [PATCH 098/138] Update collision expected again? --- .../render/tests/debug/collision/expected.png | Bin 68446 -> 68266 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/integration/render/tests/debug/collision/expected.png b/test/integration/render/tests/debug/collision/expected.png index 9ab300beb98b4781ef96093897a7bc4bad5c9870..8e5b6b994d830e3377c9440b17898d342e9b7355 100644 GIT binary patch literal 68266 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 z%0A+j>U?Tp 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

yc(&KP^sUhFS{|;?u8<&2j%G}q9 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

uWPW}Vc3oY}Ubm)K5#Om(6aw9>6` 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 Yg Date: Mon, 7 Mar 2022 07:56:06 +0100 Subject: [PATCH 099/138] calculate farZ clipping-plane in respect of transform.getHorizon --- src/geo/transform.ts | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 7cee63579c9..cde3daa7039 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -32,6 +32,7 @@ class Transform { zoomFraction: number; pixelsToGLUnits: [number, number]; cameraToCenterDistance: number; + cameraToSeaLevelDistance: number; mercatorMatrix: mat4; projMatrix: mat4; invProjMatrix: mat4; @@ -500,7 +501,10 @@ class Transform { return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); } - getCameraPosition() { + /** + * get the camera position in LngLat and altitudes in meter + */ + getCameraPosition(): {lngLat: LngLat, altitude: number} { const lngLat = this.pointLocation(this.getCameraPoint()); const altitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; return {lngLat, altitude: altitude + this.elevation}; @@ -695,6 +699,12 @@ class Transform { return new LngLatBounds([this.lngRange[0], this.latRange[0]], [this.lngRange[1], this.latRange[1]]); } + // calculate pixel height of the visible horizon, multiplied by a static factor to simulate the earth-radius. + // The calculated value is the horizontal line from the camera-height to sea-level. + getHorizon() { + return Math.tan(Math.PI / 2 - this._pitch) * this.cameraToCenterDistance * 0.85; + } + /** * Sets or clears the map's geographical constraints. * @param {LngLatBounds} bounds A {@link LngLatBounds} object describing the new geographic boundaries of the map. @@ -813,7 +823,10 @@ class Transform { const halfFov = this._fov / 2; const offset = this.centerOffset; + const hasTerrain = this.terrainSourceCache && this.terrainSourceCache.isEnabled(); + const x = this.point.x, y = this.point.y; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; + this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; let m = mat4.identity(new Float64Array(16) as any); mat4.scale(m, m, [this.width / 2, -this.height / 2, 1]); @@ -826,25 +839,31 @@ class Transform { mat4.scale(m, m, [2 / this.width, 2 / this.height, 1]); this.glCoordMatrix = m; + // calculate the camera to sea-level distance in pixel in respect of terrain + this.cameraToSeaLevelDistance = hasTerrain ? + this.cameraToCenterDistance + this._elevation * this._pixelPerMeter / Math.cos(this._pitch) : + this.cameraToCenterDistance; + // Find the distance from the center point [width/2 + offset.x, height/2 + offset.y] to the // center top point [width/2 + offset.x, 0] in Z units, using the law of sines. // 1 Z unit is equivalent to 1 horizontal px at the center of the map // (the distance between[width/2, height/2] and [width/2 + 1, height/2]) - this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; const groundAngle = Math.PI / 2 + this._pitch; const fovAboveCenter = this._fov * (0.5 + offset.y / this.height); - const cameraAltitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; - const cameraToCenterDistance = this.terrainSourceCache && this.terrainSourceCache.isEnabled() ? - (cameraAltitude + this._elevation) * this._pixelPerMeter / Math.cos(this._pitch) : - this.cameraToCenterDistance; - const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToCenterDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); - const point = this.point; - const x = point.x, y = point.y; + const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * this.cameraToSeaLevelDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); + + // Find the distance from the center point to the horizon + const horizon = this.getHorizon(); + const horizonAngle = Math.atan(horizon / this.cameraToCenterDistance); + const fovAboveCenter2 = 2 * horizonAngle * (0.5 + offset.y / (horizon * 2)); + const topHalfSurfaceDistance2 = Math.sin(fovAboveCenter2) * this.cameraToSeaLevelDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter2, 0.01, Math.PI - 0.01)); // Calculate z distance of the farthest fragment that should be rendered. - const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + cameraToCenterDistance; + const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToSeaLevelDistance; + const furthestDistance2 = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance2 + this.cameraToSeaLevelDistance; + // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` - const farZ = furthestDistance * 1.01; + const farZ = Math.min(furthestDistance, furthestDistance2) * 1.01; // The larger the value of nearZ is // - the more depth precision is available for features (good) From 9124a0fbaac2e53e87c72287554ead405afbb27c Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 7 Mar 2022 10:58:10 +0100 Subject: [PATCH 100/138] reduce number of loaded tiles --- src/geo/transform.ts | 7 +++---- src/source/source_cache.ts | 11 ++++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index cde3daa7039..5c1826e4908 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -366,7 +366,7 @@ class Transform { minZoom = z; // There should always be a certain number of maximum zoom level tiles surrounding the center location - const radiusOfMaxLvlLodInTiles = 3; + let radiusOfMaxLvlLodInTiles = tsc && tsc.isEnabled() ? 2 / options.tileSize * this.tileSize : 3; const newRootTile = (wrap: number): any => { return { @@ -430,8 +430,6 @@ class Transform { result.push({ tileID: new OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y), distanceSq: vec2.sqrLen([centerPoint[0] - 0.5 - x, centerPoint[1] - 0.5 - y]), - // this variable is currently not used, but may be important to reduce the amount of loaded tiles - tileDistanceToCamera: Math.sqrt(dx * dx + dy * dy) }); continue; } @@ -699,7 +697,8 @@ class Transform { return new LngLatBounds([this.lngRange[0], this.latRange[0]], [this.lngRange[1], this.latRange[1]]); } - // calculate pixel height of the visible horizon, multiplied by a static factor to simulate the earth-radius. + // calculate pixel height of the visible horizon in relation to map-center (e.g. height/2), + // multiplied by a static factor to simulate the earth-radius. // The calculated value is the horizontal line from the camera-height to sea-level. getHorizon() { return Math.tan(Math.PI / 2 - this._pitch) * this.cameraToCenterDistance * 0.85; diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index bffcfb9838b..0d0f4f1738b 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -525,11 +525,12 @@ class SourceCache extends Evented { if (this.usedForTerrain) { const parents = {}; for (const tileID of idealTileIDs) { - for (let dz = 1; dz <= 22; dz++) { // load all parent tiles - if (tileID.canonical.z - dz >= this._source.minzoom) { - const parent = tileID.scaledTo(tileID.canonical.z - dz); - parents[parent.key] = parent; - } + if (tileID.canonical.z > this._source.minzoom) { + const parent = tileID.scaledTo(tileID.canonical.z - 1); + parents[parent.key] = parent; + // load very low zoom to calculate tile visability in transform.coveringTiles correct + const parent2 = tileID.scaledTo(Math.max(this._source.minzoom, 5)); + parents[parent2.key] = parent2; } } idealTileIDs = idealTileIDs.concat(Object.values(parents)); From 64dda4920b81c0041de83cc20abb2d3455acc393 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Mon, 7 Mar 2022 15:24:07 +0100 Subject: [PATCH 101/138] fix transform.locationPoint in 3d-mode --- src/geo/transform.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 5c1826e4908..a41c436a78d 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -564,7 +564,7 @@ class Transform { * @private */ locationPoint3D(lnglat: LngLat) { - return this.coordinatePoint(this.locationCoordinate(lnglat), this.getElevation(lnglat)); + return this.coordinatePoint(this.locationCoordinate(lnglat), this.getElevation(lnglat), this.pixelMatrix2); } /** @@ -667,9 +667,9 @@ class Transform { * @returns {number} elevation, default 0 * @private */ - coordinatePoint(coord: MercatorCoordinate, elevation: number = 0) { + coordinatePoint(coord: MercatorCoordinate, elevation: number = 0, pixelMatrix=this.pixelMatrix) { const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1] as any; - vec4.transformMat4(p, p, this.pixelMatrix2); + vec4.transformMat4(p, p, pixelMatrix); return new Point(p[0] / p[3], p[1] / p[3]); } From 5e1f2ee7af3e674616f54e3854be3fc2a9dd2673 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 9 Mar 2022 09:29:55 +0100 Subject: [PATCH 102/138] fix not rendered areas in high zoomlevels --- src/source/terrain_source_cache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index d8d5bff5728..70d8308db28 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -280,7 +280,7 @@ class TerrainSourceCache extends Evented { const coords = {}; for (const key of this._renderableTiles) { const _tileID = this._tiles[key].tileID; - if (_tileID.equals(tileID)) { + if (_tileID.canonical.equals(tileID.canonical)) { const coord = tileID.clone(); coord.posMatrix = new Float64Array(16) as any; mat4.ortho(coord.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); From 16a6e301be42bd15c93fcfaffb663a0a8337fee5 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 9 Mar 2022 09:39:45 +0100 Subject: [PATCH 103/138] fix typescript errors --- src/geo/transform.ts | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index a41c436a78d..d7f1075b835 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -38,7 +38,7 @@ class Transform { invProjMatrix: mat4; alignedProjMatrix: mat4; pixelMatrix: mat4; - pixelMatrix2: mat4; + pixelMatrix3D: mat4; pixelMatrixInverse: mat4; glCoordMatrix: mat4; labelPlaneMatrix: mat4; @@ -366,7 +366,7 @@ class Transform { minZoom = z; // There should always be a certain number of maximum zoom level tiles surrounding the center location - let radiusOfMaxLvlLodInTiles = tsc && tsc.isEnabled() ? 2 / options.tileSize * this.tileSize : 3; + const radiusOfMaxLvlLodInTiles = tsc && tsc.isEnabled() ? 2 / Math.min(this.tileSize, options.tileSize) * this.tileSize : 3; const newRootTile = (wrap: number): any => { return { @@ -430,6 +430,8 @@ class Transform { result.push({ tileID: new OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y), distanceSq: vec2.sqrLen([centerPoint[0] - 0.5 - x, centerPoint[1] - 0.5 - y]), + // this variable is currently not used, but may be important to reduce the amount of loaded tiles + tileDistanceToCamera: Math.sqrt(dx * dx + dy * dy) }); continue; } @@ -501,8 +503,12 @@ class Transform { /** * get the camera position in LngLat and altitudes in meter + * @returns {Object} An object with lngLat & altitude. */ - getCameraPosition(): {lngLat: LngLat, altitude: number} { + getCameraPosition(): { + lngLat: LngLat; + altitude: number; + } { const lngLat = this.pointLocation(this.getCameraPoint()); const altitude = Math.cos(this._pitch) * this.cameraToCenterDistance / this._pixelPerMeter; return {lngLat, altitude: altitude + this.elevation}; @@ -564,7 +570,7 @@ class Transform { * @private */ locationPoint3D(lnglat: LngLat) { - return this.coordinatePoint(this.locationCoordinate(lnglat), this.getElevation(lnglat), this.pixelMatrix2); + return this.coordinatePoint(this.locationCoordinate(lnglat), this.getElevation(lnglat), this.pixelMatrix3D); } /** @@ -663,11 +669,12 @@ class Transform { /** * Given a coordinate, return the screen point that corresponds to it * @param {Coordinate} coord + * @params {number} elevation default = 0 + * @params {mat4} pixelMatrix, default = this.pixelMatrix * @returns {Point} screen point - * @returns {number} elevation, default 0 * @private */ - coordinatePoint(coord: MercatorCoordinate, elevation: number = 0, pixelMatrix=this.pixelMatrix) { + coordinatePoint(coord: MercatorCoordinate, elevation: number = 0, pixelMatrix = this.pixelMatrix): Point { const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1] as any; vec4.transformMat4(p, p, pixelMatrix); return new Point(p[0] / p[3], p[1] / p[3]); @@ -697,9 +704,12 @@ class Transform { return new LngLatBounds([this.lngRange[0], this.latRange[0]], [this.lngRange[1], this.latRange[1]]); } - // calculate pixel height of the visible horizon in relation to map-center (e.g. height/2), - // multiplied by a static factor to simulate the earth-radius. - // The calculated value is the horizontal line from the camera-height to sea-level. + /** + * Calculate pixel height of the visible horizon in relation to map-center (e.g. height/2), + * multiplied by a static factor to simulate the earth-radius. + * The calculated value is the horizontal line from the camera-height to sea-level. + * @returns {number} Horizon above center in pixels. + */ getHorizon() { return Math.tan(Math.PI / 2 - this._pitch) * this.cameraToCenterDistance * 0.85; } @@ -894,14 +904,16 @@ class Transform { // scale vertically to meters per pixel (inverse of ground resolution): mat4.scale(m, m, vec3.fromValues(1, 1, this._pixelPerMeter)); - // matrix for conversion from location to screen coordinates + // matrix for conversion from location to screen coordinates in 2D this.pixelMatrix = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); // matrix for conversion from location to GL coordinates (-1 .. 1) mat4.translate(m, m, [0, 0, -this.elevation]); // elevate camera over terrain this.projMatrix = m; this.invProjMatrix = mat4.invert([] as any, m); - this.pixelMatrix2 = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); + + // matrix for conversion from location to screen coordinates in 2D + this.pixelMatrix3D = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional From 269080e37be565c8c3725f6b29e12da505784e1d Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 9 Mar 2022 10:48:51 +0100 Subject: [PATCH 104/138] fix mouse zoom & tilt logic in 2D --- src/ui/handler_manager.ts | 54 ++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index 1aadb1f619e..51fdbe4eaf1 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -431,38 +431,40 @@ class HandlerManager { map._stop(true); around = around || map.transform.centerPoint; + const loc = tr.pointLocation(panDelta ? around.sub(panDelta) : around); if (bearingDelta) tr.bearing += bearingDelta; if (pitchDelta) tr.pitch += pitchDelta; if (zoomDelta) tr.zoom += zoomDelta; - // when dragging starts, remember mousedown-location and panDelta from this point - if (combinedEventsInProgress.drag && !this._drag) { - this._drag = { - center: tr.centerPoint, - lngLat: tr.pointLocation(around), - point: around, - delta: panDelta, - handlerName: combinedEventsInProgress.drag.handlerName - }; - tr.freezeElevation = true; - // when dragging ends, recalcuate the zoomlevel for the new center coordinate - } else if (this._drag && deactivatedHandlers[this._drag.handlerName]) { - tr.freezeElevation = false; - if (hasTerrain) tr.recalculateZoom(); - this._drag = null; - // drag map - } else if (combinedEventsInProgress.drag && this._drag) { - this._drag.delta = this._drag.delta.add(panDelta); - // in terrain-mode do not drag the picked point itself, instead only drag the pixel delta - // of the picked point. With this approach it is no longer possible to pick a point from - // from somewhere near the horizon to the center in one move. - // So this logic avoids the problem, that in such cases you easily loose orientation. - if (hasTerrain) { + // when 3d-terrain is enabled act a litte different: + // - draging do not drag the picked point itself, instead it drags the map by pixel-delta. + // With this approach it is no longer possible to pick a point from from somewhere near + // the horizon to the center in one move. + // So this logic avoids the problem, that in such cases you easily loose orientation. + // - scrollzoom does not zoom into the mouse-point, instead it zoomt into map-center + // this should be fixed in future-version + if (hasTerrain) { + // when dragging starts, remember mousedown-location and panDelta from this point + if (combinedEventsInProgress.drag && !this._drag) { + this._drag = { + center: tr.centerPoint, + lngLat: tr.pointLocation(around), + point: around, + handlerName: combinedEventsInProgress.drag.handlerName + }; + tr.freezeElevation = true; + // when dragging ends, recalcuate the zoomlevel for the new center coordinate + } else if (this._drag && deactivatedHandlers[this._drag.handlerName]) { + tr.freezeElevation = false; + if (hasTerrain) tr.recalculateZoom(); + this._drag = null; + // drag map + } else if (combinedEventsInProgress.drag && this._drag) { tr.center = tr.pointLocation(tr.centerPoint.sub(panDelta)); - // in flat mode leave all es it is. e.g. drag the picked point directly to the new posistion. - } else { - tr.setLocationAtPoint(this._drag.lngLat, this._drag.point.add(this._drag.delta)); } + // 2D logic + } else { + tr.setLocationAtPoint(loc, around); } this._map._update(); From 7d4bbc4d5ab8a1a644445594e134004a2e3c3c8f Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 9 Mar 2022 10:58:52 +0100 Subject: [PATCH 105/138] if last layer is a rtt layer, do not render it twice, fixes #1036 --- src/render/painter.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render/painter.ts b/src/render/painter.ts index 0c18a888029..86eec41ab73 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -575,6 +575,8 @@ class Painter { } continue; } + + if (isLastLayer) continue; } } From cc0f4c7c73468d39b2b0380fc8a333ce9b228f20 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 9 Mar 2022 11:57:45 +0100 Subject: [PATCH 106/138] correct calculation of queryRenderedFeatures coordinates in 3d-mode. fixes #1075 --- src/geo/transform.ts | 2 +- src/source/source_cache.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index d7f1075b835..8fac7765ac3 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -644,7 +644,7 @@ class Transform { // FIX ME-3D! mouseout events may contains coordinates outside the coords-framebuffer pointCoordinate3D(p: Point) { - if (!this.terrainSourceCache) return this.pointCoordinate(p); + if (!(this.terrainSourceCache && this.terrainSourceCache.isEnabled())) return this.pointCoordinate(p); const rgba = new Uint8Array(4); const painter = this.terrainSourceCache._style.map.painter, context = painter.context, gl = context.gl; // grab coordinate pixel from coordinates framebuffer diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 0d0f4f1738b..b722e8517f0 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -872,8 +872,8 @@ class SourceCache extends Evented { transform.getCameraQueryGeometry(pointQueryGeometry) : pointQueryGeometry; - const queryGeometry = pointQueryGeometry.map((p) => transform.pointCoordinate(p)); - const cameraQueryGeometry = cameraPointQueryGeometry.map((p) => transform.pointCoordinate(p)); + const queryGeometry = pointQueryGeometry.map((p) => transform.pointCoordinate3D(p)); + const cameraQueryGeometry = cameraPointQueryGeometry.map((p) => transform.pointCoordinate3D(p)); const ids = this.getIds(); From 0dfdb7bfdd53d567be12d43b6ef5a1463f16a1b3 Mon Sep 17 00:00:00 2001 From: HarelM Date: Wed, 9 Mar 2022 21:08:22 +0200 Subject: [PATCH 107/138] Fix build typescript generation --- src/ui/handler_manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index 51fdbe4eaf1..f1415d4eaf9 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -101,7 +101,7 @@ class HandlerManager { _handlersById: {[x: string]: Handler}; _updatingCamera: boolean; _changes: Array<[HandlerResult, any, any]>; - _drag: {center: Point; lngLat: LngLat; point: Point; delta: Point; handlerName: string}; + _drag: {center: Point; lngLat: LngLat; point: Point; handlerName: string}; _previousActiveHandlers: {[x: string]: Handler}; _listeners: Array<[Window | Document | HTMLElement, string, { passive?: boolean; From dde636cd10cd16c27a1a55a264881f85fcf39d21 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 10 Mar 2022 10:25:11 +0100 Subject: [PATCH 108/138] remove fixme's and create issues for that --- src/geo/transform.ts | 4 +--- src/render/draw_heatmap.ts | 2 +- src/render/painter.ts | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 8fac7765ac3..7ab8699deb7 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -411,7 +411,6 @@ class Transform { fullyVisible = intersectResult === 2; } - // FIX ME-3D. I think refPoint should in any case be the cameraPoint, this logic is only for backward-compatibliy const refPoint = tsc && tsc.isEnabled() ? cameraPoint : centerPoint; const distanceX = it.aabb.distanceX(refPoint); const distanceY = it.aabb.distanceY(refPoint); @@ -642,7 +641,6 @@ class Transform { interpolate(y0, y1, t) / this.worldSize); } - // FIX ME-3D! mouseout events may contains coordinates outside the coords-framebuffer pointCoordinate3D(p: Point) { if (!(this.terrainSourceCache && this.terrainSourceCache.isEnabled())) return this.pointCoordinate(p); const rgba = new Uint8Array(4); @@ -656,7 +654,7 @@ class Transform { const y = rgba[1] + ((rgba[2] & 15) << 8); const tileID = this.terrainSourceCache._coordsIndex[255 - rgba[3]]; const tile = tileID && this.terrainSourceCache.getTileByID(tileID); - if (!tile) return this.pointCoordinate(p); // FIX ME! remove this hack + if (!tile) return this.pointCoordinate(p); const coordsSize = this.terrainSourceCache._coordsTextureSize; const worldSize = (1 << tile.tileID.canonical.z) * coordsSize; return new MercatorCoordinate( diff --git a/src/render/draw_heatmap.ts b/src/render/draw_heatmap.ts index c81572bc400..108d38f01be 100644 --- a/src/render/draw_heatmap.ts +++ b/src/render/draw_heatmap.ts @@ -124,7 +124,7 @@ function renderTextureToMap(painter, layer) { painter.useProgram('heatmapTexture').draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, - heatmapTextureUniformValues(painter, layer, 0, 1), null, // FIX ME-3D render onto terrain-mesh + heatmapTextureUniformValues(painter, layer, 0, 1), null, layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments, layer.paint, painter.transform.zoom); } diff --git a/src/render/painter.ts b/src/render/painter.ts index 86eec41ab73..71fa654578b 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -561,12 +561,10 @@ class Painter { // the hillshading layer is a special case because it changes on every camera-movement // so rerender it in any case. - // FIX ME-3D! check if rerendering is really necessary, depending on hillshade-illumination-anchor if (type === 'hillshade') { stacks.push([layerIds[this.currentLayer]]); for (const tile of renderableTiles) { const coords = coordsDescendingInv[layer.source][tile.tileID.key]; - // FIX ME-3D! replace prepareTerrain with hillshading texture from prepareHillshading directly prepareTerrain(this, tsc, tile, stacks.length - 1); this.context.clear({color: Color.transparent}); this._renderTileClippingMasks(layer, coords); From e4674f52942c374786439a07deecb932bd70879c Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 12 Mar 2022 22:27:14 +0200 Subject: [PATCH 109/138] Small code fixes to avoid review comments --- src/data/bucket/fill_extrusion_bucket.ts | 23 +++++++++++++++-------- src/data/dem_data.test.ts | 10 ++++++---- src/data/dem_data.ts | 10 ++++++---- src/render/draw_raster.ts | 8 ++++---- src/render/draw_symbol.ts | 2 +- src/render/painter.ts | 13 ++++++------- src/symbol/placement.ts | 2 +- src/symbol/projection.ts | 4 ++-- src/ui/handler_manager.ts | 21 ++++++++++----------- 9 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/data/bucket/fill_extrusion_bucket.ts b/src/data/bucket/fill_extrusion_bucket.ts index 21fc505968f..acd2fc89501 100644 --- a/src/data/bucket/fill_extrusion_bucket.ts +++ b/src/data/bucket/fill_extrusion_bucket.ts @@ -197,13 +197,17 @@ class FillExtrusionBucket implements Bucket { addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += 2 * p1.x; centroid.y += 2 * p1.y; centroid.vertexCount += 2; + centroid.x += 2 * p1.x; + centroid.y += 2 * p1.y; + centroid.vertexCount += 2; edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += 2 * p2.x; centroid.y += 2 * p2.y; centroid.vertexCount += 2; + centroid.x += 2 * p2.x; + centroid.y += 2 * p2.y; + centroid.vertexCount += 2; const bottomRight = segment.vertexLength; @@ -249,7 +253,9 @@ class FillExtrusionBucket implements Bucket { const p = ring[i]; addVertex(this.layoutVertexArray, p.x, p.y, 0, 0, 1, 1, 0); - centroid.x += p.x; centroid.y += p.y; centroid.vertexCount += 1; + centroid.x += p.x; + centroid.y += p.y; + centroid.vertexCount += 1; flattened.push(p.x); flattened.push(p.y); @@ -273,11 +279,12 @@ class FillExtrusionBucket implements Bucket { } // remember polygon centroid to calculate elevation in GPU - for (let i = 0; i < centroid.vertexCount; i++) this.centroidVertexArray.emplaceBack( - Math.floor(centroid.x / centroid.vertexCount), - Math.floor(centroid.y / centroid.vertexCount) - ); - + for (let i = 0; i < centroid.vertexCount; i++) { + this.centroidVertexArray.emplaceBack( + Math.floor(centroid.x / centroid.vertexCount), + Math.floor(centroid.y / centroid.vertexCount) + ); + } this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, canonical); } } diff --git a/src/data/dem_data.test.ts b/src/data/dem_data.test.ts index 3224c0cc67e..9c68a9c4068 100644 --- a/src/data/dem_data.test.ts +++ b/src/data/dem_data.test.ts @@ -225,10 +225,12 @@ describe('DEMData is correctly serialized and deserialized', () => { // calculate min/max values let min = Number.MAX_SAFE_INTEGER; let max = Number.MIN_SAFE_INTEGER; - for (let x = 0; x < 4; x++) for (let y = 0; y < 4; y++) { - const ele = dem0.get(x, y); - if (ele > max) max = ele; - if (ele < min) min = ele; + for (let x = 0; x < 4; x++) { + for (let y = 0; y < 4; y++) { + const ele = dem0.get(x, y); + if (ele > max) max = ele; + if (ele < min) min = ele; + } } expect(serialized).toEqual({ diff --git a/src/data/dem_data.ts b/src/data/dem_data.ts index d90ff34dd9a..a6d0982ff9d 100644 --- a/src/data/dem_data.ts +++ b/src/data/dem_data.ts @@ -58,10 +58,12 @@ export default class DEMData { // calculate min/max values this.min = Number.MAX_SAFE_INTEGER; this.max = Number.MIN_SAFE_INTEGER; - for (let x = 0; x < dim; x++) for (let y = 0; y < dim; y++) { - const ele = this.get(x, y); - if (ele > this.max) this.max = ele; - if (ele < this.min) this.min = ele; + for (let x = 0; x < dim; x++) { + for (let y = 0; y < dim; y++) { + const ele = this.get(x, y); + if (ele > this.max) this.max = ele; + if (ele < this.min) this.min = ele; + } } } diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index c783b1e77e5..1037fac93cd 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -43,7 +43,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.registerFadeDuration(layer.paint.get('raster-fade-duration')); const parentTile = sourceCache.findLoadedParent(coord, 0), - fade = getFadeValues(tile, parentTile, sourceCache, layer, painter); + fade = getFadeValues(tile, parentTile, sourceCache, layer, painter.transform, painter.style.terrainSourceCache.isEnabled()); let parentScaleBy, parentTL; @@ -80,16 +80,16 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty } } -function getFadeValues(tile, parentTile, sourceCache, layer, painter) { +function getFadeValues(tile, parentTile, sourceCache, layer, transform, isTscEnabled) { const fadeDuration = layer.paint.get('raster-fade-duration'); - if (!painter.style.terrainSourceCache.isEnabled() && fadeDuration > 0) { + if (!isTscEnabled && fadeDuration > 0) { const now = browser.now(); const sinceTile = (now - tile.timeAdded) / fadeDuration; const sinceParent = parentTile ? (now - parentTile.timeAdded) / fadeDuration : -1; const source = sourceCache.getSource(); - const idealZ = painter.transform.coveringZoomLevel({ + const idealZ = transform.coveringZoomLevel({ tileSize: source.tileSize, roundZoom: source.roundZoom }); diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index 9f6bd5f0933..5499a8c481a 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -308,7 +308,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate if (alongLine) { const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y) : - 0; + null; symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } diff --git a/src/render/painter.ts b/src/render/painter.ts index 71fa654578b..aa7b19abec1 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -417,13 +417,12 @@ class Painter { // create a string representation of all to tiles rendered to render-to-texture tiles // this string representation is used to check if tile should be re-rendered. for (const id of layerIds) { - const layer = this.style._layers[id], source = layer.source; - if (renderToTexture[layer.type]) { - if (!coordsDescendingInvStr[source]) { - coordsDescendingInvStr[source] = {}; - for (const key in coordsDescendingInv[source]) - coordsDescendingInvStr[source][key] = coordsDescendingInv[source][key].map(c => c.key).sort().join(); - } + const layer = this.style._layers[id]; + const source = layer.source; + if (renderToTexture[layer.type] && !coordsDescendingInvStr[source]) { + coordsDescendingInvStr[source] = {}; + for (const key in coordsDescendingInv[source]) + coordsDescendingInvStr[source][key] = coordsDescendingInv[source][key].map(c => c.key).sort().join(); } } diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index e7defbc18b0..f7e7a09d9b5 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -351,7 +351,7 @@ export class Placement { bucket: SymbolBucket, orientation: number, iconBox?: SingleCollisionBox | null, - getElevation?: any + getElevation?: (x: number, y: number) => number ): { shift: Point; placedGlyphBoxes: { diff --git a/src/symbol/projection.ts b/src/symbol/projection.ts index ea269841f3e..79334d55f9b 100644 --- a/src/symbol/projection.ts +++ b/src/symbol/projection.ts @@ -145,7 +145,7 @@ function updateLineLabels(bucket: SymbolBucket, glCoordMatrix: mat4, pitchWithMap: boolean, keepUpright: boolean, - getElevation: any) { + getElevation: (x: number, y: number) => number) { const sizeData = isText ? bucket.textSizeData : bucket.iconSizeData; const partiallyEvaluatedSize = symbolSize.evaluateSizeForZoom(sizeData, painter.transform.zoom); @@ -222,7 +222,7 @@ function updateLineLabels(bucket: SymbolBucket, } } -function placeFirstAndLastGlyph(fontScale: number, glyphOffsetArray: GlyphOffsetArray, lineOffsetX: number, lineOffsetY: number, flip: boolean, anchorPoint: Point, tileAnchorPoint: Point, symbol: any, lineVertexArray: SymbolLineVertexArray, labelPlaneMatrix: mat4, projectionCache: any, getElevation: any) { +function placeFirstAndLastGlyph(fontScale: number, glyphOffsetArray: GlyphOffsetArray, lineOffsetX: number, lineOffsetY: number, flip: boolean, anchorPoint: Point, tileAnchorPoint: Point, symbol: any, lineVertexArray: SymbolLineVertexArray, labelPlaneMatrix: mat4, projectionCache: any, getElevation: (x: number, y: number) => number) { const glyphEndIndex = symbol.glyphStartIndex + symbol.numGlyphs; const lineStartIndex = symbol.lineStartIndex; const lineEndIndex = symbol.lineStartIndex + symbol.lineLength; diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index f1415d4eaf9..73703829e38 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -436,14 +436,16 @@ class HandlerManager { if (pitchDelta) tr.pitch += pitchDelta; if (zoomDelta) tr.zoom += zoomDelta; - // when 3d-terrain is enabled act a litte different: - // - draging do not drag the picked point itself, instead it drags the map by pixel-delta. - // With this approach it is no longer possible to pick a point from from somewhere near - // the horizon to the center in one move. - // So this logic avoids the problem, that in such cases you easily loose orientation. - // - scrollzoom does not zoom into the mouse-point, instead it zoomt into map-center - // this should be fixed in future-version - if (hasTerrain) { + if (!hasTerrain) { + tr.setLocationAtPoint(loc, around); + } else { + // when 3d-terrain is enabled act a litte different: + // - draging do not drag the picked point itself, instead it drags the map by pixel-delta. + // With this approach it is no longer possible to pick a point from from somewhere near + // the horizon to the center in one move. + // So this logic avoids the problem, that in such cases you easily loose orientation. + // - scrollzoom does not zoom into the mouse-point, instead it zoomt into map-center + // this should be fixed in future-version // when dragging starts, remember mousedown-location and panDelta from this point if (combinedEventsInProgress.drag && !this._drag) { this._drag = { @@ -462,9 +464,6 @@ class HandlerManager { } else if (combinedEventsInProgress.drag && this._drag) { tr.center = tr.pointLocation(tr.centerPoint.sub(panDelta)); } - // 2D logic - } else { - tr.setLocationAtPoint(loc, around); } this._map._update(); From a0bc5aa572db141cabf878290eaf0cf00cdd6502 Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 12 Mar 2022 22:38:07 +0200 Subject: [PATCH 110/138] Fix lint --- src/data/bucket/fill_extrusion_bucket.ts | 14 +++++++------- src/render/painter.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/data/bucket/fill_extrusion_bucket.ts b/src/data/bucket/fill_extrusion_bucket.ts index acd2fc89501..13d81d4467a 100644 --- a/src/data/bucket/fill_extrusion_bucket.ts +++ b/src/data/bucket/fill_extrusion_bucket.ts @@ -197,16 +197,16 @@ class FillExtrusionBucket implements Bucket { addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += 2 * p1.x; - centroid.y += 2 * p1.y; + centroid.x += 2 * p1.x; + centroid.y += 2 * p1.y; centroid.vertexCount += 2; edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); - centroid.x += 2 * p2.x; - centroid.y += 2 * p2.y; + centroid.x += 2 * p2.x; + centroid.y += 2 * p2.y; centroid.vertexCount += 2; const bottomRight = segment.vertexLength; @@ -253,8 +253,8 @@ class FillExtrusionBucket implements Bucket { const p = ring[i]; addVertex(this.layoutVertexArray, p.x, p.y, 0, 0, 1, 1, 0); - centroid.x += p.x; - centroid.y += p.y; + centroid.x += p.x; + centroid.y += p.y; centroid.vertexCount += 1; flattened.push(p.x); @@ -281,7 +281,7 @@ class FillExtrusionBucket implements Bucket { // remember polygon centroid to calculate elevation in GPU for (let i = 0; i < centroid.vertexCount; i++) { this.centroidVertexArray.emplaceBack( - Math.floor(centroid.x / centroid.vertexCount), + Math.floor(centroid.x / centroid.vertexCount), Math.floor(centroid.y / centroid.vertexCount) ); } diff --git a/src/render/painter.ts b/src/render/painter.ts index aa7b19abec1..909908bcf55 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -417,7 +417,7 @@ class Painter { // create a string representation of all to tiles rendered to render-to-texture tiles // this string representation is used to check if tile should be re-rendered. for (const id of layerIds) { - const layer = this.style._layers[id]; + const layer = this.style._layers[id]; const source = layer.source; if (renderToTexture[layer.type] && !coordsDescendingInvStr[source]) { coordsDescendingInvStr[source] = {}; From 2691ae50a06ff8bf88958c9eb37e3a517fe43ee7 Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 12 Mar 2022 22:45:49 +0200 Subject: [PATCH 111/138] Fix draw_symbol unit test --- src/render/draw_symbol.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/render/draw_symbol.test.ts b/src/render/draw_symbol.test.ts index a12d151f64e..5fd613a5232 100644 --- a/src/render/draw_symbol.test.ts +++ b/src/render/draw_symbol.test.ts @@ -12,6 +12,7 @@ import type Map from '../ui/map'; import type Transform from '../geo/transform'; import type EvaluationParameters from '../style/evaluation_parameters'; import type {SymbolLayerSpecification} from '../style-spec/types.g'; +import type Style from '../style/style'; jest.mock('./painter'); jest.mock('./program'); @@ -41,6 +42,7 @@ describe('drawSymbol', () => { painterMock.renderPass = 'translucent'; painterMock.transform = {pitch: 0, labelPlaneMatrix: mat4.create()} as any as Transform; painterMock.options = {} as any; + painterMock.style = {terrainSourceCache: {getTerrain: () => null}} as any as Style; const layerSpec = { id: 'mock-layer', @@ -56,7 +58,7 @@ describe('drawSymbol', () => { const tileId = new OverscaledTileID(1, 0, 1, 0, 0); tileId.posMatrix = mat4.create(); - const programMock = new Program(null, null, null, null, null, null); + const programMock = new Program(null, null, null, null, null, null, null); (painterMock.useProgram as jest.Mock).mockReturnValue(programMock); const bucketMock = new SymbolBucket(null); bucketMock.icon = { From ea6b9f48d461369d8641b1153f50d43e7f9b668e Mon Sep 17 00:00:00 2001 From: Oliver Wipfli Date: Tue, 15 Mar 2022 09:15:07 +0100 Subject: [PATCH 112/138] Fix unit test --- src/render/draw_symbol.test.ts | 39 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/render/draw_symbol.test.ts b/src/render/draw_symbol.test.ts index e11933ba3c7..918a7bb22fe 100644 --- a/src/render/draw_symbol.test.ts +++ b/src/render/draw_symbol.test.ts @@ -10,10 +10,13 @@ import drawSymbol from './draw_symbol'; import * as symbolProjection from '../symbol/projection'; import type ZoomHistory from '../style/zoom_history'; import type Map from '../ui/map'; -import type Transform from '../geo/transform'; +import Transform from '../geo/transform'; import type EvaluationParameters from '../style/evaluation_parameters'; import type {SymbolLayerSpecification} from '../style-spec/types.g'; -import type Style from '../style/style'; +import Style from '../style/style'; +import TerrainSourceCache from '../source/terrain_source_cache'; +import {Evented} from '../util/evented'; +import {RequestManager} from '../util/request_manager'; jest.mock('./painter'); jest.mock('./program'); @@ -22,6 +25,22 @@ jest.mock('../source/tile'); jest.mock('../data/bucket/symbol_bucket'); jest.mock('../symbol/projection'); +class StubMap extends Evented { + transform: Transform; + painter: Painter; + _requestManager: RequestManager; + + constructor() { + super(); + this.transform = new Transform(); + this._requestManager = { + transformRequest: (url) => { + return {url}; + } + } as any as RequestManager; + } +} + describe('drawSymbol', () => { test('should not do anything', () => { const mockPainter = new Painter(null, null); @@ -38,7 +57,7 @@ describe('drawSymbol', () => { painterMock.context = { gl: {}, activeTexture: { - set: () => {} + set: () => { } } } as any; painterMock.renderPass = 'translucent'; @@ -65,7 +84,7 @@ describe('drawSymbol', () => { const bucketMock = new SymbolBucket(null); bucketMock.icon = { programConfigurations: { - get: () => {} + get: () => { } }, segments: { get: () => [1] @@ -78,7 +97,7 @@ describe('drawSymbol', () => { const tile = new Tile(tileId, 256); tile.tileID = tileId; tile.imageAtlasTexture = { - bind: () => {} + bind: () => { } } as any; (tile.getBucket as jest.Mock).mockReturnValue(bucketMock); const sourceCacheMock = new SourceCache(null, null, null); @@ -96,7 +115,7 @@ describe('drawSymbol', () => { painterMock.context = { gl: {}, activeTexture: { - set: () => {} + set: () => { } } } as any; painterMock.renderPass = 'translucent'; @@ -126,7 +145,7 @@ describe('drawSymbol', () => { const bucketMock = new SymbolBucket(null); bucketMock.icon = { programConfigurations: { - get: () => {} + get: () => { } }, segments: { get: () => [1] @@ -139,13 +158,17 @@ describe('drawSymbol', () => { const tile = new Tile(tileId, 256); tile.tileID = tileId; tile.imageAtlasTexture = { - bind: () => {} + bind: () => { } } as any; (tile.getBucket as jest.Mock).mockReturnValue(bucketMock); const sourceCacheMock = new SourceCache(null, null, null); (sourceCacheMock.getTile as jest.Mock).mockReturnValue(tile); sourceCacheMock.map = {showCollisionBoxes: false} as any as Map; + painterMock.style = { + terrainSourceCache: new TerrainSourceCache(new Style(new StubMap() as any as Map)) + } as any as Style; + console.log(`painterMock.style = ${painterMock.style}`); const spy = jest.spyOn(symbolProjection, 'updateLineLabels'); drawSymbol(painterMock, sourceCacheMock, layer, [tileId], null); From 6f824b52388908d000923184af71e18bab11706c Mon Sep 17 00:00:00 2001 From: Oliver Wipfli Date: Tue, 15 Mar 2022 09:16:09 +0100 Subject: [PATCH 113/138] Remove console.log --- src/render/draw_symbol.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/render/draw_symbol.test.ts b/src/render/draw_symbol.test.ts index 918a7bb22fe..71970f79074 100644 --- a/src/render/draw_symbol.test.ts +++ b/src/render/draw_symbol.test.ts @@ -168,7 +168,6 @@ describe('drawSymbol', () => { terrainSourceCache: new TerrainSourceCache(new Style(new StubMap() as any as Map)) } as any as Style; - console.log(`painterMock.style = ${painterMock.style}`); const spy = jest.spyOn(symbolProjection, 'updateLineLabels'); drawSymbol(painterMock, sourceCacheMock, layer, [tileId], null); From 21c703b5a154596b421fc333882c5c49f07857a0 Mon Sep 17 00:00:00 2001 From: Oliver Wipfli Date: Tue, 22 Mar 2022 15:13:37 +0100 Subject: [PATCH 114/138] Fix build --- src/geo/transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 11ff9ac260b..eb6ba61c0bf 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -5,7 +5,7 @@ import Point from '@mapbox/point-geometry'; import {wrap, clamp} from '../util/util'; import {number as interpolate} from '../style-spec/util/interpolate'; import EXTENT from '../data/extent'; -import {vec4, mat4, mat2, vec2} from 'gl-matrix'; +import {vec3, vec4, mat4, mat2, vec2} from 'gl-matrix'; import {Aabb, Frustum} from '../util/primitives'; import EdgeInsets from './edge_insets'; From 99a6b13846034bca34d5a911e078a201cb76f490 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 30 Mar 2022 10:41:08 +0200 Subject: [PATCH 115/138] refacture TerrainSourceCache class --- debug/terrain.html | 2 +- debug/terrain_control.html | 4 +- src/geo/transform.ts | 60 +-- src/render/draw_background.ts | 4 +- src/render/draw_circle.ts | 12 +- src/render/draw_collision_debug.ts | 4 +- src/render/draw_debug.ts | 11 +- src/render/draw_fill.ts | 7 +- src/render/draw_fill_extrusion.ts | 4 +- src/render/draw_hillshade.ts | 6 +- src/render/draw_line.ts | 6 +- src/render/draw_raster.ts | 10 +- src/render/draw_symbol.ts | 26 +- src/render/draw_terrain.ts | 89 ++-- src/render/painter.ts | 135 +----- src/render/program.ts | 2 +- src/render/render_to_texture.ts | 153 +++++++ src/render/terrain.ts | 369 ++++++++++++++++ src/shaders/symbol_icon.fragment.glsl | 1 - src/shaders/symbol_sdf.fragment.glsl | 1 - .../symbol_text_and_icon.fragment.glsl | 1 - src/source/source_cache.ts | 7 +- src/source/terrain_source_cache.test.ts | 36 +- src/source/terrain_source_cache.ts | 415 ++---------------- src/style/style.ts | 42 +- src/symbol/placement.ts | 4 +- src/ui/camera.ts | 3 +- src/ui/control/terrain_control.ts | 18 +- src/ui/handler_manager.ts | 4 +- src/ui/map.ts | 51 +-- src/ui/marker.ts | 3 +- 31 files changed, 786 insertions(+), 704 deletions(-) create mode 100644 src/render/render_to_texture.ts create mode 100644 src/render/terrain.ts diff --git a/debug/terrain.html b/debug/terrain.html index 14861ec5615..61446d76ec9 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -36,7 +36,7 @@ 'maxzoom': 14, 'minzoom': 4 }); - map.addTerrain('terrain', {exaggeration: 0.33}); + map.setTerrain({ source: 'terrain', exaggeration: 0.33 }); }); map.on('click', e => { diff --git a/debug/terrain_control.html b/debug/terrain_control.html index 7f532f284f2..700c0a69c22 100644 --- a/debug/terrain_control.html +++ b/debug/terrain_control.html @@ -36,8 +36,8 @@ }); map.addControl( new maplibregl.TerrainControl({ - id: 'terrain', - options: {exaggeration: 0.33} + source: 'terrain', + exaggeration: 0.33 }) ); }); diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 7ab8699deb7..af2d37e817c 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -11,7 +11,7 @@ import EdgeInsets from './edge_insets'; import {UnwrappedTileID, OverscaledTileID, CanonicalTileID} from '../source/tile_id'; import type {PaddingOptions} from './edge_insets'; -import TerrainSourceCache from '../source/terrain_source_cache'; +import Terrain from '../render/terrain'; /** * A single transform, generally used for a single tile to be @@ -42,8 +42,8 @@ class Transform { pixelMatrixInverse: mat4; glCoordMatrix: mat4; labelPlaneMatrix: mat4; - terrainSourceCache: TerrainSourceCache; freezeElevation: boolean; + terrain: Terrain; _fov: number; _pitch: number; _zoom: number; @@ -103,7 +103,7 @@ class Transform { clone._pitch = this._pitch; clone._unmodified = this._unmodified; clone._edgeInsets = this._edgeInsets.clone(); - clone.terrainSourceCache = this.terrainSourceCache; + clone.terrain = this.terrain; clone._calcMatrices(); return clone; } @@ -347,7 +347,6 @@ class Transform { ): Array { let z = this.coveringZoomLevel(options); const actualZ = z; - const tsc = this.terrainSourceCache; if (options.minzoom !== undefined && z < options.minzoom) return []; if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom; @@ -362,11 +361,11 @@ class Transform { // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level let minZoom = options.minzoom || 0; // Use 0.1 as an epsilon to avoid for explicit == 0.0 floating point checks - if (!(tsc && tsc.isEnabled()) && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) + if (!this.terrain && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) minZoom = z; // There should always be a certain number of maximum zoom level tiles surrounding the center location - const radiusOfMaxLvlLodInTiles = tsc && tsc.isEnabled() ? 2 / Math.min(this.tileSize, options.tileSize) * this.tileSize : 3; + const radiusOfMaxLvlLodInTiles = this.terrain ? 2 / Math.min(this.tileSize, options.tileSize) * this.tileSize : 3; const newRootTile = (wrap: number): any => { return { @@ -411,7 +410,7 @@ class Transform { fullyVisible = intersectResult === 2; } - const refPoint = tsc && tsc.isEnabled() ? cameraPoint : centerPoint; + const refPoint = this.terrain ? cameraPoint : centerPoint; const distanceX = it.aabb.distanceX(refPoint); const distanceY = it.aabb.distanceY(refPoint); const longestDim = Math.max(Math.abs(distanceX), Math.abs(distanceY)); @@ -440,12 +439,13 @@ class Transform { const childY = (y << 1) + (i >> 1); const childZ = it.zoom + 1; let quadrant = it.aabb.quadrant(i); - if (tsc && tsc.isEnabled()) { - const tile = tsc.getSourceTile(new OverscaledTileID(childZ, it.wrap, childZ, childX, childY), true); + if (this.terrain) { + const tileID = new OverscaledTileID(childZ, it.wrap, childZ, childX, childY); + const tile = this.terrain.getTerrainData(tileID).tile; let minElevation = this.elevation, maxElevation = this.elevation; if (tile && tile.dem) { - minElevation = tile.dem.min * tsc.exaggeration; - maxElevation = tile.dem.max * tsc.exaggeration; + minElevation = tile.dem.min * this.terrain.exaggeration; + maxElevation = tile.dem.max * this.terrain.exaggeration; } quadrant = new Aabb( vec3.fromValues(quadrant.min[0], quadrant.min[1], minElevation), @@ -491,13 +491,13 @@ class Transform { } getElevation(lnglat: LngLat) { - const merc = this.locationCoordinate(lnglat), tsc = this.terrainSourceCache; - if (!(tsc && tsc.isEnabled())) return 0; - const tileSize = tsc.tileSize, worldSize = (1 << this.tileZoom) * tileSize; + if (!this.terrain) return 0; + const merc = MercatorCoordinate.fromLngLat(lnglat); + const worldSize = (1 << this.tileZoom) * EXTENT; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; - const tileX = Math.floor(mercX / tileSize), tileY = Math.floor(mercY / tileSize); + const tileX = Math.floor(mercX / EXTENT), tileY = Math.floor(mercY / EXTENT); const tileID = new OverscaledTileID(this.tileZoom, 0, this.tileZoom, tileX, tileY); - return this.terrainSourceCache.getElevation(tileID, mercX % tileSize, mercY % tileSize, tileSize); + return this.terrain.getElevation(tileID, mercX % EXTENT, mercY % EXTENT, EXTENT) } /** @@ -516,7 +516,6 @@ class Transform { // this method only works in combination with elevation enabled and freezeElevation activated, // because only in this case this.elevation holds the old elevation value. recalculateZoom() { - if (!this.terrainSourceCache || !this.terrainSourceCache.isEnabled()) return; // find position the camera is looking on const center = this.pointLocation3D(this.centerPoint); const elevation = this.getElevation(center); @@ -641,27 +640,9 @@ class Transform { interpolate(y0, y1, t) / this.worldSize); } - pointCoordinate3D(p: Point) { - if (!(this.terrainSourceCache && this.terrainSourceCache.isEnabled())) return this.pointCoordinate(p); - const rgba = new Uint8Array(4); - const painter = this.terrainSourceCache._style.map.painter, context = painter.context, gl = context.gl; - // grab coordinate pixel from coordinates framebuffer - context.bindFramebuffer.set(this.terrainSourceCache.getFramebuffer(painter, 'coords').framebuffer); - gl.readPixels(p.x, painter.height / devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); - context.bindFramebuffer.set(null); - // decode coordinates (encoding see terrain-source-cache) - const x = rgba[0] + ((rgba[2] >> 4) << 8); - const y = rgba[1] + ((rgba[2] & 15) << 8); - const tileID = this.terrainSourceCache._coordsIndex[255 - rgba[3]]; - const tile = tileID && this.terrainSourceCache.getTileByID(tileID); - if (!tile) return this.pointCoordinate(p); - const coordsSize = this.terrainSourceCache._coordsTextureSize; - const worldSize = (1 << tile.tileID.canonical.z) * coordsSize; - return new MercatorCoordinate( - (tile.tileID.canonical.x * coordsSize + x) / worldSize, - (tile.tileID.canonical.y * coordsSize + y) / worldSize, - this.terrainSourceCache.getElevation(tile.tileID, x, y, coordsSize) - ); + pointCoordinate3D(p: Point): MercatorCoordinate { + const coordinate = this.terrain && this.terrain.pointCoordinate(p); + return coordinate || this.pointCoordinate(p); } /** @@ -830,7 +811,6 @@ class Transform { const halfFov = this._fov / 2; const offset = this.centerOffset; - const hasTerrain = this.terrainSourceCache && this.terrainSourceCache.isEnabled(); const x = this.point.x, y = this.point.y; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; @@ -847,7 +827,7 @@ class Transform { this.glCoordMatrix = m; // calculate the camera to sea-level distance in pixel in respect of terrain - this.cameraToSeaLevelDistance = hasTerrain ? + this.cameraToSeaLevelDistance = this.terrain ? this.cameraToCenterDistance + this._elevation * this._pixelPerMeter / Math.cos(this._pitch) : this.cameraToCenterDistance; diff --git a/src/render/draw_background.ts b/src/render/draw_background.ts index a6a884ec77c..891eadae5ba 100644 --- a/src/render/draw_background.ts +++ b/src/render/draw_background.ts @@ -46,10 +46,10 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const uniformValues = image ? backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}, crossfade) : backgroundUniformValues(matrix, opacity, color); - const terrain = painter.style.terrainSourceCache.getTerrain(tileID); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(tileID); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - uniformValues, terrain, layer.id, painter.tileExtentBuffer, + uniformValues, terrainData, layer.id, painter.tileExtentBuffer, painter.quadTriangleIndexBuffer, painter.tileExtentSegments); } } diff --git a/src/render/draw_circle.ts b/src/render/draw_circle.ts index 39abf9d26c0..6e376f61a5d 100644 --- a/src/render/draw_circle.ts +++ b/src/render/draw_circle.ts @@ -15,7 +15,7 @@ import type VertexBuffer from '../gl/vertex_buffer'; import type IndexBuffer from '../gl/index_buffer'; import type {UniformValues} from './uniform_binding'; import type {CircleUniformsType} from './program/circle_program'; -import type {TerrainData} from '../source/terrain_source_cache'; +import type {TerrainData} from '../render/terrain'; export default drawCircles; @@ -25,7 +25,7 @@ type TileRenderState = { layoutVertexBuffer: VertexBuffer; indexBuffer: IndexBuffer; uniformValues: UniformValues; - terrain: TerrainData; + terrainData: TerrainData; }; type SegmentsTileRenderState = { @@ -68,7 +68,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const program = painter.useProgram('circle', programConfiguration); const layoutVertexBuffer = bucket.layoutVertexBuffer; const indexBuffer = bucket.indexBuffer; - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); const uniformValues = circleUniformValues(painter, coord, tile, layer); const state: TileRenderState = { @@ -77,7 +77,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt layoutVertexBuffer, indexBuffer, uniformValues, - terrain + terrainData }; if (sortFeaturesByKey) { @@ -104,11 +104,11 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt } for (const segmentsState of segmentsRenderStates) { - const {programConfiguration, program, layoutVertexBuffer, indexBuffer, uniformValues, terrain} = segmentsState.state; + const {programConfiguration, program, layoutVertexBuffer, indexBuffer, uniformValues, terrainData} = segmentsState.state; const segments = segmentsState.segments; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - uniformValues, terrain, layer.id, + uniformValues, terrainData, layer.id, layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration); } diff --git a/src/render/draw_collision_debug.ts b/src/render/draw_collision_debug.ts index 518d106d238..da85a777b8c 100644 --- a/src/render/draw_collision_debug.ts +++ b/src/render/draw_collision_debug.ts @@ -77,7 +77,7 @@ function drawCollisionDebug(painter: Painter, sourceCache: SourceCache, layer: S posMatrix, painter.transform, tile), - painter.style.terrainSourceCache.getTerrain(coord), + painter.style.terrain && painter.style.terrain.getTerrainData(coord), layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, buffers.segments, null, painter.transform.zoom, null, null, buffers.collisionVertexBuffer); @@ -135,7 +135,7 @@ function drawCollisionDebug(painter: Painter, sourceCache: SourceCache, layer: S painter.colorModeForRenderPass(), CullFaceMode.disabled, uniforms, - painter.style.terrainSourceCache.getTerrain(batch.coord), + painter.style.terrain && painter.style.terrain.getTerrainData(batch.coord), layer.id, vertexBuffer, indexBuffer, diff --git a/src/render/draw_debug.ts b/src/render/draw_debug.ts index 17223624689..210e9858fc1 100644 --- a/src/render/draw_debug.ts +++ b/src/render/draw_debug.ts @@ -77,16 +77,12 @@ function drawDebugTile(painter, sourceCache, coord: OverscaledTileID) { const stencilMode = StencilMode.disabled; const colorMode = painter.colorModeForRenderPass(); const id = '$debug'; - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); context.activeTexture.set(gl.TEXTURE0); // Bind the empty texture for drawing outlines painter.emptyTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); - program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - debugUniformValues(posMatrix, Color.red), terrain, id, - painter.debugBuffer, painter.tileBorderIndexBuffer, painter.debugSegments); - const tileRawData = sourceCache.getTileByID(coord.key).latestRawTileData; const tileByteLength = (tileRawData && tileRawData.byteLength) || 0; const tileSizeKb = Math.floor(tileByteLength / 1024); @@ -100,8 +96,11 @@ function drawDebugTile(painter, sourceCache, coord: OverscaledTileID) { drawTextToOverlay(painter, tileLabel); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, ColorMode.alphaBlended, CullFaceMode.disabled, - debugUniformValues(posMatrix, Color.transparent, scaleRatio), terrain, id, + debugUniformValues(posMatrix, Color.transparent, scaleRatio), null, id, painter.debugBuffer, painter.quadTriangleIndexBuffer, painter.debugSegments); + program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, CullFaceMode.disabled, + debugUniformValues(posMatrix, Color.red), terrainData, id, + painter.debugBuffer, painter.tileBorderIndexBuffer, painter.debugSegments); } function drawTextToOverlay(painter: Painter, text: string) { diff --git a/src/render/draw_fill.ts b/src/render/draw_fill.ts index 5b22fd4276f..9d9f560e234 100644 --- a/src/render/draw_fill.ts +++ b/src/render/draw_fill.ts @@ -81,7 +81,8 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram(programName, programConfiguration); - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); + if (image) { painter.context.activeTexture.set(gl.TEXTURE0); @@ -97,7 +98,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + const terrainCoord = terrainData ? coord : null; const posMatrix = terrainCoord ? terrainCoord.posMatrix : coord.posMatrix; const tileMatrix = painter.translatePosMatrix(posMatrix, tile, layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor')); @@ -118,7 +119,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode } program.draw(painter.context, drawMode, depthMode, - painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, terrain, + painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, terrainData, layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration); } diff --git a/src/render/draw_fill_extrusion.ts b/src/render/draw_fill_extrusion.ts index 969323a6fd6..fd50c954a46 100644 --- a/src/render/draw_fill_extrusion.ts +++ b/src/render/draw_fill_extrusion.ts @@ -58,7 +58,7 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo const bucket: FillExtrusionBucket = (tile.getBucket(layer) as any); if (!bucket) continue; - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration); @@ -87,7 +87,7 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo fillExtrusionUniformValues(matrix, painter, shouldUseVerticalGradient, opacity); program.draw(context, context.gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.backCCW, - uniformValues, terrain, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, + uniformValues, terrainData, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration, bucket.centroidVertexBuffer); } diff --git a/src/render/draw_hillshade.ts b/src/render/draw_hillshade.ts index c0eaf7832c2..a3385ee66b3 100644 --- a/src/render/draw_hillshade.ts +++ b/src/render/draw_hillshade.ts @@ -44,14 +44,14 @@ function renderHillshade(painter, coord, tile, layer, depthMode, stencilMode, co if (!fbo) return; const program = painter.useProgram('hillshade'); - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); - const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + const terrainCoord = terrainData ? coord : null; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - hillshadeUniformValues(painter, tile, layer, terrainCoord), terrain, layer.id, painter.rasterBoundsBuffer, + hillshadeUniformValues(painter, tile, layer, terrainCoord), terrainData, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } diff --git a/src/render/draw_line.ts b/src/render/draw_line.ts index a8535e4f66b..8f6a92672af 100644 --- a/src/render/draw_line.ts +++ b/src/render/draw_line.ts @@ -56,7 +56,7 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay const prevProgram = painter.context.program.get(); const program = painter.useProgram(programId, programConfiguration); const programChanged = firstTile || program.program !== prevProgram; - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); const constantPattern = patternProperty.constantOr(null); if (constantPattern && tile.imageAtlas) { @@ -66,7 +66,7 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay if (posTo && posFrom) programConfiguration.setConstantPatternPositions(posTo, posFrom); } - const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + const terrainCoord = terrainData ? coord : null; const uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade, terrainCoord) : dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade, terrainCoord) : gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length, terrainCoord) : @@ -115,7 +115,7 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay } program.draw(context, gl.TRIANGLES, depthMode, - painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, terrain, + painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, terrainData, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration, bucket.layoutVertexBuffer2); diff --git a/src/render/draw_raster.ts b/src/render/draw_raster.ts index c783b1e77e5..fea50caaf08 100644 --- a/src/render/draw_raster.ts +++ b/src/render/draw_raster.ts @@ -63,18 +63,18 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); } - const terrainCoord = painter.style.terrainSourceCache.isEnabled() ? coord : null; + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); + const terrainCoord = terrainData ? coord : null; const posMatrix = terrainCoord ? terrainCoord.posMatrix : painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); - const terrain = painter.style.terrainSourceCache.getTerrain(coord); if (source instanceof ImageSource) { program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.disabled, - uniformValues, terrain, layer.id, source.boundsBuffer, + uniformValues, terrainData, layer.id, source.boundsBuffer, painter.quadTriangleIndexBuffer, source.boundsSegments); } else { program.draw(context, gl.TRIANGLES, depthMode, stencilModes[coord.overscaledZ], colorMode, CullFaceMode.disabled, - uniformValues, terrain, layer.id, painter.rasterBoundsBuffer, + uniformValues, terrainData, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } } @@ -83,7 +83,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty function getFadeValues(tile, parentTile, sourceCache, layer, painter) { const fadeDuration = layer.paint.get('raster-fade-duration'); - if (!painter.style.terrainSourceCache.isEnabled() && fadeDuration > 0) { + if (!painter.style.terrain && fadeDuration > 0) { const now = browser.now(); const sinceTile = (now - tile.timeAdded) / fadeDuration; const sinceParent = parentTile ? (now - parentTile.timeAdded) / fadeDuration : -1; diff --git a/src/render/draw_symbol.ts b/src/render/draw_symbol.ts index 9f6bd5f0933..29707b47716 100644 --- a/src/render/draw_symbol.ts +++ b/src/render/draw_symbol.ts @@ -32,14 +32,14 @@ import type {SymbolSDFUniformsType} from '../render/program/symbol_program'; import type {CrossTileID, VariableOffset} from '../symbol/placement'; import type SymbolBucket from '../data/bucket/symbol_bucket'; import type {SymbolBuffers} from '../data/bucket/symbol_bucket'; -import type {TerrainData} from '../source/terrain_source_cache'; +import type {TerrainData} from '../render/terrain'; export default drawSymbols; type SymbolTileRenderState = { segments: SegmentVector; sortKey: number; - terrain: TerrainData; + terrainData: TerrainData; state: { program: any; buffers: SymbolBuffers; @@ -135,9 +135,7 @@ function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlig if (size) { const tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ); - const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? - (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y) : - null; + const getElevation = painter.style.terrain ? (x: number, y: number) => painter.style.terrain.getElevation(coord, x, y) : null; updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, tr, labelPlaneMatrix, coord.posMatrix, tileScale, size, updateTextFitIcon, getElevation); } @@ -269,7 +267,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate const program = painter.useProgram(getSymbolProgramName(isSDF, isText, bucket), programConfiguration); const size = symbolSize.evaluateSizeForZoom(sizeData, tr.zoom); - const terrain = painter.style.terrainSourceCache.getTerrain(coord); + const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); let texSize: [number, number]; let texSizeIcon: [number, number] = [0, 0]; @@ -306,9 +304,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate bucket.hasIconData(); if (alongLine) { - const getElevation = painter.style.terrainSourceCache && painter.style.terrainSourceCache.isEnabled() ? - (x: number, y: number) => painter.style.terrainSourceCache.getElevation(coord, x, y) : - 0; + const getElevation = painter.style.terrain ? (x: number, y: number) => painter.style.terrain.getElevation(coord, x, y) : null; symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, getElevation); } @@ -355,7 +351,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate segments: new SegmentVector([segment]), sortKey: (segment.sortKey as any as number), state, - terrain + terrainData }); } } else { @@ -363,7 +359,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate segments: buffers.segments, sortKey: 0, state, - terrain + terrainData }); } } @@ -388,19 +384,19 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate const uniformValues = (state.uniformValues as any as UniformValues); if (state.hasHalo) { uniformValues['u_is_halo'] = 1; - drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, uniformValues, segmentState.terrain); + drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, uniformValues, segmentState.terrainData); } uniformValues['u_is_halo'] = 0; } - drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, state.uniformValues, segmentState.terrain); + drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, state.uniformValues, segmentState.terrainData); } } -function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues, terrain) { +function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues, terrainData) { const context = painter.context; const gl = context.gl; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, - uniformValues, terrain, layer.id, buffers.layoutVertexBuffer, + uniformValues, terrainData, layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, segments, layer.paint, painter.transform.zoom, buffers.programConfigurations.get(layer.id), buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer); diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 44e4a25498c..8cfac84084c 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -2,53 +2,67 @@ import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; import {terrainUniformValues, terrainDepthUniformValues, terrainCoordsUniformValues} from './program/terrain_program'; import type Painter from './painter'; -import type TerrainSourceCache from '../source/terrain_source_cache'; import type Tile from '../source/tile'; import CullFaceMode from '../gl/cull_face_mode'; import Texture from './texture'; import Color from '../style-spec/util/color'; import ColorMode from '../gl/color_mode'; +import Terrain from './terrain'; /** - * Redraw the Coords & Depth Framebuffers + * Redraw the Depth Framebuffer + * @param {Painter} painter + * @param {Terrain} terrain + */ + function drawDepth(painter: Painter, terrain: Terrain) { + const context = painter.context; + const gl = context.gl; + const colorMode = ColorMode.unblended; + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); + const mesh = terrain.getTerrainMesh(); + const tiles = terrain.sourceCache.getRenderableTiles(); + const program = painter.useProgram('terrainDepth'); + context.bindFramebuffer.set(terrain.getFramebuffer('depth').framebuffer); + context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); + context.clear({color: Color.transparent, depth: 1}); + for (const tile of tiles) { + const terrainData = terrain.getTerrainData(tile.tileID); + const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); + const uniformValues = terrainDepthUniformValues(posMatrix); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + } + context.bindFramebuffer.set(null); + context.viewport.set([0, 0, painter.width, painter.height]); +} + +/** + * Redraw the Coords Framebuffers * @param {Painter} painter - the painter - * @param {TerrainSourceCache} sourceCache - the source cache + * @param {Terrain} terrain - the terrain */ -function updateTerrainFacilitators(painter: Painter, sourceCache: TerrainSourceCache) { +function drawCoords(painter: Painter, terrain: Terrain) { const context = painter.context; const gl = context.gl; const colorMode = ColorMode.unblended; const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); - const mesh = sourceCache.getTerrainMesh(context); - const coords = sourceCache.getCoordsTexture(context); - const tiles = sourceCache.getRenderableTiles(); + const mesh = terrain.getTerrainMesh(); + const coords = terrain.getCoordsTexture(); + const tiles = terrain.sourceCache.getRenderableTiles(); // draw tile-coords into framebuffer let program = painter.useProgram('terrainCoords'); - context.bindFramebuffer.set(sourceCache.getFramebuffer(painter, 'coords').framebuffer); + context.bindFramebuffer.set(terrain.getFramebuffer('coords').framebuffer); context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); context.clear({color: Color.transparent, depth: 1}); - sourceCache._coordsIndex = []; + terrain._coordsIndex = []; for (const tile of tiles) { - const terrain = sourceCache.getTerrain(tile.tileID); + const terrainData = terrain.getTerrainData(tile.tileID); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, coords.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainCoordsUniformValues(posMatrix, 255 - sourceCache._coordsIndex.length); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); - sourceCache._coordsIndex.push(tile.tileID.key); - } - - // draw depth into framebuffer - program = painter.useProgram('terrainDepth'); - context.bindFramebuffer.set(sourceCache.getFramebuffer(painter, 'depth').framebuffer); - context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); - context.clear({color: Color.transparent, depth: 1}); - for (const tile of tiles) { - const terrain = sourceCache.getTerrain(tile.tileID); - const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainDepthUniformValues(posMatrix); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + const uniformValues = terrainCoordsUniformValues(posMatrix, 255 - terrain._coordsIndex.length); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + terrain._coordsIndex.push(tile.tileID.key); } context.bindFramebuffer.set(null); @@ -58,44 +72,44 @@ function updateTerrainFacilitators(painter: Painter, sourceCache: TerrainSourceC /** * Render, e.g. drape, a render-to-texture tile onto the 3d mesh on screen. * @param {Painter} painter - the painter - * @param {TerrainSourceCache} sourceCache - the source cache + * @param {Terrain} terrain - the source cache * @param {Tile} tile - the tile */ -function drawTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile) { +function drawTerrain(painter: Painter, terrain: Terrain, tile: Tile) { const context = painter.context; const gl = context.gl; const colorMode = painter.colorModeForRenderPass(); const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); const program = painter.useProgram('terrain'); - const mesh = sourceCache.getTerrainMesh(context); - const terrain = sourceCache.getTerrain(tile.tileID); + const mesh = terrain.getTerrainMesh(); + const terrainData = terrain.getTerrainData(tile.tileID); context.bindFramebuffer.set(null); context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, sourceCache.getRTTFramebuffer(painter).colorAttachment.get()); + gl.bindTexture(gl.TEXTURE_2D, terrain.getRTTFramebuffer().colorAttachment.get()); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); const uniformValues = terrainUniformValues(posMatrix); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrain, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); } /** * prepare the render-to-texture tile. * E.g. creates the necessary textures and attach them to the render-to-texture-framebuffer. * @param {Painter} painter - the painter - * @param {TerrainSourceCache} sourceCache - the source cache + * @param {Terrain} terrain - the terrain * @param {Tile} tile - the tile * @param {number} stack number of a layer-groop. see painter.ts */ -function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: Tile, stack: number) { +function prepareTerrain(painter: Painter, terrain: Terrain, tile: Tile, stack: number) { const context = painter.context; - const size = tile.tileSize * sourceCache.qualityFactor; + const size = tile.tileSize * terrain.qualityFactor; if (!tile.textures[stack]) { tile.textures[stack] = painter.getTileTexture(size) || new Texture(context, {width: size, height: size, data: null}, context.gl.RGBA); tile.textures[stack].bind(context.gl.LINEAR, context.gl.CLAMP_TO_EDGE); - if (stack === 0) sourceCache._renderHistory.push(tile.tileID.key); + if (stack === 0) terrain.sourceCache.renderHistory.push(tile.tileID.key); } - const fb = sourceCache.getRTTFramebuffer(painter); + const fb = terrain.getRTTFramebuffer(); fb.colorAttachment.set(tile.textures[stack].texture); context.bindFramebuffer.set(fb.framebuffer); context.viewport.set([0, 0, size, size]); @@ -104,5 +118,6 @@ function prepareTerrain(painter: Painter, sourceCache: TerrainSourceCache, tile: export { prepareTerrain, drawTerrain, - updateTerrainFacilitators + drawDepth, + drawCoords }; diff --git a/src/render/painter.ts b/src/render/painter.ts index 71fa654578b..69dcc55bac3 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -31,7 +31,7 @@ import raster from './draw_raster'; import background from './draw_background'; import debug, {drawDebugPadding} from './draw_debug'; import custom from './draw_custom'; -import {prepareTerrain, drawTerrain, updateTerrainFacilitators} from './draw_terrain'; +import {drawDepth, drawCoords} from './draw_terrain'; import {OverscaledTileID} from '../source/tile_id'; const draw = { @@ -61,6 +61,7 @@ import type IndexBuffer from '../gl/index_buffer'; import type {DepthRangeType, DepthMaskType, DepthFuncType} from '../gl/types'; import type ResolvedImage from '../style-spec/expression/types/resolved_image'; import type {RGBAImage} from '../util/image'; +import RenderToTexture from './render_to_texture'; export type RenderPass = 'offscreen' | 'opaque' | 'translucent'; @@ -272,13 +273,13 @@ class Painter { for (const tileID of tileIDs) { const id = this._tileClippingMaskIDs[tileID.key] = this.nextStencilID++; - const terrain = this.style.terrainSourceCache.getTerrain(tileID); + const terrainData = this.style.terrain && this.style.terrain.getTerrainData(tileID); program.draw(context, gl.TRIANGLES, DepthMode.disabled, // Tests will always pass, and ref value will be written to stencil buffer. new StencilMode({func: gl.ALWAYS, mask: 0}, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE), ColorMode.disabled, CullFaceMode.disabled, clippingMaskUniformValues(tileID.posMatrix), - terrain, '$clipping', this.tileExtentBuffer, + terrainData, '$clipping', this.tileExtentBuffer, this.quadTriangleIndexBuffer, this.tileExtentSegments); } } @@ -377,9 +378,7 @@ class Painter { const layerIds = this.style._order; const sourceCaches = this.style.sourceCaches; - const renderToTexture = {background: true, fill: true, line: true, raster: true}; - const tsc = this.style.terrainSourceCache; - const isTerrainEnabled = tsc.isEnabled(); + const renderToTexture = this.style.terrain && new RenderToTexture(this); for (const id in sourceCaches) { const sourceCache = sourceCaches[id]; @@ -391,40 +390,12 @@ class Painter { const coordsAscending: {[_: string]: Array} = {}; const coordsDescending: {[_: string]: Array} = {}; const coordsDescendingSymbol: {[_: string]: Array} = {}; - // this is used for 3d-terrain - // coordsDescendingInv contains a list of all tiles which should be rendered for one render-to-texture tile - // e.g. render 4 raster-tiles with size 256px to the 512px render-to-texture tile - const coordsDescendingInv: {[_: string]: {[_:string]: Array}} = {}; - const coordsDescendingInvStr: {[_: string]: {[_:string]: string}} = {}; for (const id in sourceCaches) { const sourceCache = sourceCaches[id]; coordsAscending[id] = sourceCache.getVisibleCoordinates(); coordsDescending[id] = coordsAscending[id].slice().reverse(); coordsDescendingSymbol[id] = sourceCache.getVisibleCoordinates(true).reverse(); - if (isTerrainEnabled) { - coordsDescendingInv[id] = {}; - for (let c = 0; c < coordsDescending[id].length; c++) { - const coords = tsc.getTerrainCoords(coordsDescending[id][c]); - for (const key in coords) { - if (!coordsDescendingInv[id][key]) coordsDescendingInv[id][key] = []; - coordsDescendingInv[id][key].push(coords[key]); - } - } - } - } - - // create a string representation of all to tiles rendered to render-to-texture tiles - // this string representation is used to check if tile should be re-rendered. - for (const id of layerIds) { - const layer = this.style._layers[id], source = layer.source; - if (renderToTexture[layer.type]) { - if (!coordsDescendingInvStr[source]) { - coordsDescendingInvStr[source] = {}; - for (const key in coordsDescendingInv[source]) - coordsDescendingInvStr[source][key] = coordsDescendingInv[source][key].map(c => c.key).sort().join(); - } - } } this.opaquePassCutoff = Infinity; @@ -436,16 +407,17 @@ class Painter { } } - if (isTerrainEnabled) { + if (renderToTexture) { // this is disabled, because render-to-texture is rendering all layers from bottom to top. this.opaquePassCutoff = 0; - // update coords/depth-framebuffer on camera movement, ore tile reloading - const newTiles = tsc.tilesAfterTime(this.terrainFacilitator.renderTime); + // update coords/depth-framebuffer on camera movement, or tile reloading + const newTiles = this.style.terrain.sourceCache.tilesAfterTime(this.terrainFacilitator.renderTime); if (!mat4.equals(this.terrainFacilitator.matrix, this.transform.projMatrix) || newTiles.length) { mat4.copy(this.terrainFacilitator.matrix, this.transform.projMatrix); this.terrainFacilitator.renderTime = Date.now(); - updateTerrainFacilitators(this, tsc); + drawDepth(this, this.style.terrain); + drawCoords(this, this.style.terrain); } } @@ -477,7 +449,7 @@ class Painter { // Opaque pass =============================================== // Draw opaque layers top-to-bottom first. - if (!isTerrainEnabled) { + if (!renderToTexture) { this.renderPass = 'opaque'; for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) { @@ -494,90 +466,11 @@ class Painter { // Draw all other layers bottom-to-top. this.renderPass = 'translucent'; - // the following variables only used when terrain-3d is enabled - const stacks = []; // render layers not one by one, instead group into stacks - let prevType = null; // remember the type of the last layer when render to a stack - const rerender = {}; // create a lookup which tiles should rendered to texture - let renderableTiles = []; // all terrain-tiles for the current scene - if (isTerrainEnabled) { - renderableTiles = tsc.getRenderableTiles(); - renderableTiles.forEach(tile => { - for (const source in coordsDescendingInvStr) { - // rerender if there are more coords to render than in the last rendering - const coords = coordsDescendingInvStr[source][tile.tileID.key]; - if (coords && coords !== tile.textureCoords[source]) tile.clearTextures(this); - // rerender if terrainSourceCache has marked tile for rerender - if (tsc.rerender[source] && tsc.rerender[source][tile.tileID.key]) tile.clearTextures(this); - } - // rerender if there are no previous renderings - rerender[tile.tileID.key] = !tile.textures.length; - }); - // reset terrainSource rerender cache - tsc.rerender = {}; - } - for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { const layer = this.style._layers[layerIds[this.currentLayer]]; const sourceCache = sourceCaches[layer.source]; - const type = layer.type; - - if (isTerrainEnabled) { - // due that switching textures is relatively slow, the render - // layer-by-layer context here is not practicable. To bypass this problem - // this lines of code stack all layers and later render all at once. - // Because of the stylesheet possibility to mixing render-to-texture layers - // and 'live'-layers (f.e. symbols) it is necessary to create more stacks. For example - // a symbol-layer is in between of fill-layers. - - const isLastLayer = this.currentLayer + 1 === layerIds.length; - - // remember background, fill, line & raster layer to render into a stack - if (renderToTexture[type]) { - if (!prevType || !renderToTexture[prevType]) stacks.push([]); - prevType = type; - stacks[stacks.length - 1].push(layerIds[this.currentLayer]); - // rendering is done later, all in once - if (!isLastLayer) continue; - } - // in case a stack is finished render all collected stack-layers into a texture - if (renderToTexture[prevType] || type === 'hillshade' || (renderToTexture[type] && isLastLayer)) { - prevType = type; - const stack = stacks.length - 1, layers = stacks[stack] || []; - for (const tile of renderableTiles) { - prepareTerrain(this, tsc, tile, stack); - if (rerender[tile.tileID.key]) { - this.context.clear({color: Color.transparent}); - for (let l = 0; l < layers.length; l++) { - const layer = this.style._layers[layers[l]]; - const coords = layer.source ? coordsDescendingInv[layer.source][tile.tileID.key] : [tile.tileID]; - this._renderTileClippingMasks(layer, coords); - this.renderLayer(this, this.style.sourceCaches[layer.source], layer, coords); - if (layer.source) tile.textureCoords[layer.source] = coordsDescendingInvStr[layer.source][tile.tileID.key]; - } - } - drawTerrain(this, tsc, tile); - } - - // the hillshading layer is a special case because it changes on every camera-movement - // so rerender it in any case. - if (type === 'hillshade') { - stacks.push([layerIds[this.currentLayer]]); - for (const tile of renderableTiles) { - const coords = coordsDescendingInv[layer.source][tile.tileID.key]; - prepareTerrain(this, tsc, tile, stacks.length - 1); - this.context.clear({color: Color.transparent}); - this._renderTileClippingMasks(layer, coords); - this.renderLayer(this, sourceCache, layer, coords); - drawTerrain(this, tsc, tile); - } - continue; - } - - if (isLastLayer) continue; - } - - } + if (renderToTexture && renderToTexture.renderLayer(layer)) continue; // For symbol layers in the translucent pass, we add extra tiles to the renderable set // for cross-tile symbol fading. Symbol layers don't use tile clipping, so no need to render @@ -736,7 +629,7 @@ class Painter { const key = name + (programConfiguration ? programConfiguration.cacheKey : '') + (this._showOverdrawInspector ? '/overdraw' : '') + - (this.style.terrainSourceCache.isEnabled() ? '/terrain' : ''); + (this.style.terrain ? '/terrain' : ''); if (!this.cache[key]) { this.cache[key] = new Program( this.context, @@ -745,7 +638,7 @@ class Painter { programConfiguration, programUniforms[name], this._showOverdrawInspector, - this.style.terrainSourceCache.isEnabled() + this.style.terrain !== null ); } return this.cache[key]; diff --git a/src/render/program.ts b/src/render/program.ts index 9051848730c..c9f5e9ac8af 100644 --- a/src/render/program.ts +++ b/src/render/program.ts @@ -14,7 +14,7 @@ import type CullFaceMode from '../gl/cull_face_mode'; import type {UniformBindings, UniformValues, UniformLocations} from './uniform_binding'; import type {BinderUniform} from '../data/program_configuration'; import {terrainPreludeUniforms, TerrainPreludeUniformsType} from './program/terrain_program'; -import type {TerrainData} from '../source/terrain_source_cache'; +import type {TerrainData} from '../render/terrain'; export type DrawMode = WebGLRenderingContext['LINES'] | WebGLRenderingContext['TRIANGLES'] | WebGLRenderingContext['LINE_STRIP']; diff --git a/src/render/render_to_texture.ts b/src/render/render_to_texture.ts new file mode 100644 index 00000000000..5beb613d6d1 --- /dev/null +++ b/src/render/render_to_texture.ts @@ -0,0 +1,153 @@ +import Painter from "./painter"; +import Tile from "../source/tile"; +import Color from "../style-spec/util/color"; +import {OverscaledTileID} from "../source/tile_id"; +import {prepareTerrain, drawTerrain} from './draw_terrain'; + +export default class RenderToTexture { + painter: Painter; + // this object holds a lookup table which layers should rendered to texture + _renderToTexture: any; + // coordsDescendingInv contains a list of all tiles which should be rendered for one render-to-texture tile + // e.g. render 4 raster-tiles with size 256px to the 512px render-to-texture tile + _coordsDescendingInv: {[_: string]: {[_:string]: Array}} = {}; + // create a string representation of all to tiles rendered to render-to-texture tiles + // this string representation is used to check if tile should be re-rendered. + _coordsDescendingInvStr: {[_: string]: {[_:string]: string}} = {}; + // store for render-stacks + // a render stack is a set of layers which should be rendered into one texture + // every stylesheet can have multipe stacks. A new stack is created if layers which should + // not rendered to texture sit inbetween layers which should rendered to texture. e.g. hillshading or symbols + _stacks: Array>; + // remember the previous processed layer to check if a new stack is needed + _prevType: string; + // create a lookup which tiles should rendered to texture + _rerender: {[_: string]: boolean}; + // a list of tiles that can potentially rendered + _renderableTiles: Array; + + constructor(painter: Painter) { + this.painter = painter; + this._renderToTexture = {background: true, fill: true, line: true, raster: true}; + this._coordsDescendingInv = {}; + this._coordsDescendingInvStr = {}; + this._stacks = [] + this._prevType = null; + this._rerender = {}; + this._renderableTiles = painter.style.terrain.sourceCache.getRenderableTiles(); + this._init(); + } + + _init() { + const style = this.painter.style; + const terrain = style.terrain; + + // fill _coordsDescendingInv + for (const id in style.sourceCaches) { + this._coordsDescendingInv[id] = {}; + const tileIDs = style.sourceCaches[id].getVisibleCoordinates(); + for (const tileID of tileIDs) { + const keys = terrain.sourceCache.getTerrainCoords(tileID); + for (const key in keys) { + if (!this._coordsDescendingInv[id][key]) this._coordsDescendingInv[id][key] = []; + this._coordsDescendingInv[id][key].push(keys[key]); + } + } + } + + // fill _coordsDescendingInvStr + for (const id of style._order) { + const layer = style._layers[id], source = layer.source; + if (this._renderToTexture[layer.type]) { + if (!this._coordsDescendingInvStr[source]) { + this._coordsDescendingInvStr[source] = {}; + for (const key in this._coordsDescendingInv[source]) + this._coordsDescendingInvStr[source][key] = this._coordsDescendingInv[source][key].map(c => c.key).sort().join(); + } + } + } + + // remove cached textures + this._renderableTiles.forEach(tile => { + for (const source in this._coordsDescendingInvStr) { + // rerender if there are more coords to render than in the last rendering + const coords = this._coordsDescendingInvStr[source][tile.tileID.key]; + if (coords && coords !== tile.textureCoords[source]) tile.clearTextures(this.painter); + // rerender if tile is marked for rerender + if (terrain.needsRerender(source, tile.tileID)) tile.clearTextures(this.painter); + } + this._rerender[tile.tileID.key] = !tile.textures.length; + }); + terrain.clearRerenderCache(); + terrain.sourceCache.removeOutdated(this.painter); + + return this; + } + + /** + * due that switching textures is relatively slow, the render + * layer-by-layer context is not practicable. To bypass this problem + * this lines of code stack all layers and later render all at once. + * Because of the stylesheet possibility to mixing render-to-texture layers + * and 'live'-layers (f.e. symbols) it is necessary to create more stacks. For example + * a symbol-layer is in between of fill-layers. + * @param {Layer} layer + * @returns {boolean} if true layer is rendered to texture, otherwise false + */ + renderLayer(layer: any): boolean { + const type = layer.type; + const painter = this.painter; + const layerIds = painter.style._order; + const currentLayer = painter.currentLayer; + const isLastLayer = currentLayer + 1 === layerIds.length; + + // remember background, fill, line & raster layer to render into a stack + if (this._renderToTexture[type]) { + if (!this._prevType || !this._renderToTexture[this._prevType]) this._stacks.push([]); + this._prevType = type; + this._stacks[this._stacks.length - 1].push(layerIds[currentLayer]); + // rendering is done later, all in once + if (!isLastLayer) return true; + } + + // in case a stack is finished render all collected stack-layers into a texture + if (this._renderToTexture[this._prevType] || type === 'hillshade' || (this._renderToTexture[type] && isLastLayer)) { + this._prevType = type; + const stack = this._stacks.length - 1, layers = this._stacks[stack] || []; + for (const tile of this._renderableTiles) { + prepareTerrain(painter, painter.style.terrain, tile, stack); + if (this._rerender[tile.tileID.key]) { + painter.context.clear({color: Color.transparent}); + for (let l = 0; l < layers.length; l++) { + const layer = painter.style._layers[layers[l]]; + const coords = layer.source ? this._coordsDescendingInv[layer.source][tile.tileID.key] : [tile.tileID]; + painter._renderTileClippingMasks(layer, coords); + painter.renderLayer(painter, painter.style.sourceCaches[layer.source], layer, coords); + if (layer.source) tile.textureCoords[layer.source] = this._coordsDescendingInvStr[layer.source][tile.tileID.key]; + } + } + drawTerrain(painter, painter.style.terrain, tile); + } + + // the hillshading layer is a special case because it changes on every camera-movement + // so rerender it in any case. + if (type === 'hillshade') { + this._stacks.push([layerIds[currentLayer]]); + for (const tile of this._renderableTiles) { + const coords = this._coordsDescendingInv[layer.source][tile.tileID.key]; + prepareTerrain(painter, painter.style.terrain, tile, this._stacks.length - 1); + painter.context.clear({color: Color.transparent}); + painter._renderTileClippingMasks(layer, coords); + painter.renderLayer(painter, painter.style.sourceCaches[layer.source], layer, coords); + drawTerrain(painter, painter.style.terrain, tile); + } + return true; + } + + if (isLastLayer) return true; + } + + return false; + } + +} diff --git a/src/render/terrain.ts b/src/render/terrain.ts new file mode 100644 index 00000000000..bdbbec470cb --- /dev/null +++ b/src/render/terrain.ts @@ -0,0 +1,369 @@ + +import Tile from '../source/tile'; +import {mat4, vec2} from 'gl-matrix'; +import {OverscaledTileID} from '../source/tile_id'; +import {RGBAImage} from '../util/image'; +import {warnOnce} from '../util/util'; +import {PosArray, TriangleIndexArray} from '../data/array_types.g'; +import posAttributes from '../data/pos_attributes'; +import SegmentVector from '../data/segment'; +import VertexBuffer from '../gl/vertex_buffer'; +import IndexBuffer from '../gl/index_buffer'; +import Style, {TerrainOptions} from '../style/style'; +import Texture from '../render/texture'; +import type Framebuffer from '../gl/framebuffer'; +import Point from '@mapbox/point-geometry'; +import MercatorCoordinate from '../geo/mercator_coordinate'; +import TerrainSourceCache from '../source/terrain_source_cache'; +import SourceCache from '../source/source_cache'; +import EXTENT from '../data/extent'; +import {number as mix} from '../style-spec/util/interpolate'; + +/** + * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: + * 1) loads raster-dem tiles via the internal sourceCache this._source + * 2) creates a depth-framebuffer, which is used to calculate the visibility of coordinates + * 3) creates a coords-framebuffer, which is used the get to tile-coordinate for a screen-pixel + * 4) stores all render-to-texture tiles in the this._tiles variable + * 5) calculates the elevation for a spezific tile-coordinate + * 6) creates a terrain-mesh + * + * A note about the GPU resource-usage: + * Framebuffers: + * - one for the depth & coords framebuffer with the size of the map-div. + * - one for rendering a tile to texture with the size of tileSize (= 512x512). + * Textures: + * - one texture for an empty raster-dem tile with size 1x1 + * - one texture for an empty depth-buffer, when terrain is disabled with size 1x1 + * - one texture for an each loaded raster-dem with size of the source.tileSize + * - one texture for the coords-framebuffer with the size of the map-div. + * - one texture for the depth-framebuffer with the size of the map-div. + * - one texture for the encoded tile-coords with the size 2*tileSize (=1024x1024) + * - finally for each render-to-texture tile (= this._tiles) a set of textures + * for each render stack (The stack-concept is documented in painter.ts). + * Normally there exists 1-3 Textures per tile, depending on the stylesheet. + * Each Textures has the size 2*tileSize (= 1024x1024). Also there exists a + * cache of the last 150 newest rendered tiles. + * + */ + +export type TerrainData = { + 'u_depth': number; + 'u_terrain': number; + 'u_terrain_dim': number; + 'u_terrain_matrix': mat4; + 'u_terrain_unpack': number[]; + 'u_terrain_offset': number; + 'u_terrain_exaggeration': number; + texture: WebGLTexture; + depthTexture: WebGLTexture; + tile: Tile; +} + +export type TerrainMesh = { + indexBuffer: IndexBuffer; + vertexBuffer: VertexBuffer; + segments: SegmentVector; +} + +export default class Terrain { + // The style this terrain crresponds to + style: Style; + // the sourcecache this terrain is based on + sourceCache: TerrainSourceCache; + // the TerrainOptions object passed to this instance + options: TerrainOptions; + // define the meshSize per tile. + meshSize: number; + // multiplicator for the elevation. Used to make terrain more "extrem". + exaggeration: number; + // defines the global offset of putting negative elevations (e.g. dead-sea) into positive values. + elevationOffset: number; + // to not see pixels in the render-to-texture tiles it is good to render them bigger + // this number is the multiplicator (must be a power of 2) for the current tileSize. + // So to get good results with not too much memory footprint a value of 2 should be fine. + qualityFactor: number; + // holds the framebuffer object in size of the screen to render the coords & depth into a texture. + _fbo: any; + _fboCoordsTexture: Texture; + _fboDepthTexture: Texture; + _emptyDepthTexture: Texture; + // GL Objects for the terrain-mesh + // The mesh is a regular mesh, which has the advantage that it can be reused for all tiles. + _mesh: TerrainMesh; + // coords index contains a list of tileID.keys. This index is used to identify + // the tile via the alpha-cannel in the coords-texture. + // As the alpha-channel has 1 Byte a max of 255 tiles can rendered without an error. + _coordsIndex: Array; + // tile-coords encoded in the rgb channel, _coordsIndex is in the alpha-channel. + _coordsTexture: Texture; + // accuracy of the coords. 2 * tileSize should be enoughth. + _coordsTextureSize: number; + // variables for an empty dem texture, which is used while the raster-dem tile is loading. + _emptyDemUnpack: any; + _emptyDemTexture: Texture; + _emptyDemMatrix: mat4; + // as of overzooming of raster-dem tiles in high zoomlevels, this cache contains + // matrices to transform from vector-tile coords to raster-dem-tile coords. + _demMatrixCache: {[_: string]: { matrix: mat4; coord: OverscaledTileID }}; + // because of overzooming raster-dem tiles this cache holds the corresponding + // framebuffer-object to render tiles to texture + _rttFramebuffer: Framebuffer; + // loading raster-dem tiles foreach render-to-texture tile results in loading + // a lot of terrain-dem tiles with very low visual advantage. So with this setting + // remember all tiles which contains new data for a spezific source and tile-key. + _rerender: {[_: string]: {[_: number]: boolean}}; + + constructor(style: Style, sourceCache: SourceCache, options: TerrainOptions) { + this.style = style; + this.sourceCache = new TerrainSourceCache(sourceCache); + this.options = options; + this.exaggeration = typeof(options.exaggeration) === "number" ? options.exaggeration : 1.0; + this.elevationOffset = typeof(options.elevationOffset) === "number" ? options.elevationOffset : 450; // ~ dead-sea + this.qualityFactor = 2; + this.meshSize = 128; + this._demMatrixCache = {}; + this._coordsIndex = []; + this._coordsTextureSize = 1024; + this.clearRerenderCache(); + } + + /** + * get the elevation-value from original dem-data for a given tile-coordinate + * @param {OverscaledTileID} tileID - the tile to get elevation for + * @param {number} x between 0 .. EXTENT + * @param {number} y between 0 .. EXTENT + * @param {number} extent optional, default 8192 + * @returns {number} - the elevation + */ + getDEMElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { + if (!(x >= 0 && x < extent && y >= 0 && y < extent)) return this.elevationOffset; + let elevation = 0; + const terrain = this.getTerrainData(tileID); + if (terrain.tile && terrain.tile.dem) { + const pos = vec2.transformMat4([] as any, [x / extent * EXTENT, y / extent * EXTENT], terrain.u_terrain_matrix); + const coord = [ pos[0] * terrain.tile.dem.dim, pos[1] * terrain.tile.dem.dim ]; + const c = [ Math.floor(coord[0]), Math.floor(coord[1]) ]; + const tl = terrain.tile.dem.get(c[0], c[1]); + const tr = terrain.tile.dem.get(c[0], c[1] + 1); + const bl = terrain.tile.dem.get(c[0] + 1, c[1]); + const br = terrain.tile.dem.get(c[0] + 1, c[1] + 1); + elevation = mix(mix(tl, tr, coord[0] - c[0]), mix(bl, br, coord[0] - c[0]), coord[1] - c[1]); + } + return elevation; + } + + rememberForRerender(source: string, tileID: OverscaledTileID) { + for (const key in this.sourceCache._tiles) { + const tile = this.sourceCache._tiles[key]; + if (tile.tileID.equals(tileID) || tile.tileID.isChildOf(tileID)) { + if (source === this.sourceCache.sourceCache.id) tile.timeLoaded = Date.now(); + this._rerender[source] = this._rerender[source] || {}; + this._rerender[source][tile.tileID.key] = true; + } + } + } + + needsRerender(source: string, tileID: OverscaledTileID) { + return this._rerender[source] && this._rerender[source][tileID.key] + } + + clearRerenderCache() { + this._rerender = {}; + } + + /** + * get the Elevation for given coordinate in respect of elevationOffset and exaggeration. + * @param {OverscaledTileID} tileID - the tile id + * @param {number} x between 0 .. EXTENT + * @param {number} y between 0 .. EXTENT + * @param {number} extent optional, default 8192 + * @returns {number} - the elevation + */ + getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { + return (this.getDEMElevation(tileID, x, y, extent) + this.elevationOffset) * this.exaggeration; + } + + /** + * returns a Terrain Object for a tile. Unless the tile corresponds to data (e.g. tile is loading), return a flat dem object + * @param {OverscaledTileID} tileID - the tile to get the terrain for + * @returns {TerrainData} the terrain data to use in the program + */ + getTerrainData(tileID: OverscaledTileID): TerrainData { + // create empty DEM Obejcts, which will used while raster-dem tiles are loading. + // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. + if (!this._emptyDemTexture) { + const context = this.style.map.painter.context; + const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); + this._emptyDepthTexture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); + this._emptyDemUnpack = [0, 0, 0, 0]; + this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); + this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + this._emptyDemMatrix = mat4.identity([] as any); + } + // find covering dem tile and prepare demTexture + const sourceTile = this.sourceCache.getSourceTile(tileID, true); + if (sourceTile && sourceTile.dem && (!sourceTile.demTexture || sourceTile.needsTerrainPrepare)) { + const context = this.style.map.painter.context; + sourceTile.demTexture = this.style.map.painter.getTileTexture(sourceTile.dem.stride); + if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); + else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); + sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + sourceTile.needsTerrainPrepare = false; + } + // create matrix for lookup in dem data + const matrixKey = sourceTile && (sourceTile + sourceTile.tileID.key) + tileID.key; + if (matrixKey && !this._demMatrixCache[matrixKey]) { + const maxzoom = this.sourceCache.sourceCache._source.maxzoom; + let dz = tileID.canonical.z - sourceTile.tileID.canonical.z; + if (tileID.overscaledZ > tileID.canonical.z) { + if (tileID.canonical.z >= maxzoom) dz = tileID.canonical.z - maxzoom; + else warnOnce('cannot calculate elevation if elevation maxzoom > source.maxzoom'); + } + const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); + const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); + const demMatrix = mat4.fromScaling(new Float64Array(16) as any, [1 / (EXTENT << dz), 1 / (EXTENT << dz), 0]); + mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); + this._demMatrixCache[tileID.key] = {matrix: demMatrix, coord: tileID}; + } + // return uniform values & textures + return { + 'u_depth': 2, + 'u_terrain': 3, + 'u_terrain_dim': sourceTile && sourceTile.dem && sourceTile.dem.dim || 1, + 'u_terrain_matrix': matrixKey ? this._demMatrixCache[tileID.key].matrix : this._emptyDemMatrix, + 'u_terrain_unpack': sourceTile && sourceTile.dem && sourceTile.dem.getUnpackVector() || this._emptyDemUnpack, + 'u_terrain_offset': this.elevationOffset, + 'u_terrain_exaggeration': this.exaggeration, + texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, + depthTexture: (this._fboDepthTexture || this._emptyDepthTexture).texture, + tile: sourceTile + }; + } + + + /** + * create the render-to-texture framebuffer + * @returns {Framebuffer} - the frame buffer + */ + getRTTFramebuffer() { + const painter = this.style.map.painter; + if (!this._rttFramebuffer) { + const size = this.sourceCache.tileSize * this.qualityFactor; + this._rttFramebuffer = painter.context.createFramebuffer(size, size, true); + this._rttFramebuffer.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, size, size)); + } + return this._rttFramebuffer; + } + + /** + * get a framebuffer as big as the map-div, which will be used to render depth & coords into a texture + * @param {string} texture - the texture + * @returns {Framebuffer} the frame buffer + */ + getFramebuffer(texture: string): Framebuffer { + const painter = this.style.map.painter; + const width = painter.width / devicePixelRatio; + const height = painter.height / devicePixelRatio; + if (this._fbo && (this._fbo.width !== width || this._fbo.height !== height)) { + this._fbo.destroy(); + this._fboCoordsTexture.destroy(); + this._fboDepthTexture.destroy(); + delete this._fbo; + delete this._fboDepthTexture; + delete this._fboCoordsTexture; + } + if (!this._fboCoordsTexture) { + this._fboCoordsTexture = new Texture(painter.context, {width, height, data: null}, painter.context.gl.RGBA, {premultiply: false}); + this._fboCoordsTexture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); + } + if (!this._fboDepthTexture) { + this._fboDepthTexture = new Texture(painter.context, {width, height, data: null}, painter.context.gl.RGBA, {premultiply: false}); + this._fboDepthTexture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); + } + if (!this._fbo) { + this._fbo = painter.context.createFramebuffer(width, height, true); + this._fbo.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, width, height)); + } + this._fbo.colorAttachment.set(texture === 'coords' ? this._fboCoordsTexture.texture : this._fboDepthTexture.texture); + return this._fbo; + } + + /** + * create coords texture, needed to grab coordinates from canvas + * encode coords coordinate into 4 bytes: + * - 8 lower bits for x + * - 8 lower bits for y + * - 4 higher bits for x + * - 4 higher bits for y + * - 8 bits for coordsIndex (1 .. 255) (= number of terraintile), is later setted in draw_terrain uniform value + * @returns {Texture} - the texture + */ + getCoordsTexture(): Texture { + const context = this.style.map.painter.context; + if (this._coordsTexture) return this._coordsTexture; + const data = new Uint8Array(this._coordsTextureSize * this._coordsTextureSize * 4); + for (let y = 0, i = 0; y < this._coordsTextureSize; y++) for (let x = 0; x < this._coordsTextureSize; x++, i += 4) { + data[i + 0] = x & 255; + data[i + 1] = y & 255; + data[i + 2] = ((x >> 8) << 4) | (y >> 8); + data[i + 3] = 0; + } + const image = new RGBAImage({width: this._coordsTextureSize, height: this._coordsTextureSize}, new Uint8Array(data.buffer)); + const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); + texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); + this._coordsTexture = texture; + return texture; + } + + /** + * Reads a Pixel from the Coords-Framebuffer and translate this to mercator. + * @param {Point} p Screen-Coordinate + * @returns {MercatorCoordinate} mercator coordinate for a screen pixel + */ + pointCoordinate(p: Point): MercatorCoordinate { + const rgba = new Uint8Array(4); + const painter = this.style.map.painter, context = painter.context, gl = context.gl; + // grab coordinate pixel from coordinates framebuffer + context.bindFramebuffer.set(this.getFramebuffer('coords').framebuffer); + gl.readPixels(p.x, painter.height / devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); + context.bindFramebuffer.set(null); + // decode coordinates (encoding see terrain-source-cache) + const x = rgba[0] + ((rgba[2] >> 4) << 8); + const y = rgba[1] + ((rgba[2] & 15) << 8); + const tileID = this._coordsIndex[255 - rgba[3]]; + const tile = tileID && this.sourceCache.getTileByID(tileID); + if (!tile) return null; + const coordsSize = this._coordsTextureSize; + const worldSize = (1 << tile.tileID.canonical.z) * coordsSize; + return new MercatorCoordinate( + (tile.tileID.canonical.x * coordsSize + x) / worldSize, + (tile.tileID.canonical.y * coordsSize + y) / worldSize, + this.getElevation(tile.tileID, x, y, coordsSize) + ); + } + + /** + * create a regular mesh which will be used by all terrain-tiles + * @returns {TerrainMesh} - the created regular mesh + */ + getTerrainMesh(): TerrainMesh { + if (this._mesh) return this._mesh; + const context = this.style.map.painter.context; + const vertexArray = new PosArray(), indexArray = new TriangleIndexArray(); + const meshSize = this.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; + for (let y = 0; y <= meshSize; y++) for (let x = 0; x <= meshSize; x++) + vertexArray.emplaceBack(x * delta, y * delta); + for (let y = 0; y < meshSize2; y += meshSize + 1) for (let x = 0; x < meshSize; x++) { + indexArray.emplaceBack(x + y, meshSize + x + y + 1, meshSize + x + y + 2); + indexArray.emplaceBack(x + y, meshSize + x + y + 2, x + y + 1); + } + this._mesh = { + indexBuffer: context.createIndexBuffer(indexArray), + vertexBuffer: context.createVertexBuffer(vertexArray, posAttributes.members), + segments: SegmentVector.simpleSegment(0, 0, vertexArray.length, indexArray.length) + }; + return this._mesh; + } + +} diff --git a/src/shaders/symbol_icon.fragment.glsl b/src/shaders/symbol_icon.fragment.glsl index 5892ec8c1df..4f6d75e70fb 100644 --- a/src/shaders/symbol_icon.fragment.glsl +++ b/src/shaders/symbol_icon.fragment.glsl @@ -2,7 +2,6 @@ uniform sampler2D u_texture; varying vec2 v_tex; varying float v_fade_opacity; -varying float v_visibility; #pragma mapbox: define lowp float opacity diff --git a/src/shaders/symbol_sdf.fragment.glsl b/src/shaders/symbol_sdf.fragment.glsl index ba2c9756dfb..6b077543069 100644 --- a/src/shaders/symbol_sdf.fragment.glsl +++ b/src/shaders/symbol_sdf.fragment.glsl @@ -8,7 +8,6 @@ uniform bool u_is_text; varying vec2 v_data0; varying vec3 v_data1; -varying float v_visibility; #pragma mapbox: define highp vec4 fill_color #pragma mapbox: define highp vec4 halo_color diff --git a/src/shaders/symbol_text_and_icon.fragment.glsl b/src/shaders/symbol_text_and_icon.fragment.glsl index a3c2e408d19..6220563c415 100644 --- a/src/shaders/symbol_text_and_icon.fragment.glsl +++ b/src/shaders/symbol_text_and_icon.fragment.glsl @@ -11,7 +11,6 @@ uniform lowp float u_device_pixel_ratio; varying vec4 v_data0; varying vec4 v_data1; -varying float v_visibility; #pragma mapbox: define highp vec4 fill_color #pragma mapbox: define highp vec4 halo_color diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index b722e8517f0..d8529a73373 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -529,7 +529,7 @@ class SourceCache extends Evented { const parent = tileID.scaledTo(tileID.canonical.z - 1); parents[parent.key] = parent; // load very low zoom to calculate tile visability in transform.coveringTiles correct - const parent2 = tileID.scaledTo(Math.max(this._source.minzoom, 5)); + const parent2 = tileID.scaledTo(Math.max(this._source.minzoom, Math.min(tileID.canonical.z, 5))); parents[parent2.key] = parent2; } } @@ -573,9 +573,8 @@ class SourceCache extends Evented { } } - // disable fading logic in renderToTexture (e.g. 3D) mode - // e.g. avoid rendering two tiles on the same place - if (this.style && this.style.terrainSourceCache && this.style.terrainSourceCache.isEnabled()) { + // disable fading logic in terrain3D mode to avoid rendering two tiles on the same place + if (this.style && this.style.terrain) { const idealRasterTileIDs: {[_: string]: OverscaledTileID} = {}; const missingTileIDs: {[_: string]: OverscaledTileID} = {}; for (const tileID of idealTileIDs) { diff --git a/src/source/terrain_source_cache.test.ts b/src/source/terrain_source_cache.test.ts index 1fe1ce27571..87caf9b4b54 100644 --- a/src/source/terrain_source_cache.test.ts +++ b/src/source/terrain_source_cache.test.ts @@ -9,6 +9,7 @@ import Painter from '../render/painter'; import Context from '../gl/context'; import gl from 'gl'; import RasterDEMTileSource from './raster_dem_tile_source'; +import LngLat from '../geo/lng_lat'; const context = new Context(gl(10, 10)); const transform = new Transform(); @@ -67,7 +68,7 @@ describe('TerrainSourceCache', () => { const source = createSource({url: '/source.json'}); server.respond(); style.addSource('terrain', source as any); - tsc = new TerrainSourceCache(style); + tsc = new TerrainSourceCache(style.sourceCaches.terrain); done(); }); style.loadJSON({ @@ -81,25 +82,22 @@ describe('TerrainSourceCache', () => { server.restore(); }); - test('#enable', () => { - tsc.enable(style.sourceCaches['terrain']); - expect(tsc.exaggeration).toBe(1); - expect(tsc.elevationOffset).toBe(450); - expect(style.sourceCaches['terrain'].usedForTerrain).toBeTruthy(); - expect(style.sourceCaches['terrain'].tileSize).toBe(1024); - expect(tsc.isEnabled()).toBeTruthy(); - - tsc.enable(style.sourceCaches['terrain'], {exaggeration: 2, elevationOffset: 1000}); - expect(tsc.exaggeration).toBe(2); - expect(tsc.elevationOffset).toBe(1000); + test('#constructor', () => { + expect(tsc.sourceCache.usedForTerrain).toBeTruthy(); + expect(tsc.sourceCache.tileSize).toBe(tsc.tileSize * 2 ** tsc.deltaZoom); }); - test('#disable', () => { - tsc.disable(); - expect(tsc._sourceCache).toBeNull(); - expect(style.sourceCaches['terrain'].usedForTerrain).toBeFalsy(); - expect(tsc.isEnabled()).toBeFalsy(); - expect(tsc._tiles).toEqual({}); - }); + // test('#update', () => { + // const transform = new Transform(0, 22, 0, 60, true); + // transform.center = new LngLat(10, 50); + // transform.zoom = 10; + // tsc.update(transform); + + // // expect(tsc.exaggeration).toBe(1); + // // expect(tsc.elevationOffset).toBe(450); + // // expect(style.sourceCaches['terrain'].usedForTerrain).toBeTruthy(); + // // expect(style.sourceCaches['terrain'].tileSize).toBe(1024); + // // expect(tsc.isEnabled()).toBeTruthy(); + // }); }); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 70d8308db28..1953ec164b5 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -1,43 +1,11 @@ import {OverscaledTileID} from './tile_id'; import Tile from './tile'; import EXTENT from '../data/extent'; -import {mat4, vec2} from 'gl-matrix'; +import {mat4} from 'gl-matrix'; import {Evented} from '../util/evented'; -import Style from '../style/style'; -import Texture from '../render/texture'; -import {RGBAImage} from '../util/image'; -import {PosArray, TriangleIndexArray} from '../data/array_types.g'; -import {number as mix} from '../style-spec/util/interpolate'; -import posAttributes from '../data/pos_attributes'; -import SegmentVector from '../data/segment'; import type Transform from '../geo/transform'; import type SourceCache from '../source/source_cache'; -import type Context from '../gl/context'; -import type Painter from '../render/painter'; -import type RasterDEMTileSource from '../source/raster_dem_tile_source'; -import type Framebuffer from '../gl/framebuffer'; -import {warnOnce} from '../util/util'; -import VertexBuffer from '../gl/vertex_buffer'; -import IndexBuffer from '../gl/index_buffer'; - -export type TerrainData = { - 'u_depth': number; - 'u_terrain': number; - 'u_terrain_dim': number; - 'u_terrain_matrix': mat4; - 'u_terrain_unpack': number[]; - 'u_terrain_offset': number; - 'u_terrain_exaggeration': number; - texture: WebGLTexture; - depthTexture: WebGLTexture; - tile: Tile; -} - -export type TerrainMesh = { - indexBuffer: IndexBuffer; - vertexBuffer: VertexBuffer; - segments: SegmentVector; -} +import Painter from '../render/painter'; /** * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: @@ -67,153 +35,52 @@ export type TerrainMesh = { * */ -class TerrainSourceCache extends Evented { - _style: Style; - _source: RasterDEMTileSource; + export default class TerrainSourceCache extends Evented { // source-cache for the raster-dem source. - _sourceCache: SourceCache; + sourceCache: SourceCache; // stores all render-to-texture tiles. _tiles: {[_: string]: Tile}; - // because _tiles holds, for performance, also previous rendered tiles - // this variable contains a list of tiles for the current scene. - _renderableTiles: Array; - // each time a render-to-texture tile is rendered, its tileID.key is stored into this array - // each time a screen is rendered, the last 100 rendered tiles will be kept in cache (e.g. this._tiles). - _renderHistory: Array; - // holds the framebuffer object in size of the screen to render the coords & depth into a texture. - _fbo: any; - _fboCoordsTexture: Texture; - _fboDepthTexture: Texture; - _emptyDepthTexture: Texture; - // GL Objects for the terrain-mesh - // The mesh is a regular mesh, which has the advantage that it can be reused for all tiles. - _mesh: TerrainMesh; - // coords index contains a list of tileID.keys. This index is used to identify - // the tile via the alpha-cannel in the coords-texture. - // As the alpha-channel has 1 Byte a max of 255 tiles can rendered without an error. - _coordsIndex: Array; - // tile-coords encoded in the rgb channel, _coordsIndex is in the alpha-channel. - _coordsTexture: Texture; - // accuracy of the coords. 2 * tileSize should be enoughth. - _coordsTextureSize: number; - // variables for an empty dem texture, which is used while the raster-dem tile is loading. - _emptyDemUnpack: any; - _emptyDemTexture: Texture; - _emptyDemMatrix: mat4; - // as of overzooming of raster-dem tiles in high zoomlevels, this cache contains - // matrices to transform from vector-tile coords to raster-dem-tile coords. - _demMatrixCache: {[_: string]: { matrix: mat4; coord: OverscaledTileID }}; - // because of overzooming raster-dem tiles this cache holds the corresponding - // raster-dem-tile for a vector-tile. + // contains a list of tileID-keys for the current scene. (only for performance) + _renderableTilesKeys: Array; + // raster-dem-tile for a TileID cache. _sourceTileCache: {[_: string]: string}; - // framebuffer-object to render tiles to texture - _rttFramebuffer: Framebuffer; // minimum zoomlevel to render the terrain. minzoom: number; // maximum zoomlevel to render the terrain. maxzoom: number; // render-to-texture tileSize in scene. tileSize: number; - // define the meshSize per tile. - meshSize: number; - // multiplicator for the elevation. Used to make terrain more "extrem". - exaggeration: number; - // defines the global offset of putting negative elevations (e.g. dead-sea) into positive values. - elevationOffset: number; - // to not see pixels in the render-to-texture tiles it is good to render them bigger - // this number is the multiplicator (must be a power of 2) for the current tileSize. - // So to get good results with not too much memory footprint a value of 2 should be fine. - qualityFactor: number; - // loading raster-dem tiles foreach render-to-texture tile results in loading - // a lot of terrain-dem tiles with very low visual advantage. So with this setting - // the raster-dem tiles will load for the actualZoom - deltaZoom zoom-level. + // raster-dem tiles will load for performance the actualZoom - deltaZoom zoom-level. deltaZoom: number; - // remember all tiles which contains new data for a spezific source and tile-key. - rerender: {[_: string]: {[_: number]: boolean}}; + // each time a render-to-texture tile is rendered, its tileID.key is stored into this array + renderHistory: Array; + // maximal size of render-history + renderHistorySize: number - /** - * @param {Style} style - the style - */ - constructor(style: Style) { + constructor(sourceCache: SourceCache) { super(); - this._style = style; + this.sourceCache = sourceCache; this._tiles = {}; - this._renderableTiles = []; - this._renderHistory = []; - this._demMatrixCache = {}; + this._renderableTilesKeys = []; this._sourceTileCache = {}; - this._coordsIndex = []; - this._coordsTextureSize = 1024; + this.renderHistory = []; this.minzoom = 0; this.maxzoom = 22; this.tileSize = 512; - this.meshSize = 128; - this.exaggeration = 1.0; - this.elevationOffset = 450; // ~ dead-sea - this.qualityFactor = 2; this.deltaZoom = 1; - this.rerender = {}; - - // rerender corresponding tiles on terrain-dem source-tile updates - style.on('data', e => { - if (e.dataType === 'source' && e.coord && this.isEnabled()) { - // redraw current and overscaled terrain-tiles - if (e.sourceId === this._sourceCache.id) { - for (const key in this._tiles) { - const tile = this._tiles[key]; - if (tile.tileID.equals(e.coord) || tile.tileID.isChildOf(e.coord)) { - tile.timeLoaded = Date.now(); - tile.clearTextures(this._style.map.painter); - } - } - style.map.transform.updateElevation(); - } - // remember GeoJson tile updates in rerender cache - if (e.source.type === 'geojson') { - this.rerender[e.sourceId] = this.rerender[e.sourceId] || {}; - this.rerender[e.sourceId][e.tile.tileID.key] = true; - } - } - }); - } - - /** - * Loads a 3D terrain-mesh - * @param {SourceCache} sourceCache - the source cache - * @param options Allowed options are exaggeration & elevationOffset - * @param options.exaggeration - the exaggeration - * @param options.elevationOffset - the elevation offset - */ - enable(sourceCache: SourceCache, options?: {exaggeration: number; elevationOffset: number}): void { + this.renderHistorySize = 150; sourceCache.usedForTerrain = true; sourceCache.tileSize = this.tileSize * 2 ** this.deltaZoom; - this._sourceCache = sourceCache; - ['exaggeration', 'elevationOffset'].forEach(key => { - if (options && options[key] !== undefined) this[key] = options[key]; - }); } - /** - * remove the the 3d terrain from map. - */ - disable(): void { - if (!this._sourceCache) return; - this._sourceCache.usedForTerrain = false; - this._sourceCache = null; + destruct() { + this.sourceCache.usedForTerrain = false; + this.sourceCache.tileSize = null; for (const key in this._tiles) { const tile = this._tiles[key]; tile.textures.forEach(t => t.destroy()); tile.textures = []; } - this._tiles = {}; - } - - /** - * check if terrain is currently activated - * @returns {boolean} - true if the terrain source cache is enabled, false otherwise - */ - isEnabled(): boolean { - return !!this._sourceCache; } /** @@ -221,45 +88,52 @@ class TerrainSourceCache extends Evented { * @param {Transform} transform - the operation to do */ update(transform: Transform): void { - if (!this.isEnabled() || !this._sourceCache._sourceLoaded) return; // load raster-dem tiles for the current scene. - transform.updateElevation(); - this._sourceCache.update(transform); - this._renderableTiles = []; - const tileIDs = {}; + this.sourceCache.update(transform); // create internal render-to-texture tiles for the current scene. + this._renderableTilesKeys = []; for (const tileID of transform.coveringTiles({ tileSize: this.tileSize, minzoom: this.minzoom, maxzoom: this.maxzoom, reparseOverscaled: false })) { - this._renderableTiles.push(tileID.key); - tileIDs[tileID.key] = true; + this._renderableTilesKeys.push(tileID.key); if (!this._tiles[tileID.key]) { tileID.posMatrix = new Float64Array(16) as any; mat4.ortho(tileID.posMatrix, 0, EXTENT, 0, EXTENT, 0, 1); this._tiles[tileID.key] = new Tile(tileID, this.tileSize); } } - // remove duplicates from _renderHistory - this._renderHistory = this._renderHistory.filter((i, p) => this._renderHistory.indexOf(i) === p); + } + + /** + * This method should called before each render-to-texture step to free old cached tiles + * @param {Painter} painter + */ + removeOutdated(painter: Painter) { + // create lookuptable for actual needed tiles + const tileIDs = {}; + for (const key of this._renderableTilesKeys) tileIDs[key] = true; + // remove duplicates from renderHistory + this.renderHistory = this.renderHistory.filter((i, p) => this.renderHistory.indexOf(i) === p); // free (GPU) memory from previously rendered not needed tiles - while (this._renderHistory.length > 150) { - const tile = this._tiles[this._renderHistory.shift()]; + while (this.renderHistory.length > this.renderHistorySize) { + const tile = this.sourceCache._tiles[this.renderHistory.shift()]; if (tile && !tileIDs[tile.tileID.key]) { - tile.clearTextures(this._style.map.painter); - delete this._tiles[tile.tileID.key]; + tile.clearTextures(painter); + delete this.sourceCache._tiles[tile.tileID.key]; } } } + /** * get a list of tiles, which are loaded and should be rendered in the current scene * @returns {Array} the renderable tiles */ getRenderableTiles(): Array { - return this._renderableTiles.map(key => this.getTileByID(key)); + return this._renderableTilesKeys.map(key => this.getTileByID(key)); } /** @@ -272,13 +146,13 @@ class TerrainSourceCache extends Evented { } /** - * searches for the corresponding current rendered terrain-tiles + * searches for the corresponding current renderable terrain-tiles * @param {OverscaledTileID} tileID - the tile to look for * @returns {[_:string]: Tile} - the tiles that were found */ getTerrainCoords(tileID: OverscaledTileID): {[_: string]: OverscaledTileID} { const coords = {}; - for (const key of this._renderableTiles) { + for (const key of this._renderableTilesKeys) { const _tileID = this._tiles[key].tileID; if (_tileID.canonical.equals(tileID.canonical)) { const coord = tileID.clone(); @@ -318,166 +192,21 @@ class TerrainSourceCache extends Evented { * @returns {Tile} - the tile */ getSourceTile(tileID: OverscaledTileID, searchForDEM?: boolean): Tile { - if (!this.isEnabled()) return null; - const source = this._sourceCache._source; + const source = this.sourceCache._source; let z = tileID.overscaledZ - this.deltaZoom; if (z > source.maxzoom) z = source.maxzoom; if (z < source.minzoom) return null; // cache for tileID to terrain-tileID if (!this._sourceTileCache[tileID.key]) this._sourceTileCache[tileID.key] = tileID.scaledTo(z).key; - let tile = this._sourceCache.getTileByID(this._sourceTileCache[tileID.key]); + let tile = this.sourceCache.getTileByID(this._sourceTileCache[tileID.key]); // during tile-loading phase look if parent tiles (with loaded dem) are available. if (!(tile && tile.dem) && searchForDEM) while (z > source.minzoom && !(tile && tile.dem)) - tile = this._sourceCache.getTileByID(tileID.scaledTo(z--).key); + tile = this.sourceCache.getTileByID(tileID.scaledTo(z--).key); return tile; } - /** - * returns a Terrain Object for a tile. Unless the tile corresponds to data (e.g. tile is loading), return a flat dem object - * @param {OverscaledTileID} tileID - the tile to get the terrain for - * @returns {TerrainData} the terrain data to use in the program - */ - getTerrain(tileID: OverscaledTileID): TerrainData { - if (!this.isEnabled()) return null; - // create empty DEM Obejcts, which will used while raster-dem tiles are loading. - // creates an empty depth-buffer texture which is needed, during the initialisation process of the 3d mesh.. - if (!this._emptyDemTexture) { - const context = this._style.map.painter.context; - const image = new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)); - this._emptyDepthTexture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); - this._emptyDemUnpack = [0, 0, 0, 0]; - this._emptyDemTexture = new Texture(context, new RGBAImage({width: 1, height: 1}), context.gl.RGBA, {premultiply: false}); - this._emptyDemTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - this._emptyDemMatrix = mat4.identity([] as any); - } - // find covering dem tile and prepare demTexture - const sourceTile = this.getSourceTile(tileID, true); - if (sourceTile && sourceTile.dem && (!sourceTile.demTexture || sourceTile.needsTerrainPrepare)) { - const context = this._style.map.painter.context; - sourceTile.demTexture = this._style.map.painter.getTileTexture(sourceTile.dem.stride); - if (sourceTile.demTexture) sourceTile.demTexture.update(sourceTile.dem.getPixels(), {premultiply: false}); - else sourceTile.demTexture = new Texture(context, sourceTile.dem.getPixels(), context.gl.RGBA, {premultiply: false}); - sourceTile.demTexture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - sourceTile.needsTerrainPrepare = false; - } - // create matrix for lookup in dem data - const matrixKey = sourceTile && (sourceTile + sourceTile.tileID.key) + tileID.key; - if (matrixKey && !this._demMatrixCache[matrixKey]) { - const maxzoom = this._sourceCache._source.maxzoom; - let dz = tileID.canonical.z - sourceTile.tileID.canonical.z; - if (tileID.overscaledZ > tileID.canonical.z) { - if (tileID.canonical.z >= maxzoom) dz = tileID.canonical.z - maxzoom; - else warnOnce('cannot calculate elevation if elevation maxzoom > source.maxzoom'); - } - const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz); - const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz); - const demMatrix = mat4.fromScaling(new Float64Array(16) as any, [1 / (EXTENT << dz), 1 / (EXTENT << dz), 0]); - mat4.translate(demMatrix, demMatrix, [dx * EXTENT, dy * EXTENT, 0]); - this._demMatrixCache[tileID.key] = {matrix: demMatrix, coord: tileID}; - } - // return uniform values & textures - return { - 'u_depth': 2, - 'u_terrain': 3, - 'u_terrain_dim': sourceTile && sourceTile.dem && sourceTile.dem.dim || 1, - 'u_terrain_matrix': matrixKey ? this._demMatrixCache[tileID.key].matrix : this._emptyDemMatrix, - 'u_terrain_unpack': sourceTile && sourceTile.dem && sourceTile.dem.getUnpackVector() || this._emptyDemUnpack, - 'u_terrain_offset': this.elevationOffset, - 'u_terrain_exaggeration': this.exaggeration, - texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, - depthTexture: (this._fboDepthTexture || this._emptyDepthTexture).texture, - tile: sourceTile - }; - } - - /** - * get the elevation-value from original dem-data for a given tile-coordinate - * @param {OverscaledTileID} tileID - the tile to get elevation for - * @param {number} x between 0 .. EXTENT - * @param {number} y between 0 .. EXTENT - * @param {number} extent optional, default 8192 - * @returns {number} - the elevation - */ - getDEMElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { - if (!this.isEnabled()) return 0.0; - if (!(x >= 0 && x < extent && y >= 0 && y < extent)) return this.elevationOffset; - let elevation = 0; - const terrain = this.getTerrain(tileID); - if (terrain.tile && terrain.tile.dem) { - const pos = vec2.transformMat4([] as any, [x / extent * EXTENT, y / extent * EXTENT], terrain.u_terrain_matrix); - const coord = [ pos[0] * terrain.tile.dem.dim, pos[1] * terrain.tile.dem.dim ]; - const c = [ Math.floor(coord[0]), Math.floor(coord[1]) ]; - const tl = terrain.tile.dem.get(c[0], c[1]); - const tr = terrain.tile.dem.get(c[0], c[1] + 1); - const bl = terrain.tile.dem.get(c[0] + 1, c[1]); - const br = terrain.tile.dem.get(c[0] + 1, c[1] + 1); - elevation = mix(mix(tl, tr, coord[0] - c[0]), mix(bl, br, coord[0] - c[0]), coord[1] - c[1]); - } - return elevation; - } - - /** - * get the Elevation for given coordinate in respect of elevationOffset and exaggeration. - * @param {OverscaledTileID} tileID - the tile id - * @param {number} x between 0 .. EXTENT - * @param {number} y between 0 .. EXTENT - * @param {number} extent optional, default 8192 - * @returns {number} - the elevation - */ - getElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { - if (!this.isEnabled()) return 0.0; - return (this.getDEMElevation(tileID, x, y, extent) + this.elevationOffset) * this.exaggeration; - } - - /** - * create the render-to-texture framebuffer - * @param {Painter} painter - the painter - * @returns {Framebuffer} - the frame buffer - */ - getRTTFramebuffer(painter: Painter) { - if (!this._rttFramebuffer) { - const size = this.tileSize * this.qualityFactor; - this._rttFramebuffer = painter.context.createFramebuffer(size, size, true); - this._rttFramebuffer.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, size, size)); - } - return this._rttFramebuffer; - } - - /** - * get a framebuffer as big as the map-div, which will be used to render depth & coords into a texture - * @param {Painter} painter - the painter - * @param {string} texture - the texture - * @returns {Framebuffer} the frame buffer - */ - getFramebuffer(painter: Painter, texture: string): Framebuffer { - const width = painter.width / devicePixelRatio; - const height = painter.height / devicePixelRatio; - if (this._fbo && (this._fbo.width !== width || this._fbo.height !== height)) { - this._fbo.destroy(); - this._fboCoordsTexture.destroy(); - this._fboDepthTexture.destroy(); - delete this._fbo; - delete this._fboDepthTexture; - delete this._fboCoordsTexture; - } - if (!this._fboCoordsTexture) { - this._fboCoordsTexture = new Texture(painter.context, {width, height, data: null}, painter.context.gl.RGBA, {premultiply: false}); - this._fboCoordsTexture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); - } - if (!this._fboDepthTexture) { - this._fboDepthTexture = new Texture(painter.context, {width, height, data: null}, painter.context.gl.RGBA, {premultiply: false}); - this._fboDepthTexture.bind(painter.context.gl.NEAREST, painter.context.gl.CLAMP_TO_EDGE); - } - if (!this._fbo) { - this._fbo = painter.context.createFramebuffer(width, height, true); - this._fbo.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, width, height)); - } - this._fbo.colorAttachment.set(texture === 'coords' ? this._fboCoordsTexture.texture : this._fboDepthTexture.texture); - return this._fbo; - } - /** * get a list of tiles, loaded after a spezific time. This is used to update depth & coords framebuffers. * @param {Date} time - the time @@ -486,56 +215,4 @@ class TerrainSourceCache extends Evented { tilesAfterTime(time = Date.now()): Array { return Object.values(this._tiles).filter(t => t.timeLoaded >= time); } - - /** - * create a regular mesh which will be used by all terrain-tiles - * @param {Context} context - the context - * @returns {TerrainMesh} - the created regular mesh - */ - getTerrainMesh(context: Context): TerrainMesh { - if (this._mesh) return this._mesh; - const vertexArray = new PosArray(), indexArray = new TriangleIndexArray(); - const meshSize = this.meshSize, delta = EXTENT / meshSize, meshSize2 = meshSize * meshSize; - for (let y = 0; y <= meshSize; y++) for (let x = 0; x <= meshSize; x++) - vertexArray.emplaceBack(x * delta, y * delta); - for (let y = 0; y < meshSize2; y += meshSize + 1) for (let x = 0; x < meshSize; x++) { - indexArray.emplaceBack(x + y, meshSize + x + y + 1, meshSize + x + y + 2); - indexArray.emplaceBack(x + y, meshSize + x + y + 2, x + y + 1); - } - this._mesh = { - indexBuffer: context.createIndexBuffer(indexArray), - vertexBuffer: context.createVertexBuffer(vertexArray, posAttributes.members), - segments: SegmentVector.simpleSegment(0, 0, vertexArray.length, indexArray.length) - }; - return this._mesh; - } - - /** - * create coords texture, needed to grab coordinates from canvas - * encode coords coordinate into 4 bytes: - * - 8 lower bits for x - * - 8 lower bits for y - * - 4 higher bits for x - * - 4 higher bits for y - * - 8 bits for coordsIndex (1 .. 255) (= number of terraintile), is later setted in draw_terrain uniform value - * @param {Context} context - the context - * @returns {Texture} - the texture - */ - getCoordsTexture(context: Context): Texture { - if (this._coordsTexture) return this._coordsTexture; - const data = new Uint8Array(this._coordsTextureSize * this._coordsTextureSize * 4); - for (let y = 0, i = 0; y < this._coordsTextureSize; y++) for (let x = 0; x < this._coordsTextureSize; x++, i += 4) { - data[i + 0] = x & 255; - data[i + 1] = y & 255; - data[i + 2] = ((x >> 8) << 4) | (y >> 8); - data[i + 3] = 0; - } - const image = new RGBAImage({width: this._coordsTextureSize, height: this._coordsTextureSize}, new Uint8Array(data.buffer)); - const texture = new Texture(context, image, context.gl.RGBA, {premultiply: false}); - texture.bind(context.gl.NEAREST, context.gl.CLAMP_TO_EDGE); - this._coordsTexture = texture; - return texture; - } } - -export default TerrainSourceCache; diff --git a/src/style/style.ts b/src/style/style.ts index f529a387cdf..92ab087b0e5 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -17,7 +17,6 @@ import {getSourceType, setSourceType, Source} from '../source/source'; import type {SourceClass} from '../source/source'; import {queryRenderedFeatures, queryRenderedSymbols, querySourceFeatures} from '../source/query_features'; import SourceCache from '../source/source_cache'; -import TerrainSourceCache from '../source/terrain_source_cache'; import GeoJSONSource from '../source/geojson_source'; import styleSpec from '../style-spec/reference/latest'; import getWorkerPool from '../util/global_worker_pool'; @@ -62,6 +61,7 @@ import type { import type {CustomLayerInterface} from './style_layer/custom_style_layer'; import type {Validator} from './validate_style'; import type {OverscaledTileID} from '../source/tile_id'; +import Terrain from '../render/terrain'; const supportedDiffOperations = pick(diffOperations, [ 'addLayer', @@ -96,6 +96,13 @@ export type StyleOptions = { export type StyleSetterOptions = { validate?: boolean; }; + +export type TerrainOptions = { + source: string; + exaggeration?: number; + elevationOffset?: number; +}; + /** * @private */ @@ -107,6 +114,7 @@ class Style extends Evented { glyphManager: GlyphManager; lineAtlas: LineAtlas; light: Light; + terrain: Terrain; _request: Cancelable; _spriteRequest: Cancelable; @@ -114,10 +122,10 @@ class Style extends Evented { _serializedLayers: {[_: string]: any}; _order: Array; sourceCaches: {[_: string]: SourceCache}; - terrainSourceCache: TerrainSourceCache; zoomHistory: ZoomHistory; _loaded: boolean; _rtlTextPluginCallback: (a: any) => any; + _terrainDataCallback: (e: any) => any; _changed: boolean; _updatedSources: {[_: string]: 'clear' | 'reload'}; _updatedLayers: {[_: string]: true}; @@ -152,14 +160,10 @@ class Style extends Evented { this._serializedLayers = {}; this._order = []; this.sourceCaches = {}; - this.terrainSourceCache = new TerrainSourceCache(this); this.zoomHistory = new ZoomHistory(); this._loaded = false; this._availableImages = []; - // make elevation accessible from map.transform - if (map.transform) map.transform.terrainSourceCache = this.terrainSourceCache; - this._resetUpdates(); this.dispatcher.broadcast('setReferrer', getReferrer()); @@ -477,6 +481,31 @@ class Style extends Evented { this._changedImages = {}; } + setTerrain(options?: TerrainOptions) { + // clear event handlers + if (this._terrainDataCallback) this.off("data", this._terrainDataCallback) + // add terrain + if (options) { + const sourceCache = this.sourceCaches[options.source]; + this.map.transform.terrain = this.terrain = new Terrain(this, sourceCache, options); + this.map.transform.updateElevation(); + this._terrainDataCallback = e => { + if (!e.tile) return; + if (e.sourceId === options.source) { + this.map.transform.updateElevation(); + this.terrain.rememberForRerender(e.sourceId, e.tile.tileID); + } else if (e.source.type === 'geojson') { + this.terrain.rememberForRerender(e.sourceId, e.tile.tileID); + } + }; + this.on("data", this._terrainDataCallback); + // remove terrain + } else { + this.terrain = this.map.transform.terrain = null; + this.map.transform.updateElevation(); + } + } + /** * Update this style's state to match the given style JSON, performing only * the necessary mutations. @@ -1270,7 +1299,6 @@ class Style extends Evented { } _updateSources(transform: Transform) { - this.terrainSourceCache.update(transform); for (const id in this.sourceCaches) { this.sourceCaches[id].update(transform); } diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index e7defbc18b0..3a352dce8e1 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -492,9 +492,7 @@ export class Placement { // update elevation of collisionArrays const tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; - const getElevation = this.transform.terrainSourceCache && this.transform.terrainSourceCache.isEnabled() ? - (x: number, y: number) => this.transform.terrainSourceCache.getElevation(tileID, x, y) : - null; + const getElevation = this.transform.terrain ? (x: number, y: number) => this.transform.terrain.getElevation(tileID, x, y) : null; for (const boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { const box = collisionArrays[boxType]; if (box) box.elevation = getElevation ? getElevation(box.anchorPointX, box.anchorPointY) : 0; diff --git a/src/ui/camera.ts b/src/ui/camera.ts index 663b7dc63fe..1ff9903cabf 100644 --- a/src/ui/camera.ts +++ b/src/ui/camera.ts @@ -935,8 +935,7 @@ abstract class Camera extends Evented { } delete this._easeId; this.transform.freezeElevation = false; - if (this.transform.terrainSourceCache && this.transform.terrainSourceCache.isEnabled()) - this.transform.recalculateZoom(); + if (this.transform.terrain) this.transform.recalculateZoom(); const wasZooming = this._zooming; const wasRotating = this._rotating; diff --git a/src/ui/control/terrain_control.ts b/src/ui/control/terrain_control.ts index 64412eb7449..5fc952c83b2 100644 --- a/src/ui/control/terrain_control.ts +++ b/src/ui/control/terrain_control.ts @@ -3,11 +3,7 @@ import {bindAll} from '../../util/util'; import type Map from '../map'; import type {IControl} from './control'; - -type TerrainOptions = { - id?: string; - options?: {exaggeration: number; elevationOffset: number}; -}; +import type {TerrainOptions} from '../../style/style'; /** * An `TerrainControl` control adds a button to turn terrain on and off. @@ -19,7 +15,7 @@ type TerrainOptions = { * @example * var map = new maplibregl.Map({TerrainControl: false}) * .addControl(new maplibregl.TerrainControl({ - * id: "terrain" + * source: "terrain" * })); */ class TerrainControl implements IControl { @@ -28,7 +24,7 @@ class TerrainControl implements IControl { _container: HTMLElement; _terrainButton: HTMLButtonElement; - constructor(options: TerrainOptions = {}) { + constructor(options: TerrainOptions) { this.options = options; bindAll([ @@ -57,10 +53,10 @@ class TerrainControl implements IControl { } _toggleTerrain() { - if (this._map.style.terrainSourceCache.isEnabled()) { - this._map.removeTerrain(); + if (this._map.getTerrain()) { + this._map.setTerrain(null); } else { - this._map.addTerrain(this.options.id, this.options.options); + this._map.setTerrain(this.options); } this._updateTerrainIcon(); } @@ -68,7 +64,7 @@ class TerrainControl implements IControl { _updateTerrainIcon() { this._terrainButton.classList.remove('maplibregl-ctrl-terrain', 'mapboxgl-ctrl-terrain'); this._terrainButton.classList.remove('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); - if (this._map.isTerrainLoaded()) { + if (this._map.style.terrain) { this._terrainButton.classList.add('maplibregl-ctrl-terrain-enabled', 'mapboxgl-ctrl-terrain-enabled'); this._terrainButton.title = this._map._getUIString('TerrainControl.disableTerrain'); } else { diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index f1415d4eaf9..d454af20e22 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -415,7 +415,7 @@ class HandlerManager { _updateMapTransform(combinedResult: any, combinedEventsInProgress: any, deactivatedHandlers: any) { const map = this._map; const tr = map.transform; - const hasTerrain = map.style && map.style.terrainSourceCache && map.style.terrainSourceCache.isEnabled(); + const hasTerrain = map.style && map.style.terrain; if (!hasChange(combinedResult) && !(hasTerrain && this._drag)) { return this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); @@ -456,7 +456,7 @@ class HandlerManager { // when dragging ends, recalcuate the zoomlevel for the new center coordinate } else if (this._drag && deactivatedHandlers[this._drag.handlerName]) { tr.freezeElevation = false; - if (hasTerrain) tr.recalculateZoom(); + tr.recalculateZoom(); this._drag = null; // drag map } else if (combinedEventsInProgress.drag && this._drag) { diff --git a/src/ui/map.ts b/src/ui/map.ts index 79d7438006e..b4c0e77b2b4 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -3,7 +3,7 @@ import browser from '../util/browser'; import DOM from '../util/dom'; import {getImage, getJSON, ResourceType} from '../util/ajax'; import {RequestManager} from '../util/request_manager'; -import Style from '../style/style'; +import Style, { TerrainOptions } from '../style/style'; import EvaluationParameters from '../style/evaluation_parameters'; import Painter from '../render/painter'; import Transform from '../geo/transform'; @@ -55,6 +55,7 @@ import type { } from '../style-spec/types.g'; import {Callback} from '../types/callback'; import type {ControlPosition, IControl} from './control/control'; +import Terrain from '../render/terrain'; /* eslint-enable no-use-before-define */ @@ -868,7 +869,7 @@ class Map extends Camera { * var point = map.project(coordinate); */ project(lnglat: LngLatLike) { - return this.style && this.style.terrainSourceCache.isEnabled() ? + return this.style && this.style.terrain ? this.transform.locationPoint3D(LngLat.convert(lnglat)) : this.transform.locationPoint(LngLat.convert(lnglat)); } @@ -886,7 +887,7 @@ class Map extends Camera { * }); */ unproject(point: PointLike) { - return this.style && this.style.terrainSourceCache.isEnabled() ? + return this.style && this.style.terrain ? this.transform.pointLocation3D(Point.convert(point)) : this.transform.pointLocation(Point.convert(point)); } @@ -1576,48 +1577,28 @@ class Map extends Camera { /** * Loads a 3D terrain mesh, based on a "raster-dem" source. - * - * @param {string} id The ID of the raster-dem source to use. - * @param options Allowed options are exaggeration, elevationOffset - * @param options.exaggeration - the exaggeration - * @param options.elevationOffset - the elevation offset + * @param {TerrainOptions} [options] Options object. * @returns {Map} `this` * @example - * map.addTerrain('my-data'); + * map.setTerrain({ source: 'terrain' }); */ - addTerrain(id: string, options?: {exaggeration: number; elevationOffset: number}): Map { - this.isSourceLoaded(id); - this.style.terrainSourceCache.enable(this.style.sourceCaches[id], options); - this.transform.updateElevation(); - this.style.terrainSourceCache.update(this.transform); + setTerrain(options: TerrainOptions): Map { + if (options) this.isSourceLoaded(options.source); + this.style.setTerrain(options); this._sourcesDirty = true; this._styleDirty = true; this.triggerRepaint(); - this.fire(new Event('terrain')); return this; } /** - * Returns a Boolean indicating whether terrain is loaded. - * @returns {boolean} true if the terrain is loaded - */ - isTerrainLoaded(): boolean { - return this.style.terrainSourceCache.isEnabled(); - } - - /** - * Removes the 3D terrain mesh from the map. - * - * @returns {Map} `this` + * Get the terrain-options if terrain is loaded + * @returns {TerrainOptions} * @example - * map.removeTerrain(); + * map.getTerrain(); // { source: 'terrain' }; */ - removeTerrain(): Map { - this.style.terrainSourceCache.disable(); - this.transform.updateElevation(); - this.triggerRepaint(); - this.fire(new Event('terrain')); - return this; + getTerrain(): TerrainOptions { + return this.style.terrain && this.style.terrain.options; } /** @@ -2612,6 +2593,10 @@ class Map extends Camera { this.style._updateSources(this.transform); } + // update terrain stuff + if (this.style.terrain) this.style.terrain.sourceCache.update(this.transform); + this.transform.updateElevation(); + this._placementDirty = this.style && this.style._updatePlacement(this.painter.transform, this.showCollisionBoxes, this._fadeDuration, this._crossSourceCollisions); // Actually draw diff --git a/src/ui/marker.ts b/src/ui/marker.ts index 9eb516e526d..d49fd9aaefa 100644 --- a/src/ui/marker.ts +++ b/src/ui/marker.ts @@ -472,8 +472,7 @@ export default class Marker extends Evented { DOM.setTransform(this._element, `${anchorTranslate[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${pitch} ${rotation}`); // in case of 3D, ask the the terrain coords-framebuffer for this pos and check if the marker is visible - const tsc = this._map.style && this._map.style.terrainSourceCache; - if (tsc && tsc.isEnabled() && !this._opacityTimeout) this._opacityTimeout = setTimeout(() => { + if (this._map.style && this._map.style.terrain && !this._opacityTimeout) this._opacityTimeout = setTimeout(() => { const lnglat = this._map.unproject(this._pos); const metresPerPixel = 40075016.686 * Math.abs(Math.cos(this._lngLat.lat * Math.PI / 180)) / Math.pow(2, this._map.transform.tileZoom + 8); this._element.style.opacity = lnglat.distanceTo(this._lngLat) > metresPerPixel * 20 ? '0.2' : '1.0'; From 4ea0c2ad5a380a009b17f1f1554f16948a1a6b21 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 30 Mar 2022 12:42:48 +0200 Subject: [PATCH 116/138] fix lint errors --- debug/terrain.html | 2 +- src/geo/transform.ts | 2 +- src/render/draw_fill.ts | 1 - src/render/draw_terrain.ts | 44 ++++++++++++------------- src/render/render_to_texture.ts | 16 ++++----- src/render/terrain.ts | 39 +++++++++++----------- src/source/terrain_source_cache.test.ts | 14 -------- src/source/terrain_source_cache.ts | 7 ++-- src/style/style.ts | 4 +-- src/ui/map.ts | 4 +-- 10 files changed, 58 insertions(+), 75 deletions(-) diff --git a/debug/terrain.html b/debug/terrain.html index 61446d76ec9..32eaf6a48f9 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -36,7 +36,7 @@ 'maxzoom': 14, 'minzoom': 4 }); - map.setTerrain({ source: 'terrain', exaggeration: 0.33 }); + map.setTerrain({source: 'terrain', exaggeration: 0.33}); }); map.on('click', e => { diff --git a/src/geo/transform.ts b/src/geo/transform.ts index b74481ed58d..d880281e8b9 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -497,7 +497,7 @@ class Transform { const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / EXTENT), tileY = Math.floor(mercY / EXTENT); const tileID = new OverscaledTileID(this.tileZoom, 0, this.tileZoom, tileX, tileY); - return this.terrain.getElevation(tileID, mercX % EXTENT, mercY % EXTENT, EXTENT) + return this.terrain.getElevation(tileID, mercX % EXTENT, mercY % EXTENT, EXTENT); } /** diff --git a/src/render/draw_fill.ts b/src/render/draw_fill.ts index 9d9f560e234..e8a58733680 100644 --- a/src/render/draw_fill.ts +++ b/src/render/draw_fill.ts @@ -83,7 +83,6 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode const program = painter.useProgram(programName, programConfiguration); const terrainData = painter.style.terrain && painter.style.terrain.getTerrainData(coord); - if (image) { painter.context.activeTexture.set(gl.TEXTURE0); tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 8cfac84084c..6f7a08913ac 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -11,28 +11,28 @@ import Terrain from './terrain'; /** * Redraw the Depth Framebuffer - * @param {Painter} painter - * @param {Terrain} terrain + * @param {Painter} painter - the painter + * @param {Terrain} terrain - the terrain */ - function drawDepth(painter: Painter, terrain: Terrain) { - const context = painter.context; - const gl = context.gl; - const colorMode = ColorMode.unblended; - const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); - const mesh = terrain.getTerrainMesh(); - const tiles = terrain.sourceCache.getRenderableTiles(); - const program = painter.useProgram('terrainDepth'); - context.bindFramebuffer.set(terrain.getFramebuffer('depth').framebuffer); - context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); - context.clear({color: Color.transparent, depth: 1}); - for (const tile of tiles) { - const terrainData = terrain.getTerrainData(tile.tileID); - const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainDepthUniformValues(posMatrix); - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); - } - context.bindFramebuffer.set(null); - context.viewport.set([0, 0, painter.width, painter.height]); +function drawDepth(painter: Painter, terrain: Terrain) { + const context = painter.context; + const gl = context.gl; + const colorMode = ColorMode.unblended; + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); + const mesh = terrain.getTerrainMesh(); + const tiles = terrain.sourceCache.getRenderableTiles(); + const program = painter.useProgram('terrainDepth'); + context.bindFramebuffer.set(terrain.getFramebuffer('depth').framebuffer); + context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); + context.clear({color: Color.transparent, depth: 1}); + for (const tile of tiles) { + const terrainData = terrain.getTerrainData(tile.tileID); + const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); + const uniformValues = terrainDepthUniformValues(posMatrix); + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); + } + context.bindFramebuffer.set(null); + context.viewport.set([0, 0, painter.width, painter.height]); } /** @@ -50,7 +50,7 @@ function drawCoords(painter: Painter, terrain: Terrain) { const tiles = terrain.sourceCache.getRenderableTiles(); // draw tile-coords into framebuffer - let program = painter.useProgram('terrainCoords'); + const program = painter.useProgram('terrainCoords'); context.bindFramebuffer.set(terrain.getFramebuffer('coords').framebuffer); context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); context.clear({color: Color.transparent, depth: 1}); diff --git a/src/render/render_to_texture.ts b/src/render/render_to_texture.ts index 5beb613d6d1..746fbc77a43 100644 --- a/src/render/render_to_texture.ts +++ b/src/render/render_to_texture.ts @@ -1,7 +1,7 @@ -import Painter from "./painter"; -import Tile from "../source/tile"; -import Color from "../style-spec/util/color"; -import {OverscaledTileID} from "../source/tile_id"; +import Painter from './painter'; +import Tile from '../source/tile'; +import Color from '../style-spec/util/color'; +import {OverscaledTileID} from '../source/tile_id'; import {prepareTerrain, drawTerrain} from './draw_terrain'; export default class RenderToTexture { @@ -31,7 +31,7 @@ export default class RenderToTexture { this._renderToTexture = {background: true, fill: true, line: true, raster: true}; this._coordsDescendingInv = {}; this._coordsDescendingInvStr = {}; - this._stacks = [] + this._stacks = []; this._prevType = null; this._rerender = {}; this._renderableTiles = painter.style.terrain.sourceCache.getRenderableTiles(); @@ -60,9 +60,9 @@ export default class RenderToTexture { const layer = style._layers[id], source = layer.source; if (this._renderToTexture[layer.type]) { if (!this._coordsDescendingInvStr[source]) { - this._coordsDescendingInvStr[source] = {}; + this._coordsDescendingInvStr[source] = {}; for (const key in this._coordsDescendingInv[source]) - this._coordsDescendingInvStr[source][key] = this._coordsDescendingInv[source][key].map(c => c.key).sort().join(); + this._coordsDescendingInvStr[source][key] = this._coordsDescendingInv[source][key].map(c => c.key).sort().join(); } } } @@ -91,7 +91,7 @@ export default class RenderToTexture { * Because of the stylesheet possibility to mixing render-to-texture layers * and 'live'-layers (f.e. symbols) it is necessary to create more stacks. For example * a symbol-layer is in between of fill-layers. - * @param {Layer} layer + * @param {Layer} layer the layer to render * @returns {boolean} if true layer is rendered to texture, otherwise false */ renderLayer(layer: any): boolean { diff --git a/src/render/terrain.ts b/src/render/terrain.ts index bdbbec470cb..08baf6a4fb2 100644 --- a/src/render/terrain.ts +++ b/src/render/terrain.ts @@ -48,16 +48,16 @@ import {number as mix} from '../style-spec/util/interpolate'; */ export type TerrainData = { - 'u_depth': number; - 'u_terrain': number; - 'u_terrain_dim': number; - 'u_terrain_matrix': mat4; - 'u_terrain_unpack': number[]; - 'u_terrain_offset': number; - 'u_terrain_exaggeration': number; - texture: WebGLTexture; - depthTexture: WebGLTexture; - tile: Tile; + 'u_depth': number; + 'u_terrain': number; + 'u_terrain_dim': number; + 'u_terrain_matrix': mat4; + 'u_terrain_unpack': number[]; + 'u_terrain_offset': number; + 'u_terrain_exaggeration': number; + texture: WebGLTexture; + depthTexture: WebGLTexture; + tile: Tile; } export type TerrainMesh = { @@ -118,8 +118,8 @@ export default class Terrain { this.style = style; this.sourceCache = new TerrainSourceCache(sourceCache); this.options = options; - this.exaggeration = typeof(options.exaggeration) === "number" ? options.exaggeration : 1.0; - this.elevationOffset = typeof(options.elevationOffset) === "number" ? options.elevationOffset : 450; // ~ dead-sea + this.exaggeration = typeof options.exaggeration === 'number' ? options.exaggeration : 1.0; + this.elevationOffset = typeof options.elevationOffset === 'number' ? options.elevationOffset : 450; // ~ dead-sea this.qualityFactor = 2; this.meshSize = 128; this._demMatrixCache = {}; @@ -136,7 +136,7 @@ export default class Terrain { * @param {number} extent optional, default 8192 * @returns {number} - the elevation */ - getDEMElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { + getDEMElevation(tileID: OverscaledTileID, x: number, y: number, extent: number = EXTENT): number { if (!(x >= 0 && x < extent && y >= 0 && y < extent)) return this.elevationOffset; let elevation = 0; const terrain = this.getTerrainData(tileID); @@ -165,7 +165,7 @@ export default class Terrain { } needsRerender(source: string, tileID: OverscaledTileID) { - return this._rerender[source] && this._rerender[source][tileID.key] + return this._rerender[source] && this._rerender[source][tileID.key]; } clearRerenderCache() { @@ -238,10 +238,9 @@ export default class Terrain { texture: (sourceTile && sourceTile.demTexture || this._emptyDemTexture).texture, depthTexture: (this._fboDepthTexture || this._emptyDepthTexture).texture, tile: sourceTile - }; + }; } - /** * create the render-to-texture framebuffer * @returns {Framebuffer} - the frame buffer @@ -252,8 +251,8 @@ export default class Terrain { const size = this.sourceCache.tileSize * this.qualityFactor; this._rttFramebuffer = painter.context.createFramebuffer(size, size, true); this._rttFramebuffer.depthAttachment.set(painter.context.createRenderbuffer(painter.context.gl.DEPTH_COMPONENT16, size, size)); - } - return this._rttFramebuffer; + } + return this._rttFramebuffer; } /** @@ -261,7 +260,7 @@ export default class Terrain { * @param {string} texture - the texture * @returns {Framebuffer} the frame buffer */ - getFramebuffer(texture: string): Framebuffer { + getFramebuffer(texture: string): Framebuffer { const painter = this.style.map.painter; const width = painter.width / devicePixelRatio; const height = painter.height / devicePixelRatio; @@ -299,7 +298,7 @@ export default class Terrain { * - 8 bits for coordsIndex (1 .. 255) (= number of terraintile), is later setted in draw_terrain uniform value * @returns {Texture} - the texture */ - getCoordsTexture(): Texture { + getCoordsTexture(): Texture { const context = this.style.map.painter.context; if (this._coordsTexture) return this._coordsTexture; const data = new Uint8Array(this._coordsTextureSize * this._coordsTextureSize * 4); diff --git a/src/source/terrain_source_cache.test.ts b/src/source/terrain_source_cache.test.ts index 87caf9b4b54..053d30c5e4c 100644 --- a/src/source/terrain_source_cache.test.ts +++ b/src/source/terrain_source_cache.test.ts @@ -9,7 +9,6 @@ import Painter from '../render/painter'; import Context from '../gl/context'; import gl from 'gl'; import RasterDEMTileSource from './raster_dem_tile_source'; -import LngLat from '../geo/lng_lat'; const context = new Context(gl(10, 10)); const transform = new Transform(); @@ -87,17 +86,4 @@ describe('TerrainSourceCache', () => { expect(tsc.sourceCache.tileSize).toBe(tsc.tileSize * 2 ** tsc.deltaZoom); }); - // test('#update', () => { - // const transform = new Transform(0, 22, 0, 60, true); - // transform.center = new LngLat(10, 50); - // transform.zoom = 10; - // tsc.update(transform); - - // // expect(tsc.exaggeration).toBe(1); - // // expect(tsc.elevationOffset).toBe(450); - // // expect(style.sourceCaches['terrain'].usedForTerrain).toBeTruthy(); - // // expect(style.sourceCaches['terrain'].tileSize).toBe(1024); - // // expect(tsc.isEnabled()).toBeTruthy(); - // }); - }); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 1953ec164b5..b8f423b3452 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -35,7 +35,7 @@ import Painter from '../render/painter'; * */ - export default class TerrainSourceCache extends Evented { +export default class TerrainSourceCache extends Evented { // source-cache for the raster-dem source. sourceCache: SourceCache; // stores all render-to-texture tiles. @@ -55,7 +55,7 @@ import Painter from '../render/painter'; // each time a render-to-texture tile is rendered, its tileID.key is stored into this array renderHistory: Array; // maximal size of render-history - renderHistorySize: number + renderHistorySize: number; constructor(sourceCache: SourceCache) { super(); @@ -109,7 +109,7 @@ import Painter from '../render/painter'; /** * This method should called before each render-to-texture step to free old cached tiles - * @param {Painter} painter + * @param {Painter} painter - the painter */ removeOutdated(painter: Painter) { // create lookuptable for actual needed tiles @@ -127,7 +127,6 @@ import Painter from '../render/painter'; } } - /** * get a list of tiles, which are loaded and should be rendered in the current scene * @returns {Array} the renderable tiles diff --git a/src/style/style.ts b/src/style/style.ts index daab861b44a..ca4000b92e5 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -490,7 +490,7 @@ class Style extends Evented { setTerrain(options?: TerrainOptions) { // clear event handlers - if (this._terrainDataCallback) this.off("data", this._terrainDataCallback) + if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); // add terrain if (options) { const sourceCache = this.sourceCaches[options.source]; @@ -505,7 +505,7 @@ class Style extends Evented { this.terrain.rememberForRerender(e.sourceId, e.tile.tileID); } }; - this.on("data", this._terrainDataCallback); + this.on('data', this._terrainDataCallback); // remove terrain } else { this.terrain = this.map.transform.terrain = null; diff --git a/src/ui/map.ts b/src/ui/map.ts index fbcceca9275..d8040fc9076 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -3,7 +3,7 @@ import browser from '../util/browser'; import DOM from '../util/dom'; import {getImage, GetImageCallback, getJSON, ResourceType} from '../util/ajax'; import {RequestManager} from '../util/request_manager'; -import Style, { TerrainOptions } from '../style/style'; +import Style, {TerrainOptions} from '../style/style'; import EvaluationParameters from '../style/evaluation_parameters'; import Painter from '../render/painter'; import Transform from '../geo/transform'; @@ -1589,7 +1589,7 @@ class Map extends Camera { /** * Get the terrain-options if terrain is loaded - * @returns {TerrainOptions} + * @returns {TerrainOptions} the TerrainOptions passed to setTerrain * @example * map.getTerrain(); // { source: 'terrain' }; */ From 485db090b0c5a31e49313391813314db79da8ad5 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 30 Mar 2022 15:15:23 +0200 Subject: [PATCH 117/138] add tests for sourceCache.usedForTerrain partent-tile-logic --- src/source/source_cache.test.ts | 83 +++++++++++++++++++++++++++++++++ src/source/source_cache.ts | 2 +- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/source/source_cache.test.ts b/src/source/source_cache.test.ts index 4d8d309c5b0..18a9351c117 100644 --- a/src/source/source_cache.test.ts +++ b/src/source/source_cache.test.ts @@ -1690,3 +1690,86 @@ describe('SourceCache#onRemove', () => { expect(sourceOnRemove).toHaveBeenCalled(); }); }); + +describe('SourceCache#usedForTerrain', () => { + test('loads covering tiles with usedForTerrain with source zoom 0-14', done => { + const transform = new Transform(); + transform.resize(511, 511); + transform.zoom = 10; + + const sourceCache = createSourceCache({}); + sourceCache.usedForTerrain = true; + sourceCache.tileSize = 1024; + expect(sourceCache.usedForTerrain).toBeTruthy(); + sourceCache.on('data', (e) => { + if (e.sourceDataType === 'metadata') { + sourceCache.update(transform); + expect(Object.values(sourceCache._tiles).map(t => t.tileID.key)).toEqual( + ['2tc099', '2tbz99', '2sxs99', '2sxr99', 'pds88', 'eo55', 'pdr88', 'en55', 'p6o88', 'ds55', 'p6n88', 'dr55'] + ); + done(); + } + }); + sourceCache.onAdd(undefined); + }); + + test('loads covering tiles with usedForTerrain with source zoom 8-14', done => { + const transform = new Transform(); + transform.resize(511, 511); + transform.zoom = 10; + + const sourceCache = createSourceCache({minzoom: 8, maxzoom: 14}); + sourceCache.usedForTerrain = true; + sourceCache.tileSize = 1024; + sourceCache.on('data', (e) => { + if (e.sourceDataType === 'metadata') { + sourceCache.update(transform); + expect(Object.values(sourceCache._tiles).map(t => t.tileID.key)).toEqual( + ['2tc099', '2tbz99', '2sxs99', '2sxr99', 'pds88', 'pdr88', 'p6o88', 'p6n88'] + ); + done(); + } + }); + sourceCache.onAdd(undefined); + }); + + test('loads covering tiles with usedForTerrain with source zoom 0-4', done => { + const transform = new Transform(); + transform.resize(511, 511); + transform.zoom = 10; + + const sourceCache = createSourceCache({minzoom: 0, maxzoom: 4}); + sourceCache.usedForTerrain = true; + sourceCache.tileSize = 1024; + sourceCache.on('data', (e) => { + if (e.sourceDataType === 'metadata') { + sourceCache.update(transform); + expect(Object.values(sourceCache._tiles).map(t => t.tileID.key)).toEqual( + ['1033', '3s44', '3r44', '3c44', '3b44', 'z33', 's33', 'r33'] + ); + done(); + } + }); + sourceCache.onAdd(undefined); + }); + + test('loads covering tiles with usedForTerrain with source zoom 4-4', done => { + const transform = new Transform(); + transform.resize(511, 511); + transform.zoom = 10; + + const sourceCache = createSourceCache({minzoom: 4, maxzoom: 4}); + sourceCache.usedForTerrain = true; + sourceCache.tileSize = 1024; + sourceCache.on('data', (e) => { + if (e.sourceDataType === 'metadata') { + sourceCache.update(transform); + expect(Object.values(sourceCache._tiles).map(t => t.tileID.key)).toEqual( + ['3s44', '3r44', '3c44', '3b44'] + ); + done(); + } + }); + sourceCache.onAdd(undefined); + }); +}); diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index 68ec24c2f9c..e9b6239c8e5 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -532,7 +532,7 @@ class SourceCache extends Evented { if (tileID.canonical.z > this._source.minzoom) { const parent = tileID.scaledTo(tileID.canonical.z - 1); parents[parent.key] = parent; - // load very low zoom to calculate tile visability in transform.coveringTiles correct + // load very low zoom to calculate tile visability in transform.coveringTiles and high zoomlevels correct const parent2 = tileID.scaledTo(Math.max(this._source.minzoom, Math.min(tileID.canonical.z, 5))); parents[parent2.key] = parent2; } From de9e7da2b3c452387a4fa383d7d6d1c236409a82 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 30 Mar 2022 16:20:07 +0200 Subject: [PATCH 118/138] minor fixes --- src/geo/transform.ts | 8 ++++---- src/shaders/collision_box.vertex.glsl | 1 - src/ui/handler_manager.ts | 4 ++-- src/ui/marker.ts | 5 +++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index d880281e8b9..4966ce15ed7 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -842,15 +842,15 @@ class Transform { // Find the distance from the center point to the horizon const horizon = this.getHorizon(); const horizonAngle = Math.atan(horizon / this.cameraToCenterDistance); - const fovAboveCenter2 = 2 * horizonAngle * (0.5 + offset.y / (horizon * 2)); - const topHalfSurfaceDistance2 = Math.sin(fovAboveCenter2) * this.cameraToSeaLevelDistance / Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter2, 0.01, Math.PI - 0.01)); + const fovCenterToHorizon = 2 * horizonAngle * (0.5 + offset.y / (horizon * 2)); + const topHalfSurfaceDistanceHorizon = Math.sin(fovCenterToHorizon) * this.cameraToSeaLevelDistance / Math.sin(clamp(Math.PI - groundAngle - fovCenterToHorizon, 0.01, Math.PI - 0.01)); // Calculate z distance of the farthest fragment that should be rendered. const furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToSeaLevelDistance; - const furthestDistance2 = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance2 + this.cameraToSeaLevelDistance; + const furthestDistanceHorizon = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistanceHorizon + this.cameraToSeaLevelDistance; // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` - const farZ = Math.min(furthestDistance, furthestDistance2) * 1.01; + const farZ = Math.min(furthestDistance, furthestDistanceHorizon) * 1.01; // The larger the value of nearZ is // - the more depth precision is available for features (good) diff --git a/src/shaders/collision_box.vertex.glsl b/src/shaders/collision_box.vertex.glsl index f76cc473fa1..6107e234b23 100644 --- a/src/shaders/collision_box.vertex.glsl +++ b/src/shaders/collision_box.vertex.glsl @@ -1,4 +1,3 @@ -// FIXME-3D! use 3d coordinates attribute vec2 a_pos; attribute vec2 a_anchor_pos; attribute vec2 a_extrude; diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index a4dcddbfc42..b333b7d653b 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -441,10 +441,10 @@ class HandlerManager { } else { // when 3d-terrain is enabled act a litte different: // - draging do not drag the picked point itself, instead it drags the map by pixel-delta. - // With this approach it is no longer possible to pick a point from from somewhere near + // With this approach it is no longer possible to pick a point from somewhere near // the horizon to the center in one move. // So this logic avoids the problem, that in such cases you easily loose orientation. - // - scrollzoom does not zoom into the mouse-point, instead it zoomt into map-center + // - scrollzoom does not zoom into the mouse-point, instead it zooms into map-center // this should be fixed in future-version // when dragging starts, remember mousedown-location and panDelta from this point if (combinedEventsInProgress.drag && !this._drag) { diff --git a/src/ui/marker.ts b/src/ui/marker.ts index d49fd9aaefa..9aa3a193049 100644 --- a/src/ui/marker.ts +++ b/src/ui/marker.ts @@ -74,7 +74,7 @@ export default class Marker extends Evented { _pitchAlignment: string; _rotationAlignment: string; _originalTabIndex: string; // original tabindex of _element - _opacityTimeout: any; + _opacityTimeout: ReturnType; constructor(options?: MarkerOptions, legacyOptions?: MarkerOptions) { super(); @@ -471,7 +471,8 @@ export default class Marker extends Evented { DOM.setTransform(this._element, `${anchorTranslate[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${pitch} ${rotation}`); - // in case of 3D, ask the the terrain coords-framebuffer for this pos and check if the marker is visible + // in case of 3D, ask the terrain coords-framebuffer for this pos and check if the marker is visible + // call this logic in setTimeout with a timeout of 100ms to save performance in map-movement if (this._map.style && this._map.style.terrain && !this._opacityTimeout) this._opacityTimeout = setTimeout(() => { const lnglat = this._map.unproject(this._pos); const metresPerPixel = 40075016.686 * Math.abs(Math.cos(this._lngLat.lat * Math.PI / 180)) / Math.pow(2, this._map.transform.tileZoom + 8); From 433d14eb73db2581ab2d3fef04827dc6d73b2cdf Mon Sep 17 00:00:00 2001 From: HarelM Date: Wed, 30 Mar 2022 21:02:48 +0300 Subject: [PATCH 119/138] Added some types and minor changes. --- src/render/render_to_texture.ts | 7 ++++--- src/render/terrain.ts | 4 ++-- src/style/style.ts | 12 ++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/render/render_to_texture.ts b/src/render/render_to_texture.ts index 746fbc77a43..d006db5dee9 100644 --- a/src/render/render_to_texture.ts +++ b/src/render/render_to_texture.ts @@ -3,11 +3,12 @@ import Tile from '../source/tile'; import Color from '../style-spec/util/color'; import {OverscaledTileID} from '../source/tile_id'; import {prepareTerrain, drawTerrain} from './draw_terrain'; +import type StyleLayer from '../style/style_layer'; export default class RenderToTexture { painter: Painter; // this object holds a lookup table which layers should rendered to texture - _renderToTexture: any; + _renderToTexture: {[keyof in StyleLayer['type']]?: boolean}; // coordsDescendingInv contains a list of all tiles which should be rendered for one render-to-texture tile // e.g. render 4 raster-tiles with size 256px to the 512px render-to-texture tile _coordsDescendingInv: {[_: string]: {[_:string]: Array}} = {}; @@ -91,10 +92,10 @@ export default class RenderToTexture { * Because of the stylesheet possibility to mixing render-to-texture layers * and 'live'-layers (f.e. symbols) it is necessary to create more stacks. For example * a symbol-layer is in between of fill-layers. - * @param {Layer} layer the layer to render + * @param {StyleLayer} layer the layer to render * @returns {boolean} if true layer is rendered to texture, otherwise false */ - renderLayer(layer: any): boolean { + renderLayer(layer: StyleLayer): boolean { const type = layer.type; const painter = this.painter; const layerIds = painter.style._order; diff --git a/src/render/terrain.ts b/src/render/terrain.ts index 08baf6a4fb2..3382e1c1120 100644 --- a/src/render/terrain.ts +++ b/src/render/terrain.ts @@ -84,7 +84,7 @@ export default class Terrain { // So to get good results with not too much memory footprint a value of 2 should be fine. qualityFactor: number; // holds the framebuffer object in size of the screen to render the coords & depth into a texture. - _fbo: any; + _fbo: Framebuffer; _fboCoordsTexture: Texture; _fboDepthTexture: Texture; _emptyDepthTexture: Texture; @@ -100,7 +100,7 @@ export default class Terrain { // accuracy of the coords. 2 * tileSize should be enoughth. _coordsTextureSize: number; // variables for an empty dem texture, which is used while the raster-dem tile is loading. - _emptyDemUnpack: any; + _emptyDemUnpack: number[]; _emptyDemTexture: Texture; _emptyDemMatrix: mat4; // as of overzooming of raster-dem tiles in high zoomlevels, this cache contains diff --git a/src/style/style.ts b/src/style/style.ts index ca4000b92e5..41639f1f2a8 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -491,8 +491,12 @@ class Style extends Evented { setTerrain(options?: TerrainOptions) { // clear event handlers if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); - // add terrain - if (options) { + if (!options) { + // remove terrain + this.terrain = this.map.transform.terrain = null; + this.map.transform.updateElevation(); + } else { + // add terrain const sourceCache = this.sourceCaches[options.source]; this.map.transform.terrain = this.terrain = new Terrain(this, sourceCache, options); this.map.transform.updateElevation(); @@ -506,10 +510,6 @@ class Style extends Evented { } }; this.on('data', this._terrainDataCallback); - // remove terrain - } else { - this.terrain = this.map.transform.terrain = null; - this.map.transform.updateElevation(); } } From 1d9683f6ceebeaa04e900a9c2d80eb6680a6ecae Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 31 Mar 2022 16:31:08 +0200 Subject: [PATCH 120/138] encapsulate a_centroid shader attributes to #TERRAIN3D preprocessor --- src/render/terrain.ts | 4 ++-- src/shaders/fill_extrusion.vertex.glsl | 9 +++++++-- src/shaders/fill_extrusion_pattern.vertex.glsl | 17 ++++++++++++++--- src/style/style.ts | 4 ++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/render/terrain.ts b/src/render/terrain.ts index 08baf6a4fb2..2671997ea52 100644 --- a/src/render/terrain.ts +++ b/src/render/terrain.ts @@ -21,10 +21,10 @@ import {number as mix} from '../style-spec/util/interpolate'; /** * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: - * 1) loads raster-dem tiles via the internal sourceCache this._source + * 1) loads raster-dem tiles via the internal sourceCache this.sourceCache * 2) creates a depth-framebuffer, which is used to calculate the visibility of coordinates * 3) creates a coords-framebuffer, which is used the get to tile-coordinate for a screen-pixel - * 4) stores all render-to-texture tiles in the this._tiles variable + * 4) stores all render-to-texture tiles in the this.sourceCache._tiles * 5) calculates the elevation for a spezific tile-coordinate * 6) creates a terrain-mesh * diff --git a/src/shaders/fill_extrusion.vertex.glsl b/src/shaders/fill_extrusion.vertex.glsl index dcdd80987fc..836e141f0b0 100644 --- a/src/shaders/fill_extrusion.vertex.glsl +++ b/src/shaders/fill_extrusion.vertex.glsl @@ -7,7 +7,11 @@ uniform lowp float u_opacity; attribute vec2 a_pos; attribute vec4 a_normal_ed; -attribute vec2 a_centroid; + +#ifdef TERRAIN3D + attribute vec2 a_centroid; +#endif + varying vec4 v_color; @@ -23,13 +27,14 @@ void main() { vec3 normal = a_normal_ed.xyz; - float ele = get_elevation(a_centroid); #ifdef TERRAIN3D // To avoid floating buildings in 3d-terrain, especially in heavy terrain, // render the buildings a little below terrain. The unit is meter. float baseDelta = 10.0; + float ele = get_elevation(a_centroid); #else float baseDelta = 0.0; + float ele = 0.0; #endif base = max(0.0, ele + base - baseDelta); height = max(0.0, ele + height); diff --git a/src/shaders/fill_extrusion_pattern.vertex.glsl b/src/shaders/fill_extrusion_pattern.vertex.glsl index 248357ab3a8..f04e109c910 100644 --- a/src/shaders/fill_extrusion_pattern.vertex.glsl +++ b/src/shaders/fill_extrusion_pattern.vertex.glsl @@ -12,7 +12,10 @@ uniform lowp float u_lightintensity; attribute vec2 a_pos; attribute vec4 a_normal_ed; -attribute vec2 a_centroid; + +#ifdef TERRAIN3D + attribute vec2 a_centroid; +#endif varying vec2 v_pos_a; varying vec2 v_pos_b; @@ -48,8 +51,16 @@ void main() { vec2 display_size_a = (pattern_br_a - pattern_tl_a) / pixel_ratio_from; vec2 display_size_b = (pattern_br_b - pattern_tl_b) / pixel_ratio_to; - float ele = get_elevation(a_centroid); - base = max(0.0, ele + base - 10.0); // minus 10 to avoid floating buildings because centroid is used for elevation + #ifdef TERRAIN3D + // To avoid floating buildings in 3d-terrain, especially in heavy terrain, + // render the buildings a little below terrain. The unit is meter. + float baseDelta = 10.0; + float ele = get_elevation(a_centroid); + #else + float baseDelta = 0.0; + float ele = 0.0; + #endif + base = max(0.0, ele + base - baseDelta); height = max(0.0, ele + height); float t = mod(normal.x, 2.0); diff --git a/src/style/style.ts b/src/style/style.ts index ca4000b92e5..299a387ce1c 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -488,6 +488,10 @@ class Style extends Evented { this._changedImages = {}; } + /** + * Loads a 3D terrain mesh, based on a "raster-dem" source. + * @param {TerrainOptions} [options] Options object. + */ setTerrain(options?: TerrainOptions) { // clear event handlers if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); From bd572d645e47d59656f0b6926bc1f846a9f1ebf9 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 6 Apr 2022 10:40:33 +0200 Subject: [PATCH 121/138] remove terrain-instance from transform class, instead put as argument --- src/geo/transform.ts | 116 ++++++++++++++--------------- src/render/draw_background.ts | 2 +- src/source/source_cache.ts | 20 +++-- src/source/terrain_source_cache.ts | 9 ++- src/style/pauseable_placement.ts | 4 +- src/style/style.ts | 30 ++++++-- src/symbol/placement.ts | 7 +- src/ui/camera.ts | 5 +- src/ui/handler_manager.ts | 11 ++- src/ui/map.ts | 12 +-- 10 files changed, 118 insertions(+), 98 deletions(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 4966ce15ed7..b7ca29e9d7d 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -43,7 +43,6 @@ class Transform { glCoordMatrix: mat4; labelPlaneMatrix: mat4; freezeElevation: boolean; - terrain: Terrain; _fov: number; _pitch: number; _zoom: number; @@ -103,7 +102,6 @@ class Transform { clone._pitch = this._pitch; clone._unmodified = this._unmodified; clone._edgeInsets = this._edgeInsets.clone(); - clone.terrain = this.terrain; clone._calcMatrices(); return clone; } @@ -220,7 +218,6 @@ class Transform { get elevation(): number { return this._elevation; } set elevation(elevation: number) { - if (this.freezeElevation) return; if (elevation === this._elevation) return; this._unmodified = false; this._elevation = elevation; @@ -343,6 +340,7 @@ class Transform { roundZoom?: boolean; reparseOverscaled?: boolean; renderWorldCopies?: boolean; + terrain?: Terrain; } ): Array { let z = this.coveringZoomLevel(options); @@ -361,11 +359,11 @@ class Transform { // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level let minZoom = options.minzoom || 0; // Use 0.1 as an epsilon to avoid for explicit == 0.0 floating point checks - if (!this.terrain && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) + if (!options.terrain && this.pitch <= 60.0 && this._edgeInsets.top < 0.1) minZoom = z; - // There should always be a certain number of maximum zoom level tiles surrounding the center location - const radiusOfMaxLvlLodInTiles = this.terrain ? 2 / Math.min(this.tileSize, options.tileSize) * this.tileSize : 3; + // There should always be a certain number of maximum zoom level tiles surrounding the center location in 2D or in front of the camera in 3D + const radiusOfMaxLvlLodInTiles = options.terrain ? 2 / Math.min(this.tileSize, options.tileSize) * this.tileSize : 3; const newRootTile = (wrap: number): any => { return { @@ -410,7 +408,7 @@ class Transform { fullyVisible = intersectResult === 2; } - const refPoint = this.terrain ? cameraPoint : centerPoint; + const refPoint = options.terrain ? cameraPoint : centerPoint; const distanceX = it.aabb.distanceX(refPoint); const distanceY = it.aabb.distanceY(refPoint); const longestDim = Math.max(Math.abs(distanceX), Math.abs(distanceY)); @@ -439,13 +437,13 @@ class Transform { const childY = (y << 1) + (i >> 1); const childZ = it.zoom + 1; let quadrant = it.aabb.quadrant(i); - if (this.terrain) { + if (options.terrain) { const tileID = new OverscaledTileID(childZ, it.wrap, childZ, childX, childY); - const tile = this.terrain.getTerrainData(tileID).tile; + const tile = options.terrain.getTerrainData(tileID).tile; let minElevation = this.elevation, maxElevation = this.elevation; if (tile && tile.dem) { - minElevation = tile.dem.min * this.terrain.exaggeration; - maxElevation = tile.dem.max * this.terrain.exaggeration; + minElevation = tile.dem.min * options.terrain.exaggeration; + maxElevation = tile.dem.max * options.terrain.exaggeration; } quadrant = new Aabb( [quadrant.min[0], quadrant.min[1], minElevation] as vec3, @@ -486,18 +484,28 @@ class Transform { get point(): Point { return this.project(this.center); } - updateElevation() { - this.elevation = this.getElevation(this._center); + /** + * Updates the center-elevation value unless freezeElevation is activated. + * @param terrain the terrain + */ + updateElevation(terrain?: Terrain) { + if (this.freezeElevation) return; + this.elevation = terrain ? this.getElevation(this._center, terrain) : 0; } - getElevation(lnglat: LngLat) { - if (!this.terrain) return 0; + /** + * get the elevation from terrain for the current zoomlevel. + * @param lnglat the location + * @param terrain the terrain + * @returns {Number} elevation in meters + */ + getElevation(lnglat: LngLat, terrain: Terrain) { const merc = MercatorCoordinate.fromLngLat(lnglat); const worldSize = (1 << this.tileZoom) * EXTENT; const mercX = merc.x * worldSize, mercY = merc.y * worldSize; const tileX = Math.floor(mercX / EXTENT), tileY = Math.floor(mercY / EXTENT); const tileID = new OverscaledTileID(this.tileZoom, 0, this.tileZoom, tileX, tileY); - return this.terrain.getElevation(tileID, mercX % EXTENT, mercY % EXTENT, EXTENT); + return terrain.getElevation(tileID, mercX % EXTENT, mercY % EXTENT, EXTENT); } /** @@ -513,12 +521,16 @@ class Transform { return {lngLat, altitude: altitude + this.elevation}; } - // this method only works in combination with elevation enabled and freezeElevation activated, - // because only in this case this.elevation holds the old elevation value. - recalculateZoom() { + /** + * This method works in combination with freezeElevation activated. + * freezeElevtion is enabled during map-panning because during this the camera should sit in constant height. + * After panning finished, call this method to recalculate the zoomlevel for the current camera-height in current terrain. + * @param {Terrain} terrain the terrain + */ + recalculateZoom(terrain: Terrain) { // find position the camera is looking on - const center = this.pointLocation3D(this.centerPoint); - const elevation = this.getElevation(center); + const center = this.pointLocation(this.centerPoint, terrain); + const elevation = this.getElevation(center, terrain); const deltaElevation = this.elevation - elevation; if (!deltaElevation) return; @@ -554,51 +566,35 @@ class Transform { /** * Given a location, return the screen point that corresponds to it * @param {LngLat} lnglat location + * @param {Terrain} terrain optional terrain * @returns {Point} screen point * @private */ - locationPoint(lnglat: LngLat) { - return this.coordinatePoint(this.locationCoordinate(lnglat)); - } - - /** - * Given a location, return the screen point that corresponds to it - * @param {LngLat} lnglat location - * @returns {Point} screen point - * @private - */ - locationPoint3D(lnglat: LngLat) { - return this.coordinatePoint(this.locationCoordinate(lnglat), this.getElevation(lnglat), this.pixelMatrix3D); + locationPoint(lnglat: LngLat, terrain?: Terrain): Point { + return terrain ? + this.coordinatePoint(this.locationCoordinate(lnglat), this.getElevation(lnglat, terrain), this.pixelMatrix3D) : + this.coordinatePoint(this.locationCoordinate(lnglat)); } /** * Given a point on screen, return its lnglat * @param {Point} p screen point + * @param {Terrain} terrain optional terrain * @returns {LngLat} lnglat location * @private */ - pointLocation(p: Point) { - return this.coordinateLocation(this.pointCoordinate(p)); - } - - /** - * Given a point on screen, return its lnglat - * @param {Point} p screen point - * @returns {LngLat} lnglat location - * @private - */ - pointLocation3D(p: Point) { - return this.coordinateLocation(this.pointCoordinate3D(p)); + pointLocation(p: Point, terrain?: Terrain): LngLat { + return this.coordinateLocation(this.pointCoordinate(p, terrain)); } /** * Given a geographical lnglat, return an unrounded * coordinate that represents it at this transform's zoom level. * @param {LngLat} lnglat - * @returns {Coordinate} + * @returns {MercatorCoordinate} * @private */ - locationCoordinate(lnglat: LngLat) { + locationCoordinate(lnglat: LngLat): MercatorCoordinate { return MercatorCoordinate.fromLngLat(lnglat); } @@ -608,11 +604,22 @@ class Transform { * @returns {LngLat} lnglat * @private */ - coordinateLocation(coord: MercatorCoordinate) { - return coord.toLngLat(); + coordinateLocation(coord: MercatorCoordinate): LngLat { + return coord && coord.toLngLat(); } - pointCoordinate(p: Point) { + /** + * Given a Point, return its mercator coordinate. + * @param {Point} p the point + * @param {Terrain} terrain optional terrain + * @returns {LngLat} lnglat + * @private + */ + pointCoordinate(p: Point, terrain?: Terrain): MercatorCoordinate { + // get point-coordinate from terrain coordinates framebuffer + if (terrain) return terrain.pointCoordinate(p); + + // calcuate point-coordinate on flat earth const targetZ = 0; // since we don't know the correct projected z value for the point, // unproject two points to get a line and then find the point on that @@ -640,11 +647,6 @@ class Transform { interpolate(y0, y1, t) / this.worldSize); } - pointCoordinate3D(p: Point): MercatorCoordinate { - const coordinate = this.terrain && this.terrain.pointCoordinate(p); - return coordinate || this.pointCoordinate(p); - } - /** * Given a coordinate, return the screen point that corresponds to it * @param {Coordinate} coord @@ -827,9 +829,7 @@ class Transform { this.glCoordMatrix = m; // calculate the camera to sea-level distance in pixel in respect of terrain - this.cameraToSeaLevelDistance = this.terrain ? - this.cameraToCenterDistance + this._elevation * this._pixelPerMeter / Math.cos(this._pitch) : - this.cameraToCenterDistance; + this.cameraToSeaLevelDistance = this.cameraToCenterDistance + this._elevation * this._pixelPerMeter / Math.cos(this._pitch); // Find the distance from the center point [width/2 + offset.x, height/2 + offset.y] to the // center top point [width/2 + offset.x, 0] in Z units, using the law of sines. diff --git a/src/render/draw_background.ts b/src/render/draw_background.ts index 891eadae5ba..116beae5f97 100644 --- a/src/render/draw_background.ts +++ b/src/render/draw_background.ts @@ -33,7 +33,7 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const depthMode = painter.depthModeForSublayer(0, pass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly); const colorMode = painter.colorModeForRenderPass(); const program = painter.useProgram(image ? 'backgroundPattern' : 'background'); - const tileIDs = coords ? coords : transform.coveringTiles({tileSize}); + const tileIDs = coords ? coords : transform.coveringTiles({tileSize, terrain: painter.style.terrain}); if (image) { context.activeTexture.set(gl.TEXTURE0); diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index e9b6239c8e5..f8b970bc9e2 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -21,6 +21,7 @@ import type Transform from '../geo/transform'; import type {TileState} from './tile'; import type {Callback} from '../types/callback'; import type {SourceSpecification} from '../style-spec/types.g'; +import Terrain from '../render/terrain'; /** * `SourceCache` is responsible for @@ -56,6 +57,7 @@ class SourceCache extends Evented { _shouldReloadOnResume: boolean; _coveredTiles: {[_: string]: boolean}; transform: Transform; + terrain: Terrain; used: boolean; usedForTerrain: boolean; tileSize: number; @@ -81,7 +83,7 @@ class SourceCache extends Evented { if (this._sourceLoaded && !this._paused && e.dataType === 'source' && e.sourceDataType === 'content') { this.reload(); if (this.transform) { - this.update(this.transform); + this.update(this.transform, this.terrain); } } }); @@ -154,7 +156,7 @@ class SourceCache extends Evented { this._paused = false; this._shouldReloadOnResume = false; if (shouldReload) this.reload(); - if (this.transform) this.update(this.transform); + if (this.transform) this.update(this.transform, this.terrain); } _loadTile(tile: Tile, callback: Callback) { @@ -265,7 +267,7 @@ class SourceCache extends Evented { tile.state = 'errored'; if ((err as any).status !== 404) this._source.fire(new ErrorEvent(err, {tile})); // continue to try loading parent/children tiles if a tile doesn't exist (404) - else this.update(this.transform); + else this.update(this.transform, this.terrain); return; } @@ -489,8 +491,9 @@ class SourceCache extends Evented { * are inside the viewport. * @private */ - update(transform: Transform) { + update(transform: Transform, terrain: Terrain) { this.transform = transform; + this.terrain = terrain; if (!this._sourceLoaded || this._paused) { return; } this.updateCacheSize(transform); @@ -512,7 +515,8 @@ class SourceCache extends Evented { minzoom: this._source.minzoom, maxzoom: this._source.maxzoom, roundZoom: this.usedForTerrain ? false : this._source.roundZoom, - reparseOverscaled: this._source.reparseOverscaled + reparseOverscaled: this._source.reparseOverscaled, + terrain }); if (this._source.hasTile) { @@ -578,7 +582,7 @@ class SourceCache extends Evented { } // disable fading logic in terrain3D mode to avoid rendering two tiles on the same place - if (this.style && this.style.terrain) { + if (terrain) { const idealRasterTileIDs: {[_: string]: OverscaledTileID} = {}; const missingTileIDs: {[_: string]: OverscaledTileID} = {}; for (const tileID of idealTileIDs) { @@ -875,8 +879,8 @@ class SourceCache extends Evented { transform.getCameraQueryGeometry(pointQueryGeometry) : pointQueryGeometry; - const queryGeometry = pointQueryGeometry.map((p) => transform.pointCoordinate3D(p)); - const cameraQueryGeometry = cameraPointQueryGeometry.map((p) => transform.pointCoordinate3D(p)); + const queryGeometry = pointQueryGeometry.map((p: Point) => transform.pointCoordinate(p, this.terrain)); + const cameraQueryGeometry = cameraPointQueryGeometry.map((p: Point) => transform.pointCoordinate(p, this.terrain)); const ids = this.getIds(); diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index b8f423b3452..7bbae91d01a 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -6,6 +6,7 @@ import {Evented} from '../util/evented'; import type Transform from '../geo/transform'; import type SourceCache from '../source/source_cache'; import Painter from '../render/painter'; +import Terrain from '../render/terrain'; /** * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: @@ -86,17 +87,19 @@ export default class TerrainSourceCache extends Evented { /** * Load Terrain Tiles, create internal render-to-texture tiles, free GPU memory. * @param {Transform} transform - the operation to do + * @param {Terrain} terrain - the terrain */ - update(transform: Transform): void { + update(transform: Transform, terrain: Terrain): void { // load raster-dem tiles for the current scene. - this.sourceCache.update(transform); + this.sourceCache.update(transform, terrain); // create internal render-to-texture tiles for the current scene. this._renderableTilesKeys = []; for (const tileID of transform.coveringTiles({ tileSize: this.tileSize, minzoom: this.minzoom, maxzoom: this.maxzoom, - reparseOverscaled: false + reparseOverscaled: false, + terrain })) { this._renderableTilesKeys.push(tileID.key); if (!this._tiles[tileID.key]) { diff --git a/src/style/pauseable_placement.ts b/src/style/pauseable_placement.ts index 2aeb6e7f805..7fc1b5c738e 100644 --- a/src/style/pauseable_placement.ts +++ b/src/style/pauseable_placement.ts @@ -7,6 +7,7 @@ import type StyleLayer from './style_layer'; import type SymbolStyleLayer from './style_layer/symbol_style_layer'; import type Tile from '../source/tile'; import type {BucketPart} from '../symbol/placement'; +import Terrain from '../render/terrain'; class LayerPlacement { _sortAcrossTiles: boolean; @@ -69,6 +70,7 @@ class PauseablePlacement { constructor( transform: Transform, + terrain: Terrain, order: Array, forceFullPlacement: boolean, showCollisionBoxes: boolean, @@ -76,7 +78,7 @@ class PauseablePlacement { crossSourceCollisions: boolean, prevPlacement?: Placement ) { - this.placement = new Placement(transform, fadeDuration, crossSourceCollisions, prevPlacement); + this.placement = new Placement(transform, terrain, fadeDuration, crossSourceCollisions, prevPlacement); this._currentPlacementIndex = order.length - 1; this._forceFullPlacement = forceFullPlacement; this._showCollisionBoxes = showCollisionBoxes; diff --git a/src/style/style.ts b/src/style/style.ts index 7e14975d11b..9611c297558 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -133,6 +133,7 @@ class Style extends Evented { _loaded: boolean; _rtlTextPluginCallback: (a: any) => any; _terrainDataCallback: (e: any) => any; + _terrainfreezeElevationCallback: (e: any) => any; _changed: boolean; _updatedSources: {[_: string]: 'clear' | 'reload'}; _updatedLayers: {[_: string]: true}; @@ -495,26 +496,39 @@ class Style extends Evented { setTerrain(options?: TerrainOptions) { // clear event handlers if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); + if (this._terrainfreezeElevationCallback) this.off('freezeElevation', this._terrainfreezeElevationCallback); + + // remove terrain if (!options) { - // remove terrain - this.terrain = this.map.transform.terrain = null; this.map.transform.updateElevation(); + + // add terrain } else { - // add terrain const sourceCache = this.sourceCaches[options.source]; - this.map.transform.terrain = this.terrain = new Terrain(this, sourceCache, options); - this.map.transform.updateElevation(); + this.terrain = new Terrain(this, sourceCache, options); + this.map.transform.updateElevation(this.terrain); + this._terrainfreezeElevationCallback = (e: any) => { + if (e.freeze) { + this.map.transform.freezeElevation = true; + } else { + this.map.transform.freezeElevation = false; + this.map.transform.recalculateZoom(this.terrain); + } + }; this._terrainDataCallback = e => { if (!e.tile) return; if (e.sourceId === options.source) { - this.map.transform.updateElevation(); + this.map.transform.updateElevation(this.terrain); this.terrain.rememberForRerender(e.sourceId, e.tile.tileID); } else if (e.source.type === 'geojson') { this.terrain.rememberForRerender(e.sourceId, e.tile.tileID); } }; this.on('data', this._terrainDataCallback); + this.map.on('freezeElevation', this._terrainfreezeElevationCallback); } + + this.map.fire(new Event('terrain', {terrain: options})); } /** @@ -1298,7 +1312,7 @@ class Style extends Evented { _updateSources(transform: Transform) { for (const id in this.sourceCaches) { - this.sourceCaches[id].update(transform); + this.sourceCaches[id].update(transform, this.terrain); } } @@ -1339,7 +1353,7 @@ class Style extends Evented { forceFullPlacement = forceFullPlacement || this._layerOrderChanged || fadeDuration === 0; if (forceFullPlacement || !this.pauseablePlacement || (this.pauseablePlacement.isDone() && !this.placement.stillRecent(browser.now(), transform.zoom))) { - this.pauseablePlacement = new PauseablePlacement(transform, this._order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, this.placement); + this.pauseablePlacement = new PauseablePlacement(transform, this.terrain, this._order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, this.placement); this._layerOrderChanged = false; } diff --git a/src/symbol/placement.ts b/src/symbol/placement.ts index bacd5f54e40..bc826c3a3d4 100644 --- a/src/symbol/placement.ts +++ b/src/symbol/placement.ts @@ -22,6 +22,7 @@ import type {CollisionBoxArray, CollisionVertexArray, SymbolInstance} from '../d import type FeatureIndex from '../data/feature_index'; import type {OverscaledTileID} from '../source/tile_id'; import type {TextAnchor} from './symbol_layout'; +import Terrain from '../render/terrain'; class OpacityState { opacity: number; @@ -210,6 +211,7 @@ export type CrossTileID = string | number; export class Placement { transform: Transform; + terrain: Terrain; collisionIndex: CollisionIndex; placements: { [_ in CrossTileID]: JointPlacement; @@ -238,8 +240,9 @@ export class Placement { [k in any]: CollisionCircleArray; }; - constructor(transform: Transform, fadeDuration: number, crossSourceCollisions: boolean, prevPlacement?: Placement) { + constructor(transform: Transform, terrain: Terrain, fadeDuration: number, crossSourceCollisions: boolean, prevPlacement?: Placement) { this.transform = transform.clone(); + this.terrain = terrain; this.collisionIndex = new CollisionIndex(this.transform); this.placements = {}; this.opacities = {}; @@ -492,7 +495,7 @@ export class Placement { // update elevation of collisionArrays const tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID; - const getElevation = this.transform.terrain ? (x: number, y: number) => this.transform.terrain.getElevation(tileID, x, y) : null; + const getElevation = this.terrain ? (x: number, y: number) => this.terrain.getElevation(tileID, x, y) : null; for (const boxType of ['textBox', 'verticalTextBox', 'iconBox', 'verticalIconBox']) { const box = collisionArrays[boxType]; if (box) box.elevation = getElevation ? getElevation(box.anchorPointX, box.anchorPointY) : 0; diff --git a/src/ui/camera.ts b/src/ui/camera.ts index 1ff9903cabf..97a4214bfbf 100644 --- a/src/ui/camera.ts +++ b/src/ui/camera.ts @@ -898,7 +898,7 @@ abstract class Camera extends Evented { _prepareEase(eventData: any, noMoveStart: boolean, currently: any = {}) { this._moving = true; - this.transform.freezeElevation = true; + this.fire(new Event('freezeElevation', {freeze: true})); if (!noMoveStart && !currently.moving) { this.fire(new Event('movestart', eventData)); @@ -934,8 +934,7 @@ abstract class Camera extends Evented { return; } delete this._easeId; - this.transform.freezeElevation = false; - if (this.transform.terrain) this.transform.recalculateZoom(); + this.fire(new Event('freezeElevation', {freeze: false})); const wasZooming = this._zooming; const wasRotating = this._rotating; diff --git a/src/ui/handler_manager.ts b/src/ui/handler_manager.ts index b333b7d653b..9ffa6b7260e 100644 --- a/src/ui/handler_manager.ts +++ b/src/ui/handler_manager.ts @@ -415,9 +415,9 @@ class HandlerManager { _updateMapTransform(combinedResult: any, combinedEventsInProgress: any, deactivatedHandlers: any) { const map = this._map; const tr = map.transform; - const hasTerrain = map.style && map.style.terrain; + const terrain = map.style && map.style.terrain; - if (!hasChange(combinedResult) && !(hasTerrain && this._drag)) { + if (!hasChange(combinedResult) && !(terrain && this._drag)) { return this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); } @@ -436,7 +436,7 @@ class HandlerManager { if (pitchDelta) tr.pitch += pitchDelta; if (zoomDelta) tr.zoom += zoomDelta; - if (!hasTerrain) { + if (!terrain) { tr.setLocationAtPoint(loc, around); } else { // when 3d-terrain is enabled act a litte different: @@ -454,11 +454,10 @@ class HandlerManager { point: around, handlerName: combinedEventsInProgress.drag.handlerName }; - tr.freezeElevation = true; + map.fire(new Event('freezeElevation', {freeze: true})); // when dragging ends, recalcuate the zoomlevel for the new center coordinate } else if (this._drag && deactivatedHandlers[this._drag.handlerName]) { - tr.freezeElevation = false; - tr.recalculateZoom(); + map.fire(new Event('freezeElevation', {freeze: false})); this._drag = null; // drag map } else if (combinedEventsInProgress.drag && this._drag) { diff --git a/src/ui/map.ts b/src/ui/map.ts index d8040fc9076..6d6e544cd6c 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -869,9 +869,7 @@ class Map extends Camera { * var point = map.project(coordinate); */ project(lnglat: LngLatLike) { - return this.style && this.style.terrain ? - this.transform.locationPoint3D(LngLat.convert(lnglat)) : - this.transform.locationPoint(LngLat.convert(lnglat)); + this.transform.locationPoint(LngLat.convert(lnglat), this.style && this.style.terrain); } /** @@ -887,9 +885,7 @@ class Map extends Camera { * }); */ unproject(point: PointLike) { - return this.style && this.style.terrain ? - this.transform.pointLocation3D(Point.convert(point)) : - this.transform.pointLocation(Point.convert(point)); + this.transform.pointLocation(Point.convert(point), this.style && this.style.terrain); } /** @@ -2576,8 +2572,8 @@ class Map extends Camera { } // update terrain stuff - if (this.style.terrain) this.style.terrain.sourceCache.update(this.transform); - this.transform.updateElevation(); + if (this.style.terrain) this.style.terrain.sourceCache.update(this.transform, this.style.terrain); + this.transform.updateElevation(this.style.terrain); this._placementDirty = this.style && this.style._updatePlacement(this.painter.transform, this.showCollisionBoxes, this._fadeDuration, this._crossSourceCollisions); From c591a2e916105e883bbf1330d0c4b9c243523aee Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 6 Apr 2022 11:20:59 +0200 Subject: [PATCH 122/138] add forgotten return statements --- src/ui/map.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/map.ts b/src/ui/map.ts index 6d6e544cd6c..c734b5cbc85 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -869,7 +869,7 @@ class Map extends Camera { * var point = map.project(coordinate); */ project(lnglat: LngLatLike) { - this.transform.locationPoint(LngLat.convert(lnglat), this.style && this.style.terrain); + return this.transform.locationPoint(LngLat.convert(lnglat), this.style && this.style.terrain); } /** @@ -885,7 +885,7 @@ class Map extends Camera { * }); */ unproject(point: PointLike) { - this.transform.pointLocation(Point.convert(point), this.style && this.style.terrain); + return this.transform.pointLocation(Point.convert(point), this.style && this.style.terrain); } /** From 6a40579b3c333e835c18d0449ee65a3b3bb2a694 Mon Sep 17 00:00:00 2001 From: Harel M Date: Wed, 6 Apr 2022 12:22:19 +0300 Subject: [PATCH 123/138] Add terrain to style spec (#1138) * Add terrain to style spec * Fix lint * Added a test in style to make sure the terrain is created. * fix lint * Added validator to terrain object --- build/generate-style-spec.ts | 2 + debug/terrain.html | 37 ++++++++------- src/render/terrain.ts | 9 ++-- src/style-spec/error/validation_error.ts | 2 +- src/style-spec/reference/v8.json | 42 +++++++++++++++++ src/style-spec/validate/validate.ts | 2 + .../validate/validate_terrain.test.ts | 46 +++++++++++++++++++ src/style-spec/validate/validate_terrain.ts | 41 +++++++++++++++++ src/style-spec/validate_style.min.ts | 2 + src/style-spec/validate_style.ts | 1 + src/style/style.test.ts | 16 +++++++ src/style/style.ts | 15 +++--- src/style/validate_style.ts | 2 + src/ui/control/terrain_control.ts | 6 +-- src/ui/map.ts | 13 +++--- 15 files changed, 194 insertions(+), 42 deletions(-) create mode 100644 src/style-spec/validate/validate_terrain.test.ts create mode 100644 src/style-spec/validate/validate_terrain.ts diff --git a/build/generate-style-spec.ts b/build/generate-style-spec.ts index be01b4a7b90..ae39d91b1dc 100644 --- a/build/generate-style-spec.ts +++ b/build/generate-style-spec.ts @@ -197,6 +197,8 @@ ${objectDeclaration('StyleSpecification', spec.$root)} ${objectDeclaration('LightSpecification', spec.light)} +${objectDeclaration('TerrainSpecification', spec.terrain)} + ${spec.source.map(key => objectDeclaration(sourceTypeName(key), spec[key])).join('\n\n')} export type SourceSpecification = diff --git a/debug/terrain.html b/debug/terrain.html index 32eaf6a48f9..3549323a0a0 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -18,33 +18,32 @@ diff --git a/src/render/terrain.ts b/src/render/terrain.ts index 81a5dfbb3b1..a9491cadffc 100644 --- a/src/render/terrain.ts +++ b/src/render/terrain.ts @@ -9,7 +9,7 @@ import posAttributes from '../data/pos_attributes'; import SegmentVector from '../data/segment'; import VertexBuffer from '../gl/vertex_buffer'; import IndexBuffer from '../gl/index_buffer'; -import Style, {TerrainOptions} from '../style/style'; +import Style from '../style/style'; import Texture from '../render/texture'; import type Framebuffer from '../gl/framebuffer'; import Point from '@mapbox/point-geometry'; @@ -18,6 +18,7 @@ import TerrainSourceCache from '../source/terrain_source_cache'; import SourceCache from '../source/source_cache'; import EXTENT from '../data/extent'; import {number as mix} from '../style-spec/util/interpolate'; +import type {TerrainSpecification} from '../style-spec/types.g'; /** * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: @@ -71,8 +72,8 @@ export default class Terrain { style: Style; // the sourcecache this terrain is based on sourceCache: TerrainSourceCache; - // the TerrainOptions object passed to this instance - options: TerrainOptions; + // the TerrainSpecification object passed to this instance + options: TerrainSpecification; // define the meshSize per tile. meshSize: number; // multiplicator for the elevation. Used to make terrain more "extrem". @@ -114,7 +115,7 @@ export default class Terrain { // remember all tiles which contains new data for a spezific source and tile-key. _rerender: {[_: string]: {[_: number]: boolean}}; - constructor(style: Style, sourceCache: SourceCache, options: TerrainOptions) { + constructor(style: Style, sourceCache: SourceCache, options: TerrainSpecification) { this.style = style; this.sourceCache = new TerrainSourceCache(sourceCache); this.options = options; diff --git a/src/style-spec/error/validation_error.ts b/src/style-spec/error/validation_error.ts index 3b7cdf7be88..0c489cc396f 100644 --- a/src/style-spec/error/validation_error.ts +++ b/src/style-spec/error/validation_error.ts @@ -5,7 +5,7 @@ export default class ValidationError { identifier: string; line: number; - constructor(key: string, value: { + constructor(key: string, value: any & { __line__: number; }, message: string, identifier?: string | null) { this.message = (key ? `${key}: ` : '') + message; diff --git a/src/style-spec/reference/v8.json b/src/style-spec/reference/v8.json index ee173fc1890..ad35f9a8b9f 100644 --- a/src/style-spec/reference/v8.json +++ b/src/style-spec/reference/v8.json @@ -57,6 +57,15 @@ "intensity": 0.4 } }, + "terrain": { + "type": "terrain", + "doc": "The terrain configuration.", + "example": { + "source": "raster-dem-source", + "exaggeration": 0.5, + "elevationOffset": 100 + } + }, "sources": { "required": true, "type": "sources", @@ -3810,6 +3819,39 @@ } } }, + "terrain": { + "source": { + "type": "string", + "doc": "The source for the terrain data.", + "required": true, + "sdk-support": { + "basic functionality": { + "js": "2.2.0" + } + } + }, + "exaggeration": { + "type": "number", + "minimum": 0, + "doc": "The exaggeration of the terrain - how high it will look.", + "default": 1.0, + "sdk-support": { + "basic functionality": { + "js": "2.2.0" + } + } + }, + "elevationOffset": { + "type": "number", + "doc": "The elevation offset.", + "default": 450, + "sdk-support": { + "basic functionality": { + "js": "2.2.0" + } + } + } + }, "paint": [ "paint_fill", "paint_line", diff --git a/src/style-spec/validate/validate.ts b/src/style-spec/validate/validate.ts index 2c2c8aaaa1e..b827db3ba79 100644 --- a/src/style-spec/validate/validate.ts +++ b/src/style-spec/validate/validate.ts @@ -17,6 +17,7 @@ import validateFilter from './validate_filter'; import validateLayer from './validate_layer'; import validateSource from './validate_source'; import validateLight from './validate_light'; +import validateTerrain from './validate_terrain'; import validateString from './validate_string'; import validateFormatted from './validate_formatted'; import validateImage from './validate_image'; @@ -37,6 +38,7 @@ const VALIDATORS = { 'object': validateObject, 'source': validateSource, 'light': validateLight, + 'terrain': validateTerrain, 'string': validateString, 'formatted': validateFormatted, 'resolvedImage': validateImage diff --git a/src/style-spec/validate/validate_terrain.test.ts b/src/style-spec/validate/validate_terrain.test.ts new file mode 100644 index 00000000000..84cc507e1c0 --- /dev/null +++ b/src/style-spec/validate/validate_terrain.test.ts @@ -0,0 +1,46 @@ +import validateTerrain from './validate_terrain'; +import v8 from '../reference/v8.json'; + +describe('Validate Terrain', () => { + test('Should return error in case terrain is not an object', () => { + const errors = validateTerrain({value: 1 as any, styleSpec: v8, style: {} as any}); + expect(errors).toHaveLength(1); + expect(errors[0].message).toContain('number'); + expect(errors[0].message).toContain('object'); + expect(errors[0].message).toContain('terrain'); + }); + + test('Should return error in case terrain source is not a string', () => { + const errors = validateTerrain({value: {source: 1 as any}, styleSpec: v8, style: {} as any}); + expect(errors).toHaveLength(1); + expect(errors[0].message).toContain('number'); + expect(errors[0].message).toContain('string'); + expect(errors[0].message).toContain('source'); + }); + + test('Should return error in case of unknown property', () => { + const errors = validateTerrain({value: {a: 1} as any, styleSpec: v8, style: {} as any}); + expect(errors).toHaveLength(1); + expect(errors[0].message).toContain('a'); + expect(errors[0].message).toContain('unknown'); + }); + + test('Should return errors according to spec violations', () => { + const errors = validateTerrain({value: {source: 1 as any, exaggeration: {} as any, elevationOffset: 'ex2' as any}, styleSpec: v8, style: {} as any}); + expect(errors).toHaveLength(3); + expect(errors[0].message).toContain('number'); + expect(errors[0].message).toContain('string'); + expect(errors[0].message).toContain('source'); + expect(errors[1].message).toContain('number'); + expect(errors[1].message).toContain('object'); + expect(errors[1].message).toContain('exaggeration'); + expect(errors[2].message).toContain('number'); + expect(errors[2].message).toContain('string'); + expect(errors[2].message).toContain('elevationOffset'); + }); + + test('Should pass if everything is according to spec', () => { + const errors = validateTerrain({value: {source: 'source-id', elevationOffset: 1, exaggeration: 0.2}, styleSpec: v8, style: {} as any}); + expect(errors).toHaveLength(0); + }); +}); diff --git a/src/style-spec/validate/validate_terrain.ts b/src/style-spec/validate/validate_terrain.ts new file mode 100644 index 00000000000..f75153c87ea --- /dev/null +++ b/src/style-spec/validate/validate_terrain.ts @@ -0,0 +1,41 @@ +import ValidationError from '../error/validation_error'; +import getType from '../util/get_type'; +import validate from './validate'; +import type {StyleSpecification, TerrainSpecification} from '../types.g'; +import type v8 from '../reference/v8.json'; + +export default function validateTerrain( + options: {value: TerrainSpecification; styleSpec: typeof v8; style: StyleSpecification} +): ValidationError[] { + + const terrain = options.value; + const styleSpec = options.styleSpec; + const terrainSpec = styleSpec.terrain; + const style = options.style; + + let errors = []; + + const rootType = getType(terrain); + if (terrain === undefined) { + return errors; + } else if (rootType !== 'object') { + errors = errors.concat([new ValidationError('terrain', terrain, `object expected, ${rootType} found`)]); + return errors; + } + + for (const key in terrain) { + if (terrainSpec[key]) { + errors = errors.concat(validate({ + key, + value: terrain[key], + valueSpec: terrainSpec[key], + style, + styleSpec + })); + } else { + errors = errors.concat([new ValidationError(key, terrain[key], `unknown property "${key}"`)]); + } + } + + return errors; +} diff --git a/src/style-spec/validate_style.min.ts b/src/style-spec/validate_style.min.ts index 79ab747cf4a..816ed2806a0 100644 --- a/src/style-spec/validate_style.min.ts +++ b/src/style-spec/validate_style.min.ts @@ -6,6 +6,7 @@ import validateGlyphsURL from './validate/validate_glyphs_url'; import validateSource from './validate/validate_source'; import validateLight from './validate/validate_light'; +import validateTerrain from './validate/validate_terrain'; import validateLayer from './validate/validate_layer'; import validateFilter from './validate/validate_filter'; import validatePaintProperty from './validate/validate_paint_property'; @@ -58,6 +59,7 @@ function validateStyleMin(style, styleSpec = latestStyleSpec) { validateStyleMin.source = wrapCleanErrors(validateSource); validateStyleMin.light = wrapCleanErrors(validateLight); +validateStyleMin.terrain = wrapCleanErrors(validateTerrain); validateStyleMin.layer = wrapCleanErrors(validateLayer); validateStyleMin.filter = wrapCleanErrors(validateFilter); validateStyleMin.paintProperty = wrapCleanErrors(validatePaintProperty); diff --git a/src/style-spec/validate_style.ts b/src/style-spec/validate_style.ts index f8f83600892..1e809aa2a3a 100644 --- a/src/style-spec/validate_style.ts +++ b/src/style-spec/validate_style.ts @@ -33,6 +33,7 @@ export default function validateStyle(style, styleSpec = v8) { export const source = validateStyleMin.source; export const light = validateStyleMin.light; +export const terrain = validateStyleMin.terrain; export const layer = validateStyleMin.layer; export const filter = validateStyleMin.filter; export const paintProperty = validateStyleMin.paintProperty; diff --git a/src/style/style.test.ts b/src/style/style.test.ts index f12159b02e1..8cb705b17b3 100644 --- a/src/style/style.test.ts +++ b/src/style/style.test.ts @@ -379,6 +379,22 @@ describe('Style#loadJSON', () => { style._layers.background.fire(new Event('error', {mapLibre: true})); }); }); + + test('sets terrain if defined', (done) => { + const map = getStubMap(); + const style = new Style(map); + map.transform.updateElevation = jest.fn(); + style.loadJSON(createStyleJSON({ + sources: {'source-id': createGeoJSONSource()}, + terrain: {source: 'source-id', exaggeration: 0.33} + })); + + style.on('style.load', () => { + expect(style.terrain).toBeDefined(); + expect(map.transform.updateElevation).toHaveBeenCalled(); + done(); + }); + }); }); describe('Style#_remove', () => { diff --git a/src/style/style.ts b/src/style/style.ts index 9611c297558..8d4ef15ccc9 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -57,7 +57,8 @@ import type { FilterSpecification, StyleSpecification, LightSpecification, - SourceSpecification + SourceSpecification, + TerrainSpecification } from '../style-spec/types.g'; import type {CustomLayerInterface} from './style_layer/custom_style_layer'; import type {Validator} from './validate_style'; @@ -104,12 +105,6 @@ export type StyleSetterOptions = { validate?: boolean; }; -export type TerrainOptions = { - source: string; - exaggeration?: number; - elevationOffset?: number; -}; - /** * @private */ @@ -289,6 +284,8 @@ class Style extends Evented { this.light = new Light(this.stylesheet.light); + this.setTerrain(this.stylesheet.terrain); + this.fire(new Event('data', {dataType: 'style'})); this.fire(new Event('style.load')); } @@ -491,9 +488,9 @@ class Style extends Evented { /** * Loads a 3D terrain mesh, based on a "raster-dem" source. - * @param {TerrainOptions} [options] Options object. + * @param {TerrainSpecification} [options] Options object. */ - setTerrain(options?: TerrainOptions) { + setTerrain(options?: TerrainSpecification) { // clear event handlers if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); if (this._terrainfreezeElevationCallback) this.off('freezeElevation', this._terrainfreezeElevationCallback); diff --git a/src/style/validate_style.ts b/src/style/validate_style.ts index c257eea3b4b..81efa18fe17 100644 --- a/src/style/validate_style.ts +++ b/src/style/validate_style.ts @@ -15,6 +15,7 @@ type ValidateStyle = { source: Validator; layer: Validator; light: Validator; + terrain: Validator; filter: Validator; paintProperty: Validator; layoutProperty: Validator; @@ -25,6 +26,7 @@ export const validateStyle = (validateStyleMin as ValidateStyle); export const validateSource = validateStyle.source; export const validateLight = validateStyle.light; +export const validateTerrain = validateStyle.terrain; export const validateFilter = validateStyle.filter; export const validatePaintProperty = validateStyle.paintProperty; export const validateLayoutProperty = validateStyle.layoutProperty; diff --git a/src/ui/control/terrain_control.ts b/src/ui/control/terrain_control.ts index 5fc952c83b2..e819357f725 100644 --- a/src/ui/control/terrain_control.ts +++ b/src/ui/control/terrain_control.ts @@ -3,7 +3,7 @@ import {bindAll} from '../../util/util'; import type Map from '../map'; import type {IControl} from './control'; -import type {TerrainOptions} from '../../style/style'; +import type {TerrainSpecification} from '../../style-spec/types.g'; /** * An `TerrainControl` control adds a button to turn terrain on and off. @@ -19,12 +19,12 @@ import type {TerrainOptions} from '../../style/style'; * })); */ class TerrainControl implements IControl { - options: TerrainOptions; + options: TerrainSpecification; _map: Map; _container: HTMLElement; _terrainButton: HTMLButtonElement; - constructor(options: TerrainOptions) { + constructor(options: TerrainSpecification) { this.options = options; bindAll([ diff --git a/src/ui/map.ts b/src/ui/map.ts index c734b5cbc85..853b9d8cfc6 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -3,7 +3,7 @@ import browser from '../util/browser'; import DOM from '../util/dom'; import {getImage, GetImageCallback, getJSON, ResourceType} from '../util/ajax'; import {RequestManager} from '../util/request_manager'; -import Style, {TerrainOptions} from '../style/style'; +import Style from '../style/style'; import EvaluationParameters from '../style/evaluation_parameters'; import Painter from '../render/painter'; import Transform from '../geo/transform'; @@ -51,7 +51,8 @@ import type { FilterSpecification, StyleSpecification, LightSpecification, - SourceSpecification + SourceSpecification, + TerrainSpecification } from '../style-spec/types.g'; import {Callback} from '../types/callback'; import type {ControlPosition, IControl} from './control/control'; @@ -1569,12 +1570,12 @@ class Map extends Camera { /** * Loads a 3D terrain mesh, based on a "raster-dem" source. - * @param {TerrainOptions} [options] Options object. + * @param {TerrainSpecification} [options] Options object. * @returns {Map} `this` * @example * map.setTerrain({ source: 'terrain' }); */ - setTerrain(options: TerrainOptions): Map { + setTerrain(options: TerrainSpecification): Map { if (options) this.isSourceLoaded(options.source); this.style.setTerrain(options); this._sourcesDirty = true; @@ -1585,11 +1586,11 @@ class Map extends Camera { /** * Get the terrain-options if terrain is loaded - * @returns {TerrainOptions} the TerrainOptions passed to setTerrain + * @returns {TerrainSpecification} the TerrainSpecification passed to setTerrain * @example * map.getTerrain(); // { source: 'terrain' }; */ - getTerrain(): TerrainOptions { + getTerrain(): TerrainSpecification { return this.style.terrain && this.style.terrain.options; } From 5c1103c7031548ba4bf72060d542ab663bf02dab Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Wed, 6 Apr 2022 11:50:26 +0200 Subject: [PATCH 124/138] update some code-comments --- src/render/terrain.ts | 4 ++-- src/source/terrain_source_cache.ts | 31 ++++++------------------------ 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/render/terrain.ts b/src/render/terrain.ts index 81a5dfbb3b1..a3ca23f70d9 100644 --- a/src/render/terrain.ts +++ b/src/render/terrain.ts @@ -316,7 +316,7 @@ export default class Terrain { } /** - * Reads a Pixel from the Coords-Framebuffer and translate this to mercator. + * Reads a pixel from the coords-framebuffer and translate this to mercator. * @param {Point} p Screen-Coordinate * @returns {MercatorCoordinate} mercator coordinate for a screen pixel */ @@ -327,7 +327,7 @@ export default class Terrain { context.bindFramebuffer.set(this.getFramebuffer('coords').framebuffer); gl.readPixels(p.x, painter.height / devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); context.bindFramebuffer.set(null); - // decode coordinates (encoding see terrain-source-cache) + // decode coordinates (encoding see getCoordsTexture) const x = rgba[0] + ((rgba[2] >> 4) << 8); const y = rgba[1] + ((rgba[2] & 15) << 8); const tileID = this._coordsIndex[255 - rgba[3]]; diff --git a/src/source/terrain_source_cache.ts b/src/source/terrain_source_cache.ts index 7bbae91d01a..6ec9a12407e 100644 --- a/src/source/terrain_source_cache.ts +++ b/src/source/terrain_source_cache.ts @@ -9,31 +9,12 @@ import Painter from '../render/painter'; import Terrain from '../render/terrain'; /** - * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics: - * 1) loads raster-dem tiles via the internal sourceCache this._source - * 2) creates a depth-framebuffer, which is used to calculate the visibility of coordinates - * 3) creates a coords-framebuffer, which is used the get to tile-coordinate for a screen-pixel - * 4) stores all render-to-texture tiles in the this._tiles variable - * 5) calculates the elevation for a spezific tile-coordinate - * 6) creates a terrain-mesh - * - * A note about the GPU resource-usage: - * Framebuffers: - * - one for the depth & coords framebuffer with the size of the map-div. - * - one for rendering a tile to texture with the size of tileSize (= 512x512). - * Textures: - * - one texture for an empty raster-dem tile with size 1x1 - * - one texture for an empty depth-buffer, when terrain is disabled with size 1x1 - * - one texture for an each loaded raster-dem with size of the source.tileSize - * - one texture for the coords-framebuffer with the size of the map-div. - * - one texture for the depth-framebuffer with the size of the map-div. - * - one texture for the encoded tile-coords with the size 2*tileSize (=1024x1024) - * - finally for each render-to-texture tile (= this._tiles) a set of textures - * for each render stack (The stack-concept is documented in painter.ts). - * Normally there exists 1-3 Textures per tile, depending on the stylesheet. - * Each Textures has the size 2*tileSize (= 1024x1024). Also there exists a - * cache of the last 150 newest rendered tiles. - * + * This class is a helper for the Terrain-class, it: + * - loads raster-dem tiles + * - manages all renderToTexture tiles. + * - caches previous rendered tiles. + * - finds all necessary renderToTexture tiles for a OverscaledTileID area + * - finds the corresponding raster-dem tile for OverscaledTileID */ export default class TerrainSourceCache extends Evented { From 51cdd81074a0ca1638c1e3283feae5fff91609ea Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Apr 2022 16:03:33 +0200 Subject: [PATCH 125/138] do not upload fill-extrusion centroid vertextbuffer in 2d --- src/render/draw_fill_extrusion.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/draw_fill_extrusion.ts b/src/render/draw_fill_extrusion.ts index fd50c954a46..4eadce90026 100644 --- a/src/render/draw_fill_extrusion.ts +++ b/src/render/draw_fill_extrusion.ts @@ -89,6 +89,6 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo program.draw(context, context.gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, - programConfiguration, bucket.centroidVertexBuffer); + programConfiguration, painter.style.terrain && bucket.centroidVertexBuffer); } } From 9aeccbb1781665f535b7a0865b4b396623644452 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Apr 2022 16:05:47 +0200 Subject: [PATCH 126/138] transform.elevation setter: do not set unmodified state to let map.load event set correct map-location --- src/geo/transform.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/geo/transform.ts b/src/geo/transform.ts index b7ca29e9d7d..c5e115bc01f 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -219,7 +219,6 @@ class Transform { get elevation(): number { return this._elevation; } set elevation(elevation: number) { if (elevation === this._elevation) return; - this._unmodified = false; this._elevation = elevation; this._constrain(); this._calcMatrices(); From 56003920ed76885996bfc68528c5f99c75c4c9c8 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Apr 2022 16:06:27 +0200 Subject: [PATCH 127/138] fix minor bugs when enable/disable terrain --- src/render/painter.ts | 7 ++++--- src/style/style.ts | 6 +++++- src/ui/map.ts | 8 ++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/render/painter.ts b/src/render/painter.ts index 0241d9a3cc5..3feba23690a 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -129,13 +129,13 @@ class Painter { // this object stores the current camera-matrix and the last render time // of the terrain-facilitators. e.g. depth & coords framebuffers // every time the camera-matrix changes the terrain-facilitators will be redrawn. - terrainFacilitator: {matrix: mat4; renderTime: number}; + terrainFacilitator: {dirty: boolean; matrix: mat4; renderTime: number}; constructor(gl: WebGLRenderingContext, transform: Transform) { this.context = new Context(gl); this.transform = transform; this._tileTextures = {}; - this.terrainFacilitator = {matrix: mat4.create(), renderTime: 0}; + this.terrainFacilitator = {dirty: true, matrix: mat4.create(), renderTime: 0}; this.setup(); @@ -413,9 +413,10 @@ class Painter { // update coords/depth-framebuffer on camera movement, or tile reloading const newTiles = this.style.terrain.sourceCache.tilesAfterTime(this.terrainFacilitator.renderTime); - if (!mat4.equals(this.terrainFacilitator.matrix, this.transform.projMatrix) || newTiles.length) { + if (this.terrainFacilitator.dirty || !mat4.equals(this.terrainFacilitator.matrix, this.transform.projMatrix) || newTiles.length) { mat4.copy(this.terrainFacilitator.matrix, this.transform.projMatrix); this.terrainFacilitator.renderTime = Date.now(); + this.terrainFacilitator.dirty = false; drawDepth(this, this.style.terrain); drawCoords(this, this.style.terrain); } diff --git a/src/style/style.ts b/src/style/style.ts index 8d4ef15ccc9..087e7030ab1 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -491,17 +491,21 @@ class Style extends Evented { * @param {TerrainSpecification} [options] Options object. */ setTerrain(options?: TerrainSpecification) { + this._checkLoaded(); + // clear event handlers if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); if (this._terrainfreezeElevationCallback) this.off('freezeElevation', this._terrainfreezeElevationCallback); // remove terrain if (!options) { - this.map.transform.updateElevation(); + this.terrain = null; + this.map.transform.updateElevation(this.terrain); // add terrain } else { const sourceCache = this.sourceCaches[options.source]; + if (!sourceCache) throw new Error(`cannot load terrain, because there exists no source with ID: ${options.source}`); this.terrain = new Terrain(this, sourceCache, options); this.map.transform.updateElevation(this.terrain); this._terrainfreezeElevationCallback = (e: any) => { diff --git a/src/ui/map.ts b/src/ui/map.ts index 853b9d8cfc6..be5110b5fa5 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -430,6 +430,10 @@ class Map extends Camera { this.on('move', () => this._update(false)); this.on('moveend', () => this._update(false)); this.on('zoom', () => this._update(true)); + this.on('terrain', () => { + this.painter.terrainFacilitator.dirty = true; + this._update(true) + }); if (typeof window !== 'undefined') { addEventListener('online', this._onWindowOnline, false); @@ -1576,11 +1580,7 @@ class Map extends Camera { * map.setTerrain({ source: 'terrain' }); */ setTerrain(options: TerrainSpecification): Map { - if (options) this.isSourceLoaded(options.source); this.style.setTerrain(options); - this._sourcesDirty = true; - this._styleDirty = true; - this.triggerRepaint(); return this; } From c88fe1050e27f26b5f465f638524a129dd997c91 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Apr 2022 16:08:57 +0200 Subject: [PATCH 128/138] fix lint --- src/ui/map.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/map.ts b/src/ui/map.ts index be5110b5fa5..25487ea62b8 100755 --- a/src/ui/map.ts +++ b/src/ui/map.ts @@ -432,7 +432,7 @@ class Map extends Camera { this.on('zoom', () => this._update(true)); this.on('terrain', () => { this.painter.terrainFacilitator.dirty = true; - this._update(true) + this._update(true); }); if (typeof window !== 'undefined') { From c2ab1b42bca0e33e99987e68f50f91a47e4c0c5d Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Thu, 7 Apr 2022 16:27:53 +0200 Subject: [PATCH 129/138] add test for recalcuateZoom --- src/geo/transform.test.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/geo/transform.test.ts b/src/geo/transform.test.ts index faab19fc50d..73a05ae0731 100644 --- a/src/geo/transform.test.ts +++ b/src/geo/transform.test.ts @@ -340,7 +340,6 @@ describe('transform', () => { }); test('maintains high float precision when calculating matrices', () => { - const transform = new Transform(0, 22, 0, 60, true); transform.resize(200.25, 200.25); transform.zoom = 20.25; @@ -352,4 +351,26 @@ describe('transform', () => { expect(transform.glCoordMatrix[0].toString().length).toBeGreaterThan(10); expect(transform.maxPitchScaleFactor()).toBeCloseTo(2.366025418080343, 10); }); + + test('recalcuateZoom', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.elevation = 200; + transform.center = new LngLat(10.0, 50.0); + transform.zoom = 14; + transform.resize(512, 512); + + // expect same values because of no elevation change + transform.getElevation = () => 200; + transform.recalculateZoom(null); + expect(transform.zoom).toBe(14); + + // expect new zoom because of elevation change + transform.getElevation = () => 400; + transform.recalculateZoom(null); + expect(transform.zoom).toBe(14.127997275621933); + expect(transform.elevation).toBe(400); + expect(transform._center.lng).toBe(10.00000000000071); + expect(transform._center.lat).toBe(50.00000000000017); + }); + }); From 5772b4c34e2501b01a085169836095feda83a854 Mon Sep 17 00:00:00 2001 From: Harel M Date: Thu, 14 Apr 2022 23:41:56 +0300 Subject: [PATCH 130/138] Fixes related to console errors and some typings improvement in terrain branch (#1182) * Fixes related to console errors and some typings improvement * Fix lint * Added -1 for terrain calculation, added a test, fixed public field * Add typings --- debug/terrain.html | 74 ++++++++++++++++++++++++-------------- src/geo/transform.test.ts | 11 ++++++ src/geo/transform.ts | 7 +++- src/render/draw_terrain.ts | 6 ++-- src/render/terrain.test.ts | 53 +++++++++++++++++++++++++++ src/render/terrain.ts | 8 ++--- src/source/source_cache.ts | 3 +- src/ui/marker.test.ts | 21 +++++++++++ src/ui/marker.ts | 4 +++ 9 files changed, 152 insertions(+), 35 deletions(-) create mode 100644 src/render/terrain.test.ts diff --git a/debug/terrain.html b/debug/terrain.html index 3549323a0a0..cbe30aabde9 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -1,7 +1,7 @@ - MapLibre GL JS debug page + MapLibre GL JS debug page for terrian @@ -15,35 +15,57 @@

- diff --git a/src/geo/transform.test.ts b/src/geo/transform.test.ts index 73a05ae0731..e5ee162ee50 100644 --- a/src/geo/transform.test.ts +++ b/src/geo/transform.test.ts @@ -3,6 +3,7 @@ import Transform from './transform'; import LngLat from './lng_lat'; import {OverscaledTileID, CanonicalTileID} from '../source/tile_id'; import {fixedLngLat, fixedCoord} from '../../test/unit/lib/fixed'; +import type Terrain from '../render/terrain'; describe('transform', () => { test('creates a transform', () => { @@ -373,4 +374,14 @@ describe('transform', () => { expect(transform._center.lat).toBe(50.00000000000017); }); + test('pointCoordinate with terrain when returning null should fall back to 2D', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + const terrain = { + pointCoordinate: () => null + } as any as Terrain; + const coordinate = transform.pointCoordinate(new Point(0, 0), terrain); + + expect(coordinate).toBeDefined(); + }); }); diff --git a/src/geo/transform.ts b/src/geo/transform.ts index c5e115bc01f..3d068e44716 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -616,7 +616,12 @@ class Transform { */ pointCoordinate(p: Point, terrain?: Terrain): MercatorCoordinate { // get point-coordinate from terrain coordinates framebuffer - if (terrain) return terrain.pointCoordinate(p); + if (terrain) { + const coordinate = terrain.pointCoordinate(p); + if (coordinate != null) { + return coordinate; + } + } // calcuate point-coordinate on flat earth const targetZ = 0; diff --git a/src/render/draw_terrain.ts b/src/render/draw_terrain.ts index 6f7a08913ac..7ee2abb0cf6 100644 --- a/src/render/draw_terrain.ts +++ b/src/render/draw_terrain.ts @@ -54,15 +54,15 @@ function drawCoords(painter: Painter, terrain: Terrain) { context.bindFramebuffer.set(terrain.getFramebuffer('coords').framebuffer); context.viewport.set([0, 0, painter.width / devicePixelRatio, painter.height / devicePixelRatio]); context.clear({color: Color.transparent, depth: 1}); - terrain._coordsIndex = []; + terrain.coordsIndex = []; for (const tile of tiles) { const terrainData = terrain.getTerrainData(tile.tileID); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, coords.texture); const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); - const uniformValues = terrainCoordsUniformValues(posMatrix, 255 - terrain._coordsIndex.length); + const uniformValues = terrainCoordsUniformValues(posMatrix, 255 - terrain.coordsIndex.length); program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, 'terrain', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); - terrain._coordsIndex.push(tile.tileID.key); + terrain.coordsIndex.push(tile.tileID.key); } context.bindFramebuffer.set(null); diff --git a/src/render/terrain.test.ts b/src/render/terrain.test.ts new file mode 100644 index 00000000000..309c906219f --- /dev/null +++ b/src/render/terrain.test.ts @@ -0,0 +1,53 @@ +import Point from '@mapbox/point-geometry'; +import Terrain from './terrain'; +import gl from 'gl'; +import Context from '../gl/context'; +import {RGBAImage} from '../util/image'; +import Texture from './texture'; +import type Style from '../style/style'; +import type SourceCache from '../source/source_cache'; +import type TerrainSourceCache from '../source/terrain_source_cache'; +import type {TerrainSpecification} from '../style-spec/types.g'; + +describe('Terrain', () => { + test('pointCoordiate should not return null', () => { + const style = { + map: { + painter: { + context: new Context(gl(1, 1)), + width: 1, + height: 1 + } + } + } as any as Style; + const sourceCache = { + getTileByID: (tileID) => { + if (tileID !== 'abcd') { + return null; + } + return { + tileID: { + canonical: { + x: 0, + y: 0, + z: 0 + } + } + }; + } + } as any as TerrainSourceCache; + const terrain = new Terrain(style, {} as any as SourceCache, {} as any as TerrainSpecification); + terrain.sourceCache = sourceCache; + const context = style.map.painter.context as Context; + const pixels = new Uint8Array([0, 0, 255, 255]); + const image = new RGBAImage({width: 1, height: 1}, pixels); + const imageTexture = new Texture(context, image, context.gl.RGBA); + terrain.getFramebuffer('coords'); // allow init of frame buffers + terrain._fboCoordsTexture.texture = imageTexture.texture; + terrain.coordsIndex.push('abcd'); + + const coordinate = terrain.pointCoordinate(new Point(0, 0)); + + expect(coordinate).not.toBeNull(); + }); +}); diff --git a/src/render/terrain.ts b/src/render/terrain.ts index c83e03fce54..19a841ce27a 100644 --- a/src/render/terrain.ts +++ b/src/render/terrain.ts @@ -95,7 +95,7 @@ export default class Terrain { // coords index contains a list of tileID.keys. This index is used to identify // the tile via the alpha-cannel in the coords-texture. // As the alpha-channel has 1 Byte a max of 255 tiles can rendered without an error. - _coordsIndex: Array; + coordsIndex: Array; // tile-coords encoded in the rgb channel, _coordsIndex is in the alpha-channel. _coordsTexture: Texture; // accuracy of the coords. 2 * tileSize should be enoughth. @@ -124,7 +124,7 @@ export default class Terrain { this.qualityFactor = 2; this.meshSize = 128; this._demMatrixCache = {}; - this._coordsIndex = []; + this.coordsIndex = []; this._coordsTextureSize = 1024; this.clearRerenderCache(); } @@ -326,12 +326,12 @@ export default class Terrain { const painter = this.style.map.painter, context = painter.context, gl = context.gl; // grab coordinate pixel from coordinates framebuffer context.bindFramebuffer.set(this.getFramebuffer('coords').framebuffer); - gl.readPixels(p.x, painter.height / devicePixelRatio - p.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); + gl.readPixels(p.x, painter.height / devicePixelRatio - p.y - 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba); context.bindFramebuffer.set(null); // decode coordinates (encoding see getCoordsTexture) const x = rgba[0] + ((rgba[2] >> 4) << 8); const y = rgba[1] + ((rgba[2] & 15) << 8); - const tileID = this._coordsIndex[255 - rgba[3]]; + const tileID = this.coordsIndex[255 - rgba[3]]; const tile = tileID && this.sourceCache.getTileByID(tileID); if (!tile) return null; const coordsSize = this._coordsTextureSize; diff --git a/src/source/source_cache.ts b/src/source/source_cache.ts index f8b970bc9e2..ee5b41007bd 100644 --- a/src/source/source_cache.ts +++ b/src/source/source_cache.ts @@ -21,6 +21,7 @@ import type Transform from '../geo/transform'; import type {TileState} from './tile'; import type {Callback} from '../types/callback'; import type {SourceSpecification} from '../style-spec/types.g'; +import type {MapSourceDataEvent} from '../ui/events'; import Terrain from '../render/terrain'; /** @@ -72,7 +73,7 @@ class SourceCache extends Evented { this.id = id; this.dispatcher = dispatcher; - this.on('data', (e) => { + this.on('data', (e: MapSourceDataEvent) => { // this._sourceLoaded signifies that the TileJSON is loaded if applicable. // if the source type does not come with a TileJSON, the flag signifies the // source data has loaded (i.e geojson has been tiled on the worker and is ready) diff --git a/src/ui/marker.test.ts b/src/ui/marker.test.ts index 46c2a0f60b6..62aebe1a39f 100644 --- a/src/ui/marker.test.ts +++ b/src/ui/marker.test.ts @@ -4,6 +4,7 @@ import Popup from './popup'; import LngLat from '../geo/lng_lat'; import Point from '@mapbox/point-geometry'; import simulate from '../../test/unit/lib/simulate_interaction'; +import type Terrain from '../render/terrain'; function createMap(options = {}) { const container = window.document.createElement('div'); @@ -771,4 +772,24 @@ describe('marker', () => { map.remove(); }); + + test('Marker removed after update when terrain is on should clear timeout', () => { + jest.spyOn(global, 'setTimeout'); + jest.spyOn(global, 'clearTimeout'); + const map = createMap(); + const marker = new Marker() + .setLngLat([0, 0]) + .addTo(map); + map.style.terrain = { + getElevation: () => 0 + } as any as Terrain; + + marker.setOffset([10, 10]); + + expect(setTimeout).toHaveBeenCalled(); + marker.remove(); + expect(clearTimeout).toHaveBeenCalled(); + + map.remove(); + }); }); diff --git a/src/ui/marker.ts b/src/ui/marker.ts index 9aa3a193049..333cd7a4c69 100644 --- a/src/ui/marker.ts +++ b/src/ui/marker.ts @@ -265,6 +265,10 @@ export default class Marker extends Evented { * @returns {Marker} `this` */ remove() { + if (this._opacityTimeout) { + clearTimeout(this._opacityTimeout); + delete this._opacityTimeout; + } if (this._map) { this._map.off('click', this._onMapClick); this._map.off('move', this._update); From d8aa186a20650db2706b6ff2e88682d918a1b2e4 Mon Sep 17 00:00:00 2001 From: Oliver Wipfli Date: Fri, 15 Apr 2022 07:56:20 +0200 Subject: [PATCH 131/138] Use MapTiler terrain tiles (#1184) * Use MapTiler terrain tiles * Default location Innsbruck, add terrain control * Remove terrain_control debug page --- debug/terrain.html | 24 ++++++++++++------ debug/terrain_control.html | 52 -------------------------------------- 2 files changed, 16 insertions(+), 60 deletions(-) delete mode 100644 debug/terrain_control.html diff --git a/debug/terrain.html b/debug/terrain.html index cbe30aabde9..d373dc67ffb 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -19,8 +19,9 @@ var map = window.map = new maplibregl.Map({ container: 'map', - zoom: 13, - center: [35.6025, 32.8240], + zoom: 12, + center: [11.39085, 47.27574], + pitch: 52, hash: true, style: { version: 8, @@ -34,7 +35,7 @@ }, terrain: { type: 'raster-dem', - url: 'put-your-terrain-tile-source-url-here', + url: 'https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=get_your_own_OpIi9ZULNHzrESv6T2vL', tileSize: 256 }, }, @@ -54,18 +55,25 @@ ], terrain: { source: 'terrain', - exaggeration: 2 + exaggeration: 1 } }, maxZoom: 18, maxPitch: 85 }); -map.on('click', e => { - new maplibregl.Marker().setLngLat(e.lngLat).addTo(map); -}); +map.addControl(new maplibregl.NavigationControl({ + visualizePitch: true, + showZoom: true, + showCompass: true +})); -map.addControl(new maplibregl.NavigationControl()); +map.addControl( + new maplibregl.TerrainControl({ + source: 'terrain', + exaggeration: 1 + }) +); diff --git a/debug/terrain_control.html b/debug/terrain_control.html deleted file mode 100644 index 700c0a69c22..00000000000 --- a/debug/terrain_control.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - MapLibre GL JS debug page - - - - - - - -
- - - - - - From c030812908e3a1aac1ea02e26845f96cbb8cce69 Mon Sep 17 00:00:00 2001 From: max demmelbauer Date: Sat, 16 Apr 2022 09:18:24 +0200 Subject: [PATCH 132/138] remove freezeElevation event when disable terrain3d, fixes #1185 --- src/style/style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/style/style.ts b/src/style/style.ts index 087e7030ab1..f257d0bf40c 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -495,7 +495,7 @@ class Style extends Evented { // clear event handlers if (this._terrainDataCallback) this.off('data', this._terrainDataCallback); - if (this._terrainfreezeElevationCallback) this.off('freezeElevation', this._terrainfreezeElevationCallback); + if (this._terrainfreezeElevationCallback) this.map.off('freezeElevation', this._terrainfreezeElevationCallback); // remove terrain if (!options) { From c92f7a4adc79701c5a4c3506a55e02b7cf226923 Mon Sep 17 00:00:00 2001 From: HarelM Date: Sat, 16 Apr 2022 15:12:25 +0300 Subject: [PATCH 133/138] Fixes #1186 - add typeof guard check --- src/render/draw_hillshade.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/draw_hillshade.ts b/src/render/draw_hillshade.ts index a3385ee66b3..e5582ea17b0 100644 --- a/src/render/draw_hillshade.ts +++ b/src/render/draw_hillshade.ts @@ -27,7 +27,7 @@ function drawHillshade(painter: Painter, sourceCache: SourceCache, layer: Hillsh for (const coord of coords) { const tile = sourceCache.getTile(coord); - if (tile.needsHillshadePrepare && painter.renderPass === 'offscreen') { + if (typeof tile.needsHillshadePrepare !== 'undefined' && tile.needsHillshadePrepare && painter.renderPass === 'offscreen') { prepareHillshade(painter, tile, layer, depthMode, StencilMode.disabled, colorMode); } else if (painter.renderPass === 'translucent') { renderHillshade(painter, coord, tile, layer, depthMode, stencilModes[coord.overscaledZ], colorMode); From 84a1339f0d0a0a91b194f888d01475e102d6e816 Mon Sep 17 00:00:00 2001 From: Max Demmelbauer Date: Mon, 18 Apr 2022 20:31:43 +0200 Subject: [PATCH 134/138] Terrain3D symbol cutoff at horizon (#1188) * implement collision-index perspective cutoff logic * getBounds calculate corners based on visible horizion * add tests --- src/geo/transform.test.ts | 23 ++++++++ src/geo/transform.ts | 7 +-- src/symbol/collision_index.ts | 11 +++- test/integration/render/render.test.ts | 2 + .../collision-horizon-cutoff/expected.png | Bin 0 -> 16820 bytes .../debug/collision-horizon-cutoff/style.json | 49 ++++++++++++++++++ 6 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 test/integration/render/tests/debug/collision-horizon-cutoff/expected.png create mode 100644 test/integration/render/tests/debug/collision-horizon-cutoff/style.json diff --git a/src/geo/transform.test.ts b/src/geo/transform.test.ts index e5ee162ee50..2969ea3efaf 100644 --- a/src/geo/transform.test.ts +++ b/src/geo/transform.test.ts @@ -384,4 +384,27 @@ describe('transform', () => { expect(coordinate).toBeDefined(); }); + + test('horizon', () => { + const transform = new Transform(0, 22, 0, 85, true); + transform.resize(500, 500); + transform.pitch = 75; + const horizon = transform.getHorizon(); + + expect(horizon).toBeCloseTo(170.8176101748407, 10); + }); + + test('getBounds with horizon', () => { + const transform = new Transform(0, 22, 0, 85, true); + transform.resize(500, 500); + + transform.pitch = 60; + expect(transform.getBounds().getNorthWest().toArray()).toStrictEqual(transform.pointLocation(new Point(0, 0)).toArray()); + + transform.pitch = 75; + const top = Math.max(0, transform.height / 2 - transform.getHorizon()); + expect(top).toBeCloseTo(79.1823898251593, 10); + expect(transform.getBounds().getNorthWest().toArray()).toStrictEqual(transform.pointLocation(new Point(0, top)).toArray()); + }); + }); diff --git a/src/geo/transform.ts b/src/geo/transform.ts index 3d068e44716..b6258942bb2 100644 --- a/src/geo/transform.ts +++ b/src/geo/transform.ts @@ -671,9 +671,10 @@ class Transform { * @returns {LngLatBounds} Returns a {@link LngLatBounds} object describing the map's geographical bounds. */ getBounds(): LngLatBounds { + const top = Math.max(0, this.height / 2 - this.getHorizon()); return new LngLatBounds() - .extend(this.pointLocation(new Point(0, 0))) - .extend(this.pointLocation(new Point(this.width, 0))) + .extend(this.pointLocation(new Point(0, top))) + .extend(this.pointLocation(new Point(this.width, top))) .extend(this.pointLocation(new Point(this.width, this.height))) .extend(this.pointLocation(new Point(0, this.height))); } @@ -695,7 +696,7 @@ class Transform { * The calculated value is the horizontal line from the camera-height to sea-level. * @returns {number} Horizon above center in pixels. */ - getHorizon() { + getHorizon(): number { return Math.tan(Math.PI / 2 - this._pitch) * this.cameraToCenterDistance * 0.85; } diff --git a/src/symbol/collision_index.ts b/src/symbol/collision_index.ts index 73fb26f5e2b..d188ee4eb89 100644 --- a/src/symbol/collision_index.ts +++ b/src/symbol/collision_index.ts @@ -55,6 +55,10 @@ class CollisionIndex { gridRightBoundary: number; gridBottomBoundary: number; + // With perspectiveRatio the fontsize is calculated for tilted maps (near = bigger, far = smaller). + // The cutoff defines a threshold to no longer render labels near the horizon. + perspectiveRatioCutoff: number; + constructor( transform: Transform, grid = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25), @@ -70,6 +74,8 @@ class CollisionIndex { this.screenBottomBoundary = transform.height + viewportPadding; this.gridRightBoundary = transform.width + 2 * viewportPadding; this.gridBottomBoundary = transform.height + 2 * viewportPadding; + + this.perspectiveRatioCutoff = 0.6; } placeCollisionBox( @@ -91,7 +97,8 @@ class CollisionIndex { const brY = collisionBox.y2 * tileToViewport + projectedPoint.point.y; if (!this.isInsideGrid(tlX, tlY, brX, brY) || - (overlapMode !== 'always' && this.grid.hitTest(tlX, tlY, brX, brY, overlapMode, collisionGroupPredicate))) { + (overlapMode !== 'always' && this.grid.hitTest(tlX, tlY, brX, brY, overlapMode, collisionGroupPredicate)) || + projectedPoint.perspectiveRatio < this.perspectiveRatioCutoff) { return { box: [], offscreen: false @@ -268,7 +275,7 @@ class CollisionIndex { } return { - circles: ((!showCollisionCircles && collisionDetected) || !inGrid) ? [] : placedCollisionCircles, + circles: ((!showCollisionCircles && collisionDetected) || !inGrid || perspectiveRatio < this.perspectiveRatioCutoff) ? [] : placedCollisionCircles, offscreen: entirelyOffscreen, collisionDetected }; diff --git a/test/integration/render/render.test.ts b/test/integration/render/render.test.ts index d6743dd627d..2b0f40772c9 100644 --- a/test/integration/render/render.test.ts +++ b/test/integration/render/render.test.ts @@ -66,6 +66,7 @@ type TestData = { actualPath: string; diffPath: string; expectedPath: string; + maxPitch: number; } type RenderOptions = { @@ -415,6 +416,7 @@ function getImageFromStyle(style: StyleWithTestData): Promise { classes: options.classes, interactive: false, attributionControl: false, + maxPitch: options.maxPitch, pixelRatio: options.pixelRatio, preserveDrawingBuffer: true, axonometric: options.axonometric || false, diff --git a/test/integration/render/tests/debug/collision-horizon-cutoff/expected.png b/test/integration/render/tests/debug/collision-horizon-cutoff/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..73ffb2d58b481f6fd03cd708d1bd0788d0656437 GIT binary patch literal 16820 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 Date: Wed, 20 Apr 2022 16:38:58 +0200 Subject: [PATCH 135/138] Use demotiles.maplibre.org (#1190) --- debug/terrain.html | 150 +++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/debug/terrain.html b/debug/terrain.html index d373dc67ffb..afdb56cc836 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -1,79 +1,93 @@ + - MapLibre GL JS debug page for terrian - - - - + MapLibre GL JS debug page for terrian + + + + -
- - - + + map.addControl( + new maplibregl.TerrainControl({ + source: 'terrain', + exaggeration: 1 + }) + ); + - + + \ No newline at end of file From 6a9d9cc4690e3392a4bf6cd75a3ea5679ff0a35d Mon Sep 17 00:00:00 2001 From: Oliver Wipfli Date: Wed, 20 Apr 2022 19:08:38 +0200 Subject: [PATCH 136/138] Fix terrain source button (#1192) --- debug/terrain.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug/terrain.html b/debug/terrain.html index afdb56cc836..e45ca8ba998 100644 --- a/debug/terrain.html +++ b/debug/terrain.html @@ -83,7 +83,7 @@ map.addControl( new maplibregl.TerrainControl({ - source: 'terrain', + source: 'terrainSource', exaggeration: 1 }) ); From b280511a3c5deef8cfb9e549aadb148e728b2d19 Mon Sep 17 00:00:00 2001 From: Max Demmelbauer Date: Thu, 12 May 2022 15:51:11 +0200 Subject: [PATCH 137/138] When terrain is on, render last layer correct, fixes #1124 (#1189) * when terrain is on render last layer correct, fixes #1124 * Added test to verify the bug * Fix lint Co-authored-by: HarelM --- src/render/render_to_texture.test.ts | 41 ++++++++++++++++++++++++++++ src/render/render_to_texture.ts | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/render/render_to_texture.test.ts diff --git a/src/render/render_to_texture.test.ts b/src/render/render_to_texture.test.ts new file mode 100644 index 00000000000..e4f5d1141c0 --- /dev/null +++ b/src/render/render_to_texture.test.ts @@ -0,0 +1,41 @@ +import RenderToTexture from './render_to_texture'; +import type Painter from './painter'; +import type LineStyleLayer from '../style/style_layer/line_style_layer'; +import type SymbolStyleLayer from '../style/style_layer/symbol_style_layer'; + +describe('render to texture', () => { + test('should render text after a line by not adding the text to the stack', () => { + const painterMock = { + style: { + terrain: { + sourceCache: { + getRenderableTiles: () => [], + removeOutdated: () => {} + }, + clearRerenderCache: () => {} + }, + _order: [] + } + } as any as Painter; + const uut = new RenderToTexture(painterMock); + const lineLayer = { + id: 'maine-line', + type: 'line', + source: 'maine' + } as LineStyleLayer; + const symbolLayer = { + id: 'maine-text', + type: 'symbol', + source: 'maine', + layout: { + 'text-field': 'maine', + 'symbol-placement': 'line' + } + } as any as SymbolStyleLayer; + + expect(uut.renderLayer(lineLayer)).toBeTruthy(); + painterMock.style._order = ['maine-line', 'maine-text']; + painterMock.currentLayer = 1; + expect(uut.renderLayer(symbolLayer)).toBeFalsy(); + }); +}); diff --git a/src/render/render_to_texture.ts b/src/render/render_to_texture.ts index d006db5dee9..b2ad0071590 100644 --- a/src/render/render_to_texture.ts +++ b/src/render/render_to_texture.ts @@ -145,7 +145,7 @@ export default class RenderToTexture { return true; } - if (isLastLayer) return true; + return this._renderToTexture[type]; } return false; From b3c2c9421d70f62f493476f131ad91db889508e7 Mon Sep 17 00:00:00 2001 From: HarelM Date: Thu, 12 May 2022 17:45:30 +0300 Subject: [PATCH 138/138] Fix lint --- test/integration/render/render.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/render/render.test.ts b/test/integration/render/render.test.ts index 5be1107eb45..f82acb44865 100644 --- a/test/integration/render/render.test.ts +++ b/test/integration/render/render.test.ts @@ -64,7 +64,7 @@ type TestData = { queryOptions: any; error: Error; maxPitch: number; - + // base64-encoded content of the PNG results actual: string; diff: string;

v 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 IE^GJx58@wsOaK4? literal 32739 zcmeFad05W-+wZ+thD>QfC6S^eQ$om48WfroiDj&0tc)3>K@=iFhEhq&m{?}1Bq>8O zk4=V*4Tg~H*J-W$-pBpidq2lMp1<}V&+j-t{b@8@%#@9F%kb&mEnEt+aJ z{o{{6TG$S^bpGRydY|Mkg+}~I-o58xfBZ3Lw5_GNi+{a$8I6bD{hV3z>+9ELH>PNL zTvbyuRWO{Z+*t8l(N&XER{Oo8XS|HpN{rH(;XXEhPh$LE*=p0n`a4%o-e_bq*GkRf z>ZUHkDh>s_8rE zcGEH0B|mmZ?7^`|OFn$Kv7^_t*ALV5-`+nuz53<#vRAK4%gb{wt^V^{acKJosnZ&_ z8@T9lc6P|!gJTn%lW)EKJTi9ho)>xB3ok5NJbTWZZ&i6cY)6jtczE3N$=QX?CQX|3 zY{{#3?x*HnkGBecaLT9six)3yzJ2TETQsz;?rZw|4^R5p4_BBwckUtglVKN@eLe1VU31>NdESpsbSX@7$jQnIO8@!ZM{CehwJo`p zrB^mAc^N(3Ep=)`PfyR&=gt+TPP2Iy@N0#9Tjd7kHF=I5YiFGBE~wwQapUiw--gD< zw*UO*?zFP2n;$%SRF$hA>sxkJdB6Rhu+Y%P?N@wKo|dyQaagG0?jZp&d-ry@cJ11O zbBlWKmVNZ^lYDX>(-tB_Hx&Q2M-)`uUuL4<^ALNMVIPX zZ_o^JKm78|-Gk?=Zw!>T*|bTib@vHZ4~t{+w}p zUz6=UCV4$M?RWaj86Abdim`gSe9c++6>TGZeSP;X{`kzp!^5}aa+61=d>p*II`f@N zpIulckEKVC9*XS-Sk9f>Ju9?jlI@nx{!5p}J12WTJl<*0vM>80jq+-K{Lr;knK*Ic zr#E-Q)282?_v6bP&3<$9-#mk zCTjZn`eP2eXOEq(Few#>ONw7_ZLo2E-c%A{J8Og0qqQD+>Qtv zpwVxxR*#D{9iOlG+V1f9Q&%!4_pIn(8@WlZNkYNekcfzuU%q@f|NYIu;5BQeI!&0c ze%G$HpWoisH#OZcI?2A*yt3gcDk}W)mfYY1?=th_M$@MBR6kZxU7hvl(N2xtUPZ57 zh30z1pE#k$Vvbq%p?_v(=7Y59Em?mrpPZS0_4xV%@5|mM@h*n4^1C{-@=g2qFMj(r zkEL~HLAi?0`N~FFYg$apjqJn%*PbEzOMMV!Uud2EqA4^#-?;fTlm%V)(p6fC7-l1{+%a*AsE1OTA z+~MejFPeXyTl9h_%za$?{d47~Py6=m3%;_UZDG7s zGsC;dqeCe;qut%ZxQl1ZE4ER-NGV9)YKD%kNW|d#QynMR& zd8ZB?R&^e=v#6}ha>Tp(5wNpoh0PD@06jpc(o-0}a9pLPx6Gz-i9J$8BwFR0wU_ijf% zv?YJIvvB4TlO}r$s zl@3-`4I>V+^39ckLpLi2Yj*6|F|gbCzbkC^nED0YpSY|=P{yU8e6QZRHXA*7w6#t@ zzJ8p3=YSJWTYKOAw;FwCtLH?te--iQxMwq;^q+mX`j)bMxIjDGdK(&jdG~PGf(0hD zo!x_1>|FZ!P4Vm3SL=TMpx6~(-K=|ua>g>8YPMi)yM_%9jX$-K4{~&I3Er@w1n}=6)x=Rq`kT1{()DUVoY%5Ziub&Fb^#&G^0HqedkjI<(&P z;Fw-Zsyqx04Tp~yA*GInyLEJuL+?3{On5@=+Vgs4ooi249VZo>rdOr;dXW%&CGUB3iuiI`nC7qnxa2l3|l>X z_;B`vW2;yE_~Q5CS}S8?V=kdn|NhZ-XU?3_>OU`-=g<3`S@^c~(hD*D=fA9|%xOoxVV!qTrFuG2@jOD{g(pEUjP-*Y~7>5@@UusI{B zap68&RbF`P@4sKxeygS$4*pd;fA;Lz2RwXyZUT$OrLP>s)ytk%Q&T%O^RA)wdi9Lg z1qsxM$yYb&ynAwH3s2R|%*?+$ar=Qu>4T|Byp4VA;87DNYLD1vWS;EeoO}KH2A=31 zo_bYDcn_7~mMPUL%U4%feST+OaPCFM6lGz58F89eebM$jr3Z+0SQV&W5(@)q4d} zYmKL5HaNTJy=WZSe~ak(fXXvX~` z?Ua?3snbrj+dL^y+WRb(W_F+r9Xfn?N!_;3lf3zD0jf27awy-{H<5_wLc(Id?$JF9u~j9GX9tJ@b>ETgmpJ)C_dBV#pqL#=5;ZmvEzN_q>=IdadQQBF?E zixw@SQ$|KcX8wMgD_0sNvLbf%vmG@mn;r$A1c+&SjJrb5;rX#`1}=KnVaSl!W5;?@ zKy1d0k*7p|;aS_-+js8NsUf8@MX%aNDR`z`(w~R71?({O>&RWa41yLg0W6UI%?tVN zlu0^I@Z+i%diwghUDaNHe4dk&6RLf4aNgmqY9)(5TF;pk9)7UvpN*RDjeO`a_0^3% z9#1ZA*yBFx)Q6`|hEZB(zN^B*n)2#k51gWeS39Q%OR6{sykjaj?^nSJigz` zL5nwXdp&F|j@~akZL12Tyc|;f>RWNely~pnS5|)6zbry~pI*?Fh=4uzjYC`NDrCk+ zc+|BBbR1Q_VDH_kmSB^8`}B-7O}tkb<*9G5p8M>)EzR}AhY$Y#{*#TPrQCr8ADx_4 zT3R|RF+YDK*F!76O!rUuv~&>P#6Yd7yj;(g<|NOV;*vZ%Ns(5;A4p|d_O(0pS9YWw z%L5GMd}{7ryZ7u#PC0*mciVn*S%{;C4*jFG)MOqcuM#xn=VyNO{`|N1y4j5wAxNaK zaEslkxliLypH^?*zP*-~)~)iP2d$JE)XS}vE_GY}sixh(oxj8Xqnp#MQ~K{wEMEK% zE(oI5UHOdxf&*4l4p`=WV*bDWRH+9H&^Gtb<6SI1$6MC)00#UDJYc{M4t`@}tt3A+ z9sYMe*HwJ7v~nsfUts3S>tw_A>y%m8O2c+T8;#u2ztKcs#nH_`R;31USGN2g{v6%W z#mC9XrR#up4jb%q+PBtN*Fhn3(mIv6@8RqBxvyJamdsz9t*rjRiIz$$6ACMP6zB~L z+n8jrrFoYD+R>dgoEMn2au<$qH&DgA#>c(euTu?fc`q5DGBn{uL8n#Ld8$c;yxwt+ zfpXml7d407_Bpyh98Htlq4fhRUbSi6$h}*pZrFOu1JAZ9DDh=fHF9;s*O%FjC|GSB z-l6u}jFUnaqueJMja$>*%M&rwaVU8B}6z>b$r+M#0ZFC=8<-IVOop3x&&8T1){ zbqGMlAW(9A-`&S)4I&QKABJ1 zRS2JT|A^n~TRK46iZ5UG+prUplF~f$T3ZYoHtxdGJ{cJqQtQjNPg*$z4!hv}qbP`T z;r>x=-A~T6qVrW&R&ph`Ki=+Cd+nOz!MoBjDvHdzPdvZY{qTP1my}v4HI4E*y@&?v zRZ*02;9C!bgxQZytm{4fhWx&CkK&LvApaM@s@j^;2+A4UNTF%d%#MBfMA4f!@7fi< zeR~^NhJYJdY{|QK`LLoU3JOCH3RZR8W1t*!9VrPD~kSTRj=NyxIbn8>%VyHqcQKj=8-dJ+&(_GvC3Mb)^A4U;(?1C z$4nSGtYyoK4kJq6JxCSlgBpEo?$ZHh7k{*edyM~kb}_(2zjNm`>(@8`d-lV?lPCM! zG^=htxOO|=Dix6gib8_ zmM!@}^@5XKvy$vzghco5VrUpYDShSc(*d#CH_fu%9UlMf%PybS4^nlZgJ>5;(R;3+ zi;HXCw(t7XG_N>Eg99E7gV(pqJ8{c#;zbez`&qG&z_qQSOkM2-7Nuf`hR&iJ=reKv4h!P_m56`#nLD{c=TdsZtl7vGf^_+ zldVq9s_sco(i*&cN00Q{$RXEe_pQD+-lrgKxj6{{c+a&-S!r$LHuU4O3rk$A z6O1aecIDoZ1VOa-L(zG()oop51k)TEW) z8jjmmF!SV{!{gh8!`YBruHL+vlb091vE4vtclT?o9lu43Ub@>We(f<~?~>}5F4u0{ z@In&+2b7eSvi#$yOnlpo?T6ezzTu|DjXyQ_!NZ4B{C<942&@Y!@ZPub=Xd0|jly*H z3|xHs?7~^Rb_P%s(5I+JWr26JmT_3?imoJtZQ9STYYmr)%*LW@*tx;enXoz?J>^!=>5^j za7?WM3)Ui^-Qrq|!otJ-7A)8YngRdcIx~NINlD4twQGxDL);WtH^eN|$v};=D<2aA z??pX?koKB+$ADtfC}=fY7jQ^7Isf_I_~z{fY=yj}2K-uy6odZ8r}Hk6dOBw9ppza{ zE8!cS90?H#8T8d zsZL|Zj%ySpaKsuPb$ zzTBtR1ws9u`3C_z>({Se!^Tzb?bV#B^y0$TXS&pH7W;>17hp)|tFCo5ayzz))zgdb z3P+(G{ZXr2_h_p^=AW8)+LP4hp1W`pOk@m5E^7(fobixle|prnJyBnf&0`ly}cA z>;e^tf{&67e9hn0F9JRdd<6xUU8V{8`-|`xk}+UfvigS|9#ajc*EL%*djH5c&^R{3F=~ZuimqLC(Hz@M^k0o&z&dQwvgLG^hun(G zmn~U`ub*8QxcI}949YpWufTgz6qhWkzLp>D66qPu%UClNRaH~3@9e{BrL*Mo(0BCn z(H^#@c`>@FEFzfJd^Yc!JIPsa@D0`pI)eta8!}`Fx_$YhlU+ZauU15BfL<3D0 zOLopUmN50v^6;1~+pdgGEYzv3mtNP@C;hr=oTZX>PydR^xE`hfb!JUN>POjS1LM3A z-w^w*~QrBnHg)s288wg(a8i_Ms8B< z%4_IXQt1#>DWxJ6aT`wil{R9Tqr8r$iBJl%B8Jpm4QbX!p?UMNgoweJ_wR2<4C}S{ z!-S36gRVh+q;DA>9+QXEo0&Q-hZO*CuKe=Yr*NXpcLNJ;TBV4=Z{A#^Dte;_WENsXQR&8Q^YiuPR?h$aX@)$+B>O!(Xze2T zu#sdhu%b$HBBozntK3}MY=?+()20Q5I44_rdWKxPvLfKmTj@&-V}O=HG8~{qXqO2NworA9h!Ma6tL^g+UjiqnGc!UpQc} z_PIMQ+GTsTWPJ*2`sn@B@W1R8y|%1t)V6QMji={4BHG&YEt=l5=gTj1wAyqlQSI8b z``pJ@>L#s>vkGtBpyr3}L6-%lOCq~uXV)AW7xXB*VY5-jn=WmME3E7=%GkTMW(DlW zVY`%R_rqS-wstY|etj!WDq-UlwUs$$Bk5}Z=GvIPa~|EIBc#l{wYMGsx6GVnIt3NU zY5dzdc2>@9g0SnVA6-+2l0Ypo~=$ zkLHL{13*`BR?e`dHnXH{27As}Rlm8rd}W>43Vr*_ zXUzXJa$bN!TxMzQ>>8$M;;!A@uxW8Q6feNZ$!x|>j}G)0b6NIts;}3Efs%E!J<))P6^gxiC+BnvMq8e->x$b84L*wm4E8_$`LFKRE*ubwRZNIwdU~QZg_dak_s!U z_YBmUbYd;PvCEDv%r4zb>q0H-rQSR^G&JqhqB+vK8nw_2=0)h(;^wh~u=c>_ii4QJEk(GWpZ#bjyJCuQv^N_mCME{(aD2s& zML2`FaLX$)8grA7k#}HyfuX(bANdPNxIN{`lPB^=$TospPoF(&>~U2|x*E`HZFsm? zaV);#va(?KWT;}h5^AUak|n7gxhkwG5r)`mFF+8K>0Jn3^}E;Vw`$$Gq^#_6={3sl z!-vt&M`Ii$B!~K1xF=ATl-qAV)AzvU zhT=j(Ii~yu)EXfc=B|x`Fl9G;M$0?%mJpbhLU`1g>e*U|XsEAi*tDZ=@;?G1TA62N za1*16=hbPAYr_Js4%fa*uc#>sYU!5d)dCUB%m9@^3R6Jca(d^tgd>yEZ=kE!AYkMD zmY6SDvgG`iN3-&ydxvi8HonRxao@h4Gj8i`>;9M6WUWQsGE=rg3!3={Z7T>oy3JF2 zpNrw|4eX&2AMdZ;#L+3lJ~SjSbabU})4KlAp`)wPb62%$nN$|w9l5$e%vlr_dPDzZ zUyQ(w=84XgGp!olyF_>H?_be@LMPfTZcIm86&wak$xs?7-D4E=qw?!l{l0y-K^0sIn;INH!drlpYh_rpNJVIf_8NCGy62+41r5fj$?%t--{d$HJE`JEF&h z;DZOdio^f>;tFBq^aE_sbv*E6$2O6Ph}^MbEei-v)!D#cE!*S9o`E?mM6Prytzy+6 zhcFdHx%5b$kgbPaA9JayF=xS571#Sc7rSQpax?hudAIbz=T6O;M&qyf{#}?7^&{HY zvnevYv?eyjZEW$m&o7Gp^7_e{-XdNP8ng$MABEB%&EAhnG4*E5Ao+Hf9Izag6QZ=R zBQfUL5UdNMzs_!jRP>s5rTN4apIuRShO>9BUb`kQ{Zw8U3IN*@6JyV1A*jEKS*AFC z{CFcpZL_Puu~B3dpj~bYK0JvQLIuTB6bLQqj2*3#tI z>MaM?tZLPD%-*{*WjP59;rO{v&t5$~GEs0UoYL#YZb4jj z6nOgO`nLTPH&|!EE77^9-Pqm#^5x674vy`?-(|f$ntp@5uvt&+Lo+k8(`d;Ea$eu6 zBq@V{9u*T%x1_4NdfnQ!9SjY_u>GbMobs78;jh2Gfw^F1dcb2c2Z5k!-DmUeb_Zl`^9xRiL>BNsW(*kQdaj$b|ZZ2aX}(6O%6!v2y&_<=9( zC*$264Wsy#l}^f(!(nlbO3KQsMW|z+xQ!oQ$VH3wMb#E3svLPDQqL*(+O?+RwtX7} zOdYq)*1_Qw6ij+E?x7JKB{wfGD;_Wi6AJ{O^rSI2YOX%i6%H@2I&P$!XN+bx;k>^x zkq#i~8kmL{8&y^Fd=;Mt#5n1A-#^{?R|oW=M&s3zC%2w@D}5>#D;#l+8)$ zvq$lSdrGUc++eygj|BgGvNDi|JP~|!IXez*Er{(RS%t;VSL9H9m$*>+5L~I|v_+Sh zG(d2XCmdtJ$7g%s_tiA|Kz64@0b1R>V*=Hc=7p8cSw$SnU-+b&(YfH-nJa6PJf zk^>P=?~6z9_;Fjv1EBrbsZ%)~#*!hSz95clpSW}#JVP1r2=GU<=jC`#DZ9ew@KIgkJLW8Y!(*!lYPa&}W^$L=1qY#X%| zG?c}IRZvv)LZA`D7Ry|uhkxBzh~n}e?@v)QMSK%$66q+4MK8OnfB*h^ojW^2T(#P@ zTNe@W3Mx;GDV*M(Iwh+SI*ITw+@lw)yIQg=Vr7loF%)Y~95O;>UywMW4Zt&>b#A)iy9qw6>{Ux^>k^1JF&Z(BxDr5@@O1ei z=Pz8K%+jV1w)0T8vM6mLaHC_elQv_S3y|fFP80h{a)^~KP5ZDscy}JSPxL3s zrj%fc4LnbcupbbO$AFuraCpp!DRHWDXRzWjvv6U|){r78{v~*3#Amfu4L5Ignf|-i zFO>hU9ReabZuA?sIOlp8Q}uY2)^$Bn8xu;E1U{Qbl1>VN)QUIGbf94)fr%dc!E zAWNiPigENvDwwNR8sb^7=&NjRaJZOhFV+zToDU5Pa1?~pQ6XX~)tt0j;ooz{Yuf<( zQL3A(_gob!VFMxn)2hmHf9Fpmt|(kfoQ54ccBscJd8vW8LmS*u2diD8&R?7K#6A`NRec2qM4I-NK9e1Aa3!#E}kZu)N5Tj2Vl^O;(+W~N`C^} zbW~`GI~3^HqU^CwO0yT*tI zz^yf?k09sf?FawPe^AVQF+aI;Ry0s)QBnV;bG4yRg0?L#JnG(9X#H%P4B6E;f5tM-{bY)|^a5#2$SgV?vn#q3eAN3KXkMbOi z=o6_YxfY3gM0OfcLl2dx7oePIVd2q9LnM|cauv}FdRvlxyJ!BTEu^GJ_nyAVGa5a* zkoHUeSl_|rpZh`5paOS6jD%J7{zQ4*%iewWJU#YbMGQokL5L*UY>Ba$E;%{#Yis=2 zHN!xcrt@DmhhtqvyyA!GlA^}qeWk2g^#^qC3a}`e@@AK)lJ+oP@+n3}WkD?m?c4t5+x2)>N|g-rPGpqSLZv%Sd@#V`bqj zHOF@#50Qq&M0VzP6ad}*;b}izu%Cn~8a8XaY1_6dWH;!hTyJla8MlLx*hF)?d$0{x zW|L4*5xehhpncA;8Id|xp%q)ZfUFKQdiU;~I4_ZUk`YDHPOTy5K>JGad43T^P!e^i zFfo+(V;KJ@PHctS;)s;mykT!YY_v!YR@L9+5PRjR$@o(o44~Zs?0?_Ip{3 zqJE)-$rIp_(o4k@Al0@`RbN6Lfeo9vo%ipBeAuC5NBVQkSlh_pY*rU8n&^i(CiTKq zE@;~(OsP0D?!ig#jNL>y)0Xwq(a{n89uDGL@odoFp3|#Kwsv{2Y-!crS?3n@TKvkM z4Q4;|X3UeWU8iLn`AhHlnXI#U+fyNrCT-emeR@_|Q}f!+h`}Y*qmz8??4}aSl0b6V zgmYKUe}0?H6L_z0zt36dLdy25!-JC?a?^1{V>kYG%ln8k=t7Kg=1EO53PhCG0zaZ? z;}w;aQ`m&!B(Z0e+O^xjuH@SlIVInnNmNRG&{7jJkmiwkM(8*&^d_pEMdDoa;Yn^u zb~xy^2>HZJ&>gEEK~2CK5h=qnr%yYcTQo(FGd|_>{0iO|3=Ot2j40E`3tzQG zSS1}DWfuYo29R#ux|JY`@4R{Ok$Scg*miRpZf~y$S|Uvzi2QgQ_kuDqimy!@?F1=; zcfyo5z+;h*1W#})Hf`S?%B{eX64|zKPC8s-dB=;LRPt z=w*l<2=5gc!p@j^w{AH?wj|X@s0c?r&czS}v!661jSbT~)yk^UCXodAsjc@re$xdG z&k^kDqFPs1cVgzz>*8oBw(m4kVO7f4%V zA8-MZ8Bi(?Zx~u2`FzP~@wAi29@Q3F0yTD-iGOkN;zgEYkYwv$?(#8SS?e!71`^lJ z{X`Lp4(R};wr%rph^@(J;iHi@NEmal{NCZVnj6Gb5toLd@*2UO)N<{3OY16|eXohl ztPQhBc(J*BLGAe81*$Xj`{9WhsxVOe5hYE{Ft{`-r`Etl>k*rAa&a+F_&krH@A$oY z&;SNNLHX^F&~l;+eD$KQ zuqna3t`KxuNOcD)079m}IwTWqY)uCE0;lk1kpb)#-(JI;ZG7k<~55Qs~QM~73v+;b*ze-nx&vQv@7T2GC^}l zUKVkCZ$q%d_{kfY<%?-S?GdXGL)yi&?=C=u*!CVKnw#|m|G~q>LK9C`bf=!MljWc9 zj^!IRw6U=f)Ch0DMQLfQxq)h}XY2Ol+~NokSNlC*t{M;!(4hFJebTT4w6v0|*ROlh zR?RkI)6*EUPRuBzySG@z;xy1jdE5n%yeYcx|L+Arx_iTK7M!sdui%vD%J z)lhEr&2!Tq0{v<}6*`=OB!IcHrn0Bl=_uKX_yLv_9^&~jXu(j5aqr%eN=9Pjp1!$% z^yXgkAW0jrprlXX{~^a-k|=&6eo!hQAUe*D0SgW3__XoHSm$tAK2aaIE5%Hp59STO zwU+ngS6B*+yr?5^g|=)jab7rzAEPH&uvzD7BP4G!HM=S8P0BhIk!VT#wr$&vIXdzB z*XIE@5vU|huiAO!B`Q4+D0R_$clI)xN(*}1G;GJ^)z|w8I~0GPrBaO-Edw=V%&o|` zw;1c}Y(YUBwX5$7)EkBvNIaz?E$a5^(~5W{X?wPgU37Fbd0S>jR|yrr-|Zi$R;kDd-duiGM31gDRxK}NM|xB!EA?~?YpPv zwo|`-0m-P)B=eF|K7Cps-|gJTi+Nlye`J&FGIeuotONKOTydu~fW;#j>+apJV7tRB zjX=8Dh`|J&GoL^y)En)Og#X{nOoJG8w@c(+-K+nixaOhPA&`@M04T&=yX_UlcB+q^uaQw)!Q*M z0STN+d529_33j5i#@~M{(;zH8ssxD`g2NqYGt`Tr^NgdQ0vNSCab*NC_runQ$MnWe zWW{Kh`gWith|mY)s3ODA8y+CEvjwPb2nC5zV zdYfWmZg5{@r*<84s6*YaX)Om|O6gu38jwCXw)eQu#H+p?N*Xi{GaWk6bLR}N2L+x7-QIQE5gtAJ%lW>E2weRqmj9@oNKvI$a%5T3&l3{8iP*^zU_sZz}Kn zxQKSoQspa5Iq5D&xD04PTSY45>9%oo_4CHkC@3h%-`#%;>r-M1F0P*cQrS>sOc5z1 zgEV7C7m`;pGWV|%*b_2yXiV4E;UVY2B3!RfnSYr9s0`(rkD2EBuw&@SSSsV|@n4EM55aHt)?g_4{;H`Q56g zUZu(#)@XWqf?STX8fd8v!vcrBzvZ}K>7Ykj)y{6)7WpJq7dr?-rLsJ$#TUmZCtQw^ zT$%Uf-8eMQ>pbF7M05J?+JIn-+>=LF2j_Os(+eiEe2nY}uClM6U-4!eZ5>0yrdCey zK8daZ5|p*IZ^#<|DN0m%VUkFmY@K-QVzL~m-US_{+C272-@v1#wN@YSos33%N6wZnAtydD=msUT0tWWZ)!o09kMM-e@y?d?a& zLA-5BfoHHvW|_ETsBh`Vk2h5v%*>f2b8>Bkq(DR~c6n739@}{cg@R6S8nxQ2I={CB zg<5xWmp}_MBmJ2RkO>cphbK=)4049VqCgoED3*Fn_FH0UM4|Ml($KU4i{6PEvJTA` zGEV`$Mi0IX8zg6!IW1z4HG7B#LW{4uG4P`VU?#5o=6NG#P#)eXPPrZonA+Y8JJS8{ z*%Advbu()4^h{Ps(PYZ^<;;f7=>J*02WYyqYCO!Z*UmAAcRWcS@^PcOISyH6v*sSJ zUgUlHUZy&6d8Jj%iZA2DVo1>$R&m&!FP^sx^B$W*lp8de#5;(9=LU8`D?maM>W3KY z7rsuXQ@z0JF6!L^bgZ0wujb{Ik}>!Sr|0@XKc^O5T8*f# z!Dsy1W}T2xOp;s@8f<_y%{2mpQc`&Ce$_8Wu^@(1N*o4#Rzv4|5z=O2QCz6Dg_GLK z@OXo*g)>i@%FB3vxp3N%?=knof_)qvFY!-1puPa2ee?}^a^#qr>jc;6i>;WFQu5-3 z73IlK6aZvqMzva4IUSgIVE`ZGDdqqcY(l|s5FZE)P^NuhVnh(wgtI8zXmTlw+EzJ3c9nSp*}?9gJD}H75WhvMFvCPZRUQswf!E8*eyX& zGt3Eup!q%cC?Xt=Y7H5aeDwF6@GM{jkKXM2>jYB_!)evk)94nm>I}j%q4n}5#6#wb zNNM0v%m5Tp_i9_6s2!zdrNf*OH{AIMVGx(Y?osHz!hM;4%L;4NRfu%^fZAT{6}|NB z@dlcMVm>9??6n*eAu^X#Ghy z@3T|>^zd-(UZZlXu}-k>Qo5;FmgLP63d?=T5$<(Pw7YY3QY_{AID4N=LMPWKqHA?WpPoB&f6WOKvRCE3W~xC|)aO2( zI>VxVm%)RLe!S~V7iPhs29}OVR>3*1(b!;C-|dvo^h>Mi`CD4wJ~m}oNqVhHEcXO- z_~N!ohX?DGEKCReVI@+}rmm*Spg!UlGzU~;jVt@>7g7<2v&e|?VCPedq z#7DT6oC17q#@&iXRuTPNIGE^gPrZ5vuv8^om>)A}7i*_v^3MKS<|bG(9x2mL%#4}+ z%iAREjRI7s=w4SJ+aud6t=FP=ZkbtG<%CKkA4Qjcm7Ek4&;4aX`=b3KG+hpDzj7_N zj-~7o-kgET zWJ!UcZ2)jlmp5cjjYCFrNp=o_*x?Re1GFW(B&#IYM7*4cls6qRB}OtJSs7BuoR7qX zWG5nDQTE8Wx{fbqrCW%7+_9zNEBdDT8M?{we~7$x(qt6f5pOP$z;g+lRq8W&{+ zr4&rij@fUSi3XYxRZ>CGz>>wiMrAER)YSPi!m&qFAXf2Y z#L@fgB{ZNS_Vk0L5d3DKxwkZsv|v_+njF+q@(wUsv9NUIsP zO}cmQj{S= zxHK=;NaVI{)<7X4;+zB^Gwp;oa0OObCrC7@xt6IC!?qWeel{>PETJqTEQ)9Sfvw#Q zfXVlxTIxoaS-^M*9*Qe-;)Dq}N@KYw`!Q3*#z>cliOfMw8_O&yBai?}0YMjk zei<*WEO{u_TI#$PcGniYE1KtvaJqX6 zQxvnGosWiI&x16{C^-+!29_z|C1MbQs0dD0Rh@65xIfe2ORQ5p6_rb~Upjzrd6LgF zepl9j#^;`Hj5nz5*QCkhzPiCm0kP{;b-HgH(ov^gzE_~LG# zIK*ovUJA%W^ROi}$#NC6fXBxUxmCWvREzL2N|I+cHXVI19xI70$y$Pj=7T zQ(JgKKuPg1c&M}<@-M>~{^Rzz9Udb=IGhE?=gZjl@Gz`LRs4Wkcx|!|#&VA^2=|if z;F|($Bd&YtGIh$5gEh=Z_i10R`qi{kk7b&Wr(!B$M&PWP72iD#dFDp!kO-s_L`|Ju zPC*YxhB&<&l2BhyZ`H%~HB5wGnr*G1Q#V*u-(rGRfTczK9oJ2he&3y@z5F^}&aPa> z2(G+H*#aP2IQpL-h0d#0RH#IiJ^acP?7P;e?Ca#H6WGJty?*-R&AOBOjt1;2rD^B{ zE8XbaU9q!$S%iAV%`Zi}yXz~R4-Iot4ZL1E*Q<9cyKp6owE?G2o7P2@l+@_|*U$L( zqyCpa3OfcXm8{;jY1M(DHXARk4Q^03;{=!IUle_PZJ5c_e!ol%<#K(O{`VhsciGJW z`n#@Qd7eA>RJG4u-YPSBgzT6vCs|y3QC4t0!NPxXcclbOtiO>*W$DZ%yqq!8uZkuS6)&m(CS z?w0g0y3SrovZTLdSP6Fg2hbUV9BvA>V!K}_*7FTX3#Bb%=E?XJLy(~SDhex7iRr>O zYT!kA_ghsC`>a@2qw&s)$nfhjOiy92ygi}^xrZ|=e-4nm0!5C{5xtFnkQACsLts%! zap!|bA-$kdn|-=9Oh)y=)XF&A2xd^-41y9z;INVz=flq~D7Qf9tkuUI0~ zhBHKOd@g)$O*%s#KF8f0O~n?c&pt`Cagh!==7da=Fa&=*1Kt8j$?*smE0JX0Teus> zyBzF+>F$L{D3^)8HlKxOy-~}S@GYp<^V#_&g6@f+v^n?m2B>%m_YsY@BL#?3)(fi{ zECTchFl;63#@y9)=A8qp;|&n#3l5FzO>MhMw(zunWyclYKbarA8_!(go8%;!i3gHo zb4CWt8bQwjIS3}-lEWkz;3;C@b!}Lf$lFgwBo#V=rKx9VbbO|e|Cm9`uIA_O;~iLr z^lgfpNVA{^4Mao!^$2Jfu=3N}`wNE`mKSPqOve(KbYVz*=OUP8NMLb}3+UnRim54gu68|tKXEhIR2uR&A%mCiak ztI>?Bo-O<6luA3Elsn7{|`+OZ*}S9%zyqWl<+Ju;Fgl;FIn zslZ4P0a;^!`5khgi@N$%-tm^V2{4j7-Nnf0^30R-hVXWbL+I;s%jNCxeRCLvCxA%z zV+Xq&ohZhai|Y$2Fs}rDU25EZ`OrkWC|Qj}P4?Ie6ySEc8MXe9MAF(d3d5In!HG?l zR#tHaO{MgbV`NrC z(#rqE6U7B=iYhJY1e9jfP7@vGkPtBCh!yqb@(uCV3L&Z7y;M%)nB5l(K@QxZ0%RZ) zhH+1DJ}h9H-cXK|6lZ(p@sE3s_(vg^sZ=oD)V{l9nI620#w~L?a9?<6>2I2y;!pqg{@_|K2YHoPUY=ysU9s|JJYP%O z($CL~1Ep$gnyj4LamLN;%DugIDF*rI`9ttyJ)ZAq&oO~XcmX#wAbme4~j_(;N14db93-qi!C)^e? zpStqrQp0O9;7idb=TLH=RUSd}lT3$`GJIQ|$_->MIklXV+0f=y!?P`{Zzfl1YYZKfy5K6Og^)G(1~UV$^W> zGvQ0N?kv$Q(d9aGq6do=x_|8Pd&!hjuV`SJ0vBNTI%AJiJp5L@{Cjy4E!>Y3Ig^xh zF6+bNrgqO=OE&%Hw_@UuXhJ2i;_wkc z)-Z7W82>Vxli_@ zi9uppQ1p=O#u2r_uaF7Pu@jes;8C^@%8*2(3?Pyn0FJ=jhvDYo>wwRSF(+7uzYECa z_5w~X|8hr?yEXHq`0>QkHzKq(b9I%RAVNn1gy9gwE5Jh>0}IK~@`>opWth|@jD3nl zgfzj|z$$A*(I&bu?WDULlE8JnUNGRpXO;ojL{wgRL%EzH)BR|!&v|lt9{gUOwXU$ZOVC2oVZuU6S8r2G8mIvLKD zIN!K`U&42CqK8yE#K9emQ&0)SYvIHN(M8)w{d49I+7!q2IUiwk3;9FhP>9rWS7h`_ z5+?+xCL07yV23i{T1>x|Q?wA;&X5R#CCZ?NyfdEqp@|n{EJ=n|P@I$lT66;d)R}DNqrxlZeLF3B`mGUKQB1_hf@f-C)m)(8i?L<@PUNgCGt$X>)d8)bkfSbC$hG ztuiMIn3VWrXZzj5k;}d%prpvKr>uV}3gE=i-boEHTv1#Nx%|qKZ21VbTrAnp4t1I$ z9jt7F*_V>S6y20mH<54X4no^NUz?+%La1oqBdW&izHJfuS(Wj3XUbZWg92F<$O3x{ zykTENQKek)Yw6s`si|&6sxrOOrkr}rVu5th5nBHyD1-{H0GjzC5<1}N^GrqIMpe>9 z8ORK*kAVUdW{n%QZU!!W;sB?*{}$!?CA$FH{N(A=bsINIjG6)RqBm~{-dbQL5#-Pk z9Td5md$3-sed7&?g6-bYyA?oMLu*{`m$sr>|!w|Sak-s3`EV9wr&)a`| zbTS!uDi(e3-l~MSfR@sOWI3!|zrKvPc>+a)*nylKCg*p^QC(CMIcf$<#3OQqJ@alk z^KT9cwNKKe#lqkuIF1|>20`ZR5lSMYIJeED<>G^CU`>?VEcgvxD?2<)Yn<<;t@jUv zmGCGF0Jz9<=7o}KL)^H9gvbT4f`sv+TS)bCW+}7rIrjq-U4{8pf-+3PnTqX*Ov2bS zo0Ep4OwR6tZyi=w!_!KC_MDo!=K*kDHZHyhg#Lu-S)5yu;knxK{5xf>31?fbxQ zubNobZuy^}u}+0u>T&`WShow8!O)$>|7*kDnb|W>I&TKnfruzZ16%1>hWsFQDCRS0 zC(M|+KY9EN02$qdy?MNx}g*Nxni<0C6i&qp%twhzd=b zz<@bLFON5ro-IKPa01AYhT|Fb6F675HMl{~U7UlnUBV4OLpi>TRZH$oOg};mk_-SV z1O{bKMWX4&&8BQ{{+kEMOu#}rju3b{SLTo;76Zwa31GgB938^Y|INWa)PLSNcb44ha(Ws@ zhiFDxYg)FyK~~=26y244hyzM08Kg}1@IPjs9ncJQhI-TlYdL$WnCNoQs+!tmLi=Kh zA}a|0zH{qVsa(GSpc#oNSq?h{jX zD_~P%XvopG35HBu@}d>VI)OFcZU)q4F=@A>_jE-9a5Aiqclmo>nP~;$nEoHmyc#}o zDHL&O^JHG^`SIH!xWuCF&|J%3FZb6ArdBIBSUL$WNyqxbWh^6yzu zWE8h>!4e3OgMg^6fFqviG~;NQj$!~)&da8ZqcX^W86+|jX$i1%85veq{XmBY7irq$WbWynE9j$Wr|yS#V03VBgK05^NV{V4an(Tyc(mGyLAhN zLFCk7s8$qIIgwY6u3#?yC-VYQHmJyncCAEM(c1|CM6@W+2V zH9m|0ky+JM-K{^U;_N*@O9gGCV{pwJgvM5OuC9WThOq=+-Her4FXZfagQkjvQ}~{~ z;EnHJ-jBd_K$n>M@0cLDa?VJ}`Irb`qQ%Lnoj7vKlNOq z@Rh3ihTLDvI1B33U{pcqDh!?ob{A3qZ-D zb}*M5&usS>47YzA>IV-vwsC@{j)o^Z;C zj9x=(<@8w=pd4=^zs0>1a?5%zi8%iFy(xR(HU~poTlo4`J?Int5P;VK>4!kHxc2be!W&2Sh*b>Bl29*jlV>AFdJlFb-Cz7%Vs2JW{$-nO4vb6d%zY9iQv3rNEAERu zNeZM>Tr4FGjdfsTCc6ZfK6%0h=1oYc%k&Pcb05JSkb^H-k{&Q8YPBT7Sye*nWC94K zR*otM{c^N`WICAIyhd#HD%$)=7Z)|M#z1SCE+t{I^ny0;4jy4OOH2y$T$TaYVdQUN zp>FF569vVW0m5P#uViUH+9E29T8qK!Q- z0~A;qRhi9t;8MtBILCyEkODd9X!S~zorxI1jCaY&goKwt=|aX?rA#N}Q~e&0mz6gI z@8JcH9y8_&rk9+E$IQ5#yw9n4y}a_(+3&#2>OqijxanVO-$JK_r)2v>u5N zK|~nQ(vTTS2rxmx=}bRJg@VIKhLR>tRC)@NJpv*~8*XFY#NC}qf{>6xQ)0zzgoo(? zL(VOF-;pl{{Mgxbtc&Cfp4g=RYOZrRHgeM+h;Z%Y;9iDPvT|}lrScMvlDG&+h;>@Z zv@RG1_$P%2g-y7`5zX!kOK#C|@5s3Rgb&x_k3>8f-Vp6FK?p0sBPVVTm>#R6Tr zbU@!-8`!r6;Esi zFYdt-nNVukfo#L&^!2TE>h#hyD*vz@K9nfLK9U3$3Q0--uRkmsrcv%)=`$_sWho~iG(Bn6#=ib$`M>Rj9j+)QA*e`%p&$WJOUD0 zIg8qMg^3%)h%55D;7r8Ovik@mY+$A$N+-(U*d(`0`K;fq%OYHHTp$&*sa-XE9U~R&15J7`v-ihymVJ7|< zgPb0;HPixT?Icf!rXXdSgG)Ib1LpGkKbnwot*y^_b8MqC_n8$G2bct#OhNKw8GGWO zx85Wtv^XkWn99zbVpF0t%el483JoLZBPWE?gb1rQrYDm46A;YPm3cGlyEGsNGrs1S z<k0=4kcS>onW3&fB@*bmV5>{?j?XthTpL%P`i-~_d$gq zuoW`lN+3)qJE%=;dcvi!(%(mlvs%E1Fc=t^=$v>Ba#&O-UNwdLKMhkk_6so2N8=Qm z!T?46VrKEm6#iQ#H~#0HI6XJG=IiZ_mJPX2jR9GVFs`Gur*R+>k}8Nrq|}GgV!>k6PO?+Wgcnps|Y$W?*&$p6J{WEaDlLR*$jdZyz+Nspvm#sQ1IS_H<_g#!Pf%* zh_VMuLV;RGRF-T3?g0Na9?`}*ZdvFTxd61H-}EbedzezI%h#{BXpDM}MopX?i+wnT z8fI-V!k#?a4^R5b;GnsAJwXjv$3QL#4az-&Qz25rdWwn|z2R^`Xr!vE>$gsWUdfpGtg!=h+o5vB`w=r!?*z& zU~CjoP!=Rv0PuVqyPF$8887+xF(P~F6k>z&Ut}W2BBzH*@P_BTgadWa40VD}$I`5( z^0aPoPAutSb&Ws>ttsQ_^T-j!ej9h0FQb_=GQSI;%Bwb;Wg;fhfrs{J^{s zSA%V(fx9iI|B!8l5QzmSQf_QwiXl7~XOFKJN)Y&~vui8D0g`m!zdRvCQ(lB^B;SgC zBTNc?aHV_jfeycKEZd$(a0ao9+d@iq0SpdTpDS< z;!`*<|D(M#af2W<6e%Bs{#UgE-j9Y|Nr z1L9NQAHl#@^eUg<8SJ-*iWDRjNzfO;g^V{+cu(cq3o0Z@QoLLxut0osX97SzCjqd+ zRfB#6?Goe(>EbkW(63`HAWQmjgs3PsS2*Xw^nCMO#ra;nw5;TKwUUu%&n=m&J#d&` z;fdJLlHNy>zf6AfJ+HUyhwFYe&^0O zp3Ad8h>5fwd{r^x<_9Yr9(YoL^okp#p8HFVk6_-FA z?=UJy>HmFv{MV{!3aErQ``vH^BF~k%Pa7LezU69qGQ$(e#R;Z8?S-XfW#Z*R5S`6% ziO5V~qO<`y;WWcl1~X^cIXdPt!kZtl@CvSJyEX!`=IU6JLCcwSG4F3ODH)62*7Cp{xz}ELh3i79rrxo67+P^S5l7si~>i z(%LGsOn%QBU8cL=G9N!-LPJy27^}NzhQ+mCBNJy6psW3V-^Pn)46%|YAw=bL)cBj;C(UD`vc1sr<9^e#V2H1QO--fc<$@F+@@7RW`MYl6 z=j&*miP81vO)1y5aweSo7OK*~z#zJ0t?WYDLE_-6@%H;G7@_v^_I8KI^MG1;4DApu z6;a;keJ8PMo!8%aOSN}6Lhj-27Y0jb3j*sDmn)Y*AY!t$b`$YJS}N!vMcX5-T2jTV zhG?}I3ZbLE1N$XT#$9;FxFP9be0>VNlEkcTpOIT@Uy;T>Ti%I=Z%9apv;Xr}(I-Nm z!)44}wrqqbu}RF|Xqz6ybYtkS!%13-9#<{jo`1A#Ja#-_|IqG3B6}nDe|z!b0wP;( zdi}x6kgs_a5MDHHR?rA+X=$-tzPtd~KC5oW8`lA(!0@QUhrb}4$*6(Sut5)nqjmo; z5)K|5DS`-C6eUXx-ElWst-O^jMFFG4!NguWC#U?GS?xB(4Kti%5{Yjo=hXrFY#khO z9J4wcgw1D!C;L!$%h>(<_sfxgl!~sDK@vjE3=Ivp{`-gAH5)carK~Y2O^ysP`B^N* zX%gk4o_z;a!Y#u4ZKsTk3~@)6aWQcywjZDKL+;4S<6^^qf;YYn%^_xx>({SudHQrQ zAI{249UO=_?G)@4A9OS^@!ppjlf+1@V(HPixyAlr<~63Ho*(#h-Qk$NzI#i{=h%`IG+#jyNF0oz| zgn`tr-sK0_LJ3m-#Z+oyBG~R&R#qk(*?;ls)uWl4m>V2jxc%Hp$t;O!w_X!EGPj|* z`5x_~d#5Wm+%|2%xu+hwHzp$^V&5s!LS|?6FVjRnZbv*aeRh6OT0_i%`%O*rd8eh% zI%|3gbogx9h%(%em^euu(3EvUv|Z_%$aChkdGlj2ye}=iK)KK!Sx}%{?*H6d`T|3T z4Qrng5fLE-mc%Wjph?&}4rFej4w-gjRMd7N)YZ~bb2qoK+OEHqja`*U zrQl}j;bEotyPGX?0ZuL3Bke7Sz~buaD>^c(BP=@~G-JjLc{hEvti!@pu>8Ihr-q@< z9s_1pZR#!JLxisOj*jZk&|F%*X`RhK#__~&C!mdNKGQhqL1QCwTUTatR5oD1$_+p6 zNkEarHfy_DQNhUjAgWbU#f^PE9Q-DKSH_DQJ-xtD?lN^6P98 z13yGv$KvDj4e$MH_161`cQO7_8#HSBn1xe^Z9QJ_YFDfg` zne6vSL#Tc>=KaP-NmJyf1Jc*~=p#90Eu9ur`)%!>JnHNF4GlUGN;`ISTUL*+ST7;r zIvO9p8UY0kXleuR2ljrg@h(9QA8QyGSO&MmDPk6nC=B>Wu;7m?3MGrR3l(k!5?ZwweNw(pG8{hi+)UG3nAZqCoN8j zXvw)wNLlahHENE;MPFm`*+8-}U^e~bLwXlqXB9a~GBIVA;9pR_oNNF(mC>W*)2D-# zvH5(sc#^3`_;)?x%AFM0F+R~#EBK7`x}C#B=q5F$QBC_mD3AImXTSElJ6;!zCn?Ln zyWZb2wnWv0ITc}AE&1c)4e0?^lhSu2Z1nG}4EK2uHwV4j*@r)AczJo9gdA0xw5zyy zGa$7SWy9zQrP=^}m?S9@A#gP2%$faz)Ko4g_pLlVr)RMbDNp*EcHSto)YDRB0Me>_ z+p6`n2KYTWP%{O~fFz|+(+m-7^Ut|$nQg{g7OrpMcyCqFk&}@?kwcXr2$$|4cn5<^ zU6-y~Lj=ZAF3Y9AMo9%?PNMspzfez$MKDoP#XHfap#=8Gg9?e`p+SR6;)?$ zOu~>NlTO;>(5$Y2W5>qJh!qTS8lp5O4(B87@SF^Ul^HdG&JStFlpSWF8#HPHomO+* z^E%Ruq5iOUa0qgE`KG?UzG9VHUcN-ExF}%Ebc0q9W~w|cPyFmgQa}RFx2JHZPWh@} zFT*_q%al9DZB^Mgy2}Pq7vH?8baWiTXUk^fLgYD}IB_C>GBh$0`!94LqqkJK_Y-j& zEbYAsF72;LEZ{iIT6HP=c?ksrp=7pBpI?8LHN1M`Mn3$OT%NRX@ajmVb(u!QPP%boNp?ksXdRu$@3w6p_b$ybMm|a;L8*$NWknsgNeg)Dh zp$1QHI$fEDOtmkyxS1o}%R-drI6m&;prKUr1m+ zpkl3{GvqntHa+Ya9b_3;cI{ejzYuo1GIoH@CL)M?OOeHs!r`7jPp$H4JnrnC^VZK1 zMxid8Loec-yz!HH_0lg(b~_OA}7q zp-@^~_fvqV5Ltqa^LRA`8j?JrV5n}wtat9*+1ErVrLGU!`?c%WkBL8VVqer=!`(DM zq?0xkOAN7F(BZXE|3Rd$`G5br(JlhibmG(ExHl0nMy95Q+K-=4CCIF}tRtJk?KH{nN4XP9oCJZo z1qN_rg;X^{RuUVBEb|(C&Dm3vIK{XFGMHzTHQfu=t(#zDV<>9afzIG9k(if(Ae6SrL&!Kb^sF_Cm|%no{;bePC@t}IeKYP$6)igm2ATP{w3R!c3#=H2dv_#Rn2n~ao4Z&+u8VIGBufhG`U%(iF z|4sLgbx86@6B6#YI4oVtk$dB`MS=oKGO;H0q6*p;&Jl^34+ADYJV9WJl8;tf>&sZN z_Lz``Q;}DhDB1J?W631HSJD5b&IJ`X|6y(Wzu@8jFZ&Ie`ZFy^n}4s?r*VqBr%`6T P_@$VyG*6tj;>-U4l@5I| diff --git a/test/integration/render/tests/debug/collision/expected.png b/test/integration/render/tests/debug/collision/expected.png index 6dc313d95318cbad8a10e6cbf0f2573443962007..9ab300beb98b4781ef96093897a7bc4bad5c9870 100644 GIT binary patch literal 68446 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 z%0A+j>U?Tp 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