@deck.gl/geo-layers 8.10.0-alpha.7 → 9.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +2374 -19037
- package/dist/es5/geo-cell-layer/GeoCellLayer.js.map +1 -1
- package/dist/es5/geohash-layer/geohash-layer.js.map +1 -1
- package/dist/es5/great-circle-layer/great-circle-layer.js.map +1 -1
- package/dist/es5/h3-layers/h3-cluster-layer.js +10 -1
- package/dist/es5/h3-layers/h3-cluster-layer.js.map +1 -1
- package/dist/es5/h3-layers/h3-hexagon-layer.js.map +1 -1
- package/dist/es5/index.js +0 -8
- package/dist/es5/index.js.map +1 -1
- package/{src/mesh-layer/mesh-layer.ts → dist/es5/mesh-layer/mesh-layer.ts.disabled} +8 -7
- package/dist/es5/mvt-layer/mvt-layer.js +15 -6
- package/dist/es5/mvt-layer/mvt-layer.js.map +1 -1
- package/dist/es5/quadkey-layer/quadkey-layer.js.map +1 -1
- package/dist/es5/s2-layer/s2-layer.js.map +1 -1
- package/dist/es5/terrain-layer/terrain-layer.js.map +1 -1
- package/{src/tile-3d-layer/tile-3d-layer.ts → dist/es5/tile-3d-layer/tile-3d-layer.ts.disabled} +9 -9
- package/dist/es5/tile-layer/tile-layer.js +19 -9
- package/dist/es5/tile-layer/tile-layer.js.map +1 -1
- package/dist/es5/tileset-2d/tile-2d-traversal.js.map +1 -1
- package/dist/es5/tileset-2d/tileset-2d.js +1 -1
- package/dist/es5/tileset-2d/tileset-2d.js.map +1 -1
- package/dist/es5/tileset-2d/utils.js +2 -3
- package/dist/es5/tileset-2d/utils.js.map +1 -1
- package/dist/es5/trips-layer/trips-layer.js.map +1 -1
- package/dist/es5/wms-layer/wms-layer.js +6 -8
- package/dist/es5/wms-layer/wms-layer.js.map +1 -1
- package/dist/esm/geo-cell-layer/GeoCellLayer.js.map +1 -1
- package/dist/esm/geohash-layer/geohash-layer.js.map +1 -1
- package/dist/esm/great-circle-layer/great-circle-layer.js.map +1 -1
- package/dist/esm/h3-layers/h3-cluster-layer.js +5 -0
- package/dist/esm/h3-layers/h3-cluster-layer.js.map +1 -1
- package/dist/esm/h3-layers/h3-hexagon-layer.js.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mesh-layer/mesh-layer.ts.disabled +176 -0
- package/dist/esm/mvt-layer/mvt-layer.js +6 -1
- package/dist/esm/mvt-layer/mvt-layer.js.map +1 -1
- package/dist/esm/quadkey-layer/quadkey-layer.js.map +1 -1
- package/dist/esm/s2-layer/s2-layer.js.map +1 -1
- package/dist/esm/terrain-layer/terrain-layer.js.map +1 -1
- package/dist/esm/tile-3d-layer/tile-3d-layer.ts.disabled +436 -0
- package/dist/esm/tile-layer/tile-layer.js +10 -6
- package/dist/esm/tile-layer/tile-layer.js.map +1 -1
- package/dist/esm/tileset-2d/tile-2d-traversal.js.map +1 -1
- package/dist/esm/tileset-2d/tileset-2d.js +1 -1
- package/dist/esm/tileset-2d/tileset-2d.js.map +1 -1
- package/dist/esm/tileset-2d/utils.js +2 -2
- package/dist/esm/tileset-2d/utils.js.map +1 -1
- package/dist/esm/trips-layer/trips-layer.js.map +1 -1
- package/dist/esm/wms-layer/wms-layer.js +5 -5
- package/dist/esm/wms-layer/wms-layer.js.map +1 -1
- package/dist.min.js +29 -161
- package/package.json +14 -14
- package/src/geo-cell-layer/GeoCellLayer.ts +1 -1
- package/src/geohash-layer/geohash-layer.ts +2 -2
- package/src/great-circle-layer/great-circle-layer.ts +1 -1
- package/src/h3-layers/h3-cluster-layer.ts +6 -2
- package/src/h3-layers/h3-hexagon-layer.ts +2 -2
- package/src/index.ts +4 -2
- package/src/mesh-layer/mesh-layer.ts.disabled +176 -0
- package/src/mvt-layer/mvt-layer.ts +16 -6
- package/src/quadkey-layer/quadkey-layer.ts +3 -2
- package/src/s2-layer/s2-layer.ts +2 -2
- package/src/terrain-layer/terrain-layer.ts +2 -2
- package/src/tile-3d-layer/tile-3d-layer.ts.disabled +436 -0
- package/src/tile-layer/tile-layer.ts +20 -10
- package/src/tileset-2d/tile-2d-traversal.ts +1 -1
- package/src/tileset-2d/tileset-2d.ts +6 -7
- package/src/tileset-2d/utils.ts +4 -4
- package/src/trips-layer/trips-layer.ts +3 -3
- package/src/wms-layer/wms-layer.ts +10 -8
- package/typed/geo-cell-layer/GeoCellLayer.d.ts +1 -1
- package/typed/geo-cell-layer/GeoCellLayer.d.ts.map +1 -1
- package/typed/geohash-layer/geohash-layer.d.ts +2 -2
- package/typed/geohash-layer/geohash-layer.d.ts.map +1 -1
- package/typed/great-circle-layer/great-circle-layer.d.ts +2 -2
- package/typed/great-circle-layer/great-circle-layer.d.ts.map +1 -1
- package/typed/h3-layers/h3-cluster-layer.d.ts +7 -2
- package/typed/h3-layers/h3-cluster-layer.d.ts.map +1 -1
- package/typed/h3-layers/h3-hexagon-layer.d.ts +2 -2
- package/typed/h3-layers/h3-hexagon-layer.d.ts.map +1 -1
- package/typed/index.d.ts +0 -2
- package/typed/index.d.ts.map +1 -1
- package/typed/mvt-layer/mvt-layer.d.ts +9 -1
- package/typed/mvt-layer/mvt-layer.d.ts.map +1 -1
- package/typed/quadkey-layer/quadkey-layer.d.ts +2 -2
- package/typed/quadkey-layer/quadkey-layer.d.ts.map +1 -1
- package/typed/s2-layer/s2-layer.d.ts +2 -2
- package/typed/s2-layer/s2-layer.d.ts.map +1 -1
- package/typed/terrain-layer/terrain-layer.d.ts +2 -2
- package/typed/terrain-layer/terrain-layer.d.ts.map +1 -1
- package/typed/tile-layer/tile-layer.d.ts +7 -2
- package/typed/tile-layer/tile-layer.d.ts.map +1 -1
- package/typed/tileset-2d/tile-2d-traversal.d.ts +1 -1
- package/typed/tileset-2d/tile-2d-traversal.d.ts.map +1 -1
- package/typed/tileset-2d/tileset-2d.d.ts +4 -4
- package/typed/tileset-2d/tileset-2d.d.ts.map +1 -1
- package/typed/tileset-2d/utils.d.ts +2 -2
- package/typed/tileset-2d/utils.d.ts.map +1 -1
- package/typed/trips-layer/trips-layer.d.ts +3 -3
- package/typed/trips-layer/trips-layer.d.ts.map +1 -1
- package/typed/wms-layer/wms-layer.d.ts.map +1 -1
- package/dist/es5/mesh-layer/mesh-layer.js +0 -212
- package/dist/es5/mesh-layer/mesh-layer.js.map +0 -1
- package/dist/es5/tile-3d-layer/tile-3d-layer.js +0 -512
- package/dist/es5/tile-3d-layer/tile-3d-layer.js.map +0 -1
- package/dist/esm/mesh-layer/mesh-layer.js +0 -177
- package/dist/esm/mesh-layer/mesh-layer.js.map +0 -1
- package/dist/esm/tile-3d-layer/tile-3d-layer.js +0 -443
- package/dist/esm/tile-3d-layer/tile-3d-layer.js.map +0 -1
- package/typed/mesh-layer/mesh-layer.d.ts +0 -38
- package/typed/mesh-layer/mesh-layer.d.ts.map +0 -1
- package/typed/tile-3d-layer/tile-3d-layer.d.ts +0 -62
- package/typed/tile-3d-layer/tile-3d-layer.d.ts.map +0 -1
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import {GL} from '@luma.gl/constants';
|
|
2
|
+
import {Geometry} from '@luma.gl/engine';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Accessor,
|
|
6
|
+
Color,
|
|
7
|
+
CompositeLayer,
|
|
8
|
+
CompositeLayerProps,
|
|
9
|
+
COORDINATE_SYSTEM,
|
|
10
|
+
FilterContext,
|
|
11
|
+
GetPickingInfoParams,
|
|
12
|
+
Layer,
|
|
13
|
+
LayersList,
|
|
14
|
+
log,
|
|
15
|
+
PickingInfo,
|
|
16
|
+
UpdateParameters,
|
|
17
|
+
Viewport,
|
|
18
|
+
DefaultProps
|
|
19
|
+
} from '@deck.gl/core';
|
|
20
|
+
import {PointCloudLayer} from '@deck.gl/layers';
|
|
21
|
+
import {ScenegraphLayer} from '@deck.gl/mesh-layers';
|
|
22
|
+
import {default as MeshLayer} from '../mesh-layer/mesh-layer';
|
|
23
|
+
|
|
24
|
+
import {load} from '@loaders.gl/core';
|
|
25
|
+
import {MeshAttributes} from '@loaders.gl/schema';
|
|
26
|
+
import {Tileset3D, Tile3D, TILE_TYPE} from '@loaders.gl/tiles';
|
|
27
|
+
import {Tiles3DLoader} from '@loaders.gl/3d-tiles';
|
|
28
|
+
|
|
29
|
+
const SINGLE_DATA = [0];
|
|
30
|
+
|
|
31
|
+
const defaultProps: DefaultProps<Tile3DLayerProps> = {
|
|
32
|
+
getPointColor: {type: 'accessor', value: [0, 0, 0, 255]},
|
|
33
|
+
pointSize: 1.0,
|
|
34
|
+
|
|
35
|
+
// Disable async data loading (handling it in _loadTileSet)
|
|
36
|
+
data: '',
|
|
37
|
+
loader: Tiles3DLoader,
|
|
38
|
+
|
|
39
|
+
onTilesetLoad: {type: 'function', value: tileset3d => {}},
|
|
40
|
+
onTileLoad: {type: 'function', value: tileHeader => {}},
|
|
41
|
+
onTileUnload: {type: 'function', value: tileHeader => {}},
|
|
42
|
+
onTileError: {type: 'function', value: (tile, message, url) => {}},
|
|
43
|
+
_getMeshColor: {type: 'function', value: tileHeader => [255, 255, 255]}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** All properties supported by Tile3DLayer */
|
|
47
|
+
export type Tile3DLayerProps<DataT = unknown> = _Tile3DLayerProps<DataT> & CompositeLayerProps;
|
|
48
|
+
|
|
49
|
+
/** Props added by the Tile3DLayer */
|
|
50
|
+
type _Tile3DLayerProps<DataT> = {
|
|
51
|
+
data: string;
|
|
52
|
+
/** Color Accessor for point clouds. **/
|
|
53
|
+
getPointColor?: Accessor<DataT, Color>;
|
|
54
|
+
|
|
55
|
+
/** Global radius of all points in pixels. **/
|
|
56
|
+
pointSize?: number;
|
|
57
|
+
|
|
58
|
+
/** A loader which is used to decode the fetched tiles.
|
|
59
|
+
* @deprecated Use `loaders` instead
|
|
60
|
+
*/
|
|
61
|
+
loader?: typeof Tiles3DLoader;
|
|
62
|
+
|
|
63
|
+
/** Called when Tileset JSON file is loaded. **/
|
|
64
|
+
onTilesetLoad?: (tile: Tileset3D) => void;
|
|
65
|
+
|
|
66
|
+
/** Called when a tile in the tileset hierarchy is loaded. **/
|
|
67
|
+
onTileLoad?: (tile: Tile3D) => void;
|
|
68
|
+
|
|
69
|
+
/** Called when a tile is unloaded. **/
|
|
70
|
+
onTileUnload?: (tile: Tile3D) => void;
|
|
71
|
+
|
|
72
|
+
/** Called when a tile fails to load. **/
|
|
73
|
+
onTileError?: (tile: Tile3D, url: string, message: string) => void;
|
|
74
|
+
|
|
75
|
+
/** (Experimental) Accessor to change color of mesh based on properties. **/
|
|
76
|
+
_getMeshColor?: (tile: Tile3D) => Color;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/** Render 3d tiles data formatted according to the [3D Tiles Specification](https://www.opengeospatial.org/standards/3DTiles) and [`ESRI I3S`](https://github.com/Esri/i3s-spec) */
|
|
80
|
+
export default class Tile3DLayer<DataT = any, ExtraPropsT extends {} = {}> extends CompositeLayer<
|
|
81
|
+
ExtraPropsT & Required<_Tile3DLayerProps<DataT>>
|
|
82
|
+
> {
|
|
83
|
+
static defaultProps = defaultProps;
|
|
84
|
+
static layerName = 'Tile3DLayer';
|
|
85
|
+
|
|
86
|
+
state!: {
|
|
87
|
+
activeViewports: {};
|
|
88
|
+
frameNumber?: number;
|
|
89
|
+
lastUpdatedViewports: {[viewportId: string]: Viewport} | null;
|
|
90
|
+
layerMap: {[layerId: string]: any};
|
|
91
|
+
tileset3d: Tileset3D | null;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
initializeState() {
|
|
95
|
+
if ('onTileLoadFail' in this.props) {
|
|
96
|
+
log.removed('onTileLoadFail', 'onTileError')();
|
|
97
|
+
}
|
|
98
|
+
// prop verification
|
|
99
|
+
this.state = {
|
|
100
|
+
layerMap: {},
|
|
101
|
+
tileset3d: null,
|
|
102
|
+
activeViewports: {},
|
|
103
|
+
lastUpdatedViewports: null
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get isLoaded(): boolean {
|
|
108
|
+
const {tileset3d} = this.state;
|
|
109
|
+
return tileset3d !== null && tileset3d.isLoaded();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
shouldUpdateState({changeFlags}: UpdateParameters<this>): boolean {
|
|
113
|
+
return changeFlags.somethingChanged;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
updateState({props, oldProps, changeFlags}: UpdateParameters<this>): void {
|
|
117
|
+
if (props.data && props.data !== oldProps.data) {
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
119
|
+
this._loadTileset(props.data);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (changeFlags.viewportChanged) {
|
|
123
|
+
const {activeViewports} = this.state;
|
|
124
|
+
const viewportsNumber = Object.keys(activeViewports).length;
|
|
125
|
+
if (viewportsNumber) {
|
|
126
|
+
this._updateTileset(activeViewports);
|
|
127
|
+
this.state.lastUpdatedViewports = activeViewports;
|
|
128
|
+
this.state.activeViewports = {};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (changeFlags.propsChanged) {
|
|
132
|
+
const {layerMap} = this.state;
|
|
133
|
+
for (const key in layerMap) {
|
|
134
|
+
layerMap[key].needsUpdate = true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
activateViewport(viewport: Viewport): void {
|
|
140
|
+
const {activeViewports, lastUpdatedViewports} = this.state;
|
|
141
|
+
this.internalState.viewport = viewport;
|
|
142
|
+
|
|
143
|
+
activeViewports[viewport.id] = viewport;
|
|
144
|
+
const lastViewport = lastUpdatedViewports?.[viewport.id];
|
|
145
|
+
if (!lastViewport || !viewport.equals(lastViewport)) {
|
|
146
|
+
this.setChangeFlags({viewportChanged: true});
|
|
147
|
+
this.setNeedsUpdate();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
getPickingInfo({info, sourceLayer}: GetPickingInfoParams) {
|
|
152
|
+
const sourceTile = sourceLayer && (sourceLayer.props as any).tile;
|
|
153
|
+
if (info.picked) {
|
|
154
|
+
info.object = sourceTile;
|
|
155
|
+
}
|
|
156
|
+
(info as any).sourceTile = sourceTile;
|
|
157
|
+
|
|
158
|
+
return info;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
filterSubLayer({layer, viewport}: FilterContext): boolean {
|
|
162
|
+
// All sublayers will have a tile prop
|
|
163
|
+
const {tile} = layer.props as unknown as {tile: Tile3D};
|
|
164
|
+
const {id: viewportId} = viewport;
|
|
165
|
+
return tile.selected && tile.viewportIds.includes(viewportId);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
protected _updateAutoHighlight(info: PickingInfo): void {
|
|
169
|
+
const sourceTile = (info as any).sourceTile;
|
|
170
|
+
const layerCache = this.state.layerMap[sourceTile?.id];
|
|
171
|
+
if (layerCache && layerCache.layer) {
|
|
172
|
+
layerCache.layer.updateAutoHighlight(info);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private async _loadTileset(tilesetUrl) {
|
|
177
|
+
const {loadOptions = {}} = this.props;
|
|
178
|
+
|
|
179
|
+
// TODO: deprecate `loader` in v9.0
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
const loaders = this.props.loader || this.props.loaders;
|
|
182
|
+
const loader = Array.isArray(loaders) ? loaders[0] : loaders;
|
|
183
|
+
|
|
184
|
+
const options = {loadOptions: {...loadOptions}};
|
|
185
|
+
let actualTilesetUrl = tilesetUrl;
|
|
186
|
+
// @ts-expect-error preload
|
|
187
|
+
if (loader.preload) {
|
|
188
|
+
// @ts-expect-error preload
|
|
189
|
+
const preloadOptions = await loader.preload(tilesetUrl, loadOptions);
|
|
190
|
+
if (preloadOptions.url) {
|
|
191
|
+
actualTilesetUrl = preloadOptions.url;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (preloadOptions.headers) {
|
|
195
|
+
options.loadOptions.fetch = {
|
|
196
|
+
...options.loadOptions.fetch,
|
|
197
|
+
headers: preloadOptions.headers
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
Object.assign(options, preloadOptions);
|
|
201
|
+
}
|
|
202
|
+
const tilesetJson = await load(actualTilesetUrl, loader, options.loadOptions);
|
|
203
|
+
|
|
204
|
+
const tileset3d = new Tileset3D(tilesetJson, {
|
|
205
|
+
onTileLoad: this._onTileLoad.bind(this),
|
|
206
|
+
onTileUnload: this._onTileUnload.bind(this),
|
|
207
|
+
onTileError: this.props.onTileError,
|
|
208
|
+
...options
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
this.setState({
|
|
212
|
+
tileset3d,
|
|
213
|
+
layerMap: {}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
this._updateTileset(this.state.activeViewports);
|
|
217
|
+
this.props.onTilesetLoad(tileset3d);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private _onTileLoad(tileHeader: Tile3D): void {
|
|
221
|
+
const {lastUpdatedViewports} = this.state;
|
|
222
|
+
this.props.onTileLoad(tileHeader);
|
|
223
|
+
this._updateTileset(lastUpdatedViewports);
|
|
224
|
+
this.setNeedsUpdate();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private _onTileUnload(tileHeader: Tile3D): void {
|
|
228
|
+
// Was cleaned up from tileset cache. We no longer need to track it.
|
|
229
|
+
delete this.state.layerMap[tileHeader.id];
|
|
230
|
+
this.props.onTileUnload(tileHeader);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private _updateTileset(viewports: {[viewportId: string]: Viewport} | null): void {
|
|
234
|
+
if (!viewports) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const {tileset3d} = this.state;
|
|
238
|
+
const {timeline} = this.context;
|
|
239
|
+
const viewportsNumber = Object.keys(viewports).length;
|
|
240
|
+
if (!timeline || !viewportsNumber || !tileset3d) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
245
|
+
tileset3d.selectTiles(Object.values(viewports)).then(frameNumber => {
|
|
246
|
+
const tilesetChanged = this.state.frameNumber !== frameNumber;
|
|
247
|
+
if (tilesetChanged) {
|
|
248
|
+
this.setState({frameNumber});
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private _getSubLayer(
|
|
254
|
+
tileHeader: Tile3D,
|
|
255
|
+
oldLayer?: Layer
|
|
256
|
+
): MeshLayer<DataT> | PointCloudLayer<DataT> | ScenegraphLayer<DataT> | null {
|
|
257
|
+
if (!tileHeader.content) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
switch (tileHeader.type) {
|
|
262
|
+
case TILE_TYPE.POINTCLOUD:
|
|
263
|
+
return this._makePointCloudLayer(tileHeader, oldLayer as PointCloudLayer<DataT>);
|
|
264
|
+
case TILE_TYPE.SCENEGRAPH:
|
|
265
|
+
return this._make3DModelLayer(tileHeader);
|
|
266
|
+
case TILE_TYPE.MESH:
|
|
267
|
+
return this._makeSimpleMeshLayer(tileHeader, oldLayer as MeshLayer<DataT>);
|
|
268
|
+
default:
|
|
269
|
+
throw new Error(`Tile3DLayer: Failed to render layer of type ${tileHeader.content.type}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private _makePointCloudLayer(
|
|
274
|
+
tileHeader: Tile3D,
|
|
275
|
+
oldLayer?: PointCloudLayer<DataT>
|
|
276
|
+
): PointCloudLayer<DataT> | null {
|
|
277
|
+
const {attributes, pointCount, constantRGBA, cartographicOrigin, modelMatrix} =
|
|
278
|
+
tileHeader.content;
|
|
279
|
+
const {positions, normals, colors} = attributes;
|
|
280
|
+
|
|
281
|
+
if (!positions) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
const data = (oldLayer && oldLayer.props.data) || {
|
|
285
|
+
header: {
|
|
286
|
+
vertexCount: pointCount
|
|
287
|
+
},
|
|
288
|
+
attributes: {
|
|
289
|
+
POSITION: positions,
|
|
290
|
+
NORMAL: normals,
|
|
291
|
+
COLOR_0: colors
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const {pointSize, getPointColor} = this.props;
|
|
296
|
+
const SubLayerClass = this.getSubLayerClass('pointcloud', PointCloudLayer);
|
|
297
|
+
return new SubLayerClass(
|
|
298
|
+
{
|
|
299
|
+
pointSize
|
|
300
|
+
},
|
|
301
|
+
this.getSubLayerProps({
|
|
302
|
+
id: 'pointcloud'
|
|
303
|
+
}),
|
|
304
|
+
{
|
|
305
|
+
id: `${this.id}-pointcloud-${tileHeader.id}`,
|
|
306
|
+
tile: tileHeader,
|
|
307
|
+
data,
|
|
308
|
+
coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
|
|
309
|
+
coordinateOrigin: cartographicOrigin,
|
|
310
|
+
modelMatrix,
|
|
311
|
+
getColor: constantRGBA || getPointColor,
|
|
312
|
+
_offset: 0
|
|
313
|
+
}
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private _make3DModelLayer(tileHeader: Tile3D): ScenegraphLayer<DataT> {
|
|
318
|
+
const {gltf, instances, cartographicOrigin, modelMatrix} = tileHeader.content;
|
|
319
|
+
|
|
320
|
+
const SubLayerClass = this.getSubLayerClass('scenegraph', ScenegraphLayer);
|
|
321
|
+
|
|
322
|
+
return new SubLayerClass(
|
|
323
|
+
{
|
|
324
|
+
_lighting: 'pbr'
|
|
325
|
+
},
|
|
326
|
+
this.getSubLayerProps({
|
|
327
|
+
id: 'scenegraph'
|
|
328
|
+
}),
|
|
329
|
+
{
|
|
330
|
+
id: `${this.id}-scenegraph-${tileHeader.id}`,
|
|
331
|
+
tile: tileHeader,
|
|
332
|
+
data: instances || SINGLE_DATA,
|
|
333
|
+
scenegraph: gltf,
|
|
334
|
+
|
|
335
|
+
coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
|
|
336
|
+
coordinateOrigin: cartographicOrigin,
|
|
337
|
+
modelMatrix,
|
|
338
|
+
getTransformMatrix: instance => instance.modelMatrix,
|
|
339
|
+
getPosition: [0, 0, 0],
|
|
340
|
+
_offset: 0
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private _makeSimpleMeshLayer(tileHeader: Tile3D, oldLayer?: MeshLayer<DataT>): MeshLayer<DataT> {
|
|
346
|
+
const content = tileHeader.content;
|
|
347
|
+
const {
|
|
348
|
+
attributes,
|
|
349
|
+
indices,
|
|
350
|
+
modelMatrix,
|
|
351
|
+
cartographicOrigin,
|
|
352
|
+
coordinateSystem = COORDINATE_SYSTEM.METER_OFFSETS,
|
|
353
|
+
material,
|
|
354
|
+
featureIds
|
|
355
|
+
} = content;
|
|
356
|
+
const {_getMeshColor} = this.props;
|
|
357
|
+
|
|
358
|
+
const geometry =
|
|
359
|
+
(oldLayer && oldLayer.props.mesh) ||
|
|
360
|
+
new Geometry({
|
|
361
|
+
topology: 'triangle-list',
|
|
362
|
+
attributes: getMeshGeometry(attributes),
|
|
363
|
+
indices
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
const SubLayerClass = this.getSubLayerClass('mesh', MeshLayer);
|
|
367
|
+
|
|
368
|
+
return new SubLayerClass(
|
|
369
|
+
this.getSubLayerProps({
|
|
370
|
+
id: 'mesh'
|
|
371
|
+
}),
|
|
372
|
+
{
|
|
373
|
+
id: `${this.id}-mesh-${tileHeader.id}`,
|
|
374
|
+
tile: tileHeader,
|
|
375
|
+
mesh: geometry,
|
|
376
|
+
data: SINGLE_DATA,
|
|
377
|
+
getColor: _getMeshColor(tileHeader),
|
|
378
|
+
pbrMaterial: material,
|
|
379
|
+
modelMatrix,
|
|
380
|
+
coordinateOrigin: cartographicOrigin,
|
|
381
|
+
coordinateSystem,
|
|
382
|
+
featureIds,
|
|
383
|
+
_offset: 0
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
renderLayers(): Layer | null | LayersList {
|
|
389
|
+
const {tileset3d, layerMap} = this.state;
|
|
390
|
+
if (!tileset3d) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// loaders.gl doesn't provide a type for tileset3d.tiles
|
|
395
|
+
return (tileset3d.tiles as Tile3D[])
|
|
396
|
+
.map(tile => {
|
|
397
|
+
const layerCache = (layerMap[tile.id] = layerMap[tile.id] || {tile});
|
|
398
|
+
let {layer} = layerCache;
|
|
399
|
+
if (tile.selected) {
|
|
400
|
+
// render selected tiles
|
|
401
|
+
if (!layer) {
|
|
402
|
+
// create layer
|
|
403
|
+
layer = this._getSubLayer(tile);
|
|
404
|
+
} else if (layerCache.needsUpdate) {
|
|
405
|
+
// props have changed, rerender layer
|
|
406
|
+
layer = this._getSubLayer(tile, layer);
|
|
407
|
+
layerCache.needsUpdate = false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
layerCache.layer = layer;
|
|
411
|
+
return layer;
|
|
412
|
+
})
|
|
413
|
+
.filter(Boolean);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function getMeshGeometry(contentAttributes: MeshAttributes): MeshAttributes {
|
|
418
|
+
const attributes: MeshAttributes = {};
|
|
419
|
+
attributes.positions = {
|
|
420
|
+
...contentAttributes.positions,
|
|
421
|
+
value: new Float32Array(contentAttributes.positions.value)
|
|
422
|
+
};
|
|
423
|
+
if (contentAttributes.normals) {
|
|
424
|
+
attributes.normals = contentAttributes.normals;
|
|
425
|
+
}
|
|
426
|
+
if (contentAttributes.texCoords) {
|
|
427
|
+
attributes.texCoords = contentAttributes.texCoords;
|
|
428
|
+
}
|
|
429
|
+
if (contentAttributes.colors) {
|
|
430
|
+
attributes.colors = contentAttributes.colors;
|
|
431
|
+
}
|
|
432
|
+
if (contentAttributes.uvRegions) {
|
|
433
|
+
attributes.uvRegions = contentAttributes.uvRegions;
|
|
434
|
+
}
|
|
435
|
+
return attributes;
|
|
436
|
+
}
|
|
@@ -27,7 +27,7 @@ const defaultProps: DefaultProps<TileLayerProps> = {
|
|
|
27
27
|
TilesetClass: Tileset2D,
|
|
28
28
|
data: {type: 'data', value: []},
|
|
29
29
|
dataComparator: urlType.equal,
|
|
30
|
-
renderSubLayers: {type: 'function', value: props => new GeoJsonLayer(props)},
|
|
30
|
+
renderSubLayers: {type: 'function', value: (props: any) => new GeoJsonLayer(props)},
|
|
31
31
|
getTileData: {type: 'function', optional: true, value: null},
|
|
32
32
|
// TODO - change to onViewportLoad to align with Tile3DLayer
|
|
33
33
|
onViewportLoad: {type: 'function', optional: true, value: null},
|
|
@@ -48,7 +48,7 @@ const defaultProps: DefaultProps<TileLayerProps> = {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
/** All props supported by the TileLayer */
|
|
51
|
-
export type TileLayerProps<DataT =
|
|
51
|
+
export type TileLayerProps<DataT = unknown> = CompositeLayerProps & _TileLayerProps<DataT>;
|
|
52
52
|
|
|
53
53
|
/** Props added by the TileLayer */
|
|
54
54
|
type _TileLayerProps<DataT> = {
|
|
@@ -153,6 +153,12 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
153
153
|
static defaultProps: DefaultProps = defaultProps;
|
|
154
154
|
static layerName = 'TileLayer';
|
|
155
155
|
|
|
156
|
+
state!: {
|
|
157
|
+
tileset: Tileset2D | null;
|
|
158
|
+
isLoaded: boolean;
|
|
159
|
+
frameNumber?: number;
|
|
160
|
+
};
|
|
161
|
+
|
|
156
162
|
initializeState() {
|
|
157
163
|
this.state = {
|
|
158
164
|
tileset: null,
|
|
@@ -165,9 +171,12 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
165
171
|
}
|
|
166
172
|
|
|
167
173
|
get isLoaded(): boolean {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
const selectedTiles = this.state?.tileset?.selectedTiles;
|
|
175
|
+
return selectedTiles
|
|
176
|
+
? selectedTiles.every(
|
|
177
|
+
tile => tile.isLoaded && tile.layers && tile.layers.every(layer => layer.isLoaded)
|
|
178
|
+
)
|
|
179
|
+
: false;
|
|
171
180
|
}
|
|
172
181
|
|
|
173
182
|
shouldUpdateState({changeFlags}): boolean {
|
|
@@ -194,7 +203,7 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
194
203
|
tileset.reloadAll();
|
|
195
204
|
} else {
|
|
196
205
|
// some render options changed, regenerate sub layers now
|
|
197
|
-
|
|
206
|
+
tileset.tiles.forEach(tile => {
|
|
198
207
|
tile.layers = null;
|
|
199
208
|
});
|
|
200
209
|
}
|
|
@@ -235,7 +244,7 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
235
244
|
}
|
|
236
245
|
|
|
237
246
|
private _updateTileset(): void {
|
|
238
|
-
const
|
|
247
|
+
const tileset = this.state.tileset!;
|
|
239
248
|
const {zRange, modelMatrix} = this.props;
|
|
240
249
|
const frameNumber = tileset.update(this.context.viewport, {zRange, modelMatrix});
|
|
241
250
|
const {isLoaded} = tileset;
|
|
@@ -260,7 +269,8 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
260
269
|
const {onViewportLoad} = this.props;
|
|
261
270
|
|
|
262
271
|
if (onViewportLoad) {
|
|
263
|
-
|
|
272
|
+
// This method can only be called when tileset is defined and updated
|
|
273
|
+
onViewportLoad(tileset!.selectedTiles!);
|
|
264
274
|
}
|
|
265
275
|
}
|
|
266
276
|
|
|
@@ -334,7 +344,7 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
334
344
|
}
|
|
335
345
|
|
|
336
346
|
renderLayers(): Layer | null | LayersList {
|
|
337
|
-
return this.state.tileset
|
|
347
|
+
return this.state.tileset!.tiles.map((tile: Tile2DHeader) => {
|
|
338
348
|
const subLayerProps = this.getSubLayerPropsByTile(tile);
|
|
339
349
|
// cache the rendered layer in the tile
|
|
340
350
|
if (!tile.isLoaded && !tile.content) {
|
|
@@ -371,6 +381,6 @@ export default class TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends
|
|
|
371
381
|
|
|
372
382
|
filterSubLayer({layer, cullRect}: FilterContext) {
|
|
373
383
|
const {tile} = (layer as Layer<{tile: Tile2DHeader}>).props;
|
|
374
|
-
return this.state.tileset
|
|
384
|
+
return this.state.tileset!.isTileVisible(tile, cullRect);
|
|
375
385
|
}
|
|
376
386
|
}
|
|
@@ -183,7 +183,7 @@ class OSMNode {
|
|
|
183
183
|
export function getOSMTileIndices(
|
|
184
184
|
viewport: Viewport,
|
|
185
185
|
maxZ: number,
|
|
186
|
-
zRange
|
|
186
|
+
zRange?: ZRange | null,
|
|
187
187
|
bounds?: Bounds
|
|
188
188
|
): TileIndex[] {
|
|
189
189
|
const project: ((xyz: number[]) => number[]) | null =
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Viewport} from '@deck.gl/core';
|
|
2
2
|
|
|
3
3
|
import {RequestScheduler} from '@loaders.gl/loader-utils';
|
|
4
|
-
import {Matrix4, equals} from '@math.gl/core';
|
|
4
|
+
import {Matrix4, equals, NumericArray} from '@math.gl/core';
|
|
5
5
|
|
|
6
6
|
import {Tile2DHeader} from './tile-2d-header';
|
|
7
7
|
|
|
@@ -123,7 +123,7 @@ export class Tileset2D {
|
|
|
123
123
|
|
|
124
124
|
private _cacheByteSize: number;
|
|
125
125
|
private _viewport: Viewport | null;
|
|
126
|
-
private _zRange?: ZRange;
|
|
126
|
+
private _zRange?: ZRange | null;
|
|
127
127
|
private _selectedTiles: Tile2DHeader[] | null;
|
|
128
128
|
private _frameNumber: number;
|
|
129
129
|
private _modelMatrix: Matrix4;
|
|
@@ -226,9 +226,9 @@ export class Tileset2D {
|
|
|
226
226
|
*/
|
|
227
227
|
update(
|
|
228
228
|
viewport: Viewport,
|
|
229
|
-
{zRange, modelMatrix}: {zRange?: ZRange; modelMatrix?:
|
|
229
|
+
{zRange, modelMatrix}: {zRange?: ZRange | null; modelMatrix?: NumericArray | null} = {}
|
|
230
230
|
): number {
|
|
231
|
-
const modelMatrixAsMatrix4 = new Matrix4(modelMatrix);
|
|
231
|
+
const modelMatrixAsMatrix4 = modelMatrix ? new Matrix4(modelMatrix) : new Matrix4();
|
|
232
232
|
const isModelMatrixNew = !modelMatrixAsMatrix4.equals(this._modelMatrix);
|
|
233
233
|
if (
|
|
234
234
|
!this._viewport ||
|
|
@@ -326,7 +326,7 @@ export class Tileset2D {
|
|
|
326
326
|
viewport: Viewport;
|
|
327
327
|
maxZoom?: number;
|
|
328
328
|
minZoom?: number;
|
|
329
|
-
zRange
|
|
329
|
+
zRange?: ZRange | null;
|
|
330
330
|
tileSize?: number;
|
|
331
331
|
modelMatrix?: Matrix4;
|
|
332
332
|
modelMatrixInverse?: Matrix4;
|
|
@@ -359,8 +359,7 @@ export class Tileset2D {
|
|
|
359
359
|
/** Returns additional metadata to add to tile, bbox by default */
|
|
360
360
|
getTileMetadata(index: TileIndex): Record<string, any> {
|
|
361
361
|
const {tileSize} = this.opts;
|
|
362
|
-
|
|
363
|
-
return {bbox: tileToBoundingBox(this._viewport, index.x, index.y, index.z, tileSize)};
|
|
362
|
+
return {bbox: tileToBoundingBox(this._viewport!, index.x, index.y, index.z, tileSize)};
|
|
364
363
|
}
|
|
365
364
|
|
|
366
365
|
/** Returns index of the parent tile */
|
package/src/tileset-2d/utils.ts
CHANGED
|
@@ -132,18 +132,18 @@ function getBoundingBox(viewport: Viewport, zRange: number[] | null, extent: Bou
|
|
|
132
132
|
/** Get culling bounds in world space */
|
|
133
133
|
export function getCullBounds({
|
|
134
134
|
viewport,
|
|
135
|
-
z
|
|
135
|
+
z,
|
|
136
136
|
cullRect
|
|
137
137
|
}: {
|
|
138
138
|
/** Current viewport */
|
|
139
139
|
viewport: Viewport;
|
|
140
140
|
/** Current z range */
|
|
141
|
-
z
|
|
141
|
+
z?: ZRange | number | null;
|
|
142
142
|
/** Culling rectangle in screen space */
|
|
143
143
|
cullRect: {x: number; y: number; width: number; height: number};
|
|
144
144
|
}): [number, number, number, number][] {
|
|
145
145
|
const subViewports = viewport.subViewports || [viewport];
|
|
146
|
-
return subViewports.map(v => getCullBoundsInViewport(v, z, cullRect));
|
|
146
|
+
return subViewports.map(v => getCullBoundsInViewport(v, z || 0, cullRect));
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
function getCullBoundsInViewport(
|
|
@@ -273,7 +273,7 @@ export function getTileIndices({
|
|
|
273
273
|
viewport: Viewport;
|
|
274
274
|
maxZoom?: number;
|
|
275
275
|
minZoom?: number;
|
|
276
|
-
zRange
|
|
276
|
+
zRange?: ZRange | null;
|
|
277
277
|
extent?: Bounds;
|
|
278
278
|
tileSize?: number;
|
|
279
279
|
modelMatrix?: Matrix4;
|
|
@@ -26,14 +26,14 @@ const defaultProps: DefaultProps<TripsLayerProps> = {
|
|
|
26
26
|
fadeTrail: true,
|
|
27
27
|
trailLength: {type: 'number', value: 120, min: 0},
|
|
28
28
|
currentTime: {type: 'number', value: 0, min: 0},
|
|
29
|
-
getTimestamps: {type: 'accessor', value: d => d.timestamps}
|
|
29
|
+
getTimestamps: {type: 'accessor', value: (d: any) => d.timestamps}
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
/** All properties supported by TripsLayer. */
|
|
33
|
-
export type TripsLayerProps<DataT =
|
|
33
|
+
export type TripsLayerProps<DataT = unknown> = _TripsLayerProps<DataT> & PathLayerProps<DataT>;
|
|
34
34
|
|
|
35
35
|
/** Properties added by TripsLayer. */
|
|
36
|
-
type _TripsLayerProps<DataT =
|
|
36
|
+
type _TripsLayerProps<DataT = unknown> = {
|
|
37
37
|
/**
|
|
38
38
|
* Whether or not the path fades out.
|
|
39
39
|
* @default true
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
_deepEqual as deepEqual
|
|
17
17
|
} from '@deck.gl/core';
|
|
18
18
|
import {BitmapLayer} from '@deck.gl/layers';
|
|
19
|
-
import type {ImageSourceMetadata, ImageType} from '@loaders.gl/loader-utils';
|
|
19
|
+
import type {GetImageParameters, ImageSourceMetadata, ImageType} from '@loaders.gl/loader-utils';
|
|
20
20
|
import type {ImageServiceType} from '@loaders.gl/wms';
|
|
21
21
|
import {ImageSource, createImageSource} from '@loaders.gl/wms';
|
|
22
22
|
import {WGS84ToPseudoMercator} from './utils';
|
|
@@ -207,24 +207,26 @@ export class WMSLayer<ExtraPropsT extends {} = {}> extends CompositeLayer<
|
|
|
207
207
|
// BitmapLayer only supports LNGLAT or CARTESIAN (Web-Mercator)
|
|
208
208
|
srs = viewport.resolution ? 'EPSG:4326' : 'EPSG:3857';
|
|
209
209
|
}
|
|
210
|
-
const requestParams = {
|
|
210
|
+
const requestParams: GetImageParameters = {
|
|
211
211
|
width,
|
|
212
212
|
height,
|
|
213
|
-
|
|
213
|
+
boundingBox: [
|
|
214
|
+
[bounds[0], bounds[1]],
|
|
215
|
+
[bounds[2], bounds[3]]
|
|
216
|
+
],
|
|
214
217
|
layers,
|
|
215
|
-
srs
|
|
218
|
+
crs: srs
|
|
216
219
|
};
|
|
217
220
|
if (srs === 'EPSG:3857') {
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
requestParams.
|
|
221
|
+
const min = WGS84ToPseudoMercator([bounds[0], bounds[1]]);
|
|
222
|
+
const max = WGS84ToPseudoMercator([bounds[2], bounds[3]]);
|
|
223
|
+
requestParams.boundingBox = [min, max];
|
|
221
224
|
}
|
|
222
225
|
|
|
223
226
|
try {
|
|
224
227
|
this.state.loadCounter++;
|
|
225
228
|
this.props.onImageLoadStart(requestId);
|
|
226
229
|
|
|
227
|
-
// @ts-expect-error Check type changes
|
|
228
230
|
const image = await this.state.imageSource.getImage(requestParams);
|
|
229
231
|
|
|
230
232
|
// If a request takes a long time, later requests may have already loaded.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CompositeLayer, Layer, LayersList, DefaultProps } from '@deck.gl/core/typed';
|
|
2
2
|
import { PolygonLayerProps } from '@deck.gl/layers/typed';
|
|
3
3
|
/** All properties supported by GeoCellLayer. */
|
|
4
|
-
export declare type GeoCellLayerProps<DataT =
|
|
4
|
+
export declare type GeoCellLayerProps<DataT = unknown> = PolygonLayerProps<DataT>;
|
|
5
5
|
export default class GeoCellLayer<DataT = any, ExtraProps extends {} = {}> extends CompositeLayer<Required<GeoCellLayerProps<DataT>> & ExtraProps> {
|
|
6
6
|
static layerName: string;
|
|
7
7
|
static defaultProps: DefaultProps;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeoCellLayer.d.ts","sourceRoot":"","sources":["../../src/geo-cell-layer/GeoCellLayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAe,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAMhE,gDAAgD;AAChD,oBAAY,iBAAiB,CAAC,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"GeoCellLayer.d.ts","sourceRoot":"","sources":["../../src/geo-cell-layer/GeoCellLayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAe,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAMhE,gDAAgD;AAChD,oBAAY,iBAAiB,CAAC,KAAK,GAAG,OAAO,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAE1E,MAAM,CAAC,OAAO,OAAO,YAAY,CAAC,KAAK,GAAG,GAAG,EAAE,UAAU,SAAS,EAAE,GAAG,EAAE,CAAE,SAAQ,cAAc,CAC/F,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAChD;IACC,MAAM,CAAC,SAAS,SAAkB;IAClC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAgB;IAEjD,sDAAsD;IACtD,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI;IAItD,YAAY,IAAI,KAAK,GAAG,IAAI,GAAG,UAAU;CAiE1C"}
|