@mapvx/web-kit 0.0.0-stage → 1.2.0-develop.8

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 (49) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +166 -2
  3. package/dist/cjs/chunks/DRACOLoader-2PTxnG0B.cjs +2 -0
  4. package/dist/cjs/chunks/GLTFLoader-Duo42nvB.cjs +2 -0
  5. package/dist/cjs/chunks/KTX2Loader-BFPRanfV.cjs +2 -0
  6. package/dist/cjs/chunks/accessibility-B8B49hfP.cjs +2 -0
  7. package/dist/cjs/chunks/back_arrow-xE8LI3kf.cjs +2 -0
  8. package/dist/cjs/chunks/debug-hooks-Dy3VCEnb.cjs +2 -0
  9. package/dist/cjs/chunks/dist-B_S2qDE8.cjs +2 -0
  10. package/dist/cjs/chunks/dist-CVKbkSUX.cjs +2 -0
  11. package/dist/cjs/chunks/dist-Dar77TD5.cjs +2 -0
  12. package/dist/cjs/chunks/expression-CqVJF7Up.cjs +2 -0
  13. package/dist/cjs/chunks/globe-viewport-Cy7fXEJR.cjs +2 -0
  14. package/dist/cjs/chunks/icon-origin-point-Bj3Liz0V.cjs +2 -0
  15. package/dist/cjs/chunks/meshopt_decoder.module-AyBTxqo4.cjs +2 -0
  16. package/dist/cjs/chunks/repeat_icon-DzHJ0GL_.cjs +2 -0
  17. package/dist/cjs/chunks/rolldown-runtime-q6IekecT.cjs +2 -0
  18. package/dist/cjs/chunks/shader-type-decoder-axsbbPco.cjs +2 -0
  19. package/dist/cjs/chunks/styles-Di9G-XQi.cjs +2 -0
  20. package/dist/cjs/chunks/three.module-C0_ADYQD.cjs +2 -0
  21. package/dist/cjs/chunks/walking-D-LNDhrw.cjs +2 -0
  22. package/dist/cjs/chunks/webgl-544JMAWZ.cjs +2 -0
  23. package/dist/cjs/chunks/webgl-device-CDnp7hBC.cjs +2 -0
  24. package/dist/cjs/web-kit.cjs +425 -0
  25. package/dist/es/chunks/DRACOLoader-DhHvfwrR.js +2 -0
  26. package/dist/es/chunks/GLTFLoader-BXqFbldq.js +2 -0
  27. package/dist/es/chunks/KTX2Loader-89MZe3TT.js +2 -0
  28. package/dist/es/chunks/accessibility-C3tJdK9R.js +2 -0
  29. package/dist/es/chunks/back_arrow-KlmFvv0H.js +2 -0
  30. package/dist/es/chunks/debug-hooks-EAre0eyT.js +2 -0
  31. package/dist/es/chunks/dist-B52Hz0u5.js +4 -0
  32. package/dist/es/chunks/dist-CUomzeVc.js +2 -0
  33. package/dist/es/chunks/dist-DfkvAQXI.js +2 -0
  34. package/dist/es/chunks/expression-BArVovP1.js +2 -0
  35. package/dist/es/chunks/globe-viewport-DSFQ1IgJ.js +2 -0
  36. package/dist/es/chunks/icon-origin-point-9EjzWJfO.js +2 -0
  37. package/dist/es/chunks/meshopt_decoder.module-DGlvLcRK.js +2 -0
  38. package/dist/es/chunks/repeat_icon-zufPHs-C.js +2 -0
  39. package/dist/es/chunks/rolldown-runtime-BmU5BQeP.js +2 -0
  40. package/dist/es/chunks/shader-type-decoder-BgpYT6UO.js +2 -0
  41. package/dist/es/chunks/styles-DKa4saDJ.js +2 -0
  42. package/dist/es/chunks/three.module-y4zBSx1c.js +22 -0
  43. package/dist/es/chunks/walking-7Vq5kU_k.js +2 -0
  44. package/dist/es/chunks/webgl-Cl-M1sFB.js +2 -0
  45. package/dist/es/chunks/webgl-device-DF-CxjIt.js +2 -0
  46. package/dist/es/web-kit.mjs +428 -0
  47. package/dist/iife/web-kit.iife.js +425 -0
  48. package/dist/types/index.d.ts +1771 -0
  49. package/package.json +86 -4
