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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/image/ImageShapeUtil.tsx"],
4
- "sourcesContent": ["// oxlint-disable typescript/no-empty-object-type\nimport {\n\tBaseBoxShapeUtil,\n\tEditor,\n\tEllipse2d,\n\tFileHelpers,\n\tGeometry2d,\n\tHTMLContainer,\n\tImage,\n\tMediaHelpers,\n\tRectangle2d,\n\tSvgExportContext,\n\tTLAsset,\n\tTLAssetId,\n\tTLImageAsset,\n\tTLImageShape,\n\tTLImageShapeProps,\n\tTLResizeInfo,\n\tTLShapePartial,\n\tVec,\n\tVecModel,\n\tWeakCache,\n\tcreateShapeId,\n\tfetch,\n\tgetGlobalDocument,\n\timageShapeMigrations,\n\timageShapeProps,\n\tlerp,\n\tmodulate,\n\tresizeBox,\n\tstructuredClone,\n\tuseEditor,\n\tuseUniqueSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { memo, useEffect, useState } from 'react'\nimport { BrokenAssetIcon } from '../shared/BrokenAssetIcon'\nimport { getUncroppedSize } from '../shared/crop'\nimport type { ShapeOptionsWithDisplayValues } from '../shared/getDisplayValues'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { useImageOrVideoAsset } from '../shared/useImageOrVideoAsset'\nimport { usePrefersReducedMotion } from '../shared/usePrefersReducedMotion'\nimport { TRANSPARENT_IMAGE_MIMETYPES, getAlphaData, preloadAlphaData } from './ImageAlphaCache'\nimport { ImageEllipse2d, ImageRectangle2d } from './ImageAlphaGeometry'\n\nasync function getDataURIFromURL(url: string): Promise<string> {\n\tconst response = await fetch(url)\n\tconst blob = await response.blob()\n\treturn FileHelpers.blobToDataUrl(blob)\n}\n\nconst imageSvgExportCache = new WeakCache<TLAsset, Promise<string | null>>()\n\n/** @public */\nexport interface ImageShapeUtilDisplayValues {}\n\n/** @public */\nexport interface ImageShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLImageShape,\n\tImageShapeUtilDisplayValues\n> {}\n\n/** @public */\nexport class ImageShapeUtil extends BaseBoxShapeUtil<TLImageShape> {\n\tstatic override type = 'image' as const\n\tstatic override props = imageShapeProps\n\tstatic override migrations = imageShapeMigrations\n\tstatic override handledAssetTypes = ['image'] as const\n\n\toverride options: ImageShapeOptions = {\n\t\tgetDefaultDisplayValues(): ImageShapeUtilDisplayValues {\n\t\t\treturn {}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<ImageShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride isAspectRatioLocked(shape: TLImageShape) {\n\t\treturn true\n\t}\n\toverride canCrop(shape: TLImageShape) {\n\t\treturn true\n\t}\n\toverride isExportBoundsContainer(): boolean {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLImageShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tassetId: null,\n\t\t\tplaying: true,\n\t\t\turl: '',\n\t\t\tcrop: null,\n\t\t\tflipX: false,\n\t\t\tflipY: false,\n\t\t\taltText: '',\n\t\t}\n\t}\n\n\toverride createShapeForAsset(asset: TLAsset, position: VecModel): TLShapePartial | null {\n\t\tconst imageAsset = asset as TLImageAsset\n\t\treturn {\n\t\t\tid: createShapeId(),\n\t\t\ttype: 'image',\n\t\t\tx: position.x,\n\t\t\ty: position.y,\n\t\t\topacity: 1,\n\t\t\tprops: {\n\t\t\t\tassetId: imageAsset.id,\n\t\t\t\tw: imageAsset.props.w,\n\t\t\t\th: imageAsset.props.h,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLImageShape): Geometry2d {\n\t\tconst asset = shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null\n\t\tconst mimeType = asset && 'mimeType' in asset.props ? asset.props.mimeType : null\n\t\tconst supportsTransparency = mimeType != null && TRANSPARENT_IMAGE_MIMETYPES.includes(mimeType)\n\t\tconst assetSrc = asset && 'src' in asset.props ? asset.props.src : null\n\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\tif (supportsTransparency && assetSrc) {\n\t\t\t\tconst src = assetSrc\n\t\t\t\treturn new ImageEllipse2d({\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\talphaDataGetter: () => getAlphaData(src),\n\t\t\t\t\tcrop: shape.props.crop,\n\t\t\t\t\tflipX: shape.props.flipX,\n\t\t\t\t\tflipY: shape.props.flipY,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn new Ellipse2d({\n\t\t\t\twidth: shape.props.w,\n\t\t\t\theight: shape.props.h,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tif (supportsTransparency && assetSrc) {\n\t\t\tconst src = assetSrc\n\t\t\treturn new ImageRectangle2d({\n\t\t\t\twidth: shape.props.w,\n\t\t\t\theight: shape.props.h,\n\t\t\t\tisFilled: true,\n\t\t\t\talphaDataGetter: () => getAlphaData(src),\n\t\t\t\tcrop: shape.props.crop,\n\t\t\t\tflipX: shape.props.flipX,\n\t\t\t\tflipY: shape.props.flipY,\n\t\t\t})\n\t\t}\n\n\t\treturn new Rectangle2d({\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getAriaDescriptor(shape: TLImageShape) {\n\t\treturn shape.props.altText\n\t}\n\n\toverride onResize(shape: TLImageShape, info: TLResizeInfo<TLImageShape>) {\n\t\tlet resized: TLImageShape = resizeBox(shape, info)\n\t\tconst { flipX, flipY } = info.initialShape.props\n\t\tconst { scaleX, scaleY, mode } = info\n\n\t\tresized = {\n\t\t\t...resized,\n\t\t\tprops: {\n\t\t\t\t...resized.props,\n\t\t\t\tflipX: scaleX < 0 !== flipX,\n\t\t\t\tflipY: scaleY < 0 !== flipY,\n\t\t\t},\n\t\t}\n\t\tif (!shape.props.crop) return resized\n\n\t\tconst flipCropHorizontally =\n\t\t\t// We used the flip horizontally feature\n\t\t\t(mode === 'scale_shape' && scaleX === -1) ||\n\t\t\t// We resized the shape past it's bounds, so it flipped\n\t\t\t(mode === 'resize_bounds' && flipX !== resized.props.flipX)\n\t\tconst flipCropVertically =\n\t\t\t// We used the flip vertically feature\n\t\t\t(mode === 'scale_shape' && scaleY === -1) ||\n\t\t\t// We resized the shape past it's bounds, so it flipped\n\t\t\t(mode === 'resize_bounds' && flipY !== resized.props.flipY)\n\n\t\tconst { topLeft, bottomRight } = shape.props.crop\n\t\tresized.props.crop = {\n\t\t\ttopLeft: {\n\t\t\t\tx: flipCropHorizontally ? 1 - bottomRight.x : topLeft.x,\n\t\t\t\ty: flipCropVertically ? 1 - bottomRight.y : topLeft.y,\n\t\t\t},\n\t\t\tbottomRight: {\n\t\t\t\tx: flipCropHorizontally ? 1 - topLeft.x : bottomRight.x,\n\t\t\t\ty: flipCropVertically ? 1 - topLeft.y : bottomRight.y,\n\t\t\t},\n\t\t\tisCircle: shape.props.crop.isCircle,\n\t\t}\n\t\treturn resized\n\t}\n\n\tcomponent(shape: TLImageShape) {\n\t\treturn <ImageShape shape={shape} />\n\t}\n\n\toverride getIndicatorPath(shape: TLImageShape): Path2D | undefined {\n\t\tif (this.editor.getCroppingShapeId() === shape.id) return undefined\n\n\t\tconst path = new Path2D()\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\tconst cx = shape.props.w / 2\n\t\t\tconst cy = shape.props.h / 2\n\t\t\tpath.ellipse(cx, cy, cx, cy, 0, 0, Math.PI * 2)\n\t\t} else {\n\t\t\tpath.rect(0, 0, shape.props.w, shape.props.h)\n\t\t}\n\t\treturn path\n\t}\n\n\toverride async toSvg(shape: TLImageShape, ctx: SvgExportContext) {\n\t\tconst props = shape.props\n\t\tif (!props.assetId) return null\n\n\t\tconst asset = this.editor.getAsset(props.assetId)\n\n\t\tif (!asset) return null\n\n\t\tconst { w } = getUncroppedSize(shape.props, props.crop)\n\n\t\tconst src = await imageSvgExportCache.get(asset, async () => {\n\t\t\tlet src = await ctx.resolveAssetUrl(asset.id, w)\n\t\t\tif (!src) return null\n\t\t\tif (\n\t\t\t\tsrc.startsWith('blob:') ||\n\t\t\t\tsrc.startsWith('http') ||\n\t\t\t\tsrc.startsWith('/') ||\n\t\t\t\tsrc.startsWith('./')\n\t\t\t) {\n\t\t\t\t// If it's a remote image, we need to fetch it and convert it to a data URI\n\t\t\t\tsrc = (await getDataURIFromURL(src)) || ''\n\t\t\t}\n\n\t\t\t// If it's animated then we need to get the first frame\n\t\t\tif (getIsAnimated(this.editor, asset.id)) {\n\t\t\t\tconst { promise } = getFirstFrameOfAnimatedImage(src)\n\t\t\t\tsrc = await promise\n\t\t\t}\n\t\t\treturn src\n\t\t})\n\n\t\tif (!src) return null\n\n\t\treturn <SvgImage shape={shape} src={src} />\n\t}\n\n\toverride onDoubleClickEdge(shape: TLImageShape) {\n\t\tconst props = shape.props\n\t\tif (!props) return\n\n\t\tif (this.editor.getCroppingShapeId() !== shape.id) {\n\t\t\treturn\n\t\t}\n\n\t\tconst crop = structuredClone(props.crop) || {\n\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t}\n\n\t\t// The true asset dimensions\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\tconst pointDelta = new Vec(crop.topLeft.x * w, crop.topLeft.y * h).rot(shape.rotation)\n\n\t\tconst partial: TLShapePartial<TLImageShape> = {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tx: shape.x - pointDelta.x,\n\t\t\ty: shape.y - pointDelta.y,\n\t\t\tprops: {\n\t\t\t\tcrop: {\n\t\t\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t\t\t},\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t},\n\t\t}\n\n\t\tthis.editor.updateShapes([partial])\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLImageShape,\n\t\tendShape: TLImageShape,\n\t\tt: number\n\t): TLImageShapeProps {\n\t\tfunction interpolateCrop(\n\t\t\tstartShape: TLImageShape,\n\t\t\tendShape: TLImageShape\n\t\t): TLImageShapeProps['crop'] {\n\t\t\tif (startShape.props.crop === null && endShape.props.crop === null) return null\n\n\t\t\tconst startTL = startShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst startBR = startShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\t\t\tconst endTL = endShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst endBR = endShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\n\t\t\treturn {\n\t\t\t\ttopLeft: { x: lerp(startTL.x, endTL.x, t), y: lerp(startTL.y, endTL.y, t) },\n\t\t\t\tbottomRight: { x: lerp(startBR.x, endBR.x, t), y: lerp(startBR.y, endBR.y, t) },\n\t\t\t}\n\t\t}\n\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\tcrop: interpolateCrop(startShape, endShape),\n\t\t}\n\t}\n}\n\nconst ImageShape = memo(function ImageShape({ shape }: { shape: TLImageShape }) {\n\tconst editor = useEditor()\n\n\tconst { w } = getUncroppedSize(shape.props, shape.props.crop)\n\tconst { asset, url } = useImageOrVideoAsset({\n\t\tshapeId: shape.id,\n\t\tassetId: shape.props.assetId,\n\t\twidth: w,\n\t})\n\n\tconst prefersReducedMotion = usePrefersReducedMotion()\n\tconst [staticFrameSrc, setStaticFrameSrc] = useState('')\n\tconst [loadedUrl, setLoadedUrl] = useState<null | string>(null)\n\tconst isAnimated = asset && getIsAnimated(editor, asset.id)\n\n\tuseEffect(() => {\n\t\tif (url && isAnimated) {\n\t\t\tconst { promise, cancel } = getFirstFrameOfAnimatedImage(url)\n\n\t\t\tpromise.then((dataUrl) => {\n\t\t\t\tsetStaticFrameSrc(dataUrl)\n\t\t\t\tsetLoadedUrl(url)\n\t\t\t})\n\n\t\t\treturn () => {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}, [editor, isAnimated, prefersReducedMotion, url])\n\n\tconst mimeType = asset && 'mimeType' in asset.props ? asset.props.mimeType : null\n\tconst supportsTransparency = mimeType != null && TRANSPARENT_IMAGE_MIMETYPES.includes(mimeType)\n\tconst assetSrc = asset && 'src' in asset.props ? asset.props.src : null\n\n\tuseEffect(() => {\n\t\tif (url && supportsTransparency) {\n\t\t\t// Cache under asset.props.src so getGeometry (which only has the asset\n\t\t\t// record) can look up the data even when the resolved URL differs.\n\t\t\tpreloadAlphaData(url, assetSrc ?? undefined)\n\t\t}\n\t}, [url, supportsTransparency, assetSrc])\n\n\tconst showCropPreview = useValue(\n\t\t'show crop preview',\n\t\t() =>\n\t\t\tshape.id === editor.getOnlySelectedShapeId() &&\n\t\t\teditor.getCroppingShapeId() === shape.id &&\n\t\t\teditor.isIn('select.crop'),\n\t\t[editor, shape.id]\n\t)\n\n\t// We only want to reduce motion for mimeTypes that have motion\n\tconst reduceMotion =\n\t\tprefersReducedMotion && (asset?.props.mimeType?.includes('video') || isAnimated)\n\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\n\tconst nextSrc = url === loadedUrl ? null : url\n\tconst loadedSrc = reduceMotion ? staticFrameSrc : loadedUrl\n\n\t// This logic path is for when it's broken/missing asset.\n\tif (!url && !asset?.props.src) {\n\t\treturn (\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tcolor: 'var(--tl-color-text-3)',\n\t\t\t\t\tbackgroundColor: 'var(--tl-color-low)',\n\t\t\t\t\tborder: '1px solid var(--tl-color-low-border)',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classNames('tl-image-container', asset && 'tl-image-container-loading')}\n\t\t\t\t\tstyle={containerStyle}\n\t\t\t\t>\n\t\t\t\t\t{asset ? null : <BrokenAssetIcon />}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\t// We don't set crossOrigin for non-animated images because for Cloudflare we don't currently\n\t// have that set up.\n\tconst crossOrigin = isAnimated ? 'anonymous' : undefined\n\n\treturn (\n\t\t<>\n\t\t\t{showCropPreview && loadedSrc && (\n\t\t\t\t<div style={containerStyle}>\n\t\t\t\t\t<img\n\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\tstyle={{ ...getFlipStyle(shape), opacity: 0.1 }}\n\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tborderRadius: shape.props.crop?.isCircle ? '50%' : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={classNames('tl-image-container')} style={containerStyle}>\n\t\t\t\t\t{/* We have two images: the currently loaded image, and the next image that\n\t\t\t\t\twe're waiting to load. we keep the loaded image mounted while we're waiting\n\t\t\t\t\tfor the next one by storing the loaded URL in state. We use `key` props with\n\t\t\t\t\tthe src of the image so that when the next image is ready, the previous one will\n\t\t\t\t\tbe unmounted and the next will be shown with the browser having to remount a\n\t\t\t\t\tfresh image and decoded it again from the cache. */}\n\t\t\t\t\t{loadedSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={loadedSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt={shape.props.altText}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{nextSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={nextSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={nextSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt={shape.props.altText}\n\t\t\t\t\t\t\tonLoad={() => setLoadedUrl(nextSrc)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t</>\n\t)\n})\n\nfunction getIsAnimated(editor: Editor, assetId: TLAssetId) {\n\tconst asset = assetId ? editor.getAsset(assetId) : undefined\n\n\tif (!asset) return false\n\n\treturn (\n\t\t('mimeType' in asset.props && MediaHelpers.isAnimatedImageType(asset?.props.mimeType)) ||\n\t\t('isAnimated' in asset.props && asset.props.isAnimated)\n\t)\n}\n\n/**\n * When an image is cropped we need to translate the image to show the portion withing the cropped\n * area. We do this by translating the image by the negative of the top left corner of the crop\n * area.\n *\n * @param shape - Shape The image shape for which to get the container style\n * @returns - Styles to apply to the image container\n */\nfunction getCroppedContainerStyle(shape: TLImageShape) {\n\tconst crop = shape.props.crop\n\tconst topLeft = crop?.topLeft\n\tif (!topLeft) {\n\t\treturn {\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t}\n\t}\n\n\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\tconst offsetX = -topLeft.x * w\n\tconst offsetY = -topLeft.y * h\n\treturn {\n\t\ttransform: `translate(${offsetX}px, ${offsetY}px)`,\n\t\twidth: w,\n\t\theight: h,\n\t}\n}\n\nfunction getFlipStyle(shape: TLImageShape, size?: { width: number; height: number }) {\n\tconst { flipX, flipY, crop } = shape.props\n\tif (!flipX && !flipY) return undefined\n\n\tlet cropOffsetX\n\tlet cropOffsetY\n\tif (crop) {\n\t\t// We have to do all this extra math because of the whole transform origin around 0,0\n\t\t// instead of center in SVG-land, ugh.\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\t// Find the resulting w/h of the crop in normalized (0-1) coordinates\n\t\tconst cropWidth = crop.bottomRight.x - crop.topLeft.x\n\t\tconst cropHeight = crop.bottomRight.y - crop.topLeft.y\n\n\t\t// Map from the normalized crop coordinate space to shape pixel space\n\t\tcropOffsetX = modulate(crop.topLeft.x, [0, 1 - cropWidth], [0, w - shape.props.w])\n\t\tcropOffsetY = modulate(crop.topLeft.y, [0, 1 - cropHeight], [0, h - shape.props.h])\n\t}\n\n\tconst scale = `scale(${flipX ? -1 : 1}, ${flipY ? -1 : 1})`\n\tconst translate = size\n\t\t? `translate(${(flipX ? size.width : 0) - (cropOffsetX ? cropOffsetX : 0)}px,\n\t\t ${(flipY ? size.height : 0) - (cropOffsetY ? cropOffsetY : 0)}px)`\n\t\t: ''\n\n\treturn {\n\t\ttransform: `${translate} ${scale}`,\n\t\t// in SVG, flipping around the center doesn't work so we use explicit width/height\n\t\ttransformOrigin: size ? '0 0' : 'center center',\n\t}\n}\n\nfunction SvgImage({ shape, src }: { shape: TLImageShape; src: string }) {\n\tconst cropClipId = useUniqueSafeId()\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\tconst crop = shape.props.crop\n\n\tif (containerStyle.transform && crop) {\n\t\tconst { transform: cropTransform, width, height } = containerStyle\n\t\tconst croppedWidth = (crop.bottomRight.x - crop.topLeft.x) * width\n\t\tconst croppedHeight = (crop.bottomRight.y - crop.topLeft.y) * height\n\n\t\tconst points = [\n\t\t\tnew Vec(0, 0),\n\t\t\tnew Vec(croppedWidth, 0),\n\t\t\tnew Vec(croppedWidth, croppedHeight),\n\t\t\tnew Vec(0, croppedHeight),\n\t\t]\n\n\t\tconst flip = getFlipStyle(shape, { width, height })\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<defs>\n\t\t\t\t\t<clipPath id={cropClipId}>\n\t\t\t\t\t\t{crop.isCircle ? (\n\t\t\t\t\t\t\t<ellipse\n\t\t\t\t\t\t\t\tcx={croppedWidth / 2}\n\t\t\t\t\t\t\t\tcy={croppedHeight / 2}\n\t\t\t\t\t\t\t\trx={croppedWidth / 2}\n\t\t\t\t\t\t\t\try={croppedHeight / 2}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<polygon points={points.map((p) => `${p.x},${p.y}`).join(' ')} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</clipPath>\n\t\t\t\t</defs>\n\t\t\t\t<g clipPath={`url(#${cropClipId})`}>\n\t\t\t\t\t<image\n\t\t\t\t\t\thref={src}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\taria-label={shape.props.altText}\n\t\t\t\t\t\tstyle={flip ? { ...flip } : { transform: cropTransform }}\n\t\t\t\t\t/>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t} else {\n\t\treturn (\n\t\t\t<image\n\t\t\t\thref={src}\n\t\t\t\twidth={shape.props.w}\n\t\t\t\theight={shape.props.h}\n\t\t\t\taria-label={shape.props.altText}\n\t\t\t\tstyle={getFlipStyle(shape, { width: shape.props.w, height: shape.props.h })}\n\t\t\t/>\n\t\t)\n\t}\n}\n\nfunction getFirstFrameOfAnimatedImage(url: string) {\n\tlet cancelled = false\n\n\tconst promise = new Promise<string>((resolve) => {\n\t\tconst image = Image()\n\t\timage.onload = () => {\n\t\t\tif (cancelled) return\n\n\t\t\tconst canvas = getGlobalDocument().createElement('canvas')\n\t\t\tcanvas.width = image.width\n\t\t\tcanvas.height = image.height\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (!ctx) return\n\n\t\t\tctx.drawImage(image, 0, 0)\n\t\t\tresolve(canvas.toDataURL())\n\t\t}\n\t\timage.crossOrigin = 'anonymous'\n\t\timage.src = url\n\t})\n\n\treturn { promise, cancel: () => (cancelled = true) }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// oxlint-disable typescript/no-empty-object-type\nimport {\n\tBaseBoxShapeUtil,\n\tEditor,\n\tEllipse2d,\n\tFileHelpers,\n\tGeometry2d,\n\tHTMLContainer,\n\tImage,\n\tMediaHelpers,\n\tRectangle2d,\n\tSvgExportContext,\n\tTLAsset,\n\tTLAssetId,\n\tTLImageAsset,\n\tTLImageShape,\n\tTLImageShapeProps,\n\tTLResizeInfo,\n\tTLShapePartial,\n\tVec,\n\tVecModel,\n\tWeakCache,\n\tcreateShapeId,\n\tfetch,\n\tgetGlobalDocument,\n\timageShapeMigrations,\n\timageShapeProps,\n\tlerp,\n\tmodulate,\n\tresizeBox,\n\tstructuredClone,\n\tuseEditor,\n\tuseUniqueSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { memo, useEffect, useState } from 'react'\nimport { BrokenAssetIcon } from '../shared/BrokenAssetIcon'\nimport { getUncroppedSize } from '../shared/crop'\nimport type { ShapeOptionsWithDisplayValues } from '../shared/getDisplayValues'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { useImageOrVideoAsset } from '../shared/useImageOrVideoAsset'\nimport { usePrefersReducedMotion } from '../shared/usePrefersReducedMotion'\nimport { TRANSPARENT_IMAGE_MIMETYPES, getAlphaData, preloadAlphaData } from './ImageAlphaCache'\nimport { ImageEllipse2d, ImageRectangle2d } from './ImageAlphaGeometry'\n\nasync function getDataURIFromURL(url: string): Promise<string> {\n\tconst response = await fetch(url)\n\tconst blob = await response.blob()\n\treturn FileHelpers.blobToDataUrl(blob)\n}\n\nconst imageSvgExportCache = new WeakCache<TLAsset, Promise<string | null>>()\n\n/** @public */\nexport interface ImageShapeUtilDisplayValues {}\n\n/** @public */\nexport interface ImageShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLImageShape,\n\tImageShapeUtilDisplayValues\n> {}\n\n/** @public */\nexport class ImageShapeUtil extends BaseBoxShapeUtil<TLImageShape> {\n\tstatic override type = 'image' as const\n\tstatic override props = imageShapeProps\n\tstatic override migrations = imageShapeMigrations\n\tstatic override handledAssetTypes = ['image'] as const\n\n\toverride options: ImageShapeOptions = {\n\t\tgetDefaultDisplayValues(): ImageShapeUtilDisplayValues {\n\t\t\treturn {}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<ImageShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride isAspectRatioLocked(shape: TLImageShape) {\n\t\treturn true\n\t}\n\toverride canCrop(shape: TLImageShape) {\n\t\treturn true\n\t}\n\toverride isExportBoundsContainer(): boolean {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLImageShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tassetId: null,\n\t\t\tplaying: true,\n\t\t\turl: '',\n\t\t\tcrop: null,\n\t\t\tflipX: false,\n\t\t\tflipY: false,\n\t\t\taltText: '',\n\t\t}\n\t}\n\n\toverride createShapeForAsset(asset: TLAsset, position: VecModel): TLShapePartial | null {\n\t\tconst imageAsset = asset as TLImageAsset\n\t\treturn {\n\t\t\tid: createShapeId(),\n\t\t\ttype: 'image',\n\t\t\tx: position.x,\n\t\t\ty: position.y,\n\t\t\topacity: 1,\n\t\t\tprops: {\n\t\t\t\tassetId: imageAsset.id,\n\t\t\t\tw: imageAsset.props.w,\n\t\t\t\th: imageAsset.props.h,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLImageShape): Geometry2d {\n\t\tconst asset = shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null\n\t\tconst mimeType = asset && 'mimeType' in asset.props ? asset.props.mimeType : null\n\t\tconst supportsTransparency = mimeType != null && TRANSPARENT_IMAGE_MIMETYPES.includes(mimeType)\n\t\tconst assetSrc = asset && 'src' in asset.props ? asset.props.src : null\n\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\tif (supportsTransparency && assetSrc) {\n\t\t\t\tconst src = assetSrc\n\t\t\t\treturn new ImageEllipse2d({\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\talphaDataGetter: () => getAlphaData(src),\n\t\t\t\t\tcrop: shape.props.crop,\n\t\t\t\t\tflipX: shape.props.flipX,\n\t\t\t\t\tflipY: shape.props.flipY,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn new Ellipse2d({\n\t\t\t\twidth: shape.props.w,\n\t\t\t\theight: shape.props.h,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tif (supportsTransparency && assetSrc) {\n\t\t\tconst src = assetSrc\n\t\t\treturn new ImageRectangle2d({\n\t\t\t\twidth: shape.props.w,\n\t\t\t\theight: shape.props.h,\n\t\t\t\tisFilled: true,\n\t\t\t\talphaDataGetter: () => getAlphaData(src),\n\t\t\t\tcrop: shape.props.crop,\n\t\t\t\tflipX: shape.props.flipX,\n\t\t\t\tflipY: shape.props.flipY,\n\t\t\t})\n\t\t}\n\n\t\treturn new Rectangle2d({\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getAriaDescriptor(shape: TLImageShape) {\n\t\treturn shape.props.altText\n\t}\n\n\toverride onResize(shape: TLImageShape, info: TLResizeInfo<TLImageShape>) {\n\t\tlet resized: TLImageShape = resizeBox(shape, info)\n\t\tconst { flipX, flipY } = info.initialShape.props\n\t\tconst { scaleX, scaleY } = info\n\n\t\tresized = {\n\t\t\t...resized,\n\t\t\tprops: {\n\t\t\t\t...resized.props,\n\t\t\t\tflipX: scaleX < 0 !== flipX,\n\t\t\t\tflipY: scaleY < 0 !== flipY,\n\t\t\t},\n\t\t}\n\t\tif (!shape.props.crop) return resized\n\n\t\t// Mirror the crop whenever the shape is flipped along an axis. This happens both when\n\t\t// using the flip command and when dragging a resize handle (including a group's handle)\n\t\t// past the opposite edge. We can't check for an exact scale of -1 here because a group\n\t\t// flip resizes its children by an arbitrary negative scale, not just -1.\n\t\tconst flipCropHorizontally = scaleX < 0\n\t\tconst flipCropVertically = scaleY < 0\n\n\t\tconst { topLeft, bottomRight } = shape.props.crop\n\t\tresized.props.crop = {\n\t\t\ttopLeft: {\n\t\t\t\tx: flipCropHorizontally ? 1 - bottomRight.x : topLeft.x,\n\t\t\t\ty: flipCropVertically ? 1 - bottomRight.y : topLeft.y,\n\t\t\t},\n\t\t\tbottomRight: {\n\t\t\t\tx: flipCropHorizontally ? 1 - topLeft.x : bottomRight.x,\n\t\t\t\ty: flipCropVertically ? 1 - topLeft.y : bottomRight.y,\n\t\t\t},\n\t\t\tisCircle: shape.props.crop.isCircle,\n\t\t}\n\t\treturn resized\n\t}\n\n\tcomponent(shape: TLImageShape) {\n\t\treturn <ImageShape shape={shape} />\n\t}\n\n\toverride getIndicatorPath(shape: TLImageShape): Path2D | undefined {\n\t\tif (this.editor.getCroppingShapeId() === shape.id) return undefined\n\n\t\tconst path = new Path2D()\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\tconst cx = shape.props.w / 2\n\t\t\tconst cy = shape.props.h / 2\n\t\t\tpath.ellipse(cx, cy, cx, cy, 0, 0, Math.PI * 2)\n\t\t} else {\n\t\t\tpath.rect(0, 0, shape.props.w, shape.props.h)\n\t\t}\n\t\treturn path\n\t}\n\n\toverride async toSvg(shape: TLImageShape, ctx: SvgExportContext) {\n\t\tconst props = shape.props\n\t\tif (!props.assetId) return null\n\n\t\tconst asset = this.editor.getAsset(props.assetId)\n\n\t\tif (!asset) return null\n\n\t\tconst { w } = getUncroppedSize(shape.props, props.crop)\n\n\t\tconst src = await imageSvgExportCache.get(asset, async () => {\n\t\t\tlet src = await ctx.resolveAssetUrl(asset.id, w)\n\t\t\tif (!src) return null\n\t\t\tif (\n\t\t\t\tsrc.startsWith('blob:') ||\n\t\t\t\tsrc.startsWith('http') ||\n\t\t\t\tsrc.startsWith('/') ||\n\t\t\t\tsrc.startsWith('./')\n\t\t\t) {\n\t\t\t\t// If it's a remote image, we need to fetch it and convert it to a data URI\n\t\t\t\tsrc = (await getDataURIFromURL(src)) || ''\n\t\t\t}\n\n\t\t\t// If it's animated then we need to get the first frame\n\t\t\tif (getIsAnimated(this.editor, asset.id)) {\n\t\t\t\tconst { promise } = getFirstFrameOfAnimatedImage(src)\n\t\t\t\tsrc = await promise\n\t\t\t}\n\t\t\treturn src\n\t\t})\n\n\t\tif (!src) return null\n\n\t\treturn <SvgImage shape={shape} src={src} />\n\t}\n\n\toverride onDoubleClickEdge(shape: TLImageShape) {\n\t\tconst props = shape.props\n\t\tif (!props) return\n\n\t\tif (this.editor.getCroppingShapeId() !== shape.id) {\n\t\t\treturn\n\t\t}\n\n\t\tconst crop = structuredClone(props.crop) || {\n\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t}\n\n\t\t// The true asset dimensions\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\tconst pointDelta = new Vec(crop.topLeft.x * w, crop.topLeft.y * h).rot(shape.rotation)\n\n\t\tconst partial: TLShapePartial<TLImageShape> = {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tx: shape.x - pointDelta.x,\n\t\t\ty: shape.y - pointDelta.y,\n\t\t\tprops: {\n\t\t\t\tcrop: {\n\t\t\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t\t\t},\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t},\n\t\t}\n\n\t\tthis.editor.updateShapes([partial])\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLImageShape,\n\t\tendShape: TLImageShape,\n\t\tt: number\n\t): TLImageShapeProps {\n\t\tfunction interpolateCrop(\n\t\t\tstartShape: TLImageShape,\n\t\t\tendShape: TLImageShape\n\t\t): TLImageShapeProps['crop'] {\n\t\t\tif (startShape.props.crop === null && endShape.props.crop === null) return null\n\n\t\t\tconst startTL = startShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst startBR = startShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\t\t\tconst endTL = endShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst endBR = endShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\n\t\t\treturn {\n\t\t\t\ttopLeft: { x: lerp(startTL.x, endTL.x, t), y: lerp(startTL.y, endTL.y, t) },\n\t\t\t\tbottomRight: { x: lerp(startBR.x, endBR.x, t), y: lerp(startBR.y, endBR.y, t) },\n\t\t\t}\n\t\t}\n\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\tcrop: interpolateCrop(startShape, endShape),\n\t\t}\n\t}\n}\n\nconst ImageShape = memo(function ImageShape({ shape }: { shape: TLImageShape }) {\n\tconst editor = useEditor()\n\n\tconst { w } = getUncroppedSize(shape.props, shape.props.crop)\n\tconst { asset, url } = useImageOrVideoAsset({\n\t\tshapeId: shape.id,\n\t\tassetId: shape.props.assetId,\n\t\twidth: w,\n\t})\n\n\tconst prefersReducedMotion = usePrefersReducedMotion()\n\tconst [staticFrameSrc, setStaticFrameSrc] = useState('')\n\tconst [loadedUrl, setLoadedUrl] = useState<null | string>(null)\n\tconst isAnimated = asset && getIsAnimated(editor, asset.id)\n\n\tuseEffect(() => {\n\t\tif (url && isAnimated) {\n\t\t\tconst { promise, cancel } = getFirstFrameOfAnimatedImage(url)\n\n\t\t\tpromise.then((dataUrl) => {\n\t\t\t\tsetStaticFrameSrc(dataUrl)\n\t\t\t\tsetLoadedUrl(url)\n\t\t\t})\n\n\t\t\treturn () => {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}, [editor, isAnimated, prefersReducedMotion, url])\n\n\tconst mimeType = asset && 'mimeType' in asset.props ? asset.props.mimeType : null\n\tconst supportsTransparency = mimeType != null && TRANSPARENT_IMAGE_MIMETYPES.includes(mimeType)\n\tconst assetSrc = asset && 'src' in asset.props ? asset.props.src : null\n\n\tuseEffect(() => {\n\t\tif (url && supportsTransparency) {\n\t\t\t// Cache under asset.props.src so getGeometry (which only has the asset\n\t\t\t// record) can look up the data even when the resolved URL differs.\n\t\t\tpreloadAlphaData(url, assetSrc ?? undefined)\n\t\t}\n\t}, [url, supportsTransparency, assetSrc])\n\n\tconst showCropPreview = useValue(\n\t\t'show crop preview',\n\t\t() =>\n\t\t\tshape.id === editor.getOnlySelectedShapeId() &&\n\t\t\teditor.getCroppingShapeId() === shape.id &&\n\t\t\teditor.isIn('select.crop'),\n\t\t[editor, shape.id]\n\t)\n\n\t// We only want to reduce motion for mimeTypes that have motion\n\tconst reduceMotion =\n\t\tprefersReducedMotion && (asset?.props.mimeType?.includes('video') || isAnimated)\n\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\n\tconst nextSrc = url === loadedUrl ? null : url\n\tconst loadedSrc = reduceMotion ? staticFrameSrc : loadedUrl\n\n\t// This logic path is for when it's broken/missing asset.\n\tif (!url && !asset?.props.src) {\n\t\treturn (\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tcolor: 'var(--tl-color-text-3)',\n\t\t\t\t\tbackgroundColor: 'var(--tl-color-low)',\n\t\t\t\t\tborder: '1px solid var(--tl-color-low-border)',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classNames('tl-image-container', asset && 'tl-image-container-loading')}\n\t\t\t\t\tstyle={containerStyle}\n\t\t\t\t>\n\t\t\t\t\t{asset ? null : <BrokenAssetIcon />}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\t// We don't set crossOrigin for non-animated images because for Cloudflare we don't currently\n\t// have that set up.\n\tconst crossOrigin = isAnimated ? 'anonymous' : undefined\n\n\treturn (\n\t\t<>\n\t\t\t{showCropPreview && loadedSrc && (\n\t\t\t\t<div style={containerStyle}>\n\t\t\t\t\t<img\n\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\tstyle={{ ...getFlipStyle(shape), opacity: 0.1 }}\n\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tborderRadius: shape.props.crop?.isCircle ? '50%' : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={classNames('tl-image-container')} style={containerStyle}>\n\t\t\t\t\t{/* We have two images: the currently loaded image, and the next image that\n\t\t\t\t\twe're waiting to load. we keep the loaded image mounted while we're waiting\n\t\t\t\t\tfor the next one by storing the loaded URL in state. We use `key` props with\n\t\t\t\t\tthe src of the image so that when the next image is ready, the previous one will\n\t\t\t\t\tbe unmounted and the next will be shown with the browser having to remount a\n\t\t\t\t\tfresh image and decoded it again from the cache. */}\n\t\t\t\t\t{loadedSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={loadedSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt={shape.props.altText}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{nextSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={nextSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={nextSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt={shape.props.altText}\n\t\t\t\t\t\t\tonLoad={() => setLoadedUrl(nextSrc)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t</>\n\t)\n})\n\nfunction getIsAnimated(editor: Editor, assetId: TLAssetId) {\n\tconst asset = assetId ? editor.getAsset(assetId) : undefined\n\n\tif (!asset) return false\n\n\treturn (\n\t\t('mimeType' in asset.props && MediaHelpers.isAnimatedImageType(asset?.props.mimeType)) ||\n\t\t('isAnimated' in asset.props && asset.props.isAnimated)\n\t)\n}\n\n/**\n * When an image is cropped we need to translate the image to show the portion withing the cropped\n * area. We do this by translating the image by the negative of the top left corner of the crop\n * area.\n *\n * @param shape - Shape The image shape for which to get the container style\n * @returns - Styles to apply to the image container\n */\nfunction getCroppedContainerStyle(shape: TLImageShape) {\n\tconst crop = shape.props.crop\n\tconst topLeft = crop?.topLeft\n\tif (!topLeft) {\n\t\treturn {\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t}\n\t}\n\n\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\tconst offsetX = -topLeft.x * w\n\tconst offsetY = -topLeft.y * h\n\treturn {\n\t\ttransform: `translate(${offsetX}px, ${offsetY}px)`,\n\t\twidth: w,\n\t\theight: h,\n\t}\n}\n\nfunction getFlipStyle(shape: TLImageShape, size?: { width: number; height: number }) {\n\tconst { flipX, flipY, crop } = shape.props\n\tif (!flipX && !flipY) return undefined\n\n\tlet cropOffsetX\n\tlet cropOffsetY\n\tif (crop) {\n\t\t// We have to do all this extra math because of the whole transform origin around 0,0\n\t\t// instead of center in SVG-land, ugh.\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\t// Find the resulting w/h of the crop in normalized (0-1) coordinates\n\t\tconst cropWidth = crop.bottomRight.x - crop.topLeft.x\n\t\tconst cropHeight = crop.bottomRight.y - crop.topLeft.y\n\n\t\t// Map from the normalized crop coordinate space to shape pixel space\n\t\tcropOffsetX = modulate(crop.topLeft.x, [0, 1 - cropWidth], [0, w - shape.props.w])\n\t\tcropOffsetY = modulate(crop.topLeft.y, [0, 1 - cropHeight], [0, h - shape.props.h])\n\t}\n\n\tconst scale = `scale(${flipX ? -1 : 1}, ${flipY ? -1 : 1})`\n\tconst translate = size\n\t\t? `translate(${(flipX ? size.width : 0) - (cropOffsetX ? cropOffsetX : 0)}px,\n\t\t ${(flipY ? size.height : 0) - (cropOffsetY ? cropOffsetY : 0)}px)`\n\t\t: ''\n\n\treturn {\n\t\ttransform: `${translate} ${scale}`,\n\t\t// in SVG, flipping around the center doesn't work so we use explicit width/height\n\t\ttransformOrigin: size ? '0 0' : 'center center',\n\t}\n}\n\nfunction SvgImage({ shape, src }: { shape: TLImageShape; src: string }) {\n\tconst cropClipId = useUniqueSafeId()\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\tconst crop = shape.props.crop\n\n\tif (containerStyle.transform && crop) {\n\t\tconst { transform: cropTransform, width, height } = containerStyle\n\t\tconst croppedWidth = (crop.bottomRight.x - crop.topLeft.x) * width\n\t\tconst croppedHeight = (crop.bottomRight.y - crop.topLeft.y) * height\n\n\t\tconst points = [\n\t\t\tnew Vec(0, 0),\n\t\t\tnew Vec(croppedWidth, 0),\n\t\t\tnew Vec(croppedWidth, croppedHeight),\n\t\t\tnew Vec(0, croppedHeight),\n\t\t]\n\n\t\tconst flip = getFlipStyle(shape, { width, height })\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<defs>\n\t\t\t\t\t<clipPath id={cropClipId}>\n\t\t\t\t\t\t{crop.isCircle ? (\n\t\t\t\t\t\t\t<ellipse\n\t\t\t\t\t\t\t\tcx={croppedWidth / 2}\n\t\t\t\t\t\t\t\tcy={croppedHeight / 2}\n\t\t\t\t\t\t\t\trx={croppedWidth / 2}\n\t\t\t\t\t\t\t\try={croppedHeight / 2}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<polygon points={points.map((p) => `${p.x},${p.y}`).join(' ')} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</clipPath>\n\t\t\t\t</defs>\n\t\t\t\t<g clipPath={`url(#${cropClipId})`}>\n\t\t\t\t\t<image\n\t\t\t\t\t\thref={src}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\taria-label={shape.props.altText}\n\t\t\t\t\t\tstyle={flip ? { ...flip } : { transform: cropTransform }}\n\t\t\t\t\t/>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t} else {\n\t\treturn (\n\t\t\t<image\n\t\t\t\thref={src}\n\t\t\t\twidth={shape.props.w}\n\t\t\t\theight={shape.props.h}\n\t\t\t\taria-label={shape.props.altText}\n\t\t\t\tstyle={getFlipStyle(shape, { width: shape.props.w, height: shape.props.h })}\n\t\t\t/>\n\t\t)\n\t}\n}\n\nfunction getFirstFrameOfAnimatedImage(url: string) {\n\tlet cancelled = false\n\n\tconst promise = new Promise<string>((resolve) => {\n\t\tconst image = Image()\n\t\timage.onload = () => {\n\t\t\tif (cancelled) return\n\n\t\t\tconst canvas = getGlobalDocument().createElement('canvas')\n\t\t\tcanvas.width = image.width\n\t\t\tcanvas.height = image.height\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (!ctx) return\n\n\t\t\tctx.drawImage(image, 0, 0)\n\t\t\tresolve(canvas.toDataURL())\n\t\t}\n\t\timage.crossOrigin = 'anonymous'\n\t\timage.src = url\n\t})\n\n\treturn { promise, cancel: () => (cancelled = true) }\n}\n"],
5
+ "mappings": "AA+MS,SAkNP,UAlNO,KAuLN,YAvLM;AA9MT;AAAA,EACC;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EASA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,OAAO,gBAAgB;AACvB,SAAS,MAAM,WAAW,gBAAgB;AAC1C,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AAEjC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AACxC,SAAS,6BAA6B,cAAc,wBAAwB;AAC5E,SAAS,gBAAgB,wBAAwB;AAEjD,eAAe,kBAAkB,KAA8B;AAC9D,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,YAAY,cAAc,IAAI;AACtC;AAEA,MAAM,sBAAsB,IAAI,UAA2C;AAYpE,MAAM,uBAAuB,iBAA+B;AAAA,EAClE,OAAgB,OAAO;AAAA,EACvB,OAAgB,QAAQ;AAAA,EACxB,OAAgB,aAAa;AAAA,EAC7B,OAAgB,oBAAoB,CAAC,OAAO;AAAA,EAEnC,UAA6B;AAAA,IACrC,0BAAuD;AACtD,aAAO,CAAC;AAAA,IACT;AAAA,IACA,yBAA+D;AAC9D,aAAO,CAAC;AAAA,IACT;AAAA,EACD;AAAA,EAES,oBAAoB,OAAqB;AACjD,WAAO;AAAA,EACR;AAAA,EACS,QAAQ,OAAqB;AACrC,WAAO;AAAA,EACR;AAAA,EACS,0BAAmC;AAC3C,WAAO;AAAA,EACR;AAAA,EAES,kBAAyC;AACjD,WAAO;AAAA,MACN,GAAG;AAAA,MACH,GAAG;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,MACT,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,IACV;AAAA,EACD;AAAA,EAES,oBAAoB,OAAgB,UAA2C;AACvF,UAAM,aAAa;AACnB,WAAO;AAAA,MACN,IAAI,cAAc;AAAA,MAClB,MAAM;AAAA,MACN,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ,SAAS;AAAA,MACT,OAAO;AAAA,QACN,SAAS,WAAW;AAAA,QACpB,GAAG,WAAW,MAAM;AAAA,QACpB,GAAG,WAAW,MAAM;AAAA,MACrB;AAAA,IACD;AAAA,EACD;AAAA,EAES,YAAY,OAAiC;AACrD,UAAM,QAAQ,MAAM,MAAM,UAAU,KAAK,OAAO,SAAS,MAAM,MAAM,OAAO,IAAI;AAChF,UAAM,WAAW,SAAS,cAAc,MAAM,QAAQ,MAAM,MAAM,WAAW;AAC7E,UAAM,uBAAuB,YAAY,QAAQ,4BAA4B,SAAS,QAAQ;AAC9F,UAAM,WAAW,SAAS,SAAS,MAAM,QAAQ,MAAM,MAAM,MAAM;AAEnE,QAAI,MAAM,MAAM,MAAM,UAAU;AAC/B,UAAI,wBAAwB,UAAU;AACrC,cAAM,MAAM;AACZ,eAAO,IAAI,eAAe;AAAA,UACzB,OAAO,MAAM,MAAM;AAAA,UACnB,QAAQ,MAAM,MAAM;AAAA,UACpB,UAAU;AAAA,UACV,iBAAiB,MAAM,aAAa,GAAG;AAAA,UACvC,MAAM,MAAM,MAAM;AAAA,UAClB,OAAO,MAAM,MAAM;AAAA,UACnB,OAAO,MAAM,MAAM;AAAA,QACpB,CAAC;AAAA,MACF;AACA,aAAO,IAAI,UAAU;AAAA,QACpB,OAAO,MAAM,MAAM;AAAA,QACnB,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU;AAAA,MACX,CAAC;AAAA,IACF;AAEA,QAAI,wBAAwB,UAAU;AACrC,YAAM,MAAM;AACZ,aAAO,IAAI,iBAAiB;AAAA,QAC3B,OAAO,MAAM,MAAM;AAAA,QACnB,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU;AAAA,QACV,iBAAiB,MAAM,aAAa,GAAG;AAAA,QACvC,MAAM,MAAM,MAAM;AAAA,QAClB,OAAO,MAAM,MAAM;AAAA,QACnB,OAAO,MAAM,MAAM;AAAA,MACpB,CAAC;AAAA,IACF;AAEA,WAAO,IAAI,YAAY;AAAA,MACtB,OAAO,MAAM,MAAM;AAAA,MACnB,QAAQ,MAAM,MAAM;AAAA,MACpB,UAAU;AAAA,IACX,CAAC;AAAA,EACF;AAAA,EAES,kBAAkB,OAAqB;AAC/C,WAAO,MAAM,MAAM;AAAA,EACpB;AAAA,EAES,SAAS,OAAqB,MAAkC;AACxE,QAAI,UAAwB,UAAU,OAAO,IAAI;AACjD,UAAM,EAAE,OAAO,MAAM,IAAI,KAAK,aAAa;AAC3C,UAAM,EAAE,QAAQ,OAAO,IAAI;AAE3B,cAAU;AAAA,MACT,GAAG;AAAA,MACH,OAAO;AAAA,QACN,GAAG,QAAQ;AAAA,QACX,OAAO,SAAS,MAAM;AAAA,QACtB,OAAO,SAAS,MAAM;AAAA,MACvB;AAAA,IACD;AACA,QAAI,CAAC,MAAM,MAAM,KAAM,QAAO;AAM9B,UAAM,uBAAuB,SAAS;AACtC,UAAM,qBAAqB,SAAS;AAEpC,UAAM,EAAE,SAAS,YAAY,IAAI,MAAM,MAAM;AAC7C,YAAQ,MAAM,OAAO;AAAA,MACpB,SAAS;AAAA,QACR,GAAG,uBAAuB,IAAI,YAAY,IAAI,QAAQ;AAAA,QACtD,GAAG,qBAAqB,IAAI,YAAY,IAAI,QAAQ;AAAA,MACrD;AAAA,MACA,aAAa;AAAA,QACZ,GAAG,uBAAuB,IAAI,QAAQ,IAAI,YAAY;AAAA,QACtD,GAAG,qBAAqB,IAAI,QAAQ,IAAI,YAAY;AAAA,MACrD;AAAA,MACA,UAAU,MAAM,MAAM,KAAK;AAAA,IAC5B;AACA,WAAO;AAAA,EACR;AAAA,EAEA,UAAU,OAAqB;AAC9B,WAAO,oBAAC,cAAW,OAAc;AAAA,EAClC;AAAA,EAES,iBAAiB,OAAyC;AAClE,QAAI,KAAK,OAAO,mBAAmB,MAAM,MAAM,GAAI,QAAO;AAE1D,UAAM,OAAO,IAAI,OAAO;AACxB,QAAI,MAAM,MAAM,MAAM,UAAU;AAC/B,YAAM,KAAK,MAAM,MAAM,IAAI;AAC3B,YAAM,KAAK,MAAM,MAAM,IAAI;AAC3B,WAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,GAAG,GAAG,KAAK,KAAK,CAAC;AAAA,IAC/C,OAAO;AACN,WAAK,KAAK,GAAG,GAAG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;AAAA,IAC7C;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAe,MAAM,OAAqB,KAAuB;AAChE,UAAM,QAAQ,MAAM;AACpB,QAAI,CAAC,MAAM,QAAS,QAAO;AAE3B,UAAM,QAAQ,KAAK,OAAO,SAAS,MAAM,OAAO;AAEhD,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,EAAE,EAAE,IAAI,iBAAiB,MAAM,OAAO,MAAM,IAAI;AAEtD,UAAM,MAAM,MAAM,oBAAoB,IAAI,OAAO,YAAY;AAC5D,UAAIA,OAAM,MAAM,IAAI,gBAAgB,MAAM,IAAI,CAAC;AAC/C,UAAI,CAACA,KAAK,QAAO;AACjB,UACCA,KAAI,WAAW,OAAO,KACtBA,KAAI,WAAW,MAAM,KACrBA,KAAI,WAAW,GAAG,KAClBA,KAAI,WAAW,IAAI,GAClB;AAED,QAAAA,OAAO,MAAM,kBAAkBA,IAAG,KAAM;AAAA,MACzC;AAGA,UAAI,cAAc,KAAK,QAAQ,MAAM,EAAE,GAAG;AACzC,cAAM,EAAE,QAAQ,IAAI,6BAA6BA,IAAG;AACpD,QAAAA,OAAM,MAAM;AAAA,MACb;AACA,aAAOA;AAAA,IACR,CAAC;AAED,QAAI,CAAC,IAAK,QAAO;AAEjB,WAAO,oBAAC,YAAS,OAAc,KAAU;AAAA,EAC1C;AAAA,EAES,kBAAkB,OAAqB;AAC/C,UAAM,QAAQ,MAAM;AACpB,QAAI,CAAC,MAAO;AAEZ,QAAI,KAAK,OAAO,mBAAmB,MAAM,MAAM,IAAI;AAClD;AAAA,IACD;AAEA,UAAM,OAAO,gBAAgB,MAAM,IAAI,KAAK;AAAA,MAC3C,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MACtB,aAAa,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,IAC3B;AAGA,UAAM,EAAE,GAAG,EAAE,IAAI,iBAAiB,MAAM,OAAO,IAAI;AAEnD,UAAM,aAAa,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,CAAC,EAAE,IAAI,MAAM,QAAQ;AAErF,UAAM,UAAwC;AAAA,MAC7C,IAAI,MAAM;AAAA,MACV,MAAM,MAAM;AAAA,MACZ,GAAG,MAAM,IAAI,WAAW;AAAA,MACxB,GAAG,MAAM,IAAI,WAAW;AAAA,MACxB,OAAO;AAAA,QACN,MAAM;AAAA,UACL,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,UACtB,aAAa,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,QAC3B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,SAAK,OAAO,aAAa,CAAC,OAAO,CAAC;AAAA,EACnC;AAAA,EACS,qBACR,YACA,UACA,GACoB;AACpB,aAAS,gBACRC,aACAC,WAC4B;AAC5B,UAAID,YAAW,MAAM,SAAS,QAAQC,UAAS,MAAM,SAAS,KAAM,QAAO;AAE3E,YAAM,UAAUD,YAAW,MAAM,MAAM,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE;AAC/D,YAAM,UAAUA,YAAW,MAAM,MAAM,eAAe,EAAE,GAAG,GAAG,GAAG,EAAE;AACnE,YAAM,QAAQC,UAAS,MAAM,MAAM,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE;AAC3D,YAAM,QAAQA,UAAS,MAAM,MAAM,eAAe,EAAE,GAAG,GAAG,GAAG,EAAE;AAE/D,aAAO;AAAA,QACN,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,GAAG,KAAK,QAAQ,GAAG,MAAM,GAAG,CAAC,EAAE;AAAA,QAC1E,aAAa,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,GAAG,KAAK,QAAQ,GAAG,MAAM,GAAG,CAAC,EAAE;AAAA,MAC/E;AAAA,IACD;AAEA,WAAO;AAAA,MACN,GAAI,IAAI,MAAM,SAAS,QAAQ,WAAW;AAAA,MAC1C,GAAG,KAAK,WAAW,MAAM,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,MAC/C,GAAG,KAAK,WAAW,MAAM,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,MAC/C,MAAM,gBAAgB,YAAY,QAAQ;AAAA,IAC3C;AAAA,EACD;AACD;AAEA,MAAM,aAAa,KAAK,SAASC,YAAW,EAAE,MAAM,GAA4B;AAC/E,QAAM,SAAS,UAAU;AAEzB,QAAM,EAAE,EAAE,IAAI,iBAAiB,MAAM,OAAO,MAAM,MAAM,IAAI;AAC5D,QAAM,EAAE,OAAO,IAAI,IAAI,qBAAqB;AAAA,IAC3C,SAAS,MAAM;AAAA,IACf,SAAS,MAAM,MAAM;AAAA,IACrB,OAAO;AAAA,EACR,CAAC;AAED,QAAM,uBAAuB,wBAAwB;AACrD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,EAAE;AACvD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAC9D,QAAM,aAAa,SAAS,cAAc,QAAQ,MAAM,EAAE;AAE1D,YAAU,MAAM;AACf,QAAI,OAAO,YAAY;AACtB,YAAM,EAAE,SAAS,OAAO,IAAI,6BAA6B,GAAG;AAE5D,cAAQ,KAAK,CAAC,YAAY;AACzB,0BAAkB,OAAO;AACzB,qBAAa,GAAG;AAAA,MACjB,CAAC;AAED,aAAO,MAAM;AACZ,eAAO;AAAA,MACR;AAAA,IACD;AACA,WAAO;AAAA,EACR,GAAG,CAAC,QAAQ,YAAY,sBAAsB,GAAG,CAAC;AAElD,QAAM,WAAW,SAAS,cAAc,MAAM,QAAQ,MAAM,MAAM,WAAW;AAC7E,QAAM,uBAAuB,YAAY,QAAQ,4BAA4B,SAAS,QAAQ;AAC9F,QAAM,WAAW,SAAS,SAAS,MAAM,QAAQ,MAAM,MAAM,MAAM;AAEnE,YAAU,MAAM;AACf,QAAI,OAAO,sBAAsB;AAGhC,uBAAiB,KAAK,YAAY,MAAS;AAAA,IAC5C;AAAA,EACD,GAAG,CAAC,KAAK,sBAAsB,QAAQ,CAAC;AAExC,QAAM,kBAAkB;AAAA,IACvB;AAAA,IACA,MACC,MAAM,OAAO,OAAO,uBAAuB,KAC3C,OAAO,mBAAmB,MAAM,MAAM,MACtC,OAAO,KAAK,aAAa;AAAA,IAC1B,CAAC,QAAQ,MAAM,EAAE;AAAA,EAClB;AAGA,QAAM,eACL,yBAAyB,OAAO,MAAM,UAAU,SAAS,OAAO,KAAK;AAEtE,QAAM,iBAAiB,yBAAyB,KAAK;AAErD,QAAM,UAAU,QAAQ,YAAY,OAAO;AAC3C,QAAM,YAAY,eAAe,iBAAiB;AAGlD,MAAI,CAAC,OAAO,CAAC,OAAO,MAAM,KAAK;AAC9B,WACC;AAAA,MAAC;AAAA;AAAA,QACA,IAAI,MAAM;AAAA,QACV,OAAO;AAAA,UACN,UAAU;AAAA,UACV,OAAO,MAAM,MAAM;AAAA,UACnB,QAAQ,MAAM,MAAM;AAAA,UACpB,OAAO;AAAA,UACP,iBAAiB;AAAA,UACjB,QAAQ;AAAA,QACT;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACA,WAAW,WAAW,sBAAsB,SAAS,4BAA4B;AAAA,cACjF,OAAO;AAAA,cAEN,kBAAQ,OAAO,oBAAC,mBAAgB;AAAA;AAAA,UAClC;AAAA,UACC,SAAS,MAAM,SAAS,MAAM,MAAM,OAAO,oBAAC,mBAAgB,KAAK,MAAM,MAAM,KAAK;AAAA;AAAA;AAAA,IACpF;AAAA,EAEF;AAIA,QAAM,cAAc,aAAa,cAAc;AAE/C,SACC,iCACE;AAAA,uBAAmB,aACnB,oBAAC,SAAI,OAAO,gBACX;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV,OAAO,EAAE,GAAG,aAAa,KAAK,GAAG,SAAS,IAAI;AAAA,QAC9C;AAAA,QACA,KAAK;AAAA,QACL,gBAAe;AAAA,QACf,WAAW;AAAA,QACX,KAAI;AAAA;AAAA,IACL,GACD;AAAA,IAED;AAAA,MAAC;AAAA;AAAA,QACA,IAAI,MAAM;AAAA,QACV,OAAO;AAAA,UACN,UAAU;AAAA,UACV,OAAO,MAAM,MAAM;AAAA,UACnB,QAAQ,MAAM,MAAM;AAAA,UACpB,cAAc,MAAM,MAAM,MAAM,WAAW,QAAQ;AAAA,QACpD;AAAA,QAEA;AAAA,+BAAC,SAAI,WAAW,WAAW,oBAAoB,GAAG,OAAO,gBAOvD;AAAA,yBACA;AAAA,cAAC;AAAA;AAAA,gBAEA,WAAU;AAAA,gBACV,OAAO,aAAa,KAAK;AAAA,gBACzB;AAAA,gBACA,KAAK;AAAA,gBACL,gBAAe;AAAA,gBACf,WAAW;AAAA,gBACX,KAAK,MAAM,MAAM;AAAA;AAAA,cAPZ;AAAA,YAQN;AAAA,YAEA,WACA;AAAA,cAAC;AAAA;AAAA,gBAEA,WAAU;AAAA,gBACV,OAAO,aAAa,KAAK;AAAA,gBACzB;AAAA,gBACA,KAAK;AAAA,gBACL,gBAAe;AAAA,gBACf,WAAW;AAAA,gBACX,KAAK,MAAM,MAAM;AAAA,gBACjB,QAAQ,MAAM,aAAa,OAAO;AAAA;AAAA,cAR7B;AAAA,YASN;AAAA,aAEF;AAAA,UACC,MAAM,MAAM,OAAO,oBAAC,mBAAgB,KAAK,MAAM,MAAM,KAAK;AAAA;AAAA;AAAA,IAC5D;AAAA,KACD;AAEF,CAAC;AAED,SAAS,cAAc,QAAgB,SAAoB;AAC1D,QAAM,QAAQ,UAAU,OAAO,SAAS,OAAO,IAAI;AAEnD,MAAI,CAAC,MAAO,QAAO;AAEnB,SACE,cAAc,MAAM,SAAS,aAAa,oBAAoB,OAAO,MAAM,QAAQ,KACnF,gBAAgB,MAAM,SAAS,MAAM,MAAM;AAE9C;AAUA,SAAS,yBAAyB,OAAqB;AACtD,QAAM,OAAO,MAAM,MAAM;AACzB,QAAM,UAAU,MAAM;AACtB,MAAI,CAAC,SAAS;AACb,WAAO;AAAA,MACN,OAAO,MAAM,MAAM;AAAA,MACnB,QAAQ,MAAM,MAAM;AAAA,IACrB;AAAA,EACD;AAEA,QAAM,EAAE,GAAG,EAAE,IAAI,iBAAiB,MAAM,OAAO,IAAI;AACnD,QAAM,UAAU,CAAC,QAAQ,IAAI;AAC7B,QAAM,UAAU,CAAC,QAAQ,IAAI;AAC7B,SAAO;AAAA,IACN,WAAW,aAAa,OAAO,OAAO,OAAO;AAAA,IAC7C,OAAO;AAAA,IACP,QAAQ;AAAA,EACT;AACD;AAEA,SAAS,aAAa,OAAqB,MAA0C;AACpF,QAAM,EAAE,OAAO,OAAO,KAAK,IAAI,MAAM;AACrC,MAAI,CAAC,SAAS,CAAC,MAAO,QAAO;AAE7B,MAAI;AACJ,MAAI;AACJ,MAAI,MAAM;AAGT,UAAM,EAAE,GAAG,EAAE,IAAI,iBAAiB,MAAM,OAAO,IAAI;AAGnD,UAAM,YAAY,KAAK,YAAY,IAAI,KAAK,QAAQ;AACpD,UAAM,aAAa,KAAK,YAAY,IAAI,KAAK,QAAQ;AAGrD,kBAAc,SAAS,KAAK,QAAQ,GAAG,CAAC,GAAG,IAAI,SAAS,GAAG,CAAC,GAAG,IAAI,MAAM,MAAM,CAAC,CAAC;AACjF,kBAAc,SAAS,KAAK,QAAQ,GAAG,CAAC,GAAG,IAAI,UAAU,GAAG,CAAC,GAAG,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EACnF;AAEA,QAAM,QAAQ,SAAS,QAAQ,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC;AACxD,QAAM,YAAY,OACf,cAAc,QAAQ,KAAK,QAAQ,MAAM,cAAc,cAAc,EAAE;AAAA,kBACzD,QAAQ,KAAK,SAAS,MAAM,cAAc,cAAc,EAAE,QACxE;AAEH,SAAO;AAAA,IACN,WAAW,GAAG,SAAS,IAAI,KAAK;AAAA;AAAA,IAEhC,iBAAiB,OAAO,QAAQ;AAAA,EACjC;AACD;AAEA,SAAS,SAAS,EAAE,OAAO,IAAI,GAAyC;AACvE,QAAM,aAAa,gBAAgB;AACnC,QAAM,iBAAiB,yBAAyB,KAAK;AACrD,QAAM,OAAO,MAAM,MAAM;AAEzB,MAAI,eAAe,aAAa,MAAM;AACrC,UAAM,EAAE,WAAW,eAAe,OAAO,OAAO,IAAI;AACpD,UAAM,gBAAgB,KAAK,YAAY,IAAI,KAAK,QAAQ,KAAK;AAC7D,UAAM,iBAAiB,KAAK,YAAY,IAAI,KAAK,QAAQ,KAAK;AAE9D,UAAM,SAAS;AAAA,MACd,IAAI,IAAI,GAAG,CAAC;AAAA,MACZ,IAAI,IAAI,cAAc,CAAC;AAAA,MACvB,IAAI,IAAI,cAAc,aAAa;AAAA,MACnC,IAAI,IAAI,GAAG,aAAa;AAAA,IACzB;AAEA,UAAM,OAAO,aAAa,OAAO,EAAE,OAAO,OAAO,CAAC;AAElD,WACC,iCACC;AAAA,0BAAC,UACA,8BAAC,cAAS,IAAI,YACZ,eAAK,WACL;AAAA,QAAC;AAAA;AAAA,UACA,IAAI,eAAe;AAAA,UACnB,IAAI,gBAAgB;AAAA,UACpB,IAAI,eAAe;AAAA,UACnB,IAAI,gBAAgB;AAAA;AAAA,MACrB,IAEA,oBAAC,aAAQ,QAAQ,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,GAAG,GAEjE,GACD;AAAA,MACA,oBAAC,OAAE,UAAU,QAAQ,UAAU,KAC9B;AAAA,QAAC;AAAA;AAAA,UACA,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,cAAY,MAAM,MAAM;AAAA,UACxB,OAAO,OAAO,EAAE,GAAG,KAAK,IAAI,EAAE,WAAW,cAAc;AAAA;AAAA,MACxD,GACD;AAAA,OACD;AAAA,EAEF,OAAO;AACN,WACC;AAAA,MAAC;AAAA;AAAA,QACA,MAAM;AAAA,QACN,OAAO,MAAM,MAAM;AAAA,QACnB,QAAQ,MAAM,MAAM;AAAA,QACpB,cAAY,MAAM,MAAM;AAAA,QACxB,OAAO,aAAa,OAAO,EAAE,OAAO,MAAM,MAAM,GAAG,QAAQ,MAAM,MAAM,EAAE,CAAC;AAAA;AAAA,IAC3E;AAAA,EAEF;AACD;AAEA,SAAS,6BAA6B,KAAa;AAClD,MAAI,YAAY;AAEhB,QAAM,UAAU,IAAI,QAAgB,CAAC,YAAY;AAChD,UAAM,QAAQ,MAAM;AACpB,UAAM,SAAS,MAAM;AACpB,UAAI,UAAW;AAEf,YAAM,SAAS,kBAAkB,EAAE,cAAc,QAAQ;AACzD,aAAO,QAAQ,MAAM;AACrB,aAAO,SAAS,MAAM;AAEtB,YAAM,MAAM,OAAO,WAAW,IAAI;AAClC,UAAI,CAAC,IAAK;AAEV,UAAI,UAAU,OAAO,GAAG,CAAC;AACzB,cAAQ,OAAO,UAAU,CAAC;AAAA,IAC3B;AACA,UAAM,cAAc;AACpB,UAAM,MAAM;AAAA,EACb,CAAC;AAED,SAAO,EAAE,SAAS,QAAQ,MAAO,YAAY,KAAM;AACpD;",
6
6
  "names": ["src", "startShape", "endShape", "ImageShape"]
