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/tools/SelectTool/childStates/Idle.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tStateNode,\n\tTLAdjacentDirection,\n\tTLClickEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShape,\n\tVec,\n\tVecLike,\n\tcreateShapeId,\n\tdebugFlags,\n\tkickoutOccludedShapes,\n\tpointInPolygon,\n\ttoRichText,\n\tunsafe__withoutCapture,\n} from '@tldraw/editor'\nimport { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'\nimport { getHitShapeOnCanvasPointerDown } from '../../selection-logic/getHitShapeOnCanvasPointerDown'\nimport { selectOnCanvasPointerUp } from '../../selection-logic/selectOnCanvasPointerUp'\nimport { updateHoveredOverlayId } from '../../selection-logic/updateHoveredOverlayId'\nimport {\n\tcancelUpdateHoveredShapeId,\n\tupdateHoveredShapeId,\n} from '../../selection-logic/updateHoveredShapeId'\nimport { hasRichText, startEditingShapeWithRichText } from '../selectHelpers'\n\nconst SKIPPED_KEYS_FOR_AUTO_EDITING = [\n\t'Delete',\n\t'Backspace',\n\t'[',\n\t']',\n\t'Enter',\n\t' ',\n\t'Shift',\n\t'Tab',\n]\n\nexport class Idle extends StateNode {\n\tstatic override id = 'idle'\n\n\tselectedShapesOnKeyDown: TLShape[] = []\n\n\toverride onEnter() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\t// Check overlays first, then shapes\n\t\tif (!updateHoveredOverlayId(this.editor)) {\n\t\t\tupdateHoveredShapeId(this.editor)\n\t\t}\n\t\tthis.selectedShapesOnKeyDown = []\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.updateInstanceState({ isChangingStyle: false })\n\t\tcancelUpdateHoveredShapeId(this.editor)\n\t}\n\n\toverride onPointerMove() {\n\t\t// Check overlays first, then shapes\n\t\tif (!updateHoveredOverlayId(this.editor)) {\n\t\t\tupdateHoveredShapeId(this.editor)\n\t\t}\n\t\tif (unsafe__withoutCapture(() => this.editor.getInstanceState()).isChangingStyle) {\n\t\t\tthis.editor.updateInstanceState({ isChangingStyle: false })\n\t\t}\n\t}\n\n\toverride onPointerDown(info: TLPointerEventInfo) {\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\t// Check overlays first \u2014 if we hit an overlay, re-dispatch as an overlay event\n\t\t\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\t\t\t\tconst hitOverlay = this.editor.overlays.getOverlayAtPoint(\n\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\tthis.editor.options.hitTestMargin / this.editor.getZoomLevel()\n\t\t\t\t)\n\t\t\t\tif (hitOverlay) {\n\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\ttarget: 'overlay',\n\t\t\t\t\t\toverlay: hitOverlay,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Check to see if we hit any shape under the pointer; if so,\n\t\t\t\t// handle this as a pointer down on the shape instead of the canvas\n\t\t\t\tconst hitShape = getHitShapeOnCanvasPointerDown(this.editor)\n\t\t\t\tif (hitShape && (this.editor.options.selectLockedShapes || !hitShape.isLocked)) {\n\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\n\t\t\t\tif (\n\t\t\t\t\tselectedShapeIds.length > 1 ||\n\t\t\t\t\t(onlySelectedShape &&\n\t\t\t\t\t\t!this.editor.getShapeUtil(onlySelectedShape).hideSelectionBoundsBg(onlySelectedShape))\n\t\t\t\t) {\n\t\t\t\t\tif (isPointInRotatedSelectionBounds(this.editor, currentPagePoint)) {\n\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.parent.transition('pointing_canvas', info)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'overlay': {\n\t\t\t\t// Overlay events carry the overlay instance which has props\n\t\t\t\t// describing what kind of overlay it is. Delegate to the appropriate\n\t\t\t\t// state transition based on the overlay's props.\n\t\t\t\tconst { overlay } = info\n\t\t\t\tconst util = this.editor.overlays.getOverlayUtil(overlay)\n\n\t\t\t\t// Give the overlay util a chance to handle the event itself.\n\t\t\t\t// Defining onPointerDown acts as an interrupt \u2014 unless it\n\t\t\t\t// explicitly returns false, we skip the default routing below.\n\t\t\t\tif (util.onPointerDown) {\n\t\t\t\t\tconst result = util.onPointerDown(overlay, info)\n\t\t\t\t\tif (result !== false) return\n\t\t\t\t}\n\n\t\t\t\tconst overlayType = overlay.props.overlayType as string | undefined\n\n\t\t\t\t// Check overlay type to determine how to route the event\n\t\t\t\tif (overlay.type === 'shape_handle') {\n\t\t\t\t\t// Re-dispatch as a handle event\n\t\t\t\t\tconst shape = this.editor.getShape(overlay.props.shapeId as any)\n\t\t\t\t\tif (shape) {\n\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'handle',\n\t\t\t\t\t\t\tshape,\n\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (overlayType) {\n\t\t\t\t\t\tcase 'rotate_handle': {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'mobile_rotate': {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'resize_handle': {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\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}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tconst { shape } = info\n\n\t\t\t\tif (!this.editor.options.selectLockedShapes && this.editor.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\tthis.parent.transition('pointing_canvas', info)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// If we're holding ctrl key, we might select it, or start brushing...\n\t\t\t\tthis.parent.transition('pointing_shape', info)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'handle': {\n\t\t\t\tif (this.editor.getIsReadonly()) break\n\t\t\t\tif (this.editor.inputs.getAltKey()) {\n\t\t\t\t\tthis.parent.transition('pointing_shape', info)\n\t\t\t\t} else {\n\t\t\t\t\t// If we're holding ctrl key, we might select it, or start brushing...\n\t\t\t\t\tthis.parent.transition('pointing_handle', info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selection': {\n\t\t\t\tswitch (info.handle) {\n\t\t\t\t\tcase 'mobile_rotate':\n\t\t\t\t\tcase 'top_left_rotate':\n\t\t\t\t\tcase 'top_right_rotate':\n\t\t\t\t\tcase 'bottom_left_rotate':\n\t\t\t\t\tcase 'bottom_right_rotate': {\n\t\t\t\t\t\tif (info.accelKey) {\n\t\t\t\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.parent.transition('pointing_rotate_handle', info)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'top_left':\n\t\t\t\t\tcase 'top_right':\n\t\t\t\t\tcase 'bottom_left':\n\t\t\t\t\tcase 'bottom_right': {\n\t\t\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\t\t\tif (info.ctrlKey && this.editor.canCropShape(onlySelectedShape)) {\n\t\t\t\t\t\t\tthis.parent.transition('crop.pointing_crop_handle', info)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.accelKey) {\n\t\t\t\t\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.parent.transition('pointing_resize_handle', info)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst hoveredShape = this.editor.getHoveredShape()\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\thoveredShape &&\n\t\t\t\t\t\t\t!this.editor.getSelectedShapeIds().includes(hoveredShape.id) &&\n\t\t\t\t\t\t\t(this.editor.options.selectLockedShapes || !hoveredShape.isLocked)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\tshape: hoveredShape,\n\t\t\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.parent.transition('pointing_selection', info)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tif (this.editor.inputs.getShiftKey() || info.phase !== 'down') return\n\n\t\t// We don't want to double click while toggling shapes\n\t\tif (info.ctrlKey || info.shiftKey) return\n\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\t\t\t// Check overlays first \u2014 if we hit a resize/rotate handle, re-dispatch\n\t\t\t\t// as a selection event so onDoubleClickEdge / onDoubleClickCorner fire.\n\t\t\t\tconst hitOverlay = this.editor.overlays.getOverlayAtPoint(\n\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\tthis.editor.options.hitTestMargin / this.editor.getZoomLevel()\n\t\t\t\t)\n\t\t\t\tif (hitOverlay) {\n\t\t\t\t\tconst overlayType = hitOverlay.props.overlayType as string | undefined\n\t\t\t\t\tif (\n\t\t\t\t\t\toverlayType === 'resize_handle' ||\n\t\t\t\t\t\toverlayType === 'rotate_handle' ||\n\t\t\t\t\t\toverlayType === 'mobile_rotate'\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.onDoubleClick({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\thandle: hitOverlay.props.handle as any,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst hoveredShape = this.editor.getHoveredShape()\n\n\t\t\t\t// todo\n\t\t\t\t// double clicking on the middle of a hollow geo shape without a label, or\n\t\t\t\t// over the label of a hollwo shape that has a label, should start editing\n\t\t\t\t// that shape's label. We can't support \"double click anywhere inside\"\n\t\t\t\t// of the shape yet because that also creates text shapes, and can produce\n\t\t\t\t// unexpected results when working \"inside of\" a hollow shape.\n\n\t\t\t\tconst hitShape =\n\t\t\t\t\thoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')\n\t\t\t\t\t\t? hoveredShape\n\t\t\t\t\t\t: (this.editor.getSelectedShapeAtPoint(currentPagePoint) ??\n\t\t\t\t\t\t\tthis.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\t\t\t\t\tmargin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),\n\t\t\t\t\t\t\t\thitInside: false,\n\t\t\t\t\t\t\t}))\n\n\t\t\t\tif (hitShape) {\n\t\t\t\t\tif (this.editor.isShapeOfType(hitShape, 'group')) {\n\t\t\t\t\t\t// Probably select the shape\n\t\t\t\t\t\tselectOnCanvasPointerUp(this.editor, info)\n\t\t\t\t\t\treturn\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst parent = this.editor.getShape(hitShape.parentId)\n\t\t\t\t\t\tif (parent && this.editor.isShapeOfType(parent, 'group')) {\n\t\t\t\t\t\t\t// The shape is the direct child of a group. If the group is\n\t\t\t\t\t\t\t// selected, then we can select the shape.\n\t\t\t\t\t\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\t\t\t\t\t\tif (focusedGroupId && parent.id === focusedGroupId) {\n\t\t\t\t\t\t\t\t// If the group is the focus layer id, then we can double click into it as usual.\n\t\t\t\t\t\t\t\t// So here's a noop, double click on the shape as normal below\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// The shape is the child of some group other than our current\n\t\t\t\t\t\t\t\t// focus layer (ie the canvas or some other group). We should probably select the group instead.\n\t\t\t\t\t\t\t\tselectOnCanvasPointerUp(this.editor, info)\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// double click on the shape. We'll start editing the\n\t\t\t\t\t// shape if it's editable or else do a double click on\n\t\t\t\t\t// the canvas.\n\t\t\t\t\tthis.onDoubleClick({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// No hit shape, so double click on the canvas instead\n\t\t\t\tif (!this.editor.inputs.getShiftKey()) {\n\t\t\t\t\tthis.handleDoubleClickOnCanvas(info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selection': {\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\n\t\t\t\tif (onlySelectedShape) {\n\t\t\t\t\tconst util = this.editor.getShapeUtil(onlySelectedShape)\n\t\t\t\t\tconst isEdge =\n\t\t\t\t\t\tinfo.handle === 'right' ||\n\t\t\t\t\t\tinfo.handle === 'left' ||\n\t\t\t\t\t\tinfo.handle === 'top' ||\n\t\t\t\t\t\tinfo.handle === 'bottom'\n\t\t\t\t\tconst isCorner =\n\t\t\t\t\t\tinfo.handle === 'top_left' ||\n\t\t\t\t\t\tinfo.handle === 'top_right' ||\n\t\t\t\t\t\tinfo.handle === 'bottom_right' ||\n\t\t\t\t\t\tinfo.handle === 'bottom_left'\n\n\t\t\t\t\tif (this.editor.getIsReadonly()) {\n\t\t\t\t\t\t// includes readonly check\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.editor.canEditShape(onlySelectedShape, {\n\t\t\t\t\t\t\t\ttype: isCorner\n\t\t\t\t\t\t\t\t\t? 'double-click-corner'\n\t\t\t\t\t\t\t\t\t: isEdge\n\t\t\t\t\t\t\t\t\t\t? 'double-click-edge'\n\t\t\t\t\t\t\t\t\t\t: 'double-click',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.startEditingShape(onlySelectedShape, info, true /* select all */)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// Test edges for an onDoubleClickEdge handler\n\t\t\t\t\tif (isEdge) {\n\t\t\t\t\t\tconst change = util.onDoubleClickEdge?.(onlySelectedShape, info)\n\t\t\t\t\t\tif (change) {\n\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('double click edge')\n\t\t\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\t\t\tkickoutOccludedShapes(this.editor, [onlySelectedShape.id])\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isCorner) {\n\t\t\t\t\t\tconst change = util.onDoubleClickCorner?.(onlySelectedShape, info)\n\t\t\t\t\t\tif (change) {\n\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('double click corner')\n\t\t\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\t\t\tkickoutOccludedShapes(this.editor, [onlySelectedShape.id])\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// For corners OR edges but NOT rotation corners\n\t\t\t\t\tif (this.editor.canCropShape(onlySelectedShape)) {\n\t\t\t\t\t\tthis.parent.transition('crop', info)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.editor.canEditShape(onlySelectedShape)) {\n\t\t\t\t\t\tthis.startEditingShape(onlySelectedShape, info, true /* select all */)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tconst { shape } = info\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\n\t\t\t\t// Allow playing videos and embeds\n\t\t\t\tif (shape.type !== 'video' && shape.type !== 'embed' && this.editor.getIsReadonly()) break\n\n\t\t\t\tif (util.onDoubleClick) {\n\t\t\t\t\t// Call the shape's double click handler\n\t\t\t\t\tconst change = util.onDoubleClick?.(shape)\n\t\t\t\t\tif (change) {\n\t\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (util.canCrop(shape) && !this.editor.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// crop image etc on double click\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('select and crop')\n\t\t\t\t\tthis.editor.select(info.shape?.id)\n\t\t\t\t\tthis.parent.transition('crop', info)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If the shape can edit, then begin editing\n\t\t\t\tif (this.editor.canEditShape(shape)) {\n\t\t\t\t\tthis.startEditingShape(shape, info, true /* select all */)\n\t\t\t\t} else {\n\t\t\t\t\t// If the shape's double click handler has not created a change,\n\t\t\t\t\t// and if the shape cannot edit, then create a text shape and\n\t\t\t\t\t// begin editing the text shape\n\t\t\t\t\tthis.handleDoubleClickOnCanvas(info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'handle': {\n\t\t\t\tif (this.editor.getIsReadonly()) break\n\t\t\t\tconst { shape, handle } = info\n\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tconst changes = util.onDoubleClickHandle?.(shape, handle)\n\n\t\t\t\tif (changes) {\n\t\t\t\t\tthis.editor.updateShapes([changes])\n\t\t\t\t} else {\n\t\t\t\t\t// If the shape's double click handler has not created a change,\n\t\t\t\t\t// and if the shape can edit, then begin editing the shape.\n\t\t\t\t\tif (this.editor.canEditShape(shape)) {\n\t\t\t\t\t\tthis.startEditingShape(shape, info, true /* select all */)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onRightClick(info: TLPointerEventInfo) {\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\t\t\t// Check selection bounds first so that right-clicking inside the\n\t\t\t\t// selection preserves it, even when a filled shape sits behind it.\n\t\t\t\tif (\n\t\t\t\t\tselectedShapeIds.length > 1 ||\n\t\t\t\t\t(onlySelectedShape &&\n\t\t\t\t\t\t!this.editor.getShapeUtil(onlySelectedShape).hideSelectionBoundsBg(onlySelectedShape))\n\t\t\t\t) {\n\t\t\t\t\tif (isPointInRotatedSelectionBounds(this.editor, currentPagePoint)) {\n\t\t\t\t\t\tthis.onRightClick({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst hoveredShape = this.editor.getHoveredShape()\n\t\t\t\tconst hitShape =\n\t\t\t\t\thoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')\n\t\t\t\t\t\t? hoveredShape\n\t\t\t\t\t\t: this.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\t\t\t\t\tmargin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),\n\t\t\t\t\t\t\t\thitInside: false,\n\t\t\t\t\t\t\t\thitLabels: true,\n\t\t\t\t\t\t\t\thitLocked: true,\n\t\t\t\t\t\t\t\thitFrameInside: true,\n\t\t\t\t\t\t\t\trenderingOnly: true,\n\t\t\t\t\t\t\t})\n\n\t\t\t\tif (hitShape) {\n\t\t\t\t\tthis.onRightClick({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tthis.editor.selectNone()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tconst { selectedShapeIds } = this.editor.getCurrentPageState()\n\t\t\t\tconst { shape } = info\n\n\t\t\t\tconst targetShape = this.editor.getOutermostSelectableShape(\n\t\t\t\t\tshape,\n\t\t\t\t\t(parent) => !selectedShapeIds.includes(parent.id)\n\t\t\t\t)\n\n\t\t\t\tif (\n\t\t\t\t\t!selectedShapeIds.includes(targetShape.id) &&\n\t\t\t\t\t!this.editor.findShapeAncestor(targetShape, (shape) =>\n\t\t\t\t\t\tselectedShapeIds.includes(shape.id)\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\t\t\tthis.editor.setSelectedShapes([targetShape.id])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onCancel() {\n\t\tif (\n\t\t\tthis.editor.getFocusedGroupId() !== this.editor.getCurrentPageId() &&\n\t\t\tthis.editor.getSelectedShapeIds().length > 0\n\t\t) {\n\t\t\tthis.editor.popFocusedGroupId()\n\t\t} else {\n\t\t\tthis.editor.markHistoryStoppingPoint('clearing selection')\n\t\t\tthis.editor.selectNone()\n\t\t}\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tthis.selectedShapesOnKeyDown = this.editor.getSelectedShapes()\n\n\t\tswitch (info.code) {\n\t\t\tcase 'ArrowLeft':\n\t\t\tcase 'ArrowRight':\n\t\t\tcase 'ArrowUp':\n\t\t\tcase 'ArrowDown': {\n\t\t\t\tif (info.accelKey) {\n\t\t\t\t\tif (info.shiftKey) {\n\t\t\t\t\t\tif (info.code === 'ArrowDown') {\n\t\t\t\t\t\t\tthis.editor.selectFirstChildShape()\n\t\t\t\t\t\t} else if (info.code === 'ArrowUp') {\n\t\t\t\t\t\t\tthis.editor.selectParentShape()\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.editor.selectAdjacentShape(\n\t\t\t\t\t\t\tinfo.code.replace('Arrow', '').toLowerCase() as TLAdjacentDirection\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.nudgeSelectedShapes(false)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (debugFlags['editOnType'].get()) {\n\t\t\t// This feature flag lets us start editing a note shape's label when a key is pressed.\n\t\t\t// We exclude certain keys to avoid conflicting with modifiers, but there are conflicts\n\t\t\t// with other action kbds, hence why this is kept behind a feature flag.\n\t\t\tif (!SKIPPED_KEYS_FOR_AUTO_EDITING.includes(info.key) && !info.altKey && !info.ctrlKey) {\n\t\t\t\t// If the only selected shape is editable, then begin editing it\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\tif (\n\t\t\t\t\tonlySelectedShape &&\n\t\t\t\t\t// If it's a note shape, then edit on type\n\t\t\t\t\tthis.editor.isShapeOfType(onlySelectedShape, 'note') &&\n\t\t\t\t\t// If it's not locked or anything\n\t\t\t\t\tthis.editor.canEditShape(onlySelectedShape)\n\t\t\t\t) {\n\t\t\t\t\tthis.startEditingShape(\n\t\t\t\t\t\tonlySelectedShape,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\t\tshape: onlySelectedShape,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue /* select all */\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onKeyRepeat(info: TLKeyboardEventInfo) {\n\t\tswitch (info.code) {\n\t\t\tcase 'ArrowLeft':\n\t\t\tcase 'ArrowRight':\n\t\t\tcase 'ArrowUp':\n\t\t\tcase 'ArrowDown': {\n\t\t\t\tif (info.accelKey) {\n\t\t\t\t\tthis.editor.selectAdjacentShape(\n\t\t\t\t\t\tinfo.code.replace('Arrow', '').toLowerCase() as TLAdjacentDirection\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.nudgeSelectedShapes(true)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'Tab': {\n\t\t\t\tconst selectedShapes = this.editor.getSelectedShapes()\n\t\t\t\tif (selectedShapes.length && !info.altKey) {\n\t\t\t\t\tthis.editor.selectAdjacentShape(info.shiftKey ? 'prev' : 'next')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tswitch (info.key) {\n\t\t\tcase 'Enter': {\n\t\t\t\t// Because Enter onKeyDown can happen outside the canvas (but then focus the canvas potentially),\n\t\t\t\t// we need to check if the canvas was initially selecting something before continuing.\n\t\t\t\tif (!this.selectedShapesOnKeyDown.length) return\n\n\t\t\t\tconst selectedShapes = this.editor.getSelectedShapes()\n\n\t\t\t\t// On enter, if every selected shape is a group, then select all of the children of the groups\n\t\t\t\tif (selectedShapes.every((shape) => this.editor.isShapeOfType(shape, 'group'))) {\n\t\t\t\t\tthis.editor.setSelectedShapes(\n\t\t\t\t\t\tselectedShapes.flatMap((shape) => this.editor.getSortedChildIdsForParent(shape.id))\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If the only selected shape is editable, then begin editing it\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\tif (\n\t\t\t\t\tonlySelectedShape &&\n\t\t\t\t\tthis.editor.canEditShape(onlySelectedShape, { type: 'press_enter' })\n\t\t\t\t) {\n\t\t\t\t\tthis.startEditingShape(\n\t\t\t\t\t\tonlySelectedShape,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\t\tshape: onlySelectedShape,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue /* select all */\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If the only selected shape is croppable, then begin cropping it\n\t\t\t\tif (this.editor.canCropShape(onlySelectedShape)) {\n\t\t\t\t\tthis.parent.transition('crop', info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'Tab': {\n\t\t\t\tconst selectedShapes = this.editor.getSelectedShapes()\n\t\t\t\tif (selectedShapes.length && !info.altKey) {\n\t\t\t\t\tthis.editor.selectAdjacentShape(info.shiftKey ? 'prev' : 'next')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate startEditingShape(\n\t\tshape: TLShape,\n\t\tinfo: TLClickEventInfo | (TLKeyboardEventInfo & { target: 'shape'; shape: TLShape }),\n\t\tshouldSelectAll?: boolean\n\t) {\n\t\tconst { editor } = this\n\t\tthis.editor.markHistoryStoppingPoint('editing shape')\n\t\tif (hasRichText(shape)) {\n\t\t\tstartEditingShapeWithRichText(editor, shape, { selectAll: shouldSelectAll })\n\t\t} else {\n\t\t\teditor.setEditingShape(shape)\n\t\t}\n\t\tthis.parent.transition('editing_shape', info)\n\t}\n\n\tisOverArrowLabelTest(shape: TLShape | undefined) {\n\t\tif (!shape) return false\n\n\t\treturn isOverArrowLabel(this.editor, shape)\n\t}\n\n\thandleDoubleClickOnCanvas(info: TLClickEventInfo) {\n\t\t// Create text shape and transition to editing_shape\n\t\tif (this.editor.getIsReadonly()) return\n\n\t\tif (!this.editor.options.createTextOnCanvasDoubleClick) return\n\n\t\tthis.editor.markHistoryStoppingPoint('creating text shape')\n\n\t\tconst id = createShapeId()\n\n\t\tconst { x, y } = this.editor.inputs.getCurrentPagePoint()\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShapes([\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\ttype: 'text',\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tprops: {\n\t\t\t\t\trichText: toRichText(''),\n\t\t\t\t\tautoSize: true,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\n\t\tconst shape = this.editor.getShape(id)\n\t\tif (!shape) return\n\n\t\tif (!this.editor.canEditShape(shape)) return\n\n\t\tstartEditingShapeWithRichText(this.editor, id, { info })\n\t}\n\n\tprivate nudgeSelectedShapes(ephemeral = false) {\n\t\tconst {\n\t\t\teditor: {\n\t\t\t\tinputs: { keys },\n\t\t\t},\n\t\t} = this\n\n\t\t// We want to use the \"actual\" shift key state,\n\t\t// not the one that's in the editor.inputs.shiftKey,\n\t\t// because that one uses a short timeout on release\n\t\tconst shiftKey = keys.has('ShiftLeft')\n\n\t\tconst delta = new Vec(0, 0)\n\n\t\tif (keys.has('ArrowLeft')) delta.x -= 1\n\t\tif (keys.has('ArrowRight')) delta.x += 1\n\t\tif (keys.has('ArrowUp')) delta.y -= 1\n\t\tif (keys.has('ArrowDown')) delta.y += 1\n\n\t\tif (delta.equals(new Vec(0, 0))) return\n\n\t\tif (!ephemeral) this.editor.markHistoryStoppingPoint('nudge shapes')\n\n\t\t// Hide the selection overlay while nudging, same as when changing styles\n\t\tthis.editor.updateInstanceState({ isChangingStyle: true })\n\n\t\tconst { gridSize } = this.editor.getDocumentSettings()\n\n\t\tconst step = this.editor.getInstanceState().isGridMode\n\t\t\t? shiftKey\n\t\t\t\t? gridSize * GRID_INCREMENT\n\t\t\t\t: gridSize\n\t\t\t: shiftKey\n\t\t\t\t? MAJOR_NUDGE_FACTOR\n\t\t\t\t: MINOR_NUDGE_FACTOR\n\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tthis.editor.nudgeShapes(selectedShapeIds, delta.mul(step))\n\t\tkickoutOccludedShapes(this.editor, selectedShapeIds)\n\t}\n}\n\nexport const MAJOR_NUDGE_FACTOR = 10\nexport const MINOR_NUDGE_FACTOR = 1\nexport const GRID_INCREMENT = 5\n\nfunction isPointInRotatedSelectionBounds(editor: Editor, point: VecLike) {\n\tconst selectionBounds = editor.getSelectionRotatedPageBounds()\n\tif (!selectionBounds) return false\n\n\tconst selectionRotation = editor.getSelectionRotation()\n\tif (!selectionRotation) return selectionBounds.containsPoint(point)\n\n\treturn pointInPolygon(\n\t\tpoint,\n\t\tselectionBounds.corners.map((c) => Vec.RotWith(c, selectionBounds.point, selectionRotation))\n\t)\n}\n"],
5
- "mappings": "AAAA;AAAA,EAEC;AAAA,EAMA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,wBAAwB;AACjC,SAAS,sCAAsC;AAC/C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC;AAAA,EACC;AAAA,EACA;AAAA,OACM;AACP,SAAS,aAAa,qCAAqC;AAE3D,MAAM,gCAAgC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEO,MAAM,aAAa,UAAU;AAAA,EACnC,OAAgB,KAAK;AAAA,EAErB,0BAAqC,CAAC;AAAA,EAE7B,UAAU;AAClB,SAAK,OAAO,qBAAqB,MAAS;AAC1C,SAAK,OAAO,UAAU,EAAE,MAAM,WAAW,UAAU,EAAE,CAAC;AAEtD,QAAI,CAAC,uBAAuB,KAAK,MAAM,GAAG;AACzC,2BAAqB,KAAK,MAAM;AAAA,IACjC;AACA,SAAK,0BAA0B,CAAC;AAAA,EACjC;AAAA,EAES,SAAS;AACjB,SAAK,OAAO,oBAAoB,EAAE,iBAAiB,MAAM,CAAC;AAC1D,+BAA2B,KAAK,MAAM;AAAA,EACvC;AAAA,EAES,gBAAgB;AAExB,QAAI,CAAC,uBAAuB,KAAK,MAAM,GAAG;AACzC,2BAAqB,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,uBAAuB,MAAM,KAAK,OAAO,iBAAiB,CAAC,EAAE,iBAAiB;AACjF,WAAK,OAAO,oBAAoB,EAAE,iBAAiB,MAAM,CAAC;AAAA,IAC3D;AAAA,EACD;AAAA,EAES,cAAc,MAA0B;AAChD,YAAQ,KAAK,QAAQ;AAAA,MACpB,KAAK,UAAU;AAEd,cAAM,mBAAmB,KAAK,OAAO,OAAO,oBAAoB;AAChE,cAAM,aAAa,KAAK,OAAO,SAAS;AAAA,UACvC;AAAA,UACA,KAAK,OAAO,QAAQ,gBAAgB,KAAK,OAAO,aAAa;AAAA,QAC9D;AACA,YAAI,YAAY;AACf,eAAK,cAAc;AAAA,YAClB,GAAG;AAAA,YACH,QAAQ;AAAA,YACR,SAAS;AAAA,UACV,CAAC;AACD;AAAA,QACD;AAIA,cAAM,WAAW,+BAA+B,KAAK,MAAM;AAC3D,YAAI,aAAa,KAAK,OAAO,QAAQ,sBAAsB,CAAC,SAAS,WAAW;AAC/E,eAAK,cAAc;AAAA,YAClB,GAAG;AAAA,YACH,OAAO;AAAA,YACP,QAAQ;AAAA,UACT,CAAC;AACD;AAAA,QACD;AAEA,cAAM,mBAAmB,KAAK,OAAO,oBAAoB;AACzD,cAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAE3D,YACC,iBAAiB,SAAS,KACzB,qBACA,CAAC,KAAK,OAAO,aAAa,iBAAiB,EAAE,sBAAsB,iBAAiB,GACpF;AACD,cAAI,gCAAgC,KAAK,QAAQ,gBAAgB,GAAG;AACnE,iBAAK,cAAc;AAAA,cAClB,GAAG;AAAA,cACH,QAAQ;AAAA,YACT,CAAC;AACD;AAAA,UACD;AAAA,QACD;AAEA,aAAK,OAAO,WAAW,mBAAmB,IAAI;AAC9C;AAAA,MACD;AAAA,MACA,KAAK,WAAW;AAIf,cAAM,EAAE,QAAQ,IAAI;AACpB,cAAM,OAAO,KAAK,OAAO,SAAS,eAAe,OAAO;AAKxD,YAAI,KAAK,eAAe;AACvB,gBAAM,SAAS,KAAK,cAAc,SAAS,IAAI;AAC/C,cAAI,WAAW,MAAO;AAAA,QACvB;AAEA,cAAM,cAAc,QAAQ,MAAM;AAGlC,YAAI,QAAQ,SAAS,gBAAgB;AAEpC,gBAAM,QAAQ,KAAK,OAAO,SAAS,QAAQ,MAAM,OAAc;AAC/D,cAAI,OAAO;AACV,iBAAK,cAAc;AAAA,cAClB,GAAG;AAAA,cACH,QAAQ;AAAA,cACR;AAAA,cACA,QAAQ,QAAQ,MAAM;AAAA,YACvB,CAAC;AAAA,UACF;AAAA,QACD,OAAO;AACN,kBAAQ,aAAa;AAAA,YACpB,KAAK,iBAAiB;AACrB,mBAAK,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,QAAQ;AAAA,gBACR,QAAQ,QAAQ,MAAM;AAAA,cACvB,CAAC;AACD;AAAA,YACD;AAAA,YACA,KAAK,iBAAiB;AACrB,mBAAK,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,QAAQ;AAAA,gBACR,QAAQ,QAAQ,MAAM;AAAA,cACvB,CAAC;AACD;AAAA,YACD;AAAA,YACA,KAAK,iBAAiB;AACrB,mBAAK,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,QAAQ;AAAA,gBACR,QAAQ,QAAQ,MAAM;AAAA,cACvB,CAAC;AACD;AAAA,YACD;AAAA,YACA,SAAS;AACR,mBAAK,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,QAAQ;AAAA,cACT,CAAC;AAAA,YACF;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AAAA,MACA,KAAK,SAAS;AACb,cAAM,EAAE,MAAM,IAAI;AAElB,YAAI,CAAC,KAAK,OAAO,QAAQ,sBAAsB,KAAK,OAAO,wBAAwB,KAAK,GAAG;AAC1F,eAAK,OAAO,WAAW,mBAAmB,IAAI;AAC9C;AAAA,QACD;AAGA,aAAK,OAAO,WAAW,kBAAkB,IAAI;AAC7C;AAAA,MACD;AAAA,MACA,KAAK,UAAU;AACd,YAAI,KAAK,OAAO,cAAc,EAAG;AACjC,YAAI,KAAK,OAAO,OAAO,UAAU,GAAG;AACnC,eAAK,OAAO,WAAW,kBAAkB,IAAI;AAAA,QAC9C,OAAO;AAEN,eAAK,OAAO,WAAW,mBAAmB,IAAI;AAAA,QAC/C;AACA;AAAA,MACD;AAAA,MACA,KAAK,aAAa;AACjB,gBAAQ,KAAK,QAAQ;AAAA,UACpB,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK,uBAAuB;AAC3B,gBAAI,KAAK,UAAU;AAClB,mBAAK,OAAO,WAAW,YAAY,IAAI;AACvC;AAAA,YACD;AACA,iBAAK,OAAO,WAAW,0BAA0B,IAAI;AACrD;AAAA,UACD;AAAA,UACA,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK,gBAAgB;AACpB,kBAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAC3D,gBAAI,KAAK,WAAW,KAAK,OAAO,aAAa,iBAAiB,GAAG;AAChE,mBAAK,OAAO,WAAW,6BAA6B,IAAI;AAAA,YACzD,OAAO;AACN,kBAAI,KAAK,UAAU;AAClB,qBAAK,OAAO,WAAW,YAAY,IAAI;AACvC;AAAA,cACD;AACA,mBAAK,OAAO,WAAW,0BAA0B,IAAI;AAAA,YACtD;AACA;AAAA,UACD;AAAA,UACA,SAAS;AACR,kBAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,gBACC,gBACA,CAAC,KAAK,OAAO,oBAAoB,EAAE,SAAS,aAAa,EAAE,MAC1D,KAAK,OAAO,QAAQ,sBAAsB,CAAC,aAAa,WACxD;AACD,mBAAK,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,OAAO;AAAA,gBACP,QAAQ;AAAA,cACT,CAAC;AACD;AAAA,YACD;AAEA,iBAAK,OAAO,WAAW,sBAAsB,IAAI;AAAA,UAClD;AAAA,QACD;AACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,cAAc,MAAwB;AAC9C,QAAI,KAAK,OAAO,OAAO,YAAY,KAAK,KAAK,UAAU,OAAQ;AAG/D,QAAI,KAAK,WAAW,KAAK,SAAU;AAEnC,YAAQ,KAAK,QAAQ;AAAA,MACpB,KAAK,UAAU;AACd,cAAM,mBAAmB,KAAK,OAAO,OAAO,oBAAoB;AAIhE,cAAM,aAAa,KAAK,OAAO,SAAS;AAAA,UACvC;AAAA,UACA,KAAK,OAAO,QAAQ,gBAAgB,KAAK,OAAO,aAAa;AAAA,QAC9D;AACA,YAAI,YAAY;AACf,gBAAM,cAAc,WAAW,MAAM;AACrC,cACC,gBAAgB,mBAChB,gBAAgB,mBAChB,gBAAgB,iBACf;AACD,iBAAK,cAAc;AAAA,cAClB,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,QAAQ,WAAW,MAAM;AAAA,YAC1B,CAAC;AACD;AAAA,UACD;AAAA,QACD;AAEA,cAAM,eAAe,KAAK,OAAO,gBAAgB;AASjD,cAAM,WACL,gBAAgB,CAAC,KAAK,OAAO,cAAc,cAAc,OAAO,IAC7D,eACC,KAAK,OAAO,wBAAwB,gBAAgB,KACtD,KAAK,OAAO,gBAAgB,kBAAkB;AAAA,UAC7C,QAAQ,KAAK,OAAO,QAAQ,gBAAgB,KAAK,OAAO,aAAa;AAAA,UACrE,WAAW;AAAA,QACZ,CAAC;AAEJ,YAAI,UAAU;AACb,cAAI,KAAK,OAAO,cAAc,UAAU,OAAO,GAAG;AAEjD,oCAAwB,KAAK,QAAQ,IAAI;AACzC;AAAA,UACD,OAAO;AACN,kBAAM,SAAS,KAAK,OAAO,SAAS,SAAS,QAAQ;AACrD,gBAAI,UAAU,KAAK,OAAO,cAAc,QAAQ,OAAO,GAAG;AAGzD,oBAAM,iBAAiB,KAAK,OAAO,kBAAkB;AACrD,kBAAI,kBAAkB,OAAO,OAAO,gBAAgB;AAAA,cAGpD,OAAO;AAGN,wCAAwB,KAAK,QAAQ,IAAI;AACzC;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAKA,eAAK,cAAc;AAAA,YAClB,GAAG;AAAA,YACH,OAAO;AAAA,YACP,QAAQ;AAAA,UACT,CAAC;AAED;AAAA,QACD;AAGA,YAAI,CAAC,KAAK,OAAO,OAAO,YAAY,GAAG;AACtC,eAAK,0BAA0B,IAAI;AAAA,QACpC;AACA;AAAA,MACD;AAAA,MACA,KAAK,aAAa;AACjB,cAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAE3D,YAAI,mBAAmB;AACtB,gBAAM,OAAO,KAAK,OAAO,aAAa,iBAAiB;AACvD,gBAAM,SACL,KAAK,WAAW,WAChB,KAAK,WAAW,UAChB,KAAK,WAAW,SAChB,KAAK,WAAW;AACjB,gBAAM,WACL,KAAK,WAAW,cAChB,KAAK,WAAW,eAChB,KAAK,WAAW,kBAChB,KAAK,WAAW;AAEjB,cAAI,KAAK,OAAO,cAAc,GAAG;AAEhC,gBACC,KAAK,OAAO,aAAa,mBAAmB;AAAA,cAC3C,MAAM,WACH,wBACA,SACC,sBACA;AAAA,YACL,CAAC,GACA;AACD,mBAAK;AAAA,gBAAkB;AAAA,gBAAmB;AAAA,gBAAM;AAAA;AAAA,cAAqB;AAAA,YACtE;AACA;AAAA,UACD;AAGA,cAAI,QAAQ;AACX,kBAAM,SAAS,KAAK,oBAAoB,mBAAmB,IAAI;AAC/D,gBAAI,QAAQ;AACX,mBAAK,OAAO,yBAAyB,mBAAmB;AACxD,mBAAK,OAAO,aAAa,CAAC,MAAM,CAAC;AACjC,oCAAsB,KAAK,QAAQ,CAAC,kBAAkB,EAAE,CAAC;AACzD;AAAA,YACD;AAAA,UACD;AAEA,cAAI,UAAU;AACb,kBAAM,SAAS,KAAK,sBAAsB,mBAAmB,IAAI;AACjE,gBAAI,QAAQ;AACX,mBAAK,OAAO,yBAAyB,qBAAqB;AAC1D,mBAAK,OAAO,aAAa,CAAC,MAAM,CAAC;AACjC,oCAAsB,KAAK,QAAQ,CAAC,kBAAkB,EAAE,CAAC;AACzD;AAAA,YACD;AAAA,UACD;AAGA,cAAI,KAAK,OAAO,aAAa,iBAAiB,GAAG;AAChD,iBAAK,OAAO,WAAW,QAAQ,IAAI;AACnC;AAAA,UACD;AAEA,cAAI,KAAK,OAAO,aAAa,iBAAiB,GAAG;AAChD,iBAAK;AAAA,cAAkB;AAAA,cAAmB;AAAA,cAAM;AAAA;AAAA,YAAqB;AAAA,UACtE;AAAA,QACD;AACA;AAAA,MACD;AAAA,MACA,KAAK,SAAS;AACb,cAAM,EAAE,MAAM,IAAI;AAClB,cAAM,OAAO,KAAK,OAAO,aAAa,KAAK;AAG3C,YAAI,MAAM,SAAS,WAAW,MAAM,SAAS,WAAW,KAAK,OAAO,cAAc,EAAG;AAErF,YAAI,KAAK,eAAe;AAEvB,gBAAM,SAAS,KAAK,gBAAgB,KAAK;AACzC,cAAI,QAAQ;AACX,iBAAK,OAAO,aAAa,CAAC,MAAM,CAAC;AACjC;AAAA,UACD;AAAA,QACD;AAEA,YAAI,KAAK,QAAQ,KAAK,KAAK,CAAC,KAAK,OAAO,wBAAwB,KAAK,GAAG;AAEvE,eAAK,OAAO,yBAAyB,iBAAiB;AACtD,eAAK,OAAO,OAAO,KAAK,OAAO,EAAE;AACjC,eAAK,OAAO,WAAW,QAAQ,IAAI;AACnC;AAAA,QACD;AAGA,YAAI,KAAK,OAAO,aAAa,KAAK,GAAG;AACpC,eAAK;AAAA,YAAkB;AAAA,YAAO;AAAA,YAAM;AAAA;AAAA,UAAqB;AAAA,QAC1D,OAAO;AAIN,eAAK,0BAA0B,IAAI;AAAA,QACpC;AACA;AAAA,MACD;AAAA,MACA,KAAK,UAAU;AACd,YAAI,KAAK,OAAO,cAAc,EAAG;AACjC,cAAM,EAAE,OAAO,OAAO,IAAI;AAE1B,cAAM,OAAO,KAAK,OAAO,aAAa,KAAK;AAC3C,cAAM,UAAU,KAAK,sBAAsB,OAAO,MAAM;AAExD,YAAI,SAAS;AACZ,eAAK,OAAO,aAAa,CAAC,OAAO,CAAC;AAAA,QACnC,OAAO;AAGN,cAAI,KAAK,OAAO,aAAa,KAAK,GAAG;AACpC,iBAAK;AAAA,cAAkB;AAAA,cAAO;AAAA,cAAM;AAAA;AAAA,YAAqB;AAAA,UAC1D;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,aAAa,MAA0B;AAC/C,YAAQ,KAAK,QAAQ;AAAA,MACpB,KAAK,UAAU;AACd,cAAM,mBAAmB,KAAK,OAAO,oBAAoB;AACzD,cAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAC3D,cAAM,mBAAmB,KAAK,OAAO,OAAO,oBAAoB;AAIhE,YACC,iBAAiB,SAAS,KACzB,qBACA,CAAC,KAAK,OAAO,aAAa,iBAAiB,EAAE,sBAAsB,iBAAiB,GACpF;AACD,cAAI,gCAAgC,KAAK,QAAQ,gBAAgB,GAAG;AACnE,iBAAK,aAAa;AAAA,cACjB,GAAG;AAAA,cACH,QAAQ;AAAA,YACT,CAAC;AACD;AAAA,UACD;AAAA,QACD;AAEA,cAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,cAAM,WACL,gBAAgB,CAAC,KAAK,OAAO,cAAc,cAAc,OAAO,IAC7D,eACA,KAAK,OAAO,gBAAgB,kBAAkB;AAAA,UAC9C,QAAQ,KAAK,OAAO,QAAQ,gBAAgB,KAAK,OAAO,aAAa;AAAA,UACrE,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,gBAAgB;AAAA,UAChB,eAAe;AAAA,QAChB,CAAC;AAEJ,YAAI,UAAU;AACb,eAAK,aAAa;AAAA,YACjB,GAAG;AAAA,YACH,OAAO;AAAA,YACP,QAAQ;AAAA,UACT,CAAC;AACD;AAAA,QACD;AAEA,aAAK,OAAO,WAAW;AACvB;AAAA,MACD;AAAA,MACA,KAAK,SAAS;AACb,cAAM,EAAE,iBAAiB,IAAI,KAAK,OAAO,oBAAoB;AAC7D,cAAM,EAAE,MAAM,IAAI;AAElB,cAAM,cAAc,KAAK,OAAO;AAAA,UAC/B;AAAA,UACA,CAAC,WAAW,CAAC,iBAAiB,SAAS,OAAO,EAAE;AAAA,QACjD;AAEA,YACC,CAAC,iBAAiB,SAAS,YAAY,EAAE,KACzC,CAAC,KAAK,OAAO;AAAA,UAAkB;AAAA,UAAa,CAACA,WAC5C,iBAAiB,SAASA,OAAM,EAAE;AAAA,QACnC,GACC;AACD,eAAK,OAAO,yBAAyB,iBAAiB;AACtD,eAAK,OAAO,kBAAkB,CAAC,YAAY,EAAE,CAAC;AAAA,QAC/C;AACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,WAAW;AACnB,QACC,KAAK,OAAO,kBAAkB,MAAM,KAAK,OAAO,iBAAiB,KACjE,KAAK,OAAO,oBAAoB,EAAE,SAAS,GAC1C;AACD,WAAK,OAAO,kBAAkB;AAAA,IAC/B,OAAO;AACN,WAAK,OAAO,yBAAyB,oBAAoB;AACzD,WAAK,OAAO,WAAW;AAAA,IACxB;AAAA,EACD;AAAA,EAES,UAAU,MAA2B;AAC7C,SAAK,0BAA0B,KAAK,OAAO,kBAAkB;AAE7D,YAAQ,KAAK,MAAM;AAAA,MAClB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,aAAa;AACjB,YAAI,KAAK,UAAU;AAClB,cAAI,KAAK,UAAU;AAClB,gBAAI,KAAK,SAAS,aAAa;AAC9B,mBAAK,OAAO,sBAAsB;AAAA,YACnC,WAAW,KAAK,SAAS,WAAW;AACnC,mBAAK,OAAO,kBAAkB;AAAA,YAC/B;AAAA,UACD,OAAO;AACN,iBAAK,OAAO;AAAA,cACX,KAAK,KAAK,QAAQ,SAAS,EAAE,EAAE,YAAY;AAAA,YAC5C;AAAA,UACD;AACA;AAAA,QACD;AACA,aAAK,oBAAoB,KAAK;AAC9B;AAAA,MACD;AAAA,IACD;AAEA,QAAI,WAAW,YAAY,EAAE,IAAI,GAAG;AAInC,UAAI,CAAC,8BAA8B,SAAS,KAAK,GAAG,KAAK,CAAC,KAAK,UAAU,CAAC,KAAK,SAAS;AAEvF,cAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAC3D,YACC;AAAA,QAEA,KAAK,OAAO,cAAc,mBAAmB,MAAM;AAAA,QAEnD,KAAK,OAAO,aAAa,iBAAiB,GACzC;AACD,eAAK;AAAA,YACJ;AAAA,YACA;AAAA,cACC,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,OAAO;AAAA,YACR;AAAA,YACA;AAAA;AAAA,UACD;AACA;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,YAAY,MAA2B;AAC/C,YAAQ,KAAK,MAAM;AAAA,MAClB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,aAAa;AACjB,YAAI,KAAK,UAAU;AAClB,eAAK,OAAO;AAAA,YACX,KAAK,KAAK,QAAQ,SAAS,EAAE,EAAE,YAAY;AAAA,UAC5C;AACA;AAAA,QACD;AACA,aAAK,oBAAoB,IAAI;AAC7B;AAAA,MACD;AAAA,MACA,KAAK,OAAO;AACX,cAAM,iBAAiB,KAAK,OAAO,kBAAkB;AACrD,YAAI,eAAe,UAAU,CAAC,KAAK,QAAQ;AAC1C,eAAK,OAAO,oBAAoB,KAAK,WAAW,SAAS,MAAM;AAAA,QAChE;AACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,QAAQ,MAA2B;AAC3C,YAAQ,KAAK,KAAK;AAAA,MACjB,KAAK,SAAS;AAGb,YAAI,CAAC,KAAK,wBAAwB,OAAQ;AAE1C,cAAM,iBAAiB,KAAK,OAAO,kBAAkB;AAGrD,YAAI,eAAe,MAAM,CAAC,UAAU,KAAK,OAAO,cAAc,OAAO,OAAO,CAAC,GAAG;AAC/E,eAAK,OAAO;AAAA,YACX,eAAe,QAAQ,CAAC,UAAU,KAAK,OAAO,2BAA2B,MAAM,EAAE,CAAC;AAAA,UACnF;AACA;AAAA,QACD;AAGA,cAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAC3D,YACC,qBACA,KAAK,OAAO,aAAa,mBAAmB,EAAE,MAAM,cAAc,CAAC,GAClE;AACD,eAAK;AAAA,YACJ;AAAA,YACA;AAAA,cACC,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,OAAO;AAAA,YACR;AAAA,YACA;AAAA;AAAA,UACD;AACA;AAAA,QACD;AAGA,YAAI,KAAK,OAAO,aAAa,iBAAiB,GAAG;AAChD,eAAK,OAAO,WAAW,QAAQ,IAAI;AAAA,QACpC;AACA;AAAA,MACD;AAAA,MACA,KAAK,OAAO;AACX,cAAM,iBAAiB,KAAK,OAAO,kBAAkB;AACrD,YAAI,eAAe,UAAU,CAAC,KAAK,QAAQ;AAC1C,eAAK,OAAO,oBAAoB,KAAK,WAAW,SAAS,MAAM;AAAA,QAChE;AACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,kBACP,OACA,MACA,iBACC;AACD,UAAM,EAAE,OAAO,IAAI;AACnB,SAAK,OAAO,yBAAyB,eAAe;AACpD,QAAI,YAAY,KAAK,GAAG;AACvB,oCAA8B,QAAQ,OAAO,EAAE,WAAW,gBAAgB,CAAC;AAAA,IAC5E,OAAO;AACN,aAAO,gBAAgB,KAAK;AAAA,IAC7B;AACA,SAAK,OAAO,WAAW,iBAAiB,IAAI;AAAA,EAC7C;AAAA,EAEA,qBAAqB,OAA4B;AAChD,QAAI,CAAC,MAAO,QAAO;AAEnB,WAAO,iBAAiB,KAAK,QAAQ,KAAK;AAAA,EAC3C;AAAA,EAEA,0BAA0B,MAAwB;AAEjD,QAAI,KAAK,OAAO,cAAc,EAAG;AAEjC,QAAI,CAAC,KAAK,OAAO,QAAQ,8BAA+B;AAExD,SAAK,OAAO,yBAAyB,qBAAqB;AAE1D,UAAM,KAAK,cAAc;AAEzB,UAAM,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,OAAO,oBAAoB;AAGxD,SAAK,OAAO,aAAa;AAAA,MACxB;AAAA,QACC;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,OAAO;AAAA,UACN,UAAU,WAAW,EAAE;AAAA,UACvB,UAAU;AAAA,QACX;AAAA,MACD;AAAA,IACD,CAAC;AAED,UAAM,QAAQ,KAAK,OAAO,SAAS,EAAE;AACrC,QAAI,CAAC,MAAO;AAEZ,QAAI,CAAC,KAAK,OAAO,aAAa,KAAK,EAAG;AAEtC,kCAA8B,KAAK,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,EACxD;AAAA,EAEQ,oBAAoB,YAAY,OAAO;AAC9C,UAAM;AAAA,MACL,QAAQ;AAAA,QACP,QAAQ,EAAE,KAAK;AAAA,MAChB;AAAA,IACD,IAAI;AAKJ,UAAM,WAAW,KAAK,IAAI,WAAW;AAErC,UAAM,QAAQ,IAAI,IAAI,GAAG,CAAC;AAE1B,QAAI,KAAK,IAAI,WAAW,EAAG,OAAM,KAAK;AACtC,QAAI,KAAK,IAAI,YAAY,EAAG,OAAM,KAAK;AACvC,QAAI,KAAK,IAAI,SAAS,EAAG,OAAM,KAAK;AACpC,QAAI,KAAK,IAAI,WAAW,EAAG,OAAM,KAAK;AAEtC,QAAI,MAAM,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC,EAAG;AAEjC,QAAI,CAAC,UAAW,MAAK,OAAO,yBAAyB,cAAc;AAGnE,SAAK,OAAO,oBAAoB,EAAE,iBAAiB,KAAK,CAAC;AAEzD,UAAM,EAAE,SAAS,IAAI,KAAK,OAAO,oBAAoB;AAErD,UAAM,OAAO,KAAK,OAAO,iBAAiB,EAAE,aACzC,WACC,WAAW,iBACX,WACD,WACC,qBACA;AAEJ,UAAM,mBAAmB,KAAK,OAAO,oBAAoB;AACzD,SAAK,OAAO,YAAY,kBAAkB,MAAM,IAAI,IAAI,CAAC;AACzD,0BAAsB,KAAK,QAAQ,gBAAgB;AAAA,EACpD;AACD;AAEO,MAAM,qBAAqB;AAC3B,MAAM,qBAAqB;AAC3B,MAAM,iBAAiB;AAE9B,SAAS,gCAAgC,QAAgB,OAAgB;AACxE,QAAM,kBAAkB,OAAO,8BAA8B;AAC7D,MAAI,CAAC,gBAAiB,QAAO;AAE7B,QAAM,oBAAoB,OAAO,qBAAqB;AACtD,MAAI,CAAC,kBAAmB,QAAO,gBAAgB,cAAc,KAAK;AAElE,SAAO;AAAA,IACN;AAAA,IACA,gBAAgB,QAAQ,IAAI,CAAC,MAAM,IAAI,QAAQ,GAAG,gBAAgB,OAAO,iBAAiB,CAAC;AAAA,EAC5F;AACD;",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tStateNode,\n\tTLAdjacentDirection,\n\tTLClickEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShape,\n\tVec,\n\tVecLike,\n\tcreateShapeId,\n\tdebugFlags,\n\tkickoutOccludedShapes,\n\tpointInPolygon,\n\ttoRichText,\n\tunsafe__withoutCapture,\n} from '@tldraw/editor'\nimport { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'\nimport { getHitShapeOnCanvasPointerDown } from '../../selection-logic/getHitShapeOnCanvasPointerDown'\nimport { selectOnCanvasPointerUp } from '../../selection-logic/selectOnCanvasPointerUp'\nimport { updateHoveredOverlayId } from '../../selection-logic/updateHoveredOverlayId'\nimport {\n\tcancelUpdateHoveredShapeId,\n\tupdateHoveredShapeId,\n} from '../../selection-logic/updateHoveredShapeId'\nimport { hasRichText, startEditingShapeWithRichText } from '../selectHelpers'\n\nconst SKIPPED_KEYS_FOR_AUTO_EDITING = [\n\t'Delete',\n\t'Backspace',\n\t'[',\n\t']',\n\t'Enter',\n\t' ',\n\t'Shift',\n\t'Tab',\n]\n\nexport class Idle extends StateNode {\n\tstatic override id = 'idle'\n\n\tselectedShapesOnKeyDown: TLShape[] = []\n\n\toverride onEnter() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\t// Check overlays first, then shapes\n\t\tif (!updateHoveredOverlayId(this.editor)) {\n\t\t\tupdateHoveredShapeId(this.editor)\n\t\t}\n\t\tthis.selectedShapesOnKeyDown = []\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.updateInstanceState({ isChangingStyle: false })\n\t\tcancelUpdateHoveredShapeId(this.editor)\n\t}\n\n\toverride onPointerMove() {\n\t\t// Check overlays first, then shapes\n\t\tif (!updateHoveredOverlayId(this.editor)) {\n\t\t\tupdateHoveredShapeId(this.editor)\n\t\t}\n\t\tif (unsafe__withoutCapture(() => this.editor.getInstanceState()).isChangingStyle) {\n\t\t\tthis.editor.updateInstanceState({ isChangingStyle: false })\n\t\t}\n\t}\n\n\toverride onPointerDown(info: TLPointerEventInfo) {\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\t// Check overlays first \u2014 if we hit an overlay, re-dispatch as an overlay event\n\t\t\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\t\t\t\tconst hitOverlay = this.editor.overlays.getOverlayAtPoint(\n\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\tthis.editor.options.hitTestMargin / this.editor.getZoomLevel()\n\t\t\t\t)\n\t\t\t\tif (hitOverlay) {\n\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\ttarget: 'overlay',\n\t\t\t\t\t\toverlay: hitOverlay,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Check to see if we hit any shape under the pointer; if so,\n\t\t\t\t// handle this as a pointer down on the shape instead of the canvas\n\t\t\t\tconst hitShape = getHitShapeOnCanvasPointerDown(this.editor)\n\t\t\t\tif (hitShape && (this.editor.options.selectLockedShapes || !hitShape.isLocked)) {\n\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\n\t\t\t\tif (\n\t\t\t\t\tselectedShapeIds.length > 1 ||\n\t\t\t\t\t(onlySelectedShape &&\n\t\t\t\t\t\t!this.editor.getShapeUtil(onlySelectedShape).hideSelectionBoundsBg(onlySelectedShape))\n\t\t\t\t) {\n\t\t\t\t\tif (isPointInRotatedSelectionBounds(this.editor, currentPagePoint)) {\n\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.parent.transition('pointing_canvas', info)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'overlay': {\n\t\t\t\t// Overlay events carry the overlay instance which has props\n\t\t\t\t// describing what kind of overlay it is. Delegate to the appropriate\n\t\t\t\t// state transition based on the overlay's props.\n\t\t\t\tconst { overlay } = info\n\t\t\t\tconst util = this.editor.overlays.getOverlayUtil(overlay)\n\n\t\t\t\t// Give the overlay util a chance to handle the event itself.\n\t\t\t\t// Defining onPointerDown acts as an interrupt \u2014 unless it\n\t\t\t\t// explicitly returns false, we skip the default routing below.\n\t\t\t\tif (util.onPointerDown) {\n\t\t\t\t\tconst result = util.onPointerDown(overlay, info)\n\t\t\t\t\tif (result !== false) return\n\t\t\t\t}\n\n\t\t\t\tconst overlayType = overlay.props.overlayType as string | undefined\n\n\t\t\t\t// Check overlay type to determine how to route the event\n\t\t\t\tif (overlay.type === 'shape_handle') {\n\t\t\t\t\t// Re-dispatch as a handle event\n\t\t\t\t\tconst shape = this.editor.getShape(overlay.props.shapeId as any)\n\t\t\t\t\tif (shape) {\n\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'handle',\n\t\t\t\t\t\t\tshape,\n\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (overlayType) {\n\t\t\t\t\t\tcase 'rotate_handle': {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'mobile_rotate': {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'resize_handle': {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\t\thandle: overlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'selection',\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}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tconst { shape } = info\n\n\t\t\t\tif (!this.editor.options.selectLockedShapes && this.editor.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\tthis.parent.transition('pointing_canvas', info)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// If we're holding ctrl key, we might select it, or start brushing...\n\t\t\t\tthis.parent.transition('pointing_shape', info)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'handle': {\n\t\t\t\tif (this.editor.getIsReadonly()) break\n\t\t\t\tif (this.editor.inputs.getAltKey()) {\n\t\t\t\t\tthis.parent.transition('pointing_shape', info)\n\t\t\t\t} else {\n\t\t\t\t\t// If we're holding ctrl key, we might select it, or start brushing...\n\t\t\t\t\tthis.parent.transition('pointing_handle', info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selection': {\n\t\t\t\tswitch (info.handle) {\n\t\t\t\t\tcase 'mobile_rotate':\n\t\t\t\t\tcase 'top_left_rotate':\n\t\t\t\t\tcase 'top_right_rotate':\n\t\t\t\t\tcase 'bottom_left_rotate':\n\t\t\t\t\tcase 'bottom_right_rotate': {\n\t\t\t\t\t\tif (info.accelKey) {\n\t\t\t\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.parent.transition('pointing_rotate_handle', info)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'top_left':\n\t\t\t\t\tcase 'top_right':\n\t\t\t\t\tcase 'bottom_left':\n\t\t\t\t\tcase 'bottom_right': {\n\t\t\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\t\t\tif (info.ctrlKey && this.editor.canCropShape(onlySelectedShape)) {\n\t\t\t\t\t\t\tthis.parent.transition('crop.pointing_crop_handle', info)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.accelKey) {\n\t\t\t\t\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.parent.transition('pointing_resize_handle', info)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst hoveredShape = this.editor.getHoveredShape()\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\thoveredShape &&\n\t\t\t\t\t\t\t!this.editor.getSelectedShapeIds().includes(hoveredShape.id) &&\n\t\t\t\t\t\t\t(this.editor.options.selectLockedShapes || !hoveredShape.isLocked)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\tshape: hoveredShape,\n\t\t\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.parent.transition('pointing_selection', info)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tif (this.editor.inputs.getShiftKey() || info.phase !== 'down') return\n\n\t\t// We don't want to double click while toggling shapes\n\t\tif (info.ctrlKey || info.shiftKey) return\n\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\t\t\t// Check overlays first \u2014 if we hit a shape handle, re-dispatch as a\n\t\t\t\t// handle event so onDoubleClickHandle fires; if we hit a resize/rotate\n\t\t\t\t// handle, re-dispatch as a selection event so onDoubleClickEdge /\n\t\t\t\t// onDoubleClickCorner fire.\n\t\t\t\tconst hitOverlay = this.editor.overlays.getOverlayAtPoint(\n\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\tthis.editor.options.hitTestMargin / this.editor.getZoomLevel()\n\t\t\t\t)\n\t\t\t\tif (hitOverlay) {\n\t\t\t\t\tif (hitOverlay.type === 'shape_handle') {\n\t\t\t\t\t\tconst shape = this.editor.getShape(hitOverlay.props.shapeId as any)\n\t\t\t\t\t\tif (shape) {\n\t\t\t\t\t\t\tthis.onDoubleClick({\n\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\ttarget: 'handle',\n\t\t\t\t\t\t\t\tshape,\n\t\t\t\t\t\t\t\thandle: hitOverlay.props.handle as any,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst overlayType = hitOverlay.props.overlayType as string | undefined\n\t\t\t\t\tif (\n\t\t\t\t\t\toverlayType === 'resize_handle' ||\n\t\t\t\t\t\toverlayType === 'rotate_handle' ||\n\t\t\t\t\t\toverlayType === 'mobile_rotate'\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.onDoubleClick({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t\thandle: hitOverlay.props.handle as any,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst hoveredShape = this.editor.getHoveredShape()\n\n\t\t\t\t// todo\n\t\t\t\t// double clicking on the middle of a hollow geo shape without a label, or\n\t\t\t\t// over the label of a hollwo shape that has a label, should start editing\n\t\t\t\t// that shape's label. We can't support \"double click anywhere inside\"\n\t\t\t\t// of the shape yet because that also creates text shapes, and can produce\n\t\t\t\t// unexpected results when working \"inside of\" a hollow shape.\n\n\t\t\t\tconst hitShape =\n\t\t\t\t\thoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')\n\t\t\t\t\t\t? hoveredShape\n\t\t\t\t\t\t: (this.editor.getSelectedShapeAtPoint(currentPagePoint) ??\n\t\t\t\t\t\t\tthis.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\t\t\t\t\tmargin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),\n\t\t\t\t\t\t\t\thitInside: false,\n\t\t\t\t\t\t\t}))\n\n\t\t\t\tif (hitShape) {\n\t\t\t\t\tif (this.editor.isShapeOfType(hitShape, 'group')) {\n\t\t\t\t\t\t// Probably select the shape\n\t\t\t\t\t\tselectOnCanvasPointerUp(this.editor, info)\n\t\t\t\t\t\treturn\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst parent = this.editor.getShape(hitShape.parentId)\n\t\t\t\t\t\tif (parent && this.editor.isShapeOfType(parent, 'group')) {\n\t\t\t\t\t\t\t// The shape is the direct child of a group. If the group is\n\t\t\t\t\t\t\t// selected, then we can select the shape.\n\t\t\t\t\t\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\t\t\t\t\t\tif (focusedGroupId && parent.id === focusedGroupId) {\n\t\t\t\t\t\t\t\t// If the group is the focus layer id, then we can double click into it as usual.\n\t\t\t\t\t\t\t\t// So here's a noop, double click on the shape as normal below\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// The shape is the child of some group other than our current\n\t\t\t\t\t\t\t\t// focus layer (ie the canvas or some other group). We should probably select the group instead.\n\t\t\t\t\t\t\t\tselectOnCanvasPointerUp(this.editor, info)\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// double click on the shape. We'll start editing the\n\t\t\t\t\t// shape if it's editable or else do a double click on\n\t\t\t\t\t// the canvas.\n\t\t\t\t\tthis.onDoubleClick({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// No hit shape, so double click on the canvas instead\n\t\t\t\tif (!this.editor.inputs.getShiftKey()) {\n\t\t\t\t\tthis.handleDoubleClickOnCanvas(info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selection': {\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\n\t\t\t\tif (onlySelectedShape) {\n\t\t\t\t\tconst util = this.editor.getShapeUtil(onlySelectedShape)\n\t\t\t\t\tconst isEdge =\n\t\t\t\t\t\tinfo.handle === 'right' ||\n\t\t\t\t\t\tinfo.handle === 'left' ||\n\t\t\t\t\t\tinfo.handle === 'top' ||\n\t\t\t\t\t\tinfo.handle === 'bottom'\n\t\t\t\t\tconst isCorner =\n\t\t\t\t\t\tinfo.handle === 'top_left' ||\n\t\t\t\t\t\tinfo.handle === 'top_right' ||\n\t\t\t\t\t\tinfo.handle === 'bottom_right' ||\n\t\t\t\t\t\tinfo.handle === 'bottom_left'\n\n\t\t\t\t\tif (this.editor.getIsReadonly()) {\n\t\t\t\t\t\t// includes readonly check\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.editor.canEditShape(onlySelectedShape, {\n\t\t\t\t\t\t\t\ttype: isCorner\n\t\t\t\t\t\t\t\t\t? 'double-click-corner'\n\t\t\t\t\t\t\t\t\t: isEdge\n\t\t\t\t\t\t\t\t\t\t? 'double-click-edge'\n\t\t\t\t\t\t\t\t\t\t: 'double-click',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.startEditingShape(onlySelectedShape, info, true /* select all */)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// Test edges for an onDoubleClickEdge handler\n\t\t\t\t\tif (isEdge) {\n\t\t\t\t\t\tconst change = util.onDoubleClickEdge?.(onlySelectedShape, info)\n\t\t\t\t\t\tif (change) {\n\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('double click edge')\n\t\t\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\t\t\tkickoutOccludedShapes(this.editor, [onlySelectedShape.id])\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isCorner) {\n\t\t\t\t\t\tconst change = util.onDoubleClickCorner?.(onlySelectedShape, info)\n\t\t\t\t\t\tif (change) {\n\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('double click corner')\n\t\t\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\t\t\tkickoutOccludedShapes(this.editor, [onlySelectedShape.id])\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// For corners OR edges but NOT rotation corners\n\t\t\t\t\tif (this.editor.canCropShape(onlySelectedShape)) {\n\t\t\t\t\t\tthis.parent.transition('crop', info)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.editor.canEditShape(onlySelectedShape)) {\n\t\t\t\t\t\tthis.startEditingShape(onlySelectedShape, info, true /* select all */)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tconst { shape } = info\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\n\t\t\t\t// Allow playing videos and embeds\n\t\t\t\tif (shape.type !== 'video' && shape.type !== 'embed' && this.editor.getIsReadonly()) break\n\n\t\t\t\tif (util.onDoubleClick) {\n\t\t\t\t\t// Call the shape's double click handler\n\t\t\t\t\tconst change = util.onDoubleClick?.(shape)\n\t\t\t\t\tif (change) {\n\t\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (util.canCrop(shape) && !this.editor.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// crop image etc on double click\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('select and crop')\n\t\t\t\t\tthis.editor.select(info.shape?.id)\n\t\t\t\t\tthis.parent.transition('crop', info)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If the shape can edit, then begin editing\n\t\t\t\tif (this.editor.canEditShape(shape)) {\n\t\t\t\t\tthis.startEditingShape(shape, info, true /* select all */)\n\t\t\t\t} else {\n\t\t\t\t\t// If the shape's double click handler has not created a change,\n\t\t\t\t\t// and if the shape cannot edit, then create a text shape and\n\t\t\t\t\t// begin editing the text shape\n\t\t\t\t\tthis.handleDoubleClickOnCanvas(info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'handle': {\n\t\t\t\tif (this.editor.getIsReadonly()) break\n\t\t\t\tconst { shape, handle } = info\n\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tconst changes = util.onDoubleClickHandle?.(shape, handle)\n\n\t\t\t\tif (changes) {\n\t\t\t\t\tthis.editor.updateShapes([changes])\n\t\t\t\t} else {\n\t\t\t\t\t// If the shape's double click handler has not created a change,\n\t\t\t\t\t// and if the shape can edit, then begin editing the shape.\n\t\t\t\t\tif (this.editor.canEditShape(shape)) {\n\t\t\t\t\t\tthis.startEditingShape(shape, info, true /* select all */)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onRightClick(info: TLPointerEventInfo) {\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\t\t\t// Check selection bounds first so that right-clicking inside the\n\t\t\t\t// selection preserves it, even when a filled shape sits behind it.\n\t\t\t\tif (\n\t\t\t\t\tselectedShapeIds.length > 1 ||\n\t\t\t\t\t(onlySelectedShape &&\n\t\t\t\t\t\t!this.editor.getShapeUtil(onlySelectedShape).hideSelectionBoundsBg(onlySelectedShape))\n\t\t\t\t) {\n\t\t\t\t\tif (isPointInRotatedSelectionBounds(this.editor, currentPagePoint)) {\n\t\t\t\t\t\tthis.onRightClick({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst hoveredShape = this.editor.getHoveredShape()\n\t\t\t\tconst hitShape =\n\t\t\t\t\thoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')\n\t\t\t\t\t\t? hoveredShape\n\t\t\t\t\t\t: this.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\t\t\t\t\tmargin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),\n\t\t\t\t\t\t\t\thitInside: false,\n\t\t\t\t\t\t\t\thitLabels: true,\n\t\t\t\t\t\t\t\thitLocked: true,\n\t\t\t\t\t\t\t\thitFrameInside: true,\n\t\t\t\t\t\t\t\trenderingOnly: true,\n\t\t\t\t\t\t\t})\n\n\t\t\t\tif (hitShape) {\n\t\t\t\t\tthis.onRightClick({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tthis.editor.selectNone()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tconst { selectedShapeIds } = this.editor.getCurrentPageState()\n\t\t\t\tconst { shape } = info\n\n\t\t\t\tconst targetShape = this.editor.getOutermostSelectableShape(\n\t\t\t\t\tshape,\n\t\t\t\t\t(parent) => !selectedShapeIds.includes(parent.id)\n\t\t\t\t)\n\n\t\t\t\tif (\n\t\t\t\t\t!selectedShapeIds.includes(targetShape.id) &&\n\t\t\t\t\t!this.editor.findShapeAncestor(targetShape, (shape) =>\n\t\t\t\t\t\tselectedShapeIds.includes(shape.id)\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\t\t\tthis.editor.setSelectedShapes([targetShape.id])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onCancel() {\n\t\tif (\n\t\t\tthis.editor.getFocusedGroupId() !== this.editor.getCurrentPageId() &&\n\t\t\tthis.editor.getSelectedShapeIds().length > 0\n\t\t) {\n\t\t\tthis.editor.popFocusedGroupId()\n\t\t} else {\n\t\t\tthis.editor.markHistoryStoppingPoint('clearing selection')\n\t\t\tthis.editor.selectNone()\n\t\t}\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tthis.selectedShapesOnKeyDown = this.editor.getSelectedShapes()\n\n\t\tswitch (info.code) {\n\t\t\tcase 'ArrowLeft':\n\t\t\tcase 'ArrowRight':\n\t\t\tcase 'ArrowUp':\n\t\t\tcase 'ArrowDown': {\n\t\t\t\tif (info.accelKey) {\n\t\t\t\t\tif (info.shiftKey) {\n\t\t\t\t\t\tif (info.code === 'ArrowDown') {\n\t\t\t\t\t\t\tthis.editor.selectFirstChildShape()\n\t\t\t\t\t\t} else if (info.code === 'ArrowUp') {\n\t\t\t\t\t\t\tthis.editor.selectParentShape()\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.editor.selectAdjacentShape(\n\t\t\t\t\t\t\tinfo.code.replace('Arrow', '').toLowerCase() as TLAdjacentDirection\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.nudgeSelectedShapes(false)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (debugFlags['editOnType'].get()) {\n\t\t\t// This feature flag lets us start editing a note shape's label when a key is pressed.\n\t\t\t// We exclude certain keys to avoid conflicting with modifiers, but there are conflicts\n\t\t\t// with other action kbds, hence why this is kept behind a feature flag.\n\t\t\tif (!SKIPPED_KEYS_FOR_AUTO_EDITING.includes(info.key) && !info.altKey && !info.ctrlKey) {\n\t\t\t\t// If the only selected shape is editable, then begin editing it\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\tif (\n\t\t\t\t\tonlySelectedShape &&\n\t\t\t\t\t// If it's a note shape, then edit on type\n\t\t\t\t\tthis.editor.isShapeOfType(onlySelectedShape, 'note') &&\n\t\t\t\t\t// If it's not locked or anything\n\t\t\t\t\tthis.editor.canEditShape(onlySelectedShape)\n\t\t\t\t) {\n\t\t\t\t\tthis.startEditingShape(\n\t\t\t\t\t\tonlySelectedShape,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\t\tshape: onlySelectedShape,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue /* select all */\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onKeyRepeat(info: TLKeyboardEventInfo) {\n\t\tswitch (info.code) {\n\t\t\tcase 'ArrowLeft':\n\t\t\tcase 'ArrowRight':\n\t\t\tcase 'ArrowUp':\n\t\t\tcase 'ArrowDown': {\n\t\t\t\tif (info.accelKey) {\n\t\t\t\t\tthis.editor.selectAdjacentShape(\n\t\t\t\t\t\tinfo.code.replace('Arrow', '').toLowerCase() as TLAdjacentDirection\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.nudgeSelectedShapes(true)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'Tab': {\n\t\t\t\tconst selectedShapes = this.editor.getSelectedShapes()\n\t\t\t\tif (selectedShapes.length && !info.altKey) {\n\t\t\t\t\tthis.editor.selectAdjacentShape(info.shiftKey ? 'prev' : 'next')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tswitch (info.key) {\n\t\t\tcase 'Enter': {\n\t\t\t\t// Because Enter onKeyDown can happen outside the canvas (but then focus the canvas potentially),\n\t\t\t\t// we need to check if the canvas was initially selecting something before continuing.\n\t\t\t\tif (!this.selectedShapesOnKeyDown.length) return\n\n\t\t\t\tconst selectedShapes = this.editor.getSelectedShapes()\n\n\t\t\t\t// On enter, if every selected shape is a group, then select all of the children of the groups\n\t\t\t\tif (selectedShapes.every((shape) => this.editor.isShapeOfType(shape, 'group'))) {\n\t\t\t\t\tthis.editor.setSelectedShapes(\n\t\t\t\t\t\tselectedShapes.flatMap((shape) => this.editor.getSortedChildIdsForParent(shape.id))\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If the only selected shape is editable, then begin editing it\n\t\t\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\t\t\tif (\n\t\t\t\t\tonlySelectedShape &&\n\t\t\t\t\tthis.editor.canEditShape(onlySelectedShape, { type: 'press_enter' })\n\t\t\t\t) {\n\t\t\t\t\tthis.startEditingShape(\n\t\t\t\t\t\tonlySelectedShape,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\t\tshape: onlySelectedShape,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue /* select all */\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If the only selected shape is croppable, then begin cropping it\n\t\t\t\tif (this.editor.canCropShape(onlySelectedShape)) {\n\t\t\t\t\tthis.parent.transition('crop', info)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'Tab': {\n\t\t\t\tconst selectedShapes = this.editor.getSelectedShapes()\n\t\t\t\tif (selectedShapes.length && !info.altKey) {\n\t\t\t\t\tthis.editor.selectAdjacentShape(info.shiftKey ? 'prev' : 'next')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate startEditingShape(\n\t\tshape: TLShape,\n\t\tinfo: TLClickEventInfo | (TLKeyboardEventInfo & { target: 'shape'; shape: TLShape }),\n\t\tshouldSelectAll?: boolean\n\t) {\n\t\tconst { editor } = this\n\t\tthis.editor.markHistoryStoppingPoint('editing shape')\n\t\tif (hasRichText(shape)) {\n\t\t\tstartEditingShapeWithRichText(editor, shape, { selectAll: shouldSelectAll })\n\t\t} else {\n\t\t\teditor.setEditingShape(shape)\n\t\t}\n\t\tthis.parent.transition('editing_shape', info)\n\t}\n\n\tisOverArrowLabelTest(shape: TLShape | undefined) {\n\t\tif (!shape) return false\n\n\t\treturn isOverArrowLabel(this.editor, shape)\n\t}\n\n\thandleDoubleClickOnCanvas(info: TLClickEventInfo) {\n\t\t// Create text shape and transition to editing_shape\n\t\tif (this.editor.getIsReadonly()) return\n\n\t\tif (!this.editor.options.createTextOnCanvasDoubleClick) return\n\n\t\tthis.editor.markHistoryStoppingPoint('creating text shape')\n\n\t\tconst id = createShapeId()\n\n\t\tconst { x, y } = this.editor.inputs.getCurrentPagePoint()\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShapes([\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\ttype: 'text',\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tprops: {\n\t\t\t\t\trichText: toRichText(''),\n\t\t\t\t\tautoSize: true,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\n\t\tconst shape = this.editor.getShape(id)\n\t\tif (!shape) return\n\n\t\tif (!this.editor.canEditShape(shape)) return\n\n\t\tstartEditingShapeWithRichText(this.editor, id, { info })\n\t}\n\n\tprivate nudgeSelectedShapes(ephemeral = false) {\n\t\tconst {\n\t\t\teditor: {\n\t\t\t\tinputs: { keys },\n\t\t\t},\n\t\t} = this\n\n\t\t// We want to use the \"actual\" shift key state,\n\t\t// not the one that's in the editor.inputs.shiftKey,\n\t\t// because that one uses a short timeout on release\n\t\tconst shiftKey = keys.has('ShiftLeft')\n\n\t\tconst delta = new Vec(0, 0)\n\n\t\tif (keys.has('ArrowLeft')) delta.x -= 1\n\t\tif (keys.has('ArrowRight')) delta.x += 1\n\t\tif (keys.has('ArrowUp')) delta.y -= 1\n\t\tif (keys.has('ArrowDown')) delta.y += 1\n\n\t\tif (delta.equals(new Vec(0, 0))) return\n\n\t\tif (!ephemeral) this.editor.markHistoryStoppingPoint('nudge shapes')\n\n\t\t// Hide the selection overlay while nudging, same as when changing styles\n\t\tthis.editor.updateInstanceState({ isChangingStyle: true })\n\n\t\tconst { gridSize } = this.editor.getDocumentSettings()\n\n\t\tconst step = this.editor.getInstanceState().isGridMode\n\t\t\t? shiftKey\n\t\t\t\t? gridSize * GRID_INCREMENT\n\t\t\t\t: gridSize\n\t\t\t: shiftKey\n\t\t\t\t? MAJOR_NUDGE_FACTOR\n\t\t\t\t: MINOR_NUDGE_FACTOR\n\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tthis.editor.nudgeShapes(selectedShapeIds, delta.mul(step))\n\t\tkickoutOccludedShapes(this.editor, selectedShapeIds)\n\t}\n}\n\nexport const MAJOR_NUDGE_FACTOR = 10\nexport const MINOR_NUDGE_FACTOR = 1\nexport const GRID_INCREMENT = 5\n\nfunction isPointInRotatedSelectionBounds(editor: Editor, point: VecLike) {\n\tconst selectionBounds = editor.getSelectionRotatedPageBounds()\n\tif (!selectionBounds) return false\n\n\tconst selectionRotation = editor.getSelectionRotation()\n\tif (!selectionRotation) return selectionBounds.containsPoint(point)\n\n\treturn pointInPolygon(\n\t\tpoint,\n\t\tselectionBounds.corners.map((c) => Vec.RotWith(c, selectionBounds.point, selectionRotation))\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["shape"]
7
7
  }