@@ -0,0 +1,1771 @@
1
+ import { Configuration } from '@mapvx/web-js';
2
+ import { CSSResult } from 'lit';
3
+ import { InnerFloor } from '@mapvx/web-js';
4
+ import { LatLng } from '@mapvx/web-js';
5
+ import { LitElement } from 'lit';
6
+ import { MapVXSDK } from '@mapvx/web-js';
7
+ import { MVXPlace } from '@mapvx/web-js';
8
+ import { MVXRoute } from '@mapvx/web-js';
9
+ import { PropertyValues } from 'lit';
10
+ import { ReactiveController } from 'lit';
11
+ import { ReactiveControllerHost } from 'lit';
12
+ import { ReactiveElement } from '@lit/reactive-element';
13
+ import { TemplateResult } from 'lit-html';
14
+
15
+ /**
16
+ * LocalStorage keys used by the SDK for caching.
17
+ *
18
+ * @description These keys are used internally by the SDK to persist cached data, one per cache
19
+ * type (web-js 4.3.1 `DEFAULT_CACHE_CONFIGS`). Exposed for advanced use cases like manual cache
20
+ * inspection or cleanup. A unit test writes every type with the SDK's own `CacheManager` and
21
+ * checks that this list clears them all, so a renamed key fails it.
22
+ *
23
+ * @example Checking cache size
24
+ * ```typescript
25
+ * import { CACHE_STORAGE_KEYS } from '@mapvx/web-kit';
26
+ *
27
+ * let totalSize = 0;
28
+ * CACHE_STORAGE_KEYS.forEach(key => {
29
+ * const data = localStorage.getItem(key);
30
+ * if (data) totalSize += data.length;
31
+ * });
32
+ * console.log(`Cache size: ${(totalSize / 1024).toFixed(2)} KB`);
33
+ * ```
34
+ */
35
+ export declare const CACHE_STORAGE_KEYS: readonly ["mvx_places", "mvx_routes", "mvx_accessible_routes", "mvx_configurations", "mvx_categories", "mvx_vehicles", "mvx_stops", "mvx_subplaces", "mvx_available_places", "mvx_styles"];
36
+
37
+ /**
38
+ * Complete cache configuration for the SDK.
39
+ *
40
+ * @description Provides comprehensive control over SDK caching behavior.
41
+ * Use the provided presets ({@link TOTEM_CACHE_CONFIG}, {@link WEB_CACHE_CONFIG})
42
+ * or create custom configurations with {@link mergeCacheConfig}.
43
+ *
44
+ * @example Using a preset directly
45
+ * ```typescript
46
+ * import { TOTEM_CACHE_CONFIG } from '@mapvx/web-kit';
47
+ *
48
+ * // Pass to component
49
+ * element.cacheConfig = TOTEM_CACHE_CONFIG;
50
+ * ```
51
+ *
52
+ * @example Creating a custom configuration
53
+ * ```typescript
54
+ * const myConfig: CacheConfig = {
55
+ * persistent: true,
56
+ * maxStorageBytes: 10 * 1024 * 1024, // 10MB
57
+ * configs: {
58
+ * places: { maxItems: 500, ttlMs: 2 * 60 * 60 * 1000 },
59
+ * subPlaces: { maxItems: 200, ttlMs: 60 * 60 * 1000 },
60
+ * routes: { maxItems: 100, ttlMs: 15 * 60 * 1000 },
61
+ * accessibleRoutes: { maxItems: 100, ttlMs: 15 * 60 * 1000 },
62
+ * configurations: { maxItems: 10, ttlMs: 4 * 60 * 60 * 1000 },
63
+ * categories: { maxItems: 50, ttlMs: 2 * 60 * 60 * 1000 },
64
+ * vehicles: { maxItems: 20, ttlMs: 30 * 60 * 1000 },
65
+ * stops: { maxItems: 50, ttlMs: 30 * 60 * 1000 },
66
+ * },
67
+ * };
68
+ * ```
69
+ */
70
+ export declare interface CacheConfig {
71
+ /**
72
+ * Enables localStorage persistence across browser sessions.
73
+ * When true, cached data survives page reloads and browser restarts, except for the types
74
+ * whose {@link CacheTypeConfig.persist} is `false`.
75
+ * @defaultValue true (in presets)
76
+ */
77
+ persistent: boolean;
78
+ /**
79
+ * Largest localStorage entry each cache type may write, in UTF-16 code units despite the name:
80
+ * the SDK compares it with the length of the serialized string, the unit Chrome counts its quota
81
+ * in (an origin gets about 5.2 M of them). The SDK applies it to every type on its own, not to
82
+ * their sum, so it does not bound the total the components store. A type that outgrows it stops
83
+ * being written and keeps its last stored copy.
84
+ */
85
+ maxStorageBytes: number;
86
+ /**
87
+ * Per-type cache customization.
88
+ * Each key represents a different data category with independent limits. `availablePlaces` and
89
+ * `styles` are optional: left out, the SDK's own defaults apply (persisted, 5 and 20 items).
90
+ */
91
+ configs: {
92
+ /** Location/venue information (parent places, POIs) */
93
+ places: CacheTypeConfig;
94
+ /** The places inside each venue (stores, services), one list per venue and language */
95
+ subPlaces: CacheTypeConfig;
96
+ /** Standard walking route calculations */
97
+ routes: CacheTypeConfig;
98
+ /** Accessibility-optimized routes (wheelchair, reduced mobility) */
99
+ accessibleRoutes: CacheTypeConfig;
100
+ /** Map styling and system configurations */
101
+ configurations: CacheTypeConfig;
102
+ /** Place categorization and taxonomy data */
103
+ categories: CacheTypeConfig;
104
+ /** Transport mode information */
105
+ vehicles: CacheTypeConfig;
106
+ /** Transit station/stop data */
107
+ stops: CacheTypeConfig;
108
+ /** The api key's place list, which the components no longer prefetch */
109
+ availablePlaces?: CacheTypeConfig;
110
+ /** Map styles, one per venue, theme and language (about 50 KB each) */
111
+ styles?: CacheTypeConfig;
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Configuration for a specific cache type.
117
+ *
118
+ * @description Defines storage limits and expiration for a single data category.
119
+ * Each cache type (places, routes, etc.) can have independent configuration.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const routeCacheConfig: CacheTypeConfig = {
124
+ * maxItems: 100, // Store up to 100 routes
125
+ * ttlMs: 15 * 60000 // Expire after 15 minutes
126
+ * };
127
+ * ```
128
+ *
129
+ * @example Keeping a type out of localStorage
130
+ * ```typescript
131
+ * const subPlacesCacheConfig: CacheTypeConfig = {
132
+ * maxItems: 100,
133
+ * ttlMs: 15 * 60000,
134
+ * persist: false // In memory only, even when `persistent` is on
135
+ * };
136
+ * ```
137
+ */
138
+ export declare interface CacheTypeConfig {
139
+ /**
140
+ * Maximum number of entries to store in this cache.
141
+ * When exceeded, oldest entries are evicted (LRU policy).
142
+ */
143
+ maxItems: number;
144
+ /**
145
+ * Time-to-live in milliseconds before expiration.
146
+ * After this time, cached entries are considered stale and will be refetched.
147
+ */
148
+ ttlMs: number;
149
+ /**
150
+ * Whether this type is written to localStorage when {@link CacheConfig.persistent} is on.
151
+ * `false` keeps it in memory only: it is fetched again after a reload, but takes none of the
152
+ * localStorage the host page shares with the components.
153
+ * @defaultValue true
154
+ */
155
+ persist?: boolean;
156
+ }
157
+
158
+ /**
159
+ * Clears all SDK cache entries from localStorage.
160
+ *
161
+ * @description Removes all cached data stored by the SDK. This forces the SDK
162
+ * to fetch fresh data on the next request. Safe to call even if localStorage
163
+ * is unavailable (fails silently).
164
+ *
165
+ * @example Clear cache on user logout
166
+ * ```typescript
167
+ * import { clearAllCacheStorage } from '@mapvx/web-kit';
168
+ *
169
+ * function handleLogout() {
170
+ * clearAllCacheStorage();
171
+ * // ... other cleanup
172
+ * }
173
+ * ```
174
+ *
175
+ * @example Add a "clear cache" button for debugging
176
+ * ```typescript
177
+ * document.getElementById('clearCache')?.addEventListener('click', () => {
178
+ * clearAllCacheStorage();
179
+ * alert('Cache cleared. Refresh the page to see fresh data.');
180
+ * });
181
+ * ```
182
+ */
183
+ export declare function clearAllCacheStorage(): void;
184
+
185
+ /**
186
+ * Manages all application contexts and provides typed update methods.
187
+ * Acts as a single source of truth for state management across components.
188
+ */
189
+ declare class ContextManager {
190
+ private sdkProvider;
191
+ private placeProvider;
192
+ private routeProvider;
193
+ private uiProvider;
194
+ /**
195
+ * Creates a new ContextManager attached to the given host element.
196
+ * Sets up all context providers with their initial values.
197
+ *
198
+ * @param host - The host element that will provide the contexts
199
+ */
200
+ constructor(host: ReactiveElement);
201
+ /**
202
+ * Updates the SDK context with partial values.
203
+ * @param updates - Partial SDK context to merge
204
+ */
205
+ updateSDK(updates: Partial<SDKContextType>): void;
206
+ /**
207
+ * Gets the current SDK context (read-only).
208
+ */
209
+ get sdk(): SDKContextType;
210
+ /**
211
+ * Updates the place context with partial values.
212
+ * @param updates - Partial place context to merge
213
+ */
214
+ updatePlace(updates: Partial<PlaceContextType>): void;
215
+ /**
216
+ * Gets the current place context (read-only).
217
+ */
218
+ get place(): PlaceContextType;
219
+ /**
220
+ * Updates the route context with partial values.
221
+ * @param updates - Partial route context to merge
222
+ */
223
+ updateRoute(updates: Partial<RouteContextType>): void;
224
+ /**
225
+ * Gets the current route context (read-only).
226
+ */
227
+ get route(): RouteContextType;
228
+ /**
229
+ * Updates the UI context with partial values.
230
+ * @param updates - Partial UI context to merge
231
+ */
232
+ updateUI(updates: Partial<UIContextType>): void;
233
+ /**
234
+ * Gets the current UI context (read-only).
235
+ */
236
+ get ui(): UIContextType;
237
+ /**
238
+ * Resets all contexts to their initial states.
239
+ * Useful when navigating away or clearing the current session.
240
+ */
241
+ reset(): void;
242
+ /**
243
+ * Resets navigation-related state while preserving SDK and parent place.
244
+ * Useful when selecting a new destination.
245
+ */
246
+ resetNavigation(): void;
247
+ /**
248
+ * Gets a snapshot of all current context values.
249
+ * Useful for debugging or logging.
250
+ */
251
+ getSnapshot(): {
252
+ sdk: SDKContextType;
253
+ place: PlaceContextType;
254
+ route: RouteContextType;
255
+ ui: UIContextType;
256
+ };
257
+ }
258
+
259
+ /**
260
+ * Default cache configuration (uses WEB preset).
261
+ *
262
+ * @description The default configuration applied when no `cacheConfig` is specified.
263
+ * Uses {@link WEB_CACHE_CONFIG} for broad compatibility with web deployments.
264
+ *
265
+ * @see {@link WEB_CACHE_CONFIG} for detailed settings
266
+ * @see {@link TOTEM_CACHE_CONFIG} for kiosk deployments
267
+ */
268
+ export declare const DEFAULT_CACHE_CONFIG: CacheConfig;
269
+
270
+ export declare const DEFAULT_VECTOR_TILES_BASE_URL = "https://tiles.mapvx.com/tiles";
271
+
272
+ /**
273
+ * The floor a route endpoint is on, for a place that exists on several floors (an elevator, a
274
+ * staircase, an entrance shared by two levels).
275
+ *
276
+ * Without it the route starts, or ends, on the first floor the place is listed on: an elevator
277
+ * picked as the origin of someone standing on level 3 would send them from the basement. Both
278
+ * fields are optional; `floorId` wins over `level` when both are set, as in the SDK's `IdLocation`.
279
+ */
280
+ declare interface EndpointFloor {
281
+ /** Id of the floor (`InnerFloor.key`) the endpoint is on. Takes precedence over {@link level}. */
282
+ floorId?: string;
283
+ /**
284
+ * Level number of that floor (`InnerFloor.level`). A level is not the floor's name: a venue can
285
+ * call level `-2` "Nivel -1", so prefer {@link floorId} when it is known.
286
+ */
287
+ level?: number;
288
+ }
289
+
290
+ /**
291
+ * Where a floor selector is anchored inside its component: an edge, and where along that edge.
292
+ * `map-view-with-modal` and `route-view-totems` take the same values through
293
+ * `floor-selector-position`.
294
+ */
295
+ declare const FLOOR_SELECTOR_POSITIONS: readonly ["top-left", "top-center", "top-right", "center-left", "center-right", "bottom-left", "bottom-center", "bottom-right"];
296
+
297
+ /**
298
+ * Controller for managing floor-related operations.
299
+ */
300
+ declare class FloorController implements ReactiveController {
301
+ private host;
302
+ private contextManager;
303
+ constructor(host: ReactiveControllerHost, contextManager: ContextManager);
304
+ hostConnected(): void;
305
+ hostDisconnected(): void;
306
+ /**
307
+ * Sets the current floor by ID.
308
+ * Does nothing if the floor is already selected or doesn't exist.
309
+ *
310
+ * @param floorId - The floor key to select
311
+ * @returns true if floor was changed, false otherwise
312
+ */
313
+ setFloor(floorId: string): boolean;
314
+ /**
315
+ * Sets the current floor directly.
316
+ *
317
+ * @param floor - The floor object to set as current
318
+ */
319
+ setFloorDirect(floor: InnerFloor): void;
320
+ /**
321
+ * Gets the currently selected floor.
322
+ */
323
+ getCurrentFloor(): InnerFloor | undefined;
324
+ /**
325
+ * Gets all available floors in the parent place.
326
+ */
327
+ getAllFloors(): InnerFloor[];
328
+ /**
329
+ * Gets floors that are part of the current route.
330
+ * Returns all floors if no route is active.
331
+ */
332
+ getEnabledFloors(): InnerFloor[];
333
+ /**
334
+ * Checks if a floor is enabled (part of the current route or no route active).
335
+ *
336
+ * @param floorId - The floor key to check
337
+ */
338
+ isFloorEnabled(floorId: string): boolean;
339
+ /**
340
+ * Gets the index of the current floor in the floors list.
341
+ * Returns -1 if no floor is selected.
342
+ */
343
+ getCurrentFloorIndex(): number;
344
+ /**
345
+ * Moves to the next floor in the list.
346
+ * Returns false if already on the last floor.
347
+ */
348
+ nextFloor(): boolean;
349
+ /**
350
+ * Moves to the previous floor in the list.
351
+ * Returns false if already on the first floor.
352
+ */
353
+ previousFloor(): boolean;
354
+ /**
355
+ * Gets the floor count.
356
+ */
357
+ getFloorCount(): number;
358
+ /**
359
+ * Checks if the current floor is the first floor.
360
+ */
361
+ isFirstFloor(): boolean;
362
+ /**
363
+ * Checks if the current floor is the last floor.
364
+ */
365
+ isLastFloor(): boolean;
366
+ }
367
+
368
+ /** One of {@link FLOOR_SELECTOR_POSITIONS}. */
369
+ export declare type FloorSelectorPosition = (typeof FLOOR_SELECTOR_POSITIONS)[number];
370
+
371
+ /**
372
+ * @description Publishes the rendered width and height of `<floor-selector>` on its container as
373
+ * {@link FLOOR_SELECTOR_INLINE_SIZE_PROPERTY} and {@link FLOOR_SELECTOR_BLOCK_SIZE_PROPERTY}, so the
374
+ * siblings laid out around the bar can keep clear of it.
375
+ *
376
+ * The bar is as wide as the venue's longest floor name, not its CSS `min-width`: the demo venue's
377
+ * vertical bar is 115px against a min-width of 87px. `route-options` reserves this width for the
378
+ * compact card, so the card never slides under the bar in a narrow embed (MFE-492). Custom
379
+ * properties inherit across shadow roots, so setting it on the shared container is enough.
380
+ *
381
+ * Both are the selector's border box, which includes the transparent margin it keeps around the
382
+ * bar for its shadow. Only the one across the bar's edge is published: the width of a vertical bar,
383
+ * the height of a horizontal one. The other is removed, since it measures the layout rather than
384
+ * the bar (a vertical bar's host spans the full height): left in place, a bar moved to another edge
385
+ * would be laid out against it until the next report, rather than against the stylesheets'
386
+ * fallbacks. `floor-selector.css` lays a vertical bar's host out as a column, which is how the
387
+ * orientation is told apart. Tracked with a `ResizeObserver`, so they follow floor names, the layout
388
+ * switch at the container breakpoint, a new `floor-selector-position` and the late definition of
389
+ * the lazily loaded element. A report of 0px (the element before it is defined and laid out) is not
390
+ * published: the stylesheets' fallbacks stand in until the first real size. Neither is a report
391
+ * from a bar without floors, which is a placeholder rather than a bar
392
+ * ({@link FLOOR_SELECTOR_HAS_FLOORS_ATTRIBUTE}).
393
+ *
394
+ * @example
395
+ * ```ts
396
+ * // A class field next to the host's other controllers. It is never read, so `protected` rather
397
+ * // than `private`: `noUnusedLocals` rejects a private field that is only held (TS6133).
398
+ * protected readonly floorSelectorSize = new FloorSelectorSizeController(this, '.route-container')
399
+ * ```
400
+ */
401
+ declare class FloorSelectorSizeController implements ReactiveController {
402
+ private observer;
403
+ private readonly host;
404
+ private readonly containerSelector;
405
+ /**
406
+ * @param host Component that renders `<floor-selector>` in its shadow root.
407
+ * @param containerSelector Selector, in the same shadow root, of the element that receives the
408
+ * custom property: the common ancestor of the bar and the elements that keep clear of it.
409
+ */
410
+ constructor(host: ReactiveControllerHost & HTMLElement, containerSelector: string);
411
+ /** Resumes observing when an already rendered host is attached again. */
412
+ hostConnected(): void;
413
+ /** Starts observing once the first render has put the selector in the shadow root. */
414
+ hostUpdated(): void;
415
+ hostDisconnected(): void;
416
+ private observe;
417
+ }
418
+
419
+ export declare class MapViewWithModal extends LitElement {
420
+ static styles: CSSResult[];
421
+ apiKey: string;
422
+ parentPlaceId: string;
423
+ locale: string;
424
+ /**
425
+ * Enables the experimental 3D scene on the underlying map (forwarded to `<custom-map>`).
426
+ *
427
+ * **Off by default**, unlike `<route-view-totems>`. This view is the one embedded in public web
428
+ * and mobile pages, where the extra WebGL cost is rarely wanted and the 3D overlay has no label
429
+ * collision detection, so 3D is something the page opts into rather than inherits.
430
+ *
431
+ * Turning it on is still not sufficient: the parent place must also be in `scene-3d-place-ids`, and
432
+ * the API key's style must publish `fill-extrusion` layers.
433
+ */
434
+ enable3D: boolean;
435
+ /**
436
+ * Parent places the 3D scene is allowed on, as a comma-separated list of ids (forwarded to
437
+ * `<custom-map>`). Empty (the default) keeps `<custom-map>`'s own validated default set.
438
+ */
439
+ scene3dPlaceIds: string[];
440
+ /**
441
+ * Destination popup style (forwarded to `<custom-map>`): `full` shows logo + name + category,
442
+ * `compact` shows a small icon-only bubble. Defaults to `compact`; pass `full` to opt back in.
443
+ */
444
+ markerVariant: string;
445
+ /** The one place shown on the map, as a destination marker (no route, no origin). */
446
+ placeId: string;
447
+ /** Institution identifier forwarded to MapVX API as the `X-MapVx-Institution-Id` request header. */
448
+ institutionId: string;
449
+ /** Human-readable institution name forwarded to MapVX API as the `X-MapVx-Institution-Name` request header. */
450
+ institutionName: string;
451
+ /** Forwarded to `<custom-map>` and reflected on this host too, for its own compact-mode CSS. */
452
+ compactMode: boolean;
453
+ /** `'small' | 'normal' | 'large'`. Forwarded to `<custom-map>` and reflected on this host too. */
454
+ zoomButtonSize: string;
455
+ /** Maximum zoom cap used when fitting markers in the map-with-modal view. */
456
+ fitMaxZoom: number;
457
+ /** Maximum zoom cap used when focusing a single point in the map-with-modal view. */
458
+ singlePointMaxZoom: number;
459
+ /** Maximum zoom cap used when fitting route geometry in the map-with-modal view. */
460
+ routeFitMaxZoom: number;
461
+ /** Base camera padding for the top edge in the map-with-modal view. */
462
+ cameraPaddingTop: number;
463
+ /** Base camera padding for the right edge in the map-with-modal view. */
464
+ cameraPaddingRight: number;
465
+ /** Base camera padding for the bottom edge in the map-with-modal view. */
466
+ cameraPaddingBottom: number;
467
+ /** Base camera padding for the left edge in the map-with-modal view. */
468
+ cameraPaddingLeft: number;
469
+ /**
470
+ * Overlay padding strategy used by the map-with-modal view: `none`, `auto` or `left-panel-stack`.
471
+ * `free-space` (MFE-523) is for `<route-view-totems>` only: this view does not measure the compact
472
+ * floor selector it renders.
473
+ */
474
+ overlayPaddingMode: string;
475
+ /**
476
+ * Cache configuration for SDK data. Defaults to {@link WEB_CACHE_CONFIG}, the preset built for this
477
+ * component's web/mobile deployment. What is set here is merged **over that preset**, so a partial
478
+ * override changes only the entries it names.
479
+ */
480
+ cacheConfig: CacheConfig | undefined;
481
+ /** {@link cacheConfig} resolved against the web preset it defaults to. */
482
+ private get _effectiveCacheConfig();
483
+ /**
484
+ * Whether the compact floor selector is rendered. **On by default**, so the attribute value is
485
+ * what turns it off: `show-floor-selector="false"` (see {@link defaultTrueBooleanConverter}). The
486
+ * lowercase spelling `showfloorselector` is still accepted as a legacy alias.
487
+ */
488
+ showFloorSelector: boolean;
489
+ /**
490
+ * Corner or edge the floor selector is anchored to, trimmed and lowercased first. The lowercase
491
+ * `floorselectorposition` is still accepted as a legacy alias.
492
+ */
493
+ floorSelectorPosition: string;
494
+ /**
495
+ * Renders the floor selector but blocks floor changes. Off by default; present disables, absent or
496
+ * `floor-selector-disabled="false"` enables (see {@link defaultFalseBooleanConverter}). The
497
+ * lowercase `floorselectordisabled` is still accepted as a legacy alias.
498
+ */
499
+ floorSelectorDisabled: boolean;
500
+ /**
501
+ * Hides the built-in loading indicator so the host can show its own. Reads the attribute's value
502
+ * rather than its presence (see {@link defaultFalseBooleanConverter}), so `hide-loading="false"`
503
+ * keeps the indicator.
504
+ */
505
+ hideLoading: boolean;
506
+ static get observedAttributes(): string[];
507
+ attributeChangedCallback(name: string, oldValue: string | null, value: string | null): void;
508
+ /* Excluded from this release type: contextManager */
509
+ /* Excluded from this release type: placeController */
510
+ /* Excluded from this release type: routeController */
511
+ /* Excluded from this release type: floorController */
512
+ constructor();
513
+ /** The inner `custom-map`. Always rendered (no lazy loading yet; see Task 11's own scope). */
514
+ private _customMap;
515
+ /** The inner `compact-floor-selector`, or `null` while {@link showFloorSelector} is off. */
516
+ private _compactFloorSelector;
517
+ /** Context forwarded to MapVX API as `X-MapVx-*` and `mvx-product` request headers. */
518
+ private mapVxRequestContext;
519
+ private readonly analyticsController;
520
+ /**
521
+ * The tiles service worker, run exactly as the reference's own `_initTileServiceWorker()`/
522
+ * `_syncTilePrefetch()` do: registered and asked for the initial tile prefetch from
523
+ * `firstUpdated()`, asked again when `apiKey`/`parentPlaceId` change, the periodic refresh
524
+ * (production builds only) stopped on disconnect. See {@link TileServiceWorkerController}.
525
+ */
526
+ private readonly tileServiceWorker;
527
+ firstUpdated(): void;
528
+ /** Same shape as the reference's own `baseParams()`: no route, so no destination/origin fields. */
529
+ private baseParams;
530
+ private _mapReadyHandler;
531
+ private _cameraInitializedHandler;
532
+ /**
533
+ * The floor id this handler last reported `floor_change` analytics for — this element's own
534
+ * dedupe, independent of `FloorController.setFloor()`'s return value (review round 1, finding 1).
535
+ *
536
+ * An earlier version gated the analytics call on `setFloor()`'s own return (`true` only when it
537
+ * actually changed `uiContext.currentFloor`), reasoning that was a more reliable dedupe than a
538
+ * locally-tracked field. That reasoning held for `<custom-map>`'s own `floorChange` (it never
539
+ * touches `FloorController` itself before dispatching), but broke for
540
+ * `<compact-floor-selector>`'s: `BaseFloorSelector.selectFloor()` (Task 3) already calls
541
+ * `floorController.setFloor(floorKey)` ITSELF before dispatching the event, so by the time this
542
+ * handler ran, the change had already been applied and `setFloor()` correctly (but unhelpfully,
543
+ * for that gate) returned `false` for every single selector click — analytics never fired at all.
544
+ * Verified with a real click on `.floor-option` (not a mocked `setFloor`) in this file's own test
545
+ * suite. Tracking the last-notified id here, instead of trusting the controller's own return value,
546
+ * works the same for both event sources regardless of which of them already consumed the change.
547
+ */
548
+ private _lastNotifiedFloorId;
549
+ /**
550
+ * Turns `<custom-map>`'s/`<compact-floor-selector>`'s `floorChange` event into
551
+ * `FloorController.setFloor()`, closing the loop for a floor change that originated on the map SDK
552
+ * side rather than through the controller (see Task 9's identical wiring and its own doc comment).
553
+ * Safe to call for either source: idempotent on an already-applied floor.
554
+ */
555
+ private _floorChangeHandler;
556
+ updated(changedProperties: PropertyValues): void;
557
+ /** The `placeId` last passed to {@link PlaceController.setOriginAndDestination}, or `undefined`. */
558
+ private _placeIdRequestedFor;
559
+ /**
560
+ * Loads {@link placeId} through `PlaceController` once an SDK is actually available for it. No
561
+ * origin and no route: the single place is loaded as the "destination" so `PlaceController`
562
+ * marks and frames it the same way it would a route's destination.
563
+ *
564
+ * Dedupes on the value it last actually requested, independent of whether `placeId` happened to
565
+ * be in `changedProperties` for the update pass this runs in — see `updated()`'s own call site for
566
+ * why that matters (review round 1, finding 2). Checking the SDK's own readiness itself, rather
567
+ * than only relying on `PlaceController.setOriginAndDestination()`'s internal no-op when the SDK
568
+ * isn't ready yet, matters here specifically: without it, a call made before the SDK exists would
569
+ * still mark `placeId` as "already requested" and this method would never retry it once the SDK
570
+ * actually becomes available.
571
+ */
572
+ private maybeLoadPlace;
573
+ private getFloorSelectorPositionStyles;
574
+ render(): TemplateResult<1>;
575
+ /**
576
+ * Destroys the map and builds a fresh one, keeping venue, place and markers. Not needed on
577
+ * unmount: the map (and its WebGL context) is released automatically when the element leaves the
578
+ * page. A no-op until `<custom-map>` has built one.
579
+ * @example
580
+ * ```ts
581
+ * document.querySelector('map-view-with-modal')?.reloadMap();
582
+ * ```
583
+ */
584
+ reloadMap(): void;
585
+ }
586
+
587
+ declare interface MarkerContext {
588
+ style: MarkerStyle;
589
+ id: string;
590
+ data: MVXPlace | PlacePopupData;
591
+ /**
592
+ * Floor the marker is drawn on, when it is not the place's first floor: a route endpoint on a
593
+ * place that spans several floors (an elevator) is drawn on the floor the route starts or ends.
594
+ */
595
+ floorId?: string;
596
+ }
597
+
598
+ /**
599
+ * Marker visual style.
600
+ *
601
+ * Written as a frozen object + derived union rather than a TS `enum`: this project's tsconfig sets
602
+ * `erasableSyntaxOnly`, which disallows `enum` declarations because they emit non-erasable runtime
603
+ * code. Call sites are unchanged from the reference — `MarkerStyle.youAreHere` still works, and the
604
+ * type `MarkerStyle` still names the union of valid values.
605
+ */
606
+ declare const MarkerStyle: {
607
+ readonly youAreHere: "youAreHere";
608
+ readonly placePopup: "placePopup";
609
+ readonly pin: "pin";
610
+ readonly default: "default";
611
+ };
612
+
613
+ declare type MarkerStyle = (typeof MarkerStyle)[keyof typeof MarkerStyle];
614
+
615
+ /**
616
+ * Merges a partial cache configuration with a base configuration.
617
+ *
618
+ * @description Merges per cache type: the types an override names replace the base's entries
619
+ * whole, and the rest keep the base's. This is the recommended way to customize cache behavior.
620
+ *
621
+ * Because an entry is replaced whole, `persist` included, overriding `subPlaces` over
622
+ * {@link WEB_CACHE_CONFIG} without `persist: false` persists them. The SDK controller relies on
623
+ * it: it merges the totem preset over the web default, and the totem's `subPlaces` must not pick
624
+ * up the web's `persist: false`.
625
+ *
626
+ * @param base - The base configuration to start from (e.g., TOTEM_CACHE_CONFIG)
627
+ * @param overrides - Partial configuration with values to override
628
+ * @returns Complete cache configuration with overrides applied
629
+ *
630
+ * @example Override storage limit only
631
+ * ```typescript
632
+ * const config = mergeCacheConfig(WEB_CACHE_CONFIG, {
633
+ * maxStorageBytes: 8 * 1024 * 1024, // 8MB instead of 5MB
634
+ * });
635
+ * ```
636
+ *
637
+ * @example Override specific cache type
638
+ * ```typescript
639
+ * const config = mergeCacheConfig(TOTEM_CACHE_CONFIG, {
640
+ * configs: {
641
+ * routes: { maxItems: 200, ttlMs: 30 * 60 * 1000 } // Longer route cache
642
+ * }
643
+ * });
644
+ * ```
645
+ *
646
+ * @example Multiple overrides
647
+ * ```typescript
648
+ * const config = mergeCacheConfig(WEB_CACHE_CONFIG, {
649
+ * persistent: false, // Disable persistence
650
+ * maxStorageBytes: 2 * 1024 * 1024, // Reduce to 2MB
651
+ * configs: {
652
+ * places: { maxItems: 50, ttlMs: 10 * 60 * 1000 }, // Smaller, shorter
653
+ * routes: { maxItems: 25, ttlMs: 2 * 60 * 1000 }, // Very short TTL
654
+ * }
655
+ * });
656
+ * ```
657
+ */
658
+ export declare function mergeCacheConfig(base: CacheConfig, overrides?: Partial<CacheConfig>): CacheConfig;
659
+
660
+ /** Name of the event this component dispatches on a map failure. */
661
+ export declare const MVX_ERROR_EVENT = "mvxError";
662
+
663
+ /**
664
+ * Helpers for the MapVX tiles service worker shipped at `/mvx-tiles-sw.js`.
665
+ * Host apps must serve that file at the site root (HTTPS).
666
+ *
667
+ * Ported verbatim from `web-components/src/utils/mvx-tile-sw.ts` — no client-specific behavior to
668
+ * adapt and no Sentry usage to swap out (the Global Constraint against a global `Sentry.init()`
669
+ * does not apply here: this file never reports errors at all, let alone through the global client).
670
+ *
671
+ * Only the registration/messaging helpers below are ported. The reference's actual worker script
672
+ * (`web-components/src/sw/mvx-tiles-sw.js`, copied to `dist/sw/` by its own build step) is a
673
+ * separate ~570-line runtime asset, not a "util", and is out of this task's scope; a host integrator
674
+ * must still supply their own tiles service worker file at the path these helpers register.
675
+ */
676
+ export declare const MVX_TILES_SW_PATH = "/mvx-tiles-sw.js";
677
+
678
+ export declare const MVX_TILES_SW_SCOPE = "/";
679
+
680
+ /** Reasons `<custom-map>` dispatches its `mvxError` event for. Narrower than the reference's
681
+ * `MvxErrorCode`: only the map-rebuild case is reported. web-kit's `PlaceController`/
682
+ * `RouteController` do not produce the reference's place/route loading-failure codes (see
683
+ * `docs/parity-checklist.md`'s "Known gaps"). */
684
+ export declare type MvxErrorCode = 'MAP_CONTEXT_LOST';
685
+
686
+ /** Payload of the `mvxError` event, ported (narrowed) from the reference's `models/mvx-error.ts`. */
687
+ export declare interface MvxErrorDetail {
688
+ code: MvxErrorCode;
689
+ message: string;
690
+ parentPlaceId?: string;
691
+ }
692
+
693
+ /**
694
+ * Detail of the `mvxLoadingChange` event, ported verbatim from the reference's
695
+ * `models/loading-events.ts`.
696
+ */
697
+ export declare interface MvxLoadingChangeDetail {
698
+ /** Whether a loading indicator should be on screen right now. */
699
+ loading: boolean;
700
+ /**
701
+ * What is being waited on:
702
+ * - `places` — resolving the origin and destination.
703
+ * - `route` — generating the route between them.
704
+ * - `camera` — the map is settling on what it has to show: framing the pair or the route it just
705
+ * received, building itself on a cold start, or clearing itself for the next destination. The
706
+ * catch-all for "the data is in, the map is not ready to be looked at yet".
707
+ * - `idle` — nothing; emitted with `loading: false` when the load ends.
708
+ */
709
+ phase: 'places' | 'route' | 'camera' | 'idle';
710
+ }
711
+
712
+ export declare interface MvxTilePrefetchOptions {
713
+ apiKey: string;
714
+ placeId: string;
715
+ tilesBaseUrl?: string;
716
+ }
717
+
718
+ /**
719
+ * The floors asked for the two ends of a route. Same shape as the reference's `PairFloors`
720
+ * (`sdk-controller.ts`): `undefined` means "not given", `{}` means "given as no floor".
721
+ */
722
+ declare interface PairFloors {
723
+ originFloor?: EndpointFloor;
724
+ destinationFloor?: EndpointFloor;
725
+ }
726
+
727
+ /**
728
+ * Context type for place-related state.
729
+ */
730
+ declare interface PlaceContextType {
731
+ /** Parent place containing floors and configuration */
732
+ parentPlace?: MVXPlace;
733
+ /** Origin place for navigation */
734
+ origin?: MVXPlace;
735
+ /** Destination place for navigation */
736
+ destination?: MVXPlace;
737
+ /** Origin place ID */
738
+ originId?: string;
739
+ /** Destination place ID */
740
+ destinationId?: string;
741
+ /** General configuration for the parent place */
742
+ generalConfig?: Configuration;
743
+ /**
744
+ * Floor of the origin, for an origin on several floors (an elevator). See {@link EndpointFloor}.
745
+ * Matches the reference's (legacy, flat) `sdkContext` field of the same name. Written by
746
+ * `PlaceController.setOriginAndDestination` with the pair it loads; read by `route-options` (the
747
+ * floor shown next to the origin row) and by `RouteController` (the floor the route starts on).
748
+ */
749
+ originFloor?: EndpointFloor;
750
+ /** Floor of the destination, for a destination on several floors. Same notes as {@link originFloor}. */
751
+ destinationFloor?: EndpointFloor;
752
+ /**
753
+ * Whether the origin/destination places are currently being fetched — the `places` phase of
754
+ * `<custom-map>`'s loading overlay and `mvxLoadingChange`. Matches the reference's (legacy, flat)
755
+ * `sdkContext.isLoading`. Raised by `PlaceController.setOriginAndDestination` before the fetch and
756
+ * cleared once it settles (success or failure); not raised by the parent-place load, as in the
757
+ * reference.
758
+ */
759
+ isLoading?: boolean;
760
+ }
761
+
762
+ /**
763
+ * Controller for managing place-related operations.
764
+ */
765
+ declare class PlaceController implements ReactiveController {
766
+ private host;
767
+ private contextManager;
768
+ private connected;
769
+ /**
770
+ * Request counter, the reference's `placesRequest`. Every pair load bumps it and keeps the value it
771
+ * started with; its answer is written only if the counter has not moved since. Comparing ids is not
772
+ * enough: the same pair can be requested twice, and an older request for another pair can land
773
+ * after a newer one. {@link reset} bumps it too, so a load still in flight when the kiosk is reset
774
+ * for the next visitor never writes its places back.
775
+ */
776
+ private placesRequest;
777
+ /**
778
+ * The venue load in flight, if any. A pair whose floor is asked for by level waits for it before
779
+ * publishing: only the venue's floors say which floor a level is (the reference's `venueLoad`).
780
+ */
781
+ private venueLoad;
782
+ constructor(host: ReactiveControllerHost, contextManager: ContextManager);
783
+ hostConnected(): void;
784
+ hostDisconnected(): void;
785
+ /**
786
+ * Loads the parent place and its configuration.
787
+ *
788
+ * Does not raise `placeContext.isLoading`: the reference's venue load (`prewarm`/`initializeSDK`)
789
+ * does not either — that flag is the `places` loading phase of an origin/destination load only.
790
+ *
791
+ * The venue can land after the pair on screen (both start in the same update on a cold start).
792
+ * When it does, the pair's floor is shown rather than the venue's first floor, and its markers and
793
+ * enabled floors are rebuilt — only the venue's floors can resolve a floor asked for by level. The
794
+ * reference's `publishVenue`.
795
+ *
796
+ * @param parentPlaceId - The ID of the parent place to load
797
+ * @returns The loaded parent place or undefined on error
798
+ */
799
+ loadParentPlace(parentPlaceId: string): Promise<MVXPlace | undefined>;
800
+ /** The body of {@link loadParentPlace}, split out so a pair load can wait on it. */
801
+ private fetchParentPlace;
802
+ /**
803
+ * Sets the origin and destination places.
804
+ * Fetches place details and updates markers.
805
+ *
806
+ * Raises `placeContext.isLoading` before the fetch and clears it once the fetch settles, on
807
+ * success and on failure alike — the `places` phase of `<custom-map>`'s loading overlay and
808
+ * `mvxLoadingChange`. A load superseded by a newer one (or by {@link reset}) writes nothing and
809
+ * leaves the flag to the load that superseded it.
810
+ *
811
+ * @param originId - The ID of the origin place
812
+ * @param destinationId - The ID of the destination place
813
+ * @param floors - Floors asked for each end (`origin-floor-id`/`origin-level` and their destination
814
+ * twins). An end left `undefined` keeps the floor already set when it is the same place, and
815
+ * drops it otherwise — the reference's `floorsFor`; `{}` says "no floor".
816
+ * @returns `true` once this load's places are in context and every requested place resolved;
817
+ * `false` when it was superseded, could not run (disconnected, no SDK), or a place failed to
818
+ * load. A route asked for alongside this load uses it as its gate (see
819
+ * `RouteController.generateRoute`'s `after` option).
820
+ */
821
+ setOriginAndDestination(originId: string, destinationId: string, floors?: PairFloors): Promise<boolean>;
822
+ /**
823
+ * Writes the places a load resolved, with their markers, the floor to show and the floors the
824
+ * selector offers, and ends the `places` phase. The reference's `publishPlaces`.
825
+ */
826
+ private publishPlaces;
827
+ /**
828
+ * The floors of a pair about to load: the ones given, else the ones already set. A floor belongs
829
+ * to the place it was given for: kept for a reload of the same place, never carried over to
830
+ * another place, where it would name a floor that place may not even be on. The reference's
831
+ * `floorsFor`.
832
+ */
833
+ private floorsFor;
834
+ /** The venue's floors: the parent place's, else whatever the floor selector was given. */
835
+ private venueFloors;
836
+ /**
837
+ * Creates markers for origin and destination, each on the floor its end of the route is on
838
+ * ({@link endpointFloorId}: the floor asked for when the place is on it, else its first floor).
839
+ */
840
+ private updateMarkers;
841
+ /**
842
+ * Opens the floor the map shows for the pair: the destination's (the floor asked for it, when the
843
+ * place is on it), else the origin's — {@link shownFloorId}, the same rule the reference's
844
+ * `publishPlaces` selects with. A pair with no resolvable floor keeps the floor already shown.
845
+ */
846
+ private updateCurrentFloor;
847
+ /**
848
+ * Updates enabled floors to the floor each end of the route is on. Left alone while a route is on
849
+ * screen: the route enables every floor it passes through, the richer set (the reference's
850
+ * `routeOwnsFloors`). An empty list means "no endpoint floor", which the floor selector reads as
851
+ * "every floor".
852
+ */
853
+ private updateEnabledFloors;
854
+ /**
855
+ * Gets the current destination place.
856
+ */
857
+ getDestination(): MVXPlace | undefined;
858
+ /**
859
+ * Gets the current origin place.
860
+ */
861
+ getOrigin(): MVXPlace | undefined;
862
+ /**
863
+ * Resets the pair for the next visitor: origin, destination, their ids and floors, the markers,
864
+ * the `places` phase, and the view the last pair left — the camera (so `<qr-modal>`, which shows
865
+ * only once the camera is initialized, hides again) and the floor (back to the venue's first). The
866
+ * place half of the reference's `resetData()`; also drops any load still in flight.
867
+ */
868
+ reset(): void;
869
+ }
870
+
871
+ /**
872
+ * Plain-object marker payload, used when the caller renders a popup marker without a full
873
+ * {@link MVXPlace} (e.g. a destination reconstructed from host attributes). Every field is optional
874
+ * because callers outside this package build these objects by hand.
875
+ */
876
+ declare interface PlacePopupData {
877
+ name?: string;
878
+ category?: string;
879
+ logo?: string;
880
+ position?: LatLng;
881
+ floorId?: string;
882
+ }
883
+
884
+ /**
885
+ * Visual variant of the place popup marker.
886
+ *
887
+ * - `compact`: icon only, in a small bubble anchored above the point. Default, since the place name
888
+ * is usually already visible elsewhere in the UI (e.g. the modal) and the big bubble covers the map.
889
+ * - `full`: logo + name + category, the historical look. Opt-in via `marker-variant="full"`.
890
+ */
891
+ export declare type PopupVariant = 'full' | 'compact';
892
+
893
+ /**
894
+ * Registers the tiles service worker and starts bounded prefetch in one call.
895
+ *
896
+ * @description Pairs registration with the wait and the initial load, so a caller does not have to
897
+ * know that messaging a worker before it is active is dropped silently. Everything is best-effort:
898
+ * a worker that cannot be registered yields a `null` registration, and the prefetch calls then do
899
+ * nothing rather than throwing.
900
+ *
901
+ * The periodic refresh re-reads `options` on every tick, so later changes to `apiKey` and
902
+ * `placeId` are picked up. `import.meta.env.PROD` is resolved when this package is built, not when
903
+ * the host is, so in the published bundles the refresh is scheduled whenever
904
+ * `enablePeriodicRefresh` is set — a development build of the host does not turn it off.
905
+ * @param options - Prefetch credentials, plus the worker's path and scope and whether to keep
906
+ * refreshing
907
+ * @returns The registration, and a function that stops the periodic refresh (a no-op when none was
908
+ * scheduled)
909
+ * @example
910
+ * const { registration, stopPeriodicRefresh } = await registerAndTriggerTilePrefetch({
911
+ * apiKey: 'key',
912
+ * placeId: 'place',
913
+ * enablePeriodicRefresh: true,
914
+ * });
915
+ * // call stopPeriodicRefresh() when tearing the view down
916
+ */
917
+ export declare function registerAndTriggerTilePrefetch(options: MvxTilePrefetchOptions & {
918
+ swPath?: string;
919
+ swScope?: string;
920
+ enablePeriodicRefresh?: boolean;
921
+ }): Promise<{
922
+ registration: ServiceWorkerRegistration | null;
923
+ stopPeriodicRefresh: () => void;
924
+ }>;
925
+
926
+ /**
927
+ * Registers the MapVX tiles service worker.
928
+ *
929
+ * @description Best-effort: returns `null` instead of throwing when the browser has no service
930
+ * worker support, when there is no `navigator` at all (SSR), or when `register` rejects because
931
+ * the host does not serve the file, serves it with the wrong MIME type, or blocks it by CSP.
932
+ * @param swPath - Path the worker is served from
933
+ * @param scope - Scope the worker controls
934
+ * @returns The registration, or `null` when the worker could not be registered
935
+ * @example
936
+ * const registration = await registerMvxTileServiceWorker();
937
+ * if (registration) {
938
+ * await waitForServiceWorkerReady(registration);
939
+ * }
940
+ */
941
+ export declare function registerMvxTileServiceWorker(swPath?: string, scope?: string): Promise<ServiceWorkerRegistration | null>;
942
+
943
+ /**
944
+ * Context type for route-related state.
945
+ */
946
+ declare interface RouteContextType {
947
+ /** Current route being displayed/animated */
948
+ route?: MVXRoute;
949
+ /** Whether to prefer accessible routes */
950
+ accessibleRoute: boolean;
951
+ /** Whether route animation is currently playing */
952
+ isAnimating: boolean;
953
+ /** Whether a route is currently being loaded. `RouteController` keeps it in step with {@link loadingRoute}. */
954
+ isLoading: boolean;
955
+ /** Floors that are part of the current route */
956
+ enabledFloors: InnerFloor[];
957
+ /**
958
+ * Whether a route is currently being generated — the `route` phase of `<custom-map>`'s loading
959
+ * overlay and `mvxLoadingChange`, and what `route-options` reads to keep its panel busy. Matches
960
+ * the reference's (legacy, flat) `sdkContext` field of the same name (the places' own loading flag
961
+ * is `placeContext.isLoading`). Raised by `RouteController` for the whole time a route is being
962
+ * asked for — from the moment it is requested alongside a pair's places — and cleared once the
963
+ * request settles, or is dropped by `clearRoute()`.
964
+ */
965
+ loadingRoute?: boolean;
966
+ /**
967
+ * Error message from the last failed route generation attempt, surfaced by `route-options`'s
968
+ * error modal. Matches the reference's (legacy, flat) `sdkContext` field of the same name. No
969
+ * web-kit controller produces it from a real failure yet (see `docs/parity-checklist.md`'s "Known
970
+ * gaps"); `RouteController.reset()` and the `dismissRouteError` handler clear it.
971
+ */
972
+ routeError?: string;
973
+ /** Whether {@link routeError} was caused by a network failure (a different icon is shown for it). */
974
+ isNetworkError?: boolean;
975
+ /** Set when the last route request failed; stays set after the error modal is dismissed. */
976
+ routeFailed?: boolean;
977
+ /** Set when origin or destination failed to load; stays set after the error modal is dismissed. */
978
+ placesFailed?: boolean;
979
+ }
980
+
981
+ /**
982
+ * Controller for managing route-related operations.
983
+ */
984
+ declare class RouteController implements ReactiveController {
985
+ private host;
986
+ private contextManager;
987
+ private connected;
988
+ /**
989
+ * Request counter, the reference's `routeRequest`. Every route request bumps it and keeps the value
990
+ * it started with; its answer is written only if the counter has not moved since — last request
991
+ * wins (a second switch toggle, a new pair). {@link clearRoute} bumps it too: a route dropped
992
+ * because the pair was replaced or the kiosk was reset must not come back when its answer lands.
993
+ */
994
+ private routeRequest;
995
+ constructor(host: ReactiveControllerHost, contextManager: ContextManager);
996
+ hostConnected(): void;
997
+ hostDisconnected(): void;
998
+ /**
999
+ * Loads a route between two places.
1000
+ *
1001
+ * Raises `routeContext.loadingRoute` (and `isLoading`, kept in step with it) before the request
1002
+ * and clears it once the request settles, on every path this request still owns. A request
1003
+ * superseded by a newer one, or by {@link clearRoute}, writes nothing.
1004
+ *
1005
+ * @param originId - The origin place ID
1006
+ * @param destinationId - The destination place ID
1007
+ * @param preferAccessible - Whether to prefer accessible routes
1008
+ * @param floors - Floors of each end; defaults to the ones set for the pair on screen
1009
+ * (`placeContext.originFloor`/`destinationFloor`)
1010
+ * @returns The loaded route or undefined on error
1011
+ */
1012
+ loadRoute(originId: string, destinationId: string, preferAccessible?: boolean, floors?: PairFloors): Promise<MVXRoute | undefined>;
1013
+ /** The body of a route request once its token is taken and the `route` phase is raised. */
1014
+ private requestRoute;
1015
+ /** Raises or ends the `route` phase. `isLoading` is kept in step with `loadingRoute`. */
1016
+ private setLoading;
1017
+ /** The floors set for the pair on screen. */
1018
+ private pairFloors;
1019
+ /** The location of one end of the route, with its floor resolved against what is loaded. */
1020
+ private endpointLocation;
1021
+ /**
1022
+ * Whether the pair a route was asked for is still the one on screen. A context with no pair at
1023
+ * all (a route asked for directly, outside any pair load) accepts any route.
1024
+ */
1025
+ private isPairOnScreen;
1026
+ /**
1027
+ * Extracts unique floors from a route's steps.
1028
+ */
1029
+ private extractFloorsFromRoute;
1030
+ /**
1031
+ * Generates a route using current origin and destination.
1032
+ *
1033
+ * @param options.after - The pair load this route follows (`PlaceController
1034
+ * .setOriginAndDestination`'s promise). The `route` phase is raised at once, so the loading
1035
+ * overlay goes straight from `places` to `route` without ever reading as idle in between; the
1036
+ * request itself goes out only once that load resolves `true`, reading the pair, its floors and
1037
+ * the route type from context then — so a level is sent against the loaded place, and a switch
1038
+ * toggled while the places load is honoured. Resolving `false` (the places failed, or a newer
1039
+ * load superseded it) asks for nothing, the reference's `publishAfter` gate.
1040
+ */
1041
+ generateRoute(options?: {
1042
+ after?: Promise<boolean>;
1043
+ }): Promise<MVXRoute | undefined>;
1044
+ /**
1045
+ * Sets the accessible route preference and reloads route if one exists.
1046
+ *
1047
+ * @param accessible - Whether to prefer accessible routes
1048
+ */
1049
+ setAccessibleRoute(accessible: boolean): Promise<void>;
1050
+ /**
1051
+ * Starts the route animation.
1052
+ */
1053
+ startAnimation(): void;
1054
+ /**
1055
+ * Stops the route animation.
1056
+ */
1057
+ stopAnimation(): void;
1058
+ /**
1059
+ * Repeats the route animation from the beginning.
1060
+ */
1061
+ repeatAnimation(): void;
1062
+ /**
1063
+ * Clears the current route.
1064
+ *
1065
+ * By default also drops any request still in flight (its answer would otherwise land on whatever
1066
+ * pair replaced it) and ends the `route` phase — what the reference's `SDKController` does on every
1067
+ * pair replacement and on `resetData()`.
1068
+ *
1069
+ * @param options.keepInFlight - Only take the route off the screen, leaving a request in flight
1070
+ * (and its `route` phase) alone. For `<custom-map>`'s passive destination-change detection: by
1071
+ * the time it notices the new destination, whatever replaced the pair has already superseded any
1072
+ * stale request, and the one in flight is the new pair's own.
1073
+ */
1074
+ clearRoute(options?: {
1075
+ keepInFlight?: boolean;
1076
+ }): void;
1077
+ /**
1078
+ * Resets everything route-related for the next visitor: the route and any request in flight
1079
+ * ({@link clearRoute}), the floors the route enabled, the last request's error state, and the route
1080
+ * type — back to `defaultAccessibleRoute`, what the host configured (`accessible-route`), not to
1081
+ * whatever the last visitor's switch left. The route half of the reference's `resetData()`.
1082
+ *
1083
+ * @param defaultAccessibleRoute - The host's configured route type
1084
+ */
1085
+ reset(defaultAccessibleRoute: boolean): void;
1086
+ /**
1087
+ * Gets the current route.
1088
+ */
1089
+ getRoute(): MVXRoute | undefined;
1090
+ /**
1091
+ * Checks if a route is currently loaded.
1092
+ */
1093
+ hasRoute(): boolean;
1094
+ /**
1095
+ * Checks if a route is currently being loaded.
1096
+ */
1097
+ isLoading(): boolean;
1098
+ /**
1099
+ * Checks if a route animation is currently playing.
1100
+ */
1101
+ isAnimating(): boolean;
1102
+ /**
1103
+ * Clears the SDK routes cache.
1104
+ */
1105
+ clearCache(): void;
1106
+ }
1107
+
1108
+ /**
1109
+ * Layout of the route panel rendered by `<route-options>`.
1110
+ *
1111
+ * - `full`: back bar, destination name, floor and distance, origin/destination rows, accessible
1112
+ * route switch, "Repetir ruta" and "Generar ruta". Default.
1113
+ * - `compact`: a single card with the destination name, floor and distance, and the accessible
1114
+ * route switch beside them. No back bar, no origin/destination rows, no "Repetir ruta".
1115
+ */
1116
+ export declare type RoutePanelVariant = 'full' | 'compact';
1117
+
1118
+ export declare class RouteViewTotems extends LitElement {
1119
+ static styles: CSSResult[];
1120
+ apiKey: string;
1121
+ parentPlaceId: string;
1122
+ /**
1123
+ * Enables the experimental 3D scene on the underlying map (forwarded to `<custom-map>`).
1124
+ *
1125
+ * **On by default**, because it is not the only condition: the scene also requires the parent
1126
+ * place to be in `scene-3d-place-ids`, so an integration that says nothing gets 3D on the venues
1127
+ * the scene was built for and plain 2D everywhere else.
1128
+ *
1129
+ * Set `enable-3d="false"` to force 2D on a venue that is in the list.
1130
+ */
1131
+ enable3D: boolean;
1132
+ /**
1133
+ * Parent places the 3D scene is allowed on, as a comma-separated list of ids (forwarded to
1134
+ * `<custom-map>`). Empty (the default) keeps `<custom-map>`'s own validated default set.
1135
+ */
1136
+ scene3dPlaceIds: string[];
1137
+ /**
1138
+ * Destination popup style (forwarded to `<custom-map>`): `full` shows logo + name + category,
1139
+ * `compact` shows a small icon-only bubble. Defaults to `compact`; pass `full` to opt back in.
1140
+ */
1141
+ markerVariant: string;
1142
+ locale: string;
1143
+ originId: string;
1144
+ /** Institution identifier forwarded to MapVX API as the `X-MapVx-Institution-Id` request header. */
1145
+ institutionId: string;
1146
+ /** Human-readable institution name forwarded to MapVX API as the `X-MapVx-Institution-Name` request header. */
1147
+ institutionName: string;
1148
+ /** Maximum zoom cap used when fitting origin and destination in the totem view. */
1149
+ fitMaxZoom: number;
1150
+ /** Maximum zoom cap used when focusing a single point in the totem view. */
1151
+ singlePointMaxZoom: number;
1152
+ /** Maximum zoom cap used when fitting route geometry in the totem view. */
1153
+ routeFitMaxZoom: number;
1154
+ /** Base camera padding for the top edge in the totem view. */
1155
+ cameraPaddingTop: number;
1156
+ /** Base camera padding for the right edge in the totem view. */
1157
+ cameraPaddingRight: number;
1158
+ /** Base camera padding for the bottom edge in the totem view. */
1159
+ cameraPaddingBottom: number;
1160
+ /**
1161
+ * Base camera padding for the left edge in the totem view. The overlays (route panel, QR card,
1162
+ * floor bar, zoom buttons) are measured on top of it inside `<custom-map>`, as `overlay-padding-mode` says.
1163
+ */
1164
+ cameraPaddingLeft: number;
1165
+ /**
1166
+ * How the camera keeps the route clear of what is drawn over the map: `free-space` (default)
1167
+ * measures every overlay at each fit and frames the route in the free rect where it is drawn
1168
+ * largest; `left-panel-stack` reserves the panel's width over the full height; `auto` adds top
1169
+ * padding under the panel; `none` uses only `camera-padding-*`. Forwarded to `<custom-map>`.
1170
+ */
1171
+ overlayPaddingMode: string;
1172
+ /** Hides the "Volver" bar rendered on top of the route panel. */
1173
+ hideBack: boolean;
1174
+ /**
1175
+ * Hides the built-in loading indicator so the host can show its own. Reads the attribute's value
1176
+ * rather than its presence (see {@link defaultFalseBooleanConverter}), so `hide-loading="false"`
1177
+ * keeps the indicator.
1178
+ */
1179
+ hideLoading: boolean;
1180
+ /** Hides the "Repetir ruta" button shown next to the destination name once a route has been generated. */
1181
+ hideRepeatRoute: boolean;
1182
+ /** Hides the origin/destination rows of the route panel. Destination name, floor, distance and the accessible-route switch stay visible. */
1183
+ hideRouteInputs: boolean;
1184
+ /** Hides the walking / accessible route switch. Routes are then always walking routes. */
1185
+ hideAccessibilitySwitch: boolean;
1186
+ /**
1187
+ * Asks for the accessible route from the start. The visitor can still turn it off, and "Volver"
1188
+ * goes back to it for the next visitor. Reads the attribute's value (see
1189
+ * {@link defaultFalseBooleanConverter}), so `accessible-route="false"` is the walking route.
1190
+ */
1191
+ accessibleRoute: boolean;
1192
+ /**
1193
+ * Floor the route starts on, for an origin that exists on several floors (an elevator). Takes the
1194
+ * floor's id (`InnerFloor.key`) and takes precedence over `origin-level`.
1195
+ */
1196
+ originFloorId: string;
1197
+ /** Same as `origin-floor-id`, by the floor's level number instead of its id. */
1198
+ originLevel: number | undefined;
1199
+ /**
1200
+ * Floor the route ends on, for a destination on several floors. Unlike `origin-floor-id`, "Volver"
1201
+ * clears this one: it belongs to the last visitor's destination, not to the kiosk.
1202
+ */
1203
+ destinationFloorId: string;
1204
+ /** Same as `destination-floor-id`, by level number. */
1205
+ destinationLevel: number | undefined;
1206
+ /** Hides the "Generar ruta" button, and turns on {@link autoGenerateRoute} with it. */
1207
+ hideGenerateRoute: boolean;
1208
+ /**
1209
+ * Hides the QR card. Reads the attribute's value (see {@link defaultFalseBooleanConverter}), so
1210
+ * `hide-qr="false"` keeps the card.
1211
+ */
1212
+ hideQr: boolean;
1213
+ /** Requests and animates the route as soon as origin and destination are loaded, without waiting for "Generar ruta". */
1214
+ autoGenerateRoute: boolean;
1215
+ /** Whether routes are requested automatically: asked for, or implied by hiding the button. */
1216
+ private get _routesAutomatically();
1217
+ /** Route panel layout: `full` (default) or `compact`. The `hide-*` flags still apply on top. */
1218
+ panelVariant: string;
1219
+ /** Where the floor bar goes; see `<floor-selector>`'s `position` values. */
1220
+ floorSelectorPosition: string | undefined;
1221
+ /**
1222
+ * Cache configuration for SDK data (places, routes, configurations, etc.). Defaults to
1223
+ * {@link TOTEM_CACHE_CONFIG}, the preset built for this component's kiosk deployment. What is set
1224
+ * here is merged **over that preset**, so a partial override changes only the entries it names.
1225
+ */
1226
+ cacheConfig: CacheConfig | undefined;
1227
+ /** {@link cacheConfig} resolved against the kiosk preset it defaults to. */
1228
+ private get _effectiveCacheConfig();
1229
+ /**
1230
+ * The destination place ID. Setting this property (even to the same value) clears the previous
1231
+ * route and reloads the destination — handles a totem screen that re-selects the same destination
1232
+ * (e.g. after being locked).
1233
+ */
1234
+ get destinationId(): string;
1235
+ set destinationId(value: string);
1236
+ private _destinationId;
1237
+ /**
1238
+ * Assigns `destinationId` without the same-value reload above. Used by {@link updateComponent},
1239
+ * whose delegation to `<custom-map>`'s own `updateComponent()` already performed the load — a
1240
+ * second one here would be a pointless, redundant `PlaceController.setOriginAndDestination` call.
1241
+ */
1242
+ private _setDestinationIdSilently;
1243
+ /** Whether `firstUpdated` has run, enabling the destination-reload-on-same-value behavior above. */
1244
+ private _hasInitialized;
1245
+ /**
1246
+ * Set while {@link updateComponent} syncs its own reflected properties after delegating the real
1247
+ * work to `<custom-map>`'s own `updateComponent()`. Without it, those property assignments would
1248
+ * also trigger this element's OWN reactive `willUpdate`/`updated` pair-load and
1249
+ * accessible-route-reload paths below — redundantly reloading the very pair, and redundantly
1250
+ * re-applying the very accessible-route preference, `<custom-map>` just finished applying.
1251
+ *
1252
+ * Invariant (Task 14 integration-pass note): {@link _maybeLoadPair}'s suppressed branch assumes
1253
+ * nothing else can legitimately change the pair's identity while this flag is active — true today
1254
+ * only because `updateComponent()` is this flag's one and only write site; re-verify that branch
1255
+ * before ever flipping this flag from a second call site.
1256
+ */
1257
+ private _suppressPairLoad;
1258
+ /**
1259
+ * The pair's identity as last ACTUALLY requested through {@link _loadPair}, or `undefined` once
1260
+ * the pair is incomplete or has never been requested. Compared against a fresh {@link _pairKey} by
1261
+ * {@link _maybeLoadPair} to decide whether a load is due — independent of whether the id fields
1262
+ * themselves changed in the CURRENT render pass (review round 2, see `_maybeLoadPair`'s own doc
1263
+ * comment for why that independence is the fix).
1264
+ */
1265
+ private _pairRequestedFor;
1266
+ /**
1267
+ * A stable identity for the whole pair, not just `destinationId`: changing any one of these six
1268
+ * fields is a different pair that needs its own load. `undefined` when there is no complete pair
1269
+ * to load yet (no `originId` or no `destinationId`).
1270
+ */
1271
+ private _pairKey;
1272
+ /**
1273
+ * Whether {@link _maybeLoadPair} would start a fresh load for the pair as it stands right now: a
1274
+ * complete pair, not already requested, with an SDK actually available for it. Read-only (no side
1275
+ * effects, unlike `_maybeLoadPair` itself) — used by `willUpdate()` to decide whether an
1276
+ * `accessibleRoute` change should apply straight to context (a load is about to replace the route
1277
+ * anyway) or go through `RouteController.setAccessibleRoute()` (nothing else is about to touch the
1278
+ * route this pass).
1279
+ */
1280
+ private _pairLoadPending;
1281
+ /**
1282
+ * Loads the pair through {@link _loadPair} once it is complete and an SDK is actually available for
1283
+ * it. Checked on EVERY `updated()` pass — NOT gated on `changedProperties` naming the id fields,
1284
+ * unlike the version this replaced (review round 2, the same load-ordering gap Task 10's own review
1285
+ * found in `map-view-with-modal.ts`'s `maybeLoadPlace()`, ported here adapted to a full pair instead
1286
+ * of a single id):
1287
+ *
1288
+ * A pair set in an EARLIER render pass than `apiKey`/`locale`/`parentPlaceId` would otherwise never
1289
+ * load at all. `PlaceController.setOriginAndDestination()` silently no-ops with no SDK yet; by the
1290
+ * time credentials finally arrive in their OWN, later pass, the id fields are no longer "changed"
1291
+ * in THAT pass, so a `changedProperties`-gated check would never fire for them again — the pair
1292
+ * would be stuck forever. Deduping on {@link _pairKey} (the identity actually last requested)
1293
+ * instead of on Lit's own per-pass dirty-checking is what fixes this: a pair set before the SDK
1294
+ * exists is simply never marked "handled" until a pass where the SDK really is ready picks it up.
1295
+ * The same dedupe also means calling this unconditionally never causes a redundant re-fetch of an
1296
+ * already-loaded pair.
1297
+ *
1298
+ * Respects {@link _suppressPairLoad} (set by {@link updateComponent} while it syncs its own
1299
+ * reflected properties after `<custom-map>`'s own `updateComponent()` already did the real load):
1300
+ * while suppressed, this still records the CURRENT key as `_pairRequestedFor` — without that, once
1301
+ * suppression lifts, this method would see the pair `<custom-map>` just loaded as still "pending"
1302
+ * (its key was never recorded) and fire a redundant reload for it, reopening the exact bug the
1303
+ * first review round's `_suppressPairLoad` fix closed. This suppressed branch relies on nothing
1304
+ * else legitimately changing the pair's identity while `_suppressPairLoad` is active — safe only
1305
+ * because that flag has exactly one write site (`updateComponent()`); a second write site would
1306
+ * need this branch re-checked, or it could silently drop a pair load it should have started.
1307
+ *
1308
+ * @returns `true` once it actually started a load this call, so `updated()`'s own
1309
+ * auto-route-toggle branch does not duplicate the request `_loadPair()` already makes for a fresh pair.
1310
+ */
1311
+ private _maybeLoadPair;
1312
+ /**
1313
+ * Loads the current origin/destination pair, and the route too when routes are automatic.
1314
+ *
1315
+ * Clears the previous route first (review round 1, Important finding 2): without this, a route
1316
+ * loaded for the pair being left stays in context — `RouteController` has no other call site that
1317
+ * drops it on a plain property-driven pair change (unlike `<custom-map>`'s own `updateComponent()`,
1318
+ * whose `replacePair()` clears it before loading). Left uncleared, three things went wrong: a
1319
+ * same-value `destinationId` reload (the kiosk "re-select after screen lock" case) kept the stale
1320
+ * route id; an origin-only change in auto mode never asked for a new route because
1321
+ * `_requestRouteIfIdle()` saw the stale one and thought one already existed; and an origin-only
1322
+ * change outside auto mode left the old, now-wrong route drawn on the map. `clearRoute()` also
1323
+ * drops a route request still in flight for the pair being left, so its answer cannot land on this one.
1324
+ *
1325
+ * In auto mode the route is requested together with the places (`generateRoute({ after })`, the
1326
+ * reference's route-alongside-places load): its `route` loading phase is raised before the
1327
+ * `places` one ends, so `mvxLoadingChange` never reports the load as over between the two, and the
1328
+ * request itself goes out once the places are in — with the floors the host asked for resolved
1329
+ * against the loaded places — or not at all if they failed or a newer load superseded them.
1330
+ */
1331
+ private _loadPair;
1332
+ /** Generates the route for the current pair, unless one is already loaded or loading. */
1333
+ private _requestRouteIfIdle;
1334
+ /** Context forwarded to MapVX API as `X-MapVx-*` and `mvx-product` request headers. */
1335
+ private mapVxRequestContext;
1336
+ /* Excluded from this release type: contextManager */
1337
+ /* Excluded from this release type: placeController */
1338
+ /* Excluded from this release type: routeController */
1339
+ /* Excluded from this release type: floorController */
1340
+ private readonly analyticsController;
1341
+ /** The tiles service worker (see this class's doc comment), started in `firstUpdated()`. */
1342
+ private readonly tileServiceWorker;
1343
+ /**
1344
+ * Keeps the compact route card clear of the vertical floor bar, however wide the floor names make
1345
+ * it. Held only so it lives as long as the host: `protected` rather than `private` because
1346
+ * `noUnusedLocals` rejects a private field that is never read (TS6133).
1347
+ */
1348
+ protected readonly floorSelectorSize: FloorSelectorSizeController;
1349
+ constructor();
1350
+ /**
1351
+ * The inner `custom-map`. Always present (this element renders it unconditionally, unlike the
1352
+ * lazily-loaded reference), so a plain cast is enough — no `Partial<>`/optional-chaining dance.
1353
+ */
1354
+ private _customMap;
1355
+ firstUpdated(): void;
1356
+ private sendEvent;
1357
+ private _mapReadyHandler;
1358
+ private _cameraInitializedHandler;
1359
+ willUpdate(changedProperties: PropertyValues): void;
1360
+ updated(changedProperties: PropertyValues): void;
1361
+ render(): TemplateResult<1>;
1362
+ private _floorChangeHandler;
1363
+ private _accessibilityChangeHandler;
1364
+ private _repeatRouteHandler;
1365
+ private _generateRouteHandler;
1366
+ private _backHandler;
1367
+ /**
1368
+ * Turns `<custom-map>`'s `startRouteAnimation`/`routeAnimationFinished` events, and
1369
+ * `<route-options>`'s `repeatRoute` event, into the matching `RouteController` call. This is the
1370
+ * wiring Task 8b's review found missing (its M2): without it, `routeData.isAnimating` stays `true`
1371
+ * forever once a route finishes naturally, which `<custom-map>`'s stall-recovery branch
1372
+ * (`restartStalledRoute`) reads as "stalled" and restarts — an endless replay loop. See
1373
+ * `route-view-totems.test.ts`'s "route animation wiring" suite for the regression test proving a
1374
+ * natural finish does not trigger a restart.
1375
+ */
1376
+ private _startRouteAnimationHandler;
1377
+ private _routeAnimationFinishedHandler;
1378
+ private _dismissRouteErrorHandler;
1379
+ /**
1380
+ * Updates the component's origin/destination/floor/route-type without requiring a "back" event.
1381
+ * Delegates to the inner `<custom-map>`'s own `updateComponent()` (see this class's doc comment for
1382
+ * why the real work lives there), then keeps this element's own reflected properties in step with
1383
+ * what was actually requested.
1384
+ *
1385
+ * @param params - Parameters for the update
1386
+ * @returns Promise resolving to the result of the update operation
1387
+ * @example
1388
+ * ```typescript
1389
+ * const result = await totemView.updateComponent({ destinationId: 'PDP_N1_1036' });
1390
+ * if (result.success) {
1391
+ * console.log('Updated from', result.previousDestinationId, 'to', result.newDestinationId);
1392
+ * }
1393
+ * ```
1394
+ */
1395
+ updateComponent(params: UpdateComponentParams): Promise<UpdateComponentResult>;
1396
+ /**
1397
+ * Clears the map of routes and destination markers, keeping the origin.
1398
+ * @param preserveOrigin - Whether to preserve the origin marker (default: true)
1399
+ */
1400
+ clearMap(preserveOrigin?: boolean): Promise<void>;
1401
+ /**
1402
+ * Destroys the map and builds a fresh one, keeping venue, origin, destination and route.
1403
+ * @example
1404
+ * ```ts
1405
+ * document.querySelector('route-view-totems')?.reloadMap();
1406
+ * ```
1407
+ */
1408
+ reloadMap(): void;
1409
+ /**
1410
+ * Whether a load is in progress: places, route or camera. Independent of whether anything is
1411
+ * painted, so `hide-loading` does not make it `false`.
1412
+ */
1413
+ isLoading(): boolean;
1414
+ connectedCallback(): void;
1415
+ disconnectedCallback(): void;
1416
+ }
1417
+
1418
+ /**
1419
+ * Schedules periodic tile warmup (same message as initial load). Returns a cleanup function.
1420
+ */
1421
+ export declare function schedulePeriodicTileRefresh(registration: ServiceWorkerRegistration | null | undefined, options: MvxTilePrefetchOptions, intervalMs?: number): () => void;
1422
+
1423
+ /**
1424
+ * Context type for SDK core state.
1425
+ */
1426
+ declare interface SDKContextType {
1427
+ /** The initialized SDK instance */
1428
+ sdk?: MapVXSDK;
1429
+ /** Current locale for SDK operations */
1430
+ locale?: string;
1431
+ /** Parent place ID for SDK scope */
1432
+ parentPlaceId?: string;
1433
+ }
1434
+
1435
+ /**
1436
+ * Storage size constants in bytes.
1437
+ *
1438
+ * @description Helper constants for defining storage limits in cache configurations. Used as
1439
+ * {@link CacheConfig.maxStorageBytes}, the SDK reads them as UTF-16 code units, not bytes.
1440
+ *
1441
+ * @example
1442
+ * ```typescript
1443
+ * import { STORAGE_BYTES } from '@mapvx/web-kit';
1444
+ *
1445
+ * const config = {
1446
+ * maxStorageBytes: STORAGE_BYTES.MB_10, // 10MB limit
1447
+ * };
1448
+ * ```
1449
+ */
1450
+ export declare const STORAGE_BYTES: {
1451
+ /** 2 megabytes in bytes (2,097,152) */
1452
+ readonly MB_2: number;
1453
+ /** 5 megabytes in bytes (5,242,880) */
1454
+ readonly MB_5: number;
1455
+ /** 10 megabytes in bytes (10,485,760) */
1456
+ readonly MB_10: number;
1457
+ };
1458
+
1459
+ /**
1460
+ * Time constants in milliseconds for readability.
1461
+ *
1462
+ * @description Helper constants for defining TTL values in cache configurations.
1463
+ *
1464
+ * @example
1465
+ * ```typescript
1466
+ * import { TIME_MS } from '@mapvx/web-kit';
1467
+ *
1468
+ * const ttl = 15 * TIME_MS.MINUTE; // 15 minutes in ms
1469
+ * const longTtl = 2 * TIME_MS.HOUR; // 2 hours in ms
1470
+ * ```
1471
+ */
1472
+ export declare const TIME_MS: {
1473
+ /** One minute in milliseconds (60,000) */
1474
+ readonly MINUTE: number;
1475
+ /** One hour in milliseconds (3,600,000) */
1476
+ readonly HOUR: number;
1477
+ };
1478
+
1479
+ /**
1480
+ * Cache configuration optimized for totem/kiosk deployments.
1481
+ *
1482
+ * @description Designed for dedicated hardware running continuously:
1483
+ * - 2MB storage limit per cache type: a large mall's store lists in two languages fit (1.8 M
1484
+ * measured for Costanera), and no single type can fill the 5 M an origin gets on its own. A
1485
+ * third language would not fit: the SDK then stops writing that type and keeps the copy it has
1486
+ * - Longer TTLs (1-4 hours) to reduce API calls
1487
+ * - Persistent storage enabled for fast cold starts
1488
+ *
1489
+ * Unlike {@link WEB_CACHE_CONFIG}, store lists (`subPlaces`) are persisted too. A kiosk shows one
1490
+ * venue on a page no host shares, so they take a bounded share of storage nothing else competes
1491
+ * for, and a reload does not download the largest response again. The SDK also seeds every store
1492
+ * it downloads into `places`, so on a large venue the stores fill that cache as well: about 1.5 of
1493
+ * the 1.6 MB a Costanera totem stores is store data, kept twice.
1494
+ *
1495
+ * Recommended for: Digital signage, wayfinding kiosks, information totems.
1496
+ *
1497
+ * @example
1498
+ * ```typescript
1499
+ * import { TOTEM_CACHE_CONFIG } from '@mapvx/web-kit';
1500
+ *
1501
+ * // Use directly
1502
+ * <route-view-totems
1503
+ * apiKey="your-api-key"
1504
+ * parentPlaceId="venue-id"
1505
+ * .cacheConfig=${TOTEM_CACHE_CONFIG}
1506
+ * />
1507
+ * ```
1508
+ *
1509
+ * | Cache Type | Max Items | TTL | Persisted |
1510
+ * |------------------|-----------|------------|-----------|
1511
+ * | places | 500 | 2 hours | yes |
1512
+ * | subPlaces | 200 | 1 hour | yes |
1513
+ * | routes | 100 | 15 minutes | yes |
1514
+ * | accessibleRoutes | 100 | 15 minutes | yes |
1515
+ * | configurations | 10 | 4 hours | yes |
1516
+ * | categories | 50 | 2 hours | yes |
1517
+ * | vehicles | 20 | 30 minutes | yes |
1518
+ * | stops | 50 | 30 minutes | yes |
1519
+ * | styles | 20 | 24 hours | yes (SDK default) |
1520
+ */
1521
+ export declare const TOTEM_CACHE_CONFIG: CacheConfig;
1522
+
1523
+ /**
1524
+ * Asks the active service worker to run bounded progressive tile prefetch.
1525
+ */
1526
+ export declare function triggerInitialTileLoad(registration: ServiceWorkerRegistration | null | undefined, options: MvxTilePrefetchOptions): void;
1527
+
1528
+ /**
1529
+ * Context type for UI-related state.
1530
+ */
1531
+ declare interface UIContextType {
1532
+ /** Currently selected floor */
1533
+ currentFloor?: InnerFloor;
1534
+ /** All available floors in the parent place */
1535
+ allFloors: InnerFloor[];
1536
+ /** Markers to display on the map */
1537
+ markers: MarkerContext[];
1538
+ /** Whether the map is fully loaded and ready */
1539
+ mapReady: boolean;
1540
+ /** Whether the camera has been initialized with proper view */
1541
+ cameraInitialized: boolean;
1542
+ }
1543
+
1544
+ /**
1545
+ * Parameters for updating the map component programmatically. Same shape as the reference's
1546
+ * `custom-map.ts` (there, just a type; the reference's actual `updateComponent()` lives on
1547
+ * `route-view-totems.ts` — see the class doc for why it lives here instead in web-kit).
1548
+ */
1549
+ export declare interface UpdateComponentParams {
1550
+ /** New destination ID to navigate to */
1551
+ destinationId?: string;
1552
+ /** New origin ID (optional, defaults to current origin) */
1553
+ originId?: string;
1554
+ /**
1555
+ * Floor the route starts on, for an origin on several floors (an elevator). Takes precedence over
1556
+ * `originLevel`. A new `originId` given without a floor clears the previous one.
1557
+ */
1558
+ originFloorId?: string;
1559
+ /** Level of the floor the route starts on. Prefer `originFloorId`; see `origin-level`. */
1560
+ originLevel?: number;
1561
+ /** Same as `originFloorId`, for the destination. A new `destinationId` without a floor clears it. */
1562
+ destinationFloorId?: string;
1563
+ /** Same as `originLevel`, for the destination. */
1564
+ destinationLevel?: number;
1565
+ /** Asks for the accessible route (elevators over stairs and escalators). */
1566
+ accessibleRoute?: boolean;
1567
+ /** Floor shown in the floor selector (optional). Not where the route starts. */
1568
+ floor?: string;
1569
+ }
1570
+
1571
+ /** Result of an {@link CustomMap.updateComponent} call. Ported from the reference's `route-view-totems.ts`. */
1572
+ export declare interface UpdateComponentResult {
1573
+ success: boolean;
1574
+ error?: string;
1575
+ previousDestinationId?: string;
1576
+ newDestinationId?: string;
1577
+ }
1578
+
1579
+ /**
1580
+ * Waits for whichever service worker registration's scope covers this page.
1581
+ *
1582
+ * @description Kept because it is the behaviour published up to v0.13.0, and dropping it would
1583
+ * break every existing caller — silently for plain-JS importers, where there is no compiler to
1584
+ * complain. It waits for the registration whose scope covers the page, which need not be the tiles
1585
+ * one: with a host worker at a narrower scope it returns while the tiles worker is still
1586
+ * installing, and `triggerInitialTileLoad` then drops the prefetch. Per spec it never rejects, and
1587
+ * it never resolves at all while no registration covers the page.
1588
+ *
1589
+ * This signature comes first on purpose: TypeScript reads the **last** overload for
1590
+ * `Parameters<>` and for inference into generic functions, so putting it last would type the
1591
+ * function as `() => Promise<void>` and push callers towards the form being deprecated.
1592
+ * @deprecated Pass the registration {@link registerMvxTileServiceWorker} returned.
1593
+ * @returns A promise that resolves once some registration covering the page has an active worker
1594
+ * @example
1595
+ * // Prefer this instead:
1596
+ * const registration = await registerMvxTileServiceWorker();
1597
+ * await waitForServiceWorkerReady(registration);
1598
+ */
1599
+ export declare function waitForServiceWorkerReady(): Promise<void>;
1600
+
1601
+ /**
1602
+ * Waits until a tiles service worker registration can receive messages.
1603
+ *
1604
+ * @description Resolves as soon as `registration` has a messageable worker, and immediately when
1605
+ * there is nothing to wait for. `null` and `undefined` both mean that: `registerMvxTileServiceWorker`
1606
+ * returns `null` when it could not register, and `ServiceWorkerContainer.getRegistration` resolves
1607
+ * to `undefined` when nothing matches. Treating either as "wait for the page instead" is how this
1608
+ * used to hang for the life of the page.
1609
+ * @param registration - The registration {@link registerMvxTileServiceWorker} returned, or
1610
+ * `null`/`undefined` when there is none
1611
+ * @returns A promise that resolves once the worker can be messaged, or immediately when there is
1612
+ * nothing to wait for
1613
+ * @example
1614
+ * const registration = await registerMvxTileServiceWorker();
1615
+ * await waitForServiceWorkerReady(registration);
1616
+ * if (registration) {
1617
+ * triggerInitialTileLoad(registration, { apiKey: 'key', placeId: 'place' });
1618
+ * }
1619
+ */
1620
+ export declare function waitForServiceWorkerReady(registration: ServiceWorkerRegistration | null | undefined): Promise<void>;
1621
+
1622
+ /**
1623
+ * Cache configuration optimized for web browser usage.
1624
+ *
1625
+ * @description Designed for standard website visitors:
1626
+ * - 5MB storage limit per cache type
1627
+ * - Shorter TTLs (5-60 minutes) for fresher data
1628
+ * - Persistent storage enabled for return visitors, except for store lists and map styles
1629
+ *
1630
+ * Store lists (`subPlaces`) stay in memory only. They are the largest entry, 0.85 MB for one
1631
+ * language of a large mall, and they pile up with every venue a visitor opens, in the localStorage
1632
+ * the host page shares with the components: twelve venues took 3.3 MB of the 5 MB that Chrome
1633
+ * gives an origin (MFE-272). The stores themselves still reach localStorage one by one, because the
1634
+ * SDK seeds every store it downloads into `places`, which is persisted; `places.maxItems` bounds
1635
+ * them (about 280 KB here).
1636
+ *
1637
+ * Map styles (`styles`) stay in memory too, at about 50 KB per venue: twelve venues stored 561 KB
1638
+ * of them. SDK 4.0.1 kept both lists and styles in memory, in a cache of the map's own.
1639
+ *
1640
+ * Recommended for: Website embeds, mobile web apps, standard deployments.
1641
+ *
1642
+ * @example
1643
+ * ```typescript
1644
+ * import { WEB_CACHE_CONFIG } from '@mapvx/web-kit';
1645
+ *
1646
+ * // Use directly
1647
+ * <map-view-with-modal
1648
+ * apiKey="your-api-key"
1649
+ * parentPlaceId="venue-id"
1650
+ * .cacheConfig=${WEB_CACHE_CONFIG}
1651
+ * />
1652
+ * ```
1653
+ *
1654
+ * | Cache Type | Max Items | TTL | Persisted |
1655
+ * |------------------|-----------|------------|-----------|
1656
+ * | places | 200 | 30 minutes | yes |
1657
+ * | subPlaces | 100 | 15 minutes | no |
1658
+ * | routes | 50 | 5 minutes | yes |
1659
+ * | accessibleRoutes | 50 | 5 minutes | yes |
1660
+ * | configurations | 10 | 1 hour | yes |
1661
+ * | categories | 30 | 1 hour | yes |
1662
+ * | vehicles | 10 | 5 minutes | yes |
1663
+ * | stops | 20 | 5 minutes | yes |
1664
+ * | styles | 20 | 24 hours | no |
1665
+ */
1666
+ export declare const WEB_CACHE_CONFIG: CacheConfig;
1667
+
1668
+ export { }
1669
+
1670
+
1671
+ declare global {
1672
+ interface HTMLElementTagNameMap {
1673
+ 'route-view-totems': RouteViewTotems;
1674
+ }
1675
+ }
1676
+
1677
+
1678
+ declare global {
1679
+ interface HTMLElementTagNameMap {
1680
+ 'map-view-with-modal': MapViewWithModal;
1681
+ }
1682
+ }
1683
+
1684
+
1685
+ declare global {
1686
+ interface HTMLElementEventMap {
1687
+ mvxError: CustomEvent<MvxErrorDetail>;
1688
+ /**
1689
+ * The route started animating onto the map.
1690
+ *
1691
+ * **Also fires on every route repeat**, not only the first one, so treat it as "a route is
1692
+ * being drawn now" rather than "the first load finished". For the end of a load use
1693
+ * {@link HTMLElementEventMap.mvxLoadingChange}.
1694
+ */
1695
+ startRouteAnimation: CustomEvent<void>;
1696
+ /**
1697
+ * The camera finished framing its target.
1698
+ *
1699
+ * **Not the end of the load.** With `auto-generate-route` the route is requested alongside the
1700
+ * two places, so the camera frames them and fires this while the route is still being
1701
+ * generated — seconds before it appears. A host indicator taken down here leaves the visitor
1702
+ * on an empty map waiting for a route with nothing to say so.
1703
+ *
1704
+ * For the end of a load use {@link HTMLElementEventMap.mvxLoadingChange} with
1705
+ * `detail.loading === false`, which is the one signal the built-in overlay itself goes down on.
1706
+ */
1707
+ cameraInitialized: CustomEvent<Record<string, never>>;
1708
+ }
1709
+ }
1710
+
1711
+
1712
+ declare global {
1713
+ interface HTMLElementTagNameMap {
1714
+ 'custom-map': CustomMap;
1715
+ }
1716
+ }
1717
+
1718
+
1719
+ declare global {
1720
+ interface HTMLElementTagNameMap {
1721
+ 'compact-floor-selector': CompactFloorSelector;
1722
+ }
1723
+ }
1724
+
1725
+
1726
+ declare global {
1727
+ interface HTMLElementTagNameMap {
1728
+ 'floor-selector': FloorSelector;
1729
+ }
1730
+ }
1731
+
1732
+
1733
+ declare global {
1734
+ interface HTMLElementTagNameMap {
1735
+ 'route-options': RouteOptions;
1736
+ }
1737
+ }
1738
+
1739
+
1740
+ declare global {
1741
+ interface HTMLElementTagNameMap {
1742
+ 'qr-modal': QRModal;
1743
+ }
1744
+ }
1745
+
1746
+
1747
+ declare global {
1748
+ interface Window {
1749
+ dataLayer: unknown[];
1750
+ gtag: (...args: unknown[]) => void;
1751
+ }
1752
+ }
1753
+
1754
+
1755
+ declare global {
1756
+ interface HTMLElementEventMap {
1757
+ /**
1758
+ * The loading state changed, with the phase that caused it. One event per transition, and
1759
+ * `detail.loading === false` is the end of the load — the same moment the built-in indicator
1760
+ * goes down.
1761
+ */
1762
+ mvxLoadingChange: CustomEvent<MvxLoadingChangeDetail>;
1763
+ }
1764
+ }
1765
+
1766
+
1767
+ declare global {
1768
+ interface HTMLElementTagNameMap {
1769
+ 'map-loading-overlay': MapLoadingOverlay;
1770
+ }
1771
+ }