@reekon-tools/boldr-cad 0.0.0-stage → 0.1.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 (456) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -2
  3. package/dist/app/edit.d.ts +20 -0
  4. package/dist/app/edit.js +111 -0
  5. package/dist/app/edit.js.map +1 -0
  6. package/dist/app/state.d.ts +91 -0
  7. package/dist/app/state.js +35 -0
  8. package/dist/app/state.js.map +1 -0
  9. package/dist/core.d.ts +7 -0
  10. package/dist/core.js +8 -0
  11. package/dist/core.js.map +1 -0
  12. package/dist/data/memory.d.ts +17 -0
  13. package/dist/data/memory.js +35 -0
  14. package/dist/data/memory.js.map +1 -0
  15. package/dist/data/provider.d.ts +66 -0
  16. package/dist/data/provider.js +2 -0
  17. package/dist/data/provider.js.map +1 -0
  18. package/dist/data/sync.d.ts +34 -0
  19. package/dist/data/sync.js +302 -0
  20. package/dist/data/sync.js.map +1 -0
  21. package/dist/editor/actions.d.ts +21 -0
  22. package/dist/editor/actions.js +652 -0
  23. package/dist/editor/actions.js.map +1 -0
  24. package/dist/editor/conflict.d.ts +13 -0
  25. package/dist/editor/conflict.js +70 -0
  26. package/dist/editor/conflict.js.map +1 -0
  27. package/dist/editor/elevation.d.ts +118 -0
  28. package/dist/editor/elevation.js +749 -0
  29. package/dist/editor/elevation.js.map +1 -0
  30. package/dist/editor/files.d.ts +14 -0
  31. package/dist/editor/files.js +77 -0
  32. package/dist/editor/files.js.map +1 -0
  33. package/dist/editor/gestures.d.ts +31 -0
  34. package/dist/editor/gestures.js +196 -0
  35. package/dist/editor/gestures.js.map +1 -0
  36. package/dist/editor/keypad.d.ts +50 -0
  37. package/dist/editor/keypad.js +141 -0
  38. package/dist/editor/keypad.js.map +1 -0
  39. package/dist/editor/keys.d.ts +11 -0
  40. package/dist/editor/keys.js +133 -0
  41. package/dist/editor/keys.js.map +1 -0
  42. package/dist/editor/laser.d.ts +26 -0
  43. package/dist/editor/laser.js +94 -0
  44. package/dist/editor/laser.js.map +1 -0
  45. package/dist/editor/markup.d.ts +4 -0
  46. package/dist/editor/markup.js +21 -0
  47. package/dist/editor/markup.js.map +1 -0
  48. package/dist/editor/mode.d.ts +9 -0
  49. package/dist/editor/mode.js +38 -0
  50. package/dist/editor/mode.js.map +1 -0
  51. package/dist/editor/ports.d.ts +106 -0
  52. package/dist/editor/ports.js +51 -0
  53. package/dist/editor/ports.js.map +1 -0
  54. package/dist/editor/project.d.ts +41 -0
  55. package/dist/editor/project.js +170 -0
  56. package/dist/editor/project.js.map +1 -0
  57. package/dist/editor/selection.d.ts +19 -0
  58. package/dist/editor/selection.js +62 -0
  59. package/dist/editor/selection.js.map +1 -0
  60. package/dist/editor/status.d.ts +7 -0
  61. package/dist/editor/status.js +24 -0
  62. package/dist/editor/status.js.map +1 -0
  63. package/dist/export/dxf.d.ts +7 -0
  64. package/dist/export/dxf.js +119 -0
  65. package/dist/export/dxf.js.map +1 -0
  66. package/dist/export/pdf.d.ts +19 -0
  67. package/dist/export/pdf.js +270 -0
  68. package/dist/export/pdf.js.map +1 -0
  69. package/dist/export/plan.d.ts +42 -0
  70. package/dist/export/plan.js +236 -0
  71. package/dist/export/plan.js.map +1 -0
  72. package/dist/index.d.ts +7 -0
  73. package/dist/index.js +11 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/model/constraints.d.ts +13 -0
  76. package/dist/model/constraints.js +128 -0
  77. package/dist/model/constraints.js.map +1 -0
  78. package/dist/model/demo.d.ts +5 -0
  79. package/dist/model/demo.js +42 -0
  80. package/dist/model/demo.js.map +1 -0
  81. package/dist/model/elevation.d.ts +63 -0
  82. package/dist/model/elevation.js +91 -0
  83. package/dist/model/elevation.js.map +1 -0
  84. package/dist/model/geom.d.ts +23 -0
  85. package/dist/model/geom.js +92 -0
  86. package/dist/model/geom.js.map +1 -0
  87. package/dist/model/history.d.ts +21 -0
  88. package/dist/model/history.js +62 -0
  89. package/dist/model/history.js.map +1 -0
  90. package/dist/model/ids.d.ts +3 -0
  91. package/dist/model/ids.js +5 -0
  92. package/dist/model/ids.js.map +1 -0
  93. package/dist/model/index.d.ts +8 -0
  94. package/dist/model/index.js +9 -0
  95. package/dist/model/index.js.map +1 -0
  96. package/dist/model/openings.d.ts +107 -0
  97. package/dist/model/openings.js +312 -0
  98. package/dist/model/openings.js.map +1 -0
  99. package/dist/model/planGeom.d.ts +31 -0
  100. package/dist/model/planGeom.js +44 -0
  101. package/dist/model/planGeom.js.map +1 -0
  102. package/dist/model/project.d.ts +13 -0
  103. package/dist/model/project.js +16 -0
  104. package/dist/model/project.js.map +1 -0
  105. package/dist/model/projectfile.d.ts +10 -0
  106. package/dist/model/projectfile.js +49 -0
  107. package/dist/model/projectfile.js.map +1 -0
  108. package/dist/model/rooms.d.ts +30 -0
  109. package/dist/model/rooms.js +214 -0
  110. package/dist/model/rooms.js.map +1 -0
  111. package/dist/model/session.d.ts +8 -0
  112. package/dist/model/session.js +26 -0
  113. package/dist/model/session.js.map +1 -0
  114. package/dist/model/settings.d.ts +21 -0
  115. package/dist/model/settings.js +9 -0
  116. package/dist/model/settings.js.map +1 -0
  117. package/dist/model/sketch.d.ts +43 -0
  118. package/dist/model/sketch.js +305 -0
  119. package/dist/model/sketch.js.map +1 -0
  120. package/dist/model/store.d.ts +27 -0
  121. package/dist/model/store.js +76 -0
  122. package/dist/model/store.js.map +1 -0
  123. package/dist/model/stroke.d.ts +18 -0
  124. package/dist/model/stroke.js +103 -0
  125. package/dist/model/stroke.js.map +1 -0
  126. package/dist/model/types.d.ts +202 -0
  127. package/dist/model/types.js +4 -0
  128. package/dist/model/types.js.map +1 -0
  129. package/dist/model/wallfaces.d.ts +12 -0
  130. package/dist/model/wallfaces.js +69 -0
  131. package/dist/model/wallfaces.js.map +1 -0
  132. package/dist/react/BottomBar.d.ts +8 -0
  133. package/dist/react/BottomBar.js +44 -0
  134. package/dist/react/BottomBar.js.map +1 -0
  135. package/dist/react/Buttons.d.ts +29 -0
  136. package/dist/react/Buttons.js +24 -0
  137. package/dist/react/Buttons.js.map +1 -0
  138. package/dist/react/CadEditor.d.ts +38 -0
  139. package/dist/react/CadEditor.js +89 -0
  140. package/dist/react/CadEditor.js.map +1 -0
  141. package/dist/react/ConflictSheet.d.ts +4 -0
  142. package/dist/react/ConflictSheet.js +24 -0
  143. package/dist/react/ConflictSheet.js.map +1 -0
  144. package/dist/react/Drawer.d.ts +2 -0
  145. package/dist/react/Drawer.js +80 -0
  146. package/dist/react/Drawer.js.map +1 -0
  147. package/dist/react/ElevCanvas.native.d.ts +3 -0
  148. package/dist/react/ElevCanvas.native.js +58 -0
  149. package/dist/react/ElevCanvas.native.js.map +1 -0
  150. package/dist/react/ElevCanvas.web.d.ts +4 -0
  151. package/dist/react/ElevCanvas.web.js +44 -0
  152. package/dist/react/ElevCanvas.web.js.map +1 -0
  153. package/dist/react/ElevationSheet.d.ts +2 -0
  154. package/dist/react/ElevationSheet.js +38 -0
  155. package/dist/react/ElevationSheet.js.map +1 -0
  156. package/dist/react/Icon.native.d.ts +6 -0
  157. package/dist/react/Icon.native.js +8 -0
  158. package/dist/react/Icon.native.js.map +1 -0
  159. package/dist/react/Icon.web.d.ts +6 -0
  160. package/dist/react/Icon.web.js +7 -0
  161. package/dist/react/Icon.web.js.map +1 -0
  162. package/dist/react/KeypadSheet.d.ts +4 -0
  163. package/dist/react/KeypadSheet.js +51 -0
  164. package/dist/react/KeypadSheet.js.map +1 -0
  165. package/dist/react/LaserTray.d.ts +4 -0
  166. package/dist/react/LaserTray.js +23 -0
  167. package/dist/react/LaserTray.js.map +1 -0
  168. package/dist/react/PageThumb.native.d.ts +6 -0
  169. package/dist/react/PageThumb.native.js +14 -0
  170. package/dist/react/PageThumb.native.js.map +1 -0
  171. package/dist/react/PageThumb.web.d.ts +6 -0
  172. package/dist/react/PageThumb.web.js +14 -0
  173. package/dist/react/PageThumb.web.js.map +1 -0
  174. package/dist/react/PlanCanvas.native.d.ts +1 -0
  175. package/dist/react/PlanCanvas.native.js +77 -0
  176. package/dist/react/PlanCanvas.native.js.map +1 -0
  177. package/dist/react/PlanCanvas.web.d.ts +1 -0
  178. package/dist/react/PlanCanvas.web.js +71 -0
  179. package/dist/react/PlanCanvas.web.js.map +1 -0
  180. package/dist/react/Popovers.d.ts +10 -0
  181. package/dist/react/Popovers.js +71 -0
  182. package/dist/react/Popovers.js.map +1 -0
  183. package/dist/react/Rail.d.ts +5 -0
  184. package/dist/react/Rail.js +47 -0
  185. package/dist/react/Rail.js.map +1 -0
  186. package/dist/react/RichText.d.ts +6 -0
  187. package/dist/react/RichText.js +8 -0
  188. package/dist/react/RichText.js.map +1 -0
  189. package/dist/react/Sheet.d.ts +13 -0
  190. package/dist/react/Sheet.js +23 -0
  191. package/dist/react/Sheet.js.map +1 -0
  192. package/dist/react/Toast.d.ts +4 -0
  193. package/dist/react/Toast.js +19 -0
  194. package/dist/react/Toast.js.map +1 -0
  195. package/dist/react/TopBar.d.ts +12 -0
  196. package/dist/react/TopBar.js +39 -0
  197. package/dist/react/TopBar.js.map +1 -0
  198. package/dist/react/files.native.d.ts +6 -0
  199. package/dist/react/files.native.js +11 -0
  200. package/dist/react/files.native.js.map +1 -0
  201. package/dist/react/files.web.d.ts +8 -0
  202. package/dist/react/files.web.js +46 -0
  203. package/dist/react/files.web.js.map +1 -0
  204. package/dist/react/host.d.ts +8 -0
  205. package/dist/react/host.js +26 -0
  206. package/dist/react/host.js.map +1 -0
  207. package/dist/react/pageLock.native.d.ts +3 -0
  208. package/dist/react/pageLock.native.js +4 -0
  209. package/dist/react/pageLock.native.js.map +1 -0
  210. package/dist/react/pageLock.web.d.ts +2 -0
  211. package/dist/react/pageLock.web.js +55 -0
  212. package/dist/react/pageLock.web.js.map +1 -0
  213. package/dist/react/ports.d.ts +7 -0
  214. package/dist/react/ports.js +107 -0
  215. package/dist/react/ports.js.map +1 -0
  216. package/dist/react/store.d.ts +38 -0
  217. package/dist/react/store.js +35 -0
  218. package/dist/react/store.js.map +1 -0
  219. package/dist/react/theme.d.ts +27 -0
  220. package/dist/react/theme.js +14 -0
  221. package/dist/react/theme.js.map +1 -0
  222. package/dist/react/thumbnail.native.d.ts +3 -0
  223. package/dist/react/thumbnail.native.js +12 -0
  224. package/dist/react/thumbnail.native.js.map +1 -0
  225. package/dist/react/thumbnail.web.d.ts +3 -0
  226. package/dist/react/thumbnail.web.js +24 -0
  227. package/dist/react/thumbnail.web.js.map +1 -0
  228. package/dist/render/ctx.d.ts +40 -0
  229. package/dist/render/ctx.js +7 -0
  230. package/dist/render/ctx.js.map +1 -0
  231. package/dist/render/draw.d.ts +53 -0
  232. package/dist/render/draw.js +1377 -0
  233. package/dist/render/draw.js.map +1 -0
  234. package/dist/render/elevation.d.ts +82 -0
  235. package/dist/render/elevation.js +343 -0
  236. package/dist/render/elevation.js.map +1 -0
  237. package/dist/render/elevationView.d.ts +3 -0
  238. package/dist/render/elevationView.js +100 -0
  239. package/dist/render/elevationView.js.map +1 -0
  240. package/dist/render/hit.d.ts +6 -0
  241. package/dist/render/hit.js +168 -0
  242. package/dist/render/hit.js.map +1 -0
  243. package/dist/render/icons.d.ts +2 -0
  244. package/dist/render/icons.js +72 -0
  245. package/dist/render/icons.js.map +1 -0
  246. package/dist/render/snap.d.ts +12 -0
  247. package/dist/render/snap.js +132 -0
  248. package/dist/render/snap.js.map +1 -0
  249. package/dist/render/theme.d.ts +70 -0
  250. package/dist/render/theme.js +27 -0
  251. package/dist/render/theme.js.map +1 -0
  252. package/dist/render/view.d.ts +79 -0
  253. package/dist/render/view.js +210 -0
  254. package/dist/render/view.js.map +1 -0
  255. package/dist/skia/SkiaDrawCtx.d.ts +87 -0
  256. package/dist/skia/SkiaDrawCtx.js +250 -0
  257. package/dist/skia/SkiaDrawCtx.js.map +1 -0
  258. package/dist/skia/fonts.d.ts +6 -0
  259. package/dist/skia/fonts.js +4 -0
  260. package/dist/skia/fonts.js.map +1 -0
  261. package/dist/skia/host.d.ts +14 -0
  262. package/dist/skia/host.js +55 -0
  263. package/dist/skia/host.js.map +1 -0
  264. package/dist/solver/equations.d.ts +29 -0
  265. package/dist/solver/equations.js +218 -0
  266. package/dist/solver/equations.js.map +1 -0
  267. package/dist/solver/gauss-newton.d.ts +27 -0
  268. package/dist/solver/gauss-newton.js +233 -0
  269. package/dist/solver/gauss-newton.js.map +1 -0
  270. package/dist/solver/index.d.ts +5 -0
  271. package/dist/solver/index.js +6 -0
  272. package/dist/solver/index.js.map +1 -0
  273. package/dist/solver/linalg.d.ts +14 -0
  274. package/dist/solver/linalg.js +135 -0
  275. package/dist/solver/linalg.js.map +1 -0
  276. package/dist/solver/types.d.ts +45 -0
  277. package/dist/solver/types.js +2 -0
  278. package/dist/solver/types.js.map +1 -0
  279. package/dist/tools/annotate.d.ts +72 -0
  280. package/dist/tools/annotate.js +261 -0
  281. package/dist/tools/annotate.js.map +1 -0
  282. package/dist/tools/dim.d.ts +37 -0
  283. package/dist/tools/dim.js +427 -0
  284. package/dist/tools/dim.js.map +1 -0
  285. package/dist/tools/elevation.d.ts +13 -0
  286. package/dist/tools/elevation.js +125 -0
  287. package/dist/tools/elevation.js.map +1 -0
  288. package/dist/tools/freehand.d.ts +26 -0
  289. package/dist/tools/freehand.js +125 -0
  290. package/dist/tools/freehand.js.map +1 -0
  291. package/dist/tools/index.d.ts +6 -0
  292. package/dist/tools/index.js +38 -0
  293. package/dist/tools/index.js.map +1 -0
  294. package/dist/tools/line.d.ts +21 -0
  295. package/dist/tools/line.js +200 -0
  296. package/dist/tools/line.js.map +1 -0
  297. package/dist/tools/modify.d.ts +42 -0
  298. package/dist/tools/modify.js +295 -0
  299. package/dist/tools/modify.js.map +1 -0
  300. package/dist/tools/openings.d.ts +19 -0
  301. package/dist/tools/openings.js +213 -0
  302. package/dist/tools/openings.js.map +1 -0
  303. package/dist/tools/registry.d.ts +39 -0
  304. package/dist/tools/registry.js +75 -0
  305. package/dist/tools/registry.js.map +1 -0
  306. package/dist/tools/select.d.ts +106 -0
  307. package/dist/tools/select.js +451 -0
  308. package/dist/tools/select.js.map +1 -0
  309. package/dist/tools/shapes.d.ts +49 -0
  310. package/dist/tools/shapes.js +235 -0
  311. package/dist/tools/shapes.js.map +1 -0
  312. package/dist/units/format.d.ts +8 -0
  313. package/dist/units/format.js +45 -0
  314. package/dist/units/format.js.map +1 -0
  315. package/dist/units/index.d.ts +3 -0
  316. package/dist/units/index.js +4 -0
  317. package/dist/units/index.js.map +1 -0
  318. package/dist/units/parse.d.ts +11 -0
  319. package/dist/units/parse.js +102 -0
  320. package/dist/units/parse.js.map +1 -0
  321. package/dist/units/prefs.d.ts +10 -0
  322. package/dist/units/prefs.js +9 -0
  323. package/dist/units/prefs.js.map +1 -0
  324. package/package.json +84 -4
  325. package/src/app/edit.ts +107 -0
  326. package/src/app/main.ts +78 -0
  327. package/src/app/state.ts +87 -0
  328. package/src/core.ts +9 -0
  329. package/src/data/memory.ts +37 -0
  330. package/src/data/provider.ts +67 -0
  331. package/src/data/sync.ts +248 -0
  332. package/src/editor/actions.ts +418 -0
  333. package/src/editor/conflict.ts +66 -0
  334. package/src/editor/elevation.ts +591 -0
  335. package/src/editor/files.ts +72 -0
  336. package/src/editor/gestures.ts +157 -0
  337. package/src/editor/keypad.ts +138 -0
  338. package/src/editor/keys.ts +90 -0
  339. package/src/editor/laser.ts +90 -0
  340. package/src/editor/markup.ts +16 -0
  341. package/src/editor/mode.ts +39 -0
  342. package/src/editor/ports.ts +142 -0
  343. package/src/editor/project.ts +168 -0
  344. package/src/editor/selection.ts +59 -0
  345. package/src/editor/status.ts +21 -0
  346. package/src/export/dxf.ts +85 -0
  347. package/src/export/pdf.ts +267 -0
  348. package/src/export/plan.ts +231 -0
  349. package/src/index.ts +13 -0
  350. package/src/input/keyboard.ts +17 -0
  351. package/src/input/pointer.ts +28 -0
  352. package/src/model/constraints.ts +99 -0
  353. package/src/model/demo.ts +36 -0
  354. package/src/model/elevation.ts +124 -0
  355. package/src/model/geom.ts +92 -0
  356. package/src/model/history.ts +71 -0
  357. package/src/model/ids.ts +7 -0
  358. package/src/model/index.ts +8 -0
  359. package/src/model/openings.ts +309 -0
  360. package/src/model/planGeom.ts +52 -0
  361. package/src/model/project.ts +14 -0
  362. package/src/model/projectfile.ts +45 -0
  363. package/src/model/rooms.ts +183 -0
  364. package/src/model/session.ts +28 -0
  365. package/src/model/settings.ts +31 -0
  366. package/src/model/sketch.ts +213 -0
  367. package/src/model/store.ts +87 -0
  368. package/src/model/stroke.ts +87 -0
  369. package/src/model/types.ts +158 -0
  370. package/src/model/wallfaces.ts +78 -0
  371. package/src/react/BottomBar.tsx +84 -0
  372. package/src/react/Buttons.tsx +43 -0
  373. package/src/react/CadEditor.tsx +127 -0
  374. package/src/react/ConflictSheet.tsx +40 -0
  375. package/src/react/Drawer.tsx +190 -0
  376. package/src/react/ElevCanvas.native.tsx +68 -0
  377. package/src/react/ElevCanvas.web.tsx +42 -0
  378. package/src/react/ElevationSheet.tsx +88 -0
  379. package/src/react/Icon.native.tsx +7 -0
  380. package/src/react/Icon.web.tsx +6 -0
  381. package/src/react/KeypadSheet.tsx +98 -0
  382. package/src/react/LaserTray.tsx +38 -0
  383. package/src/react/PageThumb.native.tsx +19 -0
  384. package/src/react/PageThumb.web.tsx +13 -0
  385. package/src/react/PlanCanvas.native.tsx +83 -0
  386. package/src/react/PlanCanvas.web.tsx +72 -0
  387. package/src/react/Popovers.tsx +126 -0
  388. package/src/react/Rail.tsx +45 -0
  389. package/src/react/RichText.tsx +11 -0
  390. package/src/react/Sheet.tsx +33 -0
  391. package/src/react/Toast.tsx +29 -0
  392. package/src/react/TopBar.tsx +75 -0
  393. package/src/react/files.native.ts +12 -0
  394. package/src/react/files.web.ts +40 -0
  395. package/src/react/host.ts +27 -0
  396. package/src/react/pageLock.native.ts +3 -0
  397. package/src/react/pageLock.web.ts +49 -0
  398. package/src/react/ports.ts +96 -0
  399. package/src/react/store.ts +43 -0
  400. package/src/react/theme.ts +18 -0
  401. package/src/react/thumbnail.native.ts +12 -0
  402. package/src/react/thumbnail.web.ts +22 -0
  403. package/src/render/ctx.ts +47 -0
  404. package/src/render/draw.ts +996 -0
  405. package/src/render/elevation.ts +301 -0
  406. package/src/render/elevationView.ts +73 -0
  407. package/src/render/hit.ts +138 -0
  408. package/src/render/icons.ts +73 -0
  409. package/src/render/snap.ts +118 -0
  410. package/src/render/theme.ts +30 -0
  411. package/src/render/view.ts +208 -0
  412. package/src/skia/SkiaDrawCtx.ts +265 -0
  413. package/src/skia/fonts.ts +5 -0
  414. package/src/skia/host.ts +64 -0
  415. package/src/solver/equations.ts +198 -0
  416. package/src/solver/gauss-newton.ts +177 -0
  417. package/src/solver/index.ts +8 -0
  418. package/src/solver/linalg.ts +96 -0
  419. package/src/solver/types.ts +46 -0
  420. package/src/styles.css +271 -0
  421. package/src/tools/annotate.ts +197 -0
  422. package/src/tools/dim.ts +335 -0
  423. package/src/tools/elevation.ts +110 -0
  424. package/src/tools/freehand.ts +104 -0
  425. package/src/tools/index.ts +41 -0
  426. package/src/tools/line.ts +158 -0
  427. package/src/tools/modify.ts +228 -0
  428. package/src/tools/openings.ts +187 -0
  429. package/src/tools/registry.ts +89 -0
  430. package/src/tools/select.ts +363 -0
  431. package/src/tools/shapes.ts +176 -0
  432. package/src/types/skia-web.d.ts +6 -0
  433. package/src/ui/conflict.ts +51 -0
  434. package/src/ui/ctx.ts +49 -0
  435. package/src/ui/dom.ts +4 -0
  436. package/src/ui/domPorts.ts +67 -0
  437. package/src/ui/drawer.ts +106 -0
  438. package/src/ui/elevation.ts +124 -0
  439. package/src/ui/icons.ts +8 -0
  440. package/src/ui/keypad.ts +160 -0
  441. package/src/ui/laser.ts +104 -0
  442. package/src/ui/menu.ts +100 -0
  443. package/src/ui/noteinput.ts +31 -0
  444. package/src/ui/palette.ts +33 -0
  445. package/src/ui/rail.ts +58 -0
  446. package/src/ui/sheets.ts +22 -0
  447. package/src/ui/status.ts +14 -0
  448. package/src/ui/theme.ts +17 -0
  449. package/src/ui/tip.ts +26 -0
  450. package/src/ui/toast.ts +24 -0
  451. package/src/ui/topbar.ts +24 -0
  452. package/src/ui/underlay.ts +26 -0
  453. package/src/units/format.ts +35 -0
  454. package/src/units/index.ts +3 -0
  455. package/src/units/parse.ts +75 -0
  456. package/src/units/prefs.ts +19 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 REEKON Tools
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,228 @@
1
- # Temporary Holding Version
1
+ # @reekon-tools/boldr-cad
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ BOLDR's 2D layout editor (BOLDR CAD) as a React Native component, plus the
4
+ model, solver and exporters behind it. Walls, doors and windows, spaces,
5
+ dimensions and constraints, wall elevations and markup, drawn with Skia on
6
+ iOS and Android and with react-native-web in a browser. Drawings are kept in
7
+ BOLDR through a small provider interface, so the package has no Firebase
8
+ dependency of its own.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npm install @reekon-tools/boldr-cad
14
+ ```
15
+
16
+ Peer dependencies:
17
+
18
+ | Package | Range | Needed for |
19
+ | ----------------------------- | --------- | ------------------------------------------- |
20
+ | `react` | `>=19` | always |
21
+ | `react-native` | `>=0.74` | always (react-native-web in a browser) |
22
+ | `@shopify/react-native-skia` | `>=2.5` | the editor on iOS and Android |
23
+ | `react-native-gesture-handler`| `>=2.31` | the editor on iOS and Android |
24
+ | `react-native-svg` | `>=15` | the editor's icons on iOS and Android |
25
+
26
+ Only `./core` (see below) runs without the three native packages.
27
+
28
+ ## How it resolves
29
+
30
+ The package has two entry points:
31
+
32
+ - `@reekon-tools/boldr-cad` is the editor: `CadEditor`, the data layer and
33
+ the device hooks.
34
+ - `@reekon-tools/boldr-cad/core` is the drawing model without React:
35
+ types, `migrateProject`, project files, unit formatting and the PDF/DXF
36
+ exporters. For servers and tools.
37
+
38
+ **React Native hosts read the TypeScript source.** The package exports a
39
+ `react-native` condition that points at `src/`, so Metro compiles it like app
40
+ code and picks the `.native` platform files itself. Nothing is prebuilt for
41
+ native, which also means a local checkout linked into an app is live with no
42
+ build step.
43
+
44
+ For TypeScript in a React Native app, two compiler options are needed. Expo's
45
+ base tsconfig already sets the first:
46
+
47
+ ```json
48
+ {
49
+ "compilerOptions": {
50
+ "customConditions": ["react-native"],
51
+ "moduleSuffixes": [".ios", ".android", ".native", ""]
52
+ }
53
+ }
54
+ ```
55
+
56
+ **Web and Node take the built `dist/`** through the `default` and `types`
57
+ conditions. In a Vite app, alias `react-native` to `react-native-web` and let
58
+ `.web.js` win, because the platform files in `dist/` have no bare `X.js`:
59
+
60
+ ```ts
61
+ // vite.config.ts
62
+ resolve: {
63
+ alias: [{ find: /^react-native$/, replacement: 'react-native-web' }],
64
+ extensions: ['.web.js', '.web.tsx', '.web.ts', '.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],
65
+ },
66
+ ```
67
+
68
+ `dist/` is emitted with extensionless relative imports, so plain Node cannot
69
+ `import('@reekon-tools/boldr-cad/core')` directly. Run it through a bundler
70
+ (esbuild, tsx, vite-node) as BOLDR's own services do.
71
+
72
+ ## Using the editor
73
+
74
+ ```tsx
75
+ import { CadEditor, openCadDrawing, NotACadDrawing, type CadSync } from '@reekon-tools/boldr-cad';
76
+
77
+ function DrawingScreen({ provider }: { provider: CadDataProvider }) {
78
+ const [sync, setSync] = useState<CadSync | null>(null);
79
+
80
+ useEffect(() => {
81
+ let cancelled = false;
82
+ openCadDrawing(provider, { onError: e => console.error(e) }).then(
83
+ s => (cancelled ? s.stop() : setSync(s)),
84
+ e => { if (e instanceof NotACadDrawing) console.log(e.reason); }, // 'missing' | 'legacy'
85
+ );
86
+ return () => { cancelled = true; };
87
+ }, [provider]);
88
+
89
+ if (!sync) return null;
90
+ return <CadEditor sync={sync} onBack={goBack} theme="dark" devTools={false} />;
91
+ }
92
+ ```
93
+
94
+ Mount one `CadEditor` per screen. Mounting starts an editing session,
95
+ unmounting saves and stops the sync it was given. Without `sync` the drawing
96
+ lives in the browser's own storage, which is what the dev harness uses.
97
+
98
+ `CadEditor` props:
99
+
100
+ | Prop | Type | Purpose |
101
+ | ------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
102
+ | `sync` | `CadSync` | The drawing, from `openCadDrawing`. Saved there as it changes. |
103
+ | `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
+ | `theme` | `'light' \| 'dark'` | Canvas colors. The chrome is dark either way. Without it, the person's Theme setting decides. |
106
+ | `units` | `{ format: (inches: number) => string; metric: boolean; denom?: number }` | Lengths the host's way. Hides Units in Settings. |
107
+ | `fonts` | `SkiaFonts` | Typefaces for text on the plan by CSS weight, with a fallback. Device only. |
108
+ | `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
+ | `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
+ | `devTools` | `boolean` | Reset to the demo, open and save project files, in Settings. Default `true`; turn off in production. |
112
+
113
+ Fonts on a device, with react-native-skia:
114
+
115
+ ```ts
116
+ const regular = useTypeface(require('./assets/Inter-Regular.ttf'));
117
+ const bold = useTypeface(require('./assets/Inter-Bold.ttf'));
118
+ const fonts: SkiaFonts | null = regular && bold ? { weights: { 400: regular, 700: bold }, fallback: regular } : null;
119
+ ```
120
+
121
+ Wait for the typefaces before mounting the editor.
122
+
123
+ ### Keeping a drawing in BOLDR
124
+
125
+ `openCadDrawing(provider, options)` loads a drawing through a
126
+ `CadDataProvider` and keeps it in step while the editor is open: only the
127
+ pages that changed are written, each stamped with the session's id; traced
128
+ images are uploaded and stored by reference; pages another device changed are
129
+ taken in when they aren't being edited locally.
130
+
131
+ ```ts
132
+ interface CadDataProvider {
133
+ subscribeFile(cb: (file: { name: string; meta: CadFileMeta | null } | null) => void): () => void;
134
+ subscribePages(cb: (pages: Record<string, CadPageDoc>) => void): () => void;
135
+ writeMeta(meta: CadFileMeta): Promise<void>;
136
+ writePage(id: string, page: CadPageDoc): Promise<void>;
137
+ deletePage(id: string): Promise<void>;
138
+ uploadImage(pageId: string, dataUrl: string): Promise<string>; // returns a URL or a `stored:<path>` reference
139
+ imageUrl?(ref: string): Promise<string>; // turns a stored reference into a URL
140
+ uploadThumbnail?(dataUrl: string): Promise<void>;
141
+ measurements?: CadMeasurements;
142
+ }
143
+ ```
144
+
145
+ A drawing is one file document with `fileData: CadFileMeta`
146
+ (`format: 'boldr-cad'`, `version: 1`, `pageOrder`, shared settings) and one
147
+ page document per page (`name`, the sketch, the underlay, and the `rev` of
148
+ the session that wrote it last). Storage paths are relative to the drawing's
149
+ own folder, so copying or moving a drawing with its folder keeps it working.
150
+
151
+ Options: `initialize: true` starts a new drawing when the file has no drawing
152
+ record yet; `onError` hears about failed writes and uploads. The promise
153
+ rejects with `NotACadDrawing` whose `reason` is `'missing'` (no such file) or
154
+ `'legacy'` (a file from the retired layout tool).
155
+
156
+ The returned `CadSync` has `stop()`, `idle()` (resolves once every write so
157
+ far has finished), `saveThumbnail(pngDataUrl)` and `imageUrl(ref)`.
158
+
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.
164
+
165
+ For tests and prototypes, `memoryProvider()` is an in-memory provider with
166
+ `remote()` and `remoteMeasurement()` to change things as another device would.
167
+
168
+ ### Measuring devices
169
+
170
+ ```ts
171
+ import { setLaserConnected, laserReading } from '@reekon-tools/boldr-cad';
172
+
173
+ 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
175
+ ```
176
+
177
+ `laserReading` returns `false` when no drawing is open to take the value, so
178
+ the host can handle it instead.
179
+
180
+ ## `./core`
181
+
182
+ ```ts
183
+ import { sketchToPdf, pdfFileName, sketchToDxf, dxfFileName, fmtLen, parseLen, projectFromFile, migrateProject } from '@reekon-tools/boldr-cad/core';
184
+ ```
185
+
186
+ The model types (`Project`, `Page`, `Sketch`, `Line`, `Constraint`, ...),
187
+ `migrateProject` for older saves, `projectToFile` / `projectFromFile` for
188
+ project files, the unit helpers (`fmtLen`, `parseLen`, `fmtArea`) and the
189
+ PDF and DXF exporters, which return the file's contents as a string.
190
+
191
+ Geometry is stored in inches. Units are display only, and switching them
192
+ never changes a drawing.
193
+
194
+ ## Development
195
+
196
+ ```sh
197
+ npm ci
198
+ npm run dev # the editor in a browser at http://localhost:5173 (react-native-web, saves locally)
199
+ npm test # vitest: units, solver, rooms, trim, sync
200
+ npm run e2e # playwright flows against the dev server (npx playwright install first)
201
+ npm run typecheck # the browser build
202
+ npm run typecheck:native # the device build (.native files)
203
+ npm run build:lib # dist/ for web and Node consumers
204
+ npm run build:single # one self-contained HTML file for testers, in dist-single/
205
+ ```
206
+
207
+ `npm run build` is the browser harness and writes to `dist/` too, replacing
208
+ the library output. `npm run build:lib` always starts from an empty `dist/`.
209
+
210
+ To work on the package inside an app without publishing, depend on the
211
+ checkout with `link:` (yarn) or `file:` (npm). Metro then needs the checkout
212
+ as a watch folder, the package name mapped to it, and the checkout's own
213
+ `node_modules` blocked so React and React Native aren't bundled twice. The
214
+ BOLDR Pro app derives all three from its `link:` dependencies in
215
+ `metro.config.js`.
216
+
217
+ ## Publishing
218
+
219
+ ```sh
220
+ npm publish --access public
221
+ ```
222
+
223
+ `prepublishOnly` runs the native typecheck, the tests and `build:lib` first,
224
+ so the tarball always carries a fresh `dist/` next to `src/`.
225
+
226
+ ## License
227
+
228
+ MIT
@@ -0,0 +1,20 @@
1
+ import type { Constraint, SelItem } from '../model/types';
2
+ import { type AddResult, type SolveResult } from '../solver';
3
+ export declare function analyze(): void;
4
+ export declare const solveSketch: (heavy?: string[]) => SolveResult;
5
+ export declare function solveOrRevert(): SolveResult;
6
+ /** Re-place locked doors/windows from their dimensions (after any geometry change). */
7
+ export declare function resolveOpeningsNow(): void;
8
+ export declare function existsSel(s: SelItem): boolean;
9
+ /** Run after every model change: clean up, re-analyze, refresh UI, autosave. */
10
+ export declare function afterEdit(): void;
11
+ export declare function undo(): void;
12
+ export declare function redo(): void;
13
+ /**
14
+ * Add a constraint through the solver and explain the outcome:
15
+ * reference dimension → toast, conflict → conflict sheet (unless silent).
16
+ */
17
+ export declare function tryAddConstraint(c: Constraint, { silent, onResolved }?: {
18
+ onResolved?: (() => void) | null | undefined;
19
+ silent?: boolean | undefined;
20
+ }): AddResult;
@@ -0,0 +1,111 @@
1
+ import { drivingDim } from '../model/openings';
2
+ import { CONS_LABEL } from '../model/constraints';
3
+ import { HS, stepRedo, stepUndo } from '../model/history';
4
+ import { resolveOpenings } from '../model/openings';
5
+ import { gc, restorePos, snapshotPos } from '../model/sketch';
6
+ import { page, saveSoon, SK } from '../model/store';
7
+ import { requestDraw } from '../render/view';
8
+ import { solver } from '../solver';
9
+ import { cancelTool } from '../tools/registry';
10
+ import { fmtLen } from '../units';
11
+ import { ed } from './state';
12
+ import { refreshDrawerSoon, renderElevation, showConflict, toast, updateCtx, updateStatus } from '../editor/ports';
13
+ export function analyze() {
14
+ ed.ana = solver.analyzeDOF(SK());
15
+ }
16
+ export const solveSketch = (heavy) => solver.solve(SK(), heavy);
17
+ export function solveOrRevert() {
18
+ const sk = SK(), snap = snapshotPos(sk);
19
+ const s = solver.solve(sk);
20
+ if (!s.ok)
21
+ restorePos(sk, snap);
22
+ return s;
23
+ }
24
+ /** Re-place locked doors/windows from their dimensions (after any geometry change). */
25
+ export function resolveOpeningsNow() {
26
+ ed.badOpeningDims = resolveOpenings(SK());
27
+ }
28
+ export function existsSel(s) {
29
+ const sk = SK();
30
+ switch (s.type) {
31
+ case 'point': return !!sk.points[s.id];
32
+ case 'line': return !!sk.lines[s.id];
33
+ case 'circle': return !!sk.circles[s.id];
34
+ case 'arc': return !!sk.arcs[s.id];
35
+ case 'cons':
36
+ case 'dim': return !!sk.cons[s.id];
37
+ case 'room': return !!sk.rooms[s.id];
38
+ case 'opening': return !!sk.openings[s.id];
39
+ 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));
42
+ }
43
+ case 'note': return sk.notes.some(n => n.id === s.id);
44
+ case 'underlay': return !!page().underlay;
45
+ }
46
+ return false;
47
+ }
48
+ /** Run after every model change: clean up, re-analyze, refresh UI, autosave. */
49
+ export function afterEdit() {
50
+ ed.editSeq++;
51
+ gc(SK());
52
+ resolveOpeningsNow();
53
+ ed.sel = ed.sel.filter(s => existsSel(s));
54
+ analyze();
55
+ updateCtx();
56
+ updateStatus();
57
+ refreshDrawerSoon();
58
+ requestDraw();
59
+ renderElevation();
60
+ saveSoon();
61
+ }
62
+ export function undo() {
63
+ if (!HS().u.length) {
64
+ toast('Nothing to undo');
65
+ return;
66
+ }
67
+ cancelTool();
68
+ stepUndo();
69
+ ed.sel = [];
70
+ afterEdit();
71
+ toast('Undone');
72
+ }
73
+ export function redo() {
74
+ const h = HS();
75
+ if (!h.u.length && !h.r.length)
76
+ return;
77
+ if (!h.r.length) {
78
+ toast('Nothing to redo');
79
+ return;
80
+ }
81
+ cancelTool();
82
+ stepRedo();
83
+ ed.sel = [];
84
+ afterEdit();
85
+ toast('Redone');
86
+ }
87
+ /**
88
+ * Add a constraint through the solver and explain the outcome:
89
+ * reference dimension → toast, conflict → conflict sheet (unless silent).
90
+ */
91
+ export function tryAddConstraint(c, { silent = false, onResolved = null } = {}) {
92
+ const r = solver.addConstraint(SK(), c, { explain: !silent });
93
+ if (silent)
94
+ return r;
95
+ if (r.ref) {
96
+ toast(r.refSame
97
+ ? 'Added as a reference dimension. Other constraints already set this value.'
98
+ : 'Kept as a reference dimension (' + fmtLen(c.value) + '). Other constraints already set this value — remove one to drive it.', { warn: !r.refSame });
99
+ }
100
+ else if (r.redundant) {
101
+ toast(CONS_LABEL[c.type] + ' is already true — other constraints set it.');
102
+ }
103
+ else if (r.conflict === 'dependent') {
104
+ 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 });
105
+ }
106
+ else if (r.conflict === 'unsatisfiable') {
107
+ showConflict({ title: 'That doesn’t fit', msg: 'The drawing can’t satisfy this together with the constraints below. Remove one, or change a dimension.', ids: r.culprits || [], pending: c, onResolved });
108
+ }
109
+ return r;
110
+ }
111
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/app/edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import type { Analysis, OpeningEdge, SelItem, SelType } from '../model/types';
2
+ import type { Xform } from '../render/view';
3
+ import type { DrawCtx } from '../render/ctx';
4
+ export type Mode = 'draft' | 'annotate';
5
+ /** Something under the pointer: geometry, or a chip/badge drawn on the canvas. */
6
+ export interface Hit {
7
+ type: SelType | 'odim' | 'oanchor' | 'uhandle' | 'nhandle';
8
+ id: string;
9
+ /** a print dimension label */
10
+ print?: boolean;
11
+ /** low-priority hit (room fill) */
12
+ weak?: boolean;
13
+ /** 'odim': 'w' width, 'a'/'b' distance to a wall end, or 'd:<id>' a placed dimension. 'oanchor': 's0'/'s1' edge. */
14
+ part?: string;
15
+ }
16
+ export type OpeningDimPart = 'w' | 'a' | 'b' | `d:${string}`;
17
+ export interface Guide {
18
+ x1?: number;
19
+ y1?: number;
20
+ x2?: number;
21
+ y2?: number;
22
+ kind: 'H' | 'V' | 'perp';
23
+ from?: string;
24
+ label?: string;
25
+ }
26
+ export type SnapKind = 'point' | 'mid' | 'online' | 'oncircle' | 'inter' | 'free' | 'grid';
27
+ export interface Snap {
28
+ x: number;
29
+ y: number;
30
+ kind: SnapKind;
31
+ /** point id (point), line id (mid/online), curve id (oncircle) */
32
+ ref?: string | null;
33
+ /** the two lines for an intersection */
34
+ refs?: [string, string];
35
+ label?: string;
36
+ guides: Guide[];
37
+ }
38
+ /** Screen-space hit region registered while drawing chips, badges and labels. */
39
+ export interface HitChip {
40
+ kind: 'dim' | 'pdim' | 'cons' | 'room' | 'odim';
41
+ part?: string;
42
+ id: string;
43
+ x: number;
44
+ y: number;
45
+ w: number;
46
+ h: number;
47
+ weak?: boolean;
48
+ }
49
+ export interface BoxSel {
50
+ x0: number;
51
+ y0: number;
52
+ x1: number;
53
+ y1: number;
54
+ }
55
+ export type Preview = (c: DrawCtx, T: Xform) => void;
56
+ /** Shared editor state (the prototype's module-level `let`s). */
57
+ export declare const ed: {
58
+ mode: Mode;
59
+ tool: string;
60
+ sel: SelItem[];
61
+ hover: Hit | null;
62
+ snapState: Snap | null;
63
+ boxSel: BoxSel | null;
64
+ preview: Preview | null;
65
+ highlight: Set<string>;
66
+ conflictTint: boolean;
67
+ /** tap targets from the last painted frame (whoever paints stores drawPlan()'s result here) */
68
+ hitChips: HitChip[];
69
+ ana: Analysis;
70
+ lastPointerTouch: boolean;
71
+ drawConstr: boolean;
72
+ dimLayer: 'drive' | 'print';
73
+ openingType: 'door' | 'window';
74
+ noteColor: string;
75
+ /** opening dimensions that can't be met (drawn red) */
76
+ badOpeningDims: Set<string>;
77
+ /** dimension tool: an opening edge picked as the first end */
78
+ /** body: the opening itself was tapped (not an edge square), so the edge is chosen from what it's measured to */
79
+ pickedAnchor: {
80
+ id: string;
81
+ edge: OpeningEdge;
82
+ body?: boolean;
83
+ } | null;
84
+ /** bumped on every model change (so a double tap can't span an edit) */
85
+ editSeq: number;
86
+ /** recently hovered points, used for alignment guides */
87
+ recentPts: string[];
88
+ /** view only: pan and zoom, no tools, nothing saved (people who can't edit this job) */
89
+ readOnly: boolean;
90
+ };
91
+ export declare const isSel: (type: string, id: string) => boolean;
@@ -0,0 +1,35 @@
1
+ import { emptyAnalysis } from '../model/constraints';
2
+ import { sessionState } from '../model/session';
3
+ /** Shared editor state (the prototype's module-level `let`s). */
4
+ export const ed = sessionState(() => ({
5
+ mode: 'draft',
6
+ tool: 'select',
7
+ sel: [],
8
+ hover: null,
9
+ snapState: null,
10
+ boxSel: null,
11
+ preview: null,
12
+ highlight: new Set(),
13
+ conflictTint: false,
14
+ /** tap targets from the last painted frame (whoever paints stores drawPlan()'s result here) */
15
+ hitChips: [],
16
+ ana: emptyAnalysis(),
17
+ lastPointerTouch: false,
18
+ drawConstr: false,
19
+ dimLayer: 'drive',
20
+ openingType: 'door',
21
+ noteColor: '#F070EE',
22
+ /** opening dimensions that can't be met (drawn red) */
23
+ badOpeningDims: new Set(),
24
+ /** dimension tool: an opening edge picked as the first end */
25
+ /** body: the opening itself was tapped (not an edge square), so the edge is chosen from what it's measured to */
26
+ pickedAnchor: null,
27
+ /** bumped on every model change (so a double tap can't span an edit) */
28
+ editSeq: 0,
29
+ /** recently hovered points, used for alignment guides */
30
+ recentPts: [],
31
+ /** view only: pan and zoom, no tools, nothing saved (people who can't edit this job) */
32
+ readOnly: false,
33
+ }));
34
+ export const isSel = (type, id) => ed.sel.some(s => s.type === type && s.id === id);
35
+ //# sourceMappingURL=state.js.map
@@ -0,0 +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"}
package/dist/core.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './model/types';
2
+ export { migrateProject } from './model/project';
3
+ export { projectFromFile, projectToFile } from './model/projectfile';
4
+ export { fmtLen, parseLen, fmtArea } from './units';
5
+ export { sketchToPdf, pdfFileName } from './export/pdf';
6
+ export { sketchToDxf, dxfFileName } from './export/dxf';
7
+ export type { CadFileMeta, CadMeasurementValue, CadPageDoc } from './data/provider';
package/dist/core.js ADDED
@@ -0,0 +1,8 @@
1
+ /* The drawing model without React: geometry, the solver, units, and PDF/DXF export (for servers and tools). */
2
+ export * from './model/types';
3
+ export { migrateProject } from './model/project';
4
+ export { projectFromFile, projectToFile } from './model/projectfile';
5
+ export { fmtLen, parseLen, fmtArea } from './units';
6
+ export { sketchToPdf, pdfFileName } from './export/pdf';
7
+ export { sketchToDxf, dxfFileName } from './export/dxf';
8
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAE/G,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { CadDataProvider, CadFileMeta, CadMeasurementValue, CadPageDoc } from './provider';
2
+ export declare function memoryProvider(name?: string, meta?: CadFileMeta | null, pages?: Record<string, CadPageDoc>): {
3
+ provider: CadDataProvider;
4
+ state: {
5
+ name: string;
6
+ meta: CadFileMeta | null;
7
+ pages: Record<string, CadPageDoc>;
8
+ writes: number;
9
+ uploads: number;
10
+ thumbnail: string | null;
11
+ files: Record<string, string>;
12
+ measurements: Record<string, CadMeasurementValue>;
13
+ placed: string[];
14
+ };
15
+ remote: (id: string, p: CadPageDoc) => void;
16
+ remoteMeasurement: (id: string, value: number) => void;
17
+ };
@@ -0,0 +1,35 @@
1
+ /* A drawing kept in memory: for tests and the dev harness. `remote` changes it as another device would. */
2
+ const copy = (v) => JSON.parse(JSON.stringify(v));
3
+ export function memoryProvider(name = 'Test drawing', meta = null, pages = {}) {
4
+ const fileSubs = new Set();
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: [] };
7
+ const measSubs = new Set();
8
+ const emitMeas = () => measSubs.forEach(cb => cb(copy(state.measurements)));
9
+ const emitFile = () => fileSubs.forEach(cb => cb({ name: state.name, meta: state.meta && copy(state.meta) }));
10
+ const emitPages = () => pageSubs.forEach(cb => cb(copy(state.pages)));
11
+ const provider = {
12
+ subscribeFile(cb) { fileSubs.add(cb); queueMicrotask(() => cb({ name: state.name, meta: state.meta && copy(state.meta) })); return () => { fileSubs.delete(cb); }; },
13
+ subscribePages(cb) { pageSubs.add(cb); queueMicrotask(() => cb(copy(state.pages))); return () => { pageSubs.delete(cb); }; },
14
+ async writeMeta(m) { state.meta = copy(m); state.writes++; emitFile(); },
15
+ async writePage(id, p) { state.pages[id] = copy(p); state.writes++; emitPages(); },
16
+ async deletePage(id) { delete state.pages[id]; state.writes++; emitPages(); },
17
+ // stored like the real providers: a reference relative to the drawing's folder, turned into a URL on demand
18
+ async uploadImage(pageId, dataUrl) { state.uploads++; const name = `underlays/${pageId}-${state.uploads}`; state.files[name] = dataUrl; return `stored:${name}`; },
19
+ async imageUrl(ref) { const f = state.files[ref.slice('stored:'.length)]; if (!f)
20
+ throw new Error('not stored: ' + ref); return f; },
21
+ async uploadThumbnail(dataUrl) { state.thumbnail = dataUrl; },
22
+ measurements: {
23
+ async create(m) { const id = 'm' + (Object.keys(state.measurements).length + 1); state.measurements[id] = copy(m); emitMeas(); return id; },
24
+ async update(id, value) { state.measurements[id] = { ...state.measurements[id], value }; emitMeas(); },
25
+ subscribe(cb) { measSubs.add(cb); queueMicrotask(() => cb(copy(state.measurements))); return () => { measSubs.delete(cb); }; },
26
+ async setPlaced(ids) { state.placed = ids.slice(); },
27
+ },
28
+ };
29
+ /** Change a page as another device would. */
30
+ const remote = (id, p) => { state.pages[id] = copy(p); emitPages(); };
31
+ /** Change a measurement as someone else would (e.g. in the job's measurement list). */
32
+ const remoteMeasurement = (id, value) => { state.measurements[id] = { ...state.measurements[id], value }; emitMeas(); };
33
+ return { provider, state, remote, remoteMeasurement };
34
+ }
35
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/data/memory.ts"],"names":[],"mappings":"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"}