@expofp/floorplan 3.5.2 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/browser/{CookieConsent-SW2eXIC8.js → CookieConsent-D4hudhgN.js} +8 -8
  2. package/dist/browser/{Debug-t7OzIN-8.js → Debug-C6vAYMhX.js} +7 -7
  3. package/dist/browser/{Demo-DJ98mlUr.js → Demo-DtTuLI8Z.js} +11 -11
  4. package/dist/browser/{Free-B9JCPcnr.js → Free-CqdWCHcR.js} +11 -11
  5. package/dist/browser/{Gallery-CPBGS9q7.js → Gallery-8RDDPykf.js} +10 -10
  6. package/dist/browser/{GpsLoader-vcgurCKn.js → GpsLoader-B4FEU6gL.js} +42 -42
  7. package/dist/browser/{KioskStore-DzLhE0fK.js → KioskStore-phPgRGhj.js} +36 -36
  8. package/dist/browser/{MaplibreAdapter-CAGVMAol.js → MaplibreAdapter-CS16BDJC.js} +98 -98
  9. package/dist/browser/{Modal-DBVl72uz.js → Modal-D_X6o9Jg.js} +10 -10
  10. package/dist/browser/{PermissionNotice-BDny4W7h.js → PermissionNotice-B226CFBT.js} +7 -7
  11. package/dist/browser/{SetKioskMode-CjKFTXwj.js → SetKioskMode-BE0tkdDL.js} +11 -11
  12. package/dist/browser/{ShowKiosk-bwEsTLSP.js → ShowKiosk-SbRgpnQB.js} +10 -10
  13. package/dist/browser/{TouchHand-DFPQ2vE8.js → TouchHand-CzEqXotc.js} +4 -4
  14. package/dist/browser/{ViewerMenuPanel-DK-DJHgD.js → ViewerMenuPanel-CwOeHoJI.js} +12 -12
  15. package/dist/browser/{add-debug-secret-listener-ND2YIuwE.js → add-debug-secret-listener-DiNpUPIy.js} +1 -1
  16. package/dist/browser/{boolean-editor-BXVL077p.js → boolean-editor-B4fmO-H1.js} +9 -9
  17. package/dist/browser/{bootIntercom-DLTAHEbT.js → bootIntercom-78s2IZm1.js} +2 -2
  18. package/dist/browser/{browser-V3D46fyx.js → browser-D0xyTgL5.js} +2 -2
  19. package/dist/browser/bundle.json +59 -56
  20. package/dist/browser/{classnames-Dxv3Iqu-.js → classnames-BrYUjPEV.js} +2 -2
  21. package/dist/browser/{client-C1kJisHy.js → client-BFmngvOl.js} +4 -4
  22. package/dist/browser/{components-B8Qifx-N.js → components-C562ZBah.js} +1522 -1514
  23. package/dist/browser/{createWayfinding-C8Pmd2H5.js → createWayfinding-DK2PWhbe.js} +598 -614
  24. package/dist/browser/{debug-overlay-DWJkUc3u.js → debug-overlay-z6WXDPBn.js} +10 -10
  25. package/dist/browser/{debug-ui-jAj6--ux.js → debug-ui-sCW8RARU.js} +6 -6
  26. package/dist/browser/{dist-DUIasJnS.js → dist-B1wg_Vg-.js} +3 -3
  27. package/dist/browser/{dist-CPyShXna.js → dist-CRY34h6v.js} +5 -5
  28. package/dist/browser/{dist-BHV9ghY4.js → dist-DnAXhxh2.js} +6 -6
  29. package/dist/browser/{efp-debug-init-AR3Fvs_0.js → efp-debug-init-B_ntwOhP.js} +2 -2
  30. package/dist/browser/{enum-editor-FiZIrNXM.js → enum-editor-DbuXf8r8.js} +11 -11
  31. package/dist/browser/{event-not-found-BzPx68a_.js → event-not-found-CAmc16WN.js} +1 -1
  32. package/dist/browser/{exports-DlEzkzSC.js → exports-BD8GG1L5.js} +1 -1
  33. package/dist/browser/{favicon-Dobo0b59.js → favicon-sZdpacxH.js} +1 -1
  34. package/dist/browser/{fetch-retry.umd-CXT8SYkm.js → fetch-retry.umd-AjUp2dMf.js} +2 -2
  35. package/dist/browser/{flex-DGR_Loqd.js → flex-CCWA2Kd-.js} +5 -5
  36. package/dist/browser/{floorplan.loader-GMByEo0q.js → floorplan.loader-CCXe84-M.js} +48 -47
  37. package/dist/browser/{floorplan.ready-DTwVRPUA.js → floorplan.ready-VVqKSxrS.js} +232 -232
  38. package/dist/browser/{fuse-CoX8SCVF.js → fuse-B8HbR5wR.js} +2 -2
  39. package/dist/browser/{i18n-CONnsQk4.js → i18n-C4ccU4Uz.js} +570 -543
  40. package/dist/browser/icons/departure_inactive.svg +5 -0
  41. package/dist/browser/index.js +11 -11
  42. package/dist/browser/{jsx-runtime-iIXfJE8d.js → jsx-runtime-zxgo_t9B.js} +2 -2
  43. package/dist/browser/{lib-CAUtTowO.js → lib-B4liZrwq.js} +4 -4
  44. package/dist/browser/{main-5p-fstPx.js → main-Bzb6dYP_.js} +1 -1
  45. package/dist/browser/{mobx-CP3094rF.js → mobx-COHcSxbj.js} +8 -8
  46. package/dist/browser/{particles.min-BvP0Ecuj.js → particles.min-B07pddyr.js} +2 -2
  47. package/dist/browser/{prop-types-CtPkc8Dm.js → prop-types-S_wOlY3G.js} +2 -2
  48. package/dist/browser/{react-dom-Bi44rMnr.js → react-dom-uOgI3fJi.js} +3 -3
  49. package/dist/browser/{react-DgvgFS2Z.js → react-v-0l0dCU.js} +2 -2
  50. package/dist/browser/{reset-all-settings-CB8d29KN.js → reset-all-settings-DP_XEkZl.js} +7 -7
  51. package/dist/browser/{rolldown-runtime-D0nkOxqx.js → rolldown-runtime-fX7LzKTd.js} +1 -1
  52. package/dist/browser/{settings-CTPClT89.js → settings-CvUKxJUO.js} +2 -2
  53. package/dist/browser/{settings-item-DFxxEXOa.js → settings-item-9XX6a5Rl.js} +6 -6
  54. package/dist/browser/{storage-DvQIEAC7.js → storage-I3dC3nwm.js} +5 -5
  55. package/dist/browser/{store-BlZ4xT_G.js → store-DZbEm-97.js} +5746 -5681
  56. package/dist/browser/{string-editor-YIMEKgRw.js → string-editor-CC5dLlZp.js} +7 -7
  57. package/dist/browser/{theme-Gip68cNV.js → theme-CFDTZaHO.js} +8 -8
  58. package/dist/browser/{ui-CZUswZut.js → ui-R-PKHh7O.js} +8 -8
  59. package/dist/browser/{useRenderTarget-DTeVFvZz.js → useRenderTarget-Da6-PWjd.js} +4 -4
  60. package/dist/esm/components/Kiosk/integrateKiosk.js +1 -1
  61. package/dist/esm/components/Map/Map.js +1 -1
  62. package/dist/esm/components/Map/drawing/config/config-all.js +1 -1
  63. package/dist/esm/components/Wayfinding.js +1 -1
  64. package/dist/esm/services/routing.js +1 -1
  65. package/dist/esm/store/RootStore.js +1 -1
  66. package/dist/esm/store/RoutePlannerStore.js +1 -1
  67. package/dist/esm/store/RouteStore.d.ts +15 -6
  68. package/dist/esm/store/RouteStore.js +1 -1
  69. package/dist/esm/store/UIState.d.ts +1 -1
  70. package/dist/esm/store/UIState.js +1 -1
  71. package/dist/esm/types.d.ts +1 -1
  72. package/dist/esm/utils/loadIcons.js +1 -1
  73. package/dist/esm/wayfinding/adapters/arbitraryPoint.d.ts +28 -0
  74. package/dist/esm/wayfinding/adapters/arbitraryPoint.js +1 -0
  75. package/dist/esm/wayfinding/adapters/boothToEndpoint.d.ts +3 -3
  76. package/dist/esm/wayfinding/adapters/boothToEndpoint.js +1 -1
  77. package/dist/esm/wayfinding/adapters/canvasIconProvider.js +1 -1
  78. package/dist/esm/wayfinding/adapters/iconProvider.d.ts +1 -1
  79. package/dist/esm/wayfinding/adapters/index.d.ts +2 -0
  80. package/dist/esm/wayfinding/adapters/index.js +1 -1
  81. package/dist/esm/wayfinding/bindMobxReactions.d.ts +9 -1
  82. package/dist/esm/wayfinding/bindMobxReactions.js +1 -1
  83. package/dist/esm/wayfinding/core/createWayfindingEngine.js +1 -1
  84. package/dist/esm/wayfinding/core/geometry/projectPointOnSegment.d.ts +23 -0
  85. package/dist/esm/wayfinding/core/geometry/projectPointOnSegment.js +1 -0
  86. package/dist/esm/wayfinding/core/index.d.ts +6 -3
  87. package/dist/esm/wayfinding/core/index.js +1 -1
  88. package/dist/esm/wayfinding/core/position/gpsThreshold.d.ts +9 -0
  89. package/dist/esm/wayfinding/core/position/gpsThreshold.js +1 -1
  90. package/dist/esm/wayfinding/core/position/rerouteController.d.ts +10 -0
  91. package/dist/esm/wayfinding/core/position/rerouteController.js +1 -0
  92. package/dist/esm/wayfinding/core/position/snapToRoute.d.ts +2 -2
  93. package/dist/esm/wayfinding/core/position/snapToRoute.js +1 -1
  94. package/dist/esm/wayfinding/core/routing/{findNearestGraphPoint.d.ts → graphPointResolvers.d.ts} +1 -3
  95. package/dist/esm/wayfinding/core/routing/graphPointResolvers.js +1 -0
  96. package/dist/esm/wayfinding/core/routing/resolveWaypointCandidates.d.ts +17 -3
  97. package/dist/esm/wayfinding/core/routing/resolveWaypointCandidates.js +1 -1
  98. package/dist/esm/wayfinding/core/types.d.ts +5 -6
  99. package/dist/esm/wayfinding/createWayfinding.js +1 -1
  100. package/dist/esm/wayfinding/layers.d.ts +1 -0
  101. package/dist/esm/wayfinding/layers.js +1 -1
  102. package/dist/esm/wayfinding/runtime/createWayfindingRuntime.js +1 -1
  103. package/dist/esm/wayfinding/runtime/endpointView.d.ts +4 -1
  104. package/dist/esm/wayfinding/runtime/endpointView.js +1 -1
  105. package/dist/esm/wayfinding/runtime/positionTrailView.d.ts +14 -20
  106. package/dist/esm/wayfinding/runtime/positionTrailView.js +1 -1
  107. package/dist/esm/wayfinding/runtime/positionView.d.ts +1 -0
  108. package/dist/esm/wayfinding/runtime/positionView.js +1 -1
  109. package/dist/esm/wayfinding/runtime/routeRenderData.d.ts +1 -1
  110. package/dist/esm/wayfinding/runtime/types.d.ts +1 -0
  111. package/package.json +3 -3
  112. package/dist/esm/RouteCutIn.d.ts +0 -23
  113. package/dist/esm/RouteCutIn.js +0 -1
  114. package/dist/esm/wayfinding/core/position/shouldReroute.d.ts +0 -3
  115. package/dist/esm/wayfinding/core/position/shouldReroute.js +0 -1
  116. package/dist/esm/wayfinding/core/routing/findNearestGraphPoint.js +0 -1
  117. package/dist/esm/wayfinding/utils/findBoothInRadius.d.ts +0 -4
  118. package/dist/esm/wayfinding/utils/findBoothInRadius.js +0 -1
