tldraw 5.2.0-next.e2b8d10bf10e → 5.2.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 (420) hide show
  1. package/DOCS.md +20294 -0
  2. package/README.md +13 -1
  3. package/RELEASE_NOTES.md +2908 -0
  4. package/dist-cjs/index.d.ts +110 -23
  5. package/dist-cjs/index.js +3 -3
  6. package/dist-cjs/index.js.map +2 -2
  7. package/dist-cjs/lib/TldrawImage.js +0 -1
  8. package/dist-cjs/lib/TldrawImage.js.map +2 -2
  9. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js +2 -1
  10. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
  11. package/dist-cjs/lib/defaultEmbedDefinitions.js +3 -2
  12. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  13. package/dist-cjs/lib/defaultOverlayUtils.js +11 -11
  14. package/dist-cjs/lib/defaultOverlayUtils.js.map +2 -2
  15. package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js +76 -64
  16. package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js.map +2 -2
  17. package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js +1 -1
  18. package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js.map +2 -2
  19. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +107 -0
  20. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
  21. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  22. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  23. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +12 -3
  24. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  25. package/dist-cjs/lib/shapes/bookmark/bookmarks.js +54 -6
  26. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  27. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +2 -1
  28. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
  30. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  31. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +45 -47
  32. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
  33. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +2 -1
  34. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  35. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js +23 -18
  36. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +2 -2
  37. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -1
  38. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -0
  40. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  41. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +11 -7
  42. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  43. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -11
  44. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  45. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +5 -1
  46. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  47. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +31 -41
  48. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  49. package/dist-cjs/lib/shapes/note/noteHelpers.js +1 -1
  50. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  51. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +28 -6
  52. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  53. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +3 -2
  54. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  55. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +3 -3
  56. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  57. package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js +17 -3
  58. package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js.map +2 -2
  59. package/dist-cjs/lib/shapes/shared/freehand/core.js +424 -0
  60. package/dist-cjs/lib/shapes/shared/freehand/core.js.map +7 -0
  61. package/dist-cjs/lib/shapes/shared/freehand/fmt.js +106 -0
  62. package/dist-cjs/lib/shapes/shared/freehand/fmt.js.map +7 -0
  63. package/dist-cjs/lib/shapes/shared/freehand/getStroke.js +6 -6
  64. package/dist-cjs/lib/shapes/shared/freehand/getStroke.js.map +2 -2
  65. package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js +320 -86
  66. package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js.map +3 -3
  67. package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js +20 -96
  68. package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js.map +3 -3
  69. package/dist-cjs/lib/shapes/shared/freehand/svg.js +55 -19
  70. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  71. package/dist-cjs/lib/shapes/shared/freehand/svgInk.js +189 -97
  72. package/dist-cjs/lib/shapes/shared/freehand/svgInk.js.map +3 -3
  73. package/dist-cjs/lib/shapes/shared/freehand/types.js.map +1 -1
  74. package/dist-cjs/lib/shapes/shared/interpolate-props.js +6 -2
  75. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  76. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +3 -0
  77. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  78. package/dist-cjs/lib/tools/HandTool/HandTool.js +16 -6
  79. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  80. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +10 -1
  81. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  82. package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +84 -0
  83. package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +7 -0
  84. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +12 -0
  85. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  86. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -0
  87. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  88. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +107 -46
  89. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  90. package/dist-cjs/lib/ui/TldrawUi.js +4 -3
  91. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  92. package/dist-cjs/lib/ui/components/A11y.js +2 -0
  93. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  94. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +14 -1
  95. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  96. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +0 -6
  97. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
  98. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +2 -2
  99. package/dist-cjs/lib/ui/components/Dialogs.js +17 -37
  100. package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
  101. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +19 -4
  102. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
  103. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +12 -2
  104. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  105. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +47 -70
  106. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  107. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +25 -46
  108. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  109. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.js.map +2 -2
  110. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuContent.js.map +2 -2
  111. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.js.map +2 -2
  112. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -1
  113. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
  114. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -0
  115. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
  116. package/dist-cjs/lib/ui/components/menu-items.js +7 -0
  117. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  118. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +2 -1
  119. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js.map +2 -2
  120. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +14 -3
  121. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
  122. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -0
  123. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  124. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -0
  125. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +2 -2
  126. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +0 -2
  127. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  128. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js +1 -2
  129. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js.map +2 -2
  130. package/dist-cjs/lib/ui/context/actions.js +70 -1
  131. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  132. package/dist-cjs/lib/ui/context/asset-urls.js +5 -8
  133. package/dist-cjs/lib/ui/context/asset-urls.js.map +2 -2
  134. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  135. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +13 -0
  136. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  137. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  138. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  139. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  140. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
  141. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  142. package/dist-cjs/lib/ui/version.js +3 -3
  143. package/dist-cjs/lib/ui/version.js.map +1 -1
  144. package/dist-cjs/lib/utils/embeds/embeds.js +4 -4
  145. package/dist-cjs/lib/utils/embeds/embeds.js.map +2 -2
  146. package/dist-cjs/lib/utils/test-helpers.js +2 -2
  147. package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
  148. package/dist-cjs/lib/utils/text/richText.js +3 -1
  149. package/dist-cjs/lib/utils/text/richText.js.map +2 -2
  150. package/dist-esm/index.d.mts +110 -23
  151. package/dist-esm/index.mjs +5 -3
  152. package/dist-esm/index.mjs.map +2 -2
  153. package/dist-esm/lib/TldrawImage.mjs +0 -1
  154. package/dist-esm/lib/TldrawImage.mjs.map +2 -2
  155. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs +2 -1
  156. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  157. package/dist-esm/lib/defaultEmbedDefinitions.mjs +3 -2
  158. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  159. package/dist-esm/lib/defaultOverlayUtils.mjs +11 -11
  160. package/dist-esm/lib/defaultOverlayUtils.mjs.map +2 -2
  161. package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs +77 -65
  162. package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs.map +2 -2
  163. package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs +1 -1
  164. package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs.map +2 -2
  165. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +87 -0
  166. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
  167. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +9 -1
  168. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  169. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +15 -3
  170. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  171. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +54 -6
  172. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  173. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -1
  174. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  175. package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
  176. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  177. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +46 -47
  178. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
  179. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +2 -1
  180. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  181. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs +23 -18
  182. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +2 -2
  183. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +2 -1
  184. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  185. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +4 -0
  186. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  187. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +12 -7
  188. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  189. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -11
  190. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  191. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +6 -1
  192. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  193. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +32 -42
  194. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  195. package/dist-esm/lib/shapes/note/noteHelpers.mjs +1 -1
  196. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  197. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +29 -6
  198. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  199. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +3 -2
  200. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  201. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -3
  202. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  203. package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs +17 -3
  204. package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs.map +2 -2
  205. package/dist-esm/lib/shapes/shared/freehand/core.mjs +404 -0
  206. package/dist-esm/lib/shapes/shared/freehand/core.mjs.map +7 -0
  207. package/dist-esm/lib/shapes/shared/freehand/fmt.mjs +86 -0
  208. package/dist-esm/lib/shapes/shared/freehand/fmt.mjs.map +7 -0
  209. package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs +7 -7
  210. package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs.map +2 -2
  211. package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs +332 -86
  212. package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs.map +3 -3
  213. package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs +31 -96
  214. package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs.map +3 -3
  215. package/dist-esm/lib/shapes/shared/freehand/svg.mjs +55 -19
  216. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  217. package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs +214 -99
  218. package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs.map +3 -3
  219. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +6 -2
  220. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  221. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +4 -0
  222. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  223. package/dist-esm/lib/tools/HandTool/HandTool.mjs +16 -6
  224. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  225. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +10 -1
  226. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  227. package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +64 -0
  228. package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +7 -0
  229. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +12 -0
  230. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  231. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -0
  232. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  233. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +108 -46
  234. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  235. package/dist-esm/lib/ui/TldrawUi.mjs +4 -3
  236. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  237. package/dist-esm/lib/ui/components/A11y.mjs +2 -0
  238. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  239. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +21 -2
  240. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  241. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +0 -6
  242. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
  243. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +2 -2
  244. package/dist-esm/lib/ui/components/Dialogs.mjs +19 -39
  245. package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
  246. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +20 -5
  247. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
  248. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +12 -2
  249. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  250. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +47 -70
  251. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  252. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +25 -46
  253. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  254. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.mjs.map +2 -2
  255. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuContent.mjs.map +2 -2
  256. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.mjs.map +2 -2
  257. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -1
  258. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
  259. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -0
  260. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
  261. package/dist-esm/lib/ui/components/menu-items.mjs +7 -0
  262. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  263. package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs +2 -1
  264. package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs.map +2 -2
  265. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +14 -3
  266. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
  267. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +2 -0
  268. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  269. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +2 -0
  270. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  271. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +0 -2
  272. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  273. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs +1 -2
  274. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs.map +2 -2
  275. package/dist-esm/lib/ui/context/actions.mjs +71 -1
  276. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  277. package/dist-esm/lib/ui/context/asset-urls.mjs +5 -8
  278. package/dist-esm/lib/ui/context/asset-urls.mjs.map +2 -2
  279. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  280. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +13 -0
  281. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  282. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  283. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  284. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
  285. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  286. package/dist-esm/lib/ui/version.mjs +3 -3
  287. package/dist-esm/lib/ui/version.mjs.map +1 -1
  288. package/dist-esm/lib/utils/embeds/embeds.mjs +4 -4
  289. package/dist-esm/lib/utils/embeds/embeds.mjs.map +2 -2
  290. package/dist-esm/lib/utils/test-helpers.mjs +2 -2
  291. package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
  292. package/dist-esm/lib/utils/text/richText.mjs +3 -1
  293. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  294. package/package.json +11 -6
  295. package/src/index.ts +6 -1
  296. package/src/lib/TldrawImage.tsx +2 -2
  297. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +5 -1
  298. package/src/lib/defaultEmbedDefinitions.ts +28 -6
  299. package/src/lib/defaultOverlayUtils.ts +11 -11
  300. package/src/lib/overlays/SelectionForegroundOverlayUtil.ts +91 -72
  301. package/src/lib/overlays/ShapeHandleOverlayUtil.ts +3 -1
  302. package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +133 -0
  303. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +11 -1
  304. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +16 -3
  305. package/src/lib/shapes/bookmark/bookmarks.ts +105 -15
  306. package/src/lib/shapes/draw/DrawShapeUtil.tsx +7 -5
  307. package/src/lib/shapes/draw/getPath.ts +1 -1
  308. package/src/lib/shapes/draw/toolStates/Drawing.ts +55 -48
  309. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +14 -4
  310. package/src/lib/shapes/frame/FrameShapeTool.ts +35 -24
  311. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +46 -0
  312. package/src/lib/shapes/geo/GeoShapeUtil.tsx +2 -1
  313. package/src/lib/shapes/geo/toolStates/Pointing.ts +5 -0
  314. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +14 -11
  315. package/src/lib/shapes/image/ImageShapeUtil.tsx +7 -11
  316. package/src/lib/shapes/line/LineShapeTool.test.ts +41 -0
  317. package/src/lib/shapes/line/toolStates/Pointing.ts +12 -2
  318. package/src/lib/shapes/note/NoteShapeUtil.tsx +36 -51
  319. package/src/lib/shapes/note/noteCloning.test.ts +5 -5
  320. package/src/lib/shapes/note/noteHelpers.ts +1 -1
  321. package/src/lib/shapes/note/toolStates/Pointing.ts +40 -7
  322. package/src/lib/shapes/shared/PlainTextLabel.tsx +3 -3
  323. package/src/lib/shapes/shared/RichTextLabel.tsx +4 -3
  324. package/src/lib/shapes/shared/defaultStyleDefs.tsx +25 -3
  325. package/src/lib/shapes/shared/freehand/core.ts +547 -0
  326. package/src/lib/shapes/shared/freehand/fmt.ts +106 -0
  327. package/src/lib/shapes/shared/freehand/getStroke.ts +7 -7
  328. package/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts +451 -139
  329. package/src/lib/shapes/shared/freehand/getStrokePoints.ts +33 -153
  330. package/src/lib/shapes/shared/freehand/svg.ts +72 -23
  331. package/src/lib/shapes/shared/freehand/svgInk.ts +281 -136
  332. package/src/lib/shapes/shared/freehand/types.ts +0 -1
  333. package/src/lib/shapes/shared/interpolate-props.ts +6 -2
  334. package/src/lib/shapes/text/toolStates/Pointing.ts +5 -0
  335. package/src/lib/tools/HandTool/HandTool.ts +19 -6
  336. package/src/lib/tools/HandTool/childStates/Dragging.ts +17 -1
  337. package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +79 -0
  338. package/src/lib/tools/SelectTool/childStates/Idle.ts +16 -2
  339. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +8 -0
  340. package/src/lib/tools/SelectTool/childStates/Resizing.ts +137 -49
  341. package/src/lib/ui/TldrawUi.tsx +3 -3
  342. package/src/lib/ui/components/A11y.tsx +2 -0
  343. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +32 -2
  344. package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -6
  345. package/src/lib/ui/components/DefaultFollowingIndicator.tsx +2 -2
  346. package/src/lib/ui/components/Dialogs.tsx +20 -23
  347. package/src/lib/ui/components/HelperButtons/BackToContent.tsx +32 -4
  348. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +10 -0
  349. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +60 -74
  350. package/src/lib/ui/components/Minimap/MinimapManager.ts +35 -57
  351. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx +2 -2
  352. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx +2 -1
  353. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx +2 -1
  354. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +3 -3
  355. package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +5 -0
  356. package/src/lib/ui/components/menu-items.tsx +9 -0
  357. package/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx +3 -1
  358. package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +15 -3
  359. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +4 -0
  360. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +7 -0
  361. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +0 -2
  362. package/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx +0 -1
  363. package/src/lib/ui/context/actions.tsx +88 -1
  364. package/src/lib/ui/context/asset-urls.tsx +9 -8
  365. package/src/lib/ui/context/events.tsx +2 -0
  366. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +45 -7
  367. package/src/lib/ui/hooks/useTools.tsx +7 -1
  368. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  369. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
  370. package/src/lib/ui/version.ts +3 -3
  371. package/src/lib/ui.css +20 -9
  372. package/src/lib/utils/embeds/embeds.test.ts +14 -12
  373. package/src/lib/utils/embeds/embeds.ts +10 -4
  374. package/src/lib/utils/test-helpers.ts +3 -3
  375. package/src/lib/utils/text/richText.test.ts +36 -0
  376. package/src/lib/utils/text/richText.ts +9 -1
  377. package/src/test/HandTool.test.ts +93 -0
  378. package/src/test/ImageShapeUtil.test.ts +88 -0
  379. package/src/test/SelectTool.test.ts +102 -1
  380. package/src/test/__snapshots__/drawing.test.ts.snap +2 -1
  381. package/src/test/attribution.test.ts +40 -29
  382. package/src/test/bookmark-shapes.test.ts +256 -28
  383. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
  384. package/src/test/commands/clipboardCallbacks.test.ts +3 -1
  385. package/src/test/commands/getSvgString.test.ts +30 -0
  386. package/src/test/commands/penmode.test.ts +97 -1
  387. package/src/test/commands/setCamera.test.ts +12 -0
  388. package/src/test/dragFromToolbar.test.ts +67 -0
  389. package/src/test/drawing.test.ts +48 -7
  390. package/src/test/frames.test.ts +72 -0
  391. package/src/test/freehand/corpus/presets.ts +71 -0
  392. package/src/test/freehand/corpus/real.ts +370 -0
  393. package/src/test/freehand/corpus/strokes.ts +50 -0
  394. package/src/test/freehand/svg.test.ts +20 -0
  395. package/src/test/freehand/wellformed.test.ts +30 -0
  396. package/src/test/long-press-create.test.ts +102 -0
  397. package/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts +4 -4
  398. package/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts +18 -18
  399. package/src/test/overlays/CollaboratorHintOverlayUtil.test.ts +7 -7
  400. package/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts +3 -3
  401. package/src/test/overlays/OverlayManager.test.ts +1 -1
  402. package/src/test/overlays/SelectionForegroundOverlayUtil.test.ts +58 -0
  403. package/src/test/overlays/ShapeHandleOverlayUtil.test.ts +2 -2
  404. package/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts +36 -0
  405. package/src/test/resizing.test.ts +250 -0
  406. package/src/test/right-click-context-menu.test.ts +90 -0
  407. package/src/test/rightClickPanning.test.ts +11 -0
  408. package/src/test/selection-omnibus.test.ts +15 -2
  409. package/src/test/spatialIndex.test.ts +132 -0
  410. package/src/test/translating.test.ts +0 -6
  411. package/src/test/ui/ContextMenu.test.tsx +146 -3
  412. package/src/test/ui/Dialogs.test.tsx +256 -0
  413. package/src/test/ui/copyHoveredStyles.test.tsx +154 -0
  414. package/src/test/ui/keyboardShortcuts.test.tsx +266 -0
  415. package/tldraw.css +35 -12
  416. package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js +0 -100
  417. package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js.map +0 -7
  418. package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs +0 -80
  419. package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs.map +0 -7
  420. package/src/lib/shapes/shared/freehand/setStrokePointRadii.ts +0 -127
