@tldraw/editor 4.3.0-next.f4772c19540d → 4.4.0-canary.29afdff6bb04

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 (206) hide show
  1. package/README.md +1 -1
  2. package/dist-cjs/index.d.ts +503 -155
  3. package/dist-cjs/index.js +8 -1
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/components/ErrorBoundary.js.map +1 -1
  6. package/dist-cjs/lib/components/GeometryDebuggingView.js +1 -17
  7. package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +4 -5
  9. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  10. package/dist-cjs/lib/constants.js +1 -3
  11. package/dist-cjs/lib/constants.js.map +2 -2
  12. package/dist-cjs/lib/editor/Editor.js +346 -291
  13. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  14. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
  15. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  16. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +16 -23
  17. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +3 -3
  18. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +12 -3
  19. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  20. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -1
  21. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  22. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +5 -6
  23. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
  24. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +591 -0
  25. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +7 -0
  26. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +1 -1
  27. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  28. package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js +144 -0
  29. package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js.map +7 -0
  30. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +181 -0
  31. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +7 -0
  32. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -22
  33. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
  34. package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
  35. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +31 -23
  36. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  37. package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js +1 -1
  38. package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js.map +2 -2
  39. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  40. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
  41. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -3
  42. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  43. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  44. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  45. package/dist-cjs/lib/exports/parseCss.js +1 -1
  46. package/dist-cjs/lib/exports/parseCss.js.map +2 -2
  47. package/dist-cjs/lib/globals/environment.js +45 -9
  48. package/dist-cjs/lib/globals/environment.js.map +2 -2
  49. package/dist-cjs/lib/globals/menus.js +1 -1
  50. package/dist-cjs/lib/globals/menus.js.map +2 -2
  51. package/dist-cjs/lib/hooks/useCoarsePointer.js +14 -29
  52. package/dist-cjs/lib/hooks/useCoarsePointer.js.map +2 -2
  53. package/dist-cjs/lib/hooks/useEvent.js +1 -1
  54. package/dist-cjs/lib/hooks/useEvent.js.map +2 -2
  55. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
  56. package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
  57. package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
  58. package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
  59. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  60. package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
  61. package/dist-cjs/lib/hooks/useStateAttribute.js +4 -1
  62. package/dist-cjs/lib/hooks/useStateAttribute.js.map +2 -2
  63. package/dist-cjs/lib/hooks/useTransform.js.map +1 -1
  64. package/dist-cjs/lib/hooks/useZoomCss.js +4 -8
  65. package/dist-cjs/lib/hooks/useZoomCss.js.map +2 -2
  66. package/dist-cjs/lib/options.js +6 -1
  67. package/dist-cjs/lib/options.js.map +2 -2
  68. package/dist-cjs/lib/primitives/Box.js +3 -0
  69. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  70. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +1 -0
  71. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  72. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  73. package/dist-cjs/lib/utils/rotation.js +1 -1
  74. package/dist-cjs/lib/utils/rotation.js.map +2 -2
  75. package/dist-cjs/version.js +3 -3
  76. package/dist-cjs/version.js.map +1 -1
  77. package/dist-esm/index.d.mts +503 -155
  78. package/dist-esm/index.mjs +9 -2
  79. package/dist-esm/index.mjs.map +2 -2
  80. package/dist-esm/lib/components/ErrorBoundary.mjs.map +1 -1
  81. package/dist-esm/lib/components/GeometryDebuggingView.mjs +1 -17
  82. package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
  83. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +4 -5
  84. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  85. package/dist-esm/lib/constants.mjs +1 -3
  86. package/dist-esm/lib/constants.mjs.map +2 -2
  87. package/dist-esm/lib/editor/Editor.mjs +347 -294
  88. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  89. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
  90. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  91. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +16 -23
  92. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +3 -3
  93. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +13 -4
  94. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  95. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -1
  96. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  97. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +5 -6
  98. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
  99. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +573 -0
  100. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +7 -0
  101. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +1 -1
  102. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  103. package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs +114 -0
  104. package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs.map +7 -0
  105. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +161 -0
  106. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +7 -0
  107. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -22
  108. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
  109. package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
  110. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +31 -23
  111. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  112. package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs +1 -1
  113. package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs.map +2 -2
  114. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  115. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
  116. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -3
  117. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  118. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  119. package/dist-esm/lib/exports/parseCss.mjs +1 -1
  120. package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
  121. package/dist-esm/lib/globals/environment.mjs +45 -9
  122. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  123. package/dist-esm/lib/globals/menus.mjs +1 -1
  124. package/dist-esm/lib/globals/menus.mjs.map +2 -2
  125. package/dist-esm/lib/hooks/useCoarsePointer.mjs +15 -30
  126. package/dist-esm/lib/hooks/useCoarsePointer.mjs.map +2 -2
  127. package/dist-esm/lib/hooks/useEvent.mjs +1 -1
  128. package/dist-esm/lib/hooks/useEvent.mjs.map +2 -2
  129. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
  130. package/dist-esm/lib/hooks/useGestureEvents.mjs +1 -1
  131. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
  132. package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
  133. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  134. package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
  135. package/dist-esm/lib/hooks/useStateAttribute.mjs +4 -1
  136. package/dist-esm/lib/hooks/useStateAttribute.mjs.map +2 -2
  137. package/dist-esm/lib/hooks/useTransform.mjs.map +1 -1
  138. package/dist-esm/lib/hooks/useZoomCss.mjs +4 -8
  139. package/dist-esm/lib/hooks/useZoomCss.mjs.map +2 -2
  140. package/dist-esm/lib/options.mjs +6 -1
  141. package/dist-esm/lib/options.mjs.map +2 -2
  142. package/dist-esm/lib/primitives/Box.mjs +3 -0
  143. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  144. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +1 -0
  145. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  146. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  147. package/dist-esm/lib/utils/rotation.mjs +1 -1
  148. package/dist-esm/lib/utils/rotation.mjs.map +2 -2
  149. package/dist-esm/version.mjs +3 -3
  150. package/dist-esm/version.mjs.map +1 -1
  151. package/editor.css +14 -12
  152. package/package.json +21 -17
  153. package/src/index.ts +5 -1
  154. package/src/lib/components/ErrorBoundary.tsx +1 -1
  155. package/src/lib/components/GeometryDebuggingView.tsx +1 -19
  156. package/src/lib/components/default-components/DefaultCanvas.tsx +5 -8
  157. package/src/lib/config/TLUserPreferences.test.ts +40 -0
  158. package/src/lib/constants.ts +0 -2
  159. package/src/lib/editor/Editor.test.ts +150 -10
  160. package/src/lib/editor/Editor.ts +533 -384
  161. package/src/lib/editor/bindings/BindingUtil.ts +15 -9
  162. package/src/lib/editor/derivations/bindingsIndex.ts +2 -2
  163. package/src/lib/editor/derivations/notVisibleShapes.ts +21 -33
  164. package/src/lib/editor/derivations/parentsToChildren.ts +18 -7
  165. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +17 -31
  166. package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
  167. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +129 -79
  168. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +10 -6
  169. package/src/lib/editor/managers/FontManager/FontManager.test.ts +14 -4
  170. package/src/lib/editor/managers/InputsManager/InputsManager.ts +566 -0
  171. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +0 -4
  172. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +12 -0
  173. package/src/lib/editor/managers/SnapManager/SnapManager.ts +4 -4
  174. package/src/lib/editor/managers/SpatialIndexManager/RBushIndex.ts +144 -0
  175. package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +215 -0
  176. package/src/lib/editor/managers/TickManager/TickManager.test.ts +40 -107
  177. package/src/lib/editor/managers/TickManager/TickManager.ts +2 -32
  178. package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
  179. package/src/lib/editor/shapes/ShapeUtil.ts +72 -32
  180. package/src/lib/editor/shapes/group/DashedOutlineBox.tsx +1 -1
  181. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -3
  182. package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +2 -1
  183. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +6 -6
  184. package/src/lib/editor/types/emit-types.ts +3 -1
  185. package/src/lib/exports/getSvgJsx.test.ts +10 -19
  186. package/src/lib/exports/getSvgJsx.tsx +2 -5
  187. package/src/lib/exports/parseCss.test.ts +1 -0
  188. package/src/lib/exports/parseCss.ts +1 -1
  189. package/src/lib/globals/environment.ts +65 -10
  190. package/src/lib/globals/menus.ts +1 -1
  191. package/src/lib/hooks/useCoarsePointer.ts +16 -59
  192. package/src/lib/hooks/useEvent.tsx +1 -1
  193. package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +1 -1
  194. package/src/lib/hooks/useGestureEvents.ts +2 -2
  195. package/src/lib/hooks/usePassThroughMouseOverEvents.ts +1 -1
  196. package/src/lib/hooks/usePassThroughWheelEvents.ts +1 -1
  197. package/src/lib/hooks/useScreenBounds.ts +1 -1
  198. package/src/lib/hooks/useStateAttribute.ts +4 -1
  199. package/src/lib/hooks/useTransform.ts +1 -1
  200. package/src/lib/hooks/useZoomCss.ts +3 -8
  201. package/src/lib/options.ts +32 -0
  202. package/src/lib/primitives/Box.ts +9 -0
  203. package/src/lib/primitives/geometry/Geometry2d.ts +1 -0
  204. package/src/lib/utils/reparenting.ts +5 -5
  205. package/src/lib/utils/rotation.ts +1 -1
  206. package/src/version.ts +3 -3
@@ -104,7 +104,6 @@ var import_assets = require("../utils/assets");
104
104
  var import_debug_flags = require("../utils/debug-flags");
105
105
  var import_deepLinks = require("../utils/deepLinks");
106
106
  var import_getIncrementedName = require("../utils/getIncrementedName");
107
- var import_keyboard = require("../utils/keyboard");
108
107
  var import_reorderShapes = require("../utils/reorderShapes");
109
108
  var import_rotation = require("../utils/rotation");
110
109
  var import_bindingsIndex = require("./derivations/bindingsIndex");