@@ -0,0 +1,10 @@
1
+ import type { RouteLine, RoutePoint } from "../types";
2
+ /** Decides whether the current GPS tick warrants rebuilding the route. */
3
+ export interface RerouteController {
4
+ /** Evaluates the current tick. Returns `true` when the caller should rebuild the route. */
5
+ shouldReroute(position: RoutePoint, routeLines: RouteLine[]): boolean;
6
+ }
7
+ /** `thresholdSvg` — plan-scale-aware off-route distance (SVG units), produced by
8
+ * `resolveRerouteThresholdSvg` and passed in by the composition root. */
9
+ export declare function createRerouteController(thresholdSvg: number): RerouteController;
10
+ //# sourceMappingURL=rerouteController.d.ts.map
@@ -0,0 +1 @@
1
+ import{distancePointToRouteOnLayer as o}from"./distanceToRoute";export function createRerouteController(n){return{shouldReroute(r,t){if(!t.length)return!1;const e=r.layer;return e&&!t.some(a=>a.p0.layer===e&&a.p1.layer===e)?!0:o({x:r.x,y:r.y,layer:e},t)>n}}}
@@ -1,4 +1,4 @@
1
- import type { PositionPoint, RouteLine, RouteSnapResult, SnapToRouteConfig } from "../types";
1
+ import type { RouteLine, RoutePoint, RouteSnapResult, SnapToRouteConfig } from "../types";
2
2
  export { SNAP_THRESHOLD_METERS } from "./gpsThreshold";
3
- export declare function snapToRoute(position: PositionPoint, routeLines: RouteLine[], config: SnapToRouteConfig): RouteSnapResult;
3
+ export declare function snapToRoute(position: RoutePoint, routeLines: RouteLine[], config: SnapToRouteConfig): RouteSnapResult;
4
4
  //# sourceMappingURL=snapToRoute.d.ts.map
