deck.gl 9.3.0-alpha.6 → 9.3.0-beta.2

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.
Files changed (3) hide show
  1. package/dist/dist.dev.js +2240 -728
  2. package/dist.min.js +439 -271
  3. package/package.json +15 -15
package/dist/dist.dev.js CHANGED
@@ -30931,33 +30931,33 @@ float smoothedge(float edge, float x) {
30931
30931
  /**
30932
30932
  * `LNGLAT` if rendering into a geospatial viewport, `CARTESIAN` otherwise
30933
30933
  */
30934
- DEFAULT: -1,
30934
+ DEFAULT: "default",
30935
30935
  /**
30936
30936
  * Positions are interpreted as [longitude, latitude, elevation]
30937
30937
  * longitude/latitude are in degrees, elevation is in meters.
30938
30938
  * Dimensions are in meters.
30939
30939
  */
30940
- LNGLAT: 1,
30940
+ LNGLAT: "lnglat",
30941
30941
  /**
30942
30942
  * Positions are interpreted as [x, y, z] in meter offsets from the coordinate origin.
30943
30943
  * Dimensions are in meters.
30944
30944
  */
30945
- METER_OFFSETS: 2,
30945
+ METER_OFFSETS: "meter-offsets",
30946
30946
  /**
30947
30947
  * Positions are interpreted as [deltaLng, deltaLat, elevation] from the coordinate origin.
30948
30948
  * deltaLng/deltaLat are in degrees, elevation is in meters.
30949
30949
  * Dimensions are in meters.
30950
30950
  */
30951
- LNGLAT_OFFSETS: 3,
30951
+ LNGLAT_OFFSETS: "lnglat-offsets",
30952
30952
  /**
30953
30953
  * Positions and dimensions are in the common units of the viewport.
30954
30954
  */
30955
- CARTESIAN: 0
30955
+ CARTESIAN: "cartesian"
30956
30956
  };
30957
30957
  Object.defineProperty(COORDINATE_SYSTEM, "IDENTITY", {
30958
30958
  get: () => {
30959
30959
  log_default.deprecated("COORDINATE_SYSTEM.IDENTITY", "COORDINATE_SYSTEM.CARTESIAN")();
30960
- return 0;
30960
+ return COORDINATE_SYSTEM.CARTESIAN;
30961
30961
  }
30962
30962
  });
