@tldraw/editor 4.3.0-next.7f179bd04d6c → 4.3.0-next.842fb21476f2

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 (165) hide show
  1. package/dist-cjs/index.d.ts +441 -120
  2. package/dist-cjs/index.js +6 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/ErrorBoundary.js.map +1 -1
  5. package/dist-cjs/lib/components/GeometryDebuggingView.js +1 -17
  6. package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
  7. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +3 -3
  8. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  9. package/dist-cjs/lib/constants.js +1 -3
  10. package/dist-cjs/lib/constants.js.map +2 -2
  11. package/dist-cjs/lib/editor/Editor.js +288 -275
  12. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  13. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +18 -17
  14. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +3 -3
  15. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +12 -3
  16. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  17. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -1
  18. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  19. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +5 -6
  20. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
  21. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +591 -0
  22. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +7 -0
  23. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +1 -1
  24. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -22
  26. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +31 -23
  28. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js +1 -1
  30. package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js.map +2 -2
  31. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -3
  32. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  33. package/dist-cjs/lib/exports/parseCss.js +1 -1
  34. package/dist-cjs/lib/exports/parseCss.js.map +2 -2
  35. package/dist-cjs/lib/globals/environment.js +45 -9
  36. package/dist-cjs/lib/globals/environment.js.map +2 -2
  37. package/dist-cjs/lib/hooks/useCoarsePointer.js +14 -29
  38. package/dist-cjs/lib/hooks/useCoarsePointer.js.map +2 -2
  39. package/dist-cjs/lib/hooks/useEvent.js +1 -1
  40. package/dist-cjs/lib/hooks/useEvent.js.map +2 -2
  41. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
  42. package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
  43. package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
  44. package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
  45. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  46. package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
  47. package/dist-cjs/lib/hooks/useStateAttribute.js +4 -1
  48. package/dist-cjs/lib/hooks/useStateAttribute.js.map +2 -2
  49. package/dist-cjs/lib/hooks/useTransform.js.map +1 -1
  50. package/dist-cjs/lib/hooks/useZoomCss.js +4 -8
  51. package/dist-cjs/lib/hooks/useZoomCss.js.map +2 -2
  52. package/dist-cjs/lib/options.js +6 -1
  53. package/dist-cjs/lib/options.js.map +2 -2
  54. package/dist-cjs/lib/primitives/Box.js +3 -0
  55. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  56. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +1 -0
  57. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  58. package/dist-cjs/lib/utils/rotation.js +1 -1
  59. package/dist-cjs/lib/utils/rotation.js.map +2 -2
  60. package/dist-cjs/version.js +3 -3
  61. package/dist-cjs/version.js.map +1 -1
  62. package/dist-esm/index.d.mts +441 -120
  63. package/dist-esm/index.mjs +7 -2
  64. package/dist-esm/index.mjs.map +2 -2
  65. package/dist-esm/lib/components/ErrorBoundary.mjs.map +1 -1
  66. package/dist-esm/lib/components/GeometryDebuggingView.mjs +1 -17
  67. package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
  68. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +3 -3
  69. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  70. package/dist-esm/lib/constants.mjs +1 -3
  71. package/dist-esm/lib/constants.mjs.map +2 -2
  72. package/dist-esm/lib/editor/Editor.mjs +289 -278
  73. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  74. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +18 -17
  75. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +3 -3
  76. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +13 -4
  77. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  78. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -1
  79. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  80. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +5 -6
  81. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
  82. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +573 -0
  83. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +7 -0
  84. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +1 -1
  85. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  86. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -22
  87. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
  88. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +31 -23
  89. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  90. package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs +1 -1
  91. package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs.map +2 -2
  92. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -3
  93. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  94. package/dist-esm/lib/exports/parseCss.mjs +1 -1
  95. package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
  96. package/dist-esm/lib/globals/environment.mjs +45 -9
  97. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  98. package/dist-esm/lib/hooks/useCoarsePointer.mjs +15 -30
  99. package/dist-esm/lib/hooks/useCoarsePointer.mjs.map +2 -2
  100. package/dist-esm/lib/hooks/useEvent.mjs +1 -1
  101. package/dist-esm/lib/hooks/useEvent.mjs.map +2 -2
  102. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
  103. package/dist-esm/lib/hooks/useGestureEvents.mjs +1 -1
  104. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
  105. package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
  106. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  107. package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
  108. package/dist-esm/lib/hooks/useStateAttribute.mjs +4 -1
  109. package/dist-esm/lib/hooks/useStateAttribute.mjs.map +2 -2
  110. package/dist-esm/lib/hooks/useTransform.mjs.map +1 -1
  111. package/dist-esm/lib/hooks/useZoomCss.mjs +4 -8
  112. package/dist-esm/lib/hooks/useZoomCss.mjs.map +2 -2
  113. package/dist-esm/lib/options.mjs +6 -1
  114. package/dist-esm/lib/options.mjs.map +2 -2
  115. package/dist-esm/lib/primitives/Box.mjs +3 -0
  116. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  117. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +1 -0
  118. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  119. package/dist-esm/lib/utils/rotation.mjs +1 -1
  120. package/dist-esm/lib/utils/rotation.mjs.map +2 -2
  121. package/dist-esm/version.mjs +3 -3
  122. package/dist-esm/version.mjs.map +1 -1
  123. package/editor.css +14 -12
  124. package/package.json +18 -16
  125. package/src/index.ts +4 -1
  126. package/src/lib/components/ErrorBoundary.tsx +1 -1
  127. package/src/lib/components/GeometryDebuggingView.tsx +1 -19
  128. package/src/lib/components/default-components/DefaultCanvas.tsx +3 -3
  129. package/src/lib/config/TLUserPreferences.test.ts +40 -0
  130. package/src/lib/constants.ts +0 -2
  131. package/src/lib/editor/Editor.test.ts +140 -0
  132. package/src/lib/editor/Editor.ts +374 -321
  133. package/src/lib/editor/derivations/notVisibleShapes.ts +37 -23
  134. package/src/lib/editor/derivations/parentsToChildren.ts +18 -7
  135. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +17 -31
  136. package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
  137. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +129 -79
  138. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +10 -6
  139. package/src/lib/editor/managers/InputsManager/InputsManager.ts +566 -0
  140. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +0 -4
  141. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +12 -0
  142. package/src/lib/editor/managers/SnapManager/SnapManager.ts +1 -1
  143. package/src/lib/editor/managers/TickManager/TickManager.test.ts +40 -107
  144. package/src/lib/editor/managers/TickManager/TickManager.ts +2 -32
  145. package/src/lib/editor/shapes/ShapeUtil.ts +67 -24
  146. package/src/lib/editor/shapes/group/DashedOutlineBox.tsx +1 -1
  147. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +3 -3
  148. package/src/lib/exports/parseCss.test.ts +1 -0
  149. package/src/lib/exports/parseCss.ts +1 -1
  150. package/src/lib/globals/environment.ts +65 -10
  151. package/src/lib/hooks/useCoarsePointer.ts +16 -59
  152. package/src/lib/hooks/useEvent.tsx +1 -1
  153. package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +1 -1
  154. package/src/lib/hooks/useGestureEvents.ts +2 -2
  155. package/src/lib/hooks/usePassThroughMouseOverEvents.ts +1 -1
  156. package/src/lib/hooks/usePassThroughWheelEvents.ts +1 -1
  157. package/src/lib/hooks/useScreenBounds.ts +1 -1
  158. package/src/lib/hooks/useStateAttribute.ts +4 -1
  159. package/src/lib/hooks/useTransform.ts +1 -1
  160. package/src/lib/hooks/useZoomCss.ts +3 -8
  161. package/src/lib/options.ts +32 -0
  162. package/src/lib/primitives/Box.ts +9 -0
  163. package/src/lib/primitives/geometry/Geometry2d.ts +1 -0
  164. package/src/lib/utils/rotation.ts +1 -1
  165. package/src/version.ts +3 -3