@@ -1 +1 @@
1
- import{pointInPolygon as v}from"../geometry/pointInPolygon";function R(n,o){let p=0;for(const t of n){const e=Math.hypot(t.p1.x-t.p0.x,t.p1.y-t.p0.y);if(e!==0){if(p+e>=o){const c=(o-p)/e,P=t.p0.x+(t.p1.x-t.p0.x)*c,l=t.p0.y+(t.p1.y-t.p0.y)*c;return{point:{layer:t.p0.layer,x:P,y:l},line:t}}p+=e}}const i=n[n.length-1];return{point:{layer:i.p0.layer,x:i.p1.x,y:i.p1.y},line:i}}export{SNAP_THRESHOLD_METERS}from"./gpsThreshold";export function snapToRoute(n,o,p){const i=o.length;if(!i)return{snapped:!1};const{snapThreshold:t,to:e,from:c,minRemainingUnits:P=.5}=p,l=n.z!=null?String(n.z):null;let M=1/0,x=null,f=0,b=l==null;for(let a=0;a<i;a++){const d=o[a],{p0:s,p1:u}=d,h=u.x-s.x,S=u.y-s.y,D=h*h+S*S;if(D===0)continue;const F=Math.sqrt(D);if(l!=null&&String(s.layer)!==l){f+=F;continue}b=!0;const O=((n.x-s.x)*h+(n.y-s.y)*S)/D,g=Math.max(0,Math.min(1,O)),_=s.x+h*g,w=s.y+S*g,q=Math.hypot(n.x-_,n.y-w);q<M&&(M=q,x={segmentIndex:a,t:g,distanceFromPolylineStart:f+F*g}),f+=F}if(l!=null&&!b)return{snapped:!1};const r=f,E=o[0].p0,A=o[i-1].p1,z=Math.hypot(e.x-E.x,e.y-E.y),H=Math.hypot(e.x-A.x,e.y-A.y),m=z<=H,T=Math.min(P,r);if(c?.bounds&&(l==null||!c.layer||c.layer===l)&&v({x:n.x,y:n.y},c.bounds)){const a=r,d=m?a:r-a,s=R(o,d);return{snapped:!0,snappedPoint:s.point,snappedLine:s.line,distance:a}}if(e.bounds&&(l==null||!e.layer||e.layer===l)&&v({x:n.x,y:n.y},e.bounds)){const a=T,d=r-a,u=R(o,m?a:d);return{snapped:!0,snappedPoint:u.point,snappedLine:u.line,distance:a}}if(!x||M>t)return{snapped:!1};let y=m?x.distanceFromPolylineStart:r-x.distanceFromPolylineStart;y<T&&(y=T);const L=r-y,I=R(o,m?y:L);return{snapped:!0,snappedPoint:I.point,snappedLine:I.line,distance:y}}
1
+ import{pointInPolygon as E}from"../geometry/pointInPolygon";import{projectPointOnSegment as O}from"../geometry/projectPointOnSegment";function D(o,a){let y=0;for(const n of o){const t=Math.hypot(n.p1.x-n.p0.x,n.p1.y-n.p0.y);if(t!==0){if(y+t>=a){const r=(a-y)/t,h=n.p0.x+(n.p1.x-n.p0.x)*r,s=n.p0.y+(n.p1.y-n.p0.y)*r;return{point:{layer:n.p0.layer,x:h,y:s},line:n}}y+=t}}const i=o[o.length-1];return{point:{layer:i.p0.layer,x:i.p1.x,y:i.p1.y},line:i}}export{SNAP_THRESHOLD_METERS}from"./gpsThreshold";export function snapToRoute(o,a,y){const i=a.length;if(!i)return{snapped:!1};const{snapThreshold:n,to:t,from:r,minRemainingUnits:h=.5}=y,s=o.layer||null;let P=1/0,u=null,m=0,F=s==null;for(let e=0;e<i;e++){const f=a[e],{p0:l,p1:c}=f,S=Math.hypot(c.x-l.x,c.y-l.y);if(S===0)continue;if(s!=null&&String(l.layer)!==s){m+=S;continue}F=!0;const g=O({x:o.x,y:o.y},l,c);g.distance<P&&(P=g.distance,u={segmentIndex:e,t:g.t,distanceFromPolylineStart:m+S*g.t}),m+=S}if(s!=null&&!F)return{snapped:!1};const p=m,b=a[0].p0,M=a[i-1].p1,A=Math.hypot(t.x-b.x,t.y-b.y),I=Math.hypot(t.x-M.x,t.y-M.y),x=A<=I,T=Math.min(h,p);if(r?.bounds&&(s==null||!r.layer||r.layer===s)&&E({x:o.x,y:o.y},r.bounds)){const e=p,f=x?e:p-e,l=D(a,f);return{snapped:!0,snappedPoint:l.point,snappedLine:l.line,distance:e}}if(t.bounds&&(s==null||!t.layer||t.layer===s)&&E({x:o.x,y:o.y},t.bounds)){const e=T,f=p-e,c=D(a,x?e:f);return{snapped:!0,snappedPoint:c.point,snappedLine:c.line,distance:e}}if(!u||P>n)return{snapped:!1};let d=x?u.distanceFromPolylineStart:p-u.distanceFromPolylineStart;d<T&&(d=T);const L=p-d,R=D(a,x?d:L);return{snapped:!0,snappedPoint:R.point,snappedLine:R.line,distance:d}}
@@ -1,6 +1,4 @@
1
1
  import type { GraphDataSource, PolygonVertex, RoutePoint } from "../types";
2
2
  /** Graph endpoints inside a convex polygon (e.g. booth rect), filtered by layer. */
3
3
  export declare function findGraphPointsInPolygon(dataSource: GraphDataSource, polygon: ReadonlyArray<PolygonVertex>, layer?: string): RoutePoint[];