7
7
  }
@@ -4,6 +4,7 @@ import {
4
4
  Vec,
5
5
  createShapeId,
6
6
  getIndexAbove,
7
+ cancelShapeCreationOnLongPress,
7
8
  last,
8
9
  maybeSnapToGrid,
9
10
  sortByIndex,
@@ -34,7 +35,8 @@ class Pointing extends StateNode {
34
35
  const nudgedPoint = Vec.Sub(currentPagePoint, shapePagePoint).addXY(0.1, 0.1);
35
36
  const nextPoint = maybeSnapToGrid(nudgedPoint, this.editor);
36
37
  const points = structuredClone(this.shape.props.points);
37
- if (Vec.DistMin(endHandle, prevEndHandle, MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES) || Vec.DistMin(nextPoint, endHandle, MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES)) {
38
+ const minDistance = MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES / this.editor.getZoomLevel();
39
+ if (Vec.DistMin(endHandle, prevEndHandle, minDistance) || Vec.DistMin(nextPoint, endHandle, minDistance)) {
38
40
  points[endHandle.id] = {
39
41
  id: endHandle.id,
40
42
  index: endHandle.index,
@@ -104,6 +106,9 @@ class Pointing extends StateNode {
104
106
  onPointerUp() {
105
107
  this.complete();
106
108
  }
109
+ onLongPress() {
110
+ cancelShapeCreationOnLongPress(this.editor, () => this.cancel());
111
+ }
107
112
  onCancel() {
108
113
  this.cancel();
109
114
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/shapes/line/toolStates/Pointing.ts"],
4
- "sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLLineShape,\n\tTLShapeId,\n\tVec,\n\tcreateShapeId,\n\tgetIndexAbove,\n\tlast,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n\tstructuredClone,\n} from '@tldraw/editor'\n\nconst MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES = 2\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\tshape = {} as TLLineShape\n\n\tmarkId: string | undefined\n\n\toverride onEnter(info: { shapeId?: TLShapeId }) {\n\t\tconst { inputs } = this.editor\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\tthis.markId = undefined\n\n\t\t// Previously created line shape that we might be extending\n\t\tconst shape = info.shapeId && this.editor.getShape<TLLineShape>(info.shapeId)\n\n\t\tif (shape && inputs.getShiftKey()) {\n\t\t\t// Extending a previous shape\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint(`creating_line:${shape.id}`)\n\t\t\tthis.shape = shape\n\n\t\t\tconst handles = this.editor.getShapeHandles(this.shape)\n\t\t\tif (!handles) return\n\n\t\t\tconst vertexHandles = handles.filter((h) => h.type === 'vertex').sort(sortByIndex)\n\t\t\tconst endHandle = vertexHandles[vertexHandles.length - 1]\n\t\t\tconst prevEndHandle = vertexHandles[vertexHandles.length - 2]\n\n\t\t\tconst shapePagePoint = Mat.applyToPoint(\n\t\t\t\tthis.editor.getShapeParentTransform(this.shape)!,\n\t\t\t\tnew Vec(this.shape.x, this.shape.y)\n\t\t\t)\n\t\t\t// nudge the point slightly to avoid zero-length lines\n\t\t\tconst nudgedPoint = Vec.Sub(currentPagePoint, shapePagePoint).addXY(0.1, 0.1)\n\t\t\tconst nextPoint = maybeSnapToGrid(nudgedPoint, this.editor)\n\t\t\tconst points = structuredClone(this.shape.props.points)\n\n\t\t\tif (\n\t\t\t\tVec.DistMin(endHandle, prevEndHandle, MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES) ||\n\t\t\t\tVec.DistMin(nextPoint, endHandle, MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES)\n\t\t\t) {\n\t\t\t\t// Don't add a new point if the distance between the last two points is too small\n\t\t\t\tpoints[endHandle.id] = {\n\t\t\t\t\tid: endHandle.id,\n\t\t\t\t\tindex: endHandle.index,\n\t\t\t\t\tx: nextPoint.x,\n\t\t\t\t\ty: nextPoint.y,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Add a new point\n\t\t\t\tconst nextIndex = getIndexAbove(endHandle.index)\n\t\t\t\tpoints[nextIndex] = {\n\t\t\t\t\tid: nextIndex,\n\t\t\t\t\tindex: nextIndex,\n\t\t\t\t\tx: nextPoint.x,\n\t\t\t\t\ty: nextPoint.y,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.editor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid: this.shape.id,\n\t\t\t\t\ttype: this.shape.type,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tpoints,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t])\n\t\t} else {\n\t\t\tconst id = createShapeId()\n\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint(`creating_line:${id}`)\n\n\t\t\tconst newPoint = maybeSnapToGrid(currentPagePoint, this.editor)\n\n\t\t\tthis.editor.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tscale: this.editor.getResizeScaleFactor(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t])\n\n\t\t\tif (!this.editor.getShape(id)) {\n\t\t\t\tthis.cancel()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.editor.select(id)\n\t\t\tthis.shape = this.editor.getShape(id)!\n\t\t}\n\t}\n\n\toverride onPointerMove() {\n\t\tif (!this.shape) return\n\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tconst handles = this.editor.getShapeHandles(this.shape)\n\t\t\tif (!handles) {\n\t\t\t\tif (this.markId) this.editor.bailToMark(this.markId)\n\t\t\t\tthrow Error('No handles found')\n\t\t\t}\n\t\t\tconst lastHandle = last(handles)!\n\t\t\tthis.editor.setCurrentTool('select.dragging_handle', {\n\t\t\t\tshape: this.shape,\n\t\t\t\tisCreating: true,\n\t\t\t\tcreatingMarkId: this.markId,\n\t\t\t\t// remove the offset that we added to the handle when we created it\n\t\t\t\thandle: { ...lastHandle, x: lastHandle.x - 0.1, y: lastHandle.y - 0.1 },\n\t\t\t\tonInteractionEnd: 'line',\n\t\t\t})\n\t\t}\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\tthis.parent.transition('idle')\n\t\tif (this.markId) this.editor.bailToMark(this.markId)\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n\n\tcomplete() {\n\t\tthis.parent.transition('idle', { shapeId: this.shape.id })\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n\n\tcancel() {\n\t\tif (this.markId) this.editor.bailToMark(this.markId)\n\t\tthis.parent.transition('idle', { shapeId: this.shape.id })\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLLineShape,\n\tTLShapeId,\n\tVec,\n\tcreateShapeId,\n\tgetIndexAbove,\n\tcancelShapeCreationOnLongPress,\n\tlast,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n\tstructuredClone,\n} from '@tldraw/editor'\n\n// Minimum distance, in screen pixels, between two shift-clicked handles before we merge them\nconst MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES = 2\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\tshape = {} as TLLineShape\n\n\tmarkId: string | undefined\n\n\toverride onEnter(info: { shapeId?: TLShapeId }) {\n\t\tconst { inputs } = this.editor\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\tthis.markId = undefined\n\n\t\t// Previously created line shape that we might be extending\n\t\tconst shape = info.shapeId && this.editor.getShape<TLLineShape>(info.shapeId)\n\n\t\tif (shape && inputs.getShiftKey()) {\n\t\t\t// Extending a previous shape\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint(`creating_line:${shape.id}`)\n\t\t\tthis.shape = shape\n\n\t\t\tconst handles = this.editor.getShapeHandles(this.shape)\n\t\t\tif (!handles) return\n\n\t\t\tconst vertexHandles = handles.filter((h) => h.type === 'vertex').sort(sortByIndex)\n\t\t\tconst endHandle = vertexHandles[vertexHandles.length - 1]\n\t\t\tconst prevEndHandle = vertexHandles[vertexHandles.length - 2]\n\n\t\t\tconst shapePagePoint = Mat.applyToPoint(\n\t\t\t\tthis.editor.getShapeParentTransform(this.shape)!,\n\t\t\t\tnew Vec(this.shape.x, this.shape.y)\n\t\t\t)\n\t\t\t// nudge the point slightly to avoid zero-length lines\n\t\t\tconst nudgedPoint = Vec.Sub(currentPagePoint, shapePagePoint).addXY(0.1, 0.1)\n\t\t\tconst nextPoint = maybeSnapToGrid(nudgedPoint, this.editor)\n\t\t\tconst points = structuredClone(this.shape.props.points)\n\n\t\t\t// compare in screen space\n\t\t\tconst minDistance =\n\t\t\t\tMINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES / this.editor.getZoomLevel()\n\n\t\t\tif (\n\t\t\t\tVec.DistMin(endHandle, prevEndHandle, minDistance) ||\n\t\t\t\tVec.DistMin(nextPoint, endHandle, minDistance)\n\t\t\t) {\n\t\t\t\t// Don't add a new point if the distance between the last two points is too small\n\t\t\t\tpoints[endHandle.id] = {\n\t\t\t\t\tid: endHandle.id,\n\t\t\t\t\tindex: endHandle.index,\n\t\t\t\t\tx: nextPoint.x,\n\t\t\t\t\ty: nextPoint.y,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Add a new point\n\t\t\t\tconst nextIndex = getIndexAbove(endHandle.index)\n\t\t\t\tpoints[nextIndex] = {\n\t\t\t\t\tid: nextIndex,\n\t\t\t\t\tindex: nextIndex,\n\t\t\t\t\tx: nextPoint.x,\n\t\t\t\t\ty: nextPoint.y,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.editor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid: this.shape.id,\n\t\t\t\t\ttype: this.shape.type,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tpoints,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t])\n\t\t} else {\n\t\t\tconst id = createShapeId()\n\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint(`creating_line:${id}`)\n\n\t\t\tconst newPoint = maybeSnapToGrid(currentPagePoint, this.editor)\n\n\t\t\tthis.editor.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tscale: this.editor.getResizeScaleFactor(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t])\n\n\t\t\tif (!this.editor.getShape(id)) {\n\t\t\t\tthis.cancel()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.editor.select(id)\n\t\t\tthis.shape = this.editor.getShape(id)!\n\t\t}\n\t}\n\n\toverride onPointerMove() {\n\t\tif (!this.shape) return\n\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tconst handles = this.editor.getShapeHandles(this.shape)\n\t\t\tif (!handles) {\n\t\t\t\tif (this.markId) this.editor.bailToMark(this.markId)\n\t\t\t\tthrow Error('No handles found')\n\t\t\t}\n\t\t\tconst lastHandle = last(handles)!\n\t\t\tthis.editor.setCurrentTool('select.dragging_handle', {\n\t\t\t\tshape: this.shape,\n\t\t\t\tisCreating: true,\n\t\t\t\tcreatingMarkId: this.markId,\n\t\t\t\t// remove the offset that we added to the handle when we created it\n\t\t\t\thandle: { ...lastHandle, x: lastHandle.x - 0.1, y: lastHandle.y - 0.1 },\n\t\t\t\tonInteractionEnd: 'line',\n\t\t\t})\n\t\t}\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onLongPress() {\n\t\tcancelShapeCreationOnLongPress(this.editor, () => this.cancel())\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\tthis.parent.transition('idle')\n\t\tif (this.markId) this.editor.bailToMark(this.markId)\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n\n\tcomplete() {\n\t\tthis.parent.transition('idle', { shapeId: this.shape.id })\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n\n\tcancel() {\n\t\tif (this.markId) this.editor.bailToMark(this.markId)\n\t\tthis.parent.transition('idle', { shapeId: this.shape.id })\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import {
3
3
  Box,
4
- DefaultFontFamilies,
5
4
  EMPTY_ARRAY,
6
5
  Group2d,
7
6
  Rectangle2d,
@@ -16,6 +15,7 @@ import {
16
15
  noteShapeMigrations,
17
16
  noteShapeProps,
18
17
  resizeScaled,
18
+ resolveLineHeightPx,
19
19
  rng,
20
20
  toRichText,
21
21
  useColorMode,
@@ -126,7 +126,7 @@ class NoteShapeUtil extends ShapeUtil {
126
126
  fontSizeAdjustment: 1,
127
127
  url: "",
128
128
  scale: 1,
129
- textFirstEditedBy: null
129
+ textLastEditedBy: null
130
130
  };
131
131
  }
132
132
  getGeometry(shape) {
@@ -222,7 +222,7 @@ class NoteShapeUtil extends ShapeUtil {
222
222
  return renderPlaintextFromRichText(this.editor, shape.props.richText);
223
223
  }
224
224
  getReferencedUserIds(shape) {
225
- return shape.props.textFirstEditedBy ? [shape.props.textFirstEditedBy] : [];
225
+ return shape.props.textLastEditedBy ? [shape.props.textLastEditedBy] : [];
226
226
  }
227
227
  getFontFaces(shape) {
228
228
  const fonts = isEmptyRichText(shape.props.richText) ? [] : getFontsFromRichText(this.editor, shape.props.richText, {
@@ -230,7 +230,7 @@ class NoteShapeUtil extends ShapeUtil {
230
230
  weight: "normal",
231
231
  style: "normal"
232
232
  });
233
- if (shape.props.textFirstEditedBy && !isEmptyRichText(shape.props.richText)) {
233
+ if (shape.props.textLastEditedBy && !isEmptyRichText(shape.props.richText)) {
234
234
  return [...fonts, DefaultFontFaces.tldraw_sans.normal.normal];
235
235
  }
236
236
  const themeFaces = getThemeFontFaces(this.editor.getCurrentTheme(), shape.props.font);
@@ -239,7 +239,7 @@ class NoteShapeUtil extends ShapeUtil {
239
239
  }
240
240
  component(shape) {
241
241
  const { id, type, props } = shape;
242
- const { scale, richText, fontSizeAdjustment, textFirstEditedBy } = props;
242
+ const { scale, richText, fontSizeAdjustment, textLastEditedBy } = props;
243
243
  const handleKeyDown = useNoteKeydownHandler(id);
244
244
  const rotation = useValue(
245
245
  "shape rotation",
@@ -257,12 +257,12 @@ class NoteShapeUtil extends ShapeUtil {
257
257
  const attribution = useValue(
258
258
  "attribution",
259
259
  () => {
260
- if (!textFirstEditedBy || isEmpty) return null;
261
- const name = this.editor.getAttributionDisplayName(textFirstEditedBy);
260
+ if (!textLastEditedBy || isEmpty) return null;
261
+ const name = this.editor.getAttributionDisplayName(textLastEditedBy);
262
262
  if (!name) return null;
263
263
  return { short: name.split(" ")[0], full: name };
264
264
  },
265
- [textFirstEditedBy, isEmpty, this.editor]
265
+ [textLastEditedBy, isEmpty, this.editor]
266
266
  );
267
267
  return /* @__PURE__ */ jsxs(Fragment, { children: [
268
268
  /* @__PURE__ */ jsxs(
@@ -352,9 +352,8 @@ class NoteShapeUtil extends ShapeUtil {
352
352
  ] })
353
353
  ] })
354
354
  });
355
- const { textFirstEditedBy } = shape.props;
356
- const attributionFirstName = textFirstEditedBy && !isEmptyRichText(shape.props.richText) ? this.editor.getAttributionDisplayName(textFirstEditedBy)?.split(" ")[0] : null;
357
- const attributionName = attributionFirstName ? truncateAttributionForSvg(this.editor, attributionFirstName, dv.noteWidth) : null;
355
+ const { textLastEditedBy } = shape.props;
356
+ const attributionName = textLastEditedBy && !isEmptyRichText(shape.props.richText) ? this.editor.getAttributionDisplayName(textLastEditedBy)?.split(" ")[0] ?? null : null;
358
357
  return /* @__PURE__ */ jsxs(Fragment, { children: [
359
358
  ctx.isDarkMode ? null : /* @__PURE__ */ jsx(
360
359
  "rect",
@@ -383,16 +382,25 @@ class NoteShapeUtil extends ShapeUtil {
383
382
  }
384
383
  ),
385
384
  attributionName && /* @__PURE__ */ jsx(
386
- "text",
385
+ "foreignObject",
387
386
  {
388
- x: dv.noteWidth - 8,
389
- y: bounds.h - 6,
390
- textAnchor: "end",
391
- fontFamily: DefaultFontFamilies["sans"],
392
- fontSize: 11,
393
- fill: dv.labelColor,
394
- opacity: 0.6,
395
- children: attributionName
387
+ x: 0,
388
+ y: 0,
389
+ width: dv.noteWidth,
390
+ height: bounds.h,
391
+ className: "tl-export-embed-styles",
392
+ children: /* @__PURE__ */ jsx("div", { style: { position: "relative", width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
393
+ "div",
394
+ {
395
+ className: "tl-note__attribution",
396
+ style: {
397
+ fontSize: 11,
398
+ color: dv.labelColor,
399
+ opacity: 0.6
400
+ },
401
+ children: attributionName
402
+ }
403
+ ) })
396
404
  }
397
405
  )
398
406
  ] });
@@ -410,12 +418,12 @@ class NoteShapeUtil extends ShapeUtil {
410
418
  if (isEmptyRichText(next.props.richText)) {
411
419
  shape = {
412
420
  ...shape,
413
- props: { ...shape.props, textFirstEditedBy: null }
421
+ props: { ...shape.props, textLastEditedBy: null }
414
422
  };
415
- } else if (!prev.props.textFirstEditedBy) {
423
+ } else {
416
424
  shape = {
417
425
  ...shape,
418
- props: { ...shape.props, textFirstEditedBy: this.editor.getAttributionUserId() }
426
+ props: { ...shape.props, textLastEditedBy: this.editor.getAttributionUserId() }
419
427
  };
420
428
  }
421
429
  }
@@ -460,7 +468,7 @@ class NoteShapeUtil extends ShapeUtil {
460
468
  const dv = getDisplayValues(this, shape);
461
469
  const { richText } = shape.props;
462
470
  if (isEmptyRichText(richText)) {
463
- const minHeight = dv.labelFontSize * dv.labelLineHeight + dv.labelPadding * 2;
471
+ const minHeight = resolveLineHeightPx(dv.labelFontSize, dv.labelLineHeight) + dv.labelPadding * 2;
464
472
  return { labelHeight: minHeight, labelWidth: 100, fontSizeAdjustment: 1 };
465
473
  }
466
474
  const unadjustedFontSize = dv.labelFontSize;
@@ -553,24 +561,6 @@ function useNoteKeydownHandler(id) {
553
561
  function getNoteHeight(shape, noteHeight) {
554
562
  return (noteHeight + shape.props.growY) * shape.props.scale;
555
563
  }
556
- const ATTRIBUTION_MAX_WIDTH_RATIO = 0.6;
557
- function truncateAttributionForSvg(editor, name, noteWidth) {
558
- if (process.env.NODE_ENV === "test") return name;
559
- const spans = editor.textMeasure.measureTextSpans(name, {
560
- fontSize: 11,
561
- fontFamily: DefaultFontFamilies["sans"],
562
- textAlign: "end",
563
- width: noteWidth * ATTRIBUTION_MAX_WIDTH_RATIO,
564
- height: 16,
565
- padding: 0,
566
- lineHeight: 1,
567
- fontStyle: "normal",
568
- fontWeight: "normal",
569
- overflow: "truncate-ellipsis"
570
- });
571
- if (spans.length === 0) return name;
572
- return spans.map((s) => s.text).join("");
573
- }
574
564
  function getNoteShadow(id, rotation, scale) {
575
565
  const random = rng(id);
576
566
  const lift = Math.abs(random()) + 0.5;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/note/NoteShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBox,\n\tDefaultFontFamilies,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tIndexKey,\n\tRectangle2d,\n\tSafeId,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLHandle,\n\tTLNoteShape,\n\tTLNoteShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapeId,\n\tVec,\n\tWeakCache,\n\texhaustiveSwitchError,\n\tgetColorValue,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\tnoteShapeMigrations,\n\tnoteShapeProps,\n\tresizeScaled,\n\trng,\n\ttoRichText,\n\tuseColorMode,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useCallback, useContext } from 'react'\nimport { startEditingShapeWithRichText } from '../../tools/SelectTool/selectHelpers'\nimport { TldrawUiTooltip } from '../../ui/components/primitives/TldrawUiTooltip'\nimport { TranslationsContext } from '../../ui/hooks/useTranslation/useTranslation'\nimport {\n\tisEditingRichTextList,\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { isRightToLeftLanguage } from '../../utils/text/text'\nimport {\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tTEXT_PROPS,\n\tgetFontFamily,\n} from '../shared/default-shape-constants'\nimport { DefaultFontFaces, getThemeFontFaces } from '../shared/defaultFonts'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { useEfficientZoomThreshold } from '../shared/useEfficientZoomThreshold'\nimport { CLONE_HANDLE_MARGIN, getNoteShapeForAdjacentPosition } from './noteHelpers'\n\nconst NOTE_SHAPE_HORIZONTAL_ALIGNS = Object.freeze({\n\tstart: 'start',\n\tmiddle: 'center',\n\tend: 'end',\n\t'start-legacy': 'start',\n\t'end-legacy': 'end',\n\t'middle-legacy': 'center',\n} as const)\n\nconst NOTE_SHAPE_VERTICAL_ALIGNS = Object.freeze({\n\tstart: 'start',\n\tmiddle: 'middle',\n\tend: 'end',\n} as const)\n\n/** @public */\nexport interface NoteShapeUtilDisplayValues {\n\tnoteWidth: number\n\tnoteHeight: number\n\tnoteBackgroundColor: string\n\tborderColor: string\n\tborderWidth: number\n\tlabelColor: string\n\tlabelFontFamily: string\n\tlabelFontSize: number\n\tlabelLineHeight: number\n\tlabelFontWeight: string\n\tlabelFontVariant: string\n\tlabelFontStyle: string\n\tlabelPadding: number\n\tlabelHorizontalAlign: 'start' | 'center' | 'end'\n\tlabelVerticalAlign: 'start' | 'middle' | 'end'\n}\n\n/** @public */\nexport interface NoteShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLNoteShape,\n\tNoteShapeUtilDisplayValues\n> {\n\t/**\n\t * How should the note shape resize? By default it does not resize (except automatically based on its text content),\n\t * but you can set it to be user-resizable using scale.\n\t */\n\tresizeMode: 'none' | 'scale'\n}\n\n/** @public */\nexport class NoteShapeUtil extends ShapeUtil<TLNoteShape> {\n\tstatic override type = 'note' as const\n\tstatic override props = noteShapeProps\n\tstatic override migrations = noteShapeMigrations\n\n\toverride options: NoteShapeOptions = {\n\t\tresizeMode: 'none',\n\t\tgetDefaultDisplayValues(_editor, shape, theme, colorMode): NoteShapeUtilDisplayValues {\n\t\t\tconst { color, labelColor, font, size, align, verticalAlign } = shape.props\n\t\t\tconst colors = theme.colors[colorMode]\n\t\t\treturn {\n\t\t\t\tnoteWidth: 200,\n\t\t\t\tnoteHeight: 200,\n\t\t\t\tnoteBackgroundColor: getColorValue(colors, color, 'noteFill'),\n\t\t\t\tborderColor: colors.noteBorder,\n\t\t\t\tborderWidth: 2,\n\t\t\t\tlabelColor:\n\t\t\t\t\tlabelColor === 'black'\n\t\t\t\t\t\t? getColorValue(colors, color, 'noteText')\n\t\t\t\t\t\t: getColorValue(colors, labelColor, 'fill'),\n\t\t\t\tlabelFontFamily: getFontFamily(theme, font),\n\t\t\t\tlabelFontSize: theme.fontSize * LABEL_FONT_SIZES[size],\n\t\t\t\tlabelLineHeight: theme.lineHeight,\n\t\t\t\tlabelFontWeight: TEXT_PROPS.fontWeight,\n\t\t\t\tlabelFontVariant: TEXT_PROPS.fontVariant,\n\t\t\t\tlabelFontStyle: TEXT_PROPS.fontStyle,\n\t\t\t\tlabelPadding: LABEL_PADDING,\n\t\t\t\tlabelHorizontalAlign: NOTE_SHAPE_HORIZONTAL_ALIGNS[align],\n\t\t\t\tlabelVerticalAlign: NOTE_SHAPE_VERTICAL_ALIGNS[verticalAlign],\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<NoteShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride canEdit(shape: TLNoteShape) {\n\t\treturn true\n\t}\n\toverride hideResizeHandles(shape: TLNoteShape) {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked(shape: TLNoteShape) {\n\t\treturn this.options.resizeMode === 'scale'\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLNoteShape) {\n\t\treturn false\n\t}\n\n\tgetDefaultProps(): TLNoteShape['props'] {\n\t\treturn {\n\t\t\tcolor: 'black',\n\t\t\trichText: toRichText(''),\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tlabelColor: 'black',\n\t\t\tgrowY: 0,\n\t\t\tfontSizeAdjustment: 1,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\t\t\ttextFirstEditedBy: null,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLNoteShape) {\n\t\tconst { labelHeight, labelWidth } = this.getLabelSize(shape)\n\t\tconst { scale } = shape.props\n\n\t\tconst dv = getDisplayValues(this, shape)\n\n\t\tconst lh = labelHeight * scale\n\t\tconst lw = labelWidth * scale\n\t\tconst nw = dv.noteWidth * scale\n\t\tconst nh = getNoteHeight(shape, dv.noteHeight)\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({ width: nw, height: nh, isFilled: true }),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tdv.labelHorizontalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: dv.labelHorizontalAlign === 'end'\n\t\t\t\t\t\t\t\t? nw - lw\n\t\t\t\t\t\t\t\t: (nw - lw) / 2,\n\t\t\t\t\ty:\n\t\t\t\t\t\tdv.labelVerticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: dv.labelVerticalAlign === 'end'\n\t\t\t\t\t\t\t\t? nh - lh\n\t\t\t\t\t\t\t\t: (nh - lh) / 2,\n\t\t\t\t\twidth: lw,\n\t\t\t\t\theight: lh,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandles(shape: TLNoteShape): TLHandle[] {\n\t\tconst { scale } = shape.props\n\t\tconst isCoarsePointer = this.editor.getInstanceState().isCoarsePointer\n\t\tif (isCoarsePointer) return []\n\n\t\tconst zoom = this.editor.getEfficientZoomLevel()\n\t\tif (zoom * scale < 0.25) return []\n\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst nh = getNoteHeight(shape, dv.noteHeight)\n\t\tconst nw = dv.noteWidth * scale\n\t\tconst offset = (CLONE_HANDLE_MARGIN / zoom) * scale\n\n\t\tif (zoom * scale < 0.5) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'bottom',\n\t\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\t\ttype: 'clone',\n\t\t\t\t\tx: nw / 2,\n\t\t\t\t\ty: nh + offset,\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid: 'top',\n\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: -offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'right',\n\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw + offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'bottom',\n\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: nh + offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'left',\n\t\t\t\tindex: 'a4' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: -offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t]\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn resizeScaled(shape, info)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride getText(shape: TLNoteShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getReferencedUserIds(shape: TLNoteShape) {\n\t\treturn shape.props.textFirstEditedBy ? [shape.props.textFirstEditedBy] : []\n\t}\n\n\toverride getFontFaces(shape: TLNoteShape) {\n\t\tconst fonts = isEmptyRichText(shape.props.richText)\n\t\t\t? []\n\t\t\t: getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\t\t\tweight: 'normal',\n\t\t\t\t\tstyle: 'normal',\n\t\t\t\t})\n\n\t\tif (shape.props.textFirstEditedBy && !isEmptyRichText(shape.props.richText)) {\n\t\t\treturn [...fonts, DefaultFontFaces.tldraw_sans.normal.normal]\n\t\t}\n\t\tconst themeFaces = getThemeFontFaces(this.editor.getCurrentTheme(), shape.props.font)\n\t\tif (themeFaces) return [...themeFaces, ...fonts]\n\n\t\treturn fonts.length ? fonts : EMPTY_ARRAY\n\t}\n\n\tcomponent(shape: TLNoteShape) {\n\t\tconst { id, type, props } = shape\n\t\tconst { scale, richText, fontSizeAdjustment, textFirstEditedBy } = props\n\n\t\tconst handleKeyDown = useNoteKeydownHandler(id)\n\n\t\tconst rotation = useValue(\n\t\t\t'shape rotation',\n\t\t\t() => this.editor.getShapePageTransform(id)?.rotation() ?? 0,\n\t\t\t[this.editor]\n\t\t)\n\n\t\tconst colorMode = useColorMode()\n\t\tconst dv = getDisplayValues(this, shape, colorMode)\n\n\t\tconst nw = dv.noteWidth * scale\n\t\tconst nh = getNoteHeight(shape, dv.noteHeight)\n\n\t\t// Shadows are hidden when zoomed out far enough; the cheap borderBottom takes over.\n\t\tconst hideShadows = useEfficientZoomThreshold(0.25 / scale)\n\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\n\t\tconst isReadyForEditing = useIsReadyForEditing(this.editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(richText)\n\n\t\tconst attribution = useValue(\n\t\t\t'attribution',\n\t\t\t() => {\n\t\t\t\tif (!textFirstEditedBy || isEmpty) return null\n\t\t\t\tconst name = this.editor.getAttributionDisplayName(textFirstEditedBy)\n\t\t\t\tif (!name) return null\n\t\t\t\treturn { short: name.split(' ')[0], full: name }\n\t\t\t},\n\t\t\t[textFirstEditedBy, isEmpty, this.editor]\n\t\t)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div\n\t\t\t\t\tid={id}\n\t\t\t\t\tclassName=\"tl-note__container\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: nw,\n\t\t\t\t\t\theight: nh,\n\t\t\t\t\t\tbackgroundColor: dv.noteBackgroundColor,\n\t\t\t\t\t\tborderBottom: hideShadows\n\t\t\t\t\t\t\t? `${dv.borderWidth * scale}px solid ${dv.borderColor}`\n\t\t\t\t\t\t\t: 'none',\n\t\t\t\t\t\tboxShadow: hideShadows ? 'none' : getNoteShadow(shape.id, rotation, scale),\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{attribution && (\n\t\t\t\t\t\t<TldrawUiTooltip content={attribution.full} side=\"bottom\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tl-note__attribution\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t['--note-attribution-scale' as string]: scale,\n\t\t\t\t\t\t\t\t\tfontSize: 11 * scale,\n\t\t\t\t\t\t\t\t\tcolor: dv.labelColor,\n\t\t\t\t\t\t\t\t\topacity: 0.6,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{attribution.short}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TldrawUiTooltip>\n\t\t\t\t\t)}\n\t\t\t\t\t{(isSelected || isReadyForEditing || !isEmpty) && (\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfontFamily={dv.labelFontFamily}\n\t\t\t\t\t\t\tfontSize={(fontSizeAdjustment ?? 1) * dv.labelFontSize}\n\t\t\t\t\t\t\tlineHeight={dv.labelLineHeight}\n\t\t\t\t\t\t\ttextAlign={dv.labelHorizontalAlign}\n\t\t\t\t\t\t\tverticalAlign={dv.labelVerticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\t\tlabelColor={dv.labelColor}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t\tpadding={dv.labelPadding}\n\t\t\t\t\t\t\thasCustomTabBehavior\n\t\t\t\t\t\t\tshowTextOutline={false}\n\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tscale !== 1\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\ttransform: `scale(${scale})`,\n\t\t\t\t\t\t\t\t\t\t\ttransformOrigin: 'top left',\n\t\t\t\t\t\t\t\t\t\t\twidth: dv.noteWidth,\n\t\t\t\t\t\t\t\t\t\t\theight: dv.noteHeight + shape.props.growY,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLNoteShape): Path2D {\n\t\tconst { scale } = shape.props\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst path = new Path2D()\n\t\tpath.rect(0, 0, dv.noteWidth * scale, getNoteHeight(shape, dv.noteHeight))\n\t\treturn path\n\t}\n\n\toverride toSvg(shape: TLNoteShape, ctx: SvgExportContext) {\n\t\tconst dv = getDisplayValues(this, shape, ctx.colorMode)\n\t\tconst bounds = new Box(0, 0, dv.noteWidth, dv.noteHeight + shape.props.growY)\n\n\t\tconst filterId = `note-shadow-${shape.id.replace(/:/g, '_')}` as SafeId\n\n\t\tctx.addExportDef({\n\t\t\tkey: filterId,\n\t\t\tgetElement: () => (\n\t\t\t\t<filter id={filterId} x=\"-10%\" y=\"-10%\" width=\"130%\" height=\"150%\">\n\t\t\t\t\t<feMorphology in=\"SourceAlpha\" operator=\"erode\" radius=\"3\" result=\"erode1\" />\n\t\t\t\t\t<feGaussianBlur in=\"erode1\" stdDeviation=\"3\" result=\"blur1\" />\n\t\t\t\t\t<feOffset in=\"blur1\" dy=\"3\" result=\"offsetBlur1\" />\n\t\t\t\t\t<feComponentTransfer in=\"offsetBlur1\" result=\"shadow1\">\n\t\t\t\t\t\t<feFuncA type=\"linear\" slope=\"0.5\" />\n\t\t\t\t\t</feComponentTransfer>\n\t\t\t\t\t<feMorphology in=\"SourceAlpha\" operator=\"erode\" radius=\"10\" result=\"erode2\" />\n\t\t\t\t\t<feGaussianBlur in=\"erode2\" stdDeviation=\"6\" result=\"blur2\" />\n\t\t\t\t\t<feOffset in=\"blur2\" dy=\"6\" result=\"offsetBlur2\" />\n\t\t\t\t\t<feComponentTransfer in=\"offsetBlur2\" result=\"shadow2\">\n\t\t\t\t\t\t<feFuncA type=\"linear\" slope=\"0.5\" />\n\t\t\t\t\t</feComponentTransfer>\n\t\t\t\t\t<feMerge>\n\t\t\t\t\t\t<feMergeNode in=\"shadow1\" />\n\t\t\t\t\t\t<feMergeNode in=\"shadow2\" />\n\t\t\t\t\t\t<feMergeNode in=\"SourceGraphic\" />\n\t\t\t\t\t</feMerge>\n\t\t\t\t</filter>\n\t\t\t),\n\t\t})\n\n\t\tconst { textFirstEditedBy } = shape.props\n\t\tconst attributionFirstName =\n\t\t\ttextFirstEditedBy && !isEmptyRichText(shape.props.richText)\n\t\t\t\t? this.editor.getAttributionDisplayName(textFirstEditedBy)?.split(' ')[0]\n\t\t\t\t: null\n\t\tconst attributionName = attributionFirstName\n\t\t\t? truncateAttributionForSvg(this.editor, attributionFirstName, dv.noteWidth)\n\t\t\t: null\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ctx.isDarkMode ? null : (\n\t\t\t\t\t<rect\n\t\t\t\t\t\trx={1}\n\t\t\t\t\t\twidth={dv.noteWidth}\n\t\t\t\t\t\theight={bounds.h}\n\t\t\t\t\t\tfill={dv.noteBackgroundColor}\n\t\t\t\t\t\tfilter={`url(#${filterId})`}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<rect rx={1} width={dv.noteWidth} height={bounds.h} fill={dv.noteBackgroundColor} />\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={(shape.props.fontSizeAdjustment ?? 1) * dv.labelFontSize}\n\t\t\t\t\tfontFamily={dv.labelFontFamily}\n\t\t\t\t\tlineHeight={dv.labelLineHeight}\n\t\t\t\t\ttextAlign={dv.labelHorizontalAlign}\n\t\t\t\t\tverticalAlign={dv.labelVerticalAlign}\n\t\t\t\t\trichText={shape.props.richText}\n\t\t\t\t\tlabelColor={dv.labelColor}\n\t\t\t\t\tbounds={bounds}\n\t\t\t\t\tpadding={dv.labelPadding}\n\t\t\t\t\tshowTextOutline={false}\n\t\t\t\t/>\n\t\t\t\t{attributionName && (\n\t\t\t\t\t<text\n\t\t\t\t\t\tx={dv.noteWidth - 8}\n\t\t\t\t\t\ty={bounds.h - 6}\n\t\t\t\t\t\ttextAnchor=\"end\"\n\t\t\t\t\t\tfontFamily={DefaultFontFamilies['sans']}\n\t\t\t\t\t\tfontSize={11}\n\t\t\t\t\t\tfill={dv.labelColor}\n\t\t\t\t\t\topacity={0.6}\n\t\t\t\t\t>\n\t\t\t\t\t\t{attributionName}\n\t\t\t\t\t</text>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride onBeforeCreate(next: TLNoteShape) {\n\t\treturn this.getNoteSizeAdjustments(next)\n\t}\n\n\toverride onBeforeUpdate(prev: TLNoteShape, next: TLNoteShape) {\n\t\tconst richTextChanged = !isEqual(prev.props.richText, next.props.richText)\n\n\t\tif (\n\t\t\t!richTextChanged &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tlet shape = next\n\t\tif (richTextChanged) {\n\t\t\tif (isEmptyRichText(next.props.richText)) {\n\t\t\t\tshape = {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: { ...shape.props, textFirstEditedBy: null },\n\t\t\t\t}\n\t\t\t} else if (!prev.props.textFirstEditedBy) {\n\t\t\t\tshape = {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: { ...shape.props, textFirstEditedBy: this.editor.getAttributionUserId() },\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.getNoteSizeAdjustments(shape) ?? (richTextChanged ? shape : undefined)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLNoteShape,\n\t\tendShape: TLNoteShape,\n\t\tt: number\n\t): TLNoteShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n\n\t/**\n\t * Get the growY and fontSizeAdjustment for a shape.\n\t */\n\tprivate getNoteSizeAdjustments(shape: TLNoteShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst { labelHeight, fontSizeAdjustment } = this.getLabelSize(shape)\n\t\t// When the label height is more than the height of the shape, we add extra height to it\n\t\tconst growY = Math.max(0, labelHeight - dv.noteHeight)\n\n\t\tif (growY !== shape.props.growY || fontSizeAdjustment !== shape.props.fontSizeAdjustment) {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tgrowY,\n\t\t\t\t\tfontSizeAdjustment,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\treturn undefined\n\t}\n\n\tprivate _labelSizesForNoteCache = new WeakCache<\n\t\tTLShape,\n\t\t{ labelHeight: number; labelWidth: number; fontSizeAdjustment: number }\n\t>()\n\n\t/**\n\t * Get the cached label size for the shape.\n\t */\n\tprivate getLabelSize(shape: TLNoteShape) {\n\t\treturn this._labelSizesForNoteCache.get(shape, () => this.measureNoteLabelSize(shape))\n\t}\n\n\t/**\n\t * Expensively measure the label size for a note shape.\n\t */\n\tprivate measureNoteLabelSize(shape: TLNoteShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst { richText } = shape.props\n\n\t\tif (isEmptyRichText(richText)) {\n\t\t\tconst minHeight = dv.labelFontSize * dv.labelLineHeight + dv.labelPadding * 2\n\t\t\treturn { labelHeight: minHeight, labelWidth: 100, fontSizeAdjustment: 1 }\n\t\t}\n\n\t\tconst unadjustedFontSize = dv.labelFontSize\n\n\t\tlet fontSizeAdjustment = unadjustedFontSize\n\t\tlet iterations = 0\n\t\tlet labelHeight = dv.noteHeight\n\t\tlet labelWidth = dv.noteWidth\n\n\t\t// N.B. For some note shapes with text like 'hjhjhjhjhjhjhjhj', you'll run into\n\t\t// some text measurement fuzziness where the browser swears there's no overflow (scrollWidth === width)\n\t\t// but really there is when you enable overflow-wrap again. This helps account for that little bit\n\t\t// of give.\n\t\tconst FUZZ = 1\n\n\t\t// We slightly make the font smaller if the text is too big for the note, width-wise.\n\t\tdo {\n\t\t\tfontSizeAdjustment = Math.min(unadjustedFontSize, unadjustedFontSize - iterations)\n\t\t\tconst html = renderHtmlFromRichTextForMeasurement(this.editor, richText)\n\t\t\tconst nextTextSize = this.editor.textMeasure.measureHtml(html, {\n\t\t\t\t...TEXT_PROPS,\n\t\t\t\tlineHeight: dv.labelLineHeight,\n\t\t\t\tfontFamily: dv.labelFontFamily,\n\t\t\t\tfontSize: fontSizeAdjustment,\n\t\t\t\tmaxWidth: dv.noteWidth - dv.labelPadding * 2 - FUZZ,\n\t\t\t\tdisableOverflowWrapBreaking: true,\n\t\t\t\tmeasureScrollWidth: true,\n\t\t\t})\n\n\t\t\tlabelHeight = nextTextSize.h + dv.labelPadding * 2\n\t\t\tlabelWidth = nextTextSize.w + dv.labelPadding * 2\n\n\t\t\tif (fontSizeAdjustment <= 14) {\n\t\t\t\t// Too small, just rely now on CSS `overflow-wrap: break-word`\n\t\t\t\t// We need to recalculate the text measurement here with break-word enabled.\n\t\t\t\tconst html = renderHtmlFromRichTextForMeasurement(this.editor, richText)\n\t\t\t\tconst nextTextSizeWithOverflowBreak = this.editor.textMeasure.measureHtml(html, {\n\t\t\t\t\t...TEXT_PROPS,\n\t\t\t\t\tlineHeight: dv.labelLineHeight,\n\t\t\t\t\tfontFamily: dv.labelFontFamily,\n\t\t\t\t\tfontSize: fontSizeAdjustment,\n\t\t\t\t\tmaxWidth: dv.noteWidth - dv.labelPadding * 2 - FUZZ,\n\t\t\t\t})\n\t\t\t\tlabelHeight = nextTextSizeWithOverflowBreak.h + dv.labelPadding * 2\n\t\t\t\tlabelWidth = nextTextSizeWithOverflowBreak.w + dv.labelPadding * 2\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif (nextTextSize.scrollWidth.toFixed(0) === nextTextSize.w.toFixed(0)) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t} while (iterations++ < 50)\n\n\t\treturn {\n\t\t\tlabelHeight: labelHeight,\n\t\t\tlabelWidth: labelWidth,\n\t\t\tfontSizeAdjustment:\n\t\t\t\tfontSizeAdjustment === unadjustedFontSize ? 1 : fontSizeAdjustment / unadjustedFontSize,\n\t\t}\n\t}\n}\n\nfunction useNoteKeydownHandler(id: TLShapeId) {\n\tconst editor = useEditor()\n\t// Try to get the translation context, but fallback to ltr if it doesn't exist\n\tconst translation = useContext(TranslationsContext)\n\n\treturn useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tconst shape = editor.getShape<TLNoteShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst isTab = e.key === 'Tab'\n\t\t\tconst isCmdEnter = (e.metaKey || e.ctrlKey) && e.key === 'Enter'\n\n\t\t\tif (isTab && isEditingRichTextList(editor)) {\n\t\t\t\t// In a list, let the rich text editor indent the item instead of\n\t\t\t\t// creating a new note. Prevent default so Tab doesn't move focus out\n\t\t\t\t// of the editor when the item can't be indented (e.g. the first item).\n\t\t\t\te.preventDefault()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (isTab || isCmdEnter) {\n\t\t\t\te.preventDefault()\n\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\t\tconst pageRotation = pageTransform.rotation()\n\n\t\t\t\t// Based on the inputs, calculate the offset to the next note\n\t\t\t\t// tab controls x axis (shift inverts direction set by RTL)\n\t\t\t\t// cmd enter is the y axis (shift inverts direction)\n\t\t\t\tconst isRTL = !!(\n\t\t\t\t\ttranslation?.dir === 'rtl' ||\n\t\t\t\t\t// todo: can we check a partial of the text, so that we don't have to render the whole thing?\n\t\t\t\t\tisRightToLeftLanguage(renderPlaintextFromRichText(editor, shape.props.richText))\n\t\t\t\t)\n\n\t\t\t\tconst noteUtil = editor.getShapeUtil(shape) as NoteShapeUtil\n\t\t\t\tconst dv = getDisplayValues(noteUtil, shape)\n\n\t\t\t\tconst noteOffset = isTab\n\t\t\t\t\t? dv.noteWidth + editor.options.adjacentShapeMargin\n\t\t\t\t\t: dv.noteHeight +\n\t\t\t\t\t\teditor.options.adjacentShapeMargin +\n\t\t\t\t\t\t// If we're growing down, we need to account for the current shape's growY\n\t\t\t\t\t\t(isCmdEnter && !e.shiftKey ? shape.props.growY : 0)\n\t\t\t\tconst offsetLength = noteOffset * shape.props.scale\n\n\t\t\t\tconst adjacentCenter = new Vec(\n\t\t\t\t\tisTab ? (e.shiftKey != isRTL ? -1 : 1) : 0,\n\t\t\t\t\tisCmdEnter ? (e.shiftKey ? -1 : 1) : 0\n\t\t\t\t)\n\t\t\t\t\t.mul(offsetLength)\n\t\t\t\t\t.add(new Vec(dv.noteWidth / 2, dv.noteHeight / 2).mul(shape.props.scale))\n\t\t\t\t\t.rot(pageRotation)\n\t\t\t\t\t.add(pageTransform.point())\n\n\t\t\t\tconst newNote = getNoteShapeForAdjacentPosition(editor, {\n\t\t\t\t\tshape,\n\t\t\t\t\tcenter: adjacentCenter,\n\t\t\t\t\tpageRotation,\n\t\t\t\t\tnoteWidth: dv.noteWidth,\n\t\t\t\t\tnoteHeight: dv.noteHeight,\n\t\t\t\t})\n\n\t\t\t\tif (newNote) {\n\t\t\t\t\tstartEditingShapeWithRichText(editor, newNote, { selectAll: true })\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[id, editor, translation?.dir]\n\t)\n}\n\nfunction getNoteHeight(shape: TLNoteShape, noteHeight: number) {\n\treturn (noteHeight + shape.props.growY) * shape.props.scale\n}\n\n// Matches `.tl-note__attribution { max-width: 60% }` so SVG export truncates the same way.\nconst ATTRIBUTION_MAX_WIDTH_RATIO = 0.6\n\nfunction truncateAttributionForSvg(editor: Editor, name: string, noteWidth: number) {\n\tif (process.env.NODE_ENV === 'test') return name\n\tconst spans = editor.textMeasure.measureTextSpans(name, {\n\t\tfontSize: 11,\n\t\tfontFamily: DefaultFontFamilies['sans'],\n\t\ttextAlign: 'end',\n\t\twidth: noteWidth * ATTRIBUTION_MAX_WIDTH_RATIO,\n\t\theight: 16,\n\t\tpadding: 0,\n\t\tlineHeight: 1,\n\t\tfontStyle: 'normal',\n\t\tfontWeight: 'normal',\n\t\toverflow: 'truncate-ellipsis',\n\t})\n\tif (spans.length === 0) return name\n\treturn spans.map((s) => s.text).join('')\n}\n\nfunction getNoteShadow(id: string, rotation: number, scale: number) {\n\tconst random = rng(id) // seeded based on id\n\tconst lift = Math.abs(random()) + 0.5 // 0 to 1.5\n\tconst oy = Math.cos(rotation)\n\tconst a = 5 * scale\n\tconst b = 4 * scale\n\tconst c = 6 * scale\n\tconst d = 7 * scale\n\t// Clamped so shadow never goes above the note at small scales (e.g. dynamic size mode at high zoom)\n\treturn `0px ${Math.max(0, a - lift)}px ${a}px -${a}px rgba(15, 23, 31, .6),\n\t0px ${(b + lift * d) * Math.max(0, oy)}px ${c + lift * d}px -${b + lift * c}px rgba(15, 23, 31, ${(0.3 + lift * 0.1).toFixed(2)}),\n\t0px ${48 * scale}px ${10 * scale}px -${10 * scale}px inset rgba(15, 23, 44, ${((0.022 + random() * 0.005) * ((1 + oy) / 2)).toFixed(2)})`\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBox,\n\tEMPTY_ARRAY,\n\tGroup2d,\n\tIndexKey,\n\tRectangle2d,\n\tSafeId,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLHandle,\n\tTLNoteShape,\n\tTLNoteShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapeId,\n\tVec,\n\tWeakCache,\n\texhaustiveSwitchError,\n\tgetColorValue,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\tnoteShapeMigrations,\n\tnoteShapeProps,\n\tresizeScaled,\n\tresolveLineHeightPx,\n\trng,\n\ttoRichText,\n\tuseColorMode,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useCallback, useContext } from 'react'\nimport { startEditingShapeWithRichText } from '../../tools/SelectTool/selectHelpers'\nimport { TldrawUiTooltip } from '../../ui/components/primitives/TldrawUiTooltip'\nimport { TranslationsContext } from '../../ui/hooks/useTranslation/useTranslation'\nimport {\n\tisEditingRichTextList,\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { isRightToLeftLanguage } from '../../utils/text/text'\nimport {\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tTEXT_PROPS,\n\tgetFontFamily,\n} from '../shared/default-shape-constants'\nimport { DefaultFontFaces, getThemeFontFaces } from '../shared/defaultFonts'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { useEfficientZoomThreshold } from '../shared/useEfficientZoomThreshold'\nimport { CLONE_HANDLE_MARGIN, getNoteShapeForAdjacentPosition } from './noteHelpers'\n\nconst NOTE_SHAPE_HORIZONTAL_ALIGNS = Object.freeze({\n\tstart: 'start',\n\tmiddle: 'center',\n\tend: 'end',\n\t'start-legacy': 'start',\n\t'end-legacy': 'end',\n\t'middle-legacy': 'center',\n} as const)\n\nconst NOTE_SHAPE_VERTICAL_ALIGNS = Object.freeze({\n\tstart: 'start',\n\tmiddle: 'middle',\n\tend: 'end',\n} as const)\n\n/** @public */\nexport interface NoteShapeUtilDisplayValues {\n\tnoteWidth: number\n\tnoteHeight: number\n\tnoteBackgroundColor: string\n\tborderColor: string\n\tborderWidth: number\n\tlabelColor: string\n\tlabelFontFamily: string\n\tlabelFontSize: number\n\tlabelLineHeight: number\n\tlabelFontWeight: string\n\tlabelFontVariant: string\n\tlabelFontStyle: string\n\tlabelPadding: number\n\tlabelHorizontalAlign: 'start' | 'center' | 'end'\n\tlabelVerticalAlign: 'start' | 'middle' | 'end'\n}\n\n/** @public */\nexport interface NoteShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLNoteShape,\n\tNoteShapeUtilDisplayValues\n> {\n\t/**\n\t * How should the note shape resize? By default it does not resize (except automatically based on its text content),\n\t * but you can set it to be user-resizable using scale.\n\t */\n\tresizeMode: 'none' | 'scale'\n}\n\n/** @public */\nexport class NoteShapeUtil extends ShapeUtil<TLNoteShape> {\n\tstatic override type = 'note' as const\n\tstatic override props = noteShapeProps\n\tstatic override migrations = noteShapeMigrations\n\n\toverride options: NoteShapeOptions = {\n\t\tresizeMode: 'none',\n\t\tgetDefaultDisplayValues(_editor, shape, theme, colorMode): NoteShapeUtilDisplayValues {\n\t\t\tconst { color, labelColor, font, size, align, verticalAlign } = shape.props\n\t\t\tconst colors = theme.colors[colorMode]\n\t\t\treturn {\n\t\t\t\tnoteWidth: 200,\n\t\t\t\tnoteHeight: 200,\n\t\t\t\tnoteBackgroundColor: getColorValue(colors, color, 'noteFill'),\n\t\t\t\tborderColor: colors.noteBorder,\n\t\t\t\tborderWidth: 2,\n\t\t\t\tlabelColor:\n\t\t\t\t\tlabelColor === 'black'\n\t\t\t\t\t\t? getColorValue(colors, color, 'noteText')\n\t\t\t\t\t\t: getColorValue(colors, labelColor, 'fill'),\n\t\t\t\tlabelFontFamily: getFontFamily(theme, font),\n\t\t\t\tlabelFontSize: theme.fontSize * LABEL_FONT_SIZES[size],\n\t\t\t\tlabelLineHeight: theme.lineHeight,\n\t\t\t\tlabelFontWeight: TEXT_PROPS.fontWeight,\n\t\t\t\tlabelFontVariant: TEXT_PROPS.fontVariant,\n\t\t\t\tlabelFontStyle: TEXT_PROPS.fontStyle,\n\t\t\t\tlabelPadding: LABEL_PADDING,\n\t\t\t\tlabelHorizontalAlign: NOTE_SHAPE_HORIZONTAL_ALIGNS[align],\n\t\t\t\tlabelVerticalAlign: NOTE_SHAPE_VERTICAL_ALIGNS[verticalAlign],\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<NoteShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride canEdit(shape: TLNoteShape) {\n\t\treturn true\n\t}\n\toverride hideResizeHandles(shape: TLNoteShape) {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked(shape: TLNoteShape) {\n\t\treturn this.options.resizeMode === 'scale'\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLNoteShape) {\n\t\treturn false\n\t}\n\n\tgetDefaultProps(): TLNoteShape['props'] {\n\t\treturn {\n\t\t\tcolor: 'black',\n\t\t\trichText: toRichText(''),\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tlabelColor: 'black',\n\t\t\tgrowY: 0,\n\t\t\tfontSizeAdjustment: 1,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\t\t\ttextLastEditedBy: null,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLNoteShape) {\n\t\tconst { labelHeight, labelWidth } = this.getLabelSize(shape)\n\t\tconst { scale } = shape.props\n\n\t\tconst dv = getDisplayValues(this, shape)\n\n\t\tconst lh = labelHeight * scale\n\t\tconst lw = labelWidth * scale\n\t\tconst nw = dv.noteWidth * scale\n\t\tconst nh = getNoteHeight(shape, dv.noteHeight)\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({ width: nw, height: nh, isFilled: true }),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tdv.labelHorizontalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: dv.labelHorizontalAlign === 'end'\n\t\t\t\t\t\t\t\t? nw - lw\n\t\t\t\t\t\t\t\t: (nw - lw) / 2,\n\t\t\t\t\ty:\n\t\t\t\t\t\tdv.labelVerticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: dv.labelVerticalAlign === 'end'\n\t\t\t\t\t\t\t\t? nh - lh\n\t\t\t\t\t\t\t\t: (nh - lh) / 2,\n\t\t\t\t\twidth: lw,\n\t\t\t\t\theight: lh,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandles(shape: TLNoteShape): TLHandle[] {\n\t\tconst { scale } = shape.props\n\t\tconst isCoarsePointer = this.editor.getInstanceState().isCoarsePointer\n\t\tif (isCoarsePointer) return []\n\n\t\tconst zoom = this.editor.getEfficientZoomLevel()\n\t\tif (zoom * scale < 0.25) return []\n\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst nh = getNoteHeight(shape, dv.noteHeight)\n\t\tconst nw = dv.noteWidth * scale\n\t\tconst offset = (CLONE_HANDLE_MARGIN / zoom) * scale\n\n\t\tif (zoom * scale < 0.5) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'bottom',\n\t\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\t\ttype: 'clone',\n\t\t\t\t\tx: nw / 2,\n\t\t\t\t\ty: nh + offset,\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid: 'top',\n\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: -offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'right',\n\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw + offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'bottom',\n\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: nh + offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'left',\n\t\t\t\tindex: 'a4' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: -offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t]\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn resizeScaled(shape, info)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride getText(shape: TLNoteShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getReferencedUserIds(shape: TLNoteShape) {\n\t\treturn shape.props.textLastEditedBy ? [shape.props.textLastEditedBy] : []\n\t}\n\n\toverride getFontFaces(shape: TLNoteShape) {\n\t\tconst fonts = isEmptyRichText(shape.props.richText)\n\t\t\t? []\n\t\t\t: getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\t\t\tweight: 'normal',\n\t\t\t\t\tstyle: 'normal',\n\t\t\t\t})\n\n\t\tif (shape.props.textLastEditedBy && !isEmptyRichText(shape.props.richText)) {\n\t\t\treturn [...fonts, DefaultFontFaces.tldraw_sans.normal.normal]\n\t\t}\n\t\tconst themeFaces = getThemeFontFaces(this.editor.getCurrentTheme(), shape.props.font)\n\t\tif (themeFaces) return [...themeFaces, ...fonts]\n\n\t\treturn fonts.length ? fonts : EMPTY_ARRAY\n\t}\n\n\tcomponent(shape: TLNoteShape) {\n\t\tconst { id, type, props } = shape\n\t\tconst { scale, richText, fontSizeAdjustment, textLastEditedBy } = props\n\n\t\tconst handleKeyDown = useNoteKeydownHandler(id)\n\n\t\tconst rotation = useValue(\n\t\t\t'shape rotation',\n\t\t\t() => this.editor.getShapePageTransform(id)?.rotation() ?? 0,\n\t\t\t[this.editor]\n\t\t)\n\n\t\tconst colorMode = useColorMode()\n\t\tconst dv = getDisplayValues(this, shape, colorMode)\n\n\t\tconst nw = dv.noteWidth * scale\n\t\tconst nh = getNoteHeight(shape, dv.noteHeight)\n\n\t\t// Shadows are hidden when zoomed out far enough; the cheap borderBottom takes over.\n\t\tconst hideShadows = useEfficientZoomThreshold(0.25 / scale)\n\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\n\t\tconst isReadyForEditing = useIsReadyForEditing(this.editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(richText)\n\n\t\tconst attribution = useValue(\n\t\t\t'attribution',\n\t\t\t() => {\n\t\t\t\tif (!textLastEditedBy || isEmpty) return null\n\t\t\t\tconst name = this.editor.getAttributionDisplayName(textLastEditedBy)\n\t\t\t\tif (!name) return null\n\t\t\t\treturn { short: name.split(' ')[0], full: name }\n\t\t\t},\n\t\t\t[textLastEditedBy, isEmpty, this.editor]\n\t\t)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div\n\t\t\t\t\tid={id}\n\t\t\t\t\tclassName=\"tl-note__container\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: nw,\n\t\t\t\t\t\theight: nh,\n\t\t\t\t\t\tbackgroundColor: dv.noteBackgroundColor,\n\t\t\t\t\t\tborderBottom: hideShadows\n\t\t\t\t\t\t\t? `${dv.borderWidth * scale}px solid ${dv.borderColor}`\n\t\t\t\t\t\t\t: 'none',\n\t\t\t\t\t\tboxShadow: hideShadows ? 'none' : getNoteShadow(shape.id, rotation, scale),\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{attribution && (\n\t\t\t\t\t\t<TldrawUiTooltip content={attribution.full} side=\"bottom\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tl-note__attribution\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t['--note-attribution-scale' as string]: scale,\n\t\t\t\t\t\t\t\t\tfontSize: 11 * scale,\n\t\t\t\t\t\t\t\t\tcolor: dv.labelColor,\n\t\t\t\t\t\t\t\t\topacity: 0.6,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{attribution.short}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TldrawUiTooltip>\n\t\t\t\t\t)}\n\t\t\t\t\t{(isSelected || isReadyForEditing || !isEmpty) && (\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfontFamily={dv.labelFontFamily}\n\t\t\t\t\t\t\tfontSize={(fontSizeAdjustment ?? 1) * dv.labelFontSize}\n\t\t\t\t\t\t\tlineHeight={dv.labelLineHeight}\n\t\t\t\t\t\t\ttextAlign={dv.labelHorizontalAlign}\n\t\t\t\t\t\t\tverticalAlign={dv.labelVerticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\t\tlabelColor={dv.labelColor}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t\tpadding={dv.labelPadding}\n\t\t\t\t\t\t\thasCustomTabBehavior\n\t\t\t\t\t\t\tshowTextOutline={false}\n\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tscale !== 1\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\ttransform: `scale(${scale})`,\n\t\t\t\t\t\t\t\t\t\t\ttransformOrigin: 'top left',\n\t\t\t\t\t\t\t\t\t\t\twidth: dv.noteWidth,\n\t\t\t\t\t\t\t\t\t\t\theight: dv.noteHeight + shape.props.growY,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLNoteShape): Path2D {\n\t\tconst { scale } = shape.props\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst path = new Path2D()\n\t\tpath.rect(0, 0, dv.noteWidth * scale, getNoteHeight(shape, dv.noteHeight))\n\t\treturn path\n\t}\n\n\toverride toSvg(shape: TLNoteShape, ctx: SvgExportContext) {\n\t\tconst dv = getDisplayValues(this, shape, ctx.colorMode)\n\t\tconst bounds = new Box(0, 0, dv.noteWidth, dv.noteHeight + shape.props.growY)\n\n\t\tconst filterId = `note-shadow-${shape.id.replace(/:/g, '_')}` as SafeId\n\n\t\tctx.addExportDef({\n\t\t\tkey: filterId,\n\t\t\tgetElement: () => (\n\t\t\t\t<filter id={filterId} x=\"-10%\" y=\"-10%\" width=\"130%\" height=\"150%\">\n\t\t\t\t\t<feMorphology in=\"SourceAlpha\" operator=\"erode\" radius=\"3\" result=\"erode1\" />\n\t\t\t\t\t<feGaussianBlur in=\"erode1\" stdDeviation=\"3\" result=\"blur1\" />\n\t\t\t\t\t<feOffset in=\"blur1\" dy=\"3\" result=\"offsetBlur1\" />\n\t\t\t\t\t<feComponentTransfer in=\"offsetBlur1\" result=\"shadow1\">\n\t\t\t\t\t\t<feFuncA type=\"linear\" slope=\"0.5\" />\n\t\t\t\t\t</feComponentTransfer>\n\t\t\t\t\t<feMorphology in=\"SourceAlpha\" operator=\"erode\" radius=\"10\" result=\"erode2\" />\n\t\t\t\t\t<feGaussianBlur in=\"erode2\" stdDeviation=\"6\" result=\"blur2\" />\n\t\t\t\t\t<feOffset in=\"blur2\" dy=\"6\" result=\"offsetBlur2\" />\n\t\t\t\t\t<feComponentTransfer in=\"offsetBlur2\" result=\"shadow2\">\n\t\t\t\t\t\t<feFuncA type=\"linear\" slope=\"0.5\" />\n\t\t\t\t\t</feComponentTransfer>\n\t\t\t\t\t<feMerge>\n\t\t\t\t\t\t<feMergeNode in=\"shadow1\" />\n\t\t\t\t\t\t<feMergeNode in=\"shadow2\" />\n\t\t\t\t\t\t<feMergeNode in=\"SourceGraphic\" />\n\t\t\t\t\t</feMerge>\n\t\t\t\t</filter>\n\t\t\t),\n\t\t})\n\n\t\tconst { textLastEditedBy } = shape.props\n\t\tconst attributionName =\n\t\t\ttextLastEditedBy && !isEmptyRichText(shape.props.richText)\n\t\t\t\t? (this.editor.getAttributionDisplayName(textLastEditedBy)?.split(' ')[0] ?? null)\n\t\t\t\t: null\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ctx.isDarkMode ? null : (\n\t\t\t\t\t<rect\n\t\t\t\t\t\trx={1}\n\t\t\t\t\t\twidth={dv.noteWidth}\n\t\t\t\t\t\theight={bounds.h}\n\t\t\t\t\t\tfill={dv.noteBackgroundColor}\n\t\t\t\t\t\tfilter={`url(#${filterId})`}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<rect rx={1} width={dv.noteWidth} height={bounds.h} fill={dv.noteBackgroundColor} />\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={(shape.props.fontSizeAdjustment ?? 1) * dv.labelFontSize}\n\t\t\t\t\tfontFamily={dv.labelFontFamily}\n\t\t\t\t\tlineHeight={dv.labelLineHeight}\n\t\t\t\t\ttextAlign={dv.labelHorizontalAlign}\n\t\t\t\t\tverticalAlign={dv.labelVerticalAlign}\n\t\t\t\t\trichText={shape.props.richText}\n\t\t\t\t\tlabelColor={dv.labelColor}\n\t\t\t\t\tbounds={bounds}\n\t\t\t\t\tpadding={dv.labelPadding}\n\t\t\t\t\tshowTextOutline={false}\n\t\t\t\t/>\n\t\t\t\t{attributionName && (\n\t\t\t\t\t<foreignObject\n\t\t\t\t\t\tx={0}\n\t\t\t\t\t\ty={0}\n\t\t\t\t\t\twidth={dv.noteWidth}\n\t\t\t\t\t\theight={bounds.h}\n\t\t\t\t\t\tclassName=\"tl-export-embed-styles\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div style={{ position: 'relative', width: '100%', height: '100%' }}>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tl-note__attribution\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tfontSize: 11,\n\t\t\t\t\t\t\t\t\tcolor: dv.labelColor,\n\t\t\t\t\t\t\t\t\topacity: 0.6,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{attributionName}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</foreignObject>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride onBeforeCreate(next: TLNoteShape) {\n\t\treturn this.getNoteSizeAdjustments(next)\n\t}\n\n\toverride onBeforeUpdate(prev: TLNoteShape, next: TLNoteShape) {\n\t\tconst richTextChanged = !isEqual(prev.props.richText, next.props.richText)\n\n\t\tif (\n\t\t\t!richTextChanged &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tlet shape = next\n\t\tif (richTextChanged) {\n\t\t\tif (isEmptyRichText(next.props.richText)) {\n\t\t\t\tshape = {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: { ...shape.props, textLastEditedBy: null },\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tshape = {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: { ...shape.props, textLastEditedBy: this.editor.getAttributionUserId() },\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.getNoteSizeAdjustments(shape) ?? (richTextChanged ? shape : undefined)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLNoteShape,\n\t\tendShape: TLNoteShape,\n\t\tt: number\n\t): TLNoteShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n\n\t/**\n\t * Get the growY and fontSizeAdjustment for a shape.\n\t */\n\tprivate getNoteSizeAdjustments(shape: TLNoteShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst { labelHeight, fontSizeAdjustment } = this.getLabelSize(shape)\n\t\t// When the label height is more than the height of the shape, we add extra height to it\n\t\tconst growY = Math.max(0, labelHeight - dv.noteHeight)\n\n\t\tif (growY !== shape.props.growY || fontSizeAdjustment !== shape.props.fontSizeAdjustment) {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tgrowY,\n\t\t\t\t\tfontSizeAdjustment,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\treturn undefined\n\t}\n\n\tprivate _labelSizesForNoteCache = new WeakCache<\n\t\tTLShape,\n\t\t{ labelHeight: number; labelWidth: number; fontSizeAdjustment: number }\n\t>()\n\n\t/**\n\t * Get the cached label size for the shape.\n\t */\n\tprivate getLabelSize(shape: TLNoteShape) {\n\t\treturn this._labelSizesForNoteCache.get(shape, () => this.measureNoteLabelSize(shape))\n\t}\n\n\t/**\n\t * Expensively measure the label size for a note shape.\n\t */\n\tprivate measureNoteLabelSize(shape: TLNoteShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\tconst { richText } = shape.props\n\n\t\tif (isEmptyRichText(richText)) {\n\t\t\tconst minHeight =\n\t\t\t\tresolveLineHeightPx(dv.labelFontSize, dv.labelLineHeight) + dv.labelPadding * 2\n\t\t\treturn { labelHeight: minHeight, labelWidth: 100, fontSizeAdjustment: 1 }\n\t\t}\n\n\t\tconst unadjustedFontSize = dv.labelFontSize\n\n\t\tlet fontSizeAdjustment = unadjustedFontSize\n\t\tlet iterations = 0\n\t\tlet labelHeight = dv.noteHeight\n\t\tlet labelWidth = dv.noteWidth\n\n\t\t// N.B. For some note shapes with text like 'hjhjhjhjhjhjhjhj', you'll run into\n\t\t// some text measurement fuzziness where the browser swears there's no overflow (scrollWidth === width)\n\t\t// but really there is when you enable overflow-wrap again. This helps account for that little bit\n\t\t// of give.\n\t\tconst FUZZ = 1\n\n\t\t// We slightly make the font smaller if the text is too big for the note, width-wise.\n\t\tdo {\n\t\t\tfontSizeAdjustment = Math.min(unadjustedFontSize, unadjustedFontSize - iterations)\n\t\t\tconst html = renderHtmlFromRichTextForMeasurement(this.editor, richText)\n\t\t\tconst nextTextSize = this.editor.textMeasure.measureHtml(html, {\n\t\t\t\t...TEXT_PROPS,\n\t\t\t\tlineHeight: dv.labelLineHeight,\n\t\t\t\tfontFamily: dv.labelFontFamily,\n\t\t\t\tfontSize: fontSizeAdjustment,\n\t\t\t\tmaxWidth: dv.noteWidth - dv.labelPadding * 2 - FUZZ,\n\t\t\t\tdisableOverflowWrapBreaking: true,\n\t\t\t\tmeasureScrollWidth: true,\n\t\t\t})\n\n\t\t\tlabelHeight = nextTextSize.h + dv.labelPadding * 2\n\t\t\tlabelWidth = nextTextSize.w + dv.labelPadding * 2\n\n\t\t\tif (fontSizeAdjustment <= 14) {\n\t\t\t\t// Too small, just rely now on CSS `overflow-wrap: break-word`\n\t\t\t\t// We need to recalculate the text measurement here with break-word enabled.\n\t\t\t\tconst html = renderHtmlFromRichTextForMeasurement(this.editor, richText)\n\t\t\t\tconst nextTextSizeWithOverflowBreak = this.editor.textMeasure.measureHtml(html, {\n\t\t\t\t\t...TEXT_PROPS,\n\t\t\t\t\tlineHeight: dv.labelLineHeight,\n\t\t\t\t\tfontFamily: dv.labelFontFamily,\n\t\t\t\t\tfontSize: fontSizeAdjustment,\n\t\t\t\t\tmaxWidth: dv.noteWidth - dv.labelPadding * 2 - FUZZ,\n\t\t\t\t})\n\t\t\t\tlabelHeight = nextTextSizeWithOverflowBreak.h + dv.labelPadding * 2\n\t\t\t\tlabelWidth = nextTextSizeWithOverflowBreak.w + dv.labelPadding * 2\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif (nextTextSize.scrollWidth.toFixed(0) === nextTextSize.w.toFixed(0)) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t} while (iterations++ < 50)\n\n\t\treturn {\n\t\t\tlabelHeight: labelHeight,\n\t\t\tlabelWidth: labelWidth,\n\t\t\tfontSizeAdjustment:\n\t\t\t\tfontSizeAdjustment === unadjustedFontSize ? 1 : fontSizeAdjustment / unadjustedFontSize,\n\t\t}\n\t}\n}\n\nfunction useNoteKeydownHandler(id: TLShapeId) {\n\tconst editor = useEditor()\n\t// Try to get the translation context, but fallback to ltr if it doesn't exist\n\tconst translation = useContext(TranslationsContext)\n\n\treturn useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tconst shape = editor.getShape<TLNoteShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst isTab = e.key === 'Tab'\n\t\t\tconst isCmdEnter = (e.metaKey || e.ctrlKey) && e.key === 'Enter'\n\n\t\t\tif (isTab && isEditingRichTextList(editor)) {\n\t\t\t\t// In a list, let the rich text editor indent the item instead of\n\t\t\t\t// creating a new note. Prevent default so Tab doesn't move focus out\n\t\t\t\t// of the editor when the item can't be indented (e.g. the first item).\n\t\t\t\te.preventDefault()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (isTab || isCmdEnter) {\n\t\t\t\te.preventDefault()\n\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\t\tconst pageRotation = pageTransform.rotation()\n\n\t\t\t\t// Based on the inputs, calculate the offset to the next note\n\t\t\t\t// tab controls x axis (shift inverts direction set by RTL)\n\t\t\t\t// cmd enter is the y axis (shift inverts direction)\n\t\t\t\tconst isRTL = !!(\n\t\t\t\t\ttranslation?.dir === 'rtl' ||\n\t\t\t\t\t// todo: can we check a partial of the text, so that we don't have to render the whole thing?\n\t\t\t\t\tisRightToLeftLanguage(renderPlaintextFromRichText(editor, shape.props.richText))\n\t\t\t\t)\n\n\t\t\t\tconst noteUtil = editor.getShapeUtil(shape) as NoteShapeUtil\n\t\t\t\tconst dv = getDisplayValues(noteUtil, shape)\n\n\t\t\t\tconst noteOffset = isTab\n\t\t\t\t\t? dv.noteWidth + editor.options.adjacentShapeMargin\n\t\t\t\t\t: dv.noteHeight +\n\t\t\t\t\t\teditor.options.adjacentShapeMargin +\n\t\t\t\t\t\t// If we're growing down, we need to account for the current shape's growY\n\t\t\t\t\t\t(isCmdEnter && !e.shiftKey ? shape.props.growY : 0)\n\t\t\t\tconst offsetLength = noteOffset * shape.props.scale\n\n\t\t\t\tconst adjacentCenter = new Vec(\n\t\t\t\t\tisTab ? (e.shiftKey != isRTL ? -1 : 1) : 0,\n\t\t\t\t\tisCmdEnter ? (e.shiftKey ? -1 : 1) : 0\n\t\t\t\t)\n\t\t\t\t\t.mul(offsetLength)\n\t\t\t\t\t.add(new Vec(dv.noteWidth / 2, dv.noteHeight / 2).mul(shape.props.scale))\n\t\t\t\t\t.rot(pageRotation)\n\t\t\t\t\t.add(pageTransform.point())\n\n\t\t\t\tconst newNote = getNoteShapeForAdjacentPosition(editor, {\n\t\t\t\t\tshape,\n\t\t\t\t\tcenter: adjacentCenter,\n\t\t\t\t\tpageRotation,\n\t\t\t\t\tnoteWidth: dv.noteWidth,\n\t\t\t\t\tnoteHeight: dv.noteHeight,\n\t\t\t\t})\n\n\t\t\t\tif (newNote) {\n\t\t\t\t\tstartEditingShapeWithRichText(editor, newNote, { selectAll: true })\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[id, editor, translation?.dir]\n\t)\n}\n\nfunction getNoteHeight(shape: TLNoteShape, noteHeight: number) {\n\treturn (noteHeight + shape.props.growY) * shape.props.scale\n}\n\nfunction getNoteShadow(id: string, rotation: number, scale: number) {\n\tconst random = rng(id) // seeded based on id\n\tconst lift = Math.abs(random()) + 0.5 // 0 to 1.5\n\tconst oy = Math.cos(rotation)\n\tconst a = 5 * scale\n\tconst b = 4 * scale\n\tconst c = 6 * scale\n\tconst d = 7 * scale\n\t// Clamped so shadow never goes above the note at small scales (e.g. dynamic size mode at high zoom)\n\treturn `0px ${Math.max(0, a - lift)}px ${a}px -${a}px rgba(15, 23, 31, .6),\n\t0px ${(b + lift * d) * Math.max(0, oy)}px ${c + lift * d}px -${b + lift * c}px rgba(15, 23, 31, ${(0.3 + lift * 0.1).toFixed(2)}),\n\t0px ${48 * scale}px ${10 * scale}px -${10 * scale}px inset rgba(15, 23, 44, ${((0.022 + random() * 0.005) * ((1 + oy) / 2)).toFixed(2)})`\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["html"]
7
7
  }
@@ -132,7 +132,7 @@ function getNoteShapeForAdjacentPosition(editor, opts) {
132
132
  growY: 0,
133
133
  fontSizeAdjustment: 1,
134
134
  url: "",
135
- textFirstEditedBy: null
135
+ textLastEditedBy: null
136
136
  }
137
137
  });
138
138
  const createdShape = editor.getShape(id);