@expofp/floorplan 3.42.1 → 3.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/browser/{Button-CFOilpWS.js → Button-ChvBlyDe.js} +6 -6
  2. package/dist/browser/{CookieConsent-7xtFQUAC.js → CookieConsent-B79szHaS.js} +8 -8
  3. package/dist/browser/{Debug-Ccq8j5HJ.js → Debug-BmtrxpLX.js} +10 -10
  4. package/dist/browser/{DebugTools-dIItZaUb.js → DebugTools-D4NbQEtd.js} +7 -7
  5. package/dist/browser/{Demo-waaMiBvy.js → Demo-C1jGPlTZ.js} +13 -13
  6. package/dist/browser/{Free-DdCaOZ8Q.js → Free-CrPKA8NB.js} +16 -15
  7. package/dist/browser/{GalleryContainer-DlucEORI.js → GalleryContainer-Byk_AjCO.js} +470 -469
  8. package/dist/browser/{GpsLoader-cqPoX_Zr.js → GpsLoader-xcrMJQ3k.js} +40 -37
  9. package/dist/browser/{KioskStore-BJwAcVii.js → KioskStore-CCqEIeOE.js} +52 -48
  10. package/dist/browser/{store-DKVnQzpY.js → LayerStore-CfhO9JTt.js} +21374 -31265
  11. package/dist/browser/{MaplibreAdapter-BZD4cOe-.js → MaplibreAdapter-BkdCl4p0.js} +290 -285
  12. package/dist/browser/{ModalContainer-BSvSFPr9.js → ModalContainer-CdqhG7DC.js} +11 -11
  13. package/dist/browser/{PermissionNotice-DXt-j2f7.js → PermissionNotice-271evNUE.js} +7 -7
  14. package/dist/browser/RouteStore-DYDocOLg.js +1203 -0
  15. package/dist/browser/SetKioskMode-DWceqgEp.js +50 -0
  16. package/dist/browser/{ShowKiosk-BhS74u62.js → ShowKiosk-D5DyThTi.js} +18 -17
  17. package/dist/browser/UIState-Saj7Kjjr.js +2026 -0
  18. package/dist/browser/{ViewerMenuPanel-BYTeVxTR.js → ViewerMenuPanel--NAIzyGt.js} +25 -24
  19. package/dist/browser/{add-debug-secret-listener-B3Oo6_V2.js → add-debug-secret-listener-BqwoAVWZ.js} +1 -1
  20. package/dist/browser/{adopt-global-settings-Yr-a_0F-.js → adopt-global-settings-DvAJraFg.js} +10 -10
  21. package/dist/browser/{boolean-editor-BA7H18pG.js → boolean-editor-Co1Ily6N.js} +10 -10
  22. package/dist/browser/{bootIntercom-BEZV9AQ2.js → bootIntercom-BxKpklX4.js} +3 -3
  23. package/dist/browser/bundle.json +110 -71
  24. package/dist/browser/{camera-events-CJhSKz2q.js → camera-events-BnYGheBl.js} +1 -1
  25. package/dist/browser/{classnames-D4c_D7C1.js → classnames-NaSmbmqt.js} +2 -2
  26. package/dist/browser/{client-DGjMk9A1.js → client-CvZjZ5MY.js} +6 -6
  27. package/dist/browser/{components-MaSv6j2M.js → components-BC_4Rrtm.js} +1491 -1457
  28. package/dist/browser/create-live-plan-DdDxRVpo.js +3650 -0
  29. package/dist/browser/{debug-context-C2PWyEVT.js → debug-context-rb_t7BzM.js} +6 -6
  30. package/dist/browser/{debug-overlay-BXHh1LRW.js → debug-overlay-DX9d63U6.js} +11 -11
  31. package/dist/browser/{debug-ui-CO-3GLEU.js → debug-ui-1zRSn-Pt.js} +7 -7
  32. package/dist/browser/{dimming-kPNlXUew.js → dimming-D9erakE3.js} +277 -270
  33. package/dist/browser/{dist-DEm0E-fN.js → dist-BupLuz7e.js} +6 -6
  34. package/dist/browser/{dist-3gOjtf_f.js → dist-Dy3X0upa.js} +3 -3
  35. package/dist/browser/{dist-B3PLpTVy.js → dist-Dy4ATR13.js} +7 -7
  36. package/dist/browser/{efp-debug-init-DkOOpU1g.js → efp-debug-init-DTmBNC1u.js} +4 -4
  37. package/dist/browser/{enum-editor-DPAX_cAI.js → enum-editor-DS9Mi20y.js} +5 -5
  38. package/dist/browser/{es5-CpN6LQeU.js → es5-TGy8TG8S.js} +2 -2
  39. package/dist/browser/{event-head-oYEDbvk3.js → event-head-ccloCQPA.js} +1 -1
  40. package/dist/browser/{event-not-found-C7GLCJX7.js → event-not-found-B4UzwYx9.js} +4 -4
  41. package/dist/browser/event-scoped-cache-Bo8Pi1bU.js +22 -0
  42. package/dist/browser/{exports-3uPTDFG9.js → exports-DkrDN44T.js} +1 -1
  43. package/dist/browser/{favicon-CQpg641Z.js → favicon-BO6r3JQD.js} +1 -1
  44. package/dist/browser/{fetch-retry.umd-Chmlkexp.js → fetch-retry.umd-CBKWHeDp.js} +2 -2
  45. package/dist/browser/{flex--99NWgQk.js → flex-DK-UWQj-.js} +6 -6
  46. package/dist/browser/{floorplan.loader-Ci226yql.js → floorplan.loader-C3iy3aV0.js} +658 -707
  47. package/dist/browser/{floorplan.ready-y0hYLknK.js → floorplan.ready-Dfo1nWhu.js} +373 -359
  48. package/dist/browser/freeBanner-C7xKlqKw.js +31 -0
  49. package/dist/browser/{fuse-BuFi3LTO.js → fuse-BQcpTy7r.js} +2 -2
  50. package/dist/browser/{i18n-BAQekIFF.js → i18n-D6Lq_Buf.js} +1821 -3872
  51. package/dist/browser/index.js +131 -47
  52. package/dist/browser/{index.module-CXN9GK4C.js → index.module-BSoufRTU.js} +17 -17
  53. package/dist/browser/init-ui-1FfbXJGw.js +286 -0
  54. package/dist/browser/integrateKiosk-D9Q6DLBE.js +35 -0
  55. package/dist/browser/{loadImage-xbueiJmr.js → is-debug-COmQqgiL.js} +30 -14
  56. package/dist/browser/{is-own-domain-DPJZoBiw.js → is-own-domain-DJo0J_LD.js} +1 -1
  57. package/dist/browser/{is-webview-Bs8mxX94.js → is-webview-BBchBwKM.js} +1 -1
  58. package/dist/browser/{jsx-runtime-BXbSNrYY.js → jsx-runtime-DL-d6MrM.js} +2 -2
  59. package/dist/browser/kiosk-mode-_np8_B-l.js +33 -0
  60. package/dist/browser/{kiosk-record-CaWjqNGY.js → kiosk-record-BmaguqBS.js} +1 -1
  61. package/dist/browser/kioskApi-C07lc5Lj.js +440 -0
  62. package/dist/browser/{lib-jJ4yMeEA.js → lib-DrLsicOU.js} +3 -3
  63. package/dist/browser/loadImage-gvajvqmr.js +17 -0
  64. package/dist/browser/{logDeviceInfo-DSmmt_FU.js → logDeviceInfo-Dp6nkPPj.js} +9 -9
  65. package/dist/browser/{mobx-BQA2EJH7.js → mobx-Dfa_Tj0c.js} +11 -11
  66. package/dist/browser/mobx.module-ionKiiCb.js +2064 -0
  67. package/dist/browser/{optional-boolean-editor-Y_exy4JL.js → optional-boolean-editor-IDS6OcC1.js} +4 -4
  68. package/dist/browser/{optional-enum-editor-CKfj0OB9.js → optional-enum-editor-CmHeQhFh.js} +5 -5
  69. package/dist/browser/{optional-string-editor-DeavwcWv.js → optional-string-editor-5lm4OVVA.js} +5 -5
  70. package/dist/browser/{particles.min-BJkirBpN.js → particles.min-Djywwk9n.js} +2 -2
  71. package/dist/browser/{react-CV1gH7Zp.js → react-DATIS1Wg.js} +2 -2
  72. package/dist/browser/{react-dom-BEwgcqEB.js → react-dom-CZoP3ON8.js} +3 -3
  73. package/dist/browser/{rolldown-runtime-BiAnyumg.js → rolldown-runtime-C54u_qRI.js} +1 -1
  74. package/dist/browser/scene-CR4jNFce.js +108 -0
  75. package/dist/browser/{scheduler-CcNpP8xn.js → scheduler-B2SwSUg3.js} +2 -2
  76. package/dist/browser/{select-B13QBWfy.js → select-BXuAa5Mm.js} +11 -11
  77. package/dist/browser/{settings-DJUw3GyU.js → settings-DWSfrYuK.js} +2 -2
  78. package/dist/browser/{settings-item-VzMuDMX6.js → settings-item-Bg1kzAE-.js} +7 -7
  79. package/dist/browser/store-DKFByqxw.js +58 -0
  80. package/dist/browser/{string-editor-B6mio7nq.js → string-editor-CHJTsfW0.js} +5 -5
  81. package/dist/browser/{text-field-7dZmg829.js → text-field-Daedvncr.js} +6 -6
  82. package/dist/browser/{theme-BotlxmwW.js → theme-hSwmbdBg.js} +9 -9
  83. package/dist/browser/{ui-Dn5rbA7O.js → ui-BIFt_vYU.js} +9 -9
  84. package/dist/browser/{useRenderTarget-Rz0x5k4l.js → useRenderTarget-Cf0eV2dg.js} +5 -5
  85. package/dist/browser/{viewport-DOIlU3cR.js → viewport-Dvo8x5tc.js} +4 -3
  86. package/dist/browser/wayfinding-UIwKgl3o.js +2322 -0
  87. package/dist/esm/components/GalleryContainer.js +1 -1
  88. package/dist/esm/components/Kiosk/integrateKiosk.js +1 -1
  89. package/dist/esm/components/LogoOverlay.js +1 -1
  90. package/dist/esm/components/Map/Map.js +1 -1
  91. package/dist/esm/components/Map/MapCamera.js +1 -1
  92. package/dist/esm/components/Map/booth-by-xy.d.ts +8 -10
  93. package/dist/esm/components/Map/booth-by-xy.js +1 -1
  94. package/dist/esm/components/Map/drawing/config/BoothShape.d.ts +0 -1
  95. package/dist/esm/components/Map/drawing/config/BoothShape.js +1 -1
  96. package/dist/esm/components/Map/drawing/config/config-booth-bg.js +1 -1
  97. package/dist/esm/components/Map/drawing/config/config-booth-bookmark.js +1 -1
  98. package/dist/esm/components/Map/drawing/config/config-booth-border.js +1 -1
  99. package/dist/esm/components/Map/drawing/config/config-booth-labels-special.js +2 -2
  100. package/dist/esm/components/Map/drawing/config/config-booth-labels.js +1 -1
  101. package/dist/esm/components/Map/drawing/config/config-booths.js +1 -1
  102. package/dist/esm/components/Map/drawing/config/config-markers.js +1 -1
  103. package/dist/esm/components/Map/drawing/config/layer-images.d.ts +7 -2
  104. package/dist/esm/components/Map/drawing/config/layer-images.js +1 -1
  105. package/dist/esm/components/Map/traffic/useManageTraffic.js +1 -1
  106. package/dist/esm/components/Maplibre/MaplibreAdapter.js +1 -1
  107. package/dist/esm/components/Maplibre/useCameraReactions.js +1 -1
  108. package/dist/esm/components/Maplibre/utils/geo-config.js +1 -1
  109. package/dist/esm/components/Maplibre/utils/map-helpers.js +1 -1
  110. package/dist/esm/components/Menu.js +1 -1
  111. package/dist/esm/data/fpGeo.d.ts +6 -1
  112. package/dist/esm/data/fpGeo.js +1 -1
  113. package/dist/esm/data/index.d.ts +9 -4
  114. package/dist/esm/data/index.js +1 -1
  115. package/dist/esm/data/svg.d.ts +15 -13
  116. package/dist/esm/data/svg.js +1 -1
  117. package/dist/esm/floorplan.loader.d.ts +6 -1
  118. package/dist/esm/floorplan.loader.js +1 -1
  119. package/dist/esm/floorplan.ready.d.ts +8 -2
  120. package/dist/esm/floorplan.ready.js +1 -1
  121. package/dist/esm/load.js +11 -11
  122. package/dist/esm/plan-lifecycle.d.ts +65 -0
  123. package/dist/esm/plan-lifecycle.js +1 -0
  124. package/dist/esm/services/URLFilterManager.js +1 -1
  125. package/dist/esm/services/url-dispatch.js +1 -1
  126. package/dist/esm/services/url-sync.d.ts +5 -1
  127. package/dist/esm/services/url-sync.js +1 -1
  128. package/dist/esm/store/MaplibreStore.js +1 -1
  129. package/dist/esm/store/OverlayStore.d.ts +15 -2
  130. package/dist/esm/store/OverlayStore.js +1 -1
  131. package/dist/esm/store/RouteStore.js +1 -1
  132. package/dist/esm/store/UIState.js +1 -1
  133. package/dist/esm/store/create-live-plan.d.ts +13 -0
  134. package/dist/esm/store/create-live-plan.js +1 -0
  135. package/dist/esm/store/index.d.ts +2 -13
  136. package/dist/esm/store/index.js +1 -1
  137. package/dist/esm/store/init/init-booths.js +1 -1
  138. package/dist/esm/store/init/init-events.js +1 -1
  139. package/dist/esm/store/init/init-exhibitors.js +1 -1
  140. package/dist/esm/store/init/init-layers.js +1 -1
  141. package/dist/esm/store/init/init-speakers.js +1 -1
  142. package/dist/esm/store/init/init-ui.d.ts +4 -6
  143. package/dist/esm/store/init/init-ui.js +1 -1
  144. package/dist/esm/store/live-store.d.ts +19 -0
  145. package/dist/esm/store/live-store.js +1 -0
  146. package/dist/esm/store/search-buttons/SearchButtonsStore.js +1 -1
  147. package/dist/esm/tools/event-scoped-cache.d.ts +13 -0
  148. package/dist/esm/tools/event-scoped-cache.js +1 -0
  149. package/dist/esm/tools/gtag.d.ts +15 -1
  150. package/dist/esm/tools/gtag.js +1 -1
  151. package/dist/esm/tools/reset.js +1 -1
  152. package/dist/esm/tools/settings.d.ts +7 -2
  153. package/dist/esm/tools/settings.js +1 -1
  154. package/dist/esm/tools/slug.js +1 -1
  155. package/dist/esm/tools/style-registry.d.ts +28 -0
  156. package/dist/esm/tools/style-registry.js +1 -0
  157. package/dist/esm/tools/track-event.js +1 -1
  158. package/dist/esm/types.d.ts +7 -1
  159. package/dist/esm/utils/entity-storage.js +1 -1
  160. package/dist/esm/utils/gps.js +1 -1
  161. package/dist/esm/utils/plan-reactions.d.ts +20 -0
  162. package/dist/esm/utils/plan-reactions.js +1 -0
  163. package/dist/esm/utils/preview-exhibitor.d.ts +9 -2
  164. package/dist/esm/utils/preview-exhibitor.js +1 -1
  165. package/dist/esm/utils/swappable-proxy.d.ts +28 -0
  166. package/dist/esm/utils/swappable-proxy.js +1 -0
  167. package/dist/esm/wayfinding/createWayfinding.js +1 -1
  168. package/package.json +32 -10
  169. package/dist/browser/SetKioskMode-CCZNdKum.js +0 -48
  170. package/dist/browser/integrateKiosk-DjIKsfAy.js +0 -34