4
- /** Nearest graph endpoint by Euclidean distance, optionally filtered by layer. */
5
- export declare function findNearestGraphPoint(dataSource: GraphDataSource, point: RoutePoint): RoutePoint | null;
6
- //# sourceMappingURL=findNearestGraphPoint.d.ts.map
4
+ //# sourceMappingURL=graphPointResolvers.d.ts.map
@@ -0,0 +1 @@
1
+ import{computePolygonArea as i,pointInPolygon as p}from"../geometry/pointInPolygon";export function findGraphPointsInPolygon(r,o,n){const e=i(o);return r.getLineEnds().filter(t=>(!n||t.layer===n)&&p(t,o,e))}
@@ -1,4 +1,18 @@
1
- import type { GraphInstance, RouteEndpoint, RoutePoint } from "../types";
2
- /** Resolves a route endpoint to candidate graph points. */
3
- export declare function resolveWaypointCandidates(graph: GraphInstance, endpoint: RouteEndpoint): RoutePoint[];
1
+ import type { GraphInstance, RouteEndpoint, RouteLine, RoutePoint } from "../types";
2
+ export interface OffGraphEntry {
3
+ readonly segment: RouteLine;
4
+ readonly projection: RoutePoint;
5
+ }
6
+ /** A* candidates plus an optional `offGraphEntry` — set when the route's entry needs perpendicular
7
+ * trim to land on a point inside a segment instead of at a graph node. */
8
+ export interface ResolvedCandidates {
9
+ readonly candidates: RoutePoint[];
10
+ readonly offGraphEntry: OffGraphEntry | null;
11
+ }
12
+ /** Turns a route endpoint into A* candidates.
13
+ * - Booth (has `bounds`) → graph nodes inside the polygon.
14
+ * - Off-graph point → nearest segment on its layer; both ends are candidates and `offGraphEntry`
15
+ * holds the perpendicular foot to trim to. If the foot falls off the segment, attach at its node.
16
+ * */
17
+ export declare function resolveWaypointCandidates(graph: GraphInstance, endpoint: RouteEndpoint): ResolvedCandidates;
4
18
  //# sourceMappingURL=resolveWaypointCandidates.d.ts.map
@@ -1 +1 @@
1
- import{findGraphPointsInPolygon as a,findNearestGraphPoint as e}from"./findNearestGraphPoint";export function resolveWaypointCandidates(o,r){if(r.bounds?.length)return a(o.dataSource,r.bounds,r.layer);const t=e(o.dataSource,r);return t?[t]:[]}
1
+ import{projectPointOnSegment as l}from"../geometry/projectPointOnSegment";import{findGraphPointsInPolygon as p}from"./graphPointResolvers";export function resolveWaypointCandidates(i,e){if(e.bounds?.length)return{candidates:p(i.dataSource,e.bounds,e.layer),offGraphEntry:null};let a=null,f=1/0;for(const t of i.dataSource.getLines()){if(t.virtual||e.layer&&t.p0.layer!==e.layer||t.p0.x===t.p1.x&&t.p0.y===t.p1.y)continue;const o=l(e,t.p0,t.p1);o.distance<f&&(f=o.distance,a={segment:t,proj:o})}if(!a)return{candidates:[],offGraphEntry:null};const{segment:n,proj:r}=a;return r.t===0?{candidates:[n.p0],offGraphEntry:null}:r.t===1?{candidates:[n.p1],offGraphEntry:null}:{candidates:[n.p0,n.p1],offGraphEntry:{segment:n,projection:{layer:n.p0.layer,x:r.projected.x,y:r.projected.y}}}}
@@ -64,12 +64,6 @@ export interface RouteResult {
64
64
  readonly lines: RouteLine[];
65
65
  readonly totalDistance: number;
66
66
  }
