@expofp/floorplan 3.37.1 → 3.39.0

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 (108) hide show
  1. package/dist/browser/{Button-DeCrQX9Q.js → Button-bdODDPNw.js} +5 -5
  2. package/dist/browser/{CookieConsent-Vl3v-pFj.js → CookieConsent-DNrAwMNi.js} +7 -7
  3. package/dist/browser/{Debug-B5yqbERt.js → Debug-BIX5rNWa.js} +7 -7
  4. package/dist/browser/{DebugTools-DxmLwGuT.js → DebugTools-DWIya7Bp.js} +6 -6
  5. package/dist/browser/{Demo-wMGqDSlp.js → Demo-BjyJN4Lb.js} +9 -9
  6. package/dist/browser/{Free-YWqMdrkf.js → Free-GA2gE4iv.js} +9 -9
  7. package/dist/browser/{GalleryContainer-BSj0IoEg.js → GalleryContainer-BEiygMFs.js} +10 -10
  8. package/dist/browser/{GpsLoader-JZ2o-6yZ.js → GpsLoader-DamQfmE8.js} +10 -10
  9. package/dist/browser/{KioskStore-Bu3BopQw.js → KioskStore-unhS5B1M.js} +9 -7
  10. package/dist/browser/{MaplibreAdapter-Po4JkMfJ.js → MaplibreAdapter-BuFz6p4l.js} +12 -12
  11. package/dist/browser/{ModalContainer-Ca0L20OV.js → ModalContainer-BSOaylBJ.js} +10 -10
  12. package/dist/browser/{PermissionNotice-BL_Z0Gvx.js → PermissionNotice-QoBvgTxq.js} +6 -6
  13. package/dist/browser/{SetKioskMode-BLqj_oCF.js → SetKioskMode-CY8Px_y2.js} +9 -9
  14. package/dist/browser/{ShowKiosk-C_Uo4HvH.js → ShowKiosk-BdIb4cjA.js} +10 -10
  15. package/dist/browser/{ViewerMenuPanel-JVKfblYo.js → ViewerMenuPanel-CfEoeUSF.js} +9 -9
  16. package/dist/browser/{add-debug-secret-listener-DPtDyfek.js → add-debug-secret-listener-DcRkKb16.js} +1 -1
  17. package/dist/browser/{adopt-global-settings-BtOhXTvg.js → adopt-global-settings-BQr2uaJi.js} +9 -9
  18. package/dist/browser/{boolean-editor-DnFqREVk.js → boolean-editor-CO1l1mG2.js} +9 -9
  19. package/dist/browser/{bootIntercom-Bcj28u2s.js → bootIntercom-BF8W6edz.js} +2 -2
  20. package/dist/browser/bundle.json +71 -71
  21. package/dist/browser/{camera-events-7_9NDGJ3.js → camera-events-BM2DRKiu.js} +1 -1
  22. package/dist/browser/{classnames-DDNrf32h.js → classnames-zBYgq48f.js} +2 -2
  23. package/dist/browser/{client-CH-EyMGM.js → client-kHcAahev.js} +5 -5
  24. package/dist/browser/{components-CTpCoGVL.js → components-DAabWR_p.js} +37 -37
  25. package/dist/browser/{debug-context-k4yfSNiw.js → debug-context-DoIsRKLN.js} +7 -7
  26. package/dist/browser/{debug-overlay-DUJGPb45.js → debug-overlay-Cldouqb1.js} +10 -10
  27. package/dist/browser/{debug-ui-BHuX-GB3.js → debug-ui-BMvP-d9w.js} +6 -6
  28. package/dist/browser/{dimming-t9q0FUi7.js → dimming-Big09HME.js} +187 -175
  29. package/dist/browser/{dist-D53VlFs3.js → dist-BqsLBiXn.js} +6 -6
  30. package/dist/browser/{dist-BN7aRMYg.js → dist-DUkTj21m.js} +3 -3
  31. package/dist/browser/{dist-BH6ccsWu.js → dist-Da-W2paU.js} +5 -5
  32. package/dist/browser/{efp-debug-init-FVwthqE9.js → efp-debug-init-Br53YSLH.js} +3 -3
  33. package/dist/browser/{enum-editor-D2DqVE0U.js → enum-editor-BF0tTe81.js} +4 -4
  34. package/dist/browser/{es5-CTnRrfUa.js → es5-DLwEWAqt.js} +2 -2
  35. package/dist/browser/{event-head-NyeKC_a-.js → event-head-D7Uj7byv.js} +1 -1
  36. package/dist/browser/{event-not-found-DIhmLXDl.js → event-not-found-CANnIJrZ.js} +3 -3
  37. package/dist/browser/{exports-BozCwlV6.js → exports-KRrUY3Z1.js} +1 -1
  38. package/dist/browser/{favicon-B1mctnat.js → favicon-Bze7lfTk.js} +1 -1
  39. package/dist/browser/{fetch-retry.umd-D9r-WEgL.js → fetch-retry.umd-D6rdaNIF.js} +2 -2
  40. package/dist/browser/{flex-_eXPuQqS.js → flex-_QSLGHt0.js} +5 -5
  41. package/dist/browser/{floorplan.loader-CfJ8Vn2f.js → floorplan.loader-CvNH6Qc4.js} +10 -10
  42. package/dist/browser/{floorplan.ready-Di_3P8e2.js → floorplan.ready-HPblmUxV.js} +15 -15
  43. package/dist/browser/{fuse-v2l3pyGv.js → fuse-9EzVEd12.js} +2 -2
  44. package/dist/browser/{i18n-B5-zCiY_.js → i18n-DsPOygSI.js} +7 -6
  45. package/dist/browser/index.js +16 -16
  46. package/dist/browser/{index.module-6qVgT1Ws.js → index.module-BnkEmOmv.js} +4 -4
  47. package/dist/browser/{integrateKiosk-D8Xc_hN4.js → integrateKiosk-DlUC2piv.js} +4 -4
  48. package/dist/browser/{is-own-domain-CRNYcXgm.js → is-own-domain-Db2dg_LE.js} +1 -1
  49. package/dist/browser/{is-webview-BKVg7rVR.js → is-webview-CKWDUFMW.js} +1 -1
  50. package/dist/browser/{jsx-runtime-CvluGX9h.js → jsx-runtime-BxX9Q763.js} +2 -2
  51. package/dist/browser/{kiosk-record-CkIaRaVs.js → kiosk-record-BDPzvIrP.js} +1 -1
  52. package/dist/browser/{lib-F5uPIjZZ.js → lib-BuATiAoM.js} +3 -3
  53. package/dist/browser/{loadImage-CWZCt1gk.js → loadImage-BvSruq1k.js} +4 -4
  54. package/dist/browser/{logDeviceInfo-KsHijAvU.js → logDeviceInfo-Cu3Vy9La.js} +9 -9
  55. package/dist/browser/{mobx-DyNIDReK.js → mobx-C6ZnBiyR.js} +4 -4
  56. package/dist/browser/{optional-boolean-editor-BuEtS0T3.js → optional-boolean-editor-D4LT9fSN.js} +3 -3
  57. package/dist/browser/{optional-enum-editor-CdbmJsGL.js → optional-enum-editor-Cxn6rM4t.js} +4 -4
  58. package/dist/browser/{optional-string-editor-D2PcwHgW.js → optional-string-editor-CTUOwnCm.js} +4 -4
  59. package/dist/browser/{particles.min-E6qiqBch.js → particles.min-dLuHpqHJ.js} +2 -2
  60. package/dist/browser/{react-Dn5R1i44.js → react-8e9Lx7_L.js} +2 -2
  61. package/dist/browser/{react-dom-CNKhUGTA.js → react-dom-DVm8zF94.js} +3 -3
  62. package/dist/browser/{rolldown-runtime-Rtc3Wq1o.js → rolldown-runtime-CgLujcqt.js} +1 -1
  63. package/dist/browser/{scheduler-B63wNQ6O.js → scheduler-BviKXQIp.js} +2 -2
  64. package/dist/browser/{select-FAFZn4pa.js → select-DqlFRrKq.js} +10 -10
  65. package/dist/browser/{settings-DxbVRDcz.js → settings-DYHQnr2h.js} +2 -2
  66. package/dist/browser/{settings-item-BvQw5Dzf.js → settings-item-C7c9AnkF.js} +6 -6
  67. package/dist/browser/{store-BWnOp-D9.js → store-CrXKrvfj.js} +5821 -5262
  68. package/dist/browser/{string-editor-unUjOHfG.js → string-editor-DziXqaWJ.js} +4 -4
  69. package/dist/browser/{text-field-YhZt_uCf.js → text-field-Dh7Ux2mR.js} +5 -5
  70. package/dist/browser/{theme-ycAtwSHv.js → theme-me78t_PC.js} +8 -8
  71. package/dist/browser/{ui-BDt3wLKg.js → ui-yPy4UNxE.js} +8 -8
  72. package/dist/browser/{useRenderTarget-dNFV5pof.js → useRenderTarget-Cm9xuQ0_.js} +4 -4
  73. package/dist/browser/{viewport-DE8ekt3O.js → viewport-rjH0BXVJ.js} +2 -2
  74. package/dist/esm/components/Kiosk/KioskStore.js +1 -1
  75. package/dist/esm/components/Map/drawing/config/booth-logos.d.ts +38 -0
  76. package/dist/esm/components/Map/drawing/config/booth-logos.js +1 -0
  77. package/dist/esm/components/Map/drawing/config/config-all.js +1 -1
  78. package/dist/esm/components/Map/drawing/config/config-booth-labels-special.js +2 -2
  79. package/dist/esm/components/Map/drawing/config/config-booth-labels.js +1 -1
  80. package/dist/esm/components/Map/drawing/config/config-booths.js +1 -1
  81. package/dist/esm/components/Map/drawing/config/config-load-layer.js +1 -1
  82. package/dist/esm/components/Map/drawing/config/config-markers.d.ts +2 -2
  83. package/dist/esm/components/Map/drawing/config/config-markers.js +1 -1
  84. package/dist/esm/components/Map/drawing/config/layer-models.d.ts +2 -2
  85. package/dist/esm/components/Map/drawing/config/loadBoothsImages.d.ts +19 -2
  86. package/dist/esm/components/Map/drawing/config/loadBoothsImages.js +1 -1
  87. package/dist/esm/components/Map/traffic/useManageTraffic.js +1 -1
  88. package/dist/esm/engine/canvases.d.ts +1 -1
  89. package/dist/esm/engine/canvases.js +1 -1
  90. package/dist/esm/engine/defs.d.ts +7 -3
  91. package/dist/esm/engine/update-def.js +1 -1
  92. package/dist/esm/store/ExhibitorStore.d.ts +2 -0
  93. package/dist/esm/types.d.ts +1 -1
  94. package/dist/esm/utils/blob-image-size.d.ts +27 -0
  95. package/dist/esm/utils/blob-image-size.js +1 -0
  96. package/dist/esm/utils/loadBlob.d.ts +16 -0
  97. package/dist/esm/utils/loadBlob.js +1 -0
  98. package/dist/esm/utils/loadImagesInBatches.d.ts +16 -1
  99. package/dist/esm/utils/loadImagesInBatches.js +1 -1
  100. package/dist/esm/utils/loadLayerImages.d.ts +46 -0
  101. package/dist/esm/utils/loadLayerImages.js +1 -0
  102. package/dist/esm/utils/rasterize-svg.d.ts +32 -0
  103. package/dist/esm/utils/rasterize-svg.js +1 -0
  104. package/dist/esm/wayfinding/createWayfinding.js +1 -1
  105. package/dist/esm/wayfinding/handlers/kioskHandler.js +1 -1
  106. package/package.json +10 -10
  107. package/dist/esm/utils/imageloader.d.ts +0 -15
  108. package/dist/esm/utils/imageloader.js +0 -1
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Measures an image's intrinsic size without keeping its pixels.
3
+ *
4
+ * Floorplan needs one number from a logo's pixels: the aspect ratio, to fit the logo inside a
5
+ * booth. `createImageBitmap` gives that number at low cost. The browser decodes the image on its
6
+ * own thread. Then it resolves a promise. The main thread pays only for the call and for the
7
+ * promise resolution, not for the decode itself. This is the difference between
8
+ * `createImageBitmap` and an `<img>` element, which decodes on the same thread as the page.
9
+ *
10
+ * The function closes the bitmap right after it reads the size. A caller can start as many calls
11
+ * as it wants. At any instant, only a few bitmaps exist in memory: the ones the browser's decoder
12
+ * already finished but did not yet hand back. The whole batch of logos never sits in memory
13
+ * together. One cost remains, and this cost is accepted: each logo gets decoded twice, once here
14
+ * and once in the atlas worker. This happens because a Blob cannot report its own size, and the
15
+ * renderer does not report one back either.
16
+ *
17
+ * This function has no `<img>` fallback. `createImageBitmap` works on every build target that
18
+ * this SDK supports. The only targets that lack `createImageBitmap` are targets where the whole
19
+ * SDK already fails to run.
20
+ * @param blob - The image bytes.
21
+ * @returns The size, or `null` if the bytes cannot be decoded.
22
+ */
23
+ export declare function blobImageSize(blob: Blob): Promise<{
24
+ width: number;
25
+ height: number;
26
+ } | null>;
27
+ //# sourceMappingURL=blob-image-size.d.ts.map
@@ -0,0 +1 @@
1
+ export async function blobImageSize(e){try{const t=await createImageBitmap(e),i={width:t.width,height:t.height};return t.close(),i}catch{return null}}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Fetches an image as a `Blob`, the form the renderer packs from.
3
+ *
4
+ * This function returns a `Blob`, not an `HTMLImageElement`, because decoding an image element
5
+ * blocks the main thread. At a thousand booth logos, the `HTMLImageElement` route stalls the
6
+ * thread for two seconds, and the `Blob` route does not stall it at all. A `Blob` is also a handle
7
+ * to bytes that do not change. A worker that receives one gets the handle, not a copy of the bytes.
8
+ *
9
+ * This function never throws. `normalize-legacy-data.ts` mints the `__small` and `__tiny` logo
10
+ * variants by adding a suffix to the full URL. It never confirms that the variant file exists. A
11
+ * 404 here is routine. When it happens, the caller retries with its fallback URL.
12
+ * @param src - The image URL.
13
+ * @returns The bytes, or `null` when the fetch fails.
14
+ */
15
+ export declare function loadBlob(src: string): Promise<Blob | null>;
16
+ //# sourceMappingURL=loadBlob.d.ts.map
@@ -0,0 +1 @@
1
+ export async function loadBlob(o){try{const t=await fetch(o,{mode:"cors",credentials:"omit"});if(!t.ok)return null;const n=await t.blob();return n.type.startsWith("image/")?n:null}catch{return null}}
@@ -2,6 +2,21 @@ export interface ImageUrls {
2
2
  preferred?: string;
3
3
  fallback: string;
4
4
  }
