maplibre-gl 3.2.2 → 3.3.1

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 (46) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +2 -1
  3. package/build/generate-dist-package.js +7 -2
  4. package/build/generate-struct-arrays.ts +3 -1
  5. package/build/generate-style-code.ts +7 -8
  6. package/build/generate-typings.ts +1 -1
  7. package/dist/LICENSE.txt +116 -0
  8. package/dist/maplibre-gl-csp-worker.js +1 -1
  9. package/dist/maplibre-gl-csp-worker.js.map +1 -1
  10. package/dist/maplibre-gl-csp.js +1 -1
  11. package/dist/maplibre-gl-csp.js.map +1 -1
  12. package/dist/maplibre-gl-dev.js +472 -195
  13. package/dist/maplibre-gl-dev.js.map +1 -1
  14. package/dist/maplibre-gl.d.ts +58 -16
  15. package/dist/maplibre-gl.js +3 -3
  16. package/dist/maplibre-gl.js.map +1 -1
  17. package/dist/package.json +1 -1
  18. package/package.json +24 -23
  19. package/src/data/array_types.g.ts +78 -14
  20. package/src/data/bucket/symbol_attributes.ts +7 -1
  21. package/src/data/bucket/symbol_bucket.ts +4 -1
  22. package/src/render/draw_symbol.ts +8 -9
  23. package/src/render/program.ts +15 -0
  24. package/src/source/vector_tile_source.ts +0 -1
  25. package/src/source/video_source.ts +4 -0
  26. package/src/style/properties.ts +4 -0
  27. package/src/style/style.ts +14 -8
  28. package/src/style/style_layer/background_style_layer_properties.g.ts +1 -6
  29. package/src/style/style_layer/circle_style_layer_properties.g.ts +1 -6
  30. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +1 -6
  31. package/src/style/style_layer/fill_style_layer_properties.g.ts +1 -6
  32. package/src/style/style_layer/heatmap_style_layer_properties.g.ts +1 -6
  33. package/src/style/style_layer/hillshade_style_layer_properties.g.ts +1 -6
  34. package/src/style/style_layer/line_style_layer_properties.g.ts +1 -6
  35. package/src/style/style_layer/raster_style_layer_properties.g.ts +1 -6
  36. package/src/style/style_layer/symbol_style_layer_properties.g.ts +4 -6
  37. package/src/style/style_layer/variable_text_anchor.test.ts +117 -0
  38. package/src/style/style_layer/variable_text_anchor.ts +163 -0
  39. package/src/symbol/placement.ts +52 -40
  40. package/src/symbol/symbol_layout.ts +42 -116
  41. package/src/ui/control/navigation_control.ts +0 -1
  42. package/src/ui/map.test.ts +37 -8
  43. package/src/ui/map.ts +14 -13
  44. package/src/ui/marker.ts +1 -1
  45. package/src/ui/popup.ts +1 -1
  46. package/src/util/throttle.ts +7 -3
@@ -1,4 +1,4 @@
1
- /* MapLibre GL JS is licensed under the 3-Clause BSD License. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v3.2.2/LICENSE.txt */
1
+ /* MapLibre GL JS is licensed under the 3-Clause BSD License. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v3.3.1/LICENSE.txt */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -2549,6 +2549,25 @@ var layout_symbol = {
2549
2549
  },
2550
2550
  "property-type": "data-constant"
2551
2551
  },
