@dxos/plugin-tldraw 0.10.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 (401) hide show
  1. package/LICENSE +105 -0
  2. package/PLUGIN.mdl +412 -0
  3. package/README.md +3 -0
  4. package/dist/assets/embed-icons/codepen.png +0 -0
  5. package/dist/assets/embed-icons/codesandbox.png +0 -0
  6. package/dist/assets/embed-icons/desmos.png +0 -0
  7. package/dist/assets/embed-icons/excalidraw.png +0 -0
  8. package/dist/assets/embed-icons/felt.png +0 -0
  9. package/dist/assets/embed-icons/figma.png +0 -0
  10. package/dist/assets/embed-icons/github_gist.png +0 -0
  11. package/dist/assets/embed-icons/google_calendar.png +0 -0
  12. package/dist/assets/embed-icons/google_maps.png +0 -0
  13. package/dist/assets/embed-icons/google_slides.png +0 -0
  14. package/dist/assets/embed-icons/observable.png +0 -0
  15. package/dist/assets/embed-icons/replit.png +0 -0
  16. package/dist/assets/embed-icons/scratch.png +0 -0
  17. package/dist/assets/embed-icons/spotify.png +0 -0
  18. package/dist/assets/embed-icons/tldraw.png +0 -0
  19. package/dist/assets/embed-icons/val_town.png +0 -0
  20. package/dist/assets/embed-icons/vimeo.png +0 -0
  21. package/dist/assets/embed-icons/youtube.png +0 -0
  22. package/dist/assets/fonts/IBMPlexMono-Medium.woff2 +0 -0
  23. package/dist/assets/fonts/IBMPlexSans-Medium.woff2 +0 -0
  24. package/dist/assets/fonts/IBMPlexSerif-Medium.woff2 +0 -0
  25. package/dist/assets/fonts/Montserrat-Regular.woff2 +0 -0
  26. package/dist/assets/fonts/Shantell_Sans-Tldrawish.woff2 +0 -0
  27. package/dist/assets/icons/icon/0_merged.svg +1 -0
  28. package/dist/assets/icons/icon/align-bottom.svg +1 -0
  29. package/dist/assets/icons/icon/align-center-horizontal.svg +1 -0
  30. package/dist/assets/icons/icon/align-center-vertical.svg +1 -0
  31. package/dist/assets/icons/icon/align-left.svg +1 -0
  32. package/dist/assets/icons/icon/align-right.svg +1 -0
  33. package/dist/assets/icons/icon/align-top.svg +1 -0
  34. package/dist/assets/icons/icon/arrow-left.svg +1 -0
  35. package/dist/assets/icons/icon/arrowhead-arrow.svg +1 -0
  36. package/dist/assets/icons/icon/arrowhead-bar.svg +1 -0
  37. package/dist/assets/icons/icon/arrowhead-diamond.svg +1 -0
  38. package/dist/assets/icons/icon/arrowhead-dot.svg +1 -0
  39. package/dist/assets/icons/icon/arrowhead-none.svg +1 -0
  40. package/dist/assets/icons/icon/arrowhead-square.svg +1 -0
  41. package/dist/assets/icons/icon/arrowhead-triangle-inverted.svg +1 -0
  42. package/dist/assets/icons/icon/arrowhead-triangle.svg +1 -0
  43. package/dist/assets/icons/icon/blob.svg +1 -0
  44. package/dist/assets/icons/icon/bring-forward.svg +1 -0
  45. package/dist/assets/icons/icon/bring-to-front.svg +1 -0
  46. package/dist/assets/icons/icon/broken.svg +1 -0
  47. package/dist/assets/icons/icon/chat-teardrop-text.svg +1 -0
  48. package/dist/assets/icons/icon/check-circle.svg +1 -0
  49. package/dist/assets/icons/icon/check.svg +1 -0
  50. package/dist/assets/icons/icon/chevron-down.svg +1 -0
  51. package/dist/assets/icons/icon/chevron-left.svg +1 -0
  52. package/dist/assets/icons/icon/chevron-right.svg +1 -0
  53. package/dist/assets/icons/icon/chevron-up.svg +1 -0
  54. package/dist/assets/icons/icon/chevrons-ne.svg +1 -0
  55. package/dist/assets/icons/icon/chevrons-sw.svg +1 -0
  56. package/dist/assets/icons/icon/clipboard-copied.svg +1 -0
  57. package/dist/assets/icons/icon/clipboard-copy.svg +1 -0
  58. package/dist/assets/icons/icon/color.svg +1 -0
  59. package/dist/assets/icons/icon/cross-2.svg +1 -0
  60. package/dist/assets/icons/icon/cross-circle.svg +1 -0
  61. package/dist/assets/icons/icon/dash-dashed.svg +1 -0
  62. package/dist/assets/icons/icon/dash-dotted.svg +1 -0
  63. package/dist/assets/icons/icon/dash-draw.svg +1 -0
  64. package/dist/assets/icons/icon/dash-solid.svg +1 -0
  65. package/dist/assets/icons/icon/disconnected.svg +1 -0
  66. package/dist/assets/icons/icon/discord.svg +1 -0
  67. package/dist/assets/icons/icon/distribute-horizontal.svg +1 -0
  68. package/dist/assets/icons/icon/distribute-vertical.svg +1 -0
  69. package/dist/assets/icons/icon/dot.svg +1 -0
  70. package/dist/assets/icons/icon/dots-horizontal.svg +1 -0
  71. package/dist/assets/icons/icon/dots-vertical.svg +1 -0
  72. package/dist/assets/icons/icon/drag-handle-dots.svg +1 -0
  73. package/dist/assets/icons/icon/duplicate.svg +1 -0
  74. package/dist/assets/icons/icon/edit.svg +1 -0
  75. package/dist/assets/icons/icon/external-link.svg +1 -0
  76. package/dist/assets/icons/icon/fill-fill.svg +1 -0
  77. package/dist/assets/icons/icon/fill-none.svg +1 -0
  78. package/dist/assets/icons/icon/fill-pattern.svg +1 -0
  79. package/dist/assets/icons/icon/fill-semi.svg +1 -0
  80. package/dist/assets/icons/icon/fill-solid.svg +1 -0
  81. package/dist/assets/icons/icon/follow.svg +1 -0
  82. package/dist/assets/icons/icon/following.svg +1 -0
  83. package/dist/assets/icons/icon/font-draw.svg +8 -0
  84. package/dist/assets/icons/icon/font-mono.svg +1 -0
  85. package/dist/assets/icons/icon/font-sans.svg +1 -0
  86. package/dist/assets/icons/icon/font-serif.svg +1 -0
  87. package/dist/assets/icons/icon/geo-arrow-down.svg +1 -0
  88. package/dist/assets/icons/icon/geo-arrow-left.svg +1 -0
  89. package/dist/assets/icons/icon/geo-arrow-right.svg +1 -0
  90. package/dist/assets/icons/icon/geo-arrow-up.svg +1 -0
  91. package/dist/assets/icons/icon/geo-check-box.svg +1 -0
  92. package/dist/assets/icons/icon/geo-cloud.svg +1 -0
  93. package/dist/assets/icons/icon/geo-diamond.svg +1 -0
  94. package/dist/assets/icons/icon/geo-ellipse.svg +1 -0
  95. package/dist/assets/icons/icon/geo-heart.svg +1 -0
  96. package/dist/assets/icons/icon/geo-hexagon.svg +1 -0
  97. package/dist/assets/icons/icon/geo-octagon.svg +1 -0
  98. package/dist/assets/icons/icon/geo-oval.svg +1 -0
  99. package/dist/assets/icons/icon/geo-pentagon.svg +1 -0
  100. package/dist/assets/icons/icon/geo-rectangle.svg +1 -0
  101. package/dist/assets/icons/icon/geo-rhombus-2.svg +1 -0
  102. package/dist/assets/icons/icon/geo-rhombus.svg +1 -0
  103. package/dist/assets/icons/icon/geo-star.svg +1 -0
  104. package/dist/assets/icons/icon/geo-trapezoid.svg +1 -0
  105. package/dist/assets/icons/icon/geo-triangle.svg +1 -0
  106. package/dist/assets/icons/icon/geo-x-box.svg +1 -0
  107. package/dist/assets/icons/icon/github.svg +1 -0
  108. package/dist/assets/icons/icon/group.svg +1 -0
  109. package/dist/assets/icons/icon/horizontal-align-end.svg +1 -0
  110. package/dist/assets/icons/icon/horizontal-align-middle.svg +1 -0
  111. package/dist/assets/icons/icon/horizontal-align-start.svg +1 -0
  112. package/dist/assets/icons/icon/icon-names.json +143 -0
  113. package/dist/assets/icons/icon/info-circle.svg +1 -0
  114. package/dist/assets/icons/icon/leading.svg +1 -0
  115. package/dist/assets/icons/icon/link.svg +1 -0
  116. package/dist/assets/icons/icon/lock.svg +1 -0
  117. package/dist/assets/icons/icon/menu.svg +1 -0
  118. package/dist/assets/icons/icon/minus.svg +1 -0
  119. package/dist/assets/icons/icon/mixed.svg +1 -0
  120. package/dist/assets/icons/icon/pack.svg +1 -0
  121. package/dist/assets/icons/icon/plus.svg +1 -0
  122. package/dist/assets/icons/icon/question-mark-circle.svg +1 -0
  123. package/dist/assets/icons/icon/question-mark.svg +1 -0
  124. package/dist/assets/icons/icon/redo.svg +1 -0
  125. package/dist/assets/icons/icon/reset-zoom.svg +1 -0
  126. package/dist/assets/icons/icon/rotate-ccw.svg +1 -0
  127. package/dist/assets/icons/icon/rotate-cw.svg +1 -0
  128. package/dist/assets/icons/icon/send-backward.svg +1 -0
  129. package/dist/assets/icons/icon/send-to-back.svg +1 -0
  130. package/dist/assets/icons/icon/share-1.svg +1 -0
  131. package/dist/assets/icons/icon/size-extra-large.svg +1 -0
  132. package/dist/assets/icons/icon/size-large.svg +1 -0
  133. package/dist/assets/icons/icon/size-medium.svg +1 -0
  134. package/dist/assets/icons/icon/size-small.svg +1 -0
  135. package/dist/assets/icons/icon/spline-cubic.svg +1 -0
  136. package/dist/assets/icons/icon/spline-line.svg +1 -0
  137. package/dist/assets/icons/icon/stack-horizontal.svg +1 -0
  138. package/dist/assets/icons/icon/stack-vertical.svg +1 -0
  139. package/dist/assets/icons/icon/status-offline.svg +1 -0
  140. package/dist/assets/icons/icon/stretch-horizontal.svg +1 -0
  141. package/dist/assets/icons/icon/stretch-vertical.svg +1 -0
  142. package/dist/assets/icons/icon/text-align-center.svg +1 -0
  143. package/dist/assets/icons/icon/text-align-left.svg +1 -0
  144. package/dist/assets/icons/icon/text-align-right.svg +1 -0
  145. package/dist/assets/icons/icon/toggle-off.svg +1 -0
  146. package/dist/assets/icons/icon/toggle-on.svg +1 -0
  147. package/dist/assets/icons/icon/tool-arrow.svg +1 -0
  148. package/dist/assets/icons/icon/tool-eraser.svg +1 -0
  149. package/dist/assets/icons/icon/tool-frame.svg +1 -0
  150. package/dist/assets/icons/icon/tool-hand.svg +1 -0
  151. package/dist/assets/icons/icon/tool-highlight.svg +1 -0
  152. package/dist/assets/icons/icon/tool-laser.svg +1 -0
  153. package/dist/assets/icons/icon/tool-line.svg +1 -0
  154. package/dist/assets/icons/icon/tool-media.svg +1 -0
  155. package/dist/assets/icons/icon/tool-note.svg +1 -0
  156. package/dist/assets/icons/icon/tool-pencil.svg +1 -0
  157. package/dist/assets/icons/icon/tool-pointer.svg +1 -0
  158. package/dist/assets/icons/icon/tool-screenshot.svg +1 -0
  159. package/dist/assets/icons/icon/tool-text.svg +1 -0
  160. package/dist/assets/icons/icon/trash.svg +1 -0
  161. package/dist/assets/icons/icon/twitter.svg +1 -0
  162. package/dist/assets/icons/icon/undo.svg +1 -0
  163. package/dist/assets/icons/icon/ungroup.svg +1 -0
  164. package/dist/assets/icons/icon/unlock.svg +1 -0
  165. package/dist/assets/icons/icon/vertical-align-end.svg +1 -0
  166. package/dist/assets/icons/icon/vertical-align-middle.svg +1 -0
  167. package/dist/assets/icons/icon/vertical-align-start.svg +1 -0
  168. package/dist/assets/icons/icon/warning-triangle.svg +1 -0
  169. package/dist/assets/icons/icon/zoom-in.svg +1 -0
  170. package/dist/assets/icons/icon/zoom-out.svg +1 -0
  171. package/dist/assets/translations/ar.json +295 -0
  172. package/dist/assets/translations/ca.json +295 -0
  173. package/dist/assets/translations/cs.json +352 -0
  174. package/dist/assets/translations/da.json +160 -0
  175. package/dist/assets/translations/de.json +310 -0
  176. package/dist/assets/translations/en.json +1 -0
  177. package/dist/assets/translations/es.json +299 -0
  178. package/dist/assets/translations/fa.json +384 -0
  179. package/dist/assets/translations/fi.json +312 -0
  180. package/dist/assets/translations/fr.json +372 -0
  181. package/dist/assets/translations/gl.json +349 -0
  182. package/dist/assets/translations/he.json +86 -0
  183. package/dist/assets/translations/hi-in.json +290 -0
  184. package/dist/assets/translations/hr.json +358 -0
  185. package/dist/assets/translations/hu.json +365 -0
  186. package/dist/assets/translations/id.json +373 -0
  187. package/dist/assets/translations/it.json +330 -0
  188. package/dist/assets/translations/ja.json +351 -0
  189. package/dist/assets/translations/ko-kr.json +396 -0
  190. package/dist/assets/translations/ku.json +93 -0
  191. package/dist/assets/translations/languages.json +150 -0
  192. package/dist/assets/translations/main.json +396 -0
  193. package/dist/assets/translations/my.json +112 -0
  194. package/dist/assets/translations/ne.json +295 -0
  195. package/dist/assets/translations/no.json +62 -0
  196. package/dist/assets/translations/pl.json +113 -0
  197. package/dist/assets/translations/pt-br.json +333 -0
  198. package/dist/assets/translations/pt-pt.json +86 -0
  199. package/dist/assets/translations/ro.json +371 -0
  200. package/dist/assets/translations/ru.json +375 -0
  201. package/dist/assets/translations/sl.json +373 -0
  202. package/dist/assets/translations/sv.json +96 -0
  203. package/dist/assets/translations/te.json +112 -0
  204. package/dist/assets/translations/th.json +295 -0
  205. package/dist/assets/translations/tr.json +355 -0
  206. package/dist/assets/translations/uk.json +375 -0
  207. package/dist/assets/translations/vi.json +295 -0
  208. package/dist/assets/translations/zh-cn.json +386 -0
  209. package/dist/assets/translations/zh-tw.json +340 -0
  210. package/dist/lib/TldrawPlugin.mjs +22 -0
  211. package/dist/lib/TldrawPlugin.mjs.map +1 -0
  212. package/dist/lib/assets/plugin-tldraw-BDrn_mrV.css +24 -0
  213. package/dist/lib/capabilities.mjs +8 -0
  214. package/dist/lib/capabilities.mjs.map +1 -0
  215. package/dist/lib/chunk-TldrawArticle.mjs +60 -0
  216. package/dist/lib/chunk-TldrawArticle.mjs.map +1 -0
  217. package/dist/lib/chunk-TldrawCard.mjs +35 -0
  218. package/dist/lib/chunk-TldrawCard.mjs.map +1 -0
  219. package/dist/lib/chunk-meta.mjs +40 -0
  220. package/dist/lib/chunk-meta.mjs.map +1 -0
  221. package/dist/lib/chunk-settings.mjs +23 -0
  222. package/dist/lib/chunk-settings.mjs.map +1 -0
  223. package/dist/lib/chunk-sketch-variant.mjs +23 -0
  224. package/dist/lib/chunk-sketch-variant.mjs.map +1 -0
  225. package/dist/lib/chunk-types.mjs +73 -0
  226. package/dist/lib/chunk-types.mjs.map +1 -0
  227. package/dist/lib/components.mjs +443 -0
  228. package/dist/lib/components.mjs.map +1 -0
  229. package/dist/lib/containers.mjs +8 -0
  230. package/dist/lib/containers.mjs.map +1 -0
  231. package/dist/lib/hooks.mjs +116 -0
  232. package/dist/lib/hooks.mjs.map +1 -0
  233. package/dist/lib/index.mjs +4 -0
  234. package/dist/lib/meta.mjs +2 -0
  235. package/dist/lib/model.mjs +905 -0
  236. package/dist/lib/model.mjs.map +1 -0
  237. package/dist/lib/plugin.mjs +8 -0
  238. package/dist/lib/plugin.mjs.map +1 -0
  239. package/dist/lib/testing.mjs +246 -0
  240. package/dist/lib/testing.mjs.map +1 -0
  241. package/dist/lib/translations.mjs +10 -0
  242. package/dist/lib/translations.mjs.map +1 -0
  243. package/dist/lib/types.mjs +2 -0
  244. package/dist/types/dx.config.d.ts +28 -0
  245. package/dist/types/dx.config.d.ts.map +1 -0
  246. package/dist/types/src/TldrawPlugin.d.ts +4 -0
  247. package/dist/types/src/TldrawPlugin.d.ts.map +1 -0
  248. package/dist/types/src/capabilities/index.d.ts +4 -0
  249. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  250. package/dist/types/src/capabilities/settings.d.ts +5 -0
  251. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  252. package/dist/types/src/capabilities/sketch-variant.d.ts +5 -0
  253. package/dist/types/src/capabilities/sketch-variant.d.ts.map +1 -0
  254. package/dist/types/src/components/Canvas/Canvas.d.ts +17 -0
  255. package/dist/types/src/components/Canvas/Canvas.d.ts.map +1 -0
  256. package/dist/types/src/components/Canvas/Canvas.stories.d.ts +15 -0
  257. package/dist/types/src/components/Canvas/Canvas.stories.d.ts.map +1 -0
  258. package/dist/types/src/components/Canvas/index.d.ts +4 -0
  259. package/dist/types/src/components/Canvas/index.d.ts.map +1 -0
  260. package/dist/types/src/components/actions.d.ts +6 -0
  261. package/dist/types/src/components/actions.d.ts.map +1 -0
  262. package/dist/types/src/components/custom/CustomGrid.d.ts +12 -0
  263. package/dist/types/src/components/custom/CustomGrid.d.ts.map +1 -0
  264. package/dist/types/src/components/custom/CustomMenu.d.ts +4 -0
  265. package/dist/types/src/components/custom/CustomMenu.d.ts.map +1 -0
  266. package/dist/types/src/components/custom/CustomStylePanel.d.ts +4 -0
  267. package/dist/types/src/components/custom/CustomStylePanel.d.ts.map +1 -0
  268. package/dist/types/src/components/custom/CustomToolbar.d.ts +10 -0
  269. package/dist/types/src/components/custom/CustomToolbar.d.ts.map +1 -0
  270. package/dist/types/src/components/custom/DottedGrid.d.ts +4 -0
  271. package/dist/types/src/components/custom/DottedGrid.d.ts.map +1 -0
  272. package/dist/types/src/components/custom/MeshGrid.d.ts +4 -0
  273. package/dist/types/src/components/custom/MeshGrid.d.ts.map +1 -0
  274. package/dist/types/src/components/custom/index.d.ts +6 -0
  275. package/dist/types/src/components/custom/index.d.ts.map +1 -0
  276. package/dist/types/src/components/index.d.ts +2 -0
  277. package/dist/types/src/components/index.d.ts.map +1 -0
  278. package/dist/types/src/containers/TldrawArticle/TldrawArticle.d.ts +8 -0
  279. package/dist/types/src/containers/TldrawArticle/TldrawArticle.d.ts.map +1 -0
  280. package/dist/types/src/containers/TldrawArticle/index.d.ts +2 -0
  281. package/dist/types/src/containers/TldrawArticle/index.d.ts.map +1 -0
  282. package/dist/types/src/containers/TldrawCard/TldrawCard.d.ts +9 -0
  283. package/dist/types/src/containers/TldrawCard/TldrawCard.d.ts.map +1 -0
  284. package/dist/types/src/containers/TldrawCard/TldrawCard.stories.d.ts +15 -0
  285. package/dist/types/src/containers/TldrawCard/TldrawCard.stories.d.ts.map +1 -0
  286. package/dist/types/src/containers/TldrawCard/index.d.ts +2 -0
  287. package/dist/types/src/containers/TldrawCard/index.d.ts.map +1 -0
  288. package/dist/types/src/containers/index.d.ts +4 -0
  289. package/dist/types/src/containers/index.d.ts.map +1 -0
  290. package/dist/types/src/hooks/adapter.d.ts +15 -0
  291. package/dist/types/src/hooks/adapter.d.ts.map +1 -0
  292. package/dist/types/src/hooks/adapter.test.d.ts +2 -0
  293. package/dist/types/src/hooks/adapter.test.d.ts.map +1 -0
  294. package/dist/types/src/hooks/index.d.ts +3 -0
  295. package/dist/types/src/hooks/index.d.ts.map +1 -0
  296. package/dist/types/src/hooks/useStoreAdapter.d.ts +11 -0
  297. package/dist/types/src/hooks/useStoreAdapter.d.ts.map +1 -0
  298. package/dist/types/src/index.d.ts +4 -0
  299. package/dist/types/src/index.d.ts.map +1 -0
  300. package/dist/types/src/meta.d.ts +33 -0
  301. package/dist/types/src/meta.d.ts.map +1 -0
  302. package/dist/types/src/migrations/index.d.ts +3 -0
  303. package/dist/types/src/migrations/index.d.ts.map +1 -0
  304. package/dist/types/src/migrations/migrate.d.ts +9 -0
  305. package/dist/types/src/migrations/migrate.d.ts.map +1 -0
  306. package/dist/types/src/migrations/schema.d.ts +7 -0
  307. package/dist/types/src/migrations/schema.d.ts.map +1 -0
  308. package/dist/types/src/model/TldrawBuilder.d.ts +110 -0
  309. package/dist/types/src/model/TldrawBuilder.d.ts.map +1 -0
  310. package/dist/types/src/model/TldrawBuilder.test.d.ts +2 -0
  311. package/dist/types/src/model/TldrawBuilder.test.d.ts.map +1 -0
  312. package/dist/types/src/model/apply.d.ts +5 -0
  313. package/dist/types/src/model/apply.d.ts.map +1 -0
  314. package/dist/types/src/model/builder.d.ts +3 -0
  315. package/dist/types/src/model/builder.d.ts.map +1 -0
  316. package/dist/types/src/model/index.d.ts +6 -0
  317. package/dist/types/src/model/index.d.ts.map +1 -0
  318. package/dist/types/src/model/read.d.ts +8 -0
  319. package/dist/types/src/model/read.d.ts.map +1 -0
  320. package/dist/types/src/model/render.d.ts +27 -0
  321. package/dist/types/src/model/render.d.ts.map +1 -0
  322. package/dist/types/src/model/scene.test.d.ts +2 -0
  323. package/dist/types/src/model/scene.test.d.ts.map +1 -0
  324. package/dist/types/src/plugin.d.ts +3 -0
  325. package/dist/types/src/plugin.d.ts.map +1 -0
  326. package/dist/types/src/testing/data.d.ts +242 -0
  327. package/dist/types/src/testing/data.d.ts.map +1 -0
  328. package/dist/types/src/testing/index.d.ts +2 -0
  329. package/dist/types/src/testing/index.d.ts.map +1 -0
  330. package/dist/types/src/testing/schema.d.ts +7 -0
  331. package/dist/types/src/testing/schema.d.ts.map +1 -0
  332. package/dist/types/src/translations.d.ts +9 -0
  333. package/dist/types/src/translations.d.ts.map +1 -0
  334. package/dist/types/src/types/Settings.d.ts +10 -0
  335. package/dist/types/src/types/Settings.d.ts.map +1 -0
  336. package/dist/types/src/types/Tldraw.d.ts +25 -0
  337. package/dist/types/src/types/Tldraw.d.ts.map +1 -0
  338. package/dist/types/src/types/TldrawCapabilities.d.ts +4 -0
  339. package/dist/types/src/types/TldrawCapabilities.d.ts.map +1 -0
  340. package/dist/types/src/types/index.d.ts +4 -0
  341. package/dist/types/src/types/index.d.ts.map +1 -0
  342. package/dist/types/src/types/types.d.ts +6 -0
  343. package/dist/types/src/types/types.d.ts.map +1 -0
  344. package/dist/types/src/variant.test.d.ts +2 -0
  345. package/dist/types/src/variant.test.d.ts.map +1 -0
  346. package/dist/types/tsconfig.tsbuildinfo +1 -0
  347. package/dx.config.ts +35 -0
  348. package/package.json +157 -0
  349. package/src/TldrawPlugin.tsx +31 -0
  350. package/src/capabilities/index.ts +8 -0
  351. package/src/capabilities/settings.ts +31 -0
  352. package/src/capabilities/sketch-variant.ts +29 -0
  353. package/src/components/Canvas/Canvas.stories.tsx +101 -0
  354. package/src/components/Canvas/Canvas.tsx +284 -0
  355. package/src/components/Canvas/index.ts +9 -0
  356. package/src/components/Canvas/theme.css +23 -0
  357. package/src/components/actions.ts +42 -0
  358. package/src/components/custom/CustomGrid.tsx +61 -0
  359. package/src/components/custom/CustomMenu.tsx +31 -0
  360. package/src/components/custom/CustomStylePanel.tsx +38 -0
  361. package/src/components/custom/CustomToolbar.tsx +88 -0
  362. package/src/components/custom/DottedGrid.tsx +53 -0
  363. package/src/components/custom/MeshGrid.tsx +47 -0
  364. package/src/components/custom/index.ts +9 -0
  365. package/src/components/index.ts +5 -0
  366. package/src/containers/TldrawArticle/TldrawArticle.tsx +78 -0
  367. package/src/containers/TldrawArticle/index.ts +5 -0
  368. package/src/containers/TldrawCard/TldrawCard.stories.tsx +53 -0
  369. package/src/containers/TldrawCard/TldrawCard.tsx +32 -0
  370. package/src/containers/TldrawCard/index.ts +5 -0
  371. package/src/containers/index.ts +8 -0
  372. package/src/hooks/adapter.test.ts +20 -0
  373. package/src/hooks/adapter.ts +83 -0
  374. package/src/hooks/index.ts +6 -0
  375. package/src/hooks/useStoreAdapter.ts +55 -0
  376. package/src/index.ts +7 -0
  377. package/src/meta.ts +9 -0
  378. package/src/migrations/index.ts +6 -0
  379. package/src/migrations/migrate.ts +49 -0
  380. package/src/migrations/schema.ts +98 -0
  381. package/src/model/TldrawBuilder.test.ts +72 -0
  382. package/src/model/TldrawBuilder.ts +443 -0
  383. package/src/model/apply.ts +132 -0
  384. package/src/model/builder.ts +31 -0
  385. package/src/model/index.ts +9 -0
  386. package/src/model/read.ts +203 -0
  387. package/src/model/render.ts +191 -0
  388. package/src/model/scene.test.ts +222 -0
  389. package/src/plugin.ts +9 -0
  390. package/src/testing/data.ts +238 -0
  391. package/src/testing/index.ts +5 -0
  392. package/src/testing/schema.ts +98 -0
  393. package/src/translations.ts +18 -0
  394. package/src/types/Settings.ts +32 -0
  395. package/src/types/Tldraw.ts +38 -0
  396. package/src/types/TldrawCapabilities.ts +17 -0
  397. package/src/types/index.ts +8 -0
  398. package/src/types/types.ts +11 -0
  399. package/src/typings.d.ts +8 -0
  400. package/src/variant.test.ts +142 -0
  401. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,905 @@