@@ -1 +1 @@
1
- import{jsx as p}from"react/jsx-runtime";import{Gallery as u}from"@expofp/ui";import{observer as v}from"mobx-react-lite";import{useCallback as x,useState as L}from"react";import{t as n}from"../utils/i18n";import{loadImage as b}from"../utils/loadImage";import{useRenderTarget as S}from"../utils/useRenderTarget";const h=o=>{const e=o.split("/"),r=e[e.length-1];return r.includes("original-")||(e[e.length-1]="original-"+r),e.join("/")},m=new Map,C=o=>{const e=m.get(o);if(e)return e;const r=h(o),i=r===o?Promise.resolve(o):b(r).then(l=>l?r:o);return m.set(o,i),i},I=v(o=>{const{images:e,...r}=o,i=S(),[l,d]=L({}),g=x(t=>{const s=e[t];s&&C(s).then(a=>{a!==s&&d(c=>c[s]===a?c:{...c,[s]:a})})},[e]),f=e.map(t=>({thumbnailUrl:t,fullUrl:l[t]??t}));return p(u,{...r,images:f,closeLabel:n("Close"),zoomInLabel:n("Zoom In"),zoomOutLabel:n("Zoom Out"),nextSlideLabel:n("Next slide"),prevSlideLabel:n("Prev slide"),fullscreenLabel:n("View fullscreen"),itemLabel:t=>n("View image {{index}}",{index:t+1}),renderTarget:i,onSlideActivate:g})});export default I;
1
+ import{jsx as p}from"react/jsx-runtime";import{Gallery as u}from"@expofp/ui";import{observer as v}from"mobx-react-lite";import{useCallback as x,useState as L}from"react";import{eventScopedCache as S}from"../tools/event-scoped-cache.js";import{t as n}from"../utils/i18n";import{loadImage as b}from"../utils/loadImage";import{useRenderTarget as h}from"../utils/useRenderTarget";const C=o=>{const e=o.split("/"),r=e[e.length-1];return r.includes("original-")||(e[e.length-1]="original-"+r),e.join("/")},m=S(),I=o=>{const e=m().get(o);if(e)return e;const r=C(o),i=r===o?Promise.resolve(o):b(r).then(l=>l?r:o);return m().set(o,i),i},T=v(o=>{const{images:e,...r}=o,i=h(),[l,d]=L({}),f=x(t=>{const s=e[t];s&&I(s).then(a=>{a!==s&&d(c=>c[s]===a?c:{...c,[s]:a})})},[e]),g=e.map(t=>({thumbnailUrl:t,fullUrl:l[t]??t}));return p(u,{...r,images:g,closeLabel:n("Close"),zoomInLabel:n("Zoom In"),zoomOutLabel:n("Zoom Out"),nextSlideLabel:n("Next slide"),prevSlideLabel:n("Prev slide"),fullscreenLabel:n("View fullscreen"),itemLabel:t=>n("View image {{index}}",{index:t+1}),renderTarget:i,onSlideActivate:f})});export default T;
@@ -1 +1 @@
1
- import{runInAction as a,when as i}from"mobx";import e from"../../store";import{getPtScaleZoomRatio as u}from"./kiosk-record";export function integrateKioskIntoMap(t,n){t&&a(()=>{if(e.uiState.setKioskData(t),e.uiState.kiosk=n,e.maplibreStore.showMaplibre)return;const o=t.mapCenterX!=null&&t.mapCenterY!=null;e.uiState.setMapSettings({centerxy:o?`${t.mapCenterX},${t.mapCenterY}`:"",z:t.z??void 0,bearing:t.mapRollDegrees});const r=u(t);r!==void 0&&e.uiState.changeZoom(r)})}export function integrateKioskIntoWf(t){t&&(t.z!=null&&e.fp.activateFloor({name:t.z.toString()}),i(()=>!!e.uiState.selectedRoute,()=>{const n=e.uiState.selectedRoute;n?.to&&!n.from&&e.routeStore.selectRoute(n,!1,!0)}))}
1
+ import{runInAction as a}from"mobx";import e from"../../store";import{planWhen as i}from"../../utils/plan-reactions.js";import{getPtScaleZoomRatio as u}from"./kiosk-record";export function integrateKioskIntoMap(t,r){t&&a(()=>{if(e.uiState.setKioskData(t),e.uiState.kiosk=r,e.maplibreStore.showMaplibre)return;const o=t.mapCenterX!=null&&t.mapCenterY!=null;e.uiState.setMapSettings({centerxy:o?`${t.mapCenterX},${t.mapCenterY}`:"",z:t.z??void 0,bearing:t.mapRollDegrees});const n=u(t);n!==void 0&&e.uiState.changeZoom(n)})}export function integrateKioskIntoWf(t){t&&(t.z!=null&&e.fp.activateFloor({name:t.z.toString()}),i(()=>!!e.uiState.selectedRoute,()=>{const r=e.uiState.selectedRoute;r?.to&&!r.from&&e.routeStore.selectRoute(r,!1,!0)}))}
@@ -1 +1 @@
1
- import{jsx as e,jsxs as m}from"react/jsx-runtime";import"./LogoOverlay.scss";import a from"classnames";import M from"color";import{useLocalStore as P,useObserver as _}from"mobx-react-lite";import{Suspense as O}from"react";import C from"../data";import{getFpSvgJs as R}from"../data/fp-payloads";import{fpGeo as f}from"../data/fpGeo";import c,{uiState as o}from"../store";import N from"../tools/base-runtime-url";import{buildExpofpUrl as A,UTM_CAMPAIGNS as D}from"../tools/expofpUrl";import l from"../tools/settings";import{remsToPixels as p}from"../utils";import{t as r}from"../utils/i18n";import d from"../utils/is-from-designer";import E from"../utils/lazy-qr-code";import h from"./AlertContainer";const g=["info-techlive2025","metstrade-superyacht2023"].includes(l.EXPO),u=f?.properties?.style,U=l.backgroundColor!=="none"&&M(l.backgroundColor).isDark()||typeof u=="string"&&u.includes("dark");export default function V(){const b=P(()=>{const s=(i,t,j,k)=>({width:k,opacity:o.wsStarted?1:0}),n=g||o.rtl?"left":"right";return{get style(){const i=p((o.overlayPosition==="left",1));if(o.overlayPosition==="left"){const t=o.mapVisibleBottom+i;return s("bottom",n,t,"5rem")}else return s("bottom",n,20,"4.5rem")},get warningStyle(){const i=p(o.overlayPosition==="left"?1:.5);if(o.overlayPosition==="left"){const t=o.mapVisibleBottom+2*i;return s("bottom",n,t,"3rem")}else{let t=o.mapVisibleTop+2*i;return c.maplibreStore.showMaplibre&&(t=p(.5)),s("top",n,t,"2rem")}}}}),v=Math.round((R().__fpStat?.dataSize??0)/1024/1024),w=d&&v>=10,y=d&&!f&&C.allow3dView&&!o.kiosk&&!o.heatmap,S=o.kiosk&&!o.selectedRoute?.to&&!o.selectedRoute?.from,x=a("efp-qr",{"is-right":g||o.rtl});return _(()=>m("div",{children:[!c.maplibreStore.showMaplibre&&e("a",{href:A(D.SUBDOMAIN_LOGO),target:"_blank",rel:"noopener noreferrer",className:a("logo-overlay",{invert:U}),style:b.style,children:e("img",{src:`${N}expofp-overlay.png`,alt:r("Made with ExpoFP"),crossOrigin:"anonymous"})}),w&&e(h,{title:r("This floor plan is too big"),variant:"warning",showIcon:!0,position:"bottom-right",children:e("a",{rel:"noopener noreferrer",target:"_blank",href:"https://expofp.com/pages/huge-fp-warning",children:r("Read how to optimize it")})}),y&&e(h,{title:r("3D view is hidden"),variant:"warning",showIcon:!0,position:"bottom-right",children:e("a",{rel:"noopener noreferrer",target:"_blank",href:"https://expofp.com/pages/expofp-mapbox-integration",children:r("Setup mapbox first")})}),S&&e(O,{fallback:null,children:m("div",{className:a(x,{"efp-semi-transparent":o.setKioskModeEnabled}),children:[e("div",{children:r("View Map on Phone")}),e(E,{value:o.viewMapOnPhoneQRCodeUrl,size:100})]})})]}))}
1
+ import{jsx as e,jsxs as f}from"react/jsx-runtime";import"./LogoOverlay.scss";import l from"classnames";import k from"color";import{useLocalStore as M,useObserver as P}from"mobx-react-lite";import{Suspense as _}from"react";import O from"../data";import{getFpSvgJs as R}from"../data/fp-payloads";import{getFpGeo as c}from"../data/fpGeo.js";import d,{uiState as o}from"../store";import C from"../tools/base-runtime-url";import{eventScopedValue as E}from"../tools/event-scoped-cache.js";import{buildExpofpUrl as N,UTM_CAMPAIGNS as A}from"../tools/expofpUrl";import p from"../tools/settings";import{remsToPixels as m}from"../utils";import{t as r}from"../utils/i18n";import h from"../utils/is-from-designer";import D from"../utils/lazy-qr-code";import g from"./AlertContainer";const G=["info-techlive2025","metstrade-superyacht2023"];function u(){return G.includes(p.EXPO)}const I=E(()=>{const s=c()?.properties?.style;return p.backgroundColor!=="none"&&k(p.backgroundColor).isDark()||typeof s=="string"&&s.includes("dark")});export default function V(){const s=M(()=>{const n=(i,t,T,x)=>({width:x,opacity:o.wsStarted?1:0}),a=u()||o.rtl?"left":"right";return{get style(){const i=m((o.overlayPosition==="left",1));if(o.overlayPosition==="left"){const t=o.mapVisibleBottom+i;return n("bottom",a,t,"5rem")}else return n("bottom",a,20,"4.5rem")},get warningStyle(){const i=m(o.overlayPosition==="left"?1:.5);if(o.overlayPosition==="left"){const t=o.mapVisibleBottom+2*i;return n("bottom",a,t,"3rem")}else{let t=o.mapVisibleTop+2*i;return d.maplibreStore.showMaplibre&&(t=m(.5)),n("top",a,t,"2rem")}}}}),b=Math.round((R().__fpStat?.dataSize??0)/1024/1024),v=h&&b>=10,w=h&&!c()&&O.allow3dView&&!o.kiosk&&!o.heatmap,y=o.kiosk&&!o.selectedRoute?.to&&!o.selectedRoute?.from,S=l("efp-qr",{"is-right":u()||o.rtl});return P(()=>f("div",{children:[!d.maplibreStore.showMaplibre&&e("a",{href:N(A.SUBDOMAIN_LOGO),target:"_blank",rel:"noopener noreferrer",className:l("logo-overlay",{invert:I()}),style:s.style,children:e("img",{src:`${C}expofp-overlay.png`,alt:r("Made with ExpoFP"),crossOrigin:"anonymous"})}),v&&e(g,{title:r("This floor plan is too big"),variant:"warning",showIcon:!0,position:"bottom-right",children:e("a",{rel:"noopener noreferrer",target:"_blank",href:"https://expofp.com/pages/huge-fp-warning",children:r("Read how to optimize it")})}),w&&e(g,{title:r("3D view is hidden"),variant:"warning",showIcon:!0,position:"bottom-right",children:e("a",{rel:"noopener noreferrer",target:"_blank",href:"https://expofp.com/pages/expofp-mapbox-integration",children:r("Setup mapbox first")})}),y&&e(_,{fallback:null,children:f("div",{className:l(S,{"efp-semi-transparent":o.setKioskModeEnabled}),children:[e("div",{children:r("View Map on Phone")}),e(D,{value:o.viewMapOnPhoneQRCodeUrl,size:100})]})})]}))}
@@ -1 +1 @@
1
- import{jsx as h,jsxs as w}from"react/jsx-runtime";import{Renderer as F,update as b}from"@expofp/renderer";import O from"classnames";import{observable as D}from"mobx";import{useObserver as g}from"mobx-react-lite";import{useEffect as y,useMemo as I,useRef as v,useState as N}from"react";import k from"../../data";import{svgArea as z}from"../../data/svg";import{createSceneDef as Z}from"../../engine/defs";import i,{layersStore as l,uiState as a}from"../../store";import{ZOOM_IN_FACTOR as j}from"../../store/UIState";import u from"../../tools/settings";import{applyVenueDim as V,createDimmingAnimator as $}from"../../utils/dimming";import C from"../../utils/is-debug";import{isPathwayLayer as S}from"../../utils/is-pathway-layer";import{useReaction as R}from"../../utils/mobx";import{createWayfinding as U}from"../../wayfinding";import W from"./drawing/config/config-all";import{configMarkers as B}from"./drawing/config/config-markers";import{loadLayersImages as H}from"./drawing/config/loadBoothsImages";import{MapCamera as X}from"./MapCamera";import{MapCursorCoords as G}from"./MapCursorCoords";import{MapViewport as J}from"./MapViewport";import{clearSelection as q}from"./pointer";import{setMapScene as E}from"./scene";import{useBuildRoute as K}from"./traffic/useBuildRoute";import{useManageTraffic as Q}from"./traffic/useManageTraffic";import{centerCoordinates as Y}from"./viewport";const ee="#ebebeb",T="routes-api.expofp.com",re=1e4;function oe(n){return Number.isFinite(u.maxZoom)?u.maxZoom:n.viewbox.size.width>re?100:35}function te(){const{zoomtime:n,pitchtime:f}=a.mapSettings;return{zoomTime:n===void 0?void 0:n/1e3,pitchTime:f===void 0?void 0:f/1e3}}export default function ne(){const n=v(null),f=I(()=>D({moving:!1,prevLevel:i.layerStore.layers.find(r=>!r.frozen&&r.visible)}),[]),[o,M]=N(void 0),d=v(null),p=v(null);function L(){l.layers.forEach(r=>{r.configured=!1,r.children=[],r.loaded=!1})}y(()=>{let r=!1;return L(),l.layersLoaded=!1,W().then(({layers:s,cleanup:m})=>{if(r){m();return}p.current=m;const t=u.backgroundColor==="none"?ee:u.backgroundColor,e=Z(s,z,t);M(e),E(e),d.current=$(c=>{V(e,c)&&b(e.rootLayer)}),d.current.setTarget(a.dimmed,{immediate:!0}),l.layersLoaded=!0,i.fp.onFpConfigured&&i.fp.onFpConfigured(),H()}),()=>{r=!0,p.current?.(),p.current=null,d.current?.stop(),d.current=null,E(void 0),L()}},[]),R(()=>a.dimmed,r=>{d.current?.setTarget(r)}),y(()=>{i.fp.getCenterCoordinates=()=>Y(n.current)},[]),y(()=>{if(!o)return;const r=U({scene:o,store:i,canvas:n}),s=B({scene:o});return()=>{r(),s()}},[o]),R(()=>i.routeStore.currentRouteLayer,()=>{const r=i.routeStore.currentRouteLayer;if(!o||!r||f.prevLevel===r)return;const s=o.rootLayer.children.filter(e=>i.layerStore.floors.some(c=>e.name.includes(c.name))),m=r.name;if(!s.find(e=>e.name===m))return;const t=[];s.forEach(e=>{e.name===m&&e.hidden!==!1&&(e.hidden=!1,t.push(e)),e.name===f.prevLevel?.name&&e.hidden!==!0&&(e.hidden=!0,t.push(e))}),f.prevLevel=r,t.length&&b(...t)},{fireImmediately:!0},[o]),R(()=>i.layerStore.visible,r=>{if(!o)return;const s=r.filter(e=>S(e.name)),m=o.rootLayer.children,t=[];for(const e of m){if(!S(e.name))continue;const c=!s.find(P=>P.name===e.name);e.hidden!==c&&(e.hidden=c,t.push(e))}t.length&&b(...t)},{fireImmediately:!0},[o]);const x=g(()=>l.layersLoaded),_=g(()=>!!a.buildRoute);K({enabled:x&&_,scene:o});const A=k.busRoutes??!1;return Q({permission:x&&A,scene:o,dataJsonUrl:`https://${T}/v1/routes?expo=${u.EXPO}`,websocketUrl:`wss://${T}/locations?expo=${u.EXPO}`}),g(()=>o?w(F,{debug:C,style:{width:"100%",height:"100%"},ref:n,className:O({map:!0}),scene:o,maxZoom:oe(o),maxPitch:a.maxPitch,bounds:l.bounds,controls:{roll:a.rollEnabled,pitch:a.pitchEnabled,zoom:{dblclick:j}},smoothTime:te(),visibleRect:a.canvasVisibleRectPx,onPointerMissed:q,children:[h(X,{}),h(J,{}),C&&h(G,{canvas:n})]}):null)}
1
+ import{jsx as h,jsxs as w}from"react/jsx-runtime";import{Renderer as F,update as b}from"@expofp/renderer";import O from"classnames";import{observable as D}from"mobx";import{useObserver as g}from"mobx-react-lite";import{useEffect as y,useMemo as I,useRef as v,useState as N}from"react";import k from"../../data";import{getSvgArea as z}from"../../data/svg.js";import{createSceneDef as Z}from"../../engine/defs";import i,{layersStore as l,uiState as a}from"../../store";import{ZOOM_IN_FACTOR as j}from"../../store/UIState";import u from"../../tools/settings";import{applyVenueDim as V,createDimmingAnimator as $}from"../../utils/dimming";import x from"../../utils/is-debug";import{isPathwayLayer as C}from"../../utils/is-pathway-layer";import{useReaction as R}from"../../utils/mobx";import{createWayfinding as U}from"../../wayfinding";import W from"./drawing/config/config-all";import{configMarkers as B}from"./drawing/config/config-markers";import{loadLayersImages as H}from"./drawing/config/loadBoothsImages";import{MapCamera as X}from"./MapCamera";import{MapCursorCoords as G}from"./MapCursorCoords";import{MapViewport as J}from"./MapViewport";import{clearSelection as q}from"./pointer";import{setMapScene as E}from"./scene";import{useBuildRoute as K}from"./traffic/useBuildRoute";import{useManageTraffic as Q}from"./traffic/useManageTraffic";import{centerCoordinates as Y}from"./viewport";const ee="#ebebeb",T="routes-api.expofp.com",re=1e4;function oe(n){return Number.isFinite(u.maxZoom)?u.maxZoom:n.viewbox.size.width>re?100:35}function te(){const{zoomtime:n,pitchtime:f}=a.mapSettings;return{zoomTime:n===void 0?void 0:n/1e3,pitchTime:f===void 0?void 0:f/1e3}}export default function ne(){const n=v(null),f=I(()=>D({moving:!1,prevLevel:i.layerStore.layers.find(r=>!r.frozen&&r.visible)}),[]),[o,M]=N(void 0),d=v(null),p=v(null);function L(){l.layers.forEach(r=>{r.configured=!1,r.children=[],r.loaded=!1})}y(()=>{let r=!1;return L(),l.layersLoaded=!1,W().then(({layers:s,cleanup:m})=>{if(r){m();return}p.current=m;const t=u.backgroundColor==="none"?ee:u.backgroundColor,e=Z(s,z(),t);M(e),E(e),d.current=$(c=>{V(e,c)&&b(e.rootLayer)}),d.current.setTarget(a.dimmed,{immediate:!0}),l.layersLoaded=!0,i.fp.onFpConfigured&&i.fp.onFpConfigured(),H()}),()=>{r=!0,p.current?.(),p.current=null,d.current?.stop(),d.current=null,E(void 0),L()}},[]),R(()=>a.dimmed,r=>{d.current?.setTarget(r)}),y(()=>{i.fp.getCenterCoordinates=()=>Y(n.current)},[]),y(()=>{if(!o)return;const r=U({scene:o,store:i,canvas:n}),s=B({scene:o});return()=>{r(),s()}},[o]),R(()=>i.routeStore.currentRouteLayer,()=>{const r=i.routeStore.currentRouteLayer;if(!o||!r||f.prevLevel===r)return;const s=o.rootLayer.children.filter(e=>i.layerStore.floors.some(c=>e.name.includes(c.name))),m=r.name;if(!s.find(e=>e.name===m))return;const t=[];s.forEach(e=>{e.name===m&&e.hidden!==!1&&(e.hidden=!1,t.push(e)),e.name===f.prevLevel?.name&&e.hidden!==!0&&(e.hidden=!0,t.push(e))}),f.prevLevel=r,t.length&&b(...t)},{fireImmediately:!0},[o]),R(()=>i.layerStore.visible,r=>{if(!o)return;const s=r.filter(e=>C(e.name)),m=o.rootLayer.children,t=[];for(const e of m){if(!C(e.name))continue;const c=!s.find(P=>P.name===e.name);e.hidden!==c&&(e.hidden=c,t.push(e))}t.length&&b(...t)},{fireImmediately:!0},[o]);const S=g(()=>l.layersLoaded),_=g(()=>!!a.buildRoute);K({enabled:S&&_,scene:o});const A=k.busRoutes??!1;return Q({permission:S&&A,scene:o,dataJsonUrl:`https://${T}/v1/routes?expo=${u.EXPO}`,websocketUrl:`wss://${T}/locations?expo=${u.EXPO}`}),g(()=>o?w(F,{debug:x,style:{width:"100%",height:"100%"},ref:n,className:O({map:!0}),scene:o,maxZoom:oe(o),maxPitch:a.maxPitch,bounds:l.bounds,controls:{roll:a.rollEnabled,pitch:a.pitchEnabled,zoom:{dblclick:j}},smoothTime:te(),visibleRect:a.canvasVisibleRectPx,onPointerMissed:q,children:[h(X,{}),h(J,{}),x&&h(G,{canvas:n})]}):null)}
@@ -1 +1 @@
1
- import{Box as s}from"@expofp/geometry";import{useCameraAPI as g,useCameraGesture as x,useCameraMoveEnd as R,useCameraState as T}from"@expofp/renderer";import{useEffect as B,useLayoutEffect as M,useRef as P,useState as S}from"react";import{fpGeo as C}from"../../data/fpGeo";import{svgArea as F}from"../../data/svg";import l,{uiState as e}from"../../store";import{BoothBase as w}from"../../store/BoothStore";import d from"../../tools/logger";import E from"../../tools/settings";import{areLayersEnabled as N}from"../../utils/areLayersEnabled";import{parseNumberPair as v}from"../../utils/camera-map-settings";import{convertGpsToLocal as z}from"../../utils/gps";import{useOneShotReaction as f}from"../../utils/mobx";import{createMapCamera as b,setMapCamera as h}from"./camera";import{notifyCameraMoved as k}from"./camera-events";import{resetExternalOverlay as G}from"./pointer";export function MapCamera(){const t=g(),n=T(),r=P({api:t,state:n}),[a]=S(()=>b(r));return M(()=>{r.current={api:t,state:n}}),B(()=>(h(a),()=>h(void 0)),[a]),x(()=>G()),R(()=>k()),f(()=>e.zoomBy,o=>{o&&(r.current.api.zoomBy(o),e.zoomBy=null)},[]),f(()=>e.rollReset,o=>{o&&(r.current.api.reset({roll:!0}),e.rollReset=!1)},[]),f(()=>e.centerMap,o=>{o&&(r.current.api.reset({zoom:!!(e.list.type==="search"&&e.list.text)}),e.centerMap=!1)},[]),f(()=>e.moveToRect,o=>{if(!o)return;const{width:m,height:i}=o.size;m>0&&i>0&&Number.isFinite(m)&&Number.isFinite(i)&&y(r.current.api,o,e.moveToRectPaddingPercent??void 0),e.moveToRect=null,e.moveToRectPaddingPercent=null},[]),f(()=>e.moveToBooths,o=>{if(!o)return;d.log("watched moveToBooths",o);const m=o.filter(i=>i.rect).map(i=>i.rect);m.length&&y(r.current.api,s.fromUnion(...m)),e.moveToBooths=null},[]),f(()=>e.mapSettings,({center:o,centerxy:m,bearing:i,pitchdegrees:c,z:p})=>{try{p&&l.fp.activateFloor({name:p});const u=U(o,m);u&&r.current.api.panTo(u),i!==void 0&&Number.isFinite(i)&&r.current.api.rollTo(i),c!=null&&Number.isFinite(c)&&r.current.api.pitchTo(c,{immediate:!e.animatePitch})}catch(u){d.error("Error in mapSettings reaction",u)}},[]),null}function y(t,n,r){t.zoomTo(A(n),{padding:r??O(n,F),maxZoom:Number.isFinite(E.maxZoom)?void 0:10,within:L()})}function L(){const t=e.canvasVisibleRectPx;return e.shouldShiftMapRect?s.fromMinMax({x:t.min.x+e.overlayWidthPx,y:t.min.y},t.max):t}function A(t){const n=e.kioskData;if(!n)return t;const r=e.selectedRoute?.from,a=r instanceof w?r.layer?.name:r?.layer;return(N()?a===l.routeStore.currentRouteLayer?.name:!0)?s.fromUnion(t,new s(n.x,n.y,1,1)):t}function O(t,n){return!t||!n?0:(t.area/n.area>.1?15:25)/100}function U(t,n){if(t){const a=v(t);if(!a)return;const o=C?.properties?.config;if(!o)throw new Error("Map center given in GPS, but the plan has no GPS config");return z({lat:a[0],lng:a[1]},o)??void 0}const r=v(n);if(r)return{x:r[0],y:r[1]}}
1
+ import{Box as s}from"@expofp/geometry";import{useCameraAPI as g,useCameraGesture as x,useCameraMoveEnd as R,useCameraState as T}from"@expofp/renderer";import{useEffect as B,useLayoutEffect as M,useRef as P,useState as S}from"react";import{getFpGeo as F}from"../../data/fpGeo.js";import{getSvgArea as C}from"../../data/svg.js";import l,{uiState as e}from"../../store";import{BoothBase as w}from"../../store/BoothStore";import d from"../../tools/logger";import E from"../../tools/settings";import{areLayersEnabled as N}from"../../utils/areLayersEnabled";import{parseNumberPair as v}from"../../utils/camera-map-settings";import{convertGpsToLocal as z}from"../../utils/gps";import{useOneShotReaction as f}from"../../utils/mobx";import{createMapCamera as b,setMapCamera as h}from"./camera";import{notifyCameraMoved as k}from"./camera-events";import{resetExternalOverlay as G}from"./pointer";export function MapCamera(){const t=g(),n=T(),r=P({api:t,state:n}),[a]=S(()=>b(r));return M(()=>{r.current={api:t,state:n}}),B(()=>(h(a),()=>h(void 0)),[a]),x(()=>G()),R(()=>k()),f(()=>e.zoomBy,o=>{o&&(r.current.api.zoomBy(o),e.zoomBy=null)},[]),f(()=>e.rollReset,o=>{o&&(r.current.api.reset({roll:!0}),e.rollReset=!1)},[]),f(()=>e.centerMap,o=>{o&&(r.current.api.reset({zoom:!!(e.list.type==="search"&&e.list.text)}),e.centerMap=!1)},[]),f(()=>e.moveToRect,o=>{if(!o)return;const{width:m,height:i}=o.size;m>0&&i>0&&Number.isFinite(m)&&Number.isFinite(i)&&y(r.current.api,o,e.moveToRectPaddingPercent??void 0),e.moveToRect=null,e.moveToRectPaddingPercent=null},[]),f(()=>e.moveToBooths,o=>{if(!o)return;d.log("watched moveToBooths",o);const m=o.filter(i=>i.rect).map(i=>i.rect);m.length&&y(r.current.api,s.fromUnion(...m)),e.moveToBooths=null},[]),f(()=>e.mapSettings,({center:o,centerxy:m,bearing:i,pitchdegrees:c,z:p})=>{try{p&&l.fp.activateFloor({name:p});const u=U(o,m);u&&r.current.api.panTo(u),i!==void 0&&Number.isFinite(i)&&r.current.api.rollTo(i),c!=null&&Number.isFinite(c)&&r.current.api.pitchTo(c,{immediate:!e.animatePitch})}catch(u){d.error("Error in mapSettings reaction",u)}},[]),null}function y(t,n,r){t.zoomTo(A(n),{padding:r??O(n,C()),maxZoom:Number.isFinite(E.maxZoom)?void 0:10,within:L()})}function L(){const t=e.canvasVisibleRectPx;return e.shouldShiftMapRect?s.fromMinMax({x:t.min.x+e.overlayWidthPx,y:t.min.y},t.max):t}function A(t){const n=e.kioskData;if(!n)return t;const r=e.selectedRoute?.from,a=r instanceof w?r.layer?.name:r?.layer;return(N()?a===l.routeStore.currentRouteLayer?.name:!0)?s.fromUnion(t,new s(n.x,n.y,1,1)):t}function O(t,n){return!t||!n?0:(t.area/n.area>.1?15:25)/100}function U(t,n){if(t){const a=v(t);if(!a)return;const o=F()?.properties?.config;if(!o)throw new Error("Map center given in GPS, but the plan has no GPS config");return z({lat:a[0],lng:a[1]},o)??void 0}const r=v(n);if(r)return{x:r[0],y:r[1]}}
@@ -1,16 +1,14 @@
1
1
  import type { Booth } from '../../store/BoothStore';
2
2
  /**
3
- * Starts keeping the hit-test index current with the stores, and returns the disposer.
3
+ * Starts keeping the hit-test index current with the live plan's stores; the reaction is disposed
4
+ * with the plan.
4
5
  *
5
- * Called from the instance wiring (`floorplan.ready`) rather than run at module scope: this module
6
- * sits inside the store ↔ components import cycle (the store's own modules reach it through the
7
- * config chain), and `reaction` reads its expression the moment it is created — at module scope
8
- * that is `boothStore` still in its temporal dead zone. Bound at init, every store exists;
9
- * `fireImmediately` buckets whatever a remount finds already loaded, and the reaction tracks
10
- * changes from there exactly as before. One binding serves both map modes — the MapLibre path
11
- * resolves outdoor-PoI booths through this index too.
12
- * @returns Disposes the reaction.
6
+ * Called from the instance wiring (`floorplan.ready`) rather than run at module scope: the reaction
7
+ * belongs to one plan, and this module sits inside the store <-> components import cycle — `reaction`
8
+ * reads its expression the moment it is created, and at module scope that is `boothStore` still in
9
+ * its temporal dead zone. One binding serves both map modes; the MapLibre path resolves outdoor-PoI
10
+ * booths through this index too. `fireImmediately` buckets whatever the plan has already loaded.
13
11
  */
14
- export declare function bindBoothHitTest(): () => void;
12
+ export declare function bindBoothHitTest(): void;
15
13
  export default function getBoothIdFromClientXy(clientX: number, clientY: number): Booth | null;
16
14
  //# sourceMappingURL=booth-by-xy.d.ts.map
