@reekon-tools/boldr-cad 0.1.0 → 1.0.0

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 (547) hide show
  1. package/README.md +81 -9
  2. package/dist/app/edit.d.ts +12 -1
  3. package/dist/app/edit.js +96 -11
  4. package/dist/app/edit.js.map +1 -1
  5. package/dist/app/state.d.ts +31 -4
  6. package/dist/app/state.js +31 -2
  7. package/dist/app/state.js.map +1 -1
  8. package/dist/data/memory.d.ts +5 -0
  9. package/dist/data/memory.js +2 -2
  10. package/dist/data/memory.js.map +1 -1
  11. package/dist/data/provider.d.ts +19 -7
  12. package/dist/data/sync.d.ts +7 -2
  13. package/dist/data/sync.js +115 -64
  14. package/dist/data/sync.js.map +1 -1
  15. package/dist/editor/actions.d.ts +1 -2
  16. package/dist/editor/actions.js +391 -113
  17. package/dist/editor/actions.js.map +1 -1
  18. package/dist/editor/confirm.d.ts +23 -0
  19. package/dist/editor/confirm.js +35 -0
  20. package/dist/editor/confirm.js.map +1 -0
  21. package/dist/editor/elevation.d.ts +191 -90
  22. package/dist/editor/elevation.js +812 -616
  23. package/dist/editor/elevation.js.map +1 -1
  24. package/dist/editor/face.d.ts +73 -0
  25. package/dist/editor/face.js +269 -0
  26. package/dist/editor/face.js.map +1 -0
  27. package/dist/editor/files.d.ts +6 -0
  28. package/dist/editor/files.js +50 -4
  29. package/dist/editor/files.js.map +1 -1
  30. package/dist/editor/gestures.d.ts +18 -3
  31. package/dist/editor/gestures.js +145 -30
  32. package/dist/editor/gestures.js.map +1 -1
  33. package/dist/editor/keypad.d.ts +19 -4
  34. package/dist/editor/keypad.js +39 -9
  35. package/dist/editor/keypad.js.map +1 -1
  36. package/dist/editor/keys.js +36 -4
  37. package/dist/editor/keys.js.map +1 -1
  38. package/dist/editor/laser.d.ts +20 -4
  39. package/dist/editor/laser.js +104 -21
  40. package/dist/editor/laser.js.map +1 -1
  41. package/dist/editor/linkActions.d.ts +49 -0
  42. package/dist/editor/linkActions.js +210 -0
  43. package/dist/editor/linkActions.js.map +1 -0
  44. package/dist/editor/linkFollow.d.ts +2 -0
  45. package/dist/editor/linkFollow.js +53 -0
  46. package/dist/editor/linkFollow.js.map +1 -0
  47. package/dist/editor/linkWrite.d.ts +13 -0
  48. package/dist/editor/linkWrite.js +84 -0
  49. package/dist/editor/linkWrite.js.map +1 -0
  50. package/dist/editor/links.d.ts +84 -0
  51. package/dist/editor/links.js +130 -0
  52. package/dist/editor/links.js.map +1 -0
  53. package/dist/editor/markup.d.ts +29 -3
  54. package/dist/editor/markup.js +95 -10
  55. package/dist/editor/markup.js.map +1 -1
  56. package/dist/editor/mode.d.ts +40 -2
  57. package/dist/editor/mode.js +71 -4
  58. package/dist/editor/mode.js.map +1 -1
  59. package/dist/editor/ports.d.ts +36 -6
  60. package/dist/editor/ports.js +10 -1
  61. package/dist/editor/ports.js.map +1 -1
  62. package/dist/editor/project.d.ts +38 -6
  63. package/dist/editor/project.js +167 -27
  64. package/dist/editor/project.js.map +1 -1
  65. package/dist/editor/selection.d.ts +10 -0
  66. package/dist/editor/selection.js +62 -8
  67. package/dist/editor/selection.js.map +1 -1
  68. package/dist/editor/status.js +3 -0
  69. package/dist/editor/status.js.map +1 -1
  70. package/dist/editor/tooltips.d.ts +5 -0
  71. package/dist/editor/tooltips.js +48 -0
  72. package/dist/editor/tooltips.js.map +1 -0
  73. package/dist/editor/view3d.d.ts +17 -0
  74. package/dist/editor/view3d.js +135 -0
  75. package/dist/editor/view3d.js.map +1 -0
  76. package/dist/editor/view3dState.d.ts +39 -0
  77. package/dist/editor/view3dState.js +44 -0
  78. package/dist/editor/view3dState.js.map +1 -0
  79. package/dist/export/dxf.js +1 -1
  80. package/dist/export/dxf.js.map +1 -1
  81. package/dist/export/pdf.js +17 -12
  82. package/dist/export/pdf.js.map +1 -1
  83. package/dist/export/plan.d.ts +23 -6
  84. package/dist/export/plan.js +127 -44
  85. package/dist/export/plan.js.map +1 -1
  86. package/dist/index.d.ts +5 -0
  87. package/dist/index.js +2 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/model/constraints.js +15 -4
  90. package/dist/model/constraints.js.map +1 -1
  91. package/dist/model/demo.js +3 -3
  92. package/dist/model/demo.js.map +1 -1
  93. package/dist/model/elevation.d.ts +6 -9
  94. package/dist/model/elevation.js +5 -13
  95. package/dist/model/elevation.js.map +1 -1
  96. package/dist/model/faces.d.ts +58 -0
  97. package/dist/model/faces.js +197 -0
  98. package/dist/model/faces.js.map +1 -0
  99. package/dist/model/facesolve.d.ts +72 -0
  100. package/dist/model/facesolve.js +369 -0
  101. package/dist/model/facesolve.js.map +1 -0
  102. package/dist/model/history.d.ts +3 -2
  103. package/dist/model/history.js +17 -11
  104. package/dist/model/history.js.map +1 -1
  105. package/dist/model/images.d.ts +18 -0
  106. package/dist/model/images.js +26 -0
  107. package/dist/model/images.js.map +1 -0
  108. package/dist/model/links.d.ts +46 -0
  109. package/dist/model/links.js +73 -0
  110. package/dist/model/links.js.map +1 -0
  111. package/dist/model/markup.d.ts +46 -0
  112. package/dist/model/markup.js +71 -0
  113. package/dist/model/markup.js.map +1 -0
  114. package/dist/model/measurement.d.ts +11 -0
  115. package/dist/model/measurement.js +24 -0
  116. package/dist/model/measurement.js.map +1 -0
  117. package/dist/model/openings.d.ts +4 -0
  118. package/dist/model/openings.js +4 -0
  119. package/dist/model/openings.js.map +1 -1
  120. package/dist/model/planGeom.d.ts +72 -2
  121. package/dist/model/planGeom.js +184 -10
  122. package/dist/model/planGeom.js.map +1 -1
  123. package/dist/model/project.js +3 -2
  124. package/dist/model/project.js.map +1 -1
  125. package/dist/model/projectfile.js +2 -1
  126. package/dist/model/projectfile.js.map +1 -1
  127. package/dist/model/rooms.js +2 -2
  128. package/dist/model/rooms.js.map +1 -1
  129. package/dist/model/settings.d.ts +6 -0
  130. package/dist/model/settings.js +2 -2
  131. package/dist/model/settings.js.map +1 -1
  132. package/dist/model/sketch.d.ts +14 -0
  133. package/dist/model/sketch.js +143 -24
  134. package/dist/model/sketch.js.map +1 -1
  135. package/dist/model/smooth.d.ts +6 -0
  136. package/dist/model/smooth.js +52 -0
  137. package/dist/model/smooth.js.map +1 -0
  138. package/dist/model/store.d.ts +12 -0
  139. package/dist/model/store.js +35 -3
  140. package/dist/model/store.js.map +1 -1
  141. package/dist/model/types.d.ts +173 -8
  142. package/dist/model/wallfaces.d.ts +32 -0
  143. package/dist/model/wallfaces.js +133 -20
  144. package/dist/model/wallfaces.js.map +1 -1
  145. package/dist/model/wallshape.d.ts +15 -0
  146. package/dist/model/wallshape.js +89 -0
  147. package/dist/model/wallshape.js.map +1 -0
  148. package/dist/react/BottomBar.d.ts +9 -5
  149. package/dist/react/BottomBar.js +213 -24
  150. package/dist/react/BottomBar.js.map +1 -1
  151. package/dist/react/Buttons.d.ts +13 -2
  152. package/dist/react/Buttons.js +37 -5
  153. package/dist/react/Buttons.js.map +1 -1
  154. package/dist/react/CadEditor.d.ts +46 -3
  155. package/dist/react/CadEditor.js +77 -20
  156. package/dist/react/CadEditor.js.map +1 -1
  157. package/dist/react/ConfirmSheet.d.ts +4 -0
  158. package/dist/react/ConfirmSheet.js +31 -0
  159. package/dist/react/ConfirmSheet.js.map +1 -0
  160. package/dist/react/ConflictSheet.d.ts +2 -1
  161. package/dist/react/ConflictSheet.js +16 -8
  162. package/dist/react/ConflictSheet.js.map +1 -1
  163. package/dist/react/Drawer.d.ts +8 -2
  164. package/dist/react/Drawer.js +167 -38
  165. package/dist/react/Drawer.js.map +1 -1
  166. package/dist/react/Duck.d.ts +13 -0
  167. package/dist/react/Duck.js +45 -0
  168. package/dist/react/Duck.js.map +1 -0
  169. package/dist/react/Empty3D.d.ts +2 -0
  170. package/dist/react/Empty3D.js +39 -0
  171. package/dist/react/Empty3D.js.map +1 -0
  172. package/dist/react/FitScroll.d.ts +6 -0
  173. package/dist/react/FitScroll.js +14 -0
  174. package/dist/react/FitScroll.js.map +1 -0
  175. package/dist/react/Icon.native.d.ts +6 -0
  176. package/dist/react/Icon.native.js +4 -0
  177. package/dist/react/Icon.native.js.map +1 -1
  178. package/dist/react/Icon.web.d.ts +6 -0
  179. package/dist/react/Icon.web.js +4 -0
  180. package/dist/react/Icon.web.js.map +1 -1
  181. package/dist/react/KeypadSheet.d.ts +9 -2
  182. package/dist/react/KeypadSheet.js +174 -42
  183. package/dist/react/KeypadSheet.js.map +1 -1
  184. package/dist/react/LaserTray.js +8 -5
  185. package/dist/react/LaserTray.js.map +1 -1
  186. package/dist/react/MarkupPanel.d.ts +8 -0
  187. package/dist/react/MarkupPanel.js +67 -0
  188. package/dist/react/MarkupPanel.js.map +1 -0
  189. package/dist/react/PageThumb.native.d.ts +7 -2
  190. package/dist/react/PageThumb.native.js +19 -7
  191. package/dist/react/PageThumb.native.js.map +1 -1
  192. package/dist/react/PageThumb.web.d.ts +3 -2
  193. package/dist/react/PageThumb.web.js +4 -4
  194. package/dist/react/PageThumb.web.js.map +1 -1
  195. package/dist/react/PlanCanvas.native.d.ts +1 -1
  196. package/dist/react/PlanCanvas.native.js +134 -36
  197. package/dist/react/PlanCanvas.native.js.map +1 -1
  198. package/dist/react/PlanCanvas.web.js +16 -5
  199. package/dist/react/PlanCanvas.web.js.map +1 -1
  200. package/dist/react/Popovers.d.ts +12 -6
  201. package/dist/react/Popovers.js +53 -26
  202. package/dist/react/Popovers.js.map +1 -1
  203. package/dist/react/Rail.d.ts +24 -0
  204. package/dist/react/Rail.js +324 -34
  205. package/dist/react/Rail.js.map +1 -1
  206. package/dist/react/ShapeMenu.d.ts +7 -0
  207. package/dist/react/ShapeMenu.js +58 -0
  208. package/dist/react/ShapeMenu.js.map +1 -0
  209. package/dist/react/Sheet.d.ts +14 -4
  210. package/dist/react/Sheet.js +54 -9
  211. package/dist/react/Sheet.js.map +1 -1
  212. package/dist/react/Slider.d.ts +18 -0
  213. package/dist/react/Slider.js +27 -0
  214. package/dist/react/Slider.js.map +1 -0
  215. package/dist/react/Toast.js +14 -6
  216. package/dist/react/Toast.js.map +1 -1
  217. package/dist/react/ToolTip.d.ts +7 -0
  218. package/dist/react/ToolTip.js +43 -0
  219. package/dist/react/ToolTip.js.map +1 -0
  220. package/dist/react/TopBar.d.ts +6 -3
  221. package/dist/react/TopBar.js +48 -17
  222. package/dist/react/TopBar.js.map +1 -1
  223. package/dist/react/Tween.d.ts +7 -0
  224. package/dist/react/Tween.js +26 -0
  225. package/dist/react/Tween.js.map +1 -0
  226. package/dist/react/Tween.native.d.ts +6 -0
  227. package/dist/react/Tween.native.js +43 -0
  228. package/dist/react/Tween.native.js.map +1 -0
  229. package/dist/react/View3D.native.d.ts +4 -0
  230. package/dist/react/View3D.native.js +103 -0
  231. package/dist/react/View3D.native.js.map +1 -0
  232. package/dist/react/View3D.web.d.ts +4 -0
  233. package/dist/react/View3D.web.js +151 -0
  234. package/dist/react/View3D.web.js.map +1 -0
  235. package/dist/react/View3DHost.d.ts +143 -0
  236. package/dist/react/View3DHost.js +377 -0
  237. package/dist/react/View3DHost.js.map +1 -0
  238. package/dist/react/corners.d.ts +7 -0
  239. package/dist/react/corners.js +51 -0
  240. package/dist/react/corners.js.map +1 -0
  241. package/dist/react/easing.d.ts +15 -0
  242. package/dist/react/easing.js +10 -0
  243. package/dist/react/easing.js.map +1 -0
  244. package/dist/react/host.d.ts +7 -2
  245. package/dist/react/host.js +8 -3
  246. package/dist/react/host.js.map +1 -1
  247. package/dist/react/hostKeypad.d.ts +56 -0
  248. package/dist/react/hostKeypad.js +5 -0
  249. package/dist/react/hostKeypad.js.map +1 -0
  250. package/dist/react/motion.d.ts +77 -0
  251. package/dist/react/motion.js +173 -0
  252. package/dist/react/motion.js.map +1 -0
  253. package/dist/react/ports.js +90 -8
  254. package/dist/react/ports.js.map +1 -1
  255. package/dist/react/saving.d.ts +15 -0
  256. package/dist/react/saving.js +76 -0
  257. package/dist/react/saving.js.map +1 -0
  258. package/dist/react/store.d.ts +38 -1
  259. package/dist/react/store.js +31 -1
  260. package/dist/react/store.js.map +1 -1
  261. package/dist/react/theme.d.ts +10 -0
  262. package/dist/react/theme.js +8 -0
  263. package/dist/react/theme.js.map +1 -1
  264. package/dist/react/topRow.d.ts +22 -0
  265. package/dist/react/topRow.js +61 -0
  266. package/dist/react/topRow.js.map +1 -0
  267. package/dist/react/touch.d.ts +6 -0
  268. package/dist/react/touch.js +9 -0
  269. package/dist/react/touch.js.map +1 -0
  270. package/dist/render/ctx.d.ts +8 -0
  271. package/dist/render/draw.d.ts +33 -1
  272. package/dist/render/draw.js +593 -215
  273. package/dist/render/draw.js.map +1 -1
  274. package/dist/render/elevation.d.ts +65 -43
  275. package/dist/render/elevation.js +414 -140
  276. package/dist/render/elevation.js.map +1 -1
  277. package/dist/render/figmaIcons.d.ts +12 -0
  278. package/dist/render/figmaIcons.js +21 -0
  279. package/dist/render/figmaIcons.js.map +1 -0
  280. package/dist/render/hit.d.ts +22 -2
  281. package/dist/render/hit.js +168 -25
  282. package/dist/render/hit.js.map +1 -1
  283. package/dist/render/icons.js +69 -10
  284. package/dist/render/icons.js.map +1 -1
  285. package/dist/render/linkTile.d.ts +15 -0
  286. package/dist/render/linkTile.js +369 -0
  287. package/dist/render/linkTile.js.map +1 -0
  288. package/dist/render/markup.d.ts +11 -0
  289. package/dist/render/markup.js +112 -0
  290. package/dist/render/markup.js.map +1 -0
  291. package/dist/render/navigate.d.ts +88 -0
  292. package/dist/render/navigate.js +100 -0
  293. package/dist/render/navigate.js.map +1 -0
  294. package/dist/render/snap.d.ts +20 -1
  295. package/dist/render/snap.js +118 -25
  296. package/dist/render/snap.js.map +1 -1
  297. package/dist/render/squircle.d.ts +8 -0
  298. package/dist/render/squircle.js +71 -0
  299. package/dist/render/squircle.js.map +1 -0
  300. package/dist/render/view.d.ts +115 -2
  301. package/dist/render/view.js +244 -19
  302. package/dist/render/view.js.map +1 -1
  303. package/dist/skia/SkiaDrawCtx.d.ts +30 -2
  304. package/dist/skia/SkiaDrawCtx.js +198 -43
  305. package/dist/skia/SkiaDrawCtx.js.map +1 -1
  306. package/dist/skia/host.d.ts +18 -2
  307. package/dist/skia/host.js +46 -1
  308. package/dist/skia/host.js.map +1 -1
  309. package/dist/solver/equations.js +37 -2
  310. package/dist/solver/equations.js.map +1 -1
  311. package/dist/solver/gauss-newton.d.ts +17 -0
  312. package/dist/solver/gauss-newton.js +144 -36
  313. package/dist/solver/gauss-newton.js.map +1 -1
  314. package/dist/solver/linalg.d.ts +45 -2
  315. package/dist/solver/linalg.js +164 -10
  316. package/dist/solver/linalg.js.map +1 -1
  317. package/dist/solver/types.d.ts +5 -0
  318. package/dist/tools/annotate.d.ts +57 -1
  319. package/dist/tools/annotate.js +64 -43
  320. package/dist/tools/annotate.js.map +1 -1
  321. package/dist/tools/chamfer.d.ts +12 -0
  322. package/dist/tools/chamfer.js +114 -0
  323. package/dist/tools/chamfer.js.map +1 -0
  324. package/dist/tools/corner.d.ts +38 -0
  325. package/dist/tools/corner.js +99 -0
  326. package/dist/tools/corner.js.map +1 -0
  327. package/dist/tools/dim.d.ts +86 -9
  328. package/dist/tools/dim.js +581 -96
  329. package/dist/tools/dim.js.map +1 -1
  330. package/dist/tools/elevation.js +1 -1
  331. package/dist/tools/elevation.js.map +1 -1
  332. package/dist/tools/fillet.d.ts +9 -0
  333. package/dist/tools/fillet.js +86 -0
  334. package/dist/tools/fillet.js.map +1 -0
  335. package/dist/tools/freehand.d.ts +3 -2
  336. package/dist/tools/freehand.js +19 -12
  337. package/dist/tools/freehand.js.map +1 -1
  338. package/dist/tools/index.js +14 -4
  339. package/dist/tools/index.js.map +1 -1
  340. package/dist/tools/line.d.ts +8 -3
  341. package/dist/tools/line.js +66 -30
  342. package/dist/tools/line.js.map +1 -1
  343. package/dist/tools/modify.d.ts +13 -0
  344. package/dist/tools/modify.js +105 -25
  345. package/dist/tools/modify.js.map +1 -1
  346. package/dist/tools/openings.js +22 -15
  347. package/dist/tools/openings.js.map +1 -1
  348. package/dist/tools/registry.d.ts +8 -0
  349. package/dist/tools/registry.js +42 -2
  350. package/dist/tools/registry.js.map +1 -1
  351. package/dist/tools/select.d.ts +77 -3
  352. package/dist/tools/select.js +560 -74
  353. package/dist/tools/select.js.map +1 -1
  354. package/dist/tools/shapes.d.ts +14 -0
  355. package/dist/tools/shapes.js +154 -75
  356. package/dist/tools/shapes.js.map +1 -1
  357. package/dist/units/format.d.ts +10 -2
  358. package/dist/units/format.js +18 -3
  359. package/dist/units/format.js.map +1 -1
  360. package/dist/view3d/build.d.ts +35 -0
  361. package/dist/view3d/build.js +630 -0
  362. package/dist/view3d/build.js.map +1 -0
  363. package/dist/view3d/camera.d.ts +60 -0
  364. package/dist/view3d/camera.js +84 -0
  365. package/dist/view3d/camera.js.map +1 -0
  366. package/dist/view3d/fatLines.d.ts +11 -0
  367. package/dist/view3d/fatLines.js +83 -0
  368. package/dist/view3d/fatLines.js.map +1 -0
  369. package/dist/view3d/lines.d.ts +17 -0
  370. package/dist/view3d/lines.js +271 -0
  371. package/dist/view3d/lines.js.map +1 -0
  372. package/dist/view3d/mesh.d.ts +51 -0
  373. package/dist/view3d/mesh.js +101 -0
  374. package/dist/view3d/mesh.js.map +1 -0
  375. package/dist/view3d/poly.d.ts +16 -0
  376. package/dist/view3d/poly.js +109 -0
  377. package/dist/view3d/poly.js.map +1 -0
  378. package/dist/view3d/viewer.d.ts +86 -0
  379. package/dist/view3d/viewer.js +350 -0
  380. package/dist/view3d/viewer.js.map +1 -0
  381. package/package.json +15 -2
  382. package/src/app/edit.ts +83 -12
  383. package/src/app/main.ts +11 -5
  384. package/src/app/state.ts +38 -5
  385. package/src/data/memory.ts +2 -2
  386. package/src/data/provider.ts +15 -7
  387. package/src/data/sync.ts +87 -50
  388. package/src/editor/actions.ts +292 -83
  389. package/src/editor/confirm.ts +58 -0
  390. package/src/editor/elevation.ts +698 -478
  391. package/src/editor/face.ts +227 -0
  392. package/src/editor/files.ts +40 -4
  393. package/src/editor/gestures.ts +147 -31
  394. package/src/editor/keypad.ts +43 -11
  395. package/src/editor/keys.ts +25 -5
  396. package/src/editor/laser.ts +98 -20
  397. package/src/editor/linkActions.ts +194 -0
  398. package/src/editor/linkFollow.ts +43 -0
  399. package/src/editor/linkWrite.ts +77 -0
  400. package/src/editor/links.ts +181 -0
  401. package/src/editor/markup.ts +92 -8
  402. package/src/editor/mode.ts +83 -7
  403. package/src/editor/ports.ts +37 -6
  404. package/src/editor/project.ts +155 -26
  405. package/src/editor/selection.ts +54 -8
  406. package/src/editor/status.ts +2 -0
  407. package/src/editor/tooltips.ts +47 -0
  408. package/src/editor/view3d.ts +119 -0
  409. package/src/editor/view3dState.ts +61 -0
  410. package/src/export/dxf.ts +1 -1
  411. package/src/export/pdf.ts +15 -7
  412. package/src/export/plan.ts +119 -35
  413. package/src/index.ts +5 -0
  414. package/src/input/keyboard.ts +2 -4
  415. package/src/model/constraints.ts +13 -4
  416. package/src/model/demo.ts +3 -3
  417. package/src/model/elevation.ts +6 -16
  418. package/src/model/faces.ts +153 -0
  419. package/src/model/facesolve.ts +322 -0
  420. package/src/model/history.ts +19 -11
  421. package/src/model/images.ts +35 -0
  422. package/src/model/links.ts +77 -0
  423. package/src/model/markup.ts +80 -0
  424. package/src/model/measurement.ts +26 -0
  425. package/src/model/openings.ts +6 -0
  426. package/src/model/planGeom.ts +174 -8
  427. package/src/model/project.ts +3 -2
  428. package/src/model/projectfile.ts +2 -1
  429. package/src/model/rooms.ts +1 -1
  430. package/src/model/settings.ts +8 -2
  431. package/src/model/sketch.ts +101 -14
  432. package/src/model/smooth.ts +51 -0
  433. package/src/model/store.ts +35 -4
  434. package/src/model/types.ts +170 -8
  435. package/src/model/wallfaces.ts +126 -17
  436. package/src/model/wallshape.ts +97 -0
  437. package/src/react/BottomBar.tsx +263 -46
  438. package/src/react/Buttons.tsx +50 -9
  439. package/src/react/CadEditor.tsx +133 -30
  440. package/src/react/ConfirmSheet.tsx +38 -0
  441. package/src/react/ConflictSheet.tsx +19 -12
  442. package/src/react/Drawer.tsx +213 -110
  443. package/src/react/Duck.tsx +50 -0
  444. package/src/react/Empty3D.tsx +32 -0
  445. package/src/react/FitScroll.tsx +19 -0
  446. package/src/react/Icon.native.tsx +5 -0
  447. package/src/react/Icon.web.tsx +5 -0
  448. package/src/react/KeypadSheet.tsx +253 -60
  449. package/src/react/LaserTray.tsx +12 -8
  450. package/src/react/MarkupPanel.tsx +150 -0
  451. package/src/react/PageThumb.native.tsx +18 -7
  452. package/src/react/PageThumb.web.tsx +4 -4
  453. package/src/react/PlanCanvas.native.tsx +151 -34
  454. package/src/react/PlanCanvas.web.tsx +15 -5
  455. package/src/react/Popovers.tsx +116 -51
  456. package/src/react/Rail.tsx +360 -27
  457. package/src/react/ShapeMenu.tsx +66 -0
  458. package/src/react/Sheet.tsx +56 -11
  459. package/src/react/Slider.tsx +48 -0
  460. package/src/react/Toast.tsx +16 -9
  461. package/src/react/ToolTip.tsx +49 -0
  462. package/src/react/TopBar.tsx +97 -39
  463. package/src/react/Tween.native.tsx +36 -0
  464. package/src/react/Tween.tsx +24 -0
  465. package/src/react/View3D.native.tsx +131 -0
  466. package/src/react/View3D.web.tsx +131 -0
  467. package/src/react/View3DHost.ts +367 -0
  468. package/src/react/corners.ts +52 -0
  469. package/src/react/easing.ts +14 -0
  470. package/src/react/host.ts +8 -3
  471. package/src/react/hostKeypad.ts +66 -0
  472. package/src/react/motion.tsx +239 -0
  473. package/src/react/ports.ts +78 -9
  474. package/src/react/saving.ts +80 -0
  475. package/src/react/store.ts +35 -3
  476. package/src/react/theme.ts +8 -0
  477. package/src/react/topRow.ts +71 -0
  478. package/src/react/touch.ts +10 -0
  479. package/src/render/ctx.ts +8 -0
  480. package/src/render/draw.ts +437 -175
  481. package/src/render/elevation.ts +349 -143
  482. package/src/render/figmaIcons.ts +22 -0
  483. package/src/render/hit.ts +140 -21
  484. package/src/render/icons.ts +69 -10
  485. package/src/render/linkTile.ts +297 -0
  486. package/src/render/markup.ts +91 -0
  487. package/src/render/navigate.ts +114 -0
  488. package/src/render/snap.ts +105 -22
  489. package/src/render/squircle.ts +73 -0
  490. package/src/render/view.ts +255 -19
  491. package/src/skia/SkiaDrawCtx.ts +163 -41
  492. package/src/skia/host.ts +46 -1
  493. package/src/solver/equations.ts +37 -2
  494. package/src/solver/gauss-newton.ts +125 -28
  495. package/src/solver/linalg.ts +141 -5
  496. package/src/solver/types.ts +5 -0
  497. package/src/styles.css +91 -42
  498. package/src/tools/annotate.ts +58 -29
  499. package/src/tools/chamfer.ts +103 -0
  500. package/src/tools/corner.ts +99 -0
  501. package/src/tools/dim.ts +524 -92
  502. package/src/tools/elevation.ts +1 -1
  503. package/src/tools/fillet.ts +82 -0
  504. package/src/tools/freehand.ts +20 -16
  505. package/src/tools/index.ts +17 -4
  506. package/src/tools/line.ts +59 -23
  507. package/src/tools/modify.ts +86 -24
  508. package/src/tools/openings.ts +8 -13
  509. package/src/tools/registry.ts +27 -2
  510. package/src/tools/select.ts +424 -75
  511. package/src/tools/shapes.ts +119 -58
  512. package/src/ui/ctx.ts +2 -1
  513. package/src/ui/domPorts.ts +23 -4
  514. package/src/ui/drawer.ts +6 -26
  515. package/src/ui/elevation.ts +10 -101
  516. package/src/ui/keypad.ts +8 -14
  517. package/src/ui/laser.ts +2 -2
  518. package/src/ui/menu.ts +63 -17
  519. package/src/ui/noteinput.ts +3 -3
  520. package/src/ui/opacity.ts +108 -0
  521. package/src/ui/palette.ts +67 -12
  522. package/src/ui/rail.ts +21 -7
  523. package/src/ui/topbar.ts +4 -14
  524. package/src/units/format.ts +18 -3
  525. package/src/view3d/build.ts +607 -0
  526. package/src/view3d/camera.ts +113 -0
  527. package/src/view3d/fatLines.ts +83 -0
  528. package/src/view3d/lines.ts +258 -0
  529. package/src/view3d/mesh.ts +111 -0
  530. package/src/view3d/poly.ts +104 -0
  531. package/src/view3d/viewer.ts +348 -0
  532. package/dist/react/ElevCanvas.native.d.ts +0 -3
  533. package/dist/react/ElevCanvas.native.js +0 -58
  534. package/dist/react/ElevCanvas.native.js.map +0 -1
  535. package/dist/react/ElevCanvas.web.d.ts +0 -4
  536. package/dist/react/ElevCanvas.web.js +0 -44
  537. package/dist/react/ElevCanvas.web.js.map +0 -1
  538. package/dist/react/ElevationSheet.d.ts +0 -2
  539. package/dist/react/ElevationSheet.js +0 -38
  540. package/dist/react/ElevationSheet.js.map +0 -1
  541. package/dist/render/elevationView.d.ts +0 -3
  542. package/dist/render/elevationView.js +0 -100
  543. package/dist/render/elevationView.js.map +0 -1
  544. package/src/react/ElevCanvas.native.tsx +0 -68
  545. package/src/react/ElevCanvas.web.tsx +0 -42
  546. package/src/react/ElevationSheet.tsx +0 -88
  547. package/src/render/elevationView.ts +0 -73