5
- export declare function loadImagesInBatches(urls: ImageUrls[], batchSize?: number, delay?: number): Promise<HTMLImageElement[]>;
6
5
  export declare function loadImagesInBatchesById(logosUrls: Map<number, ImageUrls>, batchSize?: number, delay?: number): Promise<Map<number, HTMLImageElement>>;
6
+ /**
7
+ * Loads a map of ids to image bytes. One URL loads at most once per call, no matter how many ids
8
+ * share it.
9
+ *
10
+ * This dedup is not an optimization. It is a correctness requirement. The renderer dedupes image
11
+ * sources by object identity, so two booths that share a logo must get the very same `Blob`
12
+ * object. If they do not, the logo downloads twice, packs twice, and draws from two atlas
13
+ * regions. The cache lives only for the length of this call, because the defs keep their own
14
+ * Blobs afterward. A cache that outlived the call would give every logo on the plan a second
15
+ * place to stay in memory.
16
+ * @param logosUrls - The URLs to load, keyed by booth id.
17
+ * @param batchSize - How many URLs to load at once.
18
+ * @param delay - Milliseconds to wait between batches.
19
+ * @returns The bytes, keyed by booth id. An id is absent when its logo failed to load.
20
+ */
21
+ export declare function loadBlobsInBatchesById(logosUrls: Map<number, ImageUrls>, batchSize?: number, delay?: number): Promise<Map<number, Blob>>;
7
22
  //# sourceMappingURL=loadImagesInBatches.d.ts.map