@@ -1 +1 @@
1
- import{Box as y,Polygon as v,Rect as I}from"@expofp/geometry";import{reaction as z}from"mobx";import{getTrianglesFromFpPaths as X}from"../../data/svg";import{boothStore as b,layersStore as d}from"../../store";import{LayersMode as A}from"../../store/LayerStore";import B from"../../tools/logger";let x=[],g=new Map,u=null,w=[];function F(){const l=b.booths.filter(t=>t.visible&&t.rect&&t.rect.size.width>0&&t.rect.size.height>0);if(x=[],u=null,g=new Map,w=l.filter(t=>t.paths),!l.length)return;const c=[];let r=1/0,n=1/0,f=-1/0,e=-1/0;for(const t of l){const a=t.rotate?new I(t.rect.center,t.rect.size,t.rotate):null,o=a?a.bounds:t.rect;c.push({booth:t,shape:a??t.rect,bounds:o}),o.min.x<r&&(r=o.min.x),o.min.y<n&&(n=o.min.y),o.max.x>f&&(f=o.max.x),o.max.y>e&&(e=o.max.y)}const i=y.fromMinMax({x:r,y:n},{x:f,y:e}),s=2,m=Math.ceil(i.size.width/s),h=Math.ceil(i.size.height/s);for(let t=0;t<s;t++)for(let a=0;a<s;a++){const o=i.min.x+t*m,M=i.min.y+a*h,p=new y(o,M,m,h);x.push(p),g.set(p,c.filter(P=>p.intersects(P.bounds)))}B.log("hover segmentToHitAreas",g)}export function bindBoothHitTest(){return z(()=>[b.booths,d.loaded,d.visible],()=>F(),{fireImmediately:!0})}function H(l,c){const r={x:l,y:c};let n;u&&u.containsPoint(r)?n=u:n=x.find(e=>e.containsPoint(r)),n&&(u=n);const f=n?g.get(n):void 0;if(f){const e=f.filter(i=>i.booth.visible&&i.shape.containsPoint(r));if(e.length)return(e.length>1?e.sort((s,m)=>s.booth.rect.area-m.booth.rect.area)[0]:e[0]).booth}for(const e of w)if(e.visible)for(const i of e.paths)for(const s of X(i.index,d.mode!==A.Default?e.layer.name:"")){const m=s.map(h=>({x:h[0],y:h[1]}));if(v.fromConvexRing(m).containsPoint(r))return e}return null}export default function S(l,c){return H(l,c)}
1
+ import{Box as d,Polygon as S,Rect as P}from"@expofp/geometry";import{getTrianglesFromFpPaths as A}from"../../data/svg";import{boothStore as x,layersStore as u}from"../../store";import{LayersMode as H}from"../../store/LayerStore";import{eventScopedValue as T}from"../../tools/event-scoped-cache.js";import w from"../../tools/logger";import{planReaction as M}from"../../utils/plan-reactions.js";const b=T(()=>({segments:[],segmentToHitAreas:new Map,prevSegment:null,boothsWithPaths:[]}));function I(){const c=x.booths.filter(t=>t.visible&&t.rect&&t.rect.size.width>0&&t.rect.size.height>0),o=b();if(o.segments=[],o.prevSegment=null,o.segmentToHitAreas=new Map,o.boothsWithPaths=c.filter(t=>t.paths),!c.length)return;const s=[];let m=1/0,i=1/0,l=-1/0,e=-1/0;for(const t of c){const f=t.rotate?new P(t.rect.center,t.rect.size,t.rotate):null,n=f?f.bounds:t.rect;s.push({booth:t,shape:f??t.rect,bounds:n}),n.min.x<m&&(m=n.min.x),n.min.y<i&&(i=n.min.y),n.max.x>l&&(l=n.max.x),n.max.y>e&&(e=n.max.y)}const r=d.fromMinMax({x:m,y:i},{x:l,y:e}),a=2,h=Math.ceil(r.size.width/a),g=Math.ceil(r.size.height/a);for(let t=0;t<a;t++)for(let f=0;f<a;f++){const n=r.min.x+t*h,y=r.min.y+f*g,p=new d(n,y,h,g);o.segments.push(p),o.segmentToHitAreas.set(p,s.filter(v=>p.intersects(v.bounds)))}w.log("hover segmentToHitAreas",o.segmentToHitAreas)}export function bindBoothHitTest(){M(()=>[x.booths,u.loaded,u.visible],()=>I(),{fireImmediately:!0})}function z(c,o){const s=b(),m={x:c,y:o};let i;s.prevSegment&&s.prevSegment.containsPoint(m)?i=s.prevSegment:i=s.segments.find(e=>e.containsPoint(m)),i&&(s.prevSegment=i);const l=i?s.segmentToHitAreas.get(i):void 0;if(l){const e=l.filter(r=>r.booth.visible&&r.shape.containsPoint(m));if(e.length)return(e.length>1?e.sort((a,h)=>a.booth.rect.area-h.booth.rect.area)[0]:e[0]).booth}for(const e of s.boothsWithPaths)if(e.visible)for(const r of e.paths)for(const a of A(r.index,u.mode!==H.Default?e.layer.name:"")){const h=a.map(g=>({x:g[0],y:g[1]}));if(S.fromConvexRing(h).containsPoint(m))return e}return null}export default function X(c,o){return z(c,o)}
@@ -1,6 +1,5 @@
1
1
  import { Booth } from '../../../../store/BoothStore';