2552
+ "text-variable-anchor-offset": {
2553
+ type: "variableAnchorOffsetCollection",
2554
+ requires: [
2555
+ "text-field",
2556
+ {
2557
+ "symbol-placement": [
2558
+ "point"
2559
+ ]
2560
+ }
2561
+ ],
2562
+ expression: {
2563
+ interpolated: true,
2564
+ parameters: [
2565
+ "zoom",
2566
+ "feature"
2567
+ ]
2568
+ },
2569
+ "property-type": "data-driven"
2570
+ },
2552
2571
  "text-anchor": {
2553
2572
  type: "enum",
2554
2573
  values: {
@@ -4868,6 +4887,7 @@ const CollatorType = { kind: 'collator' };
4868
4887
  const FormattedType = { kind: 'formatted' };
4869
4888
  const PaddingType = { kind: 'padding' };
4870
4889
  const ResolvedImageType = { kind: 'resolvedImage' };
4890
+ const VariableAnchorOffsetCollectionType = { kind: 'variableAnchorOffsetCollection' };
4871
4891
  function array$1(itemType, N) {
4872
4892
  return {
4873
4893
  kind: 'array',
@@ -4896,7 +4916,8 @@ const valueMemberTypes = [
4896
4916
  ObjectType,
4897
4917
  array$1(ValueType),
4898
4918
  PaddingType,
4899
- ResolvedImageType
4919
+ ResolvedImageType,
4920
+ VariableAnchorOffsetCollectionType
4900
4921
  ];
4901
4922
  /**
4902
4923
  * Returns null if `t` is a subtype of `expected`; otherwise returns an
@@ -5592,6 +5613,44 @@ class Padding {
5592
5613
  }
5593
5614
  }
5594
5615
 
5616
+ /** Set of valid anchor positions, as a set for validation */
5617
+ const anchors = new Set(['center', 'left', 'right', 'top', 'bottom', 'top-left', 'top-right', 'bottom-left', 'bottom-right']);
5618
+ /**
5619
+ * Utility class to assist managing values for text-variable-anchor-offset property. Create instances from
5620
+ * bare arrays using the static method `VariableAnchorOffsetCollection.parse`.
5621
+ * @private
5622
+ */
5623
+ class VariableAnchorOffsetCollection {
5624
+ constructor(values) {
5625
+ this.values = values.slice();
5626
+ }
5627
+ static parse(input) {
5628
+ if (input instanceof VariableAnchorOffsetCollection) {
5629
+ return input;
5630
+ }
5631
+ if (!Array.isArray(input) ||
5632
+ input.length < 1 ||
5633
+ input.length % 2 !== 0) {
5634
+ return undefined;
5635
+ }
5636
+ for (let i = 0; i < input.length; i += 2) {
5637
+ // Elements in even positions should be anchor positions; Elements in odd positions should be offset values
5638
+ const anchorValue = input[i];
5639
+ const offsetValue = input[i + 1];
5640
+ if (typeof anchorValue !== 'string' || !anchors.has(anchorValue)) {
5641
+ return undefined;
5642
+ }
5643
+ if (!Array.isArray(offsetValue) || offsetValue.length !== 2 || typeof offsetValue[0] !== 'number' || typeof offsetValue[1] !== 'number') {
5644
+ return undefined;
5645
+ }
5646
+ }
5647
+ return new VariableAnchorOffsetCollection(input);
5648
+ }
5649
+ toString() {
5650
+ return JSON.stringify(this.values);
5651
+ }
5652
+ }
5653
+
5595
5654
  class ResolvedImage {
5596
5655
  constructor(options) {
5597
5656
  this.name = options.name;
@@ -5620,31 +5679,16 @@ function validateRGBA(r, g, b, a) {
5620
5679
  return null;
5621
5680
  }
5622
5681
  function isValue(mixed) {
5623
- if (mixed === null) {
5624
- return true;
5625
- }
5626
- else if (typeof mixed === 'string') {
5627
- return true;
5628
- }
5629
- else if (typeof mixed === 'boolean') {
5630
- return true;
5631
- }
5632
- else if (typeof mixed === 'number') {
5633
- return true;
5634
- }
5635
- else if (mixed instanceof Color) {
5636
- return true;
5637
- }
5638
- else if (mixed instanceof Collator) {
5639
- return true;
5640
- }
5641
- else if (mixed instanceof Formatted) {
5642
- return true;
5643
- }
5644
- else if (mixed instanceof Padding) {
5645
- return true;
5646
- }
5647
- else if (mixed instanceof ResolvedImage) {
5682
+ if (mixed === null ||
5683
+ typeof mixed === 'string' ||
5684
+ typeof mixed === 'boolean' ||
5685
+ typeof mixed === 'number' ||
5686
+ mixed instanceof Color ||
5687
+ mixed instanceof Collator ||
5688
+ mixed instanceof Formatted ||
5689
+ mixed instanceof Padding ||
5690
+ mixed instanceof VariableAnchorOffsetCollection ||
5691
+ mixed instanceof ResolvedImage) {
5648
5692
  return true;
5649
5693
  }
5650
5694
  else if (Array.isArray(mixed)) {
@@ -5692,6 +5736,9 @@ function typeOf(value) {
5692
5736
  else if (value instanceof Padding) {
5693
5737
  return PaddingType;
5694
5738
  }
5739
+ else if (value instanceof VariableAnchorOffsetCollection) {
5740
+ return VariableAnchorOffsetCollectionType;
5741
+ }
5695
5742
  else if (value instanceof ResolvedImage) {
5696
5743
  return ResolvedImageType;
5697
5744
  }
@@ -5725,7 +5772,7 @@ function toString(value) {
5725
5772
  else if (type === 'string' || type === 'number' || type === 'boolean') {
5726
5773
  return String(value);
5727
5774
  }
5728
- else if (value instanceof Color || value instanceof Formatted || value instanceof Padding || value instanceof ResolvedImage) {
5775
+ else if (value instanceof Color || value instanceof Formatted || value instanceof Padding || value instanceof VariableAnchorOffsetCollection || value instanceof ResolvedImage) {
5729
5776
  return value.toString();
5730
5777
  }
5731
5778
  else {
@@ -5889,71 +5936,80 @@ class Coercion {
5889
5936
  return new Coercion(type, parsed);
5890
5937
  }
5891
5938
  evaluate(ctx) {
5892
- if (this.type.kind === 'boolean') {
5893
- return Boolean(this.args[0].evaluate(ctx));
5894
- }
5895
- else if (this.type.kind === 'color') {
5896
- let input;
5897
- let error;
5898
- for (const arg of this.args) {
5899
- input = arg.evaluate(ctx);
5900
- error = null;
5901
- if (input instanceof Color) {
5902
- return input;
5903
- }
5904
- else if (typeof input === 'string') {
5905
- const c = ctx.parseColor(input);
5906
- if (c)
5907
- return c;
5908
- }
5909
- else if (Array.isArray(input)) {
5910
- if (input.length < 3 || input.length > 4) {
5911
- error = `Invalid rbga value ${JSON.stringify(input)}: expected an array containing either three or four numeric values.`;
5939
+ switch (this.type.kind) {
5940
+ case 'boolean':
5941
+ return Boolean(this.args[0].evaluate(ctx));
5942
+ case 'color': {
5943
+ let input;
5944
+ let error;
5945
+ for (const arg of this.args) {
5946
+ input = arg.evaluate(ctx);
5947
+ error = null;
5948
+ if (input instanceof Color) {
5949
+ return input;
5912
5950
  }
5913
- else {
5914
- error = validateRGBA(input[0], input[1], input[2], input[3]);
5951
+ else if (typeof input === 'string') {
5952
+ const c = ctx.parseColor(input);
5953
+ if (c)
5954
+ return c;
5915
5955
  }
5916
- if (!error) {
5917
- return new Color(input[0] / 255, input[1] / 255, input[2] / 255, input[3]);
5956
+ else if (Array.isArray(input)) {
5957
+ if (input.length < 3 || input.length > 4) {
5958
+ error = `Invalid rbga value ${JSON.stringify(input)}: expected an array containing either three or four numeric values.`;
5959
+ }
5960
+ else {
5961
+ error = validateRGBA(input[0], input[1], input[2], input[3]);
5962
+ }
5963
+ if (!error) {
5964
+ return new Color(input[0] / 255, input[1] / 255, input[2] / 255, input[3]);
5965
+ }
5918
5966
  }
5919
5967
  }
5968
+ throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
5920
5969
  }
5921
- throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
5922
- }
5923
- else if (this.type.kind === 'padding') {
5924
- let input;
5925
- for (const arg of this.args) {
5926
- input = arg.evaluate(ctx);
5927
- const pad = Padding.parse(input);
5928
- if (pad) {
5929
- return pad;
5970
+ case 'padding': {
5971
+ let input;
5972
+ for (const arg of this.args) {
5973
+ input = arg.evaluate(ctx);
5974
+ const pad = Padding.parse(input);
5975
+ if (pad) {
5976
+ return pad;
5977
+ }
5930
5978
  }
5979
+ throw new RuntimeError(`Could not parse padding from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
5931
5980
  }
5932
- throw new RuntimeError(`Could not parse padding from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
5933
- }
5934
- else if (this.type.kind === 'number') {
5935
- let value = null;
5936
- for (const arg of this.args) {
5937
- value = arg.evaluate(ctx);
5938
- if (value === null)
5939
- return 0;
5940
- const num = Number(value);
5941
- if (isNaN(num))
5942
- continue;
5943
- return num;
5981
+ case 'variableAnchorOffsetCollection': {
5982
+ let input;
5983
+ for (const arg of this.args) {
5984
+ input = arg.evaluate(ctx);
5985
+ const coll = VariableAnchorOffsetCollection.parse(input);
5986
+ if (coll) {
5987
+ return coll;
5988
+ }
5989
+ }
5990
+ throw new RuntimeError(`Could not parse variableAnchorOffsetCollection from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
5944
5991
  }
5945
- throw new RuntimeError(`Could not convert ${JSON.stringify(value)} to number.`);
5946
- }
5947
- else if (this.type.kind === 'formatted') {
5948
- // There is no explicit 'to-formatted' but this coercion can be implicitly
5949
- // created by properties that expect the 'formatted' type.
5950
- return Formatted.fromString(toString(this.args[0].evaluate(ctx)));
5951
- }
5952
- else if (this.type.kind === 'resolvedImage') {
5953
- return ResolvedImage.fromString(toString(this.args[0].evaluate(ctx)));
5954
- }
5955
- else {
5956
- return toString(this.args[0].evaluate(ctx));
5992
+ case 'number': {
5993
+ let value = null;
5994
+ for (const arg of this.args) {
5995
+ value = arg.evaluate(ctx);
5996
+ if (value === null)
5997
+ return 0;
5998
+ const num = Number(value);
5999
+ if (isNaN(num))
6000
+ continue;
6001
+ return num;
6002
+ }
6003
+ throw new RuntimeError(`Could not convert ${JSON.stringify(value)} to number.`);
6004
+ }
6005
+ case 'formatted':
6006
+ // There is no explicit 'to-formatted' but this coercion can be implicitly
6007
+ // created by properties that expect the 'formatted' type.
6008
+ return Formatted.fromString(toString(this.args[0].evaluate(ctx)));
6009
+ case 'resolvedImage':
6010
+ return ResolvedImage.fromString(toString(this.args[0].evaluate(ctx)));
6011
+ default:
6012
+ return toString(this.args[0].evaluate(ctx));
5957
6013
  }
5958
6014
  }
5959
6015
  eachChild(fn) {
@@ -6075,6 +6131,9 @@ class ParsingContext {
6075
6131
  else if (expected.kind === 'padding' && (actual.kind === 'value' || actual.kind === 'number' || actual.kind === 'array')) {
6076
6132
  parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
6077
6133
  }
6134
+ else if (expected.kind === 'variableAnchorOffsetCollection' && (actual.kind === 'value' || actual.kind === 'array')) {
6135
+ parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
6136
+ }
6078
6137
  else if (this.checkSubtype(expected, actual)) {
6079
6138
  return null;
6080
6139
  }
@@ -6845,6 +6904,7 @@ const interpolateFactory = (interpolationType) => {
6845
6904
  case 'color': return color;
6846
6905
  case 'array': return array;
6847
6906
  case 'padding': return padding;
6907
+ case 'variableAnchorOffsetCollection': return variableAnchorOffsetCollection;
6848
6908
  }
6849
6909
  };
6850
6910
  function number(from, to, t) {
@@ -6906,11 +6966,32 @@ function array(from, to, t) {
6906
6966
  function padding(from, to, t) {
6907
6967
  return new Padding(array(from.values, to.values, t));
6908
6968
  }
6969
+ function variableAnchorOffsetCollection(from, to, t) {
6970
+ const fromValues = from.values;
6971
+ const toValues = to.values;
6972
+ if (fromValues.length !== toValues.length) {
6973
+ throw new RuntimeError(`Cannot interpolate values of different length. from: ${from.toString()}, to: ${to.toString()}`);
6974
+ }
6975
+ const output = [];
6976
+ for (let i = 0; i < fromValues.length; i += 2) {
6977
+ // Anchor entries must match
6978
+ if (fromValues[i] !== toValues[i]) {
6979
+ throw new RuntimeError(`Cannot interpolate values containing mismatched anchors. from[${i}]: ${fromValues[i]}, to[${i}]: ${toValues[i]}`);
6980
+ }
6981
+ output.push(fromValues[i]);
6982
+ // Interpolate the offset values for each anchor
6983
+ const [fx, fy] = fromValues[i + 1];
6984
+ const [tx, ty] = toValues[i + 1];
6985
+ output.push([number(fx, tx, t), number(fy, ty, t)]);
6986
+ }
6987
+ return new VariableAnchorOffsetCollection(output);
6988
+ }
6909
6989
  const interpolate = {
6910
6990
  number,
6911
6991
  color,
6912
6992
  array,
6913
6993
  padding,
6994
+ variableAnchorOffsetCollection
6914
6995
  };
6915
6996
 
6916
6997
  class Interpolate {
@@ -7009,6 +7090,7 @@ class Interpolate {
7009
7090
  if (!verifyType(outputType, NumberType) &&
7010
7091
  !verifyType(outputType, ColorType) &&
7011
7092
  !verifyType(outputType, PaddingType) &&
7093
+ !verifyType(outputType, VariableAnchorOffsetCollectionType) &&
7012
7094
  !verifyType(outputType, array$1(NumberType))) {
7013
7095
  return context.error(`Type ${toString$1(outputType)} is not interpolatable.`);
7014
7096
  }
@@ -8868,6 +8950,9 @@ function normalizePropertyExpression(value, specification) {
8868
8950
  else if (specification.type === 'padding' && (typeof value === 'number' || Array.isArray(value))) {
8869
8951
  constant = Padding.parse(value);
8870
8952
  }
8953
+ else if (specification.type === 'variableAnchorOffsetCollection' && Array.isArray(value)) {
8954
+ constant = VariableAnchorOffsetCollection.parse(value);
8955
+ }
8871
8956
  return {
8872
8957
  kind: 'constant',
8873
8958
  evaluate: () => constant
@@ -8921,7 +9006,8 @@ function getExpectedType(spec) {
8921
9006
  boolean: BooleanType,
8922
9007
  formatted: FormattedType,
8923
9008
  padding: PaddingType,
8924
- resolvedImage: ResolvedImageType
9009
+ resolvedImage: ResolvedImageType,
9010
+ variableAnchorOffsetCollection: VariableAnchorOffsetCollectionType
8925
9011
  };
8926
9012
  if (spec.type === 'array') {
8927
9013
  return array$1(types[spec.value] || ValueType, spec.length);
@@ -8941,6 +9027,9 @@ function getDefaultValue(spec) {
8941
9027
  else if (spec.type === 'padding') {
8942
9028
  return Padding.parse(spec.default) || null;
8943
9029
  }
9030
+ else if (spec.type === 'variableAnchorOffsetCollection') {
9031
+ return VariableAnchorOffsetCollection.parse(spec.default) || null;
9032
+ }
8944
9033
  else if (spec.default === undefined) {
8945
9034
  return null;
8946
9035
  }
@@ -10610,6 +10699,38 @@ function validatePadding(options) {
10610
10699
  }
10611
10700
  }
10612
10701
 
10702
+ function validateVariableAnchorOffsetCollection(options) {
10703
+ const key = options.key;
10704
+ const value = options.value;
10705
+ const type = getType(value);
10706
+ const styleSpec = options.styleSpec;
10707
+ if (type !== 'array' || value.length < 1 || value.length % 2 !== 0) {
10708
+ return [new ValidationError(key, value, 'variableAnchorOffsetCollection requires a non-empty array of even length')];
10709
+ }
10710
+ let errors = [];
10711
+ for (let i = 0; i < value.length; i += 2) {
10712
+ // Elements in even positions should be values from text-anchor enum
10713
+ errors = errors.concat(validateEnum({
10714
+ key: `${key}[${i}]`,
10715
+ value: value[i],
10716
+ valueSpec: styleSpec['layout_symbol']['text-anchor']
10717
+ }));
10718
+ // Elements in odd positions should be points (2-element numeric arrays)
10719
+ errors = errors.concat(validateArray({
10720
+ key: `${key}[${i + 1}]`,
10721
+ value: value[i + 1],
10722
+ valueSpec: {
10723
+ length: 2,
10724
+ value: 'number'
10725
+ },
10726
+ validateSpec: options.validateSpec,
10727
+ style: options.style,
10728
+ styleSpec
10729
+ }));
10730
+ }
10731
+ return errors;
10732
+ }
10733
+
10613
10734
  function validateSprite(options) {
10614
10735
  let errors = [];
10615
10736
  const sprite = options.value;
@@ -10672,6 +10793,7 @@ const VALIDATORS = {
10672
10793
  'formatted': validateFormatted,
10673
10794
  'resolvedImage': validateImage,
10674
10795
  'padding': validatePadding,
10796
+ 'variableAnchorOffsetCollection': validateVariableAnchorOffsetCollection,
10675
10797
  'sprite': validateSprite,
10676
10798
  };
10677
10799
  // Main recursive validation function. Tracks:
@@ -12246,6 +12368,9 @@ class Layout {
12246
12368
  this._properties = properties;
12247
12369
  this._values = Object.create(properties.defaultPropertyValues);
12248
12370
  }
12371
+ hasValue(name) {
12372
+ return this._values[name].value !== undefined;
12373
+ }
12249
12374
  getValue(name) {
12250
12375
  return clone$9(this._values[name].value);
12251
12376
  }
@@ -13371,10 +13496,11 @@ register('StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48', StructArrayLayout2i2ui3ul3u
13371
13496
  * [0]: Int16[8]
13372
13497
  * [16]: Uint16[15]
13373
13498
  * [48]: Uint32[1]
13374
- * [52]: Float32[4]
13499
+ * [52]: Float32[2]
13500
+ * [60]: Uint16[2]
13375
13501
  *
13376
13502
  */
13377
- class StructArrayLayout8i15ui1ul4f68 extends StructArray {
13503
+ class StructArrayLayout8i15ui1ul2f2ui64 extends StructArray {
13378
13504
  _refreshViews() {
13379
13505
  this.uint8 = new Uint8Array(this.arrayBuffer);
13380
13506
  this.int16 = new Int16Array(this.arrayBuffer);
@@ -13388,8 +13514,8 @@ class StructArrayLayout8i15ui1ul4f68 extends StructArray {
13388
13514
  return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
13389
13515
  }
13390
13516
  emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) {
13391
- const o2 = i * 34;
13392
- const o4 = i * 17;
13517
+ const o2 = i * 32;
13518
+ const o4 = i * 16;
13393
13519
  this.int16[o2 + 0] = v0;
13394
13520
  this.int16[o2 + 1] = v1;
13395
13521
  this.int16[o2 + 2] = v2;
@@ -13416,13 +13542,13 @@ class StructArrayLayout8i15ui1ul4f68 extends StructArray {
13416
13542
  this.uint32[o4 + 12] = v23;
13417
13543
  this.float32[o4 + 13] = v24;
13418
13544
  this.float32[o4 + 14] = v25;
13419
- this.float32[o4 + 15] = v26;
13420
- this.float32[o4 + 16] = v27;
13545
+ this.uint16[o2 + 30] = v26;
13546
+ this.uint16[o2 + 31] = v27;
13421
13547
  return i;
13422
13548
  }
13423
13549
  }
13424
- StructArrayLayout8i15ui1ul4f68.prototype.bytesPerElement = 68;
13425
- register('StructArrayLayout8i15ui1ul4f68', StructArrayLayout8i15ui1ul4f68);
13550
+ StructArrayLayout8i15ui1ul2f2ui64.prototype.bytesPerElement = 64;
13551
+ register('StructArrayLayout8i15ui1ul2f2ui64', StructArrayLayout8i15ui1ul2f2ui64);
13426
13552
  /**
13427
13553
  * @internal
13428
13554
  * Implementation of the StructArray layout:
@@ -13447,6 +13573,35 @@ class StructArrayLayout1f4 extends StructArray {
13447
13573
  }
13448
13574
  StructArrayLayout1f4.prototype.bytesPerElement = 4;
13449
13575
  register('StructArrayLayout1f4', StructArrayLayout1f4);
13576
+ /**
13577
+ * @internal
13578
+ * Implementation of the StructArray layout:
13579
+ * [0]: Uint16[1]
13580
+ * [4]: Float32[2]
13581
+ *
13582
+ */
13583
+ class StructArrayLayout1ui2f12 extends StructArray {
13584
+ _refreshViews() {
13585
+ this.uint8 = new Uint8Array(this.arrayBuffer);
13586
+ this.uint16 = new Uint16Array(this.arrayBuffer);
13587
+ this.float32 = new Float32Array(this.arrayBuffer);
13588
+ }
13589
+ emplaceBack(v0, v1, v2) {
13590
+ const i = this.length;
13591
+ this.resize(i + 1);
13592
+ return this.emplace(i, v0, v1, v2);
13593
+ }
13594
+ emplace(i, v0, v1, v2) {
13595
+ const o2 = i * 6;
13596
+ const o4 = i * 3;
13597
+ this.uint16[o2 + 0] = v0;
13598
+ this.float32[o4 + 1] = v1;
13599
+ this.float32[o4 + 2] = v2;
13600
+ return i;
13601
+ }
13602
+ }
13603
+ StructArrayLayout1ui2f12.prototype.bytesPerElement = 12;
13604
+ register('StructArrayLayout1ui2f12', StructArrayLayout1ui2f12);
13450
13605
  /**
13451
13606
  * @internal
13452
13607
  * Implementation of the StructArray layout:
@@ -13640,13 +13795,13 @@ class SymbolInstanceStruct extends Struct {
13640
13795
  get crossTileID() { return this._structArray.uint32[this._pos4 + 12]; }
13641
13796
  set crossTileID(x) { this._structArray.uint32[this._pos4 + 12] = x; }
13642
13797
  get textBoxScale() { return this._structArray.float32[this._pos4 + 13]; }
13643
- get textOffset0() { return this._structArray.float32[this._pos4 + 14]; }
13644
- get textOffset1() { return this._structArray.float32[this._pos4 + 15]; }
13645
- get collisionCircleDiameter() { return this._structArray.float32[this._pos4 + 16]; }
13798
+ get collisionCircleDiameter() { return this._structArray.float32[this._pos4 + 14]; }
13799
+ get textAnchorOffsetStartIndex() { return this._structArray.uint16[this._pos2 + 30]; }
13800
+ get textAnchorOffsetEndIndex() { return this._structArray.uint16[this._pos2 + 31]; }
13646
13801
  }
13647
- SymbolInstanceStruct.prototype.size = 68;
13802
+ SymbolInstanceStruct.prototype.size = 64;
13648
13803
  /** @internal */
13649
- class SymbolInstanceArray extends StructArrayLayout8i15ui1ul4f68 {
13804
+ class SymbolInstanceArray extends StructArrayLayout8i15ui1ul2f2ui64 {
13650
13805
  /**
13651
13806
  * Return the SymbolInstanceStruct at the given location in the array.
13652
13807
  * @param index The index of the element.
@@ -13669,6 +13824,24 @@ class SymbolLineVertexArray extends StructArrayLayout3i6 {
13669
13824
  }
13670
13825
  register('SymbolLineVertexArray', SymbolLineVertexArray);
13671
13826
  /** @internal */
13827
+ class TextAnchorOffsetStruct extends Struct {
13828
+ get textAnchor() { return this._structArray.uint16[this._pos2 + 0]; }
13829
+ get textOffset0() { return this._structArray.float32[this._pos4 + 1]; }
13830
+ get textOffset1() { return this._structArray.float32[this._pos4 + 2]; }
13831
+ }
13832
+ TextAnchorOffsetStruct.prototype.size = 12;
13833
+ /** @internal */
13834
+ class TextAnchorOffsetArray extends StructArrayLayout1ui2f12 {
13835
+ /**
13836
+ * Return the TextAnchorOffsetStruct at the given location in the array.
13837
+ * @param index The index of the element.
13838
+ */
13839
+ get(index) {
13840
+ return new TextAnchorOffsetStruct(this, index);
13841
+ }
13842
+ }
13843
+ register('TextAnchorOffsetArray', TextAnchorOffsetArray);
13844
+ /** @internal */
13672
13845
  class FeatureIndexStruct extends Struct {
13673
13846
  get featureIndex() { return this._structArray.uint32[this._pos4 + 0]; }
13674
13847
  get sourceLayerIndex() { return this._structArray.uint16[this._pos2 + 2]; }
@@ -25433,8 +25606,9 @@ const symbolInstance = createLayout([
25433
25606
  { type: 'Uint16', name: 'useRuntimeCollisionCircles' },
25434
25607
  { type: 'Uint32', name: 'crossTileID' },
25435
25608
  { type: 'Float32', name: 'textBoxScale' },
25436
- { type: 'Float32', components: 2, name: 'textOffset' },
25437
25609
  { type: 'Float32', name: 'collisionCircleDiameter' },
25610
+ { type: 'Uint16', name: 'textAnchorOffsetStartIndex' },
25611
+ { type: 'Uint16', name: 'textAnchorOffsetEndIndex' }
25438
25612
  ]);
25439
25613
  const glyphOffset = createLayout([
25440
25614
  { type: 'Float32', name: 'offsetX' }
@@ -25444,6 +25618,10 @@ const lineVertex = createLayout([
25444
25618
  { type: 'Int16', name: 'y' },
25445
25619
  { type: 'Int16', name: 'tileUnitDistanceFromAnchor' }
25446
25620
  ]);
25621
+ const textAnchorOffset = createLayout([
25622
+ { type: 'Uint16', name: 'textAnchor' },
25623
+ { type: 'Float32', components: 2, name: 'textOffset' }
25624
+ ]);
25447
25625
 
25448
25626
  function transformTextInternal(text, layer, feature) {
25449
25627
  const transform = layer.layout.get('text-transform').evaluate(feature, {});
@@ -27436,6 +27614,7 @@ class SymbolBucket {
27436
27614
  this.glyphOffsetArray = new GlyphOffsetArray();
27437
27615
  this.lineVertexArray = new SymbolLineVertexArray();
27438
27616
  this.symbolInstances = new SymbolInstanceArray();
27617
+ this.textAnchorOffsets = new TextAnchorOffsetArray();
27439
27618
  }
27440
27619
  calculateGlyphDependencies(text, stack, textAlongLine, allowVerticalPlacement, doesAllowVerticalWritingMode) {
27441
27620
  for (let i = 0; i < text.length; i++) {
@@ -27913,6 +28092,7 @@ const getLayout = () => layout = layout || new Properties({
27913
28092
  "text-justify": new DataDrivenProperty(v8Spec["layout_symbol"]["text-justify"]),
27914
28093
  "text-radial-offset": new DataDrivenProperty(v8Spec["layout_symbol"]["text-radial-offset"]),
27915
28094
  "text-variable-anchor": new DataConstantProperty(v8Spec["layout_symbol"]["text-variable-anchor"]),
28095
+ "text-variable-anchor-offset": new DataDrivenProperty(v8Spec["layout_symbol"]["text-variable-anchor-offset"]),
27916
28096
  "text-anchor": new DataDrivenProperty(v8Spec["layout_symbol"]["text-anchor"]),
27917
28097
  "text-max-angle": new DataConstantProperty(v8Spec["layout_symbol"]["text-max-angle"]),
27918
28098
  "text-writing-mode": new DataConstantProperty(v8Spec["layout_symbol"]["text-writing-mode"]),
@@ -30044,6 +30224,18 @@ function getCentroidCell(polygon) {
30044
30224
  return new Cell(x / area, y / area, 0, polygon);
30045
30225
  }
30046
30226
 
30227
+ exports.TextAnchorEnum = void 0;
30228
+ (function (TextAnchorEnum) {
30229
+ TextAnchorEnum[TextAnchorEnum["center"] = 1] = "center";
30230
+ TextAnchorEnum[TextAnchorEnum["left"] = 2] = "left";
30231
+ TextAnchorEnum[TextAnchorEnum["right"] = 3] = "right";
30232
+ TextAnchorEnum[TextAnchorEnum["top"] = 4] = "top";
30233
+ TextAnchorEnum[TextAnchorEnum["bottom"] = 5] = "bottom";
30234
+ TextAnchorEnum[TextAnchorEnum["top-left"] = 6] = "top-left";
30235
+ TextAnchorEnum[TextAnchorEnum["top-right"] = 7] = "top-right";
30236
+ TextAnchorEnum[TextAnchorEnum["bottom-left"] = 8] = "bottom-left";
30237
+ TextAnchorEnum[TextAnchorEnum["bottom-right"] = 9] = "bottom-right";
30238
+ })(exports.TextAnchorEnum || (exports.TextAnchorEnum = {}));
30047
30239
  // The radial offset is to the edge of the text box
30048
30240
  // In the horizontal direction, the edge of the text box is where glyphs start
30049
30241
  // But in the vertical direction, the glyphs appear to "start" at the baseline
@@ -30057,7 +30249,7 @@ function evaluateVariableOffset(anchor, offset) {
30057
30249
  if (radialOffset < 0)
30058
30250
  radialOffset = 0; // Ignore negative offset.
30059
30251
  // solve for r where r^2 + r^2 = radialOffset^2
30060
- const hypotenuse = radialOffset / Math.sqrt(2);
30252
+ const hypotenuse = radialOffset / Math.SQRT2;
30061
30253
  switch (anchor) {
30062
30254
  case 'top-right':
30063
30255
  case 'top-left':
@@ -30125,14 +30317,60 @@ function evaluateVariableOffset(anchor, offset) {
30125
30317
  }
30126
30318
  return (offset[1] !== INVALID_TEXT_OFFSET) ? fromTextOffset(anchor, offset[0], offset[1]) : fromRadialOffset(anchor, offset[0]);
30127
30319
  }
30320
+ // Helper to support both text-variable-anchor and text-variable-anchor-offset. Offset values converted from EMs to PXs
30321
+ function getTextVariableAnchorOffset(layer, feature, canonical) {
30322
+ var _a;
30323
+ const layout = layer.layout;
30324
+ // If style specifies text-variable-anchor-offset, just return it
30325
+ const variableAnchorOffset = (_a = layout.get('text-variable-anchor-offset')) === null || _a === void 0 ? void 0 : _a.evaluate(feature, {}, canonical);
30326
+ if (variableAnchorOffset) {
30327
+ const sourceValues = variableAnchorOffset.values;
30328
+ const destValues = [];
30329
+ // Convert offsets from EM to PX, and apply baseline shift
30330
+ for (let i = 0; i < sourceValues.length; i += 2) {
30331
+ const anchor = destValues[i] = sourceValues[i];
30332
+ const offset = sourceValues[i + 1].map(t => t * ONE_EM);
30333
+ if (anchor.startsWith('top')) {
30334
+ offset[1] -= baselineOffset;
30335
+ }
30336
+ else if (anchor.startsWith('bottom')) {
30337
+ offset[1] += baselineOffset;
30338
+ }
30339
+ destValues[i + 1] = offset;
30340
+ }
30341
+ return new VariableAnchorOffsetCollection(destValues);
30342
+ }
30343
+ // If style specifies text-variable-anchor, convert to the new format
30344
+ const variableAnchor = layout.get('text-variable-anchor');
30345
+ if (variableAnchor) {
30346
+ let textOffset;
30347
+ const unevaluatedLayout = layer._unevaluatedLayout;
30348
+ // The style spec says don't use `text-offset` and `text-radial-offset` together
30349
+ // but doesn't actually specify what happens if you use both. We go with the radial offset.
30350
+ if (unevaluatedLayout.getValue('text-radial-offset') !== undefined) {
30351
+ textOffset = [layout.get('text-radial-offset').evaluate(feature, {}, canonical) * ONE_EM, INVALID_TEXT_OFFSET];
30352
+ }
30353
+ else {
30354
+ textOffset = layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM);
30355
+ }
30356
+ const anchorOffsets = [];
30357
+ for (const anchor of variableAnchor) {
30358
+ anchorOffsets.push(anchor, evaluateVariableOffset(anchor, textOffset));
30359
+ }
30360
+ return new VariableAnchorOffsetCollection(anchorOffsets);
30361
+ }
30362
+ return null;
30363
+ }
30364
+
30128
30365
  function performSymbolLayout(args) {
30129
30366
  args.bucket.createArrays();
30130
30367
  const tileSize = 512 * args.bucket.overscaling;
30131
30368
  args.bucket.tilePixelRatio = EXTENT / tileSize;
30132
30369
  args.bucket.compareText = {};
30133
30370
  args.bucket.iconsNeedLinear = false;
30134
- const layout = args.bucket.layers[0].layout;
30135
- const unevaluatedLayoutValues = args.bucket.layers[0]._unevaluatedLayout._values;
30371
+ const layer = args.bucket.layers[0];
30372
+ const layout = layer.layout;
30373
+ const unevaluatedLayoutValues = layer._unevaluatedLayout._values;
30136
30374
  const sizes = {
30137
30375
  // Filled in below, if *SizeData.kind is 'composite'
30138
30376
  // compositeIconSizes: undefined,
@@ -30175,8 +30413,8 @@ function performSymbolLayout(args) {
30175
30413
  const spacing = layout.get('text-letter-spacing').evaluate(feature, {}, args.canonical) * ONE_EM;
30176
30414
  const spacingIfAllowed = allowsLetterSpacing(unformattedText) ? spacing : 0;
30177
30415
  const textAnchor = layout.get('text-anchor').evaluate(feature, {}, args.canonical);
30178
- const variableTextAnchor = layout.get('text-variable-anchor');
30179
- if (!variableTextAnchor) {
30416
+ const variableAnchorOffset = getTextVariableAnchorOffset(layer, feature, args.canonical);
30417
+ if (!variableAnchorOffset) {
30180
30418
  const radialOffset = layout.get('text-radial-offset').evaluate(feature, {}, args.canonical);
30181
30419
  // Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector
30182
30420
  // is calculated at placement time instead of layout time
@@ -30205,13 +30443,18 @@ function performSymbolLayout(args) {
30205
30443
  }
30206
30444
  };
30207
30445
  // If this layer uses text-variable-anchor, generate shapings for all justification possibilities.
30208
- if (!textAlongLine && variableTextAnchor) {
30209
- const justifications = textJustify === 'auto' ?
30210
- variableTextAnchor.map(a => getAnchorJustification(a)) :
30211
- [textJustify];
30446
+ if (!textAlongLine && variableAnchorOffset) {
30447
+ const justifications = new Set();
30448
+ if (textJustify === 'auto') {
30449
+ for (let i = 0; i < variableAnchorOffset.values.length; i += 2) {
30450
+ justifications.add(getAnchorJustification(variableAnchorOffset.values[i]));
30451
+ }
30452
+ }
30453
+ else {
30454
+ justifications.add(textJustify);
30455
+ }
30212
30456
  let singleLine = false;
30213
- for (let i = 0; i < justifications.length; i++) {
30214
- const justification = justifications[i];
30457
+ for (const justification of justifications) {
30215
30458
  if (shapedTextOrientations.horizontal[justification])
30216
30459
  continue;
30217
30460
  if (singleLine) {
@@ -30376,6 +30619,18 @@ function addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMa
30376
30619
  }
30377
30620
  }
30378
30621
  }
30622
+ function addTextVariableAnchorOffsets(textAnchorOffsets, variableAnchorOffset) {
30623
+ const startIndex = textAnchorOffsets.length;
30624
+ const values = variableAnchorOffset === null || variableAnchorOffset === void 0 ? void 0 : variableAnchorOffset.values;
30625
+ if ((values === null || values === void 0 ? void 0 : values.length) > 0) {
30626
+ for (let i = 0; i < values.length; i += 2) {
30627
+ const anchor = exports.TextAnchorEnum[values[i]];
30628
+ const offset = values[i + 1];
30629
+ textAnchorOffsets.emplaceBack(anchor, offset[0], offset[1]);
30630
+ }
30631
+ }
30632
+ return [startIndex, textAnchorOffsets.length];
30633
+ }
30379
30634
  function addTextVertices(bucket, anchor, shapedText, imageMap, layer, textAlongLine, feature, textOffset, lineArray, writingMode, placementTypes, placedTextSymbolIndices, placedIconIndex, sizes, canonical) {
30380
30635
  const glyphQuads = getGlyphQuads(anchor, shapedText, textOffset, layer, textAlongLine, feature, imageMap, bucket.allowVerticalPlacement);
30381
30636
  const sizeData = bucket.textSizeData;
@@ -30427,15 +30682,6 @@ function addSymbol(bucket, anchor, line, shapedTextOrientations, shapedIcon, ima
30427
30682
  let verticalPlacedIconSymbolIndex = -1;
30428
30683
  const placedTextSymbolIndices = {};
30429
30684
  let key = murmur3$1('');
30430
- let textOffset0 = 0;
30431
- let textOffset1 = 0;
30432
- if (layer._unevaluatedLayout.getValue('text-radial-offset') === undefined) {
30433
- [textOffset0, textOffset1] = layer.layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM);
30434
- }
30435
- else {
30436
- textOffset0 = layer.layout.get('text-radial-offset').evaluate(feature, {}, canonical) * ONE_EM;
30437
- textOffset1 = INVALID_TEXT_OFFSET;
30438
- }
30439
30685
  if (bucket.allowVerticalPlacement && shapedTextOrientations.vertical) {
30440
30686
  const textRotation = layer.layout.get('text-rotate').evaluate(feature, {}, canonical);
30441
30687
  const verticalTextRotation = textRotation + 90.0;
@@ -30536,7 +30782,9 @@ function addSymbol(bucket, anchor, line, shapedTextOrientations, shapedIcon, ima
30536
30782
  if (feature.sortKey !== undefined) {
30537
30783
  bucket.addToSortKeyRanges(bucket.symbolInstances.length, feature.sortKey);
30538
30784
  }
30539
- bucket.symbolInstances.emplaceBack(anchor.x, anchor.y, placedTextSymbolIndices.right >= 0 ? placedTextSymbolIndices.right : -1, placedTextSymbolIndices.center >= 0 ? placedTextSymbolIndices.center : -1, placedTextSymbolIndices.left >= 0 ? placedTextSymbolIndices.left : -1, placedTextSymbolIndices.vertical || -1, placedIconSymbolIndex, verticalPlacedIconSymbolIndex, key, textBoxStartIndex, textBoxEndIndex, verticalTextBoxStartIndex, verticalTextBoxEndIndex, iconBoxStartIndex, iconBoxEndIndex, verticalIconBoxStartIndex, verticalIconBoxEndIndex, featureIndex, numHorizontalGlyphVertices, numVerticalGlyphVertices, numIconVertices, numVerticalIconVertices, useRuntimeCollisionCircles, 0, textBoxScale, textOffset0, textOffset1, collisionCircleDiameter);
30785
+ const variableAnchorOffset = getTextVariableAnchorOffset(layer, feature, canonical);
30786
+ const [textAnchorOffsetStartIndex, textAnchorOffsetEndIndex] = addTextVariableAnchorOffsets(bucket.textAnchorOffsets, variableAnchorOffset);
30787
+ bucket.symbolInstances.emplaceBack(anchor.x, anchor.y, placedTextSymbolIndices.right >= 0 ? placedTextSymbolIndices.right : -1, placedTextSymbolIndices.center >= 0 ? placedTextSymbolIndices.center : -1, placedTextSymbolIndices.left >= 0 ? placedTextSymbolIndices.left : -1, placedTextSymbolIndices.vertical || -1, placedIconSymbolIndex, verticalPlacedIconSymbolIndex, key, textBoxStartIndex, textBoxEndIndex, verticalTextBoxStartIndex, verticalTextBoxEndIndex, iconBoxStartIndex, iconBoxEndIndex, verticalIconBoxStartIndex, verticalIconBoxEndIndex, featureIndex, numHorizontalGlyphVertices, numVerticalGlyphVertices, numIconVertices, numVerticalIconVertices, useRuntimeCollisionCircles, 0, textBoxScale, collisionCircleDiameter, textAnchorOffsetStartIndex, textAnchorOffsetEndIndex);
30540
30788
  }
30541
30789
  function anchorIsTooClose(bucket, text, repeatDistance, anchor) {
30542
30790
  const compareText = bucket.compareText;
@@ -31058,7 +31306,6 @@ exports.emptyStyle = emptyStyle;
31058
31306
  exports.equals = equals$6;
31059
31307
  exports.evaluateSizeForFeature = evaluateSizeForFeature;
31060
31308
  exports.evaluateSizeForZoom = evaluateSizeForZoom;
31061
- exports.evaluateVariableOffset = evaluateVariableOffset;
31062
31309
  exports.evented = evented;
31063
31310
  exports.extend = extend;
31064
31311
  exports.filterObject = filterObject;
@@ -33782,7 +34029,7 @@ define(['./shared'], (function (performance) { 'use strict';
33782
34029
 
33783
34030
  var name = "maplibre-gl";
33784
34031
  var description = "BSD licensed community fork of mapbox-gl, a WebGL interactive maps library";
33785
- var version$2 = "3.2.2";
34032
+ var version$2 = "3.3.1";
33786
34033
  var main = "dist/maplibre-gl.js";
33787
34034
  var style = "dist/maplibre-gl.css";
33788
34035
  var license = "BSD-3-Clause";
@@ -33801,7 +34048,7 @@ var dependencies = {
33801
34048
  "@mapbox/unitbezier": "^0.0.1",
33802
34049
  "@mapbox/vector-tile": "^1.3.1",
33803
34050
  "@mapbox/whoots-js": "^3.1.0",
33804
- "@maplibre/maplibre-gl-style-spec": "^19.2.2",
34051
+ "@maplibre/maplibre-gl-style-spec": "^19.3.0",
33805
34052
  "@types/geojson": "^7946.0.10",
33806
34053
  "@types/mapbox__point-geometry": "^0.1.2",
33807
34054
  "@types/mapbox__vector-tile": "^1.3.0",
@@ -33823,54 +34070,54 @@ var dependencies = {
33823
34070
  var devDependencies = {
33824
34071
  "@mapbox/mapbox-gl-rtl-text": "^0.2.3",
33825
34072
  "@mapbox/mvt-fixtures": "^3.10.0",
33826
- "@rollup/plugin-commonjs": "^25.0.3",
34073
+ "@rollup/plugin-commonjs": "^25.0.4",
33827
34074
  "@rollup/plugin-json": "^6.0.0",
33828
- "@rollup/plugin-node-resolve": "^15.1.0",
34075
+ "@rollup/plugin-node-resolve": "^15.2.1",
33829
34076
  "@rollup/plugin-replace": "^5.0.2",
33830
34077
  "@rollup/plugin-strip": "^3.0.2",
33831
34078
  "@rollup/plugin-terser": "^0.4.3",
33832
- "@rollup/plugin-typescript": "^11.1.2",
34079
+ "@rollup/plugin-typescript": "^11.1.3",
33833
34080
  "@types/benchmark": "^2.1.2",
33834
34081
  "@types/cssnano": "^5.0.0",
33835
34082
  "@types/d3": "^7.4.0",
33836
34083
  "@types/diff": "^5.0.3",
33837
34084
  "@types/earcut": "^2.1.1",
33838
- "@types/eslint": "^8.44.1",
34085
+ "@types/eslint": "^8.44.2",
33839
34086
  "@types/gl": "^6.0.2",
33840
34087
  "@types/glob": "^8.1.0",
33841
34088
  "@types/jest": "^29.5.3",
33842
- "@types/jsdom": "^21.1.1",
34089
+ "@types/jsdom": "^21.1.2",
33843
34090
  "@types/minimist": "^1.2.2",
33844
34091
  "@types/murmurhash-js": "^1.0.4",
33845
34092
  "@types/nise": "^1.4.1",
33846
- "@types/node": "^20.4.5",
34093
+ "@types/node": "^20.5.7",
33847
34094
  "@types/offscreencanvas": "^2019.7.0",
33848
34095
  "@types/pixelmatch": "^5.2.4",
33849
34096
  "@types/pngjs": "^6.0.1",
33850
- "@types/react": "^18.2.17",
34097
+ "@types/react": "^18.2.21",
33851
34098
  "@types/react-dom": "^18.2.7",
33852
34099
  "@types/request": "^2.48.8",
33853
34100
  "@types/shuffle-seed": "^1.1.0",
33854
34101
  "@types/window-or-global": "^1.0.4",
33855
- "@typescript-eslint/eslint-plugin": "^6.2.0",
33856
- "@typescript-eslint/parser": "^6.2.0",
34102
+ "@typescript-eslint/eslint-plugin": "^6.4.1",
34103
+ "@typescript-eslint/parser": "^6.4.1",
33857
34104
  address: "^1.2.2",
33858
34105
  benchmark: "^2.1.4",
33859
34106
  canvas: "^2.11.2",
33860
34107
  cssnano: "^6.0.1",
33861
34108
  d3: "^7.8.5",
33862
34109
  "d3-queue": "^3.0.7",
33863
- "devtools-protocol": "^0.0.1173815",
34110
+ "devtools-protocol": "^0.0.1188743",
33864
34111
  diff: "^5.1.0",
33865
34112
  "dts-bundle-generator": "^8.0.1",
33866
- eslint: "^8.46.0",
34113
+ eslint: "^8.48.0",
33867
34114
  "eslint-config-mourner": "^3.0.0",
33868
34115
  "eslint-plugin-html": "^7.1.0",
33869
- "eslint-plugin-import": "^2.28.0",
34116
+ "eslint-plugin-import": "^2.28.1",
33870
34117
  "eslint-plugin-jest": "^27.2.3",
33871
- "eslint-plugin-react": "^7.33.1",
34118
+ "eslint-plugin-react": "^7.33.2",
33872
34119
  "eslint-plugin-tsdoc": "0.2.17",
33873
- expect: "^29.6.2",
34120
+ expect: "^29.6.4",
33874
34121
  gl: "^6.0.2",
33875
34122
  glob: "^10.3.3",
33876
34123
  "is-builtin-module": "^3.2.1",
@@ -33888,28 +34135,28 @@ var devDependencies = {
33888
34135
  "pdf-merger-js": "^4.3.0",
33889
34136
  pixelmatch: "^5.3.0",
33890
34137
  pngjs: "^7.0.0",
33891
- postcss: "^8.4.27",
34138
+ postcss: "^8.4.28",
33892
34139
  "postcss-cli": "^10.1.0",
33893
34140
  "postcss-inline-svg": "^6.0.0",
33894
34141
  "pretty-bytes": "^6.1.1",
33895
- puppeteer: "^20.9.0",
34142
+ puppeteer: "^21.1.0",
33896
34143
  react: "^18.2.0",
33897
34144
  "react-dom": "^18.2.0",
33898
- rollup: "^3.27.0",
34145
+ rollup: "^3.28.1",
33899
34146
  "rollup-plugin-sourcemaps": "^0.6.3",
33900
34147
  rw: "^1.3.3",
33901
34148
  semver: "^7.5.4",
33902
34149
  "shuffle-seed": "^1.1.6",
33903
34150
  "source-map-explorer": "^2.5.3",
33904
34151
  st: "^3.0.0",
33905
- stylelint: "^15.10.2",
34152
+ stylelint: "^15.10.3",
33906
34153
  "stylelint-config-standard": "^34.0.0",
33907
34154
  "ts-jest": "^29.1.1",
33908
34155
  "ts-node": "^10.9.1",
33909
- tslib: "^2.6.1",
34156
+ tslib: "^2.6.2",
33910
34157
  typedoc: "^0.24.8",
33911
- "typedoc-plugin-markdown": "^3.15.4",
33912
- "typedoc-plugin-missing-exports": "^2.0.1",
34158
+ "typedoc-plugin-markdown": "^3.16.0",
34159
+ "typedoc-plugin-missing-exports": "^2.1.0",
33913
34160
  typescript: "^5.1.6"
33914
34161
  };
33915
34162
  var overrides = {
@@ -33940,6 +34187,7 @@ var scripts = {
33940
34187
  "build-benchmarks": "npm run build-dev && rollup --configPlugin @rollup/plugin-typescript -c test/bench/rollup_config_benchmarks.ts",
33941
34188
  "watch-benchmarks": "rollup --configPlugin @rollup/plugin-typescript -c test/bench/rollup_config_benchmarks.ts --watch",
33942
34189
  "start-server": "st --no-cache -H 0.0.0.0 --port 9966 .",
34190
+ "start-docs": "docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material",
33943
34191
  start: "run-p watch-css watch-dev start-server",
33944
34192
  "start-bench": "run-p watch-css watch-benchmarks start-server",
33945
34193
  lint: "eslint --cache --ext .ts,.tsx,.js,.html --ignore-path .gitignore .",
@@ -35812,7 +36060,6 @@ class TileBounds {
35812
36060
  * map.getSource('some id').setTiles(['https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt']);
35813
36061
  * ```
35814
36062
  * @see [Add a vector tile source](https://maplibre.org/maplibre-gl-js/docs/examples/vector-source/)
35815
- * @see [Add a third party vector tile source](https://maplibre.org/maplibre-gl-js/docs/examples/third-party/)
35816
36063
  */
35817
36064
  class VectorTileSource extends performance.Evented {
35818
36065
  constructor(id, options, dispatcher, eventedParent) {
@@ -36842,6 +37089,10 @@ function getCoordinatesCenterTileID(coords) {
36842
37089
  * map.removeSource('some id'); // remove
36843
37090
  * ```
36844
37091
  * @see [Add a video](https://maplibre.org/maplibre-gl-js/docs/examples/video-on-a-map/)
37092
+ *
37093
+ * Note that when rendered as a raster layer, the layer's `raster-fade-duration` property will cause the video to fade in.
37094
+ * This happens when playback is started, paused and resumed, or when the video's coordinates are updated. To avoid this behavior,
37095
+ * set the layer's `raster-fade-duration` property to `0`.
36845
37096
  */
36846
37097
  class VideoSource extends ImageSource {
36847
37098
  constructor(id, options, dispatcher, eventedParent) {
@@ -40127,8 +40378,7 @@ function calculateVariableLayoutShift(anchor, width, height, textOffset, textBox
40127
40378
  const { horizontalAlign, verticalAlign } = performance.getAnchorAlignment(anchor);
40128
40379
  const shiftX = -(horizontalAlign - 0.5) * width;
40129
40380
  const shiftY = -(verticalAlign - 0.5) * height;
40130
- const offset = performance.evaluateVariableOffset(anchor, textOffset);
40131
- return new performance.Point(shiftX + offset[0] * textBoxScale, shiftY + offset[1] * textBoxScale);
40381
+ return new performance.Point(shiftX + textOffset[0] * textBoxScale, shiftY + textOffset[1] * textBoxScale);
40132
40382
  }
40133
40383
  function shiftVariableCollisionBox(collisionBox, shiftX, shiftY, rotateWithMap, pitchWithMap, angle) {
40134
40384
  const { x1, x2, y1, y2, anchorPointX, anchorPointY } = collisionBox;
@@ -40215,8 +40465,9 @@ class Placement {
40215
40465
  });
40216
40466
  }
40217
40467
  }
40218
- attemptAnchorPlacement(anchor, textBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, textOverlapMode, symbolInstance, bucket, orientation, iconBox, getElevation) {
40219
- const textOffset = [symbolInstance.textOffset0, symbolInstance.textOffset1];
40468
+ attemptAnchorPlacement(textAnchorOffset, textBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, textOverlapMode, symbolInstance, bucket, orientation, iconBox, getElevation) {
40469
+ const anchor = performance.TextAnchorEnum[textAnchorOffset.textAnchor];
40470
+ const textOffset = [textAnchorOffset.textOffset0, textAnchorOffset.textOffset1];
40220
40471
  const shift = calculateVariableLayoutShift(anchor, width, height, textOffset, textBoxScale);
40221
40472
  const placedGlyphBoxes = this.collisionIndex.placeCollisionBox(shiftVariableCollisionBox(textBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle), textOverlapMode, textPixelRatio, posMatrix, collisionGroup.predicate, getElevation);
40222
40473
  if (iconBox) {
@@ -40286,6 +40537,7 @@ class Placement {
40286
40537
  const tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID;
40287
40538
  const getElevation = this.terrain ? (x, y) => this.terrain.getElevation(tileID, x, y) : null;
40288
40539
  const placeSymbol = (symbolInstance, collisionArrays) => {
40540
+ var _a, _b;
40289
40541
  if (seenCrossTileIDs[symbolInstance.crossTileID])
40290
40542
  return;
40291
40543
  if (holdingForFade) {
@@ -40347,7 +40599,10 @@ class Placement {
40347
40599
  placed = placeHorizontalFn();
40348
40600
  }
40349
40601
  };
40350
- if (!layout.get('text-variable-anchor')) {
40602
+ const textAnchorOffsetStart = symbolInstance.textAnchorOffsetStartIndex;
40603
+ const textAnchorOffsetEnd = symbolInstance.textAnchorOffsetEndIndex;
40604
+ // If start+end indices match, text-variable-anchor is not in play.
40605
+ if (textAnchorOffsetEnd === textAnchorOffsetStart) {
40351
40606
  const placeBox = (collisionTextBox, orientation) => {
40352
40607
  const placedFeature = this.collisionIndex.placeCollisionBox(collisionTextBox, textOverlapMode, textPixelRatio, posMatrix, collisionGroup.predicate, getElevation);
40353
40608
  if (placedFeature && placedFeature.box && placedFeature.box.length) {
@@ -40370,36 +40625,41 @@ class Placement {
40370
40625
  updatePreviousOrientationIfNotPlaced(placed && placed.box && placed.box.length);
40371
40626
  }
40372
40627
  else {
40373
- let anchors = layout.get('text-variable-anchor');
40374
- // If this symbol was in the last placement, shift the previously used
40375
- // anchor to the front of the anchor list, only if the previous anchor
40376
- // is still in the anchor list
40377
- if (this.prevPlacement && this.prevPlacement.variableOffsets[symbolInstance.crossTileID]) {
40378
- const prevOffsets = this.prevPlacement.variableOffsets[symbolInstance.crossTileID];
40379
- if (anchors.indexOf(prevOffsets.anchor) > 0) {
40380
- anchors = anchors.filter(anchor => anchor !== prevOffsets.anchor);
40381
- anchors.unshift(prevOffsets.anchor);
40382
- }
40383
- }
40628
+ // If this symbol was in the last placement, prefer placement using same anchor, if it's still available
40629
+ let prevAnchor = performance.TextAnchorEnum[(_b = (_a = this.prevPlacement) === null || _a === void 0 ? void 0 : _a.variableOffsets[symbolInstance.crossTileID]) === null || _b === void 0 ? void 0 : _b.anchor];
40384
40630
  const placeBoxForVariableAnchors = (collisionTextBox, collisionIconBox, orientation) => {
40385
40631
  const width = collisionTextBox.x2 - collisionTextBox.x1;
40386
40632
  const height = collisionTextBox.y2 - collisionTextBox.y1;
40387
40633
  const textBoxScale = symbolInstance.textBoxScale;
40388
40634
  const variableIconBox = hasIconTextFit && (iconOverlapMode === 'never') ? collisionIconBox : null;
40389
40635
  let placedBox = { box: [], offscreen: false };
40390
- const placementAttempts = (textOverlapMode !== 'never') ? anchors.length * 2 : anchors.length;
40391
- for (let i = 0; i < placementAttempts; ++i) {
40392
- const anchor = anchors[i % anchors.length];
40393
- const overlapMode = (i >= anchors.length) ? textOverlapMode : 'never';
40394
- const result = this.attemptAnchorPlacement(anchor, collisionTextBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, overlapMode, symbolInstance, bucket, orientation, variableIconBox, getElevation);
40395
- if (result) {
40396
- placedBox = result.placedGlyphBoxes;
40397
- if (placedBox && placedBox.box && placedBox.box.length) {
40398
- placeText = true;
40399
- shift = result.shift;
40400
- break;
40636
+ let placementPasses = (textOverlapMode === 'never') ? 1 : 2;
40637
+ let overlapMode = 'never';
40638
+ if (prevAnchor) {
40639
+ placementPasses++;
40640
+ }
40641
+ for (let pass = 0; pass < placementPasses; pass++) {
40642
+ for (let i = textAnchorOffsetStart; i < textAnchorOffsetEnd; i++) {
40643
+ const textAnchorOffset = bucket.textAnchorOffsets.get(i);
40644
+ if (prevAnchor && textAnchorOffset.textAnchor !== prevAnchor) {
40645
+ continue;
40646
+ }
40647
+ const result = this.attemptAnchorPlacement(textAnchorOffset, collisionTextBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, overlapMode, symbolInstance, bucket, orientation, variableIconBox, getElevation);
40648
+ if (result) {
40649
+ placedBox = result.placedGlyphBoxes;
40650
+ if (placedBox && placedBox.box && placedBox.box.length) {
40651
+ placeText = true;
40652
+ shift = result.shift;
40653
+ return placedBox;
40654
+ }
40401
40655
  }
40402
40656
  }
40657
+ if (prevAnchor) {
40658
+ prevAnchor = null;
40659
+ }
40660
+ else {
40661
+ overlapMode = textOverlapMode;
40662
+ }
40403
40663
  }
40404
40664
  return placedBox;
40405
40665
  };
@@ -40670,11 +40930,12 @@ class Placement {
40670
40930
  bucket.iconCollisionBox.collisionVertexArray.clear();
40671
40931
  if (bucket.hasTextCollisionBoxData())
40672
40932
  bucket.textCollisionBox.collisionVertexArray.clear();
40673
- const layout = bucket.layers[0].layout;
40933
+ const layer = bucket.layers[0];
40934
+ const layout = layer.layout;
40674
40935
  const duplicateOpacityState = new JointOpacityState(null, 0, false, false, true);
40675
40936
  const textAllowOverlap = layout.get('text-allow-overlap');
40676
40937
  const iconAllowOverlap = layout.get('icon-allow-overlap');
40677
- const variablePlacement = layout.get('text-variable-anchor');
40938
+ const hasVariablePlacement = layer._unevaluatedLayout.hasValue('text-variable-anchor') || layer._unevaluatedLayout.hasValue('text-variable-anchor-offset');
40678
40939
  const rotateWithMap = layout.get('text-rotation-alignment') === 'map';
40679
40940
  const pitchWithMap = layout.get('text-pitch-alignment') === 'map';
40680
40941
  const hasIconTextFit = layout.get('icon-text-fit') !== 'none';
@@ -40768,7 +41029,7 @@ class Placement {
40768
41029
  let shift = new performance.Point(0, 0);
40769
41030
  if (collisionArrays.textBox || collisionArrays.verticalTextBox) {
40770
41031
  let used = true;
40771
- if (variablePlacement) {
41032
+ if (hasVariablePlacement) {
40772
41033
  const variableOffset = this.variableOffsets[crossTileID];
40773
41034
  if (variableOffset) {
40774
41035
  // This will show either the currently placed position or the last
@@ -41383,6 +41644,7 @@ class Style extends performance.Evented {
41383
41644
  this._load(empty, { validate: false });
41384
41645
  }
41385
41646
  _load(json, options, previousStyle) {
41647
+ var _a;
41386
41648
  const nextState = options.transformStyle ? options.transformStyle(previousStyle, json) : json;
41387
41649
  if (options.validate && emitValidationErrors(this, performance.validateStyle(nextState))) {
41388
41650
  return;
@@ -41401,7 +41663,7 @@ class Style extends performance.Evented {
41401
41663
  this.glyphManager.setURL(nextState.glyphs);
41402
41664
  this._createLayers();
41403
41665
  this.light = new Light(this.stylesheet.light);
41404
- this.map.setTerrain(this.stylesheet.terrain);
41666
+ this.map.setTerrain((_a = this.stylesheet.terrain) !== null && _a !== void 0 ? _a : null);
41405
41667
  this.fire(new performance.Event('data', { dataType: 'style' }));
41406
41668
  this.fire(new performance.Event('style.load'));
41407
41669
  }
@@ -41819,7 +42081,7 @@ class Style extends performance.Evented {
41819
42081
  layer = performance.createStyleLayer(layerObject);
41820
42082
  }
41821
42083
  else {
41822
- if (typeof layerObject.source === 'object') {
42084
+ if ('source' in layerObject && typeof layerObject.source === 'object') {
41823
42085
  this.addSource(id, layerObject.source);
41824
42086
  layerObject = performance.clone$1(layerObject);
41825
42087
  layerObject = performance.extend(layerObject, { source: id });
@@ -43020,6 +43282,9 @@ class Program {
43020
43282
  }
43021
43283
  gl.shaderSource(fragmentShader, fragmentSource);
43022
43284
  gl.compileShader(fragmentShader);
43285
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
43286
+ throw new Error(`Could not compile fragment shader: ${gl.getShaderInfoLog(fragmentShader)}`);
43287
+ }
43023
43288
  gl.attachShader(this.program, fragmentShader);
43024
43289
  const vertexShader = gl.createShader(gl.VERTEX_SHADER);
43025
43290
  if (gl.isContextLost()) {
@@ -43028,6 +43293,9 @@ class Program {
43028
43293
  }
43029
43294
  gl.shaderSource(vertexShader, vertexSource);
43030
43295
  gl.compileShader(vertexShader);
43296
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
43297
+ throw new Error(`Could not compile vertex shader: ${gl.getShaderInfoLog(vertexShader)}`);
43298
+ }
43031
43299
  gl.attachShader(this.program, vertexShader);
43032
43300
  this.attributes = {};
43033
43301
  const uniformLocations = {};
@@ -43039,6 +43307,9 @@ class Program {
43039
43307
  }
43040
43308
  }
43041
43309
  gl.linkProgram(this.program);
43310
+ if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
43311
+ throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
43312
+ }
43042
43313
  gl.deleteShader(vertexShader);
43043
43314
  gl.deleteShader(fragmentShader);
43044
43315
  for (let it = 0; it < allUniformsInfo.length; it++) {
@@ -44771,10 +45042,10 @@ function drawSymbols(painter, sourceCache, layer, coords, variableOffsets) {
44771
45042
  // Disable the stencil test so that labels aren't clipped to tile boundaries.
44772
45043
  const stencilMode = StencilMode.disabled;
44773
45044
  const colorMode = painter.colorModeForRenderPass();
44774
- const variablePlacement = layer.layout.get('text-variable-anchor');
45045
+ const hasVariablePlacement = layer._unevaluatedLayout.hasValue('text-variable-anchor') || layer._unevaluatedLayout.hasValue('text-variable-anchor-offset');
44775
45046
  //Compute variable-offsets before painting since icons and text data positioning
44776
45047
  //depend on each other in this case.
44777
- if (variablePlacement) {
45048
+ if (hasVariablePlacement) {
44778
45049
  updateVariableAnchors(coords, painter, layer, sourceCache, layer.layout.get('text-rotation-alignment'), layer.layout.get('text-pitch-alignment'), variableOffsets);
44779
45050
  }
44780
45051
  if (layer.paint.get('icon-opacity').constantOr(1) !== 0) {
@@ -44792,8 +45063,7 @@ function calculateVariableRenderShift(anchor, width, height, textOffset, textBox
44792
45063
  const { horizontalAlign, verticalAlign } = performance.getAnchorAlignment(anchor);
44793
45064
  const shiftX = -(horizontalAlign - 0.5) * width;
44794
45065
  const shiftY = -(verticalAlign - 0.5) * height;
44795
- const variableOffset = performance.evaluateVariableOffset(anchor, textOffset);
44796
- return new performance.Point((shiftX / textBoxScale + variableOffset[0]) * renderTextSize, (shiftY / textBoxScale + variableOffset[1]) * renderTextSize);
45066
+ return new performance.Point((shiftX / textBoxScale + textOffset[0]) * renderTextSize, (shiftY / textBoxScale + textOffset[1]) * renderTextSize);
44797
45067
  }
44798
45068
  function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlignment, pitchAlignment, variableOffsets) {
44799
45069
  const tr = painter.transform;
@@ -44909,7 +45179,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
44909
45179
  const hasSortKey = !layer.layout.get('symbol-sort-key').isConstant();
44910
45180
  let sortFeaturesByKey = false;
44911
45181
  const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly);
44912
- const variablePlacement = layer.layout.get('text-variable-anchor');
45182
+ const hasVariablePlacement = layer._unevaluatedLayout.hasValue('text-variable-anchor') || layer._unevaluatedLayout.hasValue('text-variable-anchor-offset');
44913
45183
  const tileRenderState = [];
44914
45184
  for (const coord of coords) {
44915
45185
  const tile = sourceCache.getTile(coord);
@@ -44954,7 +45224,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
44954
45224
  const s = pixelsToTileUnits(tile, 1, painter.transform.zoom);
44955
45225
  const labelPlaneMatrix = getLabelPlaneMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, s);
44956
45226
  const glCoordMatrix = getGlCoordMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, s);
44957
- const hasVariableAnchors = variablePlacement && bucket.hasTextData();
45227
+ const hasVariableAnchors = hasVariablePlacement && bucket.hasTextData();
44958
45228
  const updateTextFitIcon = layer.layout.get('icon-text-fit') !== 'none' &&
44959
45229
  hasVariableAnchors &&
44960
45230
  bucket.hasIconData();
@@ -44963,7 +45233,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
44963
45233
  const rotateToLine = layer.layout.get('text-rotation-alignment') === 'map';
44964
45234
  updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright, rotateToLine, getElevation);
44965
45235
  }
44966
- const matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor), uLabelPlaneMatrix = (alongLine || (isText && variablePlacement) || updateTextFitIcon) ? identityMat4 : labelPlaneMatrix, uglCoordMatrix = painter.translatePosMatrix(glCoordMatrix, tile, translate, translateAnchor, true);
45236
+ const matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor), uLabelPlaneMatrix = (alongLine || (isText && hasVariablePlacement) || updateTextFitIcon) ? identityMat4 : labelPlaneMatrix, uglCoordMatrix = painter.translatePosMatrix(glCoordMatrix, tile, translate, translateAnchor, true);
44967
45237
  const hasHalo = isSDF && layer.paint.get(isText ? 'text-halo-width' : 'icon-halo-width').constantOr(1) !== 0;
44968
45238
  let uniformValues;
44969
45239
  if (isSDF) {
@@ -47279,16 +47549,20 @@ class Transform {
47279
47549
  function throttle(fn, time) {
47280
47550
  let pending = false;
47281
47551
  let timerId = null;
47552
+ let lastCallContext = null;
47553
+ let lastCallArgs;
47282
47554
  const later = () => {
47283
47555
  timerId = null;
47284
47556
  if (pending) {
47285
- fn();
47557
+ fn.apply(lastCallContext, lastCallArgs);
47286
47558
  timerId = setTimeout(later, time);
47287
47559
  pending = false;
47288
47560
  }
47289
47561
  };
47290
- return () => {
47562
+ return (...args) => {
47291
47563
  pending = true;
47564
+ lastCallContext = this;
47565
+ lastCallArgs = args;
47292
47566
  if (!timerId) {
47293
47567
  later();
47294
47568
  }
@@ -52100,14 +52374,17 @@ let Map$1 = class Map extends Camera {
52100
52374
  if (typeof window !== 'undefined') {
52101
52375
  addEventListener('online', this._onWindowOnline, false);
52102
52376
  let initialResizeEventCaptured = false;
52377
+ const throttledResizeCallback = throttle((entries) => {
52378
+ if (this._trackResize && !this._removed) {
52379
+ this.resize(entries)._update();
52380
+ }
52381
+ }, 50);
52103
52382
  this._resizeObserver = new ResizeObserver((entries) => {
52104
52383
  if (!initialResizeEventCaptured) {
52105
52384
  initialResizeEventCaptured = true;
52106
52385
  return;
52107
52386
  }
52108
- if (this._trackResize) {
52109
- this.resize(entries)._update();
52110
- }
52387
+ throttledResizeCallback(entries);
52111
52388
  });
52112
52389
  this._resizeObserver.observe(this._container);
52113
52390
  }
@@ -53199,7 +53476,8 @@ let Map$1 = class Map extends Camera {
53199
53476
  * ```
53200
53477
  */
53201
53478
  getTerrain() {
53202
- return this.terrain && this.terrain.options;
53479
+ var _a, _b;
53480
+ return (_b = (_a = this.terrain) === null || _a === void 0 ? void 0 : _a.options) !== null && _b !== void 0 ? _b : null;
53203
53481
  }
53204
53482
  /**
53205
53483
  * Returns a Boolean indicating whether all tiles in the viewport from all sources on
@@ -53488,7 +53766,7 @@ let Map$1 = class Map extends Camera {
53488
53766
  *
53489
53767
  * @param layer - The layer to add,
53490
53768
  * conforming to either the MapLibre Style Specification's [layer definition](https://maplibre.org/maplibre-style-spec/layers) or,
53491
- * less commonly, the {@link CustomLayerInterface} specification.
53769
+ * less commonly, the {@link CustomLayerInterface} specification. Can also be a layer definition with an embedded source definition.
53492
53770
  * The MapLibre Style Specification's layer definition is appropriate for most layers.
53493
53771
  *
53494
53772
  * @param beforeId - The ID of an existing layer to insert the new layer before,
@@ -54492,7 +54770,6 @@ const defaultOptions$3 = {
54492
54770
  * map.addControl(nav, 'top-left');
54493
54771
  * ```
54494
54772
  * @see [Display map navigation controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigation/)
54495
- * @see [Add a third party vector tile source](https://maplibre.org/maplibre-gl-js/docs/examples/third-party/)
54496
54773
  */
54497
54774
  class NavigationControl {
54498
54775
  /**
@@ -55192,7 +55469,7 @@ class Marker extends performance.Evented {
55192
55469
  if (!('offset' in popup.options)) {
55193
55470
  const markerHeight = 41 - (5.8 / 2);
55194
55471
  const markerRadius = 13.5;
55195
- const linearOffset = Math.sqrt(Math.pow(markerRadius, 2) / 2);
55472
+ const linearOffset = Math.abs(markerRadius) / Math.SQRT2;
55196
55473
  popup.options.offset = this._defaultMarker ? {
55197
55474
  'top': [0, 0],
55198
55475
  'top-left': [0, 0],
@@ -56765,7 +57042,7 @@ function normalizeOffset(offset) {
56765
57042
  }
56766
57043
  else if (typeof offset === 'number') {
56767
57044
  // input specifies a radius from which to calculate offsets at all positions
56768
- const cornerOffset = Math.round(Math.sqrt(0.5 * Math.pow(offset, 2)));
57045
+ const cornerOffset = Math.round(Math.abs(offset) / Math.SQRT2);
56769
57046
  return {
56770
57047
  'center': new performance.Point(0, 0),
56771
57048
  'top': new performance.Point(0, offset),