package/README.md CHANGED
@@ -21,9 +21,10 @@ Peer dependencies:
21
21
  | `react-native` | `>=0.74` | always (react-native-web in a browser) |
22
22
  | `@shopify/react-native-skia` | `>=2.5` | the editor on iOS and Android |
23
23
  | `react-native-gesture-handler`| `>=2.31` | the editor on iOS and Android |
24
+ | `react-native-reanimated` | `>=4` | the editor on iOS and Android (pan and zoom run on the UI thread; its Babel plugin must be in the app's config) |
24
25
  | `react-native-svg` | `>=15` | the editor's icons on iOS and Android |
25
26
 
26
- Only `./core` (see below) runs without the three native packages.
27
+ Only `./core` (see below) runs without the four native packages.
27
28
 
28
29
  ## How it resolves
29
30
 
@@ -101,14 +102,15 @@ lives in the browser's own storage, which is what the dev harness uses.
101
102
  | ------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
102
103
  | `sync` | `CadSync` | The drawing, from `openCadDrawing`. Saved there as it changes. |
103
104
  | `onBack` | `() => void` | The top bar's back button. Without it, Back opens the project's pages. |
104
- | `headerRight` | `ReactNode` | The host's own buttons in the top bar, such as a Bluetooth status icon. |
105
+ | `headerRight` | `ReactNode \| (buttonSize: number) => ReactNode` | The host's own buttons in the top bar, such as a Bluetooth status icon. As a function it gets the bar's round-button size (42 pt on a phone, 46 otherwise). |
105
106
  | `theme` | `'light' \| 'dark'` | Canvas colors. The chrome is dark either way. Without it, the person's Theme setting decides. |
106
107
  | `units` | `{ format: (inches: number) => string; metric: boolean; denom?: number }` | Lengths the host's way. Hides Units in Settings. |
107
108
  | `fonts` | `SkiaFonts` | Typefaces for text on the plan by CSS weight, with a fallback. Device only. |
108
109
  | `pickImage` | `() => Promise<{ dataUrl: string; w: number; h: number } \| null>` | A photo or plan to trace. In a browser a file picker is the default. |
109
110
  | `saveFile` | `(name: string, mime: string, data: string) => void` | How exports (PDF, DXF, project file) reach the person, e.g. a share sheet. In a browser they download. |
110
- | `readOnly` | `boolean` | Pan and zoom only, nothing saved. |
111
+ | `readOnly` | `boolean` | Pan and zoom only, nothing saved. A tap on a link's tile asks, then opens it. |
111
112
  | `devTools` | `boolean` | Reset to the demo, open and save project files, in Settings. Default `true`; turn off in production. |
113
+ | `links` | `CadLinks` | The job's files to link on the drawing, and its lengths for lines (see below). Without it there's nothing to link. |
112
114
 
113
115
  Fonts on a device, with react-native-skia:
114
116
 
@@ -156,11 +158,81 @@ rejects with `NotACadDrawing` whose `reason` is `'missing'` (no such file) or
156
158
  The returned `CadSync` has `stop()`, `idle()` (resolves once every write so
157
159
  far has finished), `saveThumbnail(pngDataUrl)` and `imageUrl(ref)`.
158
160
 
159
- **Measurements.** When the provider supplies `measurements`, every driving
160
- dimension in the drawing is kept as a BOLDR measurement: lengths in
161
- micrometres, angles in degrees. Changing one elsewhere changes the dimension.
162
- `measurementOf(constraint)` gives a constraint's value in that form, or `null`
163
- for reference and print dimensions.
161
+ **Measurements.** A dimension drawn in the editor is the drawing's alone: no
162
+ measurement is made for it. The person saves one to the drawing's group from
163
+ its bar (Save to group, through `links.saveMeasurement`), and it's linked to
164
+ that measurement from then on. Drawings made by earlier versions kept every
165
+ driving dimension as a measurement of the drawing's file; when the provider
166
+ supplies `measurements`, those still follow their dimensions both ways
167
+ (`create` is no longer called). `setPlaced(ids, linked)` hears every
168
+ measurement the drawing shows: its own, and the job's it's linked to, each with
169
+ its group (and a form's column). `measurementOf(constraint)` gives a
170
+ constraint's value as BOLDR keeps it — lengths in micrometres, angles in
171
+ degrees — or `null` for reference and print dimensions and linked ones.
172
+
173
+ ### Linking the job's files and measurements
174
+
175
+ With `links`, Annotate gets a yellow + (under the rail; a phone's in the
176
+ trash's corner while nothing's selected) that puts the job's files on the plan
177
+ as tiles, with leaders, opened from the bar. A measurement comes into a drawing
178
+ only as the dimension it drives: in Draft, a line's length keypad (select the
179
+ line, tap +) offers the job's lengths (a page it swipes to on a touch screen,
180
+ Select from list on a desktop), and the one picked sets the line, linked to
181
+ it. A dimension is saved to the group from its bar (Save to group). A new length for a linked dimension asks first: Change both, Only this
182
+ drawing (unlinks), or Cancel.
183
+
184
+ ```ts
185
+ interface CadLinks {
186
+ pick(req: { want: 'files'; linked: LinkTarget[] }): Promise<LinkTarget[]>; // [] for nothing
187
+ measurements?(cb: (list: LinkTarget[]) => void): () => void; // the job's lengths and angles, in the order to show them
188
+ pickMeasurement?(req: { kind: 'length' | 'angle' }): Promise<LinkTarget | null>; // the host's own list (a side drawer)
189
+ subscribe(targets: LinkTarget[], cb: (info: Record<string, LinkInfo>) => void): () => void;
190
+ open(target: LinkTarget): void;
191
+ update?(target: LinkTarget, value: number, capture?: unknown): void; // µm or degrees, the person having said so
192
+ saveMeasurement?(m: { kind: 'length' | 'angle'; value: number; capture?: unknown }): Promise<LinkTarget | null>;
193
+ canSave?: boolean; // false where a measurement can't be saved (a form's group)
194
+ }
195
+ ```
196
+
197
+ - A `LinkTarget` is `{ kind: 'file' | 'measurement', id, groupId, columnId? }`
198
+ plus what it was when it was linked (`name`, `groupName`, `fileType`,
199
+ `mkind`, `value`, `text`). Resolve it by `groupId` and `id` in the job open
200
+ now, never by a stored path, so copied and moved jobs keep working.
201
+ - `pick` offers the job's files to pick. BOLDR's pickers show the measurements
202
+ too, greyed out, and a tap on one says they're added in Draft; anything but
203
+ a file handed back is dropped.
204
+ - A line's length keypad and a dimension's angle keypad take the job's
205
+ measurements. On a touch screen the keypad swipes to a page of them; on a
206
+ desktop it has Select from list, which calls `pickMeasurement` (the host's
207
+ own list, those of `kind` pickable and the rest greyed out), or shows that
208
+ page when the host has none. `measurements` calls back with the job's
209
+ lengths and angles as measurement targets (with `mkind`, `value` in
210
+ micrometres or degrees, and `text`), again as they change, and not until
211
+ the whole job's been heard from; the keypad greys out those that aren't its
212
+ kind. A host keypad (`keypad`) gets `measurementKind` and `pickMeasurement`
213
+ on such a request: show the job's measurements a swipe away, greying out
214
+ the other kind, and hand back the one tapped.
215
+ - To draw that page itself, so the list looks as it does everywhere else in
216
+ the host, pass `measurementList` to `CadEditor`: a function of
217
+ `{ kind, pick, width, height }` that returns the list's element (for
218
+ example `page => <JobList {...page} />`). It's rendered as a component of its
219
+ own from when the page is first shown, and again when what it's given
220
+ changes. List the job's measurements at that size, grey out the other kind,
221
+ and call `pick` with the one tapped. BOLDR does on a tablet, with its phone
222
+ keypad's list. Without it the page is the editor's own grid, made from
223
+ `measurements`. Either way the page is there only when `links` has
224
+ `measurements` or `pickMeasurement`, and a desktop shows it only without
225
+ `pickMeasurement`.
226
+ - `subscribe` answers by `linkKey(target)`, and again whenever that changes.
227
+ Say `exists: false` only once it's known to be gone, never while loading.
228
+ `text` is the value written the host's way; `thumbUrl` a picture to show.
229
+ - Pass one `links` object for as long as the drawing is open (memoize it).
230
+
231
+ **Laser readings.** `laserReading(inches, capture)` takes the host's own record
232
+ of a reading (anything JSON: its device, its number). It's kept on the
233
+ dimension the reading sets and handed back with `saveMeasurement`, or with
234
+ `update` for a linked one, so a measurement saved from a reading records its
235
+ device. A value typed over it isn't the reading's.
164
236
 
