From d975ea1e043a99039ffedf9771159ba1edfe63b4 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 9 Nov 2023 12:23:05 -0800 Subject: [PATCH] [Feat] support GeoArrow format (#2385) --- examples/webpack.config.local.js | 6 + jest.setup.js | 1 + package.json | 16 +- src/constants/src/default-settings.ts | 21 +- src/deckgl-layers/babel.config.js | 1 + .../deckgl-extensions/filter-arrow-layer.ts | 57 ++ .../deckgl-extensions/filter-shader-module.ts | 39 ++ src/deckgl-layers/src/index.ts | 1 + src/layers/package.json | 11 +- src/layers/src/geojson-layer/geojson-layer.ts | 160 ++++- src/layers/src/geojson-layer/geojson-utils.ts | 45 +- src/layers/src/layer-utils.ts | 96 ++- src/layers/src/trip-layer/trip-utils.ts | 1 - src/processors/package.json | 9 +- src/processors/src/data-processor.ts | 52 +- src/processors/src/file-handler.ts | 63 +- src/reducers/package.json | 2 +- src/reducers/src/interaction-utils.ts | 1 + src/reducers/src/layer-utils.ts | 9 +- src/reducers/src/vis-state-selectors.ts | 4 +- src/schemas/package.json | 2 +- src/table/src/kepler-table.ts | 11 +- src/types/actions.d.ts | 2 + src/types/types.d.ts | 8 +- src/utils/package.json | 1 + src/utils/src/arrow-data-container.ts | 255 +++++++ src/utils/src/data-container-interface.ts | 15 + src/utils/src/data-container-utils.ts | 6 +- src/utils/src/data-utils.ts | 1 + src/utils/src/dataset-utils.ts | 15 +- src/utils/src/index.ts | 7 +- .../layer-tests/geojson-layer-specs.js | 4 + webpack/umd.js | 6 + yarn.lock | 643 ++++++++++-------- 34 files changed, 1185 insertions(+), 386 deletions(-) create mode 100644 src/deckgl-layers/src/deckgl-extensions/filter-arrow-layer.ts create mode 100644 src/deckgl-layers/src/deckgl-extensions/filter-shader-module.ts create mode 100644 src/utils/src/arrow-data-container.ts diff --git a/examples/webpack.config.local.js b/examples/webpack.config.local.js index 5920de2a7a..ba6b4912da 100644 --- a/examples/webpack.config.local.js +++ b/examples/webpack.config.local.js @@ -146,6 +146,12 @@ function makeLocalDevConfig(env, EXAMPLE_DIR = LIB_DIR, externals = {}) { use: ['source-map-loader'], enforce: 'pre', exclude: [/node_modules\/react-palm/, /node_modules\/react-data-grid/] + }, + // for compiling apache-arrow ESM module + { + test: /\.mjs$/, + include: /node_modules\/apache-arrow/, + type: 'javascript/auto' } ] }, diff --git a/jest.setup.js b/jest.setup.js index a61e30567d..c3ddadd8af 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -20,6 +20,7 @@ import '@testing-library/jest-dom'; import * as Utils from '@kepler.gl/utils'; +require('@loaders.gl/polyfills'); jest.mock('mapbox-gl/dist/mapbox-gl', () => ({ Map: () => ({}) diff --git a/package.json b/package.json index 7376b84ddb..013b39e268 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "@hubble.gl/core": "1.2.0-alpha.6", "@hubble.gl/react": "1.2.0-alpha.6", "@kepler.gl/components": "3.0.0-alpha.1", - "@loaders.gl/polyfills": "^4.0.0", + "@loaders.gl/polyfills": "^4.0.3", "@types/mapbox__geo-viewport": "^0.4.1", "@typescript-eslint/parser": "^5.27.0", "eslint-config-developit": "^1.2.0", @@ -140,7 +140,7 @@ "@babel/traverse": "^7.12.1", "@cfaester/enzyme-adapter-react-18": "^0.7.0", "@deck.gl/test-utils": "^8.9.12", - "@loaders.gl/polyfills": "^4.0.0", + "@loaders.gl/polyfills": "^4.0.3", "@luma.gl/test-utils": "^8.5.19", "@nebula.gl/layers": "1.0.2-alpha.1", "@probe.gl/env": "^3.5.0", @@ -214,12 +214,12 @@ "webpack-stats-plugin": "^0.2.1" }, "resolutions": { - "@loaders.gl/core": "^4.0.0", - "@loaders.gl/csv": "^4.0.0", - "@loaders.gl/gltf": "^4.0.0", - "@loaders.gl/json": "^4.0.0", - "@loaders.gl/loader-utils": "^4.0.0", - "@loaders.gl/polyfills": "^4.0.0", + "@loaders.gl/core": "^4.0.3", + "@loaders.gl/csv": "^4.0.3", + "@loaders.gl/gltf": "^4.0.3", + "@loaders.gl/json": "^4.0.3", + "@loaders.gl/loader-utils": "^4.0.3", + "@loaders.gl/polyfills": "^4.0.3", "@luma.gl/constants": "8.5.19", "@luma.gl/core": "8.5.19", "@luma.gl/experimental": "8.5.19", diff --git a/src/constants/src/default-settings.ts b/src/constants/src/default-settings.ts index 7b0fa04223..3e06ca5ff1 100644 --- a/src/constants/src/default-settings.ts +++ b/src/constants/src/default-settings.ts @@ -430,7 +430,8 @@ export const ALL_FIELD_TYPES = keyMirror({ timestamp: null, point: null, array: null, - object: null + object: null, + geoarrow: null }); // Data Table @@ -509,6 +510,10 @@ export const FIELD_TYPE_DISPLAY = { label: 'geo', color: BLUE2 }, + [ALL_FIELD_TYPES.geoarrow]: { + label: 'geo', + color: BLUE2 + }, [ALL_FIELD_TYPES.integer]: { label: 'int', color: YELLOW @@ -757,6 +762,17 @@ export const FIELD_OPTS = { tooltip: [] } }, + [ALL_FIELD_TYPES.geoarrow]: { + type: 'geometry', + scale: { + ...notSupportedScaleOpts, + ...notSupportAggrOpts + }, + format: { + legend: d => '...', + tooltip: [] + } + }, [ALL_FIELD_TYPES.object]: { type: 'numerical', scale: {}, @@ -1122,7 +1138,8 @@ export const DATASET_FORMATS = keyMirror({ row: null, geojson: null, csv: null, - keplergl: null + keplergl: null, + arrow: null }); export const MAP_CONTROLS = keyMirror({ diff --git a/src/deckgl-layers/babel.config.js b/src/deckgl-layers/babel.config.js index 4f5da2924f..b9a60810c4 100644 --- a/src/deckgl-layers/babel.config.js +++ b/src/deckgl-layers/babel.config.js @@ -24,6 +24,7 @@ const PRESETS = ['@babel/preset-env', '@babel/preset-react', '@babel/preset-type const PLUGINS = [ ['@babel/plugin-transform-typescript', {isTSX: true, allowDeclareFields: true}], '@babel/plugin-transform-modules-commonjs', + '@babel/plugin-proposal-class-properties', // for static class properties '@babel/plugin-proposal-optional-chaining', [ '@babel/transform-runtime', diff --git a/src/deckgl-layers/src/deckgl-extensions/filter-arrow-layer.ts b/src/deckgl-layers/src/deckgl-extensions/filter-arrow-layer.ts new file mode 100644 index 0000000000..3fd593ee05 --- /dev/null +++ b/src/deckgl-layers/src/deckgl-extensions/filter-arrow-layer.ts @@ -0,0 +1,57 @@ +import {Layer, LayerExtension} from '@deck.gl/core'; +import {LayerContext} from '@deck.gl/core/lib/layer'; +import GL from '@luma.gl/constants'; + +import shaderModule from './filter-shader-module'; + +const VALUE_FILTERED = 1; + +const defaultProps = { + getFiltered: {type: 'accessor', value: VALUE_FILTERED} +}; + +export type FilterArrowExtensionProps = { + getFiltered?: () => number; +}; + +/** + * FilterArrowExtension - a deck.gl extension to filter arrow layer + * + * A simple extension to filter arrow layer based on the result of CPU filteredIndex, + * so we can avoid filtering on the raw Arrow table and recreating geometry attributes. + * Specifically, an attribute `filtered` is added to the layer to indicate whether the feature has been Filtered + * the shader module is modified to discard the feature if filtered value is 0 + * the accessor getFiltered is used to get the value of `filtered` based on the value `filteredIndex` in Arrowlayer + */ +export default class FilterArrowExtension extends LayerExtension { + static defaultProps = defaultProps; + static extensionName = 'FilterArrowExtension'; + + getShaders(extension: any) { + return { + modules: [shaderModule], + defines: {} + }; + } + + initializeState(this: Layer, context: LayerContext, extension: this) { + const attributeManager = this.getAttributeManager(); + if (attributeManager) { + attributeManager.add({ + filtered: { + size: 1, + type: GL.FLOAT, + accessor: 'getFiltered', + shaderAttributes: { + filtered: { + divisor: 0 + }, + instanceFiltered: { + divisor: 1 + } + } + } + }); + } + } +} diff --git a/src/deckgl-layers/src/deckgl-extensions/filter-shader-module.ts b/src/deckgl-layers/src/deckgl-extensions/filter-shader-module.ts new file mode 100644 index 0000000000..2270e180fc --- /dev/null +++ b/src/deckgl-layers/src/deckgl-extensions/filter-shader-module.ts @@ -0,0 +1,39 @@ +import {project} from '@deck.gl/core'; + +const vs = ` + #ifdef NON_INSTANCED_MODEL + #define FILTER_ARROW_ATTRIB filtered + #else + #define FILTER_ARROW_ATTRIB instanceFiltered + #endif + attribute float FILTER_ARROW_ATTRIB; +`; + +const fs = ``; + +const inject = { + 'vs:#decl': ` + varying float is_filtered; + `, + 'vs:#main-end': ` + is_filtered = FILTER_ARROW_ATTRIB; + `, + 'fs:#decl': ` + varying float is_filtered; + `, + 'fs:DECKGL_FILTER_COLOR': ` + // abandon the fragments if it is not filtered + if (is_filtered == 0.) { + discard; + } + ` +}; + +export default { + name: 'filter-arrow', + dependencies: [project], + vs: vs, + fs: fs, + inject: inject, + getUniforms: () => {} +}; diff --git a/src/deckgl-layers/src/index.ts b/src/deckgl-layers/src/index.ts index 459c283ede..6cdd15fc48 100644 --- a/src/deckgl-layers/src/index.ts +++ b/src/deckgl-layers/src/index.ts @@ -9,6 +9,7 @@ export {default as EnhancedGridLayer} from './grid-layer/enhanced-cpu-grid-layer export {default as EnhancedHexagonLayer} from './hexagon-layer/enhanced-hexagon-layer'; export {default as EnhancedLineLayer} from './line-layer/line-layer'; export {default as SvgIconLayer} from './svg-icon-layer/svg-icon-layer'; +export {default as FilterArrowExtension} from './deckgl-extensions/filter-arrow-layer'; export * from './layer-utils/shader-utils'; diff --git a/src/layers/package.json b/src/layers/package.json index 9f544df7e8..62e97cafb4 100644 --- a/src/layers/package.json +++ b/src/layers/package.json @@ -42,14 +42,15 @@ "@kepler.gl/table": "3.0.0-alpha.1", "@kepler.gl/types": "3.0.0-alpha.1", "@kepler.gl/utils": "3.0.0-alpha.1", - "@loaders.gl/core": "^4.0.0", - "@loaders.gl/gis": "^4.0.0", - "@loaders.gl/gltf": "^4.0.0", - "@loaders.gl/wkt": "^4.0.0", + "@loaders.gl/arrow": "^4.0.3", + "@loaders.gl/core": "^4.0.3", + "@loaders.gl/gis": "^4.0.3", + "@loaders.gl/gltf": "^4.0.3", + "@loaders.gl/wkt": "^4.0.3", "@luma.gl/constants": "^8.5.19", "@mapbox/geojson-normalize": "0.0.1", - "@nebula.gl/layers": "1.0.2-alpha.1", "@nebula.gl/edit-modes": "1.0.2-alpha.1", + "@nebula.gl/layers": "1.0.2-alpha.1", "@turf/bbox": "^6.0.1", "@turf/helpers": "^6.1.4", "@types/geojson": "^7946.0.7", diff --git a/src/layers/src/geojson-layer/geojson-layer.ts b/src/layers/src/geojson-layer/geojson-layer.ts index 6a03a5c1db..f307258b0a 100644 --- a/src/layers/src/geojson-layer/geojson-layer.ts +++ b/src/layers/src/geojson-layer/geojson-layer.ts @@ -18,9 +18,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +import * as arrow from 'apache-arrow'; +import {BinaryFeatures} from '@loaders.gl/schema'; +import {Feature} from 'geojson'; import uniq from 'lodash.uniq'; import {DATA_TYPES} from 'type-analyzer'; - import Layer, { colorMaker, LayerBaseConfig, @@ -33,12 +35,12 @@ import Layer, { LayerStrokeColorConfig } from '../base-layer'; import {GeoJsonLayer as DeckGLGeoJsonLayer} from '@deck.gl/layers'; +import {getGeojsonLayerMeta, GeojsonDataMaps, DeckGlGeoTypes} from './geojson-utils'; import { - getGeojsonDataMaps, - getGeojsonBounds, - getGeojsonFeatureTypes, - GeojsonDataMaps -} from './geojson-utils'; + getGeojsonLayerMetaFromArrow, + isLayerHoveredFromArrow, + getHoveredObjectFromArrow +} from '../layer-utils'; import GeojsonLayerIcon from './geojson-layer-icon'; import { GEOJSON_FIELDS, @@ -54,10 +56,12 @@ import { VisConfigRange, VisConfigBoolean, Merge, - RGBColor + RGBColor, + Field } from '@kepler.gl/types'; import {KeplerTable} from '@kepler.gl/table'; -import {DataContainerInterface} from '@kepler.gl/utils'; +import {DataContainerInterface, ArrowDataContainer} from '@kepler.gl/utils'; +import {FilterArrowExtension} from '@kepler.gl/deckgl-layers'; const SUPPORTED_ANALYZER_TYPES = { [DATA_TYPES.GEOMETRY]: true, @@ -165,15 +169,33 @@ export type GeoJsonLayerConfig = Merge< GeoJsonLayerVisualChannelConfig; export type GeoJsonLayerMeta = { - featureTypes?: {polygon: boolean; point: boolean; line: boolean}; + featureTypes?: DeckGlGeoTypes; fixedRadius?: boolean; }; export const geoJsonRequiredColumns: ['geojson'] = ['geojson']; + +type ObjectInfo = { + index: number; + object?: Feature | undefined; + picked: boolean; + layer: Layer; + radius?: number; + id?: string; +}; + export const featureAccessor = ({geojson}: GeoJsonLayerColumnsConfig) => ( dc: DataContainerInterface ) => d => dc.valueAt(d.index, geojson.fieldIdx); +const geoColumnAccessor = ({geojson}: GeoJsonLayerColumnsConfig) => ( + dc: DataContainerInterface +): arrow.Vector | null => dc.getColumn?.(geojson.fieldIdx) as arrow.Vector; + +const geoFieldAccessor = ({geojson}: GeoJsonLayerColumnsConfig) => ( + dc: DataContainerInterface +): Field | null => (dc.getField ? dc.getField(geojson.fieldIdx) : null); + // access feature properties from geojson sub layer export const defaultElevation = 500; export const defaultLineWidth = 1; @@ -183,12 +205,15 @@ export default class GeoJsonLayer extends Layer { declare config: GeoJsonLayerConfig; declare visConfigSettings: GeoJsonVisConfigSettings; declare meta: GeoJsonLayerMeta; - dataToFeature: GeojsonDataMaps; + + dataToFeature: GeojsonDataMaps | BinaryFeatures[] = []; + dataContainer: DataContainerInterface | null = null; + filteredIndex: Uint8ClampedArray | null = null; + filteredIndexTrigger: number[] = []; constructor(props) { super(props); - this.dataToFeature = []; this.registerVisConfig(geojsonVisConfigs); this.getPositionAccessor = (dataContainer: DataContainerInterface) => featureAccessor(this.config.columns)(dataContainer); @@ -279,7 +304,11 @@ export default class GeoJsonLayer extends Layer { static findDefaultLayerProps({label, fields = []}: KeplerTable) { const geojsonColumns = fields - .filter(f => f.type === 'geojson' && SUPPORTED_ANALYZER_TYPES[f.analyzerType]) + .filter( + f => + (f.type === 'geojson' || f.type === 'geoarrow') && + SUPPORTED_ANALYZER_TYPES[f.analyzerType] + ) .map(f => f.name); const defaultColumns = { @@ -323,7 +352,8 @@ export default class GeoJsonLayer extends Layer { getHoverData(object, dataContainer) { // index of dataContainer is saved to feature.properties - const index = object?.properties?.index; + // for arrow format, `object` is the index of the row returned from deck + const index = dataContainer instanceof ArrowDataContainer ? object : object?.properties?.index; if (index >= 0) { return dataContainer.row(index); } @@ -331,7 +361,24 @@ export default class GeoJsonLayer extends Layer { } calculateDataAttribute({dataContainer, filteredIndex}, getPosition) { - return filteredIndex.map(i => this.dataToFeature[i]).filter(d => d); + // filter geojson/arrow table by values and make a partial copy of the raw table are expensive + // so we will use filteredIndex to create an attribute e.g. filteredIndex [0|1] for GPU filtering + // in deck.gl layer, see: FilterArrowExtension in @kepler.gl/deckgl-layers + if (!this.filteredIndex) { + this.filteredIndex = new Uint8ClampedArray(dataContainer.numRows()); + } + this.filteredIndex.fill(0); + for (let i = 0; i < filteredIndex.length; ++i) { + this.filteredIndex[filteredIndex[i]] = 1; + } + + this.filteredIndexTrigger = filteredIndex; + + // for arrow, always return full dataToFeature instead of a filtered one, so there is no need to update attributes in GPU + // for geojson, this should work as well and more efficient. But we need to update some test cases e.g. #GeojsonLayer -> formatLayerData + return dataContainer instanceof ArrowDataContainer + ? this.dataToFeature + : filteredIndex.map(i => this.dataToFeature[i]).filter(d => d); } formatLayerData(datasets, oldLayerData) { @@ -349,31 +396,44 @@ export default class GeoJsonLayer extends Layer { const dataAccessor = dc => d => ({index: d.properties.index}); const accessors = this.getAttributeAccessors({dataAccessor, dataContainer}); + const isFilteredAccessor = d => { + return this.filteredIndex ? this.filteredIndex[d.properties.index] : 1; + }; + return { data, getFilterValue: gpuFilter.filterValueAccessor(dataContainer)( indexAccessor, customFilterValueAccessor ), + getFiltered: isFilteredAccessor, ...accessors }; } updateLayerMeta(dataContainer) { - const getFeature = this.getPositionAccessor(dataContainer); - this.dataToFeature = getGeojsonDataMaps(dataContainer, getFeature); - - // get bounds from features - const bounds = getGeojsonBounds(this.dataToFeature); - // if any of the feature has properties.radius set to be true - const fixedRadius = Boolean( - this.dataToFeature.find(d => d && d.properties && d.properties.radius) - ); + // check datasource is arrow format if dataContainer is arrow data container + this.dataContainer = dataContainer; - // keep a record of what type of geometry the collection has - const featureTypes = getGeojsonFeatureTypes(this.dataToFeature); + const getFeature = this.getPositionAccessor(dataContainer); + const getGeoColumn = geoColumnAccessor(this.config.columns); + const getGeoField = geoFieldAccessor(this.config.columns); + + if (this.dataToFeature.length === 0) { + const updateLayerMetaFunc = + dataContainer instanceof ArrowDataContainer + ? getGeojsonLayerMetaFromArrow + : getGeojsonLayerMeta; + const {dataToFeature, bounds, fixedRadius, featureTypes} = updateLayerMetaFunc({ + dataContainer, + getFeature, + getGeoColumn, + getGeoField + }); - this.updateMeta({bounds, fixedRadius, featureTypes}); + this.dataToFeature = dataToFeature; + this.updateMeta({bounds, fixedRadius, featureTypes}); + } } setInitialLayerConfig({dataContainer}) { @@ -399,8 +459,26 @@ export default class GeoJsonLayer extends Layer { return this; } + isLayerHovered(objectInfo: ObjectInfo): boolean { + return this.dataContainer instanceof ArrowDataContainer + ? isLayerHoveredFromArrow(objectInfo, this.id) + : super.isLayerHovered(objectInfo); + } + + hasHoveredObject(objectInfo: ObjectInfo): Feature | null { + return this.dataContainer instanceof ArrowDataContainer + ? getHoveredObjectFromArrow( + objectInfo, + this.dataContainer, + this.id, + geoColumnAccessor(this.config.columns), + geoFieldAccessor(this.config.columns) + ) + : super.hasHoveredObject(objectInfo); + } + renderLayer(opts) { - const {data, gpuFilter, objectHovered, mapState, interactionConfig} = opts; + const {data: dataProps, gpuFilter, objectHovered, mapState, interactionConfig} = opts; const {fixedRadius, featureTypes} = this.meta; const radiusScale = this.getRadiusScaleByZoom(mapState, fixedRadius); @@ -418,7 +496,8 @@ export default class GeoJsonLayer extends Layer { const updateTriggers = { ...this.getVisualChannelUpdateTriggers(), - getFilterValue: gpuFilter.filterValueUpdateTriggers + getFilterValue: gpuFilter.filterValueUpdateTriggers, + getFiltered: this.filteredIndexTrigger }; const defaultLayerProps = this.getDefaultDeckLayerProps(opts); @@ -429,11 +508,17 @@ export default class GeoJsonLayer extends Layer { const pickable = interactionConfig.tooltip.enabled; const hoveredObject = this.hasHoveredObject(objectHovered); - return [ - new DeckGLGeoJsonLayer({ + const {data, ...props} = dataProps; + + // arrow table can have multiple chunks, a deck.gl layer is created for each chunk + const deckLayerData = this.dataContainer instanceof ArrowDataContainer ? data : [data]; + const deckLayers = deckLayerData.map((d, i) => { + return new DeckGLGeoJsonLayer({ ...defaultLayerProps, ...layerProps, - ...data, + ...props, + data: d, + id: deckLayerData.length > 1 ? `${this.id}-${i}` : this.id, pickable, highlightColor: HIGHLIGH_COLOR_3D, autoHighlight: visConfig.enable3d && pickable, @@ -446,6 +531,7 @@ export default class GeoJsonLayer extends Layer { capRounded: true, jointRounded: true, updateTriggers, + extensions: [...defaultLayerProps.extensions, new FilterArrowExtension()], _subLayerProps: { ...(featureTypes?.polygon ? {'polygons-stroke': opaOverwrite} : {}), ...(featureTypes?.line ? {linestrings: opaOverwrite} : {}), @@ -457,7 +543,11 @@ export default class GeoJsonLayer extends Layer { } : {}) } - }), + }); + }); + + return [ + ...deckLayers, // hover layer ...(hoveredObject && !visConfig.enable3d ? [ @@ -467,9 +557,9 @@ export default class GeoJsonLayer extends Layer { visible: defaultLayerProps.visible, wrapLongitude: false, data: [hoveredObject], - getLineWidth: data.getLineWidth, - getPointRadius: data.getPointRadius, - getElevation: data.getElevation, + getLineWidth: props.getLineWidth, + getPointRadius: props.getPointRadius, + getElevation: props.getElevation, getLineColor: this.config.highlightColor, getFillColor: this.config.highlightColor, // always draw outline diff --git a/src/layers/src/geojson-layer/geojson-utils.ts b/src/layers/src/geojson-layer/geojson-utils.ts index 7a7492052f..72e8082721 100644 --- a/src/layers/src/geojson-layer/geojson-utils.ts +++ b/src/layers/src/geojson-layer/geojson-utils.ts @@ -18,14 +18,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +import {Feature, BBox} from 'geojson'; import normalize from '@mapbox/geojson-normalize'; import bbox from '@turf/bbox'; import {parseSync} from '@loaders.gl/core'; import {WKBLoader, WKTLoader} from '@loaders.gl/wkt'; import {binaryToGeometry} from '@loaders.gl/gis'; +import {DataContainerInterface, getSampleData} from '@kepler.gl/utils'; -import {Feature, BBox} from 'geojson'; -import {getSampleData} from '@kepler.gl/utils'; +import {GeojsonLayerMetaProps} from '../layer-utils'; export type GetFeature = (d: any) => Feature; export type GeojsonDataMaps = Array; @@ -41,9 +42,6 @@ export enum FeatureTypes { MultiPolygon = 'MultiPolygon' } -type FeatureTypeMap = { - [key in FeatureTypes]: boolean; -}; /* eslint-enable */ export function parseGeoJsonRawFeature(rawFeature: unknown): Feature | null { @@ -74,6 +72,31 @@ export function parseGeoJsonRawFeature(rawFeature: unknown): Feature | null { return null; } + +export function getGeojsonLayerMeta({ + dataContainer, + getFeature +}: { + dataContainer: DataContainerInterface; + getFeature: GetFeature; +}): GeojsonLayerMetaProps { + const dataToFeature = getGeojsonDataMaps(dataContainer, getFeature); + // get bounds from features + const bounds = getGeojsonBounds(dataToFeature); + // if any of the feature has properties.radius set to be true + const fixedRadius = Boolean(dataToFeature.find(d => d && d.properties && d.properties.radius)); + + // keep a record of what type of geometry the collection has + const featureTypes = getGeojsonFeatureTypes(dataToFeature); + + return { + dataToFeature, + bounds, + fixedRadius, + featureTypes + }; +} + /** * Parse raw data to GeoJson feature * @param dataContainer @@ -195,14 +218,20 @@ export const featureToDeckGlGeoType = { MultiPolygon: 'polygon' }; +export type DeckGlGeoTypes = { + point: boolean; + line: boolean; + polygon: boolean; +}; + /** * Parse geojson from string * @param {Array} allFeatures * @returns {Object} mapping of feature type existence */ -export function getGeojsonFeatureTypes(allFeatures: GeojsonDataMaps): FeatureTypeMap { - // @ts-expect-error - const featureTypes: FeatureTypeMap = {}; +export function getGeojsonFeatureTypes(allFeatures: GeojsonDataMaps): DeckGlGeoTypes { + // @ts-expect-error some test cases only have 1 geotype + const featureTypes: DeckGlGeoTypes = {}; for (let f = 0; f < allFeatures.length; f++) { const feature = allFeatures[f]; if (feature) { diff --git a/src/layers/src/layer-utils.ts b/src/layers/src/layer-utils.ts index 55139bcb66..47648809f1 100644 --- a/src/layers/src/layer-utils.ts +++ b/src/layers/src/layer-utils.ts @@ -18,7 +18,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import {FieldPair} from '@kepler.gl/types'; +import * as arrow from 'apache-arrow'; +import {Feature, BBox} from 'geojson'; +import {Field, FieldPair} from '@kepler.gl/types'; +import {DataContainerInterface} from '@kepler.gl/utils'; +import {BinaryFeatures} from '@loaders.gl/schema'; +import {getBinaryGeometriesFromArrow, parseGeometryFromArrow} from '@loaders.gl/arrow'; + +import {DeckGlGeoTypes} from './geojson-layer/geojson-utils'; export function assignPointPairToLayerColumn(pair: FieldPair, hasAlt: boolean) { const {lat, lng, alt} = pair.pair; @@ -34,3 +41,90 @@ export function assignPointPairToLayerColumn(pair: FieldPair, hasAlt: boolean) { altitude: alt ? {...defaultAltColumn, ...alt} : defaultAltColumn }; } + +export type GeojsonLayerMetaProps = { + dataToFeature: BinaryFeatures[] | Array; + featureTypes: DeckGlGeoTypes; + bounds: BBox | null; + fixedRadius: boolean; +}; + +export function getGeojsonLayerMetaFromArrow({ + dataContainer, + getGeoColumn, + getGeoField +}: { + dataContainer: DataContainerInterface; + getGeoColumn: (dataContainer: DataContainerInterface) => unknown; + getGeoField: (dataContainer: DataContainerInterface) => Field | null; +}): GeojsonLayerMetaProps { + const geoColumn = getGeoColumn(dataContainer) as arrow.Vector; + const arrowField = getGeoField(dataContainer); + + const encoding = arrowField?.metadata?.get('ARROW:extension:name'); + // create binary data from arrow data for GeoJsonLayer + const {binaryGeometries, featureTypes, bounds} = getBinaryGeometriesFromArrow( + geoColumn, + encoding + ); + + // since there is no feature.properties.radius, we set fixedRadius to false + const fixedRadius = false; + + return { + dataToFeature: binaryGeometries, + featureTypes, + bounds, + fixedRadius + }; +} + +export function isLayerHoveredFromArrow(objectInfo, layerId: string): boolean { + // there could be multiple deck.gl layers created from multiple chunks in arrow table + // the objectInfo.layer id should be `${this.id}-${i}` + if (objectInfo?.picked) { + const deckLayerId = objectInfo?.layer?.props?.id; + return deckLayerId.startsWith(layerId); + } + return false; +} + +export function getHoveredObjectFromArrow( + objectInfo, + dataContainer, + layerId, + columnAccessor, + fieldAccessor +): Feature | null { + // hover object returns the index of the object in the data array + // NOTE: this could be done in Deck.gl getPickingInfo(params) and binaryToGeojson() + if (isLayerHoveredFromArrow(objectInfo, layerId) && objectInfo.index >= 0 && dataContainer) { + const col = columnAccessor(dataContainer); + const rawGeometry = col?.get(objectInfo.index); + + const field = fieldAccessor(dataContainer); + const encoding = field?.metadata?.get('ARROW:extension:name'); + + const hoveredFeature = parseGeometryFromArrow({ + encoding, + data: rawGeometry + }); + + const properties = dataContainer.rowAsArray(objectInfo.index).reduce((prev, cur, i) => { + const fieldName = dataContainer?.getField?.(i).name; + if (fieldName !== field.name) { + prev[fieldName] = cur; + } + return prev; + }, {}); + + return hoveredFeature ? { + ...hoveredFeature, + properties: { + ...properties, + index: objectInfo.index + } + } : null; + } + return null; +} diff --git a/src/layers/src/trip-layer/trip-utils.ts b/src/layers/src/trip-layer/trip-utils.ts index 2174978007..36b9701459 100644 --- a/src/layers/src/trip-layer/trip-utils.ts +++ b/src/layers/src/trip-layer/trip-utils.ts @@ -95,7 +95,6 @@ export function isTripGeoJsonField(dataContainer: DataContainerInterface, field) const featureTypes = getGeojsonFeatureTypes(features); // condition 1: contain line string - // @ts-expect-error if (!featureTypes.line) { return false; } diff --git a/src/processors/package.json b/src/processors/package.json index c79a38ca67..5cb9315eb1 100644 --- a/src/processors/package.json +++ b/src/processors/package.json @@ -35,10 +35,11 @@ "@kepler.gl/schemas": "3.0.0-alpha.1", "@kepler.gl/types": "3.0.0-alpha.1", "@kepler.gl/utils": "3.0.0-alpha.1", - "@loaders.gl/core": "^4.0.0", - "@loaders.gl/csv": "^4.0.0", - "@loaders.gl/json": "^4.0.0", - "@loaders.gl/loader-utils": "^4.0.0", + "@loaders.gl/arrow": "^4.0.3", + "@loaders.gl/core": "^4.0.3", + "@loaders.gl/csv": "^4.0.3", + "@loaders.gl/json": "^4.0.3", + "@loaders.gl/loader-utils": "^4.0.3", "@mapbox/geojson-normalize": "0.0.1", "@nebula.gl/edit-modes": "1.0.2-alpha.1", "@turf/helpers": "^6.1.4", diff --git a/src/processors/src/data-processor.ts b/src/processors/src/data-processor.ts index e5d7609c33..311df6946f 100644 --- a/src/processors/src/data-processor.ts +++ b/src/processors/src/data-processor.ts @@ -18,11 +18,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +import * as arrow from 'apache-arrow'; import {csvParseRows} from 'd3-dsv'; +import {DATA_TYPES as AnalyzerDATA_TYPES} from 'type-analyzer'; import normalize from '@mapbox/geojson-normalize'; import {ALL_FIELD_TYPES, DATASET_FORMATS, GUIDES_FILE_FORMAT_DOC} from '@kepler.gl/constants'; import {ProcessorResult, Field} from '@kepler.gl/types'; import { + arrowDataTypeToAnalyzerDataType, + arrowDataTypeToFieldType, notNullorUndefined, hasOwnProperty, isPlainObject, @@ -388,21 +392,56 @@ export function processKeplerglDataset( return Array.isArray(rawData) ? results : results[0]; } -export const DATASET_HANDLERS: { - row: typeof processRowObject; - geojson: typeof processGeojson; - csv: typeof processCsvData; - keplergl: typeof processKeplerglDataset; -} = { +/** + * Parse a arrow table with geometry columns and return a dataset + * + * @param arrowTable the arrow table to parse + * @returns dataset containing `fields` and `rows` or null + */ +export function processArrowTable(arrowBatches: arrow.RecordBatch[]): ProcessorResult | null { + if (arrowBatches.length === 0) { + return null; + } + const arrowTable = new arrow.Table(arrowBatches); + const fields: Field[] = []; + + // parse fields + arrowTable.schema.fields.forEach((field: arrow.Field, index: number) => { + const isGeometryColumn = field.metadata.get('ARROW:extension:name')?.startsWith('geoarrow'); + fields.push({ + name: field.name, + id: field.name, + displayName: field.name, + format: '', + fieldIdx: index, + type: isGeometryColumn ? ALL_FIELD_TYPES.geoarrow : arrowDataTypeToFieldType(field.type), + analyzerType: isGeometryColumn + ? AnalyzerDATA_TYPES.GEOMETRY + : arrowDataTypeToAnalyzerDataType(field.type), + valueAccessor: (dc: any) => d => { + return dc.valueAt(d.index, index); + }, + metadata: field.metadata + }); + }); + + const cols = [...Array(arrowTable.numCols).keys()].map(i => arrowTable.getChildAt(i)); + // return empty rows and use raw arrow table to construct column-wise data container + return {fields, rows: [], cols, metadata: arrowTable.schema.metadata}; +} + +export const DATASET_HANDLERS = { [DATASET_FORMATS.row]: processRowObject, [DATASET_FORMATS.geojson]: processGeojson, [DATASET_FORMATS.csv]: processCsvData, + [DATASET_FORMATS.arrow]: processArrowTable, [DATASET_FORMATS.keplergl]: processKeplerglDataset }; export const Processors: { processGeojson: typeof processGeojson; processCsvData: typeof processCsvData; + processArrowTable: typeof processArrowTable; processRowObject: typeof processRowObject; processKeplerglJSON: typeof processKeplerglJSON; processKeplerglDataset: typeof processKeplerglDataset; @@ -412,6 +451,7 @@ export const Processors: { } = { processGeojson, processCsvData, + processArrowTable, processRowObject, processKeplerglJSON, processKeplerglDataset, diff --git a/src/processors/src/file-handler.ts b/src/processors/src/file-handler.ts index be7251729f..425afc1997 100644 --- a/src/processors/src/file-handler.ts +++ b/src/processors/src/file-handler.ts @@ -18,10 +18,17 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +import * as arrow from 'apache-arrow'; import {parseInBatches} from '@loaders.gl/core'; import {JSONLoader, _JSONPath} from '@loaders.gl/json'; import {CSVLoader} from '@loaders.gl/csv'; -import {processGeojson, processKeplerglJSON, processRowObject} from './data-processor'; +import {ArrowLoader} from '@loaders.gl/arrow'; +import { + processArrowTable, + processGeojson, + processKeplerglJSON, + processRowObject +} from './data-processor'; import {generateHashId, isPlainObject} from '@kepler.gl/utils'; import {DATASET_FORMATS} from '@kepler.gl/constants'; import {Loader} from '@loaders.gl/loader-utils'; @@ -40,6 +47,10 @@ const CSV_LOADER_OPTIONS = { dynamicTyping: false // not working for now }; +const ARROW_LOADER_OPTIONS = { + shape: 'arrow-table' +}; + const JSON_LOADER_OPTIONS = { shape: 'object-row-table', // instruct loaders.gl on what json paths to stream @@ -50,6 +61,33 @@ const JSON_LOADER_OPTIONS = { ] }; +export type ProcessFileDataContent = { + data: unknown; + fileName: string; + length?: number; + progress?: {rowCount?: number; rowCountInBatch?: number; percent?: number}; + /** metadata e.g. for arrow data, metadata could be the schema.fields */ + metadata?: Map; +}; + +/** + * check if table is an ArrowTable object + * @param table - object to check + * @returns {boolean} - true if table is an ArrowTable object type guarded + */ +export function isArrowTable(table: any): table is arrow.Table { + return Boolean(table instanceof arrow.Table); +} + +/** + * check if data is an ArrowData object, which is an array of RecordBatch + * @param data - object to check + * @returns {boolean} - true if data is an ArrowData object type guarded + */ +export function isArrowData(data: any): boolean { + return Array.isArray(data) && Boolean(data[0].data && data[0].schema); +} + export function isGeoJson(json: unknown): json is Feature | FeatureCollection { // json can be feature collection // or single feature @@ -86,7 +124,8 @@ export async function* makeProgressIterator( let rowCount = 0; for await (const batch of asyncIterator) { - const rowCountInBatch = (batch.data && batch.data.length) || 0; + // the length could be stored in `batch.length` for arrow batch + const rowCountInBatch = (batch.data && (batch.data.length || batch.length)) || 0; rowCount += rowCountInBatch; const percent = Number.isFinite(batch.bytesUsed) ? batch.bytesUsed / info.size : null; @@ -108,7 +147,6 @@ export async function* readBatch( ): AsyncGenerator { let result = null; const batches = []; - for await (const batch of asyncIterator) { // Last batch will have this special type and will provide all the root // properties of the parsed document. @@ -128,8 +166,9 @@ export async function* readBatch( result = batches; } } else { - for (let i = 0; i < batch.data.length; i++) { - batches.push(batch.data[i]); + const batchData = isArrowTable(batch.data) ? batch.data.batches : batch.data; + for (let i = 0; i < batchData?.length; i++) { + batches.push(batchData[i]); } } @@ -153,9 +192,10 @@ export async function readFileInBatches({ loaders: Loader[]; loadOptions: any; }): Promise { - loaders = [JSONLoader, CSVLoader, ...loaders]; + loaders = [JSONLoader, CSVLoader, ArrowLoader, ...loaders]; loadOptions = { csv: CSV_LOADER_OPTIONS, + arrow: ARROW_LOADER_OPTIONS, json: JSON_LOADER_OPTIONS, metadata: true, ...loadOptions @@ -171,15 +211,18 @@ export function processFileData({ content, fileCache }: { - content: {data: unknown; fileName: string}; + content: ProcessFileDataContent; fileCache: FileCacheItem[]; }): Promise { return new Promise((resolve, reject) => { - const {data} = content; - + let {data} = content; let format: string | undefined; let processor: Function | undefined; - if (isKeplerGlMap(data)) { + + if (isArrowData(data)) { + format = DATASET_FORMATS.arrow; + processor = processArrowTable; + } else if (isKeplerGlMap(data)) { format = DATASET_FORMATS.keplergl; processor = processKeplerglJSON; } else if (isRowObject(data)) { diff --git a/src/reducers/package.json b/src/reducers/package.json index c91d60945e..dce756dfcc 100644 --- a/src/reducers/package.json +++ b/src/reducers/package.json @@ -43,7 +43,7 @@ "@kepler.gl/tasks": "3.0.0-alpha.1", "@kepler.gl/types": "3.0.0-alpha.1", "@kepler.gl/utils": "3.0.0-alpha.1", - "@loaders.gl/loader-utils": "^4.0.0", + "@loaders.gl/loader-utils": "^4.0.3", "@types/lodash.clonedeep": "^4.5.7", "@types/lodash.flattendeep": "^4.4.7", "@types/lodash.get": "^4.4.6", diff --git a/src/reducers/src/interaction-utils.ts b/src/reducers/src/interaction-utils.ts index cfbf83e6eb..64d7a339a8 100644 --- a/src/reducers/src/interaction-utils.ts +++ b/src/reducers/src/interaction-utils.ts @@ -88,6 +88,7 @@ function autoFindTooltipFields(fields, maxDefaultTooltips) { .split(' ') .every(seg => !ptFields.includes(seg)) && type !== ALL_FIELD_TYPES.geojson && + type !== ALL_FIELD_TYPES.geoarrow && type !== 'object' ); diff --git a/src/reducers/src/layer-utils.ts b/src/reducers/src/layer-utils.ts index fe956569d7..82fd3a551d 100644 --- a/src/reducers/src/layer-utils.ts +++ b/src/reducers/src/layer-utils.ts @@ -181,7 +181,8 @@ export function getLayerHoverProp({ // deckgl layer to kepler-gl layer const layer = layers[overlay.props.idx]; - if (object && layer && layer.getHoverData && layersToRender[layer.id]) { + // NOTE: for binary format GeojsonLayer, deck will return object=null but hoverInfo.index >= 0 + if ((object || hoverInfo.index >= 0) && layer && layer.getHoverData && layersToRender[layer.id]) { // if layer is visible and have hovered data const { config: {dataId} @@ -190,7 +191,11 @@ export function getLayerHoverProp({ return null; } const {dataContainer, fields} = datasets[dataId]; - const data: DataRow | null = layer.getHoverData(object, dataContainer, fields); + const data: DataRow | null = layer.getHoverData( + object || hoverInfo.index, + dataContainer, + fields + ); if (!data) { return null; } diff --git a/src/reducers/src/vis-state-selectors.ts b/src/reducers/src/vis-state-selectors.ts index c9d7e55584..317b23d28e 100644 --- a/src/reducers/src/vis-state-selectors.ts +++ b/src/reducers/src/vis-state-selectors.ts @@ -21,8 +21,8 @@ import {createSelector} from 'reselect'; // NOTE: default formats must match file-handler-test.js -const DEFAULT_FILE_EXTENSIONS = ['csv', 'json', 'geojson']; -const DEFAULT_FILE_FORMATS = ['CSV', 'Json', 'GeoJSON']; +const DEFAULT_FILE_EXTENSIONS = ['csv', 'json', 'geojson', 'arrow']; +const DEFAULT_FILE_FORMATS = ['CSV', 'Json', 'GeoJSON', 'Arrow']; export const getFileFormatNames = createSelector( // @ts-expect-error diff --git a/src/schemas/package.json b/src/schemas/package.json index e2d52292af..13e3cca936 100644 --- a/src/schemas/package.json +++ b/src/schemas/package.json @@ -35,7 +35,7 @@ "@kepler.gl/table": "3.0.0-alpha.1", "@kepler.gl/types": "3.0.0-alpha.1", "@kepler.gl/utils": "3.0.0-alpha.1", - "@loaders.gl/loader-utils": "^4.0.0", + "@loaders.gl/loader-utils": "^4.0.3", "@types/keymirror": "^0.1.1", "@types/lodash.clonedeep": "^4.5.7", "@types/lodash.pick": "^4.4.6", diff --git a/src/table/src/kepler-table.ts b/src/table/src/kepler-table.ts index f0f2334550..acf5b16ee8 100644 --- a/src/table/src/kepler-table.ts +++ b/src/table/src/kepler-table.ts @@ -47,6 +47,7 @@ import { getSortingFunction, timeToUnixMilli, createDataContainer, + DataForm, diffFilters, filterDataByFilterTypes, FilterResult, @@ -148,8 +149,14 @@ class KeplerTable { // return this; // } - // @ts-expect-error - const dataContainer = createDataContainer(data.rows, {fields: data.fields}); + const dataContainerData = data.cols ? data.cols : data.rows; + const inputDataFormat = data.cols ? DataForm.COLS_ARRAY : DataForm.ROWS_ARRAY; + + const dataContainer = createDataContainer(dataContainerData, { + // @ts-expect-error ProtoDataset field missing property fieldIdx, valueAccessor + fields: data.fields, + inputDataFormat + }); const datasetInfo = { id: generateHashId(4), diff --git a/src/types/actions.d.ts b/src/types/actions.d.ts index 8c96a77962..cd8f4d9e72 100644 --- a/src/types/actions.d.ts +++ b/src/types/actions.d.ts @@ -42,9 +42,11 @@ export type ProtoDataset = { type?: string; format?: string; displayName?: string; + analyzerType?: string; id?: string; }[]; rows: any[][]; + cols?: any[]; }; // table-injected metadata diff --git a/src/types/types.d.ts b/src/types/types.d.ts index e65229e0a3..482724df2d 100644 --- a/src/types/types.d.ts +++ b/src/types/types.d.ts @@ -23,4 +23,10 @@ export type RowData = { [key: string]: string | null; }[]; -export type ProcessorResult = {fields: Field[]; rows: any[][]} | null; +export type ProcessorResult = { + info?: any; + fields: Field[]; + rows: any[][]; + cols?: any[]; + metadata?: any; +} | null; diff --git a/src/utils/package.json b/src/utils/package.json index 2e1088f8ae..4a2838c00d 100644 --- a/src/utils/package.json +++ b/src/utils/package.json @@ -30,6 +30,7 @@ "umd" ], "dependencies": { + "apache-arrow": "^13.0.0", "@kepler.gl/constants": "3.0.0-alpha.1", "@kepler.gl/types": "3.0.0-alpha.1", "@luma.gl/constants": "^8.5.19", diff --git a/src/utils/src/arrow-data-container.ts b/src/utils/src/arrow-data-container.ts new file mode 100644 index 0000000000..c838128c88 --- /dev/null +++ b/src/utils/src/arrow-data-container.ts @@ -0,0 +1,255 @@ +// MIT license, Copyright (c) 2023 Uber Technologies, Inc. + +import * as arrow from 'apache-arrow'; +import {console as globalConsole} from 'global/window'; +import {DATA_TYPES as AnalyzerDATA_TYPES} from 'type-analyzer'; +import {Field} from '@kepler.gl/types'; +import {ALL_FIELD_TYPES} from '@kepler.gl/constants'; + +import {DataRow, SharedRowOptions} from './data-row'; +import {DataContainerInterface, RangeOptions} from './data-container-interface'; + +type ArrowDataContainerInput = { + cols: arrow.Vector[]; + fields?: Field[]; +}; + +/** + * @param dataContainer + * @param sharedRow + */ +function* rowsIterator(dataContainer: DataContainerInterface, sharedRow: SharedRowOptions) { + const numRows = dataContainer.numRows(); + for (let rowIndex = 0; rowIndex < numRows; ++rowIndex) { + yield dataContainer.row(rowIndex, sharedRow); + } +} + +/** + * @param dataContainer + * @param columnIndex + */ +function* columnIterator(dataContainer: DataContainerInterface, columnIndex: number) { + const numRows = dataContainer.numRows(); + for (let rowIndex = 0; rowIndex < numRows; ++rowIndex) { + yield dataContainer.valueAt(rowIndex, columnIndex); + } +} + +/** + * A data container where all data is stored in raw Arrow table + */ +export class ArrowDataContainer implements DataContainerInterface { + _cols: arrow.Vector[]; + _numColumns: number; + _numRows: number; + _fields: Field[]; + // cache column data to make valueAt() faster + // _colData: any[][]; + + constructor(data: ArrowDataContainerInput) { + if (!data.cols) { + throw Error('ArrowDataContainer: no columns provided'); + } + + if (!Array.isArray(data.cols)) { + throw Error("ArrowDataContainer: columns object isn't an array"); + } + + this._cols = data.cols; + this._numColumns = data.cols.length; + this._numRows = data.cols[0].length; + this._fields = data.fields || []; + + // this._colData = data.cols.map(c => c.toArray()); + } + + numRows(): number { + return this._numRows; + } + + numColumns(): number { + return this._numColumns; + } + + valueAt(rowIndex: number, columnIndex: number): any { + // return this._colData[columnIndex][rowIndex]; + return this._cols[columnIndex].get(rowIndex); + } + + row(rowIndex: number, sharedRow?: SharedRowOptions): DataRow { + const tSharedRow = DataRow.createSharedRow(sharedRow); + if (tSharedRow) { + tSharedRow.setSource(this, rowIndex); + return tSharedRow; + } + + return new DataRow(this, rowIndex); + } + + rowAsArray(rowIndex: number): any[] { + // return this._colData.map(col => col[rowIndex]); + return this._cols.map(col => col.get(rowIndex)); + } + + rows(sharedRow: SharedRowOptions) { + const tSharedRow = DataRow.createSharedRow(sharedRow); + return rowsIterator(this, tSharedRow); + } + + column(columnIndex: number) { + return columnIterator(this, columnIndex); + } + + getColumn(columnIndex: number): arrow.Vector { + return this._cols[columnIndex]; + } + + getField(columnIndex: number): Field { + return this._fields[columnIndex]; + } + + flattenData(): any[][] { + const data: any[][] = []; + for (let i = 0; i < this._numRows; ++i) { + data.push(this.rowAsArray(i)); + } + return data; + } + + getPlainIndex(): number[] { + return [...Array(this._numRows).keys()]; + } + + map( + func: (row: DataRow, index: number) => T, + sharedRow?: SharedRowOptions, + options: RangeOptions = {} + ): T[] { + const tSharedRow = DataRow.createSharedRow(sharedRow); + + const {start = 0, end = this.numRows()} = options; + const endRow = Math.min(this.numRows(), end); + + const out: T[] = []; + for (let rowIndex = start; rowIndex < endRow; ++rowIndex) { + const row = this.row(rowIndex, tSharedRow); + out.push(func(row, rowIndex)); + } + return out; + } + + mapIndex(func: ({index}, dc: DataContainerInterface) => T, options: RangeOptions = {}): T[] { + const {start = 0, end = this.numRows()} = options; + const endRow = Math.min(this.numRows(), end); + + const out: T[] = []; + for (let rowIndex = start; rowIndex < endRow; ++rowIndex) { + out.push(func({index: rowIndex}, this)); + } + return out; + } + + find( + func: (row: DataRow, index: number) => boolean, + sharedRow?: SharedRowOptions + ): DataRow | undefined { + const tSharedRow = DataRow.createSharedRow(sharedRow); + + for (let rowIndex = 0; rowIndex < this._numRows; ++rowIndex) { + const row = this.row(rowIndex, tSharedRow); + if (func(row, rowIndex)) { + return row; + } + } + return undefined; + } + + reduce( + func: (acc: T, row: DataRow, index: number) => T, + initialValue: T, + sharedRow?: SharedRowOptions + ): T { + const tSharedRow = DataRow.createSharedRow(sharedRow); + + for (let rowIndex = 0; rowIndex < this._numRows; ++rowIndex) { + const row = this.row(rowIndex, tSharedRow); + initialValue = func(initialValue, row, rowIndex); + } + return initialValue; + } +} + +/** + * Convert arrow data type to kepler.gl field types + * + * @param arrowType the arrow data type + * @returns corresponding type in `ALL_FIELD_TYPES` + */ +export function arrowDataTypeToFieldType(arrowType: arrow.DataType): string { + // Note: this function doesn't return ALL_FIELD_TYPES.geojson or ALL_FIELD_TYPES.array, which + // should be further detected by caller + if (arrow.DataType.isDate(arrowType)) { + return ALL_FIELD_TYPES.date; + } else if (arrow.DataType.isTimestamp(arrowType) || arrow.DataType.isTime(arrowType)) { + return ALL_FIELD_TYPES.timestamp; + } else if (arrow.DataType.isFloat(arrowType)) { + return ALL_FIELD_TYPES.real; + } else if (arrow.DataType.isInt(arrowType)) { + return ALL_FIELD_TYPES.integer; + } else if (arrow.DataType.isBool(arrowType)) { + return ALL_FIELD_TYPES.boolean; + } else if (arrow.DataType.isUtf8(arrowType) || arrow.DataType.isNull(arrowType)) { + return ALL_FIELD_TYPES.string; + } else if ( + arrow.DataType.isBinary(arrowType) || + arrow.DataType.isDictionary(arrowType) || + arrow.DataType.isFixedSizeBinary(arrowType) || + arrow.DataType.isFixedSizeList(arrowType) || + arrow.DataType.isList(arrowType) || + arrow.DataType.isMap(arrowType) || + arrow.DataType.isStruct(arrowType) + ) { + return ALL_FIELD_TYPES.object; + } else { + globalConsole.warn(`Unsupported arrow type: ${arrowType}`); + return ALL_FIELD_TYPES.string; + } +} + +/** + * Convert arrow data type to analyzer type + * + * @param arrowType the arrow data type + * @returns corresponding type in `AnalyzerDATA_TYPES` + */ +export function arrowDataTypeToAnalyzerDataType( + arrowType: arrow.DataType +): typeof AnalyzerDATA_TYPES { + if (arrow.DataType.isDate(arrowType)) { + return AnalyzerDATA_TYPES.DATE; + } else if (arrow.DataType.isTimestamp(arrowType) || arrow.DataType.isTime(arrowType)) { + return AnalyzerDATA_TYPES.DATETIME; + } else if (arrow.DataType.isFloat(arrowType)) { + return AnalyzerDATA_TYPES.FLOAT; + } else if (arrow.DataType.isInt(arrowType)) { + return AnalyzerDATA_TYPES.INT; + } else if (arrow.DataType.isBool(arrowType)) { + return AnalyzerDATA_TYPES.BOOLEAN; + } else if (arrow.DataType.isUtf8(arrowType) || arrow.DataType.isNull(arrowType)) { + return AnalyzerDATA_TYPES.STRING; + } else if ( + arrow.DataType.isBinary(arrowType) || + arrow.DataType.isDictionary(arrowType) || + arrow.DataType.isFixedSizeBinary(arrowType) || + arrow.DataType.isFixedSizeList(arrowType) || + arrow.DataType.isList(arrowType) || + arrow.DataType.isMap(arrowType) || + arrow.DataType.isStruct(arrowType) + ) { + return AnalyzerDATA_TYPES.OBJECT; + } else { + globalConsole.warn(`Unsupported arrow type: ${arrowType}`); + return AnalyzerDATA_TYPES.STRING; + } +} diff --git a/src/utils/src/data-container-interface.ts b/src/utils/src/data-container-interface.ts index 76afd09ca7..cef686d1e1 100644 --- a/src/utils/src/data-container-interface.ts +++ b/src/utils/src/data-container-interface.ts @@ -1,3 +1,4 @@ +import {Field} from '@kepler.gl/types'; import {DataRow, SharedRowOptions} from './data-row'; /** @@ -60,6 +61,20 @@ export interface DataContainerInterface { */ column(columnIndex: number): Generator; + /** + * Returns the column object at the specified index. + * @param columnIndex Column index. + * @returns The column object at the specified index. + */ + getColumn?(columnIndex: number): unknown; + + /** + * Returns the field object at the specified index. + * @param columnIndex Column index. + * @returns The field object at the specified index. + */ + getField?(columnIndex: number): Field; + /** * Returns contents of the data container as a two-dimensional array. * @returns Data. diff --git a/src/utils/src/data-container-utils.ts b/src/utils/src/data-container-utils.ts index 1172554fb7..ab2d45e6ab 100644 --- a/src/utils/src/data-container-utils.ts +++ b/src/utils/src/data-container-utils.ts @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +import {ArrowDataContainer} from './arrow-data-container'; import {RowDataContainer} from './row-data-container'; import {IndexedDataContainer} from './indexed-data-container'; @@ -30,7 +31,8 @@ export type DataContainerOptions = { }; export const DataForm = { - ROWS_ARRAY: 'ROWS_ARRAY' + ROWS_ARRAY: 'ROWS_ARRAY', + COLS_ARRAY: 'COLS_ARRAY' }; const defaultOptions: DataContainerOptions = { @@ -51,6 +53,8 @@ export function createDataContainer( if (options.inputDataFormat === DataForm.ROWS_ARRAY) { return new RowDataContainer({rows: data, fields: options.fields}); + } else if (options.inputDataFormat === DataForm.COLS_ARRAY) { + return new ArrowDataContainer({cols: data, fields: options.fields}); } throw Error('Failed to create a data container: not implemented format'); diff --git a/src/utils/src/data-utils.ts b/src/utils/src/data-utils.ts index e46ec7b2fd..de9af612bb 100644 --- a/src/utils/src/data-utils.ts +++ b/src/utils/src/data-utils.ts @@ -273,6 +273,7 @@ export const FIELD_DISPLAY_FORMAT: { : Array.isArray(d) ? `[${String(d)}]` : '', + [ALL_FIELD_TYPES.geoarrow]: d => d, [ALL_FIELD_TYPES.object]: JSON.stringify, [ALL_FIELD_TYPES.array]: JSON.stringify }; diff --git a/src/utils/src/dataset-utils.ts b/src/utils/src/dataset-utils.ts index 44cc65ca94..bf4073f776 100644 --- a/src/utils/src/dataset-utils.ts +++ b/src/utils/src/dataset-utils.ts @@ -35,7 +35,8 @@ import { Field, FieldPair, TimeLabelFormat, - TooltipFields + TooltipFields, + ProtoDataset } from '@kepler.gl/types'; import {TooltipFormat} from '@kepler.gl/constants'; @@ -266,7 +267,7 @@ const IGNORE_DATA_TYPES = Object.keys(AnalyzerDATA_TYPES).filter( /** * Validate input data, adding missing field types, rename duplicate columns */ -export function validateInputData(data: Record): ProcessorResult { +export function validateInputData(data: ProtoDataset['data']): ProcessorResult { if (!isPlainObject(data)) { assert('addDataToMap Error: dataset.data cannot be null'); return null; @@ -278,13 +279,13 @@ export function validateInputData(data: Record): ProcessorResul return null; } - const {fields, rows} = data; + const {fields, rows, cols} = data; // check if all fields has name, format and type const allValid = fields.every((f, i) => { if (!isPlainObject(f)) { assert(`fields needs to be an array of object, but find ${typeof f}`); - fields[i] = {}; + fields[i] = {name: `column_${i}`}; } if (!f.name) { @@ -293,7 +294,7 @@ export function validateInputData(data: Record): ProcessorResul fields[i].name = `column_${i}`; } - if (!ALL_FIELD_TYPES[f.type]) { + if (!f.type || !ALL_FIELD_TYPES[f.type]) { assert(`unknown field type ${f.type}`); return false; } @@ -314,7 +315,7 @@ export function validateInputData(data: Record): ProcessorResul }); if (allValid) { - return {rows, fields}; + return {rows, fields, cols}; } // if any field has missing type, recalculate it for everyone @@ -469,7 +470,7 @@ export function getFieldsFromData(data: RowData, fieldOrder: string[]): Field[] const fieldMeta = metadata.find(m => m.key === field); // fieldMeta could be undefined if the field has no data and Analyzer.computeColMeta - // will dump the field. In this case, we will simply assign the field type to STRING + // will ignore the field. In this case, we will simply assign the field type to STRING // since dropping the column in the RowData could be expensive let type = fieldMeta?.type || 'STRING'; const format = fieldMeta?.format || ''; diff --git a/src/utils/src/index.ts b/src/utils/src/index.ts index 3736c23a06..98635d8093 100644 --- a/src/utils/src/index.ts +++ b/src/utils/src/index.ts @@ -106,8 +106,9 @@ export {transformRequest, isStyleUsingMapboxTiles} from './map-style-utils/mapbo // Map export * from './map-utils'; -export {createDataContainer, createIndexedDataContainer, getSampleData as getSampleContainerData} from './data-container-utils'; -export type {DataContainerInterface} from './data-container-interface'; +export {createDataContainer, createIndexedDataContainer, getSampleData as getSampleContainerData, DataForm} from './data-container-utils'; +export type { DataContainerInterface } from './data-container-interface'; +export {ArrowDataContainer, arrowDataTypeToFieldType, arrowDataTypeToAnalyzerDataType} from './arrow-data-container'; export type {FilterResult, FilterChanged, dataValueAccessor} from './filter-utils' export * from "./filter-utils"; @@ -121,4 +122,4 @@ export { export {DataRow} from './data-row'; export type {Centroid} from './h3-utils'; -export {getCentroid, idToPolygonGeo, h3IsValid, getHexFields} from './h3-utils'; \ No newline at end of file +export {getCentroid, idToPolygonGeo, h3IsValid, getHexFields} from './h3-utils'; diff --git a/test/browser/layer-tests/geojson-layer-specs.js b/test/browser/layer-tests/geojson-layer-specs.js index e6f3a19f45..c3c9e28f72 100644 --- a/test/browser/layer-tests/geojson-layer-specs.js +++ b/test/browser/layer-tests/geojson-layer-specs.js @@ -96,6 +96,7 @@ test('#GeojsonLayer -> formatLayerData', t => { 'getElevation', 'getFillColor', 'getFilterValue', + 'getFiltered', 'getLineColor', 'getLineWidth', 'getPointRadius' @@ -215,6 +216,7 @@ test('#GeojsonLayer -> formatLayerData', t => { 'getElevation', 'getFillColor', 'getFilterValue', + 'getFiltered', 'getLineColor', 'getLineWidth', 'getPointRadius' @@ -328,6 +330,7 @@ test('#GeojsonLayer -> formatLayerData', t => { 'getElevation', 'getFillColor', 'getFilterValue', + 'getFiltered', 'getLineColor', 'getLineWidth', 'getPointRadius' @@ -429,6 +432,7 @@ test('#GeojsonLayer -> formatLayerData', t => { 'getElevation', 'getFillColor', 'getFilterValue', + 'getFiltered', 'getLineColor', 'getLineWidth', 'getPointRadius' diff --git a/webpack/umd.js b/webpack/umd.js index 4fb43c9641..83ceb6e585 100644 --- a/webpack/umd.js +++ b/webpack/umd.js @@ -108,6 +108,12 @@ const LIBRARY_BUNDLE_CONFIG = env => ({ ] ] } + }, + // for compiling apache-arrow ESM module + { + test: /\.mjs$/, + include: /node_modules\/apache-arrow/, + type: 'javascript/auto' } ] }, diff --git a/yarn.lock b/yarn.lock index fe6b767079..13742617c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,14 @@ # yarn lockfile v1 +"@75lb/deep-merge@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@75lb/deep-merge/-/deep-merge-1.1.1.tgz#3b06155b90d34f5f8cc2107d796f1853ba02fd6d" + integrity sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw== + dependencies: + lodash.assignwith "^4.2.0" + typical "^7.1.1" + "@adobe/css-tools@^4.0.1": version "4.3.1" resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28" @@ -1862,6 +1870,11 @@ intl-messageformat "10.5.3" tslib "^2.4.0" +"@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@hubble.gl/core@1.2.0-alpha.6": version "1.2.0-alpha.6" resolved "https://registry.yarnpkg.com/@hubble.gl/core/-/core-1.2.0-alpha.6.tgz#24aa280218e5b6dd27275841e73edbe8b787a588" @@ -1898,18 +1911,6 @@ resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -2164,33 +2165,43 @@ "@math.gl/geospatial" "^3.5.1" long "^5.2.1" -"@loaders.gl/core@^2.1.6", "@loaders.gl/core@^3.4.13", "@loaders.gl/core@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/core/-/core-4.0.0.tgz#307c73f512833c1e0aac3a184013c6fe3232946a" - integrity sha512-7+E9fcEab0lBB16MIkZYwV7rZzApi5fnr0rAOf5EpsdKIQq5rV7xnTHLh3gL5NY1KWt0Kg9K8lVeJKRpy020+Q== +"@loaders.gl/arrow@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/arrow/-/arrow-4.0.3.tgz#e4a5478380e70d8176b1e0031687fdb17e98d227" + integrity sha512-RJQMkyTL51z5XYjRqIYBUrzIIC8ukmQj0NTeqSJAYClaSTu07PppjakYZ757hc53KPEl9b7DpLEuFE+Tobbkkg== + dependencies: + "@loaders.gl/gis" "4.0.3" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" + apache-arrow "^13.0.0" + +"@loaders.gl/core@^2.1.6", "@loaders.gl/core@^3.4.13", "@loaders.gl/core@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/core/-/core-4.0.3.tgz#a99a97623c5f3c37fef21e87aebefde828b4ec86" + integrity sha512-L2MNtzchhTyOZi8OwD8Q62VgzgCk22b9lIQ1fojR/k9/Nv8xdozMhVgV/nhiwYCdd+qVGcZzyH43B0U8jlU+QA== dependencies: "@babel/runtime" "^7.3.1" - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/worker-utils" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/worker-utils" "4.0.3" "@probe.gl/log" "^4.0.2" -"@loaders.gl/crypto@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/crypto/-/crypto-4.0.0.tgz#4689e0e09c3935568fac5d85d9e089257eb707b2" - integrity sha512-aoBU+AibJHmtap1IxROD8nH3P1OERzwpHOf3c7TZAFL18KrqSJurJWxxTSILKMgpbKLC1d8Ch2mjvPCVC1GxHA== +"@loaders.gl/crypto@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/crypto/-/crypto-4.0.3.tgz#2baef207bb0333fe3efcaba4d064d8695afa1aa3" + integrity sha512-oJmDQrtSyAiBh4V9F54SljmIasNdayB0epcaJNeal/i+PFXTn45gOPdovgFuQuuAm0rWo+S4r25KDmLBBzE3Rg== dependencies: "@babel/runtime" "^7.3.1" - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/worker-utils" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/worker-utils" "4.0.3" "@types/crypto-js" "^4.0.2" -"@loaders.gl/csv@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/csv/-/csv-4.0.0.tgz#ea7122791b205bf13b544b8a471133ec4a527211" - integrity sha512-/7X/slldXpvkgChFzTju/SgoHN3/pztK8kwVxVaA1CWuXn8qP/7J8i3ZTg5rHJgFTbWK2AERistsjETtQfF17g== +"@loaders.gl/csv@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/csv/-/csv-4.0.3.tgz#72679e7bbd7bdf27291352c07502823f3b051d96" + integrity sha512-oEYscUld0xrKlmb3ZEaNqrHIgF0kwpoEIVz5yFb/It+2kwSok0j7UdU29lT6t5NlCHTWL6Du+7NuOkSB1UGLzA== dependencies: - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/schema" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" "@loaders.gl/draco@3.4.14": version "3.4.14" @@ -2203,15 +2214,15 @@ "@loaders.gl/worker-utils" "3.4.14" draco3d "1.5.5" -"@loaders.gl/draco@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/draco/-/draco-4.0.0.tgz#5a336219e23d4f16aecff9e0e8793e993691c1a6" - integrity sha512-w8uQu9ZTD4D+yfnQwwdOaPwWYFbZuyNXxfW8nCqip4V4ByOiKhKMmvBkERQjfJg3K3GUZZt9MfrneRGSGaImPA== +"@loaders.gl/draco@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/draco/-/draco-4.0.3.tgz#a52481b1738b56cb5fb87938edfa9389c8271d9b" + integrity sha512-W6m4L5bcov2rqluZsM+wg/5kH0+mU5Vp+2DLx/CMA7LYCnrho7b1apAqPJ/fHVwQCyL392Nv+p9i8GdyX4UCEw== dependencies: "@babel/runtime" "^7.3.1" - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/schema" "4.0.0" - "@loaders.gl/worker-utils" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" + "@loaders.gl/worker-utils" "4.0.3" draco3d "1.5.5" "@loaders.gl/gis@3.4.14", "@loaders.gl/gis@^3.4.13": @@ -2225,26 +2236,26 @@ "@math.gl/polygon" "^3.5.1" pbf "^3.2.1" -"@loaders.gl/gis@4.0.0", "@loaders.gl/gis@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/gis/-/gis-4.0.0.tgz#1cef112fb9bff1a80cc84a8a6847a697c0a9b086" - integrity sha512-Hm8jHaoE7vhl36gmxkwdWl3Q4ofkxAc79Ryj9PKnhheoR96Ly95rNZc/WcFP0AK5gOOD0Id3zL20GzZ3ndptWA== +"@loaders.gl/gis@4.0.3", "@loaders.gl/gis@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/gis/-/gis-4.0.3.tgz#bdaee00825d12909eeef0fa82cfc8e60555ea96b" + integrity sha512-fBd5vxlcxZpn0g7yuW/NvhdBbcVuFfiSPmJDVOP3oyT5/c1va4h8FJaRd5RLpLep3tcrHevzjiBjfaEw9U9Z2g== dependencies: - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/schema" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" "@mapbox/vector-tile" "^1.3.1" "@math.gl/polygon" "^4.0.0" pbf "^3.2.1" -"@loaders.gl/gltf@3.4.14", "@loaders.gl/gltf@^3.4.13", "@loaders.gl/gltf@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/gltf/-/gltf-4.0.0.tgz#90e9887967e09ace5a8f63ce7b1c7065b8ff89b0" - integrity sha512-H/jSymoMfj4jN2pZW3tXoRGYlIu8JBhkZ2i73kuYSzNfSC0twyKU09G4p0T1QT6CQInKOEIC2b+hEtGHOW+iSg== +"@loaders.gl/gltf@3.4.14", "@loaders.gl/gltf@^3.4.13", "@loaders.gl/gltf@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/gltf/-/gltf-4.0.3.tgz#60a29464df34a8bee0b429ae92a3f9ce2a4d4f07" + integrity sha512-Lbve+DGkhrYMZTXCPBFbn9J30xmdoAt2TnqB3Xr6ZHytM3WOJmYeou5/t3vmUuBM1fjK0rKY1BFDvgQsX+5nNw== dependencies: - "@loaders.gl/draco" "4.0.0" - "@loaders.gl/images" "4.0.0" - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/textures" "4.0.0" + "@loaders.gl/draco" "4.0.3" + "@loaders.gl/images" "4.0.3" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/textures" "4.0.3" "@math.gl/core" "^4.0.0" "@loaders.gl/images@3.4.14", "@loaders.gl/images@^3.4.13": @@ -2254,29 +2265,29 @@ dependencies: "@loaders.gl/loader-utils" "3.4.14" -"@loaders.gl/images@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/images/-/images-4.0.0.tgz#09e64d165990bd71df7b5b0b1bf5e30c9ae2f1de" - integrity sha512-2OLIfLVnEUtC55O/CUQ9uMoBb4MF9VFkftTGgjyqZozUCI4GzU0koA4CGd3C4H8UpV6Nf1b54NF34x0WYSQdTQ== +"@loaders.gl/images@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/images/-/images-4.0.3.tgz#fd09f51c1afb25af0bf4fbe74cb4de9edd3db224" + integrity sha512-nWbp9wzO7OPt20A7hY3k0xydR9ooY4rBASiNLrzdOELQYS0YMGHsNdSQpgyZlnAUMtcQHP8CqEUHRWlO3dAi3Q== dependencies: - "@loaders.gl/loader-utils" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" -"@loaders.gl/json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/json/-/json-4.0.0.tgz#6258767fab8ff4bc1c4b2f00330a77f96785f32a" - integrity sha512-Eh92PA8qFSIw3el4c/VnDlO5p0tuNOlFvePgpNVJ3q/0YAdI7isx9Z1ty7Ff2fvrsLse7dWWk4mUo1UArzZrZA== +"@loaders.gl/json@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/json/-/json-4.0.3.tgz#ad53e4aa808d670902f12720b5cfe771484b4b85" + integrity sha512-iZUiI3KkwgXjZD1GcfyubxPhCxAtf0L+XSLDl7kIcF9Fc7ap+84JqYtmgdhzyDfK5BmvVCUh6PaouPYzCALXZA== dependencies: - "@loaders.gl/gis" "4.0.0" - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/schema" "4.0.0" + "@loaders.gl/gis" "4.0.3" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" -"@loaders.gl/loader-utils@3.4.14", "@loaders.gl/loader-utils@4.0.0", "@loaders.gl/loader-utils@^2.1.3", "@loaders.gl/loader-utils@^3.4.13", "@loaders.gl/loader-utils@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/loader-utils/-/loader-utils-4.0.0.tgz#def701a11072ccf279fda079d4a222f4e4ee3bd0" - integrity sha512-OqOJamUWXi8F0py5Lg4srUobsPtLXnT45CQ9E38nM4TEUF3EiZwv/4olBUAYSnXX94LarYsVqpgvvnn1ti/Riw== +"@loaders.gl/loader-utils@3.4.14", "@loaders.gl/loader-utils@4.0.3", "@loaders.gl/loader-utils@^2.1.3", "@loaders.gl/loader-utils@^3.4.13", "@loaders.gl/loader-utils@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/loader-utils/-/loader-utils-4.0.3.tgz#a3229e070d849bb3699a13857df5aa0e56ba73bc" + integrity sha512-orklRrTVX95C4CbPUBVwhQTe992DiRsdIh9r2vHX+geQCrPM2gkdTpm+DQvulm7uFCmP/hmqbE37mye7DnJV+g== dependencies: "@babel/runtime" "^7.3.1" - "@loaders.gl/worker-utils" "4.0.0" + "@loaders.gl/worker-utils" "4.0.3" "@probe.gl/stats" "^4.0.2" "@loaders.gl/math@3.4.14": @@ -2299,14 +2310,14 @@ "@math.gl/polygon" "^3.5.1" pbf "^3.2.1" -"@loaders.gl/polyfills@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/polyfills/-/polyfills-4.0.0.tgz#e8e17a78f45ae988299dd6788294ea974fafeeb7" - integrity sha512-j1j2TlFo/P5bc1heD42synUPajdXLBh9YPZRAWramEUPpX826Di7kUgtCxICPO36BawgSP8Xl2g3rYosUsCgEg== +"@loaders.gl/polyfills@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/polyfills/-/polyfills-4.0.3.tgz#a307909795c8af1f778c94bc540122e617cb4bb9" + integrity sha512-ldQEl7M80VNY9FewUOANASV2Q08OToVuSdO5LbuLoIO7n1VNxJmYg8AbXN5SZ5j93RUSyKVyO5WxhBQicoDuDQ== dependencies: "@babel/runtime" "^7.3.1" - "@loaders.gl/crypto" "4.0.0" - "@loaders.gl/loader-utils" "4.0.0" + "@loaders.gl/crypto" "4.0.3" + "@loaders.gl/loader-utils" "4.0.3" buffer "^6.0.3" get-pixels "^3.3.3" ndarray "^1.0.19" @@ -2322,10 +2333,10 @@ dependencies: "@types/geojson" "^7946.0.7" -"@loaders.gl/schema@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/schema/-/schema-4.0.0.tgz#59a5cc5c39bf07386bd22e87639f9a6a6669d586" - integrity sha512-jMaexN5QUSUWUFceaRODVBkUpJZi0isNhylJXpZCFnIgj9djbOj6E4KNMqfDYK25dhtMsRJxcvXlmrzaFsSkuQ== +"@loaders.gl/schema@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/schema/-/schema-4.0.3.tgz#93e0dc640c528c044b040e960d5014e746ba6fcc" + integrity sha512-WC+T0S76RbLcDq+a/aAViNSAf2Gr8rCs6tXmk3Cq/pcwLWYM8XNWlR1ZUMuyRyeZIBBur24LE4GSGlvt+xD4JA== dependencies: "@types/geojson" "^7946.0.7" @@ -2340,15 +2351,15 @@ "@loaders.gl/schema" "3.4.14" "@mapbox/martini" "^0.2.0" -"@loaders.gl/textures@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/textures/-/textures-4.0.0.tgz#3cfee9db6708c2563b8e59694b91c49c6d4c31c0" - integrity sha512-G0EYIAUTn2mGRW4t58fmUrLFJBKNURKu+KIqf1tw5Ihqnkht19hCJV8gp6VSkc3cHg+Ec6GkqLOysxILE3iD3Q== +"@loaders.gl/textures@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/textures/-/textures-4.0.3.tgz#d4e3e33d349e71797c46899d14e7470a07c26586" + integrity sha512-nwexaPrctTrwPXDMiS++jmQGUcCMg51XGSMu9kfLKhrPWiOU4yEPyAK3wjmlXHymv4FVIy8UAgGAu+8jZf3g6w== dependencies: - "@loaders.gl/images" "4.0.0" - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/schema" "4.0.0" - "@loaders.gl/worker-utils" "4.0.0" + "@loaders.gl/images" "4.0.3" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" + "@loaders.gl/worker-utils" "4.0.3" ktx-parse "^0.0.4" texture-compressor "^1.0.2" @@ -2373,13 +2384,13 @@ "@loaders.gl/loader-utils" "^2.1.3" gifshot "^0.4.5" -"@loaders.gl/wkt@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/wkt/-/wkt-4.0.0.tgz#4f1dcb116684224a324117b4c570d5f6488de666" - integrity sha512-ll/nOoeveBW2vcoDfcfhwuLY5A+kBCzQIjVyY7rwf3PpPhBdaR+pzGREQeEpjGvfB1E8KoZ7fG54bThaM3RqIg== +"@loaders.gl/wkt@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/wkt/-/wkt-4.0.3.tgz#b734a0aa99bcf5c12322f0f7e1b321b77ff3a2a4" + integrity sha512-4PsAhDKmP6sRUfeHTaClwkTi+JGlEkdU3faZaLKcF5MAuFksytZOXX4kLG2e84lFtpFH72zztivHUihEIeXuPg== dependencies: - "@loaders.gl/loader-utils" "4.0.0" - "@loaders.gl/schema" "4.0.0" + "@loaders.gl/loader-utils" "4.0.3" + "@loaders.gl/schema" "4.0.3" "@loaders.gl/wms@^3.4.13": version "3.4.14" @@ -2402,10 +2413,10 @@ dependencies: "@babel/runtime" "^7.3.1" -"@loaders.gl/worker-utils@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@loaders.gl/worker-utils/-/worker-utils-4.0.0.tgz#21fd1166ebb0870f00c7420a0d15e8fd5fbab7b7" - integrity sha512-plU2RWRV4mvAtztPRa/iqtJ389liLW0/cJCBVPAN1W8sIqzFE267qp2anG7JIjWD408A6yHvzogwdZP3yC6TrQ== +"@loaders.gl/worker-utils@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@loaders.gl/worker-utils/-/worker-utils-4.0.3.tgz#94bda0e57f686421247beb3b7c8d6eaba26b235c" + integrity sha512-P8ZvWNE3fpdb7KHYv5TxInL2AH3Z+VVnLrJjuClZrPPouvBA/pAhgPu+Y2ktvawZ35PJ1Y9EMLDin864pMXN+Q== dependencies: "@babel/runtime" "^7.3.1" @@ -2836,17 +2847,21 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" -"@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== dependencies: + "@gar/promisify" "^1.1.3" semver "^7.3.5" -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" "@popmotion/easing@^1.0.1": version "1.0.2" @@ -3546,6 +3561,16 @@ dependencies: classnames "*" +"@types/command-line-args@5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@types/command-line-args/-/command-line-args-5.2.0.tgz#adbb77980a1cc376bb208e3f4142e907410430f6" + integrity sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA== + +"@types/command-line-usage@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@types/command-line-usage/-/command-line-usage-5.0.2.tgz#ba5e3f6ae5a2009d466679cc431b50635bf1a064" + integrity sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg== + "@types/crypto-js@^4.0.2": version "4.1.3" resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.3.tgz#7f2fa22857ae2b5d3221edcba9644f67f8ea984c" @@ -3877,6 +3902,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313" integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag== +"@types/node@20.3.0": + version "20.3.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.0.tgz#719498898d5defab83c3560f45d8498f58d11938" + integrity sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ== + "@types/node@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.0.tgz#acaa89247afddc7967e9902fd11761dadea1a555" @@ -3892,6 +3922,11 @@ resolved "https://registry.yarnpkg.com/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz#e4a932069db47bb3eabeb0b305502d01586fa90d" integrity sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg== +"@types/pad-left@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@types/pad-left/-/pad-left-2.1.1.tgz#17d906fc75804e1cc722da73623f1d978f16a137" + integrity sha512-Xd22WCRBydkGSApl5Bw0PhAOHKSVjNL3E3AwzKaps96IMraPqy5BvZIsBVK6JLwdybUzjHnuWVwpDd0JjTfHXA== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -4652,11 +4687,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^2.0.1, ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -4681,11 +4711,6 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -4710,6 +4735,22 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +apache-arrow@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/apache-arrow/-/apache-arrow-13.0.0.tgz#8c8c69ca8ec53b804b4e10fe6b57483bda46dfbd" + integrity sha512-3gvCX0GDawWz6KFNC28p65U+zGh/LZ6ZNKWNu74N6CQlKzxeoWHpi4CgEQsgRSEMuyrIIXi1Ea2syja7dwcHvw== + dependencies: + "@types/command-line-args" "5.2.0" + "@types/command-line-usage" "5.0.2" + "@types/node" "20.3.0" + "@types/pad-left" "2.1.1" + command-line-args "5.2.1" + command-line-usage "7.0.1" + flatbuffers "23.5.26" + json-bignum "^0.0.3" + pad-left "^2.1.0" + tslib "^2.5.3" + append-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" @@ -4783,6 +4824,16 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-6.2.2.tgz#f567d99e9af88a6d3d2f9dfcc21db6f9ba9fd157" + integrity sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw== + array-buffer-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" @@ -5775,23 +5826,29 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^17.0.0: - version "17.1.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" lru-cache "^7.7.1" - minipass "^7.0.3" + minipass "^3.1.6" minipass-collect "^1.0.2" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" p-map "^4.0.0" - ssri "^10.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" tar "^6.1.11" - unique-filename "^3.0.0" + unique-filename "^2.0.0" cache-base@^1.0.1: version "1.0.1" @@ -5892,9 +5949,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001251, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001517: - version "1.0.30001553" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001553.tgz#e64e7dc8fd4885cd246bb476471420beb5e474b5" - integrity sha512-N0ttd6TrFfuqKNi+pMgWJTb9qrdJu4JSpgPFLe/lrD19ugC6fZgF0pUewRowDwzdDnb9V41mFcdlYgl/PyKf4A== + version "1.0.30001558" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001558.tgz#d2c6e21fdbfe83817f70feab902421a19b7983ee" + integrity sha512-/Et7DwLqpjS47JPEcz6VnxU9PwcIdVi0ciLXRWBQdj1XFye68pSQYpV0QtPTfUKWuOaEig+/Vez2l74eDc1tPQ== capture-stack-trace@^1.0.0: version "1.0.1" @@ -5911,6 +5968,13 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== +chalk-template@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-0.4.0.tgz#692c034d0ed62436b9062c1707fadcd0f753204b" + integrity sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg== + dependencies: + chalk "^4.1.2" + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -5939,7 +6003,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -6305,6 +6369,26 @@ comma-separated-tokens@^1.0.1: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +command-line-args@5.2.1, command-line-args@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@7.0.1, command-line-usage@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-7.0.1.tgz#e540afef4a4f3bc501b124ffde33956309100655" + integrity sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ== + dependencies: + array-back "^6.2.2" + chalk-template "^0.4.0" + table-layout "^3.0.0" + typical "^7.1.1" + commander@2, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.9.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -7681,11 +7765,6 @@ earcut@^2.2.4: resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -7742,11 +7821,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -8815,6 +8889,13 @@ find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -8865,6 +8946,11 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" +flatbuffers@23.5.26: + version "23.5.26" + resolved "https://registry.yarnpkg.com/flatbuffers/-/flatbuffers-23.5.26.tgz#01358e272a61239f0faf3bfbe4e014f3ace9d746" + integrity sha512-vE+SI9vrJDwi1oETtTIFldC/o9GsVKRM+s6EL0nQgxXlYV1Vc4Tk30hj4xGICftInKQKj1F3up2n8UbIVobISQ== + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" @@ -8908,14 +8994,6 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -9016,20 +9094,13 @@ fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== dependencies: minipass "^3.0.0" -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - fs-mkdirp-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" @@ -9394,17 +9465,6 @@ glob-stream@^6.1.0: to-absolute-glob "^2.0.0" unique-stream "^2.0.2" -glob@^10.2.2: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - glob@^6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" @@ -9428,6 +9488,17 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, gl once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -10023,7 +10094,7 @@ htmlparser2@^6.0.0: domutils "^2.4.4" entities "^2.0.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -10265,7 +10336,7 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= -infer-owner@^1.0.3: +infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== @@ -11164,15 +11235,6 @@ iterator.prototype@^1.1.2: reflect.getprototypeof "^1.0.4" set-function-name "^2.0.1" -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -11648,6 +11710,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= +json-bignum@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/json-bignum/-/json-bignum-0.0.3.tgz#41163b50436c773d82424dbc20ed70db7604b8d7" + integrity sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -11954,6 +12021,11 @@ lodash-es@^4.17.15: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== +lodash.assignwith@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" + integrity sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g== + lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -12120,11 +12192,6 @@ lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== - lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -12155,26 +12222,27 @@ make-event-props@^1.6.0: resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.6.1.tgz#1d587017c3f1f3b42719b775af93d5253656ccdd" integrity sha512-JhvWq/iz1BvlmnPvLJjXv+xnMPJZuychrDC68V+yCGQJn5chcA8rLGKo5EP1XwIKVrigSXKLmbeXAGkf36wdCQ== -make-fetch-happen@^11.0.3: - version "11.1.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== +make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== dependencies: agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" is-lambda "^1.0.1" lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" negotiator "^0.6.3" promise-retry "^2.0.1" socks-proxy-agent "^7.0.0" - ssri "^10.0.0" + ssri "^9.0.0" makeerror@1.0.12: version "1.0.12" @@ -12589,10 +12657,10 @@ minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" @@ -12617,12 +12685,12 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== dependencies: - minipass "^7.0.3" + minipass "^3.1.6" minipass-sized "^1.0.3" minizlib "^2.1.2" optionalDependencies: @@ -12656,16 +12724,18 @@ minipass@^3.0.0: dependencies: yallist "^4.0.0" +minipass@^3.1.1, minipass@^3.1.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + minipass@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -12726,7 +12796,7 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: dependencies: minimist "^1.2.5" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -12978,15 +13048,15 @@ node-forge@^0.10.0: integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-gyp@^9.2.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" - integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^11.0.3" + make-fetch-happen "^10.0.3" nopt "^6.0.0" npmlog "^6.0.0" rimraf "^3.0.2" @@ -13618,6 +13688,13 @@ package-json@^2.0.0: registry-url "^3.0.3" semver "^5.1.0" +pad-left@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pad-left/-/pad-left-2.1.0.tgz#16e6a3b2d44a8e138cb0838cc7cb403a4fc9e994" + integrity sha512-HJxs9K9AztdIQIAIa/OIazRAUW/L6B9hbQDxO4X07roW3eo9XqZc2ur9bn1StH9CnbbI9EgvejHQX7CBpCF1QA== + dependencies: + repeat-string "^1.5.4" + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -13869,14 +13946,6 @@ path-root@^0.1.1: dependencies: path-root-regex "^0.1.0" -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -16117,11 +16186,6 @@ signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -16447,13 +16511,6 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^10.0.0: - version "10.0.5" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== - dependencies: - minipass "^7.0.3" - ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" @@ -16461,6 +16518,13 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -16545,6 +16609,11 @@ stream-http@^3.0.0: readable-stream "^3.6.0" xtend "^4.0.2" +stream-read-all@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/stream-read-all/-/stream-read-all-3.0.1.tgz#60762ae45e61d93ba0978cda7f3913790052ad96" + integrity sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A== + stream-shift@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" @@ -16581,15 +16650,6 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -16599,6 +16659,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -16625,15 +16694,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - string.prototype.matchall@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d" @@ -16769,13 +16829,6 @@ stringify-entities@^1.0.1: is-alphanumerical "^1.0.0" is-hexadecimal "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -16804,12 +16857,12 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^6.0.1" + ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" @@ -17071,6 +17124,19 @@ tabbable@^6.0.1: resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== +table-layout@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-3.0.2.tgz#69c2be44388a5139b48c59cf21e73b488021769a" + integrity sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw== + dependencies: + "@75lb/deep-merge" "^1.1.1" + array-back "^6.2.2" + command-line-args "^5.2.1" + command-line-usage "^7.0.0" + stream-read-all "^3.0.1" + typical "^7.1.1" + wordwrapjs "^5.1.0" + table@^5.2.3: version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" @@ -17490,7 +17556,7 @@ tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tslib@^2.4.0: +tslib@^2.4.0, tslib@^2.5.3: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -17659,6 +17725,16 @@ typescript@4.5.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-7.1.1.tgz#ba177ab7ab103b78534463ffa4c0c9754523ac1f" + integrity sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA== + ua-parser-js@^0.7.18: version "0.7.33" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532" @@ -17805,12 +17881,12 @@ unique-filename@^1.1.1: dependencies: unique-slug "^2.0.0" -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== dependencies: - unique-slug "^4.0.0" + unique-slug "^3.0.0" unique-slug@^2.0.0: version "2.0.2" @@ -17819,10 +17895,10 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== dependencies: imurmurhash "^0.1.4" @@ -18703,6 +18779,11 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +wordwrapjs@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-5.1.0.tgz#4c4d20446dcc670b14fa115ef4f8fd9947af2b3a" + integrity sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg== + worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -18710,16 +18791,6 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - name wrap-ansi-cjs - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -18746,14 +18817,14 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" wrappy@1: version "1.0.2"