@kerros/viewer 0.0.0-stage → 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +31 -2
- package/dist/adapters/basemap.js +11 -0
- package/dist/adapters/basemap.js.map +1 -0
- package/dist/adapters/persistence.js +121 -0
- package/dist/adapters/persistence.js.map +1 -0
- package/dist/adapters/status.js +18 -0
- package/dist/adapters/status.js.map +1 -0
- package/dist/components/ElevatorPanel.js +120 -0
- package/dist/components/ElevatorPanel.js.map +1 -0
- package/dist/components/Icons.js +57 -0
- package/dist/components/Icons.js.map +1 -0
- package/dist/components/Inspector.js +1184 -0
- package/dist/components/Inspector.js.map +1 -0
- package/dist/components/NavigatePanel.js +301 -0
- package/dist/components/NavigatePanel.js.map +1 -0
- package/dist/components/NavigationGraph.js +234 -0
- package/dist/components/NavigationGraph.js.map +1 -0
- package/dist/components/StructureExplorer.js +510 -0
- package/dist/components/StructureExplorer.js.map +1 -0
- package/dist/components/StructureView.js +286 -0
- package/dist/components/StructureView.js.map +1 -0
- package/dist/components/controls.js +170 -0
- package/dist/components/controls.js.map +1 -0
- package/dist/components/graphLayout.js +27 -0
- package/dist/components/graphLayout.js.map +1 -0
- package/dist/host.js +169 -0
- package/dist/host.js.map +1 -0
- package/dist/i18n.js +88 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.js +171 -0
- package/dist/index.js.map +1 -0
- package/dist/map/CabinMaterials.js +81 -0
- package/dist/map/CabinMaterials.js.map +1 -0
- package/dist/map/CabinMirror.js +43 -0
- package/dist/map/CabinMirror.js.map +1 -0
- package/dist/map/Doors.js +80 -0
- package/dist/map/Doors.js.map +1 -0
- package/dist/map/ElevatorCabin.js +93 -0
- package/dist/map/ElevatorCabin.js.map +1 -0
- package/dist/map/FixtureLights.js +117 -0
- package/dist/map/FixtureLights.js.map +1 -0
- package/dist/map/MapCanvas.js +2161 -0
- package/dist/map/MapCanvas.js.map +1 -0
- package/dist/map/Passenger.js +69 -0
- package/dist/map/Passenger.js.map +1 -0
- package/dist/map/SceneLayer.js +1534 -0
- package/dist/map/SceneLayer.js.map +1 -0
- package/dist/map/UndergroundContext.js +153 -0
- package/dist/map/UndergroundContext.js.map +1 -0
- package/dist/map/ambience.js +194 -0
- package/dist/map/ambience.js.map +1 -0
- package/dist/map/architecture.js +305 -0
- package/dist/map/architecture.js.map +1 -0
- package/dist/map/bathMusic.js +92 -0
- package/dist/map/bathMusic.js.map +1 -0
- package/dist/map/cameraAim.js +33 -0
- package/dist/map/cameraAim.js.map +1 -0
- package/dist/map/elevators.js +56 -0
- package/dist/map/elevators.js.map +1 -0
- package/dist/map/excavation.js +52 -0
- package/dist/map/excavation.js.map +1 -0
- package/dist/map/exteriors.js +25 -0
- package/dist/map/exteriors.js.map +1 -0
- package/dist/map/features.js +218 -0
- package/dist/map/features.js.map +1 -0
- package/dist/map/fences.js +29 -0
- package/dist/map/fences.js.map +1 -0
- package/dist/map/journey.js +112 -0
- package/dist/map/journey.js.map +1 -0
- package/dist/map/levels.js +6 -0
- package/dist/map/levels.js.map +1 -0
- package/dist/map/lighting.js +142 -0
- package/dist/map/lighting.js.map +1 -0
- package/dist/map/loadBasemap.js +26 -0
- package/dist/map/loadBasemap.js.map +1 -0
- package/dist/map/materials.js +183 -0
- package/dist/map/materials.js.map +1 -0
- package/dist/map/poolLighting.js +39 -0
- package/dist/map/poolLighting.js.map +1 -0
- package/dist/map/projection.js +24 -0
- package/dist/map/projection.js.map +1 -0
- package/dist/map/rampGeometry.js +38 -0
- package/dist/map/rampGeometry.js.map +1 -0
- package/dist/map/route.js +107 -0
- package/dist/map/route.js.map +1 -0
- package/dist/map/stairSurfaces.js +115 -0
- package/dist/map/stairSurfaces.js.map +1 -0
- package/dist/map/surfaces.js +136 -0
- package/dist/map/surfaces.js.map +1 -0
- package/dist/map/textures.js +95 -0
- package/dist/map/textures.js.map +1 -0
- package/dist/map/underground.js +34 -0
- package/dist/map/underground.js.map +1 -0
- package/dist/map/walk.js +433 -0
- package/dist/map/walk.js.map +1 -0
- package/dist/map/walkContext.js +46 -0
- package/dist/map/walkContext.js.map +1 -0
- package/dist/map/walkDimensions.js +7 -0
- package/dist/map/walkDimensions.js.map +1 -0
- package/dist/map/walkJourney.js +85 -0
- package/dist/map/walkJourney.js.map +1 -0
- package/dist/map/walkSurfaces.js +106 -0
- package/dist/map/walkSurfaces.js.map +1 -0
- package/dist/map/wallJoins.js +70 -0
- package/dist/map/wallJoins.js.map +1 -0
- package/dist/map/water.js +274 -0
- package/dist/map/water.js.map +1 -0
- package/dist/model/authoring.js +80 -0
- package/dist/model/authoring.js.map +1 -0
- package/dist/model/boundaries.js +548 -0
- package/dist/model/boundaries.js.map +1 -0
- package/dist/model/coverage.js +30 -0
- package/dist/model/coverage.js.map +1 -0
- package/dist/model/document.js +52 -0
- package/dist/model/document.js.map +1 -0
- package/dist/model/doors.js +47 -0
- package/dist/model/doors.js.map +1 -0
- package/dist/model/factory.js +56 -0
- package/dist/model/factory.js.map +1 -0
- package/dist/model/geometry.js +394 -0
- package/dist/model/geometry.js.map +1 -0
- package/dist/model/inference.js +182 -0
- package/dist/model/inference.js.map +1 -0
- package/dist/model/materials.js +11 -0
- package/dist/model/materials.js.map +1 -0
- package/dist/model/mutations.js +157 -0
- package/dist/model/mutations.js.map +1 -0
- package/dist/model/navigation.js +275 -0
- package/dist/model/navigation.js.map +1 -0
- package/dist/model/ontology.js +109 -0
- package/dist/model/ontology.js.map +1 -0
- package/dist/model/passages.js +5 -0
- package/dist/model/passages.js.map +1 -0
- package/dist/model/portals.js +42 -0
- package/dist/model/portals.js.map +1 -0
- package/dist/model/precision.js +11 -0
- package/dist/model/precision.js.map +1 -0
- package/dist/model/project.js +17 -0
- package/dist/model/project.js.map +1 -0
- package/dist/model/ramps.js +10 -0
- package/dist/model/ramps.js.map +1 -0
- package/dist/model/roomNavigation.js +87 -0
- package/dist/model/roomNavigation.js.map +1 -0
- package/dist/model/routeClearance.js +72 -0
- package/dist/model/routeClearance.js.map +1 -0
- package/dist/model/spaces.js +104 -0
- package/dist/model/spaces.js.map +1 -0
- package/dist/model/stairGeometry.js +40 -0
- package/dist/model/stairGeometry.js.map +1 -0
- package/dist/model/stairTraversal.js +48 -0
- package/dist/model/stairTraversal.js.map +1 -0
- package/dist/model/topology.js +63 -0
- package/dist/model/topology.js.map +1 -0
- package/dist/model/types.js +35 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validate.js +240 -0
- package/dist/model/validate.js.map +1 -0
- package/dist/model/vertical.js +129 -0
- package/dist/model/vertical.js.map +1 -0
- package/dist/model/walls.js +71 -0
- package/dist/model/walls.js.map +1 -0
- package/dist/styles.css +4931 -0
- package/dist/theme/index.js +34 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/types/adapters/basemap.d.ts +2 -0
- package/dist/types/adapters/persistence.d.ts +29 -0
- package/dist/types/adapters/status.d.ts +4 -0
- package/dist/types/components/ElevatorPanel.d.ts +18 -0
- package/dist/types/components/Icons.d.ts +8 -0
- package/dist/types/components/Inspector.d.ts +38 -0
- package/dist/types/components/NavigatePanel.d.ts +27 -0
- package/dist/types/components/NavigationGraph.d.ts +10 -0
- package/dist/types/components/StructureExplorer.d.ts +8 -0
- package/dist/types/components/StructureView.d.ts +22 -0
- package/dist/types/components/controls.d.ts +52 -0
- package/dist/types/components/graphLayout.d.ts +9 -0
- package/dist/types/i18n.d.ts +85 -0
- package/dist/types/import/analysisPreview.d.ts +27 -0
- package/dist/types/import/brief.d.ts +22 -0
- package/dist/types/import/checkpoint.d.ts +49 -0
- package/dist/types/import/instructions.d.ts +7 -0
- package/dist/types/import/usage.d.ts +10 -0
- package/dist/types/map/CabinMaterials.d.ts +18 -0
- package/dist/types/map/CabinMirror.d.ts +13 -0
- package/dist/types/map/Doors.d.ts +11 -0
- package/dist/types/map/ElevatorCabin.d.ts +20 -0
- package/dist/types/map/FixtureLights.d.ts +35 -0
- package/dist/types/map/MapCanvas.d.ts +87 -0
- package/dist/types/map/Passenger.d.ts +18 -0
- package/dist/types/map/SceneLayer.d.ts +306 -0
- package/dist/types/map/UndergroundContext.d.ts +18 -0
- package/dist/types/map/ambience.d.ts +29 -0
- package/dist/types/map/architecture.d.ts +8 -0
- package/dist/types/map/bathMusic.d.ts +14 -0
- package/dist/types/map/cameraAim.d.ts +20 -0
- package/dist/types/map/elevators.d.ts +16 -0
- package/dist/types/map/excavation.d.ts +9 -0
- package/dist/types/map/exteriors.d.ts +3 -0
- package/dist/types/map/features.d.ts +33 -0
- package/dist/types/map/fences.d.ts +4 -0
- package/dist/types/map/journey.d.ts +36 -0
- package/dist/types/map/levels.d.ts +4 -0
- package/dist/types/map/lighting.d.ts +103 -0
- package/dist/types/map/loadBasemap.d.ts +4 -0
- package/dist/types/map/materials.d.ts +38 -0
- package/dist/types/map/poolLighting.d.ts +11 -0
- package/dist/types/map/projection.d.ts +9 -0
- package/dist/types/map/rampGeometry.d.ts +8 -0
- package/dist/types/map/route.d.ts +59 -0
- package/dist/types/map/stairSurfaces.d.ts +29 -0
- package/dist/types/map/surfaces.d.ts +36 -0
- package/dist/types/map/textures.d.ts +8 -0
- package/dist/types/map/underground.d.ts +30 -0
- package/dist/types/map/walk.d.ts +232 -0
- package/dist/types/map/walkContext.d.ts +11 -0
- package/dist/types/map/walkDimensions.d.ts +5 -0
- package/dist/types/map/walkJourney.d.ts +33 -0
- package/dist/types/map/walkSurfaces.d.ts +27 -0
- package/dist/types/map/wallJoins.d.ts +6 -0
- package/dist/types/map/water.d.ts +12 -0
- package/dist/types/model/authoring.d.ts +38 -0
- package/dist/types/model/boundaries.d.ts +41 -0
- package/dist/types/model/coverage.d.ts +8 -0
- package/dist/types/model/document.d.ts +9 -0
- package/dist/types/model/doors.d.ts +19 -0
- package/dist/types/model/factory.d.ts +5 -0
- package/dist/types/model/geometry.d.ts +99 -0
- package/dist/types/model/host.d.ts +154 -0
- package/dist/types/model/inference.d.ts +46 -0
- package/dist/types/model/live.d.ts +60 -0
- package/dist/types/model/materials.d.ts +28 -0
- package/dist/types/model/mutations.d.ts +178 -0
- package/dist/types/model/navigation.d.ts +70 -0
- package/dist/types/model/ontology.d.ts +43 -0
- package/dist/types/model/passages.d.ts +2 -0
- package/dist/types/model/portals.d.ts +9 -0
- package/dist/types/model/precision.d.ts +11 -0
- package/dist/types/model/project.d.ts +8 -0
- package/dist/types/model/ramps.d.ts +7 -0
- package/dist/types/model/roomNavigation.d.ts +15 -0
- package/dist/types/model/routeClearance.d.ts +11 -0
- package/dist/types/model/spaces.d.ts +46 -0
- package/dist/types/model/stairGeometry.d.ts +27 -0
- package/dist/types/model/stairTraversal.d.ts +8 -0
- package/dist/types/model/topology.d.ts +14 -0
- package/dist/types/model/types.d.ts +369 -0
- package/dist/types/model/validate.d.ts +38 -0
- package/dist/types/model/vertical.d.ts +145 -0
- package/dist/types/model/walls.d.ts +71 -0
- package/dist/types/schema/index.d.ts +25 -0
- package/dist/types/theme/index.d.ts +55 -0
- package/dist/types/viewer/FloorViewer.d.ts +76 -0
- package/dist/types/viewer/ViewerWorkspace.d.ts +2 -0
- package/dist/types/viewer/host.d.ts +11 -0
- package/dist/types/viewer/index.d.ts +2 -0
- package/dist/types/viewer/panels.d.ts +12 -0
- package/dist/viewer/FloorViewer.js +104 -0
- package/dist/viewer/FloorViewer.js.map +1 -0
- package/dist/viewer/ViewerWorkspace.js +370 -0
- package/dist/viewer/ViewerWorkspace.js.map +1 -0
- package/dist/viewer/panels.js +35 -0
- package/dist/viewer/panels.js.map +1 -0
- package/package.json +52 -4
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import { jsxs as s, jsx as n, Fragment as N } from "react/jsx-runtime";
|
|
2
|
+
import { useState as w, useId as re, useMemo as Y, useRef as ce, useEffect as ae } from "react";
|
|
3
|
+
import { LocateFixed as M } from "lucide-react";
|
|
4
|
+
import { isSpace as oe } from "../model/types.js";
|
|
5
|
+
import { zoneSpaces as de } from "../model/ontology.js";
|
|
6
|
+
import { navNodes as ue, navEdges as me } from "../model/navigation.js";
|
|
7
|
+
import { effectivePortals as he } from "../model/portals.js";
|
|
8
|
+
const z = ["Spaces", "Zones", "Portals", "Topology"], L = (i, k) => `${i} ${k}${i === 1 ? "" : "s"}`, _ = (i) => i === "none" ? "Sealed" : i === "a-to-b" ? "→" : i === "b-to-a" ? "←" : "↔";
|
|
9
|
+
function A({
|
|
10
|
+
title: i,
|
|
11
|
+
children: k,
|
|
12
|
+
className: m,
|
|
13
|
+
initialOpen: b = !1,
|
|
14
|
+
onLocate: v,
|
|
15
|
+
locateLabel: I
|
|
16
|
+
}) {
|
|
17
|
+
const [S, d] = w(b);
|
|
18
|
+
return /* @__PURE__ */ s("details", { className: m, open: S, onToggle: (h) => d(h.currentTarget.open), children: [
|
|
19
|
+
/* @__PURE__ */ s("summary", { children: [
|
|
20
|
+
/* @__PURE__ */ n("span", { className: "structure-row-title", children: i }),
|
|
21
|
+
v && /* @__PURE__ */ n(
|
|
22
|
+
"button",
|
|
23
|
+
{
|
|
24
|
+
className: "structure-locate",
|
|
25
|
+
"aria-label": I,
|
|
26
|
+
title: "Find on map",
|
|
27
|
+
onClick: (h) => {
|
|
28
|
+
h.preventDefault(), h.stopPropagation(), v();
|
|
29
|
+
},
|
|
30
|
+
children: /* @__PURE__ */ n(M, { size: 13 })
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] }),
|
|
34
|
+
S && k()
|
|
35
|
+
] });
|
|
36
|
+
}
|
|
37
|
+
function O({ items: i, render: k }) {
|
|
38
|
+
const [m, b] = w(50), v = ce(null);
|
|
39
|
+
return ae(() => {
|
|
40
|
+
const I = v.current;
|
|
41
|
+
if (!I || m >= i.length) return;
|
|
42
|
+
const S = new IntersectionObserver(
|
|
43
|
+
(d) => {
|
|
44
|
+
d.some((h) => h.isIntersecting) && b((h) => Math.min(i.length, h + 50));
|
|
45
|
+
},
|
|
46
|
+
{ root: I.closest(".inspector-scroll"), rootMargin: "160px" }
|
|
47
|
+
);
|
|
48
|
+
return S.observe(I), () => S.disconnect();
|
|
49
|
+
}, [m, i.length]), /* @__PURE__ */ s(N, { children: [
|
|
50
|
+
i.slice(0, m).map(k),
|
|
51
|
+
m < i.length && /* @__PURE__ */ s("div", { className: "structure-load-more", ref: v, children: [
|
|
52
|
+
m,
|
|
53
|
+
" of ",
|
|
54
|
+
i.length,
|
|
55
|
+
" · scroll for more"
|
|
56
|
+
] })
|
|
57
|
+
] });
|
|
58
|
+
}
|
|
59
|
+
function ye({
|
|
60
|
+
project: i,
|
|
61
|
+
selected: k,
|
|
62
|
+
onSelect: m,
|
|
63
|
+
onFloorChange: b,
|
|
64
|
+
onLocate: v,
|
|
65
|
+
onGraphView: I,
|
|
66
|
+
renderZones: S
|
|
67
|
+
}) {
|
|
68
|
+
var U, V, W, X;
|
|
69
|
+
const [d, h] = w("Spaces"), [g, ee] = w(""), [p, te] = w("all"), [B, H] = w("all"), [C, ne] = w(!1), [R, se] = w(!1), G = re(), o = Y(() => {
|
|
70
|
+
const e = new Map(i.objects.map((a) => [a.id, a])), t = i.objects.filter((a) => oe(a.kind)), l = he(i), r = /* @__PURE__ */ new Map();
|
|
71
|
+
for (const a of l)
|
|
72
|
+
for (const $ of /* @__PURE__ */ new Set([a.a, a.b])) {
|
|
73
|
+
const E = r.get($) ?? [];
|
|
74
|
+
E.push(a), r.set($, E);
|
|
75
|
+
}
|
|
76
|
+
const c = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const a of i.zones ?? [])
|
|
78
|
+
for (const $ of de(i, a)) {
|
|
79
|
+
const E = c.get($) ?? [];
|
|
80
|
+
E.push(a.name), c.set($, E);
|
|
81
|
+
}
|
|
82
|
+
const y = /* @__PURE__ */ new Map();
|
|
83
|
+
for (const a of i.objects)
|
|
84
|
+
if (a.parentId) {
|
|
85
|
+
const $ = y.get(a.parentId) ?? [];
|
|
86
|
+
$.push(a), y.set(a.parentId, $);
|
|
87
|
+
}
|
|
88
|
+
return { objects: e, spaces: t, portals: l, bySpace: r, memberships: c, children: y };
|
|
89
|
+
}, [i]), u = Y(() => {
|
|
90
|
+
var c, y;
|
|
91
|
+
if (d !== "Topology") return null;
|
|
92
|
+
const e = ue(i), t = me(i), l = new Map(e.map((a) => [a.id, a])), r = new Map(e.map((a) => [a.id, []]));
|
|
93
|
+
for (const a of t)
|
|
94
|
+
(c = r.get(a.aId)) == null || c.push(a), (y = r.get(a.bId)) == null || y.push(a);
|
|
95
|
+
return { nodes: e, edges: t, byId: l, adjacency: r };
|
|
96
|
+
}, [i, d]), x = (e) => {
|
|
97
|
+
var t;
|
|
98
|
+
return e === null ? "Outdoor site" : ((t = i.floors.find((l) => l.id === e)) == null ? void 0 : t.name) ?? e;
|
|
99
|
+
}, j = (e) => {
|
|
100
|
+
var t;
|
|
101
|
+
return ((t = o.objects.get(e)) == null ? void 0 : t.name) || e;
|
|
102
|
+
}, D = (...e) => !g.trim() || e.some((t) => t == null ? void 0 : t.toLowerCase().includes(g.trim().toLowerCase())), P = (e) => p === "all" || p === (e ?? "outdoors"), ie = (e, t = e.floorId) => {
|
|
103
|
+
m == null || m(e.id), b == null || b(t);
|
|
104
|
+
}, f = (e, t, l) => {
|
|
105
|
+
if (v) v({ objectIds: e, floorId: t, position: l });
|
|
106
|
+
else {
|
|
107
|
+
const r = o.objects.get(e[0]);
|
|
108
|
+
r ? ie(r, t === void 0 ? r.floorId : t) : t !== void 0 && (b == null || b(t));
|
|
109
|
+
}
|
|
110
|
+
}, F = (e) => {
|
|
111
|
+
const t = o.objects.get(e);
|
|
112
|
+
return t ? /* @__PURE__ */ s("span", { className: "structure-object-link", children: [
|
|
113
|
+
/* @__PURE__ */ n("span", { title: t.name || t.id, children: t.name || t.id }),
|
|
114
|
+
/* @__PURE__ */ n(
|
|
115
|
+
"button",
|
|
116
|
+
{
|
|
117
|
+
type: "button",
|
|
118
|
+
className: "structure-locate",
|
|
119
|
+
"aria-label": `Find ${t.name || t.id} on map`,
|
|
120
|
+
title: "Find on map",
|
|
121
|
+
onClick: () => f([t.id]),
|
|
122
|
+
children: /* @__PURE__ */ n(M, { size: 13 })
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
] }) : /* @__PURE__ */ n("span", { children: e });
|
|
126
|
+
}, K = (e) => /* @__PURE__ */ n(
|
|
127
|
+
A,
|
|
128
|
+
{
|
|
129
|
+
className: "structure-record",
|
|
130
|
+
onLocate: () => f([...e.openingId ? [e.openingId] : [], e.a, e.b]),
|
|
131
|
+
locateLabel: `Find ${e.name || "portal"} on map`,
|
|
132
|
+
title: /* @__PURE__ */ s(N, { children: [
|
|
133
|
+
/* @__PURE__ */ n("span", { children: e.name || (e.openingId ? j(e.openingId) : "Open boundary") }),
|
|
134
|
+
/* @__PURE__ */ n("small", { children: _(e.passage) })
|
|
135
|
+
] }),
|
|
136
|
+
children: () => /* @__PURE__ */ s("div", { className: "structure-record-body", children: [
|
|
137
|
+
/* @__PURE__ */ s("div", { className: "structure-connection", children: [
|
|
138
|
+
F(e.a),
|
|
139
|
+
/* @__PURE__ */ n("span", { children: _(e.passage) }),
|
|
140
|
+
F(e.b)
|
|
141
|
+
] }),
|
|
142
|
+
/* @__PURE__ */ n("p", { children: [...new Set([e.a, e.b].map((t) => {
|
|
143
|
+
var l;
|
|
144
|
+
return x(((l = o.objects.get(t)) == null ? void 0 : l.floorId) ?? null);
|
|
145
|
+
}))].join(
|
|
146
|
+
" · "
|
|
147
|
+
) }),
|
|
148
|
+
/* @__PURE__ */ s("div", { className: "structure-facts", children: [
|
|
149
|
+
/* @__PURE__ */ s("span", { children: [
|
|
150
|
+
"Crossing evidence: ",
|
|
151
|
+
e.attests ?? "assumed"
|
|
152
|
+
] }),
|
|
153
|
+
e.openingId && /* @__PURE__ */ s("span", { className: "structure-fact", children: [
|
|
154
|
+
"Opening: ",
|
|
155
|
+
F(e.openingId)
|
|
156
|
+
] })
|
|
157
|
+
] }),
|
|
158
|
+
(i.portalGroups ?? []).filter((t) => t.portalIds.includes(e.id)).map((t) => /* @__PURE__ */ s("p", { children: [
|
|
159
|
+
"Group: ",
|
|
160
|
+
t.name
|
|
161
|
+
] }, t.id)),
|
|
162
|
+
/* @__PURE__ */ n("code", { title: e.id, children: e.id })
|
|
163
|
+
] })
|
|
164
|
+
},
|
|
165
|
+
e.id
|
|
166
|
+
), le = (e) => /* @__PURE__ */ n(
|
|
167
|
+
A,
|
|
168
|
+
{
|
|
169
|
+
className: `structure-record ${e.id === k ? "selected" : ""}`,
|
|
170
|
+
onLocate: () => f([e.id]),
|
|
171
|
+
locateLabel: `Find ${e.name} on map`,
|
|
172
|
+
title: /* @__PURE__ */ s(N, { children: [
|
|
173
|
+
/* @__PURE__ */ n("span", { children: e.name || e.id }),
|
|
174
|
+
/* @__PURE__ */ s("small", { children: [
|
|
175
|
+
e.kind,
|
|
176
|
+
" · ",
|
|
177
|
+
(o.bySpace.get(e.id) ?? []).length,
|
|
178
|
+
" portals"
|
|
179
|
+
] })
|
|
180
|
+
] }),
|
|
181
|
+
children: () => {
|
|
182
|
+
var t, l, r;
|
|
183
|
+
return /* @__PURE__ */ s("div", { className: "structure-record-body", children: [
|
|
184
|
+
e.parentId && /* @__PURE__ */ s("p", { className: "structure-fact", children: [
|
|
185
|
+
"Inside: ",
|
|
186
|
+
F(e.parentId)
|
|
187
|
+
] }),
|
|
188
|
+
/* @__PURE__ */ s("p", { children: [
|
|
189
|
+
"Zones: ",
|
|
190
|
+
((t = o.memberships.get(e.id)) == null ? void 0 : t.join(", ")) || "Not grouped into a zone"
|
|
191
|
+
] }),
|
|
192
|
+
!!((l = e.servedFloorIds) != null && l.length) && /* @__PURE__ */ s("div", { children: [
|
|
193
|
+
/* @__PURE__ */ n("h4", { children: "Served floors" }),
|
|
194
|
+
e.servedFloorIds.map((c) => /* @__PURE__ */ s("div", { className: "structure-object-link structure-item", children: [
|
|
195
|
+
/* @__PURE__ */ n("span", { children: x(c) }),
|
|
196
|
+
/* @__PURE__ */ n(
|
|
197
|
+
"button",
|
|
198
|
+
{
|
|
199
|
+
className: "structure-locate",
|
|
200
|
+
title: "Find on map",
|
|
201
|
+
"aria-label": `Find ${e.name} on ${x(c)}`,
|
|
202
|
+
onClick: () => f([e.id], c),
|
|
203
|
+
children: /* @__PURE__ */ n(M, { size: 13 })
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
] }, c))
|
|
207
|
+
] }),
|
|
208
|
+
!!((r = o.children.get(e.id)) != null && r.length) && /* @__PURE__ */ s("div", { children: [
|
|
209
|
+
/* @__PURE__ */ n("h4", { children: "Contained objects" }),
|
|
210
|
+
/* @__PURE__ */ n(
|
|
211
|
+
O,
|
|
212
|
+
{
|
|
213
|
+
items: o.children.get(e.id),
|
|
214
|
+
render: (c) => /* @__PURE__ */ s("div", { className: "structure-item", children: [
|
|
215
|
+
F(c.id),
|
|
216
|
+
" ",
|
|
217
|
+
/* @__PURE__ */ n("small", { children: c.kind })
|
|
218
|
+
] }, c.id)
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
] }),
|
|
222
|
+
/* @__PURE__ */ n("h4", { children: "Connections" }),
|
|
223
|
+
/* @__PURE__ */ n(O, { items: o.bySpace.get(e.id) ?? [], render: K }),
|
|
224
|
+
!o.bySpace.has(e.id) && /* @__PURE__ */ n("p", { children: "No direct portals. Transport connectivity may be supplied by its zone." }),
|
|
225
|
+
/* @__PURE__ */ n("code", { title: e.id, children: e.id })
|
|
226
|
+
] });
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
e.id
|
|
230
|
+
), Q = o.spaces.filter(
|
|
231
|
+
(e) => P(e.floorId) && D(e.name, e.id, e.kind, x(e.floorId))
|
|
232
|
+
), T = (U = i.portalGroups) == null ? void 0 : U.find((e) => e.id === B), Z = o.portals.filter(
|
|
233
|
+
(e) => {
|
|
234
|
+
var t, l;
|
|
235
|
+
return (!T || T.portalIds.includes(e.id)) && (P(((t = o.objects.get(e.a)) == null ? void 0 : t.floorId) ?? null) || P(((l = o.objects.get(e.b)) == null ? void 0 : l.floorId) ?? null)) && D(
|
|
236
|
+
e.name,
|
|
237
|
+
e.id,
|
|
238
|
+
j(e.a),
|
|
239
|
+
j(e.b),
|
|
240
|
+
e.openingId ? j(e.openingId) : "Open boundary"
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
), J = (u == null ? void 0 : u.nodes.filter(
|
|
244
|
+
(e) => {
|
|
245
|
+
var t;
|
|
246
|
+
return P(e.floorId) && D(e.id, e.objectId ? j(e.objectId) : "", x(e.floorId)) && (!R || !((t = u.adjacency.get(e.id)) != null && t.length));
|
|
247
|
+
}
|
|
248
|
+
)) ?? [], q = (e, t) => {
|
|
249
|
+
if (!P(e)) return null;
|
|
250
|
+
const l = Q.filter((r) => r.floorId === e);
|
|
251
|
+
return g.trim() && !l.length ? null : /* @__PURE__ */ n(
|
|
252
|
+
A,
|
|
253
|
+
{
|
|
254
|
+
className: "structure-floor",
|
|
255
|
+
onLocate: () => f(
|
|
256
|
+
l.map((r) => r.id),
|
|
257
|
+
e
|
|
258
|
+
),
|
|
259
|
+
locateLabel: `Find ${t} on map`,
|
|
260
|
+
initialOpen: !!g.trim() || p !== "all",
|
|
261
|
+
title: /* @__PURE__ */ s(N, { children: [
|
|
262
|
+
/* @__PURE__ */ n("span", { children: t }),
|
|
263
|
+
/* @__PURE__ */ n("small", { children: L(l.length, "space") })
|
|
264
|
+
] }),
|
|
265
|
+
children: () => /* @__PURE__ */ n(N, { children: l.length ? /* @__PURE__ */ n(O, { items: l, render: le }, `${g}:${p}`) : /* @__PURE__ */ n("p", { className: "structure-note", children: "No spaces on this level." }) })
|
|
266
|
+
},
|
|
267
|
+
`${e}:${g}`
|
|
268
|
+
);
|
|
269
|
+
};
|
|
270
|
+
return /* @__PURE__ */ s("div", { className: "structure-panel", children: [
|
|
271
|
+
/* @__PURE__ */ s("div", { className: "structure-heading", children: [
|
|
272
|
+
/* @__PURE__ */ n("strong", { children: "Structure" }),
|
|
273
|
+
/* @__PURE__ */ n("small", { children: i.name })
|
|
274
|
+
] }),
|
|
275
|
+
/* @__PURE__ */ n("div", { className: "structure-tabs", role: "tablist", "aria-label": "Structure views", children: z.map((e, t) => /* @__PURE__ */ n(
|
|
276
|
+
"button",
|
|
277
|
+
{
|
|
278
|
+
role: "tab",
|
|
279
|
+
id: `${G}-${e}`,
|
|
280
|
+
"aria-controls": `${G}-panel`,
|
|
281
|
+
"aria-selected": d === e,
|
|
282
|
+
tabIndex: d === e ? 0 : -1,
|
|
283
|
+
onClick: () => h(e),
|
|
284
|
+
onKeyDown: (l) => {
|
|
285
|
+
var c;
|
|
286
|
+
const r = l.key === "ArrowRight" ? (t + 1) % z.length : l.key === "ArrowLeft" ? (t + z.length - 1) % z.length : l.key === "Home" ? 0 : l.key === "End" ? z.length - 1 : -1;
|
|
287
|
+
r >= 0 && (l.preventDefault(), h(z[r]), (c = document.getElementById(`${G}-${z[r]}`)) == null || c.focus());
|
|
288
|
+
},
|
|
289
|
+
children: e
|
|
290
|
+
},
|
|
291
|
+
e
|
|
292
|
+
)) }),
|
|
293
|
+
/* @__PURE__ */ s("div", { className: "structure-filters", children: [
|
|
294
|
+
/* @__PURE__ */ n(
|
|
295
|
+
"input",
|
|
296
|
+
{
|
|
297
|
+
type: "search",
|
|
298
|
+
"aria-label": "Search structure",
|
|
299
|
+
placeholder: `Search ${d.toLowerCase()}…`,
|
|
300
|
+
value: g,
|
|
301
|
+
onChange: (e) => ee(e.target.value)
|
|
302
|
+
}
|
|
303
|
+
),
|
|
304
|
+
/* @__PURE__ */ s("select", { "aria-label": "Structure floor", value: p, onChange: (e) => te(e.target.value), children: [
|
|
305
|
+
/* @__PURE__ */ n("option", { value: "all", children: "All floors" }),
|
|
306
|
+
/* @__PURE__ */ n("option", { value: "outdoors", children: "Outdoor site" }),
|
|
307
|
+
i.floors.map((e) => /* @__PURE__ */ n("option", { value: e.id, children: [e.code, e.name].filter(Boolean).join(" · ") }, e.id))
|
|
308
|
+
] })
|
|
309
|
+
] }),
|
|
310
|
+
/* @__PURE__ */ s("div", { className: "structure-summary", children: [
|
|
311
|
+
/* @__PURE__ */ n("span", { children: L(o.spaces.length, "space") }),
|
|
312
|
+
/* @__PURE__ */ n("span", { children: L(((V = i.zones) == null ? void 0 : V.length) ?? 0, "zone") }),
|
|
313
|
+
/* @__PURE__ */ n("span", { children: L(o.portals.length, "portal") })
|
|
314
|
+
] }),
|
|
315
|
+
/* @__PURE__ */ n("div", { role: "tabpanel", id: `${G}-panel`, "aria-labelledby": `${G}-${d}`, className: "structure-tab-content", children: d === "Zones" ? S({ query: g, floor: p }) : /* @__PURE__ */ s("div", { className: "inspector-scroll structure-scroll", children: [
|
|
316
|
+
d === "Spaces" && /* @__PURE__ */ s(N, { children: [
|
|
317
|
+
/* @__PURE__ */ n("p", { className: "structure-note", children: "Buildings → floors → spaces, including spaces outside any zone." }),
|
|
318
|
+
i.buildings.map((e) => /* @__PURE__ */ s("section", { className: "structure-group", children: [
|
|
319
|
+
/* @__PURE__ */ n("h3", { children: e.name }),
|
|
320
|
+
/* @__PURE__ */ n(
|
|
321
|
+
"button",
|
|
322
|
+
{
|
|
323
|
+
title: "Find on map",
|
|
324
|
+
className: "structure-locate structure-floor-find",
|
|
325
|
+
"aria-label": `Find ${e.name} on map`,
|
|
326
|
+
onClick: () => f(
|
|
327
|
+
o.spaces.filter(
|
|
328
|
+
(t) => i.floors.some((l) => l.id === t.floorId && l.buildingId === e.id)
|
|
329
|
+
).map((t) => t.id)
|
|
330
|
+
),
|
|
331
|
+
children: /* @__PURE__ */ n(M, { size: 13 })
|
|
332
|
+
}
|
|
333
|
+
),
|
|
334
|
+
i.floors.filter((t) => t.buildingId === e.id).sort((t, l) => l.elevation - t.elevation).map((t) => q(t.id, [t.code, t.name].filter(Boolean).join(" · ")))
|
|
335
|
+
] }, e.id)),
|
|
336
|
+
i.floors.filter((e) => !i.buildings.some((t) => t.id === e.buildingId)).map((e) => q(e.id, [e.code, e.name].filter(Boolean).join(" · "))),
|
|
337
|
+
q(null, "Outdoor site"),
|
|
338
|
+
!Q.length && /* @__PURE__ */ n("p", { className: "structure-empty", children: "No spaces match these filters." })
|
|
339
|
+
] }),
|
|
340
|
+
d === "Portals" && /* @__PURE__ */ s(N, { children: [
|
|
341
|
+
!!((W = i.portalGroups) != null && W.length) && /* @__PURE__ */ n("div", { className: "structure-group-filter", children: /* @__PURE__ */ n(
|
|
342
|
+
"button",
|
|
343
|
+
{
|
|
344
|
+
className: "text-button",
|
|
345
|
+
"aria-expanded": C,
|
|
346
|
+
onClick: () => {
|
|
347
|
+
ne(!C), C && H("all");
|
|
348
|
+
},
|
|
349
|
+
children: C ? "Remove portal group filter" : "Filter by portal group"
|
|
350
|
+
}
|
|
351
|
+
) }),
|
|
352
|
+
C && /* @__PURE__ */ s("label", { className: "structure-group-filter", children: [
|
|
353
|
+
"Portal group",
|
|
354
|
+
/* @__PURE__ */ s(
|
|
355
|
+
"select",
|
|
356
|
+
{
|
|
357
|
+
"aria-label": "Portal group",
|
|
358
|
+
value: B,
|
|
359
|
+
onChange: (e) => H(e.target.value),
|
|
360
|
+
children: [
|
|
361
|
+
/* @__PURE__ */ n("option", { value: "all", children: "All portals" }),
|
|
362
|
+
(X = i.portalGroups) == null ? void 0 : X.map((e) => /* @__PURE__ */ s("option", { value: e.id, children: [
|
|
363
|
+
e.name,
|
|
364
|
+
" · ",
|
|
365
|
+
e.portalIds.length
|
|
366
|
+
] }, e.id))
|
|
367
|
+
]
|
|
368
|
+
}
|
|
369
|
+
)
|
|
370
|
+
] }),
|
|
371
|
+
T && /* @__PURE__ */ n("div", { className: "structure-group-filter", children: /* @__PURE__ */ n(
|
|
372
|
+
"button",
|
|
373
|
+
{
|
|
374
|
+
title: "Find on map",
|
|
375
|
+
className: "structure-locate",
|
|
376
|
+
"aria-label": `Find ${T.name} on map`,
|
|
377
|
+
onClick: () => f(
|
|
378
|
+
o.portals.filter((e) => T.portalIds.includes(e.id)).flatMap((e) => [e.a, e.b])
|
|
379
|
+
),
|
|
380
|
+
children: /* @__PURE__ */ n(M, { size: 13 })
|
|
381
|
+
}
|
|
382
|
+
) }),
|
|
383
|
+
/* @__PURE__ */ s("p", { className: "structure-note", children: [
|
|
384
|
+
L(Z.length, "portal"),
|
|
385
|
+
" shown · arrows follow the two listed spaces."
|
|
386
|
+
] }),
|
|
387
|
+
/* @__PURE__ */ n(O, { items: Z, render: K }, `${g}:${p}:${B}`),
|
|
388
|
+
!Z.length && /* @__PURE__ */ n("p", { className: "structure-empty", children: "No portals match these filters." })
|
|
389
|
+
] }),
|
|
390
|
+
d === "Topology" && u && /* @__PURE__ */ s(N, { children: [
|
|
391
|
+
I && /* @__PURE__ */ n("div", { className: "structure-group-filter", children: /* @__PURE__ */ n(
|
|
392
|
+
"button",
|
|
393
|
+
{
|
|
394
|
+
className: "button secondary small",
|
|
395
|
+
onClick: () => I(p === "all" ? void 0 : p === "outdoors" ? null : p),
|
|
396
|
+
children: "Open graph view"
|
|
397
|
+
}
|
|
398
|
+
) }),
|
|
399
|
+
/* @__PURE__ */ s("p", { className: "structure-note", children: [
|
|
400
|
+
i.navNodes !== void 0 || i.navEdges !== void 0 ? "Authored graph overrides" : "Derived from spaces, portals and transport zones",
|
|
401
|
+
" ",
|
|
402
|
+
"· ",
|
|
403
|
+
L(u.nodes.length, "node"),
|
|
404
|
+
" · ",
|
|
405
|
+
L(u.edges.length, "edge")
|
|
406
|
+
] }),
|
|
407
|
+
/* @__PURE__ */ s("label", { className: "structure-group-filter", children: [
|
|
408
|
+
/* @__PURE__ */ n(
|
|
409
|
+
"input",
|
|
410
|
+
{
|
|
411
|
+
type: "checkbox",
|
|
412
|
+
checked: R,
|
|
413
|
+
onChange: (e) => se(e.target.checked)
|
|
414
|
+
}
|
|
415
|
+
),
|
|
416
|
+
"Only isolated nodes (",
|
|
417
|
+
u.nodes.filter((e) => {
|
|
418
|
+
var t;
|
|
419
|
+
return !((t = u.adjacency.get(e.id)) != null && t.length);
|
|
420
|
+
}).length,
|
|
421
|
+
")"
|
|
422
|
+
] }),
|
|
423
|
+
/* @__PURE__ */ n(
|
|
424
|
+
O,
|
|
425
|
+
{
|
|
426
|
+
items: J,
|
|
427
|
+
render: (e) => {
|
|
428
|
+
var t;
|
|
429
|
+
return /* @__PURE__ */ n(
|
|
430
|
+
A,
|
|
431
|
+
{
|
|
432
|
+
className: "structure-record",
|
|
433
|
+
onLocate: () => f(e.objectId ? [e.objectId] : [], e.floorId, e.position),
|
|
434
|
+
locateLabel: `Find ${e.objectId ? j(e.objectId) : e.id} on map`,
|
|
435
|
+
title: /* @__PURE__ */ s(N, { children: [
|
|
436
|
+
/* @__PURE__ */ n("span", { children: e.objectId ? j(e.objectId) : e.id }),
|
|
437
|
+
/* @__PURE__ */ s("small", { children: [
|
|
438
|
+
((t = u.adjacency.get(e.id)) == null ? void 0 : t.length) ?? 0,
|
|
439
|
+
" edges"
|
|
440
|
+
] })
|
|
441
|
+
] }),
|
|
442
|
+
children: () => {
|
|
443
|
+
var l;
|
|
444
|
+
return /* @__PURE__ */ s("div", { className: "structure-record-body", children: [
|
|
445
|
+
/* @__PURE__ */ s("p", { children: [
|
|
446
|
+
x(e.floorId),
|
|
447
|
+
" · ",
|
|
448
|
+
e.position.map((r) => r.toFixed(2)).join(", "),
|
|
449
|
+
" m"
|
|
450
|
+
] }),
|
|
451
|
+
/* @__PURE__ */ n(
|
|
452
|
+
O,
|
|
453
|
+
{
|
|
454
|
+
items: u.adjacency.get(e.id) ?? [],
|
|
455
|
+
render: (r) => {
|
|
456
|
+
const c = u.byId.get(r.aId === e.id ? r.bId : r.aId);
|
|
457
|
+
return /* @__PURE__ */ s("div", { className: "structure-edge", children: [
|
|
458
|
+
/* @__PURE__ */ n("div", { className: "structure-edge-target", children: c != null && c.objectId ? F(c.objectId) : /* @__PURE__ */ n("span", { title: c == null ? void 0 : c.id, children: (c == null ? void 0 : c.id) ?? "Missing node" }) }),
|
|
459
|
+
/* @__PURE__ */ s("div", { className: "structure-edge-meta", children: [
|
|
460
|
+
/* @__PURE__ */ s("span", { children: [
|
|
461
|
+
r.directed ? r.aId === e.id ? "→ outgoing" : "← incoming" : "↔ both ways",
|
|
462
|
+
" ",
|
|
463
|
+
"· ",
|
|
464
|
+
r.kind
|
|
465
|
+
] }),
|
|
466
|
+
r.objectId && /* @__PURE__ */ s("span", { className: "structure-fact", children: [
|
|
467
|
+
"Via ",
|
|
468
|
+
F(r.objectId)
|
|
469
|
+
] })
|
|
470
|
+
] }),
|
|
471
|
+
/* @__PURE__ */ n(
|
|
472
|
+
"button",
|
|
473
|
+
{
|
|
474
|
+
title: "Find on map",
|
|
475
|
+
className: "structure-locate structure-edge-locate",
|
|
476
|
+
"aria-label": `Find connection ${r.id} on map`,
|
|
477
|
+
onClick: () => f(
|
|
478
|
+
[e.objectId, c == null ? void 0 : c.objectId, r.objectId].filter(
|
|
479
|
+
(y) => !!y
|
|
480
|
+
),
|
|
481
|
+
e.floorId,
|
|
482
|
+
e.position
|
|
483
|
+
),
|
|
484
|
+
children: /* @__PURE__ */ n(M, { size: 13 })
|
|
485
|
+
}
|
|
486
|
+
)
|
|
487
|
+
] }, r.id);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
),
|
|
491
|
+
!((l = u.adjacency.get(e.id)) != null && l.length) && /* @__PURE__ */ n("p", { children: "No route connections." }),
|
|
492
|
+
/* @__PURE__ */ n("code", { title: e.id, children: e.id })
|
|
493
|
+
] });
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
e.id
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
`${g}:${p}:${R}`
|
|
501
|
+
),
|
|
502
|
+
!J.length && /* @__PURE__ */ n("p", { className: "structure-empty", children: "No nodes match these filters." })
|
|
503
|
+
] })
|
|
504
|
+
] }) })
|
|
505
|
+
] });
|
|
506
|
+
}
|
|
507
|
+
export {
|
|
508
|
+
ye as StructureExplorer
|
|
509
|
+
};
|
|
510
|
+
//# sourceMappingURL=StructureExplorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StructureExplorer.js","sources":["../../../../src/components/StructureExplorer.tsx"],"sourcesContent":["import { useEffect, useId, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { LocateFixed } from 'lucide-react';\nimport { isSpace, type Portal, type SiteObject } from '../model/types';\nimport { zoneSpaces } from '../model/ontology';\nimport { navEdges, navNodes } from '../model/navigation';\nimport { effectivePortals } from '../model/portals';\nimport type { StructureViewProps } from './StructureView';\n\nconst TABS = ['Spaces', 'Zones', 'Portals', 'Topology'] as const;\ntype Tab = (typeof TABS)[number];\nconst countLabel = (count: number, noun: string) => `${count} ${noun}${count === 1 ? '' : 's'}`;\nconst connectionLabel = (direction?: string) =>\n direction === 'none' ? 'Sealed' : direction === 'a-to-b' ? '→' : direction === 'b-to-a' ? '←' : '↔';\n\nfunction Expandable({\n title,\n children,\n className,\n initialOpen = false,\n onLocate,\n locateLabel,\n}: {\n title: ReactNode;\n children: () => ReactNode;\n className: string;\n initialOpen?: boolean;\n onLocate?: () => void;\n locateLabel?: string;\n}) {\n const [open, setOpen] = useState(initialOpen);\n return (\n <details className={className} open={open} onToggle={event => setOpen(event.currentTarget.open)}>\n <summary>\n <span className=\"structure-row-title\">{title}</span>\n {onLocate && (\n <button\n className=\"structure-locate\"\n aria-label={locateLabel}\n title=\"Find on map\"\n onClick={event => {\n event.preventDefault();\n event.stopPropagation();\n onLocate();\n }}\n >\n <LocateFixed size={13} />\n </button>\n )}\n </summary>\n {open && children()}\n </details>\n );\n}\n\n/** Bound the DOM even for the thousands of inferred portals in the sample buildings. */\nfunction Rows<T>({ items, render }: { items: T[]; render: (item: T) => ReactNode }) {\n const [limit, setLimit] = useState(50);\n const sentinel = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const element = sentinel.current;\n if (!element || limit >= items.length) return;\n const observer = new IntersectionObserver(\n entries => {\n if (entries.some(entry => entry.isIntersecting)) setLimit(current => Math.min(items.length, current + 50));\n },\n { root: element.closest('.inspector-scroll'), rootMargin: '160px' },\n );\n observer.observe(element);\n return () => observer.disconnect();\n }, [limit, items.length]);\n return (\n <>\n {items.slice(0, limit).map(render)}\n {limit < items.length && (\n <div className=\"structure-load-more\" ref={sentinel}>\n {limit} of {items.length} · scroll for more\n </div>\n )}\n </>\n );\n}\n\nexport function StructureExplorer({\n project,\n selected,\n onSelect,\n onFloorChange,\n onLocate,\n onGraphView,\n renderZones,\n}: StructureViewProps & {\n renderZones: (filter: { query: string; floor: string }) => ReactNode;\n}) {\n const [tab, setTab] = useState<Tab>('Spaces');\n const [query, setQuery] = useState('');\n const [floor, setFloor] = useState('all');\n const [portalGroup, setPortalGroup] = useState('all');\n const [groupFilterOpen, setGroupFilterOpen] = useState(false);\n const [onlyIsolated, setOnlyIsolated] = useState(false);\n const id = useId();\n const index = useMemo(() => {\n const objects = new Map(project.objects.map(o => [o.id, o]));\n const spaces = project.objects.filter(o => isSpace(o.kind));\n const portals = effectivePortals(project);\n const bySpace = new Map<string, Portal[]>();\n for (const portal of portals)\n for (const id of new Set([portal.a, portal.b])) {\n const rows = bySpace.get(id) ?? [];\n rows.push(portal);\n bySpace.set(id, rows);\n }\n const memberships = new Map<string, string[]>();\n for (const zone of project.zones ?? [])\n for (const id of zoneSpaces(project, zone)) {\n const names = memberships.get(id) ?? [];\n names.push(zone.name);\n memberships.set(id, names);\n }\n const children = new Map<string, SiteObject[]>();\n for (const object of project.objects)\n if (object.parentId) {\n const rows = children.get(object.parentId) ?? [];\n rows.push(object);\n children.set(object.parentId, rows);\n }\n return { objects, spaces, portals, bySpace, memberships, children };\n }, [project]);\n // Use the exact graph accessors that routing uses, and only build it when requested.\n const graph = useMemo(() => {\n if (tab !== 'Topology') return null;\n const nodes = navNodes(project),\n edges = navEdges(project);\n const byId = new Map(nodes.map(n => [n.id, n]));\n const adjacency = new Map(nodes.map(n => [n.id, [] as typeof edges]));\n for (const edge of edges) {\n adjacency.get(edge.aId)?.push(edge);\n adjacency.get(edge.bId)?.push(edge);\n }\n return { nodes, edges, byId, adjacency };\n }, [project, tab]);\n const floorName = (floorId: string | null) =>\n floorId === null ? 'Outdoor site' : (project.floors.find(f => f.id === floorId)?.name ?? floorId);\n const objectName = (objectId: string) => index.objects.get(objectId)?.name || objectId;\n const matches = (...values: (string | undefined)[]) =>\n !query.trim() || values.some(value => value?.toLowerCase().includes(query.trim().toLowerCase()));\n const matchesFloor = (floorId: string | null) => floor === 'all' || floor === (floorId ?? 'outdoors');\n const pick = (object: SiteObject, floorId = object.floorId) => {\n onSelect?.(object.id);\n onFloorChange?.(floorId);\n };\n const locate = (objectIds: string[], floorId?: string | null, position?: [number, number]) => {\n if (onLocate) onLocate({ objectIds, floorId, position });\n else {\n const object = index.objects.get(objectIds[0]);\n if (object) pick(object, floorId === undefined ? object.floorId : floorId);\n else if (floorId !== undefined) onFloorChange?.(floorId);\n }\n };\n const objectLink = (objectId: string) => {\n const object = index.objects.get(objectId);\n return object ? (\n <span className=\"structure-object-link\">\n <span title={object.name || object.id}>{object.name || object.id}</span>\n <button\n type=\"button\"\n className=\"structure-locate\"\n aria-label={`Find ${object.name || object.id} on map`}\n title=\"Find on map\"\n onClick={() => locate([object.id])}\n >\n <LocateFixed size={13} />\n </button>\n </span>\n ) : (\n <span>{objectId}</span>\n );\n };\n const portalRow = (portal: Portal) => (\n <Expandable\n className=\"structure-record\"\n key={portal.id}\n onLocate={() => locate([...(portal.openingId ? [portal.openingId] : []), portal.a, portal.b])}\n locateLabel={`Find ${portal.name || 'portal'} on map`}\n title={\n <>\n <span>{portal.name || (portal.openingId ? objectName(portal.openingId) : 'Open boundary')}</span>\n <small>{connectionLabel(portal.passage)}</small>\n </>\n }\n >\n {() => (\n <div className=\"structure-record-body\">\n <div className=\"structure-connection\">\n {objectLink(portal.a)}\n <span>{connectionLabel(portal.passage)}</span>\n {objectLink(portal.b)}\n </div>\n <p>\n {[...new Set([portal.a, portal.b].map(id => floorName(index.objects.get(id)?.floorId ?? null)))].join(\n ' · ',\n )}\n </p>\n <div className=\"structure-facts\">\n <span>Crossing evidence: {portal.attests ?? 'assumed'}</span>\n {portal.openingId && <span className=\"structure-fact\">Opening: {objectLink(portal.openingId)}</span>}\n </div>\n {(project.portalGroups ?? [])\n .filter(group => group.portalIds.includes(portal.id))\n .map(group => (\n <p key={group.id}>Group: {group.name}</p>\n ))}\n <code title={portal.id}>{portal.id}</code>\n </div>\n )}\n </Expandable>\n );\n const spaceRow = (space: SiteObject) => (\n <Expandable\n className={`structure-record ${space.id === selected ? 'selected' : ''}`}\n key={space.id}\n onLocate={() => locate([space.id])}\n locateLabel={`Find ${space.name} on map`}\n title={\n <>\n <span>{space.name || space.id}</span>\n <small>\n {space.kind} · {(index.bySpace.get(space.id) ?? []).length} portals\n </small>\n </>\n }\n >\n {() => (\n <div className=\"structure-record-body\">\n {space.parentId && <p className=\"structure-fact\">Inside: {objectLink(space.parentId)}</p>}\n <p>Zones: {index.memberships.get(space.id)?.join(', ') || 'Not grouped into a zone'}</p>\n {!!space.servedFloorIds?.length && (\n <div>\n <h4>Served floors</h4>\n {space.servedFloorIds.map(id => (\n <div className=\"structure-object-link structure-item\" key={id}>\n <span>{floorName(id)}</span>\n <button\n className=\"structure-locate\"\n title=\"Find on map\"\n aria-label={`Find ${space.name} on ${floorName(id)}`}\n onClick={() => locate([space.id], id)}\n >\n <LocateFixed size={13} />\n </button>\n </div>\n ))}\n </div>\n )}\n {!!index.children.get(space.id)?.length && (\n <div>\n <h4>Contained objects</h4>\n <Rows\n items={index.children.get(space.id)!}\n render={object => (\n <div className=\"structure-item\" key={object.id}>\n {objectLink(object.id)} <small>{object.kind}</small>\n </div>\n )}\n />\n </div>\n )}\n <h4>Connections</h4>\n <Rows items={index.bySpace.get(space.id) ?? []} render={portalRow} />\n {!index.bySpace.has(space.id) && (\n <p>No direct portals. Transport connectivity may be supplied by its zone.</p>\n )}\n <code title={space.id}>{space.id}</code>\n </div>\n )}\n </Expandable>\n );\n const visibleSpaces = index.spaces.filter(\n space => matchesFloor(space.floorId) && matches(space.name, space.id, space.kind, floorName(space.floorId)),\n );\n const group = project.portalGroups?.find(group => group.id === portalGroup);\n const visiblePortals = index.portals.filter(\n portal =>\n (!group || group.portalIds.includes(portal.id)) &&\n (matchesFloor(index.objects.get(portal.a)?.floorId ?? null) ||\n matchesFloor(index.objects.get(portal.b)?.floorId ?? null)) &&\n matches(\n portal.name,\n portal.id,\n objectName(portal.a),\n objectName(portal.b),\n portal.openingId ? objectName(portal.openingId) : 'Open boundary',\n ),\n );\n const visibleNodes =\n graph?.nodes.filter(\n node =>\n matchesFloor(node.floorId) &&\n matches(node.id, node.objectId ? objectName(node.objectId) : '', floorName(node.floorId)) &&\n (!onlyIsolated || !graph.adjacency.get(node.id)?.length),\n ) ?? [];\n const floorGroup = (floorId: string | null, label: string) => {\n if (!matchesFloor(floorId)) return null;\n const rows = visibleSpaces.filter(space => space.floorId === floorId);\n if (query.trim() && !rows.length) return null;\n return (\n <Expandable\n className=\"structure-floor\"\n key={`${floorId}:${query}`}\n onLocate={() =>\n locate(\n rows.map(space => space.id),\n floorId,\n )\n }\n locateLabel={`Find ${label} on map`}\n initialOpen={!!query.trim() || floor !== 'all'}\n title={\n <>\n <span>{label}</span>\n <small>{countLabel(rows.length, 'space')}</small>\n </>\n }\n >\n {() => (\n <>\n {rows.length ? (\n <Rows key={`${query}:${floor}`} items={rows} render={spaceRow} />\n ) : (\n <p className=\"structure-note\">No spaces on this level.</p>\n )}\n </>\n )}\n </Expandable>\n );\n };\n return (\n <div className=\"structure-panel\">\n <div className=\"structure-heading\">\n <strong>Structure</strong>\n <small>{project.name}</small>\n </div>\n <div className=\"structure-tabs\" role=\"tablist\" aria-label=\"Structure views\">\n {TABS.map((name, i) => (\n <button\n key={name}\n role=\"tab\"\n id={`${id}-${name}`}\n aria-controls={`${id}-panel`}\n aria-selected={tab === name}\n tabIndex={tab === name ? 0 : -1}\n onClick={() => setTab(name)}\n onKeyDown={event => {\n const next =\n event.key === 'ArrowRight'\n ? (i + 1) % TABS.length\n : event.key === 'ArrowLeft'\n ? (i + TABS.length - 1) % TABS.length\n : event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? TABS.length - 1\n : -1;\n if (next >= 0) {\n event.preventDefault();\n setTab(TABS[next]);\n document.getElementById(`${id}-${TABS[next]}`)?.focus();\n }\n }}\n >\n {name}\n </button>\n ))}\n </div>\n <div className=\"structure-filters\">\n <input\n type=\"search\"\n aria-label=\"Search structure\"\n placeholder={`Search ${tab.toLowerCase()}…`}\n value={query}\n onChange={event => setQuery(event.target.value)}\n />\n <select aria-label=\"Structure floor\" value={floor} onChange={event => setFloor(event.target.value)}>\n <option value=\"all\">All floors</option>\n <option value=\"outdoors\">Outdoor site</option>\n {project.floors.map(f => (\n <option key={f.id} value={f.id}>\n {[f.code, f.name].filter(Boolean).join(' · ')}\n </option>\n ))}\n </select>\n </div>\n <div className=\"structure-summary\">\n <span>{countLabel(index.spaces.length, 'space')}</span>\n <span>{countLabel(project.zones?.length ?? 0, 'zone')}</span>\n <span>{countLabel(index.portals.length, 'portal')}</span>\n </div>\n <div role=\"tabpanel\" id={`${id}-panel`} aria-labelledby={`${id}-${tab}`} className=\"structure-tab-content\">\n {tab === 'Zones' ? (\n renderZones({ query, floor })\n ) : (\n <div className=\"inspector-scroll structure-scroll\">\n {tab === 'Spaces' && (\n <>\n <p className=\"structure-note\">Buildings → floors → spaces, including spaces outside any zone.</p>\n {project.buildings.map(building => (\n <section className=\"structure-group\" key={building.id}>\n <h3>{building.name}</h3>\n <button\n title=\"Find on map\"\n className=\"structure-locate structure-floor-find\"\n aria-label={`Find ${building.name} on map`}\n onClick={() =>\n locate(\n index.spaces\n .filter(space =>\n project.floors.some(f => f.id === space.floorId && f.buildingId === building.id),\n )\n .map(space => space.id),\n )\n }\n >\n <LocateFixed size={13} />\n </button>\n {project.floors\n .filter(f => f.buildingId === building.id)\n .sort((a, b) => b.elevation - a.elevation)\n .map(f => floorGroup(f.id, [f.code, f.name].filter(Boolean).join(' · ')))}\n </section>\n ))}\n {project.floors\n .filter(f => !project.buildings.some(b => b.id === f.buildingId))\n .map(f => floorGroup(f.id, [f.code, f.name].filter(Boolean).join(' · ')))}\n {floorGroup(null, 'Outdoor site')}\n {!visibleSpaces.length && <p className=\"structure-empty\">No spaces match these filters.</p>}\n </>\n )}\n {tab === 'Portals' && (\n <>\n {!!project.portalGroups?.length && (\n <div className=\"structure-group-filter\">\n <button\n className=\"text-button\"\n aria-expanded={groupFilterOpen}\n onClick={() => {\n setGroupFilterOpen(!groupFilterOpen);\n if (groupFilterOpen) setPortalGroup('all');\n }}\n >\n {groupFilterOpen ? 'Remove portal group filter' : 'Filter by portal group'}\n </button>\n </div>\n )}\n {groupFilterOpen && (\n <label className=\"structure-group-filter\">\n Portal group\n <select\n aria-label=\"Portal group\"\n value={portalGroup}\n onChange={event => setPortalGroup(event.target.value)}\n >\n <option value=\"all\">All portals</option>\n {project.portalGroups?.map(group => (\n <option key={group.id} value={group.id}>\n {group.name} · {group.portalIds.length}\n </option>\n ))}\n </select>\n </label>\n )}\n {group && (\n <div className=\"structure-group-filter\">\n <button\n title=\"Find on map\"\n className=\"structure-locate\"\n aria-label={`Find ${group.name} on map`}\n onClick={() =>\n locate(\n index.portals\n .filter(portal => group.portalIds.includes(portal.id))\n .flatMap(portal => [portal.a, portal.b]),\n )\n }\n >\n <LocateFixed size={13} />\n </button>\n </div>\n )}\n <p className=\"structure-note\">\n {countLabel(visiblePortals.length, 'portal')} shown · arrows follow the two listed spaces.\n </p>\n <Rows key={`${query}:${floor}:${portalGroup}`} items={visiblePortals} render={portalRow} />\n {!visiblePortals.length && <p className=\"structure-empty\">No portals match these filters.</p>}\n </>\n )}\n {tab === 'Topology' && graph && (\n <>\n {onGraphView && (\n <div className=\"structure-group-filter\">\n <button\n className=\"button secondary small\"\n onClick={() => onGraphView(floor === 'all' ? undefined : floor === 'outdoors' ? null : floor)}\n >\n Open graph view\n </button>\n </div>\n )}\n <p className=\"structure-note\">\n {project.navNodes !== undefined || project.navEdges !== undefined\n ? 'Authored graph overrides'\n : 'Derived from spaces, portals and transport zones'}{' '}\n · {countLabel(graph.nodes.length, 'node')} · {countLabel(graph.edges.length, 'edge')}\n </p>\n <label className=\"structure-group-filter\">\n <input\n type=\"checkbox\"\n checked={onlyIsolated}\n onChange={event => setOnlyIsolated(event.target.checked)}\n />\n Only isolated nodes ({graph.nodes.filter(n => !graph.adjacency.get(n.id)?.length).length})\n </label>\n <Rows\n key={`${query}:${floor}:${onlyIsolated}`}\n items={visibleNodes}\n render={node => (\n <Expandable\n className=\"structure-record\"\n key={node.id}\n onLocate={() => locate(node.objectId ? [node.objectId] : [], node.floorId, node.position)}\n locateLabel={`Find ${node.objectId ? objectName(node.objectId) : node.id} on map`}\n title={\n <>\n <span>{node.objectId ? objectName(node.objectId) : node.id}</span>\n <small>{graph.adjacency.get(node.id)?.length ?? 0} edges</small>\n </>\n }\n >\n {() => (\n <div className=\"structure-record-body\">\n <p>\n {floorName(node.floorId)} · {node.position.map(n => n.toFixed(2)).join(', ')} m\n </p>\n\n <Rows\n items={graph.adjacency.get(node.id) ?? []}\n render={edge => {\n const other = graph.byId.get(edge.aId === node.id ? edge.bId : edge.aId);\n return (\n <div className=\"structure-edge\" key={edge.id}>\n <div className=\"structure-edge-target\">\n {other?.objectId ? (\n objectLink(other.objectId)\n ) : (\n <span title={other?.id}>{other?.id ?? 'Missing node'}</span>\n )}\n </div>\n <div className=\"structure-edge-meta\">\n <span>\n {edge.directed\n ? edge.aId === node.id\n ? '→ outgoing'\n : '← incoming'\n : '↔ both ways'}{' '}\n · {edge.kind}\n </span>\n {edge.objectId && (\n <span className=\"structure-fact\">Via {objectLink(edge.objectId)}</span>\n )}\n </div>\n <button\n title=\"Find on map\"\n className=\"structure-locate structure-edge-locate\"\n aria-label={`Find connection ${edge.id} on map`}\n onClick={() =>\n locate(\n [node.objectId, other?.objectId, edge.objectId].filter(\n (id): id is string => !!id,\n ),\n node.floorId,\n node.position,\n )\n }\n >\n <LocateFixed size={13} />\n </button>\n </div>\n );\n }}\n />\n {!graph.adjacency.get(node.id)?.length && <p>No route connections.</p>}\n <code title={node.id}>{node.id}</code>\n </div>\n )}\n </Expandable>\n )}\n />\n {!visibleNodes.length && <p className=\"structure-empty\">No nodes match these filters.</p>}\n </>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"names":["TABS","countLabel","count","noun","connectionLabel","direction","Expandable","title","children","className","initialOpen","onLocate","locateLabel","open","setOpen","useState","jsxs","event","jsx","LocateFixed","Rows","items","render","limit","setLimit","sentinel","useRef","useEffect","element","observer","entries","entry","current","Fragment","StructureExplorer","project","selected","onSelect","onFloorChange","onGraphView","renderZones","tab","setTab","query","setQuery","floor","setFloor","portalGroup","setPortalGroup","groupFilterOpen","setGroupFilterOpen","onlyIsolated","setOnlyIsolated","id","useId","index","useMemo","objects","o","spaces","isSpace","portals","effectivePortals","bySpace","portal","rows","memberships","zone","zoneSpaces","names","object","graph","nodes","navNodes","edges","navEdges","byId","n","adjacency","edge","_a","_b","floorName","floorId","f","objectName","objectId","matches","values","value","matchesFloor","pick","locate","objectIds","position","objectLink","portalRow","group","spaceRow","space","_c","visibleSpaces","visiblePortals","visibleNodes","node","floorGroup","label","name","i","next","building","a","b","_d","other"],"mappings":"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"}
|