30963
30963
  var PROJECTION_MODE = {
@@ -31043,6 +31043,20 @@ float smoothedge(float edge, float x) {
31043
31043
  var IDENTITY_MATRIX4 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
31044
31044
  var DEFAULT_PIXELS_PER_UNIT2 = [0, 0, 0];
31045
31045
  var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0];
31046
+ var COORDINATE_SYSTEM_NUMBERS = {
31047
+ default: -1,
31048
+ cartesian: 0,
31049
+ lnglat: 1,
31050
+ "meter-offsets": 2,
31051
+ "lnglat-offsets": 3
31052
+ };
31053
+ function getShaderCoordinateSystem(coordinateSystem) {
31054
+ const shaderCoordinateSystem = COORDINATE_SYSTEM_NUMBERS[coordinateSystem];
31055
+ if (shaderCoordinateSystem === void 0) {
31056
+ throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
31057
+ }
31058
+ return shaderCoordinateSystem;
31059
+ }
31046
31060
  var getMemoizedViewportUniforms = memoize(calculateViewportUniforms);
31047
31061
  function getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin = DEFAULT_COORDINATE_ORIGIN) {
31048
31062
  if (coordinateOrigin.length < 3) {
@@ -31051,7 +31065,7 @@ float smoothedge(float edge, float x) {
31051
31065
  let shaderCoordinateOrigin = coordinateOrigin;
31052
31066
  let geospatialOrigin;
31053
31067
  let offsetMode = true;
31054
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) {
31068
+ if (coordinateSystem === "lnglat-offsets" || coordinateSystem === "meter-offsets") {
31055
31069
  geospatialOrigin = coordinateOrigin;
31056
31070
  } else {
31057
31071
  geospatialOrigin = viewport.isGeospatial ? (
@@ -31061,15 +31075,15 @@ float smoothedge(float edge, float x) {
31061
31075
  }
31062
31076
  switch (viewport.projectionMode) {
31063
31077
  case PROJECTION_MODE.WEB_MERCATOR:
31064
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
31078
+ if (coordinateSystem === "lnglat" || coordinateSystem === "cartesian") {
31065
31079
  geospatialOrigin = [0, 0, 0];
31066
31080
  offsetMode = false;
31067
31081
  }
31068
31082
  break;
31069
31083
  case PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET:
31070
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
31084
+ if (coordinateSystem === "lnglat") {
31071
31085
  shaderCoordinateOrigin = geospatialOrigin;
31072
- } else if (coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
31086
+ } else if (coordinateSystem === "cartesian") {
31073
31087
  shaderCoordinateOrigin = [
31074
31088
  Math.fround(viewport.center[0]),
31075
31089
  Math.fround(viewport.center[1]),
@@ -31133,12 +31147,12 @@ float smoothedge(float edge, float x) {
31133
31147
  devicePixelRatio: devicePixelRatio2 = 1,
31134
31148
  modelMatrix: modelMatrix2 = null,
31135
31149
  // Match Layer.defaultProps
31136
- coordinateSystem = COORDINATE_SYSTEM.DEFAULT,
31150
+ coordinateSystem = "default",
31137
31151
  coordinateOrigin = DEFAULT_COORDINATE_ORIGIN,
31138
31152
  autoWrapLongitude = false
31139
31153
  }) {
31140
- if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
31141
- coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN;
31154
+ if (coordinateSystem === "default") {
31155
+ coordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
31142
31156
  }
31143
31157
  const uniforms = getMemoizedViewportUniforms({
31144
31158
  viewport,
@@ -31172,7 +31186,7 @@ float smoothedge(float edge, float x) {
31172
31186
  const focalDistance = vec4_exports.transformMat4([], [0, 0, -viewport.focalDistance, 1], viewport.projectionMatrix)[3] || 1;
31173
31187
  const uniforms = {
31174
31188
  // Projection mode values
31175
- coordinateSystem,
31189
+ coordinateSystem: getShaderCoordinateSystem(coordinateSystem),
31176
31190
  projectionMode: viewport.projectionMode,
31177
31191
  coordinateOrigin: shaderCoordinateOrigin,
31178
31192
  commonOrigin: originCommon.slice(0, 3),
@@ -31199,19 +31213,19 @@ float smoothedge(float edge, float x) {
31199
31213
  if (geospatialOrigin) {
31200
31214
  const distanceScalesAtOrigin = viewport.getDistanceScales(geospatialOrigin);
31201
31215
  switch (coordinateSystem) {
31202
- case COORDINATE_SYSTEM.METER_OFFSETS:
31216
+ case "meter-offsets":
31203
31217
  uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter;
31204
31218
  uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2;
31205
31219
  break;
31206
- case COORDINATE_SYSTEM.LNGLAT:
31207
- case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
31220
+ case "lnglat":
31221
+ case "lnglat-offsets":
31208
31222
  if (!viewport._pseudoMeters) {
31209
31223
  uniforms.commonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter;
31210
31224
  }
31211
31225
  uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerDegree;
31212
31226
  uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerDegree2;
31213
31227
  break;
31214
- case COORDINATE_SYSTEM.CARTESIAN:
31228
+ case "cartesian":
31215
31229
  uniforms.commonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]];
31216
31230
  uniforms.commonUnitsPerWorldUnit2 = [0, 0, distanceScalesAtOrigin.unitsPerMeter2[2]];
31217
31231
  break;
@@ -31223,7 +31237,16 @@ float smoothedge(float edge, float x) {
31223
31237
  }
31224
31238
 
31225
31239
  // ../core/src/shaderlib/project/project.wgsl.ts
31226
- var COORDINATE_SYSTEM_WGSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const COORDINATE_SYSTEM_${key}: i32 = ${COORDINATE_SYSTEM[key]};`).join("");
31240
+ var SHADER_COORDINATE_SYSTEMS = [
31241
+ "default",
31242
+ "lnglat",
31243
+ "meter-offsets",
31244
+ "lnglat-offsets",
31245
+ "cartesian"
31246
+ ];
31247
+ var COORDINATE_SYSTEM_WGSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS.map(
31248
+ (coordinateSystem) => `const COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll("-", "_")}: i32 = ${getShaderCoordinateSystem(coordinateSystem)};`
31249
+ ).join("");
31227
31250
  var PROJECTION_MODE_WGSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const PROJECTION_MODE_${key}: i32 = ${PROJECTION_MODE[key]};`).join("");
31228
31251
  var UNIT_WGSL_CONSTANTS = Object.keys(UNIT).map((key) => `const UNIT_${key.toUpperCase()}: i32 = ${UNIT[key]};`).join("");
31229
31252
  var projectWGSLHeader = (
@@ -31517,7 +31540,16 @@ fn project_pixel_size_vec2(pixels: vec2<f32>) -> vec2<f32> {
31517
31540
  );
31518
31541
 
31519
31542
  // ../core/src/shaderlib/project/project.glsl.ts
31520
- var COORDINATE_SYSTEM_GLSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const int COORDINATE_SYSTEM_${key} = ${COORDINATE_SYSTEM[key]};`).join("");
31543
+ var SHADER_COORDINATE_SYSTEMS2 = [
31544
+ "default",
31545
+ "lnglat",
31546
+ "meter-offsets",
31547
+ "lnglat-offsets",
31548
+ "cartesian"
31549
+ ];
31550
+ var COORDINATE_SYSTEM_GLSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS2.map(
31551
+ (coordinateSystem) => `const int COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll("-", "_")} = ${getShaderCoordinateSystem(coordinateSystem)};`
31552
+ ).join("");
31521
31553
  var PROJECTION_MODE_GLSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const int PROJECTION_MODE_${key} = ${PROJECTION_MODE[key]};`).join("");
31522
31554
  var UNIT_GLSL_CONSTANTS = Object.keys(UNIT).map((key) => `const int UNIT_${key.toUpperCase()} = ${UNIT[key]};`).join("");
31523
31555
  var projectGLSL = (
@@ -32425,7 +32457,7 @@ ${fragment}
32425
32457
  for (let i4 = 0; i4 < opts.shadowMatrices.length; i4++) {
32426
32458
  const viewProjectionMatrix = viewProjectionMatrices[i4];
32427
32459
  const viewProjectionMatrixCentered = viewProjectionMatrix.clone().translate(new Vector3(projectProps.viewport.center).negate());
32428
- if (projectUniforms.coordinateSystem === COORDINATE_SYSTEM.LNGLAT && projectUniforms.projectionMode === PROJECTION_MODE.WEB_MERCATOR) {
32460
+ if (projectUniforms.coordinateSystem === getShaderCoordinateSystem("lnglat") && projectUniforms.projectionMode === PROJECTION_MODE.WEB_MERCATOR) {
32429
32461
  viewProjectionMatrices[i4] = viewProjectionMatrixCentered;
32430
32462
  projectCenters[i4] = center2;
32431
32463
  } else {
@@ -32485,7 +32517,7 @@ ${fragment}
32485
32517
  isActive: f32,
32486
32518
  isAttribute: f32,
32487
32519
  isHighlightActive: f32,
32488
- useFloatColors: f32,
32520
+ useByteColors: f32,
32489
32521
  highlightedObjectColor: vec3<f32>,
32490
32522
  highlightColor: vec4<f32>,
32491
32523
  };
@@ -32493,11 +32525,11 @@ ${fragment}
32493
32525
  @group(0) @binding(auto) var<uniform> picking: pickingUniforms;
32494
32526
 
32495
32527
  fn picking_normalizeColor(color: vec3<f32>) -> vec3<f32> {
32496
- return select(color / 255.0, color, picking.useFloatColors > 0.5);
32528
+ return select(color, color / 255.0, picking.useByteColors > 0.5);
32497
32529
  }
32498
32530
 
32499
32531
  fn picking_normalizeColor4(color: vec4<f32>) -> vec4<f32> {
32500
- return select(color / 255.0, color, picking.useFloatColors > 0.5);
32532
+ return select(color, color / 255.0, picking.useByteColors > 0.5);
32501
32533
  }
32502
32534
 
32503
32535
  fn picking_isColorZero(color: vec3<f32>) -> bool {
@@ -32512,7 +32544,7 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
32512
32544
  var picking_default = {
32513
32545
  ...picking,
32514
32546
  source: sourceWGSL,
32515
- defaultUniforms: { ...picking.defaultUniforms, useFloatColors: false },
32547
+ defaultUniforms: { ...picking.defaultUniforms, useByteColors: true },
32516
32548
  inject: {
32517
32549
  "vs:DECKGL_FILTER_GL_POSITION": `
32518
32550
  // for picking depth values
@@ -33892,11 +33924,13 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
33892
33924
  function normalizeParameters(opts) {
33893
33925
  const { viewport, modelMatrix: modelMatrix2, coordinateOrigin } = opts;
33894
33926
  let { coordinateSystem, fromCoordinateSystem, fromCoordinateOrigin } = opts;
33895
- if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
33896
- coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN;
33927
+ if (coordinateSystem === "default") {
33928
+ coordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
33897
33929
  }
33898
33930
  if (fromCoordinateSystem === void 0) {
33899
33931
  fromCoordinateSystem = coordinateSystem;
33932
+ } else if (fromCoordinateSystem === "default") {
33933
+ fromCoordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
33900
33934
  }
33901
33935
  if (fromCoordinateOrigin === void 0) {
33902
33936
  fromCoordinateOrigin = coordinateOrigin;
@@ -33922,23 +33956,32 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
33922
33956
  [x2, y3, z3] = vec4_exports.transformMat4([], [x2, y3, z3, 1], modelMatrix2);
33923
33957
  }
33924
33958
  switch (coordinateSystem) {
33925
- case COORDINATE_SYSTEM.LNGLAT:
33959
+ case "default":
33960
+ return getWorldPosition(position, {
33961
+ viewport,
33962
+ modelMatrix: modelMatrix2,
33963
+ coordinateSystem: viewport.isGeospatial ? "lnglat" : "cartesian",
33964
+ coordinateOrigin,
33965
+ offsetMode
33966
+ });
33967
+ case "lnglat":
33926
33968
  return lngLatZToWorldPosition([x2, y3, z3], viewport, offsetMode);
33927
- case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
33969
+ case "lnglat-offsets":
33928
33970
  return lngLatZToWorldPosition(
33929
33971
  [x2 + coordinateOrigin[0], y3 + coordinateOrigin[1], z3 + (coordinateOrigin[2] || 0)],
33930
33972
  viewport,
33931
33973
  offsetMode
33932
33974
  );
33933
- case COORDINATE_SYSTEM.METER_OFFSETS:
33975
+ case "meter-offsets":
33934
33976
  return lngLatZToWorldPosition(
33935
33977
  addMetersToLngLat(coordinateOrigin, [x2, y3, z3]),
33936
33978
  viewport,
33937
33979
  offsetMode
33938
33980
  );
33939
- case COORDINATE_SYSTEM.CARTESIAN:
33940
- default:
33981
+ case "cartesian":
33941
33982
  return viewport.isGeospatial ? [x2 + coordinateOrigin[0], y3 + coordinateOrigin[1], z3 + coordinateOrigin[2]] : viewport.projectPosition([x2, y3, z3]);
33983
+ default:
33984
+ throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
33942
33985
  }
33943
33986
  }
33944
33987
  function projectPosition(position, params) {
@@ -44349,10 +44392,14 @@ void main() {
44349
44392
  }
44350
44393
  if (!this.value) {
44351
44394
  } else if (this.constant || !this.buffer || this.buffer.byteLength < this.value.byteLength + this.byteOffset) {
44352
- this.setData({
44353
- value: this.value,
44354
- constant: this.constant
44355
- });
44395
+ if (this.constant) {
44396
+ this.setConstantValue(context, this.value);
44397
+ } else {
44398
+ this.setData({
44399
+ value: this.value,
44400
+ constant: this.constant
44401
+ });
44402
+ }
44356
44403
  this.constant = false;
44357
44404
  } else {
44358
44405
  for (const [startRow, endRow] of updateRanges) {
@@ -44372,17 +44419,13 @@ void main() {
44372
44419
  // Use generic value
44373
44420
  // Returns true if successful
44374
44421
  setConstantValue(context, value) {
44375
- const isWebGPU = this.device.type === "webgpu";
44376
- if (isWebGPU || value === void 0 || typeof value === "function") {
44377
- if (isWebGPU && typeof value !== "function") {
44378
- const normalisedValue = this._normalizeValue(value, [], 0);
44379
- if (!this._areValuesEqual(normalisedValue, this.value)) {
44380
- this.setNeedsUpdate("WebGPU constant updated");
44381
- }
44382
- }
44422
+ if (value === void 0 || typeof value === "function") {
44383
44423
  return false;
44384
44424
  }
44385
44425
  const transformedValue = this.settings.transform && context ? this.settings.transform.call(context, value) : value;
44426
+ if (this.device.type === "webgpu") {
44427
+ return this.setConstantBufferValue(transformedValue, this.numInstances);
44428
+ }
44386
44429
  const hasChanged = this.setData({ constant: true, value: transformedValue });
44387
44430
  if (hasChanged) {
44388
44431
  this.setNeedsRedraw();
@@ -44390,6 +44433,41 @@ void main() {
44390
44433
  this.clearNeedsUpdate();
44391
44434
  return true;
44392
44435
  }
44436
+ setConstantBufferValue(value, numInstances) {
44437
+ const ArrayType = this.settings.defaultType;
44438
+ const constantValue = this._normalizeValue(value, new ArrayType(this.size), 0);
44439
+ if (this._hasConstantBufferValue(constantValue, numInstances)) {
44440
+ this.constant = false;
44441
+ this.clearNeedsUpdate();
44442
+ return false;
44443
+ }
44444
+ const repeatedValue = new ArrayType(Math.max(numInstances, 1) * this.size);
44445
+ for (let i4 = 0; i4 < repeatedValue.length; i4 += this.size) {
44446
+ repeatedValue.set(constantValue, i4);
44447
+ }
44448
+ const hasChanged = this.setData({ value: repeatedValue });
44449
+ this.constant = false;
44450
+ this.clearNeedsUpdate();
44451
+ if (hasChanged) {
44452
+ this.setNeedsRedraw();
44453
+ }
44454
+ return hasChanged;
44455
+ }
44456
+ _hasConstantBufferValue(value, numInstances) {
44457
+ const currentValue = this.value;
44458
+ const expectedLength = Math.max(numInstances, 1) * this.size;
44459
+ if (!ArrayBuffer.isView(currentValue) || currentValue.length !== expectedLength || currentValue.length % this.size !== 0) {
44460
+ return false;
44461
+ }
44462
+ for (let i4 = 0; i4 < currentValue.length; i4 += this.size) {
44463
+ for (let j3 = 0; j3 < this.size; j3++) {
44464
+ if (currentValue[i4 + j3] !== value[j3]) {
44465
+ return false;
44466
+ }
44467
+ }
44468
+ }
44469
+ return true;
44470
+ }
44393
44471
  // Use external buffer
44394
44472
  // Returns true if successful
44395
44473
  // eslint-disable-next-line max-statements
@@ -44498,18 +44576,10 @@ void main() {
44498
44576
  props,
44499
44577
  numInstances
44500
44578
  }) {
44501
- if (attribute.constant) {
44502
- if (this.context.device.type !== "webgpu") {
44503
- return;
44504
- }
44505
- }
44506
44579
  const { settings, state, value, size: size2, startIndices } = attribute;
44507
44580
  const { accessor, transform: transform2 } = settings;
44508
- let accessorFunc = state.binaryAccessor || // @ts-ignore
44581
+ const accessorFunc = state.binaryAccessor || // @ts-ignore
44509
44582
  (typeof accessor === "function" ? accessor : props[accessor]);
44510
- if (typeof accessorFunc !== "function" && typeof accessor === "string") {
44511
- accessorFunc = () => props[accessor];
44512
- }
44513
44583
  assert10(typeof accessorFunc === "function", `accessor "${accessor}" is not a function`);
44514
44584
  let i4 = attribute.getVertexOffset(startRow);
44515
44585
  const { iterable, objectInfo } = createIterable(data, startRow, endRow);
@@ -46665,7 +46735,7 @@ void main(void) {
46665
46735
  onDragStart: { type: "function", value: null, optional: true },
46666
46736
  onDrag: { type: "function", value: null, optional: true },
46667
46737
  onDragEnd: { type: "function", value: null, optional: true },
46668
- coordinateSystem: COORDINATE_SYSTEM.DEFAULT,
46738
+ coordinateSystem: "default",
46669
46739
  coordinateOrigin: { type: "array", value: [0, 0, 0], compare: true },
46670
46740
  modelMatrix: { type: "array", value: null, compare: true, optional: true },
46671
46741
  wrapLongitude: false,
@@ -46809,7 +46879,7 @@ void main(void) {
46809
46879
  }
46810
46880
  use64bitPositions() {
46811
46881
  const { coordinateSystem } = this.props;
46812
- return coordinateSystem === COORDINATE_SYSTEM.DEFAULT || coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN;
46882
+ return coordinateSystem === "default" || coordinateSystem === "lnglat" || coordinateSystem === "cartesian";
46813
46883
  }
46814
46884
  // Event handling
46815
46885
  onHover(info, pickingEvent) {
@@ -47189,7 +47259,6 @@ void main(void) {
47189
47259
  /* (Internal) Called by layer manager when a new layer is found */
47190
47260
  _initialize() {
47191
47261
  assert10(!this.internalState);
47192
- assert10(Number.isFinite(this.props.coordinateSystem));
47193
47262
  debug(TRACE_INITIALIZE, this);
47194
47263
  const attributeManager = this._getAttributeManager();
47195
47264
  if (attributeManager) {
@@ -50212,7 +50281,7 @@ void main(void) {
50212
50281
  var defaultProps4 = {
50213
50282
  image: { type: "image", value: null, async: true },
50214
50283
  bounds: { type: "array", value: [1, 0, 0, 1], compare: true },
50215
- _imageCoordinateSystem: COORDINATE_SYSTEM.DEFAULT,
50284
+ _imageCoordinateSystem: "default",
50216
50285
  desaturate: { type: "number", min: 0, max: 1, value: 0 },
50217
50286
  // More context: because of the blending mode we're using for ground imagery,
50218
50287
  // alpha is not effective when blending the bitmap layers with the base map.
@@ -50344,19 +50413,18 @@ void main(void) {
50344
50413
  }
50345
50414
  }
50346
50415
  _getCoordinateUniforms() {
50347
- const { LNGLAT, CARTESIAN, DEFAULT } = COORDINATE_SYSTEM;
50348
50416
  let { _imageCoordinateSystem: imageCoordinateSystem } = this.props;
50349
- if (imageCoordinateSystem !== DEFAULT) {
50417
+ if (imageCoordinateSystem !== "default") {
50350
50418
  const { bounds } = this.props;
50351
50419
  if (!isRectangularBounds(bounds)) {
50352
50420
  throw new Error("_imageCoordinateSystem only supports rectangular bounds");
50353
50421
  }
50354
- const defaultImageCoordinateSystem = this.context.viewport.resolution ? LNGLAT : CARTESIAN;
50355
- imageCoordinateSystem = imageCoordinateSystem === LNGLAT ? LNGLAT : CARTESIAN;
50356
- if (imageCoordinateSystem === LNGLAT && defaultImageCoordinateSystem === CARTESIAN) {
50422
+ const defaultImageCoordinateSystem = this.context.viewport.resolution ? "lnglat" : "cartesian";
50423
+ imageCoordinateSystem = imageCoordinateSystem === "lnglat" ? "lnglat" : "cartesian";
50424
+ if (imageCoordinateSystem === "lnglat" && defaultImageCoordinateSystem === "cartesian") {
50357
50425
  return { coordinateConversion: -1, bounds };
50358
50426
  }
50359
- if (imageCoordinateSystem === CARTESIAN && defaultImageCoordinateSystem === LNGLAT) {
50427
+ if (imageCoordinateSystem === "cartesian" && defaultImageCoordinateSystem === "lnglat") {
50360
50428
  const bottomLeft = lngLatToWorld([bounds[0], bounds[1]]);
50361
50429
  const topRight = lngLatToWorld([bounds[2], bounds[3]]);
50362
50430
  return {
@@ -50745,7 +50813,8 @@ fn fragmentMain(inp: Varyings) -> @location(0) vec4<f32> {
50745
50813
  width: oldWidth,
50746
50814
  height: oldHeight
50747
50815
  });
50748
- commandEncoder.finish();
50816
+ const commandBuffer = commandEncoder.finish();
50817
+ device.submit(commandBuffer);
50749
50818
  regenerateMipmaps(newTexture);
50750
50819
  texture.destroy();
50751
50820
  return newTexture;
@@ -52072,7 +52141,7 @@ void main(void) {
52072
52141
 
52073
52142
  float distToCenter = length(unitPosition) * outerRadiusPixels;
52074
52143
  float inCircle = scatterplot.antialiasing ?
52075
- smoothedge(distToCenter, outerRadiusPixels) :
52144
+ smoothedge(distToCenter, outerRadiusPixels) :
52076
52145
  step(distToCenter, outerRadiusPixels);
52077
52146
 
52078
52147
  if (inCircle == 0.0) {
@@ -52080,7 +52149,7 @@ void main(void) {
52080
52149
  }
52081
52150
 
52082
52151
  if (scatterplot.stroked > 0.5) {
52083
- float isLine = scatterplot.antialiasing ?
52152
+ float isLine = scatterplot.antialiasing ?
52084
52153
  smoothedge(innerUnitRadius * outerRadiusPixels, distToCenter) :
52085
52154
  step(innerUnitRadius * outerRadiusPixels, distToCenter);
52086
52155
 
@@ -52174,7 +52243,7 @@ struct Attributes {
52174
52243
  @location(4) instanceLineWidths: f32,
52175
52244
  @location(5) instanceFillColors: vec4<f32>,
52176
52245
  @location(6) instanceLineColors: vec4<f32>,
52177
- @location(7) instancePickingColors: vec3<f32>
52246
+ @location(7) instancePickingColors: vec3<f32>,
52178
52247
  };
52179
52248
 
52180
52249
  struct Varyings {
@@ -55100,11 +55169,11 @@ void main(void) {
55100
55169
  const { viewport } = this.context;
55101
55170
  let { coordinateSystem } = this.props;
55102
55171
  const { _full3d } = this.props;
55103
- if (viewport.isGeospatial && coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
55104
- coordinateSystem = COORDINATE_SYSTEM.LNGLAT;
55172
+ if (viewport.isGeospatial && coordinateSystem === "default") {
55173
+ coordinateSystem = "lnglat";
55105
55174
  }
55106
55175
  let preproject;
55107
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
55176
+ if (coordinateSystem === "lnglat") {
55108
55177
  if (_full3d) {
55109
55178
  preproject = viewport.projectPosition.bind(viewport);
55110
55179
  } else {
@@ -55671,6 +55740,7 @@ void main(void) {
55671
55740
  var glslUniformBlock3 = `layout(std140) uniform textUniforms {
55672
55741
  highp vec2 cutoffPixels;
55673
55742
  highp ivec2 align;
55743
+ highp float fontSize;
55674
55744
  bool flipY;
55675
55745
  } text;
55676
55746
 
@@ -55685,15 +55755,18 @@ void main(void) {
55685
55755
  contentCutoffPixels = [0, 0],
55686
55756
  contentAlignHorizontal = "none",
55687
55757
  contentAlignVertical = "none",
55758
+ fontSize,
55688
55759
  viewport
55689
55760
  }) => ({
55690
55761
  cutoffPixels: contentCutoffPixels,
55691
55762
  align: [CONTENT_ALIGN[contentAlignHorizontal], CONTENT_ALIGN[contentAlignVertical]],
55763
+ fontSize,
55692
55764
  flipY: viewport?.flipY ?? false
55693
55765
  }),
55694
55766
  uniformTypes: {
55695
55767
  cutoffPixels: "vec2<f32>",
55696
55768
  align: "vec2<i32>",
55769
+ fontSize: "f32",
55697
55770
  flipY: "f32"
55698
55771
  }
55699
55772
  };
@@ -55762,9 +55835,7 @@ void main(void) {
55762
55835
  icon.sizeMinPixels, icon.sizeMaxPixels
55763
55836
  );
55764
55837
 
55765
- // Choose correct constraint based on the 'sizeBasis' value (0.0 = width, 1.0 = height)
55766
- float iconConstraint = icon.sizeBasis == 0.0 ? iconSize.x : iconSize.y;
55767
- float instanceScale = iconConstraint == 0.0 ? 0.0 : sizePixels / iconConstraint;
55838
+ float instanceScale = sizePixels / text.fontSize;
55768
55839
 
55769
55840
  // scale and rotate vertex in "pixel" value and convert back to fraction in clipspace
55770
55841
  vec2 pixelOffset = positions / 2.0 * iconSize + instanceOffsets;
@@ -55902,6 +55973,7 @@ void main(void) {
55902
55973
  var defaultProps14 = {
55903
55974
  getIconOffsets: { type: "accessor", value: (x2) => x2.offsets },
55904
55975
  getContentBox: { type: "accessor", value: [0, 0, -1, -1] },
55976
+ fontSize: 1,
55905
55977
  alphaCutoff: 1e-3,
55906
55978
  smoothing: 0.1,
55907
55979
  outlineWidth: 0,
@@ -55959,6 +56031,7 @@ void main(void) {
55959
56031
  const {
55960
56032
  sdf,
55961
56033
  smoothing,
56034
+ fontSize,
55962
56035
  outlineWidth,
55963
56036
  contentCutoffPixels,
55964
56037
  contentAlignHorizontal,
@@ -55978,6 +56051,7 @@ void main(void) {
55978
56051
  contentCutoffPixels,
55979
56052
  contentAlignHorizontal,
55980
56053
  contentAlignVertical,
56054
+ fontSize,
55981
56055
  viewport: this.context.viewport
55982
56056
  };
55983
56057
  model.shaderInputs.setProps({ sdf: sdfProps, text: textProps });
@@ -56005,7 +56079,7 @@ void main(void) {
56005
56079
  for (const char of Array.from(text)) {
56006
56080
  const def = super.getInstanceIconDef(char);
56007
56081
  def[0] = offsets[j3 * 2];
56008
- def[1] = offsets[j3 * 2 + 1];
56082
+ def[1] += offsets[j3 * 2 + 1];
56009
56083
  def[6] = 1;
56010
56084
  output.set(def, i4);
56011
56085
  i4 += attribute.size;
@@ -56141,47 +56215,52 @@ void main(void) {
56141
56215
  }
56142
56216
  function buildMapping2({
56143
56217
  characterSet,
56144
- getFontWidth,
56145
- fontHeight,
56218
+ measureText: measureText2,
56146
56219
  buffer,
56147
56220
  maxCanvasWidth,
56148
56221
  mapping = {},
56149
56222
  xOffset = 0,
56150
- yOffset = 0
56223
+ yOffsetMin = 0,
56224
+ yOffsetMax = 0
56151
56225
  }) {
56152
- let row = 0;
56226
+ const row = 0;
56153
56227
  let x2 = xOffset;
56154
- const rowHeight = fontHeight + buffer * 2;
56228
+ let yMin = yOffsetMin;
56229
+ let yMax = yOffsetMax;
56155
56230
  for (const char of characterSet) {
56156
56231
  if (!mapping[char]) {
56157
- const width = getFontWidth(char);
56232
+ const { advance, width, ascent, descent } = measureText2(char);
56233
+ const height = ascent + descent;
56158
56234
  if (x2 + width + buffer * 2 > maxCanvasWidth) {
56159
56235
  x2 = 0;
56160
- row++;
56236
+ yMin = yMax;
56161
56237
  }
56162
56238
  mapping[char] = {
56163
56239
  x: x2 + buffer,
56164
- y: yOffset + row * rowHeight + buffer,
56240
+ y: yMin + buffer,
56165
56241
  width,
56166
- height: rowHeight,
56167
- layoutWidth: width,
56168
- layoutHeight: fontHeight
56242
+ height,
56243
+ advance,
56244
+ anchorX: width / 2,
56245
+ anchorY: ascent
56169
56246
  };
56170
56247
  x2 += width + buffer * 2;
56248
+ yMax = Math.max(yMax, yMin + height + buffer * 2);
56171
56249
  }
56172
56250
  }
56173
56251
  return {
56174
56252
  mapping,
56175
56253
  xOffset: x2,
56176
- yOffset: yOffset + row * rowHeight,
56177
- canvasHeight: nextPowOfTwo2(yOffset + (row + 1) * rowHeight)
56254
+ yOffsetMin: yMin,
56255
+ yOffsetMax: yMax,
56256
+ canvasHeight: nextPowOfTwo2(yMax)
56178
56257
  };
56179
56258
  }
56180
56259
  function getTextWidth(text, startIndex, endIndex, mapping) {
56181
56260
  let width = 0;
56182
56261
  for (let i4 = startIndex; i4 < endIndex; i4++) {
56183
56262
  const character = text[i4];
56184
- width += mapping[character]?.layoutWidth || 0;
56263
+ width += mapping[character]?.advance || 0;
56185
56264
  }
56186
56265
  return width;
56187
56266
  }
@@ -56257,11 +56336,15 @@ void main(void) {
56257
56336
  const character = line[i4];
56258
56337
  const frame = iconMapping[character];
56259
56338
  if (frame) {
56260
- if (!rowHeight) {
56261
- rowHeight = frame.layoutHeight;
56262
- }
56263
- leftOffsets[i4] = x2 + frame.layoutWidth / 2;
56264
- x2 += frame.layoutWidth;
56339
+ rowHeight = Math.max(rowHeight, frame.height);
56340
+ }
56341
+ }
56342
+ for (let i4 = startIndex; i4 < endIndex; i4++) {
56343
+ const character = line[i4];
56344
+ const frame = iconMapping[character];
56345
+ if (frame) {
56346
+ leftOffsets[i4] = x2 + frame.anchorX;
56347
+ x2 += frame.advance;
56265
56348
  } else {
56266
56349
  log_default.warn(`Missing character: ${character} (${character.codePointAt(0)})`)();
56267
56350
  leftOffsets[i4] = x2;
@@ -56271,7 +56354,7 @@ void main(void) {
56271
56354
  rowSize[0] = x2;
56272
56355
  rowSize[1] = rowHeight;
56273
56356
  }
56274
- function transformParagraph(paragraph, lineHeight, wordBreak, maxWidth, iconMapping) {
56357
+ function transformParagraph(paragraph, baselineOffset, lineHeight, wordBreak, maxWidth, iconMapping) {
56275
56358
  const characters = Array.from(paragraph);
56276
56359
  const numCharacters = characters.length;
56277
56360
  const x2 = new Array(numCharacters);
@@ -56280,7 +56363,8 @@ void main(void) {
56280
56363
  const autoWrappingEnabled = (wordBreak === "break-word" || wordBreak === "break-all") && isFinite(maxWidth) && maxWidth > 0;
56281
56364
  const size2 = [0, 0];
56282
56365
  const rowSize = [0, 0];
56283
- let rowOffsetTop = 0;
56366
+ let rowCount = 0;
56367
+ let rowOffsetTop = baselineOffset + lineHeight / 2;
56284
56368
  let lineStartIndex = 0;
56285
56369
  let lineEndIndex = 0;
56286
56370
  for (let i4 = 0; i4 <= numCharacters; i4++) {
@@ -56295,12 +56379,11 @@ void main(void) {
56295
56379
  const rowEnd = rowIndex < rows.length ? rows[rowIndex] : lineEndIndex;
56296
56380
  transformRow(characters, rowStart, rowEnd, iconMapping, x2, rowSize);
56297
56381
  for (let j3 = rowStart; j3 < rowEnd; j3++) {
56298
- const char2 = characters[j3];
56299
- const layoutOffsetY = iconMapping[char2]?.layoutOffsetY || 0;
56300
- y3[j3] = rowOffsetTop + rowSize[1] / 2 + layoutOffsetY;
56382
+ y3[j3] = rowOffsetTop;
56301
56383
  rowWidth[j3] = rowSize[0];
56302
56384
  }
56303
- rowOffsetTop = rowOffsetTop + rowSize[1] * lineHeight;
56385
+ rowCount++;
56386
+ rowOffsetTop += lineHeight;
56304
56387
  size2[0] = Math.max(size2[0], rowSize[0]);
56305
56388
  }
56306
56389
  lineStartIndex = lineEndIndex;
@@ -56312,7 +56395,7 @@ void main(void) {
56312
56395
  lineStartIndex++;
56313
56396
  }
56314
56397
  }
56315
- size2[1] = rowOffsetTop;
56398
+ size2[1] = rowCount * lineHeight;
56316
56399
  return { x: x2, y: y3, rowWidth, size: size2 };
56317
56400
  }
56318
56401
  function getTextFromBuffer({
@@ -56421,8 +56504,8 @@ void main(void) {
56421
56504
  smoothing: 0.1
56422
56505
  };
56423
56506
  var MAX_CANVAS_WIDTH = 1024;
56424
- var BASELINE_SCALE = 0.9;
56425
- var HEIGHT_SCALE = 1.2;
56507
+ var DEFAULT_ASCENT = 0.9;
56508
+ var DEFAULT_DESCENT = 0.3;
56426
56509
  var CACHE_LIMIT = 3;
56427
56510
  var cache = new LRUCache(CACHE_LIMIT);
56428
56511
  function getNewChars(cacheKey, characterSet) {
@@ -56454,6 +56537,40 @@ void main(void) {
56454
56537
  ctx.textBaseline = "alphabetic";
56455
56538
  ctx.textAlign = "left";
56456
56539
  }
56540
+ function measureText(ctx, fontSize, char) {
56541
+ if (char === void 0) {
56542
+ const fontMetrics = ctx.measureText("A");
56543
+ if (fontMetrics.fontBoundingBoxAscent) {
56544
+ return {
56545
+ advance: 0,
56546
+ width: 0,
56547
+ ascent: Math.ceil(fontMetrics.fontBoundingBoxAscent),
56548
+ descent: Math.ceil(fontMetrics.fontBoundingBoxDescent)
56549
+ };
56550
+ }
56551
+ return {
56552
+ advance: 0,
56553
+ width: 0,
56554
+ ascent: fontSize * DEFAULT_ASCENT,
56555
+ descent: fontSize * DEFAULT_DESCENT
56556
+ };
56557
+ }
56558
+ const metrics = ctx.measureText(char);
56559
+ if (!metrics.actualBoundingBoxAscent) {
56560
+ return {
56561
+ advance: metrics.width,
56562
+ width: metrics.width,
56563
+ ascent: fontSize * DEFAULT_ASCENT,
56564
+ descent: fontSize * DEFAULT_DESCENT
56565
+ };
56566
+ }
56567
+ return {
56568
+ advance: metrics.width,
56569
+ width: Math.ceil(metrics.actualBoundingBoxRight - metrics.actualBoundingBoxLeft),
56570
+ ascent: Math.ceil(metrics.actualBoundingBoxAscent),
56571
+ descent: Math.ceil(metrics.actualBoundingBoxDescent)
56572
+ };
56573
+ }
56457
56574
  function setFontAtlasCacheLimit(limit) {
56458
56575
  log_default.assert(Number.isFinite(limit) && limit >= CACHE_LIMIT, "Invalid cache limit");
56459
56576
  cache = new LRUCache(limit);
@@ -56473,12 +56590,11 @@ void main(void) {
56473
56590
  get mapping() {
56474
56591
  return this._atlas && this._atlas.mapping;
56475
56592
  }
56476
- get scale() {
56477
- const { fontSize, buffer } = this.props;
56478
- return (fontSize * HEIGHT_SCALE + buffer * 2) / fontSize;
56479
- }
56480
56593
  setProps(props = {}) {
56481
56594
  Object.assign(this.props, props);
56595
+ if (props._getFontRenderer) {
56596
+ this._getFontRenderer = props._getFontRenderer;
56597
+ }
56482
56598
  this._key = this._getKey();
56483
56599
  const charSet = getNewChars(this._key, this.props.characterSet);
56484
56600
  const cachedFontAtlas = cache.get(this._key);
@@ -56502,49 +56618,62 @@ void main(void) {
56502
56618
  }
56503
56619
  const ctx = canvas.getContext("2d", { willReadFrequently: true });
56504
56620
  setTextStyle(ctx, fontFamily, fontSize, fontWeight);
56505
- const { mapping, canvasHeight, xOffset, yOffset } = buildMapping2({
56506
- getFontWidth: (char) => ctx.measureText(char).width,
56507
- fontHeight: fontSize * HEIGHT_SCALE,
56621
+ const defaultMeasure = (char) => measureText(ctx, fontSize, char);
56622
+ let renderer;
56623
+ if (this._getFontRenderer) {
56624
+ renderer = this._getFontRenderer(this.props);
56625
+ } else if (sdf) {
56626
+ renderer = {
56627
+ measure: defaultMeasure,
56628
+ draw: getSdfFontRenderer(this.props)
56629
+ };
56630
+ }
56631
+ const { mapping, canvasHeight, xOffset, yOffsetMin, yOffsetMax } = buildMapping2({
56632
+ measureText: (char) => renderer ? renderer.measure(char) : defaultMeasure(char),
56508
56633
  buffer,
56509
56634
  characterSet,
56510
56635
  maxCanvasWidth: MAX_CANVAS_WIDTH,
56511
56636
  ...cachedFontAtlas && {
56512
56637
  mapping: cachedFontAtlas.mapping,
56513
56638
  xOffset: cachedFontAtlas.xOffset,
56514
- yOffset: cachedFontAtlas.yOffset
56639
+ yOffsetMin: cachedFontAtlas.yOffsetMin,
56640
+ yOffsetMax: cachedFontAtlas.yOffsetMax
56515
56641
  }
56516
56642
  });
56517
56643
  if (canvas.height !== canvasHeight) {
56518
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
56644
+ const imageData = canvas.height > 0 ? ctx.getImageData(0, 0, canvas.width, canvas.height) : null;
56519
56645
  canvas.height = canvasHeight;
56520
- ctx.putImageData(imageData, 0, 0);
56646
+ if (imageData) {
56647
+ ctx.putImageData(imageData, 0, 0);
56648
+ }
56521
56649
  }
56522
56650
  setTextStyle(ctx, fontFamily, fontSize, fontWeight);
56523
- if (sdf) {
56524
- const tinySDF = new TinySDF({
56525
- fontSize,
56526
- buffer,
56527
- radius,
56528
- cutoff,
56529
- fontFamily,
56530
- fontWeight: `${fontWeight}`
56531
- });
56651
+ if (renderer) {
56532
56652
  for (const char of characterSet) {
56533
- const { data, width, height, glyphTop } = tinySDF.draw(char);
56534
- mapping[char].width = width;
56535
- mapping[char].layoutOffsetY = fontSize * BASELINE_SCALE - glyphTop;
56536
- const imageData = ctx.createImageData(width, height);
56537
- populateAlphaChannel(data, imageData);
56538
- ctx.putImageData(imageData, mapping[char].x, mapping[char].y);
56653
+ const frame = mapping[char];
56654
+ const { data, left = 0, top = 0 } = renderer.draw(char);
56655
+ const x2 = frame.x - left;
56656
+ const y3 = frame.y - top;
56657
+ const x0 = Math.max(0, Math.round(x2));
56658
+ const y0 = Math.max(0, Math.round(y3));
56659
+ const w4 = Math.min(data.width, canvas.width - x0);
56660
+ const h4 = Math.min(data.height, canvas.height - y0);
56661
+ ctx.putImageData(data, x0, y0, 0, 0, w4, h4);
56662
+ frame.x += x0 - x2;
56663
+ frame.y += y0 - y3;
56539
56664
  }
56540
56665
  } else {
56541
56666
  for (const char of characterSet) {
56542
- ctx.fillText(char, mapping[char].x, mapping[char].y + buffer + fontSize * BASELINE_SCALE);
56667
+ const frame = mapping[char];
56668
+ ctx.fillText(char, frame.x, frame.y + frame.anchorY);
56543
56669
  }
56544
56670
  }
56671
+ const fontMetrics = renderer ? renderer.measure() : defaultMeasure();
56545
56672
  return {
56673
+ baselineOffset: (fontMetrics.ascent - fontMetrics.descent) / 2,
56546
56674
  xOffset,
56547
- yOffset,
56675
+ yOffsetMin,
56676
+ yOffsetMax,
56548
56677
  mapping,
56549
56678
  data: canvas,
56550
56679
  width: canvas.width,
@@ -56559,6 +56688,29 @@ void main(void) {
56559
56688
  return `${fontFamily} ${fontWeight} ${fontSize} ${buffer}`;
56560
56689
  }
56561
56690
  };
56691
+ function getSdfFontRenderer({
56692
+ fontSize,
56693
+ buffer,
56694
+ radius,
56695
+ cutoff,
56696
+ fontFamily,
56697
+ fontWeight
56698
+ }) {
56699
+ const tinySDF = new TinySDF({
56700
+ fontSize,
56701
+ buffer,
56702
+ radius,
56703
+ cutoff,
56704
+ fontFamily,
56705
+ fontWeight: `${fontWeight}`
56706
+ });
56707
+ return (char) => {
56708
+ const { data, width, height } = tinySDF.draw(char);
56709
+ const imageData = new ImageData(width, height);
56710
+ populateAlphaChannel(data, imageData);
56711
+ return { data: imageData, left: buffer, top: buffer };
56712
+ };
56713
+ }
56562
56714
 
56563
56715
  // ../layers/src/text-layer/text-background-layer/text-background-layer-uniforms.ts
56564
56716
  var uniformBlock14 = `layout(std140) uniform textBackgroundUniforms {
@@ -56636,10 +56788,11 @@ void main(void) {
56636
56788
  project_size_to_pixel(instanceSizes * textBackground.sizeScale, textBackground.sizeUnits),
56637
56789
  textBackground.sizeMinPixels, textBackground.sizeMaxPixels
56638
56790
  );
56791
+ float instanceScale = sizePixels / text.fontSize;
56639
56792
 
56640
- dimensions = instanceRects.zw * sizePixels + textBackground.padding.xy + textBackground.padding.zw;
56793
+ dimensions = instanceRects.zw * instanceScale + textBackground.padding.xy + textBackground.padding.zw;
56641
56794
 
56642
- vec2 pixelOffset = (positions * instanceRects.zw + instanceRects.xy) * sizePixels + mix(-textBackground.padding.xy, textBackground.padding.zw, positions);
56795
+ vec2 pixelOffset = (positions * instanceRects.zw + instanceRects.xy) * instanceScale + mix(-textBackground.padding.xy, textBackground.padding.zw, positions);
56643
56796
  pixelOffset = rotate_by_angle(pixelOffset, instanceAngles);
56644
56797
  pixelOffset += instancePixelOffsets;
56645
56798
  pixelOffset.y *= -1.0;
@@ -56730,13 +56883,15 @@ void main(void) {
56730
56883
 
56731
56884
  if (textBackground.borderRadius != vec4(0.0)) {
56732
56885
  float distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
56886
+ float shapeAlpha = smoothedge(-distToEdge, 0.0);
56887
+ if (shapeAlpha == 0.0) {
56888
+ discard;
56889
+ }
56733
56890
  if (textBackground.stroked) {
56734
56891
  fragColor = get_stroked_fragColor(distToEdge);
56735
56892
  } else {
56736
56893
  fragColor = vFillColor;
56737
56894
  }
56738
- // add border radius
56739
- float shapeAlpha = smoothedge(-distToEdge, 0.0);
56740
56895
  fragColor.a *= shapeAlpha;
56741
56896
  } else {
56742
56897
  if (textBackground.stroked) {
@@ -56757,6 +56912,7 @@ void main(void) {
56757
56912
  sizeUnits: "pixels",
56758
56913
  sizeMinPixels: 0,
56759
56914
  sizeMaxPixels: Number.MAX_SAFE_INTEGER,
56915
+ fontSize: 1,
56760
56916
  borderRadius: { type: "object", value: 0 },
56761
56917
  padding: { type: "array", value: [0, 0, 0, 0] },
56762
56918
  getPosition: { type: "accessor", value: (x2) => x2.position },
@@ -56843,7 +56999,7 @@ void main(void) {
56843
56999
  }
56844
57000
  }
56845
57001
  draw({ uniforms }) {
56846
- const { billboard, sizeScale, sizeUnits, sizeMinPixels, sizeMaxPixels, getLineWidth } = this.props;
57002
+ const { billboard, sizeScale, sizeUnits, sizeMinPixels, sizeMaxPixels, getLineWidth, fontSize } = this.props;
56847
57003
  let { padding, borderRadius } = this.props;
56848
57004
  if (padding.length < 4) {
56849
57005
  padding = [padding[0], padding[1], padding[0], padding[1]];
@@ -56868,6 +57024,7 @@ void main(void) {
56868
57024
  sizeMaxPixels
56869
57025
  };
56870
57026
  const textProps = {
57027
+ fontSize,
56871
57028
  viewport: this.context.viewport
56872
57029
  };
56873
57030
  model.shaderInputs.setProps({ textBackground: textBackgroundProps, text: textProps });
@@ -56950,12 +57107,9 @@ void main(void) {
56950
57107
  * Used to render the background.
56951
57108
  */
56952
57109
  this.getBoundingRect = (object, objectInfo) => {
56953
- let {
57110
+ const {
56954
57111
  size: [width, height]
56955
57112
  } = this.transformParagraph(object, objectInfo);
56956
- const { fontSize } = this.state.fontAtlasManager.props;
56957
- width /= fontSize;
56958
- height /= fontSize;
56959
57113
  const { getTextAnchor, getAlignmentBaseline } = this.props;
56960
57114
  const anchorX = TEXT_ANCHOR[typeof getTextAnchor === "function" ? getTextAnchor(object, objectInfo) : getTextAnchor];
56961
57115
  const anchorY = ALIGNMENT_BASELINE[typeof getAlignmentBaseline === "function" ? getAlignmentBaseline(object, objectInfo) : getAlignmentBaseline];
@@ -56970,7 +57124,7 @@ void main(void) {
56970
57124
  x: x2,
56971
57125
  y: y3,
56972
57126
  rowWidth,
56973
- size: [width, height]
57127
+ size: [, height]
56974
57128
  } = this.transformParagraph(object, objectInfo);
56975
57129
  const anchorX = TEXT_ANCHOR[typeof getTextAnchor === "function" ? getTextAnchor(object, objectInfo) : getTextAnchor];
56976
57130
  const anchorY = ALIGNMENT_BASELINE[typeof getAlignmentBaseline === "function" ? getAlignmentBaseline(object, objectInfo) : getAlignmentBaseline];
@@ -56978,8 +57132,7 @@ void main(void) {
56978
57132
  const offsets = new Array(numCharacters * 2);
56979
57133
  let index = 0;
56980
57134
  for (let i4 = 0; i4 < numCharacters; i4++) {
56981
- const rowOffset = (1 - anchorX) * (width - rowWidth[i4]) / 2;
56982
- offsets[index++] = (anchorX - 1) * width / 2 + rowOffset + x2[i4];
57135
+ offsets[index++] = (anchorX - 1) * rowWidth[i4] / 2 + x2[i4];
56983
57136
  offsets[index++] = (anchorY - 1) * height / 2 + y3[i4];
56984
57137
  }
56985
57138
  return offsets;
@@ -57015,13 +57168,14 @@ void main(void) {
57015
57168
  }
57016
57169
  /** Returns true if font has changed */
57017
57170
  _updateFontAtlas() {
57018
- const { fontSettings, fontFamily, fontWeight } = this.props;
57171
+ const { fontSettings, fontFamily, fontWeight, _getFontRenderer } = this.props;
57019
57172
  const { fontAtlasManager, characterSet } = this.state;
57020
57173
  const fontProps = {
57021
57174
  ...fontSettings,
57022
57175
  characterSet,
57023
57176
  fontFamily,
57024
- fontWeight
57177
+ fontWeight,
57178
+ _getFontRenderer
57025
57179
  };
57026
57180
  if (!fontAtlasManager.mapping) {
57027
57181
  fontAtlasManager.setProps(fontProps);
@@ -57091,14 +57245,17 @@ void main(void) {
57091
57245
  transformParagraph(object, objectInfo) {
57092
57246
  const { fontAtlasManager } = this.state;
57093
57247
  const iconMapping = fontAtlasManager.mapping;
57248
+ const { baselineOffset } = fontAtlasManager.atlas;
57249
+ const { fontSize } = fontAtlasManager.props;
57094
57250
  const getText = this.state.getText;
57095
57251
  const { wordBreak, lineHeight, maxWidth } = this.props;
57096
57252
  const paragraph = getText(object, objectInfo) || "";
57097
57253
  return transformParagraph(
57098
57254
  paragraph,
57099
- lineHeight,
57255
+ baselineOffset,
57256
+ lineHeight * fontSize,
57100
57257
  wordBreak,
57101
- maxWidth * fontAtlasManager.props.fontSize,
57258
+ maxWidth * fontSize,
57102
57259
  iconMapping
57103
57260
  );
57104
57261
  }
@@ -57107,7 +57264,7 @@ void main(void) {
57107
57264
  startIndices,
57108
57265
  numInstances,
57109
57266
  getText,
57110
- fontAtlasManager: { scale: scale8, atlas, mapping },
57267
+ fontAtlasManager: { atlas, mapping },
57111
57268
  styleVersion
57112
57269
  } = this.state;
57113
57270
  const {
@@ -57141,6 +57298,7 @@ void main(void) {
57141
57298
  } = this.props;
57142
57299
  const CharactersLayerClass = this.getSubLayerClass("characters", MultiIconLayer);
57143
57300
  const BackgroundLayerClass = this.getSubLayerClass("background", TextBackgroundLayer);
57301
+ const { fontSize } = this.state.fontAtlasManager.props;
57144
57302
  return [
57145
57303
  background && new BackgroundLayerClass(
57146
57304
  {
@@ -57161,6 +57319,7 @@ void main(void) {
57161
57319
  sizeUnits,
57162
57320
  sizeMinPixels,
57163
57321
  sizeMaxPixels,
57322
+ fontSize,
57164
57323
  transitions: transitions && {
57165
57324
  getPosition: transitions.getPosition,
57166
57325
  getAngle: transitions.getAngle,
@@ -57218,10 +57377,11 @@ void main(void) {
57218
57377
  getPixelOffset,
57219
57378
  getContentBox,
57220
57379
  billboard,
57221
- sizeScale: sizeScale * scale8,
57380
+ sizeScale,
57222
57381
  sizeUnits,
57223
- sizeMinPixels: sizeMinPixels * scale8,
57224
- sizeMaxPixels: sizeMaxPixels * scale8,
57382
+ sizeMinPixels,
57383
+ sizeMaxPixels,
57384
+ fontSize,
57225
57385
  contentCutoffPixels,
57226
57386
  contentAlignHorizontal,
57227
57387
  contentAlignVertical,
@@ -59371,6 +59531,8 @@ void main(void) {
59371
59531
  var distanceToVertex = 3 - Math.sqrt(5);
59372
59532
  var Rmidedge = Math.sqrt(3 - \u03C6);
59373
59533
  var Rcircumscribed = Math.sqrt(3) * Rmidedge / \u03C6;
59534
+ var AUTHALIC_RADIUS_EARTH = 63710072e-1;
59535
+ var AUTHALIC_AREA_EARTH = 4 * Math.PI * AUTHALIC_RADIUS_EARTH * AUTHALIC_RADIUS_EARTH;
59374
59536
  common_exports2.setMatrixArrayType(Float64Array);
59375
59537
  var PentagonShape = class _PentagonShape {
59376
59538
  constructor(vertices) {
@@ -60072,12 +60234,13 @@ void main(void) {
60072
60234
  }
60073
60235
  }
60074
60236
  };
60075
- common_exports2.setMatrixArrayType(Float64Array);
60076
60237
  var YES = -1;
60077
60238
  var NO = 1;
60239
+ common_exports2.setMatrixArrayType(Float64Array);
60078
60240
  var KJToIJ = ([k3, j3]) => {
60079
60241
  return vec2_exports2.fromValues(k3 - j3, j3);
60080
60242
  };
60243
+ common_exports2.setMatrixArrayType(Float64Array);
60081
60244
  var kPos = vec2_exports2.fromValues(1, 0);
60082
60245
  var jPos = vec2_exports2.fromValues(0, 1);
60083
60246
  var kNeg = vec2_exports2.negate(vec2_exports2.create(), kPos);
@@ -60115,7 +60278,6 @@ void main(void) {
60115
60278
  var quaternaryToFlips = (n2) => {
60116
60279
  return [[NO, NO], [NO, YES], [NO, NO], [YES, NO]][n2];
60117
60280
  };
60118
- var FLIP_SHIFT = vec2_exports2.fromValues(-1, 1);
60119
60281
  function reversePattern(pattern) {
60120
60282
  return Array.from({ length: pattern.length }, (_3, i4) => pattern.indexOf(i4));
60121
60283
  }
@@ -60123,7 +60285,7 @@ void main(void) {
60123
60285
  var PATTERN_FLIPPED = [0, 1, 2, 7, 3, 4, 5, 6];
60124
60286
  var PATTERN_REVERSED = reversePattern(PATTERN);
60125
60287
  var PATTERN_FLIPPED_REVERSED = reversePattern(PATTERN_FLIPPED);
60126
- var _shiftDigits = (digits, i4, flips, invertJ, pattern) => {
60288
+ var shiftDigits = (digits, i4, flips, invertJ, pattern) => {
60127
60289
  if (i4 <= 0)
60128
60290
  return;
60129
60291
  const parentK = digits[i4] || 0;
@@ -60145,7 +60307,10 @@ void main(void) {
60145
60307
  digits[i4 - 1] = dst % 4;
60146
60308
  digits[i4] = (parentK + 4 + Math.floor(dst / 4) - Math.floor(src / 4)) % 4;
60147
60309
  };
60148
- var sToAnchor = (s3, resolution, orientation) => {
60310
+ common_exports2.setMatrixArrayType(Float64Array);
60311
+ var FLIP_SHIFT = vec2_exports2.fromValues(-1, 1);
60312
+ var SHIFTDIGITS = true;
60313
+ var sToAnchor = (s3, resolution, orientation, doShiftDigits = SHIFTDIGITS) => {
60149
60314
  let input = BigInt(s3);
60150
60315
  const reverse = orientation === "vu" || orientation === "wu" || orientation === "vw";
60151
60316
  const invertJ = orientation === "wv" || orientation === "vw";
@@ -60153,7 +60318,7 @@ void main(void) {
60153
60318
  if (reverse) {
60154
60319
  input = (1n << BigInt(2 * resolution)) - input - 1n;
60155
60320
  }
60156
- const anchor = _sToAnchor(input, resolution, invertJ, flipIJ);
60321
+ const anchor = _sToAnchor(input, resolution, invertJ, flipIJ, doShiftDigits);
60157
60322
  if (flipIJ) {
60158
60323
  const { offset: [_i, _j], flips: [flipX, flipY] } = anchor;
60159
60324
  anchor.offset = [_j, _i];
@@ -60171,7 +60336,7 @@ void main(void) {
60171
60336
  }
60172
60337
  return anchor;
60173
60338
  };
60174
- var _sToAnchor = (s3, resolution, invertJ, flipIJ) => {
60339
+ var _sToAnchor = (s3, resolution, invertJ, flipIJ, doShiftDigits = SHIFTDIGITS) => {
60175
60340
  const offset3 = vec2_exports2.create();
60176
60341
  const flips = [NO, NO];
60177
60342
  let input = BigInt(s3);
@@ -60182,7 +60347,9 @@ void main(void) {
60182
60347
  }
60183
60348
  const pattern = flipIJ ? PATTERN_FLIPPED : PATTERN;
60184
60349
  for (let i4 = digits.length - 1; i4 >= 0; i4--) {
60185
- _shiftDigits(digits, i4, flips, invertJ, pattern);
60350
+ if (doShiftDigits) {
60351
+ shiftDigits(digits, i4, flips, invertJ, pattern);
60352
+ }
60186
60353
  vec2_exports2.multiply(flips, flips, quaternaryToFlips(digits[i4]));
60187
60354
  }
60188
60355
  flips[0] = NO;
@@ -60193,9 +60360,16 @@ void main(void) {
60193
60360
  vec2_exports2.add(offset3, offset3, childOffset);
60194
60361
  vec2_exports2.multiply(flips, flips, quaternaryToFlips(digits[i4]));
60195
60362
  }
60196
- const k3 = digits[0] || 0;
60197
- return { flips, k: k3, offset: KJToIJ(offset3) };
60363
+ const q3 = digits[0] || 0;
60364
+ return { q: q3, offset: KJToIJ(offset3), flips };
60198
60365
  };
60366
+ var PROBE_R = 0.1;
60367
+ var PROBE_OFFSETS = [
60368
+ [PROBE_R * Math.cos(45 * Math.PI / 180), PROBE_R * Math.sin(45 * Math.PI / 180)],
60369
+ [PROBE_R * Math.cos(113 * Math.PI / 180), PROBE_R * Math.sin(113 * Math.PI / 180)],
60370
+ [PROBE_R * Math.cos(293 * Math.PI / 180), PROBE_R * Math.sin(293 * Math.PI / 180)],
60371
+ [PROBE_R * Math.cos(225 * Math.PI / 180), PROBE_R * Math.sin(225 * Math.PI / 180)]
60372
+ ];
60199
60373
  common_exports2.setMatrixArrayType(Float64Array);
60200
60374
  var TRIANGLE_MODE = false;
60201
60375
  var shiftRight = vec2_exports2.clone(w);
@@ -60212,12 +60386,12 @@ void main(void) {
60212
60386
  if (anchor.flips[0] === NO && anchor.flips[1] === YES) {
60213
60387
  pentagon.rotate180();
60214
60388
  }
60215
- const { k: k3 } = anchor;
60389
+ const { q: q3 } = anchor;
60216
60390
  const F22 = anchor.flips[0] + anchor.flips[1];
60217
60391
  if (
60218
60392
  // Orient last two pentagons when both or neither flips are YES
60219
- (F22 === -2 || F22 === 2) && k3 > 1 || // Orient first & last pentagons when only one of flips is YES
60220
- F22 === 0 && (k3 === 0 || k3 === 3)
60393
+ (F22 === -2 || F22 === 2) && q3 > 1 || // Orient first & last pentagons when only one of flips is YES
60394
+ F22 === 0 && (q3 === 0 || q3 === 3)
60221
60395
  ) {
60222
60396
  pentagon.reflectY();
60223
60397
  }
@@ -60451,13 +60625,40 @@ void main(void) {
60451
60625
  var FIRST_HILBERT_RESOLUTION = 2;
60452
60626
  var MAX_RESOLUTION = 30;
60453
60627
  var HILBERT_START_BIT = 58n;
60454
- var REMOVAL_MASK = 0x3ffffffffffffffn;
60628
+ var WORLD_CELL = 0n;
60455
60629
  function getResolution(index) {
60630
+ if (index === 0n)
60631
+ return -1;
60632
+ if (index & 1n || (index & 0b111n) === 0b100n || (index & 0b11111n) === 0b10000n)
60633
+ return MAX_RESOLUTION;
60456
60634
  let resolution = MAX_RESOLUTION - 1;
60457
60635
  let shifted = index >> 1n;
60458
- while (resolution > -1 && (shifted & 0b1n) === 0n) {
60636
+ if (shifted === 0n)
60637
+ return -1;
60638
+ let low32 = Number(shifted & 0xFFFFFFFFn);
60639
+ let remaining;
60640
+ if (low32 === 0) {
60641
+ shifted >>= 32n;
60642
+ resolution -= 16;
60643
+ remaining = Number(shifted);
60644
+ } else {
60645
+ remaining = low32;
60646
+ }
60647
+ if ((remaining & 65535) === 0) {
60648
+ remaining >>= 16;
60649
+ resolution -= 8;
60650
+ }
60651
+ if (resolution >= 6 && (remaining & 255) === 0) {
60652
+ remaining >>= 8;
60653
+ resolution -= 4;
60654
+ }
60655
+ if (resolution >= 4 && (remaining & 15) === 0) {
60656
+ remaining >>= 4;
60657
+ resolution -= 2;
60658
+ }
60659
+ while (resolution > -1 && (remaining & 1) === 0) {
60459
60660
  resolution -= 1;
60460
- shifted = shifted >> (resolution < FIRST_HILBERT_RESOLUTION ? 1n : 2n);
60661
+ remaining = remaining >> (resolution < FIRST_HILBERT_RESOLUTION ? 1 : 2);
60461
60662
  }
60462
60663
  return resolution;
60463
60664
  }
@@ -60466,27 +60667,33 @@ void main(void) {
60466
60667
  if (resolution === -1) {
60467
60668
  return { origin: origins[0], segment: 0, S: 0n, resolution };
60468
60669
  }
60469
- const top6Bits = Number(index >> 58n);
60670
+ let quintantShift = HILBERT_START_BIT;
60671
+ let quintantOffset = 0;
60672
+ if (resolution === MAX_RESOLUTION) {
60673
+ const markerBits = index & 1n ? 1n : index & 0b100n ? 3n : 5n;
60674
+ quintantShift = HILBERT_START_BIT + markerBits;
60675
+ quintantOffset = markerBits === 1n ? 0 : markerBits === 3n ? 32 : 40;
60676
+ }
60677
+ const topBits = Number(index >> quintantShift) + quintantOffset;
60470
60678
  let origin, segment;
60471
60679
  if (resolution === 0) {
60472
- const originId2 = top6Bits;
60473
- origin = origins[originId2];
60680
+ origin = origins[topBits];
60474
60681
  segment = 0;
60475
60682
  } else {
60476
- const originId2 = Math.floor(top6Bits / 5);
60683
+ const originId2 = Math.floor(topBits / 5);
60477
60684
  origin = origins[originId2];
60478
- segment = (top6Bits + origin.firstQuintant) % 5;
60685
+ segment = (topBits + origin.firstQuintant) % 5;
60479
60686
  }
60480
60687
  if (!origin) {
60481
- throw new Error(`Could not parse origin: ${top6Bits}`);
60688
+ throw new Error(`Could not parse origin: ${topBits}`);
60482
60689
  }
60483
60690
  if (resolution < FIRST_HILBERT_RESOLUTION) {
60484
60691
  return { origin, segment, S: 0n, resolution };
60485
60692
  }
60486
60693
  const hilbertLevels = resolution - FIRST_HILBERT_RESOLUTION + 1;
60487
60694
  const hilbertBits = BigInt(2 * hilbertLevels);
60488
- const shift3 = HILBERT_START_BIT - hilbertBits;
60489
- const S2 = (index & REMOVAL_MASK) >> shift3;
60695
+ const removalMask = (1n << quintantShift) - 1n;
60696
+ const S2 = (index & removalMask) >> quintantShift - hilbertBits;
60490
60697
  return { origin, segment, S: S2, resolution };
60491
60698
  }
60492
60699
  common_exports2.setMatrixArrayType(Float64Array);
@@ -60505,6 +60712,9 @@ void main(void) {
60505
60712
  return getPentagonVertices(hilbertResolution, quintant, anchor);
60506
60713
  }
60507
60714
  function cellToBoundary(cellId, { closedRing = true, segments = "auto" } = { closedRing: true, segments: "auto" }) {
60715
+ if (cellId === WORLD_CELL) {
60716
+ return [];
60717
+ }
60508
60718
  const { S: S2, segment, origin, resolution } = deserialize(cellId);
60509
60719
  if (segments === "auto") {
60510
60720
  segments = Math.max(1, Math.pow(2, 6 - resolution));
@@ -60524,8 +60734,13 @@ void main(void) {
60524
60734
  function hexToU64(hex) {
60525
60735
  return BigInt(`0x${hex}`);
60526
60736
  }
60527
- var AUTHALIC_RADIUS = 63710072e-1;
60528
- var AUTHALIC_AREA = 4 * Math.PI * AUTHALIC_RADIUS * AUTHALIC_RADIUS;
60737
+ var CELL_RADIUS_SAFETY_FACTOR = 2;
60738
+ var BASE_CELL_RADIUS = CELL_RADIUS_SAFETY_FACTOR * AUTHALIC_RADIUS_EARTH / Math.sqrt(15);
60739
+ var _cellRadius = new Array(31);
60740
+ _cellRadius[0] = CELL_RADIUS_SAFETY_FACTOR * AUTHALIC_RADIUS_EARTH / Math.sqrt(3);
60741
+ for (let r3 = 1; r3 <= 30; r3++) {
60742
+ _cellRadius[r3] = BASE_CELL_RADIUS / (1 << r3 - 1);
60743
+ }
60529
60744
  common_exports2.setMatrixArrayType(Float64Array);
60530
60745
 
60531
60746
  // ../geo-layers/src/h3-layers/h3-utils.ts
@@ -60646,6 +60861,19 @@ void main(void) {
60646
60861
  function isExist(v4) {
60647
60862
  return typeof v4 !== "undefined";
60648
60863
  }
60864
+ var DANGEROUS_PROPERTY_NAMES = [
60865
+ // '__proto__',
60866
+ // 'constructor',
60867
+ // 'prototype',
60868
+ "hasOwnProperty",
60869
+ "toString",
60870
+ "valueOf",
60871
+ "__defineGetter__",
60872
+ "__defineSetter__",
60873
+ "__lookupGetter__",
60874
+ "__lookupSetter__"
60875
+ ];
60876
+ var criticalProperties = ["__proto__", "constructor", "prototype"];
60649
60877
 
60650
60878
  // ../../node_modules/fast-xml-parser/src/validator.js
60651
60879
  var defaultOptions2 = {
@@ -60887,7 +61115,7 @@ void main(void) {
60887
61115
  if (!validateAttrName(attrName)) {
60888
61116
  return getErrorObject("InvalidAttr", "Attribute '" + attrName + "' is an invalid name.", getPositionFromMatch(matches3[i4]));
60889
61117
  }
60890
- if (!attrNames.hasOwnProperty(attrName)) {
61118
+ if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {
60891
61119
  attrNames[attrName] = 1;
60892
61120
  } else {
60893
61121
  return getErrorObject("InvalidAttr", "Attribute '" + attrName + "' is repeated.", getPositionFromMatch(matches3[i4]));
@@ -60956,6 +61184,12 @@ void main(void) {
60956
61184
  }
60957
61185
 
60958
61186
  // ../../node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js
61187
+ var defaultOnDangerousProperty = (name13) => {
61188
+ if (DANGEROUS_PROPERTY_NAMES.includes(name13)) {
61189
+ return "__" + name13;
61190
+ }
61191
+ return name13;
61192
+ };
60959
61193
  var defaultOptions3 = {
60960
61194
  preserveOrder: false,
60961
61195
  attributeNamePrefix: "@_",
@@ -60999,8 +61233,29 @@ void main(void) {
60999
61233
  return tagName;
61000
61234
  },
61001
61235
  // skipEmptyListItem: false
61002
- captureMetaData: false
61003
- };
61236
+ captureMetaData: false,
61237
+ maxNestedTags: 100,
61238
+ strictReservedNames: true,
61239
+ jPath: true,
61240
+ // if true, pass jPath string to callbacks; if false, pass matcher instance
61241
+ onDangerousProperty: defaultOnDangerousProperty
61242
+ };
61243
+ function validatePropertyName(propertyName, optionName) {
61244
+ if (typeof propertyName !== "string") {
61245
+ return;
61246
+ }
61247
+ const normalized = propertyName.toLowerCase();
61248
+ if (DANGEROUS_PROPERTY_NAMES.some((dangerous) => normalized === dangerous.toLowerCase())) {
61249
+ throw new Error(
61250
+ `[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`
61251
+ );
61252
+ }
61253
+ if (criticalProperties.some((dangerous) => normalized === dangerous.toLowerCase())) {
61254
+ throw new Error(
61255
+ `[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`
61256
+ );
61257
+ }
61258
+ }
61004
61259
  function normalizeProcessEntities(value) {
61005
61260
  if (typeof value === "boolean") {
61006
61261
  return {
@@ -61010,6 +61265,7 @@ void main(void) {
61010
61265
  maxExpansionDepth: 10,
61011
61266
  maxTotalExpansions: 1e3,
61012
61267
  maxExpandedLength: 1e5,
61268
+ maxEntityCount: 100,
61013
61269
  allowedTags: null,
61014
61270
  tagFilter: null
61015
61271
  };
@@ -61017,11 +61273,11 @@ void main(void) {
61017
61273
  if (typeof value === "object" && value !== null) {
61018
61274
  return {
61019
61275
  enabled: value.enabled !== false,
61020
- // default true if not specified
61021
- maxEntitySize: value.maxEntitySize ?? 1e4,
61022
- maxExpansionDepth: value.maxExpansionDepth ?? 10,
61023
- maxTotalExpansions: value.maxTotalExpansions ?? 1e3,
61024
- maxExpandedLength: value.maxExpandedLength ?? 1e5,
61276
+ maxEntitySize: Math.max(1, value.maxEntitySize ?? 1e4),
61277
+ maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 1e4),
61278
+ maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),
61279
+ maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 1e5),
61280
+ maxEntityCount: Math.max(1, value.maxEntityCount ?? 1e3),
61025
61281
  allowedTags: value.allowedTags ?? null,
61026
61282
  tagFilter: value.tagFilter ?? null
61027
61283
  };
@@ -61030,7 +61286,31 @@ void main(void) {
61030
61286
  }
61031
61287
  var buildOptions = function(options) {
61032
61288
  const built = Object.assign({}, defaultOptions3, options);
61289
+ const propertyNameOptions = [
61290
+ { value: built.attributeNamePrefix, name: "attributeNamePrefix" },
61291
+ { value: built.attributesGroupName, name: "attributesGroupName" },
61292
+ { value: built.textNodeName, name: "textNodeName" },
61293
+ { value: built.cdataPropName, name: "cdataPropName" },
61294
+ { value: built.commentPropName, name: "commentPropName" }
61295
+ ];
61296
+ for (const { value, name: name13 } of propertyNameOptions) {
61297
+ if (value) {
61298
+ validatePropertyName(value, name13);
61299
+ }
61300
+ }
61301
+ if (built.onDangerousProperty === null) {
61302
+ built.onDangerousProperty = defaultOnDangerousProperty;
61303
+ }
61033
61304
  built.processEntities = normalizeProcessEntities(built.processEntities);
61305
+ built.unpairedTagsSet = new Set(built.unpairedTags);
61306
+ if (built.stopNodes && Array.isArray(built.stopNodes)) {
61307
+ built.stopNodes = built.stopNodes.map((node) => {
61308
+ if (typeof node === "string" && node.startsWith("*.")) {
61309
+ return ".." + node.substring(2);
61310
+ }
61311
+ return node;
61312
+ });
61313
+ }
61034
61314
  return built;
61035
61315
  };
61036
61316
 
@@ -61045,7 +61325,7 @@ void main(void) {
61045
61325
  constructor(tagname) {
61046
61326
  this.tagname = tagname;
61047
61327
  this.child = [];
61048
- this[":@"] = {};
61328
+ this[":@"] = /* @__PURE__ */ Object.create(null);
61049
61329
  }
61050
61330
  add(key, val) {
61051
61331
  if (key === "__proto__")
@@ -61077,7 +61357,8 @@ void main(void) {
61077
61357
  this.options = options;
61078
61358
  }
61079
61359
  readDocType(xmlData, i4) {
61080
- const entities = {};
61360
+ const entities = /* @__PURE__ */ Object.create(null);
61361
+ let entityCount = 0;
61081
61362
  if (xmlData[i4 + 3] === "O" && xmlData[i4 + 4] === "C" && xmlData[i4 + 5] === "T" && xmlData[i4 + 6] === "Y" && xmlData[i4 + 7] === "P" && xmlData[i4 + 8] === "E") {
61082
61363
  i4 = i4 + 9;
61083
61364
  let angleBracketsCount = 1;
@@ -61090,11 +61371,17 @@ void main(void) {
61090
61371
  let entityName, val;
61091
61372
  [entityName, val, i4] = this.readEntityExp(xmlData, i4 + 1, this.suppressValidationErr);
61092
61373
  if (val.indexOf("&") === -1) {
61093
- const escaped = entityName.replace(/[.\-+*:]/g, "\\.");
61374
+ if (this.options.enabled !== false && this.options.maxEntityCount != null && entityCount >= this.options.maxEntityCount) {
61375
+ throw new Error(
61376
+ `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`
61377
+ );
61378
+ }
61379
+ const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
61094
61380
  entities[entityName] = {
61095
61381
  regx: RegExp(`&${escaped};`, "g"),
61096
61382
  val
61097
61383
  };
61384
+ entityCount++;
61098
61385
  }
61099
61386
  } else if (hasBody && hasSeq(xmlData, "!ELEMENT", i4)) {
61100
61387
  i4 += 8;
@@ -61140,11 +61427,11 @@ void main(void) {
61140
61427
  }
61141
61428
  readEntityExp(xmlData, i4) {
61142
61429
  i4 = skipWhitespace(xmlData, i4);
61143
- let entityName = "";
61430
+ const startIndex = i4;
61144
61431
  while (i4 < xmlData.length && !/\s/.test(xmlData[i4]) && xmlData[i4] !== '"' && xmlData[i4] !== "'") {
61145
- entityName += xmlData[i4];
61146
61432
  i4++;
61147
61433
  }
61434
+ let entityName = xmlData.substring(startIndex, i4);
61148
61435
  validateEntityName(entityName);
61149
61436
  i4 = skipWhitespace(xmlData, i4);
61150
61437
  if (!this.suppressValidationErr) {
@@ -61156,7 +61443,7 @@ void main(void) {
61156
61443
  }
61157
61444
  let entityValue = "";
61158
61445
  [i4, entityValue] = this.readIdentifierVal(xmlData, i4, "entity");
61159
- if (this.options.enabled !== false && this.options.maxEntitySize && entityValue.length > this.options.maxEntitySize) {
61446
+ if (this.options.enabled !== false && this.options.maxEntitySize != null && entityValue.length > this.options.maxEntitySize) {
61160
61447
  throw new Error(
61161
61448
  `Entity "${entityName}" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`
61162
61449
  );
@@ -61166,11 +61453,11 @@ void main(void) {
61166
61453
  }
61167
61454
  readNotationExp(xmlData, i4) {
61168
61455
  i4 = skipWhitespace(xmlData, i4);
61169
- let notationName = "";
61456
+ const startIndex = i4;
61170
61457
  while (i4 < xmlData.length && !/\s/.test(xmlData[i4])) {
61171
- notationName += xmlData[i4];
61172
61458
  i4++;
61173
61459
  }
61460
+ let notationName = xmlData.substring(startIndex, i4);
61174
61461
  !this.suppressValidationErr && validateEntityName(notationName);
61175
61462
  i4 = skipWhitespace(xmlData, i4);
61176
61463
  const identifierType = xmlData.substring(i4, i4 + 6).toUpperCase();
@@ -61202,10 +61489,11 @@ void main(void) {
61202
61489
  throw new Error(`Expected quoted string, found "${startChar}"`);
61203
61490
  }
61204
61491
  i4++;
61492
+ const startIndex = i4;
61205
61493
  while (i4 < xmlData.length && xmlData[i4] !== startChar) {
61206
- identifierVal += xmlData[i4];
61207
61494
  i4++;
61208
61495
  }
61496
+ identifierVal = xmlData.substring(startIndex, i4);
61209
61497
  if (xmlData[i4] !== startChar) {
61210
61498
  throw new Error(`Unterminated ${type} value`);
61211
61499
  }
@@ -61214,11 +61502,11 @@ void main(void) {
61214
61502
  }
61215
61503
  readElementExp(xmlData, i4) {
61216
61504
  i4 = skipWhitespace(xmlData, i4);
61217
- let elementName = "";
61505
+ const startIndex = i4;
61218
61506
  while (i4 < xmlData.length && !/\s/.test(xmlData[i4])) {
61219
- elementName += xmlData[i4];
61220
61507
  i4++;
61221
61508
  }
61509
+ let elementName = xmlData.substring(startIndex, i4);
61222
61510
  if (!this.suppressValidationErr && !isName(elementName)) {
61223
61511
  throw new Error(`Invalid element name: "${elementName}"`);
61224
61512
  }
@@ -61230,10 +61518,11 @@ void main(void) {
61230
61518
  i4 += 2;
61231
61519
  else if (xmlData[i4] === "(") {
61232
61520
  i4++;
61521
+ const startIndex2 = i4;
61233
61522
  while (i4 < xmlData.length && xmlData[i4] !== ")") {
61234
- contentModel += xmlData[i4];
61235
61523
  i4++;
61236
61524
  }
61525
+ contentModel = xmlData.substring(startIndex2, i4);
61237
61526
  if (xmlData[i4] !== ")") {
61238
61527
  throw new Error("Unterminated content model");
61239
61528
  }
@@ -61248,18 +61537,18 @@ void main(void) {
61248
61537
  }
61249
61538
  readAttlistExp(xmlData, i4) {
61250
61539
  i4 = skipWhitespace(xmlData, i4);
61251
- let elementName = "";
61540
+ let startIndex = i4;
61252
61541
  while (i4 < xmlData.length && !/\s/.test(xmlData[i4])) {
61253
- elementName += xmlData[i4];
61254
61542
  i4++;
61255
61543
  }
61544
+ let elementName = xmlData.substring(startIndex, i4);
61256
61545
  validateEntityName(elementName);
61257
61546
  i4 = skipWhitespace(xmlData, i4);
61258
- let attributeName = "";
61547
+ startIndex = i4;
61259
61548
  while (i4 < xmlData.length && !/\s/.test(xmlData[i4])) {
61260
- attributeName += xmlData[i4];
61261
61549
  i4++;
61262
61550
  }
61551
+ let attributeName = xmlData.substring(startIndex, i4);
61263
61552
  if (!validateEntityName(attributeName)) {
61264
61553
  throw new Error(`Invalid attribute name: "${attributeName}"`);
61265
61554
  }
@@ -61275,11 +61564,11 @@ void main(void) {
61275
61564
  i4++;
61276
61565
  let allowedNotations = [];
61277
61566
  while (i4 < xmlData.length && xmlData[i4] !== ")") {
61278
- let notation = "";
61567
+ const startIndex2 = i4;
61279
61568
  while (i4 < xmlData.length && xmlData[i4] !== "|" && xmlData[i4] !== ")") {
61280
- notation += xmlData[i4];
61281
61569
  i4++;
61282
61570
  }
61571
+ let notation = xmlData.substring(startIndex2, i4);
61283
61572
  notation = notation.trim();
61284
61573
  if (!validateEntityName(notation)) {
61285
61574
  throw new Error(`Invalid notation name: "${notation}"`);
@@ -61296,10 +61585,11 @@ void main(void) {
61296
61585
  i4++;
61297
61586
  attributeType += " (" + allowedNotations.join("|") + ")";
61298
61587
  } else {
61588
+ const startIndex2 = i4;
61299
61589
  while (i4 < xmlData.length && !/\s/.test(xmlData[i4])) {
61300
- attributeType += xmlData[i4];
61301
61590
  i4++;
61302
61591
  }
61592
+ attributeType += xmlData.substring(startIndex2, i4);
61303
61593
  const validTypes = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
61304
61594
  if (!this.suppressValidationErr && !validTypes.includes(attributeType.toUpperCase())) {
61305
61595
  throw new Error(`Invalid attribute type: "${attributeType}"`);
@@ -61353,20 +61643,26 @@ void main(void) {
61353
61643
  // oct: false,
61354
61644
  leadingZeros: true,
61355
61645
  decimalPoint: ".",
61356
- eNotation: true
61357
- //skipLike: /regex/
61646
+ eNotation: true,
61647
+ //skipLike: /regex/,
61648
+ infinity: "original"
61649
+ // "null", "infinity" (Infinity type), "string" ("Infinity" (the string literal))
61358
61650
  };
61359
61651
  function toNumber(str6, options = {}) {
61360
61652
  options = Object.assign({}, consider, options);
61361
61653
  if (!str6 || typeof str6 !== "string")
61362
61654
  return str6;
61363
61655
  let trimmedStr = str6.trim();
61364
- if (options.skipLike !== void 0 && options.skipLike.test(trimmedStr))
61656
+ if (trimmedStr.length === 0)
61657
+ return str6;
61658
+ else if (options.skipLike !== void 0 && options.skipLike.test(trimmedStr))
61365
61659
  return str6;
61366
- else if (str6 === "0")
61660
+ else if (trimmedStr === "0")
61367
61661
  return 0;
61368
61662
  else if (options.hex && hexRegex.test(trimmedStr)) {
61369
61663
  return parse_int(trimmedStr, 16);
61664
+ } else if (!isFinite(trimmedStr)) {
61665
+ return handleInfinity(str6, Number(trimmedStr), options);
61370
61666
  } else if (trimmedStr.includes("e") || trimmedStr.includes("E")) {
61371
61667
  return resolveEnotation(str6, trimmedStr, options);
61372
61668
  } else {
@@ -61430,11 +61726,15 @@ void main(void) {
61430
61726
  return str6;
61431
61727
  else if (leadingZeros.length === 1 && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {
61432
61728
  return Number(trimmedStr);
61433
- } else if (options.leadingZeros && !eAdjacentToLeadingZeros) {
61434
- trimmedStr = (notation[1] || "") + notation[3];
61729
+ } else if (leadingZeros.length > 0) {
61730
+ if (options.leadingZeros && !eAdjacentToLeadingZeros) {
61731
+ trimmedStr = (notation[1] || "") + notation[3];
61732
+ return Number(trimmedStr);
61733
+ } else
61734
+ return str6;
61735
+ } else {
61435
61736
  return Number(trimmedStr);
61436
- } else
61437
- return str6;
61737
+ }
61438
61738
  } else {
61439
61739
  return str6;
61440
61740
  }
@@ -61462,6 +61762,20 @@ void main(void) {
61462
61762
  else
61463
61763
  throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
61464
61764
  }
61765
+ function handleInfinity(str6, num, options) {
61766
+ const isPositive2 = num === Infinity;
61767
+ switch (options.infinity.toLowerCase()) {
61768
+ case "null":
61769
+ return null;
61770
+ case "infinity":
61771
+ return num;
61772
+ case "string":
61773
+ return isPositive2 ? "Infinity" : "-Infinity";
61774
+ case "original":
61775
+ default:
61776
+ return str6;
61777
+ }
61778
+ }
61465
61779
 
61466
61780
  // ../../node_modules/fast-xml-parser/src/ignoreAttributes.js
61467
61781
  function getIgnoreAttributesFn(ignoreAttributes) {
@@ -61483,7 +61797,776 @@ void main(void) {
61483
61797
  return () => false;
61484
61798
  }
61485
61799
 
61800
+ // ../../node_modules/path-expression-matcher/src/Expression.js
61801
+ var Expression = class {
61802
+ /**
61803
+ * Create a new Expression
61804
+ * @param {string} pattern - Pattern string (e.g., "root.users.user", "..user[id]")
61805
+ * @param {Object} options - Configuration options
61806
+ * @param {string} options.separator - Path separator (default: '.')
61807
+ */
61808
+ constructor(pattern, options = {}, data) {
61809
+ this.pattern = pattern;
61810
+ this.separator = options.separator || ".";
61811
+ this.segments = this._parse(pattern);
61812
+ this.data = data;
61813
+ this._hasDeepWildcard = this.segments.some((seg) => seg.type === "deep-wildcard");
61814
+ this._hasAttributeCondition = this.segments.some((seg) => seg.attrName !== void 0);
61815
+ this._hasPositionSelector = this.segments.some((seg) => seg.position !== void 0);
61816
+ }
61817
+ /**
61818
+ * Parse pattern string into segments
61819
+ * @private
61820
+ * @param {string} pattern - Pattern to parse
61821
+ * @returns {Array} Array of segment objects
61822
+ */
61823
+ _parse(pattern) {
61824
+ const segments = [];
61825
+ let i4 = 0;
61826
+ let currentPart = "";
61827
+ while (i4 < pattern.length) {
61828
+ if (pattern[i4] === this.separator) {
61829
+ if (i4 + 1 < pattern.length && pattern[i4 + 1] === this.separator) {
61830
+ if (currentPart.trim()) {
61831
+ segments.push(this._parseSegment(currentPart.trim()));
61832
+ currentPart = "";
61833
+ }
61834
+ segments.push({ type: "deep-wildcard" });
61835
+ i4 += 2;
61836
+ } else {
61837
+ if (currentPart.trim()) {
61838
+ segments.push(this._parseSegment(currentPart.trim()));
61839
+ }
61840
+ currentPart = "";
61841
+ i4++;
61842
+ }
61843
+ } else {
61844
+ currentPart += pattern[i4];
61845
+ i4++;
61846
+ }
61847
+ }
61848
+ if (currentPart.trim()) {
61849
+ segments.push(this._parseSegment(currentPart.trim()));
61850
+ }
61851
+ return segments;
61852
+ }
61853
+ /**
61854
+ * Parse a single segment
61855
+ * @private
61856
+ * @param {string} part - Segment string (e.g., "user", "ns::user", "user[id]", "ns::user:first")
61857
+ * @returns {Object} Segment object
61858
+ */
61859
+ _parseSegment(part) {
61860
+ const segment = { type: "tag" };
61861
+ let bracketContent = null;
61862
+ let withoutBrackets = part;
61863
+ const bracketMatch = part.match(/^([^\[]+)(\[[^\]]*\])(.*)$/);
61864
+ if (bracketMatch) {
61865
+ withoutBrackets = bracketMatch[1] + bracketMatch[3];
61866
+ if (bracketMatch[2]) {
61867
+ const content = bracketMatch[2].slice(1, -1);
61868
+ if (content) {
61869
+ bracketContent = content;
61870
+ }
61871
+ }
61872
+ }
61873
+ let namespace = void 0;
61874
+ let tagAndPosition = withoutBrackets;
61875
+ if (withoutBrackets.includes("::")) {
61876
+ const nsIndex = withoutBrackets.indexOf("::");
61877
+ namespace = withoutBrackets.substring(0, nsIndex).trim();
61878
+ tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim();
61879
+ if (!namespace) {
61880
+ throw new Error(`Invalid namespace in pattern: ${part}`);
61881
+ }
61882
+ }
61883
+ let tag = void 0;
61884
+ let positionMatch = null;
61885
+ if (tagAndPosition.includes(":")) {
61886
+ const colonIndex = tagAndPosition.lastIndexOf(":");
61887
+ const tagPart = tagAndPosition.substring(0, colonIndex).trim();
61888
+ const posPart = tagAndPosition.substring(colonIndex + 1).trim();
61889
+ const isPositionKeyword = ["first", "last", "odd", "even"].includes(posPart) || /^nth\(\d+\)$/.test(posPart);
61890
+ if (isPositionKeyword) {
61891
+ tag = tagPart;
61892
+ positionMatch = posPart;
61893
+ } else {
61894
+ tag = tagAndPosition;
61895
+ }
61896
+ } else {
61897
+ tag = tagAndPosition;
61898
+ }
61899
+ if (!tag) {
61900
+ throw new Error(`Invalid segment pattern: ${part}`);
61901
+ }
61902
+ segment.tag = tag;
61903
+ if (namespace) {
61904
+ segment.namespace = namespace;
61905
+ }
61906
+ if (bracketContent) {
61907
+ if (bracketContent.includes("=")) {
61908
+ const eqIndex = bracketContent.indexOf("=");
61909
+ segment.attrName = bracketContent.substring(0, eqIndex).trim();
61910
+ segment.attrValue = bracketContent.substring(eqIndex + 1).trim();
61911
+ } else {
61912
+ segment.attrName = bracketContent.trim();
61913
+ }
61914
+ }
61915
+ if (positionMatch) {
61916
+ const nthMatch = positionMatch.match(/^nth\((\d+)\)$/);
61917
+ if (nthMatch) {
61918
+ segment.position = "nth";
61919
+ segment.positionValue = parseInt(nthMatch[1], 10);
61920
+ } else {
61921
+ segment.position = positionMatch;
61922
+ }
61923
+ }
61924
+ return segment;
61925
+ }
61926
+ /**
61927
+ * Get the number of segments
61928
+ * @returns {number}
61929
+ */
61930
+ get length() {
61931
+ return this.segments.length;
61932
+ }
61933
+ /**
61934
+ * Check if expression contains deep wildcard
61935
+ * @returns {boolean}
61936
+ */
61937
+ hasDeepWildcard() {
61938
+ return this._hasDeepWildcard;
61939
+ }
61940
+ /**
61941
+ * Check if expression has attribute conditions
61942
+ * @returns {boolean}
61943
+ */
61944
+ hasAttributeCondition() {
61945
+ return this._hasAttributeCondition;
61946
+ }
61947
+ /**
61948
+ * Check if expression has position selectors
61949
+ * @returns {boolean}
61950
+ */
61951
+ hasPositionSelector() {
61952
+ return this._hasPositionSelector;
61953
+ }
61954
+ /**
61955
+ * Get string representation
61956
+ * @returns {string}
61957
+ */
61958
+ toString() {
61959
+ return this.pattern;
61960
+ }
61961
+ };
61962
+
61963
+ // ../../node_modules/path-expression-matcher/src/ExpressionSet.js
61964
+ var ExpressionSet = class {
61965
+ constructor() {
61966
+ this._byDepthAndTag = /* @__PURE__ */ new Map();
61967
+ this._wildcardByDepth = /* @__PURE__ */ new Map();
61968
+ this._deepWildcards = [];
61969
+ this._patterns = /* @__PURE__ */ new Set();
61970
+ this._sealed = false;
61971
+ }
61972
+ /**
61973
+ * Add an Expression to the set.
61974
+ * Duplicate patterns (same pattern string) are silently ignored.
61975
+ *
61976
+ * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance
61977
+ * @returns {this} for chaining
61978
+ * @throws {TypeError} if called after seal()
61979
+ *
61980
+ * @example
61981
+ * set.add(new Expression('root.users.user'));
61982
+ * set.add(new Expression('..script'));
61983
+ */
61984
+ add(expression) {
61985
+ if (this._sealed) {
61986
+ throw new TypeError(
61987
+ "ExpressionSet is sealed. Create a new ExpressionSet to add more expressions."
61988
+ );
61989
+ }
61990
+ if (this._patterns.has(expression.pattern))
61991
+ return this;
61992
+ this._patterns.add(expression.pattern);
61993
+ if (expression.hasDeepWildcard()) {
61994
+ this._deepWildcards.push(expression);
61995
+ return this;
61996
+ }
61997
+ const depth = expression.length;
61998
+ const lastSeg = expression.segments[expression.segments.length - 1];
61999
+ const tag = lastSeg?.tag;
62000
+ if (!tag || tag === "*") {
62001
+ if (!this._wildcardByDepth.has(depth))
62002
+ this._wildcardByDepth.set(depth, []);
62003
+ this._wildcardByDepth.get(depth).push(expression);
62004
+ } else {
62005
+ const key = `${depth}:${tag}`;
62006
+ if (!this._byDepthAndTag.has(key))
62007
+ this._byDepthAndTag.set(key, []);
62008
+ this._byDepthAndTag.get(key).push(expression);
62009
+ }
62010
+ return this;
62011
+ }
62012
+ /**
62013
+ * Add multiple expressions at once.
62014
+ *
62015
+ * @param {import('./Expression.js').default[]} expressions - Array of Expression instances
62016
+ * @returns {this} for chaining
62017
+ *
62018
+ * @example
62019
+ * set.addAll([
62020
+ * new Expression('root.users.user'),
62021
+ * new Expression('root.config.setting'),
62022
+ * ]);
62023
+ */
62024
+ addAll(expressions) {
62025
+ for (const expr of expressions)
62026
+ this.add(expr);
62027
+ return this;
62028
+ }
62029
+ /**
62030
+ * Check whether a pattern string is already present in the set.
62031
+ *
62032
+ * @param {import('./Expression.js').default} expression
62033
+ * @returns {boolean}
62034
+ */
62035
+ has(expression) {
62036
+ return this._patterns.has(expression.pattern);
62037
+ }
62038
+ /**
62039
+ * Number of expressions in the set.
62040
+ * @type {number}
62041
+ */
62042
+ get size() {
62043
+ return this._patterns.size;
62044
+ }
62045
+ /**
62046
+ * Seal the set against further modifications.
62047
+ * Useful to prevent accidental mutations after config is built.
62048
+ * Calling add() or addAll() on a sealed set throws a TypeError.
62049
+ *
62050
+ * @returns {this}
62051
+ */
62052
+ seal() {
62053
+ this._sealed = true;
62054
+ return this;
62055
+ }
62056
+ /**
62057
+ * Whether the set has been sealed.
62058
+ * @type {boolean}
62059
+ */
62060
+ get isSealed() {
62061
+ return this._sealed;
62062
+ }
62063
+ /**
62064
+ * Test whether the matcher's current path matches any expression in the set.
62065
+ *
62066
+ * Evaluation order (cheapest → most expensive):
62067
+ * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions
62068
+ * 2. Depth-only wildcard bucket — O(1) lookup, rare
62069
+ * 3. Deep-wildcard list — always checked, but usually small
62070
+ *
62071
+ * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)
62072
+ * @returns {boolean} true if any expression matches the current path
62073
+ *
62074
+ * @example
62075
+ * if (stopNodes.matchesAny(matcher)) {
62076
+ * // handle stop node
62077
+ * }
62078
+ */
62079
+ matchesAny(matcher) {
62080
+ return this.findMatch(matcher) !== null;
62081
+ }
62082
+ /**
62083
+ * Find and return the first Expression that matches the matcher's current path.
62084
+ *
62085
+ * Uses the same evaluation order as matchesAny (cheapest → most expensive):
62086
+ * 1. Exact depth + tag bucket
62087
+ * 2. Depth-only wildcard bucket
62088
+ * 3. Deep-wildcard list
62089
+ *
62090
+ * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)
62091
+ * @returns {import('./Expression.js').default | null} the first matching Expression, or null
62092
+ *
62093
+ * @example
62094
+ * const expr = stopNodes.findMatch(matcher);
62095
+ * if (expr) {
62096
+ * // access expr.config, expr.pattern, etc.
62097
+ * }
62098
+ */
62099
+ findMatch(matcher) {
62100
+ const depth = matcher.getDepth();
62101
+ const tag = matcher.getCurrentTag();
62102
+ const exactKey = `${depth}:${tag}`;
62103
+ const exactBucket = this._byDepthAndTag.get(exactKey);
62104
+ if (exactBucket) {
62105
+ for (let i4 = 0; i4 < exactBucket.length; i4++) {
62106
+ if (matcher.matches(exactBucket[i4]))
62107
+ return exactBucket[i4];
62108
+ }
62109
+ }
62110
+ const wildcardBucket = this._wildcardByDepth.get(depth);
62111
+ if (wildcardBucket) {
62112
+ for (let i4 = 0; i4 < wildcardBucket.length; i4++) {
62113
+ if (matcher.matches(wildcardBucket[i4]))
62114
+ return wildcardBucket[i4];
62115
+ }
62116
+ }
62117
+ for (let i4 = 0; i4 < this._deepWildcards.length; i4++) {
62118
+ if (matcher.matches(this._deepWildcards[i4]))
62119
+ return this._deepWildcards[i4];
62120
+ }
62121
+ return null;
62122
+ }
62123
+ };
62124
+
62125
+ // ../../node_modules/path-expression-matcher/src/Matcher.js
62126
+ var MUTATING_METHODS = /* @__PURE__ */ new Set(["push", "pop", "reset", "updateCurrent", "restore"]);
62127
+ var Matcher = class {
62128
+ /**
62129
+ * Create a new Matcher
62130
+ * @param {Object} options - Configuration options
62131
+ * @param {string} options.separator - Default path separator (default: '.')
62132
+ */
62133
+ constructor(options = {}) {
62134
+ this.separator = options.separator || ".";
62135
+ this.path = [];
62136
+ this.siblingStacks = [];
62137
+ this._pathStringCache = null;
62138
+ this._frozenPathCache = null;
62139
+ this._frozenSiblingsCache = null;
62140
+ }
62141
+ /**
62142
+ * Push a new tag onto the path
62143
+ * @param {string} tagName - Name of the tag
62144
+ * @param {Object} attrValues - Attribute key-value pairs for current node (optional)
62145
+ * @param {string} namespace - Namespace for the tag (optional)
62146
+ */
62147
+ push(tagName, attrValues = null, namespace = null) {
62148
+ this._pathStringCache = null;
62149
+ this._frozenPathCache = null;
62150
+ this._frozenSiblingsCache = null;
62151
+ if (this.path.length > 0) {
62152
+ const prev = this.path[this.path.length - 1];
62153
+ prev.values = void 0;
62154
+ }
62155
+ const currentLevel = this.path.length;
62156
+ if (!this.siblingStacks[currentLevel]) {
62157
+ this.siblingStacks[currentLevel] = /* @__PURE__ */ new Map();
62158
+ }
62159
+ const siblings = this.siblingStacks[currentLevel];
62160
+ const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;
62161
+ const counter2 = siblings.get(siblingKey) || 0;
62162
+ let position = 0;
62163
+ for (const count3 of siblings.values()) {
62164
+ position += count3;
62165
+ }
62166
+ siblings.set(siblingKey, counter2 + 1);
62167
+ const node = {
62168
+ tag: tagName,
62169
+ position,
62170
+ counter: counter2
62171
+ };
62172
+ if (namespace !== null && namespace !== void 0) {
62173
+ node.namespace = namespace;
62174
+ }
62175
+ if (attrValues !== null && attrValues !== void 0) {
62176
+ node.values = attrValues;
62177
+ }
62178
+ this.path.push(node);
62179
+ }
62180
+ /**
62181
+ * Pop the last tag from the path
62182
+ * @returns {Object|undefined} The popped node
62183
+ */
62184
+ pop() {
62185
+ if (this.path.length === 0)
62186
+ return void 0;
62187
+ this._pathStringCache = null;
62188
+ this._frozenPathCache = null;
62189
+ this._frozenSiblingsCache = null;
62190
+ const node = this.path.pop();
62191
+ if (this.siblingStacks.length > this.path.length + 1) {
62192
+ this.siblingStacks.length = this.path.length + 1;
62193
+ }
62194
+ return node;
62195
+ }
62196
+ /**
62197
+ * Update current node's attribute values
62198
+ * Useful when attributes are parsed after push
62199
+ * @param {Object} attrValues - Attribute values
62200
+ */
62201
+ updateCurrent(attrValues) {
62202
+ if (this.path.length > 0) {
62203
+ const current = this.path[this.path.length - 1];
62204
+ if (attrValues !== null && attrValues !== void 0) {
62205
+ current.values = attrValues;
62206
+ this._frozenPathCache = null;
62207
+ }
62208
+ }
62209
+ }
62210
+ /**
62211
+ * Get current tag name
62212
+ * @returns {string|undefined}
62213
+ */
62214
+ getCurrentTag() {
62215
+ return this.path.length > 0 ? this.path[this.path.length - 1].tag : void 0;
62216
+ }
62217
+ /**
62218
+ * Get current namespace
62219
+ * @returns {string|undefined}
62220
+ */
62221
+ getCurrentNamespace() {
62222
+ return this.path.length > 0 ? this.path[this.path.length - 1].namespace : void 0;
62223
+ }
62224
+ /**
62225
+ * Get current node's attribute value
62226
+ * @param {string} attrName - Attribute name
62227
+ * @returns {*} Attribute value or undefined
62228
+ */
62229
+ getAttrValue(attrName) {
62230
+ if (this.path.length === 0)
62231
+ return void 0;
62232
+ const current = this.path[this.path.length - 1];
62233
+ return current.values?.[attrName];
62234
+ }
62235
+ /**
62236
+ * Check if current node has an attribute
62237
+ * @param {string} attrName - Attribute name
62238
+ * @returns {boolean}
62239
+ */
62240
+ hasAttr(attrName) {
62241
+ if (this.path.length === 0)
62242
+ return false;
62243
+ const current = this.path[this.path.length - 1];
62244
+ return current.values !== void 0 && attrName in current.values;
62245
+ }
62246
+ /**
62247
+ * Get current node's sibling position (child index in parent)
62248
+ * @returns {number}
62249
+ */
62250
+ getPosition() {
62251
+ if (this.path.length === 0)
62252
+ return -1;
62253
+ return this.path[this.path.length - 1].position ?? 0;
62254
+ }
62255
+ /**
62256
+ * Get current node's repeat counter (occurrence count of this tag name)
62257
+ * @returns {number}
62258
+ */
62259
+ getCounter() {
62260
+ if (this.path.length === 0)
62261
+ return -1;
62262
+ return this.path[this.path.length - 1].counter ?? 0;
62263
+ }
62264
+ /**
62265
+ * Get current node's sibling index (alias for getPosition for backward compatibility)
62266
+ * @returns {number}
62267
+ * @deprecated Use getPosition() or getCounter() instead
62268
+ */
62269
+ getIndex() {
62270
+ return this.getPosition();
62271
+ }
62272
+ /**
62273
+ * Get current path depth
62274
+ * @returns {number}
62275
+ */
62276
+ getDepth() {
62277
+ return this.path.length;
62278
+ }
62279
+ /**
62280
+ * Get path as string
62281
+ * @param {string} separator - Optional separator (uses default if not provided)
62282
+ * @param {boolean} includeNamespace - Whether to include namespace in output (default: true)
62283
+ * @returns {string}
62284
+ */
62285
+ toString(separator, includeNamespace = true) {
62286
+ const sep = separator || this.separator;
62287
+ const isDefault = sep === this.separator && includeNamespace === true;
62288
+ if (isDefault) {
62289
+ if (this._pathStringCache !== null && this._pathStringCache !== void 0) {
62290
+ return this._pathStringCache;
62291
+ }
62292
+ const result = this.path.map(
62293
+ (n2) => includeNamespace && n2.namespace ? `${n2.namespace}:${n2.tag}` : n2.tag
62294
+ ).join(sep);
62295
+ this._pathStringCache = result;
62296
+ return result;
62297
+ }
62298
+ return this.path.map(
62299
+ (n2) => includeNamespace && n2.namespace ? `${n2.namespace}:${n2.tag}` : n2.tag
62300
+ ).join(sep);
62301
+ }
62302
+ /**
62303
+ * Get path as array of tag names
62304
+ * @returns {string[]}
62305
+ */
62306
+ toArray() {
62307
+ return this.path.map((n2) => n2.tag);
62308
+ }
62309
+ /**
62310
+ * Reset the path to empty
62311
+ */
62312
+ reset() {
62313
+ this._pathStringCache = null;
62314
+ this._frozenPathCache = null;
62315
+ this._frozenSiblingsCache = null;
62316
+ this.path = [];
62317
+ this.siblingStacks = [];
62318
+ }
62319
+ /**
62320
+ * Match current path against an Expression
62321
+ * @param {Expression} expression - The expression to match against
62322
+ * @returns {boolean} True if current path matches the expression
62323
+ */
62324
+ matches(expression) {
62325
+ const segments = expression.segments;
62326
+ if (segments.length === 0) {
62327
+ return false;
62328
+ }
62329
+ if (expression.hasDeepWildcard()) {
62330
+ return this._matchWithDeepWildcard(segments);
62331
+ }
62332
+ return this._matchSimple(segments);
62333
+ }
62334
+ /**
62335
+ * Match simple path (no deep wildcards)
62336
+ * @private
62337
+ */
62338
+ _matchSimple(segments) {
62339
+ if (this.path.length !== segments.length) {
62340
+ return false;
62341
+ }
62342
+ for (let i4 = 0; i4 < segments.length; i4++) {
62343
+ const segment = segments[i4];
62344
+ const node = this.path[i4];
62345
+ const isCurrentNode = i4 === this.path.length - 1;
62346
+ if (!this._matchSegment(segment, node, isCurrentNode)) {
62347
+ return false;
62348
+ }
62349
+ }
62350
+ return true;
62351
+ }
62352
+ /**
62353
+ * Match path with deep wildcards
62354
+ * @private
62355
+ */
62356
+ _matchWithDeepWildcard(segments) {
62357
+ let pathIdx = this.path.length - 1;
62358
+ let segIdx = segments.length - 1;
62359
+ while (segIdx >= 0 && pathIdx >= 0) {
62360
+ const segment = segments[segIdx];
62361
+ if (segment.type === "deep-wildcard") {
62362
+ segIdx--;
62363
+ if (segIdx < 0) {
62364
+ return true;
62365
+ }
62366
+ const nextSeg = segments[segIdx];
62367
+ let found = false;
62368
+ for (let i4 = pathIdx; i4 >= 0; i4--) {
62369
+ const isCurrentNode = i4 === this.path.length - 1;
62370
+ if (this._matchSegment(nextSeg, this.path[i4], isCurrentNode)) {
62371
+ pathIdx = i4 - 1;
62372
+ segIdx--;
62373
+ found = true;
62374
+ break;
62375
+ }
62376
+ }
62377
+ if (!found) {
62378
+ return false;
62379
+ }
62380
+ } else {
62381
+ const isCurrentNode = pathIdx === this.path.length - 1;
62382
+ if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) {
62383
+ return false;
62384
+ }
62385
+ pathIdx--;
62386
+ segIdx--;
62387
+ }
62388
+ }
62389
+ return segIdx < 0;
62390
+ }
62391
+ /**
62392
+ * Match a single segment against a node
62393
+ * @private
62394
+ * @param {Object} segment - Segment from Expression
62395
+ * @param {Object} node - Node from path
62396
+ * @param {boolean} isCurrentNode - Whether this is the current (last) node
62397
+ * @returns {boolean}
62398
+ */
62399
+ _matchSegment(segment, node, isCurrentNode) {
62400
+ if (segment.tag !== "*" && segment.tag !== node.tag) {
62401
+ return false;
62402
+ }
62403
+ if (segment.namespace !== void 0) {
62404
+ if (segment.namespace !== "*" && segment.namespace !== node.namespace) {
62405
+ return false;
62406
+ }
62407
+ }
62408
+ if (segment.attrName !== void 0) {
62409
+ if (!isCurrentNode) {
62410
+ return false;
62411
+ }
62412
+ if (!node.values || !(segment.attrName in node.values)) {
62413
+ return false;
62414
+ }
62415
+ if (segment.attrValue !== void 0) {
62416
+ const actualValue = node.values[segment.attrName];
62417
+ if (String(actualValue) !== String(segment.attrValue)) {
62418
+ return false;
62419
+ }
62420
+ }
62421
+ }
62422
+ if (segment.position !== void 0) {
62423
+ if (!isCurrentNode) {
62424
+ return false;
62425
+ }
62426
+ const counter2 = node.counter ?? 0;
62427
+ if (segment.position === "first" && counter2 !== 0) {
62428
+ return false;
62429
+ } else if (segment.position === "odd" && counter2 % 2 !== 1) {
62430
+ return false;
62431
+ } else if (segment.position === "even" && counter2 % 2 !== 0) {
62432
+ return false;
62433
+ } else if (segment.position === "nth") {
62434
+ if (counter2 !== segment.positionValue) {
62435
+ return false;
62436
+ }
62437
+ }
62438
+ }
62439
+ return true;
62440
+ }
62441
+ /**
62442
+ * Match any expression in the given set against the current path.
62443
+ * @param {ExpressionSet} exprSet - The set of expressions to match against.
62444
+ * @returns {boolean} - True if any expression in the set matches the current path, false otherwise.
62445
+ */
62446
+ matchesAny(exprSet) {
62447
+ return exprSet.matchesAny(this);
62448
+ }
62449
+ /**
62450
+ * Create a snapshot of current state
62451
+ * @returns {Object} State snapshot
62452
+ */
62453
+ snapshot() {
62454
+ return {
62455
+ path: this.path.map((node) => ({ ...node })),
62456
+ siblingStacks: this.siblingStacks.map((map3) => new Map(map3))
62457
+ };
62458
+ }
62459
+ /**
62460
+ * Restore state from snapshot
62461
+ * @param {Object} snapshot - State snapshot
62462
+ */
62463
+ restore(snapshot) {
62464
+ this._pathStringCache = null;
62465
+ this._frozenPathCache = null;
62466
+ this._frozenSiblingsCache = null;
62467
+ this.path = snapshot.path.map((node) => ({ ...node }));
62468
+ this.siblingStacks = snapshot.siblingStacks.map((map3) => new Map(map3));
62469
+ }
62470
+ /**
62471
+ * Return a read-only view of this matcher.
62472
+ *
62473
+ * The returned object exposes all query/inspection methods but throws a
62474
+ * TypeError if any state-mutating method is called (`push`, `pop`, `reset`,
62475
+ * `updateCurrent`, `restore`). Property reads (e.g. `.path`, `.separator`)
62476
+ * are allowed but the returned arrays/objects are frozen so callers cannot
62477
+ * mutate internal state through them either.
62478
+ *
62479
+ * @returns {ReadOnlyMatcher} A proxy that forwards read operations and blocks writes.
62480
+ *
62481
+ * @example
62482
+ * const matcher = new Matcher();
62483
+ * matcher.push("root", {});
62484
+ *
62485
+ * const ro = matcher.readOnly();
62486
+ * ro.matches(expr); // ✓ works
62487
+ * ro.getCurrentTag(); // ✓ works
62488
+ * ro.push("child", {}); // ✗ throws TypeError
62489
+ * ro.reset(); // ✗ throws TypeError
62490
+ */
62491
+ readOnly() {
62492
+ const self2 = this;
62493
+ return new Proxy(self2, {
62494
+ get(target2, prop, receiver) {
62495
+ if (MUTATING_METHODS.has(prop)) {
62496
+ return () => {
62497
+ throw new TypeError(
62498
+ `Cannot call '${prop}' on a read-only Matcher. Obtain a writable instance to mutate state.`
62499
+ );
62500
+ };
62501
+ }
62502
+ if (prop === "path") {
62503
+ if (target2._frozenPathCache === null) {
62504
+ target2._frozenPathCache = Object.freeze(
62505
+ target2.path.map((node) => Object.freeze({ ...node }))
62506
+ );
62507
+ }
62508
+ return target2._frozenPathCache;
62509
+ }
62510
+ if (prop === "siblingStacks") {
62511
+ if (target2._frozenSiblingsCache === null) {
62512
+ target2._frozenSiblingsCache = Object.freeze(
62513
+ target2.siblingStacks.map((map3) => Object.freeze(new Map(map3)))
62514
+ );
62515
+ }
62516
+ return target2._frozenSiblingsCache;
62517
+ }
62518
+ const value = Reflect.get(target2, prop, receiver);
62519
+ if (typeof value === "function") {
62520
+ return value.bind(target2);
62521
+ }
62522
+ return value;
62523
+ },
62524
+ // Prevent any property assignment on the read-only view
62525
+ set(_target, prop) {
62526
+ throw new TypeError(
62527
+ `Cannot set property '${String(prop)}' on a read-only Matcher.`
62528
+ );
62529
+ },
62530
+ // Prevent property deletion
62531
+ deleteProperty(_target, prop) {
62532
+ throw new TypeError(
62533
+ `Cannot delete property '${String(prop)}' from a read-only Matcher.`
62534
+ );
62535
+ }
62536
+ });
62537
+ }
62538
+ };
62539
+
61486
62540
  // ../../node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js
62541
+ function extractRawAttributes(prefixedAttrs, options) {
62542
+ if (!prefixedAttrs)
62543
+ return {};
62544
+ const attrs = options.attributesGroupName ? prefixedAttrs[options.attributesGroupName] : prefixedAttrs;
62545
+ if (!attrs)
62546
+ return {};
62547
+ const rawAttrs = {};
62548
+ for (const key in attrs) {
62549
+ if (key.startsWith(options.attributeNamePrefix)) {
62550
+ const rawName = key.substring(options.attributeNamePrefix.length);
62551
+ rawAttrs[rawName] = attrs[key];
62552
+ } else {
62553
+ rawAttrs[key] = attrs[key];
62554
+ }
62555
+ }
62556
+ return rawAttrs;
62557
+ }
62558
+ function extractNamespace(rawTagName) {
62559
+ if (!rawTagName || typeof rawTagName !== "string")
62560
+ return void 0;
62561
+ const colonIndex = rawTagName.indexOf(":");
62562
+ if (colonIndex !== -1 && colonIndex > 0) {
62563
+ const ns = rawTagName.substring(0, colonIndex);
62564
+ if (ns !== "xmlns") {
62565
+ return ns;
62566
+ }
62567
+ }
62568
+ return void 0;
62569
+ }
61487
62570
  var OrderedObjParser = class {
61488
62571
  constructor(options) {
61489
62572
  this.options = options;
@@ -61527,19 +62610,21 @@ void main(void) {
61527
62610
  this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
61528
62611
  this.entityExpansionCount = 0;
61529
62612
  this.currentExpandedLength = 0;
61530
- if (this.options.stopNodes && this.options.stopNodes.length > 0) {
61531
- this.stopNodesExact = /* @__PURE__ */ new Set();
61532
- this.stopNodesWildcard = /* @__PURE__ */ new Set();
61533
- for (let i4 = 0; i4 < this.options.stopNodes.length; i4++) {
61534
- const stopNodeExp = this.options.stopNodes[i4];
61535
- if (typeof stopNodeExp !== "string")
61536
- continue;
61537
- if (stopNodeExp.startsWith("*.")) {
61538
- this.stopNodesWildcard.add(stopNodeExp.substring(2));
61539
- } else {
61540
- this.stopNodesExact.add(stopNodeExp);
62613
+ this.matcher = new Matcher();
62614
+ this.readonlyMatcher = this.matcher.readOnly();
62615
+ this.isCurrentNodeStopNode = false;
62616
+ this.stopNodeExpressionsSet = new ExpressionSet();
62617
+ const stopNodesOpts = this.options.stopNodes;
62618
+ if (stopNodesOpts && stopNodesOpts.length > 0) {
62619
+ for (let i4 = 0; i4 < stopNodesOpts.length; i4++) {
62620
+ const stopNodeExp = stopNodesOpts[i4];
62621
+ if (typeof stopNodeExp === "string") {
62622
+ this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));
62623
+ } else if (stopNodeExp instanceof Expression) {
62624
+ this.stopNodeExpressionsSet.add(stopNodeExp);
61541
62625
  }
61542
62626
  }
62627
+ this.stopNodeExpressionsSet.seal();
61543
62628
  }
61544
62629
  }
61545
62630
  };
@@ -61555,24 +62640,26 @@ void main(void) {
61555
62640
  }
61556
62641
  }
61557
62642
  function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {
62643
+ const options = this.options;
61558
62644
  if (val !== void 0) {
61559
- if (this.options.trimValues && !dontTrim) {
62645
+ if (options.trimValues && !dontTrim) {
61560
62646
  val = val.trim();
61561
62647
  }
61562
62648
  if (val.length > 0) {
61563
62649
  if (!escapeEntities)
61564
62650
  val = this.replaceEntitiesValue(val, tagName, jPath);
61565
- const newval = this.options.tagValueProcessor(tagName, val, jPath, hasAttributes, isLeafNode);
62651
+ const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;
62652
+ const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);
61566
62653
  if (newval === null || newval === void 0) {
61567
62654
  return val;
61568
62655
  } else if (typeof newval !== typeof val || newval !== val) {
61569
62656
  return newval;
61570
- } else if (this.options.trimValues) {
61571
- return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);
62657
+ } else if (options.trimValues) {
62658
+ return parseValue(val, options.parseTagValue, options.numberParseOptions);
61572
62659
  } else {
61573
62660
  const trimmedVal = val.trim();
61574
62661
  if (trimmedVal === val) {
61575
- return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);
62662
+ return parseValue(val, options.parseTagValue, options.numberParseOptions);
61576
62663
  } else {
61577
62664
  return val;
61578
62665
  }
@@ -61595,51 +62682,64 @@ void main(void) {
61595
62682
  }
61596
62683
  var attrsRegx = new RegExp(`([^\\s=]+)\\s*(=\\s*(['"])([\\s\\S]*?)\\3)?`, "gm");
61597
62684
  function buildAttributesMap(attrStr, jPath, tagName) {
61598
- if (this.options.ignoreAttributes !== true && typeof attrStr === "string") {
62685
+ const options = this.options;
62686
+ if (options.ignoreAttributes !== true && typeof attrStr === "string") {
61599
62687
  const matches3 = getAllMatches(attrStr, attrsRegx);
61600
62688
  const len5 = matches3.length;
61601
62689
  const attrs = {};
62690
+ const processedVals = new Array(len5);
62691
+ let hasRawAttrs = false;
62692
+ const rawAttrsForMatcher = {};
62693
+ for (let i4 = 0; i4 < len5; i4++) {
62694
+ const attrName = this.resolveNameSpace(matches3[i4][1]);
62695
+ const oldVal = matches3[i4][4];
62696
+ if (attrName.length && oldVal !== void 0) {
62697
+ let val = oldVal;
62698
+ if (options.trimValues)
62699
+ val = val.trim();
62700
+ val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);
62701
+ processedVals[i4] = val;
62702
+ rawAttrsForMatcher[attrName] = val;
62703
+ hasRawAttrs = true;
62704
+ }
62705
+ }
62706
+ if (hasRawAttrs && typeof jPath === "object" && jPath.updateCurrent) {
62707
+ jPath.updateCurrent(rawAttrsForMatcher);
62708
+ }
62709
+ const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;
62710
+ let hasAttrs = false;
61602
62711
  for (let i4 = 0; i4 < len5; i4++) {
61603
62712
  const attrName = this.resolveNameSpace(matches3[i4][1]);
61604
- if (this.ignoreAttributesFn(attrName, jPath)) {
62713
+ if (this.ignoreAttributesFn(attrName, jPathStr))
61605
62714
  continue;
61606
- }
61607
- let oldVal = matches3[i4][4];
61608
- let aName = this.options.attributeNamePrefix + attrName;
62715
+ let aName = options.attributeNamePrefix + attrName;
61609
62716
  if (attrName.length) {
61610
- if (this.options.transformAttributeName) {
61611
- aName = this.options.transformAttributeName(aName);
61612
- }
61613
- if (aName === "__proto__")
61614
- aName = "#__proto__";
61615
- if (oldVal !== void 0) {
61616
- if (this.options.trimValues) {
61617
- oldVal = oldVal.trim();
61618
- }
61619
- oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath);
61620
- const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPath);
62717
+ if (options.transformAttributeName) {
62718
+ aName = options.transformAttributeName(aName);
62719
+ }
62720
+ aName = sanitizeName(aName, options);
62721
+ if (matches3[i4][4] !== void 0) {
62722
+ const oldVal = processedVals[i4];
62723
+ const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);
61621
62724
  if (newVal === null || newVal === void 0) {
61622
62725
  attrs[aName] = oldVal;
61623
62726
  } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {
61624
62727
  attrs[aName] = newVal;
61625
62728
  } else {
61626
- attrs[aName] = parseValue(
61627
- oldVal,
61628
- this.options.parseAttributeValue,
61629
- this.options.numberParseOptions
61630
- );
62729
+ attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);
61631
62730
  }
61632
- } else if (this.options.allowBooleanAttributes) {
62731
+ hasAttrs = true;
62732
+ } else if (options.allowBooleanAttributes) {
61633
62733
  attrs[aName] = true;
62734
+ hasAttrs = true;
61634
62735
  }
61635
62736
  }
61636
62737
  }
61637
- if (!Object.keys(attrs).length) {
62738
+ if (!hasAttrs)
61638
62739
  return;
61639
- }
61640
- if (this.options.attributesGroupName) {
62740
+ if (options.attributesGroupName) {
61641
62741
  const attrCollection = {};
61642
- attrCollection[this.options.attributesGroupName] = attrs;
62742
+ attrCollection[options.attributesGroupName] = attrs;
61643
62743
  return attrCollection;
61644
62744
  }
61645
62745
  return attrs;
@@ -61650,123 +62750,144 @@ void main(void) {
61650
62750
  const xmlObj = new XmlNode("!xml");
61651
62751
  let currentNode = xmlObj;
61652
62752
  let textData = "";
61653
- let jPath = "";
62753
+ this.matcher.reset();
61654
62754
  this.entityExpansionCount = 0;
61655
62755
  this.currentExpandedLength = 0;
61656
- const docTypeReader = new DocTypeReader(this.options.processEntities);
61657
- for (let i4 = 0; i4 < xmlData.length; i4++) {
62756
+ this.docTypeEntitiesKeys = [];
62757
+ this.lastEntitiesKeys = Object.keys(this.lastEntities);
62758
+ this.htmlEntitiesKeys = this.options.htmlEntities ? Object.keys(this.htmlEntities) : [];
62759
+ const options = this.options;
62760
+ const docTypeReader = new DocTypeReader(options.processEntities);
62761
+ const xmlLen = xmlData.length;
62762
+ for (let i4 = 0; i4 < xmlLen; i4++) {
61658
62763
  const ch = xmlData[i4];
61659
62764
  if (ch === "<") {
61660
- if (xmlData[i4 + 1] === "/") {
62765
+ const c1 = xmlData.charCodeAt(i4 + 1);
62766
+ if (c1 === 47) {
61661
62767
  const closeIndex = findClosingIndex(xmlData, ">", i4, "Closing Tag is not closed.");
61662
62768
  let tagName = xmlData.substring(i4 + 2, closeIndex).trim();
61663
- if (this.options.removeNSPrefix) {
62769
+ if (options.removeNSPrefix) {
61664
62770
  const colonIndex = tagName.indexOf(":");
61665
62771
  if (colonIndex !== -1) {
61666
62772
  tagName = tagName.substr(colonIndex + 1);
61667
62773
  }
61668
62774
  }
61669
- if (this.options.transformTagName) {
61670
- tagName = this.options.transformTagName(tagName);
61671
- }
62775
+ tagName = transformTagName(options.transformTagName, tagName, "", options).tagName;
61672
62776
  if (currentNode) {
61673
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
62777
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
61674
62778
  }
61675
- const lastTagName = jPath.substring(jPath.lastIndexOf(".") + 1);
61676
- if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) {
62779
+ const lastTagName = this.matcher.getCurrentTag();
62780
+ if (tagName && options.unpairedTagsSet.has(tagName)) {
61677
62781
  throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
61678
62782
  }
61679
- let propIndex = 0;
61680
- if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) {
61681
- propIndex = jPath.lastIndexOf(".", jPath.lastIndexOf(".") - 1);
62783
+ if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {
62784
+ this.matcher.pop();
61682
62785
  this.tagsNodeStack.pop();
61683
- } else {
61684
- propIndex = jPath.lastIndexOf(".");
61685
62786
  }
61686
- jPath = jPath.substring(0, propIndex);
62787
+ this.matcher.pop();
62788
+ this.isCurrentNodeStopNode = false;
61687
62789
  currentNode = this.tagsNodeStack.pop();
61688
62790
  textData = "";
61689
62791
  i4 = closeIndex;
61690
- } else if (xmlData[i4 + 1] === "?") {
62792
+ } else if (c1 === 63) {
61691
62793
  let tagData = readTagExp(xmlData, i4, false, "?>");
61692
62794
  if (!tagData)
61693
62795
  throw new Error("Pi Tag is not closed.");
61694
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
61695
- if (this.options.ignoreDeclaration && tagData.tagName === "?xml" || this.options.ignorePiTags) {
62796
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
62797
+ if (options.ignoreDeclaration && tagData.tagName === "?xml" || options.ignorePiTags) {
61696
62798
  } else {
61697
62799
  const childNode = new XmlNode(tagData.tagName);
61698
- childNode.add(this.options.textNodeName, "");
62800
+ childNode.add(options.textNodeName, "");
61699
62801
  if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) {
61700
- childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
62802
+ childNode[":@"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName);
61701
62803
  }
61702
- this.addChild(currentNode, childNode, jPath, i4);
62804
+ this.addChild(currentNode, childNode, this.readonlyMatcher, i4);
61703
62805
  }
61704
62806
  i4 = tagData.closeIndex + 1;
61705
- } else if (xmlData.substr(i4 + 1, 3) === "!--") {
62807
+ } else if (c1 === 33 && xmlData.charCodeAt(i4 + 2) === 45 && xmlData.charCodeAt(i4 + 3) === 45) {
61706
62808
  const endIndex = findClosingIndex(xmlData, "-->", i4 + 4, "Comment is not closed.");
61707
- if (this.options.commentPropName) {
62809
+ if (options.commentPropName) {
61708
62810
  const comment = xmlData.substring(i4 + 4, endIndex - 2);
61709
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
61710
- currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]);
62811
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
62812
+ currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);
61711
62813
  }
61712
62814
  i4 = endIndex;
61713
- } else if (xmlData.substr(i4 + 1, 2) === "!D") {
62815
+ } else if (c1 === 33 && xmlData.charCodeAt(i4 + 2) === 68) {
61714
62816
  const result = docTypeReader.readDocType(xmlData, i4);
61715
62817
  this.docTypeEntities = result.entities;
62818
+ this.docTypeEntitiesKeys = Object.keys(this.docTypeEntities) || [];
61716
62819
  i4 = result.i;
61717
- } else if (xmlData.substr(i4 + 1, 2) === "![") {
62820
+ } else if (c1 === 33 && xmlData.charCodeAt(i4 + 2) === 91) {
61718
62821
  const closeIndex = findClosingIndex(xmlData, "]]>", i4, "CDATA is not closed.") - 2;
61719
62822
  const tagExp = xmlData.substring(i4 + 9, closeIndex);
61720
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
61721
- let val = this.parseTextData(tagExp, currentNode.tagname, jPath, true, false, true, true);
62823
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
62824
+ let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);
61722
62825
  if (val == void 0)
61723
62826
  val = "";
61724
- if (this.options.cdataPropName) {
61725
- currentNode.add(this.options.cdataPropName, [{ [this.options.textNodeName]: tagExp }]);
62827
+ if (options.cdataPropName) {
62828
+ currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);
61726
62829
  } else {
61727
- currentNode.add(this.options.textNodeName, val);
62830
+ currentNode.add(options.textNodeName, val);
61728
62831
  }
61729
62832
  i4 = closeIndex + 2;
61730
62833
  } else {
61731
- let result = readTagExp(xmlData, i4, this.options.removeNSPrefix);
62834
+ let result = readTagExp(xmlData, i4, options.removeNSPrefix);
62835
+ if (!result) {
62836
+ const context = xmlData.substring(Math.max(0, i4 - 50), Math.min(xmlLen, i4 + 50));
62837
+ throw new Error(`readTagExp returned undefined at position ${i4}. Context: "${context}"`);
62838
+ }
61732
62839
  let tagName = result.tagName;
61733
62840
  const rawTagName = result.rawTagName;
61734
62841
  let tagExp = result.tagExp;
61735
62842
  let attrExpPresent = result.attrExpPresent;
61736
62843
  let closeIndex = result.closeIndex;
61737
- if (this.options.transformTagName) {
61738
- const newTagName = this.options.transformTagName(tagName);
61739
- if (tagExp === tagName) {
61740
- tagExp = newTagName;
61741
- }
61742
- tagName = newTagName;
62844
+ ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));
62845
+ if (options.strictReservedNames && (tagName === options.commentPropName || tagName === options.cdataPropName || tagName === options.textNodeName || tagName === options.attributesGroupName)) {
62846
+ throw new Error(`Invalid tag name: ${tagName}`);
61743
62847
  }
61744
62848
  if (currentNode && textData) {
61745
62849
  if (currentNode.tagname !== "!xml") {
61746
- textData = this.saveTextToParentTag(textData, currentNode, jPath, false);
62850
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);
61747
62851
  }
61748
62852
  }
61749
62853
  const lastTag = currentNode;
61750
- if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) {
62854
+ if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {
61751
62855
  currentNode = this.tagsNodeStack.pop();
61752
- jPath = jPath.substring(0, jPath.lastIndexOf("."));
62856
+ this.matcher.pop();
62857
+ }
62858
+ let isSelfClosing = false;
62859
+ if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
62860
+ isSelfClosing = true;
62861
+ if (tagName[tagName.length - 1] === "/") {
62862
+ tagName = tagName.substr(0, tagName.length - 1);
62863
+ tagExp = tagName;
62864
+ } else {
62865
+ tagExp = tagExp.substr(0, tagExp.length - 1);
62866
+ }
62867
+ attrExpPresent = tagName !== tagExp;
61753
62868
  }
62869
+ let prefixedAttrs = null;
62870
+ let rawAttrs = {};
62871
+ let namespace = void 0;
62872
+ namespace = extractNamespace(rawTagName);
61754
62873
  if (tagName !== xmlObj.tagname) {
61755
- jPath += jPath ? "." + tagName : tagName;
62874
+ this.matcher.push(tagName, {}, namespace);
62875
+ }
62876
+ if (tagName !== tagExp && attrExpPresent) {
62877
+ prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);
62878
+ if (prefixedAttrs) {
62879
+ rawAttrs = extractRawAttributes(prefixedAttrs, options);
62880
+ }
62881
+ }
62882
+ if (tagName !== xmlObj.tagname) {
62883
+ this.isCurrentNodeStopNode = this.isItStopNode();
61756
62884
  }
61757
62885
  const startIndex = i4;
61758
- if (this.isItStopNode(this.stopNodesExact, this.stopNodesWildcard, jPath, tagName)) {
62886
+ if (this.isCurrentNodeStopNode) {
61759
62887
  let tagContent = "";
61760
- if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
61761
- if (tagName[tagName.length - 1] === "/") {
61762
- tagName = tagName.substr(0, tagName.length - 1);
61763
- jPath = jPath.substr(0, jPath.length - 1);
61764
- tagExp = tagName;
61765
- } else {
61766
- tagExp = tagExp.substr(0, tagExp.length - 1);
61767
- }
62888
+ if (isSelfClosing) {
61768
62889
  i4 = result.closeIndex;
61769
- } else if (this.options.unpairedTags.indexOf(tagName) !== -1) {
62890
+ } else if (options.unpairedTagsSet.has(tagName)) {
61770
62891
  i4 = result.closeIndex;
61771
62892
  } else {
61772
62893
  const result2 = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);
@@ -61776,44 +62897,43 @@ void main(void) {
61776
62897
  tagContent = result2.tagContent;
61777
62898
  }
61778
62899
  const childNode = new XmlNode(tagName);
61779
- if (tagName !== tagExp && attrExpPresent) {
61780
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
61781
- }
61782
- if (tagContent) {
61783
- tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
62900
+ if (prefixedAttrs) {
62901
+ childNode[":@"] = prefixedAttrs;
61784
62902
  }
61785
- jPath = jPath.substr(0, jPath.lastIndexOf("."));
61786
- childNode.add(this.options.textNodeName, tagContent);
61787
- this.addChild(currentNode, childNode, jPath, startIndex);
62903
+ childNode.add(options.textNodeName, tagContent);
62904
+ this.matcher.pop();
62905
+ this.isCurrentNodeStopNode = false;
62906
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
61788
62907
  } else {
61789
- if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
61790
- if (tagName[tagName.length - 1] === "/") {
61791
- tagName = tagName.substr(0, tagName.length - 1);
61792
- jPath = jPath.substr(0, jPath.length - 1);
61793
- tagExp = tagName;
61794
- } else {
61795
- tagExp = tagExp.substr(0, tagExp.length - 1);
61796
- }
61797
- if (this.options.transformTagName) {
61798
- const newTagName = this.options.transformTagName(tagName);
61799
- if (tagExp === tagName) {
61800
- tagExp = newTagName;
61801
- }
61802
- tagName = newTagName;
62908
+ if (isSelfClosing) {
62909
+ ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));
62910
+ const childNode = new XmlNode(tagName);
62911
+ if (prefixedAttrs) {
62912
+ childNode[":@"] = prefixedAttrs;
61803
62913
  }
62914
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
62915
+ this.matcher.pop();
62916
+ this.isCurrentNodeStopNode = false;
62917
+ } else if (options.unpairedTagsSet.has(tagName)) {
61804
62918
  const childNode = new XmlNode(tagName);
61805
- if (tagName !== tagExp && attrExpPresent) {
61806
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
62919
+ if (prefixedAttrs) {
62920
+ childNode[":@"] = prefixedAttrs;
61807
62921
  }
61808
- this.addChild(currentNode, childNode, jPath, startIndex);
61809
- jPath = jPath.substr(0, jPath.lastIndexOf("."));
62922
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
62923
+ this.matcher.pop();
62924
+ this.isCurrentNodeStopNode = false;
62925
+ i4 = result.closeIndex;
62926
+ continue;
61810
62927
  } else {
61811
62928
  const childNode = new XmlNode(tagName);
62929
+ if (this.tagsNodeStack.length > options.maxNestedTags) {
62930
+ throw new Error("Maximum nested tags exceeded");
62931
+ }
61812
62932
  this.tagsNodeStack.push(currentNode);
61813
- if (tagName !== tagExp && attrExpPresent) {
61814
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
62933
+ if (prefixedAttrs) {
62934
+ childNode[":@"] = prefixedAttrs;
61815
62935
  }
61816
- this.addChild(currentNode, childNode, jPath, startIndex);
62936
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
61817
62937
  currentNode = childNode;
61818
62938
  }
61819
62939
  textData = "";
@@ -61826,10 +62946,11 @@ void main(void) {
61826
62946
  }
61827
62947
  return xmlObj.child;
61828
62948
  };
61829
- function addChild(currentNode, childNode, jPath, startIndex) {
62949
+ function addChild(currentNode, childNode, matcher, startIndex) {
61830
62950
  if (!this.options.captureMetaData)
61831
62951
  startIndex = void 0;
61832
- const result = this.options.updateTag(childNode.tagname, jPath, childNode[":@"]);
62952
+ const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;
62953
+ const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[":@"]);
61833
62954
  if (result === false) {
61834
62955
  } else if (typeof result === "string") {
61835
62956
  childNode.tagname = result;
@@ -61838,25 +62959,25 @@ void main(void) {
61838
62959
  currentNode.addChild(childNode, startIndex);
61839
62960
  }
61840
62961
  }
61841
- var replaceEntitiesValue = function(val, tagName, jPath) {
61842
- if (val.indexOf("&") === -1) {
61843
- return val;
61844
- }
62962
+ function replaceEntitiesValue(val, tagName, jPath) {
61845
62963
  const entityConfig = this.options.processEntities;
61846
- if (!entityConfig.enabled) {
62964
+ if (!entityConfig || !entityConfig.enabled) {
61847
62965
  return val;
61848
62966
  }
61849
62967
  if (entityConfig.allowedTags) {
61850
- if (!entityConfig.allowedTags.includes(tagName)) {
62968
+ const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
62969
+ const allowed = Array.isArray(entityConfig.allowedTags) ? entityConfig.allowedTags.includes(tagName) : entityConfig.allowedTags(tagName, jPathOrMatcher);
62970
+ if (!allowed) {
61851
62971
  return val;
61852
62972
  }
61853
62973
  }
61854
62974
  if (entityConfig.tagFilter) {
61855
- if (!entityConfig.tagFilter(tagName, jPath)) {
62975
+ const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
62976
+ if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {
61856
62977
  return val;
61857
62978
  }
61858
62979
  }
61859
- for (let entityName in this.docTypeEntities) {
62980
+ for (const entityName of this.docTypeEntitiesKeys) {
61860
62981
  const entity = this.docTypeEntities[entityName];
61861
62982
  const matches3 = val.match(entity.regx);
61862
62983
  if (matches3) {
@@ -61880,74 +63001,86 @@ void main(void) {
61880
63001
  }
61881
63002
  if (val.indexOf("&") === -1)
61882
63003
  return val;
61883
- for (let entityName in this.lastEntities) {
63004
+ for (const entityName of this.lastEntitiesKeys) {
61884
63005
  const entity = this.lastEntities[entityName];
63006
+ const matches3 = val.match(entity.regex);
63007
+ if (matches3) {
63008
+ this.entityExpansionCount += matches3.length;
63009
+ if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) {
63010
+ throw new Error(
63011
+ `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
63012
+ );
63013
+ }
63014
+ }
61885
63015
  val = val.replace(entity.regex, entity.val);
61886
63016
  }
61887
63017
  if (val.indexOf("&") === -1)
61888
63018
  return val;
61889
- if (this.options.htmlEntities) {
61890
- for (let entityName in this.htmlEntities) {
61891
- const entity = this.htmlEntities[entityName];
61892
- val = val.replace(entity.regex, entity.val);
63019
+ for (const entityName of this.htmlEntitiesKeys) {
63020
+ const entity = this.htmlEntities[entityName];
63021
+ const matches3 = val.match(entity.regex);
63022
+ if (matches3) {
63023
+ this.entityExpansionCount += matches3.length;
63024
+ if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) {
63025
+ throw new Error(
63026
+ `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
63027
+ );
63028
+ }
61893
63029
  }
63030
+ val = val.replace(entity.regex, entity.val);
61894
63031
  }
61895
63032
  val = val.replace(this.ampEntity.regex, this.ampEntity.val);
61896
63033
  return val;
61897
- };
61898
- function saveTextToParentTag(textData, currentNode, jPath, isLeafNode) {
63034
+ }
63035
+ function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {
61899
63036
  if (textData) {
61900
63037
  if (isLeafNode === void 0)
61901
- isLeafNode = currentNode.child.length === 0;
63038
+ isLeafNode = parentNode.child.length === 0;
61902
63039
  textData = this.parseTextData(
61903
63040
  textData,
61904
- currentNode.tagname,
61905
- jPath,
63041
+ parentNode.tagname,
63042
+ matcher,
61906
63043
  false,
61907
- currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false,
63044
+ parentNode[":@"] ? Object.keys(parentNode[":@"]).length !== 0 : false,
61908
63045
  isLeafNode
61909
63046
  );
61910
63047
  if (textData !== void 0 && textData !== "")
61911
- currentNode.add(this.options.textNodeName, textData);
63048
+ parentNode.add(this.options.textNodeName, textData);
61912
63049
  textData = "";
61913
63050
  }
61914
63051
  return textData;
61915
63052
  }
61916
- function isItStopNode(stopNodesExact, stopNodesWildcard, jPath, currentTagName) {
61917
- if (stopNodesWildcard && stopNodesWildcard.has(currentTagName))
61918
- return true;
61919
- if (stopNodesExact && stopNodesExact.has(jPath))
61920
- return true;
61921
- return false;
63053
+ function isItStopNode() {
63054
+ if (this.stopNodeExpressionsSet.size === 0)
63055
+ return false;
63056
+ return this.matcher.matchesAny(this.stopNodeExpressionsSet);
61922
63057
  }
61923
63058
  function tagExpWithClosingIndex(xmlData, i4, closingChar = ">") {
61924
- let attrBoundary;
61925
- let tagExp = "";
61926
- for (let index = i4; index < xmlData.length; index++) {
61927
- let ch = xmlData[index];
63059
+ let attrBoundary = 0;
63060
+ const chars = [];
63061
+ const len5 = xmlData.length;
63062
+ const closeCode0 = closingChar.charCodeAt(0);
63063
+ const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;
63064
+ for (let index = i4; index < len5; index++) {
63065
+ const code = xmlData.charCodeAt(index);
61928
63066
  if (attrBoundary) {
61929
- if (ch === attrBoundary)
61930
- attrBoundary = "";
61931
- } else if (ch === '"' || ch === "'") {
61932
- attrBoundary = ch;
61933
- } else if (ch === closingChar[0]) {
61934
- if (closingChar[1]) {
61935
- if (xmlData[index + 1] === closingChar[1]) {
61936
- return {
61937
- data: tagExp,
61938
- index
61939
- };
63067
+ if (code === attrBoundary)
63068
+ attrBoundary = 0;
63069
+ } else if (code === 34 || code === 39) {
63070
+ attrBoundary = code;
63071
+ } else if (code === closeCode0) {
63072
+ if (closeCode1 !== -1) {
63073
+ if (xmlData.charCodeAt(index + 1) === closeCode1) {
63074
+ return { data: String.fromCharCode(...chars), index };
61940
63075
  }
61941
63076
  } else {
61942
- return {
61943
- data: tagExp,
61944
- index
61945
- };
63077
+ return { data: String.fromCharCode(...chars), index };
61946
63078
  }
61947
- } else if (ch === " ") {
61948
- ch = " ";
63079
+ } else if (code === 9) {
63080
+ chars.push(32);
63081
+ continue;
61949
63082
  }
61950
- tagExp += ch;
63083
+ chars.push(code);
61951
63084
  }
61952
63085
  }
61953
63086
  function findClosingIndex(xmlData, str6, i4, errMsg) {
@@ -61958,6 +63091,12 @@ void main(void) {
61958
63091
  return closingIndex + str6.length - 1;
61959
63092
  }
61960
63093
  }
63094
+ function findClosingChar(xmlData, char, i4, errMsg) {
63095
+ const closingIndex = xmlData.indexOf(char, i4);
63096
+ if (closingIndex === -1)
63097
+ throw new Error(errMsg);
63098
+ return closingIndex;
63099
+ }
61961
63100
  function readTagExp(xmlData, i4, removeNSPrefix, closingChar = ">") {
61962
63101
  const result = tagExpWithClosingIndex(xmlData, i4 + 1, closingChar);
61963
63102
  if (!result)
@@ -61990,10 +63129,12 @@ void main(void) {
61990
63129
  function readStopNodeData(xmlData, tagName, i4) {
61991
63130
  const startIndex = i4;
61992
63131
  let openTagCount = 1;
61993
- for (; i4 < xmlData.length; i4++) {
63132
+ const xmllen = xmlData.length;
63133
+ for (; i4 < xmllen; i4++) {
61994
63134
  if (xmlData[i4] === "<") {
61995
- if (xmlData[i4 + 1] === "/") {
61996
- const closeIndex = findClosingIndex(xmlData, ">", i4, `${tagName} is not closed`);
63135
+ const c1 = xmlData.charCodeAt(i4 + 1);
63136
+ if (c1 === 47) {
63137
+ const closeIndex = findClosingChar(xmlData, ">", i4, `${tagName} is not closed`);
61997
63138
  let closeTagName = xmlData.substring(i4 + 2, closeIndex).trim();
61998
63139
  if (closeTagName === tagName) {
61999
63140
  openTagCount--;
@@ -62005,13 +63146,13 @@ void main(void) {
62005
63146
  }
62006
63147
  }
62007
63148
  i4 = closeIndex;
62008
- } else if (xmlData[i4 + 1] === "?") {
63149
+ } else if (c1 === 63) {
62009
63150
  const closeIndex = findClosingIndex(xmlData, "?>", i4 + 1, "StopNode is not closed.");
62010
63151
  i4 = closeIndex;
62011
- } else if (xmlData.substr(i4 + 1, 3) === "!--") {
63152
+ } else if (c1 === 33 && xmlData.charCodeAt(i4 + 2) === 45 && xmlData.charCodeAt(i4 + 3) === 45) {
62012
63153
  const closeIndex = findClosingIndex(xmlData, "-->", i4 + 3, "StopNode is not closed.");
62013
63154
  i4 = closeIndex;
62014
- } else if (xmlData.substr(i4 + 1, 2) === "![") {
63155
+ } else if (c1 === 33 && xmlData.charCodeAt(i4 + 2) === 91) {
62015
63156
  const closeIndex = findClosingIndex(xmlData, "]]>", i4, "StopNode is not closed.") - 2;
62016
63157
  i4 = closeIndex;
62017
63158
  } else {
@@ -62052,23 +63193,60 @@ void main(void) {
62052
63193
  return prefix + str6 + ";";
62053
63194
  }
62054
63195
  }
63196
+ function transformTagName(fn, tagName, tagExp, options) {
63197
+ if (fn) {
63198
+ const newTagName = fn(tagName);
63199
+ if (tagExp === tagName) {
63200
+ tagExp = newTagName;
63201
+ }
63202
+ tagName = newTagName;
63203
+ }
63204
+ tagName = sanitizeName(tagName, options);
63205
+ return { tagName, tagExp };
63206
+ }
63207
+ function sanitizeName(name13, options) {
63208
+ if (criticalProperties.includes(name13)) {
63209
+ throw new Error(`[SECURITY] Invalid name: "${name13}" is a reserved JavaScript keyword that could cause prototype pollution`);
63210
+ } else if (DANGEROUS_PROPERTY_NAMES.includes(name13)) {
63211
+ return options.onDangerousProperty(name13);
63212
+ }
63213
+ return name13;
63214
+ }
62055
63215
 
62056
63216
  // ../../node_modules/fast-xml-parser/src/xmlparser/node2json.js
62057
63217
  var METADATA_SYMBOL2 = XmlNode.getMetaDataSymbol();
62058
- function prettify(node, options) {
62059
- return compress(node, options);
63218
+ function stripAttributePrefix(attrs, prefix) {
63219
+ if (!attrs || typeof attrs !== "object")
63220
+ return {};
63221
+ if (!prefix)
63222
+ return attrs;
63223
+ const rawAttrs = {};
63224
+ for (const key in attrs) {
63225
+ if (key.startsWith(prefix)) {
63226
+ const rawName = key.substring(prefix.length);
63227
+ rawAttrs[rawName] = attrs[key];
63228
+ } else {
63229
+ rawAttrs[key] = attrs[key];
63230
+ }
63231
+ }
63232
+ return rawAttrs;
63233
+ }
63234
+ function prettify(node, options, matcher, readonlyMatcher) {
63235
+ return compress(node, options, matcher, readonlyMatcher);
62060
63236
  }
62061
- function compress(arr, options, jPath) {
63237
+ function compress(arr, options, matcher, readonlyMatcher) {
62062
63238
  let text;
62063
63239
  const compressedObj = {};
62064
63240
  for (let i4 = 0; i4 < arr.length; i4++) {
62065
63241
  const tagObj = arr[i4];
62066
63242
  const property = propName(tagObj);
62067
- let newJpath = "";
62068
- if (jPath === void 0)
62069
- newJpath = property;
62070
- else
62071
- newJpath = jPath + "." + property;
63243
+ if (property !== void 0 && property !== options.textNodeName) {
63244
+ const rawAttrs = stripAttributePrefix(
63245
+ tagObj[":@"] || {},
63246
+ options.attributeNamePrefix
63247
+ );
63248
+ matcher.push(property, rawAttrs);
63249
+ }
62072
63250
  if (property === options.textNodeName) {
62073
63251
  if (text === void 0)
62074
63252
  text = tagObj[property];
@@ -62077,13 +63255,10 @@ void main(void) {
62077
63255
  } else if (property === void 0) {
62078
63256
  continue;
62079
63257
  } else if (tagObj[property]) {
62080
- let val = compress(tagObj[property], options, newJpath);
63258
+ let val = compress(tagObj[property], options, matcher, readonlyMatcher);
62081
63259
  const isLeaf = isLeafTag(val, options);
62082
- if (tagObj[METADATA_SYMBOL2] !== void 0) {
62083
- val[METADATA_SYMBOL2] = tagObj[METADATA_SYMBOL2];
62084
- }
62085
63260
  if (tagObj[":@"]) {
62086
- assignAttributes(val, tagObj[":@"], newJpath, options);
63261
+ assignAttributes(val, tagObj[":@"], readonlyMatcher, options);
62087
63262
  } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== void 0 && !options.alwaysCreateTextNode) {
62088
63263
  val = val[options.textNodeName];
62089
63264
  } else if (Object.keys(val).length === 0) {
@@ -62092,18 +63267,25 @@ void main(void) {
62092
63267
  else
62093
63268
  val = "";
62094
63269
  }
62095
- if (compressedObj[property] !== void 0 && compressedObj.hasOwnProperty(property)) {
63270
+ if (tagObj[METADATA_SYMBOL2] !== void 0 && typeof val === "object" && val !== null) {
63271
+ val[METADATA_SYMBOL2] = tagObj[METADATA_SYMBOL2];
63272
+ }
63273
+ if (compressedObj[property] !== void 0 && Object.prototype.hasOwnProperty.call(compressedObj, property)) {
62096
63274
  if (!Array.isArray(compressedObj[property])) {
62097
63275
  compressedObj[property] = [compressedObj[property]];
62098
63276
  }
62099
63277
  compressedObj[property].push(val);
62100
63278
  } else {
62101
- if (options.isArray(property, newJpath, isLeaf)) {
63279
+ const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;
63280
+ if (options.isArray(property, jPathOrMatcher, isLeaf)) {
62102
63281
  compressedObj[property] = [val];
62103
63282
  } else {
62104
63283
  compressedObj[property] = val;
62105
63284
  }
62106
63285
  }
63286
+ if (property !== void 0 && property !== options.textNodeName) {
63287
+ matcher.pop();
63288
+ }
62107
63289
  }
62108
63290
  }
62109
63291
  if (typeof text === "string") {
@@ -62121,13 +63303,15 @@ void main(void) {
62121
63303
  return key;
62122
63304
  }
62123
63305
  }
62124
- function assignAttributes(obj, attrMap, jpath, options) {
63306
+ function assignAttributes(obj, attrMap, readonlyMatcher, options) {
62125
63307
  if (attrMap) {
62126
63308
  const keys = Object.keys(attrMap);
62127
63309
  const len5 = keys.length;
62128
63310
  for (let i4 = 0; i4 < len5; i4++) {
62129
63311
  const atrrName = keys[i4];
62130
- if (options.isArray(atrrName, jpath + "." + atrrName, true, true)) {
63312
+ const rawAttrName = atrrName.startsWith(options.attributeNamePrefix) ? atrrName.substring(options.attributeNamePrefix.length) : atrrName;
63313
+ const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() + "." + rawAttrName : readonlyMatcher;
63314
+ if (options.isArray(atrrName, jPathOrMatcher, true, true)) {
62131
63315
  obj[atrrName] = [attrMap[atrrName]];
62132
63316
  } else {
62133
63317
  obj[atrrName] = attrMap[atrrName];
@@ -62178,7 +63362,7 @@ void main(void) {
62178
63362
  if (this.options.preserveOrder || orderedResult === void 0)
62179
63363
  return orderedResult;
62180
63364
  else
62181
- return prettify(orderedResult, this.options);
63365
+ return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);
62182
63366
  }
62183
63367
  /**
62184
63368
  * Add Entity which is not by default supported by this library
@@ -64612,7 +65796,7 @@ void main(void) {
64612
65796
  visibleMinZoom,
64613
65797
  visibleMaxZoom
64614
65798
  }) {
64615
- let z3 = viewport.isGeospatial ? Math.round(viewport.zoom + Math.log2(TILE_SIZE4 / tileSize)) + zoomOffset : Math.ceil(viewport.zoom) + zoomOffset;
65799
+ let z3 = viewport.isGeospatial ? Math.round(viewport.zoom + Math.log2(TILE_SIZE4 / tileSize) + zoomOffset) : Math.ceil(viewport.zoom + zoomOffset);
64616
65800
  if (typeof minZoom === "number" && Number.isFinite(minZoom) && z3 < minZoom) {
64617
65801
  if (!extent) {
64618
65802
  return [];
@@ -65787,7 +66971,7 @@ out float vTime;
65787
66971
  }
65788
66972
  };
65789
66973
  function shouldComposeModelMatrix(viewport, coordinateSystem) {
65790
- return coordinateSystem === COORDINATE_SYSTEM.CARTESIAN || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.DEFAULT && !viewport.isGeospatial;
66974
+ return coordinateSystem === "cartesian" || coordinateSystem === "meter-offsets" || coordinateSystem === "default" && !viewport.isGeospatial;
65791
66975
  }
65792
66976
 
65793
66977
  // ../mesh-layers/src/simple-mesh-layer/simple-mesh-layer-uniforms.ts
@@ -82201,7 +83385,7 @@ vec4 project_position_to_clipspace(
82201
83385
  var Fp64Extension = class extends LayerExtension {
82202
83386
  getShaders() {
82203
83387
  const { coordinateSystem } = this.props;
82204
- if (coordinateSystem !== COORDINATE_SYSTEM.LNGLAT && coordinateSystem !== COORDINATE_SYSTEM.DEFAULT) {
83388
+ if (coordinateSystem !== "lnglat" && coordinateSystem !== "default") {
82205
83389
  throw new Error("fp64: coordinateSystem must be LNGLAT");
82206
83390
  }
82207
83391
  return {
@@ -82287,6 +83471,209 @@ in float vDashOffset;
82287
83471
  }
82288
83472
  }
82289
83473
  }
83474
+ `
83475
+ }
83476
+ };
83477
+ var scatterplotDashShaders = {
83478
+ inject: {
83479
+ "vs:#decl": `
83480
+ in vec2 instanceDashArrays;
83481
+ out vec2 vDashArray;
83482
+ `,
83483
+ "vs:#main-end": `
83484
+ vDashArray = instanceDashArrays;
83485
+ `,
83486
+ "fs:#decl": `
83487
+ layout(std140) uniform pathStyleUniforms {
83488
+ bool dashGapPickable;
83489
+ } pathStyle;
83490
+
83491
+ in vec2 vDashArray;
83492
+
83493
+ #define PI 3.141592653589793
83494
+ `,
83495
+ "fs:#main-start": `
83496
+ bool inDashGap = false;
83497
+ float dashUnitLength = vDashArray.x + vDashArray.y;
83498
+ if (dashUnitLength > 0.0 && scatterplot.stroked > 0.5) {
83499
+ float _distToCenter = length(unitPosition) * outerRadiusPixels;
83500
+ float innerRadius = innerUnitRadius * outerRadiusPixels;
83501
+ if (_distToCenter >= innerRadius) {
83502
+ float strokeWidth = (1.0 - innerUnitRadius) * outerRadiusPixels;
83503
+ float midStrokeRadius = (innerUnitRadius + 1.0) * 0.5 * outerRadiusPixels;
83504
+ float angle = atan(unitPosition.y, unitPosition.x) + PI;
83505
+ float circumference = 2.0 * PI * midStrokeRadius;
83506
+ float posAlongStroke = (angle / (2.0 * PI)) * circumference / strokeWidth;
83507
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
83508
+ if (unitOffset > vDashArray.x) {
83509
+ if (scatterplot.filled > 0.5) {
83510
+ inDashGap = true;
83511
+ } else {
83512
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
83513
+ discard;
83514
+ }
83515
+ }
83516
+ }
83517
+ }
83518
+ }
83519
+ `,
83520
+ "fs:#main-end": `
83521
+ if (inDashGap) {
83522
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
83523
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
83524
+ fragColor = picking_filterPickingColor(fragColor);
83525
+ fragColor = picking_filterHighlightColor(fragColor);
83526
+ }
83527
+ `
83528
+ }
83529
+ };
83530
+ var textBackgroundDashShaders = {
83531
+ inject: {
83532
+ "vs:#decl": `
83533
+ in vec2 instanceDashArrays;
83534
+ out vec2 vDashArray;
83535
+ `,
83536
+ "vs:#main-end": `
83537
+ vDashArray = instanceDashArrays;
83538
+ `,
83539
+ "fs:#decl": `
83540
+ layout(std140) uniform pathStyleUniforms {
83541
+ bool dashGapPickable;
83542
+ } pathStyle;
83543
+
83544
+ in vec2 vDashArray;
83545
+
83546
+ #define PI 3.141592653589793
83547
+
83548
+ // Calculate position along rounded rectangle perimeter in stroke-width units
83549
+ float getPerimeterPosition(vec2 fragUV, vec2 dims, vec4 radii, float lineWidth) {
83550
+ float width = dims.x;
83551
+ float height = dims.y;
83552
+
83553
+ float maxRadius = min(width, height) * 0.5;
83554
+ float rBL = min(radii.w, maxRadius);
83555
+ float rTL = min(radii.z, maxRadius);
83556
+ float rTR = min(radii.x, maxRadius);
83557
+ float rBR = min(radii.y, maxRadius);
83558
+
83559
+ vec2 p = fragUV * dims;
83560
+
83561
+ float leftLen = height - rBL - rTL;
83562
+ float topLen = width - rTL - rTR;
83563
+ float rightLen = height - rTR - rBR;
83564
+ float bottomLen = width - rBR - rBL;
83565
+
83566
+ float arcBL = PI * 0.5 * rBL;
83567
+ float arcTL = PI * 0.5 * rTL;
83568
+ float arcTR = PI * 0.5 * rTR;
83569
+ float arcBR = PI * 0.5 * rBR;
83570
+
83571
+ float pos = 0.0;
83572
+
83573
+ float distLeft = p.x;
83574
+ float distRight = width - p.x;
83575
+ float distBottom = p.y;
83576
+ float distTop = height - p.y;
83577
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
83578
+
83579
+ if (p.x < rBL && p.y < rBL) {
83580
+ vec2 c = vec2(rBL, rBL);
83581
+ vec2 d = p - c;
83582
+ float angle = atan(-d.x, -d.y);
83583
+ pos = angle / (PI * 0.5) * arcBL;
83584
+ } else if (p.x < rTL && p.y > height - rTL) {
83585
+ vec2 c = vec2(rTL, height - rTL);
83586
+ vec2 d = p - c;
83587
+ float angle = atan(d.y, -d.x);
83588
+ pos = arcBL + leftLen + angle / (PI * 0.5) * arcTL;
83589
+ } else if (p.x > width - rTR && p.y > height - rTR) {
83590
+ vec2 c = vec2(width - rTR, height - rTR);
83591
+ vec2 d = p - c;
83592
+ float angle = atan(d.x, d.y);
83593
+ pos = arcBL + leftLen + arcTL + topLen + angle / (PI * 0.5) * arcTR;
83594
+ } else if (p.x > width - rBR && p.y < rBR) {
83595
+ vec2 c = vec2(width - rBR, rBR);
83596
+ vec2 d = p - c;
83597
+ float angle = atan(-d.y, d.x);
83598
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + angle / (PI * 0.5) * arcBR;
83599
+ } else if (minDist == distLeft) {
83600
+ pos = arcBL + clamp(p.y - rBL, 0.0, leftLen);
83601
+ } else if (minDist == distTop) {
83602
+ pos = arcBL + leftLen + arcTL + clamp(p.x - rTL, 0.0, topLen);
83603
+ } else if (minDist == distRight) {
83604
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + clamp(height - rTR - p.y, 0.0, rightLen);
83605
+ } else {
83606
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + arcBR + clamp(width - rBR - p.x, 0.0, bottomLen);
83607
+ }
83608
+
83609
+ return pos / lineWidth;
83610
+ }
83611
+
83612
+ // Simple rectangular perimeter calculation (no rounded corners)
83613
+ float getRectPerimeterPosition(vec2 fragUV, vec2 dims, float lineWidth) {
83614
+ float width = dims.x;
83615
+ float height = dims.y;
83616
+
83617
+ float distLeft = fragUV.x * width;
83618
+ float distRight = (1.0 - fragUV.x) * width;
83619
+ float distBottom = fragUV.y * height;
83620
+ float distTop = (1.0 - fragUV.y) * height;
83621
+
83622
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
83623
+
83624
+ float pos = 0.0;
83625
+ if (minDist == distLeft) {
83626
+ pos = fragUV.y * height;
83627
+ } else if (minDist == distTop) {
83628
+ pos = height + fragUV.x * width;
83629
+ } else if (minDist == distRight) {
83630
+ pos = height + width + (1.0 - fragUV.y) * height;
83631
+ } else {
83632
+ pos = 2.0 * height + width + (1.0 - fragUV.x) * width;
83633
+ }
83634
+
83635
+ return pos / lineWidth;
83636
+ }
83637
+ `,
83638
+ "fs:#main-start": `
83639
+ bool inDashGap = false;
83640
+ float dashUnitLength = vDashArray.x + vDashArray.y;
83641
+ if (dashUnitLength > 0.0 && textBackground.stroked) {
83642
+ float distToEdge;
83643
+ bool hasRoundedCorners = textBackground.borderRadius != vec4(0.0);
83644
+ if (hasRoundedCorners) {
83645
+ distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
83646
+ } else {
83647
+ distToEdge = rect(uv, dimensions);
83648
+ }
83649
+
83650
+ if (distToEdge <= vLineWidth && distToEdge >= 0.0) {
83651
+ float posAlongStroke;
83652
+ if (hasRoundedCorners) {
83653
+ posAlongStroke = getPerimeterPosition(uv, dimensions, textBackground.borderRadius, vLineWidth);
83654
+ } else {
83655
+ posAlongStroke = getRectPerimeterPosition(uv, dimensions, vLineWidth);
83656
+ }
83657
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
83658
+ if (unitOffset > vDashArray.x) {
83659
+ if (vFillColor.a > 0.0) {
83660
+ inDashGap = true;
83661
+ } else {
83662
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
83663
+ discard;
83664
+ }
83665
+ }
83666
+ }
83667
+ }
83668
+ }
83669
+ `,
83670
+ "fs:#main-end": `
83671
+ if (inDashGap) {
83672
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
83673
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
83674
+ fragColor = picking_filterPickingColor(fragColor);
83675
+ fragColor = picking_filterHighlightColor(fragColor);
83676
+ }
82290
83677
  `
82291
83678
  }
82292
83679
  };
@@ -82331,13 +83718,41 @@ in float instanceOffsets;
82331
83718
  } = {}) {
82332
83719
  super({ dash: dash || highPrecisionDash, offset: offset3, highPrecisionDash });
82333
83720
  }
83721
+ getLayerType(layer) {
83722
+ if ("pathTesselator" in layer.state) {
83723
+ return "path";
83724
+ }
83725
+ const layerName = layer.constructor.layerName;
83726
+ if (layerName === "ScatterplotLayer") {
83727
+ return "scatterplot";
83728
+ }
83729
+ if (layerName === "TextBackgroundLayer") {
83730
+ return "textBackground";
83731
+ }
83732
+ return null;
83733
+ }
82334
83734
  isEnabled(layer) {
82335
- return "pathTesselator" in layer.state;
83735
+ return this.getLayerType(layer) !== null;
82336
83736
  }
82337
83737
  getShaders(extension) {
82338
- if (!extension.isEnabled(this)) {
83738
+ const layerType = extension.getLayerType(this);
83739
+ if (!layerType) {
82339
83740
  return null;
82340
83741
  }
83742
+ if (layerType === "scatterplot" || layerType === "textBackground") {
83743
+ if (!extension.opts.dash) {
83744
+ return null;
83745
+ }
83746
+ const inject7 = layerType === "scatterplot" ? scatterplotDashShaders.inject : textBackgroundDashShaders.inject;
83747
+ const pathStyle2 = {
83748
+ name: "pathStyle",
83749
+ inject: inject7,
83750
+ uniformTypes: {
83751
+ dashGapPickable: "i32"
83752
+ }
83753
+ };
83754
+ return { modules: [pathStyle2] };
83755
+ }
82341
83756
  let result = {};
82342
83757
  const defines2 = {};
82343
83758
  if (extension.opts.dash) {
@@ -82365,13 +83780,14 @@ in float instanceOffsets;
82365
83780
  }
82366
83781
  initializeState(context, extension) {
82367
83782
  const attributeManager = this.getAttributeManager();
82368
- if (!attributeManager || !extension.isEnabled(this)) {
83783
+ const layerType = extension.getLayerType(this);
83784
+ if (!attributeManager || !layerType) {
82369
83785
  return;
82370
83786
  }
82371
83787
  if (extension.opts.dash) {
82372
83788
  attributeManager.addInstanced({
82373
83789
  instanceDashArrays: { size: 2, accessor: "getDashArray" },
82374
- ...extension.opts.highPrecisionDash ? {
83790
+ ...layerType === "path" && extension.opts.highPrecisionDash ? {
82375
83791
  instanceDashOffsets: {
82376
83792
  size: 1,
82377
83793
  accessor: "getPath",
@@ -82380,7 +83796,7 @@ in float instanceOffsets;
82380
83796
  } : {}
82381
83797
  });
82382
83798
  }
82383
- if (extension.opts.offset) {
83799
+ if (layerType === "path" && extension.opts.offset) {
82384
83800
  attributeManager.addInstanced({
82385
83801
  instanceOffsets: { size: 1, accessor: "getOffset" }
82386
83802
  });
@@ -82391,11 +83807,19 @@ in float instanceOffsets;
82391
83807
  return;
82392
83808
  }
82393
83809
  if (extension.opts.dash) {
82394
- const pathStyleProps = {
82395
- dashAlignMode: this.props.dashJustified ? 1 : 0,
82396
- dashGapPickable: Boolean(this.props.dashGapPickable)
82397
- };
82398
- this.setShaderModuleProps({ pathStyle: pathStyleProps });
83810
+ const layerType = extension.getLayerType(this);
83811
+ if (layerType === "scatterplot" || layerType === "textBackground") {
83812
+ const pathStyleProps = {
83813
+ dashGapPickable: Boolean(this.props.dashGapPickable)
83814
+ };
83815
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
83816
+ } else {
83817
+ const pathStyleProps = {
83818
+ dashAlignMode: this.props.dashJustified ? 1 : 0,
83819
+ dashGapPickable: Boolean(this.props.dashGapPickable)
83820
+ };
83821
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
83822
+ }
82399
83823
  }
82400
83824
  }
82401
83825
  getDashOffsets(path) {
@@ -87055,6 +88479,9 @@ void main() {
87055
88479
  }
87056
88480
  `
87057
88481
  );
88482
+ if (device.type === "webgl") {
88483
+ device.getExtension("GL_ARB_shader_bit_encoding");
88484
+ }
87058
88485
  return new BufferTransform(device, {
87059
88486
  vs: vs15,
87060
88487
  fs: fs12,
@@ -90477,7 +91904,7 @@ void main() {
90477
91904
  {
90478
91905
  // position buffer is filled with world coordinates generated from viewport.unproject
90479
91906
  // i.e. LNGLAT if geospatial, CARTESIAN otherwise
90480
- coordinateSystem: COORDINATE_SYSTEM.DEFAULT,
91907
+ coordinateSystem: "default",
90481
91908
  data: {
90482
91909
  attributes: {
90483
91910
  positions: triPositionBuffer,
@@ -90679,7 +92106,7 @@ void main() {
90679
92106
  if (forceUpdate || !this.state.worldBounds || !boundsContain(this.state.worldBounds, visibleWorldBounds)) {
90680
92107
  const scaledCommonBounds = this._worldToCommonBounds(visibleWorldBounds);
90681
92108
  const worldBounds = this._commonToWorldBounds(scaledCommonBounds);
90682
- if (this.props.coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
92109
+ if (this.props.coordinateSystem === "lnglat") {
90683
92110
  worldBounds[1] = Math.max(worldBounds[1], -85.051129);
90684
92111
  worldBounds[3] = Math.min(worldBounds[3], 85.051129);
90685
92112
  worldBounds[0] = Math.max(worldBounds[0], -360);
@@ -90781,7 +92208,7 @@ void main() {
90781
92208
  const { viewport } = this.context;
90782
92209
  const { textureSize } = this.state;
90783
92210
  const { coordinateSystem } = this.props;
90784
- const offsetMode = useLayerCoordinateSystem && (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS);
92211
+ const offsetMode = useLayerCoordinateSystem && (coordinateSystem === "lnglat-offsets" || coordinateSystem === "meter-offsets");
90785
92212
  const offsetOriginCommon = offsetMode ? viewport.projectPosition(this.props.coordinateOrigin) : [0, 0];
90786
92213
  const size2 = textureSize * RESOLUTION / viewport.scale;
90787
92214
  let bottomLeftCommon;
@@ -91285,6 +92712,85 @@ void main() {
91285
92712
  }
91286
92713
  };
91287
92714
 
92715
+ // ../mapbox/src/mapbox-layer-group.ts
92716
+ var MapboxLayerGroup = class {
92717
+ /* eslint-disable no-this-before-super */
92718
+ constructor(props) {
92719
+ assert10(props.id, "id is required");
92720
+ this.id = props.id;
92721
+ this.type = "custom";
92722
+ this.renderingMode = props.renderingMode || "3d";
92723
+ this.slot = props.slot;
92724
+ this.beforeId = props.beforeId;
92725
+ this.map = null;
92726
+ }
92727
+ /* Mapbox custom layer methods */
92728
+ onAdd(map3, gl) {
92729
+ this.map = map3;
92730
+ }
92731
+ render(gl, renderParameters) {
92732
+ if (!this.map)
92733
+ return;
92734
+ drawLayerGroup(this.map.__deck, this.map, this, renderParameters);
92735
+ }
92736
+ };
92737
+
92738
+ // ../mapbox/src/resolve-layer-groups.ts
92739
+ var UNDEFINED_BEFORE_ID = "__UNDEFINED__";
92740
+ function getLayerGroupId(layer) {
92741
+ if (layer.props.beforeId) {
92742
+ return `deck-layer-group-before:${layer.props.beforeId}`;
92743
+ } else if (layer.props.slot) {
92744
+ return `deck-layer-group-slot:${layer.props.slot}`;
92745
+ }
92746
+ return "deck-layer-group-last";
92747
+ }
92748
+ function resolveLayerGroups(map3, oldLayers, newLayers) {
92749
+ if (!map3 || !map3.style || !map3.style._loaded) {
92750
+ return;
92751
+ }
92752
+ const layers = flatten(newLayers, Boolean);
92753
+ if (oldLayers !== newLayers) {
92754
+ const prevLayers = flatten(oldLayers, Boolean);
92755
+ const prevLayerGroupIds = new Set(prevLayers.map((l3) => getLayerGroupId(l3)));
92756
+ const newLayerGroupIds = new Set(layers.map((l3) => getLayerGroupId(l3)));
92757
+ for (const groupId of prevLayerGroupIds) {
92758
+ if (!newLayerGroupIds.has(groupId)) {
92759
+ if (map3.getLayer(groupId)) {
92760
+ map3.removeLayer(groupId);
92761
+ }
92762
+ }
92763
+ }
92764
+ }
92765
+ const layerGroups = {};
92766
+ for (const layer of layers) {
92767
+ const groupId = getLayerGroupId(layer);
92768
+ const mapboxGroup = map3.getLayer(groupId);
92769
+ if (mapboxGroup) {
92770
+ const groupInstance = mapboxGroup.implementation || mapboxGroup;
92771
+ layerGroups[groupId] = groupInstance;
92772
+ } else {
92773
+ const newGroup = new MapboxLayerGroup({
92774
+ id: groupId,
92775
+ slot: layer.props.slot,
92776
+ beforeId: layer.props.beforeId
92777
+ });
92778
+ layerGroups[groupId] = newGroup;
92779
+ map3.addLayer(newGroup, layer.props.beforeId);
92780
+ }
92781
+ }
92782
+ const mapLayers = map3.style._order;
92783
+ for (const [groupId, group] of Object.entries(layerGroups)) {
92784
+ const beforeId = group.beforeId || UNDEFINED_BEFORE_ID;
92785
+ const expectedGroupIndex = beforeId === UNDEFINED_BEFORE_ID ? mapLayers.length : mapLayers.indexOf(beforeId);
92786
+ const currentGropupIndex = mapLayers.indexOf(groupId);
92787
+ if (currentGropupIndex !== expectedGroupIndex - 1) {
92788
+ const moveBeforeId = beforeId === UNDEFINED_BEFORE_ID ? void 0 : beforeId;
92789
+ map3.moveLayer(groupId, moveBeforeId);
92790
+ }
92791
+ }
92792
+ }
92793
+
91288
92794
  // ../mapbox/src/deck-utils.ts
91289
92795
  var MAPBOX_VIEW_ID = "mapbox";
91290
92796
  var TILE_SIZE5 = 512;
@@ -91360,27 +92866,6 @@ void main() {
91360
92866
  }
91361
92867
  return result;
91362
92868
  }
91363
- function drawLayer(deck, map3, layer, renderParameters) {
91364
- if (!deck.isInitialized) {
91365
- return;
91366
- }
91367
- let { currentViewport } = deck.userData;
91368
- let clearStack = false;
91369
- if (!currentViewport) {
91370
- currentViewport = getViewport(deck, map3, renderParameters);
91371
- deck.userData.currentViewport = currentViewport;
91372
- clearStack = true;
91373
- }
91374
- if (!currentViewport) {
91375
- return;
91376
- }
91377
- deck._drawLayers("mapbox-repaint", {
91378
- viewports: [currentViewport],
91379
- layerFilter: (params) => (!deck.props.layerFilter || deck.props.layerFilter(params)) && (layer.id === params.layer.id || params.layer.props.operation.includes("terrain")),
91380
- clearStack,
91381
- clearCanvas: false
91382
- });
91383
- }
91384
92869
  function drawLayerGroup(deck, map3, group, renderParameters) {
91385
92870
  if (!deck.isInitialized) {
91386
92871
  return;
@@ -91499,7 +92984,9 @@ void main() {
91499
92984
  }
91500
92985
  function afterRender(deck, map3) {
91501
92986
  const deckLayers = flatten(deck.props.layers, Boolean);
91502
- const hasNonMapboxLayers = deckLayers.some((layer) => layer && !map3.getLayer(layer.id));
92987
+ const hasNonMapboxLayers = deckLayers.some(
92988
+ (layer) => layer && !map3.getLayer(getLayerGroupId(layer))
92989
+ );
91503
92990
  let viewports = deck.getViewports();
91504
92991
  const mapboxViewportIdx = viewports.findIndex((vp) => vp.id === MAPBOX_VIEW_ID);
91505
92992
  const hasNonMapboxViews = viewports.length > 1 || mapboxViewportIdx < 0;
@@ -91515,7 +93002,7 @@ void main() {
91515
93002
  }
91516
93003
  deck._drawLayers("mapbox-repaint", {
91517
93004
  viewports,
91518
- layerFilter: (params) => (!deck.props.layerFilter || deck.props.layerFilter(params)) && (params.viewport.id !== MAPBOX_VIEW_ID || !map3.getLayer(params.layer.id)),
93005
+ layerFilter: (params) => (!deck.props.layerFilter || deck.props.layerFilter(params)) && (params.viewport.id !== MAPBOX_VIEW_ID || !map3.getLayer(getLayerGroupId(params.layer))),
91519
93006
  clearCanvas: false
91520
93007
  });
91521
93008
  } else {
@@ -91533,181 +93020,6 @@ void main() {
91533
93020
  deck.needsRedraw({ clearRedrawFlags: true });
91534
93021
  }
91535
93022
 
91536
- // ../mapbox/src/mapbox-layer.ts
91537
- var MapboxLayer = class {
91538
- /* eslint-disable no-this-before-super */
91539
- constructor(props) {
91540
- if (!props.id) {
91541
- throw new Error("Layer must have an unique id");
91542
- }
91543
- this.id = props.id;
91544
- this.type = "custom";
91545
- this.renderingMode = props.renderingMode || "3d";
91546
- this.slot = props.slot;
91547
- this.map = null;
91548
- this.props = props;
91549
- }
91550
- /* Mapbox custom layer methods */
91551
- onAdd(map3, gl) {
91552
- this.map = map3;
91553
- }
91554
- onRemove() {
91555
- this.map = null;
91556
- }
91557
- setProps(props) {
91558
- Object.assign(this.props, props, { id: this.id });
91559
- }
91560
- render(gl, renderParameters) {
91561
- if (!this.map)
91562
- return;
91563
- drawLayer(this.map.__deck, this.map, this, renderParameters);
91564
- }
91565
- };
91566
-
91567
- // ../mapbox/src/resolve-layers.ts
91568
- var UNDEFINED_BEFORE_ID = "__UNDEFINED__";
91569
- function resolveLayers(map3, deck, oldLayers, newLayers) {
91570
- if (!map3 || !deck || !map3.style || !map3.style._loaded) {
91571
- return;
91572
- }
91573
- const layers = flatten(newLayers, Boolean);
91574
- if (oldLayers !== newLayers) {
91575
- const prevLayers = flatten(oldLayers, Boolean);
91576
- const prevLayerIds = new Set(prevLayers.map((l3) => l3.id));
91577
- for (const layer of layers) {
91578
- prevLayerIds.delete(layer.id);
91579
- }
91580
- for (const id of prevLayerIds) {
91581
- if (map3.getLayer(id)) {
91582
- map3.removeLayer(id);
91583
- }
91584
- }
91585
- }
91586
- for (const layer of layers) {
91587
- const mapboxLayer = map3.getLayer(layer.id);
91588
- if (mapboxLayer) {
91589
- const layerInstance = mapboxLayer.implementation || mapboxLayer;
91590
- layerInstance.setProps(layer.props);
91591
- } else {
91592
- map3.addLayer(
91593
- new MapboxLayer({
91594
- id: layer.id,
91595
- // @ts-expect-error slot is not defined in LayerProps
91596
- slot: layer.props.slot
91597
- }),
91598
- // @ts-expect-error beforeId is not defined in LayerProps
91599
- layer.props.beforeId
91600
- );
91601
- }
91602
- }
91603
- const mapLayers = map3.style._order;
91604
- const layerGroups = {};
91605
- for (const layer of layers) {
91606
- let { beforeId } = layer.props;
91607
- if (!beforeId || !mapLayers.includes(beforeId)) {
91608
- beforeId = UNDEFINED_BEFORE_ID;
91609
- }
91610
- layerGroups[beforeId] = layerGroups[beforeId] || [];
91611
- layerGroups[beforeId].push(layer.id);
91612
- }
91613
- for (const beforeId in layerGroups) {
91614
- const layerGroup = layerGroups[beforeId];
91615
- let lastLayerIndex = beforeId === UNDEFINED_BEFORE_ID ? mapLayers.length : mapLayers.indexOf(beforeId);
91616
- let lastLayerId = beforeId === UNDEFINED_BEFORE_ID ? void 0 : beforeId;
91617
- for (let i4 = layerGroup.length - 1; i4 >= 0; i4--) {
91618
- const layerId = layerGroup[i4];
91619
- const layerIndex = mapLayers.indexOf(layerId);
91620
- if (layerIndex !== lastLayerIndex - 1) {
91621
- map3.moveLayer(layerId, lastLayerId);
91622
- if (layerIndex > lastLayerIndex) {
91623
- lastLayerIndex++;
91624
- }
91625
- }
91626
- lastLayerIndex--;
91627
- lastLayerId = layerId;
91628
- }
91629
- }
91630
- }
91631
-
91632
- // ../mapbox/src/mapbox-layer-group.ts
91633
- var MapboxLayerGroup = class {
91634
- /* eslint-disable no-this-before-super */
91635
- constructor(props) {
91636
- assert10(props.id, "id is required");
91637
- this.id = props.id;
91638
- this.type = "custom";
91639
- this.renderingMode = props.renderingMode || "3d";
91640
- this.slot = props.slot;
91641
- this.beforeId = props.beforeId;
91642
- this.map = null;
91643
- }
91644
- /* Mapbox custom layer methods */
91645
- onAdd(map3, gl) {
91646
- this.map = map3;
91647
- }
91648
- render(gl, renderParameters) {
91649
- if (!this.map)
91650
- return;
91651
- drawLayerGroup(this.map.__deck, this.map, this, renderParameters);
91652
- }
91653
- };
91654
-
91655
- // ../mapbox/src/resolve-layer-groups.ts
91656
- var UNDEFINED_BEFORE_ID2 = "__UNDEFINED__";
91657
- function getLayerGroupId(layer) {
91658
- if (layer.props.beforeId) {
91659
- return `deck-layer-group-before:${layer.props.beforeId}`;
91660
- } else if (layer.props.slot) {
91661
- return `deck-layer-group-slot:${layer.props.slot}`;
91662
- }
91663
- return "deck-layer-group-last";
91664
- }
91665
- function resolveLayerGroups(map3, oldLayers, newLayers) {
91666
- if (!map3 || !map3.style || !map3.style._loaded) {
91667
- return;
91668
- }
91669
- const layers = flatten(newLayers, Boolean);
91670
- if (oldLayers !== newLayers) {
91671
- const prevLayers = flatten(oldLayers, Boolean);
91672
- const prevLayerGroupIds = new Set(prevLayers.map((l3) => getLayerGroupId(l3)));
91673
- const newLayerGroupIds = new Set(layers.map((l3) => getLayerGroupId(l3)));
91674
- for (const groupId of prevLayerGroupIds) {
91675
- if (!newLayerGroupIds.has(groupId)) {
91676
- if (map3.getLayer(groupId)) {
91677
- map3.removeLayer(groupId);
91678
- }
91679
- }
91680
- }
91681
- }
91682
- const layerGroups = {};
91683
- for (const layer of layers) {
91684
- const groupId = getLayerGroupId(layer);
91685
- const mapboxGroup = map3.getLayer(groupId);
91686
- if (mapboxGroup) {
91687
- const groupInstance = mapboxGroup.implementation || mapboxGroup;
91688
- layerGroups[groupId] = groupInstance;
91689
- } else {
91690
- const newGroup = new MapboxLayerGroup({
91691
- id: groupId,
91692
- slot: layer.props.slot,
91693
- beforeId: layer.props.beforeId
91694
- });
91695
- layerGroups[groupId] = newGroup;
91696
- map3.addLayer(newGroup, layer.props.beforeId);
91697
- }
91698
- }
91699
- const mapLayers = map3.style._order;
91700
- for (const [groupId, group] of Object.entries(layerGroups)) {
91701
- const beforeId = group.beforeId || UNDEFINED_BEFORE_ID2;
91702
- const expectedGroupIndex = beforeId === UNDEFINED_BEFORE_ID2 ? mapLayers.length : mapLayers.indexOf(beforeId);
91703
- const currentGropupIndex = mapLayers.indexOf(groupId);
91704
- if (currentGropupIndex !== expectedGroupIndex - 1) {
91705
- const moveBeforeId = beforeId === UNDEFINED_BEFORE_ID2 ? void 0 : beforeId;
91706
- map3.moveLayer(groupId, moveBeforeId);
91707
- }
91708
- }
91709
- }
91710
-
91711
93023
  // ../mapbox/src/mapbox-overlay.ts
91712
93024
  var MapboxOverlay = class {
91713
93025
  constructor(props) {
@@ -91716,8 +93028,8 @@ void main() {
91716
93028
  if (!this._map)
91717
93029
  return;
91718
93030
  const projection = getProjection(this._map);
91719
- if (projection && !this._props.views) {
91720
- this._deck?.setProps({ views: getDefaultView(this._map) });
93031
+ if (projection) {
93032
+ this._deck?.setProps({ views: this._getViews(this._map) });
91721
93033
  }
91722
93034
  };
91723
93035
  this._updateContainerSize = () => {
@@ -91734,7 +93046,7 @@ void main() {
91734
93046
  const map3 = this._map;
91735
93047
  if (deck && map3) {
91736
93048
  deck.setProps({
91737
- views: this._props.views || getDefaultView(map3),
93049
+ views: this._getViews(map3),
91738
93050
  viewState: getViewState(map3)
91739
93051
  });
91740
93052
  if (deck.isInitialized) {
@@ -91806,7 +93118,6 @@ void main() {
91806
93118
  };
91807
93119
  const { interleaved = false } = props;
91808
93120
  this._interleaved = interleaved;
91809
- this._renderLayersInGroups = props._renderLayersInGroups || false;
91810
93121
  this._props = this.filterProps(props);
91811
93122
  }
91812
93123
  /** Filter out props to pass to Deck **/
@@ -91826,6 +93137,7 @@ void main() {
91826
93137
  if (this._deck && this._map) {
91827
93138
  this._deck.setProps({
91828
93139
  ...this._props,
93140
+ views: this._getViews(this._map),
91829
93141
  parameters: {
91830
93142
  ...getDefaultParameters(this._map, this._interleaved),
91831
93143
  ...this._props.parameters
@@ -91854,7 +93166,7 @@ void main() {
91854
93166
  ...this._props,
91855
93167
  parent: container,
91856
93168
  parameters: { ...getDefaultParameters(map3, false), ...this._props.parameters },
91857
- views: this._props.views || getDefaultView(map3),
93169
+ views: this._getViews(map3),
91858
93170
  viewState: getViewState(map3)
91859
93171
  });
91860
93172
  map3.on("resize", this._updateContainerSize);
@@ -91881,6 +93193,7 @@ void main() {
91881
93193
  map: map3,
91882
93194
  deck: new Deck({
91883
93195
  ...this._props,
93196
+ views: this._getViews(map3),
91884
93197
  gl,
91885
93198
  parameters: { ...getDefaultParameters(map3, true), ...this._props.parameters }
91886
93199
  })
@@ -91889,12 +93202,8 @@ void main() {
91889
93202
  this._resolveLayers(map3, this._deck, [], this._props.layers);
91890
93203
  return document.createElement("div");
91891
93204
  }
91892
- _resolveLayers(map3, deck, prevLayers, newLayers) {
91893
- if (this._renderLayersInGroups) {
91894
- resolveLayerGroups(map3, prevLayers, newLayers);
91895
- } else {
91896
- resolveLayers(map3, deck, prevLayers, newLayers);
91897
- }
93205
+ _resolveLayers(map3, _deck, prevLayers, newLayers) {
93206
+ resolveLayerGroups(map3, prevLayers, newLayers);
91898
93207
  }
91899
93208
  /** Called when the control is removed from a map */
91900
93209
  onRemove() {
@@ -91959,6 +93268,17 @@ void main() {
91959
93268
  }
91960
93269
  return this._interleaved ? this._map.getCanvas() : this._deck.getCanvas();
91961
93270
  }
93271
+ _getViews(map3) {
93272
+ if (!this._props.views) {
93273
+ return getDefaultView(map3);
93274
+ }
93275
+ const views = Array.isArray(this._props.views) ? this._props.views : [this._props.views];
93276
+ const hasMapboxView = views.some((v4) => v4.id === MAPBOX_VIEW_ID);
93277
+ if (hasMapboxView) {
93278
+ return this._props.views;
93279
+ }
93280
+ return [getDefaultView(map3), ...views];
93281
+ }
91962
93282
  };
91963
93283
 
91964
93284
  // ../../node_modules/preact/dist/preact.module.js
@@ -92515,25 +93835,65 @@ void main() {
92515
93835
  ] });
92516
93836
  B2(ui, rootElement);
92517
93837
  }
92518
- handleZoom(viewId, nextZoom) {
93838
+ isOrthographicView(viewId) {
93839
+ const deck = this.deck;
93840
+ const view = deck?.isInitialized && deck.getView(viewId);
93841
+ return view instanceof OrthographicView;
93842
+ }
93843
+ handleZoom(viewId, delta) {
92519
93844
  const viewState = this.getViewState(viewId);
92520
- if (viewState) {
92521
- const { minZoom, maxZoom } = viewState;
92522
- if (Number.isFinite(minZoom)) {
92523
- nextZoom = Math.max(minZoom, nextZoom);
92524
- }
92525
- if (Number.isFinite(maxZoom)) {
92526
- nextZoom = Math.min(maxZoom, nextZoom);
92527
- }
93845
+ const newViewState = {};
93846
+ if (this.isOrthographicView(viewId)) {
93847
+ const { zoomAxis } = this.props;
93848
+ const { zoomX, minZoomX, maxZoomX, zoomY, minZoomY, maxZoomY } = normalizeOrthographicViewState(
93849
+ viewState
93850
+ );
93851
+ let nextZoom;
93852
+ let nextZoomY;
93853
+ if (zoomAxis === "X") {
93854
+ nextZoom = clamp3(zoomX + delta, minZoomX, maxZoomX);
93855
+ nextZoomY = zoomY;
93856
+ } else if (zoomAxis === "Y") {
93857
+ nextZoom = zoomX;
93858
+ nextZoomY = clamp3(zoomY + delta, minZoomY, maxZoomY);
93859
+ } else {
93860
+ const clampedDelta = clamp3(
93861
+ delta,
93862
+ Math.max(minZoomX - zoomX, minZoomY - zoomY),
93863
+ Math.min(maxZoomX - zoomX, maxZoomY - zoomY)
93864
+ );
93865
+ nextZoom = zoomX + clampedDelta;
93866
+ nextZoomY = zoomY + clampedDelta;
93867
+ }
93868
+ newViewState.zoom = [nextZoom, nextZoomY];
93869
+ newViewState.zoomX = nextZoom;
93870
+ newViewState.zoomY = nextZoomY;
93871
+ this.props.onZoom?.({
93872
+ viewId,
93873
+ delta,
93874
+ // `zoom` will not match the new state if using 2D zoom. Deprecated behavior for backward compatibility.
93875
+ zoom: zoomAxis === "Y" ? nextZoomY : nextZoom,
93876
+ zoomX: nextZoom,
93877
+ zoomY: nextZoomY
93878
+ });
93879
+ } else {
93880
+ const { zoom = 0, minZoom, maxZoom } = viewState;
93881
+ const nextZoom = clamp3(zoom + delta, minZoom, maxZoom);
93882
+ newViewState.zoom = nextZoom;
93883
+ this.props.onZoom?.({
93884
+ viewId,
93885
+ delta,
93886
+ zoom: nextZoom
93887
+ });
92528
93888
  }
92529
93889
  const nextViewState = {
92530
93890
  ...viewState,
92531
- zoom: nextZoom
93891
+ ...newViewState
92532
93892
  };
92533
93893
  if (this.props.transitionDuration > 0) {
92534
93894
  nextViewState.transitionDuration = this.props.transitionDuration;
92535
93895
  nextViewState.transitionInterpolator = "latitude" in nextViewState ? new FlyToInterpolator() : new LinearInterpolator({
92536
- transitionProps: ["zoom"]
93896
+ transitionProps: "zoomX" in newViewState ? ["zoomX", "zoomY"] : ["zoom"]
92537
93897
  });
92538
93898
  }
92539
93899
  this.setViewState(viewId, nextViewState);
@@ -92541,15 +93901,13 @@ void main() {
92541
93901
  handleZoomIn() {
92542
93902
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v4) => v4.id) ?? [];
92543
93903
  for (const viewId of viewIds) {
92544
- const viewState = this.getViewState(viewId);
92545
- this.handleZoom(viewId, viewState.zoom + 1);
93904
+ this.handleZoom(viewId, 1);
92546
93905
  }
92547
93906
  }
92548
93907
  handleZoomOut() {
92549
93908
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v4) => v4.id) ?? [];
92550
93909
  for (const viewId of viewIds) {
92551
- const viewState = this.getViewState(viewId);
92552
- this.handleZoom(viewId, viewState.zoom - 1);
93910
+ this.handleZoom(viewId, -1);
92553
93911
  }
92554
93912
  }
92555
93913
  };
@@ -92561,8 +93919,29 @@ void main() {
92561
93919
  transitionDuration: 200,
92562
93920
  zoomInLabel: "Zoom In",
92563
93921
  zoomOutLabel: "Zoom Out",
92564
- viewId: null
93922
+ zoomAxis: "all",
93923
+ viewId: null,
93924
+ onZoom: () => {
93925
+ }
92565
93926
  };
93927
+ function clamp3(zoom, minZoom, maxZoom) {
93928
+ return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
93929
+ }
93930
+ function normalizeOrthographicViewState({
93931
+ zoom = 0,
93932
+ zoomX,
93933
+ zoomY,
93934
+ minZoom = -Infinity,
93935
+ maxZoom = Infinity,
93936
+ minZoomX = minZoom,
93937
+ maxZoomX = maxZoom,
93938
+ minZoomY = minZoom,
93939
+ maxZoomY = maxZoom
93940
+ }) {
93941
+ zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
93942
+ zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
93943
+ return { zoomX, zoomY, minZoomX, minZoomY, maxZoomX, maxZoomY };
93944
+ }
92566
93945
 
92567
93946
  // ../widgets/src/reset-view-widget.tsx
92568
93947
  var ResetViewWidget = class extends Widget {
@@ -92603,6 +93982,7 @@ void main() {
92603
93982
  // transitionDuration: this.props.transitionDuration,
92604
93983
  // transitionInterpolator: new FlyToInterpolator()
92605
93984
  };
93985
+ this.props.onReset?.({ viewId, viewState: nextViewState });
92606
93986
  this.setViewState(viewId, nextViewState);
92607
93987
  }
92608
93988
  }
@@ -92613,7 +93993,9 @@ void main() {
92613
93993
  placement: "top-left",
92614
93994
  label: "Reset View",
92615
93995
  initialViewState: void 0,
92616
- viewId: null
93996
+ viewId: null,
93997
+ onReset: () => {
93998
+ }
92617
93999
  };
92618
94000
 
92619
94001
  // ../widgets/src/gimbal-widget.tsx
@@ -92711,6 +94093,7 @@ void main() {
92711
94093
  const viewId = this.viewId || viewport?.id || "OrbitView";
92712
94094
  const viewState = this.getViewState(viewId);
92713
94095
  if ("rotationOrbit" in viewState || "rotationX" in viewState) {
94096
+ this.props.onReset?.({ viewId, rotationOrbit: 0, rotationX: 0 });
92714
94097
  const nextViewState = {
92715
94098
  ...viewState,
92716
94099
  rotationOrbit: 0,
@@ -92745,7 +94128,9 @@ void main() {
92745
94128
  viewId: null,
92746
94129
  label: "Gimbal",
92747
94130
  strokeWidth: 1.5,
92748
- transitionDuration: 200
94131
+ transitionDuration: 200,
94132
+ onReset: () => {
94133
+ }
92749
94134
  };
92750
94135
  function normalizeAndClampAngle(angle4) {
92751
94136
  let normalized = ((angle4 + 180) % 360 + 360) % 360 - 180;
@@ -92828,10 +94213,14 @@ void main() {
92828
94213
  const viewId = this.viewId || viewport.id;
92829
94214
  if (viewport instanceof WebMercatorViewport2) {
92830
94215
  const viewState = this.getViewState(viewId);
94216
+ const resetPitch = this.getRotation(viewport)[0] === 0;
94217
+ const nextBearing = 0;
94218
+ const nextPitch = resetPitch ? 0 : viewport.pitch;
94219
+ this.props.onReset?.({ viewId, bearing: nextBearing, pitch: nextPitch });
92831
94220
  const nextViewState = {
92832
94221
  ...viewState,
92833
- bearing: 0,
92834
- ...this.getRotation(viewport)[0] === 0 ? { pitch: 0 } : {},
94222
+ bearing: nextBearing,
94223
+ ...resetPitch ? { pitch: nextPitch } : {},
92835
94224
  transitionDuration: this.props.transitionDuration,
92836
94225
  transitionInterpolator: new FlyToInterpolator()
92837
94226
  };
@@ -92845,7 +94234,9 @@ void main() {
92845
94234
  placement: "top-left",
92846
94235
  viewId: null,
92847
94236
  label: "Reset Compass",
92848
- transitionDuration: 200
94237
+ transitionDuration: 200,
94238
+ onReset: () => {
94239
+ }
92849
94240
  };
92850
94241
 
92851
94242
  // ../widgets/src/scale-widget.tsx
@@ -93354,6 +94745,16 @@ void main() {
93354
94745
  flyTo(viewState) {
93355
94746
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v4) => v4.id) ?? [];
93356
94747
  for (const viewId of viewIds) {
94748
+ if ("longitude" in viewState && "latitude" in viewState) {
94749
+ this.props.onGeocode?.({
94750
+ viewId,
94751
+ coordinates: {
94752
+ longitude: viewState.longitude,
94753
+ latitude: viewState.latitude,
94754
+ zoom: viewState.zoom
94755
+ }
94756
+ });
94757
+ }
93357
94758
  const currentViewState = this.getViewState(viewId);
93358
94759
  const nextViewState = {
93359
94760
  ...currentViewState,
@@ -93377,7 +94778,9 @@ void main() {
93377
94778
  geocoder: "coordinates",
93378
94779
  customGeocoder: CoordinatesGeocoder,
93379
94780
  apiKey: "",
93380
- _geolocation: false
94781
+ _geolocation: false,
94782
+ onGeocode: () => {
94783
+ }
93381
94784
  };
93382
94785
  function getGeocoder(props) {
93383
94786
  switch (props.geocoder) {
@@ -93415,6 +94818,7 @@ void main() {
93415
94818
  document.removeEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
93416
94819
  }
93417
94820
  onRenderHTML(rootElement) {
94821
+ const isFullscreen = this.getFullscreen();
93418
94822
  B2(
93419
94823
  /* @__PURE__ */ u3(
93420
94824
  IconButton,
@@ -93422,8 +94826,8 @@ void main() {
93422
94826
  onClick: () => {
93423
94827
  this.handleClick().catch((err) => log_default.error(err)());
93424
94828
  },
93425
- label: this.fullscreen ? this.props.exitLabel : this.props.enterLabel,
93426
- className: this.fullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter"
94829
+ label: isFullscreen ? this.props.exitLabel : this.props.enterLabel,
94830
+ className: isFullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter"
93427
94831
  }
93428
94832
  ),
93429
94833
  rootElement
@@ -93437,21 +94841,24 @@ void main() {
93437
94841
  getContainer() {
93438
94842
  return this.props.container || this.deck?.props.parent || this.deck?.getCanvas()?.parentElement;
93439
94843
  }
94844
+ getFullscreen() {
94845
+ return this.fullscreen;
94846
+ }
93440
94847
  onFullscreenChange() {
93441
- const prevFullscreen = this.fullscreen;
93442
94848
  const fullscreen = document.fullscreenElement === this.getContainer();
93443
- if (prevFullscreen !== fullscreen) {
93444
- this.fullscreen = !this.fullscreen;
94849
+ if (fullscreen !== this.fullscreen) {
94850
+ this.fullscreen = fullscreen;
94851
+ this.props.onFullscreenChange?.(fullscreen);
94852
+ this.updateHTML();
93445
94853
  }
93446
- this.updateHTML();
93447
94854
  }
93448
94855
  async handleClick() {
93449
- if (this.fullscreen) {
94856
+ const isFullscreen = this.getFullscreen();
94857
+ if (isFullscreen) {
93450
94858
  await this.exitFullscreen();
93451
94859
  } else {
93452
94860
  await this.requestFullscreen();
93453
94861
  }
93454
- this.updateHTML();
93455
94862
  }
93456
94863
  async requestFullscreen() {
93457
94864
  const container = this.getContainer();
@@ -93470,6 +94877,9 @@ void main() {
93470
94877
  }
93471
94878
  togglePseudoFullscreen() {
93472
94879
  this.getContainer()?.classList.toggle("deck-pseudo-fullscreen");
94880
+ this.fullscreen = !this.fullscreen;
94881
+ this.props.onFullscreenChange?.(this.fullscreen);
94882
+ this.updateHTML();
93473
94883
  }
93474
94884
  };
93475
94885
  FullscreenWidget.defaultProps = {
@@ -93479,7 +94889,9 @@ void main() {
93479
94889
  viewId: null,
93480
94890
  enterLabel: "Enter Fullscreen",
93481
94891
  exitLabel: "Exit Fullscreen",
93482
- container: void 0
94892
+ container: void 0,
94893
+ onFullscreenChange: () => {
94894
+ }
93483
94895
  };
93484
94896
 
93485
94897
  // ../widgets/src/splitter-widget.tsx
@@ -93728,7 +95140,7 @@ void main() {
93728
95140
  bottom: "top",
93729
95141
  top: "bottom"
93730
95142
  };
93731
- function clamp3(start, value, end) {
95143
+ function clamp4(start, value, end) {
93732
95144
  return max6(start, min6(value, end));
93733
95145
  }
93734
95146
  function evaluate(value, param) {
@@ -94088,7 +95500,7 @@ void main() {
94088
95500
  const min$1 = minPadding;
94089
95501
  const max7 = clientSize - arrowDimensions[length6] - maxPadding;
94090
95502
  const center2 = clientSize / 2 - arrowDimensions[length6] / 2 + centerToReference;
94091
- const offset3 = clamp3(min$1, center2, max7);
95503
+ const offset3 = clamp4(min$1, center2, max7);
94092
95504
  const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center2 !== offset3 && rects.reference[length6] / 2 - (center2 < min$1 ? minPadding : maxPadding) - arrowDimensions[length6] / 2 < 0;
94093
95505
  const alignmentOffset = shouldAddOffset ? center2 < min$1 ? center2 - min$1 : center2 - max7 : 0;
94094
95506
  return {
@@ -94326,14 +95738,14 @@ void main() {
94326
95738
  const maxSide = mainAxis === "y" ? "bottom" : "right";
94327
95739
  const min7 = mainAxisCoord + overflow[minSide];
94328
95740
  const max7 = mainAxisCoord - overflow[maxSide];
94329
- mainAxisCoord = clamp3(min7, mainAxisCoord, max7);
95741
+ mainAxisCoord = clamp4(min7, mainAxisCoord, max7);
94330
95742
  }
94331
95743
  if (checkCrossAxis) {
94332
95744
  const minSide = crossAxis === "y" ? "top" : "left";
94333
95745
  const maxSide = crossAxis === "y" ? "bottom" : "right";
94334
95746
  const min7 = crossAxisCoord + overflow[minSide];
94335
95747
  const max7 = crossAxisCoord - overflow[maxSide];
94336
- crossAxisCoord = clamp3(min7, crossAxisCoord, max7);
95748
+ crossAxisCoord = clamp4(min7, crossAxisCoord, max7);
94337
95749
  }
94338
95750
  const limitedCoords = limiter.fn({
94339
95751
  ...state,
@@ -95546,7 +96958,7 @@ void main() {
95546
96958
 
95547
96959
  // ../widgets/src/lib/components/range-input.tsx
95548
96960
  var wheelListenerOptions = { passive: false };
95549
- var clamp4 = (value, min7, max7) => {
96961
+ var clamp5 = (value, min7, max7) => {
95550
96962
  if (value < min7) {
95551
96963
  return min7;
95552
96964
  }
@@ -95602,7 +97014,7 @@ void main() {
95602
97014
  const range = max7 - min7;
95603
97015
  const rangeSize = Math.max(0, value[1] - value[0]);
95604
97016
  const maxStart = Math.max(0, range - rangeSize);
95605
- const clampedStart = clamp4(value[0], min7, min7 + maxStart);
97017
+ const clampedStart = clamp5(value[0], min7, min7 + maxStart);
95606
97018
  const { thumbLength, thumbOffset } = T2(() => {
95607
97019
  if (trackLength <= 0 || range <= 0) {
95608
97020
  return { thumbLength: 0, thumbOffset: 0 };
@@ -95612,7 +97024,7 @@ void main() {
95612
97024
  }
95613
97025
  const nextThumbLength = rangeSize / range;
95614
97026
  const travel = Math.max(0, 1 - nextThumbLength);
95615
- const ratio = maxStart <= 0 ? 0 : clamp4((clampedStart - min7) / maxStart, 0, 1);
97027
+ const ratio = maxStart <= 0 ? 0 : clamp5((clampedStart - min7) / maxStart, 0, 1);
95616
97028
  return {
95617
97029
  thumbLength: Math.max(0, Math.min(nextThumbLength, 1)),
95618
97030
  thumbOffset: travel * ratio
@@ -95623,7 +97035,7 @@ void main() {
95623
97035
  if (!onChange) {
95624
97036
  return;
95625
97037
  }
95626
- const clamped = clamp4(nextStart, min7, min7 + maxStart);
97038
+ const clamped = clamp5(nextStart, min7, min7 + maxStart);
95627
97039
  onChange([clamped, clamped + rangeSize]);
95628
97040
  },
95629
97041
  [onChange, min7, maxStart, rangeSize]
@@ -95661,7 +97073,7 @@ void main() {
95661
97073
  const coordinate = vertical ? event.clientY - trackStart : event.clientX - trackStart;
95662
97074
  const span = Math.max(1, 1 - thumbLength) * trackLength;
95663
97075
  const thumbCenter = thumbLength / 2 * trackLength;
95664
- const ratio = span <= 0 ? 0 : clamp4((coordinate - thumbCenter) / span, 0, 1);
97076
+ const ratio = span <= 0 ? 0 : clamp5((coordinate - thumbCenter) / span, 0, 1);
95665
97077
  emitRange(min7 + ratio * maxStart);
95666
97078
  },
95667
97079
  [vertical, trackLength, thumbLength, emitRange, min7, maxStart]
@@ -95696,7 +97108,7 @@ void main() {
95696
97108
  const coordinate = vertical ? event.clientY : event.clientX;
95697
97109
  const delta = coordinate - state.startCoord;
95698
97110
  const ratio = state.startRatio + delta / trackLength2;
95699
- const nextStart = clamp4(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
97111
+ const nextStart = clamp5(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
95700
97112
  emitRange(nextStart);
95701
97113
  event.preventDefault();
95702
97114
  },
@@ -95886,7 +97298,7 @@ void main() {
95886
97298
  }
95887
97299
 
95888
97300
  // ../widgets/src/scrollbar-widget.tsx
95889
- var clamp5 = (value, min7, max7) => {
97301
+ var clamp6 = (value, min7, max7) => {
95890
97302
  if (value < min7) {
95891
97303
  return min7;
95892
97304
  }
@@ -96015,7 +97427,7 @@ void main() {
96015
97427
  }
96016
97428
  getClampedOffset() {
96017
97429
  const maxScroll = this.getMaxScroll();
96018
- return clamp5(this.scrollOffset, 0, maxScroll);
97430
+ return clamp6(this.scrollOffset, 0, maxScroll);
96019
97431
  }
96020
97432
  isVertical() {
96021
97433
  return this.props.orientation !== "horizontal";
@@ -96034,7 +97446,7 @@ void main() {
96034
97446
  }
96035
97447
  emitScroll(next) {
96036
97448
  const maxScroll = this.getMaxScroll();
96037
- const target2 = clamp5(Math.round(next), 0, maxScroll);
97449
+ const target2 = clamp6(Math.round(next), 0, maxScroll);
96038
97450
  const viewport = this.viewport;
96039
97451
  if (viewport && target2 !== this.getClampedOffset()) {
96040
97452
  const pixel = viewport.project(viewport.position);
@@ -96263,20 +97675,27 @@ void main() {
96263
97675
  this.id = "timeline";
96264
97676
  this.className = "deck-widget-timeline";
96265
97677
  this.placement = "fill";
96266
- this.playing = false;
97678
+ this._playing = false;
96267
97679
  this.timerId = null;
96268
97680
  this.handlePlayPause = () => {
96269
- if (this.playing) {
96270
- this.stop();
96271
- } else {
96272
- this.play();
97681
+ const isPlaying = this.getPlaying();
97682
+ const nextPlaying = !isPlaying;
97683
+ this.props.onPlayingChange?.(nextPlaying);
97684
+ if (this.props.playing === void 0) {
97685
+ if (nextPlaying) {
97686
+ this.play();
97687
+ } else {
97688
+ this.stop();
97689
+ }
96273
97690
  }
96274
97691
  };
96275
97692
  this.handleTimeChange = ([value]) => {
96276
- this.currentTime = value;
96277
- this.props.timeline?.setTime(value);
96278
97693
  this.props.onTimeChange(value);
96279
- this.updateHTML();
97694
+ if (this.props.time === void 0) {
97695
+ this.currentTime = value;
97696
+ this.props.timeline?.setTime(value);
97697
+ this.updateHTML();
97698
+ }
96280
97699
  };
96281
97700
  this.tick = () => {
96282
97701
  const {
@@ -96285,51 +97704,90 @@ void main() {
96285
97704
  loop
96286
97705
  } = this.props;
96287
97706
  if (step > 0) {
96288
- let next = Math.round(this.currentTime / step) * step + step;
97707
+ const currentTime = this.getTime();
97708
+ let next = Math.round(currentTime / step) * step + step;
96289
97709
  if (next > max7) {
96290
- if (this.currentTime < max7) {
97710
+ if (currentTime < max7) {
96291
97711
  next = max7;
96292
97712
  } else if (loop) {
96293
97713
  next = min7;
96294
97714
  } else {
96295
97715
  next = max7;
96296
- this.playing = false;
97716
+ this._playing = false;
97717
+ this.props.onPlayingChange?.(false);
96297
97718
  }
96298
97719
  }
96299
- this.currentTime = next;
96300
97720
  this.props.onTimeChange(next);
97721
+ if (this.props.time === void 0) {
97722
+ this.currentTime = next;
97723
+ this.props.timeline?.setTime(next);
97724
+ }
96301
97725
  this.updateHTML();
96302
97726
  }
96303
- if (this.playing) {
97727
+ if (this._playing) {
96304
97728
  this.timerId = window.setTimeout(this.tick, this.props.playInterval);
96305
97729
  } else {
96306
97730
  this.timerId = null;
96307
97731
  }
96308
97732
  };
96309
97733
  this.currentTime = this.props.initialTime ?? this.props.timeRange[0];
96310
- this.props.timeline?.setTime(this.currentTime);
97734
+ const syncTime = this.props.time ?? this.currentTime;
97735
+ this.props.timeline?.setTime(syncTime);
96311
97736
  this.setProps(this.props);
96312
97737
  }
97738
+ /**
97739
+ * Returns the current time value.
97740
+ * In controlled mode, returns the time prop.
97741
+ * In uncontrolled mode, returns the internal state.
97742
+ */
97743
+ getTime() {
97744
+ return this.props.time ?? this.currentTime;
97745
+ }
97746
+ /**
97747
+ * Returns the current playing state.
97748
+ * In controlled mode, returns the playing prop.
97749
+ * In uncontrolled mode, returns the internal state.
97750
+ */
97751
+ getPlaying() {
97752
+ return this.props.playing ?? this._playing;
97753
+ }
96313
97754
  setProps(props) {
97755
+ const { playing: prevPlaying, time: prevTime } = this.props;
96314
97756
  this.viewId = props.viewId ?? this.viewId;
96315
97757
  super.setProps(props);
97758
+ if (props.time !== void 0 && props.time !== prevTime) {
97759
+ this.props.timeline?.setTime(props.time);
97760
+ }
97761
+ if (props.playing !== void 0 && props.playing !== prevPlaying) {
97762
+ if (props.playing && !this._playing) {
97763
+ this._startTimer();
97764
+ } else if (!props.playing && this._playing) {
97765
+ this._stopTimer();
97766
+ }
97767
+ }
96316
97768
  }
96317
97769
  onAdd() {
96318
- this.playing = false;
97770
+ this._playing = false;
96319
97771
  this.timerId = null;
96320
- if (this.props.autoPlay)
96321
- this.play();
97772
+ if (this.props.autoPlay) {
97773
+ if (this.props.playing !== void 0) {
97774
+ this.props.onPlayingChange?.(true);
97775
+ } else {
97776
+ this.play();
97777
+ }
97778
+ }
96322
97779
  }
96323
97780
  onRemove() {
96324
97781
  this.stop();
96325
97782
  }
96326
97783
  onRenderHTML(rootElement) {
96327
97784
  const { timeRange, step, formatLabel } = this.props;
96328
- const currentTime = this.currentTime;
97785
+ const isPlaying = this.getPlaying();
97786
+ const currentTime = this.getTime();
96329
97787
  rootElement.dataset.placement = this.props.placement;
96330
97788
  B2(
96331
97789
  /* @__PURE__ */ u3("div", { className: "deck-widget-button-group", children: [
96332
- this.playing ? /* @__PURE__ */ u3(
97790
+ isPlaying ? /* @__PURE__ */ u3(
96333
97791
  IconButton,
96334
97792
  {
96335
97793
  label: "Pause",
@@ -96366,24 +97824,34 @@ void main() {
96366
97824
  );
96367
97825
  }
96368
97826
  play() {
96369
- this.playing = true;
97827
+ this._playing = true;
96370
97828
  const {
96371
97829
  timeRange: [min7, max7]
96372
97830
  } = this.props;
96373
- if (this.currentTime >= max7) {
97831
+ if (this.props.time === void 0 && this.getTime() >= max7) {
96374
97832
  this.currentTime = min7;
96375
97833
  this.props.onTimeChange(min7);
97834
+ this.props.timeline?.setTime(min7);
96376
97835
  }
96377
97836
  this.updateHTML();
96378
97837
  this.tick();
96379
97838
  }
96380
97839
  stop() {
96381
- this.playing = false;
97840
+ this._stopTimer();
97841
+ this.updateHTML();
97842
+ }
97843
+ /** Start the playback timer (used internally) */
97844
+ _startTimer() {
97845
+ this._playing = true;
97846
+ this.tick();
97847
+ }
97848
+ /** Stop the playback timer (used internally) */
97849
+ _stopTimer() {
97850
+ this._playing = false;
96382
97851
  if (this.timerId !== null) {
96383
97852
  window.clearTimeout(this.timerId);
96384
97853
  this.timerId = null;
96385
97854
  }
96386
- this.updateHTML();
96387
97855
  }
96388
97856
  };
96389
97857
  TimelineWidget.defaultProps = {
@@ -96395,11 +97863,15 @@ void main() {
96395
97863
  timeRange: [0, 100],
96396
97864
  step: 1,
96397
97865
  initialTime: void 0,
97866
+ time: void 0,
96398
97867
  onTimeChange: () => {
96399
97868
  },
96400
97869
  autoPlay: false,
96401
97870
  loop: false,
96402
97871
  playInterval: 1e3,
97872
+ playing: void 0,
97873
+ onPlayingChange: () => {
97874
+ },
96403
97875
  formatLabel: String
96404
97876
  };
96405
97877
 
@@ -96589,53 +98061,72 @@ void main() {
96589
98061
  }
96590
98062
  // eslint-disable-next-line complexity
96591
98063
  setProps(props) {
96592
- const { lightModeTheme, darkModeTheme } = this.props;
98064
+ const { lightModeTheme, darkModeTheme, themeMode: prevThemeMode } = this.props;
96593
98065
  this.placement = props.placement ?? this.placement;
96594
98066
  this.viewId = props.viewId ?? this.viewId;
96595
98067
  super.setProps(props);
96596
- switch (this.themeMode) {
98068
+ const currentMode = this.getThemeMode();
98069
+ if (props.themeMode !== void 0 && props.themeMode !== prevThemeMode) {
98070
+ this._applyTheme(props.themeMode);
98071
+ return;
98072
+ }
98073
+ switch (currentMode) {
96597
98074
  case "light":
96598
98075
  if (props.lightModeTheme && !deepEqual2(props.lightModeTheme, lightModeTheme, 1)) {
96599
- this._setThemeMode("light");
98076
+ this._applyTheme("light");
96600
98077
  }
96601
98078
  break;
96602
98079
  case "dark":
96603
98080
  if (props.darkModeTheme && !deepEqual2(props.darkModeTheme, darkModeTheme, 1)) {
96604
- this._setThemeMode("dark");
98081
+ this._applyTheme("dark");
96605
98082
  }
96606
98083
  break;
96607
98084
  default:
96608
- log_default.warn(`Invalid theme mode ${this.themeMode}`)();
98085
+ log_default.warn(`Invalid theme mode ${currentMode}`)();
96609
98086
  }
96610
98087
  }
96611
98088
  onRenderHTML(rootElement) {
96612
98089
  const { lightModeLabel, darkModeLabel } = this.props;
98090
+ const currentMode = this.getThemeMode();
96613
98091
  B2(
96614
98092
  /* @__PURE__ */ u3(
96615
98093
  IconButton,
96616
98094
  {
96617
98095
  onClick: this._handleClick.bind(this),
96618
- label: this.themeMode === "dark" ? darkModeLabel : lightModeLabel,
96619
- className: this.themeMode === "dark" ? "deck-widget-moon" : "deck-widget-sun"
98096
+ label: currentMode === "dark" ? darkModeLabel : lightModeLabel,
98097
+ className: currentMode === "dark" ? "deck-widget-moon" : "deck-widget-sun"
96620
98098
  }
96621
98099
  ),
96622
98100
  rootElement
96623
98101
  );
96624
98102
  }
96625
98103
  onAdd() {
96626
- this._setThemeMode(this.themeMode);
98104
+ this._applyTheme(this.getThemeMode());
98105
+ }
98106
+ /**
98107
+ * Returns the current theme mode.
98108
+ * In controlled mode, returns the themeMode prop.
98109
+ * In uncontrolled mode, returns the internal state.
98110
+ */
98111
+ getThemeMode() {
98112
+ return this.props.themeMode ?? this.themeMode;
96627
98113
  }
96628
98114
  _handleClick() {
96629
- const newThemeMode = this.themeMode === "dark" ? "light" : "dark";
96630
- this._setThemeMode(newThemeMode);
98115
+ const currentMode = this.getThemeMode();
98116
+ const nextMode = currentMode === "dark" ? "light" : "dark";
98117
+ this.props.onThemeModeChange?.(nextMode);
98118
+ if (this.props.themeMode === void 0) {
98119
+ this.themeMode = nextMode;
98120
+ this._applyTheme(nextMode);
98121
+ }
96631
98122
  }
96632
- _setThemeMode(themeMode) {
96633
- this.themeMode = themeMode;
98123
+ /** Apply theme styling without changing internal state */
98124
+ _applyTheme(themeMode) {
96634
98125
  const container = this.rootElement?.closest(".deck-widget-container");
96635
98126
  if (container) {
96636
98127
  const themeStyle = themeMode === "dark" ? this.props.darkModeTheme : this.props.lightModeTheme;
96637
98128
  applyStyles(container, themeStyle);
96638
- const label = this.themeMode === "dark" ? this.props.darkModeLabel : this.props.lightModeLabel;
98129
+ const label = themeMode === "dark" ? this.props.darkModeLabel : this.props.lightModeLabel;
96639
98130
  log_default.log(1, `Switched theme to ${label}`, themeStyle)();
96640
98131
  this.updateHTML();
96641
98132
  }
@@ -96661,7 +98152,10 @@ void main() {
96661
98152
  lightModeTheme: LightGlassTheme,
96662
98153
  darkModeLabel: "Dark Mode",
96663
98154
  darkModeTheme: DarkGlassTheme,
96664
- initialThemeMode: "auto"
98155
+ initialThemeMode: "auto",
98156
+ themeMode: void 0,
98157
+ onThemeModeChange: () => {
98158
+ }
96665
98159
  };
96666
98160
 
96667
98161
  // ../widgets/src/loading-widget.tsx
@@ -96696,6 +98190,7 @@ void main() {
96696
98190
  const loading = layers.some((layer) => !layer.isLoaded);
96697
98191
  if (loading !== this.loading) {
96698
98192
  this.loading = loading;
98193
+ this.props.onLoadingChange?.(loading);
96699
98194
  this.updateHTML();
96700
98195
  }
96701
98196
  }
@@ -96708,7 +98203,9 @@ void main() {
96708
98203
  id: "loading",
96709
98204
  placement: "top-left",
96710
98205
  viewId: null,
96711
- label: "Loading layer data"
98206
+ label: "Loading layer data",
98207
+ onLoadingChange: () => {
98208
+ }
96712
98209
  };
96713
98210
 
96714
98211
  // ../widgets/src/stats-widget.tsx
@@ -96734,19 +98231,31 @@ void main() {
96734
98231
  this.className = "deck-widget-stats";
96735
98232
  this.placement = "top-left";
96736
98233
  this._counter = 0;
96737
- this.collapsed = true;
96738
- this._toggleCollapsed = () => {
96739
- this.collapsed = !this.collapsed;
96740
- this.updateHTML();
98234
+ this._expanded = false;
98235
+ this._toggleExpanded = () => {
98236
+ const nextExpanded = !this.getExpanded();
98237
+ this.props.onExpandedChange?.(nextExpanded);
98238
+ if (this.props.expanded === void 0) {
98239
+ this._expanded = nextExpanded;
98240
+ this.updateHTML();
98241
+ }
96741
98242
  };
96742
98243
  this._getFps = () => {
96743
98244
  return Math.round(this.deck?.metrics.fps ?? 0);
96744
98245
  };
96745
98246
  this._formatters = { ...DEFAULT_FORMATTERS };
96746
98247
  this._resetOnUpdate = { ...this.props.resetOnUpdate };
96747
- this.collapsed = !props.defaultIsExpanded;
98248
+ this._expanded = Boolean(props.initialExpanded);
96748
98249
  this.setProps(props);
96749
98250
  }
98251
+ /**
98252
+ * Returns the current expanded state.
98253
+ * In controlled mode, returns the expanded prop.
98254
+ * In uncontrolled mode, returns the internal state.
98255
+ */
98256
+ getExpanded() {
98257
+ return this.props.expanded ?? this._expanded;
98258
+ }
96750
98259
  setProps(props) {
96751
98260
  this.placement = props.placement ?? this.placement;
96752
98261
  this.viewId = props.viewId ?? this.viewId;
@@ -96767,9 +98276,9 @@ void main() {
96767
98276
  }
96768
98277
  }
96769
98278
  onRenderHTML(rootElement) {
96770
- const collapsed = this.collapsed;
96771
- if (collapsed) {
96772
- B2(/* @__PURE__ */ u3(FpsIcon, { getFps: this._getFps, onClick: this._toggleCollapsed }), rootElement);
98279
+ const isExpanded = this.getExpanded();
98280
+ if (!isExpanded) {
98281
+ B2(/* @__PURE__ */ u3(FpsIcon, { getFps: this._getFps, onClick: this._toggleExpanded }), rootElement);
96773
98282
  return;
96774
98283
  }
96775
98284
  const stats2 = this._getStats();
@@ -96796,7 +98305,7 @@ void main() {
96796
98305
  {
96797
98306
  className: "deck-widget-stats-header",
96798
98307
  style: { cursor: "pointer", pointerEvents: "auto" },
96799
- onClick: this._toggleCollapsed,
98308
+ onClick: this._toggleExpanded,
96800
98309
  children: [
96801
98310
  /* @__PURE__ */ u3("b", { children: title }),
96802
98311
  deviceLabel && /* @__PURE__ */ u3("span", { className: "deck-widget-stats-device", children: deviceLabel }),
@@ -96810,7 +98319,7 @@ void main() {
96810
98319
  );
96811
98320
  }
96812
98321
  onRedraw() {
96813
- if (!this.collapsed) {
98322
+ if (this.getExpanded()) {
96814
98323
  const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);
96815
98324
  if (this._counter++ % framesPerUpdate === 0) {
96816
98325
  this.updateHTML();
@@ -96863,13 +98372,16 @@ void main() {
96863
98372
  type: "deck",
96864
98373
  placement: "top-left",
96865
98374
  viewId: null,
96866
- defaultIsExpanded: false,
98375
+ initialExpanded: false,
96867
98376
  stats: void 0,
96868
98377
  title: "Stats",
96869
98378
  framesPerUpdate: 1,
96870
98379
  formatters: {},
96871
98380
  resetOnUpdate: {},
96872
- id: "stats"
98381
+ id: "stats",
98382
+ expanded: void 0,
98383
+ onExpandedChange: () => {
98384
+ }
96873
98385
  };
96874
98386
  function FpsIcon({ getFps, onClick }) {
96875
98387
  const [fps, setFps] = h2(getFps());