@@ -116,14 +115,16 @@ var import_EdgeScrollManager = require("./managers/EdgeScrollManager/EdgeScrollM
116
115
  var import_FocusManager = require("./managers/FocusManager/FocusManager");
117
116
  var import_FontManager = require("./managers/FontManager/FontManager");
118
117
  var import_HistoryManager = require("./managers/HistoryManager/HistoryManager");
118
+ var import_InputsManager = require("./managers/InputsManager/InputsManager");
119
119
  var import_ScribbleManager = require("./managers/ScribbleManager/ScribbleManager");
120
120
  var import_SnapManager = require("./managers/SnapManager/SnapManager");
121
+ var import_SpatialIndexManager = require("./managers/SpatialIndexManager/SpatialIndexManager");
121
122
  var import_TextManager = require("./managers/TextManager/TextManager");
122
123
  var import_TickManager = require("./managers/TickManager/TickManager");
123
124
  var import_UserPreferencesManager = require("./managers/UserPreferencesManager/UserPreferencesManager");
124
125
  var import_RootState = require("./tools/RootState");
125
- var __setMetaKeyTimeout_dec, __setCtrlKeyTimeout_dec, __setAltKeyTimeout_dec, __setShiftKeyTimeout_dec, _getIsReadonly_dec, _getIsFocused_dec, _getSharedOpacity_dec, _getSharedStyles_dec, __getSelectionSharedStyles_dec, __getBindingsIndexCache_dec, _getCurrentPageRenderingShapesSorted_dec, _getCurrentPageShapesSorted_dec, _getCurrentPageShapes_dec, _getCurrentPageBounds_dec, _getCulledShapes_dec, _getNotVisibleShapes_dec, __getShapeMaskedPageBoundsCache_dec, __getShapeMaskCache_dec, __getShapeClipPathCache_dec, __getShapePageBoundsCache_dec, __getShapePageTransformCache_dec, __getShapeHandlesCache_dec, __getAllAssetsQuery_dec, _getCurrentPageShapeIdsSorted_dec, _getCurrentPageId_dec, _getPages_dec, __getAllPagesQuery_dec, _getRenderingShapes_dec, _getCollaboratorsOnCurrentPage_dec, _getCollaborators_dec, __getCollaboratorsQuery_dec, _getViewportPageBounds_dec, _getViewportScreenCenter_dec, _getViewportScreenBounds_dec, _getZoomLevel_dec, _getCameraForFollowing_dec, _getViewportPageBoundsForFollowing_dec, _getCamera_dec, __unsafe_getCameraId_dec, _getErasingShapes_dec, _getErasingShapeIds_dec, _getHintingShape_dec, _getHintingShapeIds_dec, _getHoveredShape_dec, _getHoveredShapeId_dec, _getRichTextEditor_dec, _getEditingShape_dec, _getEditingShapeId_dec, _getFocusedGroup_dec, _getFocusedGroupId_dec, _getSelectionRotatedScreenBounds_dec, _getSelectionRotatedPageBounds_dec, _getSelectionRotation_dec, _getSelectionPageBounds_dec, _getOnlySelectedShape_dec, _getOnlySelectedShapeId_dec, _getCurrentPageShapesInReadingOrder_dec, _getSelectedShapes_dec, _getSelectedShapeIds_dec, __getCurrentPageStateId_dec, _getCurrentPageState_dec, __getPageStatesQuery_dec, _getPageStates_dec, _getInstanceState_dec, _getDocumentSettings_dec, _getCurrentToolId_dec, _getCurrentTool_dec, _getPath_dec, _getCanRedo_dec, _getCanUndo_dec, _getIsShapeHiddenCache_dec, _a, _init;
126
- class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_dec = [import_state.computed], _getCanUndo_dec = [import_state.computed], _getCanRedo_dec = [import_state.computed], _getPath_dec = [import_state.computed], _getCurrentTool_dec = [import_state.computed], _getCurrentToolId_dec = [import_state.computed], _getDocumentSettings_dec = [import_state.computed], _getInstanceState_dec = [import_state.computed], _getPageStates_dec = [import_state.computed], __getPageStatesQuery_dec = [import_state.computed], _getCurrentPageState_dec = [import_state.computed], __getCurrentPageStateId_dec = [import_state.computed], _getSelectedShapeIds_dec = [import_state.computed], _getSelectedShapes_dec = [import_state.computed], _getCurrentPageShapesInReadingOrder_dec = [import_state.computed], _getOnlySelectedShapeId_dec = [import_state.computed], _getOnlySelectedShape_dec = [import_state.computed], _getSelectionPageBounds_dec = [import_state.computed], _getSelectionRotation_dec = [import_state.computed], _getSelectionRotatedPageBounds_dec = [import_state.computed], _getSelectionRotatedScreenBounds_dec = [import_state.computed], _getFocusedGroupId_dec = [import_state.computed], _getFocusedGroup_dec = [import_state.computed], _getEditingShapeId_dec = [import_state.computed], _getEditingShape_dec = [import_state.computed], _getRichTextEditor_dec = [import_state.computed], _getHoveredShapeId_dec = [import_state.computed], _getHoveredShape_dec = [import_state.computed], _getHintingShapeIds_dec = [import_state.computed], _getHintingShape_dec = [import_state.computed], _getErasingShapeIds_dec = [import_state.computed], _getErasingShapes_dec = [import_state.computed], __unsafe_getCameraId_dec = [import_state.computed], _getCamera_dec = [import_state.computed], _getViewportPageBoundsForFollowing_dec = [import_state.computed], _getCameraForFollowing_dec = [import_state.computed], _getZoomLevel_dec = [import_state.computed], _getViewportScreenBounds_dec = [import_state.computed], _getViewportScreenCenter_dec = [import_state.computed], _getViewportPageBounds_dec = [import_state.computed], __getCollaboratorsQuery_dec = [import_state.computed], _getCollaborators_dec = [import_state.computed], _getCollaboratorsOnCurrentPage_dec = [import_state.computed], _getRenderingShapes_dec = [import_state.computed], __getAllPagesQuery_dec = [import_state.computed], _getPages_dec = [import_state.computed], _getCurrentPageId_dec = [import_state.computed], _getCurrentPageShapeIdsSorted_dec = [import_state.computed], __getAllAssetsQuery_dec = [import_state.computed], __getShapeHandlesCache_dec = [import_state.computed], __getShapePageTransformCache_dec = [import_state.computed], __getShapePageBoundsCache_dec = [import_state.computed], __getShapeClipPathCache_dec = [import_state.computed], __getShapeMaskCache_dec = [import_state.computed], __getShapeMaskedPageBoundsCache_dec = [import_state.computed], _getNotVisibleShapes_dec = [import_state.computed], _getCulledShapes_dec = [import_state.computed], _getCurrentPageBounds_dec = [import_state.computed], _getCurrentPageShapes_dec = [import_state.computed], _getCurrentPageShapesSorted_dec = [import_state.computed], _getCurrentPageRenderingShapesSorted_dec = [import_state.computed], __getBindingsIndexCache_dec = [import_state.computed], __getSelectionSharedStyles_dec = [import_state.computed], _getSharedStyles_dec = [(0, import_state.computed)({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [import_state.computed], _getIsFocused_dec = [import_state.computed], _getIsReadonly_dec = [import_state.computed], __setShiftKeyTimeout_dec = [import_utils.bind], __setAltKeyTimeout_dec = [import_utils.bind], __setCtrlKeyTimeout_dec = [import_utils.bind], __setMetaKeyTimeout_dec = [import_utils.bind], _a) {
126
+ var __setMetaKeyTimeout_dec, __setCtrlKeyTimeout_dec, __setAltKeyTimeout_dec, __setShiftKeyTimeout_dec, _getIsReadonly_dec, _getIsFocused_dec, _getSharedOpacity_dec, _getSharedStyles_dec, __getSelectionSharedStyles_dec, __getBindingsIndexCache_dec, _getCurrentPageRenderingShapesSorted_dec, _getCurrentPageShapesSorted_dec, _getCurrentPageShapes_dec, _getCurrentPageBounds_dec, _getCulledShapes_dec, _getNotVisibleShapes_dec, __getShapeMaskedPageBoundsCache_dec, __getShapeMaskCache_dec, __getShapeClipPathCache_dec, __getShapePageBoundsCache_dec, __getShapePageTransformCache_dec, __getShapeHandlesCache_dec, __getAllAssetsQuery_dec, _getCurrentPageShapeIdsSorted_dec, _getCurrentPageId_dec, _getPages_dec, __getAllPagesQuery_dec, _getRenderingShapes_dec, _getCollaboratorsOnCurrentPage_dec, _getCollaborators_dec, __getCollaboratorsQuery_dec, _getViewportPageBounds_dec, _getViewportScreenCenter_dec, _getViewportScreenBounds_dec, _getEfficientZoomLevel_dec, __getAboveDebouncedZoomThreshold_dec, _getDebouncedZoomLevel_dec, _getZoomLevel_dec, _getCameraForFollowing_dec, _getViewportPageBoundsForFollowing_dec, _getCamera_dec, __unsafe_getCameraId_dec, _getErasingShapes_dec, _getErasingShapeIds_dec, _getHintingShape_dec, _getHintingShapeIds_dec, _getHoveredShape_dec, _getHoveredShapeId_dec, _getRichTextEditor_dec, _getEditingShape_dec, _getEditingShapeId_dec, _getFocusedGroup_dec, _getFocusedGroupId_dec, _getSelectionRotatedScreenBounds_dec, _getSelectionRotatedPageBounds_dec, _getSelectionRotation_dec, _getSelectionPageBounds_dec, _getOnlySelectedShape_dec, _getOnlySelectedShapeId_dec, _getCurrentPageShapesInReadingOrder_dec, _getSelectedShapes_dec, _getSelectedShapeIds_dec, __getCurrentPageStateId_dec, _getCurrentPageState_dec, __getPageStatesQuery_dec, _getPageStates_dec, _getInstanceState_dec, _getDocumentSettings_dec, _getCurrentToolId_dec, _getCurrentTool_dec, _getPath_dec, _canRedo_dec, _canUndo_dec, _getIsShapeHiddenCache_dec, _a, _init;
127
+ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_dec = [import_state.computed], _canUndo_dec = [import_state.computed], _canRedo_dec = [import_state.computed], _getPath_dec = [import_state.computed], _getCurrentTool_dec = [import_state.computed], _getCurrentToolId_dec = [import_state.computed], _getDocumentSettings_dec = [import_state.computed], _getInstanceState_dec = [import_state.computed], _getPageStates_dec = [import_state.computed], __getPageStatesQuery_dec = [import_state.computed], _getCurrentPageState_dec = [import_state.computed], __getCurrentPageStateId_dec = [import_state.computed], _getSelectedShapeIds_dec = [import_state.computed], _getSelectedShapes_dec = [import_state.computed], _getCurrentPageShapesInReadingOrder_dec = [import_state.computed], _getOnlySelectedShapeId_dec = [import_state.computed], _getOnlySelectedShape_dec = [import_state.computed], _getSelectionPageBounds_dec = [import_state.computed], _getSelectionRotation_dec = [import_state.computed], _getSelectionRotatedPageBounds_dec = [import_state.computed], _getSelectionRotatedScreenBounds_dec = [import_state.computed], _getFocusedGroupId_dec = [import_state.computed], _getFocusedGroup_dec = [import_state.computed], _getEditingShapeId_dec = [import_state.computed], _getEditingShape_dec = [import_state.computed], _getRichTextEditor_dec = [import_state.computed], _getHoveredShapeId_dec = [import_state.computed], _getHoveredShape_dec = [import_state.computed], _getHintingShapeIds_dec = [import_state.computed], _getHintingShape_dec = [import_state.computed], _getErasingShapeIds_dec = [import_state.computed], _getErasingShapes_dec = [import_state.computed], __unsafe_getCameraId_dec = [import_state.computed], _getCamera_dec = [import_state.computed], _getViewportPageBoundsForFollowing_dec = [import_state.computed], _getCameraForFollowing_dec = [import_state.computed], _getZoomLevel_dec = [import_state.computed], _getDebouncedZoomLevel_dec = [import_state.computed], __getAboveDebouncedZoomThreshold_dec = [import_state.computed], _getEfficientZoomLevel_dec = [import_state.computed], _getViewportScreenBounds_dec = [import_state.computed], _getViewportScreenCenter_dec = [import_state.computed], _getViewportPageBounds_dec = [import_state.computed], __getCollaboratorsQuery_dec = [import_state.computed], _getCollaborators_dec = [import_state.computed], _getCollaboratorsOnCurrentPage_dec = [import_state.computed], _getRenderingShapes_dec = [import_state.computed], __getAllPagesQuery_dec = [import_state.computed], _getPages_dec = [import_state.computed], _getCurrentPageId_dec = [import_state.computed], _getCurrentPageShapeIdsSorted_dec = [import_state.computed], __getAllAssetsQuery_dec = [import_state.computed], __getShapeHandlesCache_dec = [import_state.computed], __getShapePageTransformCache_dec = [import_state.computed], __getShapePageBoundsCache_dec = [import_state.computed], __getShapeClipPathCache_dec = [import_state.computed], __getShapeMaskCache_dec = [import_state.computed], __getShapeMaskedPageBoundsCache_dec = [import_state.computed], _getNotVisibleShapes_dec = [import_state.computed], _getCulledShapes_dec = [import_state.computed], _getCurrentPageBounds_dec = [import_state.computed], _getCurrentPageShapes_dec = [import_state.computed], _getCurrentPageShapesSorted_dec = [import_state.computed], _getCurrentPageRenderingShapesSorted_dec = [import_state.computed], __getBindingsIndexCache_dec = [import_state.computed], __getSelectionSharedStyles_dec = [import_state.computed], _getSharedStyles_dec = [(0, import_state.computed)({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [import_state.computed], _getIsFocused_dec = [import_state.computed], _getIsReadonly_dec = [import_state.computed], __setShiftKeyTimeout_dec = [import_utils.bind], __setAltKeyTimeout_dec = [import_utils.bind], __setCtrlKeyTimeout_dec = [import_utils.bind], __setMetaKeyTimeout_dec = [import_utils.bind], _a) {
127
128
  constructor({
128
129
  store,
129
130
  user,
@@ -159,7 +160,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
159
160
  */
160
161
  __publicField(this, "root");
161
162
  /**
162
- * A set of functions to call when the app is disposed.
163
+ * A set of functions to call when the editor is disposed.
163
164
  *
164
165
  * @public
165
166
  */
@@ -170,14 +171,24 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
170
171
  * @public
171
172
  */
172
173
  __publicField(this, "isDisposed", false);
173
- /** @internal */
174
+ /**
175
+ * A manager for the editor's tick events.
176
+ *
177
+ * @internal */
174
178
  __publicField(this, "_tickManager");
175
179
  /**
176
- * A manager for the app's snapping feature.
180
+ * A manager for the editor's input state.
181
+ *
182
+ * @public
183
+ */
184
+ __publicField(this, "inputs");
185
+ /**
186
+ * A manager for the editor's snapping feature.
177
187
  *
178
188
  * @public
179
189
  */
180
190
  __publicField(this, "snaps");
191
+ __publicField(this, "_spatialIndex");
181
192
  /**
182
193
  * A manager for the any asynchronous events and making sure they're
183
194
  * cleaned up upon disposal.
@@ -255,7 +266,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
255
266
  __publicField(this, "bindingUtils");
256
267
  /* --------------------- History -------------------- */
257
268
  /**
258
- * A manager for the app's history.
269
+ * A manager for the editor's history.
259
270
  *
260
271
  * @readonly
261
272
  */
@@ -270,6 +281,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
270
281
  // Rich text editor
271
282
  __publicField(this, "_currentRichTextEditor", (0, import_state.atom)("rich text editor", null));
272
283
  __publicField(this, "_textOptions");
284
+ __publicField(this, "_debouncedZoomLevel", (0, import_state.atom)("debounced zoom level", 1));
273
285
  __publicField(this, "_cameraOptions", (0, import_state.atom)("camera options", import_constants.DEFAULT_CAMERA_OPTIONS));
274
286
  /** @internal */
275
287
  __publicField(this, "_viewportAnimation", null);
@@ -293,6 +305,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
293
305
  /* --------------------- Shapes --------------------- */
294
306
  __publicField(this, "_shapeGeometryCaches", {});
295
307
  __publicField(this, "_notVisibleShapes", (0, import_notVisibleShapes.notVisibleShapes)(this));
308
+ __publicField(this, "_culledShapesCache", null);
296
309
  // Parents and children
297
310
  /**
298
311
  * A cache of parents to children.
@@ -320,54 +333,6 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
320
333
  tldraw: null,
321
334
  excalidraw: null
322
335
  });
323
- /* --------------------- Events --------------------- */
324
- /**
325
- * The app's current input state.
326
- *
327
- * @public
328
- */
329
- __publicField(this, "inputs", {
330
- /** The most recent pointer down's position in the current page space. */
331
- originPagePoint: new import_Vec.Vec(),
332
- /** The most recent pointer down's position in screen space. */
333
- originScreenPoint: new import_Vec.Vec(),
334
- /** The previous pointer position in the current page space. */
335
- previousPagePoint: new import_Vec.Vec(),
336
- /** The previous pointer position in screen space. */
337
- previousScreenPoint: new import_Vec.Vec(),
338
- /** The most recent pointer position in the current page space. */
339
- currentPagePoint: new import_Vec.Vec(),
340
- /** The most recent pointer position in screen space. */
341
- currentScreenPoint: new import_Vec.Vec(),
342
- /** A set containing the currently pressed keys. */
343
- keys: /* @__PURE__ */ new Set(),
344
- /** A set containing the currently pressed buttons. */
345
- buttons: /* @__PURE__ */ new Set(),
346
- /** Whether the input is from a pe. */
347
- isPen: false,
348
- /** Whether the shift key is currently pressed. */
349
- shiftKey: false,
350
- /** Whether the meta key is currently pressed. */
351
- metaKey: false,
352
- /** Whether the control or command key is currently pressed. */
353
- ctrlKey: false,
354
- /** Whether the alt or option key is currently pressed. */
355
- altKey: false,
356
- /** Whether the user is dragging. */
357
- isDragging: false,
358
- /** Whether the user is pointing. */
359
- isPointing: false,
360
- /** Whether the user is pinching. */
361
- isPinching: false,
362
- /** Whether the user is editing. */
363
- isEditing: false,
364
- /** Whether the user is panning. */
365
- isPanning: false,
366
- /** Whether the user is spacebar panning. */
367
- isSpacebarPanning: false,
368
- /** Velocity of mouse pointer, in pixels per millisecond */
369
- pointerVelocity: new import_Vec.Vec()
370
- });
371
336
  /**
372
337
  * A manager for recording multiple click events.
373
338
  *
@@ -391,8 +356,6 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
391
356
  /** @internal */
392
357
  __publicField(this, "_restoreToolId", "select");
393
358
  /** @internal */
394
- __publicField(this, "_pinchStart", 1);
395
- /** @internal */
396
359
  __publicField(this, "_didPinch", false);
397
360
  /** @internal */
398
361
  __publicField(this, "_selectedShapeIdsAtPointerDown", []);
@@ -418,6 +381,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
418
381
  }
419
382
  });
420
383
  this.snaps = new import_SnapManager.SnapManager(this);
384
+ this._spatialIndex = new import_SpatialIndexManager.SpatialIndexManager(this);
385
+ this.disposables.add(() => this._spatialIndex.dispose());
421
386
  this.disposables.add(this.timers.dispose);
422
387
  this._cameraOptions.set({ ...import_constants.DEFAULT_CAMERA_OPTIONS, ...cameraOptions });
423
388
  this._textOptions = (0, import_state.atom)("text options", textOptions ?? null);
@@ -428,6 +393,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
428
393
  this.disposables.add(() => this.textMeasure.dispose());
429
394
  this.fonts = new import_FontManager.FontManager(this, fontAssetUrls);
430
395
  this._tickManager = new import_TickManager.TickManager(this);
396
+ this.inputs = new import_InputsManager.InputsManager(this);
431
397
  class NewRoot extends import_RootState.RootState {
432
398
  static initial = initialState ?? "";
433
399
  }
@@ -860,6 +826,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
860
826
  this.disposables.clear();
861
827
  this.store.dispose();
862
828
  this.isDisposed = true;
829
+ this.emit("dispose");
863
830
  }
864
831
  getShapeUtil(arg) {
865
832
  const type = typeof arg === "string" ? arg : arg.type;
@@ -893,9 +860,12 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
893
860
  this.history.undo();
894
861
  return this;
895
862
  }
896
- getCanUndo() {
863
+ canUndo() {
897
864
  return this.history.getNumUndos() > 0;
898
865
  }
866
+ getCanUndo() {
867
+ return this.canUndo();
868
+ }
899
869
  /**
900
870
  * Redo to the next mark.
901
871
  *
@@ -912,13 +882,16 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
912
882
  this.history.redo();
913
883
  return this;
914
884
  }
885
+ canRedo() {
886
+ return this.history.getNumRedos() > 0;
887
+ }
888
+ getCanRedo() {
889
+ return this.canRedo();
890
+ }
915
891
  clearHistory() {
916
892
  this.history.clear();
917
893
  return this;
918
894
  }
919
- getCanRedo() {
920
- return this.history.getNumRedos() > 0;
921
- }
922
895
  /**
923
896
  * Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
924
897
  * any redos. You typically want to do this just before a user interaction begins or is handled.
@@ -1073,7 +1046,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1073
1046
  }),
1074
1047
  selectionCount: this.getSelectedShapes().length,
1075
1048
  editingShape: editingShapeId ? this.getShape(editingShapeId) : void 0,
1076
- inputs: this.inputs,
1049
+ inputs: this.inputs.toJson(),
1077
1050
  pageState: this.getCurrentPageState(),
1078
1051
  instanceState: this.getInstanceState(),
1079
1052
  collaboratorCount: this.getCollaboratorsOnCurrentPage().length
@@ -1094,7 +1067,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1094
1067
  * we're in a transaction that's about to be rolled back due to the same error we're currently
1095
1068
  * reporting.
1096
1069
  *
1097
- * Instead, to listen to changes to this value, you need to listen to app's `crash` event.
1070
+ * Instead, to listen to changes to this value, you need to listen to editor's `crash` event.
1098
1071
  *
1099
1072
  * @internal
1100
1073
  */
@@ -1745,6 +1718,28 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1745
1718
  const editingShapeId = this.getEditingShapeId();
1746
1719
  return editingShapeId ? this.getShape(editingShapeId) : void 0;
1747
1720
  }
1721
+ /**
1722
+ * Whether the shape can be edited.
1723
+ *
1724
+ * @param shape - The shape (or shape id) to check if it can be edited.
1725
+ * @param info - The info about the edit start.
1726
+ *
1727
+ * @public
1728
+ * @returns true if the shape can be edited, false otherwise.
1729
+ */
1730
+ canEditShape(shape, info) {
1731
+ const id = typeof shape === "string" ? shape : shape?.id ?? null;
1732
+ if (!id) return false;
1733
+ if (id === this.getEditingShapeId()) return false;
1734
+ const _shape = this.getShape(id);
1735
+ if (!_shape) return false;
1736
+ const util = this.getShapeUtil(_shape);
1737
+ const _info = info ?? { type: "unknown" };
1738
+ if (!util.canEdit(_shape, _info)) return false;
1739
+ if (this.getIsReadonly() && !util.canEditInReadonly(_shape)) return false;
1740
+ if (this.isShapeOrAncestorLocked(_shape) && !util.canEditWhileLocked(_shape)) return false;
1741
+ return true;
1742
+ }
1748
1743
  /**
1749
1744
  * Set the current editing shape.
1750
1745
  *
@@ -1760,42 +1755,42 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1760
1755
  */
1761
1756
  setEditingShape(shape) {
1762
1757
  const id = typeof shape === "string" ? shape : shape?.id ?? null;
1763
- this.setRichTextEditor(null);
1764
- const prevEditingShapeId = this.getEditingShapeId();
1765
- if (id !== prevEditingShapeId) {
1766
- if (id) {
1767
- const shape2 = this.getShape(id);
1768
- if (shape2 && this.getShapeUtil(shape2).canEdit(shape2)) {
1769
- this.run(
1770
- () => {
1771
- this._updateCurrentPageState({ editingShapeId: id });
1772
- if (prevEditingShapeId) {
1773
- const prevEditingShape = this.getShape(prevEditingShapeId);
1774
- if (prevEditingShape) {
1775
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1776
- }
1777
- }
1778
- this.getShapeUtil(shape2).onEditStart?.(shape2);
1779
- },
1780
- { history: "ignore" }
1781
- );
1782
- return this;
1783
- }
1784
- }
1758
+ if (!id) {
1785
1759
  this.run(
1786
1760
  () => {
1787
- this._updateCurrentPageState({ editingShapeId: null });
1788
- this._currentRichTextEditor.set(null);
1761
+ const prevEditingShapeId = this.getEditingShapeId();
1789
1762
  if (prevEditingShapeId) {
1790
1763
  const prevEditingShape = this.getShape(prevEditingShapeId);
1791
1764
  if (prevEditingShape) {
1792
1765
  this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1793
1766
  }
1794
1767
  }
1768
+ this._updateCurrentPageState({ editingShapeId: null });
1769
+ this._currentRichTextEditor.set(null);
1795
1770
  },
1796
1771
  { history: "ignore" }
1797
1772
  );
1773
+ return this;
1798
1774
  }
1775
+ if (!this.canEditShape(id)) return this;
1776
+ this.run(
1777
+ () => {
1778
+ const prevEditingShapeId = this.getEditingShapeId();
1779
+ if (prevEditingShapeId) {
1780
+ const prevEditingShape = this.getShape(prevEditingShapeId);
1781
+ if (prevEditingShape) {
1782
+ this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1783
+ }
1784
+ }
1785
+ this._updateCurrentPageState({ editingShapeId: null });
1786
+ this._currentRichTextEditor.set(null);
1787
+ this.select(id);
1788
+ this._updateCurrentPageState({ editingShapeId: id });
1789
+ const nextEditingShape = this.getShape(id);
1790
+ this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
1791
+ },
1792
+ { history: "ignore" }
1793
+ );
1799
1794
  return this;
1800
1795
  }
1801
1796
  getRichTextEditor() {
@@ -1928,6 +1923,25 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1928
1923
  getCroppingShapeId() {
1929
1924
  return this.getCurrentPageState().croppingShapeId;
1930
1925
  }
1926
+ /**
1927
+ * Whether the shape can be cropped.
1928
+ *
1929
+ * @param shape - The shape (or shape id) to check if it can be cropped.
1930
+ *
1931
+ * @public
1932
+ * @returns true if the shape can be cropped, false otherwise.
1933
+ */
1934
+ canCropShape(shape) {
1935
+ if (!shape) return false;
1936
+ const id = typeof shape === "string" ? shape : shape?.id ?? null;
1937
+ if (!id) return false;
1938
+ const _shape = this.getShape(id);
1939
+ if (!_shape) return false;
1940
+ const util = this.getShapeUtil(_shape);
1941
+ if (!util.canCrop(_shape)) return false;
1942
+ if (this.isShapeOrAncestorLocked(_shape)) return false;
1943
+ return true;
1944
+ }
1931
1945
  /**
1932
1946
  * Set the current cropping shape.
1933
1947
  *
@@ -1949,12 +1963,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1949
1963
  () => {
1950
1964
  if (!id) {
1951
1965
  this.updateCurrentPageState({ croppingShapeId: null });
1952
- } else {
1953
- const shape2 = this.getShape(id);
1954
- const util = this.getShapeUtil(shape2);
1955
- if (shape2 && util.canCrop(shape2)) {
1956
- this.updateCurrentPageState({ croppingShapeId: id });
1957
- }
1966
+ } else if (this.canCropShape(id)) {
1967
+ this.updateCurrentPageState({ croppingShapeId: id });
1958
1968
  }
1959
1969
  },
1960
1970
  { history: "ignore" }
@@ -2029,6 +2039,22 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2029
2039
  getZoomLevel() {
2030
2040
  return this.getCamera().z;
2031
2041
  }
2042
+ getDebouncedZoomLevel() {
2043
+ if (this.options.debouncedZoom) {
2044
+ if (this.getCameraState() === "idle") {
2045
+ return this.getZoomLevel();
2046
+ } else {
2047
+ return this._debouncedZoomLevel.get();
2048
+ }
2049
+ }
2050
+ return this.getZoomLevel();
2051
+ }
2052
+ _getAboveDebouncedZoomThreshold() {
2053
+ return this.getCurrentPageShapeIds().size > this.options.debouncedZoomThreshold;
2054
+ }
2055
+ getEfficientZoomLevel() {
2056
+ return this._getAboveDebouncedZoomThreshold() ? this.getDebouncedZoomLevel() : this.getZoomLevel();
2057
+ }
2032
2058
  /**
2033
2059
  * Get the camera's initial or reset zoom level.
2034
2060
  *
@@ -2274,7 +2300,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2274
2300
  },
2275
2301
  { history: "ignore" }
2276
2302
  );
2277
- const { currentScreenPoint, currentPagePoint } = this.inputs;
2303
+ const currentScreenPoint = this.inputs.getCurrentScreenPoint();
2304
+ const currentPagePoint = this.inputs.getCurrentPagePoint();
2278
2305
  if (currentScreenPoint.x / z - x !== currentPagePoint.x || currentScreenPoint.y / z - y !== currentPagePoint.y) {
2279
2306
  this.updatePointer({
2280
2307
  immediate: opts?.immediate,
@@ -2409,7 +2436,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2409
2436
  * ```ts
2410
2437
  * editor.zoomIn()
2411
2438
  * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })
2412
- * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })
2439
+ * editor.zoomIn(editor.inputs.getCurrentScreenPoint(), { animation: { duration: 200 } })
2413
2440
  * ```
2414
2441
  *
2415
2442
  * @param point - The screen point to zoom in on. Defaults to the screen center
@@ -2450,7 +2477,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2450
2477
  * ```ts
2451
2478
  * editor.zoomOut()
2452
2479
  * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })
2453
- * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })
2480
+ * editor.zoomOut(editor.inputs.getCurrentScreenPoint(), { animation: { duration: 120 } })
2454
2481
  * ```
2455
2482
  *
2456
2483
  * @param point - The point to zoom out on. Defaults to the viewport screen center.
@@ -2502,10 +2529,15 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2502
2529
  if (isLocked && !opts?.force) return this;
2503
2530
  const selectionPageBounds = this.getSelectionPageBounds();
2504
2531
  if (selectionPageBounds) {
2505
- this.zoomToBounds(selectionPageBounds, {
2506
- targetZoom: Math.max(1, this.getZoomLevel()),
2507
- ...opts
2508
- });
2532
+ const currentZoom = this.getZoomLevel();
2533
+ if (Math.abs(currentZoom - 1) < 0.01) {
2534
+ this.zoomToBounds(selectionPageBounds, opts);
2535
+ } else {
2536
+ this.zoomToBounds(selectionPageBounds, {
2537
+ targetZoom: 1,
2538
+ ...opts
2539
+ });
2540
+ }
2509
2541
  }
2510
2542
  return this;
2511
2543
  }
@@ -2545,7 +2577,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2545
2577
  const cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture();
2546
2578
  if (cameraOptions.isLocked && !opts?.force) return this;
2547
2579
  const viewportScreenBounds = this.getViewportScreenBounds();
2548
- const inset = opts?.inset ?? Math.min(import_constants.ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28);
2580
+ const inset = opts?.inset ?? Math.min(this.options.zoomToFitPadding, viewportScreenBounds.width * 0.28);
2549
2581
  const baseZoom = this.getBaseZoom();
2550
2582
  const zoomMin = cameraOptions.zoomSteps[0];
2551
2583
  const zoomMax = (0, import_utils.last)(cameraOptions.zoomSteps);
@@ -2769,18 +2801,20 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
2769
2801
  }
2770
2802
  if (_willSetInitialBounds) {
2771
2803
  this.updateInstanceState({ screenBounds: screenBounds.toJson(), insets });
2804
+ this.emit("resize", screenBounds.toJson());
2772
2805
  this.setCamera(this.getCamera());
2773
2806
  } else {
2774
2807
  if (center && !this.getInstanceState().followingUserId) {
2775
2808
  const before = this.getViewportPageBounds().center;
2776
2809
  this.updateInstanceState({ screenBounds: screenBounds.toJson(), insets });
2810
+ this.emit("resize", screenBounds.toJson());
2777
2811
  this.centerOnPoint(before);
2778
2812
  } else {
2779
2813
  this.updateInstanceState({ screenBounds: screenBounds.toJson(), insets });
2814
+ this.emit("resize", screenBounds.toJson());
2780
2815
  this._setCamera(import_Vec.Vec.From({ ...this.getCamera() }));
2781
2816
  }
2782
2817
  }
2783
- this._tickCameraState();
2784
2818
  return this;
2785
2819
  }
2786
2820
  getViewportScreenBounds() {
@@ -3060,6 +3094,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3060
3094
  this._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs;
3061
3095
  if (this._cameraState.__unsafe__getWithoutCapture() !== "idle") return;
3062
3096
  this._cameraState.set("moving");
3097
+ this._debouncedZoomLevel.set((0, import_state.unsafe__withoutCapture)(() => this.getCamera().z));
3063
3098
  this.on("tick", this._decayCameraStateTimeout);
3064
3099
  }
3065
3100
  /**
@@ -3812,14 +3847,29 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3812
3847
  const notVisibleShapes2 = this.getNotVisibleShapes();
3813
3848
  const selectedShapeIds = this.getSelectedShapeIds();
3814
3849
  const editingId = this.getEditingShapeId();
3815
- const culledShapes = new Set(notVisibleShapes2);
3850
+ const nextValue = new Set(notVisibleShapes2);
3816
3851
  if (editingId) {
3817
- culledShapes.delete(editingId);
3852
+ nextValue.delete(editingId);
3818
3853
  }
3819
3854
  selectedShapeIds.forEach((id) => {
3820
- culledShapes.delete(id);
3855
+ nextValue.delete(id);
3821
3856
  });
3822
- return culledShapes;
3857
+ const prevValue = this._culledShapesCache;
3858
+ if (prevValue) {
3859
+ if (prevValue.size !== nextValue.size) {
3860
+ this._culledShapesCache = nextValue;
3861
+ return nextValue;
3862
+ }
3863
+ for (const id of prevValue) {
3864
+ if (!nextValue.has(id)) {
3865
+ this._culledShapesCache = nextValue;
3866
+ return nextValue;
3867
+ }
3868
+ }
3869
+ return prevValue;
3870
+ }
3871
+ this._culledShapesCache = nextValue;
3872
+ return nextValue;
3823
3873
  }
3824
3874
  getCurrentPageBounds() {
3825
3875
  let commonBounds;
@@ -3869,7 +3919,10 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3869
3919
  let inHollowSmallestAreaHit = null;
3870
3920
  let inMarginClosestToEdgeDistance = Infinity;
3871
3921
  let inMarginClosestToEdgeHit = null;
3922
+ const searchMargin = Math.max(innerMargin, outerMargin, this.options.hitTestMargin / zoomLevel);
3923
+ const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin);
3872
3924
  const shapesToCheck = (opts.renderingOnly ? this.getCurrentPageRenderingShapesSorted() : this.getCurrentPageShapesSorted()).filter((shape) => {
3925
+ if (!candidateIds.has(shape.id) && !this.isShapeOfType(shape, "frame")) return false;
3873
3926
  if (shape.isLocked && !hitLocked || this.isShapeHidden(shape) || this.isShapeOfType(shape, "group"))
3874
3927
  return false;
3875
3928
  const pageMask = this.getShapeMask(shape);
@@ -3976,7 +4029,33 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3976
4029
  * @public
3977
4030
  */
3978
4031
  getShapesAtPoint(point, opts = {}) {
3979
- return this.getCurrentPageShapesSorted().filter((shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)).reverse();
4032
+ const margin = opts.margin ?? 0;
4033
+ const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, margin);
4034
+ return this.getCurrentPageShapesSorted().filter((shape) => {
4035
+ if (this.isShapeHidden(shape)) return false;
4036
+ if (!candidateIds.has(shape.id) && !this.isShapeOfType(shape, "frame")) return false;
4037
+ return this.isPointInShape(shape, point, opts);
4038
+ }).reverse();
4039
+ }
4040
+ /**
4041
+ * Get shape IDs within the given bounds.
4042
+ *
4043
+ * Note: Uses shape page bounds only. Frames with labels outside their bounds
4044
+ * may not be included even if the label is within the search bounds.
4045
+ *
4046
+ * Note: Results are unordered. If you need z-order, combine with sorted shapes:
4047
+ * ```ts
4048
+ * const candidates = editor.getShapeIdsInsideBounds(bounds)
4049
+ * const sorted = editor.getCurrentPageShapesSorted().filter(s => candidates.has(s.id))
4050
+ * ```
4051
+ *
4052
+ * @param bounds - The bounds to search within.
4053
+ * @returns Unordered set of shape IDs within the given bounds.
4054
+ *
4055
+ * @internal
4056
+ */
4057
+ getShapeIdsInsideBounds(bounds) {
4058
+ return this._spatialIndex.getShapeIdsInsideBounds(bounds);
3980
4059
  }
3981
4060
  /**
3982
4061
  * Test whether a point (in the current page space) will will a shape. This method takes into account masks,
@@ -4400,30 +4479,18 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
4400
4479
  getBinding(id) {
4401
4480
  return this.store.get(id);
4402
4481
  }
4403
- /**
4404
- * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose
4405
- * `fromId` matched the shape's ID.
4406
- */
4407
4482
  getBindingsFromShape(shape, type) {
4408
4483
  const id = typeof shape === "string" ? shape : shape.id;
4409
4484
  return this.getBindingsInvolvingShape(id).filter(
4410
4485
  (b) => b.fromId === id && b.type === type
4411
4486
  );
4412
4487
  }
4413
- /**
4414
- * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose
4415
- * `toId` matches the shape's ID.
4416
- */
4417
4488
  getBindingsToShape(shape, type) {
4418
4489
  const id = typeof shape === "string" ? shape : shape.id;
4419
4490
  return this.getBindingsInvolvingShape(id).filter(
4420
4491
  (b) => b.toId === id && b.type === type
4421
4492
  );
4422
4493
  }
4423
- /**
4424
- * Get all bindings involving a particular shape. This includes bindings where the shape is the
4425
- * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.
4426
- */
4427
4494
  getBindingsInvolvingShape(shape, type) {
4428
4495
  const id = typeof shape === "string" ? shape : shape.id;
4429
4496
  const result = this._getBindingsIndexCache().get(id) ?? import_state.EMPTY_ARRAY;
@@ -5671,8 +5738,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5671
5738
  isAspectRatioLocked: options.isAspectRatioLocked
5672
5739
  });
5673
5740
  if (Math.sign(scale.x) * Math.sign(scale.y) < 0) {
5674
- let { rotation } = import_Mat.Mat.Decompose(options.initialPageTransform);
5675
- rotation -= 2 * rotation;
5741
+ const parentRotation = this.getShapeParentTransform(id).rotation();
5742
+ const rotation = -options.initialShape.rotation - 2 * parentRotation;
5676
5743
  this.updateShapes([{ id, type, rotation }]);
5677
5744
  }
5678
5745
  const preScaleShapePageCenter = import_Mat.Mat.applyToPoint(
@@ -5685,9 +5752,9 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5685
5752
  scale,
5686
5753
  options.scaleAxisRotation
5687
5754
  );
5688
- const pageBounds = this.getShapePageBounds(id);
5689
5755
  const pageTransform = this.getShapePageTransform(id);
5690
- const currentPageCenter = pageBounds.center;
5756
+ const currentLocalBounds = this.getShapeGeometry(id).bounds;
5757
+ const currentPageCenter = import_Mat.Mat.applyToPoint(pageTransform, currentLocalBounds.center);
5691
5758
  const shapePageTransformOrigin = pageTransform.point();
5692
5759
  if (!currentPageCenter || !shapePageTransformOrigin) return this;
5693
5760
  const pageDelta = import_Vec.Vec.Sub(postScaleShapePageCenter, currentPageCenter);
@@ -5973,7 +6040,11 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5973
6040
  )
5974
6041
  );
5975
6042
  const sortedShapeIds = shapesToGroup.sort(import_utils.sortByIndex).map((s) => s.id);
5976
- const pageBounds = import_Box.Box.Common((0, import_utils.compact)(shapesToGroup.map((id) => this.getShapePageBounds(id))));
6043
+ const childBounds = (0, import_utils.compact)(shapesToGroup.map((shape) => this.getShapePageBounds(shape)));
6044
+ const pageBounds = import_Box.Box.Common(childBounds);
6045
+ if (!pageBounds.isValid()) {
6046
+ throw Error(`Editor.groupShapes: group bounds are invalid (NaN).`);
6047
+ }
5977
6048
  const { x, y } = pageBounds.point;
5978
6049
  const parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId();
5979
6050
  if (this.getCurrentToolId() !== "select") return this;
@@ -6663,6 +6734,25 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
6663
6734
  }
6664
6735
  }
6665
6736
  }
