@mapvx/web-js 3.3.2 → 3.4.0-dev.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 (60) hide show
  1. package/dist/cjs/index.js.map +1 -1
  2. package/dist/cjs/logger/sentry.js +1 -1
  3. package/dist/cjs/map/map.js +5 -1
  4. package/dist/cjs/map/map.js.map +1 -1
  5. package/dist/cjs/map/scene3DController.js +200 -44
  6. package/dist/cjs/map/scene3DController.js.map +1 -1
  7. package/dist/cjs/repository/repository.js +2 -2
  8. package/dist/cjs/repository/repository.js.map +1 -1
  9. package/dist/cjs/repository/requester.js +32 -7
  10. package/dist/cjs/repository/requester.js.map +1 -1
  11. package/dist/cjs/sdk.js +14 -1
  12. package/dist/cjs/sdk.js.map +1 -1
  13. package/dist/cjs/utils/3d.js +79 -1
  14. package/dist/cjs/utils/3d.js.map +1 -1
  15. package/dist/cjs/utils/loadGlb.js +5 -0
  16. package/dist/cjs/utils/loadGlb.js.map +1 -1
  17. package/dist/cjs/utils/three.js +3 -1
  18. package/dist/cjs/utils/three.js.map +1 -1
  19. package/dist/es/config/sdkConfig.d.ts +36 -1
  20. package/dist/es/config/sdkConfig.d.ts.map +1 -1
  21. package/dist/es/domain/models/mapConfig.d.ts +15 -0
  22. package/dist/es/domain/models/mapConfig.d.ts.map +1 -1
  23. package/dist/es/domain/models/scene3D.d.ts +110 -0
  24. package/dist/es/domain/models/scene3D.d.ts.map +1 -1
  25. package/dist/es/index.d.ts +2 -2
  26. package/dist/es/index.d.ts.map +1 -1
  27. package/dist/es/index.js.map +1 -1
  28. package/dist/es/logger/sentry.js +1 -1
  29. package/dist/es/map/map.d.ts.map +1 -1
  30. package/dist/es/map/map.js +5 -1
  31. package/dist/es/map/map.js.map +1 -1
  32. package/dist/es/map/scene3DController.d.ts +67 -2
  33. package/dist/es/map/scene3DController.d.ts.map +1 -1
  34. package/dist/es/map/scene3DController.js +201 -45
  35. package/dist/es/map/scene3DController.js.map +1 -1
  36. package/dist/es/repository/repository.d.ts +2 -2
  37. package/dist/es/repository/repository.d.ts.map +1 -1
  38. package/dist/es/repository/repository.js +2 -2
  39. package/dist/es/repository/repository.js.map +1 -1
  40. package/dist/es/repository/requester.d.ts +2 -2
  41. package/dist/es/repository/requester.d.ts.map +1 -1
  42. package/dist/es/repository/requester.js +32 -7
  43. package/dist/es/repository/requester.js.map +1 -1
  44. package/dist/es/sdk.d.ts.map +1 -1
  45. package/dist/es/sdk.js +14 -1
  46. package/dist/es/sdk.js.map +1 -1
  47. package/dist/es/utils/3d.d.ts +44 -1
  48. package/dist/es/utils/3d.d.ts.map +1 -1
  49. package/dist/es/utils/3d.js +75 -0
  50. package/dist/es/utils/3d.js.map +1 -1
  51. package/dist/es/utils/loadGlb.d.ts.map +1 -1
  52. package/dist/es/utils/loadGlb.js +5 -0
  53. package/dist/es/utils/loadGlb.js.map +1 -1
  54. package/dist/es/utils/three.d.ts +7 -0
  55. package/dist/es/utils/three.d.ts.map +1 -1
  56. package/dist/es/utils/three.js +3 -1
  57. package/dist/es/utils/three.js.map +1 -1
  58. package/dist/umd/index.js +556 -165
  59. package/dist/umd/index.js.map +1 -1
  60. package/package.json +1 -1
package/dist/umd/index.js CHANGED
@@ -43,6 +43,14 @@ module.exports = require("three");
43
43
 
44
44
  /***/ },
45
45
 
46
+ /***/ 502
47
+ (module) {
48
+
49
+ "use strict";
50
+ module.exports = require("three/addons/libs/meshopt_decoder.module.js");
51
+
52
+ /***/ },
53
+
46
54
  /***/ 303