@@ -55,6 +55,10 @@ class PointingShape extends StateNode {
55
55
  hitInside: true,
56
56
  renderingOnly: true
57
57
  }) ?? this.hitShape;
58
+ if (!this.editor.getShape(hitShape.id)) {
59
+ this.parent.transition("idle", info);
60
+ return;
61
+ }
58
62
  const selectingShape = hitShape ? this.editor.getOutermostSelectableShape(hitShape) : this.hitShapeForPointerUp;
59
63
  if (selectingShape) {
60
64
  const util = this.editor.getShapeUtil(selectingShape);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/tools/SelectTool/childStates/PointingShape.ts"],
4
- "sourcesContent": ["import { StateNode, TLClickEventInfo, TLPointerEventInfo, TLShape } from '@tldraw/editor'\nimport { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'\nimport { getTextLabels } from '../../../utils/shapes/shapes'\n\nexport class PointingShape extends StateNode {\n\tstatic override id = 'pointing_shape'\n\n\thitShape = {} as TLShape\n\thitShapeForPointerUp = {} as TLShape\n\tisDoubleClick = false\n\n\tdidCtrlOnEnter = false\n\tdidSelectOnEnter = false\n\n\toverride onEnter(info: TLPointerEventInfo & { target: 'shape' }) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\t\tconst { shiftKey, altKey, accelKey } = info\n\n\t\tthis.hitShape = info.shape\n\t\tthis.isDoubleClick = false\n\t\tthis.didCtrlOnEnter = accelKey\n\t\tconst outermostSelectingShape = this.editor.getOutermostSelectableShape(info.shape)\n\t\tconst selectedAncestor = this.editor.findShapeAncestor(outermostSelectingShape, (parent) =>\n\t\t\tselectedShapeIds.includes(parent.id)\n\t\t)\n\n\t\tif (\n\t\t\tthis.didCtrlOnEnter ||\n\t\t\t// If the shape has an onClick handler\n\t\t\tthis.editor.getShapeUtil(info.shape).onClick ||\n\t\t\t// ...or if the shape is the focused layer (e.g. group)\n\t\t\toutermostSelectingShape.id === focusedGroupId ||\n\t\t\t// ...or if the shape is within the selection\n\t\t\tselectedShapeIds.includes(outermostSelectingShape.id) ||\n\t\t\t// ...or if an ancestor of the shape is selected\n\t\t\tselectedAncestor ||\n\t\t\t// ...or if the current point is NOT within the selection bounds\n\t\t\t(selectedShapeIds.length > 1 && selectionBounds?.containsPoint(currentPagePoint))\n\t\t) {\n\t\t\t// We won't select the shape on enter, though we might select it on pointer up!\n\t\t\tthis.didSelectOnEnter = false\n\t\t\tthis.hitShapeForPointerUp = outermostSelectingShape\n\t\t\treturn\n\t\t}\n\n\t\tthis.didSelectOnEnter = true\n\n\t\tif (shiftKey && !altKey) {\n\t\t\tthis.editor.cancelDoubleClick()\n\t\t\tif (!selectedShapeIds.includes(outermostSelectingShape.id)) {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift selecting shape')\n\t\t\t\tthis.editor.setSelectedShapes([...selectedShapeIds, outermostSelectingShape.id])\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([outermostSelectingShape.id])\n\t\t}\n\t}\n\n\toverride onPointerUp(info: TLPointerEventInfo) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst zoomLevel = this.editor.getZoomLevel()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\tconst additiveSelectionKey = info.shiftKey || info.accelKey\n\n\t\tconst hitShape =\n\t\t\tthis.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\tmargin: this.editor.options.hitTestMargin / zoomLevel,\n\t\t\t\thitInside: true,\n\t\t\t\trenderingOnly: true,\n\t\t\t}) ?? this.hitShape\n\n\t\tconst selectingShape = hitShape\n\t\t\t? this.editor.getOutermostSelectableShape(hitShape)\n\t\t\t: this.hitShapeForPointerUp\n\n\t\tif (selectingShape) {\n\t\t\t// If the selecting shape has a click handler, call it instead of selecting the shape\n\t\t\tconst util = this.editor.getShapeUtil(selectingShape)\n\t\t\tif (util.onClick) {\n\t\t\t\tconst change = util.onClick?.(selectingShape)\n\t\t\t\tif (change) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('shape on click')\n\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (selectingShape.id === focusedGroupId) {\n\t\t\t\tif (selectedShapeIds.length > 0) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('clearing shape ids')\n\t\t\t\t\tthis.editor.setSelectedShapes([])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t\t}\n\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (!this.didSelectOnEnter) {\n\t\t\t// if the shape has an ancestor which is a focusable layer and it is not focused but it is selected\n\t\t\t// then we should focus the layer and select the shape\n\n\t\t\tconst outermostSelectableShape = this.editor.getOutermostSelectableShape(\n\t\t\t\thitShape,\n\t\t\t\t// if a group is selected, we want to stop before reaching that group\n\t\t\t\t// so we can drill down into the group\n\t\t\t\t(parent) => !selectedShapeIds.includes(parent.id)\n\t\t\t)\n\n\t\t\t// If the outermost shape is selected, then either select or deselect the SELECTING shape\n\t\t\tif (selectedShapeIds.includes(outermostSelectableShape.id)) {\n\t\t\t\t// same shape, so deselect it if shift is pressed, otherwise deselect all others\n\t\t\t\tif (additiveSelectionKey) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('deselecting on pointer up')\n\t\t\t\t\tthis.editor.deselect(selectingShape)\n\t\t\t\t} else {\n\t\t\t\t\tif (selectedShapeIds.includes(selectingShape.id)) {\n\t\t\t\t\t\t// todo\n\t\t\t\t\t\t// if the shape is editable and we're inside of an editable part of that shape, e.g. the label of a geo shape,\n\t\t\t\t\t\t// then we would want to begin editing the shape. At the moment we're relying on the shape label's onPointerUp\n\t\t\t\t\t\t// handler to do this logic, and prevent the regular pointer up event, so we won't be here in that case.\n\n\t\t\t\t\t\t// if the shape has a text label, and we're inside of the label, then we want to begin editing the label.\n\t\t\t\t\t\tif (selectedShapeIds.length === 1) {\n\t\t\t\t\t\t\tconst geometry = this.editor.getShapeUtil(selectingShape).getGeometry(selectingShape)\n\t\t\t\t\t\t\tconst textLabels = getTextLabels(geometry)\n\t\t\t\t\t\t\tconst textLabel = textLabels.length === 1 ? textLabels[0] : undefined\n\t\t\t\t\t\t\t// N.B. we're only interested if there is exactly one text label. We don't handle the\n\t\t\t\t\t\t\t// case if there's potentially more than one text label at the moment.\n\t\t\t\t\t\t\tif (textLabel) {\n\t\t\t\t\t\t\t\tconst pointInShapeSpace = this.editor.getPointInShapeSpace(\n\t\t\t\t\t\t\t\t\tselectingShape,\n\t\t\t\t\t\t\t\t\tcurrentPagePoint\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\ttextLabel.bounds.containsPoint(pointInShapeSpace, 0) &&\n\t\t\t\t\t\t\t\t\ttextLabel.hitTestPoint(pointInShapeSpace)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tthis.editor.run(() => {\n\t\t\t\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('editing on pointer up')\n\t\t\t\t\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\n\t\t\t\t\t\t\t\t\t\tif (!this.editor.canEditShape(selectingShape)) return\n\t\t\t\t\t\t\t\t\t\tthis.editor.setEditingShape(selectingShape.id)\n\t\t\t\t\t\t\t\t\t\tthis.editor.setCurrentTool('select.editing_shape')\n\n\t\t\t\t\t\t\t\t\t\tif (this.isDoubleClick) {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('select-all-text', { shapeId: selectingShape.id })\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('place-caret', {\n\t\t\t\t\t\t\t\t\t\t\t\tshapeId: selectingShape.id,\n\t\t\t\t\t\t\t\t\t\t\t\tpoint: info.point,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We just want to select the single shape from the selection\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (additiveSelectionKey) {\n\t\t\t\t// Different shape, so we are drilling down into a group with shift key held.\n\t\t\t\t// Deselect any ancestors and add the target shape to the selection\n\t\t\t\tconst ancestors = this.editor.getShapeAncestors(outermostSelectableShape)\n\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift deselecting on pointer up')\n\t\t\t\tthis.editor.setSelectedShapes([\n\t\t\t\t\t...this.editor.getSelectedShapeIds().filter((id) => !ancestors.find((a) => a.id === id)),\n\t\t\t\t\toutermostSelectableShape.id,\n\t\t\t\t])\n\t\t\t} else {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t// different shape and we are drilling down, but no shift held so just select it straight up\n\t\t\t\tthis.editor.setSelectedShapes([outermostSelectableShape.id])\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle', info)\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tthis.isDoubleClick = true\n\n\t\tif (\n\t\t\tthis.editor.inputs.getShiftKey() ||\n\t\t\tinfo.phase !== 'down' ||\n\t\t\tinfo.ctrlKey ||\n\t\t\tinfo.shiftKey\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { shape: _shape, ...canvasInfo } = info as TLClickEventInfo & { target: 'shape' }\n\t\tthis.parent.transition('idle')\n\t\tthis.parent.getCurrent()?.handleEvent({\n\t\t\t...canvasInfo,\n\t\t\ttarget: 'canvas',\n\t\t})\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tif (isOverArrowLabel(this.editor, this.hitShape)) {\n\t\t\t\t// We're moving the label on a shape.\n\t\t\t\tthis.parent.transition('pointing_arrow_label', { ...info, shape: this.hitShape })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (this.didCtrlOnEnter) {\n\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t} else {\n\t\t\t\tthis.startTranslating(info)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onLongPress(info: TLPointerEventInfo) {\n\t\tthis.startTranslating(info)\n\t}\n\n\tprivate startTranslating(info: TLPointerEventInfo) {\n\t\tif (this.editor.getIsReadonly()) return\n\n\t\t// If we didn't select the shape on enter (e.g. because it has an onClick handler),\n\t\t// and there's no current selection, select it now before transitioning to translating.\n\t\tif (!this.didSelectOnEnter && !this.editor.getSelectedShapeIds().length) {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([this.hitShapeForPointerUp.id])\n\t\t}\n\n\t\t// Re-focus the editor, just in case the text label of the shape has stolen focus\n\t\tthis.editor.focus()\n\t\tthis.parent.transition('translating', info)\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tthis.parent.transition('idle')\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { StateNode, TLClickEventInfo, TLPointerEventInfo, TLShape } from '@tldraw/editor'\nimport { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'\nimport { getTextLabels } from '../../../utils/shapes/shapes'\n\nexport class PointingShape extends StateNode {\n\tstatic override id = 'pointing_shape'\n\n\thitShape = {} as TLShape\n\thitShapeForPointerUp = {} as TLShape\n\tisDoubleClick = false\n\n\tdidCtrlOnEnter = false\n\tdidSelectOnEnter = false\n\n\toverride onEnter(info: TLPointerEventInfo & { target: 'shape' }) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\t\tconst { shiftKey, altKey, accelKey } = info\n\n\t\tthis.hitShape = info.shape\n\t\tthis.isDoubleClick = false\n\t\tthis.didCtrlOnEnter = accelKey\n\t\tconst outermostSelectingShape = this.editor.getOutermostSelectableShape(info.shape)\n\t\tconst selectedAncestor = this.editor.findShapeAncestor(outermostSelectingShape, (parent) =>\n\t\t\tselectedShapeIds.includes(parent.id)\n\t\t)\n\n\t\tif (\n\t\t\tthis.didCtrlOnEnter ||\n\t\t\t// If the shape has an onClick handler\n\t\t\tthis.editor.getShapeUtil(info.shape).onClick ||\n\t\t\t// ...or if the shape is the focused layer (e.g. group)\n\t\t\toutermostSelectingShape.id === focusedGroupId ||\n\t\t\t// ...or if the shape is within the selection\n\t\t\tselectedShapeIds.includes(outermostSelectingShape.id) ||\n\t\t\t// ...or if an ancestor of the shape is selected\n\t\t\tselectedAncestor ||\n\t\t\t// ...or if the current point is NOT within the selection bounds\n\t\t\t(selectedShapeIds.length > 1 && selectionBounds?.containsPoint(currentPagePoint))\n\t\t) {\n\t\t\t// We won't select the shape on enter, though we might select it on pointer up!\n\t\t\tthis.didSelectOnEnter = false\n\t\t\tthis.hitShapeForPointerUp = outermostSelectingShape\n\t\t\treturn\n\t\t}\n\n\t\tthis.didSelectOnEnter = true\n\n\t\tif (shiftKey && !altKey) {\n\t\t\tthis.editor.cancelDoubleClick()\n\t\t\tif (!selectedShapeIds.includes(outermostSelectingShape.id)) {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift selecting shape')\n\t\t\t\tthis.editor.setSelectedShapes([...selectedShapeIds, outermostSelectingShape.id])\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([outermostSelectingShape.id])\n\t\t}\n\t}\n\n\toverride onPointerUp(info: TLPointerEventInfo) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst zoomLevel = this.editor.getZoomLevel()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\tconst additiveSelectionKey = info.shiftKey || info.accelKey\n\n\t\tconst hitShape =\n\t\t\tthis.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\tmargin: this.editor.options.hitTestMargin / zoomLevel,\n\t\t\t\thitInside: true,\n\t\t\t\trenderingOnly: true,\n\t\t\t}) ?? this.hitShape\n\n\t\t// The hit shape may have been deleted between pointer down and pointer up\n\t\t// (e.g. by a remote user or an undo), in which case the fallback hitShape\n\t\t// is stale. Bail to idle so we don't dereference a missing shape.\n\t\tif (!this.editor.getShape(hitShape.id)) {\n\t\t\tthis.parent.transition('idle', info)\n\t\t\treturn\n\t\t}\n\n\t\tconst selectingShape = hitShape\n\t\t\t? this.editor.getOutermostSelectableShape(hitShape)\n\t\t\t: this.hitShapeForPointerUp\n\n\t\tif (selectingShape) {\n\t\t\t// If the selecting shape has a click handler, call it instead of selecting the shape\n\t\t\tconst util = this.editor.getShapeUtil(selectingShape)\n\t\t\tif (util.onClick) {\n\t\t\t\tconst change = util.onClick?.(selectingShape)\n\t\t\t\tif (change) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('shape on click')\n\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (selectingShape.id === focusedGroupId) {\n\t\t\t\tif (selectedShapeIds.length > 0) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('clearing shape ids')\n\t\t\t\t\tthis.editor.setSelectedShapes([])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t\t}\n\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (!this.didSelectOnEnter) {\n\t\t\t// if the shape has an ancestor which is a focusable layer and it is not focused but it is selected\n\t\t\t// then we should focus the layer and select the shape\n\n\t\t\tconst outermostSelectableShape = this.editor.getOutermostSelectableShape(\n\t\t\t\thitShape,\n\t\t\t\t// if a group is selected, we want to stop before reaching that group\n\t\t\t\t// so we can drill down into the group\n\t\t\t\t(parent) => !selectedShapeIds.includes(parent.id)\n\t\t\t)\n\n\t\t\t// If the outermost shape is selected, then either select or deselect the SELECTING shape\n\t\t\tif (selectedShapeIds.includes(outermostSelectableShape.id)) {\n\t\t\t\t// same shape, so deselect it if shift is pressed, otherwise deselect all others\n\t\t\t\tif (additiveSelectionKey) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('deselecting on pointer up')\n\t\t\t\t\tthis.editor.deselect(selectingShape)\n\t\t\t\t} else {\n\t\t\t\t\tif (selectedShapeIds.includes(selectingShape.id)) {\n\t\t\t\t\t\t// todo\n\t\t\t\t\t\t// if the shape is editable and we're inside of an editable part of that shape, e.g. the label of a geo shape,\n\t\t\t\t\t\t// then we would want to begin editing the shape. At the moment we're relying on the shape label's onPointerUp\n\t\t\t\t\t\t// handler to do this logic, and prevent the regular pointer up event, so we won't be here in that case.\n\n\t\t\t\t\t\t// if the shape has a text label, and we're inside of the label, then we want to begin editing the label.\n\t\t\t\t\t\tif (selectedShapeIds.length === 1) {\n\t\t\t\t\t\t\tconst geometry = this.editor.getShapeUtil(selectingShape).getGeometry(selectingShape)\n\t\t\t\t\t\t\tconst textLabels = getTextLabels(geometry)\n\t\t\t\t\t\t\tconst textLabel = textLabels.length === 1 ? textLabels[0] : undefined\n\t\t\t\t\t\t\t// N.B. we're only interested if there is exactly one text label. We don't handle the\n\t\t\t\t\t\t\t// case if there's potentially more than one text label at the moment.\n\t\t\t\t\t\t\tif (textLabel) {\n\t\t\t\t\t\t\t\tconst pointInShapeSpace = this.editor.getPointInShapeSpace(\n\t\t\t\t\t\t\t\t\tselectingShape,\n\t\t\t\t\t\t\t\t\tcurrentPagePoint\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\ttextLabel.bounds.containsPoint(pointInShapeSpace, 0) &&\n\t\t\t\t\t\t\t\t\ttextLabel.hitTestPoint(pointInShapeSpace)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tthis.editor.run(() => {\n\t\t\t\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('editing on pointer up')\n\t\t\t\t\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\n\t\t\t\t\t\t\t\t\t\tif (!this.editor.canEditShape(selectingShape)) return\n\t\t\t\t\t\t\t\t\t\tthis.editor.setEditingShape(selectingShape.id)\n\t\t\t\t\t\t\t\t\t\tthis.editor.setCurrentTool('select.editing_shape')\n\n\t\t\t\t\t\t\t\t\t\tif (this.isDoubleClick) {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('select-all-text', { shapeId: selectingShape.id })\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('place-caret', {\n\t\t\t\t\t\t\t\t\t\t\t\tshapeId: selectingShape.id,\n\t\t\t\t\t\t\t\t\t\t\t\tpoint: info.point,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We just want to select the single shape from the selection\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (additiveSelectionKey) {\n\t\t\t\t// Different shape, so we are drilling down into a group with shift key held.\n\t\t\t\t// Deselect any ancestors and add the target shape to the selection\n\t\t\t\tconst ancestors = this.editor.getShapeAncestors(outermostSelectableShape)\n\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift deselecting on pointer up')\n\t\t\t\tthis.editor.setSelectedShapes([\n\t\t\t\t\t...this.editor.getSelectedShapeIds().filter((id) => !ancestors.find((a) => a.id === id)),\n\t\t\t\t\toutermostSelectableShape.id,\n\t\t\t\t])\n\t\t\t} else {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t// different shape and we are drilling down, but no shift held so just select it straight up\n\t\t\t\tthis.editor.setSelectedShapes([outermostSelectableShape.id])\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle', info)\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tthis.isDoubleClick = true\n\n\t\tif (\n\t\t\tthis.editor.inputs.getShiftKey() ||\n\t\t\tinfo.phase !== 'down' ||\n\t\t\tinfo.ctrlKey ||\n\t\t\tinfo.shiftKey\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { shape: _shape, ...canvasInfo } = info as TLClickEventInfo & { target: 'shape' }\n\t\tthis.parent.transition('idle')\n\t\tthis.parent.getCurrent()?.handleEvent({\n\t\t\t...canvasInfo,\n\t\t\ttarget: 'canvas',\n\t\t})\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tif (isOverArrowLabel(this.editor, this.hitShape)) {\n\t\t\t\t// We're moving the label on a shape.\n\t\t\t\tthis.parent.transition('pointing_arrow_label', { ...info, shape: this.hitShape })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (this.didCtrlOnEnter) {\n\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t} else {\n\t\t\t\tthis.startTranslating(info)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onLongPress(info: TLPointerEventInfo) {\n\t\tthis.startTranslating(info)\n\t}\n\n\tprivate startTranslating(info: TLPointerEventInfo) {\n\t\tif (this.editor.getIsReadonly()) return\n\n\t\t// If we didn't select the shape on enter (e.g. because it has an onClick handler),\n\t\t// and there's no current selection, select it now before transitioning to translating.\n\t\tif (!this.didSelectOnEnter && !this.editor.getSelectedShapeIds().length) {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([this.hitShapeForPointerUp.id])\n\t\t}\n\n\t\t// Re-focus the editor, just in case the text label of the shape has stolen focus\n\t\tthis.editor.focus()\n\t\tthis.parent.transition('translating', info)\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tthis.parent.transition('idle')\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -8,8 +8,10 @@ import {
8
8
  areAnglesCompatible,
9
9
  compact,
10
10
  isAccelKey,
11
+ isShapeId,
11
12
  kickoutOccludedShapes
12
13
  } from "@tldraw/editor";
14
+ import { getEnclosedShapeIds } from "../../../shapes/frame/FrameShapeTool.mjs";
13
15
  import { batchMeasureGeoLabels, setBatchLabelSizeCache } from "../../../shapes/geo/GeoShapeUtil.mjs";
14
16
  class Resizing extends StateNode {
15
17
  static id = "resizing";
@@ -154,39 +156,45 @@ class Resizing extends StateNode {
154
156
  }
155
157
  }
156
158
  updateShapes() {
157
- const altKey = this.editor.inputs.getAltKey();
158
- const shiftKey = this.editor.inputs.getShiftKey();
159
159
  const {
160
- frames,
161
- shapeSnapshots,
162
- selectionBounds,
163
- cursorHandleOffset,
164
- selectedShapeIds,
165
- selectionRotation,
166
- canShapesDeform
167
- } = this.snapshot;
160
+ editor,
161
+ info,
162
+ snapshot: {
163
+ frames,
164
+ shapeSnapshots,
165
+ selectionBounds,
166
+ cursorHandleOffset,
167
+ selectedShapeIds,
168
+ selectionRotation,
169
+ canShapesDeform,
170
+ initialSelectionPageBounds,
171
+ resizeLevels
172
+ }
173
+ } = this;
174
+ const altKey = editor.inputs.getAltKey();
175
+ const shiftKey = editor.inputs.getShiftKey();
168
176
  let isAspectRatioLocked = shiftKey || !canShapesDeform;
169
177
  if (shapeSnapshots.size === 1) {
170
178
  const onlySnapshot = [...shapeSnapshots.values()][0];
171
- if (this.editor.isShapeOfType(onlySnapshot.shape, "text")) {
172
- isAspectRatioLocked = !(this.info.handle === "left" || this.info.handle === "right");
179
+ if (editor.isShapeOfType(onlySnapshot.shape, "text")) {
180
+ isAspectRatioLocked = !(info.handle === "left" || info.handle === "right");
173
181
  }
174
182
  }
175
- const isHoldingAccel = isAccelKey(this.editor.inputs);
176
- const currentPagePoint = this.editor.inputs.getCurrentPagePoint().clone().sub(cursorHandleOffset).sub(this.creationCursorOffset);
177
- const originPagePoint = this.editor.inputs.getOriginPagePoint().clone().sub(cursorHandleOffset);
178
- if (this.editor.getInstanceState().isGridMode && !isHoldingAccel) {
179
- const { gridSize } = this.editor.getDocumentSettings();
183
+ const isHoldingAccel = isAccelKey(editor.inputs);
184
+ const currentPagePoint = editor.inputs.getCurrentPagePoint().clone().sub(cursorHandleOffset).sub(this.creationCursorOffset);
185
+ const originPagePoint = editor.inputs.getOriginPagePoint().clone().sub(cursorHandleOffset);
186
+ if (editor.getInstanceState().isGridMode && !isHoldingAccel) {
187
+ const { gridSize } = editor.getDocumentSettings();
180
188
  currentPagePoint.snapToGrid(gridSize);
181
189
  }
182
- const dragHandle = this.info.handle;
190
+ const dragHandle = info.handle;
183
191
  const scaleOriginHandle = rotateSelectionHandle(dragHandle, Math.PI);
184
- this.editor.snaps.clearIndicators();
185
- const shouldSnap = this.editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel;
192
+ editor.snaps.clearIndicators();
193
+ const shouldSnap = editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel;
186
194
  if (shouldSnap && selectionRotation % HALF_PI === 0) {
187
- const { nudge } = this.editor.snaps.shapeBounds.snapResizeShapes({
195
+ const { nudge } = editor.snaps.shapeBounds.snapResizeShapes({
188
196
  dragDelta: Vec.Sub(currentPagePoint, originPagePoint),
189
- initialSelectionPageBounds: this.snapshot.initialSelectionPageBounds,
197
+ initialSelectionPageBounds,
190
198
  handle: rotateSelectionHandle(dragHandle, selectionRotation),
191
199
  isAspectRatioLocked,
192
200
  isResizingFromCenter: altKey
@@ -244,22 +252,30 @@ class Resizing extends StateNode {
244
252
  isAspectRatioLocked
245
253
  );
246
254
  }
247
- for (const id of shapeSnapshots.keys()) {
248
- const snapshot = shapeSnapshots.get(id);
249
- this.editor.resizeShape(id, scale, {
250
- initialShape: snapshot.shape,
251
- initialBounds: snapshot.bounds,
252
- initialPageTransform: snapshot.pageTransform,
253
- dragHandle,
254
- mode: selectedShapeIds.length === 1 && id === selectedShapeIds[0] ? "resize_bounds" : "scale_shape",
255
- scaleOrigin: scaleOriginPage,
256
- isAspectRatioLocked,
257
- scaleAxisRotation: selectionRotation,
258
- skipStartAndEndCallbacks: true
259
- });
255
+ for (const level of resizeLevels) {
256
+ const changes = [];
257
+ for (const id of level) {
258
+ const snapshot = shapeSnapshots.get(id);
259
+ const change = editor.getResizeShapePartial(id, scale, {
260
+ initialShape: snapshot.shape,
261
+ initialBounds: snapshot.bounds,
262
+ initialPageTransform: snapshot.pageTransform,
263
+ dragHandle,
264
+ mode: selectedShapeIds.length === 1 && id === selectedShapeIds[0] ? "resize_bounds" : "scale_shape",
265
+ scaleOrigin: scaleOriginPage,
266
+ isAspectRatioLocked,
267
+ scaleAxisRotation: selectionRotation,
268
+ skipStartAndEndCallbacks: true
269
+ });
270
+ if (change) changes.push(change);
271
+ }
272
+ if (changes.length > 0) {
273
+ editor.updateShapes(changes);
274
+ }
260
275
  }
261
276
  if (isHoldingAccel) {
262
277
  this.didHoldCommand = true;
278
+ const childChanges = [];
263
279
  for (const { id, children } of frames) {
264
280
  if (!children.length) continue;
265
281
  const initial = shapeSnapshots.get(id).shape;
@@ -270,7 +286,7 @@ class Resizing extends StateNode {
270
286
  const delta = new Vec(dx, dy).rot(-initial.rotation);
271
287
  if (delta.x !== 0 || delta.y !== 0) {
272
288
  for (const child of children) {
273
- this.editor.updateShape({
289
+ childChanges.push({
274
290
  id: child.id,
275
291
  type: child.type,
276
292
  x: child.x - delta.x,
@@ -279,12 +295,15 @@ class Resizing extends StateNode {
279
295
  }
280
296
  }
281
297
  }
298
+ if (childChanges.length > 0) {
299
+ this.editor.updateShapes(childChanges);
300
+ }
282
301
  } else if (this.didHoldCommand) {
283
302
  this.didHoldCommand = false;
303
+ const childChanges = [];
284
304
  for (const { children } of frames) {
285
- if (!children.length) continue;
286
305
  for (const child of children) {
287
- this.editor.updateShape({
306
+ childChanges.push({
288
307
  id: child.id,
289
308
  type: child.type,
290
309
  x: child.x,
@@ -292,7 +311,23 @@ class Resizing extends StateNode {
292
311
  });
293
312
  }
294
313
  }
314
+ if (childChanges.length > 0) {
315
+ this.editor.updateShapes(childChanges);
316
+ }
317
+ }
318
+ this.updateEnclosureHints();
319
+ }
320
+ // While drag-creating a frame, hint the sibling shapes that would become its children on pointer up
321
+ updateEnclosureHints() {
322
+ if (!this.info.isCreating) return;
323
+ const shape = this.editor.getOnlySelectedShape();
324
+ if (!shape || !this.editor.isShapeOfType(shape, "frame")) return;
325
+ const hintingShapeIds = getEnclosedShapeIds(this.editor, shape);
326
+ const prevHintingShapeIds = this.editor.getHintingShapeIds();
327
+ if (hintingShapeIds.length === prevHintingShapeIds.length && hintingShapeIds.every((id, i) => id === prevHintingShapeIds[i])) {
328
+ return;
295
329
  }
330
+ this.editor.setHintingShapes(hintingShapeIds);
296
331
  }
297
332
  // ---
298
333
  updateCursor({
@@ -301,33 +336,37 @@ class Resizing extends StateNode {
301
336
  isFlippedY,
302
337
  rotation
303
338
  }) {
304
- const nextCursor = { ...this.editor.getInstanceState().cursor };
339
+ const prevCursor = this.editor.getInstanceState().cursor;
340
+ let nextCursorType = prevCursor.type;
305
341
  switch (dragHandle) {
306
342
  case "top_left":
307
343
  case "bottom_right": {
308
- nextCursor.type = "nwse-resize";
344
+ nextCursorType = "nwse-resize";
309
345
  if (isFlippedX !== isFlippedY) {
310
- nextCursor.type = "nesw-resize";
346
+ nextCursorType = "nesw-resize";
311
347
  }
312
348
  break;
313
349
  }
314
350
  case "top_right":
315
351
  case "bottom_left": {
316
- nextCursor.type = "nesw-resize";
352
+ nextCursorType = "nesw-resize";
317
353
  if (isFlippedX !== isFlippedY) {
318
- nextCursor.type = "nwse-resize";
354
+ nextCursorType = "nwse-resize";
319
355
  }
320
356
  break;
321
357
  }
322
358
  }
323
- nextCursor.rotation = rotation;
324
- this.editor.setCursor(nextCursor);
359
+ if (nextCursorType === prevCursor.type && rotation === prevCursor.rotation) return;
360
+ this.editor.setCursor({ type: nextCursorType, rotation });
325
361
  }
326
362
  onExit() {
327
363
  this.parent.setCurrentToolIdMask(void 0);
328
364
  this.editor.setCursor({ type: "default", rotation: 0 });
329
365
  this.editor.snaps.clearIndicators();
330
366
  setBatchLabelSizeCache(this.editor, null);
367
+ if (this.info.isCreating && this.editor.getHintingShapeIds().length > 0) {
368
+ this.editor.setHintingShapes([]);
369
+ }
331
370
  }
332
371
  _createSnapshot() {
333
372
  const { editor } = this;
@@ -377,6 +416,28 @@ class Resizing extends StateNode {
377
416
  const canShapesDeform = ![...shapeSnapshots.values()].some(
378
417
  (shape) => !areAnglesCompatible(shape.pageRotation, selectionRotation) || shape.isAspectRatioLocked
379
418
  );
419
+ const resizeLevels = [];
420
+ const levelByShapeId = /* @__PURE__ */ new Map();
421
+ const getLevel = (id) => {
422
+ const cached = levelByShapeId.get(id);
423
+ if (cached !== void 0) return cached;
424
+ let level = 0;
425
+ let parentId = editor.getShape(id)?.parentId;
426
+ while (parentId && isShapeId(parentId)) {
427
+ if (shapeSnapshots.has(parentId)) {
428
+ level = getLevel(parentId) + 1;
429
+ break;
430
+ }
431
+ parentId = editor.getShape(parentId)?.parentId;
432
+ }
433
+ levelByShapeId.set(id, level);
434
+ return level;
435
+ };
436
+ for (const id of shapeSnapshots.keys()) {
437
+ const level = getLevel(id);
438
+ while (resizeLevels.length <= level) resizeLevels.push([]);
439
+ resizeLevels[level].push(id);
440
+ }
380
441
  return {
381
442
  shapeSnapshots,
382
443
  selectionBounds,
@@ -385,7 +446,8 @@ class Resizing extends StateNode {
385
446
  selectedShapeIds,
386
447
  canShapesDeform,
387
448
  initialSelectionPageBounds: this.editor.getSelectionPageBounds(),
388
- frames
449
+ frames,
450
+ resizeLevels
389
451
  };
390
452
  }
391
453
  }