@@ -46,7 +46,7 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
46
46
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
47
47
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
48
48
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
49
- 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;
49
+ 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;
50
50
  import {
51
51
  EMPTY_ARRAY,
52
52
  atom,
@@ -64,7 +64,6 @@ import {
64
64
  PageRecordType,
65
65
  TLDOCUMENT_ID,
66
66
  TLINSTANCE_ID,
67
- TLPOINTER_ID,
68
67
  createBindingId,
69
68
  createShapeId,
70
69
  getShapePropKeysByStyle,
@@ -116,8 +115,7 @@ import {
116
115
  LEFT_MOUSE_BUTTON,
117
116
  MIDDLE_MOUSE_BUTTON,
118
117
  RIGHT_MOUSE_BUTTON,
119
- STYLUS_ERASER_BUTTON,
120
- ZOOM_TO_FIT_PADDING
118
+ STYLUS_ERASER_BUTTON
121
119
  } from "../constants.mjs";
122
120
  import { exportToSvg } from "../exports/exportToSvg.mjs";
123
121
  import { getSvgAsImage } from "../exports/getSvgAsImage.mjs";
@@ -140,7 +138,6 @@ import {
140
138
  parseDeepLinkString
141
139
  } from "../utils/deepLinks.mjs";
142
140
  import { getIncrementedName } from "../utils/getIncrementedName.mjs";
143
- import { isAccelKey } from "../utils/keyboard.mjs";
144
141
  import { getReorderingShapesChanges } from "../utils/reorderShapes.mjs";
145
142
  import { applyRotationToSnapshotShapes, getRotationSnapshot } from "../utils/rotation.mjs";
146
143
  import { bindingsIndex } from "./derivations/bindingsIndex.mjs";
@@ -152,13 +149,14 @@ import { EdgeScrollManager } from "./managers/EdgeScrollManager/EdgeScrollManage
152
149
  import { FocusManager } from "./managers/FocusManager/FocusManager.mjs";
153
150
  import { FontManager } from "./managers/FontManager/FontManager.mjs";
154
151
  import { HistoryManager } from "./managers/HistoryManager/HistoryManager.mjs";
152
+ import { InputsManager } from "./managers/InputsManager/InputsManager.mjs";
155
153
  import { ScribbleManager } from "./managers/ScribbleManager/ScribbleManager.mjs";
156
154
  import { SnapManager } from "./managers/SnapManager/SnapManager.mjs";
157
155
  import { TextManager } from "./managers/TextManager/TextManager.mjs";
158
156
  import { TickManager } from "./managers/TickManager/TickManager.mjs";
159
157
  import { UserPreferencesManager } from "./managers/UserPreferencesManager/UserPreferencesManager.mjs";
160
158
  import { RootState } from "./tools/RootState.mjs";
161
- class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed], _getCanUndo_dec = [computed], _getCanRedo_dec = [computed], _getPath_dec = [computed], _getCurrentTool_dec = [computed], _getCurrentToolId_dec = [computed], _getDocumentSettings_dec = [computed], _getInstanceState_dec = [computed], _getPageStates_dec = [computed], __getPageStatesQuery_dec = [computed], _getCurrentPageState_dec = [computed], __getCurrentPageStateId_dec = [computed], _getSelectedShapeIds_dec = [computed], _getSelectedShapes_dec = [computed], _getCurrentPageShapesInReadingOrder_dec = [computed], _getOnlySelectedShapeId_dec = [computed], _getOnlySelectedShape_dec = [computed], _getSelectionPageBounds_dec = [computed], _getSelectionRotation_dec = [computed], _getSelectionRotatedPageBounds_dec = [computed], _getSelectionRotatedScreenBounds_dec = [computed], _getFocusedGroupId_dec = [computed], _getFocusedGroup_dec = [computed], _getEditingShapeId_dec = [computed], _getEditingShape_dec = [computed], _getRichTextEditor_dec = [computed], _getHoveredShapeId_dec = [computed], _getHoveredShape_dec = [computed], _getHintingShapeIds_dec = [computed], _getHintingShape_dec = [computed], _getErasingShapeIds_dec = [computed], _getErasingShapes_dec = [computed], __unsafe_getCameraId_dec = [computed], _getCamera_dec = [computed], _getViewportPageBoundsForFollowing_dec = [computed], _getCameraForFollowing_dec = [computed], _getZoomLevel_dec = [computed], _getViewportScreenBounds_dec = [computed], _getViewportScreenCenter_dec = [computed], _getViewportPageBounds_dec = [computed], __getCollaboratorsQuery_dec = [computed], _getCollaborators_dec = [computed], _getCollaboratorsOnCurrentPage_dec = [computed], _getRenderingShapes_dec = [computed], __getAllPagesQuery_dec = [computed], _getPages_dec = [computed], _getCurrentPageId_dec = [computed], _getCurrentPageShapeIdsSorted_dec = [computed], __getAllAssetsQuery_dec = [computed], __getShapeHandlesCache_dec = [computed], __getShapePageTransformCache_dec = [computed], __getShapePageBoundsCache_dec = [computed], __getShapeClipPathCache_dec = [computed], __getShapeMaskCache_dec = [computed], __getShapeMaskedPageBoundsCache_dec = [computed], _getNotVisibleShapes_dec = [computed], _getCulledShapes_dec = [computed], _getCurrentPageBounds_dec = [computed], _getCurrentPageShapes_dec = [computed], _getCurrentPageShapesSorted_dec = [computed], _getCurrentPageRenderingShapesSorted_dec = [computed], __getBindingsIndexCache_dec = [computed], __getSelectionSharedStyles_dec = [computed], _getSharedStyles_dec = [computed({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [computed], _getIsFocused_dec = [computed], _getIsReadonly_dec = [computed], __setShiftKeyTimeout_dec = [bind], __setAltKeyTimeout_dec = [bind], __setCtrlKeyTimeout_dec = [bind], __setMetaKeyTimeout_dec = [bind], _a) {
159
+ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed], _canUndo_dec = [computed], _canRedo_dec = [computed], _getPath_dec = [computed], _getCurrentTool_dec = [computed], _getCurrentToolId_dec = [computed], _getDocumentSettings_dec = [computed], _getInstanceState_dec = [computed], _getPageStates_dec = [computed], __getPageStatesQuery_dec = [computed], _getCurrentPageState_dec = [computed], __getCurrentPageStateId_dec = [computed], _getSelectedShapeIds_dec = [computed], _getSelectedShapes_dec = [computed], _getCurrentPageShapesInReadingOrder_dec = [computed], _getOnlySelectedShapeId_dec = [computed], _getOnlySelectedShape_dec = [computed], _getSelectionPageBounds_dec = [computed], _getSelectionRotation_dec = [computed], _getSelectionRotatedPageBounds_dec = [computed], _getSelectionRotatedScreenBounds_dec = [computed], _getFocusedGroupId_dec = [computed], _getFocusedGroup_dec = [computed], _getEditingShapeId_dec = [computed], _getEditingShape_dec = [computed], _getRichTextEditor_dec = [computed], _getHoveredShapeId_dec = [computed], _getHoveredShape_dec = [computed], _getHintingShapeIds_dec = [computed], _getHintingShape_dec = [computed], _getErasingShapeIds_dec = [computed], _getErasingShapes_dec = [computed], __unsafe_getCameraId_dec = [computed], _getCamera_dec = [computed], _getViewportPageBoundsForFollowing_dec = [computed], _getCameraForFollowing_dec = [computed], _getZoomLevel_dec = [computed], _getDebouncedZoomLevel_dec = [computed], __getAboveDebouncedZoomThreshold_dec = [computed], _getEfficientZoomLevel_dec = [computed], _getViewportScreenBounds_dec = [computed], _getViewportScreenCenter_dec = [computed], _getViewportPageBounds_dec = [computed], __getCollaboratorsQuery_dec = [computed], _getCollaborators_dec = [computed], _getCollaboratorsOnCurrentPage_dec = [computed], _getRenderingShapes_dec = [computed], __getAllPagesQuery_dec = [computed], _getPages_dec = [computed], _getCurrentPageId_dec = [computed], _getCurrentPageShapeIdsSorted_dec = [computed], __getAllAssetsQuery_dec = [computed], __getShapeHandlesCache_dec = [computed], __getShapePageTransformCache_dec = [computed], __getShapePageBoundsCache_dec = [computed], __getShapeClipPathCache_dec = [computed], __getShapeMaskCache_dec = [computed], __getShapeMaskedPageBoundsCache_dec = [computed], _getNotVisibleShapes_dec = [computed], _getCulledShapes_dec = [computed], _getCurrentPageBounds_dec = [computed], _getCurrentPageShapes_dec = [computed], _getCurrentPageShapesSorted_dec = [computed], _getCurrentPageRenderingShapesSorted_dec = [computed], __getBindingsIndexCache_dec = [computed], __getSelectionSharedStyles_dec = [computed], _getSharedStyles_dec = [computed({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [computed], _getIsFocused_dec = [computed], _getIsReadonly_dec = [computed], __setShiftKeyTimeout_dec = [bind], __setAltKeyTimeout_dec = [bind], __setCtrlKeyTimeout_dec = [bind], __setMetaKeyTimeout_dec = [bind], _a) {
162
160
  constructor({
163
161
  store,
164
162
  user,
@@ -194,7 +192,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
194
192
  */
195
193
  __publicField(this, "root");
196
194
  /**
197
- * A set of functions to call when the app is disposed.
195
+ * A set of functions to call when the editor is disposed.
198
196
  *
199
197
  * @public
200
198
  */
@@ -205,10 +203,19 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
205
203
  * @public
206
204
  */
207
205
  __publicField(this, "isDisposed", false);
208
- /** @internal */
206
+ /**
207
+ * A manager for the editor's tick events.
208
+ *
209
+ * @internal */
209
210
  __publicField(this, "_tickManager");
210
211
  /**
211
- * A manager for the app's snapping feature.
212
+ * A manager for the editor's input state.
213
+ *
214
+ * @public
215
+ */
216
+ __publicField(this, "inputs");
217
+ /**
218
+ * A manager for the editor's snapping feature.
212
219
  *
213
220
  * @public
214
221
  */
@@ -290,7 +297,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
290
297
  __publicField(this, "bindingUtils");
291
298
  /* --------------------- History -------------------- */
292
299
  /**
293
- * A manager for the app's history.
300
+ * A manager for the editor's history.
294
301
  *
295
302
  * @readonly
296
303
  */
@@ -305,6 +312,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
305
312
  // Rich text editor
306
313
  __publicField(this, "_currentRichTextEditor", atom("rich text editor", null));
307
314
  __publicField(this, "_textOptions");
315
+ __publicField(this, "_debouncedZoomLevel", atom("debounced zoom level", 1));
308
316
  __publicField(this, "_cameraOptions", atom("camera options", DEFAULT_CAMERA_OPTIONS));
309
317
  /** @internal */
310
318
  __publicField(this, "_viewportAnimation", null);
@@ -355,54 +363,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
355
363
  tldraw: null,
356
364
  excalidraw: null
357
365
  });
358
- /* --------------------- Events --------------------- */
359
- /**
360
- * The app's current input state.
361
- *
362
- * @public
363
- */
364
- __publicField(this, "inputs", {
365
- /** The most recent pointer down's position in the current page space. */
366
- originPagePoint: new Vec(),
367
- /** The most recent pointer down's position in screen space. */
368
- originScreenPoint: new Vec(),
369
- /** The previous pointer position in the current page space. */
370
- previousPagePoint: new Vec(),
371
- /** The previous pointer position in screen space. */
372
- previousScreenPoint: new Vec(),
373
- /** The most recent pointer position in the current page space. */
374
- currentPagePoint: new Vec(),
375
- /** The most recent pointer position in screen space. */
376
- currentScreenPoint: new Vec(),
377
- /** A set containing the currently pressed keys. */
378
- keys: /* @__PURE__ */ new Set(),
379
- /** A set containing the currently pressed buttons. */
380
- buttons: /* @__PURE__ */ new Set(),
381
- /** Whether the input is from a pe. */
382
- isPen: false,
383
- /** Whether the shift key is currently pressed. */
384
- shiftKey: false,
385
- /** Whether the meta key is currently pressed. */
386
- metaKey: false,
387
- /** Whether the control or command key is currently pressed. */
388
- ctrlKey: false,
389
- /** Whether the alt or option key is currently pressed. */
390
- altKey: false,
391
- /** Whether the user is dragging. */
392
- isDragging: false,
393
- /** Whether the user is pointing. */
394
- isPointing: false,
395
- /** Whether the user is pinching. */
396
- isPinching: false,
397
- /** Whether the user is editing. */
398
- isEditing: false,
399
- /** Whether the user is panning. */
400
- isPanning: false,
401
- /** Whether the user is spacebar panning. */
402
- isSpacebarPanning: false,
403
- /** Velocity of mouse pointer, in pixels per millisecond */
404
- pointerVelocity: new Vec()
405
- });
406
366
  /**
407
367
  * A manager for recording multiple click events.
408
368
  *
@@ -426,8 +386,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
426
386
  /** @internal */
427
387
  __publicField(this, "_restoreToolId", "select");
428
388
  /** @internal */
429
- __publicField(this, "_pinchStart", 1);
430
- /** @internal */
431
389
  __publicField(this, "_didPinch", false);
432
390
  /** @internal */
433
391
  __publicField(this, "_selectedShapeIdsAtPointerDown", []);
@@ -463,6 +421,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
463
421
  this.disposables.add(() => this.textMeasure.dispose());
464
422
  this.fonts = new FontManager(this, fontAssetUrls);
465
423
  this._tickManager = new TickManager(this);
424
+ this.inputs = new InputsManager(this);
466
425
  class NewRoot extends RootState {
467
426
  static initial = initialState ?? "";
468
427
  }
@@ -929,9 +888,12 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
929
888
  this.history.undo();
930
889
  return this;
931
890
  }
932
- getCanUndo() {
891
+ canUndo() {
933
892
  return this.history.getNumUndos() > 0;
934
893
  }
894
+ getCanUndo() {
895
+ return this.canUndo();
896
+ }
935
897
  /**
936
898
  * Redo to the next mark.
937
899
  *
@@ -948,13 +910,16 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
948
910
  this.history.redo();
949
911
  return this;
950
912
  }
913
+ canRedo() {
914
+ return this.history.getNumRedos() > 0;
915
+ }
916
+ getCanRedo() {
917
+ return this.canRedo();
918
+ }
951
919
  clearHistory() {
952
920
  this.history.clear();
953
921
  return this;
954
922
  }
955
- getCanRedo() {
956
- return this.history.getNumRedos() > 0;
957
- }
958
923
  /**
959
924
  * Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
960
925
  * any redos. You typically want to do this just before a user interaction begins or is handled.
@@ -1109,7 +1074,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1109
1074
  }),
1110
1075
  selectionCount: this.getSelectedShapes().length,
1111
1076
  editingShape: editingShapeId ? this.getShape(editingShapeId) : void 0,
1112
- inputs: this.inputs,
1077
+ inputs: this.inputs.toJson(),
1113
1078
  pageState: this.getCurrentPageState(),
1114
1079
  instanceState: this.getInstanceState(),
1115
1080
  collaboratorCount: this.getCollaboratorsOnCurrentPage().length
@@ -1130,7 +1095,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1130
1095
  * we're in a transaction that's about to be rolled back due to the same error we're currently
1131
1096
  * reporting.
1132
1097
  *
1133
- * Instead, to listen to changes to this value, you need to listen to app's `crash` event.
1098
+ * Instead, to listen to changes to this value, you need to listen to editor's `crash` event.
1134
1099
  *
1135
1100
  * @internal
1136
1101
  */
@@ -1781,6 +1746,28 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1781
1746
  const editingShapeId = this.getEditingShapeId();
1782
1747
  return editingShapeId ? this.getShape(editingShapeId) : void 0;
1783
1748
  }
1749
+ /**
1750
+ * Whether the shape can be edited.
1751
+ *
1752
+ * @param shape - The shape (or shape id) to check if it can be edited.
1753
+ * @param info - The info about the edit start.
1754
+ *
1755
+ * @public
1756
+ * @returns true if the shape can be edited, false otherwise.
1757
+ */
1758
+ canEditShape(shape, info) {
1759
+ const id = typeof shape === "string" ? shape : shape?.id ?? null;
1760
+ if (!id) return false;
1761
+ if (id === this.getEditingShapeId()) return false;
1762
+ const _shape = this.getShape(id);
1763
+ if (!_shape) return false;
1764
+ const util = this.getShapeUtil(_shape);
1765
+ const _info = info ?? { type: "unknown" };
1766
+ if (!util.canEdit(_shape, _info)) return false;
1767
+ if (this.getIsReadonly() && !util.canEditInReadonly(_shape)) return false;
1768
+ if (this.isShapeOrAncestorLocked(_shape) && !util.canEditWhileLocked(_shape)) return false;
1769
+ return true;
1770
+ }
1784
1771
  /**
1785
1772
  * Set the current editing shape.
1786
1773
  *
@@ -1796,42 +1783,42 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1796
1783
  */
1797
1784
  setEditingShape(shape) {
1798
1785
  const id = typeof shape === "string" ? shape : shape?.id ?? null;
1799
- this.setRichTextEditor(null);
1800
- const prevEditingShapeId = this.getEditingShapeId();
1801
- if (id !== prevEditingShapeId) {
1802
- if (id) {
1803
- const shape2 = this.getShape(id);
1804
- if (shape2 && this.getShapeUtil(shape2).canEdit(shape2)) {
1805
- this.run(
1806
- () => {
1807
- this._updateCurrentPageState({ editingShapeId: id });
1808
- if (prevEditingShapeId) {
1809
- const prevEditingShape = this.getShape(prevEditingShapeId);
1810
- if (prevEditingShape) {
1811
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1812
- }
1813
- }
1814
- this.getShapeUtil(shape2).onEditStart?.(shape2);
1815
- },
1816
- { history: "ignore" }
1817
- );
1818
- return this;
1819
- }
1820
- }
1786
+ if (!id) {
1821
1787
  this.run(
1822
1788
  () => {
1823
- this._updateCurrentPageState({ editingShapeId: null });
1824
- this._currentRichTextEditor.set(null);
1789
+ const prevEditingShapeId = this.getEditingShapeId();
1825
1790
  if (prevEditingShapeId) {
1826
1791
  const prevEditingShape = this.getShape(prevEditingShapeId);
1827
1792
  if (prevEditingShape) {
1828
1793
  this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1829
1794
  }
1830
1795
  }
1796
+ this._updateCurrentPageState({ editingShapeId: null });
1797
+ this._currentRichTextEditor.set(null);
1831
1798
  },
1832
1799
  { history: "ignore" }
1833
1800
  );
1801
+ return this;
1834
1802
  }
1803
+ if (!this.canEditShape(id)) return this;
1804
+ this.run(
1805
+ () => {
1806
+ const prevEditingShapeId = this.getEditingShapeId();
1807
+ if (prevEditingShapeId) {
1808
+ const prevEditingShape = this.getShape(prevEditingShapeId);
1809
+ if (prevEditingShape) {
1810
+ this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1811
+ }
1812
+ }
1813
+ this._updateCurrentPageState({ editingShapeId: null });
1814
+ this._currentRichTextEditor.set(null);
1815
+ this.select(id);
1816
+ this._updateCurrentPageState({ editingShapeId: id });
1817
+ const nextEditingShape = this.getShape(id);
1818
+ this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
1819
+ },
1820
+ { history: "ignore" }
1821
+ );
1835
1822
  return this;
1836
1823
  }
1837
1824
  getRichTextEditor() {
@@ -1964,6 +1951,25 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1964
1951
  getCroppingShapeId() {
1965
1952
  return this.getCurrentPageState().croppingShapeId;
1966
1953
  }
1954
+ /**
1955
+ * Whether the shape can be cropped.
1956
+ *
1957
+ * @param shape - The shape (or shape id) to check if it can be cropped.
1958
+ *
1959
+ * @public
1960
+ * @returns true if the shape can be cropped, false otherwise.
1961
+ */
1962
+ canCropShape(shape) {
1963
+ if (!shape) return false;
1964
+ const id = typeof shape === "string" ? shape : shape?.id ?? null;
1965
+ if (!id) return false;
1966
+ const _shape = this.getShape(id);
1967
+ if (!_shape) return false;
1968
+ const util = this.getShapeUtil(_shape);
1969
+ if (!util.canCrop(_shape)) return false;
1970
+ if (this.isShapeOrAncestorLocked(_shape)) return false;
1971
+ return true;
1972
+ }
1967
1973
  /**
1968
1974
  * Set the current cropping shape.
1969
1975
  *
@@ -1985,12 +1991,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1985
1991
  () => {
1986
1992
  if (!id) {
1987
1993
  this.updateCurrentPageState({ croppingShapeId: null });
1988
- } else {
1989
- const shape2 = this.getShape(id);
1990
- const util = this.getShapeUtil(shape2);
1991
- if (shape2 && util.canCrop(shape2)) {
1992
- this.updateCurrentPageState({ croppingShapeId: id });
1993
- }
1994
+ } else if (this.canCropShape(id)) {
1995
+ this.updateCurrentPageState({ croppingShapeId: id });
1994
1996
  }
1995
1997
  },
1996
1998
  { history: "ignore" }
@@ -2065,6 +2067,22 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2065
2067
  getZoomLevel() {
2066
2068
  return this.getCamera().z;
2067
2069
  }
2070
+ getDebouncedZoomLevel() {
2071
+ if (this.options.debouncedZoom) {
2072
+ if (this.getCameraState() === "idle") {
2073
+ return this.getZoomLevel();
2074
+ } else {
2075
+ return this._debouncedZoomLevel.get();
2076
+ }
2077
+ }
2078
+ return this.getZoomLevel();
2079
+ }
2080
+ _getAboveDebouncedZoomThreshold() {
2081
+ return this.getCurrentPageShapeIds().size > this.options.debouncedZoomThreshold;
2082
+ }
2083
+ getEfficientZoomLevel() {
2084
+ return this._getAboveDebouncedZoomThreshold() ? this.getDebouncedZoomLevel() : this.getZoomLevel();
2085
+ }
2068
2086
  /**
2069
2087
  * Get the camera's initial or reset zoom level.
2070
2088
  *
@@ -2310,7 +2328,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2310
2328
  },
2311
2329
  { history: "ignore" }
2312
2330
  );
2313
- const { currentScreenPoint, currentPagePoint } = this.inputs;
2331
+ const currentScreenPoint = this.inputs.getCurrentScreenPoint();
2332
+ const currentPagePoint = this.inputs.getCurrentPagePoint();
2314
2333
  if (currentScreenPoint.x / z - x !== currentPagePoint.x || currentScreenPoint.y / z - y !== currentPagePoint.y) {
2315
2334
  this.updatePointer({
2316
2335
  immediate: opts?.immediate,
@@ -2445,7 +2464,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2445
2464
  * ```ts
2446
2465
  * editor.zoomIn()
2447
2466
  * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })
2448
- * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })
2467
+ * editor.zoomIn(editor.inputs.getCurrentScreenPoint(), { animation: { duration: 200 } })
2449
2468
  * ```
2450
2469
  *
2451
2470
  * @param point - The screen point to zoom in on. Defaults to the screen center
@@ -2486,7 +2505,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2486
2505
  * ```ts
2487
2506
  * editor.zoomOut()
2488
2507
  * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })
2489
- * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })
2508
+ * editor.zoomOut(editor.inputs.getCurrentScreenPoint(), { animation: { duration: 120 } })
2490
2509
  * ```
2491
2510
  *
2492
2511
  * @param point - The point to zoom out on. Defaults to the viewport screen center.
@@ -2538,10 +2557,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2538
2557
  if (isLocked && !opts?.force) return this;
2539
2558
  const selectionPageBounds = this.getSelectionPageBounds();
2540
2559
  if (selectionPageBounds) {
2541
- this.zoomToBounds(selectionPageBounds, {
2542
- targetZoom: Math.max(1, this.getZoomLevel()),
2543
- ...opts
2544
- });
2560
+ const currentZoom = this.getZoomLevel();
2561
+ if (Math.abs(currentZoom - 1) < 0.01) {
2562
+ this.zoomToBounds(selectionPageBounds, opts);
2563
+ } else {
2564
+ this.zoomToBounds(selectionPageBounds, {
2565
+ targetZoom: 1,
2566
+ ...opts
2567
+ });
2568
+ }
2545
2569
  }
2546
2570
  return this;
2547
2571
  }
@@ -2581,7 +2605,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2581
2605
  const cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture();
2582
2606
  if (cameraOptions.isLocked && !opts?.force) return this;
2583
2607
  const viewportScreenBounds = this.getViewportScreenBounds();
2584
- const inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28);
2608
+ const inset = opts?.inset ?? Math.min(this.options.zoomToFitPadding, viewportScreenBounds.width * 0.28);
2585
2609
  const baseZoom = this.getBaseZoom();
2586
2610
  const zoomMin = cameraOptions.zoomSteps[0];
2587
2611
  const zoomMax = last(cameraOptions.zoomSteps);
@@ -2819,7 +2843,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2819
2843
  this._setCamera(Vec.From({ ...this.getCamera() }));
2820
2844
  }
2821
2845
  }
2822
- this._tickCameraState();
2823
2846
  return this;
2824
2847
  }
2825
2848
  getViewportScreenBounds() {
@@ -3099,6 +3122,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3099
3122
  this._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs;
3100
3123
  if (this._cameraState.__unsafe__getWithoutCapture() !== "idle") return;
3101
3124
  this._cameraState.set("moving");
3125
+ this._debouncedZoomLevel.set(unsafe__withoutCapture(() => this.getCamera().z));
3102
3126
  this.on("tick", this._decayCameraStateTimeout);
3103
3127
  }
3104
3128
  /**
@@ -5698,8 +5722,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5698
5722
  isAspectRatioLocked: options.isAspectRatioLocked
5699
5723
  });
5700
5724
  if (Math.sign(scale.x) * Math.sign(scale.y) < 0) {
5701
- let { rotation } = Mat.Decompose(options.initialPageTransform);
5702
- rotation -= 2 * rotation;
5725
+ const parentRotation = this.getShapeParentTransform(id).rotation();
5726
+ const rotation = -options.initialShape.rotation - 2 * parentRotation;
5703
5727
  this.updateShapes([{ id, type, rotation }]);
5704
5728
  }
5705
5729
  const preScaleShapePageCenter = Mat.applyToPoint(
@@ -5712,9 +5736,9 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5712
5736
  scale,
5713
5737
  options.scaleAxisRotation
5714
5738
  );
5715
- const pageBounds = this.getShapePageBounds(id);
5716
5739
  const pageTransform = this.getShapePageTransform(id);
5717
- const currentPageCenter = pageBounds.center;
5740
+ const currentLocalBounds = this.getShapeGeometry(id).bounds;
5741
+ const currentPageCenter = Mat.applyToPoint(pageTransform, currentLocalBounds.center);
5718
5742
  const shapePageTransformOrigin = pageTransform.point();
5719
5743
  if (!currentPageCenter || !shapePageTransformOrigin) return this;
5720
5744
  const pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter);
@@ -6000,7 +6024,11 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6000
6024
  )
6001
6025
  );
6002
6026
  const sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id);
6003
- const pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))));
6027
+ const childBounds = compact(shapesToGroup.map((shape) => this.getShapePageBounds(shape)));
6028
+ const pageBounds = Box.Common(childBounds);
6029
+ if (!pageBounds.isValid()) {
6030
+ throw Error(`Editor.groupShapes: group bounds are invalid (NaN).`);
6031
+ }
6004
6032
  const { x, y } = pageBounds.point;
6005
6033
  const parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId();
6006
6034
  if (this.getCurrentToolId() !== "select") return this;
@@ -6690,6 +6718,25 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6690
6718
  }
6691
6719
  }
6692
6720
  }
6721
+ if (point) {
6722
+ const shapesById = new Map(shapes.map((shape) => [shape.id, shape]));
6723
+ const rootShapesFromContent = compact(rootShapeIds.map((id) => shapesById.get(id)));
6724
+ if (rootShapesFromContent.length > 0) {
6725
+ const targetParent = this.getShapeAtPoint(point, {
6726
+ hitInside: true,
6727
+ hitFrameInside: true,
6728
+ hitLocked: true,
6729
+ filter: (shape) => {
6730
+ const util = this.getShapeUtil(shape);
6731
+ if (!util.canReceiveNewChildrenOfType) return false;
6732
+ return rootShapesFromContent.every(
6733
+ (rootShape) => util.canReceiveNewChildrenOfType(shape, rootShape.type)
6734
+ );
6735
+ }
6736
+ });
6737
+ pasteParentId = targetParent ? targetParent.id : currentPageId;
6738
+ }
6739
+ }
6693
6740
  let isDuplicating = false;
6694
6741
  if (!isPageId(pasteParentId)) {
6695
6742
  const parent = this.getShape(pasteParentId);
@@ -6934,60 +6981,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6934
6981
  height
6935
6982
  };
6936
6983
  }
6937
- /**
6938
- * Update the input points from a pointer, pinch, or wheel event.
6939
- *
6940
- * @param info - The event info.
6941
- */
6942
- _updateInputsFromEvent(info) {
6943
- const {
6944
- pointerVelocity,
6945
- previousScreenPoint,
6946
- previousPagePoint,
6947
- currentScreenPoint,
6948
- currentPagePoint,
6949
- originScreenPoint,
6950
- originPagePoint
6951
- } = this.inputs;
6952
- const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID);
6953
- const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
6954
- const sx = info.point.x - screenBounds.x;
6955
- const sy = info.point.y - screenBounds.y;
6956
- const sz = info.point.z ?? 0.5;
6957
- previousScreenPoint.setTo(currentScreenPoint);
6958
- previousPagePoint.setTo(currentPagePoint);
6959
- currentScreenPoint.set(sx, sy);
6960
- const nx = sx / cz - cx;
6961
- const ny = sy / cz - cy;
6962
- if (isFinite(nx) && isFinite(ny)) {
6963
- currentPagePoint.set(nx, ny, sz);
6964
- }
6965
- this.inputs.isPen = info.type === "pointer" && info.isPen;
6966
- if (info.name === "pointer_down" || this.inputs.isPinching) {
6967
- pointerVelocity.set(0, 0);
6968
- originScreenPoint.setTo(currentScreenPoint);
6969
- originPagePoint.setTo(currentPagePoint);
6970
- }
6971
- this.run(
6972
- () => {
6973
- this.store.put([
6974
- {
6975
- id: TLPOINTER_ID,
6976
- typeName: "pointer",
6977
- x: currentPagePoint.x,
6978
- y: currentPagePoint.y,
6979
- lastActivityTimestamp: (
6980
- // If our pointer moved only because we're following some other user, then don't
6981
- // update our last activity timestamp; otherwise, update it to the current timestamp.
6982
- (info.type === "pointer" && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE ? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ?? this._tickManager.now : this._tickManager.now)
6983
- ),
6984
- meta: {}
6985
- }
6986
- ]);
6987
- },
6988
- { history: "ignore" }
6989
- );
6990
- }
6984
+ /* --------------------- Events --------------------- */
6991
6985
  /**
6992
6986
  * Dispatch a cancel event.
6993
6987
  *
@@ -7052,18 +7046,19 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7052
7046
  point: options?.point ?? // weird but true: what `inputs` calls screen-space is actually viewport space. so
7053
7047
  // we need to convert back into true screen space first. we should fix this...
7054
7048
  Vec.Add(
7055
- this.inputs.currentScreenPoint,
7049
+ this.inputs.getCurrentScreenPoint(),
7056
7050
  this.store.unsafeGetWithoutCapture(TLINSTANCE_ID).screenBounds
7057
7051
  ),
7058
7052
  pointerId: options?.pointerId ?? 0,
7059
7053
  button: options?.button ?? 0,
7060
- isPen: options?.isPen ?? this.inputs.isPen,
7061
- shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
7062
- altKey: options?.altKey ?? this.inputs.altKey,
7063
- ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
7064
- metaKey: options?.metaKey ?? this.inputs.metaKey,
7065
- accelKey: options?.accelKey ?? isAccelKey(this.inputs)
7054
+ isPen: options?.isPen ?? this.inputs.getIsPen(),
7055
+ shiftKey: options?.shiftKey ?? this.inputs.getShiftKey(),
7056
+ altKey: options?.altKey ?? this.inputs.getAltKey(),
7057
+ ctrlKey: options?.ctrlKey ?? this.inputs.getCtrlKey(),
7058
+ metaKey: options?.metaKey ?? this.inputs.getMetaKey(),
7059
+ accelKey: false
7066
7060
  };
7061
+ event.accelKey = options?.accelKey ?? this.inputs.getAccelKey();
7067
7062
  if (options?.immediate) {
7068
7063
  this._flushEventForTick(event);
7069
7064
  } else {
@@ -7379,58 +7374,58 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7379
7374
  this._clickManager.cancelDoubleClickTimeout();
7380
7375
  }
7381
7376
  _setShiftKeyTimeout() {
7382
- this.inputs.shiftKey = false;
7377
+ this.inputs.setShiftKey(false);
7383
7378
  this.dispatch({
7384
7379
  type: "keyboard",
7385
7380
  name: "key_up",
7386
7381
  key: "Shift",
7387
- shiftKey: this.inputs.shiftKey,
7388
- ctrlKey: this.inputs.ctrlKey,
7389
- altKey: this.inputs.altKey,
7390
- metaKey: this.inputs.metaKey,
7391
- accelKey: isAccelKey(this.inputs),
7382
+ shiftKey: this.inputs.getShiftKey(),
7383
+ ctrlKey: this.inputs.getCtrlKey(),
7384
+ altKey: this.inputs.getAltKey(),
7385
+ metaKey: this.inputs.getMetaKey(),
7386
+ accelKey: this.inputs.getAccelKey(),
7392
7387
  code: "ShiftLeft"
7393
7388
  });
7394
7389
  }
7395
7390
  _setAltKeyTimeout() {
7396
- this.inputs.altKey = false;
7391
+ this.inputs.setAltKey(false);
7397
7392
  this.dispatch({
7398
7393
  type: "keyboard",
7399
7394
  name: "key_up",
7400
7395
  key: "Alt",
7401
- shiftKey: this.inputs.shiftKey,
7402
- ctrlKey: this.inputs.ctrlKey,
7403
- altKey: this.inputs.altKey,
7404
- metaKey: this.inputs.metaKey,
7405
- accelKey: isAccelKey(this.inputs),
7396
+ shiftKey: this.inputs.getShiftKey(),
7397
+ ctrlKey: this.inputs.getCtrlKey(),
7398
+ altKey: this.inputs.getAltKey(),
7399
+ metaKey: this.inputs.getMetaKey(),
7400
+ accelKey: this.inputs.getAccelKey(),
7406
7401
  code: "AltLeft"
7407
7402
  });
7408
7403
  }
7409
7404
  _setCtrlKeyTimeout() {
7410
- this.inputs.ctrlKey = false;
7405
+ this.inputs.setCtrlKey(false);
7411
7406
  this.dispatch({
7412
7407
  type: "keyboard",
7413
7408
  name: "key_up",
7414
7409
  key: "Ctrl",
7415
- shiftKey: this.inputs.shiftKey,
7416
- ctrlKey: this.inputs.ctrlKey,
7417
- altKey: this.inputs.altKey,
7418
- metaKey: this.inputs.metaKey,
7419
- accelKey: isAccelKey(this.inputs),
7410
+ shiftKey: this.inputs.getShiftKey(),
7411
+ ctrlKey: this.inputs.getCtrlKey(),
7412
+ altKey: this.inputs.getAltKey(),
7413
+ metaKey: this.inputs.getMetaKey(),
7414
+ accelKey: this.inputs.getAccelKey(),
7420
7415
  code: "ControlLeft"
7421
7416
  });
7422
7417
  }
7423
7418
  _setMetaKeyTimeout() {
7424
- this.inputs.metaKey = false;
7419
+ this.inputs.setMetaKey(false);
7425
7420
  this.dispatch({
7426
7421
  type: "keyboard",
7427
7422
  name: "key_up",
7428
7423
  key: "Meta",
7429
- shiftKey: this.inputs.shiftKey,
7430
- ctrlKey: this.inputs.ctrlKey,
7431
- altKey: this.inputs.altKey,
7432
- metaKey: this.inputs.metaKey,
7433
- accelKey: isAccelKey(this.inputs),
7424
+ shiftKey: this.inputs.getShiftKey(),
7425
+ ctrlKey: this.inputs.getCtrlKey(),
7426
+ altKey: this.inputs.getAltKey(),
7427
+ metaKey: this.inputs.getMetaKey(),
7428
+ accelKey: this.inputs.getAccelKey(),
7434
7429
  code: "MetaLeft"
7435
7430
  });
7436
7431
  }
@@ -7501,48 +7496,47 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7501
7496
  const { type } = info;
7502
7497
  if (info.type === "misc") {
7503
7498
  if (info.name === "cancel" || info.name === "complete") {
7504
- this.inputs.isDragging = false;
7505
- if (this.inputs.isPanning) {
7506
- this.inputs.isPanning = false;
7507
- this.inputs.isSpacebarPanning = false;
7499
+ this.inputs.setIsDragging(false);
7500
+ if (this.inputs.getIsPanning()) {
7501
+ this.inputs.setIsPanning(false);
7502
+ this.inputs.setIsSpacebarPanning(false);
7508
7503
  this.setCursor({ type: this._prevCursor, rotation: 0 });
7509
7504
  }
7510
7505
  }
7511
- this.emit("event", info);
7512
7506
  this.root.handleEvent(info);
7507
+ this.emit("event", info);
7513
7508
  return;
7514
7509
  }
7515
7510
  if (info.shiftKey) {
7516
7511
  clearTimeout(this._shiftKeyTimeout);
7517
7512
  this._shiftKeyTimeout = -1;
7518
- inputs.shiftKey = true;
7519
- } else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {
7513
+ inputs.setShiftKey(true);
7514
+ } else if (!info.shiftKey && inputs.getShiftKey() && this._shiftKeyTimeout === -1) {
7520
7515
  this._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150);
7521
7516
  }
7522
7517
  if (info.altKey) {
7523
7518
  clearTimeout(this._altKeyTimeout);
7524
7519
  this._altKeyTimeout = -1;
7525
- inputs.altKey = true;
7526
- } else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {
7520
+ inputs.setAltKey(true);
7521
+ } else if (!info.altKey && inputs.getAltKey() && this._altKeyTimeout === -1) {
7527
7522
  this._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150);
7528
7523
  }
7529
7524
  if (info.ctrlKey) {
7530
7525
  clearTimeout(this._ctrlKeyTimeout);
7531
7526
  this._ctrlKeyTimeout = -1;
7532
- inputs.ctrlKey = true;
7533
- } else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {
7527
+ inputs.setCtrlKey(true);
7528
+ } else if (!info.ctrlKey && inputs.getCtrlKey() && this._ctrlKeyTimeout === -1) {
7534
7529
  this._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150);
7535
7530
  }
7536
7531
  if (info.metaKey) {
7537
7532
  clearTimeout(this._metaKeyTimeout);
7538
7533
  this._metaKeyTimeout = -1;
7539
- inputs.metaKey = true;
7540
- } else if (!info.metaKey && inputs.metaKey && this._metaKeyTimeout === -1) {
7534
+ inputs.setMetaKey(true);
7535
+ } else if (!info.metaKey && inputs.getMetaKey() && this._metaKeyTimeout === -1) {
7541
7536
  this._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150);
7542
7537
  }
7543
- const { originPagePoint, currentPagePoint } = inputs;
7544
- if (!inputs.isPointing) {
7545
- inputs.isDragging = false;
7538
+ if (!inputs.getIsPointing()) {
7539
+ inputs.setIsDragging(false);
7546
7540
  }
7547
7541
  const instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID);
7548
7542
  const pageState = this.store.get(this._getCurrentPageStateId());
@@ -7551,23 +7545,23 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7551
7545
  case "pinch": {
7552
7546
  if (cameraOptions.isLocked) return;
7553
7547
  clearTimeout(this._longPressTimeout);
7554
- this._updateInputsFromEvent(info);
7548
+ this.inputs.updateFromEvent(info);
7555
7549
  switch (info.name) {
7556
7550
  case "pinch_start": {
7557
- if (inputs.isPinching) return;
7558
- if (!inputs.isEditing) {
7559
- this._pinchStart = this.getCamera().z;
7551
+ if (inputs.getIsPinching()) return;
7552
+ if (!inputs.getIsEditing()) {
7560
7553
  if (!this._selectedShapeIdsAtPointerDown.length) {
7561
7554
  this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
7562
7555
  }
7563
7556
  this._didPinch = true;
7564
- inputs.isPinching = true;
7557
+ inputs.setIsPinching(true);
7565
7558
  this.interrupt();
7566
7559
  }
7560
+ this.emit("event", info);
7567
7561
  return;
7568
7562
  }
7569
7563
  case "pinch": {
7570
- if (!inputs.isPinching) return;
7564
+ if (!inputs.getIsPinching()) return;
7571
7565
  const {
7572
7566
  point: { z = 1 },
7573
7567
  delta: { x: dx, y: dy }
@@ -7591,11 +7585,12 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7591
7585
  ),
7592
7586
  { immediate: true }
7593
7587
  );
7588
+ this.emit("event", info);
7594
7589
  return;
7595
7590
  }
7596
7591
  case "pinch_end": {
7597
- if (!inputs.isPinching) return this;
7598
- inputs.isPinching = false;
7592
+ if (!inputs.getIsPinching()) return this;
7593
+ inputs.setIsPinching(false);
7599
7594
  const { _selectedShapeIdsAtPointerDown: shapesToReselect } = this;
7600
7595
  this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
7601
7596
  this._selectedShapeIdsAtPointerDown = [];
@@ -7609,13 +7604,14 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7609
7604
  });
7610
7605
  }
7611
7606
  }
7607
+ this.emit("event", info);
7612
7608
  return;
7613
7609
  }
7614
7610
  }
7615
7611
  }
7616
7612
  case "wheel": {
7617
7613
  if (cameraOptions.isLocked) return;
7618
- this._updateInputsFromEvent(info);
7614
+ this.inputs.updateFromEvent(info);
7619
7615
  const { panSpeed, zoomSpeed } = cameraOptions;
7620
7616
  let wheelBehavior = cameraOptions.wheelBehavior;
7621
7617
  const inputMode = this.user.getUserPreferences().inputMode;
@@ -7633,7 +7629,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7633
7629
  if (info.ctrlKey) behavior = wheelBehavior === "pan" ? "zoom" : "pan";
7634
7630
  switch (behavior) {
7635
7631
  case "zoom": {
7636
- const { x, y } = this.inputs.currentScreenPoint;
7632
+ const { x, y } = this.inputs.getCurrentScreenPoint();
7637
7633
  let delta = dz;
7638
7634
  if (wheelBehavior === "zoom") {
7639
7635
  if (Math.abs(dy) > 10) {
@@ -7647,6 +7643,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7647
7643
  immediate: true
7648
7644
  });
7649
7645
  this.maybeTrackPerformance("Zooming");
7646
+ this.root.handleEvent(info);
7647
+ this.emit("event", info);
7650
7648
  return;
7651
7649
  }
7652
7650
  case "pan": {
@@ -7654,6 +7652,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7654
7652
  immediate: true
7655
7653
  });
7656
7654
  this.maybeTrackPerformance("Panning");
7655
+ this.root.handleEvent(info);
7656
+ this.emit("event", info);
7657
7657
  return;
7658
7658
  }
7659
7659
  }
@@ -7661,14 +7661,14 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7661
7661
  break;
7662
7662
  }
7663
7663
  case "pointer": {
7664
- if (inputs.isPinching) return;
7665
- this._updateInputsFromEvent(info);
7664
+ if (inputs.getIsPinching()) return;
7665
+ this.inputs.updateFromEvent(info);
7666
7666
  const { isPen } = info;
7667
7667
  const { isPenMode } = instanceState;
7668
7668
  switch (info.name) {
7669
7669
  case "pointer_down": {
7670
7670
  if (isPenMode && !isPen) return;
7671
- if (!this.inputs.isPanning) {
7671
+ if (!this.inputs.getIsPanning()) {
7672
7672
  this._longPressTimeout = this.timers.setTimeout(() => {
7673
7673
  const vsb = this.getViewportScreenBounds();
7674
7674
  this.dispatch({
@@ -7677,7 +7677,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7677
7677
  // viewport bounds, and will be again when this event is handled...
7678
7678
  // so we need to counter-adjust from the stored value so that the
7679
7679
  // new value is set correctly.
7680
- point: this.inputs.originScreenPoint.clone().addXY(vsb.x, vsb.y),
7680
+ point: this.inputs.getOriginScreenPoint().clone().addXY(vsb.x, vsb.y),
7681
7681
  name: "long_press"
7682
7682
  });
7683
7683
  }, this.options.longPressDurationMs);
@@ -7685,21 +7685,21 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7685
7685
  this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
7686
7686
  if (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId;
7687
7687
  inputs.buttons.add(info.button);
7688
- inputs.isPointing = true;
7689
- inputs.isDragging = false;
7688
+ inputs.setIsPointing(true);
7689
+ inputs.setIsDragging(false);
7690
7690
  if (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true });
7691
7691
  if (info.button === STYLUS_ERASER_BUTTON) {
7692
7692
  this._restoreToolId = this.getCurrentToolId();
7693
7693
  this.complete();
7694
7694
  this.setCurrentTool("eraser");
7695
7695
  } else if (info.button === MIDDLE_MOUSE_BUTTON) {
7696
- if (!this.inputs.isPanning) {
7696
+ if (!this.inputs.getIsPanning()) {
7697
7697
  this._prevCursor = this.getInstanceState().cursor.type;
7698
7698
  }
7699
- this.inputs.isPanning = true;
7699
+ this.inputs.setIsPanning(true);
7700
7700
  clearTimeout(this._longPressTimeout);
7701
7701
  }
7702
- if (this.inputs.isPanning) {
7702
+ if (this.inputs.getIsPanning()) {
7703
7703
  this.stopCameraAnimation();
7704
7704
  this.setCursor({ type: "grabbing", rotation: 0 });
7705
7705
  return this;
@@ -7709,8 +7709,9 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7709
7709
  case "pointer_move": {
7710
7710
  if (!isPen && isPenMode) return;
7711
7711
  const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
7712
- if (this.inputs.isPanning && this.inputs.isPointing) {
7713
- const { currentScreenPoint, previousScreenPoint } = this.inputs;
7712
+ if (this.inputs.getIsPanning() && this.inputs.getIsPointing()) {
7713
+ const currentScreenPoint = this.inputs.getCurrentScreenPoint();
7714
+ const previousScreenPoint = this.inputs.getPreviousScreenPoint();
7714
7715
  const offset = Vec.Sub(currentScreenPoint, previousScreenPoint);
7715
7716
  this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
7716
7717
  immediate: true
@@ -7718,15 +7719,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7718
7719
  this.maybeTrackPerformance("Panning");
7719
7720
  return;
7720
7721
  }
7721
- if (inputs.isPointing && !inputs.isDragging && Vec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
7722
- inputs.isDragging = true;
7722
+ if (inputs.getIsPointing() && !inputs.getIsDragging() && Vec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
7723
+ inputs.setIsDragging(true);
7723
7724
  clearTimeout(this._longPressTimeout);
7724
7725
  }
7725
7726
  break;
7726
7727
  }
7727
7728
  case "pointer_up": {
7728
- inputs.isDragging = false;
7729
- inputs.isPointing = false;
7729
+ inputs.setIsDragging(false);
7730
+ inputs.setIsPointing(false);
7730
7731
  clearTimeout(this._longPressTimeout);
7731
7732
  inputs.buttons.delete(info.button);
7732
7733
  if (instanceState.isPenMode && !isPen) return;
@@ -7734,12 +7735,12 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7734
7735
  this.capturedPointerId = null;
7735
7736
  info.button = 0;
7736
7737
  }
7737
- if (inputs.isPanning) {
7738
+ if (inputs.getIsPanning()) {
7738
7739
  if (!inputs.keys.has("Space")) {
7739
- inputs.isPanning = false;
7740
- inputs.isSpacebarPanning = false;
7740
+ inputs.setIsPanning(false);
7741
+ inputs.setIsSpacebarPanning(false);
7741
7742
  }
7742
- const slideDirection = this.inputs.pointerVelocity;
7743
+ const slideDirection = this.inputs.getPointerVelocity();
7743
7744
  const slideSpeed = Math.min(2, slideDirection.len());
7744
7745
  switch (info.button) {
7745
7746
  case LEFT_MOUSE_BUTTON: {
@@ -7776,51 +7777,58 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7776
7777
  switch (info.name) {
7777
7778
  case "key_down": {
7778
7779
  inputs.keys.add(info.code);
7779
- if (info.code === "Space" && !info.ctrlKey) {
7780
- if (!this.inputs.isPanning) {
7781
- this._prevCursor = instanceState.cursor.type;
7782
- }
7783
- this.inputs.isPanning = true;
7784
- this.inputs.isSpacebarPanning = true;
7785
- clearTimeout(this._longPressTimeout);
7786
- this.setCursor({ type: this.inputs.isPointing ? "grabbing" : "grab", rotation: 0 });
7787
- }
7788
- if (this.inputs.isSpacebarPanning) {
7789
- let offset;
7790
- switch (info.code) {
7791
- case "ArrowUp": {
7792
- offset = new Vec(0, -1);
7793
- break;
7780
+ if (this.options.spacebarPanning) {
7781
+ if (info.code === "Space" && !info.ctrlKey) {
7782
+ if (!this.inputs.getIsPanning()) {
7783
+ this._prevCursor = instanceState.cursor.type;
7794
7784
  }
7795
- case "ArrowRight": {
7796
- offset = new Vec(1, 0);
7797
- break;
7798
- }
7799
- case "ArrowDown": {
7800
- offset = new Vec(0, 1);
7801
- break;
7785
+ this.inputs.setIsPanning(true);
7786
+ this.inputs.setIsSpacebarPanning(true);
7787
+ clearTimeout(this._longPressTimeout);
7788
+ this.setCursor({
7789
+ type: this.inputs.getIsPointing() ? "grabbing" : "grab",
7790
+ rotation: 0
7791
+ });
7792
+ }
7793
+ if (this.inputs.getIsSpacebarPanning()) {
7794
+ let offset;
7795
+ switch (info.code) {
7796
+ case "ArrowUp": {
7797
+ offset = new Vec(0, -1);
7798
+ break;
7799
+ }
7800
+ case "ArrowRight": {
7801
+ offset = new Vec(1, 0);
7802
+ break;
7803
+ }
7804
+ case "ArrowDown": {
7805
+ offset = new Vec(0, 1);
7806
+ break;
7807
+ }
7808
+ case "ArrowLeft": {
7809
+ offset = new Vec(-1, 0);
7810
+ break;
7811
+ }
7802
7812
  }
7803
- case "ArrowLeft": {
7804
- offset = new Vec(-1, 0);
7805
- break;
7813
+ if (offset) {
7814
+ const bounds = this.getViewportPageBounds();
7815
+ const next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }));
7816
+ this._animateToViewport(next, { animation: { duration: 320 } });
7806
7817
  }
7807
7818
  }
7808
- if (offset) {
7809
- const bounds = this.getViewportPageBounds();
7810
- const next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }));
7811
- this._animateToViewport(next, { animation: { duration: 320 } });
7812
- }
7813
7819
  }
7814
7820
  break;
7815
7821
  }
7816
7822
  case "key_up": {
7817
7823
  inputs.keys.delete(info.code);
7818
- if (info.code === "Space") {
7819
- if (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {
7820
- } else {
7821
- this.inputs.isPanning = false;
7822
- this.inputs.isSpacebarPanning = false;
7823
- this.setCursor({ type: this._prevCursor, rotation: 0 });
7824
+ if (this.options.spacebarPanning) {
7825
+ if (info.code === "Space") {
7826
+ if (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {
7827
+ } else {
7828
+ this.inputs.setIsPanning(false);
7829
+ this.inputs.setIsSpacebarPanning(false);
7830
+ this.setCursor({ type: this._prevCursor, rotation: 0 });
7831
+ }
7824
7832
  }
7825
7833
  }
7826
7834
  break;
@@ -7873,8 +7881,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7873
7881
  }
7874
7882
  _init = __decoratorStart(_a);
7875
7883
  __decorateElement(_init, 1, "getIsShapeHiddenCache", _getIsShapeHiddenCache_dec, Editor);
7876
- __decorateElement(_init, 1, "getCanUndo", _getCanUndo_dec, Editor);
7877
- __decorateElement(_init, 1, "getCanRedo", _getCanRedo_dec, Editor);
7884
+ __decorateElement(_init, 1, "canUndo", _canUndo_dec, Editor);
7885
+ __decorateElement(_init, 1, "canRedo", _canRedo_dec, Editor);
7878
7886
  __decorateElement(_init, 1, "getPath", _getPath_dec, Editor);
7879
7887
  __decorateElement(_init, 1, "getCurrentTool", _getCurrentTool_dec, Editor);
7880
7888
  __decorateElement(_init, 1, "getCurrentToolId", _getCurrentToolId_dec, Editor);
@@ -7909,6 +7917,9 @@ __decorateElement(_init, 1, "getCamera", _getCamera_dec, Editor);
7909
7917
  __decorateElement(_init, 1, "getViewportPageBoundsForFollowing", _getViewportPageBoundsForFollowing_dec, Editor);
7910
7918
  __decorateElement(_init, 1, "getCameraForFollowing", _getCameraForFollowing_dec, Editor);
7911
7919
  __decorateElement(_init, 1, "getZoomLevel", _getZoomLevel_dec, Editor);
7920
+ __decorateElement(_init, 1, "getDebouncedZoomLevel", _getDebouncedZoomLevel_dec, Editor);
7921
+ __decorateElement(_init, 1, "_getAboveDebouncedZoomThreshold", __getAboveDebouncedZoomThreshold_dec, Editor);
7922
+ __decorateElement(_init, 1, "getEfficientZoomLevel", _getEfficientZoomLevel_dec, Editor);
7912
7923
  __decorateElement(_init, 1, "getViewportScreenBounds", _getViewportScreenBounds_dec, Editor);
7913
7924
  __decorateElement(_init, 1, "getViewportScreenCenter", _getViewportScreenCenter_dec, Editor);
7914
7925
  __decorateElement(_init, 1, "getViewportPageBounds", _getViewportPageBounds_dec, Editor);