67
- /** Minimal position interface — replaces CurrentPosition class dependency in core. */
68
- export interface PositionPoint {
69
- readonly x: number;
70
- readonly y: number;
71
- readonly z?: string | number | null;
72
- }
73
67
  export type RouteSnapResult = {
74
68
  snapped: false;
75
69
  } | {
@@ -83,9 +77,14 @@ export type RouteSnapResult = {
83
77
  * Route endpoint: anchor on a layer, with optional perimeter polygon (booth bounds).
84
78
  * With `bounds` → engine picks the optimal graph node inside the polygon.
85
79
  * Without `bounds` → off-graph point (e.g. kiosk); engine snaps to nearest graph anchor.
80
+ *
81
+ * `id` is an opaque runtime discriminator the engine ignores — used by the
82
+ * adapter layer to mark off-graph endpoints (e.g. CP-derived vs kiosk anchor)
83
+ * so the renderer can branch on endpoint origin without re-checking UI types.
86
84
  */
87
85
  export interface RouteEndpoint extends RoutePoint {
88
86
  readonly bounds?: ReadonlyArray<PolygonVertex>;
87
+ readonly id?: string;
89
88
  }
90
89
  export type SnapToRouteConfig = {
91
90
  snapThreshold: number;
@@ -1 +1 @@
1
- import _ from"../core/Rect";import{fpGeo as p}from"../data/fpGeo";import t,{layersStore as n,uiState as f}from"../store";import{createCanvasIconProvider as A,createFloorContext as u,graphDataSource as x}from"./adapters";import{bindMobxReactions as T}from"./bindMobxReactions";import{createWayfindingEngine as M,getThresholdSafe as L,getThresholdFromMetersToSvg as N,SNAP_THRESHOLD_METERS as I}from"./core";import{createKioskHandler as W}from"./handlers/kioskHandler";import{createYahHandler as k}from"./handlers/yahHandler";import{WF_LINES_ANIMATED_LAYER_NAME as v,WF_LINES_LAYER_NAME as F,WF_POINTS_LAYER_NAME as H,WF_TRAIL_LAYER_NAME as P}from"./layers";import{createWayfindingRuntime as C}from"./runtime/createWayfindingRuntime";import{createWayfindingRenderer as D}from"./renderer";export function createWayfinding(m){const l=M(x),a=A({iconMap:t.fp.icons,pixelRatio:devicePixelRatio}),r=D(m),s=u(n,t.routeStore),i={points:H,trail:P,lines:F,linesAnimated:v},d=L(p?.properties?.config?.snapThreshold)||I,y=N({thresholdInMeters:d,gpsConfig:p?.properties?.config}),c=C({engine:l,renderer:r,iconProvider:a,floorContext:s,layers:i,snapThreshold:y,onTransitionClick:o=>{o.role==="exit"&&n.updateVisibility(o.targetLayer,!0)},onRouteUpdate:(o,e)=>{if(t.routeStore.updateRoute(o),e){const S=e.x2-e.x1,E=e.y2-e.y1;f.moveToRect=_.fromX1y1x2y2(e.x1,e.y1,e.x2,e.y2).withPadding(S,E)}},onRouteDistance:o=>t.routeStore.updateRouteDistance(o)}),R=W({renderer:r,kioskIconMap:t.fp.icons,layer:i.points}),g=k({renderer:r,iconProvider:a,floorContext:s,layer:i.points}),h=T({runtime:c,kioskHandler:R,yahHandler:g,stores:{routeStore:t.routeStore,uiState:f,layerStore:n}});return r.flush(),()=>{h(),c.destroy()}}
1
+ import h from"../core/Rect";import{fpGeo as n}from"../data/fpGeo";import o,{layersStore as s,uiState as f}from"../store";import{createCanvasIconProvider as E,createFloorContext as y,graphDataSource as T}from"./adapters";import{bindMobxReactions as A}from"./bindMobxReactions";import{SNAP_THRESHOLD_METERS as M,createWayfindingEngine as N,getThresholdFromMetersToSvg as x,getThresholdSafe as I,resolveRerouteThresholdSvg as L}from"./core";import{createKioskHandler as v}from"./handlers/kioskHandler";import{createYahHandler as W}from"./handlers/yahHandler";import{WF_CURRENT_POSITION_LAYER_NAME as F,WF_LINES_ANIMATED_LAYER_NAME as P,WF_LINES_LAYER_NAME as k,WF_POINTS_LAYER_NAME as C,WF_TRAIL_LAYER_NAME as H}from"./layers";import{createWayfindingRuntime as Y}from"./runtime/createWayfindingRuntime";import{createWayfindingRenderer as D}from"./renderer";export function createWayfinding(l){const m=N(T),a=E({iconMap:o.fp.icons,pixelRatio:devicePixelRatio}),t=D(l),c=y(s,o.routeStore),i={points:C,trail:H,lines:k,linesAnimated:P,currentPosition:F},d=I(n?.properties?.config?.snapThreshold)||M,R=x({thresholdInMeters:d,gpsConfig:n?.properties?.config}),p=Y({engine:m,renderer:t,iconProvider:a,floorContext:c,layers:i,snapThreshold:R,onTransitionClick:e=>{e.role==="exit"&&s.updateVisibility(e.targetLayer,!0)},onRouteUpdate:(e,r)=>{o.routeStore.updateRoute(e),r&&(f.moveToRect=h.fromX1y1x2y2(r.x1,r.y1,r.x2,r.y2))},onRouteDistance:e=>o.routeStore.updateRouteDistance(e)}),S=v({renderer:t,kioskIconMap:o.fp.icons,layer:i.points}),g=W({renderer:t,iconProvider:a,floorContext:c,layer:i.points}),u=L(n?.properties?.config),_=A({runtime:p,kioskHandler:S,yahHandler:g,stores:{routeStore:o.routeStore,uiState:f,layerStore:s},rerouteThresholdSvg:u});return t.flush(),()=>{_(),p.destroy()}}
@@ -11,4 +11,5 @@ export declare const WF_POINTS_LAYER_NAME = "wf-points";
11
11
  export declare const WF_TRAIL_LAYER_NAME = "wf-trail-points";
12
12
  export declare const WF_LINES_LAYER_NAME = "wf-lines";
13
13
  export declare const WF_LINES_ANIMATED_LAYER_NAME = "wf-lines-animated";
14
+ export declare const WF_CURRENT_POSITION_LAYER_NAME = "wf-current-position";
14
15
  //# sourceMappingURL=layers.d.ts.map
@@ -1 +1 @@
1
- export const WF_POINTS_LAYER_NAME="wf-points",WF_TRAIL_LAYER_NAME="wf-trail-points",WF_LINES_LAYER_NAME="wf-lines",WF_LINES_ANIMATED_LAYER_NAME="wf-lines-animated";
1
+ export const WF_POINTS_LAYER_NAME="wf-points",WF_TRAIL_LAYER_NAME="wf-trail-points",WF_LINES_LAYER_NAME="wf-lines",WF_LINES_ANIMATED_LAYER_NAME="wf-lines-animated",WF_CURRENT_POSITION_LAYER_NAME="wf-current-position";
@@ -1 +1 @@
1
- import{getRouteLength as B,snapToRoute as G}from"../core";import{getRouteLines as H}from"./getRouteLines";import{createEndpointView as J}from"./endpointView";import{createPositionTrailView as K}from"./positionTrailView";import{createRouteLinesView as N}from"./routeLinesView";import{computeRouteRenderData as O}from"./routeRenderData";import{computeRouteUpdate as Q}from"./routeUpdate";import{createTrailView as X}from"./trailView";import{createTransitionView as Y}from"./transitionView";const Z=g=>g.flatMap(e=>[e.p0,e.p1]);export function createWayfindingRuntime({engine:g,renderer:e,iconProvider:h,floorContext:s,layers:a,snapThreshold:b,onTransitionClick:E,onRouteUpdate:d,onRouteDistance:m}){const L=J({renderer:e,iconProvider:h,floorContext:s,layer:a.points}),y=Y({renderer:e,iconProvider:h,floorContext:s,onTransitionClick:E,layer:a.points}),M=X({renderer:e,iconProvider:h,floorContext:s,layer:a.trail}),o=K({renderer:e,iconProvider:h,floorContext:s,trails:M,iconLayer:a.points,snapThreshold:b}),F=N({renderer:e,linesLayer:a.lines,animatedLinesLayer:a.linesAnimated});let u=[],i=null,r=null,l=null,c=0;function P(){return s.showAllFloors()?null:s.getActiveFloor()}function A(){const t=P();return t===null?u.filter(n=>!n.virtual):u.filter(n=>n.p0.layer===t&&!n.virtual)}function R(){if(!i||!r)return null;const t=A();return t.length?{from:i,to:r,routePoints:Z(t),visibleLines:t}:null}function f(t,n=!1){if(!i||!r)return;const p=O({routeLines:u,currentRouteLayer:P(),from:i,to:r,snap:t});F.draw(p,n),c=p.distance}function v(){if(!i||!r)return;const t=R();if(!t){L.hide(),y.clear(),o.refreshTrail(null),f();return}L.place(i,r,t.routePoints),y.place(u),f(),o.refreshTrail(t)}function T(){if(!l||!i||!r)return;const t=u.filter(p=>!p.virtual);if(!t.length)return;const n=R();return n?o.applyToRoute(l,n,t):(o.refreshTrail(null),G({x:l.x,y:l.y,z:l.layer||null},t,{snapThreshold:b,from:i,to:r}))}function I(){const t=Q(u,A());return d(t.lines,t.bounds),t}function S({from:t,to:n,waypoints:p,accessible:k}){const z=H({engine:g,from:t,to:n,waypoints:p,accessible:k});if(!z.length)return V(),!1;i=t,r=n,u=z,v();const{lines:q}=I(),w=T();return w&&f(w,!0),m(w?c:B(q)),e.flush(),!0}function U(t){if(l=t,!t){o.hideIcon(),o.refreshTrail(R()),f(),m(c),e.flush();return}o.placeIcon(t);const n=T();n&&f(n,!0),m(c),e.flush()}function W(){v();const t=T();t&&f(t,!0),u.length&&I(),m(c),e.flush()}function V(){u=[],i=null,r=null,c=0,L.hide(),y.clear(),o.clearTrail(),F.clear(),d([],null),m(0),e.flush()}function j(){V(),l=null,e.destroy()}return{setRoute:S,onPositionChanged:U,onFloorChanged:W,clearRoute:V,destroy:j}}
1
+ import{CURRENT_POSITION_POINT_ID as C}from"./positionView";import{getRouteLength as G,snapToRoute as H}from"../core";import{getRouteLines as J}from"./getRouteLines";import{createEndpointView as K}from"./endpointView";import{createPositionTrailView as Q}from"./positionTrailView";import{createRouteLinesView as X}from"./routeLinesView";import{computeRouteRenderData as Y}from"./routeRenderData";import{computeRouteUpdate as Z}from"./routeUpdate";import{createTrailView as $}from"./trailView";import{createTransitionView as D}from"./transitionView";const x=A=>A.flatMap(e=>[e.p0,e.p1]);export function createWayfindingRuntime({engine:A,renderer:e,iconProvider:P,floorContext:c,layers:f,snapThreshold:E,onTransitionClick:M,onRouteUpdate:N,onRouteDistance:R}){const d=K({renderer:e,iconProvider:P,floorContext:c,layer:f.points}),I=D({renderer:e,iconProvider:P,floorContext:c,onTransitionClick:M,layer:f.points}),W=$({renderer:e,iconProvider:P,floorContext:c,layer:f.trail}),l=Q({renderer:e,iconProvider:P,floorContext:c,trails:W,iconLayer:f.currentPosition,snapThreshold:E}),O=X({renderer:e,linesLayer:f.lines,animatedLinesLayer:f.linesAnimated});let r=[],o=null,u=null,s=null,p=0,y=!1,T=!1;function S(){return c.showAllFloors()?null:c.getActiveFloor()}function _(){const t=S();return t===null?r.filter(n=>!n.virtual):r.filter(n=>n.p0.layer===t&&!n.virtual)}function V(){if(!o||!u)return null;const t=_();return t.length?{from:o,to:u,routePoints:x(t),visibleLines:t}:null}function m(t=null,n=!1){if(!o||!u)return;const i=Y({routeLines:r,currentRouteLayer:S(),from:o,to:u,snap:t});O.draw(i,n),p=i.distance}function g(t){const n=V();if(!n){l.setTrail(null,null);return}const i=s&&t&&!t.snapped?s:null,h=a=>a.bounds?.length?null:a.id===C?i:a,L=y?null:h(n.from);if(L){l.setTrail(n.routePoints[n.routePoints.length-1],L);return}const b=h(n.to);l.setTrail(b?n.routePoints[0]:null,b)}function U(){if(!o||!u)return;const t=V();if(!t){d.hide(),I.clear(),l.clearTrail(),m();return}d.place(o,u,t.routePoints,T),I.place(r),m(),g(null)}function w(){if(!o||!u)return;const t=V();t&&d.place(o,u,t.routePoints,T)}function F(){if(T=!1,!s||!o||!u)return null;const t=r.filter(h=>!h.virtual);if(!t.length)return null;const n=V(),i=n?l.applyToRoute(s,n,t):H(s,t,{snapThreshold:E,from:o,to:u});return i.snapped&&(y=!0),T=i.snapped,i}function k(){const t=Z(r,_());return N(t.lines,t.bounds),t}function j({from:t,to:n,waypoints:i,accessible:h}){const L=J({engine:A,from:t,to:n,waypoints:i,accessible:h});if(!L.length)return v(),!1;y=!1,o=t,u=n,r=L,U();const{lines:b}=k(),a=F();return w(),g(a),a&&m(a,!0),R(a?p:G(b)),e.flush(),!0}function q(t){const n=s!==null;if(s=t,!t){T=!1,l.hideIcon(),g(null),n&&w(),m(),R(p),e.flush();return}l.placeIcon(t);const i=F();w(),g(i),i&&m(i,!0),R(p),e.flush()}function z(){U();const t=F();w(),g(t),t&&m(t,!0),r.length&&k(),R(p),e.flush()}function v(){y=!1,r=[],o=null,u=null,p=0,d.hide(),I.clear(),l.clearTrail(),O.clear(),N([],null),R(0),e.flush()}function B(){v(),s=null,e.destroy()}return{setRoute:j,onPositionChanged:q,onFloorChanged:z,clearRoute:v,destroy:B}}
@@ -3,7 +3,10 @@ import type { RouteEndpoint, RoutePoint } from "../core";
3
3
  import type { WayfindingRenderer } from "../renderer";
4
4
  import type { FloorContext } from "./types";
5
5
  interface EndpointView {
6
- place(from: RouteEndpoint, to: RouteEndpoint, visibleRoutePoints: ReadonlyArray<RoutePoint>): void;
6
+ /** Place source/destination icons. `snapped` — the live CP is currently on the route, so its
7
+ * source shows greyed-out. A kiosk anchor (off-graph origin that isn't the CP) stays hidden;
8
+ * everything else (booth, CP off-route, no live CP) shows full-colour. */
9
+ place(from: RouteEndpoint, to: RouteEndpoint, visibleRoutePoints: ReadonlyArray<RoutePoint>, snapped: boolean): void;
7
10
  hide(): void;
8
11
  }
9
12
  export declare function createEndpointView({ renderer, iconProvider, floorContext, layer, }: {
@@ -1 +1 @@
1
- export function createEndpointView({renderer:n,iconProvider:c,floorContext:s,layer:t}){return{place(o,e,a){if(!a.length)return;const i=s.isLayerVisible(o.layer),d=s.isLayerVisible(e.layer),l=a[a.length-1],u=a[0];n.setIcon("source",{canvas:c.getIcon("source").canvas,layer:t,x:l.x,y:l.y,hidden:!i||!o.bounds,dimmed:!i,cardinalSnap:!0}),n.setIcon("destination",{canvas:c.getIcon("destination").canvas,layer:t,x:u.x,y:u.y,hidden:!d||!e.bounds,dimmed:!d,cardinalSnap:!0})},hide(){n.setIcon("source",null),n.setIcon("destination",null)}}}
1
+ import{CURRENT_POSITION_POINT_ID as I}from"./positionView";function p(n,c){return!c||!n.bounds&&n.id!==I}export function createEndpointView({renderer:n,iconProvider:c,floorContext:e,layer:i}){return{place(s,o,t,l){if(!t.length)return;const a=e.isLayerVisible(s.layer),d=e.isLayerVisible(o.layer),u=t[t.length-1],r=t[0],y=s.id===I&&l;n.setIcon("source",{canvas:c.getIcon(y?"source_inactive":"source").canvas,layer:i,x:u.x,y:u.y,hidden:p(s,a),dimmed:!a,cardinalSnap:!0}),n.setIcon("destination",{canvas:c.getIcon("destination").canvas,layer:i,x:r.x,y:r.y,hidden:!d||!o.bounds,dimmed:!d,cardinalSnap:!0})},hide(){n.setIcon("source",null),n.setIcon("destination",null)}}}
@@ -4,9 +4,9 @@ import type { WayfindingRenderer } from "../renderer";
4
4
  import type { FloorContext, PositionInput } from "./types";
5
5
  import type { TrailView } from "./trailView";
6
6
  /**
7
- * Snapshot of the visible route the position-trail view operates on. The
8
- * runtime computes it (visibility filtering, route-points derivation) and
9
- * passes it in so the view stays free of route-state knowledge.
7
+ * Snapshot of the visible route the position-trail view operates on. The runtime computes it
8
+ * (visibility filtering, route-points derivation) and passes it in so the view stays free of
9
+ * route-state knowledge.
10
10
  */
11
11
  export interface RouteSnapshot {
12
12
  readonly from: RouteEndpoint;
@@ -15,10 +15,9 @@ export interface RouteSnapshot {
15
15
  readonly visibleLines: ReadonlyArray<RouteLine>;
16
16
  }
17
17
  /**
18
- * Owns the user-position icon and the single shared trail slot. The two
19
- * trail variants off-graph endpoint trail (when an endpoint has no
20
- * `bounds`) and off-route position trail are mutually exclusive and reuse
21
- * the same slot, so a single owner keeps the state machine simple.
18
+ * Owns the user-position icon and the single off-graph trail slot. The runtime decides which end of
19
+ * the route needs a trail (kiosk FROM, kiosk TO, or off-route CP FROM never both at once in
20
+ * practice) and passes the corresponding `tip` + `anchor` here.
22
21
  */
23
22
  interface PositionTrailView {
24
23
  /** Place the position icon at the raw position. */
@@ -26,22 +25,17 @@ interface PositionTrailView {
26
25
  /** Hide the position icon. */
27
26
  hideIcon(): void;
28
27
  /**
29
- * Snap the position to `routeLines` (caller-provided — typically the full
30
- * non-virtual route across all floors) and update the trail slot.
31
- * - Snapped: icon moves to the snap point; the off-graph endpoint trail
32
- * is restored (or cleared when neither endpoint is off-graph).
33
- * - Off-route: a trail is drawn from the position to the nearest end of
34
- * the visible route; the icon stays where it was last placed.
28
+ * Snap the position to `routeLines` (caller-provided — typically the full non-virtual route
29
+ * across all floors) and place the position icon at the snap point or at the raw position.
30
+ * Returns the snap result; the trail is **not** touched — call `setTrail` separately.
35
31
  *
36
- * `routeLines` is decoupled from `route.visibleLines` so the snap stays
37
- * correct regardless of which floor is currently selected in the UI.
32
+ * `routeLines` is decoupled from `route.visibleLines` so the snap stays correct regardless of
33
+ * which floor is currently selected in the UI.
38
34
  */
39
35
  applyToRoute(position: PositionInput, route: RouteSnapshot, routeLines: ReadonlyArray<RouteLine>): RouteSnapResult;
40
- /**
41
- * Re-evaluate the trail when no position is active. Restores the
42
- * off-graph endpoint trail when applicable; otherwise clears the slot.
43
- */
44
- refreshTrail(route: RouteSnapshot | null): void;
36
+ /** Draw the trail from `tip` (a route's graph endpoint) to `anchor` (the off-graph point).
37
+ * Passing either as null hides the trail. */
38
+ setTrail(tip: RoutePoint | null, anchor: RoutePoint | null): void;
45
39
  /** Clear the trail slot (does not touch the icon). */
46
40
  clearTrail(): void;
47
41
  }
@@ -1 +1 @@
1
- import{snapToRoute as P}from"../core";import{createPositionView as h}from"./positionView";const a="trail";export function createPositionTrailView({renderer:o,iconProvider:f,floorContext:y,trails:n,iconLayer:t,snapThreshold:p}){const c=h({renderer:o,iconProvider:f,layer:t});function i(e){if(!e.routePoints.length){n.clear(a);return}if(!e.from.bounds){n.place(a,e.routePoints[e.routePoints.length-1],{x:e.from.x,y:e.from.y,layer:e.from.layer});return}if(!e.to.bounds){n.place(a,e.routePoints[0],{x:e.to.x,y:e.to.y,layer:e.to.layer});return}n.clear(a)}return{placeIcon(e){const r=!y.isLayerVisible(e.layer);c.place(e,r)},hideIcon(){c.hide()},applyToRoute(e,r,s){const l=P({x:e.x,y:e.y,z:e.layer||null},[...s],{snapThreshold:p,from:r.from,to:r.to});if(l.snapped){i(r);const d=!y.isLayerVisible(e.layer);return c.place({...e,x:l.snappedPoint.x,y:l.snappedPoint.y},d),l}return r.routePoints.length?n.place(a,{x:e.x,y:e.y,layer:e.layer},r.routePoints[r.routePoints.length-1]):n.clear(a),l},refreshTrail(e){if(!e){n.clear(a);return}i(e)},clearTrail(){n.clear(a)}}}
1
+ import{snapToRoute as T}from"../core";import{createPositionView as f}from"./positionView";const n="trail";export function createPositionTrailView({renderer:p,iconProvider:s,floorContext:l,trails:i,iconLayer:t,snapThreshold:d}){const r=f({renderer:p,iconProvider:s,layer:t});return{placeIcon(e){const a=!l.isLayerVisible(e.layer);r.place(e,a)},hideIcon(){r.hide()},applyToRoute(e,a,y){const c=T(e,[...y],{snapThreshold:d,from:a.from,to:a.to}),o=!l.isLayerVisible(e.layer);return c.snapped?r.place({...e,x:c.snappedPoint.x,y:c.snappedPoint.y},o):r.place(e,o),c},setTrail(e,a){e&&a?i.place(n,e,a):i.clear(n)},clearTrail(){i.clear(n)}}}
@@ -1,6 +1,7 @@
1
1
  import type { IconProvider } from "../adapters";
2
2
  import type { WayfindingRenderer } from "../renderer";
3
3
  import type { PositionInput } from "./types";
4
+ export declare const CURRENT_POSITION_POINT_ID = "current-position";
4
5
  interface PositionView {
5
6
  /**
6
7
  * Place or update the current-position icon. The icon variant (dot vs
@@ -1 +1 @@
1
- const c="position";export function createPositionView({renderer:o,iconProvider:a,layer:i}){return{place(n,e){const t=Number.isFinite(n.angle),s=t?"current_arrow":"current",r=t?n.angle*Math.PI/180:void 0;o.setIcon(c,{canvas:a.getIcon(s).canvas,layer:i,x:n.x,y:n.y,rotation:r,hidden:e,dimmed:e,origin:[.5,.5]})},hide(){o.setIcon(c,null)}}}
1
+ export const CURRENT_POSITION_POINT_ID="current-position";const c="position";export function createPositionView({renderer:o,iconProvider:i,layer:s}){return{place(n,t){const e=Number.isFinite(n.angle),a=e?"current_arrow":"current",r=e?n.angle*Math.PI/180:void 0;o.setIcon(c,{canvas:i.getIcon(a).canvas,layer:s,x:n.x,y:n.y,rotation:r,hidden:t,dimmed:t,origin:[.5,.5]})},hide(){o.setIcon(c,null)}}}
@@ -23,7 +23,7 @@ export declare function computeRouteRenderData({ routeLines, currentRouteLayer,
23
23
  readonly currentRouteLayer: string | null;
24
24
  readonly from: RouteEndpoint;
25
25
  readonly to: RouteEndpoint;
26
- readonly snap: RouteSnapResult | undefined;
26
+ readonly snap: RouteSnapResult | null;
27
27
  }): RouteRenderData;
28
28
  export {};
29
29
  //# sourceMappingURL=routeRenderData.d.ts.map
@@ -14,6 +14,7 @@ export interface LayerNames {
14
14
  readonly trail: string;
15
15
  readonly lines: string;
16
16
  readonly linesAnimated: string;
17
+ readonly currentPosition: string;
17
18
  }
18
19
  export interface SetRouteInput {
19
20
  readonly from: RouteEndpoint;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/floorplan",
3
- "version": "3.5.2",
3
+ "version": "3.6.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/expofp/efp-app.git",
@@ -73,8 +73,8 @@
73
73
  "tslib": "^2.3.0",
74
74
  "uuid": "^9.0.1",
75
75
  "zod": "4.3.5",
76
- "@expofp/debug": "3.5.2",
77
- "@expofp/resolve": "3.5.2"
76
+ "@expofp/debug": "3.6.0",
77
+ "@expofp/resolve": "3.6.0"
78
78
  },
79
79
  "devDependencies": {
80
80
  "@babel/plugin-proposal-decorators": "^7.29.7",
@@ -1,23 +0,0 @@
1
- import { SpecialBooth } from "./store/BoothStore";
2
- import Rect from "./core/Rect";
3
- export declare class RouteCutIn extends SpecialBooth {
4
- readonly id: number;
5
- readonly name: string;
6
- readonly destination: LayerPoint;
7
- readonly slug: string;
8
- readonly meta: {};
9
- protected readonly store: import("./store/BoothStore").default;
10
- readonly exhibitors: never[];
11
- readonly paths: never[];
12
- readonly routePoint: LayerPoint;
13
- readonly rect: Rect;
14
- readonly entity: {
15
- readonly type: "route-cut-in";
16
- };
17
- constructor(id: number, name: string, destination: LayerPoint, slug: string, meta?: {});
18
- private findClosestRoutePoint;
19
- private distanceToLine;
20
- private findClosestPointOnLine;
21
- private findClosestLineEnd;
22
- }
23
- //# sourceMappingURL=RouteCutIn.d.ts.map
@@ -1 +0,0 @@
1
- import{SpecialBooth as b}from"./store/BoothStore";import{graphDataSource as E}from"./wayfinding/adapters";import P from"./store";import D from"./core/Rect";import{areLayersEnabled as S}from"./utils/areLayersEnabled";export class RouteCutIn extends b{id;name;destination;slug;meta;store=P.boothStore;exhibitors=[];paths=[];routePoint;rect=D.fromCxcywh(0,0,0,0);entity={type:"route-cut-in"};constructor(i,r,n,s,t={}){super(),this.id=i,this.name=r,this.destination=n,this.slug=s,this.meta=t,this.layer=P.layerStore.findLayer(n.layer),this.routePoint=this.findClosestRoutePoint();const e=this.findClosestLineEnd(this.routePoint);e&&(this.rect=D.fromCxcywh(e.x,e.y,1,1)),Object.freeze(this)}findClosestRoutePoint(){const i=E.getLines(),r=S()?i.filter(t=>t.p0.layer===this.destination.layer&&t.p1.layer===this.destination.layer):i;if(!r?.length)return null;let n=1/0,s=null;return r.forEach(t=>{const e=this.distanceToLine(this.destination,t.p0,t.p1);e<n&&(n=e,s=t)}),{...this.findClosestPointOnLine(this.destination,s),layer:this.destination.layer}}distanceToLine(i,r,n){const s=i.x,t=i.y,e=r.x,o=r.y,l=n.x,d=n.y,x=s-e,h=t-o,a=l-e,u=d-o,m=x*a+h*u,f=a*a+u*u;let c=-1;f!==0&&(c=m/f);let y,p;c<0?(y=e,p=o):c>1?(y=l,p=d):(y=e+c*a,p=o+c*u);const L=s-y,C=t-p;return Math.sqrt(L*L+C*C)}findClosestPointOnLine(i,r){const{x:n,y:s}=r.p0,{x:t,y:e}=r.p1,{x:o,y:l}=i,d=o-n,x=l-s,h=t-n,a=e-s,u=d*h+x*a,m=h*h+a*a;let f=-1;m!==0&&(f=u/m);let c,y;return f<0?(c=n,y=s):f>1?(c=t,y=e):(c=n+f*h,y=s+f*a),{x:c,y}}findClosestLineEnd(i){if(!i)return null;const r=E.getLineEnds(),n=S()?r.filter(o=>o.layer===i.layer):r;let s=null,t=1/0;function e(o,l,d,x){return Math.sqrt((d-o)**2+(x-l)**2)}return n.forEach(o=>{const l=e(i.x,i.y,o.x,o.y);l<t&&(t=l,s=o)}),s}}
@@ -1,3 +0,0 @@
1
- import type { PositionPoint, RouteLine } from "../types";
2
- export declare function shouldReroute(position: PositionPoint | null, routeLines: RouteLine[], threshold?: number): boolean;
3
- //# sourceMappingURL=shouldReroute.d.ts.map
@@ -1 +0,0 @@
1
- import{distancePointToRouteOnLayer as u}from"./distanceToRoute";const c=10;export function shouldReroute(t,e,r=c){if(!t||!e.length)return!1;const l={layer:t.z!=null?String(t.z):"",x:t.x,y:t.y},n=u(l,e);return isFinite(n)&&n>r}
@@ -1 +0,0 @@
1
- import{lineLength as f}from"simple-geometry";import{computePolygonArea as l,pointInPolygon as a}from"../geometry/pointInPolygon";export function findGraphPointsInPolygon(r,n,t){const o=l(n);return r.getLineEnds().filter(e=>(!t||e.layer===t)&&a(e,n,o))}export function findNearestGraphPoint(r,n){let t=null,o=1/0;for(const e of r.getLineEnds()){if(n.layer&&e.layer!==n.layer)continue;const i=f(e,n);i<o&&(o=i,t=e)}return t}
@@ -1,4 +0,0 @@
1
- import type { Booth } from "../../store/BoothStore";
2
- import type { CurrentPosition } from "../../store/RouteStore";
3
- export declare function findBoothInRadius(position: CurrentPosition | null, booths: Booth[], excludeBooths?: Booth[], radius?: number): Booth | null;
4
- //# sourceMappingURL=findBoothInRadius.d.ts.map
@@ -1 +0,0 @@
1
- const s=20;function f(n,i,t){const u=n<t.x1?t.x1-n:n>t.x2?n-t.x2:0,d=i<t.y1?t.y1-i:i>t.y2?i-t.y2:0;return u*u+d*d}export function findBoothInRadius(n,i,t=[],u=20){if(!n||!i.length)return null;const d=n.z!=null?String(n.z):null,o=u*u,r=new Set(t.filter(e=>e?.id).map(e=>String(e.id)));let a=null,c=1/0;for(const e of i){if(!e.rect||e.id&&r.has(String(e.id))||d&&e.layer?.name!==d)continue;const l=f(n.x,n.y,e.rect);l<=o&&l<c&&(c=l,a=e)}return a}