@kerros/editor 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.
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 +52 -4
@@ -0,0 +1,1184 @@
1
+ import { jsxs as n, jsx as i, Fragment as I } from "react/jsx-runtime";
2
+ import { useState as Ae } from "react";
3
+ import { X as xe, Layers3 as ue, ShieldCheck as ge, Camera as De, ArrowUpRight as Ue, ChevronRight as H, LockKeyhole as Le, Compass as pe, ArrowUp as Me, ArrowLeft as Te, ArrowRight as W, ArrowDown as Ee, MoreHorizontal as $e, Trash2 as ve, Copy as Oe, Unplug as Re, Eye as fe, Layers as Be } from "lucide-react";
4
+ import { isArea as be, isSpace as Se, isOpening as Pe } from "../model/types.js";
5
+ import { objectArea as Ne, distance as K, objectPosition as ye, barrierEnds as q } from "../model/geometry.js";
6
+ import { entryInto as Ge, zoneSpaces as He } from "../model/ontology.js";
7
+ import { effectivePortals as Fe } from "../model/portals.js";
8
+ import { coverageOf as we } from "../model/coverage.js";
9
+ import { spaceAt as We } from "../model/spaces.js";
10
+ import { statusTone as T, statusLabel as ke } from "../adapters/status.js";
11
+ import { EntityIcon as P } from "./Icons.js";
12
+ import { Field as v, Choice as Ke, Toggle as G } from "./controls.js";
13
+ import { LAMPS as Ce, DEFAULT_LIGHT as D, lampFor as Ve, kelvinColor as Ye } from "../map/lighting.js";
14
+ import { AMBIENCES as Ie } from "../map/ambience.js";
15
+ function qe({
16
+ project: t,
17
+ object: r,
18
+ onSelect: z,
19
+ onFloor: S
20
+ }) {
21
+ var k;
22
+ const f = (a) => {
23
+ var o;
24
+ return ((o = t.objects.find((p) => p.id === a)) == null ? void 0 : o.name) ?? "elsewhere";
25
+ }, F = (a) => {
26
+ var o;
27
+ return ((o = t.floors.find((p) => p.id === a)) == null ? void 0 : o.name) ?? a;
28
+ }, h = [], y = (a) => {
29
+ var o;
30
+ return ((o = t.objects.find((p) => p.id === a)) == null ? void 0 : o.kind) ?? "";
31
+ }, U = Fe(t), l = U.find((a) => a.openingId === r.id);
32
+ if (l)
33
+ for (const a of [l.a, l.b]) {
34
+ const o = a === l.a ? l.b : l.a, p = Ge(l, a);
35
+ h.push({
36
+ key: `p-${a}`,
37
+ icon: /* @__PURE__ */ i(W, { size: 14 }),
38
+ label: f(a),
39
+ detail: p ? `enter from ${f(o)}` : `no way through from ${f(o)}`,
40
+ go: () => z(a)
41
+ });
42
+ }
43
+ if (!l && Pe(r.kind) && r.barrierId) {
44
+ const a = t.barriers.find((o) => o.id === r.barrierId);
45
+ if (a) {
46
+ const [o, p] = q(t, a), w = K(o, p) || 1, O = -(p[1] - o[1]) / w, R = (p[0] - o[0]) / w, L = a.thickness / 2 + 0.35;
47
+ for (const E of [1, -1]) {
48
+ const M = [r.position[0] + O * L * E, r.position[1] + R * L * E], C = We(t, r.floorId, M);
49
+ h.push({
50
+ key: `s-${E}`,
51
+ icon: /* @__PURE__ */ i(W, { size: 14 }),
52
+ label: (C == null ? void 0 : C.name) ?? "Outside any space",
53
+ detail: C ? "on this side of the doorway" : "nothing drawn on this side",
54
+ go: () => C && z(C.id)
55
+ });
56
+ }
57
+ }
58
+ }
59
+ if (r.kind === "camera")
60
+ for (const a of we(t, r))
61
+ h.push({
62
+ key: `c-${a}`,
63
+ icon: /* @__PURE__ */ i(fe, { size: 14 }),
64
+ label: f(a),
65
+ detail: `in view · ${y(a)}`,
66
+ go: () => z(a)
67
+ });
68
+ if ((k = r.servedFloorIds) != null && k.length)
69
+ for (const a of r.servedFloorIds) {
70
+ const o = t.floors.find((p) => p.id === a);
71
+ o && h.push({
72
+ key: `f-${a}`,
73
+ icon: /* @__PURE__ */ i(Be, { size: 14 }),
74
+ label: F(a),
75
+ detail: `${o.elevation.toFixed(1)} m`,
76
+ go: () => S(a)
77
+ });
78
+ }
79
+ if (Se(r.kind))
80
+ for (const a of U) {
81
+ if (a.a !== r.id && a.b !== r.id) continue;
82
+ const o = a.a === r.id ? a.b : a.a, p = a.openingId ? t.objects.find((w) => w.id === a.openingId) : void 0;
83
+ h.push({
84
+ key: `w-${a.id}`,
85
+ icon: /* @__PURE__ */ i(W, { size: 14 }),
86
+ label: f(o),
87
+ detail: p ? p.name ?? p.kind : "open boundary",
88
+ go: () => z(a.openingId ?? o)
89
+ });
90
+ }
91
+ for (const a of t.objects)
92
+ a.kind === "camera" && a.floorId === r.floorId && a.id !== r.id && we(t, a).includes(r.id) && h.push({
93
+ key: `v-${a.id}`,
94
+ icon: /* @__PURE__ */ i(fe, { size: 14 }),
95
+ label: a.name,
96
+ detail: "has this in view",
97
+ go: () => z(a.id)
98
+ });
99
+ const m = (t.zones ?? []).filter((a) => He(t, a).includes(r.id));
100
+ return !h.length && !m.length ? null : /* @__PURE__ */ n("section", { className: "property-section", children: [
101
+ /* @__PURE__ */ i("h3", { children: "Connections" }),
102
+ h.map((a) => /* @__PURE__ */ n("button", { className: "object-row", onClick: a.go, children: [
103
+ a.icon,
104
+ /* @__PURE__ */ n("span", { children: [
105
+ a.label,
106
+ /* @__PURE__ */ i("small", { children: a.detail })
107
+ ] }),
108
+ /* @__PURE__ */ i(H, { size: 15 })
109
+ ] }, a.key)),
110
+ m.map((a) => /* @__PURE__ */ n("p", { className: "helper", children: [
111
+ "In zone ",
112
+ /* @__PURE__ */ i("strong", { children: a.name }),
113
+ a.purpose ? ` · ${a.purpose}` : ""
114
+ ] }, a.id))
115
+ ] });
116
+ }
117
+ function di(t) {
118
+ var Z, j, ee, ie, ne, le, ae, te, oe, re, de, se, ce, he;
119
+ const { project: r, floorId: z, selected: S, statuses: f, monitoring: F, editing: h } = t, y = Fe(r).find((e) => e.openingId === S), U = (e) => {
120
+ var d;
121
+ return ((d = r.objects.find((s) => s.id === e)) == null ? void 0 : d.name) ?? "elsewhere";
122
+ }, l = r.objects.find((e) => e.id === S), m = r.barriers.find((e) => e.id === S), k = (Z = r.virtualBoundaries) == null ? void 0 : Z.find((e) => e.id === S), a = r.drawings.find((e) => e.id === S), o = r.floors.find((e) => e.id === z), p = r.objects.filter((e) => e.floorId === z), w = p.filter((e) => e.feedId), O = r.objects.filter((e) => e.feedId), R = O.filter((e) => T(f.get(e.feedId)) === "critical"), L = w.filter((e) => {
123
+ var d, s;
124
+ return ((s = (d = f.get(e.feedId)) == null ? void 0 : d.metrics) == null ? void 0 : s.occupancy) !== void 0;
125
+ }), E = (e) => e.reduce((d, s) => {
126
+ var c, g;
127
+ return d + (((g = (c = f.get(s.feedId)) == null ? void 0 : c.metrics) == null ? void 0 : g.occupancy) ?? 0);
128
+ }, 0), M = L.map((e) => f.get(e.feedId).metrics.co2).filter((e) => e !== void 0), C = [...L].sort(
129
+ (e, d) => {
130
+ var s, c, g, N;
131
+ return (((c = (s = f.get(d.feedId)) == null ? void 0 : s.metrics) == null ? void 0 : c.occupancy) ?? 0) - (((N = (g = f.get(e.feedId)) == null ? void 0 : g.metrics) == null ? void 0 : N.occupancy) ?? 0);
132
+ }
133
+ )[0], u = l != null && l.feedId ? f.get(l.feedId) : void 0, [$, ze] = Ae(0.5), V = (e) => {
134
+ var s;
135
+ if (!Number.isFinite(e)) return;
136
+ const d = (e % 360 + 360) % 360;
137
+ (s = t.onEdit) == null || s.call(t, (c) => {
138
+ c.origin = d ? [c.origin[0], c.origin[1], d] : [c.origin[0], c.origin[1]];
139
+ });
140
+ }, X = (e) => V((r.origin[2] ?? 0) + e), B = (e, d) => {
141
+ var s;
142
+ return (s = t.onShiftOrigin) == null ? void 0 : s.call(t, e, d);
143
+ }, Q = (e, d) => {
144
+ var c;
145
+ const s = Number(d);
146
+ d.trim() === "" || !Number.isFinite(s) || e === 0 && Math.abs(s) > 180 || e === 1 && Math.abs(s) > 90 || (c = t.onEdit) == null || c.call(t, (g) => {
147
+ const [N, x, me = 0] = g.origin, Y = e === 0 ? [s, x, me] : e === 1 ? [N, s, me] : [N, x, s];
148
+ g.origin = Y[2] ? Y : Y.slice(0, 2);
149
+ });
150
+ }, _ = l ? r.objects.find((e) => {
151
+ var d;
152
+ return e.kind === "camera" && ((d = e.watchedIds) == null ? void 0 : d.includes(l.id));
153
+ }) : void 0, b = (e) => l && t.onUpdateObject(l.id, e), A = (e, d, s, c = "m", g = 0.01, N) => /* @__PURE__ */ i(
154
+ v,
155
+ {
156
+ label: e,
157
+ value: d,
158
+ type: "number",
159
+ suffix: c,
160
+ min: g,
161
+ max: N,
162
+ onChange: (x) => b({ [s]: Number(x) })
163
+ }
164
+ ), J = (l == null ? void 0 : l.name) ?? (m == null ? void 0 : m.name) ?? (a == null ? void 0 : a.name) ?? (k ? "Virtual boundary" : void 0);
165
+ return /* @__PURE__ */ n("aside", { className: "inspector", children: [
166
+ /* @__PURE__ */ n("div", { className: "inspector-top", children: [
167
+ /* @__PURE__ */ i("span", { children: S ? "Properties" : "Space overview" }),
168
+ S ? /* @__PURE__ */ i("button", { className: "icon-button", "aria-label": "Close properties", onClick: t.onClose, children: /* @__PURE__ */ i(xe, { size: 17 }) }) : /* @__PURE__ */ i(ue, { size: 17 })
169
+ ] }),
170
+ /* @__PURE__ */ i("div", { className: "inspector-scroll", children: J ? /* @__PURE__ */ n(I, { children: [
171
+ /* @__PURE__ */ n("div", { className: "object-title", children: [
172
+ /* @__PURE__ */ i("div", { className: `object-avatar ${l ? T(u) : ""}`, children: l ? /* @__PURE__ */ i(P, { kind: l.kind, size: 25, symbol: l.symbol, travel: l.travel }) : m ? /* @__PURE__ */ i(P, { kind: m.kind, size: 25 }) : /* @__PURE__ */ i(ue, { size: 25 }) }),
173
+ /* @__PURE__ */ i("span", { className: "eyebrow", children: (l == null ? void 0 : l.kind) ?? (m == null ? void 0 : m.kind) ?? (k ? "SPACE BOUNDARY" : "REFERENCE DRAWING") }),
174
+ /* @__PURE__ */ i("h2", { children: J }),
175
+ /* @__PURE__ */ i("p", { children: ((j = r.floors.find(
176
+ (e) => e.id === ((l == null ? void 0 : l.floorId) ?? (m == null ? void 0 : m.floorId) ?? (k == null ? void 0 : k.floorId) ?? (a == null ? void 0 : a.floorId))
177
+ )) == null ? void 0 : j.name) ?? "Outdoor site" })
178
+ ] }),
179
+ F && (l == null ? void 0 : l.feedId) && !be(l.kind) && /* @__PURE__ */ n("section", { className: "property-section", children: [
180
+ /* @__PURE__ */ n("div", { className: `status-banner ${T(u)}`, children: [
181
+ /* @__PURE__ */ i(ge, { size: 18 }),
182
+ /* @__PURE__ */ i("strong", { children: ke(u) }),
183
+ /* @__PURE__ */ i("span", { className: "live-pip" })
184
+ ] }),
185
+ /* @__PURE__ */ i("div", { className: "status-grid", children: /* @__PURE__ */ n("div", { children: [
186
+ /* @__PURE__ */ i("span", { children: "Last update" }),
187
+ /* @__PURE__ */ i("strong", { children: u != null && u.timestamp ? new Date(u.timestamp).toLocaleTimeString([], {
188
+ hour: "2-digit",
189
+ minute: "2-digit",
190
+ second: "2-digit"
191
+ }) : "—" })
192
+ ] }) }),
193
+ _ && /* @__PURE__ */ n("p", { className: "helper", children: [
194
+ /* @__PURE__ */ i(De, { size: 13 }),
195
+ " ",
196
+ _.name,
197
+ " covers this ",
198
+ l.kind,
199
+ "."
200
+ ] })
201
+ ] }),
202
+ (u == null ? void 0 : u.metrics) && /* @__PURE__ */ n("section", { className: "property-section", children: [
203
+ /* @__PURE__ */ i("h3", { children: "Environment" }),
204
+ /* @__PURE__ */ n("div", { className: "status-grid", children: [
205
+ u.metrics.occupancy !== void 0 && /* @__PURE__ */ n("div", { children: [
206
+ /* @__PURE__ */ i("span", { children: "People" }),
207
+ /* @__PURE__ */ n("strong", { children: [
208
+ u.metrics.occupancy,
209
+ u.metrics.capacity ? ` / ${u.metrics.capacity}` : ""
210
+ ] })
211
+ ] }),
212
+ u.metrics.co2 !== void 0 && /* @__PURE__ */ n("div", { children: [
213
+ /* @__PURE__ */ i("span", { children: "CO₂" }),
214
+ /* @__PURE__ */ n("strong", { children: [
215
+ u.metrics.co2,
216
+ " ppm"
217
+ ] })
218
+ ] }),
219
+ u.metrics.lux !== void 0 && /* @__PURE__ */ n("div", { children: [
220
+ /* @__PURE__ */ i("span", { children: "Light" }),
221
+ /* @__PURE__ */ n("strong", { children: [
222
+ u.metrics.lux,
223
+ " lx"
224
+ ] })
225
+ ] }),
226
+ u.metrics.temperature !== void 0 && /* @__PURE__ */ n("div", { children: [
227
+ /* @__PURE__ */ i("span", { children: "Temperature" }),
228
+ /* @__PURE__ */ n("strong", { children: [
229
+ u.metrics.temperature,
230
+ " °C"
231
+ ] })
232
+ ] })
233
+ ] }),
234
+ u.metrics.presence !== void 0 && /* @__PURE__ */ i("p", { className: "helper", children: u.metrics.presence ? "Presence detected in this space." : "No presence detected right now." })
235
+ ] }),
236
+ h && l && /* @__PURE__ */ n("section", { className: "property-section", children: [
237
+ /* @__PURE__ */ i("h3", { children: "Object details" }),
238
+ /* @__PURE__ */ i(v, { label: "Name", value: l.name, onChange: (e) => b({ name: e }) }),
239
+ be(l.kind) && /* @__PURE__ */ n(I, { children: [
240
+ /* @__PURE__ */ n("label", { className: "field", children: [
241
+ /* @__PURE__ */ i("span", { children: "Space geometry" }),
242
+ /* @__PURE__ */ n(
243
+ "select",
244
+ {
245
+ "aria-label": "Space geometry",
246
+ value: ((ee = l.geometry) == null ? void 0 : ee.mode) ?? "independent",
247
+ onChange: (e) => {
248
+ var s;
249
+ const d = e.target.value;
250
+ (s = t.onSpaceGeometry) == null || s.call(t, l.id, d === "boundaries" ? "outline" : "independent");
251
+ },
252
+ children: [
253
+ /* @__PURE__ */ i("option", { value: "boundaries", children: "Shared boundaries" }),
254
+ /* @__PURE__ */ i("option", { value: "independent", children: "Independent outline" })
255
+ ]
256
+ }
257
+ )
258
+ ] }),
259
+ /* @__PURE__ */ i("p", { className: "helper", children: ((ie = l.geometry) == null ? void 0 : ie.mode) === "boundaries" ? "Move the boundary handles or walls. Adjacent spaces follow the same boundary." : "This outline stays where you draw it. Connect it to share edits with adjacent spaces." }),
260
+ ((ne = l.geometry) == null ? void 0 : ne.mode) !== "boundaries" && /* @__PURE__ */ i("button", { className: "button secondary", onClick: () => {
261
+ var e;
262
+ return (e = t.onSpaceGeometry) == null ? void 0 : e.call(t, l.id, "walls");
263
+ }, children: "Use surrounding walls" })
264
+ ] }),
265
+ l.feedId !== void 0 || ["door", "gate", "camera", "reader", "turnstile", "elevator"].includes(l.kind) ? /* @__PURE__ */ i(
266
+ v,
267
+ {
268
+ label: "Feed ID",
269
+ value: l.feedId ?? "",
270
+ onChange: (e) => b({ feedId: e || void 0 })
271
+ }
272
+ ) : null,
273
+ ((le = l.geometry) == null ? void 0 : le.mode) !== "boundaries" && /* @__PURE__ */ n("div", { className: "field-grid", children: [
274
+ l.barrierId ? A("Along barrier", l.offset ?? 0, "offset", "m", 0) : /* @__PURE__ */ i(
275
+ v,
276
+ {
277
+ label: "East / X",
278
+ value: l.position[0],
279
+ type: "number",
280
+ suffix: "m",
281
+ onChange: (e) => b({ position: [Number(e), l.position[1]] })
282
+ }
283
+ ),
284
+ l.barrierId ? A("Width", l.width, "width") : /* @__PURE__ */ i(
285
+ v,
286
+ {
287
+ label: "North / Y",
288
+ value: l.position[1],
289
+ type: "number",
290
+ suffix: "m",
291
+ onChange: (e) => b({ position: [l.position[0], Number(e)] })
292
+ }
293
+ )
294
+ ] }),
295
+ !l.barrierId && ((ae = l.geometry) == null ? void 0 : ae.mode) !== "boundaries" && /* @__PURE__ */ n("div", { className: "field-grid", children: [
296
+ A("Width", l.width, "width"),
297
+ A("Depth", l.depth, "depth")
298
+ ] }),
299
+ l.kind === "door" && /* @__PURE__ */ n(I, { children: [
300
+ /* @__PURE__ */ n("label", { className: "field", children: [
301
+ /* @__PURE__ */ i("span", { children: "Door type" }),
302
+ /* @__PURE__ */ n(
303
+ "select",
304
+ {
305
+ value: l.doorType ?? "hinged",
306
+ disabled: !h,
307
+ onChange: (e) => b({ doorType: e.target.value }),
308
+ children: [
309
+ /* @__PURE__ */ i("option", { value: "hinged", children: "Hinged door" }),
310
+ /* @__PURE__ */ i("option", { value: "sliding", children: "Sliding door" }),
311
+ /* @__PURE__ */ i("option", { value: "double", children: "Double-leaf door" })
312
+ ]
313
+ }
314
+ )
315
+ ] }),
316
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
317
+ /* @__PURE__ */ n("label", { className: "field", children: [
318
+ /* @__PURE__ */ i("span", { children: l.doorType === "sliding" ? "Slide direction" : "Door hinge" }),
319
+ /* @__PURE__ */ n(
320
+ "select",
321
+ {
322
+ value: l.doorHinge ?? "left",
323
+ disabled: !h || l.doorType === "double",
324
+ onChange: (e) => b({ doorHinge: e.target.value }),
325
+ children: [
326
+ /* @__PURE__ */ i("option", { value: "left", children: l.doorType === "sliding" ? "Left" : "Left-handed" }),
327
+ /* @__PURE__ */ i("option", { value: "right", children: l.doorType === "sliding" ? "Right" : "Right-handed" })
328
+ ]
329
+ }
330
+ )
331
+ ] }),
332
+ /* @__PURE__ */ n("label", { className: "field", children: [
333
+ /* @__PURE__ */ i("span", { children: "Opening side" }),
334
+ /* @__PURE__ */ n(
335
+ "select",
336
+ {
337
+ value: l.doorSwing ?? 1,
338
+ disabled: !h,
339
+ onChange: (e) => b({ doorSwing: Number(e.target.value) }),
340
+ children: [
341
+ /* @__PURE__ */ i("option", { value: 1, children: "Side A" }),
342
+ /* @__PURE__ */ i("option", { value: -1, children: "Side B" })
343
+ ]
344
+ }
345
+ )
346
+ ] })
347
+ ] }),
348
+ /* @__PURE__ */ i("small", { children: l.doorType === "sliding" ? "Slides along the wall on the selected side. Left is toward the wall’s start; right toward its end." : l.doorType === "double" ? "Two leaves hinge at opposite jambs and open to the selected side." : "Left hinges at the wall’s start; right at its end. Drag across the wall to change the opening side." })
349
+ ] }),
350
+ y && /* @__PURE__ */ n("label", { className: "field", children: [
351
+ /* @__PURE__ */ i("span", { children: "Passage" }),
352
+ /* @__PURE__ */ n(
353
+ "select",
354
+ {
355
+ value: y.passage ?? "both",
356
+ disabled: !h,
357
+ onChange: (e) => {
358
+ var s;
359
+ const d = e.target.value;
360
+ (s = t.onEdit) == null || s.call(t, (c) => {
361
+ var N;
362
+ const g = (N = c.portals) == null ? void 0 : N.find((x) => x.id === y.id);
363
+ g && (g.passage = d === "both" ? void 0 : d);
364
+ });
365
+ },
366
+ children: [
367
+ /* @__PURE__ */ i("option", { value: "both", children: "Both ways" }),
368
+ /* @__PURE__ */ i("option", { value: "a-to-b", children: `Into ${U(y.b)} only` }),
369
+ /* @__PURE__ */ i("option", { value: "b-to-a", children: `Into ${U(y.a)} only` }),
370
+ /* @__PURE__ */ i("option", { value: "none", children: "Sealed" })
371
+ ]
372
+ }
373
+ ),
374
+ /* @__PURE__ */ i("small", { children: `Between ${U(y.a)} and ${U(y.b)}. Routing obeys this — a one-way portal is a one-way edge.` })
375
+ ] }),
376
+ y && /* @__PURE__ */ n("label", { className: "field", children: [
377
+ /* @__PURE__ */ i("span", { children: "Attestation" }),
378
+ /* @__PURE__ */ n(
379
+ "select",
380
+ {
381
+ value: y.attests ?? "assumed",
382
+ disabled: !h,
383
+ onChange: (e) => {
384
+ var s;
385
+ const d = e.target.value;
386
+ (s = t.onEdit) == null || s.call(t, (c) => {
387
+ var N;
388
+ const g = (N = c.portals) == null ? void 0 : N.find((x) => x.id === y.id);
389
+ g && (g.attests = d);
390
+ });
391
+ },
392
+ children: [
393
+ /* @__PURE__ */ i("option", { value: "confirmed", children: "Confirmed — a sensor sees it" }),
394
+ /* @__PURE__ */ i("option", { value: "assumed", children: "Assumed — granted, not watched" }),
395
+ /* @__PURE__ */ i("option", { value: "none", children: "None — a request, not an event" })
396
+ ]
397
+ }
398
+ ),
399
+ /* @__PURE__ */ i("small", { children: "How far a crossing here can be trusted to have happened. Anything counting crossings must ignore portals that attest nothing." })
400
+ ] }),
401
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
402
+ A("Height", l.height, "height", "m", 0),
403
+ !l.barrierId && ((te = l.geometry) == null ? void 0 : te.mode) !== "boundaries" && A("Rotation", l.rotation, "rotation", "°", -360, 360)
404
+ ] }),
405
+ l.rings && /* @__PURE__ */ n("div", { className: "measurement-row", children: [
406
+ /* @__PURE__ */ i("span", { children: "Net area" }),
407
+ /* @__PURE__ */ n("strong", { children: [
408
+ Ne(l).toFixed(1),
409
+ " m²"
410
+ ] })
411
+ ] }),
412
+ l.rings && /* @__PURE__ */ n("label", { className: "field", children: [
413
+ /* @__PURE__ */ i("span", { children: "Fill colour" }),
414
+ /* @__PURE__ */ i(
415
+ "input",
416
+ {
417
+ "aria-label": "Fill colour",
418
+ type: "color",
419
+ value: l.color ?? "#e0e8df",
420
+ onChange: (e) => b({ color: e.target.value })
421
+ }
422
+ )
423
+ ] }),
424
+ l.rings && /* @__PURE__ */ n("label", { className: "field", children: [
425
+ /* @__PURE__ */ i("span", { children: "Parent zone" }),
426
+ /* @__PURE__ */ n(
427
+ "select",
428
+ {
429
+ value: l.parentId ?? "",
430
+ onChange: (e) => b({ parentId: e.target.value || void 0 }),
431
+ children: [
432
+ /* @__PURE__ */ i("option", { value: "", children: "None · independent area" }),
433
+ r.objects.filter((e) => e.id !== l.id && e.floorId === l.floorId && e.kind === "zone").map((e) => /* @__PURE__ */ i("option", { value: e.id, children: e.name }, e.id))
434
+ ]
435
+ }
436
+ )
437
+ ] }),
438
+ l.kind === "poi" && /* @__PURE__ */ n("label", { className: "field", children: [
439
+ /* @__PURE__ */ i("span", { children: "Symbol" }),
440
+ /* @__PURE__ */ n(
441
+ "select",
442
+ {
443
+ value: l.symbol,
444
+ onChange: (e) => b({ symbol: e.target.value }),
445
+ children: [
446
+ /* @__PURE__ */ i("option", { value: "personnel", children: "Personnel entrance" }),
447
+ /* @__PURE__ */ i("option", { value: "service", children: "Service access" }),
448
+ /* @__PURE__ */ i("option", { value: "driveway", children: "Main driveway" }),
449
+ /* @__PURE__ */ i("option", { value: "parking", children: "Parking" }),
450
+ /* @__PURE__ */ i("option", { value: "assembly", children: "Assembly point" }),
451
+ /* @__PURE__ */ i("option", { value: "info", children: "Information" })
452
+ ]
453
+ }
454
+ )
455
+ ] }),
456
+ Se(l.kind) && /* @__PURE__ */ n("label", { className: "field", children: [
457
+ /* @__PURE__ */ i("span", { children: "Ambient sound" }),
458
+ /* @__PURE__ */ n(
459
+ "select",
460
+ {
461
+ "aria-label": "Ambient sound",
462
+ value: ((oe = l.ambience) == null ? void 0 : oe.preset) ?? "floor",
463
+ onChange: (e) => b({
464
+ ambience: e.target.value === "floor" ? void 0 : { preset: e.target.value }
465
+ }),
466
+ children: [
467
+ /* @__PURE__ */ i("option", { value: "floor", children: "Same as the floor" }),
468
+ Ie.map((e) => /* @__PURE__ */ i("option", { value: e.id, title: e.description, children: e.label }, e.id))
469
+ ]
470
+ }
471
+ )
472
+ ] }),
473
+ l.kind === "light" && l.light && /* @__PURE__ */ n(I, { children: [
474
+ /* @__PURE__ */ i("h3", { children: "Ceiling light" }),
475
+ /* @__PURE__ */ i("div", { className: "field-grid", children: [
476
+ ["Colour temperature", "kelvin", "K", 1e3, 12e3],
477
+ ["Light intensity", "intensity", "cd", 0, 1e4],
478
+ ["Light range", "range", "m", 0.1, 100],
479
+ ["Flicker depth", "flicker", "", 0, 1]
480
+ ].map(([e, d, s, c, g]) => /* @__PURE__ */ i(
481
+ v,
482
+ {
483
+ label: e,
484
+ value: l.light[d] ?? 0,
485
+ type: "number",
486
+ suffix: s,
487
+ min: c,
488
+ max: g,
489
+ onChange: (N) => b({ light: { ...l.light, [d]: Number(N) } })
490
+ },
491
+ d
492
+ )) })
493
+ ] }),
494
+ l.kind === "camera" && /* @__PURE__ */ n(I, { children: [
495
+ /* @__PURE__ */ i("h3", { children: "Illustrative coverage" }),
496
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
497
+ A("Field of view", l.coverageAngle ?? 70, "coverageAngle", "°", 1, 360),
498
+ A("Range", l.coverageRange ?? 12, "coverageRange")
499
+ ] }),
500
+ /* @__PURE__ */ i("p", { className: "helper", children: "Coverage illustrates direction and range; walls do not calculate occlusion." }),
501
+ /* @__PURE__ */ i("h3", { children: "Watches" }),
502
+ r.objects.filter(
503
+ (e) => e.floorId === l.floorId && e.id !== l.id && ["door", "gate", "turnstile", "elevator", "room", "zone"].includes(e.kind)
504
+ ).map((e) => ({ x: e, d: K(ye(r, e), l.position) })).sort((e, d) => e.d - d.d).slice(0, 12).map(({ x: e, d }) => {
505
+ var s;
506
+ return /* @__PURE__ */ n("label", { className: "check-row", children: [
507
+ /* @__PURE__ */ i(
508
+ "input",
509
+ {
510
+ type: "checkbox",
511
+ checked: ((s = l.watchedIds) == null ? void 0 : s.includes(e.id)) ?? !1,
512
+ onChange: (c) => b({
513
+ watchedIds: c.target.checked ? [...l.watchedIds ?? [], e.id] : (l.watchedIds ?? []).filter((g) => g !== e.id)
514
+ })
515
+ }
516
+ ),
517
+ e.name,
518
+ /* @__PURE__ */ n("span", { children: [
519
+ d.toFixed(0),
520
+ " m"
521
+ ] })
522
+ ] }, e.id);
523
+ }),
524
+ /* @__PURE__ */ i("p", { className: "helper", children: "Watched objects use this camera for event footage." })
525
+ ] }),
526
+ h && l.kind === "stairs" && /* @__PURE__ */ n(I, { children: [
527
+ /* @__PURE__ */ i("h3", { children: "Stair geometry" }),
528
+ /* @__PURE__ */ n(
529
+ "select",
530
+ {
531
+ className: "field",
532
+ value: l.stairModel ?? "",
533
+ onChange: (e) => b({ stairModel: e.target.value || void 0 }),
534
+ children: [
535
+ /* @__PURE__ */ i("option", { value: "", children: "Fit to the footprint" }),
536
+ /* @__PURE__ */ i("option", { value: "straight", children: "Straight flight" }),
537
+ /* @__PURE__ */ i("option", { value: "switchback", children: "Switchback (half turn)" }),
538
+ /* @__PURE__ */ i("option", { value: "dogleg", children: "Dogleg (quarter turn)" }),
539
+ /* @__PURE__ */ i("option", { value: "spiral", children: "Spiral" }),
540
+ /* @__PURE__ */ i("option", { value: "escalator", children: "Escalator" })
541
+ ]
542
+ }
543
+ ),
544
+ /* @__PURE__ */ i("p", { className: "helper", children: "Left to fit, a run too steep for its footprint is drawn as the stair that turns." }),
545
+ l.stairModel === "escalator" && /* @__PURE__ */ n(I, { children: [
546
+ /* @__PURE__ */ i(
547
+ Ke,
548
+ {
549
+ label: "Carries you",
550
+ description: "An escalator runs one way — routing rides it that way and walks round to come back",
551
+ value: l.travel ?? "up",
552
+ options: [
553
+ { value: "up", label: "Up", title: "From the lower landing to the upper" },
554
+ { value: "down", label: "Down", title: "From the upper landing to the lower" }
555
+ ],
556
+ onChange: (e) => b({ travel: e })
557
+ }
558
+ ),
559
+ l.feedId && /* @__PURE__ */ i("p", { className: "helper", children: ((re = f.get(l.feedId)) == null ? void 0 : re.running) === !1 ? "Stopped right now — the plan draws its steps standing still." : "Running. A feed may stop it or reverse it; the direction above is how it was built." })
560
+ ] })
561
+ ] }),
562
+ h && l.kind === "elevator" && /* @__PURE__ */ n(I, { children: [
563
+ /* @__PURE__ */ i("h3", { children: "Doors open onto" }),
564
+ ["front", "right", "back", "left"].map((e) => /* @__PURE__ */ n("label", { className: "check-row", children: [
565
+ /* @__PURE__ */ i(
566
+ "input",
567
+ {
568
+ type: "checkbox",
569
+ checked: (l.doorSides ?? ["front"]).includes(e),
570
+ onChange: (d) => {
571
+ const s = new Set(l.doorSides ?? ["front"]);
572
+ d.target.checked ? s.add(e) : s.delete(e), b({
573
+ doorSides: s.size ? ["front", "back", "left", "right"].filter((c) => s.has(c)) : void 0
574
+ });
575
+ }
576
+ }
577
+ ),
578
+ e[0].toUpperCase() + e.slice(1)
579
+ ] }, e)),
580
+ /* @__PURE__ */ i("p", { className: "helper", children: "Relative to the lift's own rotation. A level it passes without serving has no doors at all." })
581
+ ] }),
582
+ h && ["elevator", "stairs"].includes(l.kind) && /* @__PURE__ */ n(I, { children: [
583
+ /* @__PURE__ */ i("h3", { children: "Served floors" }),
584
+ r.floors.map((e) => {
585
+ var d;
586
+ return /* @__PURE__ */ n("label", { className: "check-row", children: [
587
+ /* @__PURE__ */ i(
588
+ "input",
589
+ {
590
+ type: "checkbox",
591
+ checked: ((d = l.servedFloorIds) == null ? void 0 : d.includes(e.id)) ?? !1,
592
+ onChange: (s) => {
593
+ var c;
594
+ return b({
595
+ servedFloorIds: s.target.checked ? [...l.servedFloorIds ?? [], e.id] : (c = l.servedFloorIds) == null ? void 0 : c.filter((g) => g !== e.id)
596
+ });
597
+ }
598
+ }
599
+ ),
600
+ e.name,
601
+ /* @__PURE__ */ n("span", { children: [
602
+ e.elevation,
603
+ " m"
604
+ ] })
605
+ ] }, e.id);
606
+ })
607
+ ] }),
608
+ l.kind === "building" && /* @__PURE__ */ n("button", { className: "button secondary full", onClick: () => t.onTraceFootprint(l.id), children: [
609
+ "Create floor walls",
610
+ /* @__PURE__ */ i(Ue, { size: 15 })
611
+ ] })
612
+ ] }),
613
+ !h && l && /* @__PURE__ */ n("section", { className: "property-section", children: [
614
+ /* @__PURE__ */ i("h3", { children: "Object details" }),
615
+ /* @__PURE__ */ n("div", { className: "measurement-row", children: [
616
+ /* @__PURE__ */ i("span", { children: "Type" }),
617
+ /* @__PURE__ */ i("strong", { children: l.kind })
618
+ ] }),
619
+ /* @__PURE__ */ n("div", { className: "measurement-row", children: [
620
+ /* @__PURE__ */ i("span", { children: "Position" }),
621
+ /* @__PURE__ */ n("strong", { children: [
622
+ ye(r, l).map((e) => e.toFixed(1)).join(", "),
623
+ " ",
624
+ "m"
625
+ ] })
626
+ ] }),
627
+ l.rings && /* @__PURE__ */ n("div", { className: "measurement-row", children: [
628
+ /* @__PURE__ */ i("span", { children: "Area" }),
629
+ /* @__PURE__ */ n("strong", { children: [
630
+ Ne(l).toFixed(1),
631
+ " m²"
632
+ ] })
633
+ ] }),
634
+ l.feedId && /* @__PURE__ */ i("p", { className: "feed-id", children: l.feedId })
635
+ ] }),
636
+ h && m && /* @__PURE__ */ n("section", { className: "property-section", children: [
637
+ /* @__PURE__ */ i("h3", { children: "Barrier geometry" }),
638
+ /* @__PURE__ */ i(
639
+ v,
640
+ {
641
+ label: "Name",
642
+ value: m.name,
643
+ onChange: (e) => t.onUpdateBarrier(m.id, { name: e })
644
+ }
645
+ ),
646
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
647
+ /* @__PURE__ */ i(
648
+ v,
649
+ {
650
+ label: "Thickness",
651
+ value: m.thickness,
652
+ type: "number",
653
+ suffix: "m",
654
+ onChange: (e) => t.onUpdateBarrier(m.id, { thickness: Number(e) })
655
+ }
656
+ ),
657
+ /* @__PURE__ */ i(
658
+ v,
659
+ {
660
+ label: "Height",
661
+ value: m.height,
662
+ type: "number",
663
+ suffix: "m",
664
+ onChange: (e) => t.onUpdateBarrier(m.id, { height: Number(e) })
665
+ }
666
+ )
667
+ ] }),
668
+ /* @__PURE__ */ n("div", { className: "measurement-row", children: [
669
+ /* @__PURE__ */ i("span", { children: "Length" }),
670
+ /* @__PURE__ */ n("strong", { children: [
671
+ K(...q(r, m)).toFixed(2),
672
+ " m"
673
+ ] })
674
+ ] }),
675
+ /* @__PURE__ */ i("p", { className: "helper", children: "Drag the endpoint handles to reshape this segment. Connected walls and attached openings follow." }),
676
+ /* @__PURE__ */ i("h3", { children: "Attached objects" }),
677
+ r.objects.filter((e) => e.barrierId === m.id).map((e) => /* @__PURE__ */ n("button", { className: "object-row", onClick: () => t.onSelect(e.id), children: [
678
+ /* @__PURE__ */ i(P, { kind: e.kind }),
679
+ /* @__PURE__ */ i("span", { children: e.name }),
680
+ /* @__PURE__ */ i(H, { size: 14 })
681
+ ] }, e.id))
682
+ ] }),
683
+ h && k && /* @__PURE__ */ n("section", { className: "property-section", children: [
684
+ /* @__PURE__ */ i("h3", { children: "Virtual boundary" }),
685
+ /* @__PURE__ */ n("div", { className: "measurement-row", children: [
686
+ /* @__PURE__ */ i("span", { children: "Length" }),
687
+ /* @__PURE__ */ n("strong", { children: [
688
+ K(...q(r, k)).toFixed(2),
689
+ " m"
690
+ ] })
691
+ ] }),
692
+ /* @__PURE__ */ i("p", { className: "helper", children: "Drag its handles to reshape the shared division. To remove a division between spaces, choose which space survives the merge." })
693
+ ] }),
694
+ h && a && /* @__PURE__ */ n("section", { className: "property-section", children: [
695
+ /* @__PURE__ */ i("h3", { children: "Reference image" }),
696
+ /* @__PURE__ */ i(
697
+ v,
698
+ {
699
+ label: "Name",
700
+ value: a.name,
701
+ onChange: (e) => t.onUpdateDrawing(a.id, { name: e })
702
+ }
703
+ ),
704
+ /* @__PURE__ */ i(
705
+ G,
706
+ {
707
+ label: "Visible",
708
+ value: a.visible,
709
+ onChange: () => t.onUpdateDrawing(a.id, { visible: !a.visible })
710
+ }
711
+ ),
712
+ /* @__PURE__ */ i(
713
+ G,
714
+ {
715
+ label: "Lock position",
716
+ value: a.locked,
717
+ onChange: () => t.onUpdateDrawing(a.id, { locked: !a.locked })
718
+ }
719
+ ),
720
+ /* @__PURE__ */ n("label", { className: "field", children: [
721
+ /* @__PURE__ */ n("span", { children: [
722
+ "Opacity · ",
723
+ Math.round(a.opacity * 100),
724
+ "%"
725
+ ] }),
726
+ /* @__PURE__ */ i(
727
+ "input",
728
+ {
729
+ type: "range",
730
+ min: 0,
731
+ max: 1,
732
+ step: 0.05,
733
+ value: a.opacity,
734
+ onChange: (e) => t.onUpdateDrawing(a.id, { opacity: Number(e.target.value) })
735
+ }
736
+ )
737
+ ] }),
738
+ !a.locked && /* @__PURE__ */ n(I, { children: [
739
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
740
+ /* @__PURE__ */ i(
741
+ v,
742
+ {
743
+ label: "East / X",
744
+ value: a.origin[0],
745
+ type: "number",
746
+ suffix: "m",
747
+ onChange: (e) => t.onUpdateDrawing(a.id, { origin: [Number(e), a.origin[1]] })
748
+ }
749
+ ),
750
+ /* @__PURE__ */ i(
751
+ v,
752
+ {
753
+ label: "North / Y",
754
+ value: a.origin[1],
755
+ type: "number",
756
+ suffix: "m",
757
+ onChange: (e) => t.onUpdateDrawing(a.id, { origin: [a.origin[0], Number(e)] })
758
+ }
759
+ )
760
+ ] }),
761
+ /* @__PURE__ */ i(
762
+ v,
763
+ {
764
+ label: "Metres per pixel",
765
+ value: a.scale,
766
+ type: "number",
767
+ step: 1e-3,
768
+ min: 1e-6,
769
+ onChange: (e) => t.onUpdateDrawing(a.id, { scale: Number(e) })
770
+ }
771
+ ),
772
+ /* @__PURE__ */ i(
773
+ v,
774
+ {
775
+ label: "Rotation",
776
+ value: a.rotation,
777
+ type: "number",
778
+ suffix: "°",
779
+ onChange: (e) => t.onUpdateDrawing(a.id, { rotation: Number(e) })
780
+ }
781
+ )
782
+ ] })
783
+ ] }),
784
+ l && /* @__PURE__ */ i(qe, { project: r, object: l, onSelect: t.onSelect, onFloor: t.onFloor }),
785
+ F && (l == null ? void 0 : l.feedId) && ((de = t.renderStatusPanel) == null ? void 0 : de.call(t, { object: l, status: u, editing: h, live: t.live }))
786
+ ] }) : /* @__PURE__ */ n(I, { children: [
787
+ /* @__PURE__ */ n("div", { className: "overview-hero", children: [
788
+ /* @__PURE__ */ n("div", { className: "overview-art", children: [
789
+ /* @__PURE__ */ n("div", { className: "mini-building", children: [
790
+ /* @__PURE__ */ i("i", {}),
791
+ /* @__PURE__ */ i("i", {}),
792
+ /* @__PURE__ */ i("i", {}),
793
+ /* @__PURE__ */ i("i", {}),
794
+ /* @__PURE__ */ i("div", { className: "mini-access", children: /* @__PURE__ */ i(Le, { size: 15 }) })
795
+ ] }),
796
+ /* @__PURE__ */ i("span", { className: "hero-dots" })
797
+ ] }),
798
+ /* @__PURE__ */ i("span", { className: "eyebrow", children: o ? "MAIN BUILDING" : "SITE & SURROUNDINGS" }),
799
+ /* @__PURE__ */ i("h2", { children: (o == null ? void 0 : o.name) ?? "Outdoor site" }),
800
+ /* @__PURE__ */ i("p", { children: o ? `Level ${o.elevation < 0 ? "B" + r.floors.filter((e) => e.buildingId === o.buildingId && e.elevation < 0 && e.elevation >= o.elevation).length : r.floors.filter((e) => e.buildingId === o.buildingId && e.elevation >= 0 && e.elevation < o.elevation).length} · ${o.elevation.toFixed(1)} m elevation` : r.description })
801
+ ] }),
802
+ h && /* @__PURE__ */ n("section", { className: "property-section", children: [
803
+ /* @__PURE__ */ n("h3", { children: [
804
+ "Site anchor ",
805
+ /* @__PURE__ */ i(pe, { size: 15 })
806
+ ] }),
807
+ /* @__PURE__ */ i("p", { className: "helper", children: "Where the plan is pinned and which way it faces — the one thing a drawing cannot tell you. Geometry is untouched: metres stay metres, only the frame moves." }),
808
+ /* @__PURE__ */ n("label", { className: "field", children: [
809
+ /* @__PURE__ */ i("span", { children: "Bearing" }),
810
+ /* @__PURE__ */ i(
811
+ "input",
812
+ {
813
+ type: "range",
814
+ "aria-label": "Bearing slider",
815
+ min: 0,
816
+ max: 360,
817
+ step: 0.1,
818
+ value: ((r.origin[2] ?? 0) + 360) % 360,
819
+ onChange: (e) => V(Number(e.target.value))
820
+ }
821
+ )
822
+ ] }),
823
+ /* @__PURE__ */ n("div", { className: "nudge-row", children: [
824
+ [-5, -1, -0.1].map((e) => /* @__PURE__ */ n("button", { className: "button secondary small", onClick: () => X(e), children: [
825
+ e,
826
+ "°"
827
+ ] }, e)),
828
+ /* @__PURE__ */ i(
829
+ "input",
830
+ {
831
+ className: "nudge-value",
832
+ "aria-label": "Bearing",
833
+ type: "number",
834
+ step: 0.1,
835
+ value: Number((((r.origin[2] ?? 0) + 360) % 360).toFixed(2)),
836
+ onChange: (e) => V(Number(e.target.value))
837
+ }
838
+ ),
839
+ [0.1, 1, 5].map((e) => /* @__PURE__ */ n("button", { className: "button secondary small", onClick: () => X(e), children: [
840
+ "+",
841
+ e,
842
+ "°"
843
+ ] }, e))
844
+ ] }),
845
+ /* @__PURE__ */ i("label", { className: "field", children: /* @__PURE__ */ i("span", { children: "Move the site" }) }),
846
+ /* @__PURE__ */ n("div", { className: "nudge-pad", children: [
847
+ /* @__PURE__ */ i("button", { className: "button secondary small up", onClick: () => B(0, $), "aria-label": "Move north", children: /* @__PURE__ */ i(Me, { size: 14 }) }),
848
+ /* @__PURE__ */ i(
849
+ "button",
850
+ {
851
+ className: "button secondary small left",
852
+ onClick: () => B(-$, 0),
853
+ "aria-label": "Move west",
854
+ children: /* @__PURE__ */ i(Te, { size: 14 })
855
+ }
856
+ ),
857
+ /* @__PURE__ */ i(
858
+ "select",
859
+ {
860
+ className: "step",
861
+ "aria-label": "Step size",
862
+ value: $,
863
+ onChange: (e) => ze(Number(e.target.value)),
864
+ children: [0.1, 0.25, 0.5, 1, 5].map((e) => /* @__PURE__ */ n("option", { value: e, children: [
865
+ e,
866
+ " m"
867
+ ] }, e))
868
+ }
869
+ ),
870
+ /* @__PURE__ */ i(
871
+ "button",
872
+ {
873
+ className: "button secondary small right",
874
+ onClick: () => B($, 0),
875
+ "aria-label": "Move east",
876
+ children: /* @__PURE__ */ i(W, { size: 14 })
877
+ }
878
+ ),
879
+ /* @__PURE__ */ i(
880
+ "button",
881
+ {
882
+ className: "button secondary small down",
883
+ onClick: () => B(0, -$),
884
+ "aria-label": "Move south",
885
+ children: /* @__PURE__ */ i(Ee, { size: 14 })
886
+ }
887
+ )
888
+ ] }),
889
+ /* @__PURE__ */ i("p", { className: "helper", children: "Steps are metres on the ground, north-up — the compass, not the plan's own grid." }),
890
+ /* @__PURE__ */ n("details", { className: "anchor-exact", children: [
891
+ /* @__PURE__ */ i("summary", { children: "Exact coordinates" }),
892
+ /* @__PURE__ */ n("div", { className: "field-row", children: [
893
+ /* @__PURE__ */ i(
894
+ v,
895
+ {
896
+ label: "Longitude",
897
+ type: "number",
898
+ step: 1e-6,
899
+ value: r.origin[0],
900
+ onChange: (e) => Q(0, e),
901
+ suffix: "°"
902
+ }
903
+ ),
904
+ /* @__PURE__ */ i(
905
+ v,
906
+ {
907
+ label: "Latitude",
908
+ type: "number",
909
+ step: 1e-6,
910
+ value: r.origin[1],
911
+ onChange: (e) => Q(1, e),
912
+ suffix: "°"
913
+ }
914
+ )
915
+ ] })
916
+ ] })
917
+ ] }),
918
+ /* @__PURE__ */ n("div", { className: "overview-stats", children: [
919
+ F ? /* @__PURE__ */ n("div", { children: [
920
+ /* @__PURE__ */ i("strong", { children: w.length }),
921
+ /* @__PURE__ */ i("span", { children: "Live bindings" })
922
+ ] }) : /* @__PURE__ */ n("div", { children: [
923
+ /* @__PURE__ */ i("strong", { children: p.length }),
924
+ /* @__PURE__ */ i("span", { children: "Objects here" })
925
+ ] }),
926
+ /* @__PURE__ */ n("div", { children: [
927
+ /* @__PURE__ */ i("strong", { children: p.filter((e) => e.kind === "room" || e.kind === "zone").length }),
928
+ /* @__PURE__ */ i("span", { children: "Spaces & zones" })
929
+ ] })
930
+ ] }),
931
+ F && L.length > 0 && /* @__PURE__ */ n("section", { className: "property-section", children: [
932
+ /* @__PURE__ */ i("h3", { children: "Occupancy & environment" }),
933
+ /* @__PURE__ */ n("div", { className: "overview-status", children: [
934
+ /* @__PURE__ */ i("span", { className: "status-dot normal" }),
935
+ /* @__PURE__ */ n("span", { children: [
936
+ "People on this ",
937
+ o ? "floor" : "site"
938
+ ] }),
939
+ /* @__PURE__ */ i("strong", { children: E(L) })
940
+ ] }),
941
+ /* @__PURE__ */ n("div", { className: "overview-status", children: [
942
+ /* @__PURE__ */ i("span", { className: "status-dot normal" }),
943
+ /* @__PURE__ */ i("span", { children: "Whole building" }),
944
+ /* @__PURE__ */ i("strong", { children: E(O) })
945
+ ] }),
946
+ M.length > 0 && /* @__PURE__ */ n("div", { className: "overview-status", children: [
947
+ /* @__PURE__ */ i("span", { className: `status-dot ${Math.max(...M) > 1e3 ? "warning" : "normal"}` }),
948
+ /* @__PURE__ */ i("span", { children: "CO₂ · avg / peak" }),
949
+ /* @__PURE__ */ n("strong", { children: [
950
+ Math.round(M.reduce((e, d) => e + d, 0) / M.length),
951
+ " / ",
952
+ Math.max(...M),
953
+ " ",
954
+ "ppm"
955
+ ] })
956
+ ] }),
957
+ C && /* @__PURE__ */ n("button", { className: "alarm-row", onClick: () => t.onSelect(C.id), children: [
958
+ /* @__PURE__ */ i("span", { className: "status-dot normal" }),
959
+ /* @__PURE__ */ n("span", { children: [
960
+ C.name,
961
+ /* @__PURE__ */ n("small", { children: [
962
+ "Busiest space · ",
963
+ (ce = (se = f.get(C.feedId)) == null ? void 0 : se.metrics) == null ? void 0 : ce.occupancy,
964
+ " people"
965
+ ] })
966
+ ] }),
967
+ /* @__PURE__ */ i(H, { size: 15 })
968
+ ] })
969
+ ] }),
970
+ F && /* @__PURE__ */ n("section", { className: "property-section", children: [
971
+ /* @__PURE__ */ n("h3", { children: [
972
+ "Status overview ",
973
+ /* @__PURE__ */ i(ge, { size: 15 })
974
+ ] }),
975
+ /* @__PURE__ */ n("div", { className: "overview-status", children: [
976
+ /* @__PURE__ */ i("span", { className: "status-dot normal" }),
977
+ /* @__PURE__ */ i("span", { children: "Normal" }),
978
+ /* @__PURE__ */ i("strong", { children: w.filter((e) => T(f.get(e.feedId)) === "normal").length })
979
+ ] }),
980
+ /* @__PURE__ */ n("div", { className: "overview-status", children: [
981
+ /* @__PURE__ */ i("span", { className: "status-dot critical" }),
982
+ /* @__PURE__ */ i("span", { children: "Active alarms" }),
983
+ /* @__PURE__ */ i("strong", { children: w.filter((e) => T(f.get(e.feedId)) === "critical").length })
984
+ ] }),
985
+ /* @__PURE__ */ n("div", { className: "overview-status", children: [
986
+ /* @__PURE__ */ i("span", { className: "status-dot warning" }),
987
+ /* @__PURE__ */ i("span", { children: "Offline / stale / unknown" }),
988
+ /* @__PURE__ */ i("strong", { children: w.filter((e) => ["warning", "unknown"].includes(T(f.get(e.feedId)))).length })
989
+ ] })
990
+ ] }),
991
+ F && R.length > 0 && /* @__PURE__ */ n("section", { className: "property-section", children: [
992
+ /* @__PURE__ */ i("h3", { children: "Site alarms" }),
993
+ R.map((e) => /* @__PURE__ */ n("button", { className: "alarm-row", onClick: () => t.onSelect(e.id), children: [
994
+ /* @__PURE__ */ i("span", { className: "status-dot critical" }),
995
+ /* @__PURE__ */ n("span", { children: [
996
+ e.name,
997
+ /* @__PURE__ */ i("small", { children: ke(f.get(e.feedId)) })
998
+ ] }),
999
+ /* @__PURE__ */ i(H, { size: 15 })
1000
+ ] }, e.id))
1001
+ ] }),
1002
+ /* @__PURE__ */ n("section", { className: "property-section", children: [
1003
+ /* @__PURE__ */ n("h3", { children: [
1004
+ "Quick access ",
1005
+ /* @__PURE__ */ i($e, { size: 16 })
1006
+ ] }),
1007
+ w.slice(0, 4).map((e) => /* @__PURE__ */ n("button", { className: "object-row", onClick: () => t.onSelect(e.id), children: [
1008
+ /* @__PURE__ */ i(P, { kind: e.kind }),
1009
+ /* @__PURE__ */ i("span", { children: e.name }),
1010
+ /* @__PURE__ */ i("span", { className: `status-dot ${T(f.get(e.feedId))}` })
1011
+ ] }, e.id)),
1012
+ !w.length && /* @__PURE__ */ i("p", { className: "helper", children: "Give an object a feed id to connect it to your own live data." })
1013
+ ] }),
1014
+ h && o && /* @__PURE__ */ n("section", { className: "property-section", children: [
1015
+ /* @__PURE__ */ i("h3", { children: "Floor settings" }),
1016
+ /* @__PURE__ */ i(
1017
+ v,
1018
+ {
1019
+ label: "Floor name",
1020
+ value: o.name,
1021
+ onChange: (e) => t.onUpdateFloor(o.id, { name: e })
1022
+ }
1023
+ ),
1024
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
1025
+ /* @__PURE__ */ i(
1026
+ v,
1027
+ {
1028
+ label: "Elevation",
1029
+ value: o.elevation,
1030
+ type: "number",
1031
+ suffix: "m",
1032
+ onChange: (e) => t.onUpdateFloor(o.id, { elevation: Number(e) })
1033
+ }
1034
+ ),
1035
+ /* @__PURE__ */ i(
1036
+ v,
1037
+ {
1038
+ label: "Floor height",
1039
+ value: o.height,
1040
+ type: "number",
1041
+ suffix: "m",
1042
+ onChange: (e) => t.onUpdateFloor(o.id, { height: Number(e) })
1043
+ }
1044
+ )
1045
+ ] }),
1046
+ /* @__PURE__ */ i(
1047
+ G,
1048
+ {
1049
+ label: "Intermediate level",
1050
+ description: "An entresol between full floors: the plan shows it over the level below",
1051
+ value: o.mezzanine ?? !1,
1052
+ onChange: () => t.onUpdateFloor(o.id, { mezzanine: !o.mezzanine || void 0 })
1053
+ }
1054
+ ),
1055
+ /* @__PURE__ */ n("label", { className: "field", children: [
1056
+ /* @__PURE__ */ i("span", { children: "Ceiling light" }),
1057
+ /* @__PURE__ */ i(
1058
+ "select",
1059
+ {
1060
+ "aria-label": "Ceiling light",
1061
+ value: Ve((o.light ?? D).kelvin).id,
1062
+ onChange: (e) => t.onUpdateFloor(o.id, {
1063
+ light: {
1064
+ ...o.light ?? D,
1065
+ kelvin: Ce.find((d) => d.id === e.target.value).kelvin
1066
+ }
1067
+ }),
1068
+ children: Ce.map((e) => /* @__PURE__ */ n("option", { value: e.id, children: [
1069
+ e.label,
1070
+ " · ",
1071
+ e.kelvin,
1072
+ " K"
1073
+ ] }, e.id))
1074
+ }
1075
+ )
1076
+ ] }),
1077
+ /* @__PURE__ */ n("label", { className: "field", children: [
1078
+ /* @__PURE__ */ i("span", { children: "Ambient sound" }),
1079
+ /* @__PURE__ */ i(
1080
+ "select",
1081
+ {
1082
+ "aria-label": "Ambient sound",
1083
+ value: ((he = o.ambience) == null ? void 0 : he.preset) ?? "silent",
1084
+ onChange: (e) => t.onUpdateFloor(o.id, {
1085
+ ambience: e.target.value === "silent" ? void 0 : { preset: e.target.value }
1086
+ }),
1087
+ children: Ie.map((e) => /* @__PURE__ */ i("option", { value: e.id, title: e.description, children: e.label }, e.id))
1088
+ }
1089
+ )
1090
+ ] }),
1091
+ /* @__PURE__ */ n("div", { className: "field-grid", children: [
1092
+ /* @__PURE__ */ i(
1093
+ v,
1094
+ {
1095
+ label: "Colour temperature",
1096
+ value: (o.light ?? D).kelvin,
1097
+ type: "number",
1098
+ suffix: "K",
1099
+ min: 1500,
1100
+ max: 12e3,
1101
+ step: 100,
1102
+ onChange: (e) => t.onUpdateFloor(o.id, {
1103
+ light: {
1104
+ ...o.light ?? D,
1105
+ kelvin: Math.max(1e3, Math.min(12e3, Number(e) || D.kelvin))
1106
+ }
1107
+ })
1108
+ }
1109
+ ),
1110
+ /* @__PURE__ */ i(
1111
+ v,
1112
+ {
1113
+ label: "Brightness",
1114
+ value: Math.round((o.light ?? D).level * 100),
1115
+ type: "number",
1116
+ suffix: "%",
1117
+ min: 0,
1118
+ max: 100,
1119
+ step: 5,
1120
+ onChange: (e) => t.onUpdateFloor(o.id, {
1121
+ light: {
1122
+ ...o.light ?? D,
1123
+ level: Math.max(0, Math.min(1, Number(e) / 100))
1124
+ }
1125
+ })
1126
+ }
1127
+ )
1128
+ ] }),
1129
+ /* @__PURE__ */ n("p", { className: "helper lamp-note", children: [
1130
+ /* @__PURE__ */ i("i", { style: { background: Ye((o.light ?? D).kelvin) } }),
1131
+ "This level's own lighting, which stays on whatever the sun is doing — it is what keeps the plan legible after dark."
1132
+ ] }),
1133
+ /* @__PURE__ */ i(
1134
+ G,
1135
+ {
1136
+ label: "Open here by default",
1137
+ description: "Anyone opening this plan starts on this level instead of the ground floor",
1138
+ value: r.initialFloorId === o.id,
1139
+ onChange: () => t.onSetInitialFloor(r.initialFloorId === o.id ? null : o.id)
1140
+ }
1141
+ ),
1142
+ r.floors.length > 1 && /* @__PURE__ */ n("button", { className: "text-button danger", onClick: () => t.onDeleteFloor(o.id), children: [
1143
+ /* @__PURE__ */ i(ve, { size: 14 }),
1144
+ "Delete this floor"
1145
+ ] }),
1146
+ /* @__PURE__ */ i("p", { className: "helper", children: r.datum })
1147
+ ] }),
1148
+ /* @__PURE__ */ n("div", { className: "inspector-note", children: [
1149
+ /* @__PURE__ */ i(pe, { size: 17 }),
1150
+ /* @__PURE__ */ n("p", { children: [
1151
+ "Your space, described.",
1152
+ /* @__PURE__ */ i("br", {}),
1153
+ /* @__PURE__ */ i("span", { children: "Select anything on the plan to inspect and edit it." })
1154
+ ] })
1155
+ ] })
1156
+ ] }) }),
1157
+ S && h && /* @__PURE__ */ n("div", { className: "inspector-footer", children: [
1158
+ /* @__PURE__ */ n(
1159
+ "button",
1160
+ {
1161
+ className: "button secondary",
1162
+ onClick: t.onDuplicate,
1163
+ disabled: !!a || !!m || !!k || !!(l != null && l.barrierId),
1164
+ children: [
1165
+ /* @__PURE__ */ i(Oe, { size: 15 }),
1166
+ "Duplicate"
1167
+ ]
1168
+ }
1169
+ ),
1170
+ /* @__PURE__ */ n("button", { className: "button danger-quiet", onClick: t.onDelete, children: [
1171
+ /* @__PURE__ */ i(ve, { size: 16 }),
1172
+ "Delete"
1173
+ ] })
1174
+ ] }),
1175
+ !h && F && /* @__PURE__ */ n("div", { className: "viewer-note", children: [
1176
+ /* @__PURE__ */ i(Re, { size: 14 }),
1177
+ "Read-only status feed"
1178
+ ] })
1179
+ ] });
1180
+ }
1181
+ export {
1182
+ di as Inspector
1183
+ };
1184
+ //# sourceMappingURL=Inspector.js.map