@@ -33,6 +33,10 @@ class Drawing extends import_editor.StateNode {
33
33
  util = this.editor.getShapeUtil(this.shapeType);
34
34
  isPen = false;
35
35
  isPenOrStylus = false;
36
+ // Encoding dimension for segments created during this stroke. `2` drops the
37
+ // constant pressure value (non-pressure devices), `undefined` keeps full 3D.
38
+ // Decided once in startShape from the input device — see the note there.
39
+ segmentDim = void 0;
36
40
  segmentMode = "free";
37
41
  didJustShiftClickToExtendPreviousShapeLine = false;
38
42
  pagePointWhereCurrentSegmentChanged = {};
@@ -120,9 +124,9 @@ class Drawing extends import_editor.StateNode {
120
124
  const theme = this.editor.getCurrentTheme();
121
125
  strokeWidth = theme.strokeWidth * import_default_shape_constants.STROKE_SIZES[size];
122
126
  }
123
- const firstPoint = import_editor.b64Vecs.decodeFirstPoint(segments[0].path);
127
+ const firstPoint = import_editor.b64Vecs.decodeFirstPoint(segments[0].path, segments[0].dim);
124
128
  const lastSegment = segments[segments.length - 1];
125
- const lastPoint = import_editor.b64Vecs.decodeLastPoint(lastSegment.path);
129
+ const lastPoint = import_editor.b64Vecs.decodeLastPoint(lastSegment.path, lastSegment.dim);
126
130
  const isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode();
127
131
  const threshold = isDynamicResizingEnabled ? (strokeWidth + 2) * scale : (
128
132
  // 6 is a base floor, 2 is stroke influence, 0.8 tempers width growth
@@ -131,6 +135,15 @@ class Drawing extends import_editor.StateNode {
131
135
  );
132
136
  return firstPoint !== null && lastPoint !== null && firstPoint !== lastPoint && this.currentLineLength > strokeWidth * 4 * scale && import_editor.Vec.DistMin(firstPoint, lastPoint, threshold);
133
137
  }
138
+ /**
139
+ * Build a segment from points, encoding `path` at this stroke's `segmentDim` and
140
+ * attaching `dim: 2` only when z was dropped. 3D segments omit `dim` so they
141
+ * serialize byte-identically to pre-#8879 data.
142
+ */
143
+ makeSegment(type, points) {
144
+ const path = import_editor.b64Vecs.encodePoints(points, this.segmentDim);
145
+ return this.segmentDim === import_editor.DIM_2D ? { type, path, dim: import_editor.DIM_2D } : { type, path };
146
+ }
134
147
  startShape() {
135
148
  const inputs = this.editor.inputs;
136
149
  const originPagePoint = inputs.getOriginPagePoint();
@@ -139,6 +152,7 @@ class Drawing extends import_editor.StateNode {
139
152
  const { z = 0.5 } = this.info.point;
140
153
  this.isPen = isPen;
141
154
  this.isPenOrStylus = isPen && z !== 0 || z > 0 && z < 0.5 || z > 0.5 && z < 1;
155
+ this.segmentDim = this.isPenOrStylus ? void 0 : import_editor.DIM_2D;
142
156
  const pressure = this.isPenOrStylus ? z * 1.25 : 0.5;
143
157
  this.segmentMode = this.editor.inputs.getShiftKey() ? "straight" : "free";
144
158
  this.didJustShiftClickToExtendPreviousShapeLine = false;
@@ -149,16 +163,13 @@ class Drawing extends import_editor.StateNode {
149
163
  this.didJustShiftClickToExtendPreviousShapeLine = true;
150
164
  const prevSegment = (0, import_editor.last)(shape2.props.segments);
151
165
  if (!prevSegment) throw Error("Expected a previous segment!");
152
- const prevPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path);
166
+ const prevPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim);
153
167
  if (!prevPoint) throw Error("Expected a previous point!");
154
168
  const { x, y } = this.editor.getPointInShapeSpace(shape2, originPagePoint).toFixed();
155
- const newSegment = {
156
- type: this.segmentMode,
157
- path: import_editor.b64Vecs.encodePoints([
158
- { x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },
159
- { x, y, z: +pressure.toFixed(2) }
160
- ])
161
- };
169
+ const newSegment = this.makeSegment(this.segmentMode, [
170
+ { x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },
171
+ { x, y, z: +pressure.toFixed(2) }
172
+ ]);
162
173
  const prevPointPageSpace = import_editor.Mat.applyToPoint(
163
174
  this.editor.getShapePageTransform(shape2.id),
164
175
  prevPoint
@@ -201,12 +212,7 @@ class Drawing extends import_editor.StateNode {
201
212
  props: {
202
213
  isPen: this.isPenOrStylus,
203
214
  scale: this.editor.getResizeScaleFactor(),
204
- segments: [
205
- {
206
- type: this.segmentMode,
207
- path: import_editor.b64Vecs.encodePoints([initialPoint])
208
- }
209
- ]
215
+ segments: [this.makeSegment(this.segmentMode, [initialPoint])]
210
216
  }
211
217
  });
212
218
  const shape = this.editor.getShape(id);
@@ -245,23 +251,17 @@ class Drawing extends import_editor.StateNode {
245
251
  this.segmentMode = "straight";
246
252
  const prevSegment = (0, import_editor.last)(segments);
247
253
  if (!prevSegment) throw Error("Expected a previous segment!");
248
- const prevLastPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path);
254
+ const prevLastPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim);
249
255
  if (!prevLastPoint) throw Error("Expected a previous last point!");
250
256
  let newSegment;
251
257
  const newLastPoint = this.editor.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged).toFixed().toJson();