@@ -1 +1 @@
1
- import d from"./is-mobile";import h from"./is-webview";import{loadImage as l}from"./loadImage";const u=d||h,f=u?8:512,w=u?100:0;async function p(e){return Promise.all(e.map(async([n,{preferred:a,fallback:i}])=>{let t=null;return a&&(t=await l(a)),!t&&i&&(t=await l(i)),[n,t]}))}export async function loadImagesInBatches(e,n=f,a=w){if(!e.length)return[];const i=[];for(let t=0;t<e.length;t+=n){const r=e.slice(t,t+n).map(async({preferred:o,fallback:c})=>{let s=null;return o&&(s=await l(o)),!s&&c&&(s=await l(c)),s}),m=await Promise.all(r);i.push(...m.filter(o=>o!==null)),await new Promise(o=>setTimeout(o,a))}return i}export async function loadImagesInBatchesById(e,n=f,a=w){if(!e.size)return new Map;const i=Array.from(e.entries()),t=new Map;for(let r=0;r<i.length;r+=n){const m=i.slice(r,r+n);(await p(m)).forEach(([c,s])=>{s&&t.set(c,s)}),a&&await new Promise(c=>setTimeout(c,a))}return t}
1
+ import w from"./is-mobile";import y from"./is-webview";import{loadBlob as B}from"./loadBlob";import{loadImage as I}from"./loadImage";const f=w||y,l=f?8:512,d=f?100:0;async function b(e,o){const t=e.preferred?await o(e.preferred):null;return t||(e.fallback?o(e.fallback):null)}async function m(e,o,t,a){if(!e.size)return new Map;const c=Array.from(e.entries()),r=new Map;for(let n=0;n<c.length;n+=t){const p=c.slice(n,n+t),u=await Promise.all(p.map(async([i,s])=>[i,await b(s,o)]));for(const[i,s]of u)s&&r.set(i,s);a&&await new Promise(i=>setTimeout(i,a))}return r}export async function loadImagesInBatchesById(e,o=l,t=d){return m(e,I,o,t)}export async function loadBlobsInBatchesById(e,o=l,t=d){const a=new Map;return m(e,r=>{let n=a.get(r);return n||(n=B(r),a.set(r,n)),n},o,t)}
@@ -0,0 +1,46 @@
1
+ import { type Booth } from '../store/BoothStore';
2
+ /** One `<image>` from a layer's drawing: where it sits, and the pixels to draw there. */
3
+ export interface LayerImage {
4
+ /** The booth this image belongs to, or null for a plain layer graphic. */
5
+ booth: Booth | null;
6
+ /** The image's name, when it has one. */
7
+ name?: string;
8
+ /**
9
+ * The bytes the renderer packs. An SVG image is rasterized and re-encoded as PNG.
10
+ *
11
+ * `createImageBitmap` rejects SVG bytes, so an SVG cannot travel to the atlas worker as it is.
12
+ * It stays a `Blob` all the same: a layer packs in the worker only while every one of its
13
+ * sources is a `Blob`, so one canvas among a layer's graphics would drop the whole layer back
14
+ * onto the main thread.
15
+ */
16
+ source: Blob;
17
+ /** Placement read off the SVG element: top-left, size, and rotation in degrees. */
18
+ bounds: {
19
+ x: number;
20
+ y: number;
21
+ width: number;
22
+ height: number;
23
+ angle: number;
24
+ };
25
+ }
26
+ /**
27
+ * Loads a layer's drawing images as bytes.
28
+ *
29
+ * The placement comes from the SVG element, not from the file. Nothing here needs the image's
30
+ * intrinsic size, so a raster image is never decoded. Avoiding that decode on the main thread is
31
+ * the reason for this change.
32
+ *
33
+ * Most of these hrefs are inline `data:image/webp;base64` URLs, not file references. The
34
+ * converter embeds designer graphics directly in the drawing payload. In a real plan, the first
35
+ * such image is 74KB of WebP inside a 68-unit box. `fetch` serves a `data:` URL from the browser
36
+ * itself, with no network call and no CORS check, and returns a Blob whose `type` matches the one
37
+ * the URL declares. These Blobs reach the renderer exactly as a fetched logo does, and take the
38
+ * same worker path. A drawing can also carry `svg-images/…` file references. `@expofp/config`
39
+ * rebases those to absolute URLs before this function sees them. Both forms go through `loadBlob`
40
+ * unchanged.
41
+ * @param svgImages - The `<image>` elements to load.
42
+ * @returns One entry per image that loaded, in element order. Images that failed to load are
43
+ * dropped.
44
+ */
45
+ export declare function loadLayerImages(svgImages: SVGImageElement[]): Promise<LayerImage[]>;
46
+ //# sourceMappingURL=loadLayerImages.d.ts.map
@@ -0,0 +1 @@
1
+ import{loadBlob as e}from"./loadBlob";import{isSvgBlob as u,svgToPngBlob as i}from"./rasterize-svg";export async function loadLayerImages(a){const t=new Map,r=n=>{let l=t.get(n);return l||(l=s(n),t.set(n,l)),l};return(await Promise.all(a.map(async n=>{const l=n.getAttribute("xlink:href")??n.getAttribute("href"),o=l?await r(l):null;return o?{bounds:{x:n.x.animVal.value,y:n.y.animVal.value,width:n.width.animVal.value,height:n.height.animVal.value,angle:n.transform?.animVal[0]?.angle??0},source:o,booth:null}:null}))).filter(n=>n!==null)}async function s(a){const t=await e(a);return t?u(t)?i(t):t:null}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Whether these bytes are an SVG.
3
+ *
4
+ * The test reads a prefix, not the whole type. A server may send `image/svg+xml; charset=utf-8`,
5
+ * and these images come from customer origins and CDNs, not only from this repository's own
6
+ * server. An exact match lets that form through to `createImageBitmap`, which rejects SVG bytes,
7
+ * and the image then disappears with no sign of why.
8
+ * @param blob - The bytes to test.
9
+ * @returns Whether the bytes are an SVG.
10
+ */
11
+ export declare function isSvgBlob(blob: Blob): boolean;
12
+ /**
13
+ * Draws an SVG into a canvas at its own intrinsic size.
14
+ *
15
+ * `createImageBitmap` refuses SVG bytes (`InvalidStateError`, measured in Chrome 153, even for an
16
+ * SVG with an explicit `width` and `height`), so an SVG cannot travel to the atlas worker as it is.
17
+ * An `<img>` element renders the same bytes. This function does that conversion once, at load time.
18
+ * @param blob - The SVG bytes.
19
+ * @returns The rasterized canvas, or null when the SVG does not render, or declares no size.
20
+ */
21
+ export declare function rasterizeSvg(blob: Blob): Promise<HTMLCanvasElement | null>;
22
+ /**
23
+ * Rasterizes an SVG and hands the pixels back as PNG bytes.
24
+ *
25
+ * The result is a `Blob` and not a canvas on purpose. A layer packs in the atlas worker only while
26
+ * every one of its sources is a `Blob`, so one canvas among a thousand booth logos would drop the
27
+ * whole layer back onto the main thread — the exact layer the worker exists for.
28
+ * @param blob - The SVG bytes.
29
+ * @returns The PNG bytes, or null when the SVG does not render.
30
+ */
31
+ export declare function svgToPngBlob(blob: Blob): Promise<Blob | null>;
32
+ //# sourceMappingURL=rasterize-svg.d.ts.map
@@ -0,0 +1 @@
1
+ import{loadImage as o}from"./loadImage";export function isSvgBlob(n){return n.type.startsWith("image/svg+xml")}export async function rasterizeSvg(n){const t=URL.createObjectURL(n);try{const e=await o(t);if(!e?.naturalWidth||!e.naturalHeight)return null;const a=document.createElement("canvas");a.width=e.naturalWidth,a.height=e.naturalHeight;const r=a.getContext("2d");return r?(r.drawImage(e,0,0),a):null}finally{URL.revokeObjectURL(t)}}export async function svgToPngBlob(n){const t=await rasterizeSvg(n);return t?i(t):null}function i(n){return new Promise(t=>{try{n.toBlob(e=>t(e),"image/png")}catch{t(null)}})}
@@ -1 +1 @@
1
- import{update as d}from"@expofp/renderer";import{createWayfinding as g,resolveWayfindingLayers as S}from"@expofp/wayfinding";import{fpGeo as R}from"../data/fpGeo";import{attachCardinalSnap as v}from"../engine/utils/rotation";import{createCanvasIconProvider as h,createFloorContext as x,createGraphDataSource as k}from"./adapters";import{bindMobxReactions as C}from"./bindMobxReactions";import{createKioskHandler as P}from"./handlers/kioskHandler";import{createYahHandler as W}from"./handlers/yahHandler";let u=null;export function isWayfindingReady(){return u!==null}function b(){if(!u)throw new Error("Wayfinding is not initialized \u2014 call createWayfinding() first.");return u}export function buildRoute(e,n,r){return b().wayfinding.buildRoute(e,n,r)}export function createWayfinding(e){const{scene:n,store:r,canvas:o}=e,c=S(n.rootLayer),{wayfinding:s,dispose:i}=w(r,c,{attachCardinalSnap:v,update:d}),t=c.icons;return t.onClick=f=>M(s,f),t.onPointerMove=f=>y(s,o,f),t.onPointerOut=()=>y(s,o),d(t),()=>{t.onClick=void 0,t.onPointerMove=void 0,t.onPointerOut=void 0,o.current&&(o.current.style.cursor=""),d(t),i()}}function w(e,n,r){const o=k(),c=h({iconMap:e.fp.icons,pixelRatio:devicePixelRatio}),s=x(e.layerStore,e.routeStore),i=g({dataSource:o,renderer:r,iconProvider:c,floorContext:s,layers:n,gpsConfig:R?.properties?.config,onTransitionClick:a=>{a.role==="exit"&&e.layerStore.updateVisibility(a.targetLayer,!0)},onRouteUpdate:(a,p)=>{e.routeStore.updateRoute([...a]),p.isEmpty()||(e.uiState.moveToRect=p)},onRouteDistance:a=>e.routeStore.updateRouteDistance(a)}),t=P({wayfinding:i,kioskIconMap:e.fp.icons}),f=W({wayfinding:i,iconMap:e.fp.icons,pixelRatio:devicePixelRatio,floorContext:s}),m=C({wayfinding:i,kioskHandler:t,yahHandler:f,stores:{routeStore:e.routeStore,uiState:e.uiState,layerStore:e.layerStore}});e.routeStore.showAccessible=o.getLines().some(a=>a.unaccessible);const l={wayfinding:i};return u=l,i.flush(),{wayfinding:i,dispose(){H(l)&&(u=null,e.routeStore.showAccessible=!1),m(),i.destroy()}}}function H(e){return u===e}function M(e,n){e.handleClick([n.def])&&n.stopPropagation()}function y(e,n,r){const o=n.current;if(!o)return;const c=r?e.handleHover([r.def]):!1;o.style.cursor=c?"pointer":""}
1
+ import{update as d}from"@expofp/renderer";import{createWayfinding as S,resolveWayfindingLayers as g}from"@expofp/wayfinding";import{fpGeo as R}from"../data/fpGeo";import{attachCardinalSnap as v}from"../engine/utils/rotation";import{createCanvasIconProvider as h,createFloorContext as x,createGraphDataSource as k}from"./adapters";import{bindMobxReactions as C}from"./bindMobxReactions";import{createKioskHandler as P}from"./handlers/kioskHandler";import{createYahHandler as W}from"./handlers/yahHandler";let u=null;export function isWayfindingReady(){return u!==null}function w(){if(!u)throw new Error("Wayfinding is not initialized \u2014 call createWayfinding() first.");return u}export function buildRoute(e,n,r){return w().wayfinding.buildRoute(e,n,r)}export function createWayfinding(e){const{scene:n,store:r,canvas:o}=e,c=g(n.rootLayer),{wayfinding:s,dispose:t}=b(r,c,{attachCardinalSnap:v,update:d}),i=c.icons;return i.onClick=f=>M(s,f),i.onPointerMove=f=>y(s,o,f),i.onPointerOut=()=>y(s,o),d(i),()=>{i.onClick=void 0,i.onPointerMove=void 0,i.onPointerOut=void 0,o.current&&(o.current.style.cursor=""),d(i),t()}}function b(e,n,r){const o=k(),c=h({iconMap:e.fp.icons,pixelRatio:devicePixelRatio}),s=x(e.layerStore,e.routeStore),t=S({dataSource:o,renderer:r,iconProvider:c,floorContext:s,layers:n,gpsConfig:R?.properties?.config,screenSpaceIcons:e.uiState.is3DView,onTransitionClick:a=>{a.role==="exit"&&e.layerStore.updateVisibility(a.targetLayer,!0)},onRouteUpdate:(a,p)=>{e.routeStore.updateRoute([...a]),p.isEmpty()||(e.uiState.moveToRect=p)},onRouteDistance:a=>e.routeStore.updateRouteDistance(a)}),i=P({wayfinding:t,kioskIconMap:e.fp.icons}),f=W({wayfinding:t,iconMap:e.fp.icons,pixelRatio:devicePixelRatio,floorContext:s}),m=C({wayfinding:t,kioskHandler:i,yahHandler:f,stores:{routeStore:e.routeStore,uiState:e.uiState,layerStore:e.layerStore}});e.routeStore.showAccessible=o.getLines().some(a=>a.unaccessible);const l={wayfinding:t};return u=l,t.flush(),{wayfinding:t,dispose(){H(l)&&(u=null,e.routeStore.showAccessible=!1),m(),t.destroy()}}}function H(e){return u===e}function M(e,n){e.handleClick([n.def])&&n.stopPropagation()}function y(e,n,r){const o=n.current;if(!o)return;const c=r?e.handleHover([r.def]):!1;o.style.cursor=c?"pointer":""}
@@ -1 +1 @@
1
- import{degToRad as l}from"@expofp/geometry";import{createKioskCanvas as f}from"../adapters";const n="kiosk",p=0;export function createKioskHandler({wayfinding:t,kioskIconMap:a}){const s=new Map,u=e=>{const o=e??100,c=s.get(o);if(c)return c;const r=f(a,e);return s.set(o,r),r};return(e,o,c)=>{if(!e){t.setIcon(n,null),t.flush();return}if(c!==p&&e.z&&o&&e.z!==o){t.setIcon(n,null),t.flush();return}t.setIcon(n,{canvas:u(e.iconSizePercent),x:e.x,y:e.y,rotation:l(e.heading??0)}),t.flush()}}
1
+ import{degToRad as l}from"@expofp/geometry";import{createKioskCanvas as f}from"../adapters";const n="kiosk",p=0;export function createKioskHandler({wayfinding:t,kioskIconMap:a}){const s=new Map,u=e=>{const c=e??100,o=s.get(c);if(o)return o;const r=f(a,e);return s.set(c,r),r};return(e,c,o)=>{if(!e){t.setIcon(n,null),t.flush();return}if(o!==p&&e.z&&c&&e.z!==c){t.setIcon(n,null),t.flush();return}t.setIcon(n,{canvas:u(e.iconSizePercent),x:e.x,y:e.y,rotation:l(e.heading??0),screenSpace:!1}),t.flush()}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/floorplan",
3
- "version": "3.37.1",
3
+ "version": "3.39.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/expofp/efp-app.git",
@@ -69,15 +69,15 @@
69
69
  "tslib": "^2.3.0",
70
70
  "uuid": "^9.0.1",
71
71
  "zod": "4.4.3",
72
- "@expofp/config": "3.37.1",
73
- "@expofp/debug": "3.37.1",
74
- "@expofp/geometry": "3.37.1",
75
- "@expofp/renderer": "3.37.1",
76
- "@expofp/resolve": "3.37.1",
77
- "@expofp/schema": "3.37.1",
78
- "@expofp/ui": "3.37.1",
79
- "@expofp/utils": "3.37.1",
80
- "@expofp/wayfinding": "3.37.1"
72
+ "@expofp/config": "3.39.0",
73
+ "@expofp/debug": "3.39.0",
74
+ "@expofp/geometry": "3.39.0",
75
+ "@expofp/renderer": "3.39.0",
76
+ "@expofp/resolve": "3.39.0",
77
+ "@expofp/schema": "3.39.0",
78
+ "@expofp/ui": "3.39.0",
79
+ "@expofp/utils": "3.39.0",
80
+ "@expofp/wayfinding": "3.39.0"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@babel/plugin-proposal-decorators": "^8.0.2",
@@ -1,15 +0,0 @@
1
- import { type Booth } from '../store/BoothStore';
2
- export interface Img {
3
- booth: Booth;
4
- name?: string;
5
- htmlImage: HTMLImageElement;
6
- bounds: {
7
- x: number;
8
- y: number;
9
- width: number;
10
- height: number;
11
- angle: number;
12
- };
13
- }
14
- export declare function loadIcons(svgImages: SVGImageElement[]): Promise<Img[]>;
15
- //# sourceMappingURL=imageloader.d.ts.map
@@ -1 +0,0 @@
1
- import{loadImage as e}from"./loadImage";export function loadIcons(t){return Promise.all(t.map(a=>new Promise(async n=>{var l=await e(a.getAttribute("xlink:href")||a.getAttribute("href"));n(l?{bounds:{x:a.x.animVal.value,y:a.y.animVal.value,width:a.width.animVal.value,height:a.height.animVal.value,angle:a.transform?.animVal[0]?.angle??0},htmlImage:l,booth:null}:null)})))}