47
55
  (module) {
48
56
 
@@ -11240,7 +11248,7 @@ const extractSafariExtensionDetails = (func, filename) => {
11240
11248
  // exists only for the type-checker, so in the ES/CJS builds the identifier is
11241
11249
  // genuinely absent and a direct comparison throws ReferenceError at module load.
11242
11250
  // `typeof` is the only safe way to probe a possibly-undeclared global.
11243
- var sentry_SDK_VERSION = false ? 0 : "3.3.2";
11251
+ var sentry_SDK_VERSION = false ? 0 : "3.4.0-dev.2";
11244
11252
  var DSN = false ? 0 : "https://872f598f020e3cd73a0933b562d24c81@sentry.mapvx.app/5";
11245
11253
 
11246
11254
  /**
@@ -16078,25 +16086,53 @@ function requester_toPrimitive(t, r) { if ("object" != requester_typeof(t) || !t
16078
16086
 
16079
16087
 
16080
16088
 
16089
+ /**
16090
+ * Default host for routing, health and legacy transport endpoints. In
16091
+ * production this differs from the data-API host (`public-api.mapvx.com`).
16092
+ * @hidden
16093
+ */
16094
+ var DEFAULT_MAPVX_API_URL = "https://api.mapvx.com";
16095
+
16096
+ /**
16097
+ * Ensures a base URL is absolute (prepends `https://` when the protocol is
16098
+ * missing) and strips any trailing slash, so path segments concatenate cleanly.
16099
+ * @hidden
16100
+ */
16101
+ function normalizeBaseUrl(url) {
16102
+ var withProtocol = url.startsWith("http://") || url.startsWith("https://") ? url : "https://".concat(url);
16103
+ return withProtocol.endsWith("/") ? withProtocol.slice(0, -1) : withProtocol;
16104
+ }
16105
+
16081
16106
  /**
16082
16107
  * Represents the requester for the repository.
16083
16108
  * @hidden
16084
16109
  */
16085
16110
  var Requester = /*#__PURE__*/function () {
16086
16111
  function Requester(lang) {
16112
+ var _endpoints$routeApiUr, _endpoints$healthApiU, _endpoints$legacyApiU;
16087
16113
  var apiUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "https://public-api.mapvx.com";
16088
16114
  var mapvxRequestContext = arguments.length > 2 ? arguments[2] : undefined;
16115
+ var endpoints = arguments.length > 3 ? arguments[3] : undefined;
16089
16116
  requester_classCallCheck(this, Requester);
16090
16117
  this.lang = lang;
16091
16118
  this.mapvxRequestContext = mapvxRequestContext;
16092
- // Ensure we have an absolute URL (required for new URL() in fetchFromUrl)
16093
- var withProtocol = apiUrl.startsWith("http://") || apiUrl.startsWith("https://") ? apiUrl : "https://".concat(apiUrl);
16094
- var cleanApiUrl = withProtocol.endsWith("/") ? withProtocol.slice(0, -1) : withProtocol;
16119
+ var cleanApiUrl = normalizeBaseUrl(apiUrl);
16095
16120
  this.baseUrl = "".concat(cleanApiUrl, "/api/sdk/v2/");
16096
16121
  this.baseUrlPortal = "".concat(cleanApiUrl, "/api/portal/");
16097
- this.baseUrlHealth = "https://api.mapvx.com/api/sdk/v2/health";
16098
- this.oldBaseUrl = "https://api.mapvx.com/api/sdk/";
16099
- this.routeBaseUrl = "https://api.mapvx.com/sdk/";
16122
+ // Routing, health and legacy-transport endpoints live on a different host
16123
+ // than `apiUrl` in production (api.mapvx.com vs public-api.mapvx.com), so
16124
+ // they default to that host and can each be overridden independently — an
16125
+ // offline totem points them at its local edge server so routes resolve
16126
+ // without reaching the public internet.
16127
+ // `?.trim() ||`, not `??`: an explicit blank/whitespace override (e.g. from a config object
16128
+ // spread over incomplete defaults) must fall back to the default host too, not resolve to a
16129
+ // bare-hostname URL like `https://sdk/`.
16130
+ var routeBase = normalizeBaseUrl((endpoints === null || endpoints === void 0 || (_endpoints$routeApiUr = endpoints.routeApiUrl) === null || _endpoints$routeApiUr === void 0 ? void 0 : _endpoints$routeApiUr.trim()) || DEFAULT_MAPVX_API_URL);
16131
+ var healthBase = normalizeBaseUrl((endpoints === null || endpoints === void 0 || (_endpoints$healthApiU = endpoints.healthApiUrl) === null || _endpoints$healthApiU === void 0 ? void 0 : _endpoints$healthApiU.trim()) || DEFAULT_MAPVX_API_URL);
16132
+ var legacyBase = normalizeBaseUrl((endpoints === null || endpoints === void 0 || (_endpoints$legacyApiU = endpoints.legacyApiUrl) === null || _endpoints$legacyApiU === void 0 ? void 0 : _endpoints$legacyApiU.trim()) || DEFAULT_MAPVX_API_URL);
16133
+ this.baseUrlHealth = "".concat(healthBase, "/api/sdk/v2/health");
16134
+ this.oldBaseUrl = "".concat(legacyBase, "/api/sdk/");
16135
+ this.routeBaseUrl = "".concat(routeBase, "/sdk/");
16100
16136
  }
16101
16137
 
16102
16138
  /**
@@ -17149,14 +17185,14 @@ function extractErrorMessage(errorBody) {
17149
17185
  * @hidden
17150
17186
  */
17151
17187
  var Repository = /*#__PURE__*/function (_Loggeable) {
17152
- function Repository(token, lang, apiUrl, cache, mapvxRequestContext) {
17188
+ function Repository(token, lang, apiUrl, cache, mapvxRequestContext, endpoints) {
17153
17189
  var _this;
17154
17190
  repository_classCallCheck(this, Repository);
17155
17191
  _this = repository_callSuper(this, Repository);
17156
17192
  repository_defineProperty(_this, "currentLang", "en");
17157
17193
  _this.token = token;
17158
17194
  _this.currentLang = lang;
17159
- _this.requester = new Requester(lang, apiUrl, mapvxRequestContext);
17195
+ _this.requester = new Requester(lang, apiUrl, mapvxRequestContext, endpoints);
17160
17196
  _this.cache = cache !== null && cache !== void 0 ? cache : new CacheManager();
17161
17197
  return _this;
17162
17198
  }
@@ -18626,6 +18662,89 @@ function _3d_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof
18626
18662
  function _3d_iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
18627
18663
  function _3d_arrayWithoutHoles(r) { if (Array.isArray(r)) return _3d_arrayLikeToArray(r); }
18628
18664
  function _3d_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
18665
+ /** Default LOD hysteresis (zoom units) when {@link Models3DLodConfig.hysteresis} is unset. */
18666
+ var DEFAULT_LOD_HYSTERESIS = 0.5;
18667
+
18668
+ /**
18669
+ * Resolved LOD zoom boundaries: models unload strictly below `unloadBelow` and (re)load at or
18670
+ * above `reloadAtOrAbove`. The gap between them is the hysteresis dead-band.
18671
+ * @internal
18672
+ */
18673
+
18674
+ /**
18675
+ * Computes the unload/reload zoom boundaries from {@link Models3DConfig.lod}, or `null` when LOD is
18676
+ * disabled (no `lod`, no models, or a non-finite `minZoom`). Pure — safe to unit-test without WebGL.
18677
+ */
18678
+ var resolveModels3DLodThresholds = function resolveModels3DLodThresholds(models) {
18679
+ var lod = models === null || models === void 0 ? void 0 : models.lod;
18680
+ if (!models || models.enabled === false || !lod || typeof lod.minZoom !== "number" || !Number.isFinite(lod.minZoom)) {
18681
+ return null;
18682
+ }
18683
+ var hysteresis = typeof lod.hysteresis === "number" && Number.isFinite(lod.hysteresis) && lod.hysteresis >= 0 ? lod.hysteresis : DEFAULT_LOD_HYSTERESIS;
18684
+ return {
18685
+ reloadAtOrAbove: lod.minZoom,
18686
+ unloadBelow: lod.minZoom - hysteresis
18687
+ };
18688
+ };
18689
+
18690
+ /**
18691
+ * Decides what the LOD controller should do at the current zoom given whether the models are
18692
+ * currently unloaded. Returns `"unload"` when they are loaded but the camera is below the unload
18693
+ * boundary, `"reload"` when they are unloaded but the camera has returned to/above the reload
18694
+ * boundary, and `"none"` otherwise (including within the hysteresis band). Pure/testable.
18695
+ */
18696
+ var lodActionForZoom = function lodActionForZoom(zoom, thresholds, currentlyUnloaded) {
18697
+ if (!currentlyUnloaded && zoom < thresholds.unloadBelow) {
18698
+ return "unload";
18699
+ }
18700
+ if (currentlyUnloaded && zoom >= thresholds.reloadAtOrAbove) {
18701
+ return "reload";
18702
+ }
18703
+ return "none";
18704
+ };
18705
+
18706
+ /**
18707
+ * Resolved deck.gl tile-cache props: every field concrete, ready to spread onto an `MVTLayer`.
18708
+ * @internal
18709
+ */
18710
+
18711
+ /**
18712
+ * Conservative defaults that bound each deck.gl overlay layer's in-memory tile cache. Chosen to
18713
+ * favor low RAM: only the visible working set (plus a small margin) stays parsed in memory; the
18714
+ * raw tile bytes remain on disk in the Service Worker cache, so an evicted tile is re-parsed
18715
+ * rather than re-downloaded. Raise `maxCacheSize` only if profiling shows flashing at the
18716
+ * viewport edge while panning.
18717
+ * @internal
18718
+ */
18719
+ var DEFAULT_DECK_TILE_CACHE = {
18720
+ // Per layer; with four overlay layers this caps the parsed-tile set at ~4x this number.
18721
+ maxCacheSize: 64,
18722
+ maxRequests: 6,
18723
+ // Drop parent tiles once children cover the viewport — keeps the resident set smallest.
18724
+ refinementStrategy: "no-overlap",
18725
+ // Byte budget is opt-in (deck.gl only enforces it when a tile's byte size is known).
18726
+ maxCacheByteSize: undefined
18727
+ };
18728
+
18729
+ /**
18730
+ * Merges an optional {@link DeckTileCacheConfig} over {@link DEFAULT_DECK_TILE_CACHE}, ignoring
18731
+ * `undefined`/`null` fields and clamping numeric bounds to at least 1. The result is always
18732
+ * bounded — passing `undefined` yields the defaults, never an unlimited cache.
18733
+ */
18734
+ var resolveDeckTileCache = function resolveDeckTileCache(config) {
18735
+ var _config$refinementStr;
18736
+ var clampPositive = function clampPositive(value, fallback) {
18737
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : fallback;
18738
+ };
18739
+ var maxCacheByteSize = typeof (config === null || config === void 0 ? void 0 : config.maxCacheByteSize) === "number" && Number.isFinite(config.maxCacheByteSize) && config.maxCacheByteSize >= 1 ? Math.floor(config.maxCacheByteSize) : DEFAULT_DECK_TILE_CACHE.maxCacheByteSize;
18740
+ return {
18741
+ maxCacheSize: clampPositive(config === null || config === void 0 ? void 0 : config.maxCacheSize, DEFAULT_DECK_TILE_CACHE.maxCacheSize),
18742
+ maxRequests: clampPositive(config === null || config === void 0 ? void 0 : config.maxRequests, DEFAULT_DECK_TILE_CACHE.maxRequests),
18743
+ refinementStrategy: (_config$refinementStr = config === null || config === void 0 ? void 0 : config.refinementStrategy) !== null && _config$refinementStr !== void 0 ? _config$refinementStr : DEFAULT_DECK_TILE_CACHE.refinementStrategy,
18744
+ maxCacheByteSize: maxCacheByteSize
18745
+ };
18746
+ };
18747
+
18629
18748
  /**
18630
18749
  * Default lights matching the legacy escalator scene when {@link Models3DConfig.lights} is unset.
18631
18750
  * @internal
@@ -19035,17 +19154,19 @@ var deckPromise;
19035
19154
  * Subsequent calls return the same promise, so a single Three.js instance is shared.
19036
19155
  */
19037
19156
  function loadThree() {
19038
- threePromise !== null && threePromise !== void 0 ? threePromise : threePromise = Promise.all([Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 912, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 833, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 303, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 373, 23))]).then(function (_ref) {
19039
- var _ref2 = three_slicedToArray(_ref, 4),
19157
+ threePromise !== null && threePromise !== void 0 ? threePromise : threePromise = Promise.all([Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 912, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 833, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 303, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 373, 23)), Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 502, 23))]).then(function (_ref) {
19158
+ var _ref2 = three_slicedToArray(_ref, 5),
19040
19159
  three = _ref2[0],
19041
19160
  gltf = _ref2[1],
19042
19161
  draco = _ref2[2],
19043
- ktx2 = _ref2[3];
19162
+ ktx2 = _ref2[3],
19163
+ meshopt = _ref2[4];
19044
19164
  return {
19045
19165
  THREE: three,
19046
19166
  GLTFLoader: gltf.GLTFLoader,
19047
19167
  DRACOLoader: draco.DRACOLoader,
19048
- KTX2Loader: ktx2.KTX2Loader
19168
+ KTX2Loader: ktx2.KTX2Loader,
19169
+ MeshoptDecoder: meshopt.MeshoptDecoder
19049
19170
  };
19050
19171
  });
19051
19172
  return threePromise;
@@ -19103,6 +19224,12 @@ function getGltfLoader() {
19103
19224
  ktx2Loader.detectSupport(new mod.THREE.WebGLRenderer({
19104
19225
  antialias: true
19105
19226
  }));
19227
+
19228
+ // Enable EXT_meshopt_compression so meshopt-compressed GLBs decode. The decoder is a WASM
19229
+ // singleton; GLTFLoader awaits its `.ready` promise internally before parsing. Assets that
19230
+ // don't use the extension are unaffected. This lets the offline pipeline pick meshopt (often
19231
+ // smaller than Draco for the scene's meshes) without a runtime change.
19232
+ gltfLoader.setMeshoptDecoder(mod.MeshoptDecoder);
19106
19233
  return gltfLoader;
19107
19234
  });
19108
19235
  return gltfLoaderPromise;
@@ -19460,6 +19587,7 @@ function scene3DController_toPrimitive(t, r) { if ("object" != scene3DController
19460
19587
  */
19461
19588
  var Scene3DController = /*#__PURE__*/function () {
19462
19589
  function Scene3DController(map, scene3DConfig, initialCenter, onModelsProgress) {
19590
+ var _scene3DConfig$custom;
19463
19591
  scene3DController_classCallCheck(this, Scene3DController);
19464
19592
  /** Latest known floor key; updated by the floor-change hooks and read when (re)building layers. */
19465
19593
  scene3DController_defineProperty(this, "currentFloor", "");
@@ -19487,10 +19615,21 @@ var Scene3DController = /*#__PURE__*/function () {
19487
19615
  scene3DController_defineProperty(this, "scene3DRouteCollisionPoints", []);
19488
19616
  scene3DController_defineProperty(this, "spriteIconMapping", {});
19489
19617
  scene3DController_defineProperty(this, "spriteAtlasImage", new Image());
19618
+ /** True while the GLB models are unloaded by LOD (camera zoomed out past the threshold). */
19619
+ scene3DController_defineProperty(this, "modelsUnloadedByLod", false);
19620
+ /**
19621
+ * True while {@link loadScene3DGlbTemplates} is populating `scene3DGlbRootByUrl` /
19622
+ * `scene3DGlbTemplateById` (initial load or an LOD reload). Guards against overlapping reloads
19623
+ * and, in {@link updateLodForZoom}, against an LOD unload running concurrently and clearing
19624
+ * those same maps out from under the in-flight load.
19625
+ */
19626
+ scene3DController_defineProperty(this, "glbTemplatesLoadInFlight", false);
19490
19627
  this.map = map;
19491
19628
  this.scene3DConfig = scene3DConfig;
19492
19629
  this.initialCenter = initialCenter;
19493
19630
  this.onModelsProgress = onModelsProgress;
19631
+ this.deckTileCache = resolveDeckTileCache((_scene3DConfig$custom = scene3DConfig.customLayers) === null || _scene3DConfig$custom === void 0 ? void 0 : _scene3DConfig$custom.tileCache);
19632
+ this.lodThresholds = resolveModels3DLodThresholds(scene3DConfig.models);
19494
19633
  }
19495
19634
 
19496
19635
  // Lifecycle entry points forwarded by the map ---------------------------------------------
@@ -19544,6 +19683,7 @@ var Scene3DController = /*#__PURE__*/function () {
19544
19683
  this.map.addControl(this.deckOverlay);
19545
19684
  // Hide MapLibre icon layers — replaced by deck.gl IconLayer
19546
19685
  this.hideLayers(this.scene3DConfig.hideLayers);
19686
+ this.installDebugStatsHook();
19547
19687
  models = this.scene3DConfig.models;
19548
19688
  glbModelsActive = models !== undefined && models.enabled !== false && models.assets.length > 0;
19549
19689
  if (glbModelsActive) {
@@ -19564,19 +19704,136 @@ var Scene3DController = /*#__PURE__*/function () {
19564
19704
  return _onMapLoad.apply(this, arguments);
19565
19705
  }
19566
19706
  return onMapLoad;
19567
- }() /** Re-applies zoom-based model transparency; call on every map `zoom`. */
19707
+ }() /** Re-applies zoom-based model transparency and evaluates LOD; call on every map `zoom`. */
19568
19708
  }, {
19569
19709
  key: "onZoom",
19570
19710
  value: function onZoom() {
19571
19711
  this.applyModelOpacity();
19712
+ this.updateLodForZoom();
19713
+ }
19714
+
19715
+ /**
19716
+ * Evaluates the zoom-based LOD (see {@link Models3DConfig.lod}): unloads the GLB models from
19717
+ * memory when the camera drops below the unload boundary and reloads them when it returns to the
19718
+ * reload boundary. No-op when LOD is disabled. Cheap enough to call on every `zoom` event — it
19719
+ * only acts on a boundary crossing.
19720
+ */
19721
+ }, {
19722
+ key: "updateLodForZoom",
19723
+ value: function updateLodForZoom() {
19724
+ if (!this.lodThresholds) {
19725
+ return;
19726
+ }
19727
+ var action = lodActionForZoom(this.map.getZoom(), this.lodThresholds, this.modelsUnloadedByLod);
19728
+ if (action === "unload") {
19729
+ if (this.glbTemplatesLoadInFlight) {
19730
+ // A load is already populating the model maps; unloading now would race with it.
19731
+ // reloadScene3DModelsForLod()/the initial load re-evaluate the zoom once they settle.
19732
+ return;
19733
+ }
19734
+ this.unloadScene3DModelsForLod();
19735
+ } else if (action === "reload") {
19736
+ void this.reloadScene3DModelsForLod();
19737
+ }
19572
19738
  }
19573
19739
 
19740
+ /**
19741
+ * Frees the GLB models' GPU resources (placed group's material clones + every cached template's
19742
+ * geometry/textures) while keeping the custom layer, its `WebGLRenderer`, scene and lights alive,
19743
+ * so a later {@link reloadScene3DModelsForLod} can repopulate without recreating the map layer.
19744
+ * Distinct from {@link dispose}, which tears the whole controller down.
19745
+ */
19746
+ }, {
19747
+ key: "unloadScene3DModelsForLod",
19748
+ value: function unloadScene3DModelsForLod() {
19749
+ var _this$threeMod;
19750
+ var three = (_this$threeMod = this.threeMod) === null || _this$threeMod === void 0 ? void 0 : _this$threeMod.THREE;
19751
+ if (!three) {
19752
+ return;
19753
+ }
19754
+ if (this.scene3DModelsGroup) {
19755
+ var _this$scene3DGlbScene;
19756
+ disposeMaterialsOnly(three, this.scene3DModelsGroup);
19757
+ (_this$scene3DGlbScene = this.scene3DGlbScene) === null || _this$scene3DGlbScene === void 0 || _this$scene3DGlbScene.remove(this.scene3DModelsGroup);
19758
+ this.scene3DModelsGroup = undefined;
19759
+ }
19760
+ // Iterate the deduped-by-URL roots so a shared root is never disposed twice (mirrors dispose()).
19761
+ var _iterator = scene3DController_createForOfIteratorHelper(this.scene3DGlbRootByUrl.values()),
19762
+ _step;
19763
+ try {
19764
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
19765
+ var root = _step.value;
19766
+ disposeObject3D(three, root);
19767
+ }
19768
+ } catch (err) {
19769
+ _iterator.e(err);
19770
+ } finally {
19771
+ _iterator.f();
19772
+ }
19773
+ this.scene3DGlbRootByUrl.clear();
19774
+ this.scene3DGlbTemplateById.clear();
19775
+ this.modelsUnloadedByLod = true;
19776
+ this.map.triggerRepaint();
19777
+ }
19778
+
19779
+ /**
19780
+ * Reloads the GLB templates from disk/network and re-places them for the current floor after an
19781
+ * LOD unload. Guards against overlapping reloads, and re-evaluates the zoom on completion so a
19782
+ * camera that zoomed back out mid-download ends up unloaded again rather than stuck loaded.
19783
+ */
19784
+ }, {
19785
+ key: "reloadScene3DModelsForLod",
19786
+ value: (function () {
19787
+ var _reloadScene3DModelsForLod = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee2() {
19788
+ var _t2;
19789
+ return scene3DController_regenerator().w(function (_context2) {
19790
+ while (1) switch (_context2.p = _context2.n) {
19791
+ case 0:
19792
+ if (!this.glbTemplatesLoadInFlight) {
19793
+ _context2.n = 1;
19794
+ break;
19795
+ }
19796
+ return _context2.a(2);
19797
+ case 1:
19798
+ this.glbTemplatesLoadInFlight = true;
19799
+ _context2.p = 2;
19800
+ _context2.n = 3;
19801
+ return this.loadScene3DGlbTemplates();
19802
+ case 3:
19803
+ this.placeScene3DModels();
19804
+ // Only mark as loaded once placement actually succeeded, so a failed reload leaves
19805
+ // modelsUnloadedByLod = true and the trailing updateLodForZoom() below retries it.
19806
+ this.modelsUnloadedByLod = false;
19807
+ _context2.n = 5;
19808
+ break;
19809
+ case 4:
19810
+ _context2.p = 4;
19811
+ _t2 = _context2.v;
19812
+ console.error("Failed to reload declarative GLB models after LOD unload", _t2);
19813
+ case 5:
19814
+ _context2.p = 5;
19815
+ this.glbTemplatesLoadInFlight = false;
19816
+ return _context2.f(5);
19817
+ case 6:
19818
+ // The camera may have moved during the async load; re-evaluate so a zoom back out unloads again.
19819
+ this.updateLodForZoom();
19820
+ case 7:
19821
+ return _context2.a(2);
19822
+ }
19823
+ }, _callee2, this, [[2, 4, 5, 6]]);
19824
+ }));
19825
+ function reloadScene3DModelsForLod() {
19826
+ return _reloadScene3DModelsForLod.apply(this, arguments);
19827
+ }
19828
+ return reloadScene3DModelsForLod;
19829
+ }()
19574
19830
  /**
19575
19831
  * Sets the route path used for GLB route-transparency collision and re-evaluates which models a
19576
19832
  * route currently crosses. Points are tagged with the floor on which their route segment is
19577
19833
  * visible; only points on the current floor participate, so a model never fades unless a route is
19578
19834
  * visibly crossing it on the displayed floor. Pass an empty array to clear.
19579
19835
  */
19836
+ )
19580
19837
  }, {
19581
19838
  key: "setRouteCollisionPath",
19582
19839
  value: function setRouteCollisionPath(points) {
@@ -19611,6 +19868,93 @@ var Scene3DController = /*#__PURE__*/function () {
19611
19868
  this.updateDeckOverlay();
19612
19869
  }
19613
19870
 
19871
+ /**
19872
+ * A point-in-time snapshot of the 3D scene's memory drivers, for profiling. The Three.js
19873
+ * `renderer.info` counters are the best in-page proxy for GLB VRAM (decoded geometries/textures
19874
+ * live on the GPU and are not visible to `performance.memory`, which only reports the JS heap).
19875
+ * The deck tile counts approximate the overlay's parsed-tile working set — the thing the tile-cache
19876
+ * bounds (see {@link DeckTileCacheConfig}) keep from growing without limit as the map pans/zooms.
19877
+ *
19878
+ * @group Map
19879
+ */
19880
+ }, {
19881
+ key: "getDebugStats",
19882
+ value: function getDebugStats() {
19883
+ var _this$glbRenderer, _info$programs$length, _info$programs, _this$scene3DModelsGr, _this$scene3DModelsGr2;
19884
+ var info = (_this$glbRenderer = this.glbRenderer) === null || _this$glbRenderer === void 0 ? void 0 : _this$glbRenderer.info;
19885
+ var three = info ? {
19886
+ geometries: info.memory.geometries,
19887
+ textures: info.memory.textures,
19888
+ programs: (_info$programs$length = (_info$programs = info.programs) === null || _info$programs === void 0 ? void 0 : _info$programs.length) !== null && _info$programs$length !== void 0 ? _info$programs$length : 0,
19889
+ renderCalls: info.render.calls,
19890
+ triangles: info.render.triangles
19891
+ } : null;
19892
+ var deckTiles = null;
19893
+ try {
19894
+ var _overlay$_deck;
19895
+ // Best-effort read of each overlay layer's parsed-tile count. deck.gl internals are private,
19896
+ // so this is guarded — it degrades to `null` rather than throwing if the shape changes.
19897
+ var overlay = this.deckOverlay;
19898
+ var layers = overlay === null || overlay === void 0 || (_overlay$_deck = overlay._deck) === null || _overlay$_deck === void 0 || (_overlay$_deck = _overlay$_deck.layerManager) === null || _overlay$_deck === void 0 ? void 0 : _overlay$_deck.layers;
19899
+ if (Array.isArray(layers)) {
19900
+ var counts = {};
19901
+ for (var _i = 0, _arr = layers; _i < _arr.length; _i++) {
19902
+ var _layer$state;
19903
+ var layer = _arr[_i];
19904
+ var size = layer === null || layer === void 0 || (_layer$state = layer.state) === null || _layer$state === void 0 || (_layer$state = _layer$state.tileset) === null || _layer$state === void 0 || (_layer$state = _layer$state._cache) === null || _layer$state === void 0 ? void 0 : _layer$state.size;
19905
+ if (typeof size === "number" && layer.id) {
19906
+ var _counts$baseId;
19907
+ // Strip deck's per-sublayer suffixes so the four MVT roots aggregate by base id.
19908
+ var baseId = layer.id.split("-sublayer")[0];
19909
+ counts[baseId] = Math.max((_counts$baseId = counts[baseId]) !== null && _counts$baseId !== void 0 ? _counts$baseId : 0, size);
19910
+ }
19911
+ }
19912
+ deckTiles = counts;
19913
+ }
19914
+ } catch (_unused) {
19915
+ deckTiles = null;
19916
+ }
19917
+ return {
19918
+ zoom: this.map.getZoom(),
19919
+ currentFloor: this.currentFloor,
19920
+ modelsUnloadedByLod: this.modelsUnloadedByLod,
19921
+ glbRoots: this.scene3DGlbRootByUrl.size,
19922
+ glbTemplates: this.scene3DGlbTemplateById.size,
19923
+ placedModels: (_this$scene3DModelsGr = (_this$scene3DModelsGr2 = this.scene3DModelsGroup) === null || _this$scene3DModelsGr2 === void 0 ? void 0 : _this$scene3DModelsGr2.children.length) !== null && _this$scene3DModelsGr !== void 0 ? _this$scene3DModelsGr : 0,
19924
+ three: three,
19925
+ deckTiles: deckTiles,
19926
+ deckTileCache: this.deckTileCache,
19927
+ lodThresholds: this.lodThresholds
19928
+ };
19929
+ }
19930
+
19931
+ /**
19932
+ * Exposes {@link getDebugStats} as `globalThis.__mvxScene3DStats()` when the opt-in flag
19933
+ * `globalThis.__MVX_SCENE3D_DEBUG__` is truthy, so a profiling session can read the scene's memory
19934
+ * drivers from the console/tests without external tooling. No-op (and no global written) otherwise.
19935
+ */
19936
+ }, {
19937
+ key: "installDebugStatsHook",
19938
+ value: function installDebugStatsHook() {
19939
+ var _this = this;
19940
+ var g = globalThis;
19941
+ if (g.__MVX_SCENE3D_DEBUG__) {
19942
+ g.__mvxScene3DStats = function () {
19943
+ return _this.getDebugStats();
19944
+ };
19945
+ }
19946
+ }
19947
+
19948
+ /** Removes the debug hook if it points at this controller. Called from {@link dispose}. */
19949
+ }, {
19950
+ key: "uninstallDebugStatsHook",
19951
+ value: function uninstallDebugStatsHook() {
19952
+ var g = globalThis;
19953
+ if (g.__mvxScene3DStats) {
19954
+ delete g.__mvxScene3DStats;
19955
+ }
19956
+ }
19957
+
19614
19958
  /**
19615
19959
  * Releases every GPU resource this controller owns: the placed models group's material clones,
19616
19960
  * the cached GLB templates' geometries/materials/textures, and the `WebGLRenderer` created for the
@@ -19624,8 +19968,8 @@ var Scene3DController = /*#__PURE__*/function () {
19624
19968
  }, {
19625
19969
  key: "dispose",
19626
19970
  value: function dispose() {
19627
- var _this$threeMod, _this$glbRenderer;
19628
- var three = (_this$threeMod = this.threeMod) === null || _this$threeMod === void 0 ? void 0 : _this$threeMod.THREE;
19971
+ var _this$threeMod2, _this$glbRenderer2;
19972
+ var three = (_this$threeMod2 = this.threeMod) === null || _this$threeMod2 === void 0 ? void 0 : _this$threeMod2.THREE;
19629
19973
  if (three) {
19630
19974
  if (this.scene3DModelsGroup) {
19631
19975
  disposeMaterialsOnly(three, this.scene3DModelsGroup);
@@ -19633,24 +19977,25 @@ var Scene3DController = /*#__PURE__*/function () {
19633
19977
  }
19634
19978
  // Iterate the deduplicated-by-URL roots (not `scene3DGlbTemplateById`, which may map several
19635
19979
  // asset ids to the same root) so a shared root is never disposed more than once.
19636
- var _iterator = scene3DController_createForOfIteratorHelper(this.scene3DGlbRootByUrl.values()),
19637
- _step;
19980
+ var _iterator2 = scene3DController_createForOfIteratorHelper(this.scene3DGlbRootByUrl.values()),
19981
+ _step2;
19638
19982
  try {
19639
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
19640
- var root = _step.value;
19983
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
19984
+ var root = _step2.value;
19641
19985
  disposeObject3D(three, root);
19642
19986
  }
19643
19987
  } catch (err) {
19644
- _iterator.e(err);
19988
+ _iterator2.e(err);
19645
19989
  } finally {
19646
- _iterator.f();
19990
+ _iterator2.f();
19647
19991
  }
19648
19992
  }
19649
19993
  this.scene3DGlbRootByUrl.clear();
19650
19994
  this.scene3DGlbTemplateById.clear();
19651
19995
  this.scene3DGlbScene = undefined;
19652
- (_this$glbRenderer = this.glbRenderer) === null || _this$glbRenderer === void 0 || _this$glbRenderer.dispose();
19996
+ (_this$glbRenderer2 = this.glbRenderer) === null || _this$glbRenderer2 === void 0 || _this$glbRenderer2.dispose();
19653
19997
  this.glbRenderer = undefined;
19998
+ this.uninstallDebugStatsHook();
19654
19999
  }
19655
20000
 
19656
20001
  // Internal implementation -----------------------------------------------------------------
@@ -19662,40 +20007,40 @@ var Scene3DController = /*#__PURE__*/function () {
19662
20007
  }, {
19663
20008
  key: "ensure3DLibs",
19664
20009
  value: function () {
19665
- var _ensure3DLibs = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee2() {
19666
- var _this$threeMod2, _this$deckMod;
19667
- return scene3DController_regenerator().w(function (_context2) {
19668
- while (1) switch (_context2.n) {
20010
+ var _ensure3DLibs = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee3() {
20011
+ var _this$threeMod3, _this$deckMod;
20012
+ return scene3DController_regenerator().w(function (_context3) {
20013
+ while (1) switch (_context3.n) {
19669
20014
  case 0:
19670
- if (!((_this$threeMod2 = this.threeMod) !== null && _this$threeMod2 !== void 0)) {
19671
- _context2.n = 1;
20015
+ if (!((_this$threeMod3 = this.threeMod) !== null && _this$threeMod3 !== void 0)) {
20016
+ _context3.n = 1;
19672
20017
  break;
19673
20018
  }
19674
- _this$threeMod2;
19675
- _context2.n = 3;
20019
+ _this$threeMod3;
20020
+ _context3.n = 3;
19676
20021
  break;
19677
20022
  case 1:
19678
- _context2.n = 2;
20023
+ _context3.n = 2;
19679
20024
  return loadThree();
19680
20025
  case 2:
19681
- this.threeMod = _context2.v;
20026
+ this.threeMod = _context3.v;
19682
20027
  case 3:
19683
20028
  if (!((_this$deckMod = this.deckMod) !== null && _this$deckMod !== void 0)) {
19684
- _context2.n = 4;
20029
+ _context3.n = 4;
19685
20030
  break;
19686
20031
  }
19687
20032
  _this$deckMod;
19688
- _context2.n = 6;
20033
+ _context3.n = 6;
19689
20034
  break;
19690
20035
  case 4:
19691
- _context2.n = 5;
20036
+ _context3.n = 5;
19692
20037
  return loadDeck();
19693
20038
  case 5:
19694
- this.deckMod = _context2.v;
20039
+ this.deckMod = _context3.v;
19695
20040
  case 6:
19696
- return _context2.a(2);
20041
+ return _context3.a(2);
19697
20042
  }
19698
- }, _callee2, this);
20043
+ }, _callee3, this);
19699
20044
  }));
19700
20045
  function ensure3DLibs() {
19701
20046
  return _ensure3DLibs.apply(this, arguments);
@@ -19705,7 +20050,7 @@ var Scene3DController = /*#__PURE__*/function () {
19705
20050
  }, {
19706
20051
  key: "createGlbCustomLayer",
19707
20052
  value: function createGlbCustomLayer() {
19708
- var _this = this;
20053
+ var _this2 = this;
19709
20054
  var three = this.threeMod.THREE;
19710
20055
  var refMercator = maplibre_gl.MercatorCoordinate.fromLngLat(this.initialCenter, 0);
19711
20056
  var meterScale = refMercator.meterInMercatorCoordinateUnits();
@@ -19718,10 +20063,16 @@ var Scene3DController = /*#__PURE__*/function () {
19718
20063
  } else {
19719
20064
  this.scene3DGlbLightCount = 0;
19720
20065
  }
20066
+ this.glbTemplatesLoadInFlight = true;
19721
20067
  void this.loadScene3DGlbTemplates().then(function () {
19722
- return _this.placeScene3DModels();
20068
+ _this2.placeScene3DModels();
19723
20069
  })["catch"](function (err) {
19724
20070
  console.error("Failed to initialize declarative GLB models", err);
20071
+ })["finally"](function () {
20072
+ _this2.glbTemplatesLoadInFlight = false;
20073
+ // Honor LOD from the first frame: if the map opened below the unload threshold, free the
20074
+ // models just loaded (they reload when the user zooms in). No-op when LOD is disabled.
20075
+ _this2.updateLodForZoom();
19725
20076
  });
19726
20077
  var renderer = undefined;
19727
20078
  var camera = undefined;
@@ -19745,17 +20096,17 @@ var Scene3DController = /*#__PURE__*/function () {
19745
20096
  // Stored on the controller (not just this closure) so `dispose()` can release it — MapLibre
19746
20097
  // does not call a custom layer's `onRemove` when the whole map/style is torn down via
19747
20098
  // `map.remove()`, so callers must dispose this controller explicitly before that happens.
19748
- _this.glbRenderer = renderer;
20099
+ _this2.glbRenderer = renderer;
19749
20100
  },
19750
20101
  onRemove: function onRemove() {
19751
- _this.dispose();
20102
+ _this2.dispose();
19752
20103
  },
19753
20104
  render: function render(_gl, args) {
19754
20105
  var _args$defaultProjecti;
19755
- if (!camera || !renderer || !_this.scene3DGlbScene || !_this.scene3DModelsGroup || _this.scene3DModelsGroup.children.length === 0) {
20106
+ if (!camera || !renderer || !_this2.scene3DGlbScene || !_this2.scene3DModelsGroup || _this2.scene3DModelsGroup.children.length === 0) {
19756
20107
  return;
19757
20108
  }
19758
- var canvas = _this.map.getCanvas();
20109
+ var canvas = _this2.map.getCanvas();
19759
20110
  var width = canvas.width;
19760
20111
  var height = canvas.height;
19761
20112
  // Skip while the framebuffer has no drawable area (e.g. devtools opening).
@@ -19770,27 +20121,27 @@ var Scene3DController = /*#__PURE__*/function () {
19770
20121
  tmpMatrix.fromArray(mainMatrix).multiply(modelTransform);
19771
20122
  camera.projectionMatrix.copy(tmpMatrix);
19772
20123
  renderer.resetState();
19773
- renderer.render(_this.scene3DGlbScene, camera);
20124
+ renderer.render(_this2.scene3DGlbScene, camera);
19774
20125
  }
19775
20126
  };
19776
20127
  }
19777
20128
  }, {
19778
20129
  key: "loadScene3DGlbTemplates",
19779
20130
  value: function () {
19780
- var _loadScene3DGlbTemplates = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee4() {
19781
- var _this$threeMod3,
19782
- _this2 = this;
19783
- var three, models, uniqueUrls, errorByUrl, semaphore, loadedBytesByUrl, totalBytesByUrl, settledAssets, totalAssets, reportProgress, _iterator3, _step3, asset, root, center, _t5;
19784
- return scene3DController_regenerator().w(function (_context4) {
19785
- while (1) switch (_context4.p = _context4.n) {
20131
+ var _loadScene3DGlbTemplates = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee5() {
20132
+ var _this$threeMod4,
20133
+ _this3 = this;
20134
+ var three, models, uniqueUrls, errorByUrl, semaphore, loadedBytesByUrl, totalBytesByUrl, settledAssets, totalAssets, reportProgress, _iterator4, _step4, asset, root, center, _t6;
20135
+ return scene3DController_regenerator().w(function (_context5) {
20136
+ while (1) switch (_context5.p = _context5.n) {
19786
20137
  case 0:
19787
- three = (_this$threeMod3 = this.threeMod) === null || _this$threeMod3 === void 0 ? void 0 : _this$threeMod3.THREE;
20138
+ three = (_this$threeMod4 = this.threeMod) === null || _this$threeMod4 === void 0 ? void 0 : _this$threeMod4.THREE;
19788
20139
  models = this.scene3DConfig.models;
19789
20140
  if (!(!three || !models || models.enabled === false || models.assets.length === 0)) {
19790
- _context4.n = 1;
20141
+ _context5.n = 1;
19791
20142
  break;
19792
20143
  }
19793
- return _context4.a(2);
20144
+ return _context5.a(2);
19794
20145
  case 1:
19795
20146
  this.scene3DGlbRootByUrl.clear();
19796
20147
  this.scene3DGlbTemplateById.clear();
@@ -19811,26 +20162,26 @@ var Scene3DController = /*#__PURE__*/function () {
19811
20162
  settledAssets = 0;
19812
20163
  totalAssets = uniqueUrls.length;
19813
20164
  reportProgress = function reportProgress(done) {
19814
- if (!_this2.onModelsProgress) return;
20165
+ if (!_this3.onModelsProgress) return;
19815
20166
  var loadedBytes = 0;
19816
20167
  var totalBytes = 0;
19817
- var _iterator2 = scene3DController_createForOfIteratorHelper(uniqueUrls),
19818
- _step2;
20168
+ var _iterator3 = scene3DController_createForOfIteratorHelper(uniqueUrls),
20169
+ _step3;
19819
20170
  try {
19820
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
20171
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
19821
20172
  var _loadedBytesByUrl$get;
19822
- var url = _step2.value;
20173
+ var url = _step3.value;
19823
20174
  loadedBytes += (_loadedBytesByUrl$get = loadedBytesByUrl.get(url)) !== null && _loadedBytesByUrl$get !== void 0 ? _loadedBytesByUrl$get : 0;
19824
20175
  var total = totalBytesByUrl.get(url);
19825
20176
  totalBytes = total == null || totalBytes === null ? null : totalBytes + total;
19826
20177
  }
19827
20178
  } catch (err) {
19828
- _iterator2.e(err);
20179
+ _iterator3.e(err);
19829
20180
  } finally {
19830
- _iterator2.f();
20181
+ _iterator3.f();
19831
20182
  }
19832
20183
  try {
19833
- _this2.onModelsProgress({
20184
+ _this3.onModelsProgress({
19834
20185
  loadedAssets: settledAssets,
19835
20186
  totalAssets: totalAssets,
19836
20187
  loadedBytes: loadedBytes,
@@ -19844,20 +20195,20 @@ var Scene3DController = /*#__PURE__*/function () {
19844
20195
  console.error("onScene3DModelsProgress callback threw", err);
19845
20196
  }
19846
20197
  };
19847
- _context4.n = 2;
20198
+ _context5.n = 2;
19848
20199
  return Promise.all(uniqueUrls.map(/*#__PURE__*/function () {
19849
- var _ref = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee3(url) {
19850
- var _ref2, _totalBytesByUrl$get, _t2, _t3, _t4;
19851
- return scene3DController_regenerator().w(function (_context3) {
19852
- while (1) switch (_context3.p = _context3.n) {
20200
+ var _ref = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee4(url) {
20201
+ var _ref2, _totalBytesByUrl$get, _t3, _t4, _t5;
20202
+ return scene3DController_regenerator().w(function (_context4) {
20203
+ while (1) switch (_context4.p = _context4.n) {
19853
20204
  case 0:
19854
- _context3.n = 1;
20205
+ _context4.n = 1;
19855
20206
  return semaphore.acquire();
19856
20207
  case 1:
19857
- _context3.p = 1;
19858
- _t2 = _this2.scene3DGlbRootByUrl;
19859
- _t3 = url;
19860
- _context3.n = 2;
20208
+ _context4.p = 1;
20209
+ _t3 = _this3.scene3DGlbRootByUrl;
20210
+ _t4 = url;
20211
+ _context4.n = 2;
19861
20212
  return loadGlbRoot(url, {
19862
20213
  onProgress: function onProgress(event) {
19863
20214
  loadedBytesByUrl.set(url, event.loaded);
@@ -19866,15 +20217,15 @@ var Scene3DController = /*#__PURE__*/function () {
19866
20217
  }
19867
20218
  });
19868
20219
  case 2:
19869
- _t2.set.call(_t2, _t3, _context3.v);
19870
- _context3.n = 4;
20220
+ _t3.set.call(_t3, _t4, _context4.v);
20221
+ _context4.n = 4;
19871
20222
  break;
19872
20223
  case 3:
19873
- _context3.p = 3;
19874
- _t4 = _context3.v;
19875
- errorByUrl.set(url, _t4);
20224
+ _context4.p = 3;
20225
+ _t5 = _context4.v;
20226
+ errorByUrl.set(url, _t5);
19876
20227
  case 4:
19877
- _context3.p = 4;
20228
+ _context4.p = 4;
19878
20229
  settledAssets++;
19879
20230
  // Once a URL has settled, its total is knowable even if no progress event ever supplied
19880
20231
  // one (failed before the first byte, or the server omitted Content-Length): fall back to
@@ -19883,11 +20234,11 @@ var Scene3DController = /*#__PURE__*/function () {
19883
20234
  totalBytesByUrl.set(url, (_ref2 = (_totalBytesByUrl$get = totalBytesByUrl.get(url)) !== null && _totalBytesByUrl$get !== void 0 ? _totalBytesByUrl$get : loadedBytesByUrl.get(url)) !== null && _ref2 !== void 0 ? _ref2 : 0);
19884
20235
  semaphore.release();
19885
20236
  reportProgress(false);
19886
- return _context3.f(4);
20237
+ return _context4.f(4);
19887
20238
  case 5:
19888
- return _context3.a(2);
20239
+ return _context4.a(2);
19889
20240
  }
19890
- }, _callee3, null, [[1, 3, 4, 5]]);
20241
+ }, _callee4, null, [[1, 3, 4, 5]]);
19891
20242
  }));
19892
20243
  return function (_x) {
19893
20244
  return _ref.apply(this, arguments);
@@ -19895,22 +20246,22 @@ var Scene3DController = /*#__PURE__*/function () {
19895
20246
  }()));
19896
20247
  case 2:
19897
20248
  reportProgress(true);
19898
- _iterator3 = scene3DController_createForOfIteratorHelper(models.assets);
19899
- _context4.p = 3;
19900
- _iterator3.s();
20249
+ _iterator4 = scene3DController_createForOfIteratorHelper(models.assets);
20250
+ _context5.p = 3;
20251
+ _iterator4.s();
19901
20252
  case 4:
19902
- if ((_step3 = _iterator3.n()).done) {
19903
- _context4.n = 7;
20253
+ if ((_step4 = _iterator4.n()).done) {
20254
+ _context5.n = 7;
19904
20255
  break;
19905
20256
  }
19906
- asset = _step3.value;
20257
+ asset = _step4.value;
19907
20258
  root = this.scene3DGlbRootByUrl.get(asset.url);
19908
20259
  if (root) {
19909
- _context4.n = 5;
20260
+ _context5.n = 5;
19910
20261
  break;
19911
20262
  }
19912
20263
  console.error("Failed to load GLB asset \"".concat(asset.id, "\" from ").concat(asset.url), errorByUrl.get(asset.url));
19913
- return _context4.a(3, 6);
20264
+ return _context5.a(3, 6);
19914
20265
  case 5:
19915
20266
  center = computeGlbBottomAnchor(three, root);
19916
20267
  this.scene3DGlbTemplateById.set(asset.id, {
@@ -19918,23 +20269,23 @@ var Scene3DController = /*#__PURE__*/function () {
19918
20269
  center: center
19919
20270
  });
19920
20271
  case 6:
19921
- _context4.n = 4;
20272
+ _context5.n = 4;
19922
20273
  break;
19923
20274
  case 7:
19924
- _context4.n = 9;
20275
+ _context5.n = 9;
19925
20276
  break;
19926
20277
  case 8:
19927
- _context4.p = 8;
19928
- _t5 = _context4.v;
19929
- _iterator3.e(_t5);
20278
+ _context5.p = 8;
20279
+ _t6 = _context5.v;
20280
+ _iterator4.e(_t6);
19930
20281
  case 9:
19931
- _context4.p = 9;
19932
- _iterator3.f();
19933
- return _context4.f(9);
20282
+ _context5.p = 9;
20283
+ _iterator4.f();
20284
+ return _context5.f(9);
19934
20285
  case 10:
19935
- return _context4.a(2);
20286
+ return _context5.a(2);
19936
20287
  }
19937
- }, _callee4, this, [[3, 8, 9, 10]]);
20288
+ }, _callee5, this, [[3, 8, 9, 10]]);
19938
20289
  }));
19939
20290
  function loadScene3DGlbTemplates() {
19940
20291
  return _loadScene3DGlbTemplates.apply(this, arguments);
@@ -19944,15 +20295,15 @@ var Scene3DController = /*#__PURE__*/function () {
19944
20295
  }, {
19945
20296
  key: "placeScene3DModels",
19946
20297
  value: function placeScene3DModels() {
19947
- var _this$threeMod4,
20298
+ var _this$threeMod5,
19948
20299
  _models$globalOffset$,
19949
20300
  _models$globalOffset,
19950
20301
  _models$globalOffset$2,
19951
20302
  _models$globalOffset2,
19952
20303
  _models$globalOffset$3,
19953
20304
  _models$globalOffset3,
19954
- _this3 = this;
19955
- var three = (_this$threeMod4 = this.threeMod) === null || _this$threeMod4 === void 0 ? void 0 : _this$threeMod4.THREE;
20305
+ _this4 = this;
20306
+ var three = (_this$threeMod5 = this.threeMod) === null || _this$threeMod5 === void 0 ? void 0 : _this$threeMod5.THREE;
19956
20307
  if (!three || !this.scene3DGlbScene) {
19957
20308
  return;
19958
20309
  }
@@ -19976,16 +20327,16 @@ var Scene3DController = /*#__PURE__*/function () {
19976
20327
  var floorKey = this.currentFloor;
19977
20328
  var modelsGroup = new three.Group();
19978
20329
  modelsGroup.position.set((_models$globalOffset$ = (_models$globalOffset = models.globalOffset) === null || _models$globalOffset === void 0 ? void 0 : _models$globalOffset.x) !== null && _models$globalOffset$ !== void 0 ? _models$globalOffset$ : 0, (_models$globalOffset$2 = (_models$globalOffset2 = models.globalOffset) === null || _models$globalOffset2 === void 0 ? void 0 : _models$globalOffset2.y) !== null && _models$globalOffset$2 !== void 0 ? _models$globalOffset$2 : 0, (_models$globalOffset$3 = (_models$globalOffset3 = models.globalOffset) === null || _models$globalOffset3 === void 0 ? void 0 : _models$globalOffset3.z) !== null && _models$globalOffset$3 !== void 0 ? _models$globalOffset$3 : 0);
19979
- var _iterator4 = scene3DController_createForOfIteratorHelper(models.placements),
19980
- _step4;
20330
+ var _iterator5 = scene3DController_createForOfIteratorHelper(models.placements),
20331
+ _step5;
19981
20332
  try {
19982
20333
  var _loop = function _loop() {
19983
20334
  var _placement$position$a;
19984
- var placement = _step4.value;
20335
+ var placement = _step5.value;
19985
20336
  if (!isPlacementVisibleOnFloor(placement, floorKey)) {
19986
20337
  return 0; // continue
19987
20338
  }
19988
- var template = _this3.scene3DGlbTemplateById.get(placement.assetId);
20339
+ var template = _this4.scene3DGlbTemplateById.get(placement.assetId);
19989
20340
  if (!template) {
19990
20341
  return 0; // continue
19991
20342
  }
@@ -20047,14 +20398,14 @@ var Scene3DController = /*#__PURE__*/function () {
20047
20398
  modelsGroup.add(pivot);
20048
20399
  },
20049
20400
  _ret;
20050
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
20401
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
20051
20402
  _ret = _loop();
20052
20403
  if (_ret === 0) continue;
20053
20404
  }
20054
20405
  } catch (err) {
20055
- _iterator4.e(err);
20406
+ _iterator5.e(err);
20056
20407
  } finally {
20057
- _iterator4.f();
20408
+ _iterator5.f();
20058
20409
  }
20059
20410
  this.scene3DModelsGroup = modelsGroup;
20060
20411
  this.scene3DGlbScene.add(modelsGroup);
@@ -20074,15 +20425,15 @@ var Scene3DController = /*#__PURE__*/function () {
20074
20425
  }, {
20075
20426
  key: "recomputeRouteAffectedModels",
20076
20427
  value: function recomputeRouteAffectedModels() {
20077
- var _this$threeMod5,
20078
- _this4 = this;
20079
- var three = (_this$threeMod5 = this.threeMod) === null || _this$threeMod5 === void 0 ? void 0 : _this$threeMod5.THREE;
20428
+ var _this$threeMod6,
20429
+ _this5 = this;
20430
+ var three = (_this$threeMod6 = this.threeMod) === null || _this$threeMod6 === void 0 ? void 0 : _this$threeMod6.THREE;
20080
20431
  var modelsGroup = this.scene3DModelsGroup;
20081
20432
  if (!three || !modelsGroup) {
20082
20433
  return;
20083
20434
  }
20084
20435
  var points = this.scene3DRouteCollisionPoints.filter(function (p) {
20085
- return p.floorKey === _this4.currentFloor;
20436
+ return p.floorKey === _this5.currentFloor;
20086
20437
  });
20087
20438
 
20088
20439
  // Convert each route point into the models group's local frame (metres relative to
@@ -20099,11 +20450,11 @@ var Scene3DController = /*#__PURE__*/function () {
20099
20450
  });
20100
20451
  modelsGroup.updateMatrixWorld(true);
20101
20452
  var local = new three.Vector3();
20102
- var _iterator5 = scene3DController_createForOfIteratorHelper(modelsGroup.children),
20103
- _step5;
20453
+ var _iterator6 = scene3DController_createForOfIteratorHelper(modelsGroup.children),
20454
+ _step6;
20104
20455
  try {
20105
20456
  var _loop2 = function _loop2() {
20106
- var pivot = _step5.value;
20457
+ var pivot = _step6.value;
20107
20458
  var routeCfg = pivot.userData.routeTransparency;
20108
20459
  var footprint = pivot.userData.footprint;
20109
20460
  // Only models with a route-transparency config participate (feature activation gate).
@@ -20120,13 +20471,13 @@ var Scene3DController = /*#__PURE__*/function () {
20120
20471
  return pointInFootprint(footprint, local.x, local.z);
20121
20472
  });
20122
20473
  };
20123
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
20474
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
20124
20475
  if (_loop2()) continue;
20125
20476
  }
20126
20477
  } catch (err) {
20127
- _iterator5.e(err);
20478
+ _iterator6.e(err);
20128
20479
  } finally {
20129
- _iterator5.f();
20480
+ _iterator6.f();
20130
20481
  }
20131
20482
  }
20132
20483
 
@@ -20146,11 +20497,11 @@ var Scene3DController = /*#__PURE__*/function () {
20146
20497
  }
20147
20498
  var zoom = this.map.getZoom();
20148
20499
  var changed = false;
20149
- var _iterator6 = scene3DController_createForOfIteratorHelper(this.scene3DModelsGroup.children),
20150
- _step6;
20500
+ var _iterator7 = scene3DController_createForOfIteratorHelper(this.scene3DModelsGroup.children),
20501
+ _step7;
20151
20502
  try {
20152
20503
  var _loop3 = function _loop3() {
20153
- var pivot = _step6.value;
20504
+ var pivot = _step7.value;
20154
20505
  var zoomCfg = pivot.userData.zoomTransparency;
20155
20506
  var routeCfg = pivot.userData.routeTransparency;
20156
20507
  var routeAffected = pivot.userData.routeAffected === true;
@@ -20161,11 +20512,11 @@ var Scene3DController = /*#__PURE__*/function () {
20161
20512
  return;
20162
20513
  }
20163
20514
  var materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
20164
- var _iterator7 = scene3DController_createForOfIteratorHelper(materials),
20165
- _step7;
20515
+ var _iterator8 = scene3DController_createForOfIteratorHelper(materials),
20516
+ _step8;
20166
20517
  try {
20167
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
20168
- var material = _step7.value;
20518
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
20519
+ var material = _step8.value;
20169
20520
  if (material.opacity !== opacity) {
20170
20521
  material.transparent = opacity < 1;
20171
20522
  material.opacity = opacity;
@@ -20175,19 +20526,19 @@ var Scene3DController = /*#__PURE__*/function () {
20175
20526
  }
20176
20527
  }
20177
20528
  } catch (err) {
20178
- _iterator7.e(err);
20529
+ _iterator8.e(err);
20179
20530
  } finally {
20180
- _iterator7.f();
20531
+ _iterator8.f();
20181
20532
  }
20182
20533
  });
20183
20534
  };
20184
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
20535
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
20185
20536
  _loop3();
20186
20537
  }
20187
20538
  } catch (err) {
20188
- _iterator6.e(err);
20539
+ _iterator7.e(err);
20189
20540
  } finally {
20190
- _iterator6.f();
20541
+ _iterator7.f();
20191
20542
  }
20192
20543
  if (changed) {
20193
20544
  this.map.triggerRepaint();
@@ -20196,12 +20547,12 @@ var Scene3DController = /*#__PURE__*/function () {
20196
20547
  }, {
20197
20548
  key: "loadSpriteAtlas",
20198
20549
  value: function () {
20199
- var _loadSpriteAtlas = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee5(spriteUrl) {
20550
+ var _loadSpriteAtlas = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee6(spriteUrl) {
20200
20551
  var _yield$Promise$all, _yield$Promise$all2, json, img;
20201
- return scene3DController_regenerator().w(function (_context5) {
20202
- while (1) switch (_context5.n) {
20552
+ return scene3DController_regenerator().w(function (_context6) {
20553
+ while (1) switch (_context6.n) {
20203
20554
  case 0:
20204
- _context5.n = 1;
20555
+ _context6.n = 1;
20205
20556
  return Promise.all([fetch("".concat(spriteUrl, ".json")).then(function (r) {
20206
20557
  return r.json();
20207
20558
  }), new Promise(function (resolve, reject) {
@@ -20214,29 +20565,52 @@ var Scene3DController = /*#__PURE__*/function () {
20214
20565
  image.src = "".concat(spriteUrl, ".png");
20215
20566
  })]);
20216
20567
  case 1:
20217
- _yield$Promise$all = _context5.v;
20568
+ _yield$Promise$all = _context6.v;
20218
20569
  _yield$Promise$all2 = scene3DController_slicedToArray(_yield$Promise$all, 2);
20219
20570
  json = _yield$Promise$all2[0];
20220
20571
  img = _yield$Promise$all2[1];
20221
20572
  this.spriteIconMapping = json;
20222
20573
  this.spriteAtlasImage = img;
20223
20574
  case 2:
20224
- return _context5.a(2);
20575
+ return _context6.a(2);
20225
20576
  }
20226
- }, _callee5, this);
20577
+ }, _callee6, this);
20227
20578
  }));
20228
20579
  function loadSpriteAtlas(_x2) {
20229
20580
  return _loadSpriteAtlas.apply(this, arguments);
20230
20581
  }
20231
20582
  return loadSpriteAtlas;
20232
20583
  }()
20584
+ /**
20585
+ * Cache-bounding props spread onto every deck.gl `MVTLayer` so the overlays never keep an
20586
+ * unbounded set of parsed tiles in memory. `maxCacheByteSize` is only included when configured
20587
+ * (deck.gl enforces it only when a tile's byte size is known).
20588
+ */
20589
+ }, {
20590
+ key: "deckTileCacheProps",
20591
+ get: function get() {
20592
+ var _this$deckTileCache = this.deckTileCache,
20593
+ maxCacheSize = _this$deckTileCache.maxCacheSize,
20594
+ maxRequests = _this$deckTileCache.maxRequests,
20595
+ refinementStrategy = _this$deckTileCache.refinementStrategy,
20596
+ maxCacheByteSize = _this$deckTileCache.maxCacheByteSize;
20597
+ var props = {
20598
+ maxCacheSize: maxCacheSize,
20599
+ maxRequests: maxRequests,
20600
+ refinementStrategy: refinementStrategy
20601
+ };
20602
+ if (maxCacheByteSize !== undefined) {
20603
+ props.maxCacheByteSize = maxCacheByteSize;
20604
+ }
20605
+ return props;
20606
+ }
20233
20607
  }, {
20234
20608
  key: "makeElevatedLinesLayer",
20235
20609
  value: function makeElevatedLinesLayer(floorKey, layerConfig) {
20236
20610
  var _layerConfig$binaryDa;
20237
20611
  var deck = this.deckMod;
20238
20612
  if (!deck) return null;
20239
- return new deck.MVTLayer({
20613
+ return new deck.MVTLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, this.deckTileCacheProps), {}, {
20240
20614
  id: "indoor-lines-elevated",
20241
20615
  data: layerConfig.dataUrl,
20242
20616
  binary: (_layerConfig$binaryDa = layerConfig.binaryData) !== null && _layerConfig$binaryDa !== void 0 ? _layerConfig$binaryDa : false,
@@ -20261,7 +20635,7 @@ var Scene3DController = /*#__PURE__*/function () {
20261
20635
  updateTriggers: {
20262
20636
  renderSubLayers: [floorKey]
20263
20637
  }
20264
- });
20638
+ }));
20265
20639
  }
20266
20640
  }, {
20267
20641
  key: "makeLabelLayer",
@@ -20269,11 +20643,11 @@ var Scene3DController = /*#__PURE__*/function () {
20269
20643
  var _layerConfig$binaryDa2,
20270
20644
  _layerConfig$minZoom,
20271
20645
  _layerConfig$maxZoom,
20272
- _this5 = this;
20646
+ _this6 = this;
20273
20647
  var useSdf = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
20274
20648
  var deck = this.deckMod;
20275
20649
  if (!deck) return null;
20276
- return new deck.MVTLayer({
20650
+ return new deck.MVTLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, this.deckTileCacheProps), {}, {
20277
20651
  id: "indoor-labels",
20278
20652
  data: layerConfig.dataUrl,
20279
20653
  binary: (_layerConfig$binaryDa2 = layerConfig.binaryData) !== null && _layerConfig$binaryDa2 !== void 0 ? _layerConfig$binaryDa2 : false,
@@ -20284,7 +20658,7 @@ var Scene3DController = /*#__PURE__*/function () {
20284
20658
  // Use area_name and poi Point features — unique per tile, no duplicates.
20285
20659
  // If a logo-{name} image exists in the sprite, the icon takes priority over the text label.
20286
20660
  var textData = buildLabelData(props.data || [], floorKey, function (imageId) {
20287
- return _this5.map.hasImage(imageId);
20661
+ return _this6.map.hasImage(imageId);
20288
20662
  }, (_layerConfig$defaultH2 = layerConfig.defaultHeight) !== null && _layerConfig$defaultH2 !== void 0 ? _layerConfig$defaultH2 : 5);
20289
20663
  if (!textData.length) return null;
20290
20664
  return new deck.TextLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, props), {}, {
@@ -20315,7 +20689,7 @@ var Scene3DController = /*#__PURE__*/function () {
20315
20689
  updateTriggers: {
20316
20690
  renderSubLayers: [floorKey]
20317
20691
  }
20318
- });
20692
+ }));
20319
20693
  }
20320
20694
  }, {
20321
20695
  key: "makePoiIconLayer",
@@ -20323,10 +20697,10 @@ var Scene3DController = /*#__PURE__*/function () {
20323
20697
  var _layerConfig$binaryDa3,
20324
20698
  _layerConfig$minZoom2,
20325
20699
  _layerConfig$maxZoom2,
20326
- _this6 = this;
20700
+ _this7 = this;
20327
20701
  var deck = this.deckMod;
20328
20702
  if (!deck || !this.spriteIconMapping || !this.spriteAtlasImage) return null;
20329
- return new deck.MVTLayer({
20703
+ return new deck.MVTLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, this.deckTileCacheProps), {}, {
20330
20704
  id: "indoor-poi-icons",
20331
20705
  data: layerConfig.dataUrl,
20332
20706
  binary: (_layerConfig$binaryDa3 = layerConfig.binaryData) !== null && _layerConfig$binaryDa3 !== void 0 ? _layerConfig$binaryDa3 : false,
@@ -20339,8 +20713,8 @@ var Scene3DController = /*#__PURE__*/function () {
20339
20713
  return new deck.IconLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, props), {}, {
20340
20714
  id: "".concat(props.id, "-poi-icons"),
20341
20715
  data: iconData,
20342
- iconAtlas: _this6.spriteAtlasImage,
20343
- iconMapping: _this6.spriteIconMapping,
20716
+ iconAtlas: _this7.spriteAtlasImage,
20717
+ iconMapping: _this7.spriteIconMapping,
20344
20718
  getIcon: function getIcon(d) {
20345
20719
  return d.icon;
20346
20720
  },
@@ -20357,7 +20731,7 @@ var Scene3DController = /*#__PURE__*/function () {
20357
20731
  updateTriggers: {
20358
20732
  renderSubLayers: [floorKey]
20359
20733
  }
20360
- });
20734
+ }));
20361
20735
  }
20362
20736
  }, {
20363
20737
  key: "makeStoreLogoLayer",
@@ -20365,10 +20739,10 @@ var Scene3DController = /*#__PURE__*/function () {
20365
20739
  var _layerConfig$binaryDa4,
20366
20740
  _layerConfig$minZoom3,
20367
20741
  _layerConfig$maxZoom3,
20368
- _this7 = this;
20742
+ _this8 = this;
20369
20743
  var deck = this.deckMod;
20370
20744
  if (!deck || !this.spriteIconMapping || !this.spriteAtlasImage) return null;
20371
- return new deck.MVTLayer({
20745
+ return new deck.MVTLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, this.deckTileCacheProps), {}, {
20372
20746
  id: "indoor-store-logos",
20373
20747
  data: layerConfig.dataUrl,
20374
20748
  binary: (_layerConfig$binaryDa4 = layerConfig.binaryData) !== null && _layerConfig$binaryDa4 !== void 0 ? _layerConfig$binaryDa4 : false,
@@ -20376,13 +20750,13 @@ var Scene3DController = /*#__PURE__*/function () {
20376
20750
  maxZoom: (_layerConfig$maxZoom3 = layerConfig.maxZoom) !== null && _layerConfig$maxZoom3 !== void 0 ? _layerConfig$maxZoom3 : 24,
20377
20751
  renderSubLayers: function renderSubLayers(props) {
20378
20752
  var _layerConfig$defaultH4, _layerConfig$sizeUnit2, _layerConfig$sizeScal2, _layerConfig$billboar2;
20379
- var logoData = buildStoreLogoData(props.data || [], floorKey, _this7.spriteIconMapping, (_layerConfig$defaultH4 = layerConfig.defaultHeight) !== null && _layerConfig$defaultH4 !== void 0 ? _layerConfig$defaultH4 : 5);
20753
+ var logoData = buildStoreLogoData(props.data || [], floorKey, _this8.spriteIconMapping, (_layerConfig$defaultH4 = layerConfig.defaultHeight) !== null && _layerConfig$defaultH4 !== void 0 ? _layerConfig$defaultH4 : 5);
20380
20754
  if (!logoData.length) return null;
20381
20755
  return new deck.IconLayer(scene3DController_objectSpread(scene3DController_objectSpread({}, props), {}, {
20382
20756
  id: "".concat(props.id, "-store-logos"),
20383
20757
  data: logoData,
20384
- iconAtlas: _this7.spriteAtlasImage,
20385
- iconMapping: _this7.spriteIconMapping,
20758
+ iconAtlas: _this8.spriteAtlasImage,
20759
+ iconMapping: _this8.spriteIconMapping,
20386
20760
  getIcon: function getIcon(d) {
20387
20761
  return d.icon;
20388
20762
  },
@@ -20394,7 +20768,7 @@ var Scene3DController = /*#__PURE__*/function () {
20394
20768
  },
20395
20769
  getSize: function getSize(d) {
20396
20770
  var _layerConfig$logoScal;
20397
- return computeStoreLogoSize(_this7.spriteIconMapping, d.icon, (_layerConfig$logoScal = layerConfig.logoScale) !== null && _layerConfig$logoScal !== void 0 ? _layerConfig$logoScal : {});
20771
+ return computeStoreLogoSize(_this8.spriteIconMapping, d.icon, (_layerConfig$logoScal = layerConfig.logoScale) !== null && _layerConfig$logoScal !== void 0 ? _layerConfig$logoScal : {});
20398
20772
  },
20399
20773
  sizeUnits: (_layerConfig$sizeUnit2 = layerConfig.sizeUnits) !== null && _layerConfig$sizeUnit2 !== void 0 ? _layerConfig$sizeUnit2 : "meters",
20400
20774
  sizeScale: (_layerConfig$sizeScal2 = layerConfig.sizeScale) !== null && _layerConfig$sizeScal2 !== void 0 ? _layerConfig$sizeScal2 : 1,
@@ -20405,7 +20779,7 @@ var Scene3DController = /*#__PURE__*/function () {
20405
20779
  updateTriggers: {
20406
20780
  renderSubLayers: [floorKey]
20407
20781
  }
20408
- });
20782
+ }));
20409
20783
  }
20410
20784
  }, {
20411
20785
  key: "updateDeckOverlay",
@@ -20439,19 +20813,19 @@ var Scene3DController = /*#__PURE__*/function () {
20439
20813
  key: "hideLayers",
20440
20814
  value: function hideLayers(layersIds) {
20441
20815
  if (!layersIds) return;
20442
- var _iterator8 = scene3DController_createForOfIteratorHelper(layersIds),
20443
- _step8;
20816
+ var _iterator9 = scene3DController_createForOfIteratorHelper(layersIds),
20817
+ _step9;
20444
20818
  try {
20445
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
20446
- var layerId = _step8.value;
20819
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
20820
+ var layerId = _step9.value;
20447
20821
  var layer = this.map.getLayer(layerId);
20448
20822
  if (!layer) continue;
20449
20823
  this.map.setLayoutProperty(layer.id, "visibility", "none");
20450
20824
  }
20451
20825
  } catch (err) {
20452
- _iterator8.e(err);
20826
+ _iterator9.e(err);
20453
20827
  } finally {
20454
- _iterator8.f();
20828
+ _iterator9.f();
20455
20829
  }
20456
20830
  }
20457
20831
  }]);
@@ -20980,7 +21354,11 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
20980
21354
  if (rtlLanguages.includes((_mapConfig$lang = mapConfig.lang) !== null && _mapConfig$lang !== void 0 ? _mapConfig$lang : "")) {
20981
21355
  _this.setRTLSupport();
20982
21356
  }
20983
- _this.repository = new Repository(token, (_mapConfig$lang2 = mapConfig.lang) !== null && _mapConfig$lang2 !== void 0 ? _mapConfig$lang2 : "en", mapConfig.apiUrl, undefined, mapConfig.mapvxRequestContext);
21357
+ _this.repository = new Repository(token, (_mapConfig$lang2 = mapConfig.lang) !== null && _mapConfig$lang2 !== void 0 ? _mapConfig$lang2 : "en", mapConfig.apiUrl, undefined, mapConfig.mapvxRequestContext, {
21358
+ routeApiUrl: mapConfig.routeApiUrl,
21359
+ healthApiUrl: mapConfig.healthApiUrl,
21360
+ legacyApiUrl: mapConfig.legacyApiUrl
21361
+ });
20984
21362
  _this.token = token;
20985
21363
  _this.parentPlaceId = mapConfig.parentPlaceId;
20986
21364
  _this.routeController = new RouteController(_this);
@@ -23524,6 +23902,9 @@ function initializeSDK(token, config) {
23524
23902
  var defaultConfig = {
23525
23903
  lang: "en",
23526
23904
  apiUrl: "https://public-api.mapvx.com",
23905
+ routeApiUrl: "https://api.mapvx.com",
23906
+ healthApiUrl: "https://api.mapvx.com",
23907
+ legacyApiUrl: "https://api.mapvx.com",
23527
23908
  cache: {
23528
23909
  persistent: false
23529
23910
  }
@@ -23560,7 +23941,11 @@ var InternalMapVXSDK = /*#__PURE__*/function (_Loggeable) {
23560
23941
  maxStorageBytes: (_config$cache2 = config.cache) === null || _config$cache2 === void 0 ? void 0 : _config$cache2.maxStorageBytes,
23561
23942
  configs: (_config$cache3 = config.cache) === null || _config$cache3 === void 0 ? void 0 : _config$cache3.configs
23562
23943
  });
23563
- _this.repository = new Repository(token, _this.config.lang, _this.config.apiUrl, cacheManager, _this.config.mapvxRequestContext);
23944
+ _this.repository = new Repository(token, _this.config.lang, _this.config.apiUrl, cacheManager, _this.config.mapvxRequestContext, {
23945
+ routeApiUrl: _this.config.routeApiUrl,
23946
+ healthApiUrl: _this.config.healthApiUrl,
23947
+ legacyApiUrl: _this.config.legacyApiUrl
23948
+ });
23564
23949
  _this.cachePlaces();
23565
23950
  _this.logEvent("initSDK");
23566
23951
  return _this;
@@ -23677,6 +24062,12 @@ var InternalMapVXSDK = /*#__PURE__*/function (_Loggeable) {
23677
24062
  mapConfig.lang = this.config.lang;
23678
24063
  mapConfig.apiUrl = this.config.apiUrl;
23679
24064
  mapConfig.mapvxRequestContext = this.config.mapvxRequestContext;
24065
+ // Routing endpoints go through the map's own Repository, so forward the
24066
+ // (possibly overridden) hosts too — otherwise routes would fall back to
24067
+ // the hardcoded api.mapvx.com even when the SDK was pointed at an edge.
24068
+ mapConfig.routeApiUrl = this.config.routeApiUrl;
24069
+ mapConfig.healthApiUrl = this.config.healthApiUrl;
24070
+ mapConfig.legacyApiUrl = this.config.legacyApiUrl;
23680
24071
  var map = new InternalMapVXMap(mapConfig, container, this.token);
23681
24072
  var originalDestroyMap = map.destroyMap.bind(map);
23682
24073
  map.destroyMap = function () {