252
258
  if (prevSegment.type === "straight") {
253
259
  this.currentLineLength += import_editor.Vec.Dist(prevLastPoint, newLastPoint);
254
- newSegment = {
255
- type: "straight",
256
- path: import_editor.b64Vecs.encodePoints([prevLastPoint, newLastPoint])
257
- };
260
+ newSegment = this.makeSegment("straight", [prevLastPoint, newLastPoint]);
258
261
  const transform = this.editor.getShapePageTransform(shape);
259
262
  this.pagePointWhereCurrentSegmentChanged = import_editor.Mat.applyToPoint(transform, prevLastPoint);
260
263
  } else {
261
- newSegment = {
262
- type: "straight",
263
- path: import_editor.b64Vecs.encodePoints([newLastPoint, newPoint])
264
- };
264
+ newSegment = this.makeSegment("straight", [newLastPoint, newPoint]);
265
265
  }
266
266
  const shapePartial = {
267
267
  id,
@@ -294,7 +294,10 @@ class Drawing extends import_editor.StateNode {
294
294
  this.segmentMode = "free";
295
295
  const newSegments = segments.slice();
296
296
  const prevStraightSegment = newSegments[newSegments.length - 1];
297
- const prevPoint = import_editor.b64Vecs.decodeLastPoint(prevStraightSegment.path);
297
+ const prevPoint = import_editor.b64Vecs.decodeLastPoint(
298
+ prevStraightSegment.path,
299
+ prevStraightSegment.dim
300
+ );
298
301
  if (!prevPoint) {
299
302
  throw Error("No previous point!");
300
303
  }
@@ -302,10 +305,7 @@ class Drawing extends import_editor.StateNode {
302
305
  (p) => new import_editor.Vec((0, import_editor.toFixed)(p.x), (0, import_editor.toFixed)(p.y), (0, import_editor.toFixed)(p.z))
303
306
  );
304
307
  this.currentSegmentPoints = interpolatedPoints;
305
- const newFreeSegment = {
306
- type: "free",
307
- path: import_editor.b64Vecs.encodePoints(interpolatedPoints)
308
- };
308
+ const newFreeSegment = this.makeSegment("free", interpolatedPoints);
309
309
  const finalSegments = [...newSegments, newFreeSegment];
310
310
  const dvStrokeWidth = (0, import_getDisplayValues.getDisplayValues)(this.util, shape).strokeWidth;
311
311
  if (this.currentLineLength < dvStrokeWidth * 4) {
@@ -362,8 +362,8 @@ class Drawing extends import_editor.StateNode {
362
362
  const segment = segments[i];
363
363
  if (!segment) break;
364
364
  if (segment.type === "free") continue;
365
- const first = import_editor.b64Vecs.decodeFirstPoint(segment.path);
366
- const lastPoint = import_editor.b64Vecs.decodeLastPoint(segment.path);
365
+ const first = import_editor.b64Vecs.decodeFirstPoint(segment.path, segment.dim);
366
+ const lastPoint = import_editor.b64Vecs.decodeLastPoint(segment.path, segment.dim);
367
367
  if (!(first && lastPoint)) continue;
368
368
  const nearestPointOnSegment = import_editor.Vec.NearestPointOnLineSegment(
369
369
  first,
@@ -385,8 +385,8 @@ class Drawing extends import_editor.StateNode {
385
385
  }
386
386
  if (didSnap && snapSegment) {
387
387
  const transform = this.editor.getShapePageTransform(shape);
388
- const first = import_editor.b64Vecs.decodeFirstPoint(snapSegment.path);
389
- const lastPoint = import_editor.b64Vecs.decodeLastPoint(snapSegment.path);
388
+ const first = import_editor.b64Vecs.decodeFirstPoint(snapSegment.path, snapSegment.dim);
389
+ const lastPoint = import_editor.b64Vecs.decodeLastPoint(snapSegment.path, snapSegment.dim);
390
390
  if (!first || !lastPoint) throw Error("Expected a last point!");
391
391
  const A = import_editor.Mat.applyToPoint(transform, first);
392
392
  const B = import_editor.Mat.applyToPoint(transform, lastPoint);
@@ -414,14 +414,17 @@ class Drawing extends import_editor.StateNode {
414
414
  }
415
415
  newPoint2 = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson();
416
416
  }
417
- this.currentLineLength += newSegments.length && import_editor.b64Vecs.decodeFirstPoint(newSegment.path) ? import_editor.Vec.Dist(import_editor.b64Vecs.decodeFirstPoint(newSegment.path), import_editor.Vec.From(newPoint2)) : 0;
417
+ this.currentLineLength += newSegments.length && import_editor.b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim) ? import_editor.Vec.Dist(
418
+ import_editor.b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim),
419
+ import_editor.Vec.From(newPoint2)
420
+ ) : 0;
418
421
  newSegments[newSegments.length - 1] = {
419
422
  ...newSegment,
420
423
  type: "straight",
421
- path: import_editor.b64Vecs.encodePoints([
422
- import_editor.b64Vecs.decodeFirstPoint(newSegment.path),
423
- import_editor.Vec.From(newPoint2)
424
- ])
424
+ path: import_editor.b64Vecs.encodePoints(
425
+ [import_editor.b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim), import_editor.Vec.From(newPoint2)],
426
+ newSegment.dim
427
+ )
425
428
  };
426
429
  const shapePartial = {
427
430
  id,
@@ -456,7 +459,7 @@ class Drawing extends import_editor.StateNode {
456
459
  const newSegment = newSegments[newSegments.length - 1];
457
460
  newSegments[newSegments.length - 1] = {
458
461
  ...newSegment,
459
- path: import_editor.b64Vecs.encodePoints(cachedPoints)
462
+ path: import_editor.b64Vecs.encodePoints(cachedPoints, newSegment.dim)
460
463
  };
461
464
  const dvStrokeWidth = (0, import_getDisplayValues.getDisplayValues)(this.util, shape).strokeWidth;
462
465
  if (this.currentLineLength < dvStrokeWidth * 4) {
@@ -494,12 +497,7 @@ class Drawing extends import_editor.StateNode {
494
497
  props: {
495
498
  isPen: this.isPenOrStylus,
496
499
  scale: props.scale,
497
- segments: [
498
- {
499
- type: "free",
500
- path: import_editor.b64Vecs.encodePoints([initialPoint])
501
- }
502
- ]
500
+ segments: [this.makeSegment("free", [initialPoint])]
503
501
  }
504
502
  });
505
503
  const shape2 = this.editor.getShape(newShapeId);
@@ -518,7 +516,7 @@ class Drawing extends import_editor.StateNode {
518
516
  getLineLength(segments) {
519
517
  let length = 0;
520
518
  for (let j = 0; j < segments.length; j++) {
521
- const points = import_editor.b64Vecs.decodePoints(segments[j].path);
519
+ const points = import_editor.b64Vecs.decodePoints(segments[j].path, segments[j].dim);
522
520
  for (let i = 0; i < points.length - 1; i++) {
523
521
  length += import_editor.Vec.Dist2(points[i], points[i + 1]);
524
522
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/shapes/draw/toolStates/Drawing.ts"],
4
- "sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLDefaultSizeStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShapePartial,\n\tVec,\n\tVecModel,\n\tb64Vecs,\n\tcreateShapeId,\n\tlast,\n\tsnapAngle,\n\tstructuredClone,\n\ttoFixed,\n\tuniqueId,\n} from '@tldraw/editor'\nimport { HighlightShapeUtil } from '../../highlight/HighlightShapeUtil'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { getDisplayValues } from '../../shared/getDisplayValues'\nimport { DrawShapeUtil } from '../DrawShapeUtil'\n\ntype DrawableShape = TLDrawShape | TLHighlightShape\n\nexport class Drawing extends StateNode {\n\tstatic override id = 'drawing'\n\tstatic override trackPerformance = true\n\n\tinfo = {} as TLPointerEventInfo\n\n\tinitialShape?: DrawableShape\n\n\toverride shapeType = this.parent.id === 'highlight' ? ('highlight' as const) : ('draw' as const)\n\n\tutil = this.editor.getShapeUtil(this.shapeType) as DrawShapeUtil | HighlightShapeUtil\n\n\tisPen = false\n\tisPenOrStylus = false\n\n\tsegmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'\n\n\tdidJustShiftClickToExtendPreviousShapeLine = false\n\n\tpagePointWhereCurrentSegmentChanged = {} as Vec\n\n\tpagePointWhereNextSegmentChanged = null as Vec | null\n\n\tlastRecordedPoint = {} as Vec\n\tmergeNextPoint = false\n\tcurrentLineLength = 0\n\tzoomOnEnter = 1\n\n\t// Cache for current segment's points to avoid repeated b64 decode/encode\n\tcurrentSegmentPoints: Vec[] = []\n\n\tmarkId = null as null | string\n\n\toverride onEnter(info: TLPointerEventInfo) {\n\t\tthis.markId = null\n\t\tthis.info = info\n\t\tthis.lastRecordedPoint = this.editor.inputs.getCurrentPagePoint().clone()\n\t\tthis.zoomOnEnter = this.editor.getZoomLevel()\n\t\tthis.startShape()\n\t}\n\n\toverride onPointerMove() {\n\t\tconst { inputs } = this.editor\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tif (this.isPen && !isPen) {\n\t\t\t// The user made a palm gesture before starting a pen gesture;\n\t\t\t// ideally we'd start the new shape here but we could also just bail\n\t\t\t// as the next interaction will work correctly\n\t\t\tif (this.markId) {\n\t\t\t\tthis.editor.bailToMark(this.markId)\n\t\t\t\tthis.startShape()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isPenOrStylus) {\n\t\t\t// Don't update the shape if we haven't moved far enough from the last time we recorded a point\n\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\t\tif (Vec.Dist(currentPagePoint, this.lastRecordedPoint) >= 1 / this.zoomOnEnter) {\n\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\tthis.mergeNextPoint = false\n\t\t\t} else {\n\t\t\t\tthis.mergeNextPoint = true\n\t\t\t}\n\t\t} else {\n\t\t\tthis.mergeNextPoint = false\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'free': {\n\t\t\t\t\t// We've just entered straight mode, go to straight mode\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_free': {\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'straight': {\n\t\t\t\t\t// We've just exited straight mode, go back to free mode\n\t\t\t\t\tthis.segmentMode = 'starting_free'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_straight': {\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\t\tthis.segmentMode = 'free'\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.pagePointWhereCurrentSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t}\n\n\tcanClose() {\n\t\treturn this.shapeType !== 'highlight'\n\t}\n\n\tgetIsClosed(\n\t\tsegments: TLDrawShapeSegment[],\n\t\tsize: TLDefaultSizeStyle,\n\t\tscale: number,\n\t\tstrokeWidth?: number\n\t) {\n\t\tif (!this.canClose()) return false\n\n\t\tif (strokeWidth === undefined) {\n\t\t\tconst theme = this.editor.getCurrentTheme()\n\t\t\tstrokeWidth = theme.strokeWidth * STROKE_SIZES[size]\n\t\t}\n\t\tconst firstPoint = b64Vecs.decodeFirstPoint(segments[0].path)\n\t\tconst lastSegment = segments[segments.length - 1]\n\t\tconst lastPoint = b64Vecs.decodeLastPoint(lastSegment.path)\n\n\t\tconst isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode()\n\n\t\tconst threshold = isDynamicResizingEnabled // when dynamic resizing is enabled scale is 1/zoom, so the threshold should not scale directly with zoom at all\n\t\t\t? (strokeWidth + 2) * scale // +2 keeps tiny strokes from being too hard to close\n\t\t\t: // 6 is a base floor, 2 is stroke influence, 0.8 tempers width growth\n\t\t\t\t6 +\n\t\t\t\t2 * Math.sqrt(strokeWidth * 0.8) +\n\t\t\t\t// 100 is low-zoom boost, 0.18 is the zoom knee, 3 controls falloff steepness\n\t\t\t\t100 / (1 + Math.pow(this.zoomOnEnter / 0.18, 3))\n\n\t\treturn (\n\t\t\tfirstPoint !== null &&\n\t\t\tlastPoint !== null &&\n\t\t\tfirstPoint !== lastPoint &&\n\t\t\tthis.currentLineLength > strokeWidth * 4 * scale &&\n\t\t\tVec.DistMin(firstPoint, lastPoint, threshold)\n\t\t)\n\t}\n\n\tprivate startShape() {\n\t\tconst inputs = this.editor.inputs\n\t\tconst originPagePoint = inputs.getOriginPagePoint()\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('draw start')\n\n\t\t// If the pressure is weird, then it's probably a stylus reporting as a mouse\n\t\t// We treat pen/stylus inputs differently in the drawing tool, so we need to\n\t\t// have our own value for this. The inputs.isPen is only if the input is a regular\n\t\t// pen, like an iPad pen, which needs to trigger \"pen mode\" in order to avoid\n\t\t// accidental palm touches. We don't have to worry about that with styluses though.\n\t\tconst { z = 0.5 } = this.info.point\n\n\t\tthis.isPen = isPen\n\t\t// if z === 0 on the initial point, treat this pen as a mouse because it's likely a broken pen\n\t\t// or a broken OS.\n\t\tthis.isPenOrStylus = (isPen && z !== 0) || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)\n\n\t\tconst pressure = this.isPenOrStylus ? z * 1.25 : 0.5\n\n\t\tthis.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'\n\n\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\n\t\tthis.lastRecordedPoint = originPagePoint.clone()\n\n\t\tif (this.initialShape) {\n\t\t\tconst shape = this.editor.getShape<DrawableShape>(this.initialShape.id)\n\n\t\t\tif (shape && this.segmentMode === 'straight') {\n\t\t\t\t// Connect dots\n\n\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = true\n\n\t\t\t\tconst prevSegment = last(shape.props.segments)\n\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevSegment.path)\n\t\t\t\tif (!prevPoint) throw Error('Expected a previous point!')\n\n\t\t\t\tconst { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()\n\n\t\t\t\tconst newSegment: TLDrawShapeSegment = {\n\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\tpath: b64Vecs.encodePoints([\n\t\t\t\t\t\t{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },\n\t\t\t\t\t\t{ x, y, z: +pressure.toFixed(2) },\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\t// Convert prevPoint to page space\n\t\t\t\tconst prevPointPageSpace = Mat.applyToPoint(\n\t\t\t\t\tthis.editor.getShapePageTransform(shape.id)!,\n\t\t\t\t\tprevPoint\n\t\t\t\t)\n\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = prevPointPageSpace\n\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\tconst segments = [...shape.props.segments, newSegment]\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(segments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tshape.props.size,\n\t\t\t\t\t\tshape.props.scale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Create a new shape\n\n\t\tthis.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()\n\t\tconst id = createShapeId()\n\n\t\t// Initialize the segment points cache\n\t\tconst initialPoint = new Vec(0, 0, +pressure.toFixed(2))\n\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShape({\n\t\t\tid,\n\t\t\ttype: this.shapeType,\n\t\t\tx: originPagePoint.x,\n\t\t\ty: originPagePoint.y,\n\t\t\tprops: {\n\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\tscale: this.editor.getResizeScaleFactor(),\n\t\t\t\tsegments: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\t\tpath: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t})\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\t\tthis.currentLineLength = 0\n\t\tthis.initialShape = this.editor.getShape<DrawableShape>(id)\n\t}\n\n\tprivate updateDrawingShape() {\n\t\tconst { initialShape } = this\n\t\tconst { inputs } = this.editor\n\n\t\tif (!initialShape) return\n\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { size, scale },\n\t\t} = initialShape\n\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)!\n\n\t\tif (!shape) return\n\n\t\tconst { segments } = shape.props\n\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\tconst { x, y, z } = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed()\n\t\tconst pressure = this.isPenOrStylus ? +(currentPagePoint.z! * 1.25).toFixed(2) : 0.5\n\t\tconst newPoint = { x, y, z: pressure }\n\n\t\tswitch (this.segmentMode) {\n\t\t\tcase 'starting_straight': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'straight'\n\n\t\t\t\t\tconst prevSegment = last(segments)\n\t\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\n\t\t\t\t\tconst prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path)\n\t\t\t\t\tif (!prevLastPoint) throw Error('Expected a previous last point!')\n\n\t\t\t\t\tlet newSegment: TLDrawShapeSegment\n\n\t\t\t\t\tconst newLastPoint = this.editor\n\t\t\t\t\t\t.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\t\t.toFixed()\n\t\t\t\t\t\t.toJson()\n\n\t\t\t\t\tif (prevSegment.type === 'straight') {\n\t\t\t\t\t\tthis.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)\n\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([prevLastPoint, newLastPoint]),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\n\t\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([newLastPoint, newPoint]),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: [...segments, newSegment],\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tsegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'starting_free': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'free'\n\n\t\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\t\tconst prevStraightSegment = newSegments[newSegments.length - 1]\n\t\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevStraightSegment.path)\n\n\t\t\t\t\tif (!prevPoint) {\n\t\t\t\t\t\tthrow Error('No previous point!')\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create the new free segment and interpolate the points between where the last line\n\t\t\t\t\t// ended and where the pointer is now\n\t\t\t\t\tconst interpolatedPoints = Vec.PointsBetween(prevPoint, newPoint, 6).map(\n\t\t\t\t\t\t(p) => new Vec(toFixed(p.x), toFixed(p.y), toFixed(p.z))\n\t\t\t\t\t)\n\t\t\t\t\t// Initialize cache for the new free segment\n\t\t\t\t\tthis.currentSegmentPoints = interpolatedPoints\n\n\t\t\t\t\tconst newFreeSegment: TLDrawShapeSegment = {\n\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\tpath: b64Vecs.encodePoints(interpolatedPoints),\n\t\t\t\t\t}\n\n\t\t\t\t\tconst finalSegments = [...newSegments, newFreeSegment]\n\n\t\t\t\t\tconst dvStrokeWidth = (\n\t\t\t\t\t\tgetDisplayValues(this.util as any, shape) as { strokeWidth: number }\n\t\t\t\t\t).strokeWidth\n\t\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\t\tthis.currentLineLength = this.getLineLength(finalSegments)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: finalSegments,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tfinalSegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'straight': {\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\n\t\t\t\tconst { pagePointWhereCurrentSegmentChanged } = this\n\t\t\t\tconst inputs = this.editor.inputs\n\t\t\t\tconst ctrlKey = inputs.getCtrlKey()\n\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\tif (!pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\n\t\t\t\tlet pagePoint: VecModel\n\t\t\t\tlet shouldSnapToAngle = false\n\n\t\t\t\tif (this.didJustShiftClickToExtendPreviousShapeLine) {\n\t\t\t\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\t\t\t\t// If we've just shift clicked to extend a line, only snap once we've started dragging\n\t\t\t\t\t\tshouldSnapToAngle = !ctrlKey\n\t\t\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If we're not shift clicking to extend a line, but we're holding shift, then we should snap\n\t\t\t\t\tshouldSnapToAngle = !ctrlKey // don't snap angle while snapping line\n\t\t\t\t}\n\n\t\t\t\tlet newPoint = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson()\n\t\t\t\tlet didSnap = false\n\t\t\t\tlet snapSegment: TLDrawShapeSegment | undefined = undefined\n\n\t\t\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !ctrlKey : ctrlKey\n\n\t\t\t\tif (shouldSnap) {\n\t\t\t\t\tif (newSegments.length > 2) {\n\t\t\t\t\t\tlet nearestPoint: VecModel | undefined = undefined\n\t\t\t\t\t\tlet minDistance = 8 / this.zoomOnEnter\n\n\t\t\t\t\t\t// Don't try to snap to the last two segments\n\t\t\t\t\t\tfor (let i = 0, n = segments.length - 2; i < n; i++) {\n\t\t\t\t\t\t\tconst segment = segments[i]\n\t\t\t\t\t\t\tif (!segment) break\n\t\t\t\t\t\t\tif (segment.type === 'free') continue\n\n\t\t\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(segment.path)\n\t\t\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(segment.path)\n\t\t\t\t\t\t\tif (!(first && lastPoint)) continue\n\n\t\t\t\t\t\t\t// Snap to the nearest point on the segment, if it's closer than the previous snapped point\n\t\t\t\t\t\t\tconst nearestPointOnSegment = Vec.NearestPointOnLineSegment(\n\t\t\t\t\t\t\t\tfirst,\n\t\t\t\t\t\t\t\tlastPoint,\n\t\t\t\t\t\t\t\tnewPoint\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\tif (Vec.DistMin(nearestPointOnSegment, newPoint, minDistance)) {\n\t\t\t\t\t\t\t\tnearestPoint = nearestPointOnSegment.toFixed().toJson()\n\t\t\t\t\t\t\t\tminDistance = Vec.Dist(nearestPointOnSegment, newPoint)\n\t\t\t\t\t\t\t\tsnapSegment = segment\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (nearestPoint) {\n\t\t\t\t\t\t\tdidSnap = true\n\t\t\t\t\t\t\tnewPoint = nearestPoint\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (didSnap && snapSegment) {\n\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(snapSegment.path)\n\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(snapSegment.path)\n\t\t\t\t\tif (!first || !lastPoint) throw Error('Expected a last point!')\n\n\t\t\t\t\tconst A = Mat.applyToPoint(transform, first)\n\n\t\t\t\t\tconst B = Mat.applyToPoint(transform, lastPoint)\n\n\t\t\t\t\tconst snappedPoint = Mat.applyToPoint(transform, newPoint)\n\n\t\t\t\t\tthis.editor.snaps.setIndicators([\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttype: 'points',\n\t\t\t\t\t\t\tpoints: [A, snappedPoint, B],\n\t\t\t\t\t\t},\n\t\t\t\t\t])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\t\t\tif (shouldSnapToAngle) {\n\t\t\t\t\t\t// Snap line angle to nearest 15 degrees\n\t\t\t\t\t\tconst currentAngle = Vec.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint)\n\t\t\t\t\t\tconst snappedAngle = snapAngle(currentAngle, 24)\n\t\t\t\t\t\tconst angleDiff = snappedAngle - currentAngle\n\n\t\t\t\t\t\tpagePoint = Vec.RotWith(\n\t\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\t\tpagePointWhereCurrentSegmentChanged,\n\t\t\t\t\t\t\tangleDiff\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpagePoint = currentPagePoint.clone()\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPoint = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson()\n\t\t\t\t}\n\n\t\t\t\t// If the previous segment is a one point free shape and is the first segment of the line,\n\t\t\t\t// then the user just did a click-and-immediately-press-shift to create a new straight line\n\t\t\t\t// without continuing the previous line. In this case, we want to remove the previous segment.\n\n\t\t\t\tthis.currentLineLength +=\n\t\t\t\t\tnewSegments.length && b64Vecs.decodeFirstPoint(newSegment.path)\n\t\t\t\t\t\t? Vec.Dist(b64Vecs.decodeFirstPoint(newSegment.path)!, Vec.From(newPoint))\n\t\t\t\t\t\t: 0\n\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\ttype: 'straight',\n\t\t\t\t\tpath: b64Vecs.encodePoints([\n\t\t\t\t\t\tb64Vecs.decodeFirstPoint(newSegment.path)!,\n\t\t\t\t\t\tVec.From(newPoint),\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'free': {\n\t\t\t\t// Use cached points instead of decoding from b64 on every update\n\t\t\t\tconst cachedPoints = this.currentSegmentPoints\n\n\t\t\t\tif (cachedPoints.length && this.mergeNextPoint) {\n\t\t\t\t\tconst lastPoint = cachedPoints[cachedPoints.length - 1]\n\t\t\t\t\tlastPoint.x = newPoint.x\n\t\t\t\t\tlastPoint.y = newPoint.y\n\t\t\t\t\tlastPoint.z = lastPoint.z ? Math.max(lastPoint.z, newPoint.z) : newPoint.z\n\t\t\t\t\t// Note: we could recompute the line length here, but it's not really necessary\n\t\t\t\t\t// this.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentLineLength += cachedPoints.length\n\t\t\t\t\t\t? Vec.Dist(cachedPoints[cachedPoints.length - 1], newPoint)\n\t\t\t\t\t\t: 0\n\t\t\t\t\tcachedPoints.push(new Vec(newPoint.x, newPoint.y, newPoint.z))\n\t\t\t\t}\n\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\tpath: b64Vecs.encodePoints(cachedPoints),\n\t\t\t\t}\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tnewSegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\t// Set a maximum length for the lines array; after 200 points, complete the line.\n\t\t\t\tif (cachedPoints.length > this.util.options.maxPointsPerShape) {\n\t\t\t\t\tthis.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }])\n\n\t\t\t\t\tconst newShapeId = createShapeId()\n\n\t\t\t\t\tconst props = this.editor.getShape<DrawableShape>(id)!.props\n\n\t\t\t\t\tif (!this.editor.canCreateShapes([newShapeId])) return this.cancel()\n\t\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// Reset cache for the new shape's segment\n\t\t\t\t\tconst initialPoint = new Vec(0, 0, this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5)\n\t\t\t\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t\t\t\tthis.editor.createShape({\n\t\t\t\t\t\tid: newShapeId,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tx: toFixed(currentPagePoint.x),\n\t\t\t\t\t\ty: toFixed(currentPagePoint.y),\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\t\t\t\tscale: props.scale,\n\t\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst shape = this.editor.getShape<DrawableShape>(newShapeId)\n\n\t\t\t\t\tif (!shape) {\n\t\t\t\t\t\t// This would only happen if the page is full and no more shapes can be created. The bug would manifest as a crash when we try to clone the shape.\n\t\t\t\t\t\t// todo: handle this type of thing better\n\t\t\t\t\t\treturn this.cancel()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.initialShape = structuredClone(shape)\n\t\t\t\t\tthis.mergeNextPoint = false\n\t\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\t\tthis.currentLineLength = 0\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLineLength(segments: TLDrawShapeSegment[]) {\n\t\tlet length = 0\n\n\t\tfor (let j = 0; j < segments.length; j++) {\n\t\t\tconst points = b64Vecs.decodePoints(segments[j].path)\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tlength += Vec.Dist2(points[i], points[i + 1])\n\t\t\t}\n\t\t}\n\n\t\treturn Math.sqrt(length)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.markId) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst { initialShape } = this\n\t\tif (!initialShape) return\n\t\tthis.editor.updateShapes([\n\t\t\t{ id: initialShape.id, type: initialShape.type, props: { isComplete: true } },\n\t\t])\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLDefaultSizeStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShapePartial,\n\tDIM_2D,\n\tVec,\n\tVecModel,\n\tb64Vecs,\n\tcreateShapeId,\n\tlast,\n\tsnapAngle,\n\tstructuredClone,\n\ttoFixed,\n\tuniqueId,\n} from '@tldraw/editor'\nimport { HighlightShapeUtil } from '../../highlight/HighlightShapeUtil'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { getDisplayValues } from '../../shared/getDisplayValues'\nimport { DrawShapeUtil } from '../DrawShapeUtil'\n\ntype DrawableShape = TLDrawShape | TLHighlightShape\n\nexport class Drawing extends StateNode {\n\tstatic override id = 'drawing'\n\tstatic override trackPerformance = true\n\n\tinfo = {} as TLPointerEventInfo\n\n\tinitialShape?: DrawableShape\n\n\toverride shapeType = this.parent.id === 'highlight' ? ('highlight' as const) : ('draw' as const)\n\n\tutil = this.editor.getShapeUtil(this.shapeType) as DrawShapeUtil | HighlightShapeUtil\n\n\tisPen = false\n\tisPenOrStylus = false\n\n\t// Encoding dimension for segments created during this stroke. `2` drops the\n\t// constant pressure value (non-pressure devices), `undefined` keeps full 3D.\n\t// Decided once in startShape from the input device \u2014 see the note there.\n\tsegmentDim: 2 | undefined = undefined\n\n\tsegmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'\n\n\tdidJustShiftClickToExtendPreviousShapeLine = false\n\n\tpagePointWhereCurrentSegmentChanged = {} as Vec\n\n\tpagePointWhereNextSegmentChanged = null as Vec | null\n\n\tlastRecordedPoint = {} as Vec\n\tmergeNextPoint = false\n\tcurrentLineLength = 0\n\tzoomOnEnter = 1\n\n\t// Cache for current segment's points to avoid repeated b64 decode/encode\n\tcurrentSegmentPoints: Vec[] = []\n\n\tmarkId = null as null | string\n\n\toverride onEnter(info: TLPointerEventInfo) {\n\t\tthis.markId = null\n\t\tthis.info = info\n\t\tthis.lastRecordedPoint = this.editor.inputs.getCurrentPagePoint().clone()\n\t\tthis.zoomOnEnter = this.editor.getZoomLevel()\n\t\tthis.startShape()\n\t}\n\n\toverride onPointerMove() {\n\t\tconst { inputs } = this.editor\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tif (this.isPen && !isPen) {\n\t\t\t// The user made a palm gesture before starting a pen gesture;\n\t\t\t// ideally we'd start the new shape here but we could also just bail\n\t\t\t// as the next interaction will work correctly\n\t\t\tif (this.markId) {\n\t\t\t\tthis.editor.bailToMark(this.markId)\n\t\t\t\tthis.startShape()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isPenOrStylus) {\n\t\t\t// Don't update the shape if we haven't moved far enough from the last time we recorded a point\n\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\t\tif (Vec.Dist(currentPagePoint, this.lastRecordedPoint) >= 1 / this.zoomOnEnter) {\n\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\tthis.mergeNextPoint = false\n\t\t\t} else {\n\t\t\t\tthis.mergeNextPoint = true\n\t\t\t}\n\t\t} else {\n\t\t\tthis.mergeNextPoint = false\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'free': {\n\t\t\t\t\t// We've just entered straight mode, go to straight mode\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_free': {\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'straight': {\n\t\t\t\t\t// We've just exited straight mode, go back to free mode\n\t\t\t\t\tthis.segmentMode = 'starting_free'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_straight': {\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\t\tthis.segmentMode = 'free'\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.pagePointWhereCurrentSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t}\n\n\tcanClose() {\n\t\treturn this.shapeType !== 'highlight'\n\t}\n\n\tgetIsClosed(\n\t\tsegments: TLDrawShapeSegment[],\n\t\tsize: TLDefaultSizeStyle,\n\t\tscale: number,\n\t\tstrokeWidth?: number\n\t) {\n\t\tif (!this.canClose()) return false\n\n\t\tif (strokeWidth === undefined) {\n\t\t\tconst theme = this.editor.getCurrentTheme()\n\t\t\tstrokeWidth = theme.strokeWidth * STROKE_SIZES[size]\n\t\t}\n\t\tconst firstPoint = b64Vecs.decodeFirstPoint(segments[0].path, segments[0].dim)\n\t\tconst lastSegment = segments[segments.length - 1]\n\t\tconst lastPoint = b64Vecs.decodeLastPoint(lastSegment.path, lastSegment.dim)\n\n\t\tconst isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode()\n\n\t\tconst threshold = isDynamicResizingEnabled // when dynamic resizing is enabled scale is 1/zoom, so the threshold should not scale directly with zoom at all\n\t\t\t? (strokeWidth + 2) * scale // +2 keeps tiny strokes from being too hard to close\n\t\t\t: // 6 is a base floor, 2 is stroke influence, 0.8 tempers width growth\n\t\t\t\t6 +\n\t\t\t\t2 * Math.sqrt(strokeWidth * 0.8) +\n\t\t\t\t// 100 is low-zoom boost, 0.18 is the zoom knee, 3 controls falloff steepness\n\t\t\t\t100 / (1 + Math.pow(this.zoomOnEnter / 0.18, 3))\n\n\t\treturn (\n\t\t\tfirstPoint !== null &&\n\t\t\tlastPoint !== null &&\n\t\t\tfirstPoint !== lastPoint &&\n\t\t\tthis.currentLineLength > strokeWidth * 4 * scale &&\n\t\t\tVec.DistMin(firstPoint, lastPoint, threshold)\n\t\t)\n\t}\n\n\t/**\n\t * Build a segment from points, encoding `path` at this stroke's `segmentDim` and\n\t * attaching `dim: 2` only when z was dropped. 3D segments omit `dim` so they\n\t * serialize byte-identically to pre-#8879 data.\n\t */\n\tprivate makeSegment(type: TLDrawShapeSegment['type'], points: VecModel[]): TLDrawShapeSegment {\n\t\tconst path = b64Vecs.encodePoints(points, this.segmentDim)\n\t\treturn this.segmentDim === DIM_2D ? { type, path, dim: DIM_2D } : { type, path }\n\t}\n\n\tprivate startShape() {\n\t\tconst inputs = this.editor.inputs\n\t\tconst originPagePoint = inputs.getOriginPagePoint()\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('draw start')\n\n\t\t// If the pressure is weird, then it's probably a stylus reporting as a mouse\n\t\t// We treat pen/stylus inputs differently in the drawing tool, so we need to\n\t\t// have our own value for this. The inputs.isPen is only if the input is a regular\n\t\t// pen, like an iPad pen, which needs to trigger \"pen mode\" in order to avoid\n\t\t// accidental palm touches. We don't have to worry about that with styluses though.\n\t\tconst { z = 0.5 } = this.info.point\n\n\t\tthis.isPen = isPen\n\t\t// if z === 0 on the initial point, treat this pen as a mouse because it's likely a broken pen\n\t\t// or a broken OS.\n\t\tthis.isPenOrStylus = (isPen && z !== 0) || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)\n\n\t\t// Decide the encoding dimension once, here, from the input device \u2014 not by\n\t\t// scanning point data (content-driven). Device-driven keeps the encoded bytes\n\t\t// deterministic and is O(1) at stroke start. Non-pressure devices report a\n\t\t// constant z (0 / 0.5 / 1) that we normalize to 0.5 and omit entirely (2D);\n\t\t// pen/stylus input keeps the full 3D encoding.\n\t\tthis.segmentDim = this.isPenOrStylus ? undefined : DIM_2D\n\n\t\tconst pressure = this.isPenOrStylus ? z * 1.25 : 0.5\n\n\t\tthis.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'\n\n\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\n\t\tthis.lastRecordedPoint = originPagePoint.clone()\n\n\t\tif (this.initialShape) {\n\t\t\tconst shape = this.editor.getShape<DrawableShape>(this.initialShape.id)\n\n\t\t\tif (shape && this.segmentMode === 'straight') {\n\t\t\t\t// Connect dots\n\n\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = true\n\n\t\t\t\tconst prevSegment = last(shape.props.segments)\n\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim)\n\t\t\t\tif (!prevPoint) throw Error('Expected a previous point!')\n\n\t\t\t\tconst { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()\n\n\t\t\t\tconst newSegment = this.makeSegment(this.segmentMode, [\n\t\t\t\t\t{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },\n\t\t\t\t\t{ x, y, z: +pressure.toFixed(2) },\n\t\t\t\t])\n\n\t\t\t\t// Convert prevPoint to page space\n\t\t\t\tconst prevPointPageSpace = Mat.applyToPoint(\n\t\t\t\t\tthis.editor.getShapePageTransform(shape.id)!,\n\t\t\t\t\tprevPoint\n\t\t\t\t)\n\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = prevPointPageSpace\n\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\tconst segments = [...shape.props.segments, newSegment]\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(segments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tshape.props.size,\n\t\t\t\t\t\tshape.props.scale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Create a new shape\n\n\t\tthis.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()\n\t\tconst id = createShapeId()\n\n\t\t// Initialize the segment points cache\n\t\tconst initialPoint = new Vec(0, 0, +pressure.toFixed(2))\n\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShape({\n\t\t\tid,\n\t\t\ttype: this.shapeType,\n\t\t\tx: originPagePoint.x,\n\t\t\ty: originPagePoint.y,\n\t\t\tprops: {\n\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\tscale: this.editor.getResizeScaleFactor(),\n\t\t\t\tsegments: [this.makeSegment(this.segmentMode, [initialPoint])],\n\t\t\t},\n\t\t})\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\t\tthis.currentLineLength = 0\n\t\tthis.initialShape = this.editor.getShape<DrawableShape>(id)\n\t}\n\n\tprivate updateDrawingShape() {\n\t\tconst { initialShape } = this\n\t\tconst { inputs } = this.editor\n\n\t\tif (!initialShape) return\n\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { size, scale },\n\t\t} = initialShape\n\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)!\n\n\t\tif (!shape) return\n\n\t\tconst { segments } = shape.props\n\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\tconst { x, y, z } = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed()\n\t\tconst pressure = this.isPenOrStylus ? +(currentPagePoint.z! * 1.25).toFixed(2) : 0.5\n\t\tconst newPoint = { x, y, z: pressure }\n\n\t\tswitch (this.segmentMode) {\n\t\t\tcase 'starting_straight': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'straight'\n\n\t\t\t\t\tconst prevSegment = last(segments)\n\t\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\n\t\t\t\t\tconst prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim)\n\t\t\t\t\tif (!prevLastPoint) throw Error('Expected a previous last point!')\n\n\t\t\t\t\tlet newSegment: TLDrawShapeSegment\n\n\t\t\t\t\tconst newLastPoint = this.editor\n\t\t\t\t\t\t.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\t\t.toFixed()\n\t\t\t\t\t\t.toJson()\n\n\t\t\t\t\tif (prevSegment.type === 'straight') {\n\t\t\t\t\t\tthis.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)\n\n\t\t\t\t\t\tnewSegment = this.makeSegment('straight', [prevLastPoint, newLastPoint])\n\n\t\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\n\t\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSegment = this.makeSegment('straight', [newLastPoint, newPoint])\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: [...segments, newSegment],\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tsegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'starting_free': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'free'\n\n\t\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\t\tconst prevStraightSegment = newSegments[newSegments.length - 1]\n\t\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(\n\t\t\t\t\t\tprevStraightSegment.path,\n\t\t\t\t\t\tprevStraightSegment.dim\n\t\t\t\t\t)\n\n\t\t\t\t\tif (!prevPoint) {\n\t\t\t\t\t\tthrow Error('No previous point!')\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create the new free segment and interpolate the points between where the last line\n\t\t\t\t\t// ended and where the pointer is now\n\t\t\t\t\tconst interpolatedPoints = Vec.PointsBetween(prevPoint, newPoint, 6).map(\n\t\t\t\t\t\t(p) => new Vec(toFixed(p.x), toFixed(p.y), toFixed(p.z))\n\t\t\t\t\t)\n\t\t\t\t\t// Initialize cache for the new free segment\n\t\t\t\t\tthis.currentSegmentPoints = interpolatedPoints\n\n\t\t\t\t\tconst newFreeSegment = this.makeSegment('free', interpolatedPoints)\n\n\t\t\t\t\tconst finalSegments = [...newSegments, newFreeSegment]\n\n\t\t\t\t\tconst dvStrokeWidth = (\n\t\t\t\t\t\tgetDisplayValues(this.util as any, shape) as { strokeWidth: number }\n\t\t\t\t\t).strokeWidth\n\t\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\t\tthis.currentLineLength = this.getLineLength(finalSegments)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: finalSegments,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tfinalSegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'straight': {\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\n\t\t\t\tconst { pagePointWhereCurrentSegmentChanged } = this\n\t\t\t\tconst inputs = this.editor.inputs\n\t\t\t\tconst ctrlKey = inputs.getCtrlKey()\n\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\tif (!pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\n\t\t\t\tlet pagePoint: VecModel\n\t\t\t\tlet shouldSnapToAngle = false\n\n\t\t\t\tif (this.didJustShiftClickToExtendPreviousShapeLine) {\n\t\t\t\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\t\t\t\t// If we've just shift clicked to extend a line, only snap once we've started dragging\n\t\t\t\t\t\tshouldSnapToAngle = !ctrlKey\n\t\t\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If we're not shift clicking to extend a line, but we're holding shift, then we should snap\n\t\t\t\t\tshouldSnapToAngle = !ctrlKey // don't snap angle while snapping line\n\t\t\t\t}\n\n\t\t\t\tlet newPoint = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson()\n\t\t\t\tlet didSnap = false\n\t\t\t\tlet snapSegment: TLDrawShapeSegment | undefined = undefined\n\n\t\t\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !ctrlKey : ctrlKey\n\n\t\t\t\tif (shouldSnap) {\n\t\t\t\t\tif (newSegments.length > 2) {\n\t\t\t\t\t\tlet nearestPoint: VecModel | undefined = undefined\n\t\t\t\t\t\tlet minDistance = 8 / this.zoomOnEnter\n\n\t\t\t\t\t\t// Don't try to snap to the last two segments\n\t\t\t\t\t\tfor (let i = 0, n = segments.length - 2; i < n; i++) {\n\t\t\t\t\t\t\tconst segment = segments[i]\n\t\t\t\t\t\t\tif (!segment) break\n\t\t\t\t\t\t\tif (segment.type === 'free') continue\n\n\t\t\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(segment.path, segment.dim)\n\t\t\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(segment.path, segment.dim)\n\t\t\t\t\t\t\tif (!(first && lastPoint)) continue\n\n\t\t\t\t\t\t\t// Snap to the nearest point on the segment, if it's closer than the previous snapped point\n\t\t\t\t\t\t\tconst nearestPointOnSegment = Vec.NearestPointOnLineSegment(\n\t\t\t\t\t\t\t\tfirst,\n\t\t\t\t\t\t\t\tlastPoint,\n\t\t\t\t\t\t\t\tnewPoint\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\tif (Vec.DistMin(nearestPointOnSegment, newPoint, minDistance)) {\n\t\t\t\t\t\t\t\tnearestPoint = nearestPointOnSegment.toFixed().toJson()\n\t\t\t\t\t\t\t\tminDistance = Vec.Dist(nearestPointOnSegment, newPoint)\n\t\t\t\t\t\t\t\tsnapSegment = segment\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (nearestPoint) {\n\t\t\t\t\t\t\tdidSnap = true\n\t\t\t\t\t\t\tnewPoint = nearestPoint\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (didSnap && snapSegment) {\n\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(snapSegment.path, snapSegment.dim)\n\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(snapSegment.path, snapSegment.dim)\n\t\t\t\t\tif (!first || !lastPoint) throw Error('Expected a last point!')\n\n\t\t\t\t\tconst A = Mat.applyToPoint(transform, first)\n\n\t\t\t\t\tconst B = Mat.applyToPoint(transform, lastPoint)\n\n\t\t\t\t\tconst snappedPoint = Mat.applyToPoint(transform, newPoint)\n\n\t\t\t\t\tthis.editor.snaps.setIndicators([\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttype: 'points',\n\t\t\t\t\t\t\tpoints: [A, snappedPoint, B],\n\t\t\t\t\t\t},\n\t\t\t\t\t])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\t\t\tif (shouldSnapToAngle) {\n\t\t\t\t\t\t// Snap line angle to nearest 15 degrees\n\t\t\t\t\t\tconst currentAngle = Vec.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint)\n\t\t\t\t\t\tconst snappedAngle = snapAngle(currentAngle, 24)\n\t\t\t\t\t\tconst angleDiff = snappedAngle - currentAngle\n\n\t\t\t\t\t\tpagePoint = Vec.RotWith(\n\t\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\t\tpagePointWhereCurrentSegmentChanged,\n\t\t\t\t\t\t\tangleDiff\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpagePoint = currentPagePoint.clone()\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPoint = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson()\n\t\t\t\t}\n\n\t\t\t\t// If the previous segment is a one point free shape and is the first segment of the line,\n\t\t\t\t// then the user just did a click-and-immediately-press-shift to create a new straight line\n\t\t\t\t// without continuing the previous line. In this case, we want to remove the previous segment.\n\n\t\t\t\tthis.currentLineLength +=\n\t\t\t\t\tnewSegments.length && b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)\n\t\t\t\t\t\t? Vec.Dist(\n\t\t\t\t\t\t\t\tb64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)!,\n\t\t\t\t\t\t\t\tVec.From(newPoint)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: 0\n\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\ttype: 'straight',\n\t\t\t\t\tpath: b64Vecs.encodePoints(\n\t\t\t\t\t\t[b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)!, Vec.From(newPoint)],\n\t\t\t\t\t\tnewSegment.dim\n\t\t\t\t\t),\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'free': {\n\t\t\t\t// Use cached points instead of decoding from b64 on every update\n\t\t\t\tconst cachedPoints = this.currentSegmentPoints\n\n\t\t\t\tif (cachedPoints.length && this.mergeNextPoint) {\n\t\t\t\t\tconst lastPoint = cachedPoints[cachedPoints.length - 1]\n\t\t\t\t\tlastPoint.x = newPoint.x\n\t\t\t\t\tlastPoint.y = newPoint.y\n\t\t\t\t\tlastPoint.z = lastPoint.z ? Math.max(lastPoint.z, newPoint.z) : newPoint.z\n\t\t\t\t\t// Note: we could recompute the line length here, but it's not really necessary\n\t\t\t\t\t// this.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentLineLength += cachedPoints.length\n\t\t\t\t\t\t? Vec.Dist(cachedPoints[cachedPoints.length - 1], newPoint)\n\t\t\t\t\t\t: 0\n\t\t\t\t\tcachedPoints.push(new Vec(newPoint.x, newPoint.y, newPoint.z))\n\t\t\t\t}\n\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\tpath: b64Vecs.encodePoints(cachedPoints, newSegment.dim),\n\t\t\t\t}\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tnewSegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\t// Set a maximum length for the lines array; after 200 points, complete the line.\n\t\t\t\tif (cachedPoints.length > this.util.options.maxPointsPerShape) {\n\t\t\t\t\tthis.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }])\n\n\t\t\t\t\tconst newShapeId = createShapeId()\n\n\t\t\t\t\tconst props = this.editor.getShape<DrawableShape>(id)!.props\n\n\t\t\t\t\tif (!this.editor.canCreateShapes([newShapeId])) return this.cancel()\n\t\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// Reset cache for the new shape's segment\n\t\t\t\t\tconst initialPoint = new Vec(0, 0, this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5)\n\t\t\t\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t\t\t\tthis.editor.createShape({\n\t\t\t\t\t\tid: newShapeId,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tx: toFixed(currentPagePoint.x),\n\t\t\t\t\t\ty: toFixed(currentPagePoint.y),\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\t\t\t\tscale: props.scale,\n\t\t\t\t\t\t\tsegments: [this.makeSegment('free', [initialPoint])],\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst shape = this.editor.getShape<DrawableShape>(newShapeId)\n\n\t\t\t\t\tif (!shape) {\n\t\t\t\t\t\t// This would only happen if the page is full and no more shapes can be created. The bug would manifest as a crash when we try to clone the shape.\n\t\t\t\t\t\t// todo: handle this type of thing better\n\t\t\t\t\t\treturn this.cancel()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.initialShape = structuredClone(shape)\n\t\t\t\t\tthis.mergeNextPoint = false\n\t\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\t\tthis.currentLineLength = 0\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLineLength(segments: TLDrawShapeSegment[]) {\n\t\tlet length = 0\n\n\t\tfor (let j = 0; j < segments.length; j++) {\n\t\t\tconst points = b64Vecs.decodePoints(segments[j].path, segments[j].dim)\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tlength += Vec.Dist2(points[i], points[i + 1])\n\t\t\t}\n\t\t}\n\n\t\treturn Math.sqrt(length)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.markId) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst { initialShape } = this\n\t\tif (!initialShape) return\n\t\tthis.editor.updateShapes([\n\t\t\t{ id: initialShape.id, type: initialShape.type, props: { isComplete: true } },\n\t\t])\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["shape", "inputs", "currentPagePoint", "newPoint"]
7
7
  }
@@ -37,6 +37,7 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
37
37
  static migrations = import_editor.embedShapeMigrations;
38
38
  options = {
39
39
  embedDefinitions: import_defaultEmbedDefinitions.DEFAULT_EMBED_DEFINITIONS,
40
+ embedConfig: {},
40
41
  getDefaultDisplayValues() {
41
42
  return {
42
43
  showShadow: true
@@ -63,7 +64,7 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
63
64
  return this.getEmbedDefs();
64
65
  }
65
66
  getEmbedDefinition(url) {
66
- return (0, import_embeds.getEmbedInfo)(this.getEmbedDefs(), url);
67
+ return (0, import_embeds.getEmbedInfo)(this.getEmbedDefs(), url, this.options.embedConfig);
67
68
  }
68
69
  getText(shape) {
69
70
  return shape.props.url;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/embed/EmbedShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseColorMode,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n\tunknownEmbedShapePermissionOverrides,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { BookmarkShapeComponent } from '../bookmark/BookmarkShapeUtil'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\n/** @public */\nexport interface EmbedShapeUtilDisplayValues {\n\tshowShadow: boolean\n}\n\n/** @public */\nexport interface EmbedShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLEmbedShape,\n\tEmbedShapeUtilDisplayValues\n> {\n\t/** The embed definitions to use for this shape util. */\n\treadonly embedDefinitions: readonly TLEmbedDefinition[]\n}\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\n\toverride options: EmbedShapeOptions = {\n\t\tembedDefinitions: DEFAULT_EMBED_DEFINITIONS,\n\t\tgetDefaultDisplayValues(): EmbedShapeUtilDisplayValues {\n\t\t\treturn {\n\t\t\t\tshowShadow: true,\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<EmbedShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride canEditWhileLocked(shape: TLEmbedShape) {\n\t\tconst result = this.getEmbedDefinition(shape.props.url)\n\t\tif (!result) return true\n\t\treturn result.definition.canEditWhileLocked ?? true\n\t}\n\n\tprivate static legacyEmbedDefinitions: readonly EmbedDefinition[] | null = null\n\n\t/** @deprecated - Use `EmbedShapeUtil.configure({ embedDefinitions: [...] })` instead. */\n\tstatic setEmbedDefinitions(embedDefinitions: readonly EmbedDefinition[]) {\n\t\tEmbedShapeUtil.legacyEmbedDefinitions = embedDefinitions\n\t}\n\n\tprivate getEmbedDefs(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.legacyEmbedDefinitions ?? this.options.embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn this.getEmbedDefs()\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(this.getEmbedDefs(), url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn this.getEmbedDefinition(shape.props.url)?.definition?.doesResize ?? true\n\t}\n\toverride canEditInReadonly(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLEmbedShape) {\n\t\treturn super.getGeometry(shape)\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\t\tconst colorMode = useColorMode()\n\t\tconst dv = getDisplayValues(this, shape, colorMode)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo\n\t\t\t\t? (embedInfo.definition.overridePermissions ?? {})\n\t\t\t\t: unknownEmbedShapePermissionOverrides),\n\t\t})\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\t// Gist embeds use srcDoc, so we must disable allow-same-origin. Otherwise\n\t\t\t// the embedded script shares the parent's origin and can escape the sandbox.\n\t\t\tconst gistSandbox = getSandboxPermissions({\n\t\t\t\t...embedShapePermissionDefaults,\n\t\t\t\t...(embedInfo?.definition?.overridePermissions ?? {}),\n\t\t\t\t'allow-same-origin': false,\n\t\t\t})\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\tsandbox={gistSandbox}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t\tshowShadow={dv.showShadow}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst iframeSrc = embedInfo?.embedUrl ?? url\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{iframeSrc ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={iframeSrc}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tallowFullScreen\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition?.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition?.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<BookmarkShapeComponent\n\t\t\t\t\t\turl={url}\n\t\t\t\t\t\th={h}\n\t\t\t\t\t\trotation={pageRotation}\n\t\t\t\t\t\tassetId={null}\n\t\t\t\t\t\tshowImageContainer={false}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLEmbedShape): Path2D {\n\t\tconst path = new Path2D()\n\t\tpath.rect(0, 0, shape.props.w, shape.props.h)\n\t\treturn path\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tsandbox,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n\tshowShadow,\n}: {\n\tid: string\n\tsandbox: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tshowShadow: boolean\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tsandbox={sandbox}\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseColorMode,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tDefaultEmbedConfig,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n\tunknownEmbedShapePermissionOverrides,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { BookmarkShapeComponent } from '../bookmark/BookmarkShapeUtil'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\n/** @public */\nexport interface EmbedShapeUtilDisplayValues {\n\tshowShadow: boolean\n}\n\n/** @public */\nexport interface EmbedShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLEmbedShape,\n\tEmbedShapeUtilDisplayValues\n> {\n\t/** The embed definitions to use for this shape util. */\n\treadonly embedDefinitions: readonly TLEmbedDefinition[]\n\t/**\n\t * Per-embed configuration, keyed by embed type. Passed to each definition's `toEmbedUrl` when\n\t * building its embed URL \u2014 for example, an API key for the default Google Maps embed:\n\t *\n\t * ```ts\n\t * EmbedShapeUtil.configure({ embedConfig: { google_maps: { apiKey: '...' } } })\n\t * ```\n\t */\n\treadonly embedConfig?: DefaultEmbedConfig & Record<string, unknown>\n}\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\n\toverride options: EmbedShapeOptions = {\n\t\tembedDefinitions: DEFAULT_EMBED_DEFINITIONS,\n\t\tembedConfig: {},\n\t\tgetDefaultDisplayValues(): EmbedShapeUtilDisplayValues {\n\t\t\treturn {\n\t\t\t\tshowShadow: true,\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<EmbedShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride canEditWhileLocked(shape: TLEmbedShape) {\n\t\tconst result = this.getEmbedDefinition(shape.props.url)\n\t\tif (!result) return true\n\t\treturn result.definition.canEditWhileLocked ?? true\n\t}\n\n\tprivate static legacyEmbedDefinitions: readonly TLEmbedDefinition[] | null = null\n\n\t/** @deprecated - Use `EmbedShapeUtil.configure({ embedDefinitions: [...] })` instead. */\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.legacyEmbedDefinitions = embedDefinitions\n\t}\n\n\tprivate getEmbedDefs(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.legacyEmbedDefinitions ?? this.options.embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn this.getEmbedDefs()\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(this.getEmbedDefs(), url, this.options.embedConfig)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn this.getEmbedDefinition(shape.props.url)?.definition?.doesResize ?? true\n\t}\n\toverride canEditInReadonly(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLEmbedShape) {\n\t\treturn super.getGeometry(shape)\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\t\tconst colorMode = useColorMode()\n\t\tconst dv = getDisplayValues(this, shape, colorMode)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo\n\t\t\t\t? (embedInfo.definition.overridePermissions ?? {})\n\t\t\t\t: unknownEmbedShapePermissionOverrides),\n\t\t})\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\t// Gist embeds use srcDoc, so we must disable allow-same-origin. Otherwise\n\t\t\t// the embedded script shares the parent's origin and can escape the sandbox.\n\t\t\tconst gistSandbox = getSandboxPermissions({\n\t\t\t\t...embedShapePermissionDefaults,\n\t\t\t\t...(embedInfo?.definition?.overridePermissions ?? {}),\n\t\t\t\t'allow-same-origin': false,\n\t\t\t})\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\tsandbox={gistSandbox}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t\tshowShadow={dv.showShadow}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst iframeSrc = embedInfo?.embedUrl ?? url\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{iframeSrc ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={iframeSrc}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tallowFullScreen\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition?.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition?.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<BookmarkShapeComponent\n\t\t\t\t\t\turl={url}\n\t\t\t\t\t\th={h}\n\t\t\t\t\t\trotation={pageRotation}\n\t\t\t\t\t\tassetId={null}\n\t\t\t\t\t\tshowImageContainer={false}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLEmbedShape): Path2D {\n\t\tconst path = new Path2D()\n\t\tpath.rect(0, 0, shape.props.w, shape.props.h)\n\t\treturn path\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tsandbox,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n\tshowShadow,\n}: {\n\tid: string\n\tsandbox: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tshowShadow: boolean\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tsandbox={sandbox}\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,7 +18,8 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var FrameShapeTool_exports = {};
20
20
  __export(FrameShapeTool_exports, {
21
- FrameShapeTool: () => FrameShapeTool
21
+ FrameShapeTool: () => FrameShapeTool,
22
+ getEnclosedShapeIds: () => getEnclosedShapeIds
22
23
  });
23
24
  module.exports = __toCommonJS(FrameShapeTool_exports);
24
25
  var import_editor = require("@tldraw/editor");
@@ -28,23 +29,7 @@ class FrameShapeTool extends import_editor.BaseBoxShapeTool {
28
29
  shapeType = "frame";
29
30
  onCreate(shape) {
30
31
  if (!shape) return;
31
- const bounds = this.editor.getShapePageBounds(shape);
32
- const shapesToAddToFrame = [];
33
- const ancestorIds = this.editor.getShapeAncestors(shape).map((shape2) => shape2.id);
34
- this.editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {
35
- const siblingShape = this.editor.getShape(siblingShapeId);
36
- if (!siblingShape) return;
37
- if (siblingShape.id === shape.id) return;
38
- if (siblingShape.isLocked) return;
39
- const pageShapeBounds = this.editor.getShapePageBounds(siblingShape);
40
- if (!pageShapeBounds) return;
41
- if (bounds.contains(pageShapeBounds)) {
42
- if (canEnclose(siblingShape, ancestorIds, shape)) {
43
- shapesToAddToFrame.push(siblingShape.id);
44
- }
45
- }
46
- });
47
- this.editor.reparentShapes(shapesToAddToFrame, shape.id);
32
+ this.editor.reparentShapes(getEnclosedShapeIds(this.editor, shape), shape.id);
48
33
  if (this.editor.getInstanceState().isToolLocked) {
49
34
  this.editor.setCurrentTool("frame");
50
35
  } else {
@@ -52,6 +37,26 @@ class FrameShapeTool extends import_editor.BaseBoxShapeTool {
52
37
  }
53
38
  }
54
39
  }
40
+ function getEnclosedShapeIds(editor, shape) {
41
+ const bounds = editor.getShapePageBounds(shape);
42
+ if (!bounds) return [];
43
+ const enclosedShapeIds = [];
44
+ const ancestorIds = editor.getShapeAncestors(shape).map((shape2) => shape2.id);
45
+ editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {
46
+ const siblingShape = editor.getShape(siblingShapeId);
47
+ if (!siblingShape) return;
48
+ if (siblingShape.id === shape.id) return;
49
+ if (siblingShape.isLocked) return;
50
+ const pageShapeBounds = editor.getShapePageBounds(siblingShape);
51
+ if (!pageShapeBounds) return;
52
+ if (bounds.contains(pageShapeBounds)) {
53
+ if (canEnclose(siblingShape, ancestorIds, shape)) {
54
+ enclosedShapeIds.push(siblingShape.id);
55
+ }
56
+ }
57
+ });
58
+ return enclosedShapeIds;
59
+ }
55
60
  function canEnclose(shape, ancestorIds, frame) {
56
61
  if (ancestorIds.includes(shape.id)) {
57
62
  return false;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/frame/FrameShapeTool.ts"],
4
- "sourcesContent": ["import { BaseBoxShapeTool, TLShape, TLShapeId } from '@tldraw/editor'\n\n/** @public */\nexport class FrameShapeTool extends BaseBoxShapeTool {\n\tstatic override id = 'frame'\n\tstatic override initial = 'idle'\n\toverride shapeType = 'frame' as const\n\n\toverride onCreate(shape: TLShape | null): void {\n\t\tif (!shape) return\n\n\t\tconst bounds = this.editor.getShapePageBounds(shape)!\n\t\tconst shapesToAddToFrame: TLShapeId[] = []\n\t\tconst ancestorIds = this.editor.getShapeAncestors(shape).map((shape) => shape.id)\n\n\t\tthis.editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {\n\t\t\tconst siblingShape = this.editor.getShape(siblingShapeId)\n\t\t\tif (!siblingShape) return\n\t\t\t// We don't want to frame the frame itself\n\t\t\tif (siblingShape.id === shape.id) return\n\t\t\tif (siblingShape.isLocked) return\n\n\t\t\tconst pageShapeBounds = this.editor.getShapePageBounds(siblingShape)\n\t\t\tif (!pageShapeBounds) return\n\n\t\t\t// Frame shape encloses page shape\n\t\t\tif (bounds.contains(pageShapeBounds)) {\n\t\t\t\tif (canEnclose(siblingShape, ancestorIds, shape)) {\n\t\t\t\t\tshapesToAddToFrame.push(siblingShape.id)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tthis.editor.reparentShapes(shapesToAddToFrame, shape.id)\n\n\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\tthis.editor.setCurrentTool('frame')\n\t\t} else {\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n}\n\n/** @internal */\nfunction canEnclose(shape: TLShape, ancestorIds: TLShapeId[], frame: TLShape): boolean {\n\t// We don't want to pull in shapes that are ancestors of the frame (can create a cycle)\n\tif (ancestorIds.includes(shape.id)) {\n\t\treturn false\n\t}\n\t// We only want to pull in shapes that are siblings of the frame\n\tif (shape.parentId === frame.parentId) {\n\t\treturn true\n\t}\n\treturn false\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAqD;AAG9C,MAAM,uBAAuB,+BAAiB;AAAA,EACpD,OAAgB,KAAK;AAAA,EACrB,OAAgB,UAAU;AAAA,EACjB,YAAY;AAAA,EAEZ,SAAS,OAA6B;AAC9C,QAAI,CAAC,MAAO;AAEZ,UAAM,SAAS,KAAK,OAAO,mBAAmB,KAAK;AACnD,UAAM,qBAAkC,CAAC;AACzC,UAAM,cAAc,KAAK,OAAO,kBAAkB,KAAK,EAAE,IAAI,CAACA,WAAUA,OAAM,EAAE;AAEhF,SAAK,OAAO,2BAA2B,MAAM,QAAQ,EAAE,IAAI,CAAC,mBAAmB;AAC9E,YAAM,eAAe,KAAK,OAAO,SAAS,cAAc;AACxD,UAAI,CAAC,aAAc;AAEnB,UAAI,aAAa,OAAO,MAAM,GAAI;AAClC,UAAI,aAAa,SAAU;AAE3B,YAAM,kBAAkB,KAAK,OAAO,mBAAmB,YAAY;AACnE,UAAI,CAAC,gBAAiB;AAGtB,UAAI,OAAO,SAAS,eAAe,GAAG;AACrC,YAAI,WAAW,cAAc,aAAa,KAAK,GAAG;AACjD,6BAAmB,KAAK,aAAa,EAAE;AAAA,QACxC;AAAA,MACD;AAAA,IACD,CAAC;AAED,SAAK,OAAO,eAAe,oBAAoB,MAAM,EAAE;AAEvD,QAAI,KAAK,OAAO,iBAAiB,EAAE,cAAc;AAChD,WAAK,OAAO,eAAe,OAAO;AAAA,IACnC,OAAO;AACN,WAAK,OAAO,eAAe,aAAa;AAAA,IACzC;AAAA,EACD;AACD;AAGA,SAAS,WAAW,OAAgB,aAA0B,OAAyB;AAEtF,MAAI,YAAY,SAAS,MAAM,EAAE,GAAG;AACnC,WAAO;AAAA,EACR;AAEA,MAAI,MAAM,aAAa,MAAM,UAAU;AACtC,WAAO;AAAA,EACR;AACA,SAAO;AACR;",
4
+ "sourcesContent": ["import { BaseBoxShapeTool, Editor, TLShape, TLShapeId } from '@tldraw/editor'\n\n/** @public */\nexport class FrameShapeTool extends BaseBoxShapeTool {\n\tstatic override id = 'frame'\n\tstatic override initial = 'idle'\n\toverride shapeType = 'frame' as const\n\n\toverride onCreate(shape: TLShape | null): void {\n\t\tif (!shape) return\n\n\t\tthis.editor.reparentShapes(getEnclosedShapeIds(this.editor, shape), shape.id)\n\n\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\tthis.editor.setCurrentTool('frame')\n\t\t} else {\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n}\n\n/**\n * Get the ids of the sibling shapes that a frame would enclose at its current page bounds.\n *\n * @internal\n */\nexport function getEnclosedShapeIds(editor: Editor, shape: TLShape): TLShapeId[] {\n\tconst bounds = editor.getShapePageBounds(shape)\n\tif (!bounds) return []\n\n\tconst enclosedShapeIds: TLShapeId[] = []\n\tconst ancestorIds = editor.getShapeAncestors(shape).map((shape) => shape.id)\n\n\teditor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {\n\t\tconst siblingShape = editor.getShape(siblingShapeId)\n\t\tif (!siblingShape) return\n\t\t// We don't want to frame the frame itself\n\t\tif (siblingShape.id === shape.id) return\n\t\tif (siblingShape.isLocked) return\n\n\t\tconst pageShapeBounds = editor.getShapePageBounds(siblingShape)\n\t\tif (!pageShapeBounds) return\n\n\t\t// Frame shape encloses page shape\n\t\tif (bounds.contains(pageShapeBounds)) {\n\t\t\tif (canEnclose(siblingShape, ancestorIds, shape)) {\n\t\t\t\tenclosedShapeIds.push(siblingShape.id)\n\t\t\t}\n\t\t}\n\t})\n\n\treturn enclosedShapeIds\n}\n\n/** @internal */\nfunction canEnclose(shape: TLShape, ancestorIds: TLShapeId[], frame: TLShape): boolean {\n\t// We don't want to pull in shapes that are ancestors of the frame (can create a cycle)\n\tif (ancestorIds.includes(shape.id)) {\n\t\treturn false\n\t}\n\t// We only want to pull in shapes that are siblings of the frame\n\tif (shape.parentId === frame.parentId) {\n\t\treturn true\n\t}\n\treturn false\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6D;AAGtD,MAAM,uBAAuB,+BAAiB;AAAA,EACpD,OAAgB,KAAK;AAAA,EACrB,OAAgB,UAAU;AAAA,EACjB,YAAY;AAAA,EAEZ,SAAS,OAA6B;AAC9C,QAAI,CAAC,MAAO;AAEZ,SAAK,OAAO,eAAe,oBAAoB,KAAK,QAAQ,KAAK,GAAG,MAAM,EAAE;AAE5E,QAAI,KAAK,OAAO,iBAAiB,EAAE,cAAc;AAChD,WAAK,OAAO,eAAe,OAAO;AAAA,IACnC,OAAO;AACN,WAAK,OAAO,eAAe,aAAa;AAAA,IACzC;AAAA,EACD;AACD;AAOO,SAAS,oBAAoB,QAAgB,OAA6B;AAChF,QAAM,SAAS,OAAO,mBAAmB,KAAK;AAC9C,MAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,QAAM,mBAAgC,CAAC;AACvC,QAAM,cAAc,OAAO,kBAAkB,KAAK,EAAE,IAAI,CAACA,WAAUA,OAAM,EAAE;AAE3E,SAAO,2BAA2B,MAAM,QAAQ,EAAE,IAAI,CAAC,mBAAmB;AACzE,UAAM,eAAe,OAAO,SAAS,cAAc;AACnD,QAAI,CAAC,aAAc;AAEnB,QAAI,aAAa,OAAO,MAAM,GAAI;AAClC,QAAI,aAAa,SAAU;AAE3B,UAAM,kBAAkB,OAAO,mBAAmB,YAAY;AAC9D,QAAI,CAAC,gBAAiB;AAGtB,QAAI,OAAO,SAAS,eAAe,GAAG;AACrC,UAAI,WAAW,cAAc,aAAa,KAAK,GAAG;AACjD,yBAAiB,KAAK,aAAa,EAAE;AAAA,MACtC;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAGA,SAAS,WAAW,OAAgB,aAA0B,OAAyB;AAEtF,MAAI,YAAY,SAAS,MAAM,EAAE,GAAG;AACnC,WAAO;AAAA,EACR;AAEA,MAAI,MAAM,aAAa,MAAM,UAAU;AACtC,WAAO;AAAA,EACR;AACA,SAAO;AACR;",
6
6
  "names": ["shape"]
7
7
  }
@@ -158,7 +158,7 @@ class GeoShapeUtil extends import_editor.BaseBoxShapeUtil {
158
158
  const unscaledLabelSize = isEmptyLabel ? GEO_SHAPE_EMPTY_LABEL_SIZE : this.getUnscaledLabelSize(shape);
159
159
  const unscaledMinWidth = Math.min(100, unscaledShapeW / 2);
160
160
  const unscaledMinHeight = Math.min(
161
- dv.labelFontSize * dv.labelLineHeight + dv.labelPadding * 2,
161
+ (0, import_editor.resolveLineHeightPx)(dv.labelFontSize, dv.labelLineHeight) + dv.labelPadding * 2,
162
162
  unscaledShapeH / 2
163
163
  );
164
164
  const unscaledLabelW = Math.min(