2
2
  export default class BoothShape {
3
- private readonly booth;
4
3
  selectBgAnimationPart: number;
5
4
  constructor(booth: Booth);
6
5
  static get(b: Booth): BoothShape;
@@ -1 +1 @@
1
- import{__decorate as l}from"tslib";import{easeQuadInOut as b}from"d3-ease";import{observable as A,reaction as M}from"mobx";const s=new Map;export default class a{constructor(t){this.booth=t,N(()=>t.selected,n=>this.selectBgAnimationPart=b(n),1e3,8,!0)}static get(t){let n=s.get(t);return n||(n=new a(t),s.set(t,n)),n}}l([A],a.prototype,"selectBgAnimationPart",void 0);function N(c,t,n,i,m){const p=m?u:f;i%2===1&&i++,M(c,()=>{if(c()){const o=performance.now(),r=o+i*n,e=()=>{if(c()){if(performance.now()>=r){t(1);return}t(p(o,n)),window.requestAnimationFrame(e)}};e()}else t(0)},{fireImmediately:!0});function f(o,r){return(performance.now()-o)%r/1e3}function u(o,r){const d=((performance.now()-o)%(r*2)-r)/1e3;return 1-Math.abs(Math.abs(d)-r/1e3)/(r/1e3)}}
1
+ import{__decorate as l}from"tslib";import{easeQuadInOut as P}from"d3-ease";import{observable as A,reaction as b}from"mobx";import{registerPlanDisposer as g}from"../../../../plan-lifecycle.js";import{eventScopedCache as h}from"../../../../tools/event-scoped-cache.js";const s=h();export default class a{constructor(t){this.selectBgAnimationPart=0,B(()=>t.selected,r=>this.selectBgAnimationPart=P(r),1e3,8,!0)}static get(t){let r=s().get(t);return r||(r=new a(t),s().set(t,r)),r}}l([A],a.prototype,"selectBgAnimationPart",void 0);function B(c,t,r,i,m){const p=m?u:f;i%2===1&&i++,g(b(c,()=>{if(c()){const o=performance.now(),e=o+i*r,n=()=>{if(c()){if(performance.now()>=e){t(1);return}t(p(o,r)),window.requestAnimationFrame(n)}};n()}else t(0)},{fireImmediately:!0}));function f(o,e){return(performance.now()-o)%e/1e3}function u(o,e){const d=((performance.now()-o)%(e*2)-e)/1e3;return 1-Math.abs(Math.abs(d)-e/1e3)/(e/1e3)}}
@@ -1 +1 @@
1
- import{__decorate as d}from"tslib";import{Rect as y}from"@expofp/geometry";import{update as B}from"@expofp/renderer";import l from"color";import S from"color-interpolate";import{computed as u,reaction as m}from"mobx";import a from"../../../../data";import{getFpSvgJs as k}from"../../../../data/fp-payloads";import{createShapeDef as D}from"../../../../engine/defs";import v,{boothStore as x,heatmapStore as H,layersStore as g,uiState as n}from"../../../../store";import{RegularBooth as I,SpecialBooth as L}from"../../../../store/BoothStore";import{RebookingState as P}from"../../../../store/ExhibitorStore";import{LayersMode as w}from"../../../../store/LayerStore";import{rebookingStateConfig as b}from"../../../../tools/rebooking-config";import s from"../../../../tools/settings";import{BoothDrawerBaseWithoutPainter as A}from"./BoothDrawerBase";import{buildPathDef as F}from"./config-bg";export default function R(i){return new c(i)}function W(i){if(i.length===0)return null;const o=i[0];return i.every(t=>t===o)?o:null}export function pathToShapeDef(i,o){const e=[];for(const t of i){const r=F({index:t.index,color:t.color,unblinking:t.unblinking},o);r&&e.push(r)}return e}class c extends A{constructor(o){if(super(o),o.paths){const e=pathToShapeDef(o.paths,v.layerStore.mode!==w.Default?o.layer.name:"");o.shapes=e.map(t=>{const r=n.monochrome?l(t.color).grayscale().rgb().string():this.getBoothColor().string();return t.color==="transparent"?t.color=r:t.defaultColor=t.color,t})}else{const e=o.borderColor==="none"?0:isNaN(o.borderWidth)?x.borderWidth:o.borderWidth,t=this.booth.rect.expand(-e/2),r=this.getBoothColor().string();o.shapes=[D(new y(t.center,t.size,this.booth.rotate,this.booth.elevation),r)]}m(()=>this.booth.hover,()=>!this.booth.selected&&this.update()),m(()=>[g.layersLoaded,this.booth.skipDim,this.booth.selected,this.boothShape.selectBgAnimationPart],()=>this.update())}getShape(){return this.booth.shapes}update(){if(g.layersLoaded)for(const o of this.booth.shapes){if(o.dim=this.booth.skipDim?0:void 0,o.color&&!o.unblinking){const e=o.defaultColor?this.getBoothPathColor(o.defaultColor):this.getBoothColor();o.color=e.string()}B(o)}}get poiHighlighted(){const o=this.booth;return!o.selected&&o.poiTypeId!=null&&o.skipDim}getBoothPathColor(o){if(n.heatmap)return this.getHeatmapColor();const e=this.booth,t=s.colors.booths.selected;let r=l(this.poiHighlighted?t:o).hsl();if(e.selected){if(k().__fpSettings?.fpVer){const p=this.selectedColorInterpolateFunc(this.boothShape.selectBgAnimationPart),f=l(p==="none"?t:p);return n.monochrome?f.grayscale():f}const h=l(t).hsl(),C=h.lightness()*this.boothShape.selectBgAnimationPart;r=r.hue(h.hue()).lightness(C)}else e.hover&&(r=r.darken(.1));return n.monochrome&&(r=r.grayscale()),r}getHeatmapColor(){const o=this.booth,e=H.getHeatmapColorForBooth(o);if(o.selected){const t=this.selectedColorInterpolateFunc(this.boothShape.selectBgAnimationPart);return l(t==="none"?"#f33":t)}return o.hover?e.darken(.2).alpha(e.alpha()*1.5):e}get defaultColor(){const o=this.booth;let e=s.colors.booths.default;if(o instanceof L)e=o.color||s.colors.booths.empty;else if(o instanceof I){if(a.isRebooking){if(!o.exhibitors?.length)return b[P.Unasked].color.primary;const r=W((o.exhibitors??[]).map(h=>h.rebookingState));return r!==null?b[r].color.primary:"#000000"}const t=s.colors.booths;o.onHold?e=o.holdColor||t.defaultHold:o.exhibitors.length||o.reserved?e=o.soldColor||t.defaultSold:e=o.availColor||t.empty}try{e==="none"&&(e=s.colors.booths.default),l(e)}catch(t){e=s.colors.booths.default,console.error("Booth: defaultColor",t)}return e}get selectedColorInterpolateFunc(){const o=s.colors.booths.seectedLight||(l(this.booth.labelColor||s.boothLabelColor).isLight()?"#000":"#fff"),e=n.selectedRoute?s?.colors?.booths?.wayfinding?.selected:s?.colors?.booths?.selected;return S([o,e])}getBoothColor(){const o=this.booth;if(n.heatmap)return this.getHeatmapColor();let e;o.error?e="#f33":a.isRebooking?e=this.defaultColor:o.selected?e=this.selectedColorInterpolateFunc(this.boothShape.selectBgAnimationPart):this.poiHighlighted?e=s.colors.booths.selected:e=this.defaultColor;let t;try{t=l(e==="none"?"#f33":e)}catch{t=l(this.defaultColor)}return(o.hover&&!o.selected||o.selected&&a.isRebooking)&&(t=t.darken(.2).alpha(t.alpha()*1.5)),(n.monochrome||n.heatmapYah)&&(t=t.grayscale()),t}}d([u({keepAlive:!0})],c.prototype,"defaultColor",null),d([u({keepAlive:!0})],c.prototype,"selectedColorInterpolateFunc",null);
1
+ import{__decorate as d}from"tslib";import{Rect as y}from"@expofp/geometry";import{update as B}from"@expofp/renderer";import l from"color";import S from"color-interpolate";import{computed as u}from"mobx";import a from"../../../../data";import{getFpSvgJs as k}from"../../../../data/fp-payloads";import{createShapeDef as D}from"../../../../engine/defs";import v,{boothStore as x,heatmapStore as H,layersStore as m,uiState as n}from"../../../../store";import{RegularBooth as I,SpecialBooth as L}from"../../../../store/BoothStore";import{RebookingState as P}from"../../../../store/ExhibitorStore";import{LayersMode as R}from"../../../../store/LayerStore";import{rebookingStateConfig as g}from"../../../../tools/rebooking-config";import s from"../../../../tools/settings";import{planReaction as b}from"../../../../utils/plan-reactions.js";import{BoothDrawerBaseWithoutPainter as w}from"./BoothDrawerBase";import{buildPathDef as A}from"./config-bg";export default function F(i){return new c(i)}function W(i){if(i.length===0)return null;const o=i[0];return i.every(t=>t===o)?o:null}export function pathToShapeDef(i,o){const e=[];for(const t of i){const r=A({index:t.index,color:t.color,unblinking:t.unblinking},o);r&&e.push(r)}return e}class c extends w{constructor(o){if(super(o),o.paths){const e=pathToShapeDef(o.paths,v.layerStore.mode!==R.Default?o.layer.name:"");o.shapes=e.map(t=>{const r=n.monochrome?l(t.color).grayscale().rgb().string():this.getBoothColor().string();return t.color==="transparent"?t.color=r:t.defaultColor=t.color,t})}else{const e=o.borderColor==="none"?0:isNaN(o.borderWidth)?x.borderWidth:o.borderWidth,t=this.booth.rect.expand(-e/2),r=this.getBoothColor().string();o.shapes=[D(new y(t.center,t.size,this.booth.rotate,this.booth.elevation),r)]}b(()=>this.booth.hover,()=>!this.booth.selected&&this.update()),b(()=>[m.layersLoaded,this.booth.skipDim,this.booth.selected,this.boothShape.selectBgAnimationPart],()=>this.update())}getShape(){return this.booth.shapes}update(){if(m.layersLoaded)for(const o of this.booth.shapes){if(o.dim=this.booth.skipDim?0:void 0,o.color&&!o.unblinking){const e=o.defaultColor?this.getBoothPathColor(o.defaultColor):this.getBoothColor();o.color=e.string()}B(o)}}get poiHighlighted(){const o=this.booth;return!o.selected&&o.poiTypeId!=null&&o.skipDim}getBoothPathColor(o){if(n.heatmap)return this.getHeatmapColor();const e=this.booth,t=s.colors.booths.selected;let r=l(this.poiHighlighted?t:o).hsl();if(e.selected){if(k().__fpSettings?.fpVer){const p=this.selectedColorInterpolateFunc(this.boothShape.selectBgAnimationPart),f=l(p==="none"?t:p);return n.monochrome?f.grayscale():f}const h=l(t).hsl(),C=h.lightness()*this.boothShape.selectBgAnimationPart;r=r.hue(h.hue()).lightness(C)}else e.hover&&(r=r.darken(.1));return n.monochrome&&(r=r.grayscale()),r}getHeatmapColor(){const o=this.booth,e=H.getHeatmapColorForBooth(o);if(o.selected){const t=this.selectedColorInterpolateFunc(this.boothShape.selectBgAnimationPart);return l(t==="none"?"#f33":t)}return o.hover?e.darken(.2).alpha(e.alpha()*1.5):e}get defaultColor(){const o=this.booth;let e=s.colors.booths.default;if(o instanceof L)e=o.color||s.colors.booths.empty;else if(o instanceof I){if(a.isRebooking){if(!o.exhibitors?.length)return g[P.Unasked].color.primary;const r=W((o.exhibitors??[]).map(h=>h.rebookingState));return r!==null?g[r].color.primary:"#000000"}const t=s.colors.booths;o.onHold?e=o.holdColor||t.defaultHold:o.exhibitors.length||o.reserved?e=o.soldColor||t.defaultSold:e=o.availColor||t.empty}try{e==="none"&&(e=s.colors.booths.default),l(e)}catch(t){e=s.colors.booths.default,console.error("Booth: defaultColor",t)}return e}get selectedColorInterpolateFunc(){const o=s.colors.booths.seectedLight||(l(this.booth.labelColor||s.boothLabelColor).isLight()?"#000":"#fff"),e=n.selectedRoute?s?.colors?.booths?.wayfinding?.selected:s?.colors?.booths?.selected;return S([o,e])}getBoothColor(){const o=this.booth;if(n.heatmap)return this.getHeatmapColor();let e;o.error?e="#f33":a.isRebooking?e=this.defaultColor:o.selected?e=this.selectedColorInterpolateFunc(this.boothShape.selectBgAnimationPart):this.poiHighlighted?e=s.colors.booths.selected:e=this.defaultColor;let t;try{t=l(e==="none"?"#f33":e)}catch{t=l(this.defaultColor)}return(o.hover&&!o.selected||o.selected&&a.isRebooking)&&(t=t.darken(.2).alpha(t.alpha()*1.5)),(n.monochrome||n.heatmapYah)&&(t=t.grayscale()),t}}d([u({keepAlive:!0})],c.prototype,"defaultColor",null),d([u({keepAlive:!0})],c.prototype,"selectedColorInterpolateFunc",null);
@@ -1 +1 @@
1
- import{Rect as m}from"@expofp/geometry";import{update as d}from"@expofp/renderer";import{reaction as i}from"mobx";import{createBookmarkCanvas as p}from"../../../../engine/canvases";import{createImageDef as u}from"../../../../engine/defs";import{getClampedBoundsCanvas as k,getQuarterTurns as c,getRollValue as l,rotateRectByQuarters as f}from"../../../../engine/update-def";import{layersStore as a,uiState as s}from"../../../../store";import{BoothDrawerBaseWithoutPainter as b}from"./BoothDrawerBase";export default function B(r){if(!s.kiosk)return new BoothBookmarkDrawer(r)}export class BoothBookmarkDrawer extends b{constructor(t){super(t),this.getShape=()=>this.shape,this.padding=this.booth.borderWidth/2,this.rect=new m(this.booth.rect.center,this.booth.rect.size,this.booth.rotate,this.booth.elevation),this.canvas=p(11,devicePixelRatio),this.bookmarkId=`bookmark-${this.booth.id}`,this.shape=u(this.canvas,this.rect,{hidden:!t.bookmarked}),this.shape.onScale=({pixelSize:e})=>this.layOutBookmark(e),i(()=>[t.bookmarked,a.layersLoaded,this.booth.skipDim],()=>this.update(t.bookmarked),{fireImmediately:t.bookmarked}),i(()=>s.mapSettings,({roll:e})=>{l(e??0)&&(this.shape.onRoll=({roll:h,pixelSize:n})=>{const o=c(h,this.rect.rotation);if(o!==0)return this.rect=f(this.rect,o),this.layOutBookmark(n),[this.shape]})},{fireImmediately:!0})}update(t){a.layersLoaded&&(this.shape.hidden=!t,this.shape.dim=this.booth.skipDim?0:void 0,d(this.shape))}layOutBookmark(t){return this.shape.bounds=k(this.rect,this.canvas,this.padding,t),this.shape.hidden?[]:[this.shape]}}
1
+ import{Rect as m}from"@expofp/geometry";import{update as d}from"@expofp/renderer";import{createBookmarkCanvas as p}from"../../../../engine/canvases";import{createImageDef as u}from"../../../../engine/defs";import{getClampedBoundsCanvas as k,getQuarterTurns as c,getRollValue as l,rotateRectByQuarters as f}from"../../../../engine/update-def";import{layersStore as i,uiState as a}from"../../../../store";import{planReaction as s}from"../../../../utils/plan-reactions.js";import{BoothDrawerBaseWithoutPainter as b}from"./BoothDrawerBase";export default function B(r){if(!a.kiosk)return new BoothBookmarkDrawer(r)}export class BoothBookmarkDrawer extends b{constructor(t){super(t),this.getShape=()=>this.shape,this.padding=this.booth.borderWidth/2,this.rect=new m(this.booth.rect.center,this.booth.rect.size,this.booth.rotate,this.booth.elevation),this.canvas=p(11,devicePixelRatio),this.bookmarkId=`bookmark-${this.booth.id}`,this.shape=u(this.canvas,this.rect,{hidden:!t.bookmarked}),this.shape.onScale=({pixelSize:e})=>this.layOutBookmark(e),s(()=>[t.bookmarked,i.layersLoaded,this.booth.skipDim],()=>this.update(t.bookmarked),{fireImmediately:t.bookmarked}),s(()=>a.mapSettings,({roll:e})=>{l(e??0)&&(this.shape.onRoll=({roll:h,pixelSize:n})=>{const o=c(h,this.rect.rotation);if(o!==0)return this.rect=f(this.rect,o),this.layOutBookmark(n),[this.shape]})},{fireImmediately:!0})}update(t){i.layersLoaded&&(this.shape.hidden=!t,this.shape.dim=this.booth.skipDim?0:void 0,d(this.shape))}layOutBookmark(t){return this.shape.bounds=k(this.rect,this.canvas,this.padding,t),this.shape.hidden?[]:[this.shape]}}
@@ -1 +1 @@
1
- import{Polygon as w,Rect as S}from"@expofp/geometry";import{update as W}from"@expofp/renderer";import l from"color";import{reaction as k}from"mobx";import{createShapeDef as D}from"../../../../engine/defs";import{boothStore as p,heatmapStore as P,layersStore as m,uiState as f}from"../../../../store";import a from"../../../../tools/settings";import{BoothDrawerBaseWithoutPainter as v}from"./BoothDrawerBase";export default function L(s){if(a.EXPO!=="confex20"&&!(s.poiType||s.borderColor==="none"||s.borderWidth===0&&!p.borderWidth||s.paths&&!s.pathsWithRect))return new R(s)}class R extends v{constructor(o){super(o);const i=this.booth.rect,{x:e,y:r}=i.center,{width:n,height:h}=i.size,t=o.borderWidth||p.borderWidth,c=[],d=(y,B,b,C)=>{const x=new S({x:y,y:B},{x:b,y:C},0,o.elevation).toPolygon();c.push(x.rotate(o.rotate??0,{x:e,y:r}))};d(e,r-h/2,n+t,t),d(e,r+h/2,n+t,t),d(e-n/2,r,t,h+t),d(e+n/2,r,t,h+t);const u=w.merge(...c),g=this.getBorderColor();this.shape=D(u,g.string()),k(()=>[this.booth.skipDim,m.layersLoaded,this.booth.hover,this.booth.selected,f.heatmap],()=>{m.layersLoaded&&(this.shape.dim=this.booth.skipDim?!1:void 0,this.shape.color=this.getBorderColor().string(),W(this.shape))})}getBorderColor(){const o=this.booth;if(f.heatmap){const e=P.getHeatmapColorForBooth(o);if(o.selected){const r=a.colors.booths.selectedBorder;return r?l(r):e.darken(.4)}return o.hover?e.darken(.3):e.darken(.2)}const i=o.selected?a.colors.booths.selectedBorder:o.borderColor;return l(i||a.colors.booths.default)}getShape(){return this.shape}}
1
+ import{Polygon as w,Rect as S}from"@expofp/geometry";import{update as W}from"@expofp/renderer";import l from"color";import{createShapeDef as k}from"../../../../engine/defs";import{boothStore as p,heatmapStore as D,layersStore as m,uiState as f}from"../../../../store";import a from"../../../../tools/settings";import{planReaction as P}from"../../../../utils/plan-reactions.js";import{BoothDrawerBaseWithoutPainter as v}from"./BoothDrawerBase";export default function L(s){if(a.EXPO!=="confex20"&&!(s.poiType||s.borderColor==="none"||s.borderWidth===0&&!p.borderWidth||s.paths&&!s.pathsWithRect))return new R(s)}class R extends v{constructor(o){super(o);const i=this.booth.rect,{x:e,y:r}=i.center,{width:n,height:h}=i.size,t=o.borderWidth||p.borderWidth,c=[],d=(y,B,b,C)=>{const x=new S({x:y,y:B},{x:b,y:C},0,o.elevation).toPolygon();c.push(x.rotate(o.rotate??0,{x:e,y:r}))};d(e,r-h/2,n+t,t),d(e,r+h/2,n+t,t),d(e-n/2,r,t,h+t),d(e+n/2,r,t,h+t);const u=w.merge(...c),g=this.getBorderColor();this.shape=k(u,g.string()),P(()=>[this.booth.skipDim,m.layersLoaded,this.booth.hover,this.booth.selected,f.heatmap],()=>{m.layersLoaded&&(this.shape.dim=this.booth.skipDim?0:void 0,this.shape.color=this.getBorderColor().string(),W(this.shape))})}getBorderColor(){const o=this.booth;if(f.heatmap){const e=D.getHeatmapColorForBooth(o);if(o.selected){const r=a.colors.booths.selectedBorder;return r?l(r):e.darken(.4)}return o.hover?e.darken(.3):e.darken(.2)}const i=o.selected?a.colors.booths.selectedBorder:o.borderColor;return l(i||a.colors.booths.default)}getShape(){return this.shape}}
@@ -1,2 +1,2 @@
1
- import{Rect as u}from"@expofp/geometry";import{update as L}from"@expofp/renderer";import{reaction as m}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as g,FONT_WEIGHT_PRIMARY_SPECIAL as y}from"../../../../constants";import{createTextDef as F}from"../../../../engine/defs";import{loadCustomFontsUrls as D}from"../../../../engine/fonts";import{getQuarterTurns as x,getRollValue as R,rotateRectByQuarters as S,rotateTextDefByQuarters as T,shouldFlip as v}from"../../../../engine/update-def";import{heatmapStore as B,layersStore as I,uiState as b}from"../../../../store";import{SpecialBooth as w}from"../../../../store/BoothStore";import z from"../../../../tools/settings";import{getFont as O}from"./canvases";import{BoothLabelDrawer as C,getFontUrlByWeight as M,getMinZoomFactorForDot as P}from"./config-booth-labels";import{LABEL_MARGIN_FRACTION as f}from"./label-inset.js";import _ from"./TextFitter";const l=new Map;function A(i){let t=l.get(i);if(!t){const s=[18,16,14,12,10,7].map(o=>o*i),e=14*i;t=new _(O,s,e),l.set(i,t),setTimeout(()=>l.delete(i),5e3)}return t}export default function N(i){if(!(!(i instanceof w)||i.noLabels))return new V(i)}class V extends C{constructor(t){super(t),this.steps=[],this.text="";const s=this.booth.rect,e=Number(getComputedStyle(document.body).getPropertyValue(y))||Number(getComputedStyle(document.body).getPropertyValue(g))||500,o=M(e,D()),r=s.expand({x:-(s.size.width*f+this.padding),y:-(s.size.height*f+this.padding)});this.setText(),this.canvasRect=new u(r.center,r.size,t.rotate,t.elevation),this.setFactors(this.text),this.labelIsVertical=Math.abs(Math.abs(t.rotate)-Math.PI/2)<.01,this.fontSizes=[this.steps,[]],this.minZoomDotVisible=P(this.steps.map(a=>a.scaleFactor)),this.shapeLabel=F([{text:this.text,color:t.labelColor||z.boothLabelColor,fontUrl:o,fontSize:0}],new u(r.center,r.size,t.rotate,t.elevation),[this.padding,this.padding],{horizontal:"center",text:"center",vertical:"center"}),this.shapeLabel.onScale=({pixelSize:a})=>this.layOutLabel(a),this.getShapeDot(),m(()=>I.layersLoaded&&this.booth.skipDim===!0,a=>{this.shapeLabel.dim=a?0:void 0,this.shapeDot.dim=a?0:void 0,L(this.shapeLabel,this.shapeDot)}),m(()=>b.mapSettings,({roll:a})=>{R(a??0)&&(this.shapeLabel.onRoll=({roll:c,pixelSize:p})=>{const h=this.shapeLabel.bounds.rotation;if(this.labelIsVertical)return v(c,h)?(this.shapeLabel.bounds.rotate(-2*h,this.shapeLabel.bounds),[this.shapeLabel,this.shapeDot]):void 0;const n=x(c,h);if(n===0)return;const{size:d}=this.canvasRect;return this.shapeLabel=T(this.shapeLabel,n),d.x!==d.y&&!this.shapeLabel.hidden&&(this.canvasRect=S(this.canvasRect,n),this.setFactors(this.text),this.layOutLabel(p),this.layOutDot(p)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0})}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const s=this.steps.find(e=>e.scaleFactor<1/t);return s?(this.shapeLabel.lines[0].fontSize=s.value*t,this.shapeLabel.lines[0].text=s.lines.join(`
2
- `),this.shapeLabel.padding=[this.paddingScaled[0]*t+this.padding,this.paddingScaled[1]*t+this.padding],[this.shapeLabel]):(this.shapeLabel.lines[0].fontSize=0,[this.shapeLabel])}layOutDot(t){const s=this.steps.find(r=>r.scaleFactor<1/t),e=this.shapeDot.bounds,o=this.shapeDot.source;return e.scale({x:o.width*t/e.size.x,y:o.height*t/e.size.y},e.center,e),this.shapeDot.hidden=!!s,[this.shapeDot]}setFactors(t){this.steps=A(devicePixelRatio).getStepsForRect(t,this.canvasRect.size.x,this.canvasRect.size.y)}setText(){const t=this.booth.title||this.booth.name,e=`Clicks: ${B.getTotalClicksByBooth(this.booth)}`;this.text=b.heatmap?`${t} - ${e}`:t}}
1
+ import{Rect as u}from"@expofp/geometry";import{update as L}from"@expofp/renderer";import{reaction as m}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as g,FONT_WEIGHT_PRIMARY_SPECIAL as y}from"../../../../constants";import{createTextDef as F}from"../../../../engine/defs";import{loadCustomFontsUrls as D}from"../../../../engine/fonts";import{getQuarterTurns as x,getRollValue as S,rotateRectByQuarters as R,rotateTextDefByQuarters as T,shouldFlip as v}from"../../../../engine/update-def";import{heatmapStore as B,layersStore as I,uiState as f}from"../../../../store";import{SpecialBooth as z}from"../../../../store/BoothStore";import{eventScopedCache as C}from"../../../../tools/event-scoped-cache.js";import O from"../../../../tools/settings";import{getFont as w}from"./canvases";import{BoothLabelDrawer as M,getFontUrlByWeight as P,getMinZoomFactorForDot as _}from"./config-booth-labels";import{LABEL_MARGIN_FRACTION as b}from"./label-inset.js";import A from"./TextFitter";const l=C();function N(i){let t=l().get(i);if(!t){const s=[18,16,14,12,10,7].map(o=>o*i),e=14*i;t=new A(w,s,e),l().set(i,t),setTimeout(()=>l().delete(i),5e3)}return t}export default function V(i){if(!(!(i instanceof z)||i.noLabels))return new k(i)}class k extends M{constructor(t){super(t),this.steps=[],this.text="";const s=this.booth.rect,e=Number(getComputedStyle(document.body).getPropertyValue(y))||Number(getComputedStyle(document.body).getPropertyValue(g))||500,o=P(e,D()),r=s.expand({x:-(s.size.width*b+this.padding),y:-(s.size.height*b+this.padding)});this.setText(),this.canvasRect=new u(r.center,r.size,t.rotate,t.elevation),this.setFactors(this.text),this.labelIsVertical=Math.abs(Math.abs(t.rotate)-Math.PI/2)<.01,this.fontSizes=[this.steps,[]],this.minZoomDotVisible=_(this.steps.map(a=>a.scaleFactor)),this.shapeLabel=F([{text:this.text,color:t.labelColor||O.boothLabelColor,fontUrl:o,fontSize:0}],new u(r.center,r.size,t.rotate,t.elevation),[this.padding,this.padding],{horizontal:"center",text:"center",vertical:"center"}),this.shapeLabel.onScale=({pixelSize:a})=>this.layOutLabel(a),this.getShapeDot(),m(()=>I.layersLoaded&&this.booth.skipDim===!0,a=>{this.shapeLabel.dim=a?0:void 0,this.shapeDot.dim=a?0:void 0,L(this.shapeLabel,this.shapeDot)}),m(()=>f.mapSettings,({roll:a})=>{S(a??0)&&(this.shapeLabel.onRoll=({roll:c,pixelSize:p})=>{const h=this.shapeLabel.bounds.rotation;if(this.labelIsVertical)return v(c,h)?(this.shapeLabel.bounds.rotate(-2*h,this.shapeLabel.bounds),[this.shapeLabel,this.shapeDot]):void 0;const n=x(c,h);if(n===0)return;const{size:d}=this.canvasRect;return this.shapeLabel=T(this.shapeLabel,n),d.x!==d.y&&!this.shapeLabel.hidden&&(this.canvasRect=R(this.canvasRect,n),this.setFactors(this.text),this.layOutLabel(p),this.layOutDot(p)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0})}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const s=this.steps.find(e=>e.scaleFactor<1/t);return s?(this.shapeLabel.lines[0].fontSize=s.value*t,this.shapeLabel.lines[0].text=s.lines.join(`
2
+ `),this.shapeLabel.padding=[this.paddingScaled[0]*t+this.padding,this.paddingScaled[1]*t+this.padding],[this.shapeLabel]):(this.shapeLabel.lines[0].fontSize=0,[this.shapeLabel])}layOutDot(t){const s=this.steps.find(r=>r.scaleFactor<1/t),e=this.shapeDot.bounds,o=this.shapeDot.source;return e.scale({x:o.width*t/e.size.x,y:o.height*t/e.size.y},e.center,e),this.shapeDot.hidden=!!s,[this.shapeDot]}setFactors(t){this.steps=N(devicePixelRatio).getStepsForRect(t,this.canvasRect.size.x,this.canvasRect.size.y)}setText(){const t=this.booth.title||this.booth.name,e=`Clicks: ${B.getTotalClicksByBooth(this.booth)}`;this.text=f.heatmap?`${t} - ${e}`:t}}
@@ -1 +1 @@
1
- import{Rect as B}from"@expofp/geometry";import{update as H}from"@expofp/renderer";import{reaction as M}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as U,FONT_WEIGHT_PRIMARY_EXHIBITOR as V,FONT_WEIGHT_SECONDARY_BOOTH as Z,FONT_WEIGHT_SECONDARY_EXHIBITOR as X}from"../../../../constants";import c from"../../../../data";import{createShapeDot as G,createTextDef as Y,createTextDefLines as Q}from"../../../../engine/defs";import{DEFAULT_FONT_LIGHT_URL as $,DEFAULT_FONT_URL as W,loadCustomFontsUrls as q}from"../../../../engine/fonts";import{getQuarterTurns as j,getRollValue as k,rotateRectByQuarters as J,rotateTextDefByQuarters as K,updateLinesScale as tt}from"../../../../engine/update-def";import{boothStore as et,layersStore as it,uiState as f}from"../../../../store";import{RegularBooth as st,SpecialBooth as ot}from"../../../../store/BoothStore";import D from"../../../../tools/settings";import{t as S}from"../../../../utils/i18n";import nt from"../../../../utils/is-mobile";import at from"../../../../utils/is-webview";import{isArabicText as rt}from"../../../../utils/rtl";import{BoothDrawerBaseWithoutPainter as ht}from"./BoothDrawerBase";import{getFont as _}from"./canvases";import{getLabelBorderInset as lt}from"./label-inset.js";let z=D.boothLabelColor;D.EXPO==="tqs2021"&&(z="#000");const x=nt||at,F=n=>n.replace(" ","").substring(0,4).replace(/[0-9]/g,"3").replace(/[A-Z]/gi,"A"),I=document.createElement("canvas").getContext("2d");export default function ct(n){if(!(!(n instanceof st)||n.noLabels))return new BoothLabelDrawer(n)}export function getMinZoomFactorForDot(n){return Array.isArray(n)&&n.length>0?Math.max(...n.map(t=>t)):typeof n=="number"?n:-0}export const isDirectionsMode=()=>!!(f.selectedRoute?.from&&f.selectedRoute?.to);export function getFontUrlByWeight(n,t=[],e="normal"){return[...t,{weight:500,url:W,style:"normal"},{weight:300,url:$,style:"normal"}].find(s=>+s.weight===n&&s.style===e)?.url||W}function b(n,t){return Number(getComputedStyle(document.body).getPropertyValue(n))||t}export function getBoothLabelWeights(){return{main:b(U,500),details:b(Z,300)}}export function getExhibitorLabelWeights(){return{main:b(V,500),details:b(X,300)}}export function getBadgeFontWeight(){return getExhibitorLabelWeights().details}const y="Details";export class BoothLabelDrawer extends ht{constructor(t){super(t),this.minZoomDotVisible=0,this.maxZoomDotVisible=0,this.exh=[],this.shapeLabel=void 0,this.shapeDot=void 0,this.fontSizes=[[],[]],this.lines=[[],[]],this.fontUrls=["",""],this.canvasRect=new B(t.rect.center,t.rect.size,t.rotate,t.elevation),this.paddingScaled=[4,4],this.padding=lt(t.borderWidth||et.borderWidth,t.rect.size),this.topLeftAlignment={horizontal:f.rtl?"right":"left",vertical:"top"},this.centerAlignment={horizontal:"center",vertical:"center"},this.prefixes=x?[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:16,name:y,short:!1}]:[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:12,name:"M",short:!0},{fontSize:14,name:"L",short:!0},{fontSize:18,name:y,short:!1}],!(t instanceof ot)&&(this.exh=c.hideExhibitors?[]:c.onlyFeaturedExhibitors?t.exhibitors.filter(e=>e.featured):t.exhibitors,x&&this.optimizationLevel()>=3&&(this.prefixes=this.prefixes.filter(e=>e.name!=="S")),this.createLines(),this.calculateFontSizeFactors(),this.shapeLabel=Y(Q(this.lines,this.booth.labelColor||z,0,this.fontUrls),new B(this.booth.rect.center,this.booth.rect.size,this.booth.rotate,this.booth.elevation),[...this.paddingScaled],{horizontal:"left",vertical:"top"}),this.shapeLabel.onScale=({pixelSize:e})=>this.layOutLabel(e),this.getShapeDot(),M(()=>it.layersLoaded&&this.booth.skipDim===!0,e=>{this.shapeLabel.dim=e?0:void 0,this.shapeDot.dim=e?0:void 0,H(this.shapeLabel,this.shapeDot)}),M(()=>f.mapSettings,({roll:e})=>{k(e??0)&&(this.shapeLabel.onRoll=({roll:i,pixelSize:a})=>{const s=j(i,this.shapeLabel.bounds.rotation);if(s===0)return;const{size:r}=this.canvasRect;return this.shapeLabel=K(this.shapeLabel,s),!this.shapeLabel.hidden&&!this.exh.length&&r.x!==r.y&&(this.canvasRect=J(this.canvasRect,s),this.calculateFontSizeFactors(),this.layOutLabel(a),this.layOutDot(a)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0}))}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const e=this.lines[1]??[],i=this.fontSizes[1]??[];if(D.EXPO!=="wineparis2026"){const s=this.exh.length?this.topLeftAlignment:e.length?t<i[i.length-1].scaleFactor?this.topLeftAlignment:this.centerAlignment:this.topLeftAlignment;this.shapeLabel.alignment=s}return tt(this.shapeLabel.lines,t,this.fontSizes)?(this.shapeLabel.padding[0]=this.paddingScaled[0]*t+this.padding,this.shapeLabel.padding[1]=this.paddingScaled[1]*t+this.padding,[this.shapeLabel]):[]}layOutDot(t){const e=t>=this.minZoomDotVisible&&t<=this.maxZoomDotVisible;if(!e&&this.shapeDot.hidden)return[];const i=this.shapeDot.bounds,a=this.shapeDot.source;return i.scale({x:a.width*t/i.size.x,y:a.height*t/i.size.y},i.center,i),this.shapeDot.hidden=!e,[this.shapeDot]}getShapeDot(){this.shapeDot=G(this.canvasRect,this.booth.labelColor||z),this.shapeDot.hidden=!0,this.shapeDot.onScale=({pixelSize:e})=>this.layOutDot(e);const t=this.shapeDot.source;this.maxZoomDotVisible=Math.min(this.canvasRect.size.x/t.width,this.canvasRect.size.y/t.height)}createLines(){const t=this.booth,e=[],i=[],a=x&&this.optimizationLevel()>=3?1:3;if(this.exh.length){const s=t.exhibitors.filter(o=>o.order===0),r=t.exhibitors.filter(o=>o.order);if(s.length>0)e.push(...s.map(o=>o.name));else if(c.onlyFeaturedExhibitors)e.push(...t.exhibitors.filter(o=>o.featured).map(o=>o.name));else if(r.length>0){e.push(...r.map(m=>m.name));const o=t.exhibitors.filter(m=>m.order===void 0);o.length>0&&e.push(S("and {{moreCount}} more",{moreCount:o.length}))}else t.exhibitors.length>a?e.push(`${t.exhibitors.length} ${c.exhibitorTermPlural}`):e.push(...t.exhibitors.map(o=>o.name));i.push(t.title||t.name)}else{const s=!!t.exhibitors.length;e.push(t.title||t.name),t.onHold?i.push(S("On Hold")):t.reserved?i.push(S("Reserved")):s||i.push(...t.exhibitors.map(r=>r.name).sort((r,o)=>r>o?1:-1)),t.size&&i.push(t.size.indexOf("/")>-1?t.size.substring(0,t.size.indexOf("/")).trim():t.size),t.price&&t.price!=="0"&&!f.previewMode&&i.push(t.price)}f.rtl&&e.forEach((s,r)=>{(s.endsWith(".")||s.endsWith("!")||s.endsWith("?"))&&(e[r]=e[r]+"\u200F"),rt(s)&&(e[r]=e[r]+" ")}),this.lines=[e,i]}calculateFontSizeFactors(){const t=this.lines[0];let e;const i=this.canvasRect,a=[],s=[],r=this.prefixes.slice(0,this.exh.length?this.prefixes.length:this.prefixes.length-1),{main:o,details:m}=this.exh.length?getExhibitorLabelWeights():getBoothLabelWeights();for(const{fontSize:l,short:u}of r){const p=l*devicePixelRatio,L=.9*l*devicePixelRatio,d=_(p,o),T=_(L,m),O=c.hideExhibitorBoothNumber||u;let w,A,v,g;if(this.exh.length)e=u?[]:this.lines[1],v=Math.max(...t.map(h=>this.measureText(h,d).width),...e.map(h=>this.measureText(h,T).width)),w=Math.max(...t.map(h=>this.exh.length?this.measureText(F(h),d).width:this.measureText(F(h),d).width+3+3),...e.map(h=>this.measureText(F(h),T).width)),g=p*t.length+L*e.length+devicePixelRatio*(t.length+e.length)+3,A=O?g/t.length:null;else{const h=t[0].replace(/[0-9]/g,"3").replace(/[A-Z]/g,"A"),N=4;v=this.measureText(h,d).width+3+3,g=p+N}const P=i.size.x/(w||v),C=i.size.y/(A||g),E=Math.min(P,C);a.push({scaleFactor:E,value:p,lines:[]}),O||s.push({scaleFactor:E,value:L,lines:[]})}if(!this.exh.length){const l=a[a.length-1],u=this.prefixes.find(p=>p.name===y);u&&(a.push({scaleFactor:l.scaleFactor/1.8,value:u.fontSize*devicePixelRatio,lines:[]}),s.push({scaleFactor:l.scaleFactor/1.8,value:u.fontSize*(x?1:.9)*devicePixelRatio,lines:[]}))}const R=q();this.fontUrls=[getFontUrlByWeight(o,R),getFontUrlByWeight(m,R)],this.minZoomDotVisible=getMinZoomFactorForDot(a.map(l=>l.scaleFactor)),this.fontSizes=[a,s]}calcArea(t,e){return Math.floor(Math.max(0,t)*Math.max(0,e)/1e3)}optimizationLevel(){return Math.min(c.viewOptimizationLevel?c.viewOptimizationLevel:Math.floor(this.calcArea(this.canvasRect.size.x,this.canvasRect.size.y)/5e3),3)}measureText(t,e){return I.font=e,I.measureText(t)}}
1
+ import{Rect as E}from"@expofp/geometry";import{update as H}from"@expofp/renderer";import{FONT_WEIGHT_PRIMARY_BOOTH as U,FONT_WEIGHT_PRIMARY_EXHIBITOR as V,FONT_WEIGHT_SECONDARY_BOOTH as Z,FONT_WEIGHT_SECONDARY_EXHIBITOR as X}from"../../../../constants";import c from"../../../../data";import{createShapeDot as G,createTextDef as Y,createTextDefLines as Q}from"../../../../engine/defs";import{DEFAULT_FONT_LIGHT_URL as $,DEFAULT_FONT_URL as B,loadCustomFontsUrls as q}from"../../../../engine/fonts";import{getQuarterTurns as j,getRollValue as k,rotateRectByQuarters as J,rotateTextDefByQuarters as K,updateLinesScale as tt}from"../../../../engine/update-def";import{boothStore as et,layersStore as it,uiState as f}from"../../../../store";import{RegularBooth as st,SpecialBooth as ot}from"../../../../store/BoothStore";import D from"../../../../tools/settings";import{t as S}from"../../../../utils/i18n";import nt from"../../../../utils/is-mobile";import at from"../../../../utils/is-webview";import{planReaction as M}from"../../../../utils/plan-reactions.js";import{isArabicText as rt}from"../../../../utils/rtl";import{BoothDrawerBaseWithoutPainter as ht}from"./BoothDrawerBase";import{getFont as W}from"./canvases";import{getLabelBorderInset as lt}from"./label-inset.js";function _(){return D.EXPO==="tqs2021"?"#000":D.boothLabelColor}const x=nt||at,z=n=>n.replace(" ","").substring(0,4).replace(/[0-9]/g,"3").replace(/[A-Z]/gi,"A"),I=document.createElement("canvas").getContext("2d");export default function ct(n){if(!(!(n instanceof st)||n.noLabels))return new BoothLabelDrawer(n)}export function getMinZoomFactorForDot(n){return Array.isArray(n)&&n.length>0?Math.max(...n.map(t=>t)):typeof n=="number"?n:-0}export const isDirectionsMode=()=>!!(f.selectedRoute?.from&&f.selectedRoute?.to);export function getFontUrlByWeight(n,t=[],e="normal"){return[...t,{weight:500,url:B,style:"normal"},{weight:300,url:$,style:"normal"}].find(s=>+s.weight===n&&s.style===e)?.url||B}function b(n,t){return Number(getComputedStyle(document.body).getPropertyValue(n))||t}export function getBoothLabelWeights(){return{main:b(U,500),details:b(Z,300)}}export function getExhibitorLabelWeights(){return{main:b(V,500),details:b(X,300)}}export function getBadgeFontWeight(){return getExhibitorLabelWeights().details}const F="Details";export class BoothLabelDrawer extends ht{constructor(t){super(t),this.minZoomDotVisible=0,this.maxZoomDotVisible=0,this.exh=[],this.shapeLabel=void 0,this.shapeDot=void 0,this.fontSizes=[[],[]],this.lines=[[],[]],this.fontUrls=["",""],this.canvasRect=new E(t.rect.center,t.rect.size,t.rotate,t.elevation),this.paddingScaled=[4,4],this.padding=lt(t.borderWidth||et.borderWidth,t.rect.size),this.topLeftAlignment={horizontal:f.rtl?"right":"left",vertical:"top"},this.centerAlignment={horizontal:"center",vertical:"center"},this.prefixes=x?[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:16,name:F,short:!1}]:[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:12,name:"M",short:!0},{fontSize:14,name:"L",short:!0},{fontSize:18,name:F,short:!1}],!(t instanceof ot)&&(this.exh=c.hideExhibitors?[]:c.onlyFeaturedExhibitors?t.exhibitors.filter(e=>e.featured):t.exhibitors,x&&this.optimizationLevel()>=3&&(this.prefixes=this.prefixes.filter(e=>e.name!=="S")),this.createLines(),this.calculateFontSizeFactors(),this.shapeLabel=Y(Q(this.lines,this.booth.labelColor||_(),0,this.fontUrls),new E(this.booth.rect.center,this.booth.rect.size,this.booth.rotate,this.booth.elevation),[...this.paddingScaled],{horizontal:"left",vertical:"top"}),this.shapeLabel.onScale=({pixelSize:e})=>this.layOutLabel(e),this.getShapeDot(),M(()=>it.layersLoaded&&this.booth.skipDim===!0,e=>{this.shapeLabel.dim=e?0:void 0,this.shapeDot.dim=e?0:void 0,H(this.shapeLabel,this.shapeDot)}),M(()=>f.mapSettings,({roll:e})=>{k(e??0)&&(this.shapeLabel.onRoll=({roll:i,pixelSize:a})=>{const s=j(i,this.shapeLabel.bounds.rotation);if(s===0)return;const{size:r}=this.canvasRect;return this.shapeLabel=K(this.shapeLabel,s),!this.shapeLabel.hidden&&!this.exh.length&&r.x!==r.y&&(this.canvasRect=J(this.canvasRect,s),this.calculateFontSizeFactors(),this.layOutLabel(a),this.layOutDot(a)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0}))}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const e=this.lines[1]??[],i=this.fontSizes[1]??[];if(D.EXPO!=="wineparis2026"){const s=this.exh.length?this.topLeftAlignment:e.length?t<i[i.length-1].scaleFactor?this.topLeftAlignment:this.centerAlignment:this.topLeftAlignment;this.shapeLabel.alignment=s}return tt(this.shapeLabel.lines,t,this.fontSizes)?(this.shapeLabel.padding[0]=this.paddingScaled[0]*t+this.padding,this.shapeLabel.padding[1]=this.paddingScaled[1]*t+this.padding,[this.shapeLabel]):[]}layOutDot(t){const e=t>=this.minZoomDotVisible&&t<=this.maxZoomDotVisible;if(!e&&this.shapeDot.hidden)return[];const i=this.shapeDot.bounds,a=this.shapeDot.source;return i.scale({x:a.width*t/i.size.x,y:a.height*t/i.size.y},i.center,i),this.shapeDot.hidden=!e,[this.shapeDot]}getShapeDot(){this.shapeDot=G(this.canvasRect,this.booth.labelColor||_()),this.shapeDot.hidden=!0,this.shapeDot.onScale=({pixelSize:e})=>this.layOutDot(e);const t=this.shapeDot.source;this.maxZoomDotVisible=Math.min(this.canvasRect.size.x/t.width,this.canvasRect.size.y/t.height)}createLines(){const t=this.booth,e=[],i=[],a=x&&this.optimizationLevel()>=3?1:3;if(this.exh.length){const s=t.exhibitors.filter(o=>o.order===0),r=t.exhibitors.filter(o=>o.order);if(s.length>0)e.push(...s.map(o=>o.name));else if(c.onlyFeaturedExhibitors)e.push(...t.exhibitors.filter(o=>o.featured).map(o=>o.name));else if(r.length>0){e.push(...r.map(m=>m.name));const o=t.exhibitors.filter(m=>m.order===void 0);o.length>0&&e.push(S("and {{moreCount}} more",{moreCount:o.length}))}else t.exhibitors.length>a?e.push(`${t.exhibitors.length} ${c.exhibitorTermPlural}`):e.push(...t.exhibitors.map(o=>o.name));i.push(t.title||t.name)}else{const s=!!t.exhibitors.length;e.push(t.title||t.name),t.onHold?i.push(S("On Hold")):t.reserved?i.push(S("Reserved")):s||i.push(...t.exhibitors.map(r=>r.name).sort((r,o)=>r>o?1:-1)),t.size&&i.push(t.size.indexOf("/")>-1?t.size.substring(0,t.size.indexOf("/")).trim():t.size),t.price&&t.price!=="0"&&!f.previewMode&&i.push(t.price)}f.rtl&&e.forEach((s,r)=>{(s.endsWith(".")||s.endsWith("!")||s.endsWith("?"))&&(e[r]=e[r]+"\u200F"),rt(s)&&(e[r]=e[r]+" ")}),this.lines=[e,i]}calculateFontSizeFactors(){const t=this.lines[0];let e;const i=this.canvasRect,a=[],s=[],r=this.prefixes.slice(0,this.exh.length?this.prefixes.length:this.prefixes.length-1),{main:o,details:m}=this.exh.length?getExhibitorLabelWeights():getBoothLabelWeights();for(const{fontSize:l,short:u}of r){const p=l*devicePixelRatio,L=.9*l*devicePixelRatio,d=W(p,o),R=W(L,m),T=c.hideExhibitorBoothNumber||u;let O,w,v,g;if(this.exh.length)e=u?[]:this.lines[1],v=Math.max(...t.map(h=>this.measureText(h,d).width),...e.map(h=>this.measureText(h,R).width)),O=Math.max(...t.map(h=>this.exh.length?this.measureText(z(h),d).width:this.measureText(z(h),d).width+3+3),...e.map(h=>this.measureText(z(h),R).width)),g=p*t.length+L*e.length+devicePixelRatio*(t.length+e.length)+3,w=T?g/t.length:null;else{const h=t[0].replace(/[0-9]/g,"3").replace(/[A-Z]/g,"A"),N=4;v=this.measureText(h,d).width+3+3,g=p+N}const P=i.size.x/(O||v),C=i.size.y/(w||g),A=Math.min(P,C);a.push({scaleFactor:A,value:p,lines:[]}),T||s.push({scaleFactor:A,value:L,lines:[]})}if(!this.exh.length){const l=a[a.length-1],u=this.prefixes.find(p=>p.name===F);u&&(a.push({scaleFactor:l.scaleFactor/1.8,value:u.fontSize*devicePixelRatio,lines:[]}),s.push({scaleFactor:l.scaleFactor/1.8,value:u.fontSize*(x?1:.9)*devicePixelRatio,lines:[]}))}const y=q();this.fontUrls=[getFontUrlByWeight(o,y),getFontUrlByWeight(m,y)],this.minZoomDotVisible=getMinZoomFactorForDot(a.map(l=>l.scaleFactor)),this.fontSizes=[a,s]}calcArea(t,e){return Math.floor(Math.max(0,t)*Math.max(0,e)/1e3)}optimizationLevel(){return Math.min(c.viewOptimizationLevel?c.viewOptimizationLevel:Math.floor(this.calcArea(this.canvasRect.size.x,this.canvasRect.size.y)/5e3),3)}measureText(t,e){return I.font=e,I.measureText(t)}}
@@ -1 +1 @@
1
- import{Rect as C}from"@expofp/geometry";import{update as E}from"@expofp/renderer";import G from"debug";import{reaction as M}from"mobx";import{SEPARATOR as s}from"../../../../constants";import{createImageDef as T}from"../../../../engine/defs";import{flipImageDef as U,isInnerInsideOuter as _,rotateImageDef as z}from"../../../../engine/utils/rotation";import{boothStore as $,layersStore as K,uiState as Z}from"../../../../store";import j from"../../../../tools/settings";import{loadBlobsInBatchesById as q}from"../../../../utils/loadImagesInBatches";import{clearHoveredBooth as F,hoverBooth as J,rememberBoothShapes as Q,selectBooth as V}from"../../pointer";import{createLogoPreparer as X}from"./booth-logos";import Y from"./config-booth-bg";import oo from"./config-booth-bookmark";import eo from"./config-booth-border";import to,{isDirectionsMode as ro}from"./config-booth-labels";import no from"./config-booth-labels-special";import{registerLayerImages as so}from"./layer-images";import{createBoothImg as ao,getImageLayerName as io,mapBoothsLogos as co}from"./loadBoothsImages";const k=G("efp:booth-logos");export const BOOTHS_CHUNK_SIZE=350;export default function lo(D,R){return(h=>{const e=D,g=[],p=[],d=[],u=[],B=[],L=io(e),S={name:L,children:[]};for(const o of h){const i=Y(o)?.getShape();i&&(g.push(...i),Q(o,i));const c=to(o)?.getShape();c&&p.push(...c);const l=no(o)?.getShape();if(l&&d.push(...l),!j.borderless){const t=eo(o)?.getShape();t&&u.push(t)}const m=oo(o)?.getShape();m&&B.push(m)}const x=p.filter(o=>o.lines),O=d.filter(o=>o.lines),P=p.filter(o=>o.source),w=d.filter(o=>o.source);if(!Z.hideLogoInBooth){const o=co(h);so(L,async()=>{const i=await q(o,BOOTHS_CHUNK_SIZE),c=[],l=X(),m=await Promise.all([...i].map(async([t,r])=>{const a=$.boothById.get(t);return[t,a,a?await l(a,r):null]}));for(const[t,r,a]of m){if(!r){k("dropped a logo: no booth has id %s",t);continue}if(!a){k("dropped the logo of booth %s: the image could not be read",t);continue}const{blob:v,aspectRatio:H}=a,{bounds:N}=ao(r,H),n=T(v,N),W=r.borderWidth||$.borderWidth,I=r.rect.expand(-W),A=new C(I.center,I.size,r.rotate);n.onRoll=_(n.bounds,A)?({roll:b})=>z(n,b)?[n]:void 0:({roll:b})=>U(n,b)?[n]:void 0,r.shapes.push(n),c.push(n)}return{layer:S,children:c}})}const f={name:`${e}${s}labelGroup`,children:[{name:`${e}${s}labels`,children:x},{name:`${e}${s}specialLabels`,children:O},{name:`${e}${s}dots`,children:P},{name:`${e}${s}specialDots`,children:w}]};M(()=>K.layersLoaded&&ro(),o=>{f.dim=o?0:void 0,E(f)},{fireImmediately:!0});let y=[];if(h.length){const o=e+s;y=[{name:`${o}boothBackground`,children:g,onPointerMove:J,onPointerOut:F,onClick:V},f,S,{name:`${o}boothsBookmark`,children:B},{name:`${e}${s}boothBorder`,children:u}]}return{name:e,children:y}})(R)}
1
+ import{Rect as E}from"@expofp/geometry";import{update as M}from"@expofp/renderer";import T from"debug";import{SEPARATOR as n}from"../../../../constants";import{createImageDef as U}from"../../../../engine/defs";import{flipImageDef as _,isInnerInsideOuter as z,rotateImageDef as K}from"../../../../engine/utils/rotation";import{planGeneration as u}from"../../../../plan-lifecycle.js";import{boothStore as D,layersStore as Z,uiState as j}from"../../../../store";import q from"../../../../tools/settings";import{loadBlobsInBatchesById as F}from"../../../../utils/loadImagesInBatches";import{planReaction as J}from"../../../../utils/plan-reactions.js";import{clearHoveredBooth as Q,hoverBooth as V,rememberBoothShapes as X,selectBooth as Y}from"../../pointer";import{createLogoPreparer as oo}from"./booth-logos";import eo from"./config-booth-bg";import to from"./config-booth-bookmark";import ro from"./config-booth-border";import no,{isDirectionsMode as so}from"./config-booth-labels";import io from"./config-booth-labels-special";import{registerLayerImages as ao}from"./layer-images";import{createBoothImg as co,getImageLayerName as lo,mapBoothsLogos as mo}from"./loadBoothsImages";const R=T("efp:booth-logos");export const BOOTHS_CHUNK_SIZE=350;export default function po(x,O){return(h=>{const e=x,B=[],d=[],f=[],L=[],S=[],y=lo(e),I={name:y,children:[]};for(const o of h){const s=eo(o)?.getShape();s&&(B.push(...s),X(o,s));const l=no(o)?.getShape();l&&d.push(...l);const a=io(o)?.getShape();if(a&&f.push(...a),!q.borderless){const p=ro(o)?.getShape();p&&L.push(p)}const m=to(o)?.getShape();m&&S.push(m)}const P=d.filter(o=>o.lines),w=f.filter(o=>o.lines),v=d.filter(o=>o.source),G=f.filter(o=>o.source);if(!j.hideLogoInBooth){const o=mo(h),s=u();ao(y,async()=>{const l=await F(o,BOOTHS_CHUNK_SIZE);if(u()!==s)return;const a=[],m=oo(),p=await Promise.all([...l].map(async([c,t])=>{const i=D.boothById.get(c);return[c,i,i?await m(i,t):null]}));if(u()===s){for(const[c,t,i]of p){if(!t){R("dropped a logo: no booth has id %s",c);continue}if(!i){R("dropped the logo of booth %s: the image could not be read",c);continue}const{blob:H,aspectRatio:N}=i,{bounds:W}=co(t,N),r=U(H,W),A=t.borderWidth||D.borderWidth,k=t.rect.expand(-A),C=new E(k.center,k.size,t.rotate);r.onRoll=z(r.bounds,C)?({roll:g})=>K(r,g)?[r]:void 0:({roll:g})=>_(r,g)?[r]:void 0,t.shapes.push(r),a.push(r)}return{layer:I,children:a}}})}const b={name:`${e}${n}labelGroup`,children:[{name:`${e}${n}labels`,children:P},{name:`${e}${n}specialLabels`,children:w},{name:`${e}${n}dots`,children:v},{name:`${e}${n}specialDots`,children:G}]};J(()=>Z.layersLoaded&&so(),o=>{b.dim=o?0:void 0,M(b)},{fireImmediately:!0});let $=[];if(h.length){const o=e+n;$=[{name:`${o}boothBackground`,children:B,onPointerMove:V,onPointerOut:Q,onClick:Y},b,I,{name:`${o}boothsBookmark`,children:S},{name:`${e}${n}boothBorder`,children:L}]}return{name:e,children:$}})(O)}
@@ -1 +1 @@
1
- import{Box as K}from"@expofp/geometry";import{update as v}from"@expofp/renderer";import{reaction as I}from"mobx";import{getBounds as y}from"../../../../engine/canvases";import{createImageDef as E}from"../../../../engine/defs";import l,{layersStore as R,uiState as N}from"../../../../store";import{setMarkerResolver as P}from"../../pointer";import{createImageCanvas as O}from"./canvases";const C="_selected";export const MARKER_LAYER_NAME="markers";function T(r,f){const{center:c,rotation:o,elevation:d}=r.bounds,{width:i,height:s}=r.source;return r.bounds=y(c.x,c.y,i,s,f,o,d),[r]}function V(r){L=r}export function configMarkers(r){const{scene:f}=r,c=[],o=new Map,d=new Map;let i=[];const s=f.rootLayer.children.find(e=>e.name===MARKER_LAYER_NAME);s.onScale=({pixelSize:e})=>V(e),P(markerAt),v(s);async function p(e){const n=[];e.forEach(u=>{const{name:a,content:t,width:h,height:D,scale:g}=u;if(o.has(a))return;const m=new Image,S=new Promise((M,b)=>{m.onload=()=>{o.set(a,{img:m,width:h,height:D,scale:g}),M()},m.onerror=x=>{b(x)}});n.push(S),m.src=t,m.crossOrigin="anonymous"}),await Promise.all(n)}const B=e=>{e.onScale=({pixelSize:n})=>T(e,n)},z=e=>{e.screenSpace||(e.onRoll=({roll:n})=>{if(n!==e.bounds.rotation)return e.bounds.rotate(n-e.bounds.rotation,e.bounds),[e]})};function w(e,n,u){const a=d.get(e);if(a)return a;const t=O(n.img,n.width,n.height,u);return d.set(e,t),t}function A(){const e=l.routeStore.markersData.markers;if(!e.length)return;i=[];const n=1,u=0,a=N.is3DView;e.forEach(t=>{const h=o.get(t.icon);if(!h)return;const D=o.get(t.selectedIcon);if(!D)return;const g=h.scale||window.devicePixelRatio,m=w(t.icon,h,g),S=w(t.selectedIcon,D,g),M=R.findLayer(t.z)?.visible??!0,b=y(t.x,t.y,m.width,m.height,n,u),x=y(t.x,t.y,S.width,S.height,n,u);let k;switch(t.position){case"lefttop":k=[0,0];break;case"centertop":k=[.5,0];break;case"centerbottom":k=[.5,1];break;default:k=[.5,.5]}const F={...E(m,b,{hidden:!M,origin:k}),id:t.id,scale:g,screenSpace:a},H={...E(S,x,{hidden:!(M&&t.active),origin:k}),id:`${t.id}${C}`,scale:g,screenSpace:a};i.push(F,H)}),s.children=i,i.forEach(t=>{B(t),z(t)})}function _(){s.children=[],i=[]}function $(){const e=l.routeStore.markersData.markers;e.length&&e.forEach(n=>{const u=i.find(h=>h.id===n.id),a=i.find(h=>h.id===`${n.id}${C}`);if(!u||!a)return;const t=R.findLayer(n.z)?.visible??!0;n.active?(u.hidden=!0,a.hidden=!(t&&n.active)):(u.hidden=!t,a.hidden=!0)})}return c.push(I(()=>[l.routeStore.selectedMarkers,l.layerStore.visible],()=>{if(!l.routeStore.markersData.markers.length){_(),v(s);return}$(),v(...i)})),c.push(I(()=>l.routeStore.markersData.markers,()=>{p(l.routeStore.markersData.icons).then(()=>{A(),v(s)})},{fireImmediately:!0})),function(){c.forEach(n=>n()),c.length=0,s.onScale=void 0,P(),v(s)}}export function markerAt(r,f){return getMarkerFromClick(r,f,L)}export function getMarkerFromClick(r,f,c){for(const o of l.routeStore.markersData.markers){const d=l.routeStore.markersData.icons.find(p=>p.name===o.icon);if(!d)continue;const i=d.width*c*devicePixelRatio,s=d.height*c*devicePixelRatio;if(W(r,f,o.x,o.y,i,s)){const p=l.layerStore.findLayer(o.z);if(!p||p&&p.visible)return o}}return null}function W(r,f,c,o,d,i){return K.fromCenter({x:c,y:o},{x:2*d,y:2*i}).containsPoint({x:r,y:f})}let L=1;
1
+ import{Box as K}from"@expofp/geometry";import{update as v}from"@expofp/renderer";import{reaction as E}from"mobx";import{getBounds as y}from"../../../../engine/canvases";import{createImageDef as R}from"../../../../engine/defs";import l,{layersStore as P,uiState as N}from"../../../../store";import{setMarkerResolver as C}from"../../pointer";import{createImageCanvas as O}from"./canvases";const L="_selected";export const MARKER_LAYER_NAME="markers";function T(r,f){const{center:c,rotation:o,elevation:d}=r.bounds,{width:i,height:s}=r.source;return r.bounds=y(c.x,c.y,i,s,f,o,d),[r]}function V(r){w=r}export function configMarkers(r){const{scene:f}=r,c=[],o=new Map,d=new Map;let i=[];const s=f.rootLayer.children.find(e=>e.name===MARKER_LAYER_NAME);s.onScale=({pixelSize:e})=>V(e),C(markerAt),v(s);async function p(e){const n=[];e.forEach(u=>{const{name:a,content:t,width:h,height:D,scale:g}=u;if(o.has(a))return;const m=new Image,S=new Promise((M,b)=>{m.onload=()=>{o.set(a,{img:m,width:h,height:D,scale:g}),M()},m.onerror=x=>{b(x)}});n.push(S),m.src=t,m.crossOrigin="anonymous"}),await Promise.all(n)}const B=e=>{e.onScale=({pixelSize:n})=>T(e,n)},z=e=>{e.screenSpace||(e.onRoll=({roll:n})=>{if(n!==e.bounds.rotation)return e.bounds.rotate(n-e.bounds.rotation,e.bounds),[e]})};function I(e,n,u){const a=d.get(e);if(a)return a;const t=O(n.img,n.width,n.height,u);return d.set(e,t),t}function A(){const e=l.routeStore.markersData.markers;if(!e.length)return;i=[];const n=1,u=0,a=N.is3DView;e.forEach(t=>{const h=o.get(t.icon);if(!h)return;const D=o.get(t.selectedIcon);if(!D)return;const g=h.scale||window.devicePixelRatio,m=I(t.icon,h,g),S=I(t.selectedIcon,D,g),M=P.findLayer(t.z)?.visible??!0,b=y(t.x,t.y,m.width,m.height,n,u),x=y(t.x,t.y,S.width,S.height,n,u);let k;switch(t.position){case"lefttop":k=[0,0];break;case"centertop":k=[.5,0];break;case"centerbottom":k=[.5,1];break;default:k=[.5,.5]}const F={...R(m,b,{hidden:!M,origin:k}),id:t.id,scale:g,screenSpace:a},H={...R(S,x,{hidden:!(M&&t.active),origin:k}),id:`${t.id}${L}`,scale:g,screenSpace:a};i.push(F,H)}),s.children=i,i.forEach(t=>{B(t),z(t)})}function _(){s.children=[],i=[]}function $(){const e=l.routeStore.markersData.markers;e.length&&e.forEach(n=>{const u=i.find(h=>h.id===n.id),a=i.find(h=>h.id===`${n.id}${L}`);if(!u||!a)return;const t=P.findLayer(n.z)?.visible??!0;n.active?(u.hidden=!0,a.hidden=!(t&&n.active)):(u.hidden=!t,a.hidden=!0)})}return c.push(E(()=>[l.routeStore.selectedMarkers,l.layerStore.visible],()=>{if(!l.routeStore.markersData.markers.length){_(),v(s);return}$(),v(...i)})),c.push(E(()=>l.routeStore.markersData.markers,()=>{p(l.routeStore.markersData.icons).then(()=>{A(),v(s)})},{fireImmediately:!0})),function(){c.forEach(n=>n()),c.length=0,s.onScale=void 0,C(),w=1,v(s)}}export function markerAt(r,f){return getMarkerFromClick(r,f,w)}export function getMarkerFromClick(r,f,c){for(const o of l.routeStore.markersData.markers){const d=l.routeStore.markersData.icons.find(p=>p.name===o.icon);if(!d)continue;const i=d.width*c*devicePixelRatio,s=d.height*c*devicePixelRatio;if(W(r,f,o.x,o.y,i,s)){const p=l.layerStore.findLayer(o.z);if(!p||p&&p.visible)return o}}return null}function W(r,f,c,o,d,i){return K.fromCenter({x:c,y:o},{x:2*d,y:2*i}).containsPoint({x:r,y:f})}let w=1;
@@ -1,9 +1,14 @@
1
1
  import { type ImageDef, type LayerDef } from '@expofp/renderer';
2
- /** Loads one configured layer's designer images and hands back where they belong. */
2
+ /**
3
+ * Loads one configured layer's designer images and hands back where they belong.
4
+ *
5
+ * Resolves to `undefined` when there is nothing to place any more — an image load still in flight
6
+ * when the plan was destroyed, whose result no longer has a plan to be drawn into.
7
+ */
3
8
  export type LayerImagesHandler = () => Promise<{
4
9
  layer: LayerDef;
5
10
  children: ImageDef[];
6
- }>;
11
+ } | undefined>;
7
12
  /**
8
13
  * Registers a layer's image loader under its layer name.
9
14
  * @param name - The image layer's name.
@@ -1 +1 @@
1
- const t=new Map;export function registerLayerImages(e,r){return t.set(e,r),()=>{t.get(e)===r&&t.delete(e)}}export function invokeLayerImages(){return[...t.values()].map(e=>e())}
1
+ import{eventScopedCache as o}from"../../../../tools/event-scoped-cache.js";const t=o();export function registerLayerImages(e,r){return t().set(e,r),()=>{t().get(e)===r&&t().delete(e)}}export function invokeLayerImages(){return[...t().values()].map(e=>e())}
@@ -1 +1 @@
1
- import{degToRad as Me,lineAngle as ae,pointDistance as le}from"@expofp/geometry";import{update as Y}from"@expofp/renderer";import{useEffect as ve,useRef as v}from"react";import{getBounds as $}from"../../../engine/canvases";import Le from"../../../tools/base-runtime-url";import{loadImage as Re}from"../../../utils/loadImage";import{mapCamera as ue}from"../camera";import{createImageCanvas as Se}from"../drawing/config/canvases";import{getRouteLayerRegex as be,getRouteStopLayerRegex as Te,TRAFFIC_VEHICLES as te}from"./trafficLayers";import{UpdateQueue as Ae}from"./UpdateQueue";const ne=2,Fe=ne*3.5,Z=ne*12,de=Z*.7,Pe=8,Ce="transport_locations",_e=150,Ne="#a4aab6",he=1e3,De=2e4,fe=500;export function useManageTraffic({permission:t,scene:r,dataJsonUrl:n,websocketUrl:a}){const e=v(window.devicePixelRatio),s=v(new Map),o=v(new Map),c=v(null),h=v(null),u=v(0),M=v(1),T=v(new Ae),L=v(new Map),x=v(he),f=v(new Map),p=v(void 0);ve(()=>{if(!t||!r)return;let l=!1,P;const R=r.rootLayer.children,g=o.current,y=s.current,I=T.current;async function ye(){try{let d;try{const i=await fetch(n,{method:"GET",headers:{"Content-Type":"application/json"}});if(!i.ok||i.status===204)return;d=await i.json()}catch(i){console.warn("useManageTraffic failed to get JSON",i)}if(!d||d.disabled||d.error)return;e.current=ge(ue()?.state().pixelSize??window.devicePixelRatio);const D=new Map(d.routes.map(({id:i,color:m})=>[i,m])),z=new Map;D.forEach(i=>{z.set(i,Ve({radius:Fe,color:i,scale:window.devicePixelRatio}))});const U=be(),j=R.filter(i=>U.test(i.name)),Q=Te(),q=R.filter(i=>Q.test(i.name));d.routes.slice(0,j.length).forEach(({id:i,color:m,path:w,stops:C,hiddenPoints:S},V)=>{L.current.set(i,w);const E=j[V];if(E){const H=new Map(S?.map(_=>[ce(_),_])??[]);for(let _=1;_<w.length;_++){const b=w[_-1],W=w[_];H.has(ce(b))||H.has(ce(W))||E.children.push({points:{p0:b,p1:W},color:m,width:ne})}E.children.length&&I.add(()=>Y(E))}const A=q[V],F=z.get(m);A&&F&&C?.length&&(C.forEach(H=>{A.children.push({source:F,bounds:$(H.x,H.y,F.width,F.height,e.current)})}),A.children.length&&I.add(()=>Y(A)))});const O=R.find(i=>i.name===te);if(!O){console.warn(`useManageTraffic: the scene has no "${te}" layer`);return}const B=new Map;O.onScale=({pixelSize:i})=>{e.current=ge(i);const m=[];for(const w of q){const C=w.children;for(const S of C){const V=S.source;S.bounds=$(S.bounds.center.x,S.bounds.center.y,V.width,V.height,e.current,S.bounds.rotation),m.push(S)}}for(const w of s.current.values()){const C=w.source;w.bounds=$(w.bounds.center.x,w.bounds.center.y,C.width,C.height,e.current,w.bounds.rotation),m.push(w)}return m},I.add(()=>Y(O)),D.forEach((i,m)=>{B.set(m,me({id:m,width:Z,height:Z,color:i,scale:window.devicePixelRatio}))});const xe=me({id:"orphan",width:Z,height:Z,color:Ne,scale:window.devicePixelRatio});let G=null;try{const i=await Re(`${Le}icons/bus-white.svg`);G=Se(i,de,de,window.devicePixelRatio)}catch(i){console.error(i)}h.current=i=>{try{const m=JSON.parse(i.data);if(m.type!==Ce)return;const w=i.timeStamp||performance.now();M.current=Math.round(w-u.current),u.current=w;const C=Math.max(M.current??fe,fe),S=O.children;let V=!1;m.data.forEach(({id:E,x:A,y:F,route_id:H,hidden:_})=>{g.has(E)&&(g.get(E)?.(),g.delete(E));const b=y.get(E),W=y.get(re(E))??null;if(_&&b&&W){b.hidden=!0,W.hidden=!0,I.add(()=>Y(b,W));return}if(f.current.set(E,performance.now()),!b){const k=B.get(H)??xe,N={source:k,bounds:$(A,F,k.width,k.height,e.current,0)};if(y.set(E,N),G){const X=re(E),ie={source:G,bounds:$(A,F,G.width,G.height,e.current,0)};G.setAttribute("id",X),y.set(X,ie),S.push(N,ie)}else S.push(N);V=!0;return}const Ee=b.bounds.center,ee=We(Ee,{x:A,y:F},L.current.get(H));if(ee.reduce((k,N,X)=>X===0?k:k+oe(ee[X-1],N),0)>=_e||document.hidden)we({updateQueue:I,vehicle:b,vehicleFinery:W,x:A,y:F,scale:e.current,angle:Oe(b.bounds.center,{x:A,y:F})});else{const k=ke(ee,C,N=>{we({updateQueue:I,vehicle:b,vehicleFinery:W,x:N.x,y:N.y,scale:e.current,angle:N.angle})});g.set(E,k)}}),V&&I.add(()=>Y(O))}catch(m){console.error("handleSocketMessage",m)}},u.current=performance.now(),K(),window.addEventListener("online",se),Ie(d.config?(Number(d.config.vehicle_inactive_interval)||20)*1e3:De)}catch(d){console.warn(d)}}ye();function K(){l||c.current?.readyState===WebSocket.OPEN||c.current?.readyState===WebSocket.CONNECTING||(c.current=new WebSocket(a),c.current.onmessage=h.current,c.current.onopen=()=>{x.current=he},c.current.onclose=()=>{if(l||!navigator.onLine)return;P=window.setTimeout(K,x.current);const d=3e4;x.current=Math.min(x.current*2,d)})}function se(){K()}function Ie(d){clearInterval(p.current),p.current=window.setInterval(()=>{const D=performance.now(),z=[],U=[];f.current.forEach((j,Q)=>{if(D-j<d)return;const q=y.get(Q);q&&(q.hidden=!0,U.push(q),z.push(Q));const O=re(Q),B=y.get(O);B&&(B.hidden=!0,U.push(B),z.push(O))}),U.length&&I.add(()=>Y(...U)),z.forEach(j=>f.current.delete(j))},d)}return()=>{l=!0,clearTimeout(P),c.current?.close(),c.current=null;const d=R.find(D=>D.name===te);d&&(d.onScale=void 0),g.forEach(D=>D?.()),g.clear(),y.clear(),I.destroy(),window.removeEventListener("online",se),clearInterval(p.current)}},[t,r,n,a])}function ge(t){return Math.min(t||window.devicePixelRatio,Pe)}function Oe(t,r){return ae(t,r)}function Ve({radius:t,scale:r,color:n}){const a=document.createElement("canvas"),e=a.getContext("2d");e.imageSmoothingEnabled=!1;const s=Math.ceil(t*2*r),o=s/2,c=t*.78,h=t*.33;return a.width=s,a.height=s,e.translate(o,o),e.scale(r,r),e.beginPath(),e.arc(0,0,t,0,2*Math.PI),e.fillStyle="#FFFFFF",e.fill(),e.beginPath(),e.arc(0,0,c,0,2*Math.PI),e.fillStyle=n,e.fill(),e.beginPath(),e.arc(0,0,h,0,2*Math.PI),e.fillStyle="#FFFFFF",e.fill(),a}function me({id:t,width:r,height:n,color:a,scale:e}){const s=2*e,o=r/2*e,c=n*e,h=.6,u=.01,M=c*h,T=c,L=8*e,x=T+s+M/2+L*2,f=o*2+M+s+L*2,p=document.createElement("canvas");p.setAttribute("id",t),p.width=x,p.height=f;const l=p.getContext("2d"),P=x/2,R=f/2;l.save(),l.translate(P,R),l.rotate(-Math.PI/2),l.translate(-P,-R);const g=P,y=R-T/2+o,I=y+M;return l.shadowColor="rgba(16, 24, 40, 0.2)",l.shadowBlur=L/2,l.beginPath(),l.arc(g,y,o,Math.PI,0,!1),l.bezierCurveTo(g+o,y+c*.3,g+u*o,I,g,I),l.bezierCurveTo(g-u*o,I,g-o,y+c*.3,g-o,y),l.closePath(),l.fillStyle=a,l.fill(),l.strokeStyle="#FFFFFF",l.lineWidth=s,l.stroke(),l.restore(),p}function oe(t,r){return le(t,r)}function re(t){return`${t}_finery`}function we({updateQueue:t,vehicle:r,vehicleFinery:n,x:a,y:e,scale:s,angle:o}){const c=r.source;if(r.bounds=$(a,e,c.width,c.height,s,o),r.hidden=!1,n){const h=ue()?.state().roll??0,u=n.source;n.bounds=$(a,e,u.width,u.height,s,Me(h)),n.hidden=!1,t.add(()=>Y(n,r))}else t.add(()=>Y(r))}function J(t,r,n){return{x:t.x+(r.x-t.x)*n,y:t.y+(r.y-t.y)*n}}function pe(t,r){let n=1/0,a={index:0,t:0};for(let e=0;e<r.length-1;e++){const s=r[e],o=r[e+1],c=o.x-s.x,h=o.y-s.y,u=c*c+h*h,M=u?((t.x-s.x)*c+(t.y-s.y)*h)/u:0,T=Math.max(0,Math.min(1,M)),L=J(s,o,T),x=oe(t,L);x<n&&(n=x,a={index:e,t:T})}return a}function He(t,r,n){const a=oe(t,r),e=Math.max(2,Math.ceil(a/n)+1),s=[];for(let o=0;o<e;o++){const c=o/(e-1),h=J(t,r,c);s.push(h)}return s}function We(t,r,n){if(!n||!n.length)return He(t,r,10);const a=pe(t,n),e=pe(r,n),s=[],o=c=>s.push(c);a.index+1<n.length?o(J(n[a.index],n[a.index+1],a.t)):o(n[a.index]);for(let c=a.index+1;c<=e.index&&c<n.length;c++)o(n[c]);return e.index+1<n.length?o(J(n[e.index],n[e.index+1],e.t)):o(n[e.index]),s}function ke(t,r,n,a){if(t.length<2)return()=>{};let e=null,s;const o=[];let c=0;for(let u=0;u<t.length-1;u++){const M=le(t[u],t[u+1]);o.push(M),c+=M}const h=u=>{e||(e=u);const M=u-e,T=Math.min(M/r,1),L=T*c;let x=0,f=0;for(;f<o.length&&x+o[f]<L;)x+=o[f],f++;f>=o.length&&(f=o.length-1);const p=t[f],l=t[Math.min(f+1,t.length-1)],P=o[f]||0,R=P===0?0:(L-x)/P,g=p.x+(l.x-p.x)*R,y=p.y+(l.y-p.y)*R,I=ae(p,l);n({x:g,y,angle:I}),T<1?s=requestAnimationFrame(h):a&&a()};return s=requestAnimationFrame(h),()=>{s&&cancelAnimationFrame(s)}}function ce(t){return`${t.x},${t.y}`}
1
+ import{degToRad as Me,lineAngle as ae,pointDistance as le}from"@expofp/geometry";import{update as Y}from"@expofp/renderer";import{useEffect as ve,useRef as v}from"react";import{getBounds as z}from"../../../engine/canvases";import Le from"../../../tools/base-runtime-url";import{loadImage as Re}from"../../../utils/loadImage";import{mapCamera as ue}from"../camera";import{createImageCanvas as Se}from"../drawing/config/canvases";import{getRouteLayerRegex as be,getRouteStopLayerRegex as Te,TRAFFIC_VEHICLES as te}from"./trafficLayers";import{UpdateQueue as Ae}from"./UpdateQueue";const ne=2,Fe=ne*3.5,Z=ne*12,de=Z*.7,Pe=8,Ce="transport_locations",_e=150,Ne="#a4aab6",fe=1e3,De=2e4,he=500;export function useManageTraffic({permission:t,scene:r,dataJsonUrl:n,websocketUrl:l}){const e=v(window.devicePixelRatio),s=v(new Map),o=v(new Map),c=v(null),f=v(null),d=v(0),M=v(1),T=v(new Ae),L=v(new Map),x=v(fe),h=v(new Map),p=v(void 0);ve(()=>{if(!t||!r)return;let a=!1,C;const R=r.rootLayer.children,g=o.current,y=s.current,I=T.current;async function ye(){try{let u;try{const i=await fetch(n,{method:"GET",headers:{"Content-Type":"application/json"}});if(!i.ok||i.status===204)return;u=await i.json()}catch(i){console.warn("useManageTraffic failed to get JSON",i)}if(a||!u||u.disabled||u.error)return;e.current=ge(ue()?.state().pixelSize??window.devicePixelRatio);const $=new Map(u.routes.map(({id:i,color:m})=>[i,m])),A=new Map;$.forEach(i=>{A.set(i,Ve({radius:Fe,color:i,scale:window.devicePixelRatio}))});const U=be(),j=R.filter(i=>U.test(i.name)),Q=Te(),q=R.filter(i=>Q.test(i.name));u.routes.slice(0,j.length).forEach(({id:i,color:m,path:w,stops:_,hiddenPoints:S},V)=>{L.current.set(i,w);const E=j[V];if(E){const H=new Map(S?.map(N=>[ce(N),N])??[]);for(let N=1;N<w.length;N++){const b=w[N-1],k=w[N];H.has(ce(b))||H.has(ce(k))||E.children.push({points:{p0:b,p1:k},color:m,width:ne})}E.children.length&&I.add(()=>Y(E))}const F=q[V],P=A.get(m);F&&P&&_?.length&&(_.forEach(H=>{F.children.push({source:P,bounds:z(H.x,H.y,P.width,P.height,e.current)})}),F.children.length&&I.add(()=>Y(F)))});const O=R.find(i=>i.name===te);if(!O){console.warn(`useManageTraffic: the scene has no "${te}" layer`);return}const B=new Map;O.onScale=({pixelSize:i})=>{e.current=ge(i);const m=[];for(const w of q){const _=w.children;for(const S of _){const V=S.source;S.bounds=z(S.bounds.center.x,S.bounds.center.y,V.width,V.height,e.current,S.bounds.rotation),m.push(S)}}for(const w of s.current.values()){const _=w.source;w.bounds=z(w.bounds.center.x,w.bounds.center.y,_.width,_.height,e.current,w.bounds.rotation),m.push(w)}return m},I.add(()=>Y(O)),$.forEach((i,m)=>{B.set(m,me({id:m,width:Z,height:Z,color:i,scale:window.devicePixelRatio}))});const xe=me({id:"orphan",width:Z,height:Z,color:Ne,scale:window.devicePixelRatio});let G=null;try{const i=await Re(`${Le}icons/bus-white.svg`);if(a)return;G=Se(i,de,de,window.devicePixelRatio)}catch(i){console.error(i)}f.current=i=>{try{const m=JSON.parse(i.data);if(m.type!==Ce)return;const w=i.timeStamp||performance.now();M.current=Math.round(w-d.current),d.current=w;const _=Math.max(M.current??he,he),S=O.children;let V=!1;m.data.forEach(({id:E,x:F,y:P,route_id:H,hidden:N})=>{g.has(E)&&(g.get(E)?.(),g.delete(E));const b=y.get(E),k=y.get(re(E))??null;if(N&&b&&k){b.hidden=!0,k.hidden=!0,I.add(()=>Y(b,k));return}if(h.current.set(E,performance.now()),!b){const W=B.get(H)??xe,D={source:W,bounds:z(F,P,W.width,W.height,e.current,0)};if(y.set(E,D),G){const X=re(E),ie={source:G,bounds:z(F,P,G.width,G.height,e.current,0)};G.setAttribute("id",X),y.set(X,ie),S.push(D,ie)}else S.push(D);V=!0;return}const Ee=b.bounds.center,ee=ke(Ee,{x:F,y:P},L.current.get(H));if(ee.reduce((W,D,X)=>X===0?W:W+oe(ee[X-1],D),0)>=_e||document.hidden)we({updateQueue:I,vehicle:b,vehicleFinery:k,x:F,y:P,scale:e.current,angle:Oe(b.bounds.center,{x:F,y:P})});else{const W=We(ee,_,D=>{we({updateQueue:I,vehicle:b,vehicleFinery:k,x:D.x,y:D.y,scale:e.current,angle:D.angle})});g.set(E,W)}}),V&&I.add(()=>Y(O))}catch(m){console.error("handleSocketMessage",m)}},d.current=performance.now(),K(),window.addEventListener("online",se),Ie(u.config?(Number(u.config.vehicle_inactive_interval)||20)*1e3:De)}catch(u){console.warn(u)}}ye();function K(){a||c.current?.readyState===WebSocket.OPEN||c.current?.readyState===WebSocket.CONNECTING||(c.current=new WebSocket(l),c.current.onmessage=f.current,c.current.onopen=()=>{x.current=fe},c.current.onclose=()=>{if(a||!navigator.onLine)return;C=window.setTimeout(K,x.current);const u=3e4;x.current=Math.min(x.current*2,u)})}function se(){K()}function Ie(u){clearInterval(p.current),!a&&(p.current=window.setInterval(()=>{const $=performance.now(),A=[],U=[];h.current.forEach((j,Q)=>{if($-j<u)return;const q=y.get(Q);q&&(q.hidden=!0,U.push(q),A.push(Q));const O=re(Q),B=y.get(O);B&&(B.hidden=!0,U.push(B),A.push(O))}),U.length&&I.add(()=>Y(...U)),A.forEach(j=>h.current.delete(j))},u))}return()=>{a=!0,clearTimeout(C);const u=c.current;u&&(u.onopen=null,u.onmessage=null,u.onclose=null,u.close(),c.current=null),f.current=null;const $=R.find(A=>A.name===te);$&&($.onScale=void 0),g.forEach(A=>A?.()),g.clear(),y.clear(),I.destroy(),window.removeEventListener("online",se),clearInterval(p.current)}},[t,r,n,l])}function ge(t){return Math.min(t||window.devicePixelRatio,Pe)}function Oe(t,r){return ae(t,r)}function Ve({radius:t,scale:r,color:n}){const l=document.createElement("canvas"),e=l.getContext("2d");e.imageSmoothingEnabled=!1;const s=Math.ceil(t*2*r),o=s/2,c=t*.78,f=t*.33;return l.width=s,l.height=s,e.translate(o,o),e.scale(r,r),e.beginPath(),e.arc(0,0,t,0,2*Math.PI),e.fillStyle="#FFFFFF",e.fill(),e.beginPath(),e.arc(0,0,c,0,2*Math.PI),e.fillStyle=n,e.fill(),e.beginPath(),e.arc(0,0,f,0,2*Math.PI),e.fillStyle="#FFFFFF",e.fill(),l}function me({id:t,width:r,height:n,color:l,scale:e}){const s=2*e,o=r/2*e,c=n*e,f=.6,d=.01,M=c*f,T=c,L=8*e,x=T+s+M/2+L*2,h=o*2+M+s+L*2,p=document.createElement("canvas");p.setAttribute("id",t),p.width=x,p.height=h;const a=p.getContext("2d"),C=x/2,R=h/2;a.save(),a.translate(C,R),a.rotate(-Math.PI/2),a.translate(-C,-R);const g=C,y=R-T/2+o,I=y+M;return a.shadowColor="rgba(16, 24, 40, 0.2)",a.shadowBlur=L/2,a.beginPath(),a.arc(g,y,o,Math.PI,0,!1),a.bezierCurveTo(g+o,y+c*.3,g+d*o,I,g,I),a.bezierCurveTo(g-d*o,I,g-o,y+c*.3,g-o,y),a.closePath(),a.fillStyle=l,a.fill(),a.strokeStyle="#FFFFFF",a.lineWidth=s,a.stroke(),a.restore(),p}function oe(t,r){return le(t,r)}function re(t){return`${t}_finery`}function we({updateQueue:t,vehicle:r,vehicleFinery:n,x:l,y:e,scale:s,angle:o}){const c=r.source;if(r.bounds=z(l,e,c.width,c.height,s,o),r.hidden=!1,n){const f=ue()?.state().roll??0,d=n.source;n.bounds=z(l,e,d.width,d.height,s,Me(f)),n.hidden=!1,t.add(()=>Y(n,r))}else t.add(()=>Y(r))}function J(t,r,n){return{x:t.x+(r.x-t.x)*n,y:t.y+(r.y-t.y)*n}}function pe(t,r){let n=1/0,l={index:0,t:0};for(let e=0;e<r.length-1;e++){const s=r[e],o=r[e+1],c=o.x-s.x,f=o.y-s.y,d=c*c+f*f,M=d?((t.x-s.x)*c+(t.y-s.y)*f)/d:0,T=Math.max(0,Math.min(1,M)),L=J(s,o,T),x=oe(t,L);x<n&&(n=x,l={index:e,t:T})}return l}function He(t,r,n){const l=oe(t,r),e=Math.max(2,Math.ceil(l/n)+1),s=[];for(let o=0;o<e;o++){const c=o/(e-1),f=J(t,r,c);s.push(f)}return s}function ke(t,r,n){if(!n||!n.length)return He(t,r,10);const l=pe(t,n),e=pe(r,n),s=[],o=c=>s.push(c);l.index+1<n.length?o(J(n[l.index],n[l.index+1],l.t)):o(n[l.index]);for(let c=l.index+1;c<=e.index&&c<n.length;c++)o(n[c]);return e.index+1<n.length?o(J(n[e.index],n[e.index+1],e.t)):o(n[e.index]),s}function We(t,r,n,l){if(t.length<2)return()=>{};let e=null,s;const o=[];let c=0;for(let d=0;d<t.length-1;d++){const M=le(t[d],t[d+1]);o.push(M),c+=M}const f=d=>{e||(e=d);const M=d-e,T=Math.min(M/r,1),L=T*c;let x=0,h=0;for(;h<o.length&&x+o[h]<L;)x+=o[h],h++;h>=o.length&&(h=o.length-1);const p=t[h],a=t[Math.min(h+1,t.length-1)],C=o[h]||0,R=C===0?0:(L-x)/C,g=p.x+(a.x-p.x)*R,y=p.y+(a.y-p.y)*R,I=ae(p,a);n({x:g,y,angle:I}),T<1?s=requestAnimationFrame(f):l&&l()};return s=requestAnimationFrame(f),()=>{s&&cancelAnimationFrame(s)}}function ce(t){return`${t.x},${t.y}`}
@@ -1 +1 @@
1
- import{jsx as F,jsxs as Y}from"react/jsx-runtime";import{isLayerDefs as q}from"@expofp/renderer";import ee from"color";import{runInAction as re}from"mobx";import{observer as te}from"mobx-react-lite";import{useCallback as j,useEffect as R,useMemo as u,useRef as f,useState as $}from"react";import oe from"../../data";import{getLayerSvg as ne,svgArea as C,svgAreaExplicit as ie}from"../../data/svg";import{createSceneDef as ae}from"../../engine/defs";import t,{uiState as i}from"../../store";import M from"../../tools/settings";import V from"../../utils/is-debug";import{fitRectIsFraming as ce,getVenueFitMarginPercent as se,resolveVenueFitRect as le}from"../../utils/scene-bounds";import me from"../Map/drawing/config/config-all";import{loadLayersImages as ue}from"../Map/drawing/config/loadBoothsImages";import{MapCursorCoords as fe}from"../Map/MapCursorCoords";import{MapViewport as pe}from"../Map/MapViewport";import{clearSelection as de}from"../Map/pointer";import{setMapScene as B}from"../Map/scene";import{useBuildRoute as ge}from"../Map/traffic/useBuildRoute";import{useManageTraffic as be}from"../Map/traffic/useManageTraffic";import{centerCoordinates as Se}from"../Map/viewport";import he from"./MaplibreWrapper";import{useCameraReactions as ye}from"./useCameraReactions";import{useDimming as Re}from"./useDimming";import{useKioskCameraEvents as Ce}from"./useKioskCameraEvents";import{useLayerVisibilitySync as Me}from"./useLayerVisibilitySync";import{usePoiMarkers as Ae}from"./usePoiMarkers";import{useWayfindingAndMarkers as Le}from"./useWayfindingAndMarkers";import{cameraForLocalRect as Pe,deriveGeoConfig as ve,getLocalRectGeoBounds as ze,getVisibleRectFitPadding as De,INITIAL_FIT_ZOOM_ADJUSTMENT as xe}from"./utils/geo-config";import{applyMapOptions as N,getTileSource as Te,MAP_MIN_ZOOM as Ee}from"./utils/map-helpers";import{calculateTransformMatrix as Oe}from"./utils/solver";const U="routes-api.expofp.com",we=800;function Ie(a,b,s){return{getCameraState:()=>{const o=a.getCenter();return{lng:o.lng,lat:o.lat,zoom:a.getZoom(),bearing:a.getBearing(),pitch:a.getPitch()}},applyCameraState:o=>{a.easeTo({center:[o.lng,o.lat],zoom:o.zoom,bearing:o.bearing??b,pitch:o.pitch??s(),duration:we,essential:!0})},resetPitch:()=>{const o=s();a.getPitch()!==o&&a.jumpTo({pitch:o})}}}function Z(){t.poiMarkerStore.clear(),re(()=>{t.layerStore.layers.forEach(a=>{a.configured=!1,a.children=[],a.loaded=!1}),t.layerStore.layersLoaded=!1})}const _e=te(function({viewMode:b}){const[s,o]=$(null),[z,D]=$(!1),m=f(null),p=f(null),A=f(null),x=f(null),S=f(null),r=u(()=>ve(),[]),L=u(()=>le({layerViewbox:t.layerStore.viewboxRectangle,explicitArea:ie?C:null,layerRectangle:t.layerStore.rectangle,sceneDef:s,svgArea:C}),[s]),h=L.rect,d=u(()=>{if(!r)return null;const e=ce(L.source)?0:se(h,C),n=De(0);e&&i.screenSize&&(n.left+=i.screenSize.width*e,n.right+=i.screenSize.width*e,n.top+=i.screenSize.height*e,n.bottom+=i.screenSize.height*e);const l=i.screenSize?Pe(h,r.gpsConfig,r.bearing,{width:i.screenSize.width,height:i.screenSize.height},n):null;return l?{center:l.center,bearing:r.bearing,zoom:l.zoom}:{center:r.center,bearing:r.bearing,zoom:r.zoom,bounds:ze(h,r.gpsConfig),fitPadding:n,zoomAdjustment:xe}},[r,L,h]),y=u(()=>r?Oe(r.gpsConfig,ne()?.getAttribute("units")):null,[r]),T=i.mapSettings.pitchdegrees,E=i.maxPitch,g=u(()=>{const e=b==="map2d";return{pitch:e?0:T,maxPitch:e?0:E,minZoom:Ee}},[b,T,E]),P=f(g),G=u(()=>Te(),[]),c=u(()=>{if(!s||!y)return null;const e=s.rootLayer.children,n=q(e)?e.filter(l=>l.name.toLowerCase()!=="areamap"):e;return{...s,rootLayer:{...s.rootLayer,children:n},background:void 0,staticTransform:y}},[s,y]),O=f(null);R(()=>{O.current=c},[c]),R(()=>{if(c)return B(c),()=>B(void 0)},[c]);const{mapDimAnimatorRef:w,venueDimAnimatorRef:I,applyDimmingTarget:_,handleMapDimLayerReady:J}=Re(m,O);R(()=>{if(!r)return;let e=!1;Z(),me().then(({layers:v,cleanup:k})=>{if(e){k();return}A.current=k;const Q=ee(M.backgroundColor==="none"?"#ebebeb":M.backgroundColor).string();o(ae(v,C,Q))}).catch(v=>{e||console.warn("Maplibre scene configuration failed.",v)});const n=w.current,l=I.current;return()=>{e=!0,Z(),A.current?.(),A.current=null,S.current&&(t.maplibreStore.clearCameraPortIfCurrent(S.current),S.current=null),m.current=null,p.current=null,x.current=null,D(!1),n?.stop(),l?.stop(),i.sceneDefReady=!1}},[r,w,I]);const K=j((e,n)=>{m.current=e,p.current=e.getCanvas(),x.current=n,D(!0),e.once("idle",()=>N(e,P.current));const l=Ie(e,r?.bearing??e.getBearing(),()=>P.current.pitch??0);S.current=l,t.maplibreStore.setCameraPort(l),t.fp.getCenterCoordinates=()=>Se(p.current),_({immediate:!0}),ue(),t.layerStore.layersLoaded=!0,t.fp.onFpConfigured&&t.fp.onFpConfigured(),i.sceneDefReady=!0,n()},[_,r]);R(()=>{P.current=g,N(m.current,g)},[g]),Ce(z,m),Le(c,p),Ae(z,m,r),Me(c,m,r),ye(m,r,c),ge({enabled:t.layerStore.layersLoaded&&i.buildRoute,scene:c??void 0});const W=oe.busRoutes??!1;be({permission:t.layerStore.layersLoaded&&W,scene:c??void 0,dataJsonUrl:`https://${U}/v1/routes?expo=${M.EXPO}`,websocketUrl:`wss://${U}/locations?expo=${M.EXPO}`});const X=j(e=>{console.warn("Maplibre map failed to load; falling back to floorplan mode.",e),t.maplibreStore.deactivateMaplibre()},[]);if(!r||!d||!y||!c)return null;const H=`${d.center.join(",")}:${d.bearing}:${d.zoom}`;return Y(he,{sceneDef:c,geoConfig:d,tileSource:G,mapOptions:g,debug:V,onMapReady:K,onMapDimLayerReady:J,onMapLoadError:X,onPointerMissed:de,children:[F(pe,{}),V&&F(fe,{canvas:p})]},H)});export default _e;
1
+ import{jsx as F,jsxs as Y}from"react/jsx-runtime";import{isLayerDefs as q}from"@expofp/renderer";import ee from"color";import{runInAction as re}from"mobx";import{observer as te}from"mobx-react-lite";import{useCallback as j,useEffect as R,useMemo as u,useRef as f,useState as $}from"react";import oe from"../../data";import{getLayerSvg as ne,getSvgArea as C,isSvgAreaExplicit as ie}from"../../data/svg.js";import{createSceneDef as ae}from"../../engine/defs";import t,{uiState as i}from"../../store";import M from"../../tools/settings";import V from"../../utils/is-debug";import{fitRectIsFraming as ce,getVenueFitMarginPercent as se,resolveVenueFitRect as le}from"../../utils/scene-bounds";import me from"../Map/drawing/config/config-all";import{loadLayersImages as ue}from"../Map/drawing/config/loadBoothsImages";import{MapCursorCoords as fe}from"../Map/MapCursorCoords";import{MapViewport as pe}from"../Map/MapViewport";import{clearSelection as de}from"../Map/pointer";import{setMapScene as B}from"../Map/scene";import{useBuildRoute as ge}from"../Map/traffic/useBuildRoute";import{useManageTraffic as be}from"../Map/traffic/useManageTraffic";import{centerCoordinates as Se}from"../Map/viewport";import he from"./MaplibreWrapper";import{useCameraReactions as ye}from"./useCameraReactions";import{useDimming as Re}from"./useDimming";import{useKioskCameraEvents as Ce}from"./useKioskCameraEvents";import{useLayerVisibilitySync as Me}from"./useLayerVisibilitySync";import{usePoiMarkers as Ae}from"./usePoiMarkers";import{useWayfindingAndMarkers as Le}from"./useWayfindingAndMarkers";import{cameraForLocalRect as Pe,deriveGeoConfig as ve,getLocalRectGeoBounds as ze,getVisibleRectFitPadding as De,INITIAL_FIT_ZOOM_ADJUSTMENT as xe}from"./utils/geo-config";import{applyMapOptions as N,getTileSource as Te,MAP_MIN_ZOOM as Ee}from"./utils/map-helpers";import{calculateTransformMatrix as Oe}from"./utils/solver";const U="routes-api.expofp.com",we=800;function Ie(a,b,s){return{getCameraState:()=>{const o=a.getCenter();return{lng:o.lng,lat:o.lat,zoom:a.getZoom(),bearing:a.getBearing(),pitch:a.getPitch()}},applyCameraState:o=>{a.easeTo({center:[o.lng,o.lat],zoom:o.zoom,bearing:o.bearing??b,pitch:o.pitch??s(),duration:we,essential:!0})},resetPitch:()=>{const o=s();a.getPitch()!==o&&a.jumpTo({pitch:o})}}}function Z(){t.poiMarkerStore.clear(),re(()=>{t.layerStore.layers.forEach(a=>{a.configured=!1,a.children=[],a.loaded=!1}),t.layerStore.layersLoaded=!1})}const _e=te(function({viewMode:b}){const[s,o]=$(null),[z,D]=$(!1),m=f(null),p=f(null),A=f(null),x=f(null),S=f(null),r=u(()=>ve(),[]),L=u(()=>le({layerViewbox:t.layerStore.viewboxRectangle,explicitArea:ie()?C():null,layerRectangle:t.layerStore.rectangle,sceneDef:s,svgArea:C()}),[s]),h=L.rect,d=u(()=>{if(!r)return null;const e=ce(L.source)?0:se(h,C()),n=De(0);e&&i.screenSize&&(n.left+=i.screenSize.width*e,n.right+=i.screenSize.width*e,n.top+=i.screenSize.height*e,n.bottom+=i.screenSize.height*e);const l=i.screenSize?Pe(h,r.gpsConfig,r.bearing,{width:i.screenSize.width,height:i.screenSize.height},n):null;return l?{center:l.center,bearing:r.bearing,zoom:l.zoom}:{center:r.center,bearing:r.bearing,zoom:r.zoom,bounds:ze(h,r.gpsConfig),fitPadding:n,zoomAdjustment:xe}},[r,L,h]),y=u(()=>r?Oe(r.gpsConfig,ne()?.getAttribute("units")):null,[r]),T=i.mapSettings.pitchdegrees,E=i.maxPitch,g=u(()=>{const e=b==="map2d";return{pitch:e?0:T,maxPitch:e?0:E,minZoom:Ee}},[b,T,E]),P=f(g),G=u(()=>Te(),[]),c=u(()=>{if(!s||!y)return null;const e=s.rootLayer.children,n=q(e)?e.filter(l=>l.name.toLowerCase()!=="areamap"):e;return{...s,rootLayer:{...s.rootLayer,children:n},background:void 0,staticTransform:y}},[s,y]),O=f(null);R(()=>{O.current=c},[c]),R(()=>{if(c)return B(c),()=>B(void 0)},[c]);const{mapDimAnimatorRef:w,venueDimAnimatorRef:I,applyDimmingTarget:_,handleMapDimLayerReady:J}=Re(m,O);R(()=>{if(!r)return;let e=!1;Z(),me().then(({layers:v,cleanup:k})=>{if(e){k();return}A.current=k;const Q=ee(M.backgroundColor==="none"?"#ebebeb":M.backgroundColor).string();o(ae(v,C(),Q))}).catch(v=>{e||console.warn("Maplibre scene configuration failed.",v)});const n=w.current,l=I.current;return()=>{e=!0,Z(),A.current?.(),A.current=null,S.current&&(t.maplibreStore.clearCameraPortIfCurrent(S.current),S.current=null),m.current=null,p.current=null,x.current=null,D(!1),n?.stop(),l?.stop(),i.sceneDefReady=!1}},[r,w,I]);const K=j((e,n)=>{m.current=e,p.current=e.getCanvas(),x.current=n,D(!0),e.once("idle",()=>N(e,P.current));const l=Ie(e,r?.bearing??e.getBearing(),()=>P.current.pitch??0);S.current=l,t.maplibreStore.setCameraPort(l),t.fp.getCenterCoordinates=()=>Se(p.current),_({immediate:!0}),ue(),t.layerStore.layersLoaded=!0,t.fp.onFpConfigured&&t.fp.onFpConfigured(),i.sceneDefReady=!0,n()},[_,r]);R(()=>{P.current=g,N(m.current,g)},[g]),Ce(z,m),Le(c,p),Ae(z,m,r),Me(c,m,r),ye(m,r,c),ge({enabled:t.layerStore.layersLoaded&&i.buildRoute,scene:c??void 0});const W=oe.busRoutes??!1;be({permission:t.layerStore.layersLoaded&&W,scene:c??void 0,dataJsonUrl:`https://${U}/v1/routes?expo=${M.EXPO}`,websocketUrl:`wss://${U}/locations?expo=${M.EXPO}`});const X=j(e=>{console.warn("Maplibre map failed to load; falling back to floorplan mode.",e),t.maplibreStore.deactivateMaplibre()},[]);if(!r||!d||!y||!c)return null;const H=`${d.center.join(",")}:${d.bearing}:${d.zoom}`;return Y(he,{sceneDef:c,geoConfig:d,tileSource:G,mapOptions:g,debug:V,onMapReady:K,onMapDimLayerReady:J,onMapLoadError:X,onPointerMissed:de,children:[F(pe,{}),V&&F(fe,{canvas:p})]},H)});export default _e;
@@ -1 +1 @@
1
- import{Box as h}from"@expofp/geometry";import{svgArea as f,svgAreaExplicit as y}from"../../data/svg";import u,{uiState as s}from"../../store";import{convertLocalToGps as T}from"../../utils/gps";import{useReaction as l}from"../../utils/mobx";import{expandRectByPercent as b,getVenueFitMarginPercent as v,resolveVenueFitRect as x}from"../../utils/scene-bounds";import{fitMapToLocalRect as d,getVisibleRectFitPadding as O,isLngLatInVisibleViewport as M}from"./utils/geo-config";const a=s,S=15,g=24,L=20;function R(e){return b(e,v(e,f)).expand(L)}function B(e,r){return Math.min(Math.max(r,e.getMinZoom()),e.getMaxZoom())}function I(e,r,m){if(m.length!==1)return!1;const o=m[0]?.id,t=u.poiMarkerStore.markers.find(c=>c.boothId===o);if(!t)return!1;const n=T(t.center.x,t.center.y,r.gpsConfig),i=O(g);return M(e,n,i)||e.easeTo({center:n,zoom:B(e,S),bearing:r.bearing,duration:500,essential:!0}),!0}export function useCameraReactions(e,r,m){l(()=>a.moveToBooths,o=>{const t=e.current;if(!o||!t||!r)return;const n=o.filter(c=>c.rect);if(n.length===0)return;if(I(t,r,n)){a.moveToBooths=null;return}const i=h.fromUnion(...n.map(c=>c.rect));d(t,R(i),r),a.moveToBooths=null}),l(()=>a.moveToRect,o=>{const t=e.current;!o||!t||!r||(d(t,o,r,{paddingPercent:a.moveToRectPaddingPercent}),a.moveToRect=null,a.moveToRectPaddingPercent=null)}),l(()=>a.zoomBy,o=>{const t=e.current;!o||!t||(t.flyTo({zoom:t.getZoom()+(o>1?.5:-.5),animate:!0,duration:500}),a.zoomBy=null)}),l(()=>[s.moveToLocation,u.maplibreStore.cameraPort,u.routeStore.currentPosition],([o])=>{if(!o)return;const t=e.current,n=u.routeStore.currentPosition;if(!n){s.moveToLocation=!1;return}if(!t)return;const{lng:i,lat:c}=n,P=typeof i=="number"&&Number.isFinite(i)&&typeof c=="number"&&Number.isFinite(c);s.moveToLocation=!1;let p;if(P)p=[i,c];else{if(!r)return;p=T(n.x,n.y,r.gpsConfig)}t.flyTo({center:p,animate:!0,duration:1e3})}),l(()=>s.centerMap,o=>{const t=e.current;if(!o||!t||!r)return;if(!(s.list.type==="search"&&!s.list.text)){const{rect:i}=x({layerViewbox:u.layerStore.viewboxRectangle,explicitArea:y?f:null,layerRectangle:u.layerStore.rectangle,sceneDef:m,svgArea:f});d(t,i,r)}s.centerMap=!1})}
1
+ import{Box as h}from"@expofp/geometry";import{getSvgArea as f,isSvgAreaExplicit as v}from"../../data/svg.js";import u,{uiState as s}from"../../store";import{convertLocalToGps as T}from"../../utils/gps";import{useReaction as l}from"../../utils/mobx";import{expandRectByPercent as y,getVenueFitMarginPercent as b,resolveVenueFitRect as S}from"../../utils/scene-bounds";import{fitMapToLocalRect as d,getVisibleRectFitPadding as x,isLngLatInVisibleViewport as O}from"./utils/geo-config";const a=s,g=15,M=24,L=20;function R(e){return y(e,b(e,f())).expand(L)}function B(e,r){return Math.min(Math.max(r,e.getMinZoom()),e.getMaxZoom())}function I(e,r,m){if(m.length!==1)return!1;const o=m[0]?.id,t=u.poiMarkerStore.markers.find(c=>c.boothId===o);if(!t)return!1;const n=T(t.center.x,t.center.y,r.gpsConfig),i=x(M);return O(e,n,i)||e.easeTo({center:n,zoom:B(e,g),bearing:r.bearing,duration:500,essential:!0}),!0}export function useCameraReactions(e,r,m){l(()=>a.moveToBooths,o=>{const t=e.current;if(!o||!t||!r)return;const n=o.filter(c=>c.rect);if(n.length===0)return;if(I(t,r,n)){a.moveToBooths=null;return}const i=h.fromUnion(...n.map(c=>c.rect));d(t,R(i),r),a.moveToBooths=null}),l(()=>a.moveToRect,o=>{const t=e.current;!o||!t||!r||(d(t,o,r,{paddingPercent:a.moveToRectPaddingPercent}),a.moveToRect=null,a.moveToRectPaddingPercent=null)}),l(()=>a.zoomBy,o=>{const t=e.current;!o||!t||(t.flyTo({zoom:t.getZoom()+(o>1?.5:-.5),animate:!0,duration:500}),a.zoomBy=null)}),l(()=>[s.moveToLocation,u.maplibreStore.cameraPort,u.routeStore.currentPosition],([o])=>{if(!o)return;const t=e.current,n=u.routeStore.currentPosition;if(!n){s.moveToLocation=!1;return}if(!t)return;const{lng:i,lat:c}=n,P=typeof i=="number"&&Number.isFinite(i)&&typeof c=="number"&&Number.isFinite(c);s.moveToLocation=!1;let p;if(P)p=[i,c];else{if(!r)return;p=T(n.x,n.y,r.gpsConfig)}t.flyTo({center:p,animate:!0,duration:1e3})}),l(()=>s.centerMap,o=>{const t=e.current;if(!o||!t||!r)return;if(!(s.list.type==="search"&&!s.list.text)){const{rect:i}=S({layerViewbox:u.layerStore.viewboxRectangle,explicitArea:v()?f():null,layerRectangle:u.layerStore.rectangle,sceneDef:m,svgArea:f()});d(t,i,r)}s.centerMap=!1})}
@@ -1 +1 @@
1
- import{LngLatBounds as D,MercatorCoordinate as E}from"maplibre-gl";import{fpGeo as I}from"../../../data/fpGeo";import{svgArea as x}from"../../../data/svg";import{uiState as z}from"../../../store";import{convertLocalToGps as u}from"../../../utils/gps";import{planBearing as N}from"../../../utils/planBearing";export const MAP_BOUNDS_PADDING_FACTOR=3,MAP_BOUNDS_MIN_PADDING_DEGREES=.02,INITIAL_FIT_ZOOM_ADJUSTMENT=.15;const T=1.42,F=.35,S=.9,A=.85,P=8,B=.05;export function deriveVenueMapBounds(t){const n=[[x.min.x,x.min.y],[x.max.x,x.min.y],[x.max.x,x.max.y],[x.min.x,x.max.y]].map(([c,l])=>u(c,l,t));if(!n.every(([c,l])=>Number.isFinite(c)&&Number.isFinite(l)))return;const e=n.map(([c])=>c),o=n.map(([,c])=>c),i=Math.min(...e),r=Math.max(...e),s=Math.min(...o),a=Math.max(...o),m=Math.max((r-i)*MAP_BOUNDS_PADDING_FACTOR,MAP_BOUNDS_MIN_PADDING_DEGREES),h=Math.max((a-s)*MAP_BOUNDS_PADDING_FACTOR,MAP_BOUNDS_MIN_PADDING_DEGREES);return[[i-m,s-h],[r+m,a+h]]}function O(t,n,e,o){const i=Math.min(t.getZoom(),n),r=(e-i)*Math.min(1,o/T);return i+r>=t.getMinZoom()-B}function w(t,n,e){if(O(t,n,e,T))return T;if(!O(t,n,e,F))return null;let o=F,i=T;for(let r=0;r<P;r++){const s=(o+i)/2;O(t,n,e,s)?o=s:i=s}return o}export function getLocalRectGeoBounds(t,n){const e=[u(t.min.x,t.min.y,n),u(t.max.x,t.min.y,n),u(t.max.x,t.max.y,n),u(t.min.x,t.max.y,n)],o=e.map(([r])=>r),i=e.map(([,r])=>r);return[[Math.min(...o),Math.min(...i)],[Math.max(...o),Math.max(...i)]]}const R=512;export function cameraForLocalRect(t,n,e,o,i){const r=[u(t.min.x,t.min.y,n),u(t.max.x,t.min.y,n),u(t.max.x,t.max.y,n),u(t.min.x,t.max.y,n)].map(([M,p])=>E.fromLngLat({lng:M,lat:p}));if(!r.every(({x:M,y:p})=>Number.isFinite(M)&&Number.isFinite(p)))return null;const s=-e*Math.PI/180,a=Math.cos(s),m=Math.sin(s),h=r.map(({x:M,y:p})=>M*a-p*m),c=r.map(({x:M,y:p})=>M*m+p*a),l=Math.max(...h)-Math.min(...h),y=Math.max(...c)-Math.min(...c);if(l<=0||y<=0)return null;const b=o.width-i.left-i.right,f=o.height-i.top-i.bottom;if(b<=0||f<=0)return null;const d=Math.min(b/(l*R),f/(y*R));if(!(d>0))return null;const g=R*d,L=(Math.min(...h)+Math.max(...h))/2-(i.left-i.right)/2/g,_=(Math.min(...c)+Math.max(...c))/2-(i.top-i.bottom)/2/g,{lng:v,lat:C}=new E(L*a+_*m,-L*m+_*a).toLngLat();return{center:[v,C],zoom:Math.log2(d)}}function U(t,n){return{top:t.top+n.top,bottom:t.bottom+n.bottom,left:t.left+n.left,right:t.right+n.right}}export function getVisibleRectFitPadding(t=0){const n=z.canvasVisibleRectPx,e=z.screenSize;return n?{top:Math.max(0,n.min.y)+t,bottom:Math.max(0,e.height-n.max.y)+t,left:Math.max(0,n.min.x)+t,right:Math.max(0,e.width-n.max.x)+t}:{top:t,bottom:t,left:t,right:t}}export function isLngLatInVisibleViewport(t,n,e){const o=t.project(n),i=t.getCanvas();return o.x>=e.left&&o.x<=i.clientWidth-e.right&&o.y>=e.top&&o.y<=i.clientHeight-e.bottom}export function deriveGeoConfig(){if(!I?.properties?.config)return null;const t=I.properties.config,n=(t.p0.lng+t.p2.lng)/2,e=(t.p0.lat+t.p2.lat)/2,o=N(t.p0,t.p2),i=Number.isFinite(o)?o:t.bearing??0;return{center:[n,e],bearing:i,zoom:16,gpsConfig:t}}export function fitMapToLocalRect(t,n,e,o={}){if(!t||!n||!e||n.size.height===1/0||n.size.width===1/0||n.size.height<=0||n.size.width<=0)return;const i=getLocalRectGeoBounds(n,e.gpsConfig),r=t.getCanvas(),s=o.paddingPercent==null?getVisibleRectFitPadding(o.padding??50):U(getVisibleRectFitPadding(0),{top:r.clientHeight*o.paddingPercent,bottom:r.clientHeight*o.paddingPercent,left:r.clientWidth*o.paddingPercent,right:r.clientWidth*o.paddingPercent}),a=cameraForLocalRect(n,e.gpsConfig,e.bearing,{width:r.clientWidth,height:r.clientHeight},s);if(!a){t.fitBounds(i,{padding:s,bearing:e.bearing,essential:!0});return}const m=t.project(t.getCenter()),h=t.project(a.center),c=Math.max(t.getCanvas().clientWidth,t.getCanvas().clientHeight,1),l=Math.hypot(h.x-m.x,h.y-m.y)/c,y=Math.abs(t.getZoom()-a.zoom),b=o.duration??Math.min(2800,500+l*450+y*150),f={center:a.center,zoom:a.zoom,bearing:e.bearing,duration:b,essential:!0};if(l<=1.2&&y<=1.5){t.easeTo(f);return}const d=t.getBounds().extend(D.convert(i)),g=t.cameraForBounds(d,{padding:s,bearing:e.bearing});if(!g?.center||typeof g.zoom!="number"||g.zoom>=t.getZoom()-.2){t.easeTo(f);return}const L=w(t,a.zoom,g.zoom);if(L!==null){const _=Math.max(F,L*S),v=Math.round(b*A);t.flyTo({...f,curve:_,duration:v});return}t.easeTo(f)}
1
+ import{LngLatBounds as S,MercatorCoordinate as R}from"maplibre-gl";import{getFpGeo as z}from"../../../data/fpGeo.js";import{getSvgArea as A}from"../../../data/svg.js";import{uiState as E}from"../../../store";import{convertLocalToGps as x}from"../../../utils/gps";import{planBearing as C}from"../../../utils/planBearing";export const MAP_BOUNDS_PADDING_FACTOR=3,MAP_BOUNDS_MIN_PADDING_DEGREES=.02,INITIAL_FIT_ZOOM_ADJUSTMENT=.15;const _=1.42,v=.35,D=.9,N=.85,P=8,B=.05;export function deriveVenueMapBounds(t){const n=A(),e=[[n.min.x,n.min.y],[n.max.x,n.min.y],[n.max.x,n.max.y],[n.min.x,n.max.y]].map(([c,u])=>x(c,u,t));if(!e.every(([c,u])=>Number.isFinite(c)&&Number.isFinite(u)))return;const o=e.map(([c])=>c),i=e.map(([,c])=>c),r=Math.min(...o),s=Math.max(...o),a=Math.min(...i),m=Math.max(...i),h=Math.max((s-r)*MAP_BOUNDS_PADDING_FACTOR,MAP_BOUNDS_MIN_PADDING_DEGREES),l=Math.max((m-a)*MAP_BOUNDS_PADDING_FACTOR,MAP_BOUNDS_MIN_PADDING_DEGREES);return[[r-h,a-l],[s+h,m+l]]}function F(t,n,e,o){const i=Math.min(t.getZoom(),n),r=(e-i)*Math.min(1,o/_);return i+r>=t.getMinZoom()-B}function w(t,n,e){if(F(t,n,e,_))return _;if(!F(t,n,e,v))return null;let o=v,i=_;for(let r=0;r<P;r++){const s=(o+i)/2;F(t,n,e,s)?o=s:i=s}return o}export function getLocalRectGeoBounds(t,n){const e=[x(t.min.x,t.min.y,n),x(t.max.x,t.min.y,n),x(t.max.x,t.max.y,n),x(t.min.x,t.max.y,n)],o=e.map(([r])=>r),i=e.map(([,r])=>r);return[[Math.min(...o),Math.min(...i)],[Math.max(...o),Math.max(...i)]]}const O=512;export function cameraForLocalRect(t,n,e,o,i){const r=[x(t.min.x,t.min.y,n),x(t.max.x,t.min.y,n),x(t.max.x,t.max.y,n),x(t.min.x,t.max.y,n)].map(([M,p])=>R.fromLngLat({lng:M,lat:p}));if(!r.every(({x:M,y:p})=>Number.isFinite(M)&&Number.isFinite(p)))return null;const s=-e*Math.PI/180,a=Math.cos(s),m=Math.sin(s),h=r.map(({x:M,y:p})=>M*a-p*m),l=r.map(({x:M,y:p})=>M*m+p*a),c=Math.max(...h)-Math.min(...h),u=Math.max(...l)-Math.min(...l);if(c<=0||u<=0)return null;const y=o.width-i.left-i.right,f=o.height-i.top-i.bottom;if(y<=0||f<=0)return null;const b=Math.min(y/(c*O),f/(u*O));if(!(b>0))return null;const g=O*b,d=(Math.min(...h)+Math.max(...h))/2-(i.left-i.right)/2/g,L=(Math.min(...l)+Math.max(...l))/2-(i.top-i.bottom)/2/g,{lng:T,lat:I}=new R(d*a+L*m,-d*m+L*a).toLngLat();return{center:[T,I],zoom:Math.log2(b)}}function U(t,n){return{top:t.top+n.top,bottom:t.bottom+n.bottom,left:t.left+n.left,right:t.right+n.right}}export function getVisibleRectFitPadding(t=0){const n=E.canvasVisibleRectPx,e=E.screenSize;return n?{top:Math.max(0,n.min.y)+t,bottom:Math.max(0,e.height-n.max.y)+t,left:Math.max(0,n.min.x)+t,right:Math.max(0,e.width-n.max.x)+t}:{top:t,bottom:t,left:t,right:t}}export function isLngLatInVisibleViewport(t,n,e){const o=t.project(n),i=t.getCanvas();return o.x>=e.left&&o.x<=i.clientWidth-e.right&&o.y>=e.top&&o.y<=i.clientHeight-e.bottom}export function deriveGeoConfig(){const t=z()?.properties?.config;if(!t)return null;const n=(t.p0.lng+t.p2.lng)/2,e=(t.p0.lat+t.p2.lat)/2,o=C(t.p0,t.p2),i=Number.isFinite(o)?o:t.bearing??0;return{center:[n,e],bearing:i,zoom:16,gpsConfig:t}}export function fitMapToLocalRect(t,n,e,o={}){if(!t||!n||!e||n.size.height===1/0||n.size.width===1/0||n.size.height<=0||n.size.width<=0)return;const i=getLocalRectGeoBounds(n,e.gpsConfig),r=t.getCanvas(),s=o.paddingPercent==null?getVisibleRectFitPadding(o.padding??50):U(getVisibleRectFitPadding(0),{top:r.clientHeight*o.paddingPercent,bottom:r.clientHeight*o.paddingPercent,left:r.clientWidth*o.paddingPercent,right:r.clientWidth*o.paddingPercent}),a=cameraForLocalRect(n,e.gpsConfig,e.bearing,{width:r.clientWidth,height:r.clientHeight},s);if(!a){t.fitBounds(i,{padding:s,bearing:e.bearing,essential:!0});return}const m=t.project(t.getCenter()),h=t.project(a.center),l=Math.max(t.getCanvas().clientWidth,t.getCanvas().clientHeight,1),c=Math.hypot(h.x-m.x,h.y-m.y)/l,u=Math.abs(t.getZoom()-a.zoom),y=o.duration??Math.min(2800,500+c*450+u*150),f={center:a.center,zoom:a.zoom,bearing:e.bearing,duration:y,essential:!0};if(c<=1.2&&u<=1.5){t.easeTo(f);return}const b=t.getBounds().extend(S.convert(i)),g=t.cameraForBounds(b,{padding:s,bearing:e.bearing});if(!g?.center||typeof g.zoom!="number"||g.zoom>=t.getZoom()-.2){t.easeTo(f);return}const d=w(t,a.zoom,g.zoom);if(d!==null){const L=Math.max(v,d*D),T=Math.round(y*N);t.flyTo({...f,curve:L,duration:T});return}t.easeTo(f)}
@@ -1 +1 @@
1
- import{fpGeo as a}from"../../../data/fpGeo.js";import f,{uiState as s}from"../../../store/index.js";import u from"../../../tools/settings.js";import{MAP_DIM_LAYER_ID as c}from"../MaplibreWrapper.js";import{resolveMapTheme as p}from"./map-theme.js";export const LIGHT_TILE_SOURCE={style:"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"},DARK_TILE_SOURCE={style:"https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"},MAP_MIN_ZOOM=12;export function applyMapDimValue(t,e){t?.getLayer(c)&&(t.setPaintProperty(c,"fill-opacity",m(e)),t.triggerRepaint())}function m(t){return Math.min(Math.max(t,0),1)}export function applyMapOptions(t,e){if(!t)return;t.setMinZoom(e.minZoom??null),t.setMaxZoom(e.maxZoom??null),t.setMaxBounds(e.maxBounds??null);const{pitch:o,maxPitch:n}=e,r=s.animatePitch,i=t.getPitch(),l=!!(r&&o!=null&&n!=null&&n<i);l||t.setMaxPitch(n??null),!(o==null||i===o)&&(r?(t.easeTo({pitch:o,duration:s.mapSettings.pitchtime}),l&&t.once("moveend",()=>t.setMaxPitch(n))):t.jumpTo({pitch:o}))}export function getTileSource(){const t=f.fp?.maplibre??window.__efpMaplibre;return t?.style?{style:t.style,offline:t.offline}:t?.styleUrl?{style:t.styleUrl,offline:t.offline}:p(a?.properties?.config?.style,u.backgroundColor)==="dark"?DARK_TILE_SOURCE:LIGHT_TILE_SOURCE}
1
+ import{getFpGeo as a}from"../../../data/fpGeo.js";import f,{uiState as s}from"../../../store/index.js";import u from"../../../tools/settings.js";import{MAP_DIM_LAYER_ID as c}from"../MaplibreWrapper.js";import{resolveMapTheme as p}from"./map-theme.js";export const LIGHT_TILE_SOURCE={style:"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"},DARK_TILE_SOURCE={style:"https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"},MAP_MIN_ZOOM=12;export function applyMapDimValue(t,e){t?.getLayer(c)&&(t.setPaintProperty(c,"fill-opacity",m(e)),t.triggerRepaint())}function m(t){return Math.min(Math.max(t,0),1)}export function applyMapOptions(t,e){if(!t)return;t.setMinZoom(e.minZoom??null),t.setMaxZoom(e.maxZoom??null),t.setMaxBounds(e.maxBounds??null);const{pitch:o,maxPitch:n}=e,r=s.animatePitch,i=t.getPitch(),l=!!(r&&o!=null&&n!=null&&n<i);l||t.setMaxPitch(n??null),!(o==null||i===o)&&(r?(t.easeTo({pitch:o,duration:s.mapSettings.pitchtime}),l&&t.once("moveend",()=>t.setMaxPitch(n))):t.jumpTo({pitch:o}))}export function getTileSource(){const t=f.fp?.maplibre??window.__efpMaplibre;return t?.style?{style:t.style,offline:t.offline}:t?.styleUrl?{style:t.styleUrl,offline:t.offline}:p(a()?.properties?.config?.style,u.backgroundColor)==="dark"?DARK_TILE_SOURCE:LIGHT_TILE_SOURCE}
@@ -1 +1 @@
1
- import{Fragment as L,jsx as e,jsxs as s}from"react/jsx-runtime";import{Badge as N}from"@expofp/ui";import{autorun as S}from"mobx";import{useLocalStore as C,useObserver as f}from"mobx-react-lite";import x,{Suspense as D}from"react";import r from"../data";import{getFpSvgJs as E}from"../data/fp-payloads";import t,{uiState as n}from"../store";import{getLocale as T,getLocales as U,t as m}from"../utils/i18n";import d from"../utils/is-iframe";const j=x.lazy(()=>import("./ViewerMenuPanel"));import"./Menu.scss";import"./Menu_custom.scss";import h from"../tools/logger";import g from"../tools/settings";const u=r.logo;h.log("Logo url: ",u),window.setTimeout(function(){const l=new Image;l.onload=()=>{h.log("Logo image loaded")},l.crossOrigin="anonymous",l.src=u},1500);function F({consent:l,isGDPR:c}){const a=C(()=>({logoVisibility:"visible",shown:!1,shownTimeout:void 0,modalOpen:!1,selectedCategoryIds:(n.selectedCategoryFilters||[]).map(o=>Number(o.id)),pendingSelectedIds:(n.selectedCategoryFilters||[]).map(o=>Number(o.id))}));S(()=>{n.menu?(a.shownTimeout=window.setTimeout(()=>a.shown=!0,1),n.list.type==="sessions"&&t.searchStore.selectSearch()):(a.shown=!1,a.shownTimeout&&window.clearTimeout(a.shownTimeout))});function p(o){if(n.kiosk)return o.preventDefault()}function v(o){o.preventDefault(),w(),t.searchStore.selectSearch()}function k(o){o.preventDefault(),t.fp?.onLeaveEvent?.()}function _(o){o.preventDefault(),t.clickLanguage()}return f(()=>{if(!n.menu)return null;const o=t.boothStore.booths.filter(i=>i.bookmarked).map(i=>i.name),b=E().__fpSettings?.fpVer?`https://d2.expofp.com/export/v2/${g.EXPO}/pdf`:`https://api.expofp.com/service/convert/${g.EXPO}/pdf`,y=n.viewerMode&&typeof t.fp?.onLeaveEvent=="function";return s("div",{className:`menu ${a.shown?"shown":""}`,children:[d?e("div",{className:"menu__cover -empty"}):e("div",{className:"menu__cover",children:e("a",{href:r.homeUrl,target:"_blank",rel:"noopener noreferrer",onClick:p,children:e("img",{src:u,onError:()=>a.logoVisibility="hidden",style:{visibility:a.logoVisibility},alt:"",crossOrigin:"anonymous"})})}),s("div",{className:"menu__content",children:[n.viewerMode&&e(D,{fallback:null,children:e(j,{})}),!n.viewerMode&&e("a",{href:"/#",onClick:v,className:"menu__item",children:m("Search")}),!r.hideEventHomeLink&&!n.kiosk&&!d&&!!r.homeUrl&&s("a",{href:r.homeUrl,target:"_blank",className:"menu__item",rel:"noopener noreferrer",children:[m("Event Home").replace(/ /g,"\xA0"),e("i",{className:"icon-link-external"})]}),!r.hideRegisterToAttendLink&&!n.kiosk&&!d&&!!r.registerUrl&&s("a",{href:r.registerUrl,target:"_blank",className:"menu__item",rel:"noopener noreferrer",children:[m("Register to Attend").replace(/ /g,"\xA0"),e("i",{className:"icon-link-external"})]}),!n.hideLanguage&&!r.hideLanguage&&!r.hideLanguageLink&&s("a",{href:"?language",onClick:_,className:"menu__item -language",children:[s("span",{children:[m("Language")," "]}),s("span",{className:"menu__icons",children:[e(N,{variant:"gray",size:"md",noMargins:!0,rounded:!0,children:U().find(i=>i.id===T())?.name}),e("i",{className:"icon-chevron-right"})]})]}),!r.hideDownloadPdfLink&&!n.kiosk&&e("a",{className:"menu__item -pdf",target:"_blank",rel:"noopener noreferrer",href:`${b}/?exhibitors=true&bookmarks=${o.join(",")}&layers=${(t.layerStore.layers.length>=t.layerStore.visible.length?t.layerStore.visible.map(i=>i.name).join(","):"").replace(/&/g,"%26")}`,children:m("Download PDF")}),l==="ask"&&c&&e("a",{href:"/#",className:"menu__item -cookie-consent",onClick:i=>{i.preventDefault(),n.hideCookieConsent=!1},children:m("Review Cookie Consent")}),y&&e("div",{className:"menu__item-leave",children:e("a",{href:"/#",className:"menu__item -leave-event menu__leave-link",onClick:k,children:m("Select another event")})})]})]})});function w(){n.menu=!1}}export default({isGDPR:l,consent:c})=>f(()=>e(L,{children:n.menu?e(F,{isGDPR:l,consent:c}):null}));
1
+ import{Fragment as b,jsx as e,jsxs as l}from"react/jsx-runtime";import{Badge as y}from"@expofp/ui";import{useLocalStore as L,useObserver as u}from"mobx-react-lite";import N,{Suspense as S}from"react";import r from"../data";import{getFpSvgJs as C}from"../data/fp-payloads";import t,{uiState as n}from"../store";import{getLocale as x,getLocales as D,t as m}from"../utils/i18n";import d from"../utils/is-iframe";import{useAutorun as E}from"../utils/mobx.js";const T=N.lazy(()=>import("./ViewerMenuPanel"));import"./Menu.scss";import"./Menu_custom.scss";import j from"../tools/logger";import f from"../tools/settings";window.setTimeout(function(){const s=new Image;s.onload=()=>{j.log("Logo image loaded")},s.crossOrigin="anonymous",s.src=r.logo},1500);function F({consent:s,isGDPR:c}){const a=L(()=>({logoVisibility:"visible",shown:!1,shownTimeout:void 0,modalOpen:!1,selectedCategoryIds:(n.selectedCategoryFilters||[]).map(o=>Number(o.id)),pendingSelectedIds:(n.selectedCategoryFilters||[]).map(o=>Number(o.id))}));E(()=>{n.menu?(a.shownTimeout=window.setTimeout(()=>a.shown=!0,1),n.list.type==="sessions"&&t.searchStore.selectSearch()):(a.shown=!1,a.shownTimeout&&window.clearTimeout(a.shownTimeout))});function h(o){if(n.kiosk)return o.preventDefault()}function g(o){o.preventDefault(),k(),t.searchStore.selectSearch()}function p(o){o.preventDefault(),t.fp?.onLeaveEvent?.()}function v(o){o.preventDefault(),t.clickLanguage()}return u(()=>{if(!n.menu)return null;const o=t.boothStore.booths.filter(i=>i.bookmarked).map(i=>i.name),_=C().__fpSettings?.fpVer?`https://d2.expofp.com/export/v2/${f.EXPO}/pdf`:`https://api.expofp.com/service/convert/${f.EXPO}/pdf`,w=n.viewerMode&&typeof t.fp?.onLeaveEvent=="function";return l("div",{className:`menu ${a.shown?"shown":""}`,children:[d?e("div",{className:"menu__cover -empty"}):e("div",{className:"menu__cover",children:e("a",{href:r.homeUrl,target:"_blank",rel:"noopener noreferrer",onClick:h,children:e("img",{src:r.logo,onError:()=>a.logoVisibility="hidden",style:{visibility:a.logoVisibility},alt:"",crossOrigin:"anonymous"})})}),l("div",{className:"menu__content",children:[n.viewerMode&&e(S,{fallback:null,children:e(T,{})}),!n.viewerMode&&e("a",{href:"/#",onClick:g,className:"menu__item",children:m("Search")}),!r.hideEventHomeLink&&!n.kiosk&&!d&&!!r.homeUrl&&l("a",{href:r.homeUrl,target:"_blank",className:"menu__item",rel:"noopener noreferrer",children:[m("Event Home").replace(/ /g,"\xA0"),e("i",{className:"icon-link-external"})]}),!r.hideRegisterToAttendLink&&!n.kiosk&&!d&&!!r.registerUrl&&l("a",{href:r.registerUrl,target:"_blank",className:"menu__item",rel:"noopener noreferrer",children:[m("Register to Attend").replace(/ /g,"\xA0"),e("i",{className:"icon-link-external"})]}),!n.hideLanguage&&!r.hideLanguage&&!r.hideLanguageLink&&l("a",{href:"?language",onClick:v,className:"menu__item -language",children:[l("span",{children:[m("Language")," "]}),l("span",{className:"menu__icons",children:[e(y,{variant:"gray",size:"md",noMargins:!0,rounded:!0,children:D().find(i=>i.id===x())?.name}),e("i",{className:"icon-chevron-right"})]})]}),!r.hideDownloadPdfLink&&!n.kiosk&&e("a",{className:"menu__item -pdf",target:"_blank",rel:"noopener noreferrer",href:`${_}/?exhibitors=true&bookmarks=${o.join(",")}&layers=${(t.layerStore.layers.length>=t.layerStore.visible.length?t.layerStore.visible.map(i=>i.name).join(","):"").replace(/&/g,"%26")}`,children:m("Download PDF")}),s==="ask"&&c&&e("a",{href:"/#",className:"menu__item -cookie-consent",onClick:i=>{i.preventDefault(),n.hideCookieConsent=!1},children:m("Review Cookie Consent")}),w&&e("div",{className:"menu__item-leave",children:e("a",{href:"/#",className:"menu__item -leave-event menu__leave-link",onClick:p,children:m("Select another event")})})]})]})});function k(){n.menu=!1}}export default({isGDPR:s,consent:c})=>u(()=>e(b,{children:n.menu?e(F,{isGDPR:s,consent:c}):null}));
@@ -35,6 +35,11 @@ interface ExtendFeatureCollection {
35
35
  properties: FpGeoProperties;
36
36
  images: ImageData[];
37
37
  }
38
- export declare const fpGeo: ExtendFeatureCollection | undefined;
38
+ /**
39
+ * The live event's georeferencing block, or `undefined` when the drawing has
40
+ * none. Read through the call — a module-scope capture would pin the previous
41
+ * plan's geometry across a swap (ADR-0011).
42
+ */
43
+ export declare function getFpGeo(): ExtendFeatureCollection | undefined;
39
44
  export {};
40
45
  //# sourceMappingURL=fpGeo.d.ts.map
@@ -1 +1 @@
1
- import{getFpSvgJs as o}from"./fp-payloads.js";export const fpGeo=o().__fpGeo;
1
+ import{getFpSvgJs as e}from"./fp-payloads.js";export function getFpGeo(){return e().__fpGeo}
@@ -1,9 +1,14 @@
1
1
  import { type Config } from '@expofp/config';
2
2
  /**
3
- * The event data document, read straight off the active config — the merged,
4
- * asset-resolved, normalized and frozen copy `loadConfig` produced (it carries
5
- * every legacy `data.js` field; `window.__data` is gone). This module only
6
- * loads inside the floorplan chunk, after `load()` has called `setConfig`.
3
+ * The event data document — the merged, asset-resolved, normalized and frozen
4
+ * copy `loadConfig` produced (it carries every legacy `data.js` field;
5
+ * `window.__data` is gone).
6
+ *
7
+ * Every property read forwards to whatever config is installed *now*, so a
8
+ * plan swap is visible through this binding without any of its ~38 importers
9
+ * changing (ADR-0011). Capturing it — `const { title } = data` at module
10
+ * scope, or stashing the object in a module-level variable — reintroduces the
11
+ * staleness this indirection exists to remove.
7
12
  */
8
13
  declare const data: Config;
9
14
  export default data;
@@ -1 +1 @@
1
- import{getConfig as t}from"@expofp/config";const o=t();export default o;
1
+ import{getConfig as t}from"@expofp/config";import{createSwappableProxy as a}from"../utils/swappable-proxy.js";const o=a("data",()=>t());export default o;