@kerros/editor 0.0.0-stage → 0.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -2
  3. package/dist/SitePlanner.js +1189 -0
  4. package/dist/SitePlanner.js.map +1 -0
  5. package/dist/adapters/basemap.js +11 -0
  6. package/dist/adapters/basemap.js.map +1 -0
  7. package/dist/adapters/persistence.js +121 -0
  8. package/dist/adapters/persistence.js.map +1 -0
  9. package/dist/adapters/status.js +11 -0
  10. package/dist/adapters/status.js.map +1 -0
  11. package/dist/adapters/useProjectPersistence.js +56 -0
  12. package/dist/adapters/useProjectPersistence.js.map +1 -0
  13. package/dist/components/AiImportPanel.js +635 -0
  14. package/dist/components/AiImportPanel.js.map +1 -0
  15. package/dist/components/AnalysisPreview.js +179 -0
  16. package/dist/components/AnalysisPreview.js.map +1 -0
  17. package/dist/components/ElevatorPanel.js +120 -0
  18. package/dist/components/ElevatorPanel.js.map +1 -0
  19. package/dist/components/Icons.js +57 -0
  20. package/dist/components/Icons.js.map +1 -0
  21. package/dist/components/ImportDialog.js +467 -0
  22. package/dist/components/ImportDialog.js.map +1 -0
  23. package/dist/components/Inspector.js +1184 -0
  24. package/dist/components/Inspector.js.map +1 -0
  25. package/dist/components/NavigatePanel.js +301 -0
  26. package/dist/components/NavigatePanel.js.map +1 -0
  27. package/dist/components/NavigationGraph.js +234 -0
  28. package/dist/components/NavigationGraph.js.map +1 -0
  29. package/dist/components/StructureExplorer.js +510 -0
  30. package/dist/components/StructureExplorer.js.map +1 -0
  31. package/dist/components/StructureView.js +286 -0
  32. package/dist/components/StructureView.js.map +1 -0
  33. package/dist/components/controls.js +209 -0
  34. package/dist/components/controls.js.map +1 -0
  35. package/dist/components/graphLayout.js +27 -0
  36. package/dist/components/graphLayout.js.map +1 -0
  37. package/dist/host.js +175 -0
  38. package/dist/host.js.map +1 -0
  39. package/dist/i18n.js +88 -0
  40. package/dist/i18n.js.map +1 -0
  41. package/dist/import/analysisPreview.js +41 -0
  42. package/dist/import/analysisPreview.js.map +1 -0
  43. package/dist/import/brief.js +29 -0
  44. package/dist/import/brief.js.map +1 -0
  45. package/dist/import/checkpoint.js +50 -0
  46. package/dist/import/checkpoint.js.map +1 -0
  47. package/dist/import/detect.js +120 -0
  48. package/dist/import/detect.js.map +1 -0
  49. package/dist/import/documentSvg.js +49 -0
  50. package/dist/import/documentSvg.js.map +1 -0
  51. package/dist/import/instructions.js +20 -0
  52. package/dist/import/instructions.js.map +1 -0
  53. package/dist/import/openings.js +61 -0
  54. package/dist/import/openings.js.map +1 -0
  55. package/dist/import/planImport.js +233 -0
  56. package/dist/import/planImport.js.map +1 -0
  57. package/dist/import/register.js +47 -0
  58. package/dist/import/register.js.map +1 -0
  59. package/dist/import/runs.js +67 -0
  60. package/dist/import/runs.js.map +1 -0
  61. package/dist/import/session.js +23 -0
  62. package/dist/import/session.js.map +1 -0
  63. package/dist/import/types.js +13 -0
  64. package/dist/import/types.js.map +1 -0
  65. package/dist/import/usage.js +29 -0
  66. package/dist/import/usage.js.map +1 -0
  67. package/dist/import/walls.js +112 -0
  68. package/dist/import/walls.js.map +1 -0
  69. package/dist/index.js +178 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/map/CabinMaterials.js +81 -0
  72. package/dist/map/CabinMaterials.js.map +1 -0
  73. package/dist/map/CabinMirror.js +43 -0
  74. package/dist/map/CabinMirror.js.map +1 -0
  75. package/dist/map/Doors.js +80 -0
  76. package/dist/map/Doors.js.map +1 -0
  77. package/dist/map/ElevatorCabin.js +93 -0
  78. package/dist/map/ElevatorCabin.js.map +1 -0
  79. package/dist/map/FixtureLights.js +117 -0
  80. package/dist/map/FixtureLights.js.map +1 -0
  81. package/dist/map/MapCanvas.js +2161 -0
  82. package/dist/map/MapCanvas.js.map +1 -0
  83. package/dist/map/Passenger.js +69 -0
  84. package/dist/map/Passenger.js.map +1 -0
  85. package/dist/map/SceneLayer.js +1534 -0
  86. package/dist/map/SceneLayer.js.map +1 -0
  87. package/dist/map/UndergroundContext.js +153 -0
  88. package/dist/map/UndergroundContext.js.map +1 -0
  89. package/dist/map/ambience.js +194 -0
  90. package/dist/map/ambience.js.map +1 -0
  91. package/dist/map/architecture.js +305 -0
  92. package/dist/map/architecture.js.map +1 -0
  93. package/dist/map/bathMusic.js +92 -0
  94. package/dist/map/bathMusic.js.map +1 -0
  95. package/dist/map/cameraAim.js +33 -0
  96. package/dist/map/cameraAim.js.map +1 -0
  97. package/dist/map/elevators.js +56 -0
  98. package/dist/map/elevators.js.map +1 -0
  99. package/dist/map/excavation.js +52 -0
  100. package/dist/map/excavation.js.map +1 -0
  101. package/dist/map/exteriors.js +25 -0
  102. package/dist/map/exteriors.js.map +1 -0
  103. package/dist/map/features.js +218 -0
  104. package/dist/map/features.js.map +1 -0
  105. package/dist/map/fences.js +29 -0
  106. package/dist/map/fences.js.map +1 -0
  107. package/dist/map/journey.js +112 -0
  108. package/dist/map/journey.js.map +1 -0
  109. package/dist/map/levels.js +6 -0
  110. package/dist/map/levels.js.map +1 -0
  111. package/dist/map/lighting.js +143 -0
  112. package/dist/map/lighting.js.map +1 -0
  113. package/dist/map/loadBasemap.js +26 -0
  114. package/dist/map/loadBasemap.js.map +1 -0
  115. package/dist/map/materials.js +183 -0
  116. package/dist/map/materials.js.map +1 -0
  117. package/dist/map/poolLighting.js +39 -0
  118. package/dist/map/poolLighting.js.map +1 -0
  119. package/dist/map/projection.js +24 -0
  120. package/dist/map/projection.js.map +1 -0
  121. package/dist/map/rampGeometry.js +38 -0
  122. package/dist/map/rampGeometry.js.map +1 -0
  123. package/dist/map/route.js +107 -0
  124. package/dist/map/route.js.map +1 -0
  125. package/dist/map/stairSurfaces.js +115 -0
  126. package/dist/map/stairSurfaces.js.map +1 -0
  127. package/dist/map/surfaces.js +136 -0
  128. package/dist/map/surfaces.js.map +1 -0
  129. package/dist/map/textures.js +95 -0
  130. package/dist/map/textures.js.map +1 -0
  131. package/dist/map/underground.js +34 -0
  132. package/dist/map/underground.js.map +1 -0
  133. package/dist/map/walk.js +433 -0
  134. package/dist/map/walk.js.map +1 -0
  135. package/dist/map/walkContext.js +46 -0
  136. package/dist/map/walkContext.js.map +1 -0
  137. package/dist/map/walkDimensions.js +7 -0
  138. package/dist/map/walkDimensions.js.map +1 -0
  139. package/dist/map/walkJourney.js +85 -0
  140. package/dist/map/walkJourney.js.map +1 -0
  141. package/dist/map/walkSurfaces.js +106 -0
  142. package/dist/map/walkSurfaces.js.map +1 -0
  143. package/dist/map/wallJoins.js +70 -0
  144. package/dist/map/wallJoins.js.map +1 -0
  145. package/dist/map/water.js +274 -0
  146. package/dist/map/water.js.map +1 -0
  147. package/dist/model/authoring.js +99 -0
  148. package/dist/model/authoring.js.map +1 -0
  149. package/dist/model/boundaries.js +548 -0
  150. package/dist/model/boundaries.js.map +1 -0
  151. package/dist/model/coverage.js +30 -0
  152. package/dist/model/coverage.js.map +1 -0
  153. package/dist/model/document.js +52 -0
  154. package/dist/model/document.js.map +1 -0
  155. package/dist/model/doors.js +47 -0
  156. package/dist/model/doors.js.map +1 -0
  157. package/dist/model/factory.js +56 -0
  158. package/dist/model/factory.js.map +1 -0
  159. package/dist/model/geometry.js +454 -0
  160. package/dist/model/geometry.js.map +1 -0
  161. package/dist/model/history.js +29 -0
  162. package/dist/model/history.js.map +1 -0
  163. package/dist/model/imports.js +45 -0
  164. package/dist/model/imports.js.map +1 -0
  165. package/dist/model/inference.js +182 -0
  166. package/dist/model/inference.js.map +1 -0
  167. package/dist/model/materials.js +11 -0
  168. package/dist/model/materials.js.map +1 -0
  169. package/dist/model/mutations.js +157 -0
  170. package/dist/model/mutations.js.map +1 -0
  171. package/dist/model/navigation.js +275 -0
  172. package/dist/model/navigation.js.map +1 -0
  173. package/dist/model/ontology.js +109 -0
  174. package/dist/model/ontology.js.map +1 -0
  175. package/dist/model/passages.js +5 -0
  176. package/dist/model/passages.js.map +1 -0
  177. package/dist/model/portals.js +42 -0
  178. package/dist/model/portals.js.map +1 -0
  179. package/dist/model/precision.js +11 -0
  180. package/dist/model/precision.js.map +1 -0
  181. package/dist/model/project.js +31 -0
  182. package/dist/model/project.js.map +1 -0
  183. package/dist/model/ramps.js +10 -0
  184. package/dist/model/ramps.js.map +1 -0
  185. package/dist/model/roomNavigation.js +87 -0
  186. package/dist/model/roomNavigation.js.map +1 -0
  187. package/dist/model/routeClearance.js +72 -0
  188. package/dist/model/routeClearance.js.map +1 -0
  189. package/dist/model/spaces.js +104 -0
  190. package/dist/model/spaces.js.map +1 -0
  191. package/dist/model/stairGeometry.js +40 -0
  192. package/dist/model/stairGeometry.js.map +1 -0
  193. package/dist/model/stairTraversal.js +48 -0
  194. package/dist/model/stairTraversal.js.map +1 -0
  195. package/dist/model/topology.js +63 -0
  196. package/dist/model/topology.js.map +1 -0
  197. package/dist/model/types.js +35 -0
  198. package/dist/model/types.js.map +1 -0
  199. package/dist/model/validate.js +240 -0
  200. package/dist/model/validate.js.map +1 -0
  201. package/dist/model/vertical.js +129 -0
  202. package/dist/model/vertical.js.map +1 -0
  203. package/dist/model/walls.js +261 -0
  204. package/dist/model/walls.js.map +1 -0
  205. package/dist/planner/DrawingDock.js +231 -0
  206. package/dist/planner/DrawingDock.js.map +1 -0
  207. package/dist/planner/FloorControls.js +93 -0
  208. package/dist/planner/FloorControls.js.map +1 -0
  209. package/dist/planner/MapSettings.js +143 -0
  210. package/dist/planner/MapSettings.js.map +1 -0
  211. package/dist/planner/PlannerHelp.js +57 -0
  212. package/dist/planner/PlannerHelp.js.map +1 -0
  213. package/dist/planner/ProjectSidebar.js +246 -0
  214. package/dist/planner/ProjectSidebar.js.map +1 -0
  215. package/dist/planner/floors.js +18 -0
  216. package/dist/planner/floors.js.map +1 -0
  217. package/dist/planner/useDrawingTools.js +341 -0
  218. package/dist/planner/useDrawingTools.js.map +1 -0
  219. package/dist/planner/useMapDisplay.js +51 -0
  220. package/dist/planner/useMapDisplay.js.map +1 -0
  221. package/dist/planner/usePlannerKeyboard.js +138 -0
  222. package/dist/planner/usePlannerKeyboard.js.map +1 -0
  223. package/dist/planner/useReferenceAlignment.js +50 -0
  224. package/dist/planner/useReferenceAlignment.js.map +1 -0
  225. package/dist/styles.css +4931 -0
  226. package/dist/theme/index.js +34 -0
  227. package/dist/theme/index.js.map +1 -0
  228. package/dist/types/SitePlanner.d.ts +5 -0
  229. package/dist/types/adapters/basemap.d.ts +2 -0
  230. package/dist/types/adapters/persistence.d.ts +29 -0
  231. package/dist/types/adapters/status.d.ts +4 -0
  232. package/dist/types/adapters/useProjectPersistence.d.ts +13 -0
  233. package/dist/types/components/AiImportPanel.d.ts +9 -0
  234. package/dist/types/components/AnalysisPreview.d.ts +4 -0
  235. package/dist/types/components/ElevatorPanel.d.ts +18 -0
  236. package/dist/types/components/Icons.d.ts +8 -0
  237. package/dist/types/components/ImportDialog.d.ts +42 -0
  238. package/dist/types/components/Inspector.d.ts +38 -0
  239. package/dist/types/components/NavigatePanel.d.ts +27 -0
  240. package/dist/types/components/NavigationGraph.d.ts +10 -0
  241. package/dist/types/components/StructureExplorer.d.ts +8 -0
  242. package/dist/types/components/StructureView.d.ts +22 -0
  243. package/dist/types/components/controls.d.ts +52 -0
  244. package/dist/types/components/graphLayout.d.ts +9 -0
  245. package/dist/types/editor/host.d.ts +9 -0
  246. package/dist/types/editor/index.d.ts +2 -0
  247. package/dist/types/i18n.d.ts +85 -0
  248. package/dist/types/import/analysisPreview.d.ts +27 -0
  249. package/dist/types/import/brief.d.ts +22 -0
  250. package/dist/types/import/checkpoint.d.ts +49 -0
  251. package/dist/types/import/detect.d.ts +34 -0
  252. package/dist/types/import/documentSvg.d.ts +2 -0
  253. package/dist/types/import/index.d.ts +10 -0
  254. package/dist/types/import/instructions.d.ts +7 -0
  255. package/dist/types/import/openings.d.ts +22 -0
  256. package/dist/types/import/planImport.d.ts +22 -0
  257. package/dist/types/import/register.d.ts +25 -0
  258. package/dist/types/import/runs.d.ts +31 -0
  259. package/dist/types/import/session.d.ts +33 -0
  260. package/dist/types/import/types.d.ts +56 -0
  261. package/dist/types/import/usage.d.ts +10 -0
  262. package/dist/types/import/walls.d.ts +37 -0
  263. package/dist/types/map/CabinMaterials.d.ts +18 -0
  264. package/dist/types/map/CabinMirror.d.ts +13 -0
  265. package/dist/types/map/Doors.d.ts +11 -0
  266. package/dist/types/map/ElevatorCabin.d.ts +20 -0
  267. package/dist/types/map/FixtureLights.d.ts +35 -0
  268. package/dist/types/map/MapCanvas.d.ts +87 -0
  269. package/dist/types/map/Passenger.d.ts +18 -0
  270. package/dist/types/map/SceneLayer.d.ts +306 -0
  271. package/dist/types/map/UndergroundContext.d.ts +18 -0
  272. package/dist/types/map/ambience.d.ts +29 -0
  273. package/dist/types/map/architecture.d.ts +8 -0
  274. package/dist/types/map/bathMusic.d.ts +14 -0
  275. package/dist/types/map/cameraAim.d.ts +20 -0
  276. package/dist/types/map/elevators.d.ts +16 -0
  277. package/dist/types/map/excavation.d.ts +9 -0
  278. package/dist/types/map/exteriors.d.ts +3 -0
  279. package/dist/types/map/features.d.ts +33 -0
  280. package/dist/types/map/fences.d.ts +4 -0
  281. package/dist/types/map/journey.d.ts +36 -0
  282. package/dist/types/map/levels.d.ts +4 -0
  283. package/dist/types/map/lighting.d.ts +103 -0
  284. package/dist/types/map/loadBasemap.d.ts +4 -0
  285. package/dist/types/map/materials.d.ts +38 -0
  286. package/dist/types/map/poolLighting.d.ts +11 -0
  287. package/dist/types/map/projection.d.ts +9 -0
  288. package/dist/types/map/rampGeometry.d.ts +8 -0
  289. package/dist/types/map/route.d.ts +59 -0
  290. package/dist/types/map/stairSurfaces.d.ts +29 -0
  291. package/dist/types/map/surfaces.d.ts +36 -0
  292. package/dist/types/map/textures.d.ts +8 -0
  293. package/dist/types/map/underground.d.ts +30 -0
  294. package/dist/types/map/walk.d.ts +232 -0
  295. package/dist/types/map/walkContext.d.ts +11 -0
  296. package/dist/types/map/walkDimensions.d.ts +5 -0
  297. package/dist/types/map/walkJourney.d.ts +33 -0
  298. package/dist/types/map/walkSurfaces.d.ts +27 -0
  299. package/dist/types/map/wallJoins.d.ts +6 -0
  300. package/dist/types/map/water.d.ts +12 -0
  301. package/dist/types/model/authoring.d.ts +38 -0
  302. package/dist/types/model/boundaries.d.ts +41 -0
  303. package/dist/types/model/coverage.d.ts +8 -0
  304. package/dist/types/model/document.d.ts +9 -0
  305. package/dist/types/model/doors.d.ts +19 -0
  306. package/dist/types/model/factory.d.ts +5 -0
  307. package/dist/types/model/geometry.d.ts +99 -0
  308. package/dist/types/model/history.d.ts +10 -0
  309. package/dist/types/model/host.d.ts +154 -0
  310. package/dist/types/model/imports.d.ts +7 -0
  311. package/dist/types/model/inference.d.ts +46 -0
  312. package/dist/types/model/live.d.ts +60 -0
  313. package/dist/types/model/materials.d.ts +28 -0
  314. package/dist/types/model/mutations.d.ts +178 -0
  315. package/dist/types/model/navigation.d.ts +70 -0
  316. package/dist/types/model/ontology.d.ts +43 -0
  317. package/dist/types/model/passages.d.ts +2 -0
  318. package/dist/types/model/portals.d.ts +9 -0
  319. package/dist/types/model/precision.d.ts +11 -0
  320. package/dist/types/model/project.d.ts +8 -0
  321. package/dist/types/model/ramps.d.ts +7 -0
  322. package/dist/types/model/roomNavigation.d.ts +15 -0
  323. package/dist/types/model/routeClearance.d.ts +11 -0
  324. package/dist/types/model/spaces.d.ts +46 -0
  325. package/dist/types/model/stairGeometry.d.ts +27 -0
  326. package/dist/types/model/stairTraversal.d.ts +8 -0
  327. package/dist/types/model/topology.d.ts +14 -0
  328. package/dist/types/model/types.d.ts +369 -0
  329. package/dist/types/model/validate.d.ts +38 -0
  330. package/dist/types/model/vertical.d.ts +145 -0
  331. package/dist/types/model/walls.d.ts +71 -0
  332. package/dist/types/planner/DrawingDock.d.ts +16 -0
  333. package/dist/types/planner/FloorControls.d.ts +17 -0
  334. package/dist/types/planner/MapSettings.d.ts +16 -0
  335. package/dist/types/planner/PlannerHelp.d.ts +3 -0
  336. package/dist/types/planner/ProjectSidebar.d.ts +32 -0
  337. package/dist/types/planner/floors.d.ts +3 -0
  338. package/dist/types/planner/types.d.ts +3 -0
  339. package/dist/types/planner/useDrawingTools.d.ts +52 -0
  340. package/dist/types/planner/useMapDisplay.d.ts +29 -0
  341. package/dist/types/planner/usePlannerKeyboard.d.ts +18 -0
  342. package/dist/types/planner/useReferenceAlignment.d.ts +30 -0
  343. package/dist/types/schema/index.d.ts +25 -0
  344. package/dist/types/theme/index.d.ts +55 -0
  345. package/package.json +58 -4