6737
+ if (point) {
6738
+ const shapesById = new Map(shapes.map((shape) => [shape.id, shape]));
6739
+ const rootShapesFromContent = (0, import_utils.compact)(rootShapeIds.map((id) => shapesById.get(id)));
6740
+ if (rootShapesFromContent.length > 0) {
6741
+ const targetParent = this.getShapeAtPoint(point, {
6742
+ hitInside: true,
6743
+ hitFrameInside: true,
6744
+ hitLocked: true,
6745
+ filter: (shape) => {
6746
+ const util = this.getShapeUtil(shape);
6747
+ if (!util.canReceiveNewChildrenOfType) return false;
6748
+ return rootShapesFromContent.every(
6749
+ (rootShape) => util.canReceiveNewChildrenOfType(shape, rootShape.type)
6750
+ );
6751
+ }
6752
+ });
6753
+ pasteParentId = targetParent ? targetParent.id : currentPageId;
6754
+ }
6755
+ }
6666
6756
  let isDuplicating = false;
6667
6757
  if (!(0, import_tlschema.isPageId)(pasteParentId)) {
6668
6758
  const parent = this.getShape(pasteParentId);
@@ -6907,60 +6997,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
6907
6997
  height
6908
6998
  };
6909
6999
  }
6910
- /**
6911
- * Update the input points from a pointer, pinch, or wheel event.
6912
- *
6913
- * @param info - The event info.
6914
- */
6915
- _updateInputsFromEvent(info) {
6916
- const {
6917
- pointerVelocity,
6918
- previousScreenPoint,
6919
- previousPagePoint,
6920
- currentScreenPoint,
6921
- currentPagePoint,
6922
- originScreenPoint,
6923
- originPagePoint
6924
- } = this.inputs;
6925
- const { screenBounds } = this.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID);
6926
- const { x: cx, y: cy, z: cz } = (0, import_state.unsafe__withoutCapture)(() => this.getCamera());
6927
- const sx = info.point.x - screenBounds.x;
6928
- const sy = info.point.y - screenBounds.y;
6929
- const sz = info.point.z ?? 0.5;
6930
- previousScreenPoint.setTo(currentScreenPoint);
6931
- previousPagePoint.setTo(currentPagePoint);
6932
- currentScreenPoint.set(sx, sy);
6933
- const nx = sx / cz - cx;
6934
- const ny = sy / cz - cy;
6935
- if (isFinite(nx) && isFinite(ny)) {
6936
- currentPagePoint.set(nx, ny, sz);
6937
- }
6938
- this.inputs.isPen = info.type === "pointer" && info.isPen;
6939
- if (info.name === "pointer_down" || this.inputs.isPinching) {
6940
- pointerVelocity.set(0, 0);
6941
- originScreenPoint.setTo(currentScreenPoint);
6942
- originPagePoint.setTo(currentPagePoint);
6943
- }
6944
- this.run(
6945
- () => {
6946
- this.store.put([
6947
- {
6948
- id: import_tlschema.TLPOINTER_ID,
6949
- typeName: "pointer",
6950
- x: currentPagePoint.x,
6951
- y: currentPagePoint.y,
6952
- lastActivityTimestamp: (
6953
- // If our pointer moved only because we're following some other user, then don't
6954
- // update our last activity timestamp; otherwise, update it to the current timestamp.
6955
- info.type === "pointer" && info.pointerId === import_constants.INTERNAL_POINTER_IDS.CAMERA_MOVE ? this.store.unsafeGetWithoutCapture(import_tlschema.TLPOINTER_ID)?.lastActivityTimestamp ?? this._tickManager.now : this._tickManager.now
6956
- ),
6957
- meta: {}
6958
- }
6959
- ]);
6960
- },
6961
- { history: "ignore" }
6962
- );
6963
- }
7000
+ /* --------------------- Events --------------------- */
6964
7001
  /**
6965
7002
  * Dispatch a cancel event.
6966
7003
  *
@@ -7025,18 +7062,19 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7025
7062
  point: options?.point ?? // weird but true: what `inputs` calls screen-space is actually viewport space. so
7026
7063
  // we need to convert back into true screen space first. we should fix this...
7027
7064
  import_Vec.Vec.Add(
7028
- this.inputs.currentScreenPoint,
7065
+ this.inputs.getCurrentScreenPoint(),
7029
7066
  this.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID).screenBounds
7030
7067
  ),
7031
7068
  pointerId: options?.pointerId ?? 0,
7032
7069
  button: options?.button ?? 0,
7033
- isPen: options?.isPen ?? this.inputs.isPen,
7034
- shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
7035
- altKey: options?.altKey ?? this.inputs.altKey,
7036
- ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
7037
- metaKey: options?.metaKey ?? this.inputs.metaKey,
7038
- accelKey: options?.accelKey ?? (0, import_keyboard.isAccelKey)(this.inputs)
7070
+ isPen: options?.isPen ?? this.inputs.getIsPen(),
7071
+ shiftKey: options?.shiftKey ?? this.inputs.getShiftKey(),
7072
+ altKey: options?.altKey ?? this.inputs.getAltKey(),
7073
+ ctrlKey: options?.ctrlKey ?? this.inputs.getCtrlKey(),
7074
+ metaKey: options?.metaKey ?? this.inputs.getMetaKey(),
7075
+ accelKey: false
7039
7076
  };
7077
+ event.accelKey = options?.accelKey ?? this.inputs.getAccelKey();
7040
7078
  if (options?.immediate) {
7041
7079
  this._flushEventForTick(event);
7042
7080
  } else {
@@ -7352,58 +7390,58 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7352
7390
  this._clickManager.cancelDoubleClickTimeout();
7353
7391
  }
7354
7392
  _setShiftKeyTimeout() {
7355
- this.inputs.shiftKey = false;
7393
+ this.inputs.setShiftKey(false);
7356
7394
  this.dispatch({
7357
7395
  type: "keyboard",
7358
7396
  name: "key_up",
7359
7397
  key: "Shift",
7360
- shiftKey: this.inputs.shiftKey,
7361
- ctrlKey: this.inputs.ctrlKey,
7362
- altKey: this.inputs.altKey,
7363
- metaKey: this.inputs.metaKey,
7364
- accelKey: (0, import_keyboard.isAccelKey)(this.inputs),
7398
+ shiftKey: this.inputs.getShiftKey(),
7399
+ ctrlKey: this.inputs.getCtrlKey(),
7400
+ altKey: this.inputs.getAltKey(),
7401
+ metaKey: this.inputs.getMetaKey(),
7402
+ accelKey: this.inputs.getAccelKey(),
7365
7403
  code: "ShiftLeft"
7366
7404
  });
7367
7405
  }
7368
7406
  _setAltKeyTimeout() {
7369
- this.inputs.altKey = false;
7407
+ this.inputs.setAltKey(false);
7370
7408
  this.dispatch({
7371
7409
  type: "keyboard",
7372
7410
  name: "key_up",
7373
7411
  key: "Alt",
7374
- shiftKey: this.inputs.shiftKey,
7375
- ctrlKey: this.inputs.ctrlKey,
7376
- altKey: this.inputs.altKey,
7377
- metaKey: this.inputs.metaKey,
7378
- accelKey: (0, import_keyboard.isAccelKey)(this.inputs),
7412
+ shiftKey: this.inputs.getShiftKey(),
7413
+ ctrlKey: this.inputs.getCtrlKey(),
7414
+ altKey: this.inputs.getAltKey(),
7415
+ metaKey: this.inputs.getMetaKey(),
7416
+ accelKey: this.inputs.getAccelKey(),
7379
7417
  code: "AltLeft"
7380
7418
  });
7381
7419
  }
7382
7420
  _setCtrlKeyTimeout() {
7383
- this.inputs.ctrlKey = false;
7421
+ this.inputs.setCtrlKey(false);
7384
7422
  this.dispatch({
7385
7423
  type: "keyboard",
7386
7424
  name: "key_up",
7387
7425
  key: "Ctrl",
7388
- shiftKey: this.inputs.shiftKey,
7389
- ctrlKey: this.inputs.ctrlKey,
7390
- altKey: this.inputs.altKey,
7391
- metaKey: this.inputs.metaKey,
7392
- accelKey: (0, import_keyboard.isAccelKey)(this.inputs),
7426
+ shiftKey: this.inputs.getShiftKey(),
7427
+ ctrlKey: this.inputs.getCtrlKey(),
7428
+ altKey: this.inputs.getAltKey(),
7429
+ metaKey: this.inputs.getMetaKey(),
7430
+ accelKey: this.inputs.getAccelKey(),
7393
7431
  code: "ControlLeft"
7394
7432
  });
7395
7433
  }
7396
7434
  _setMetaKeyTimeout() {
7397
- this.inputs.metaKey = false;
7435
+ this.inputs.setMetaKey(false);
7398
7436
  this.dispatch({
7399
7437
  type: "keyboard",
7400
7438
  name: "key_up",
7401
7439
  key: "Meta",
7402
- shiftKey: this.inputs.shiftKey,
7403
- ctrlKey: this.inputs.ctrlKey,
7404
- altKey: this.inputs.altKey,
7405
- metaKey: this.inputs.metaKey,
7406
- accelKey: (0, import_keyboard.isAccelKey)(this.inputs),
7440
+ shiftKey: this.inputs.getShiftKey(),
7441
+ ctrlKey: this.inputs.getCtrlKey(),
7442
+ altKey: this.inputs.getAltKey(),
7443
+ metaKey: this.inputs.getMetaKey(),
7444
+ accelKey: this.inputs.getAccelKey(),
7407
7445
  code: "MetaLeft"
7408
7446
  });
7409
7447
  }
@@ -7474,47 +7512,47 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7474
7512
  const { type } = info;
7475
7513
  if (info.type === "misc") {
7476
7514
  if (info.name === "cancel" || info.name === "complete") {
7477
- this.inputs.isDragging = false;
7478
- if (this.inputs.isPanning) {
7479
- this.inputs.isPanning = false;
7480
- this.inputs.isSpacebarPanning = false;
7515
+ this.inputs.setIsDragging(false);
7516
+ if (this.inputs.getIsPanning()) {
7517
+ this.inputs.setIsPanning(false);
7518
+ this.inputs.setIsSpacebarPanning(false);
7481
7519
  this.setCursor({ type: this._prevCursor, rotation: 0 });
7482
7520
  }
7483
7521
  }
7484
7522
  this.root.handleEvent(info);
7523
+ this.emit("event", info);
7485
7524
  return;
7486
7525
  }
7487
7526
  if (info.shiftKey) {
7488
7527
  clearTimeout(this._shiftKeyTimeout);
7489
7528
  this._shiftKeyTimeout = -1;
7490
- inputs.shiftKey = true;
7491
- } else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {
7529
+ inputs.setShiftKey(true);
7530
+ } else if (!info.shiftKey && inputs.getShiftKey() && this._shiftKeyTimeout === -1) {
7492
7531
  this._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150);
7493
7532
  }
7494
7533
  if (info.altKey) {
7495
7534
  clearTimeout(this._altKeyTimeout);
7496
7535
  this._altKeyTimeout = -1;
7497
- inputs.altKey = true;
7498
- } else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {
7536
+ inputs.setAltKey(true);
7537
+ } else if (!info.altKey && inputs.getAltKey() && this._altKeyTimeout === -1) {
7499
7538
  this._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150);
7500
7539
  }
7501
7540
  if (info.ctrlKey) {
7502
7541
  clearTimeout(this._ctrlKeyTimeout);
7503
7542
  this._ctrlKeyTimeout = -1;
7504
- inputs.ctrlKey = true;
7505
- } else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {
7543
+ inputs.setCtrlKey(true);
7544
+ } else if (!info.ctrlKey && inputs.getCtrlKey() && this._ctrlKeyTimeout === -1) {
7506
7545
  this._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150);
7507
7546
  }
7508
7547
  if (info.metaKey) {
7509
7548
  clearTimeout(this._metaKeyTimeout);
7510
7549
  this._metaKeyTimeout = -1;
7511
- inputs.metaKey = true;
7512
- } else if (!info.metaKey && inputs.metaKey && this._metaKeyTimeout === -1) {
7550
+ inputs.setMetaKey(true);
7551
+ } else if (!info.metaKey && inputs.getMetaKey() && this._metaKeyTimeout === -1) {
7513
7552
  this._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150);
7514
7553
  }
7515
- const { originPagePoint, currentPagePoint } = inputs;
7516
- if (!inputs.isPointing) {
7517
- inputs.isDragging = false;
7554
+ if (!inputs.getIsPointing()) {
7555
+ inputs.setIsDragging(false);
7518
7556
  }
7519
7557
  const instanceState = this.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID);
7520
7558
  const pageState = this.store.get(this._getCurrentPageStateId());
@@ -7523,23 +7561,23 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7523
7561
  case "pinch": {
7524
7562
  if (cameraOptions.isLocked) return;
7525
7563
  clearTimeout(this._longPressTimeout);
7526
- this._updateInputsFromEvent(info);
7564
+ this.inputs.updateFromEvent(info);
7527
7565
  switch (info.name) {
7528
7566
  case "pinch_start": {
7529
- if (inputs.isPinching) return;
7530
- if (!inputs.isEditing) {
7531
- this._pinchStart = this.getCamera().z;
7567
+ if (inputs.getIsPinching()) return;
7568
+ if (!inputs.getIsEditing()) {
7532
7569
  if (!this._selectedShapeIdsAtPointerDown.length) {
7533
7570
  this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
7534
7571
  }
7535
7572
  this._didPinch = true;
7536
- inputs.isPinching = true;
7573
+ inputs.setIsPinching(true);
7537
7574
  this.interrupt();
7538
7575
  }
7576
+ this.emit("event", info);
7539
7577
  return;
7540
7578
  }
7541
7579
  case "pinch": {
7542
- if (!inputs.isPinching) return;
7580
+ if (!inputs.getIsPinching()) return;
7543
7581
  const {
7544
7582
  point: { z = 1 },
7545
7583
  delta: { x: dx, y: dy }
@@ -7563,11 +7601,12 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7563
7601
  ),
7564
7602
  { immediate: true }
7565
7603
  );
7604
+ this.emit("event", info);
7566
7605
  return;
7567
7606
  }
7568
7607
  case "pinch_end": {
7569
- if (!inputs.isPinching) return this;
7570
- inputs.isPinching = false;
7608
+ if (!inputs.getIsPinching()) return this;
7609
+ inputs.setIsPinching(false);
7571
7610
  const { _selectedShapeIdsAtPointerDown: shapesToReselect } = this;
7572
7611
  this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
7573
7612
  this._selectedShapeIdsAtPointerDown = [];
@@ -7581,13 +7620,14 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7581
7620
  });
7582
7621
  }
7583
7622
  }
7623
+ this.emit("event", info);
7584
7624
  return;
7585
7625
  }
7586
7626
  }
7587
7627
  }
7588
7628
  case "wheel": {
7589
7629
  if (cameraOptions.isLocked) return;
7590
- this._updateInputsFromEvent(info);
7630
+ this.inputs.updateFromEvent(info);
7591
7631
  const { panSpeed, zoomSpeed } = cameraOptions;
7592
7632
  let wheelBehavior = cameraOptions.wheelBehavior;
7593
7633
  const inputMode = this.user.getUserPreferences().inputMode;
@@ -7605,7 +7645,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7605
7645
  if (info.ctrlKey) behavior = wheelBehavior === "pan" ? "zoom" : "pan";
7606
7646
  switch (behavior) {
7607
7647
  case "zoom": {
7608
- const { x, y } = this.inputs.currentScreenPoint;
7648
+ const { x, y } = this.inputs.getCurrentScreenPoint();
7609
7649
  let delta = dz;
7610
7650
  if (wheelBehavior === "zoom") {
7611
7651
  if (Math.abs(dy) > 10) {
@@ -7619,6 +7659,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7619
7659
  immediate: true
7620
7660
  });
7621
7661
  this.maybeTrackPerformance("Zooming");
7662
+ this.root.handleEvent(info);
7663
+ this.emit("event", info);
7622
7664
  return;
7623
7665
  }
7624
7666
  case "pan": {
@@ -7626,6 +7668,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7626
7668
  immediate: true
7627
7669
  });
7628
7670
  this.maybeTrackPerformance("Panning");
7671
+ this.root.handleEvent(info);
7672
+ this.emit("event", info);
7629
7673
  return;
7630
7674
  }
7631
7675
  }
@@ -7633,14 +7677,14 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7633
7677
  break;
7634
7678
  }
7635
7679
  case "pointer": {
7636
- if (inputs.isPinching) return;
7637
- this._updateInputsFromEvent(info);
7680
+ if (inputs.getIsPinching()) return;
7681
+ this.inputs.updateFromEvent(info);
7638
7682
  const { isPen } = info;
7639
7683
  const { isPenMode } = instanceState;
7640
7684
  switch (info.name) {
7641
7685
  case "pointer_down": {
7642
7686
  if (isPenMode && !isPen) return;
7643
- if (!this.inputs.isPanning) {
7687
+ if (!this.inputs.getIsPanning()) {
7644
7688
  this._longPressTimeout = this.timers.setTimeout(() => {
7645
7689
  const vsb = this.getViewportScreenBounds();
7646
7690
  this.dispatch({
@@ -7649,7 +7693,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7649
7693
  // viewport bounds, and will be again when this event is handled...
7650
7694
  // so we need to counter-adjust from the stored value so that the
7651
7695
  // new value is set correctly.
7652
- point: this.inputs.originScreenPoint.clone().addXY(vsb.x, vsb.y),
7696
+ point: this.inputs.getOriginScreenPoint().clone().addXY(vsb.x, vsb.y),
7653
7697
  name: "long_press"
7654
7698
  });
7655
7699
  }, this.options.longPressDurationMs);
@@ -7657,21 +7701,21 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7657
7701
  this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
7658
7702
  if (info.button === import_constants.LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId;
7659
7703
  inputs.buttons.add(info.button);
7660
- inputs.isPointing = true;
7661
- inputs.isDragging = false;
7704
+ inputs.setIsPointing(true);
7705
+ inputs.setIsDragging(false);
7662
7706
  if (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true });
7663
7707
  if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
7664
7708
  this._restoreToolId = this.getCurrentToolId();
7665
7709
  this.complete();
7666
7710
  this.setCurrentTool("eraser");
7667
7711
  } else if (info.button === import_constants.MIDDLE_MOUSE_BUTTON) {
7668
- if (!this.inputs.isPanning) {
7712
+ if (!this.inputs.getIsPanning()) {
7669
7713
  this._prevCursor = this.getInstanceState().cursor.type;
7670
7714
  }
7671
- this.inputs.isPanning = true;
7715
+ this.inputs.setIsPanning(true);
7672
7716
  clearTimeout(this._longPressTimeout);
7673
7717
  }
7674
- if (this.inputs.isPanning) {
7718
+ if (this.inputs.getIsPanning()) {
7675
7719
  this.stopCameraAnimation();
7676
7720
  this.setCursor({ type: "grabbing", rotation: 0 });
7677
7721
  return this;
@@ -7681,8 +7725,9 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7681
7725
  case "pointer_move": {
7682
7726
  if (!isPen && isPenMode) return;
7683
7727
  const { x: cx, y: cy, z: cz } = (0, import_state.unsafe__withoutCapture)(() => this.getCamera());
7684
- if (this.inputs.isPanning && this.inputs.isPointing) {
7685
- const { currentScreenPoint, previousScreenPoint } = this.inputs;
7728
+ if (this.inputs.getIsPanning() && this.inputs.getIsPointing()) {
7729
+ const currentScreenPoint = this.inputs.getCurrentScreenPoint();
7730
+ const previousScreenPoint = this.inputs.getPreviousScreenPoint();
7686
7731
  const offset = import_Vec.Vec.Sub(currentScreenPoint, previousScreenPoint);
7687
7732
  this.setCamera(new import_Vec.Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
7688
7733
  immediate: true
@@ -7690,15 +7735,15 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7690
7735
  this.maybeTrackPerformance("Panning");
7691
7736
  return;
7692
7737
  }
7693
- if (inputs.isPointing && !inputs.isDragging && import_Vec.Vec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
7694
- inputs.isDragging = true;
7738
+ if (inputs.getIsPointing() && !inputs.getIsDragging() && import_Vec.Vec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
7739
+ inputs.setIsDragging(true);
7695
7740
  clearTimeout(this._longPressTimeout);
7696
7741
  }
7697
7742
  break;
7698
7743
  }
7699
7744
  case "pointer_up": {
7700
- inputs.isDragging = false;
7701
- inputs.isPointing = false;
7745
+ inputs.setIsDragging(false);
7746
+ inputs.setIsPointing(false);
7702
7747
  clearTimeout(this._longPressTimeout);
7703
7748
  inputs.buttons.delete(info.button);
7704
7749
  if (instanceState.isPenMode && !isPen) return;
@@ -7706,12 +7751,12 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7706
7751
  this.capturedPointerId = null;
7707
7752
  info.button = 0;
7708
7753
  }
7709
- if (inputs.isPanning) {
7754
+ if (inputs.getIsPanning()) {
7710
7755
  if (!inputs.keys.has("Space")) {
7711
- inputs.isPanning = false;
7712
- inputs.isSpacebarPanning = false;
7756
+ inputs.setIsPanning(false);
7757
+ inputs.setIsSpacebarPanning(false);
7713
7758
  }
7714
- const slideDirection = this.inputs.pointerVelocity;
7759
+ const slideDirection = this.inputs.getPointerVelocity();
7715
7760
  const slideSpeed = Math.min(2, slideDirection.len());
7716
7761
  switch (info.button) {
7717
7762
  case import_constants.LEFT_MOUSE_BUTTON: {
@@ -7748,51 +7793,58 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7748
7793
  switch (info.name) {
7749
7794
  case "key_down": {
7750
7795
  inputs.keys.add(info.code);
7751
- if (info.code === "Space" && !info.ctrlKey) {
7752
- if (!this.inputs.isPanning) {
7753
- this._prevCursor = instanceState.cursor.type;
7754
- }
7755
- this.inputs.isPanning = true;
7756
- this.inputs.isSpacebarPanning = true;
7757
- clearTimeout(this._longPressTimeout);
7758
- this.setCursor({ type: this.inputs.isPointing ? "grabbing" : "grab", rotation: 0 });
7759
- }
7760
- if (this.inputs.isSpacebarPanning) {
7761
- let offset;
7762
- switch (info.code) {
7763
- case "ArrowUp": {
7764
- offset = new import_Vec.Vec(0, -1);
7765
- break;
7766
- }
7767
- case "ArrowRight": {
7768
- offset = new import_Vec.Vec(1, 0);
7769
- break;
7796
+ if (this.options.spacebarPanning) {
7797
+ if (info.code === "Space" && !info.ctrlKey) {
7798
+ if (!this.inputs.getIsPanning()) {
7799
+ this._prevCursor = instanceState.cursor.type;
7770
7800
  }
7771
- case "ArrowDown": {
7772
- offset = new import_Vec.Vec(0, 1);
7773
- break;
7801
+ this.inputs.setIsPanning(true);
7802
+ this.inputs.setIsSpacebarPanning(true);
7803
+ clearTimeout(this._longPressTimeout);
7804
+ this.setCursor({
7805
+ type: this.inputs.getIsPointing() ? "grabbing" : "grab",
7806
+ rotation: 0
7807
+ });
7808
+ }
7809
+ if (this.inputs.getIsSpacebarPanning()) {
7810
+ let offset;
7811
+ switch (info.code) {
7812
+ case "ArrowUp": {
7813
+ offset = new import_Vec.Vec(0, -1);
7814
+ break;
7815
+ }
7816
+ case "ArrowRight": {
7817
+ offset = new import_Vec.Vec(1, 0);
7818
+ break;
7819
+ }
7820
+ case "ArrowDown": {
7821
+ offset = new import_Vec.Vec(0, 1);
7822
+ break;
7823
+ }
7824
+ case "ArrowLeft": {
7825
+ offset = new import_Vec.Vec(-1, 0);
7826
+ break;
7827
+ }
7774
7828
  }
7775
- case "ArrowLeft": {
7776
- offset = new import_Vec.Vec(-1, 0);
7777
- break;
7829
+ if (offset) {
7830
+ const bounds = this.getViewportPageBounds();
7831
+ const next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }));
7832
+ this._animateToViewport(next, { animation: { duration: 320 } });
7778
7833
  }
7779
7834
  }
7780
- if (offset) {
7781
- const bounds = this.getViewportPageBounds();
7782
- const next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }));
7783
- this._animateToViewport(next, { animation: { duration: 320 } });
7784
- }
7785
7835
  }
7786
7836
  break;
7787
7837
  }
7788
7838
  case "key_up": {
7789
7839
  inputs.keys.delete(info.code);
7790
- if (info.code === "Space") {
7791
- if (this.inputs.buttons.has(import_constants.MIDDLE_MOUSE_BUTTON)) {
7792
- } else {
7793
- this.inputs.isPanning = false;
7794
- this.inputs.isSpacebarPanning = false;
7795
- this.setCursor({ type: this._prevCursor, rotation: 0 });
7840
+ if (this.options.spacebarPanning) {
7841
+ if (info.code === "Space") {
7842
+ if (this.inputs.buttons.has(import_constants.MIDDLE_MOUSE_BUTTON)) {
7843
+ } else {
7844
+ this.inputs.setIsPanning(false);
7845
+ this.inputs.setIsSpacebarPanning(false);
7846
+ this.setCursor({ type: this._prevCursor, rotation: 0 });
7847
+ }
7796
7848
  }
7797
7849
  }
7798
7850
  break;
@@ -7845,8 +7897,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
7845
7897
  }
7846
7898
  _init = __decoratorStart(_a);
7847
7899
  __decorateElement(_init, 1, "getIsShapeHiddenCache", _getIsShapeHiddenCache_dec, Editor);
7848
- __decorateElement(_init, 1, "getCanUndo", _getCanUndo_dec, Editor);
7849
- __decorateElement(_init, 1, "getCanRedo", _getCanRedo_dec, Editor);
7900
+ __decorateElement(_init, 1, "canUndo", _canUndo_dec, Editor);
7901
+ __decorateElement(_init, 1, "canRedo", _canRedo_dec, Editor);
7850
7902
  __decorateElement(_init, 1, "getPath", _getPath_dec, Editor);
7851
7903
  __decorateElement(_init, 1, "getCurrentTool", _getCurrentTool_dec, Editor);
7852
7904
  __decorateElement(_init, 1, "getCurrentToolId", _getCurrentToolId_dec, Editor);
@@ -7881,6 +7933,9 @@ __decorateElement(_init, 1, "getCamera", _getCamera_dec, Editor);
7881
7933
  __decorateElement(_init, 1, "getViewportPageBoundsForFollowing", _getViewportPageBoundsForFollowing_dec, Editor);
7882
7934
  __decorateElement(_init, 1, "getCameraForFollowing", _getCameraForFollowing_dec, Editor);
7883
7935
  __decorateElement(_init, 1, "getZoomLevel", _getZoomLevel_dec, Editor);
7936
+ __decorateElement(_init, 1, "getDebouncedZoomLevel", _getDebouncedZoomLevel_dec, Editor);
7937
+ __decorateElement(_init, 1, "_getAboveDebouncedZoomThreshold", __getAboveDebouncedZoomThreshold_dec, Editor);
7938
+ __decorateElement(_init, 1, "getEfficientZoomLevel", _getEfficientZoomLevel_dec, Editor);
7884
7939
  __decorateElement(_init, 1, "getViewportScreenBounds", _getViewportScreenBounds_dec, Editor);
7885
7940
  __decorateElement(_init, 1, "getViewportScreenCenter", _getViewportScreenCenter_dec, Editor);
7886
7941
  __decorateElement(_init, 1, "getViewportPageBounds", _getViewportPageBounds_dec, Editor);