@eyeon/map 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/dist/assets/MapViewer.css +1 -1
- package/dist/assets/index.css +1 -1
- package/dist/chunks/MapViewer.js +1745 -356
- package/dist/chunks/MapViewer.js.map +1 -1
- package/dist/chunks/stacking.js +1321 -0
- package/dist/chunks/stacking.js.map +1 -0
- package/dist/core/geometry/index.d.ts +41 -4
- package/dist/core/geometry/index.d.ts.map +1 -1
- package/dist/core/hostChrome.d.ts +20 -0
- package/dist/core/hostChrome.d.ts.map +1 -0
- package/dist/core/import/index.d.ts +48 -3
- package/dist/core/import/index.d.ts.map +1 -1
- package/dist/core/import/svgStyle.d.ts +21 -0
- package/dist/core/import/svgStyle.d.ts.map +1 -0
- package/dist/core/import/svgTransform.d.ts +49 -0
- package/dist/core/import/svgTransform.d.ts.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +207 -266
- package/dist/core/index.js.map +1 -1
- package/dist/core/layerStyles.d.ts +28 -0
- package/dist/core/layerStyles.d.ts.map +1 -0
- package/dist/core/publish/index.d.ts +8 -2
- package/dist/core/publish/index.d.ts.map +1 -1
- package/dist/core/routing/graph-tools.d.ts +5 -1
- package/dist/core/routing/graph-tools.d.ts.map +1 -1
- package/dist/core/stacking.d.ts +61 -0
- package/dist/core/stacking.d.ts.map +1 -0
- package/dist/core/types.d.ts +27 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/editor/MapEditor.d.ts +28 -16
- package/dist/editor/MapEditor.d.ts.map +1 -1
- package/dist/editor/canvas/EditorCanvas.d.ts +15 -3
- package/dist/editor/canvas/EditorCanvas.d.ts.map +1 -1
- package/dist/editor/canvas/coords.d.ts +21 -0
- package/dist/editor/canvas/coords.d.ts.map +1 -0
- package/dist/editor/draftOps.d.ts +19 -0
- package/dist/editor/draftOps.d.ts.map +1 -0
- package/dist/editor/geometryEdit.d.ts +34 -0
- package/dist/editor/geometryEdit.d.ts.map +1 -0
- package/dist/editor/index.css +1281 -145
- package/dist/editor/index.d.ts +8 -2
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +2293 -585
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/labels.d.ts +5 -0
- package/dist/editor/labels.d.ts.map +1 -0
- package/dist/editor/panels/FloorsPanel.d.ts +60 -0
- package/dist/editor/panels/FloorsPanel.d.ts.map +1 -0
- package/dist/editor/panels/ImportReviewPanel.d.ts +22 -0
- package/dist/editor/panels/ImportReviewPanel.d.ts.map +1 -0
- package/dist/editor/panels/Inspector.d.ts +4 -2
- package/dist/editor/panels/Inspector.d.ts.map +1 -1
- package/dist/editor/panels/LeftRail.d.ts +19 -6
- package/dist/editor/panels/LeftRail.d.ts.map +1 -1
- package/dist/editor/panels/PreviewOverlay.d.ts +11 -2
- package/dist/editor/panels/PreviewOverlay.d.ts.map +1 -1
- package/dist/editor/portalSurface.d.ts +11 -0
- package/dist/editor/portalSurface.d.ts.map +1 -0
- package/dist/editor/previewDocument.d.ts +9 -0
- package/dist/editor/previewDocument.d.ts.map +1 -0
- package/dist/editor/tools.d.ts +20 -0
- package/dist/editor/tools.d.ts.map +1 -0
- package/dist/test-maps/shops-at-south-town/BASE - Shops At South Town.ai +26780 -26
- package/dist/test-maps/shops-at-south-town/LF - Shops At South Town.ai +4487 -2
- package/dist/test-maps/shops-at-south-town/SVG/BASE - Shops At South Town.svg +567 -0
- package/dist/test-maps/shops-at-south-town/SVG/LF - Shops At South Town.svg +238 -0
- package/dist/test-maps/shops-at-south-town/SVG/UF - Shops At South Town.svg +276 -0
- package/dist/test-maps/shops-at-south-town/UF - Shops At South Town.ai +4228 -1
- package/dist/viewer/MapViewer.d.ts +14 -3
- package/dist/viewer/MapViewer.d.ts.map +1 -1
- package/dist/viewer/camera.d.ts +34 -0
- package/dist/viewer/camera.d.ts.map +1 -0
- package/dist/viewer/components/CameraRig.d.ts +18 -0
- package/dist/viewer/components/CameraRig.d.ts.map +1 -0
- package/dist/viewer/components/LevelMeshes.d.ts +6 -1
- package/dist/viewer/components/LevelMeshes.d.ts.map +1 -1
- package/dist/viewer/components/MapScene.d.ts +6 -1
- package/dist/viewer/components/MapScene.d.ts.map +1 -1
- package/dist/viewer/components/SvgVectorLayer.d.ts +18 -0
- package/dist/viewer/components/SvgVectorLayer.d.ts.map +1 -0
- package/dist/viewer/index.css +124 -35
- package/dist/viewer/index.d.ts +4 -0
- package/dist/viewer/index.d.ts.map +1 -1
- package/dist/viewer/index.js +9 -4
- package/dist/viewer/index.js.map +1 -1
- package/dist/viewer/ui/MapControls.d.ts +14 -0
- package/dist/viewer/ui/MapControls.d.ts.map +1 -0
- package/dist/viewer/ui/RuntimeChrome.d.ts +3 -3
- package/dist/viewer/ui/RuntimeChrome.d.ts.map +1 -1
- package/package.json +17 -7
- package/dist/chunks/graph-tools.js +0 -153
- package/dist/chunks/graph-tools.js.map +0 -1
- package/dist/chunks/pathfinding.js +0 -343
- package/dist/chunks/pathfinding.js.map +0 -1
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { D as x, n as v, d as A, p as k, a as M } from "./pathfinding.js";
|
|
2
|
-
function b(i, l, r, s = x) {
|
|
3
|
-
const n = i.filter((e) => r.includes(e.id));
|
|
4
|
-
if (n.length < 2) return null;
|
|
5
|
-
const d = n.reduce((e, u) => u.id < e.id ? u : e), o = [];
|
|
6
|
-
for (const e of n)
|
|
7
|
-
e.id !== d.id && A(e, d) <= s && o.push(e.id);
|
|
8
|
-
if (o.length === 0) return null;
|
|
9
|
-
const f = new Set(o), h = [];
|
|
10
|
-
for (const e of l) {
|
|
11
|
-
let u = !1;
|
|
12
|
-
if (f.has(e.fromAnchorId) && (e.fromAnchorId = d.id, u = !0), f.has(e.toAnchorId) && (e.toAnchorId = d.id, u = !0), e.fromAnchorId === e.toAnchorId) {
|
|
13
|
-
h.push(e.id);
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
u && h.push(e.id);
|
|
17
|
-
}
|
|
18
|
-
return {
|
|
19
|
-
survivingAnchorId: d.id,
|
|
20
|
-
removedAnchorIds: o,
|
|
21
|
-
rewiredEdgeIds: h
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function E(i, l = x) {
|
|
25
|
-
const r = [], s = /* @__PURE__ */ new Set();
|
|
26
|
-
for (let n = 0; n < i.length; n++) {
|
|
27
|
-
if (s.has(i[n].id)) continue;
|
|
28
|
-
const d = [i[n].id];
|
|
29
|
-
for (let o = n + 1; o < i.length; o++)
|
|
30
|
-
s.has(i[o].id) || i[n].levelId === i[o].levelId && A(i[n], i[o]) <= l && (d.push(i[o].id), s.add(i[o].id));
|
|
31
|
-
d.length > 1 && (s.add(i[n].id), r.push(d));
|
|
32
|
-
}
|
|
33
|
-
return r;
|
|
34
|
-
}
|
|
35
|
-
function T(i, l, r, s = x) {
|
|
36
|
-
let n = null;
|
|
37
|
-
for (const o of l) {
|
|
38
|
-
const f = v(i, o);
|
|
39
|
-
f && (!n || f.distance < n.distance) && (n = { point: f.point, distance: f.distance });
|
|
40
|
-
}
|
|
41
|
-
if (!n) return null;
|
|
42
|
-
const d = r.find(
|
|
43
|
-
(o) => o.levelId === i.levelId && A(o, n.point) <= s
|
|
44
|
-
);
|
|
45
|
-
return {
|
|
46
|
-
unitAnchorId: i.id,
|
|
47
|
-
junctionAnchor: d ? { x: d.x, y: d.y, existingId: d.id } : { x: n.point.x, y: n.point.y },
|
|
48
|
-
edge: {
|
|
49
|
-
fromAnchorId: i.id,
|
|
50
|
-
toAnchorId: d == null ? void 0 : d.id
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function C(i, l, r, s) {
|
|
55
|
-
if (r.length === 0) return null;
|
|
56
|
-
const n = r.flat();
|
|
57
|
-
if (n.length === 0) return null;
|
|
58
|
-
let d = 0, o = 0;
|
|
59
|
-
for (const e of n)
|
|
60
|
-
d += e.x, o += e.y;
|
|
61
|
-
const f = { x: d / n.length, y: o / n.length }, h = k(f, r) ? f : n[0];
|
|
62
|
-
return {
|
|
63
|
-
id: s,
|
|
64
|
-
levelId: l,
|
|
65
|
-
shapeId: i,
|
|
66
|
-
kind: "unit",
|
|
67
|
-
x: h.x,
|
|
68
|
-
y: h.y,
|
|
69
|
-
connectorId: null
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function j(i, l, r = 20) {
|
|
73
|
-
if (i.length === 0)
|
|
74
|
-
return { anchors: [], edges: [] };
|
|
75
|
-
let s = 1 / 0, n = 1 / 0, d = -1 / 0, o = -1 / 0;
|
|
76
|
-
for (const t of i)
|
|
77
|
-
for (const c of t)
|
|
78
|
-
s = Math.min(s, c.x), n = Math.min(n, c.y), d = Math.max(d, c.x), o = Math.max(o, c.y);
|
|
79
|
-
const f = Math.max(1, Math.ceil((d - s) / r)), h = Math.max(1, Math.ceil((o - n) / r)), e = [];
|
|
80
|
-
for (let t = 0; t < h; t++)
|
|
81
|
-
for (let c = 0; c < f; c++) {
|
|
82
|
-
const g = s + (c + 0.5) * r, I = n + (t + 0.5) * r, m = { x: g, y: I };
|
|
83
|
-
k(m, i) && (l.length > 0 && k(m, l) || e.push({ key: `${c},${t}`, x: g, y: I, col: c, row: t }));
|
|
84
|
-
}
|
|
85
|
-
const u = new Map(e.map((t) => [t.key, t])), y = e.map((t) => ({
|
|
86
|
-
tempId: t.key,
|
|
87
|
-
x: t.x,
|
|
88
|
-
y: t.y,
|
|
89
|
-
kind: "junction"
|
|
90
|
-
})), p = [], a = /* @__PURE__ */ new Set();
|
|
91
|
-
for (const t of e) {
|
|
92
|
-
const c = [
|
|
93
|
-
[t.col + 1, t.row],
|
|
94
|
-
[t.col, t.row + 1]
|
|
95
|
-
];
|
|
96
|
-
for (const [g, I] of c) {
|
|
97
|
-
const m = `${g},${I}`;
|
|
98
|
-
if (!u.has(m)) continue;
|
|
99
|
-
const w = t.key < m ? `${t.key}|${m}` : `${m}|${t.key}`;
|
|
100
|
-
a.has(w) || (a.add(w), p.push({ fromTempId: t.key, toTempId: m }));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return { anchors: y, edges: p };
|
|
104
|
-
}
|
|
105
|
-
function D(i, l, r, s, n = x, d) {
|
|
106
|
-
const o = [], f = [];
|
|
107
|
-
let h = s;
|
|
108
|
-
const e = (u, y) => {
|
|
109
|
-
const p = o.find(
|
|
110
|
-
(t) => A(t, { x: u, y }) <= n
|
|
111
|
-
);
|
|
112
|
-
if (p) return p.id;
|
|
113
|
-
const a = h++;
|
|
114
|
-
return o.push({
|
|
115
|
-
id: a,
|
|
116
|
-
levelId: l,
|
|
117
|
-
shapeId: null,
|
|
118
|
-
kind: "junction",
|
|
119
|
-
x: u,
|
|
120
|
-
y,
|
|
121
|
-
connectorId: null
|
|
122
|
-
}), a;
|
|
123
|
-
};
|
|
124
|
-
for (const u of i) {
|
|
125
|
-
const y = M(u, d);
|
|
126
|
-
for (const p of y)
|
|
127
|
-
for (let a = 0; a < p.length - 1; a++) {
|
|
128
|
-
const t = e(p[a].x, p[a].y), c = e(p[a + 1].x, p[a + 1].y);
|
|
129
|
-
t === c || f.some(
|
|
130
|
-
(I) => I.fromAnchorId === t && I.toAnchorId === c || I.fromAnchorId === c && I.toAnchorId === t
|
|
131
|
-
) || f.push({
|
|
132
|
-
id: h++,
|
|
133
|
-
mapId: r,
|
|
134
|
-
fromAnchorId: t,
|
|
135
|
-
toAnchorId: c,
|
|
136
|
-
weight: null,
|
|
137
|
-
directed: !1,
|
|
138
|
-
accessible: !0,
|
|
139
|
-
kind: "walk"
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return { anchors: o, edges: f, nextId: h };
|
|
144
|
-
}
|
|
145
|
-
export {
|
|
146
|
-
T as a,
|
|
147
|
-
j as b,
|
|
148
|
-
E as f,
|
|
149
|
-
D as i,
|
|
150
|
-
C as u,
|
|
151
|
-
b as w
|
|
152
|
-
};
|
|
153
|
-
//# sourceMappingURL=graph-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graph-tools.js","sources":["../../src/core/routing/graph-tools.ts"],"sourcesContent":["import type {\n AutoConnectResult,\n CmAnchor,\n CmRouteEdge,\n SkeletonSuggestion,\n Vec2,\n WeldResult,\n} from '../types';\nimport { DEFAULT_WELD_TOLERANCE } from '../types';\nimport {\n distance,\n nearestPointOnPolyline,\n pathToPolygons,\n pointInPolygons,\n} from '../geometry';\n\nexport interface AnchorLike {\n id: number;\n x: number;\n y: number;\n levelId: number;\n shapeId?: number | null;\n kind?: string;\n}\n\nexport interface EdgeLike {\n id: number;\n fromAnchorId: number;\n toAnchorId: number;\n}\n\n/**\n * Weld anchors within tolerance into the surviving (lowest id) anchor.\n * Rewires edges that referenced removed anchors.\n */\nexport function weldAnchors(\n anchors: AnchorLike[],\n edges: EdgeLike[],\n candidateIds: number[],\n tolerance = DEFAULT_WELD_TOLERANCE,\n): WeldResult | null {\n const candidates = anchors.filter((a) => candidateIds.includes(a.id));\n if (candidates.length < 2) return null;\n\n // Cluster by proximity from the first candidate's position centroid of group\n const surviving = candidates.reduce((min, a) => (a.id < min.id ? a : min));\n const removed: number[] = [];\n\n for (const a of candidates) {\n if (a.id === surviving.id) continue;\n if (distance(a, surviving) <= tolerance) {\n removed.push(a.id);\n }\n }\n\n if (removed.length === 0) return null;\n\n const removedSet = new Set(removed);\n const rewired: number[] = [];\n\n for (const edge of edges) {\n let changed = false;\n if (removedSet.has(edge.fromAnchorId)) {\n edge.fromAnchorId = surviving.id;\n changed = true;\n }\n if (removedSet.has(edge.toAnchorId)) {\n edge.toAnchorId = surviving.id;\n changed = true;\n }\n // Drop self-loops\n if (edge.fromAnchorId === edge.toAnchorId) {\n rewired.push(edge.id);\n continue;\n }\n if (changed) rewired.push(edge.id);\n }\n\n return {\n survivingAnchorId: surviving.id,\n removedAnchorIds: removed,\n rewiredEdgeIds: rewired,\n };\n}\n\n/**\n * Find all pairs of anchors within tolerance that should be welded.\n */\nexport function findWeldCandidates(\n anchors: AnchorLike[],\n tolerance = DEFAULT_WELD_TOLERANCE,\n): number[][] {\n const groups: number[][] = [];\n const used = new Set<number>();\n\n for (let i = 0; i < anchors.length; i++) {\n if (used.has(anchors[i].id)) continue;\n const group = [anchors[i].id];\n for (let j = i + 1; j < anchors.length; j++) {\n if (used.has(anchors[j].id)) continue;\n if (\n anchors[i].levelId === anchors[j].levelId &&\n distance(anchors[i], anchors[j]) <= tolerance\n ) {\n group.push(anchors[j].id);\n used.add(anchors[j].id);\n }\n }\n if (group.length > 1) {\n used.add(anchors[i].id);\n groups.push(group);\n }\n }\n return groups;\n}\n\n/**\n * Auto-connect a unit anchor to the nearest walkable segment via perpendicular projection.\n */\nexport function autoConnectUnitAnchor(\n unitAnchor: AnchorLike,\n walkablePolylines: Vec2[][],\n existingJunctions: AnchorLike[],\n weldTolerance = DEFAULT_WELD_TOLERANCE,\n): AutoConnectResult | null {\n let best: { point: Vec2; distance: number } | null = null;\n\n for (const line of walkablePolylines) {\n const hit = nearestPointOnPolyline(unitAnchor, line);\n if (hit && (!best || hit.distance < best.distance)) {\n best = { point: hit.point, distance: hit.distance };\n }\n }\n\n if (!best) return null;\n\n // Reuse existing junction if within weld tolerance\n const existing = existingJunctions.find(\n (j) =>\n j.levelId === unitAnchor.levelId &&\n distance(j, best!.point) <= weldTolerance,\n );\n\n return {\n unitAnchorId: unitAnchor.id,\n junctionAnchor: existing\n ? { x: existing.x, y: existing.y, existingId: existing.id }\n : { x: best.point.x, y: best.point.y },\n edge: {\n fromAnchorId: unitAnchor.id,\n toAnchorId: existing?.id,\n },\n };\n}\n\n/**\n * Place a unit anchor at the centroid of a shape's polygons, if the point lies inside.\n */\nexport function unitAnchorFromShape(\n shapeId: number,\n levelId: number,\n polygons: Vec2[][],\n tempId: number,\n): CmAnchor | null {\n if (polygons.length === 0) return null;\n const flat = polygons.flat();\n if (flat.length === 0) return null;\n\n let sx = 0;\n let sy = 0;\n for (const p of flat) {\n sx += p.x;\n sy += p.y;\n }\n const c = { x: sx / flat.length, y: sy / flat.length };\n\n // Prefer centroid if inside; otherwise use first polygon's average of extremes\n const point = pointInPolygons(c, polygons) ? c : flat[0];\n\n return {\n id: tempId,\n levelId,\n shapeId,\n kind: 'unit',\n x: point.x,\n y: point.y,\n connectorId: null,\n };\n}\n\n/**\n * Build a simple medial-axis-ish skeleton from walkable polygons minus voids.\n * This is a pragmatic approximation: sample a grid inside walkable, reject void cells,\n * connect adjacent free cells into a sparse graph, then prune to a polyline network.\n */\nexport function buildAutoSkeleton(\n walkablePolygons: Vec2[][],\n voidPolygons: Vec2[][],\n cellSize = 20,\n): SkeletonSuggestion {\n if (walkablePolygons.length === 0) {\n return { anchors: [], edges: [] };\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const poly of walkablePolygons) {\n for (const p of poly) {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n }\n }\n\n const cols = Math.max(1, Math.ceil((maxX - minX) / cellSize));\n const rows = Math.max(1, Math.ceil((maxY - minY) / cellSize));\n const free: Array<{ key: string; x: number; y: number; col: number; row: number }> = [];\n\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n const x = minX + (col + 0.5) * cellSize;\n const y = minY + (row + 0.5) * cellSize;\n const pt = { x, y };\n if (!pointInPolygons(pt, walkablePolygons)) continue;\n if (voidPolygons.length > 0 && pointInPolygons(pt, voidPolygons)) continue;\n free.push({ key: `${col},${row}`, x, y, col, row });\n }\n }\n\n const byKey = new Map(free.map((c) => [c.key, c]));\n const anchors = free.map((c) => ({\n tempId: c.key,\n x: c.x,\n y: c.y,\n kind: 'junction' as const,\n }));\n\n const edges: Array<{ fromTempId: string; toTempId: string }> = [];\n const seen = new Set<string>();\n\n for (const cell of free) {\n const neighbors = [\n [cell.col + 1, cell.row],\n [cell.col, cell.row + 1],\n ];\n for (const [nc, nr] of neighbors) {\n const nk = `${nc},${nr}`;\n if (!byKey.has(nk)) continue;\n const edgeKey = cell.key < nk ? `${cell.key}|${nk}` : `${nk}|${cell.key}`;\n if (seen.has(edgeKey)) continue;\n seen.add(edgeKey);\n edges.push({ fromTempId: cell.key, toTempId: nk });\n }\n }\n\n return { anchors, edges };\n}\n\n/**\n * Convert route-path SVG line endpoints into welded anchors + edges.\n * This is the key converter step that repairs coincident-but-disconnected joins.\n */\nexport function importRoutePaths(\n pathDs: string[],\n levelId: number,\n mapId: number,\n startId: number,\n weldTolerance = DEFAULT_WELD_TOLERANCE,\n viewboxHeight?: number,\n): { anchors: CmAnchor[]; edges: CmRouteEdge[]; nextId: number } {\n const anchors: CmAnchor[] = [];\n const edges: CmRouteEdge[] = [];\n let nextId = startId;\n\n const findOrCreate = (x: number, y: number): number => {\n const existing = anchors.find(\n (a) => distance(a, { x, y }) <= weldTolerance,\n );\n if (existing) return existing.id;\n const id = nextId++;\n anchors.push({\n id,\n levelId,\n shapeId: null,\n kind: 'junction',\n x,\n y,\n connectorId: null,\n });\n return id;\n };\n\n for (const d of pathDs) {\n const polys = pathToPolygons(d, viewboxHeight);\n for (const poly of polys) {\n for (let i = 0; i < poly.length - 1; i++) {\n const a = findOrCreate(poly[i].x, poly[i].y);\n const b = findOrCreate(poly[i + 1].x, poly[i + 1].y);\n if (a === b) continue;\n // Avoid duplicate edges\n const dup = edges.some(\n (e) =>\n (e.fromAnchorId === a && e.toAnchorId === b) ||\n (e.fromAnchorId === b && e.toAnchorId === a),\n );\n if (dup) continue;\n edges.push({\n id: nextId++,\n mapId,\n fromAnchorId: a,\n toAnchorId: b,\n weight: null,\n directed: false,\n accessible: true,\n kind: 'walk',\n });\n }\n }\n }\n\n return { anchors, edges, nextId };\n}\n"],"names":["weldAnchors","anchors","edges","candidateIds","tolerance","DEFAULT_WELD_TOLERANCE","candidates","a","surviving","min","removed","distance","removedSet","rewired","edge","changed","findWeldCandidates","groups","used","i","group","j","autoConnectUnitAnchor","unitAnchor","walkablePolylines","existingJunctions","weldTolerance","best","line","hit","nearestPointOnPolyline","existing","unitAnchorFromShape","shapeId","levelId","polygons","tempId","flat","sx","sy","p","c","point","pointInPolygons","buildAutoSkeleton","walkablePolygons","voidPolygons","cellSize","minX","minY","maxX","maxY","poly","cols","rows","free","row","col","x","y","pt","byKey","seen","cell","neighbors","nc","nr","nk","edgeKey","importRoutePaths","pathDs","mapId","startId","viewboxHeight","nextId","findOrCreate","id","d","polys","pathToPolygons","b","e"],"mappings":"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"}
|
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
import N from "ngraph.graph";
|
|
2
|
-
import C from "ngraph.path";
|
|
3
|
-
const X = {
|
|
4
|
-
MAP_STYLE: "2D",
|
|
5
|
-
MAP_BACKGROUND_COLOR: "#f5f5f5",
|
|
6
|
-
ACCENT_COLOR: "#2563eb",
|
|
7
|
-
STORE_DEFAULT_COLOR: "#e2e8f0",
|
|
8
|
-
STORE_TEXT_COLOR: "#1e293b",
|
|
9
|
-
STORE_HEIGHT: 4,
|
|
10
|
-
WALL_COLOR: "#64748b",
|
|
11
|
-
WALL_THICKNESS: 0.4,
|
|
12
|
-
BOUNDARY_COLOR: "#334155",
|
|
13
|
-
BOUNDARY_THICKNESS: 0.6,
|
|
14
|
-
BASE_COLOR: "#ffffff",
|
|
15
|
-
OVERLAY_COLOR: "#000000",
|
|
16
|
-
OVERLAY_OPACITY: 0.15,
|
|
17
|
-
PARKING_ZONE_COLOR: "#cbd5e1",
|
|
18
|
-
GREEN_AREA_COLOR: "#86efac",
|
|
19
|
-
WATER_COLOR: "#7dd3fc",
|
|
20
|
-
WALKABLE_COLOR: "#f8fafc",
|
|
21
|
-
KIOSK_SIZE: 12,
|
|
22
|
-
ZOOM_STEP: 0.5,
|
|
23
|
-
CAMERA_MAX_DISTANCE: 2e3,
|
|
24
|
-
CAMERA_MIN_DISTANCE: 50
|
|
25
|
-
}, B = [
|
|
26
|
-
"unit",
|
|
27
|
-
"amenity",
|
|
28
|
-
"kiosk_screen",
|
|
29
|
-
"connector",
|
|
30
|
-
"entrance",
|
|
31
|
-
"parking_zone"
|
|
32
|
-
], _ = 1e4, W = 2.5;
|
|
33
|
-
function b(e, n) {
|
|
34
|
-
return e.map((i) => ({ x: i.x, y: n - i.y }));
|
|
35
|
-
}
|
|
36
|
-
function A(e, n) {
|
|
37
|
-
const i = e.x - n.x, r = e.y - n.y;
|
|
38
|
-
return Math.hypot(i, r);
|
|
39
|
-
}
|
|
40
|
-
function M(e) {
|
|
41
|
-
if (e.length === 0)
|
|
42
|
-
return { minX: 0, minY: 0, maxX: 0, maxY: 0 };
|
|
43
|
-
let n = e[0].x, i = e[0].y, r = e[0].x, o = e[0].y;
|
|
44
|
-
for (let s = 1; s < e.length; s++) {
|
|
45
|
-
const t = e[s];
|
|
46
|
-
t.x < n && (n = t.x), t.y < i && (i = t.y), t.x > r && (r = t.x), t.y > o && (o = t.y);
|
|
47
|
-
}
|
|
48
|
-
return { minX: n, minY: i, maxX: r, maxY: o };
|
|
49
|
-
}
|
|
50
|
-
function F(e, n) {
|
|
51
|
-
return {
|
|
52
|
-
minX: Math.min(e.minX, n.minX),
|
|
53
|
-
minY: Math.min(e.minY, n.minY),
|
|
54
|
-
maxX: Math.max(e.maxX, n.maxX),
|
|
55
|
-
maxY: Math.max(e.maxY, n.maxY)
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function T(e) {
|
|
59
|
-
if (e.length === 0) return { x: 0, y: 0 };
|
|
60
|
-
let n = 0, i = 0;
|
|
61
|
-
for (const r of e)
|
|
62
|
-
n += r.x, i += r.y;
|
|
63
|
-
return { x: n / e.length, y: i / e.length };
|
|
64
|
-
}
|
|
65
|
-
function k(e, n) {
|
|
66
|
-
let i = !1;
|
|
67
|
-
for (let r = 0, o = n.length - 1; r < n.length; o = r++) {
|
|
68
|
-
const s = n[r].x, t = n[r].y, u = n[o].x, c = n[o].y;
|
|
69
|
-
t > e.y != c > e.y && e.x < (u - s) * (e.y - t) / (c - t + Number.EPSILON) + s && (i = !i);
|
|
70
|
-
}
|
|
71
|
-
return i;
|
|
72
|
-
}
|
|
73
|
-
function G(e, n) {
|
|
74
|
-
return n.some((i) => k(e, i));
|
|
75
|
-
}
|
|
76
|
-
function S(e, n, i) {
|
|
77
|
-
const r = i.x - n.x, o = i.y - n.y, s = r * r + o * o;
|
|
78
|
-
if (s === 0)
|
|
79
|
-
return { point: { ...n }, t: 0, distance: A(e, n) };
|
|
80
|
-
let t = ((e.x - n.x) * r + (e.y - n.y) * o) / s;
|
|
81
|
-
t = Math.max(0, Math.min(1, t));
|
|
82
|
-
const u = { x: n.x + t * r, y: n.y + t * o };
|
|
83
|
-
return { point: u, t, distance: A(e, u) };
|
|
84
|
-
}
|
|
85
|
-
function K(e, n) {
|
|
86
|
-
if (n.length < 2) return null;
|
|
87
|
-
let i = null;
|
|
88
|
-
for (let r = 0; r < n.length - 1; r++) {
|
|
89
|
-
const o = S(e, n[r], n[r + 1]);
|
|
90
|
-
(!i || o.distance < i.distance) && (i = { point: o.point, segmentIndex: r, distance: o.distance });
|
|
91
|
-
}
|
|
92
|
-
return i;
|
|
93
|
-
}
|
|
94
|
-
function R(e, n, i, r, o = 8) {
|
|
95
|
-
const s = [];
|
|
96
|
-
for (let t = 0; t <= o; t++) {
|
|
97
|
-
const u = t / o, c = 1 - u;
|
|
98
|
-
s.push({
|
|
99
|
-
x: c * c * c * e.x + 3 * c * c * u * n.x + 3 * c * u * u * i.x + u * u * u * r.x,
|
|
100
|
-
y: c * c * c * e.y + 3 * c * c * u * n.y + 3 * c * u * u * i.y + u * u * u * r.y
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
return s;
|
|
104
|
-
}
|
|
105
|
-
function L(e, n, i, r = 6) {
|
|
106
|
-
const o = [];
|
|
107
|
-
for (let s = 0; s <= r; s++) {
|
|
108
|
-
const t = s / r, u = 1 - t;
|
|
109
|
-
o.push({
|
|
110
|
-
x: u * u * e.x + 2 * u * t * n.x + t * t * i.x,
|
|
111
|
-
y: u * u * e.y + 2 * u * t * n.y + t * t * i.y
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
return o;
|
|
115
|
-
}
|
|
116
|
-
function P(e, n) {
|
|
117
|
-
const i = e.match(/[a-zA-Z]|-?\d*\.?\d+(?:e[-+]?\d+)?/g) ?? [], r = [];
|
|
118
|
-
let o = [], s = 0, t = 0, u = 0, c = 0, d = null, m = 0, y = "";
|
|
119
|
-
const a = () => Number(i[m++]);
|
|
120
|
-
for (; m < i.length; ) {
|
|
121
|
-
const h = i[m];
|
|
122
|
-
switch (/[a-zA-Z]/.test(h) && (y = h, m++), y) {
|
|
123
|
-
case "M":
|
|
124
|
-
case "m": {
|
|
125
|
-
const l = y === "m", f = a(), x = a();
|
|
126
|
-
s = l ? s + f : f, t = l ? t + x : x, o.length > 0 && r.push(o), o = [{ x: s, y: t }], u = s, c = t, d = null, y = l ? "l" : "L";
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
case "L":
|
|
130
|
-
case "l": {
|
|
131
|
-
const l = y === "l", f = a(), x = a();
|
|
132
|
-
s = l ? s + f : f, t = l ? t + x : x, o.push({ x: s, y: t }), d = null;
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
case "H":
|
|
136
|
-
case "h": {
|
|
137
|
-
const l = y === "h", f = a();
|
|
138
|
-
s = l ? s + f : f, o.push({ x: s, y: t }), d = null;
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
case "V":
|
|
142
|
-
case "v": {
|
|
143
|
-
const l = y === "v", f = a();
|
|
144
|
-
t = l ? t + f : f, o.push({ x: s, y: t }), d = null;
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
case "C":
|
|
148
|
-
case "c": {
|
|
149
|
-
const l = y === "c", f = l ? s + a() : a(), x = l ? t + a() : a(), I = l ? s + a() : a(), p = l ? t + a() : a(), g = l ? s + a() : a(), O = l ? t + a() : a(), E = R(
|
|
150
|
-
{ x: s, y: t },
|
|
151
|
-
{ x: f, y: x },
|
|
152
|
-
{ x: I, y: p },
|
|
153
|
-
{ x: g, y: O }
|
|
154
|
-
);
|
|
155
|
-
o.push(...E.slice(1)), d = { x: I, y: p }, s = g, t = O;
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case "Q":
|
|
159
|
-
case "q": {
|
|
160
|
-
const l = y === "q", f = l ? s + a() : a(), x = l ? t + a() : a(), I = l ? s + a() : a(), p = l ? t + a() : a(), g = L(
|
|
161
|
-
{ x: s, y: t },
|
|
162
|
-
{ x: f, y: x },
|
|
163
|
-
{ x: I, y: p }
|
|
164
|
-
);
|
|
165
|
-
o.push(...g.slice(1)), d = { x: f, y: x }, s = I, t = p;
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
case "S":
|
|
169
|
-
case "s": {
|
|
170
|
-
const l = y === "s", f = d ? 2 * s - d.x : s, x = d ? 2 * t - d.y : t, I = l ? s + a() : a(), p = l ? t + a() : a(), g = l ? s + a() : a(), O = l ? t + a() : a(), E = R(
|
|
171
|
-
{ x: s, y: t },
|
|
172
|
-
{ x: f, y: x },
|
|
173
|
-
{ x: I, y: p },
|
|
174
|
-
{ x: g, y: O }
|
|
175
|
-
);
|
|
176
|
-
o.push(...E.slice(1)), d = { x: I, y: p }, s = g, t = O;
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
case "T":
|
|
180
|
-
case "t": {
|
|
181
|
-
const l = y === "t", f = d ? 2 * s - d.x : s, x = d ? 2 * t - d.y : t, I = l ? s + a() : a(), p = l ? t + a() : a(), g = L(
|
|
182
|
-
{ x: s, y: t },
|
|
183
|
-
{ x: f, y: x },
|
|
184
|
-
{ x: I, y: p }
|
|
185
|
-
);
|
|
186
|
-
o.push(...g.slice(1)), d = { x: f, y: x }, s = I, t = p;
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
case "Z":
|
|
190
|
-
case "z": {
|
|
191
|
-
o.push({ x: u, y: c }), r.push(o), o = [], s = u, t = c, d = null;
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
default:
|
|
195
|
-
m++;
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return o.length > 0 && r.push(o), n != null ? r.map((h) => b(h, n)) : r;
|
|
200
|
-
}
|
|
201
|
-
function j(e, n, i = !0) {
|
|
202
|
-
const r = (n == null ? void 0 : n.height) ?? 0, o = e.map((t) => ({
|
|
203
|
-
d: t,
|
|
204
|
-
closed: /z/i.test(t)
|
|
205
|
-
})), s = e.flatMap(
|
|
206
|
-
(t) => P(t, i && r > 0 ? r : void 0)
|
|
207
|
-
);
|
|
208
|
-
return { paths: o, polygons: s };
|
|
209
|
-
}
|
|
210
|
-
function w(e) {
|
|
211
|
-
const n = e.polygons.flat();
|
|
212
|
-
return M(n);
|
|
213
|
-
}
|
|
214
|
-
function H(e) {
|
|
215
|
-
return T(e.polygons.flat());
|
|
216
|
-
}
|
|
217
|
-
function U(e, n, i = 0, r = [15, 45, 90]) {
|
|
218
|
-
const o = n.x - e.x, s = n.y - e.y, t = Math.hypot(o, s);
|
|
219
|
-
if (t === 0) return { ...n };
|
|
220
|
-
const c = Math.atan2(s, o) * 180 / Math.PI - i;
|
|
221
|
-
let d = c, m = 1 / 0;
|
|
222
|
-
for (const a of r) {
|
|
223
|
-
const h = Math.round(c / a) * a, l = Math.abs(c - h);
|
|
224
|
-
l < m && (m = l, d = h);
|
|
225
|
-
}
|
|
226
|
-
const y = (d + i) * Math.PI / 180;
|
|
227
|
-
return {
|
|
228
|
-
x: e.x + Math.cos(y) * t,
|
|
229
|
-
y: e.y + Math.sin(y) * t
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
function V(e, n) {
|
|
233
|
-
return Math.atan2(n.y - e.y, n.x - e.x) * 180 / Math.PI;
|
|
234
|
-
}
|
|
235
|
-
function Z(e) {
|
|
236
|
-
if (!e) return null;
|
|
237
|
-
const n = e.trim().split(/[\s,]+/).map(Number);
|
|
238
|
-
return n.length !== 4 || n.some((i) => Number.isNaN(i)) ? null : { x: n[0], y: n[1], width: n[2], height: n[3] };
|
|
239
|
-
}
|
|
240
|
-
function z(e, n, i = []) {
|
|
241
|
-
const r = N(), o = new Map(e.map((c) => [c.id, c])), s = new Map(i.map((c) => [c.id, c])), t = e.map((c) => ({
|
|
242
|
-
id: c.id,
|
|
243
|
-
levelId: c.levelId,
|
|
244
|
-
x: c.x,
|
|
245
|
-
y: c.y,
|
|
246
|
-
kind: c.kind,
|
|
247
|
-
shapeId: c.shapeId,
|
|
248
|
-
connectorId: c.connectorId
|
|
249
|
-
}));
|
|
250
|
-
for (const c of t)
|
|
251
|
-
r.addNode(c.id, c);
|
|
252
|
-
const u = [];
|
|
253
|
-
for (const c of n) {
|
|
254
|
-
const d = o.get(c.fromAnchorId), m = o.get(c.toAnchorId);
|
|
255
|
-
if (!d || !m) continue;
|
|
256
|
-
let y = c.weight;
|
|
257
|
-
y == null && (y = A(d, m), d.levelId !== m.levelId && (y += _));
|
|
258
|
-
let a = c.accessible;
|
|
259
|
-
if (c.kind === "connector" && d.connectorId != null) {
|
|
260
|
-
const l = s.get(d.connectorId);
|
|
261
|
-
l && (a = l.accessible);
|
|
262
|
-
}
|
|
263
|
-
const h = {
|
|
264
|
-
id: c.id,
|
|
265
|
-
from: c.fromAnchorId,
|
|
266
|
-
to: c.toAnchorId,
|
|
267
|
-
weight: y,
|
|
268
|
-
directed: c.directed,
|
|
269
|
-
accessible: a,
|
|
270
|
-
kind: c.kind
|
|
271
|
-
};
|
|
272
|
-
u.push(h), r.addLink(c.fromAnchorId, c.toAnchorId, h), c.directed || r.addLink(c.toAnchorId, c.fromAnchorId, h);
|
|
273
|
-
}
|
|
274
|
-
return { graph: r, nodes: t, edges: u, anchorById: o };
|
|
275
|
-
}
|
|
276
|
-
function Y(e, n, i, r = {}) {
|
|
277
|
-
const { graph: o, anchorById: s } = e;
|
|
278
|
-
if (!s.has(n) || !s.has(i))
|
|
279
|
-
return null;
|
|
280
|
-
const u = C.nba(o, {
|
|
281
|
-
distance(h, l, f) {
|
|
282
|
-
const x = f.data;
|
|
283
|
-
return r.accessibleOnly && x && !x.accessible ? Number.POSITIVE_INFINITY : (x == null ? void 0 : x.weight) ?? 1;
|
|
284
|
-
},
|
|
285
|
-
heuristic(h, l) {
|
|
286
|
-
const f = s.get(h.id), x = s.get(l.id);
|
|
287
|
-
if (!f || !x) return 0;
|
|
288
|
-
let I = A(f, x);
|
|
289
|
-
return f.levelId !== x.levelId && (I += _), I;
|
|
290
|
-
}
|
|
291
|
-
}).find(n, i);
|
|
292
|
-
if (!u || u.length === 0) return null;
|
|
293
|
-
const d = u.reverse().map((h) => h.id), m = [], y = [];
|
|
294
|
-
let a = 0;
|
|
295
|
-
for (let h = 0; h < d.length; h++) {
|
|
296
|
-
const l = s.get(d[h]);
|
|
297
|
-
if (m.push({ x: l.x, y: l.y, levelId: l.levelId }), h > 0) {
|
|
298
|
-
const f = s.get(d[h - 1]);
|
|
299
|
-
a += A(f, l), f.levelId !== l.levelId && (a += _, y.push({
|
|
300
|
-
fromLevelId: f.levelId,
|
|
301
|
-
toLevelId: l.levelId,
|
|
302
|
-
connectorId: l.connectorId ?? f.connectorId
|
|
303
|
-
}));
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return { anchorIds: d, points: m, totalWeight: a, levelChanges: y };
|
|
307
|
-
}
|
|
308
|
-
function q(e, n, i, r = {}) {
|
|
309
|
-
let o = null;
|
|
310
|
-
for (const s of i) {
|
|
311
|
-
const t = Y(e, n, s, r);
|
|
312
|
-
t && (!o || t.totalWeight < o.totalWeight) && (o = t);
|
|
313
|
-
}
|
|
314
|
-
return o;
|
|
315
|
-
}
|
|
316
|
-
export {
|
|
317
|
-
W as D,
|
|
318
|
-
_ as F,
|
|
319
|
-
B as I,
|
|
320
|
-
P as a,
|
|
321
|
-
j as b,
|
|
322
|
-
Z as c,
|
|
323
|
-
A as d,
|
|
324
|
-
X as e,
|
|
325
|
-
z as f,
|
|
326
|
-
w as g,
|
|
327
|
-
V as h,
|
|
328
|
-
R as i,
|
|
329
|
-
L as j,
|
|
330
|
-
M as k,
|
|
331
|
-
F as l,
|
|
332
|
-
T as m,
|
|
333
|
-
K as n,
|
|
334
|
-
q as o,
|
|
335
|
-
G as p,
|
|
336
|
-
Y as q,
|
|
337
|
-
b as r,
|
|
338
|
-
H as s,
|
|
339
|
-
k as t,
|
|
340
|
-
S as u,
|
|
341
|
-
U as v
|
|
342
|
-
};
|
|
343
|
-
//# sourceMappingURL=pathfinding.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pathfinding.js","sources":["../../src/core/types.ts","../../src/core/geometry/index.ts","../../src/core/routing/pathfinding.ts"],"sourcesContent":["/**\n * @eyeon/map/core — shared document model types.\n * Pure TypeScript; no React / Three.js.\n */\n\nexport type MapVersion = 1 | 2;\n\nexport type LevelKind = 'outdoor' | 'floor';\n\nexport type ShapeKind =\n | 'unit'\n | 'amenity'\n | 'kiosk_screen'\n | 'connector'\n | 'entrance'\n | 'walkable'\n | 'void'\n | 'wall'\n | 'boundary'\n | 'floorplate'\n | 'decor'\n | 'label'\n | 'zone'\n | 'parking_zone'\n | 'green_area'\n | 'water'\n | 'parking_icon';\n\nexport type AnchorKind = 'unit' | 'junction' | 'connector' | 'entrance';\n\nexport type EdgeKind = 'walk' | 'unit_link' | 'connector' | 'entrance_link';\n\nexport type ConnectorKind =\n | 'escalator'\n | 'elevator'\n | 'stairs'\n | 'ramp'\n | 'travelator';\n\nexport type ConnectorDirection = 'up' | 'down' | 'both';\n\nexport type UnitStatus =\n | 'occupied'\n | 'vacant'\n | 'coming_soon'\n | 'under_renovation';\n\nexport type AssignmentTargetType =\n | 'retailer'\n | 'amenity'\n | 'kiosk'\n | 'none';\n\nexport type ShapeOrigin = 'import' | 'manual';\n\nexport type DeviceType = 'display_app' | 'desktop' | 'tablet' | 'mobile';\n\nexport type MapRenderMode = '2D' | '3D';\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport interface Vec3 {\n x: number;\n y: number;\n z: number;\n}\n\nexport interface BBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface ViewBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Absolute SVG path subpath preserving Illustrator beziers. */\nexport interface PathSubpath {\n d: string;\n closed: boolean;\n}\n\nexport interface ShapeGeometry {\n /** Absolute path data (Illustrator-compatible). */\n paths: PathSubpath[];\n /** Cached polygon approximation for hit-testing / routing. */\n polygons: Vec2[][];\n}\n\nexport interface ShapeStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n extrudeHeight?: number;\n transparent?: boolean;\n}\n\nexport interface ShapeLabel {\n text?: string;\n imageKey?: string;\n size?: number;\n rotate?: number;\n offsetX?: number;\n offsetY?: number;\n color?: string;\n autoFit?: boolean;\n}\n\nexport interface LevelTransform {\n translateX: number;\n translateY: number;\n scale: number;\n rotate: number;\n}\n\nexport interface ThemeDefaults {\n MAP_STYLE: MapRenderMode;\n MAP_BACKGROUND_COLOR: string;\n ACCENT_COLOR: string;\n STORE_DEFAULT_COLOR: string;\n STORE_TEXT_COLOR: string;\n STORE_HEIGHT: number;\n WALL_COLOR: string;\n WALL_THICKNESS: number;\n BOUNDARY_COLOR: string;\n BOUNDARY_THICKNESS: number;\n BASE_COLOR: string;\n OVERLAY_COLOR: string;\n OVERLAY_OPACITY: number;\n PARKING_ZONE_COLOR: string;\n GREEN_AREA_COLOR: string;\n WATER_COLOR: string;\n WALKABLE_COLOR: string;\n KIOSK_SIZE: number;\n ZOOM_STEP: number;\n CAMERA_MAX_DISTANCE: number;\n CAMERA_MIN_DISTANCE: number;\n}\n\nexport const DEFAULT_THEME: ThemeDefaults = {\n MAP_STYLE: '2D',\n MAP_BACKGROUND_COLOR: '#f5f5f5',\n ACCENT_COLOR: '#2563eb',\n STORE_DEFAULT_COLOR: '#e2e8f0',\n STORE_TEXT_COLOR: '#1e293b',\n STORE_HEIGHT: 4,\n WALL_COLOR: '#64748b',\n WALL_THICKNESS: 0.4,\n BOUNDARY_COLOR: '#334155',\n BOUNDARY_THICKNESS: 0.6,\n BASE_COLOR: '#ffffff',\n OVERLAY_COLOR: '#000000',\n OVERLAY_OPACITY: 0.15,\n PARKING_ZONE_COLOR: '#cbd5e1',\n GREEN_AREA_COLOR: '#86efac',\n WATER_COLOR: '#7dd3fc',\n WALKABLE_COLOR: '#f8fafc',\n KIOSK_SIZE: 12,\n ZOOM_STEP: 0.5,\n CAMERA_MAX_DISTANCE: 2000,\n CAMERA_MIN_DISTANCE: 50,\n};\n\nexport interface CmMap {\n id: number;\n centerId: number;\n baseSvgKey: string | null;\n baseViewbox: ViewBox | null;\n unitsPerMeter: number;\n theme: Partial<ThemeDefaults>;\n publishedRevisionId: number | null;\n draftUpdatedAt: string | null;\n createdAt: string;\n}\n\nexport interface CmBuilding {\n id: number;\n mapId: number;\n name: string;\n ordering: number;\n}\n\nexport interface CmLevel {\n id: number;\n mapId: number;\n buildingId: number | null;\n kind: LevelKind;\n name: string;\n levelIndex: number;\n ordering: number;\n sourceSvgKey: string | null;\n sourceViewbox: ViewBox | null;\n transform: LevelTransform;\n isActive: boolean;\n}\n\nexport interface CmShape {\n id: number;\n levelId: number;\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n zIndex: number;\n style: ShapeStyle;\n label: ShapeLabel;\n sourceSvgId: string | null;\n origin: ShapeOrigin;\n}\n\nexport interface CmShapeAssignment {\n shapeId: number;\n targetType: AssignmentTargetType;\n retailerId: number | null;\n amenityId: number | null;\n kioskId: number | null;\n unitStatus: UnitStatus;\n unitNumber: string | null;\n customLabel: string | null;\n customImageKey: string | null;\n}\n\nexport interface CmAnchor {\n id: number;\n levelId: number;\n shapeId: number | null;\n kind: AnchorKind;\n x: number;\n y: number;\n connectorId: number | null;\n}\n\nexport interface CmRouteEdge {\n id: number;\n mapId: number;\n fromAnchorId: number;\n toAnchorId: number;\n weight: number | null;\n directed: boolean;\n accessible: boolean;\n kind: EdgeKind;\n}\n\nexport interface CmConnector {\n id: number;\n mapId: number;\n kind: ConnectorKind;\n name: string;\n direction: ConnectorDirection;\n accessible: boolean;\n}\n\nexport interface CmAmenityCatalogItem {\n id: number;\n centerId: number | null;\n code: string;\n name: string;\n iconKey: string | null;\n builtinIcon: string | null;\n ordering: number;\n isActive: boolean;\n}\n\nexport interface CmResponsiveOverride {\n id: number;\n mapId: number;\n levelId: number | null;\n device: DeviceType;\n camera: Vec3;\n controls: Vec3;\n}\n\nexport interface PublishedGraphNode {\n id: number;\n levelId: number;\n x: number;\n y: number;\n kind: AnchorKind;\n shapeId: number | null;\n connectorId: number | null;\n}\n\nexport interface PublishedGraphEdge {\n id: number;\n from: number;\n to: number;\n weight: number;\n directed: boolean;\n accessible: boolean;\n kind: EdgeKind;\n}\n\nexport interface PublishedLevel {\n id: number;\n buildingId: number | null;\n kind: LevelKind;\n name: string;\n levelIndex: number;\n ordering: number;\n sourceSvgUrl: string | null;\n viewbox: ViewBox | null;\n transform: LevelTransform;\n shapes: Array<CmShape & { assignment?: CmShapeAssignment | null }>;\n anchors: CmAnchor[];\n}\n\nexport interface PublishedDocument {\n version: 2;\n revisionId: number;\n revisionNumber: number;\n centerId: number;\n mapId: number;\n theme: ThemeDefaults;\n baseSvgUrl: string | null;\n baseViewbox: ViewBox | null;\n buildings: CmBuilding[];\n levels: PublishedLevel[];\n connectors: CmConnector[];\n amenities: CmAmenityCatalogItem[];\n graph: {\n nodes: PublishedGraphNode[];\n edges: PublishedGraphEdge[];\n };\n responsiveOverrides: CmResponsiveOverride[];\n publishedAt: string;\n}\n\nexport interface ImportClassification {\n sourceSvgId: string;\n kind: ShapeKind | null;\n guessed: boolean;\n message?: string;\n}\n\nexport interface ImportReport {\n classified: ImportClassification[];\n unrecognized: string[];\n guessed: ImportClassification[];\n walkableCount: number;\n voidCount: number;\n unitCount: number;\n warnings: string[];\n}\n\nexport type DiffChangeType = 'added' | 'removed' | 'moved' | 'unchanged' | 'kind_changed';\n\nexport interface ImportDiffItem {\n sourceSvgId: string;\n change: DiffChangeType;\n existingShapeId?: number;\n newKind?: ShapeKind | null;\n existingKind?: ShapeKind | null;\n preserve?: {\n key?: string;\n assignment?: boolean;\n anchors?: boolean;\n };\n}\n\nexport interface ImportDiff {\n items: ImportDiffItem[];\n shapes: Array<{\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n sourceSvgId: string;\n style: ShapeStyle;\n }>;\n viewbox: ViewBox | null;\n}\n\nexport interface WeldResult {\n survivingAnchorId: number;\n removedAnchorIds: number[];\n rewiredEdgeIds: number[];\n}\n\nexport interface AutoConnectResult {\n unitAnchorId: number;\n junctionAnchor: { x: number; y: number; existingId?: number };\n edge: { fromAnchorId: number; toAnchorId?: number };\n}\n\nexport interface SkeletonSuggestion {\n anchors: Array<{ tempId: string; x: number; y: number; kind: AnchorKind }>;\n edges: Array<{ fromTempId: string; toTempId: string }>;\n}\n\nexport interface PathResult {\n anchorIds: number[];\n points: Array<Vec2 & { levelId: number }>;\n totalWeight: number;\n levelChanges: Array<{ fromLevelId: number; toLevelId: number; connectorId: number | null }>;\n}\n\nexport type BatchOp =\n | { op: 'upsert_shape'; shape: Partial<CmShape> & { levelId: number; key: string } }\n | { op: 'delete_shape'; shapeId: number }\n | { op: 'upsert_assignment'; assignment: CmShapeAssignment }\n | { op: 'delete_assignment'; shapeId: number }\n | { op: 'upsert_anchor'; anchor: Partial<CmAnchor> & { levelId: number; x: number; y: number; kind: AnchorKind } }\n | { op: 'delete_anchor'; anchorId: number }\n | { op: 'upsert_edge'; edge: Partial<CmRouteEdge> & { mapId: number; fromAnchorId: number; toAnchorId: number } }\n | { op: 'delete_edge'; edgeId: number }\n | { op: 'weld_anchors'; anchorIds: number[]; tolerance?: number }\n | { op: 'upsert_level'; level: Partial<CmLevel> & { mapId: number; name: string; kind: LevelKind } }\n | { op: 'delete_level'; levelId: number }\n | { op: 'upsert_building'; building: Partial<CmBuilding> & { mapId: number; name: string } }\n | { op: 'delete_building'; buildingId: number }\n | { op: 'update_theme'; theme: Partial<ThemeDefaults> }\n | { op: 'upsert_connector'; connector: Partial<CmConnector> & { mapId: number; kind: ConnectorKind; name: string } }\n | { op: 'delete_connector'; connectorId: number };\n\nexport const INTERACTIVE_SHAPE_KINDS: ShapeKind[] = [\n 'unit',\n 'amenity',\n 'kiosk_screen',\n 'connector',\n 'entrance',\n 'parking_zone',\n];\n\nexport const FLOOR_CHANGE_PENALTY = 10000;\n\nexport const DEFAULT_WELD_TOLERANCE = 2.5;\n","import type { BBox, PathSubpath, ShapeGeometry, Vec2, ViewBox } from '../types';\n\n/** Flip Y once at import so DB space is Y-up / consistent. */\nexport function flipY(points: Vec2[], viewboxHeight: number): Vec2[] {\n return points.map((p) => ({ x: p.x, y: viewboxHeight - p.y }));\n}\n\nexport function distance(a: Vec2, b: Vec2): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.hypot(dx, dy);\n}\n\nexport function bboxOf(points: Vec2[]): BBox {\n if (points.length === 0) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 };\n }\n let minX = points[0].x;\n let minY = points[0].y;\n let maxX = points[0].x;\n let maxY = points[0].y;\n for (let i = 1; i < points.length; i++) {\n const p = points[i];\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n return { minX, minY, maxX, maxY };\n}\n\nexport function bboxUnion(a: BBox, b: BBox): BBox {\n return {\n minX: Math.min(a.minX, b.minX),\n minY: Math.min(a.minY, b.minY),\n maxX: Math.max(a.maxX, b.maxX),\n maxY: Math.max(a.maxY, b.maxY),\n };\n}\n\nexport function centroid(points: Vec2[]): Vec2 {\n if (points.length === 0) return { x: 0, y: 0 };\n let sx = 0;\n let sy = 0;\n for (const p of points) {\n sx += p.x;\n sy += p.y;\n }\n return { x: sx / points.length, y: sy / points.length };\n}\n\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x;\n const yi = polygon[i].y;\n const xj = polygon[j].x;\n const yj = polygon[j].y;\n const intersect =\n yi > point.y !== yj > point.y &&\n point.x < ((xj - xi) * (point.y - yi)) / (yj - yi + Number.EPSILON) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\n\nexport function pointInPolygons(point: Vec2, polygons: Vec2[][]): boolean {\n return polygons.some((poly) => pointInPolygon(point, poly));\n}\n\n/** Project point onto segment; returns closest point and t in [0,1]. */\nexport function projectOntoSegment(\n point: Vec2,\n a: Vec2,\n b: Vec2,\n): { point: Vec2; t: number; distance: number } {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n return { point: { ...a }, t: 0, distance: distance(point, a) };\n }\n let t = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq;\n t = Math.max(0, Math.min(1, t));\n const proj = { x: a.x + t * dx, y: a.y + t * dy };\n return { point: proj, t, distance: distance(point, proj) };\n}\n\nexport function nearestPointOnPolyline(\n point: Vec2,\n polyline: Vec2[],\n): { point: Vec2; segmentIndex: number; distance: number } | null {\n if (polyline.length < 2) return null;\n let best: { point: Vec2; segmentIndex: number; distance: number } | null = null;\n for (let i = 0; i < polyline.length - 1; i++) {\n const proj = projectOntoSegment(point, polyline[i], polyline[i + 1]);\n if (!best || proj.distance < best.distance) {\n best = { point: proj.point, segmentIndex: i, distance: proj.distance };\n }\n }\n return best;\n}\n\n/**\n * Approximate a cubic bezier into line segments.\n */\nexport function approximateCubic(\n p0: Vec2,\n p1: Vec2,\n p2: Vec2,\n p3: Vec2,\n segments = 8,\n): Vec2[] {\n const out: Vec2[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = i / segments;\n const u = 1 - t;\n out.push({\n x:\n u * u * u * p0.x +\n 3 * u * u * t * p1.x +\n 3 * u * t * t * p2.x +\n t * t * t * p3.x,\n y:\n u * u * u * p0.y +\n 3 * u * u * t * p1.y +\n 3 * u * t * t * p2.y +\n t * t * t * p3.y,\n });\n }\n return out;\n}\n\nexport function approximateQuadratic(\n p0: Vec2,\n p1: Vec2,\n p2: Vec2,\n segments = 6,\n): Vec2[] {\n const out: Vec2[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = i / segments;\n const u = 1 - t;\n out.push({\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n });\n }\n return out;\n}\n\n/**\n * Parse SVG path `d` into absolute polygon approximations.\n * Supports M/L/H/V/C/Q/S/T/Z (absolute and relative).\n */\nexport function pathToPolygons(d: string, flipYHeight?: number): Vec2[][] {\n const tokens = d.match(/[a-zA-Z]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/g) ?? [];\n const polygons: Vec2[][] = [];\n let current: Vec2[] = [];\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n let lastCtrl: Vec2 | null = null;\n let i = 0;\n let cmd = '';\n\n const readNum = () => Number(tokens[i++]);\n\n while (i < tokens.length) {\n const t = tokens[i];\n if (/[a-zA-Z]/.test(t)) {\n cmd = t;\n i++;\n }\n\n switch (cmd) {\n case 'M':\n case 'm': {\n const isRel = cmd === 'm';\n const nx = readNum();\n const ny = readNum();\n x = isRel ? x + nx : nx;\n y = isRel ? y + ny : ny;\n if (current.length > 0) polygons.push(current);\n current = [{ x, y }];\n startX = x;\n startY = y;\n lastCtrl = null;\n cmd = isRel ? 'l' : 'L';\n break;\n }\n case 'L':\n case 'l': {\n const isRel = cmd === 'l';\n const nx = readNum();\n const ny = readNum();\n x = isRel ? x + nx : nx;\n y = isRel ? y + ny : ny;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'H':\n case 'h': {\n const isRel = cmd === 'h';\n const nx = readNum();\n x = isRel ? x + nx : nx;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'V':\n case 'v': {\n const isRel = cmd === 'v';\n const ny = readNum();\n y = isRel ? y + ny : ny;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'C':\n case 'c': {\n const isRel = cmd === 'c';\n const x1 = isRel ? x + readNum() : readNum();\n const y1 = isRel ? y + readNum() : readNum();\n const x2 = isRel ? x + readNum() : readNum();\n const y2 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateCubic(\n { x, y },\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x2, y: y2 };\n x = nx;\n y = ny;\n break;\n }\n case 'Q':\n case 'q': {\n const isRel = cmd === 'q';\n const x1 = isRel ? x + readNum() : readNum();\n const y1 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateQuadratic(\n { x, y },\n { x: x1, y: y1 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x1, y: y1 };\n x = nx;\n y = ny;\n break;\n }\n case 'S':\n case 's': {\n const isRel = cmd === 's';\n const cx: number = lastCtrl ? 2 * x - lastCtrl.x : x;\n const cy: number = lastCtrl ? 2 * y - lastCtrl.y : y;\n const x2 = isRel ? x + readNum() : readNum();\n const y2 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateCubic(\n { x, y },\n { x: cx, y: cy },\n { x: x2, y: y2 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x2, y: y2 };\n x = nx;\n y = ny;\n break;\n }\n case 'T':\n case 't': {\n const isRel = cmd === 't';\n const cx: number = lastCtrl ? 2 * x - lastCtrl.x : x;\n const cy: number = lastCtrl ? 2 * y - lastCtrl.y : y;\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateQuadratic(\n { x, y },\n { x: cx, y: cy },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: cx, y: cy };\n x = nx;\n y = ny;\n break;\n }\n case 'Z':\n case 'z': {\n current.push({ x: startX, y: startY });\n polygons.push(current);\n current = [];\n x = startX;\n y = startY;\n lastCtrl = null;\n break;\n }\n default:\n // Unknown command — skip one token to avoid infinite loop\n i++;\n break;\n }\n }\n\n if (current.length > 0) polygons.push(current);\n\n if (flipYHeight != null) {\n return polygons.map((poly) => flipY(poly, flipYHeight));\n }\n return polygons;\n}\n\nexport function buildGeometryFromPaths(\n pathDs: string[],\n viewbox: ViewBox | null,\n normalizeY = true,\n): ShapeGeometry {\n const height = viewbox?.height ?? 0;\n const paths: PathSubpath[] = pathDs.map((d) => ({\n d,\n closed: /z/i.test(d),\n }));\n const polygons = pathDs.flatMap((d) =>\n pathToPolygons(d, normalizeY && height > 0 ? height : undefined),\n );\n return { paths, polygons };\n}\n\nexport function geometryBBox(geometry: ShapeGeometry): BBox {\n const all = geometry.polygons.flat();\n return bboxOf(all);\n}\n\nexport function geometryCentroid(geometry: ShapeGeometry): Vec2 {\n return centroid(geometry.polygons.flat());\n}\n\n/**\n * Snap a delta angle to the nearest increment around a base angle.\n * baseDeg is the working orientation (e.g. from \"match this wall\").\n */\nexport function snapAngle(\n from: Vec2,\n to: Vec2,\n baseDeg = 0,\n increments: number[] = [15, 45, 90],\n): Vec2 {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return { ...to };\n\n const rawDeg = (Math.atan2(dy, dx) * 180) / Math.PI;\n const relative = rawDeg - baseDeg;\n let best = relative;\n let bestDiff = Infinity;\n for (const step of increments) {\n const snapped = Math.round(relative / step) * step;\n const diff = Math.abs(relative - snapped);\n if (diff < bestDiff) {\n bestDiff = diff;\n best = snapped;\n }\n }\n const finalDeg = ((best + baseDeg) * Math.PI) / 180;\n return {\n x: from.x + Math.cos(finalDeg) * len,\n y: from.y + Math.sin(finalDeg) * len,\n };\n}\n\n/** Derive working base angle from two wall points (degrees). */\nexport function angleFromWall(a: Vec2, b: Vec2): number {\n return (Math.atan2(b.y - a.y, b.x - a.x) * 180) / Math.PI;\n}\n\nexport function parseViewBox(raw: string | null | undefined): ViewBox | null {\n if (!raw) return null;\n const parts = raw.trim().split(/[\\s,]+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], width: parts[2], height: parts[3] };\n}\n","import createGraph, { type Graph } from 'ngraph.graph';\nimport path from 'ngraph.path';\nimport type {\n CmAnchor,\n CmConnector,\n CmRouteEdge,\n PathResult,\n PublishedGraphEdge,\n PublishedGraphNode,\n} from '../types';\nimport { FLOOR_CHANGE_PENALTY } from '../types';\nimport { distance } from '../geometry';\n\nexport interface CompiledGraph {\n graph: Graph;\n nodes: PublishedGraphNode[];\n edges: PublishedGraphEdge[];\n anchorById: Map<number, CmAnchor>;\n}\n\nexport function compileGraph(\n anchors: CmAnchor[],\n edges: CmRouteEdge[],\n connectors: CmConnector[] = [],\n): CompiledGraph {\n const graph = createGraph();\n const anchorById = new Map(anchors.map((a) => [a.id, a]));\n const connectorById = new Map(connectors.map((c) => [c.id, c]));\n\n const nodes: PublishedGraphNode[] = anchors.map((a) => ({\n id: a.id,\n levelId: a.levelId,\n x: a.x,\n y: a.y,\n kind: a.kind,\n shapeId: a.shapeId,\n connectorId: a.connectorId,\n }));\n\n for (const n of nodes) {\n graph.addNode(n.id, n);\n }\n\n const publishedEdges: PublishedGraphEdge[] = [];\n\n for (const e of edges) {\n const from = anchorById.get(e.fromAnchorId);\n const to = anchorById.get(e.toAnchorId);\n if (!from || !to) continue;\n\n let weight = e.weight;\n if (weight == null) {\n weight = distance(from, to);\n if (from.levelId !== to.levelId) {\n weight += FLOOR_CHANGE_PENALTY;\n }\n }\n\n // Accessibility: connector edges inherit connector.accessible\n let accessible = e.accessible;\n if (e.kind === 'connector' && from.connectorId != null) {\n const conn = connectorById.get(from.connectorId);\n if (conn) accessible = conn.accessible;\n }\n\n const pub: PublishedGraphEdge = {\n id: e.id,\n from: e.fromAnchorId,\n to: e.toAnchorId,\n weight,\n directed: e.directed,\n accessible,\n kind: e.kind,\n };\n publishedEdges.push(pub);\n\n graph.addLink(e.fromAnchorId, e.toAnchorId, pub);\n if (!e.directed) {\n graph.addLink(e.toAnchorId, e.fromAnchorId, pub);\n }\n }\n\n return { graph, nodes, edges: publishedEdges, anchorById };\n}\n\nexport interface FindPathOptions {\n accessibleOnly?: boolean;\n}\n\n/**\n * NBA* pathfinding over the compiled graph.\n * Returns null if no path exists.\n */\nexport function findPath(\n compiled: CompiledGraph,\n fromAnchorId: number,\n toAnchorId: number,\n options: FindPathOptions = {},\n): PathResult | null {\n const { graph, anchorById } = compiled;\n if (!anchorById.has(fromAnchorId) || !anchorById.has(toAnchorId)) {\n return null;\n }\n\n const finder = path.nba(graph, {\n distance(fromNode, toNode, link) {\n const data = link.data as PublishedGraphEdge | undefined;\n if (options.accessibleOnly && data && !data.accessible) {\n return Number.POSITIVE_INFINITY;\n }\n return data?.weight ?? 1;\n },\n heuristic(fromNode, toNode) {\n const a = anchorById.get(fromNode.id as number);\n const b = anchorById.get(toNode.id as number);\n if (!a || !b) return 0;\n let d = distance(a, b);\n if (a.levelId !== b.levelId) d += FLOOR_CHANGE_PENALTY;\n return d;\n },\n });\n\n const raw = finder.find(fromAnchorId, toAnchorId);\n if (!raw || raw.length === 0) return null;\n\n // ngraph returns destination → start; reverse\n const nodes = raw.reverse();\n const anchorIds = nodes.map((n) => n.id as number);\n const points: PathResult['points'] = [];\n const levelChanges: PathResult['levelChanges'] = [];\n let totalWeight = 0;\n\n for (let i = 0; i < anchorIds.length; i++) {\n const a = anchorById.get(anchorIds[i])!;\n points.push({ x: a.x, y: a.y, levelId: a.levelId });\n if (i > 0) {\n const prev = anchorById.get(anchorIds[i - 1])!;\n totalWeight += distance(prev, a);\n if (prev.levelId !== a.levelId) {\n totalWeight += FLOOR_CHANGE_PENALTY;\n levelChanges.push({\n fromLevelId: prev.levelId,\n toLevelId: a.levelId,\n connectorId: a.connectorId ?? prev.connectorId,\n });\n }\n }\n }\n\n return { anchorIds, points, totalWeight, levelChanges };\n}\n\n/**\n * Find the nearest matching amenity shape anchor from a start point.\n */\nexport function findNearestAmenityPath(\n compiled: CompiledGraph,\n fromAnchorId: number,\n amenityAnchorIds: number[],\n options: FindPathOptions = {},\n): PathResult | null {\n let best: PathResult | null = null;\n for (const targetId of amenityAnchorIds) {\n const result = findPath(compiled, fromAnchorId, targetId, options);\n if (!result) continue;\n if (!best || result.totalWeight < best.totalWeight) {\n best = result;\n }\n }\n return best;\n}\n"],"names":["DEFAULT_THEME","INTERACTIVE_SHAPE_KINDS","FLOOR_CHANGE_PENALTY","DEFAULT_WELD_TOLERANCE","flipY","points","viewboxHeight","p","distance","a","b","dx","dy","bboxOf","minX","minY","maxX","maxY","i","bboxUnion","centroid","sx","sy","pointInPolygon","point","polygon","inside","j","xi","yi","xj","yj","pointInPolygons","polygons","poly","projectOntoSegment","lenSq","proj","nearestPointOnPolyline","polyline","best","approximateCubic","p0","p1","p2","p3","segments","out","t","u","approximateQuadratic","pathToPolygons","d","flipYHeight","tokens","current","x","y","startX","startY","lastCtrl","cmd","readNum","isRel","nx","ny","x1","y1","x2","y2","approx","cx","cy","buildGeometryFromPaths","pathDs","viewbox","normalizeY","height","paths","geometryBBox","geometry","all","geometryCentroid","snapAngle","from","to","baseDeg","increments","len","relative","bestDiff","step","snapped","diff","finalDeg","angleFromWall","parseViewBox","raw","parts","n","compileGraph","anchors","edges","connectors","graph","createGraph","anchorById","connectorById","nodes","publishedEdges","e","weight","accessible","conn","pub","findPath","compiled","fromAnchorId","toAnchorId","options","path","fromNode","toNode","link","data","anchorIds","levelChanges","totalWeight","prev","findNearestAmenityPath","amenityAnchorIds","targetId","result"],"mappings":"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"}
|