@@ -0,0 +1,93 @@
1
+ import { jsxs as i, Fragment as z, jsx as o } from "react/jsx-runtime";
2
+ import { Layers3 as v, Box as y, Footprints as D, ChevronUp as T, ChevronDown as O } from "lucide-react";
3
+ import { FloorSelect as U } from "../components/controls.js";
4
+ import { floorCode as d, floorBand as A } from "./floors.js";
5
+ function H({
6
+ project: a,
7
+ floorId: r,
8
+ mode: f,
9
+ viewMode: e,
10
+ stack: c,
11
+ alarmFloors: C,
12
+ showKeys: N,
13
+ changeFloor: w,
14
+ chooseMode: u,
15
+ setStack: g,
16
+ stepFloor: m
17
+ }) {
18
+ const b = a.floors.find((l) => l.id === r), k = e === "2d" ? "3d" : e === "3d" ? "walk" : "2d", p = e !== "2d", x = e === "walk", t = (l) => N ? /* @__PURE__ */ o("kbd", { className: "key-hint", children: l }) : null;
19
+ return /* @__PURE__ */ i(z, { children: [
20
+ /* @__PURE__ */ i("div", { className: "canvas-top-left", children: [
21
+ /* @__PURE__ */ i("div", { className: "floor-chip", children: [
22
+ /* @__PURE__ */ o(v, { size: 17 }),
23
+ /* @__PURE__ */ o(
24
+ U,
25
+ {
26
+ ariaLabel: "Active floor",
27
+ value: r ?? "outdoors",
28
+ onPick: (l) => w(l === "outdoors" ? null : l),
29
+ entries: [
30
+ { id: "outdoors", code: "OUT", name: "Outdoor site" },
31
+ ...a.buildings.flatMap(
32
+ (l) => a.floors.filter((n) => n.buildingId === l.id).sort((n, s) => s.elevation - n.elevation).map((n) => ({
33
+ id: n.id,
34
+ code: d(a, n),
35
+ name: f !== "view" && C.has(n.id) ? `⚠ ${n.name}` : n.name,
36
+ hint: a.buildings.length > 1 ? l.name : void 0
37
+ }))
38
+ )
39
+ ]
40
+ }
41
+ ),
42
+ t("⇧↑↓")
43
+ ] }),
44
+ /* @__PURE__ */ i("div", { className: "view-switch", children: [
45
+ /* @__PURE__ */ i("button", { className: e === "2d" ? "active" : "", onClick: () => u("2d"), children: [
46
+ "2D",
47
+ k === "2d" && t("T")
48
+ ] }),
49
+ /* @__PURE__ */ i("button", { className: e === "3d" ? "active" : "", onClick: () => u("3d"), children: [
50
+ /* @__PURE__ */ o(y, { size: 14 }),
51
+ "3D",
52
+ k === "3d" && t("T")
53
+ ] }),
54
+ /* @__PURE__ */ i(
55
+ "button",
56
+ {
57
+ className: e === "walk" ? "active" : "",
58
+ title: "Walk through the building at eye level",
59
+ onClick: () => u("walk"),
60
+ children: [
61
+ /* @__PURE__ */ o(D, { size: 14 }),
62
+ "Walk",
63
+ e !== "walk" && t("3")
64
+ ]
65
+ }
66
+ )
67
+ ] }),
68
+ p && !x && /* @__PURE__ */ i("button", { className: `stack-button ${c ? "active" : ""}`, onClick: () => g(!c), children: [
69
+ /* @__PURE__ */ o(v, { size: 15 }),
70
+ c ? "All floors" : "Cutaway",
71
+ t("X")
72
+ ] })
73
+ ] }),
74
+ (() => {
75
+ const l = A(a, r), n = l.findIndex((F) => F.id === r), s = n < 0 ? l[0] : l[n + 1], h = n < 0 ? void 0 : l[n - 1];
76
+ return /* @__PURE__ */ i("div", { className: "floor-step", children: [
77
+ /* @__PURE__ */ i("button", { "aria-label": "Floor up", title: "Floor up (⇧↑)", disabled: !s, onClick: () => m(1), children: [
78
+ /* @__PURE__ */ o(T, { size: 14 }),
79
+ s && /* @__PURE__ */ o("b", { children: d(a, s) })
80
+ ] }),
81
+ /* @__PURE__ */ o("span", { className: "floor-step-current", children: b ? d(a, b) : "OUT" }),
82
+ /* @__PURE__ */ i("button", { "aria-label": "Floor down", title: "Floor down (⇧↓)", disabled: !h, onClick: () => m(-1), children: [
83
+ h && /* @__PURE__ */ o("b", { children: d(a, h) }),
84
+ /* @__PURE__ */ o(O, { size: 14 })
85
+ ] })
86
+ ] });
87
+ })()
88
+ ] });
89
+ }
90
+ export {
91
+ H as FloorControls
92
+ };
93
+ //# sourceMappingURL=FloorControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloorControls.js","sources":["../../../../src/planner/FloorControls.tsx"],"sourcesContent":["import { Box, ChevronDown, ChevronUp, Footprints, Layers3 } from 'lucide-react';\nimport { FloorSelect } from '../components/controls';\nimport type { PlannerMode } from '../model/host';\nimport type { ProjectDocument } from '../model/types';\nimport { floorBand, floorCode } from './floors';\n\ninterface FloorControlsProps {\n project: ProjectDocument;\n floorId: string | null;\n mode: PlannerMode;\n viewMode: '2d' | '3d' | 'walk';\n stack: boolean;\n alarmFloors: Set<string | null>;\n showKeys: boolean;\n changeFloor: (id: string | null) => void;\n chooseMode: (mode: '2d' | '3d' | 'walk') => void;\n setStack: (enabled: boolean) => void;\n stepFloor: (direction: 1 | -1) => void;\n}\n\nexport function FloorControls({\n project,\n floorId,\n mode,\n viewMode,\n stack,\n alarmFloors,\n showKeys,\n changeFloor,\n chooseMode,\n setStack,\n stepFloor,\n}: FloorControlsProps) {\n const floor = project.floors.find(f => f.id === floorId);\n const nextView = viewMode === '2d' ? '3d' : viewMode === '3d' ? 'walk' : '2d';\n const threeD = viewMode !== '2d';\n const walk = viewMode === 'walk';\n const keyHint = (label: string) => (showKeys ? <kbd className=\"key-hint\">{label}</kbd> : null);\n return (\n <>\n <div className=\"canvas-top-left\">\n <div className=\"floor-chip\">\n <Layers3 size={17} />\n <FloorSelect\n ariaLabel=\"Active floor\"\n value={floorId ?? 'outdoors'}\n onPick={id => changeFloor(id === 'outdoors' ? null : id)}\n entries={[\n { id: 'outdoors', code: 'OUT', name: 'Outdoor site' },\n ...project.buildings.flatMap(b =>\n project.floors\n .filter(f => f.buildingId === b.id)\n .sort((a, c) => c.elevation - a.elevation)\n .map(f => ({\n id: f.id,\n code: floorCode(project, f),\n name: mode !== 'view' && alarmFloors.has(f.id) ? `⚠ ${f.name}` : f.name,\n hint: project.buildings.length > 1 ? b.name : undefined,\n })),\n ),\n ]}\n />\n {keyHint('⇧↑↓')}\n </div>\n <div className=\"view-switch\">\n <button className={viewMode === '2d' ? 'active' : ''} onClick={() => chooseMode('2d')}>\n 2D{nextView === '2d' && keyHint('T')}\n </button>\n <button className={viewMode === '3d' ? 'active' : ''} onClick={() => chooseMode('3d')}>\n <Box size={14} />\n 3D{nextView === '3d' && keyHint('T')}\n </button>\n <button\n className={viewMode === 'walk' ? 'active' : ''}\n title=\"Walk through the building at eye level\"\n onClick={() => chooseMode('walk')}\n >\n <Footprints size={14} />\n Walk{viewMode !== 'walk' && keyHint('3')}\n </button>\n </div>\n {threeD && !walk && (\n <button className={`stack-button ${stack ? 'active' : ''}`} onClick={() => setStack(!stack)}>\n <Layers3 size={15} />\n {stack ? 'All floors' : 'Cutaway'}\n {keyHint('X')}\n </button>\n )}\n </div>\n {(() => {\n const band = floorBand(project, floorId);\n const index = band.findIndex(f => f.id === floorId);\n const above = index < 0 ? band[0] : band[index + 1],\n below = index < 0 ? undefined : band[index - 1];\n return (\n <div className=\"floor-step\">\n <button aria-label=\"Floor up\" title=\"Floor up (⇧↑)\" disabled={!above} onClick={() => stepFloor(1)}>\n <ChevronUp size={14} />\n {above && <b>{floorCode(project, above)}</b>}\n </button>\n <span className=\"floor-step-current\">{floor ? floorCode(project, floor) : 'OUT'}</span>\n <button aria-label=\"Floor down\" title=\"Floor down (⇧↓)\" disabled={!below} onClick={() => stepFloor(-1)}>\n {below && <b>{floorCode(project, below)}</b>}\n <ChevronDown size={14} />\n </button>\n </div>\n );\n })()}\n </>\n );\n}\n"],"names":["FloorControls","project","floorId","mode","viewMode","stack","alarmFloors","showKeys","changeFloor","chooseMode","setStack","stepFloor","floor","f","nextView","threeD","walk","keyHint","label","jsxs","Fragment","jsx","Layers3","FloorSelect","id","b","a","c","floorCode","Box","Footprints","band","floorBand","index","above","below","ChevronUp","ChevronDown"],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
+ import { X as T } from "lucide-react";
3
+ import { Toggle as i, Choice as I } from "../components/controls.js";
4
+ import { EXTERIOR_PRESETS as X } from "../model/materials.js";
5
+ function G({
6
+ display: f,
7
+ project: o,
8
+ floorId: C,
9
+ editing: r,
10
+ hostBasemap: d,
11
+ commit: y,
12
+ snapping: u,
13
+ setSnapping: x
14
+ }) {
15
+ const {
16
+ coverage: h,
17
+ setCoverage: w,
18
+ showLabels: c,
19
+ setShowLabels: S,
20
+ basemapMode: M,
21
+ setBasemapMode: k,
22
+ setSettings: P,
23
+ showPlan: g,
24
+ setShowPlan: A,
25
+ lighting: b,
26
+ setLighting: E,
27
+ sunNote: N,
28
+ excavation: p,
29
+ setExcavation: L,
30
+ cityBuildings: m,
31
+ setCityBuildings: B,
32
+ cadastre: v,
33
+ setCadastre: R,
34
+ hasCadastre: D,
35
+ surveyed: O
36
+ } = f;
37
+ return /* @__PURE__ */ a("div", { className: "map-settings", children: [
38
+ /* @__PURE__ */ a("h3", { children: [
39
+ "Map display",
40
+ /* @__PURE__ */ e("button", { className: "icon-button", "aria-label": "Close map settings", onClick: () => P(!1), children: /* @__PURE__ */ e(T, { size: 15 }) })
41
+ ] }),
42
+ /* @__PURE__ */ a("label", { className: "field", children: [
43
+ /* @__PURE__ */ e("span", { children: "Basemap" }),
44
+ /* @__PURE__ */ a(
45
+ "select",
46
+ {
47
+ "aria-label": "Basemap",
48
+ value: M,
49
+ onChange: (t) => k(t.target.value),
50
+ children: [
51
+ /* @__PURE__ */ e("option", { value: "plan", children: "Plan background · offline" }),
52
+ d && /* @__PURE__ */ e("option", { value: "host", children: d.label ?? "Map background" })
53
+ ]
54
+ }
55
+ )
56
+ ] }),
57
+ r && (() => {
58
+ const t = o.buildings.find((l) => {
59
+ var n;
60
+ return l.id === ((n = o.floors.find((s) => s.id === C)) == null ? void 0 : n.buildingId);
61
+ }) ?? o.buildings[0];
62
+ return /* @__PURE__ */ a("label", { className: "field", children: [
63
+ /* @__PURE__ */ a("span", { children: [
64
+ "Exterior finish · ",
65
+ t.name
66
+ ] }),
67
+ /* @__PURE__ */ a(
68
+ "select",
69
+ {
70
+ "aria-label": "Exterior finish",
71
+ value: t.exteriorPreset ?? "",
72
+ onChange: (l) => y((n) => {
73
+ n.buildings.find((s) => s.id === t.id).exteriorPreset = l.target.value || void 0;
74
+ }),
75
+ children: [
76
+ /* @__PURE__ */ e("option", { value: "", children: "Original materials" }),
77
+ Object.entries(X).map(([l, n]) => /* @__PURE__ */ e("option", { value: l, children: n.name }, l))
78
+ ]
79
+ }
80
+ ),
81
+ /* @__PURE__ */ e("small", { children: "Applies to the exterior on every floor." })
82
+ ] });
83
+ })(),
84
+ /* @__PURE__ */ e(
85
+ i,
86
+ {
87
+ label: "Architecture plan",
88
+ description: "Hide to see the basemap under this floor",
89
+ value: g,
90
+ onChange: () => A(!g)
91
+ }
92
+ ),
93
+ /* @__PURE__ */ e(i, { label: "Space labels", value: c, onChange: () => S(!c) }),
94
+ /* @__PURE__ */ e(i, { label: "Camera coverage", value: h, onChange: () => w(!h) }),
95
+ /* @__PURE__ */ e(
96
+ I,
97
+ {
98
+ label: "Sunlight",
99
+ description: b === "auto" ? `Following the sun over this site — ${N}` : "Pinned; switch to Auto to follow the clock",
100
+ value: b,
101
+ options: [
102
+ { value: "auto", label: "Auto", title: "Sun position from this site and the time of day" },
103
+ { value: "day", label: "Day", title: "A fixed afternoon sun" },
104
+ { value: "evening", label: "Dusk", title: "A fixed dusk, with lamps lit" }
105
+ ],
106
+ onChange: E
107
+ }
108
+ ),
109
+ /* @__PURE__ */ e(
110
+ i,
111
+ {
112
+ label: "Ground section",
113
+ description: "Cut the earth away around below-grade floors",
114
+ value: p,
115
+ onChange: () => L(!p)
116
+ }
117
+ ),
118
+ /* @__PURE__ */ e(
119
+ i,
120
+ {
121
+ label: "3D city buildings",
122
+ description: "Raise surrounding basemap buildings by their MML attributes",
123
+ value: m,
124
+ onChange: () => B(!m)
125
+ }
126
+ ),
127
+ D && /* @__PURE__ */ e(
128
+ i,
129
+ {
130
+ label: "Property boundaries",
131
+ description: "MML cadastral parcel overlay",
132
+ value: v,
133
+ onChange: () => R(!v)
134
+ }
135
+ ),
136
+ r && /* @__PURE__ */ e(i, { label: "Snap to geometry & grid", value: u, onChange: () => x(!u) }),
137
+ /* @__PURE__ */ e("p", { className: "helper", children: O ? "Vector map background; attribution is shown on the map." : "A quiet background for detailed floor planning." })
138
+ ] });
139
+ }
140
+ export {
141
+ G as MapSettings
142
+ };
143
+ //# sourceMappingURL=MapSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapSettings.js","sources":["../../../../src/planner/MapSettings.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { Choice, Toggle } from '../components/controls';\nimport type { BasemapConfig } from '../model/host';\nimport { EXTERIOR_PRESETS, type ExteriorPreset } from '../model/materials';\nimport type { ProjectDocument } from '../model/types';\nimport type { CommitProject } from './types';\nimport type { useMapDisplay } from './useMapDisplay';\n\ninterface MapSettingsProps {\n display: ReturnType<typeof useMapDisplay>;\n project: ProjectDocument;\n floorId: string | null;\n editing: boolean;\n hostBasemap?: BasemapConfig;\n commit: CommitProject;\n snapping: boolean;\n setSnapping: (enabled: boolean) => void;\n}\n\nexport function MapSettings({\n display,\n project,\n floorId,\n editing,\n hostBasemap,\n commit,\n snapping,\n setSnapping,\n}: MapSettingsProps) {\n const {\n coverage,\n setCoverage,\n showLabels,\n setShowLabels,\n basemapMode,\n setBasemapMode,\n setSettings,\n showPlan,\n setShowPlan,\n lighting,\n setLighting,\n sunNote,\n excavation,\n setExcavation,\n cityBuildings,\n setCityBuildings,\n cadastre,\n setCadastre,\n hasCadastre,\n surveyed,\n } = display;\n return (\n <div className=\"map-settings\">\n <h3>\n Map display\n <button className=\"icon-button\" aria-label=\"Close map settings\" onClick={() => setSettings(false)}>\n <X size={15} />\n </button>\n </h3>\n <label className=\"field\">\n <span>Basemap</span>\n <select\n aria-label=\"Basemap\"\n value={basemapMode}\n onChange={e => setBasemapMode(e.target.value as typeof basemapMode)}\n >\n <option value=\"plan\">Plan background · offline</option>\n {hostBasemap && <option value=\"host\">{hostBasemap.label ?? 'Map background'}</option>}\n </select>\n </label>\n {editing &&\n (() => {\n const building =\n project.buildings.find(b => b.id === project.floors.find(f => f.id === floorId)?.buildingId) ??\n project.buildings[0];\n return (\n <label className=\"field\">\n <span>Exterior finish · {building.name}</span>\n <select\n aria-label=\"Exterior finish\"\n value={building.exteriorPreset ?? ''}\n onChange={e =>\n commit(p => {\n p.buildings.find(b => b.id === building.id)!.exteriorPreset = (e.target.value || undefined) as\n | ExteriorPreset\n | undefined;\n })\n }\n >\n <option value=\"\">Original materials</option>\n {Object.entries(EXTERIOR_PRESETS).map(([id, preset]) => (\n <option key={id} value={id}>\n {preset.name}\n </option>\n ))}\n </select>\n <small>Applies to the exterior on every floor.</small>\n </label>\n );\n })()}\n <Toggle\n label=\"Architecture plan\"\n description=\"Hide to see the basemap under this floor\"\n value={showPlan}\n onChange={() => setShowPlan(!showPlan)}\n />\n <Toggle label=\"Space labels\" value={showLabels} onChange={() => setShowLabels(!showLabels)} />\n <Toggle label=\"Camera coverage\" value={coverage} onChange={() => setCoverage(!coverage)} />\n <Choice\n label=\"Sunlight\"\n description={\n lighting === 'auto'\n ? `Following the sun over this site — ${sunNote}`\n : 'Pinned; switch to Auto to follow the clock'\n }\n value={lighting}\n options={[\n { value: 'auto', label: 'Auto', title: 'Sun position from this site and the time of day' },\n { value: 'day', label: 'Day', title: 'A fixed afternoon sun' },\n { value: 'evening', label: 'Dusk', title: 'A fixed dusk, with lamps lit' },\n ]}\n onChange={setLighting}\n />\n <Toggle\n label=\"Ground section\"\n description=\"Cut the earth away around below-grade floors\"\n value={excavation}\n onChange={() => setExcavation(!excavation)}\n />\n <Toggle\n label=\"3D city buildings\"\n description=\"Raise surrounding basemap buildings by their MML attributes\"\n value={cityBuildings}\n onChange={() => setCityBuildings(!cityBuildings)}\n />\n {hasCadastre && (\n <Toggle\n label=\"Property boundaries\"\n description=\"MML cadastral parcel overlay\"\n value={cadastre}\n onChange={() => setCadastre(!cadastre)}\n />\n )}\n {editing && <Toggle label=\"Snap to geometry & grid\" value={snapping} onChange={() => setSnapping(!snapping)} />}\n <p className=\"helper\">\n {surveyed\n ? 'Vector map background; attribution is shown on the map.'\n : 'A quiet background for detailed floor planning.'}\n </p>\n </div>\n );\n}\n"],"names":["MapSettings","display","project","floorId","editing","hostBasemap","commit","snapping","setSnapping","coverage","setCoverage","showLabels","setShowLabels","basemapMode","setBasemapMode","setSettings","showPlan","setShowPlan","lighting","setLighting","sunNote","excavation","setExcavation","cityBuildings","setCityBuildings","cadastre","setCadastre","hasCadastre","surveyed","jsxs","jsx","X","e","building","b","_a","f","p","EXTERIOR_PRESETS","id","preset","Toggle","Choice"],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { jsx as e, jsxs as a } from "react/jsx-runtime";
2
+ import { Modal as n } from "../components/controls.js";
3
+ function s({ onClose: o }) {
4
+ return /* @__PURE__ */ e(
5
+ n,
6
+ {
7
+ title: "A few tools. A whole new perspective.",
8
+ subtitle: "Everything you need to model and monitor your site.",
9
+ onClose: o,
10
+ children: /* @__PURE__ */ a("div", { className: "help-content", children: [
11
+ /* @__PURE__ */ e("h3", { children: "Start with your sources" }),
12
+ /* @__PURE__ */ e("p", { children: "Import footprint GeoJSON or an architectural PNG, JPEG, or PDF. Align two image points to two map points, then trace walls and zones. Choose a drawing in Reference drawings to fine-tune its position." }),
13
+ /* @__PURE__ */ e("h3", { children: "Connected by design" }),
14
+ /* @__PURE__ */ e("p", { children: "Rooms follow shared walls and virtual boundaries. New spaces need at least 1 m² of usable area. Doors and windows attach to walls; gates attach to fences. Select an area and use “Cut a hole” for courtyards or exclusions. Parent zones must contain their children." }),
15
+ /* @__PURE__ */ e("h3", { children: "Explore and monitor" }),
16
+ /* @__PURE__ */ e("p", { children: "Switch to 3D for a floor cutaway or a building stack. Basement cutaways rebase the view while preserving saved elevations. Select any bound object to inspect its live status." }),
17
+ /* @__PURE__ */ e("div", { className: "shortcut-grid", children: [
18
+ ["1 · 2 · 4", "Viewer · Editor · Live"],
19
+ ["3", "Walk through at eye level"],
20
+ ["T", "2D / 3D / Walk"],
21
+ ["X", "Cutaway / all floors"],
22
+ ["⇧ ↑ / ⇧ ↓", "Floor up / down"],
23
+ ["⇧ ← / ⇧ →", "Rotate map"],
24
+ ["↑ ↓ ← →", "Pan map · walk and turn"],
25
+ ["W A S D", "Pan in 2D · walk and turn in POV"],
26
+ ["⇧ W / ⇧ S", "Tilt 3D camera"],
27
+ ["N", "Dark / light mode"],
28
+ ["B", "Side panel"],
29
+ ["I", "Properties panel"],
30
+ ["G", "Navigate & directions"],
31
+ ["F", "Full-screen map"],
32
+ ["⇧ (hold)", "Show shortcuts"],
33
+ ["V", "Select"],
34
+ ["H", "Pan"],
35
+ ["W / D / S", "Drawing: wall / door / split (while a drawing tool is active)"],
36
+ ["C", "Camera"],
37
+ ["Z", "Zone"],
38
+ ["M", "Measure"],
39
+ ["Enter", "Finish drawing"],
40
+ ["Esc", "Close panel / cancel"],
41
+ ["⌘/Ctrl Z", "Undo"],
42
+ ["⌘/Ctrl ⇧ Z", "Redo"],
43
+ ["⌘/Ctrl D", "Duplicate"],
44
+ ["⌘/Ctrl S", "Export"]
45
+ ].map(([t, r]) => /* @__PURE__ */ a("div", { children: [
46
+ /* @__PURE__ */ e("span", { children: r }),
47
+ /* @__PURE__ */ e("kbd", { children: t })
48
+ ] }, t)) }),
49
+ /* @__PURE__ */ e("p", { className: "helper", children: "Projects save in this browser. Export a portable JSON backup to move projects and their reference drawings between them." })
50
+ ] })
51
+ }
52
+ );
53
+ }
54
+ export {
55
+ s as PlannerHelp
56
+ };
57
+ //# sourceMappingURL=PlannerHelp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlannerHelp.js","sources":["../../../../src/planner/PlannerHelp.tsx"],"sourcesContent":["import { Modal } from '../components/controls';\n\nexport function PlannerHelp({ onClose }: { onClose: () => void }) {\n return (\n <Modal\n title=\"A few tools. A whole new perspective.\"\n subtitle=\"Everything you need to model and monitor your site.\"\n onClose={onClose}\n >\n <div className=\"help-content\">\n <h3>Start with your sources</h3>\n <p>\n Import footprint GeoJSON or an architectural PNG, JPEG, or PDF. Align two image points to two map points, then\n trace walls and zones. Choose a drawing in Reference drawings to fine-tune its position.\n </p>\n <h3>Connected by design</h3>\n <p>\n Rooms follow shared walls and virtual boundaries. New spaces need at least 1 m² of usable area. Doors and\n windows attach to walls; gates attach to fences. Select an area and use “Cut a hole” for courtyards or\n exclusions. Parent zones must contain their children.\n </p>\n <h3>Explore and monitor</h3>\n <p>\n Switch to 3D for a floor cutaway or a building stack. Basement cutaways rebase the view while preserving saved\n elevations. Select any bound object to inspect its live status.\n </p>\n <div className=\"shortcut-grid\">\n {[\n ['1 · 2 · 4', 'Viewer · Editor · Live'],\n ['3', 'Walk through at eye level'],\n ['T', '2D / 3D / Walk'],\n ['X', 'Cutaway / all floors'],\n ['⇧ ↑ / ⇧ ↓', 'Floor up / down'],\n ['⇧ ← / ⇧ →', 'Rotate map'],\n ['↑ ↓ ← →', 'Pan map · walk and turn'],\n ['W A S D', 'Pan in 2D · walk and turn in POV'],\n ['⇧ W / ⇧ S', 'Tilt 3D camera'],\n ['N', 'Dark / light mode'],\n ['B', 'Side panel'],\n ['I', 'Properties panel'],\n ['G', 'Navigate & directions'],\n ['F', 'Full-screen map'],\n ['⇧ (hold)', 'Show shortcuts'],\n ['V', 'Select'],\n ['H', 'Pan'],\n ['W / D / S', 'Drawing: wall / door / split (while a drawing tool is active)'],\n ['C', 'Camera'],\n ['Z', 'Zone'],\n ['M', 'Measure'],\n ['Enter', 'Finish drawing'],\n ['Esc', 'Close panel / cancel'],\n ['⌘/Ctrl Z', 'Undo'],\n ['⌘/Ctrl ⇧ Z', 'Redo'],\n ['⌘/Ctrl D', 'Duplicate'],\n ['⌘/Ctrl S', 'Export'],\n ].map(([key, name]) => (\n <div key={key}>\n <span>{name}</span>\n <kbd>{key}</kbd>\n </div>\n ))}\n </div>\n <p className=\"helper\">\n Projects save in this browser. Export a portable JSON backup to move projects and their reference drawings\n between them.\n </p>\n </div>\n </Modal>\n );\n}\n"],"names":["PlannerHelp","onClose","jsx","Modal","jsxs","key","name"],"mappings":";;AAEO,SAASA,EAAY,EAAE,SAAAC,KAAoC;AAChE,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,UAAS;AAAA,MACT,SAAAF;AAAA,MAEA,UAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,QAAG,UAAA,0BAAA,CAAuB;AAAA,QAC3B,gBAAAA,EAAC,OAAE,UAAA,0MAAA,CAGH;AAAA,QACA,gBAAAA,EAAC,QAAG,UAAA,sBAAA,CAAmB;AAAA,QACvB,gBAAAA,EAAC,OAAE,UAAA,yQAAA,CAIH;AAAA,QACA,gBAAAA,EAAC,QAAG,UAAA,sBAAA,CAAmB;AAAA,QACvB,gBAAAA,EAAC,OAAE,UAAA,iLAAA,CAGH;AAAA,QACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAA;AAAA,UACC,CAAC,aAAa,wBAAwB;AAAA,UACtC,CAAC,KAAK,2BAA2B;AAAA,UACjC,CAAC,KAAK,gBAAgB;AAAA,UACtB,CAAC,KAAK,sBAAsB;AAAA,UAC5B,CAAC,aAAa,iBAAiB;AAAA,UAC/B,CAAC,aAAa,YAAY;AAAA,UAC1B,CAAC,WAAW,yBAAyB;AAAA,UACrC,CAAC,WAAW,kCAAkC;AAAA,UAC9C,CAAC,aAAa,gBAAgB;AAAA,UAC9B,CAAC,KAAK,mBAAmB;AAAA,UACzB,CAAC,KAAK,YAAY;AAAA,UAClB,CAAC,KAAK,kBAAkB;AAAA,UACxB,CAAC,KAAK,uBAAuB;AAAA,UAC7B,CAAC,KAAK,iBAAiB;AAAA,UACvB,CAAC,YAAY,gBAAgB;AAAA,UAC7B,CAAC,KAAK,QAAQ;AAAA,UACd,CAAC,KAAK,KAAK;AAAA,UACX,CAAC,aAAa,+DAA+D;AAAA,UAC7E,CAAC,KAAK,QAAQ;AAAA,UACd,CAAC,KAAK,MAAM;AAAA,UACZ,CAAC,KAAK,SAAS;AAAA,UACf,CAAC,SAAS,gBAAgB;AAAA,UAC1B,CAAC,OAAO,sBAAsB;AAAA,UAC9B,CAAC,YAAY,MAAM;AAAA,UACnB,CAAC,cAAc,MAAM;AAAA,UACrB,CAAC,YAAY,WAAW;AAAA,UACxB,CAAC,YAAY,QAAQ;AAAA,QAAA,EACrB,IAAI,CAAC,CAACG,GAAKC,CAAI,wBACd,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAJ,EAAC,UAAM,UAAAI,EAAA,CAAK;AAAA,UACZ,gBAAAJ,EAAC,SAAK,UAAAG,EAAA,CAAI;AAAA,QAAA,KAFFA,CAGV,CACD,GACH;AAAA,QACA,gBAAAH,EAAC,KAAA,EAAE,WAAU,UAAS,UAAA,2HAAA,CAGtB;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}
@@ -0,0 +1,246 @@
1
+ import { jsxs as l, jsx as e, Fragment as y } from "react/jsx-runtime";
2
+ import { ArrowLeft as G, Building2 as x, MapPin as M, ChevronDown as P, Compass as W, ChevronRight as A, Plus as p, Leaf as J, Copy as R, FileImage as F, Search as q, Settings2 as H } from "lucide-react";
3
+ import { useState as L } from "react";
4
+ import { statusTone as Q } from "../adapters/status.js";
5
+ import { EntityIcon as U } from "../components/Icons.js";
6
+ import { useStrings as V } from "../theme/index.js";
7
+ import { floorCode as X } from "./floors.js";
8
+ function ae() {
9
+ const [o, a] = L(""), [n, t] = L(/* @__PURE__ */ new Set());
10
+ return { search: o, setSearch: a, collapsedBuildings: n, setCollapsedBuildings: t };
11
+ }
12
+ function se({
13
+ state: o,
14
+ project: a,
15
+ floorId: n,
16
+ selected: t,
17
+ mode: g,
18
+ editing: c,
19
+ readOnly: B,
20
+ statuses: O,
21
+ alarmFloors: N,
22
+ activeTab: h,
23
+ setActiveTab: v,
24
+ leave: f,
25
+ select: k,
26
+ changeFloor: w,
27
+ onAnchor: $,
28
+ onAddFloor: D,
29
+ onDuplicateFloor: E,
30
+ onImportReference: C
31
+ }) {
32
+ var S;
33
+ const z = V(), m = a.floors.find((i) => i.id === n), { search: d, setSearch: I, collapsedBuildings: K, setCollapsedBuildings: j } = o, u = a.objects.filter(
34
+ (i) => (d ? i.name.toLowerCase().includes(d.toLowerCase()) : i.floorId === n || i.kind === "building") && i.kind !== "window"
35
+ );
36
+ return /* @__PURE__ */ l("aside", { className: "sidebar", children: [
37
+ /* @__PURE__ */ l("button", { className: "back-link", onClick: f, children: [
38
+ /* @__PURE__ */ e(G, { size: 14 }),
39
+ "All spaces"
40
+ ] }),
41
+ /* @__PURE__ */ l("div", { className: "site-card", children: [
42
+ /* @__PURE__ */ e("div", { className: "site-icon", children: /* @__PURE__ */ e(x, { size: 24 }) }),
43
+ /* @__PURE__ */ l("div", { children: [
44
+ /* @__PURE__ */ e("h1", { children: a.name }),
45
+ /* @__PURE__ */ l("span", { children: [
46
+ /* @__PURE__ */ e(M, { size: 11 }),
47
+ (S = a.description.split("·").at(-1)) == null ? void 0 : S.trim()
48
+ ] })
49
+ ] }),
50
+ /* @__PURE__ */ e("button", { className: "icon-button", "aria-label": "Switch project", onClick: f, children: /* @__PURE__ */ e(P, { size: 15 }) })
51
+ ] }),
52
+ /* @__PURE__ */ l("div", { className: "site-badge", children: [
53
+ /* @__PURE__ */ e("span", {}),
54
+ "WORKSPACE",
55
+ /* @__PURE__ */ l("span", { className: "badge-right", children: [
56
+ a.buildings.length,
57
+ " building",
58
+ a.buildings.length > 1 ? "s" : ""
59
+ ] })
60
+ ] }),
61
+ /* @__PURE__ */ l("div", { className: "sidebar-tabs", children: [
62
+ /* @__PURE__ */ e("button", { className: h === "structure" ? "active" : "", onClick: () => v("structure"), children: "Structure" }),
63
+ /* @__PURE__ */ l("button", { className: h === "objects" ? "active" : "", onClick: () => v("objects"), children: [
64
+ "Objects",
65
+ /* @__PURE__ */ e("span", { children: a.objects.filter((i) => i.kind !== "window").length })
66
+ ] })
67
+ ] }),
68
+ /* @__PURE__ */ e("div", { className: "sidebar-scroll", children: h === "structure" ? /* @__PURE__ */ l(y, { children: [
69
+ !B && /* @__PURE__ */ l(
70
+ "button",
71
+ {
72
+ className: "anchor-entry",
73
+ title: "Where the plan is pinned and which way it faces",
74
+ onClick: $,
75
+ children: [
76
+ /* @__PURE__ */ e(W, { size: 16 }),
77
+ /* @__PURE__ */ l("span", { children: [
78
+ "Site anchor",
79
+ /* @__PURE__ */ l("small", { children: [
80
+ (a.origin[2] ?? 0).toFixed(1),
81
+ "° · ",
82
+ a.origin[1].toFixed(5),
83
+ ",",
84
+ " ",
85
+ a.origin[0].toFixed(5)
86
+ ] })
87
+ ] }),
88
+ /* @__PURE__ */ e(A, { size: 15 })
89
+ ]
90
+ }
91
+ ),
92
+ /* @__PURE__ */ l("div", { className: "section-label", children: [
93
+ z.floors,
94
+ c && /* @__PURE__ */ e("button", { className: "icon-button", "aria-label": "Add floor", onClick: D, children: /* @__PURE__ */ e(p, { size: 15 }) })
95
+ ] }),
96
+ /* @__PURE__ */ l(
97
+ "button",
98
+ {
99
+ className: `floor-item outdoor ${n === null ? "active" : ""}`,
100
+ onClick: () => w(null),
101
+ children: [
102
+ /* @__PURE__ */ e(J, { size: 17 }),
103
+ /* @__PURE__ */ l("span", { children: [
104
+ "Outdoor site",
105
+ /* @__PURE__ */ e("small", { children: "Perimeters & surroundings" })
106
+ ] })
107
+ ]
108
+ }
109
+ ),
110
+ a.buildings.map((i) => {
111
+ const b = !K.has(i.id);
112
+ return /* @__PURE__ */ l("div", { className: "building-group", children: [
113
+ /* @__PURE__ */ l(
114
+ "button",
115
+ {
116
+ className: "building-label",
117
+ "aria-expanded": b,
118
+ onClick: () => j((s) => {
119
+ const r = new Set(s);
120
+ return r.has(i.id) ? r.delete(i.id) : r.add(i.id), r;
121
+ }),
122
+ children: [
123
+ /* @__PURE__ */ e(x, { size: 13 }),
124
+ i.name,
125
+ g !== "view" && a.floors.some((s) => s.buildingId === i.id && N.has(s.id)) && /* @__PURE__ */ e("span", { className: "floor-alarm", title: "Active alarm in this building" }),
126
+ /* @__PURE__ */ e("span", { className: "building-count", children: a.floors.filter((s) => s.buildingId === i.id).length }),
127
+ b ? /* @__PURE__ */ e(P, { size: 13 }) : /* @__PURE__ */ e(A, { size: 13 })
128
+ ]
129
+ }
130
+ ),
131
+ b && a.floors.filter((s) => s.buildingId === i.id).sort((s, r) => r.elevation - s.elevation).map((s) => /* @__PURE__ */ l(
132
+ "button",
133
+ {
134
+ className: `floor-item ${n === s.id ? "active" : ""}`,
135
+ onClick: () => w(s.id),
136
+ children: [
137
+ /* @__PURE__ */ e("span", { className: "floor-number", children: X(a, s) }),
138
+ /* @__PURE__ */ l("span", { children: [
139
+ s.name,
140
+ /* @__PURE__ */ l("small", { children: [
141
+ s.elevation.toFixed(1),
142
+ " m elevation"
143
+ ] })
144
+ ] }),
145
+ g !== "view" && N.has(s.id) && /* @__PURE__ */ e("span", { className: "floor-alarm", title: "Active alarm on this floor" }),
146
+ n === s.id && /* @__PURE__ */ e("span", { className: "active-floor-dot" })
147
+ ]
148
+ },
149
+ s.id
150
+ ))
151
+ ] }, i.id);
152
+ }),
153
+ c && n && /* @__PURE__ */ l("button", { className: "duplicate-floor", onClick: E, children: [
154
+ /* @__PURE__ */ e(R, { size: 13 }),
155
+ "Duplicate current floor"
156
+ ] }),
157
+ /* @__PURE__ */ l("div", { className: "section-label drawings-heading", children: [
158
+ z.drawings,
159
+ c && /* @__PURE__ */ e(
160
+ "button",
161
+ {
162
+ className: "icon-button",
163
+ "aria-label": "Import reference drawing",
164
+ onClick: () => C(),
165
+ children: /* @__PURE__ */ e(p, { size: 15 })
166
+ }
167
+ )
168
+ ] }),
169
+ a.drawings.filter((i) => i.floorId === n).length ? a.drawings.filter((i) => i.floorId === n).map((i) => /* @__PURE__ */ l(
170
+ "button",
171
+ {
172
+ className: `drawing-item ${t === i.id ? "active" : ""}`,
173
+ onClick: () => k(i.id),
174
+ children: [
175
+ /* @__PURE__ */ e(F, { size: 18 }),
176
+ /* @__PURE__ */ l("span", { children: [
177
+ i.name,
178
+ /* @__PURE__ */ l("small", { children: [
179
+ i.locked ? "Locked" : "Aligned reference",
180
+ " · ",
181
+ Math.round(i.opacity * 100),
182
+ "%"
183
+ ] })
184
+ ] })
185
+ ]
186
+ },
187
+ i.id
188
+ )) : /* @__PURE__ */ l("button", { className: "empty-drawings", onClick: () => c && C(), children: [
189
+ /* @__PURE__ */ l("div", { children: [
190
+ /* @__PURE__ */ e(F, { size: 20 }),
191
+ /* @__PURE__ */ e(p, { size: 12 })
192
+ ] }),
193
+ /* @__PURE__ */ e("strong", { children: "Add a floor drawing" }),
194
+ /* @__PURE__ */ e("span", { children: "Align a plan. Trace your space." }),
195
+ /* @__PURE__ */ e("small", { children: "PNG, JPEG or PDF" })
196
+ ] })
197
+ ] }) : /* @__PURE__ */ l(y, { children: [
198
+ /* @__PURE__ */ l("label", { className: "object-search", children: [
199
+ /* @__PURE__ */ e(q, { size: 15 }),
200
+ /* @__PURE__ */ e(
201
+ "input",
202
+ {
203
+ "aria-label": "Search objects",
204
+ placeholder: "Find a space or object…",
205
+ value: d,
206
+ onChange: (i) => I(i.target.value)
207
+ }
208
+ )
209
+ ] }),
210
+ /* @__PURE__ */ l("div", { className: "section-label", children: [
211
+ d ? "Search all floors" : (m == null ? void 0 : m.name) ?? "Outdoor objects",
212
+ /* @__PURE__ */ e("span", { children: u.length })
213
+ ] }),
214
+ u.map((i) => /* @__PURE__ */ l(
215
+ "button",
216
+ {
217
+ className: `object-row list-object ${t === i.id ? "active" : ""}`,
218
+ onClick: () => k(i.id, !0),
219
+ children: [
220
+ /* @__PURE__ */ e(U, { kind: i.kind, symbol: i.symbol, travel: i.travel }),
221
+ /* @__PURE__ */ l("span", { children: [
222
+ i.name,
223
+ /* @__PURE__ */ e("small", { children: i.kind })
224
+ ] }),
225
+ i.feedId && /* @__PURE__ */ e("span", { className: `status-dot ${Q(O.get(i.feedId))}` })
226
+ ]
227
+ },
228
+ i.id
229
+ )),
230
+ !u.length && /* @__PURE__ */ e("p", { className: "helper padded", children: "No matching objects." })
231
+ ] }) }),
232
+ /* @__PURE__ */ l("div", { className: "sidebar-footer", children: [
233
+ /* @__PURE__ */ e("span", { className: "workspace-avatar", children: "K" }),
234
+ /* @__PURE__ */ l("div", { children: [
235
+ /* @__PURE__ */ e("strong", { children: "Kerros workspace" }),
236
+ /* @__PURE__ */ e("small", { children: "Local prototype" })
237
+ ] }),
238
+ /* @__PURE__ */ e(H, { size: 16 })
239
+ ] })
240
+ ] });
241
+ }
242
+ export {
243
+ se as ProjectSidebar,
244
+ ae as useProjectSidebar
245
+ };
246
+ //# sourceMappingURL=ProjectSidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectSidebar.js","sources":["../../../../src/planner/ProjectSidebar.tsx"],"sourcesContent":["import {\n ArrowLeft,\n Building2,\n ChevronDown,\n ChevronRight,\n Compass,\n Copy,\n FileImage,\n Leaf,\n MapPin,\n Plus,\n Search,\n Settings2,\n} from 'lucide-react';\nimport { useState } from 'react';\nimport { statusTone } from '../adapters/status';\nimport { EntityIcon } from '../components/Icons';\nimport type { PlannerMode } from '../model/host';\nimport type { StatusReading } from '../model/live';\nimport type { ProjectDocument } from '../model/types';\nimport { useStrings } from '../theme';\nimport { floorCode } from './floors';\n\ninterface ProjectSidebarProps {\n state: ReturnType<typeof useProjectSidebar>;\n project: ProjectDocument;\n floorId: string | null;\n selected: string | null;\n mode: PlannerMode;\n editing: boolean;\n readOnly: boolean;\n statuses: Map<string, StatusReading>;\n alarmFloors: Set<string | null>;\n activeTab: 'structure' | 'objects';\n setActiveTab: (tab: 'structure' | 'objects') => void;\n leave: () => void;\n select: (id: string | null, focus?: boolean) => void;\n changeFloor: (id: string | null) => void;\n onAnchor: () => void;\n onAddFloor: () => void;\n onDuplicateFloor: () => void;\n onImportReference: () => void;\n}\n\n// Owned by the planner so closing the panel preserves the current search and expansion.\nexport function useProjectSidebar() {\n const [search, setSearch] = useState('');\n const [collapsedBuildings, setCollapsedBuildings] = useState<Set<string>>(new Set());\n return { search, setSearch, collapsedBuildings, setCollapsedBuildings };\n}\n\n/** Project browsing chrome, with search and collapsed groups local to the sidebar. */\nexport function ProjectSidebar({\n state,\n project,\n floorId,\n selected,\n mode,\n editing,\n readOnly,\n statuses,\n alarmFloors,\n activeTab,\n setActiveTab,\n leave,\n select,\n changeFloor,\n onAnchor,\n onAddFloor,\n onDuplicateFloor,\n onImportReference,\n}: ProjectSidebarProps) {\n const en = useStrings();\n const floor = project.floors.find(f => f.id === floorId);\n const { search, setSearch, collapsedBuildings, setCollapsedBuildings } = state;\n const filteredObjects = project.objects.filter(\n o =>\n (search ? o.name.toLowerCase().includes(search.toLowerCase()) : o.floorId === floorId || o.kind === 'building') &&\n o.kind !== 'window',\n );\n return (\n <aside className=\"sidebar\">\n <button className=\"back-link\" onClick={leave}>\n <ArrowLeft size={14} />\n All spaces\n </button>\n <div className=\"site-card\">\n <div className=\"site-icon\">\n <Building2 size={24} />\n </div>\n <div>\n <h1>{project.name}</h1>\n <span>\n <MapPin size={11} />\n {project.description.split('·').at(-1)?.trim()}\n </span>\n </div>\n <button className=\"icon-button\" aria-label=\"Switch project\" onClick={leave}>\n <ChevronDown size={15} />\n </button>\n </div>\n <div className=\"site-badge\">\n <span />\n WORKSPACE\n <span className=\"badge-right\">\n {project.buildings.length} building{project.buildings.length > 1 ? 's' : ''}\n </span>\n </div>\n <div className=\"sidebar-tabs\">\n <button className={activeTab === 'structure' ? 'active' : ''} onClick={() => setActiveTab('structure')}>\n Structure\n </button>\n <button className={activeTab === 'objects' ? 'active' : ''} onClick={() => setActiveTab('objects')}>\n Objects<span>{project.objects.filter(o => o.kind !== 'window').length}</span>\n </button>\n </div>\n <div className=\"sidebar-scroll\">\n {activeTab === 'structure' ? (\n <>\n {!readOnly && (\n <button\n className=\"anchor-entry\"\n title=\"Where the plan is pinned and which way it faces\"\n onClick={onAnchor}\n >\n <Compass size={16} />\n <span>\n Site anchor\n <small>\n {(project.origin[2] ?? 0).toFixed(1)}° · {project.origin[1].toFixed(5)},{' '}\n {project.origin[0].toFixed(5)}\n </small>\n </span>\n <ChevronRight size={15} />\n </button>\n )}\n <div className=\"section-label\">\n {en.floors}\n {editing && (\n <button className=\"icon-button\" aria-label=\"Add floor\" onClick={onAddFloor}>\n <Plus size={15} />\n </button>\n )}\n </div>\n <button\n className={`floor-item outdoor ${floorId === null ? 'active' : ''}`}\n onClick={() => changeFloor(null)}\n >\n <Leaf size={17} />\n <span>\n Outdoor site<small>Perimeters & surroundings</small>\n </span>\n </button>\n {project.buildings.map(building => {\n const open = !collapsedBuildings.has(building.id);\n return (\n <div className=\"building-group\" key={building.id}>\n <button\n className=\"building-label\"\n aria-expanded={open}\n onClick={() =>\n setCollapsedBuildings(prev => {\n const next = new Set(prev);\n if (next.has(building.id)) next.delete(building.id);\n else next.add(building.id);\n return next;\n })\n }\n >\n <Building2 size={13} />\n {building.name}\n {mode !== 'view' &&\n project.floors.some(f => f.buildingId === building.id && alarmFloors.has(f.id)) && (\n <span className=\"floor-alarm\" title=\"Active alarm in this building\" />\n )}\n <span className=\"building-count\">\n {project.floors.filter(f => f.buildingId === building.id).length}\n </span>\n {open ? <ChevronDown size={13} /> : <ChevronRight size={13} />}\n </button>\n {open &&\n project.floors\n .filter(f => f.buildingId === building.id)\n .sort((a, b) => b.elevation - a.elevation)\n .map(f => (\n <button\n key={f.id}\n className={`floor-item ${floorId === f.id ? 'active' : ''}`}\n onClick={() => changeFloor(f.id)}\n >\n <span className=\"floor-number\">{floorCode(project, f)}</span>\n <span>\n {f.name}\n <small>{f.elevation.toFixed(1)} m elevation</small>\n </span>\n {mode !== 'view' && alarmFloors.has(f.id) && (\n <span className=\"floor-alarm\" title=\"Active alarm on this floor\" />\n )}\n {floorId === f.id && <span className=\"active-floor-dot\" />}\n </button>\n ))}\n </div>\n );\n })}\n {editing && floorId && (\n <button className=\"duplicate-floor\" onClick={onDuplicateFloor}>\n <Copy size={13} />\n Duplicate current floor\n </button>\n )}\n <div className=\"section-label drawings-heading\">\n {en.drawings}\n {editing && (\n <button\n className=\"icon-button\"\n aria-label=\"Import reference drawing\"\n onClick={() => onImportReference()}\n >\n <Plus size={15} />\n </button>\n )}\n </div>\n {project.drawings.filter(d => d.floorId === floorId).length ? (\n project.drawings\n .filter(d => d.floorId === floorId)\n .map(d => (\n <button\n className={`drawing-item ${selected === d.id ? 'active' : ''}`}\n key={d.id}\n onClick={() => select(d.id)}\n >\n <FileImage size={18} />\n <span>\n {d.name}\n <small>\n {d.locked ? 'Locked' : 'Aligned reference'} · {Math.round(d.opacity * 100)}%\n </small>\n </span>\n </button>\n ))\n ) : (\n <button className=\"empty-drawings\" onClick={() => editing && onImportReference()}>\n <div>\n <FileImage size={20} />\n <Plus size={12} />\n </div>\n <strong>Add a floor drawing</strong>\n <span>Align a plan. Trace your space.</span>\n <small>PNG, JPEG or PDF</small>\n </button>\n )}\n </>\n ) : (\n <>\n <label className=\"object-search\">\n <Search size={15} />\n <input\n aria-label=\"Search objects\"\n placeholder=\"Find a space or object…\"\n value={search}\n onChange={e => setSearch(e.target.value)}\n />\n </label>\n <div className=\"section-label\">\n {search ? 'Search all floors' : (floor?.name ?? 'Outdoor objects')}\n <span>{filteredObjects.length}</span>\n </div>\n {filteredObjects.map(o => (\n <button\n key={o.id}\n className={`object-row list-object ${selected === o.id ? 'active' : ''}`}\n onClick={() => select(o.id, true)}\n >\n <EntityIcon kind={o.kind} symbol={o.symbol} travel={o.travel} />\n <span>\n {o.name}\n <small>{o.kind}</small>\n </span>\n {o.feedId && <span className={`status-dot ${statusTone(statuses.get(o.feedId))}`} />}\n </button>\n ))}\n {!filteredObjects.length && <p className=\"helper padded\">No matching objects.</p>}\n </>\n )}\n </div>\n <div className=\"sidebar-footer\">\n <span className=\"workspace-avatar\">K</span>\n <div>\n <strong>Kerros workspace</strong>\n <small>Local prototype</small>\n </div>\n <Settings2 size={16} />\n </div>\n </aside>\n );\n}\n"],"names":["useProjectSidebar","search","setSearch","useState","collapsedBuildings","setCollapsedBuildings","ProjectSidebar","state","project","floorId","selected","mode","editing","readOnly","statuses","alarmFloors","activeTab","setActiveTab","leave","select","changeFloor","onAnchor","onAddFloor","onDuplicateFloor","onImportReference","en","useStrings","floor","f","filteredObjects","o","jsxs","jsx","ArrowLeft","Building2","MapPin","_a","ChevronDown","Fragment","Compass","ChevronRight","Plus","Leaf","building","open","prev","next","a","b","floorCode","Copy","d","FileImage","Search","e","EntityIcon","statusTone","Settings2"],"mappings":"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"}