165
237
  For tests and prototypes, `memoryProvider()` is an in-memory provider with
166
238
  `remote()` and `remoteMeasurement()` to change things as another device would.
@@ -171,7 +243,7 @@ For tests and prototypes, `memoryProvider()` is an in-memory provider with
171
243
  import { setLaserConnected, laserReading } from '@reekon-tools/boldr-cad';
172
244
 
173
245
  setLaserConnected(true); // shows the reading tray, enables the keypad's Laser key
174
- laserReading(inches); // into an open keypad, onto the selected wall, or into the tray
246
+ laserReading(inches, capture); // into an open keypad, onto the selected wall, or into the tray
175
247
  ```
176
248
 
177
249
  `laserReading` returns `false` when no drawing is open to take the value, so
@@ -1,8 +1,14 @@
1
- import type { Constraint, SelItem } from '../model/types';
1
+ import type { Constraint, SelItem, Sketch } from '../model/types';
2
2
  import { type AddResult, type SolveResult } from '../solver';
3
3
  export declare function analyze(): void;
4
4
  export declare const solveSketch: (heavy?: string[]) => SolveResult;
5
5
  export declare function solveOrRevert(): SolveResult;
6
+ /**
7
+ * Walls made thicker or thinner, or lines turned into walls: what's measured on walls' faces holds, their centrelines
8
+ * moving to keep it (a face's length depends on the walls at its corners as well as its own). False — and nothing
9
+ * moved — when it can't hold.
10
+ */
11
+ export declare function holdFaces(): boolean;
6
12
  /** Re-place locked doors/windows from their dimensions (after any geometry change). */
7
13
  export declare function resolveOpeningsNow(): void;
8
14
  export declare function existsSel(s: SelItem): boolean;
@@ -10,6 +16,11 @@ export declare function existsSel(s: SelItem): boolean;
10
16
  export declare function afterEdit(): void;
11
17
  export declare function undo(): void;
12
18
  export declare function redo(): void;
19
+ /**
20
+ * The things a constraint ties together, each as the points to hold for it: a cabinet (its corners, when it's one of
21
+ * its edges or corners), a line (its ends), a point.
22
+ */
23
+ export declare function holdGroups(sk: Sketch, c: Constraint): string[][];
13
24
  /**
14
25
  * Add a constraint through the solver and explain the outcome:
15
26
  * reference dimension → toast, conflict → conflict sheet (unless silent).
package/dist/app/edit.js CHANGED
@@ -1,15 +1,21 @@
1
1
  import { drivingDim } from '../model/openings';
2
+ import { edgeOf, wallOf } from '../model/planGeom';
2
3
  import { CONS_LABEL } from '../model/constraints';
3
4
  import { HS, stepRedo, stepUndo } from '../model/history';
5
+ import { pushedOut, syncFaces } from '../model/facesolve';
6
+ import { elevSyncFrame, fitState, overflow, pastWallMsg, restoreFit } from '../editor/elevation';
4
7
  import { resolveOpenings } from '../model/openings';
5
8
  import { gc, restorePos, snapshotPos } from '../model/sketch';
6
- import { page, saveSoon, SK } from '../model/store';
9
+ import { page, planSK, saveSoon, SK } from '../model/store';
10
+ import { cabOfPoint, cabPoints } from '../model/faces';
7
11
  import { requestDraw } from '../render/view';
8
12
  import { solver } from '../solver';
9
13
  import { cancelTool } from '../tools/registry';
10
14
  import { fmtLen } from '../units';
11
15
  import { ed } from './state';
12
16
  import { refreshDrawerSoon, renderElevation, showConflict, toast, updateCtx, updateStatus } from '../editor/ports';
17
+ import { refreshLinks } from '../editor/links';
18
+ import { followLinked } from '../editor/linkFollow';
13
19
  export function analyze() {
14
20
  ed.ana = solver.analyzeDOF(SK());
15
21
  }
@@ -21,9 +27,19 @@ export function solveOrRevert() {
21
27
  restorePos(sk, snap);
22
28
  return s;
23
29
  }
30
+ /**
31
+ * Walls made thicker or thinner, or lines turned into walls: what's measured on walls' faces holds, their centrelines
32
+ * moving to keep it (a face's length depends on the walls at its corners as well as its own). False — and nothing
33
+ * moved — when it can't hold.
34
+ */
35
+ export function holdFaces() {
36
+ if (!Object.values(SK().cons).some(c => c.face || c.faces))
37
+ return true;
38
+ return solveOrRevert().ok;
39
+ }
24
40
  /** Re-place locked doors/windows from their dimensions (after any geometry change). */
25
41
  export function resolveOpeningsNow() {
26
- ed.badOpeningDims = resolveOpenings(SK());
42
+ ed.badOpeningDims = resolveOpenings(planSK());
27
43
  }
28
44
  export function existsSel(s) {
29
45
  const sk = SK();
@@ -35,21 +51,28 @@ export function existsSel(s) {
35
51
  case 'cons':
36
52
  case 'dim': return !!sk.cons[s.id];
37
53
  case 'room': return !!sk.rooms[s.id];
38
- case 'opening': return !!sk.openings[s.id];
54
+ case 'opening': return !!planSK().openings[s.id];
55
+ case 'cab': return !!sk.cabs?.[s.id];
56
+ case 'elev': return true;
57
+ case 'oanchor': return !!planSK().openings[s.id.split('|')[0]];
58
+ case 'wface': return !!wallOf(sk, edgeOf(s.id)[0]);
39
59
  case 'odim': {
40
- const [op, part] = s.id.split('|'), o = sk.openings[op];
41
- return !!o && (part.startsWith('d:') ? (o.dims || []).some(d => d.id === part.slice(2)) : !drivingDim(o));
60
+ const [op, part] = s.id.split('|'), o = planSK().openings[op];
61
+ return !!o && (part === 'w' || (part.startsWith('d:') ? (o.dims || []).some(d => d.id === part.slice(2)) : !drivingDim(o)));
42
62
  }
43
63
  case 'note': return sk.notes.some(n => n.id === s.id);
44
- case 'underlay': return !!page().underlay;
64
+ case 'underlay': return page().underlays.some(u => u.id === s.id);
45
65
  }
46
66
  return false;
47
67
  }
48
68
  /** Run after every model change: clean up, re-analyze, refresh UI, autosave. */
49
69
  export function afterEdit() {
50
70
  ed.editSeq++;
51
- gc(SK());
71
+ gc(planSK()); // the plan, and each wall face
52
72
  resolveOpeningsNow();
73
+ // what's drawn on wall faces follows the plan's corners, doors and windows
74
+ ed.badFaceCons = syncFaces(planSK());
75
+ elevSyncFrame(); // the open wall's frame (its length, its corners) as the plan has it now
53
76
  ed.sel = ed.sel.filter(s => existsSel(s));
54
77
  analyze();
55
78
  updateCtx();
@@ -57,11 +80,13 @@ export function afterEdit() {
57
80
  refreshDrawerSoon();
58
81
  requestDraw();
59
82
  renderElevation();
83
+ refreshLinks(); // (what's linked may have changed: the host is asked about it)
84
+ followLinked(); // (and an undo may have put a linked dimension at something else than the job says)
60
85
  saveSoon();
61
86
  }
62
87
  export function undo() {
63
88
  if (!HS().u.length) {
64
- toast('Nothing to undo');
89
+ toast('Nothing to undo', { warn: true });
65
90
  return;
66
91
  }
67
92
  cancelTool();
@@ -75,7 +100,7 @@ export function redo() {
75
100
  if (!h.u.length && !h.r.length)
76
101
  return;
77
102
  if (!h.r.length) {
78
- toast('Nothing to redo');
103
+ toast('Nothing to redo', { warn: true });
79
104
  return;
80
105
  }
81
106
  cancelTool();
@@ -84,12 +109,72 @@ export function redo() {
84
109
  afterEdit();
85
110
  toast('Redone');
86
111
  }
112
+ /** Solve with these points held exactly where they are (fixed for the solve, then as they were). */
113
+ function solveHolding(sk, hold) {
114
+ const pts = hold.map(id => sk.points[id]).filter(Boolean), had = pts.map(p => p.fixed);
115
+ pts.forEach(p => { p.fixed = true; });
116
+ const s = solver.solve(sk);
117
+ pts.forEach((p, i) => { if (had[i])
118
+ p.fixed = true;
119
+ else
120
+ delete p.fixed; });
121
+ return s;
122
+ }
123
+ /**
124
+ * The things a constraint ties together, each as the points to hold for it: a cabinet (its corners, when it's one of
125
+ * its edges or corners), a line (its ends), a point.
126
+ */
127
+ export function holdGroups(sk, c) {
128
+ const face = sk, groups = [], seen = new Set();
129
+ const add = (key, pts) => { if (!seen.has(key) && pts.length) {
130
+ seen.add(key);
131
+ groups.push(pts);
132
+ } };
133
+ const point = (pid) => {
134
+ if (!pid || !sk.points[pid])
135
+ return;
136
+ const cab = cabOfPoint(sk, pid);
137
+ if (cab)
138
+ add('cab:' + cab, cabPoints(face.cabs[cab]));
139
+ else
140
+ add('pt:' + pid, [pid]);
141
+ };
142
+ for (const lid of [c.l, c.l1, c.l2, c.line]) {
143
+ const l = lid ? sk.lines[lid] : undefined;
144
+ if (!l)
145
+ continue;
146
+ if (l.cab && face.cabs?.[l.cab])
147
+ add('cab:' + l.cab, cabPoints(face.cabs[l.cab]));
148
+ else
149
+ add('line:' + lid, [l.a, l.b]);
150
+ }
151
+ for (const pid of [c.a, c.b, c.p])
152
+ point(pid);
153
+ return groups;
154
+ }
87
155
  /**
88
156
  * Add a constraint through the solver and explain the outcome:
89
157
  * reference dimension → toast, conflict → conflict sheet (unless silent).
90
158
  */
91
159
  export function tryAddConstraint(c, { silent = false, onResolved = null } = {}) {
92
- const r = solver.addConstraint(SK(), c, { explain: !silent });
160
+ // nothing may be pushed past its wall (in the wall view, past the wall; in the plan, a wall made shorter than
161
+ // what's on it): a constraint that would is taken back
162
+ const sk = SK(), was = overflow(sk), held = fitState(sk);
163
+ const r = solver.addConstraint(sk, c, { explain: !silent });
164
+ // met by moving everything a little, it ran past the wall: try keeping each thing it ties still in turn, so the
165
+ // other one moves to meet it (a short cabinet lifted to line up with a tall one, not the tall one sunk into the floor)
166
+ if (r.ok && r.id && !r.ref && pushedOut(was, overflow(sk))) {
167
+ for (const hold of holdGroups(sk, c)) {
168
+ restoreFit(sk, held);
169
+ if (solveHolding(sk, hold).ok && !pushedOut(was, overflow(sk)))
170
+ return r;
171
+ }
172
+ delete sk.cons[r.id];
173
+ restoreFit(sk, held);
174
+ if (!silent)
175
+ toast(pastWallMsg(), { warn: true });
176
+ return { ok: false };
177
+ }
93
178
  if (silent)
94
179
  return r;
95
180
  if (r.ref) {
@@ -98,7 +183,7 @@ export function tryAddConstraint(c, { silent = false, onResolved = null } = {})
98
183
  : 'Kept as a reference dimension (' + fmtLen(c.value) + '). Other constraints already set this value — remove one to drive it.', { warn: !r.refSame });
99
184
  }
100
185
  else if (r.redundant) {
101
- toast(CONS_LABEL[c.type] + ' is already true — other constraints set it.');
186
+ toast(CONS_LABEL[c.type] + ' is already true — other constraints set it.', { warn: true });
102
187
  }
103
188
  else if (r.conflict === 'dependent') {
104
189
  showConflict({ title: 'Can’t add ' + (CONS_LABEL[c.type] || 'constraint').toLowerCase(), msg: 'It fights with constraints already on the drawing. Remove one of these to apply it.', ids: r.culprits || [], pending: c, onResolved });
@@ -1 +1 @@
1
- {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/app/edit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/app/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAoC,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACnH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,UAAU,OAAO;IACrB,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAgB,EAAe,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;AAExF,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAChC,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,aAAa,EAAE,CAAC,EAAE,CAAC;AAC5B,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,kBAAkB;IAChC,EAAE,CAAC,cAAc,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,CAAU;IAClC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvC,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrC,KAAK,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzC,KAAK,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC;QAAC,KAAK,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChD,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrC,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjD,KAAK,KAAK,EAAE,OAAO,CAAC,CAAE,EAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnD,KAAK,MAAM,EAAE,OAAO,IAAI,CAAC;QACzB,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,KAAK,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC9D,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9H,CAAC;QACD,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,KAAK,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,SAAS;IACvB,EAAE,CAAC,OAAO,EAAE,CAAC;IACb,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,+BAA+B;IAC7C,kBAAkB,EAAE,CAAC;IACrB,2EAA2E;IAC3E,EAAE,CAAC,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,aAAa,EAAE,CAAC,CAAC,yEAAyE;IAC1F,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,YAAY,EAAE,CAAC;IACf,iBAAiB,EAAE,CAAC;IACpB,WAAW,EAAE,CAAC;IACd,eAAe,EAAE,CAAC;IAClB,YAAY,EAAE,CAAC,CAAC,+DAA+D;IAC/E,YAAY,EAAE,CAAC,CAAC,oFAAoF;IACpG,QAAQ,EAAE,CAAC;AACb,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACzE,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,KAAK,CAAC,QAAQ,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC;IACf,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;QAAE,OAAO;IACvC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACtE,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,KAAK,CAAC,QAAQ,CAAC,CAAC;AAClB,CAAC;AAED,oGAAoG;AACpG,SAAS,YAAY,CAAC,EAAU,EAAE,IAAc;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvF,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;QAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC;;QAAM,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,CAAa;IAClD,MAAM,IAAI,GAAG,EAAc,EAAE,MAAM,GAAe,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/E,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,GAAa,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC;IACvH,MAAM,KAAK,GAAG,CAAC,GAAuB,EAAE,EAAE;QACxC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YAAE,OAAO;QACpC,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,GAAG;YAAE,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;;YAAM,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1C,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;;YAC7E,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAa,EAAE,EAAE,MAAM,GAAG,KAAK,EAAE,UAAU,GAAG,IAA2B,EAAE,GAAG,EAAE;IAC/G,8GAA8G;IAC9G,uDAAuD;IACvD,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5D,gHAAgH;IAChH,uHAAuH;IACvH,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3D,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;YACrC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACrB,IAAI,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrB,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM;YAAE,KAAK,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,IAAI,MAAM;QAAE,OAAO,CAAC,CAAC;IACrB,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QACV,KAAK,CAAC,CAAC,CAAC,OAAO;YACb,CAAC,CAAC,2EAA2E;YAC7E,CAAC,CAAC,iCAAiC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAM,CAAC,GAAG,uEAAuE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5J,CAAC;SAAM,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,8CAA8C,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7F,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACtC,YAAY,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,qFAAqF,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IACxO,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;QAC1C,YAAY,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,wGAAwG,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5M,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -1,17 +1,24 @@
1
+ import { type NoteStyle } from '../model/markup';
1
2
  import type { Analysis, OpeningEdge, SelItem, SelType } from '../model/types';
2
3
  import type { Xform } from '../render/view';
3
4
  import type { DrawCtx } from '../render/ctx';
4
5
  export type Mode = 'draft' | 'annotate';
5
6
  /** Something under the pointer: geometry, or a chip/badge drawn on the canvas. */
6
7
  export interface Hit {
7
- type: SelType | 'odim' | 'oanchor' | 'uhandle' | 'nhandle';
8
+ /** 'cabfoot': a cabinet's footprint in the plan (id: its wall face's key, '#', its id) */
9
+ type: SelType | 'odim' | 'oanchor' | 'uhandle' | 'nhandle' | 'cabfoot';
8
10
  id: string;
9
11
  /** a print dimension label */
10
12
  print?: boolean;
11
13
  /** low-priority hit (room fill) */
12
14
  weak?: boolean;
13
- /** 'odim': 'w' width, 'a'/'b' distance to a wall end, or 'd:<id>' a placed dimension. 'oanchor': 's0'/'s1' edge. */
15
+ /**
16
+ * 'odim': 'w' width, 'a'/'b' distance to a wall end, or 'd:<id>' a placed dimension. 'oanchor': 's0'/'s1' edge.
17
+ * 'note', a link's tile: 'tip' its leader's tip, 'leader' along its leader (unset: its card).
18
+ */
14
19
  part?: string;
20
+ /** a wall picked whole: the side of its centreline the pointer was on (+1 the left of its A → B; a curved one's, outside) */
21
+ side?: 1 | -1;
15
22
  }
16
23
  export type OpeningDimPart = 'w' | 'a' | 'b' | `d:${string}`;
17
24
  export interface Guide {
@@ -37,7 +44,8 @@ export interface Snap {
37
44
  }
38
45
  /** Screen-space hit region registered while drawing chips, badges and labels. */
39
46
  export interface HitChip {
40
- kind: 'dim' | 'pdim' | 'cons' | 'room' | 'odim';
47
+ /** 'elev': one of the wall view's dimension chips (id: what it measures, as JSON) */
48
+ kind: 'dim' | 'pdim' | 'cons' | 'room' | 'odim' | 'elev';
41
49
  part?: string;
42
50
  id: string;
43
51
  x: number;
@@ -69,11 +77,20 @@ export declare const ed: {
69
77
  ana: Analysis;
70
78
  lastPointerTouch: boolean;
71
79
  drawConstr: boolean;
80
+ /** the rail's Walls toggle: what's drawn (lines, rectangles, circles, arcs, Draw to shape) is walls */
81
+ drawWalls: boolean;
72
82
  dimLayer: 'drive' | 'print';
73
83
  openingType: 'door' | 'window';
84
+ /** new markup's look (the stroke panel sets them; selected markup changes with them) */
74
85
  noteColor: string;
86
+ noteWidth: number;
87
+ noteStyle: NoteStyle;
88
+ /** new text notes' letter height on the drawing, inches */
89
+ noteTextIn: number;
75
90
  /** opening dimensions that can't be met (drawn red) */
76
91
  badOpeningDims: Set<string>;
92
+ /** wall-face constraints that can't be met (drawn red in the elevation) */
93
+ badFaceCons: Set<string>;
77
94
  /** dimension tool: an opening edge picked as the first end */
78
95
  /** body: the opening itself was tapped (not an edge square), so the edge is chosen from what it's measured to */
79
96
  pickedAnchor: {
@@ -83,9 +100,19 @@ export declare const ed: {
83
100
  } | null;
84
101
  /** bumped on every model change (so a double tap can't span an edit) */
85
102
  editSeq: number;
103
+ /** the side a wall was last tapped on, picking it whole: between two spaces, its length is measured on that side */
104
+ wallTap: {
105
+ id: string;
106
+ side: 1 | -1;
107
+ } | null;
86
108
  /** recently hovered points, used for alignment guides */
87
109
  recentPts: string[];
88
110
  /** view only: pan and zoom, no tools, nothing saved (people who can't edit this job) */
89
111
  readOnly: boolean;
90
112
  };
91
- export declare const isSel: (type: string, id: string) => boolean;
113
+ /**
114
+ * Whether something is selected. Drawing asks it of everything on the plan, every frame: with many things selected (a
115
+ * double tap takes in every wall joined to one) that was each against each, so a larger selection is looked up in a
116
+ * set, made again only when the selection changes (it's replaced, or added to).
117
+ */
118
+ export declare function isSel(type: string, id: string): boolean;
package/dist/app/state.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { emptyAnalysis } from '../model/constraints';
2
+ import { DEFAULT_NOTE_COLOR, DEFAULT_NOTE_WIDTH, NOTE_TEXT_IN } from '../model/markup';
2
3
  import { sessionState } from '../model/session';
3
4
  /** Shared editor state (the prototype's module-level `let`s). */
4
5
  export const ed = sessionState(() => ({
@@ -16,20 +17,48 @@ export const ed = sessionState(() => ({
16
17
  ana: emptyAnalysis(),
17
18
  lastPointerTouch: false,
18
19
  drawConstr: false,
20
+ /** the rail's Walls toggle: what's drawn (lines, rectangles, circles, arcs, Draw to shape) is walls */
21
+ drawWalls: false,
19
22
  dimLayer: 'drive',
20
23
  openingType: 'door',
21
- noteColor: '#F070EE',
24
+ /** new markup's look (the stroke panel sets them; selected markup changes with them) */
25
+ noteColor: DEFAULT_NOTE_COLOR,
26
+ noteWidth: DEFAULT_NOTE_WIDTH,
27
+ noteStyle: 'solid',
28
+ /** new text notes' letter height on the drawing, inches */
29
+ noteTextIn: NOTE_TEXT_IN,
22
30
  /** opening dimensions that can't be met (drawn red) */
23
31
  badOpeningDims: new Set(),
32
+ /** wall-face constraints that can't be met (drawn red in the elevation) */
33
+ badFaceCons: new Set(),
24
34
  /** dimension tool: an opening edge picked as the first end */
25
35
  /** body: the opening itself was tapped (not an edge square), so the edge is chosen from what it's measured to */
26
36
  pickedAnchor: null,
27
37
  /** bumped on every model change (so a double tap can't span an edit) */
28
38
  editSeq: 0,
39
+ /** the side a wall was last tapped on, picking it whole: between two spaces, its length is measured on that side */
40
+ wallTap: null,
29
41
  /** recently hovered points, used for alignment guides */
30
42
  recentPts: [],
31
43
  /** view only: pan and zoom, no tools, nothing saved (people who can't edit this job) */
32
44
  readOnly: false,
33
45
  }));
34
- export const isSel = (type, id) => ed.sel.some(s => s.type === type && s.id === id);
46
+ /**
47
+ * Whether something is selected. Drawing asks it of everything on the plan, every frame: with many things selected (a
48
+ * double tap takes in every wall joined to one) that was each against each, so a larger selection is looked up in a
49
+ * set, made again only when the selection changes (it's replaced, or added to).
50
+ */
51
+ export function isSel(type, id) {
52
+ const sel = ed.sel;
53
+ if (sel.length < 8) {
54
+ for (const s of sel)
55
+ if (s.type === type && s.id === id)
56
+ return true;
57
+ return false;
58
+ }
59
+ if (!selKeys || selKeys.sel !== sel || selKeys.n !== sel.length)
60
+ selKeys = { sel, n: sel.length, keys: new Set(sel.map(s => s.type + ' ' + s.id)) };
61
+ return selKeys.keys.has(type + ' ' + id);
62
+ }
63
+ let selKeys = null;
35
64
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/app/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAmDhD,iEAAiE;AACjE,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,EAAE,OAAe;IACrB,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,EAAe;IACpB,KAAK,EAAE,IAAkB;IACzB,SAAS,EAAE,IAAmB;IAC9B,MAAM,EAAE,IAAqB;IAC7B,OAAO,EAAE,IAAsB;IAC/B,SAAS,EAAE,IAAI,GAAG,EAAU;IAC5B,YAAY,EAAE,KAAK;IACnB,+FAA+F;IAC/F,QAAQ,EAAE,EAAe;IACzB,GAAG,EAAE,aAAa,EAAc;IAChC,gBAAgB,EAAE,KAAK;IACvB,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,OAA4B;IACtC,WAAW,EAAE,MAA2B;IACxC,SAAS,EAAE,SAAS;IACpB,uDAAuD;IACvD,cAAc,EAAE,IAAI,GAAG,EAAU;IACjC,8DAA8D;IAC9D,iHAAiH;IACjH,YAAY,EAAE,IAAgE;IAC9E,wEAAwE;IACxE,OAAO,EAAE,CAAC;IACV,yDAAyD;IACzD,SAAS,EAAE,EAAc;IACzB,wFAAwF;IACxF,QAAQ,EAAE,KAAK;CAChB,CAAC,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAU,EAAW,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/app/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAkB,MAAM,iBAAiB,CAAC;AAGvG,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA0DhD,iEAAiE;AACjE,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,EAAE,OAAe;IACrB,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,EAAe;IACpB,KAAK,EAAE,IAAkB;IACzB,SAAS,EAAE,IAAmB;IAC9B,MAAM,EAAE,IAAqB;IAC7B,OAAO,EAAE,IAAsB;IAC/B,SAAS,EAAE,IAAI,GAAG,EAAU;IAC5B,YAAY,EAAE,KAAK;IACnB,+FAA+F;IAC/F,QAAQ,EAAE,EAAe;IACzB,GAAG,EAAE,aAAa,EAAc;IAChC,gBAAgB,EAAE,KAAK;IACvB,UAAU,EAAE,KAAK;IACjB,uGAAuG;IACvG,SAAS,EAAE,KAAK;IAChB,QAAQ,EAAE,OAA4B;IACtC,WAAW,EAAE,MAA2B;IACxC,wFAAwF;IACxF,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,OAAoB;IAC/B,2DAA2D;IAC3D,UAAU,EAAE,YAAY;IACxB,uDAAuD;IACvD,cAAc,EAAE,IAAI,GAAG,EAAU;IACjC,2EAA2E;IAC3E,WAAW,EAAE,IAAI,GAAG,EAAU;IAC9B,8DAA8D;IAC9D,iHAAiH;IACjH,YAAY,EAAE,IAAgE;IAC9E,wEAAwE;IACxE,OAAO,EAAE,CAAC;IACV,oHAAoH;IACpH,OAAO,EAAE,IAA2C;IACpD,yDAAyD;IACzD,SAAS,EAAE,EAAc;IACzB,wFAAwF;IACxF,QAAQ,EAAE,KAAK;CAChB,CAAC,CAAC,CAAC;AAEJ;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,EAAU;IAC5C,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC;IACnB,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,GAAG;YAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE;gBAAE,OAAO,IAAI,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM;QAAE,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACpJ,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;AAC3C,CAAC;AACD,IAAI,OAAO,GAA4D,IAAI,CAAC"}
@@ -11,6 +11,11 @@ export declare function memoryProvider(name?: string, meta?: CadFileMeta | null,
11
11
  files: Record<string, string>;
12
12
  measurements: Record<string, CadMeasurementValue>;
13
13
  placed: string[];
14
+ placedLinked: {
15
+ groupId: string;
16
+ id: string;
17
+ columnId?: string;
18
+ }[];
14
19
  };
15
20
  remote: (id: string, p: CadPageDoc) => void;
16
21
  remoteMeasurement: (id: string, value: number) => void;
@@ -3,7 +3,7 @@ const copy = (v) => JSON.parse(JSON.stringify(v));
3
3
  export function memoryProvider(name = 'Test drawing', meta = null, pages = {}) {
4
4
  const fileSubs = new Set();
5
5
  const pageSubs = new Set();
6
- const state = { name, meta: meta && copy(meta), pages: copy(pages), writes: 0, uploads: 0, thumbnail: null, files: {}, measurements: {}, placed: [] };
6
+ const state = { name, meta: meta && copy(meta), pages: copy(pages), writes: 0, uploads: 0, thumbnail: null, files: {}, measurements: {}, placed: [], placedLinked: [] };
7
7
  const measSubs = new Set();
8
8
  const emitMeas = () => measSubs.forEach(cb => cb(copy(state.measurements)));
9
9
  const emitFile = () => fileSubs.forEach(cb => cb({ name: state.name, meta: state.meta && copy(state.meta) }));
@@ -23,7 +23,7 @@ export function memoryProvider(name = 'Test drawing', meta = null, pages = {}) {
23
23
  async create(m) { const id = 'm' + (Object.keys(state.measurements).length + 1); state.measurements[id] = copy(m); emitMeas(); return id; },
24
24
  async update(id, value) { state.measurements[id] = { ...state.measurements[id], value }; emitMeas(); },
25
25
  subscribe(cb) { measSubs.add(cb); queueMicrotask(() => cb(copy(state.measurements))); return () => { measSubs.delete(cb); }; },
26
- async setPlaced(ids) { state.placed = ids.slice(); },
26
+ async setPlaced(ids, linked = []) { state.placed = ids.slice(); state.placedLinked = copy(linked); },
27
27
  },
28
28
  };
29
29
  /** Change a page as another device would. */
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/data/memory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/data/memory.ts"],"names":[],"mappings":"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"}
@@ -12,11 +12,14 @@ export interface CadFileMeta {
12
12
  layers?: Partial<Layers>;
13
13
  };
14
14
  }
15
- /** One page as stored. The underlay's src is an uploaded image's URL, never inline image data. */
15
+ /** One page as stored. Its images' src are uploaded images' addresses, never inline image data. */
16
16
  export interface CadPageDoc {
17
17
  name: string;
18
18
  sk: Sketch;
19
- underlay: Underlay | null;
19
+ /** the page's photos and plans, bottom first */
20
+ underlays: Underlay[];
21
+ /** pages written when a page held one image: read as `underlays` of that one, never written */
22
+ underlay?: Underlay | null;
20
23
  /** the editing session that wrote it last, and its write count (to recognise our own writes coming back) */
21
24
  rev?: {
22
25
  clientId: string;
@@ -53,14 +56,23 @@ export interface CadMeasurementValue {
53
56
  value: number;
54
57
  }
55
58
  /**
56
- * The drawing's measurements in BOLDR. Every driving dimension set in the drawing is kept as one (scoped to the
57
- * drawing's file); changing one elsewhere changes the dimension.
59
+ * The drawing's own measurements in BOLDR (scoped to the drawing's file): the ones an earlier version kept for each
60
+ * driving dimension. They still follow their dimensions, and changing one elsewhere changes its dimension; no new ones
61
+ * are made (a dimension is saved to the group through CadEditorProps.links instead).
58
62
  */
59
63
  export interface CadMeasurements {
60
- create(m: CadMeasurementValue): Promise<string>;
64
+ /** No longer called: kept so an older host still type-checks. */
65
+ create?(m: CadMeasurementValue): Promise<string>;
61
66
  update(id: string, value: number): Promise<void>;
62
67
  /** The drawing's measurements, by id. Returns an unsubscribe function. */
63
68
  subscribe(cb: (values: Record<string, CadMeasurementValue>) => void): () => void;
64
- /** Record which measurements the drawing shows (for "Associated Files"). */
65
- setPlaced?(ids: string[]): Promise<void>;
69
+ /**
70
+ * Record which measurements the drawing shows (for "Associated Files"): its own (`ids`, in the drawing's group), and
71
+ * the job's it's linked to (`linked`, each in its own group; a form's with its column). All of them, every time.
72
+ */
73
+ setPlaced?(ids: string[], linked?: {
74
+ groupId: string;
75
+ id: string;
76
+ columnId?: string;
77
+ }[]): Promise<void>;
66
78
  }