1
+ import { n as Canvas, o as __exportAll } from "./chunk-types.mjs";
2
+ import { invariant } from "@dxos/invariant";
3
+ import { Obj } from "@dxos/echo";
4
+ //#region src/model/read.ts
5
+ /** Read the derived scene from canvas content. */
6
+ var readScene = (content) => {
7
+ const groups = /* @__PURE__ */ new Map();
8
+ let unmanaged = 0;
9
+ for (const record of Object.values(content ?? {})) {
10
+ if (record?.typeName !== "shape") continue;
11
+ const objectId = record.meta?.object;
12
+ if (typeof objectId !== "string" || typeof record.meta?.element !== "string") {
13
+ unmanaged++;
14
+ continue;
15
+ }
16
+ groups.set(objectId, [...groups.get(objectId) ?? [], record]);
17
+ }
18
+ return {
19
+ scene: { objects: [...groups.entries()].map(([objectId, records]) => readObject(objectId, records, content)) },
20
+ unmanaged
21
+ };
22
+ };
23
+ /** Canvas-px bounding boxes of all managed elements, keyed by `objectId/elementId`. */
24
+ var elementBoxes = (content) => {
25
+ const boxes = {};
26
+ for (const record of Object.values(content ?? {})) if (record?.typeName === "shape" && record.meta?.object && record.meta?.element) boxes[`${record.meta.object}/${record.meta.element}`] = bounds(record);
27
+ return boxes;
28
+ };
29
+ var readObject = (objectId, records, content) => {
30
+ const scale = records.find((record) => typeof record.meta?.scale === "number")?.meta.scale ?? 1;
31
+ const origin = {
32
+ x: Math.min(...records.map((record) => bounds(record).x)),
33
+ y: Math.min(...records.map((record) => bounds(record).y))
34
+ };
35
+ const local = (abs) => ({
36
+ x: round((abs.x - origin.x) / scale),
37
+ y: round((abs.y - origin.y) / scale)
38
+ });
39
+ const length = (px) => round(px / scale);
40
+ return {
41
+ id: objectId,
42
+ origin,
43
+ scale,
44
+ elements: records.map((record) => readElement(record, {
45
+ local,
46
+ length,
47
+ objectId,
48
+ content
49
+ })).filter((element) => element !== void 0)
50
+ };
51
+ };
52
+ var readElement = (record, ctx) => {
53
+ const id = record.meta.element;
54
+ const kind = record.meta.kind;
55
+ switch (record.type) {
56
+ case "geo": return {
57
+ kind: kind === "rect" || kind === "diamond" || kind === "triangle" ? kind : "ellipse",
58
+ id,
59
+ ...ctx.local({
60
+ x: record.x,
61
+ y: record.y
62
+ }),
63
+ w: ctx.length(record.props.w),
64
+ h: ctx.length(record.props.h),
65
+ ...record.rotation ? { rotation: round(record.rotation * 180 / Math.PI) } : {},
66
+ ...record.props.text ? { text: record.props.text } : {},
67
+ ...readStyle(record)
68
+ };
69
+ case "text": return {
70
+ kind: "text",
71
+ id,
72
+ ...ctx.local({
73
+ x: record.x,
74
+ y: record.y
75
+ }),
76
+ ...record.props.autoSize ? {} : { w: ctx.length(record.props.w) },
77
+ text: record.props.text ?? "",
78
+ ...readStyle(record)
79
+ };
80
+ case "line": {
81
+ const points = linePoints(record).map((point) => ctx.local({
82
+ x: record.x + point.x,
83
+ y: record.y + point.y
84
+ }));
85
+ if (kind === "curve") return {
86
+ kind: "curve",
87
+ id,
88
+ points,
89
+ ...readStyle(record)
90
+ };
91
+ const closed = points.length > 2 && points[0].x === points[points.length - 1].x && points[0].y === points[points.length - 1].y;
92
+ return {
93
+ kind: "line",
94
+ id,
95
+ points: closed ? points.slice(0, -1) : points,
96
+ ...closed ? { closed: true } : {},
97
+ ...readStyle(record)
98
+ };
99
+ }
100
+ case "arrow": {
101
+ const { from, to } = arrowRefs(record, ctx);
102
+ return {
103
+ kind: "arrow",
104
+ id,
105
+ ...from ? { from } : { start: ctx.local({
106
+ x: record.x + record.props.start.x,
107
+ y: record.y + record.props.start.y
108
+ }) },
109
+ ...to ? { to } : { end: ctx.local({
110
+ x: record.x + record.props.end.x,
111
+ y: record.y + record.props.end.y
112
+ }) },
113
+ ...record.props.text ? { text: record.props.text } : {},
114
+ ...readStyle(record)
115
+ };
116
+ }
117
+ default: return;
118
+ }
119
+ };
120
+ /** Resolve arrow terminal bindings back to element refs (same-object refs are shortened). */
121
+ var arrowRefs = (record, ctx) => {
122
+ const refs = {};
123
+ for (const binding of Object.values(ctx.content ?? {})) {
124
+ if (binding?.typeName !== "binding" || binding.fromId !== record.id) continue;
125
+ const target = ctx.content[binding.toId];
126
+ if (!target?.meta?.object || !target?.meta?.element) continue;
127
+ const ref = target.meta.object === ctx.objectId ? target.meta.element : `${target.meta.object}/${target.meta.element}`;
128
+ if (binding.props?.terminal === "start") refs.from = ref;
129
+ else refs.to = ref;
130
+ }
131
+ return refs;
132
+ };
133
+ /** Report only non-default styles to keep the read output compact. */
134
+ var readStyle = (record) => {
135
+ const { color, fill, dash, size } = record.props;
136
+ return {
137
+ ...color && color !== "black" ? { color } : {},
138
+ ...fill && fill !== "none" ? { fill: fill === "pattern" ? "pattern" : "solid" } : {},
139
+ ...dash && dash !== "draw" ? { stroke: dash } : {},
140
+ ...size && size !== "m" ? { weight: size } : {}
141
+ };
142
+ };
143
+ var linePoints = (record) => Object.values(record.props.points ?? {}).sort((a, b) => Number(String(a.index).slice(1)) - Number(String(b.index).slice(1))).map((point) => ({
144
+ x: point.x,
145
+ y: point.y
146
+ }));
147
+ /** Bounding box of a shape record in canvas px. */
148
+ var bounds = (record) => {
149
+ switch (record.type) {
150
+ case "geo": return {
151
+ x: record.x,
152
+ y: record.y,
153
+ w: record.props.w,
154
+ h: record.props.h
155
+ };
156
+ case "text": return {
157
+ x: record.x,
158
+ y: record.y,
159
+ w: record.props.w ?? 0,
160
+ h: 0
161
+ };
162
+ case "line": {
163
+ const points = linePoints(record);
164
+ return boxFrom(points.map((point) => record.x + point.x), points.map((point) => record.y + point.y));
165
+ }
166
+ case "arrow": return boxFrom([record.x + record.props.start.x, record.x + record.props.end.x], [record.y + record.props.start.y, record.y + record.props.end.y]);
167
+ default: return {
168
+ x: record.x ?? 0,
169
+ y: record.y ?? 0,
170
+ w: record.props?.w ?? 0,
171
+ h: record.props?.h ?? 0
172
+ };
173
+ }
174
+ };
175
+ var boxFrom = (xs, ys) => {
176
+ const x = Math.min(...xs);
177
+ const y = Math.min(...ys);
178
+ return {
179
+ x,
180
+ y,
181
+ w: Math.max(...xs) - x,
182
+ h: Math.max(...ys) - y
183
+ };
184
+ };
185
+ var round = (value) => Math.round(value * 100) / 100;
186
+ //#endregion
187
+ //#region src/model/TldrawBuilder.ts
188
+ var __dxlog_file$2 = "/Users/burdon/Code/dxos/dxos/.claude/worktrees/peaceful-allen-9b542f/packages/plugins/plugin-tldraw/src/model/TldrawBuilder.ts";
189
+ var PAGE_ID = "page:page";
190
+ var DOCUMENT_ID = "document:document";
191
+ var DEFAULTS = {
192
+ color: "black",
193
+ fill: "none",
194
+ dash: "draw",
195
+ size: "m",
196
+ font: "draw",
197
+ align: "middle",
198
+ w: 160,
199
+ h: 120
200
+ };
201
+ /**
202
+ * Chainable builder for sketch (tldraw) canvas content.
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * const content = new TldrawBuilder()
207
+ * .rectangle({ id: 'a', x: 0, y: 0, text: 'DXOS', color: 'blue' })
208
+ * .ellipse({ id: 'b', x: 320, y: 0, text: 'ECHO', color: 'green' })
209
+ * .arrow({ from: 'a', to: 'b' })
210
+ * .build();
211
+ * ```
212
+ */
213
+ var TldrawBuilder = class {
214
+ #records = {};
215
+ #boxes = /* @__PURE__ */ new Map();
216
+ #metaFor;
217
+ #shapeCount = 0;
218
+ #bindingCount = 0;
219
+ #indexCount;
220
+ constructor(options = {}) {
221
+ this.#indexCount = options.indexStart ?? 0;
222
+ this.#metaFor = options.metaFor;
223
+ }
224
+ /**
225
+ * Register a shape that already exists on the canvas (its bounding box in canvas px)
226
+ * so connectors added by this builder can bind to it.
227
+ */
228
+ external(handle, box, shapeId) {
229
+ invariant(!this.#boxes.has(handle), `duplicate shape id: ${handle}`, {
230
+ "~LogMeta": "~LogMeta",
231
+ F: __dxlog_file$2,
232
+ L: 162,
233
+ S: this,
234
+ A: ["!this.#boxes.has(handle)", "`duplicate shape id: ${handle}`"]
235
+ });
236
+ this.#boxes.set(handle, {
237
+ id: shapeId ?? `shape:${handle}`,
238
+ ...box
239
+ });
240
+ return this;
241
+ }
242
+ /** Add a rectangle. */
243
+ rectangle(props = {}) {
244
+ return this.geo("rectangle", props);
245
+ }
246
+ /** Add an ellipse. */
247
+ ellipse(props = {}) {
248
+ return this.geo("ellipse", props);
249
+ }
250
+ /** Add a circle (an ellipse with equal width and height). */
251
+ circle(props = {}) {
252
+ const size = props.w ?? props.h ?? DEFAULTS.w;
253
+ return this.geo("ellipse", {
254
+ ...props,
255
+ w: size,
256
+ h: size
257
+ });
258
+ }
259
+ /** Add an arbitrary geometric shape. */
260
+ geo(geo, props = {}) {
261
+ const { id, x = 0, y = 0, w = DEFAULTS.w, h = DEFAULTS.h, rotation = 0 } = props;
262
+ const shapeId = this.#registerShape({
263
+ id,
264
+ x,
265
+ y,
266
+ w,
267
+ h
268
+ });
269
+ this.#records[shapeId] = {
270
+ id: shapeId,
271
+ typeName: "shape",
272
+ type: "geo",
273
+ x,
274
+ y,
275
+ rotation,
276
+ index: this.#nextIndex(),
277
+ parentId: PAGE_ID,
278
+ isLocked: false,
279
+ opacity: 1,
280
+ meta: this.#meta(id),
281
+ props: {
282
+ geo,
283
+ w,
284
+ h,
285
+ color: props.color ?? DEFAULTS.color,
286
+ labelColor: DEFAULTS.color,
287
+ fill: props.fill ?? DEFAULTS.fill,
288
+ dash: props.dash ?? DEFAULTS.dash,
289
+ size: props.size ?? DEFAULTS.size,
290
+ font: props.font ?? DEFAULTS.font,
291
+ align: props.align ?? DEFAULTS.align,
292
+ verticalAlign: "middle",
293
+ url: "",
294
+ growY: 0,
295
+ text: props.text ?? "",
296
+ scale: 1
297
+ }
298
+ };
299
+ return this;
300
+ }
301
+ /** Add a free-standing text label. */
302
+ text(props = {}) {
303
+ const { id, x = 0, y = 0, w = DEFAULTS.w, rotation = 0 } = props;
304
+ const shapeId = this.#registerShape({
305
+ id,
306
+ x,
307
+ y,
308
+ w,
309
+ h: 0
310
+ });
311
+ this.#records[shapeId] = {
312
+ id: shapeId,
313
+ typeName: "shape",
314
+ type: "text",
315
+ x,
316
+ y,
317
+ rotation,
318
+ index: this.#nextIndex(),
319
+ parentId: PAGE_ID,
320
+ isLocked: false,
321
+ opacity: 1,
322
+ meta: this.#meta(id),
323
+ props: {
324
+ color: props.color ?? DEFAULTS.color,
325
+ size: props.size ?? DEFAULTS.size,
326
+ font: props.font ?? DEFAULTS.font,
327
+ textAlign: props.align ?? DEFAULTS.align,
328
+ w,
329
+ text: props.text ?? "",
330
+ scale: 1,
331
+ autoSize: true
332
+ }
333
+ };
334
+ return this;
335
+ }
336
+ /** Add an arrow, optionally bound to source/target shapes so it tracks them. */
337
+ arrow(props = {}) {
338
+ return this.#connector("arrow", props);
339
+ }
340
+ /** Add a line between two shapes (or explicit points). */
341
+ line(props = {}) {
342
+ return this.#connector("line", props);
343
+ }
344
+ /** Add a path (open or closed, straight or smooth) through explicit points. */
345
+ path(props) {
346
+ const { id, smooth, closed } = props;
347
+ const source = closed && props.points.length > 1 ? [...props.points, props.points[0]] : [...props.points];
348
+ invariant(source.length >= 2, "path requires at least two points", {
349
+ "~LogMeta": "~LogMeta",
350
+ F: __dxlog_file$2,
351
+ L: 266,
352
+ S: this,
353
+ A: ["source.length >= 2", "'path requires at least two points'"]
354
+ });
355
+ const origin = source[0];
356
+ const xs = source.map((point) => point.x);
357
+ const ys = source.map((point) => point.y);
358
+ const shapeId = this.#registerShape({
359
+ id,
360
+ x: Math.min(...xs),
361
+ y: Math.min(...ys),
362
+ w: Math.max(...xs) - Math.min(...xs),
363
+ h: Math.max(...ys) - Math.min(...ys)
364
+ });
365
+ this.#records[shapeId] = {
366
+ id: shapeId,
367
+ typeName: "shape",
368
+ type: "line",
369
+ x: origin.x,
370
+ y: origin.y,
371
+ rotation: 0,
372
+ index: this.#nextIndex(),
373
+ parentId: PAGE_ID,
374
+ isLocked: false,
375
+ opacity: 1,
376
+ meta: this.#meta(id),
377
+ props: {
378
+ color: props.color ?? DEFAULTS.color,
379
+ dash: props.dash ?? DEFAULTS.dash,
380
+ size: props.size ?? DEFAULTS.size,
381
+ spline: smooth ? "cubic" : "line",
382
+ points: Object.fromEntries(source.map((point, i) => [`a${i + 1}`, {
383
+ id: `a${i + 1}`,
384
+ index: `a${i + 1}`,
385
+ x: point.x - origin.x,
386
+ y: point.y - origin.y
387
+ }])),
388
+ scale: 1
389
+ }
390
+ };
391
+ return this;
392
+ }
393
+ /** Build the full canvas snapshot (document + page + records). */
394
+ build() {
395
+ return {
396
+ [DOCUMENT_ID]: {
397
+ gridSize: 10,
398
+ name: "",
399
+ meta: {},
400
+ id: DOCUMENT_ID,
401
+ typeName: "document"
402
+ },
403
+ [PAGE_ID]: {
404
+ meta: {},
405
+ id: PAGE_ID,
406
+ name: "Page 1",
407
+ index: "a1",
408
+ typeName: "page"
409
+ },
410
+ ...this.#records
411
+ };
412
+ }
413
+ /** Return only the generated records (for merging into an existing canvas). */
414
+ records() {
415
+ return { ...this.#records };
416
+ }
417
+ #connector(type, props) {
418
+ const from = props.from ? this.#boxes.get(props.from) : void 0;
419
+ const to = props.to ? this.#boxes.get(props.to) : void 0;
420
+ invariant(!props.from || from, `unknown source shape: ${props.from}`, {
421
+ "~LogMeta": "~LogMeta",
422
+ F: __dxlog_file$2,
423
+ L: 325,
424
+ S: this,
425
+ A: ["!props.from || from", "`unknown source shape: ${props.from}`"]
426
+ });
427
+ invariant(!props.to || to, `unknown target shape: ${props.to}`, {
428
+ "~LogMeta": "~LogMeta",
429
+ F: __dxlog_file$2,
430
+ L: 326,
431
+ S: this,
432
+ A: ["!props.to || to", "`unknown target shape: ${props.to}`"]
433
+ });
434
+ const start = from ? center(from) : props.start ?? {
435
+ x: 0,
436
+ y: 0
437
+ };
438
+ const end = to ? center(to) : props.end ?? {
439
+ x: DEFAULTS.w,
440
+ y: 0
441
+ };
442
+ const shapeId = this.#registerShape({
443
+ id: props.id,
444
+ x: start.x,
445
+ y: start.y,
446
+ w: 0,
447
+ h: 0
448
+ });
449
+ const relativeEnd = {
450
+ x: end.x - start.x,
451
+ y: end.y - start.y
452
+ };
453
+ const style = {
454
+ color: props.color ?? DEFAULTS.color,
455
+ dash: props.dash ?? DEFAULTS.dash,
456
+ size: props.size ?? DEFAULTS.size
457
+ };
458
+ if (type === "arrow") {
459
+ this.#records[shapeId] = {
460
+ id: shapeId,
461
+ typeName: "shape",
462
+ type: "arrow",
463
+ x: start.x,
464
+ y: start.y,
465
+ rotation: 0,
466
+ index: this.#nextIndex(),
467
+ parentId: PAGE_ID,
468
+ isLocked: false,
469
+ opacity: 1,
470
+ meta: this.#meta(props.id),
471
+ props: {
472
+ ...style,
473
+ labelColor: DEFAULTS.color,
474
+ fill: props.fill ?? DEFAULTS.fill,
475
+ font: props.font ?? DEFAULTS.font,
476
+ arrowheadStart: "none",
477
+ arrowheadEnd: "arrow",
478
+ start: {
479
+ x: 0,
480
+ y: 0
481
+ },
482
+ end: relativeEnd,
483
+ bend: 0,
484
+ text: props.text ?? "",
485
+ labelPosition: .5,
486
+ scale: 1
487
+ }
488
+ };
489
+ if (from) this.#binding(shapeId, from.id, "start");
490
+ if (to) this.#binding(shapeId, to.id, "end");
491
+ } else this.#records[shapeId] = {
492
+ id: shapeId,
493
+ typeName: "shape",
494
+ type: "line",
495
+ x: start.x,
496
+ y: start.y,
497
+ rotation: 0,
498
+ index: this.#nextIndex(),
499
+ parentId: PAGE_ID,
500
+ isLocked: false,
501
+ opacity: 1,
502
+ meta: this.#meta(props.id),
503
+ props: {
504
+ ...style,
505
+ spline: "line",
506
+ points: {
507
+ a1: {
508
+ id: "a1",
509
+ index: "a1",
510
+ x: 0,
511
+ y: 0
512
+ },
513
+ a2: {
514
+ id: "a2",
515
+ index: "a2",
516
+ x: relativeEnd.x,
517
+ y: relativeEnd.y
518
+ }
519
+ },
520
+ scale: 1
521
+ }
522
+ };
523
+ return this;
524
+ }
525
+ #binding(arrowId, shapeId, terminal) {
526
+ const bindingId = `binding:${arrowId.slice(6)}/${terminal}-${++this.#bindingCount}`;
527
+ this.#records[bindingId] = {
528
+ id: bindingId,
529
+ typeName: "binding",
530
+ type: "arrow",
531
+ fromId: arrowId,
532
+ toId: shapeId,
533
+ meta: {},
534
+ props: {
535
+ terminal,
536
+ normalizedAnchor: {
537
+ x: .5,
538
+ y: .5
539
+ },
540
+ isExact: false,
541
+ isPrecise: false
542
+ }
543
+ };
544
+ }
545
+ #meta(handle) {
546
+ return handle && this.#metaFor ? this.#metaFor(handle) : {};
547
+ }
548
+ #registerShape(box) {
549
+ let shapeId = box.id ? `shape:${box.id}` : `shape:s${++this.#shapeCount}`;
550
+ while (!box.id && this.#records[shapeId]) shapeId = `shape:s${++this.#shapeCount}`;
551
+ const handle = box.id ?? shapeId;
552
+ invariant(!this.#records[shapeId] && !this.#boxes.has(handle), `duplicate shape id: ${handle}`, {
553
+ "~LogMeta": "~LogMeta",
554
+ F: __dxlog_file$2,
555
+ L: 433,
556
+ S: this,
557
+ A: ["!this.#records[shapeId] && !this.#boxes.has(handle)", "`duplicate shape id: ${handle}`"]
558
+ });
559
+ this.#boxes.set(handle, {
560
+ id: shapeId,
561
+ x: box.x,
562
+ y: box.y,
563
+ w: box.w,
564
+ h: box.h
565
+ });
566
+ return shapeId;
567
+ }
568
+ #nextIndex() {
569
+ return `a${++this.#indexCount}`;
570
+ }
571
+ };
572
+ var center = (box) => ({
573
+ x: box.x + box.w / 2,
574
+ y: box.y + box.h / 2
575
+ });
576
+ //#endregion
577
+ //#region src/model/render.ts
578
+ var DEFAULT_SCALE = 1;
579
+ /** Stable record id for an element: `shape:<objectId>/<elementId>`. */
580
+ var shapeId = (objectId, elementId) => `shape:${objectId}/${elementId}`;
581
+ var strokeToDash = {
582
+ sketchy: "draw",
583
+ solid: "solid",
584
+ dashed: "dashed",
585
+ dotted: "dotted"
586
+ };
587
+ var fillToFill = {
588
+ none: "none",
589
+ solid: "solid",
590
+ pattern: "pattern"
591
+ };
592
+ var boxKindToGeo = {
593
+ rect: "rectangle",
594
+ ellipse: "ellipse",
595
+ diamond: "diamond",
596
+ triangle: "triangle"
597
+ };
598
+ var style = (element) => ({
599
+ color: element.color,
600
+ fill: "fill" in element && element.fill ? fillToFill[element.fill] : void 0,
601
+ dash: element.stroke ? strokeToDash[element.stroke] : void 0,
602
+ size: element.weight
603
+ });
604
+ /**
605
+ * Compile one world object into tldraw records (canvas-px coordinates).
606
+ * Local coordinates are mapped via `canvas = origin + local * scale`.
607
+ */
608
+ var renderObject = (object, options) => {
609
+ const { origin, scale, indexStart, external = {}, dialect = "scene" } = options;
610
+ const point = (local) => ({
611
+ x: origin.x + local.x * scale,
612
+ y: origin.y + local.y * scale
613
+ });
614
+ const length = (units) => units * scale;
615
+ const kinds = /* @__PURE__ */ new Map();
616
+ const builder = new TldrawBuilder({
617
+ indexStart,
618
+ metaFor: (handle) => {
619
+ const [objectId, elementId] = splitHandle(handle);
620
+ return {
621
+ object: objectId,
622
+ element: elementId,
623
+ kind: kinds.get(handle),
624
+ scale,
625
+ dialect
626
+ };
627
+ }
628
+ });
629
+ for (const [handle, box] of Object.entries(external)) builder.external(handle, box);
630
+ const ref = (value) => value.includes("/") ? value : `${object.id}/${value}`;
631
+ for (const element of object.elements) {
632
+ const handle = `${object.id}/${element.id}`;
633
+ kinds.set(handle, element.kind);
634
+ switch (element.kind) {
635
+ case "rect":
636
+ case "ellipse":
637
+ case "diamond":
638
+ case "triangle":
639
+ builder.geo(boxKindToGeo[element.kind], {
640
+ id: handle,
641
+ ...point(element),
642
+ w: length(element.w),
643
+ h: length(element.h),
644
+ rotation: element.rotation !== void 0 ? element.rotation * Math.PI / 180 : void 0,
645
+ text: element.text,
646
+ ...style(element)
647
+ });
648
+ break;
649
+ case "circle":
650
+ kinds.set(handle, "ellipse");
651
+ builder.circle({
652
+ id: handle,
653
+ ...point({
654
+ x: element.cx - element.r,
655
+ y: element.cy - element.r
656
+ }),
657
+ w: length(element.r * 2),
658
+ text: element.text,
659
+ ...style(element)
660
+ });
661
+ break;
662
+ case "line": {
663
+ const props = {
664
+ id: handle,
665
+ points: element.points.map(point),
666
+ closed: element.closed,
667
+ ...style(element)
668
+ };
669
+ builder.path(props);
670
+ break;
671
+ }
672
+ case "curve":
673
+ builder.path({
674
+ id: handle,
675
+ points: element.points.map(point),
676
+ smooth: true,
677
+ ...style(element)
678
+ });
679
+ break;
680
+ case "arc":
681
+ kinds.set(handle, "curve");
682
+ builder.path({
683
+ id: handle,
684
+ points: sampleArc(element).map(point),
685
+ smooth: true,
686
+ ...style(element)
687
+ });
688
+ break;
689
+ case "text":
690
+ builder.text({
691
+ id: handle,
692
+ ...point(element),
693
+ w: element.w !== void 0 ? length(element.w) : void 0,
694
+ text: element.text,
695
+ color: element.color,
696
+ size: element.weight
697
+ });
698
+ break;
699
+ case "arrow": {
700
+ const props = {
701
+ id: handle,
702
+ from: element.from ? ref(element.from) : void 0,
703
+ to: element.to ? ref(element.to) : void 0,
704
+ start: element.start ? point(element.start) : void 0,
705
+ end: element.end ? point(element.end) : void 0,
706
+ text: element.text,
707
+ ...style(element)
708
+ };
709
+ builder.arrow(props);
710
+ break;
711
+ }
712
+ }
713
+ }
714
+ return builder.records();
715
+ };
716
+ /** `objectId/elementId` — element ids may themselves not contain `/`. */
717
+ var splitHandle = (handle) => {
718
+ const index = handle.indexOf("/");
719
+ return [handle.slice(0, index), handle.slice(index + 1)];
720
+ };
721
+ /** Sample an arc (degrees, clockwise from +x, y-down screen coords) into spline points. */
722
+ var sampleArc = ({ cx, cy, r, startAngle, endAngle }) => {
723
+ const sweep = endAngle - startAngle;
724
+ const steps = Math.max(4, Math.ceil(Math.abs(sweep) / 22.5));
725
+ return Array.from({ length: steps + 1 }, (_, i) => {
726
+ const angle = (startAngle + sweep * i / steps) * Math.PI / 180;
727
+ return {
728
+ x: cx + r * Math.cos(angle),
729
+ y: cy + r * Math.sin(angle)
730
+ };
731
+ });
732
+ };
733
+ //#endregion
734
+ //#region src/model/apply.ts
735
+ var __dxlog_file$1 = "/Users/burdon/Code/dxos/dxos/.claude/worktrees/peaceful-allen-9b542f/packages/plugins/plugin-tldraw/src/model/apply.ts";
736
+ /** Apply a batch of edit commands to the canvas content (mutates `content`). */
737
+ var applyCommands = (content, commands) => {
738
+ ensurePage(content);
739
+ const upserted = /* @__PURE__ */ new Set();
740
+ let removed = 0;
741
+ for (const command of commands) switch (command.op) {
742
+ case "upsert-object": {
743
+ const previous = readScene(content).scene.objects.find((object) => object.id === command.object.id);
744
+ removed += remove(content, (record) => record.meta?.object === command.object.id);
745
+ merge(content, command.object, {
746
+ origin: command.object.origin ?? previous?.origin ?? {
747
+ x: 0,
748
+ y: 0
749
+ },
750
+ scale: command.object.scale ?? previous?.scale ?? 1
751
+ });
752
+ upserted.add(command.object.id);
753
+ break;
754
+ }
755
+ case "upsert-elements": {
756
+ const previous = readScene(content).scene.objects.find((object) => object.id === command.objectId);
757
+ invariant(previous, `unknown object: ${command.objectId} (use upsert-object to create it)`, {
758
+ "~LogMeta": "~LogMeta",
759
+ F: __dxlog_file$1,
760
+ L: 37,
761
+ S: void 0,
762
+ A: ["previous", "`unknown object: ${command.objectId} (use upsert-object to create it)`"]
763
+ });
764
+ const ids = new Set(command.elements.map((element) => element.id));
765
+ removed += remove(content, (record) => record.meta?.object === command.objectId && ids.has(record.meta?.element));
766
+ merge(content, {
767
+ id: command.objectId,
768
+ elements: command.elements
769
+ }, {
770
+ origin: previous.origin,
771
+ scale: previous.scale
772
+ });
773
+ upserted.add(command.objectId);
774
+ break;
775
+ }
776
+ case "remove-elements": {
777
+ const ids = new Set(command.elementIds);
778
+ removed += remove(content, (record) => record.meta?.object === command.objectId && ids.has(record.meta?.element));
779
+ break;
780
+ }
781
+ case "remove-object":
782
+ removed += remove(content, (record) => record.meta?.object === command.objectId);
783
+ break;
784
+ case "move-object": {
785
+ const previous = readScene(content).scene.objects.find((object) => object.id === command.objectId);
786
+ invariant(previous, `unknown object: ${command.objectId}`, {
787
+ "~LogMeta": "~LogMeta",
788
+ F: __dxlog_file$1,
789
+ L: 65,
790
+ S: void 0,
791
+ A: ["previous", "`unknown object: ${command.objectId}`"]
792
+ });
793
+ const delta = {
794
+ x: command.origin.x - previous.origin.x,
795
+ y: command.origin.y - previous.origin.y
796
+ };
797
+ for (const record of Object.values(content)) if (record?.typeName === "shape" && record.meta?.object === command.objectId) {
798
+ record.x += delta.x;
799
+ record.y += delta.y;
800
+ }
801
+ upserted.add(command.objectId);
802
+ break;
803
+ }
804
+ }
805
+ return {
806
+ upserted: [...upserted],
807
+ removed
808
+ };
809
+ };
810
+ var merge = (content, object, placement) => {
811
+ const records = renderObject(object, {
812
+ ...placement,
813
+ indexStart: nextIndex(content),
814
+ external: elementBoxes(content)
815
+ });
816
+ Object.assign(content, records);
817
+ };
818
+ /** Delete matching shape records, then any bindings left dangling. */
819
+ var remove = (content, predicate) => {
820
+ let removed = 0;
821
+ for (const [key, record] of Object.entries(content)) if (record?.typeName === "shape" && predicate(record)) {
822
+ delete content[key];
823
+ removed++;
824
+ }
825
+ for (const [key, record] of Object.entries(content)) if (record?.typeName === "binding" && (!content[record.fromId] || !content[record.toId])) delete content[key];
826
+ return removed;
827
+ };
828
+ /** Seed the fractional-index counter past any existing `a<n>` indexes. */
829
+ var nextIndex = (content) => {
830
+ let max = 0;
831
+ let shapes = 0;
832
+ for (const record of Object.values(content)) {
833
+ if (record?.typeName !== "shape") continue;
834
+ shapes++;
835
+ const match = /^a(\d+)$/.exec(record.index ?? "");
836
+ if (match) max = Math.max(max, Number(match[1]));
837
+ }
838
+ return Math.max(max, shapes);
839
+ };
840
+ var ensurePage = (content) => {
841
+ content[DOCUMENT_ID] ??= {
842
+ gridSize: 10,
843
+ name: "",
844
+ meta: {},
845
+ id: DOCUMENT_ID,
846
+ typeName: "document"
847
+ };
848
+ content[PAGE_ID] ??= {
849
+ meta: {},
850
+ id: PAGE_ID,
851
+ name: "Page 1",
852
+ index: "a1",
853
+ typeName: "page"
854
+ };
855
+ };
856
+ //#endregion
857
+ //#region src/model/builder.ts
858
+ var __dxlog_file = "/Users/burdon/Code/dxos/dxos/.claude/worktrees/peaceful-allen-9b542f/packages/plugins/plugin-tldraw/src/model/builder.ts";
859
+ var tldrawBuilder = {
860
+ read: (canvas) => {
861
+ invariant(Obj.instanceOf(Canvas, canvas), void 0, {
862
+ "~LogMeta": "~LogMeta",
863
+ F: __dxlog_file,
864
+ L: 20,
865
+ S: void 0,
866
+ A: ["Obj.instanceOf(Tldraw.Canvas, canvas)", ""]
867
+ });
868
+ return readScene(canvas.content);
869
+ },
870
+ apply: (canvas, commands) => {
871
+ invariant(Obj.instanceOf(Canvas, canvas), void 0, {
872
+ "~LogMeta": "~LogMeta",
873
+ F: __dxlog_file,
874
+ L: 24,
875
+ S: void 0,
876
+ A: ["Obj.instanceOf(Tldraw.Canvas, canvas)", ""]
877
+ });
878
+ let result = {
879
+ upserted: [],
880
+ removed: 0
881
+ };
882
+ Obj.update(canvas, (canvas) => {
883
+ result = applyCommands(canvas.content, commands);
884
+ });
885
+ return result;
886
+ }
887
+ };
888
+ //#endregion
889
+ //#region src/model/index.ts
890
+ var model_exports = /* @__PURE__ */ __exportAll({
891
+ DEFAULT_SCALE: () => 1,
892
+ DOCUMENT_ID: () => DOCUMENT_ID,
893
+ PAGE_ID: () => PAGE_ID,
894
+ TldrawBuilder: () => TldrawBuilder,
895
+ applyCommands: () => applyCommands,
896
+ elementBoxes: () => elementBoxes,
897
+ readScene: () => readScene,
898
+ renderObject: () => renderObject,
899
+ shapeId: () => shapeId,
900
+ tldrawBuilder: () => tldrawBuilder
901
+ });
902
+ //#endregion
903
+ export { DEFAULT_SCALE, DOCUMENT_ID, PAGE_ID, TldrawBuilder, applyCommands, elementBoxes, readScene, renderObject, shapeId, model_exports as t, tldrawBuilder };
904
+
905
+ //# sourceMappingURL=model.mjs.map