@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,178 @@
|
|
|
1
|
+
import type { Barrier, Building, Floor, NavEdge, NavNode, ObjectKind, Origin, Point, Portal, PortalGroup, ProjectDocument, Ring, SiteObject, Zone } from './types';
|
|
2
|
+
import { type GeometryDrag } from './authoring';
|
|
3
|
+
import { type TransactResult } from './validate';
|
|
4
|
+
/** Every mutation the schema can execute, as data. `kind` names the operation; the rest are its
|
|
5
|
+
* arguments, exactly as the underlying authoring function takes them. */
|
|
6
|
+
export type Mutation = {
|
|
7
|
+
kind: 'addBuilding';
|
|
8
|
+
building: Building;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'patchBuilding';
|
|
11
|
+
buildingId: string;
|
|
12
|
+
set: Partial<Omit<Building, 'id'>>;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'addFloor';
|
|
15
|
+
floor: Floor;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'patchFloor';
|
|
18
|
+
floorId: string;
|
|
19
|
+
set: Partial<Omit<Floor, 'id' | 'buildingId'>>;
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'removeFloor';
|
|
22
|
+
floorId: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'duplicateFloor';
|
|
25
|
+
floorId: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'patchProject';
|
|
28
|
+
set: Partial<Pick<ProjectDocument, 'name' | 'description' | 'datum' | 'initialFloorId'>>;
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'patchBarrier';
|
|
31
|
+
barrierId: string;
|
|
32
|
+
set: Partial<Omit<Barrier, 'id' | 'startId' | 'endId' | 'floorId'>>;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'removeBarrier';
|
|
35
|
+
barrierId: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'moveGeometry';
|
|
38
|
+
move: GeometryDrag;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'drawBoundary';
|
|
41
|
+
a: Point;
|
|
42
|
+
b: Point;
|
|
43
|
+
floorId: string | null;
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'drawBarrier';
|
|
46
|
+
a: Point;
|
|
47
|
+
b: Point;
|
|
48
|
+
floorId: string | null;
|
|
49
|
+
barrierKind?: 'wall' | 'fence';
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'encloseRoom';
|
|
52
|
+
floorId: string | null;
|
|
53
|
+
point: Point;
|
|
54
|
+
name?: string;
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'addHole';
|
|
57
|
+
objectId: string;
|
|
58
|
+
ring: Ring;
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'patchZone';
|
|
61
|
+
zoneId: string;
|
|
62
|
+
set: Partial<Pick<Zone, 'name' | 'purpose' | 'connects' | 'metadata'>>;
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'addPortal';
|
|
65
|
+
portal: Omit<Portal, 'id'>;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'removePortal';
|
|
68
|
+
portalId: string;
|
|
69
|
+
} | {
|
|
70
|
+
kind: 'setNavigation';
|
|
71
|
+
nodes: NavNode[];
|
|
72
|
+
edges: NavEdge[];
|
|
73
|
+
} | {
|
|
74
|
+
kind: 'addZone';
|
|
75
|
+
name: string;
|
|
76
|
+
spaceIds: string[];
|
|
77
|
+
purpose?: string;
|
|
78
|
+
} | {
|
|
79
|
+
kind: 'removeZone';
|
|
80
|
+
zoneId: string;
|
|
81
|
+
} | {
|
|
82
|
+
kind: 'setZoneMembers';
|
|
83
|
+
zoneId: string;
|
|
84
|
+
spaceIds: string[];
|
|
85
|
+
member: boolean;
|
|
86
|
+
} | {
|
|
87
|
+
kind: 'nestZone';
|
|
88
|
+
parentId: string;
|
|
89
|
+
childId: string;
|
|
90
|
+
} | {
|
|
91
|
+
kind: 'addPortalGroup';
|
|
92
|
+
name: string;
|
|
93
|
+
portalIds: string[];
|
|
94
|
+
} | {
|
|
95
|
+
kind: 'removePortalGroup';
|
|
96
|
+
groupId: string;
|
|
97
|
+
} | {
|
|
98
|
+
kind: 'setPortalGroupMembers';
|
|
99
|
+
groupId: string;
|
|
100
|
+
portalIds: string[];
|
|
101
|
+
member: boolean;
|
|
102
|
+
} | {
|
|
103
|
+
kind: 'patchPortal';
|
|
104
|
+
portalId: string;
|
|
105
|
+
set: Partial<Omit<Portal, 'id' | 'a' | 'b' | 'openingId'>>;
|
|
106
|
+
} | {
|
|
107
|
+
kind: 'patchObject';
|
|
108
|
+
objectId: string;
|
|
109
|
+
set: Partial<Omit<SiteObject, 'id' | 'kind'>>;
|
|
110
|
+
} | {
|
|
111
|
+
kind: 'addObject';
|
|
112
|
+
objectKind: ObjectKind;
|
|
113
|
+
name: string;
|
|
114
|
+
position: Point;
|
|
115
|
+
floorId: string | null;
|
|
116
|
+
set?: Partial<Omit<SiteObject, 'id' | 'kind'>>;
|
|
117
|
+
} | {
|
|
118
|
+
kind: 'removeObjects';
|
|
119
|
+
ids: string[];
|
|
120
|
+
} | {
|
|
121
|
+
kind: 'refreshPortals';
|
|
122
|
+
} | {
|
|
123
|
+
kind: 'pruneOntology';
|
|
124
|
+
} | {
|
|
125
|
+
kind: 'addBarrier';
|
|
126
|
+
a: Point;
|
|
127
|
+
b: Point;
|
|
128
|
+
floorId: string | null;
|
|
129
|
+
barrierKind: 'wall' | 'fence';
|
|
130
|
+
} | {
|
|
131
|
+
kind: 'addBoundary';
|
|
132
|
+
a: Point;
|
|
133
|
+
b: Point;
|
|
134
|
+
floorId: string | null;
|
|
135
|
+
} | {
|
|
136
|
+
kind: 'connectSpace';
|
|
137
|
+
objectId: string;
|
|
138
|
+
source?: 'outline' | 'walls';
|
|
139
|
+
} | {
|
|
140
|
+
kind: 'disconnectSpace';
|
|
141
|
+
objectId: string;
|
|
142
|
+
} | {
|
|
143
|
+
kind: 'splitRoom';
|
|
144
|
+
roomId: string;
|
|
145
|
+
a: Point;
|
|
146
|
+
b: Point;
|
|
147
|
+
wall?: boolean;
|
|
148
|
+
} | {
|
|
149
|
+
kind: 'divideSpaces';
|
|
150
|
+
floorId: string | null;
|
|
151
|
+
a: Point;
|
|
152
|
+
b: Point;
|
|
153
|
+
} | {
|
|
154
|
+
kind: 'mergeSpaces';
|
|
155
|
+
keepId: string;
|
|
156
|
+
absorbedId: string;
|
|
157
|
+
}
|
|
158
|
+
/** Move or turn the whole site. The geometry is untouched — local metres stay what they were; only
|
|
159
|
+
* where the frame is pinned and which way it faces change. A plan carries no heading, so this is
|
|
160
|
+
* how an imported one is squared onto the street it actually stands on. */
|
|
161
|
+
| {
|
|
162
|
+
kind: 'setOrigin';
|
|
163
|
+
origin: Origin;
|
|
164
|
+
};
|
|
165
|
+
/** What a mutation reports back, beyond the new document: the entity it created, or whether it did
|
|
166
|
+
* anything at all. Read it off the result rather than hunting the document for what changed.
|
|
167
|
+
* Entity outcomes are views INTO the frozen result — read them freely, but editing one throws;
|
|
168
|
+
* the next change goes through the next transaction like every other. */
|
|
169
|
+
export type MutationOutcome = Zone | PortalGroup | string[] | string | boolean | number | undefined;
|
|
170
|
+
export type MutationResult = TransactResult & {
|
|
171
|
+
outcomes?: MutationOutcome[];
|
|
172
|
+
};
|
|
173
|
+
/** Execute one mutation atomically. Sugar over `applyMutations` with a single step. */
|
|
174
|
+
export declare const applyMutation: (project: ProjectDocument, mutation: Mutation) => MutationResult;
|
|
175
|
+
/** Execute a sequence of mutations as ONE transaction: all of them apply and the result passes
|
|
176
|
+
* every rule, or none of them do and `error` says why. `outcomes` reports what each step returned
|
|
177
|
+
* (created zones, split-off ids), in order — present only on success. */
|
|
178
|
+
export declare function applyMutations(project: ProjectDocument, mutations: Mutation[]): MutationResult;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { NavEdge, NavEdgeKind, NavNode, Point, ProjectDocument, SiteObject } from './types';
|
|
2
|
+
import type { StatusReading } from './live';
|
|
3
|
+
export declare const ELEVATOR_BASE = 25, ELEVATOR_PER_METRE = 1, STAIR_CLIMB_FACTOR = 5, DOOR_COST = 1.5;
|
|
4
|
+
/** addNavNode welds onto any existing node within this range (mirrors joinAt's junction reuse). */
|
|
5
|
+
export declare const NAV_WELD = 0.25;
|
|
6
|
+
export declare const navNodes: (p: ProjectDocument) => NavNode[];
|
|
7
|
+
export declare const navEdges: (p: ProjectDocument) => NavEdge[];
|
|
8
|
+
/** Find-or-create a route node at a point on a floor, welding onto any node within NAV_WELD. */
|
|
9
|
+
export declare function addNavNode(p: ProjectDocument, floorId: string | null, position: Point, objectId?: string): NavNode;
|
|
10
|
+
/** Connect two nodes, reusing an existing edge of the same kind between the same pair. */
|
|
11
|
+
export declare function addNavEdge(p: ProjectDocument, kind: NavEdgeKind, a: NavNode, b: NavNode, objectId?: string): NavEdge;
|
|
12
|
+
/** Draw a chain of walk edges through the given points, welding onto existing nodes en route. */
|
|
13
|
+
export declare function navPath(p: ProjectDocument, floorId: string | null, points: Point[]): NavNode[];
|
|
14
|
+
/** Thread a vertical connection through an elevator/stairs object: one node per served floor at the object's position. Stairs chain adjacent served floors (you pass every level); an elevator gets an edge per floor pair (a ride is direct, so ELEVATOR_BASE is paid once). Per-floor twin objects share a name (see the demo lifts); pass any one of them and each edge binds the twin on its upper floor. */
|
|
15
|
+
export declare function chainVertical(p: ProjectDocument, object: SiteObject): NavNode[];
|
|
16
|
+
export interface RouteLeg {
|
|
17
|
+
edge: NavEdge;
|
|
18
|
+
from: NavNode;
|
|
19
|
+
to: NavNode;
|
|
20
|
+
cost: number;
|
|
21
|
+
}
|
|
22
|
+
export interface RouteStep {
|
|
23
|
+
kind: 'depart' | 'walk' | 'door' | 'stairs' | 'elevator' | 'arrive';
|
|
24
|
+
text: string;
|
|
25
|
+
floorId: string | null;
|
|
26
|
+
nodeIds: string[];
|
|
27
|
+
objectId?: string;
|
|
28
|
+
distance?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Either end of a route: an object in the document by id, or a point on a floor — where the
|
|
31
|
+
* walker is standing, which is the start most people want and no object describes. */
|
|
32
|
+
export type RouteEnd = string | {
|
|
33
|
+
name?: string;
|
|
34
|
+
floorId: string | null;
|
|
35
|
+
position: Point;
|
|
36
|
+
};
|
|
37
|
+
/** What a route knows about its ends: enough to name them and place them, whether they came from
|
|
38
|
+
* an object or a point. */
|
|
39
|
+
export type RoutePlace = Pick<SiteObject, 'id' | 'kind' | 'name' | 'floorId' | 'position'>;
|
|
40
|
+
/** The id a host uses for "where the walker is" in a picker; findRoute() never sees it. */
|
|
41
|
+
export declare const HERE = "@here";
|
|
42
|
+
export interface Route {
|
|
43
|
+
from: RoutePlace;
|
|
44
|
+
to: RoutePlace;
|
|
45
|
+
nodes: NavNode[];
|
|
46
|
+
legs: RouteLeg[];
|
|
47
|
+
steps: RouteStep[];
|
|
48
|
+
distance: number;
|
|
49
|
+
cost: number;
|
|
50
|
+
}
|
|
51
|
+
/** Metres-equivalent cost of traversing an edge; authored weight wins over the derived cost. */
|
|
52
|
+
export declare function edgeCost(p: ProjectDocument, edge: NavEdge, a: NavNode, b: NavNode): number;
|
|
53
|
+
/** Walking metres of an edge (horizontal run, plus the rise on vertical edges) — for display, not costing. */
|
|
54
|
+
export declare function edgeLength(p: ProjectDocument, edge: NavEdge, a: NavNode, b: NavNode): number;
|
|
55
|
+
/** Candidate graph entry points for a room/door/poi: nodes bound to the object at cost 0, else nodes inside an area's outer ring, else the nearest node on the object's floor. Cost is the straight-line approach in metres. */
|
|
56
|
+
export declare function routeAnchors(p: ProjectDocument, object: SiteObject): {
|
|
57
|
+
node: NavNode;
|
|
58
|
+
cost: number;
|
|
59
|
+
}[];
|
|
60
|
+
/** Shortest route between two ends — objects (rooms, doors, POIs, …) or points on a floor — over
|
|
61
|
+
* the authored graph, with human step instructions. Returns null when either end has no anchor or
|
|
62
|
+
* no path exists. */
|
|
63
|
+
export interface RouteOptions {
|
|
64
|
+
statuses?: ReadonlyMap<string, StatusReading>;
|
|
65
|
+
}
|
|
66
|
+
export declare function findRoute(p: ProjectDocument, fromEnd: RouteEnd, toEnd: RouteEnd, options?: RouteOptions): Route | null;
|
|
67
|
+
/** Human name of a level: "Menswear & denim (level 3)" via Floor.code, "outside" for the site level. */
|
|
68
|
+
export declare function floorPhrase(p: ProjectDocument, floorId: string | null): string;
|
|
69
|
+
/** Build the human step list: walking grouped per floor, vertical rides merged per lift/stair name, doors called out — "Exit through Aleksanterinkatu entrance", "Take Lift A to Offices · buying & admin (level 8)". */
|
|
70
|
+
export declare function routeSteps(p: ProjectDocument, from: RoutePlace, to: RoutePlace, path: NavNode[], legs: RouteLeg[]): RouteStep[];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type Portal, type PortalGroup, type ProjectDocument, type Zone } from './types';
|
|
2
|
+
/** Which way you must cross `portal` to arrive in `spaceId`, or null if you cannot get there that way.
|
|
3
|
+
* Direction is asked, never stored: a door's entry side is relative to the area you mean. */
|
|
4
|
+
export declare function entryInto(portal: Portal, spaceId: string): 'a-to-b' | 'b-to-a' | null;
|
|
5
|
+
/** Every space in `zone`, including those reached through nested zones. */
|
|
6
|
+
export declare const zoneSpaces: (project: ProjectDocument, zone: Zone) => string[];
|
|
7
|
+
/** Portals on the boundary of `zone` — one side in, one side out. These are the ways in, and the
|
|
8
|
+
* thing software without a floor plan to ask makes you enumerate by hand. Derived, so it cannot go
|
|
9
|
+
* stale when the building is redrawn. */
|
|
10
|
+
export declare function perimeter(project: ProjectDocument, zone: Zone): Portal[];
|
|
11
|
+
/** Portals wholly inside `zone`. Not decorative: anything tracking where somebody ended up needs to
|
|
12
|
+
* know that crossing one of these does not change which zone you are in. */
|
|
13
|
+
export declare function captive(project: ProjectDocument, zone: Zone): Portal[];
|
|
14
|
+
/** Create a zone over the given spaces. Ids that are not spaces are dropped rather than rejected —
|
|
15
|
+
* a selection usually contains a door or a fixture alongside the rooms, and losing the whole gesture
|
|
16
|
+
* over that would be tiresome. */
|
|
17
|
+
export declare function addZone(project: ProjectDocument, name: string, spaceIds: string[], purpose?: string): Zone;
|
|
18
|
+
/** Remove a zone, and any nesting reference to it. A dangling childZoneIds entry fails validation. */
|
|
19
|
+
export declare function removeZone(project: ProjectDocument, zoneId: string): void;
|
|
20
|
+
/** Add or remove spaces on a zone. Membership is a set: adding twice is not an error, and neither is
|
|
21
|
+
* removing something that was never there. */
|
|
22
|
+
export declare function setZoneMembers(project: ProjectDocument, zoneId: string, spaceIds: string[], member: boolean): void;
|
|
23
|
+
/** Nest one zone inside another, refusing anything that would make a cycle. Zones form a DAG, and a
|
|
24
|
+
* cycle is the one shape the validator will not accept. */
|
|
25
|
+
export declare function nestZone(project: ProjectDocument, parentId: string, childId: string): boolean;
|
|
26
|
+
/** Create a portal group over the given portals. The escape hatch for sets that are not a zone
|
|
27
|
+
* boundary — "all loading-bay shutters", "every door on the night circuit". Where a set *is* a zone
|
|
28
|
+
* boundary, derive it with `perimeter` instead; a derived list cannot go stale. Ids that are not
|
|
29
|
+
* portals are dropped rather than rejected, mirroring addZone. */
|
|
30
|
+
export declare function addPortalGroup(project: ProjectDocument, name: string, portalIds: string[]): PortalGroup;
|
|
31
|
+
/** Remove a portal group. Nothing references groups, so nothing needs cleaning up after one. */
|
|
32
|
+
export declare function removePortalGroup(project: ProjectDocument, groupId: string): void;
|
|
33
|
+
/** Add or remove portals on a group. Membership is a set, exactly as setZoneMembers. */
|
|
34
|
+
export declare function setPortalGroupMembers(project: ProjectDocument, groupId: string, portalIds: string[], member: boolean): void;
|
|
35
|
+
/** Drop ontology references to things that no longer exist.
|
|
36
|
+
*
|
|
37
|
+
* Every reference here is validated, so a delete that skips this step produces an invalid document
|
|
38
|
+
* and gets refused — from the outside that looks like the delete silently doing nothing, which is
|
|
39
|
+
* the worst way for a bug to present. Call it after removing objects, from every path that can.
|
|
40
|
+
*
|
|
41
|
+
* A portal whose opening is gone goes with it: the door was the way through, and keeping a portal
|
|
42
|
+
* that no longer has one would quietly turn a closed doorway into an open boundary. */
|
|
43
|
+
export declare function pruneOntology(project: ProjectDocument): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Portal, type ProjectDocument } from './types';
|
|
2
|
+
/** A shared virtual edge explicitly declares an unwalled connection. Read its two sides directly;
|
|
3
|
+
* sampling inset room outlines loses narrow openings near the ends of adjoining walls. */
|
|
4
|
+
export declare function sharedBoundaryPortals(project: ProjectDocument): Portal[];
|
|
5
|
+
/** The readable portal layer, including explicit shared openings in older saved plans. A stored
|
|
6
|
+
* portal takes precedence, including sealed and one-way passage. No document mutation is needed.
|
|
7
|
+
* Once both spaces use shared boundaries, an inferred open connection also disappears when its
|
|
8
|
+
* virtual edge is replaced by a wall. Legacy independent outlines retain their inferred portals. */
|
|
9
|
+
export declare function effectivePortals(project: ProjectDocument): Portal[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Numerical tolerances are independent of the user's positioning grid. All values are metres. */
|
|
2
|
+
export declare const GEOMETRY_EPS = 0.000001;
|
|
3
|
+
export declare const JOIN_EPS = 0.001;
|
|
4
|
+
export declare const MIN_WALL_LENGTH = 0.01;
|
|
5
|
+
export declare const MIN_RING_EDGE = 0.001;
|
|
6
|
+
/** Usable floor area, after subtracting holes and physical walls, in square metres. */
|
|
7
|
+
export declare const MIN_SPACE_AREA = 1;
|
|
8
|
+
/** Topological faces and holes may be smaller than a labelled space. Square metres. */
|
|
9
|
+
export declare const MIN_FACE_AREA = 1e-8;
|
|
10
|
+
/** Only derived polygon-clipping inputs use this precision; junctions retain their coordinates. */
|
|
11
|
+
export declare const CLIP_SCALE = 10000;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProjectDocument, SiteObject } from './types';
|
|
2
|
+
export declare function copyProject(project: ProjectDocument): ProjectDocument;
|
|
3
|
+
/** Apply dimensions in the object's own axes, then rotate and translate its polygon. */
|
|
4
|
+
export declare function transformObject(object: SiteObject, patch: Partial<SiteObject>): void;
|
|
5
|
+
/** The floor a viewer should open on: the document's own `initialFloorId` when it names a floor that
|
|
6
|
+
* still exists, otherwise the ground floor, otherwise the lowest one. An explicit `null` is a real
|
|
7
|
+
* answer — it means the outdoor site — so it is distinguished from the field being absent. */
|
|
8
|
+
export declare function openingFloorId(project: ProjectDocument): string | null;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProjectDocument, SiteObject } from './types';
|
|
2
|
+
export declare const rampJoins: (o: SiteObject, elevation: number) => boolean;
|
|
3
|
+
/** Only the end levels in the ramp's building are connected, never a storey it passes through. */
|
|
4
|
+
export declare function rampFloors(project: ProjectDocument, o: SiteObject): {
|
|
5
|
+
low: import("./types").Floor | undefined;
|
|
6
|
+
high: import("./types").Floor | undefined;
|
|
7
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { NavEdge, NavNode, ProjectDocument } from './types';
|
|
2
|
+
/** Bind a graph node to the room whose walkable floor it can enter. Use separate nodes on the
|
|
3
|
+
* sides of a controlled portal and join those with a directed/door edge in `graph`. */
|
|
4
|
+
export interface RoomAccess {
|
|
5
|
+
spaceId: string;
|
|
6
|
+
nodeId: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RoomNavigationGraph {
|
|
9
|
+
nodes: NavNode[];
|
|
10
|
+
edges: NavEdge[];
|
|
11
|
+
}
|
|
12
|
+
/** Build the geometric walking graph inside rooms. Explicit access points describe connectivity;
|
|
13
|
+
* room outlines, holes, pools and wall thickness describe where a person can walk. The input
|
|
14
|
+
* document/graph are not mutated. Supplied door/vertical/directed edges are kept verbatim. */
|
|
15
|
+
export declare function buildRoomNavigation(project: ProjectDocument, access: readonly RoomAccess[], graph?: RoomNavigationGraph): RoomNavigationGraph;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Point, ProjectDocument } from './types';
|
|
2
|
+
/** Extra room for shoulders and for the route marking, in plan metres. */
|
|
3
|
+
export declare const ROUTE_CLEARANCE = 0.4;
|
|
4
|
+
type Bounds = [number, number, number, number];
|
|
5
|
+
export declare const routeBounds: (points: Point[], pad?: number) => Bounds;
|
|
6
|
+
/** A geometric guard for walking connections. It checks the whole segment, not samples along it.
|
|
7
|
+
* Walls retain their thickness; doors/gates cut their actual apertures. Pools and floor holes are
|
|
8
|
+
* obstacles even when a containing room's outer ring includes them. Build once for a document. */
|
|
9
|
+
export declare function createRouteClearance(project: ProjectDocument): (floorId: string | null, extent?: Bounds) => (a: Point, b: Point) => boolean;
|
|
10
|
+
export declare function routeClearance(project: ProjectDocument): (floorId: string | null, extent?: Bounds) => (a: Point, b: Point) => boolean;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type Point, type ProjectDocument, type Ring, type SiteObject } from './types';
|
|
2
|
+
/** The enclosed region a point stands in, read off the walls around it.
|
|
3
|
+
*
|
|
4
|
+
* A floor's open area is its extent minus the bodies of its walls, and that difference falls apart
|
|
5
|
+
* into exactly the regions the walls divide it into — so the room under a click is whichever of
|
|
6
|
+
* those contains the click. No tracing, no flood fill, no tolerance to tune: the walls say where
|
|
7
|
+
* the rooms are, and this reads the answer.
|
|
8
|
+
*
|
|
9
|
+
* Doorways do not leak, because a door is an object ON a continuous wall rather than a hole in the
|
|
10
|
+
* run of it. A doorless passage does leak, and should: the drawing said those two places flow into
|
|
11
|
+
* one another. Returns null when the point is not enclosed — outside the building, or inside a
|
|
12
|
+
* boundary with a gap in it, where the region reaches the edge of the extent. */
|
|
13
|
+
export declare function enclosedRegion(project: ProjectDocument, floorId: string | null, point: Point): Ring | null;
|
|
14
|
+
/** Every enclosed region on a floor, largest first.
|
|
15
|
+
*
|
|
16
|
+
* Outer rings only: a region with a walled island inside it comes back with the island filled in,
|
|
17
|
+
* so its area overstates the floor you could stand on by the island's footprint. Carrying the holes
|
|
18
|
+
* through as further rings is the complete answer and changes this signature; until then the island
|
|
19
|
+
* is its own region in the list, and enclosedRegion returns it for a click inside it.
|
|
20
|
+
*
|
|
21
|
+
* The same difference as `enclosedRegion`, read whole rather than probed: one subtraction gives all
|
|
22
|
+
* the rooms the walls describe. Regions touching the extent are open to the outside and dropped,
|
|
23
|
+
* and slivers below `minArea` — the gap between two walls that nearly meet — with them. */
|
|
24
|
+
export declare function enclosedRegions(project: ProjectDocument, floorId: string | null, minArea?: number): Ring[];
|
|
25
|
+
/** Re-fit the rooms that the walls were defining, after those walls have moved.
|
|
26
|
+
*
|
|
27
|
+
* A room stores its own outline, which is what lets a space exist where no wall does — a zone over
|
|
28
|
+
* an open floor, a parcel, an area someone drew freehand. The cost is that moving a wall used to
|
|
29
|
+
* leave the room it bounded exactly where it was, so the two drifted apart and had to be kept in
|
|
30
|
+
* step by hand.
|
|
31
|
+
*
|
|
32
|
+
* They do not have to be. Pass the regions as they stood BEFORE the edit: a room whose outline was
|
|
33
|
+
* one of them was being defined by the walls, so it takes the region that now stands in its place.
|
|
34
|
+
* A room that matched nothing was drawn rather than enclosed, and is left alone. Identity is never
|
|
35
|
+
* touched — the name, colour, bindings and id are the room; only its shape came from the walls. */
|
|
36
|
+
export declare function refitEnclosedRooms(project: ProjectDocument, floorId: string | null, before: Ring[]): number;
|
|
37
|
+
/** Spaces are objects you can stand in — the areas already in the document, plus lifts and stairs.
|
|
38
|
+
* Nothing new is stored for them: a room *is* a space, and zones and portals reference it by id. */
|
|
39
|
+
export declare const spaces: (project: ProjectDocument) => SiteObject[];
|
|
40
|
+
/** Where a space sits for routing. Its footprint's centroid, falling back to its placed position. */
|
|
41
|
+
export declare function spacePoint(project: ProjectDocument, space: SiteObject): Point;
|
|
42
|
+
/** True when `point` falls inside a space's footprint — inside its outline and outside its holes. */
|
|
43
|
+
export declare function inSpace(space: SiteObject, point: Point): boolean;
|
|
44
|
+
/** The space a point falls in: the *smallest* one containing it, since a room inside a zone inside a
|
|
45
|
+
* floor plate are all true and only the innermost is useful. */
|
|
46
|
+
export declare function spaceAt(project: ProjectDocument, floorId: string | null, point: Point): SiteObject | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Point, Ring, SiteObject } from './types';
|
|
2
|
+
import { type FlightRun, type StairModel } from './vertical';
|
|
3
|
+
export interface StairLane {
|
|
4
|
+
foot: Point;
|
|
5
|
+
head: Point;
|
|
6
|
+
width: number;
|
|
7
|
+
base: number;
|
|
8
|
+
rise: number;
|
|
9
|
+
steps: number;
|
|
10
|
+
}
|
|
11
|
+
export interface StairLanding {
|
|
12
|
+
ring: Ring;
|
|
13
|
+
height: number;
|
|
14
|
+
}
|
|
15
|
+
/** One description of the steps and landings, used by both rendering and walking support. */
|
|
16
|
+
export declare function stairGeometry(o: SiteObject, run: FlightRun, rise: number, model: StairModel): {
|
|
17
|
+
lanes: StairLane[];
|
|
18
|
+
landings: StairLanding[];
|
|
19
|
+
};
|
|
20
|
+
/** The same wedge treads for the spiral mesh and its walkable support. */
|
|
21
|
+
export declare function spiralGeometry(o: SiteObject, position: Point, rise: number): {
|
|
22
|
+
inner: number;
|
|
23
|
+
wedges: {
|
|
24
|
+
ring: Ring;
|
|
25
|
+
height: number;
|
|
26
|
+
}[];
|
|
27
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Point, ProjectDocument, SiteObject } from './types';
|
|
2
|
+
/** The tread/landing centreline shared with physical walking, in travel order. */
|
|
3
|
+
export declare function stairTraversal(project: ProjectDocument, object: SiteObject, from: string, to: string): {
|
|
4
|
+
points: Point[];
|
|
5
|
+
up: boolean;
|
|
6
|
+
escalator: boolean;
|
|
7
|
+
speed: number;
|
|
8
|
+
} | null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type NavEdge, type NavNode } from './types';
|
|
2
|
+
import type { ProjectDocument } from './types';
|
|
3
|
+
/** Node id for a space. Prefixed so a derived graph can never collide with an authored entity id. */
|
|
4
|
+
export declare const spaceNodeId: (spaceId: string) => string;
|
|
5
|
+
export declare function derivedGraph(project: ProjectDocument): {
|
|
6
|
+
nodes: NavNode[];
|
|
7
|
+
edges: NavEdge[];
|
|
8
|
+
};
|
|
9
|
+
export declare function topology(project: ProjectDocument): {
|
|
10
|
+
nodes: NavNode[];
|
|
11
|
+
edges: NavEdge[];
|
|
12
|
+
};
|
|
13
|
+
/** Straight-line length of a derived edge, for cost comparisons against an authored graph. */
|
|
14
|
+
export declare const edgeSpan: (nodes: Map<string, NavNode>, edge: NavEdge) => number;
|