@sequent-org/moodboard 1.2.119 → 1.3.1

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 (122) hide show
  1. package/package.json +11 -1
  2. package/src/assets/icons/rotate-icon.svg +1 -1
  3. package/src/core/HistoryManager.js +16 -16
  4. package/src/core/KeyboardManager.js +48 -539
  5. package/src/core/PixiEngine.js +9 -9
  6. package/src/core/SaveManager.js +56 -31
  7. package/src/core/bootstrap/CoreInitializer.js +65 -0
  8. package/src/core/commands/DeleteObjectCommand.js +8 -0
  9. package/src/core/commands/GroupDeleteCommand.js +75 -0
  10. package/src/core/commands/GroupRotateCommand.js +6 -0
  11. package/src/core/commands/UpdateContentCommand.js +52 -0
  12. package/src/core/commands/UpdateFramePropertiesCommand.js +98 -0
  13. package/src/core/commands/UpdateFrameTypeCommand.js +85 -0
  14. package/src/core/commands/UpdateNoteStyleCommand.js +88 -0
  15. package/src/core/commands/UpdateTextStyleCommand.js +90 -0
  16. package/src/core/commands/index.js +6 -0
  17. package/src/core/events/Events.js +6 -0
  18. package/src/core/flows/ClipboardFlow.js +553 -0
  19. package/src/core/flows/LayerAndViewportFlow.js +283 -0
  20. package/src/core/flows/ObjectLifecycleFlow.js +336 -0
  21. package/src/core/flows/SaveFlow.js +34 -0
  22. package/src/core/flows/TransformFlow.js +277 -0
  23. package/src/core/flows/TransformFlowResizeHelpers.js +83 -0
  24. package/src/core/index.js +41 -1773
  25. package/src/core/keyboard/KeyboardClipboardImagePaste.js +190 -0
  26. package/src/core/keyboard/KeyboardContextGuards.js +35 -0
  27. package/src/core/keyboard/KeyboardEventRouter.js +92 -0
  28. package/src/core/keyboard/KeyboardSelectionActions.js +103 -0
  29. package/src/core/keyboard/KeyboardShortcutMap.js +31 -0
  30. package/src/core/keyboard/KeyboardToolSwitching.js +26 -0
  31. package/src/core/rendering/ObjectRenderer.js +3 -7
  32. package/src/grid/BaseGrid.js +26 -0
  33. package/src/grid/CrossGrid.js +7 -6
  34. package/src/grid/DotGrid.js +89 -33
  35. package/src/grid/DotGridZoomPhases.js +42 -0
  36. package/src/grid/LineGrid.js +22 -21
  37. package/src/moodboard/MoodBoard.js +31 -532
  38. package/src/moodboard/bootstrap/MoodBoardInitializer.js +47 -0
  39. package/src/moodboard/bootstrap/MoodBoardManagersFactory.js +38 -0
  40. package/src/moodboard/bootstrap/MoodBoardUiFactory.js +109 -0
  41. package/src/moodboard/integration/MoodBoardEventBindings.js +65 -0
  42. package/src/moodboard/integration/MoodBoardLoadApi.js +82 -0
  43. package/src/moodboard/integration/MoodBoardScreenshotApi.js +33 -0
  44. package/src/moodboard/integration/MoodBoardScreenshotCanvas.js +98 -0
  45. package/src/moodboard/lifecycle/MoodBoardDestroyer.js +97 -0
  46. package/src/objects/FileObject.js +17 -6
  47. package/src/objects/FrameObject.js +50 -10
  48. package/src/objects/NoteObject.js +5 -4
  49. package/src/services/BoardService.js +42 -2
  50. package/src/services/FrameService.js +83 -42
  51. package/src/services/ResizePolicyService.js +152 -0
  52. package/src/services/SettingsApplier.js +7 -2
  53. package/src/services/ZoomPanController.js +35 -9
  54. package/src/tools/ToolManager.js +30 -537
  55. package/src/tools/board-tools/PanTool.js +5 -11
  56. package/src/tools/manager/ToolActivationController.js +49 -0
  57. package/src/tools/manager/ToolEventRouter.js +396 -0
  58. package/src/tools/manager/ToolManagerGuards.js +33 -0
  59. package/src/tools/manager/ToolManagerLifecycle.js +110 -0
  60. package/src/tools/manager/ToolRegistry.js +33 -0
  61. package/src/tools/object-tools/DrawingTool.js +48 -14
  62. package/src/tools/object-tools/PlacementTool.js +50 -1049
  63. package/src/tools/object-tools/PlacementToolV2.js +88 -0
  64. package/src/tools/object-tools/SelectTool.js +174 -2681
  65. package/src/tools/object-tools/placement/GhostController.js +504 -0
  66. package/src/tools/object-tools/placement/PlacementCoordinateResolver.js +20 -0
  67. package/src/tools/object-tools/placement/PlacementEventsBridge.js +91 -0
  68. package/src/tools/object-tools/placement/PlacementInputRouter.js +267 -0
  69. package/src/tools/object-tools/placement/PlacementPayloadFactory.js +111 -0
  70. package/src/tools/object-tools/placement/PlacementSessionStore.js +18 -0
  71. package/src/tools/object-tools/selection/BoxSelectController.js +0 -5
  72. package/src/tools/object-tools/selection/CloneFlowController.js +71 -0
  73. package/src/tools/object-tools/selection/CoordinateMapper.js +10 -0
  74. package/src/tools/object-tools/selection/CursorController.js +78 -0
  75. package/src/tools/object-tools/selection/FileNameInlineEditorController.js +184 -0
  76. package/src/tools/object-tools/selection/HitTestService.js +102 -0
  77. package/src/tools/object-tools/selection/InlineEditorController.js +24 -0
  78. package/src/tools/object-tools/selection/InlineEditorDomFactory.js +50 -0
  79. package/src/tools/object-tools/selection/InlineEditorListenersRegistry.js +14 -0
  80. package/src/tools/object-tools/selection/InlineEditorPositioningService.js +25 -0
  81. package/src/tools/object-tools/selection/NoteInlineEditorController.js +113 -0
  82. package/src/tools/object-tools/selection/SelectInputRouter.js +267 -0
  83. package/src/tools/object-tools/selection/SelectToolLifecycleController.js +128 -0
  84. package/src/tools/object-tools/selection/SelectToolSetup.js +134 -0
  85. package/src/tools/object-tools/selection/SelectionOverlayService.js +81 -0
  86. package/src/tools/object-tools/selection/SelectionStateController.js +91 -0
  87. package/src/tools/object-tools/selection/TextEditorDomFactory.js +65 -0
  88. package/src/tools/object-tools/selection/TextEditorInteractionController.js +266 -0
  89. package/src/tools/object-tools/selection/TextEditorLifecycleRegistry.js +90 -0
  90. package/src/tools/object-tools/selection/TextEditorPositioningService.js +158 -0
  91. package/src/tools/object-tools/selection/TextEditorSyncService.js +110 -0
  92. package/src/tools/object-tools/selection/TextInlineEditorController.js +457 -0
  93. package/src/tools/object-tools/selection/TransformInteractionController.js +466 -0
  94. package/src/ui/FilePropertiesPanel.js +61 -32
  95. package/src/ui/FramePropertiesPanel.js +176 -101
  96. package/src/ui/HtmlHandlesLayer.js +121 -999
  97. package/src/ui/MapPanel.js +12 -7
  98. package/src/ui/NotePropertiesPanel.js +17 -2
  99. package/src/ui/TextPropertiesPanel.js +124 -738
  100. package/src/ui/Toolbar.js +82 -1181
  101. package/src/ui/Topbar.js +23 -25
  102. package/src/ui/ZoomPanel.js +16 -5
  103. package/src/ui/handles/GroupSelectionHandlesController.js +29 -0
  104. package/src/ui/handles/HandlesDomRenderer.js +278 -0
  105. package/src/ui/handles/HandlesEventBridge.js +102 -0
  106. package/src/ui/handles/HandlesInteractionController.js +772 -0
  107. package/src/ui/handles/HandlesPositioningService.js +206 -0
  108. package/src/ui/handles/SingleSelectionHandlesController.js +22 -0
  109. package/src/ui/styles/toolbar.css +2 -0
  110. package/src/ui/styles/workspace.css +13 -6
  111. package/src/ui/text-properties/TextPropertiesPanelBindings.js +92 -0
  112. package/src/ui/text-properties/TextPropertiesPanelEventBridge.js +77 -0
  113. package/src/ui/text-properties/TextPropertiesPanelMapper.js +173 -0
  114. package/src/ui/text-properties/TextPropertiesPanelRenderer.js +434 -0
  115. package/src/ui/text-properties/TextPropertiesPanelState.js +39 -0
  116. package/src/ui/toolbar/ToolbarActionRouter.js +193 -0
  117. package/src/ui/toolbar/ToolbarDialogsController.js +186 -0
  118. package/src/ui/toolbar/ToolbarPopupsController.js +665 -0
  119. package/src/ui/toolbar/ToolbarRenderer.js +97 -0
  120. package/src/ui/toolbar/ToolbarStateController.js +79 -0
  121. package/src/ui/toolbar/ToolbarTooltipController.js +52 -0
  122. package/src/utils/emojiLoaderNoBundler.js +1 -1
@@ -0,0 +1,277 @@
1
+ import { Events } from '../events/Events.js';
2
+ import {
3
+ GroupResizeCommand,
4
+ ResizeObjectCommand,
5
+ GroupRotateCommand
6
+ } from '../commands/index.js';
7
+ import {
8
+ getActiveResize,
9
+ normalizeResizeEndPayload,
10
+ normalizeResizeUpdatePayload,
11
+ resolveResizePositionFallback,
12
+ } from './TransformFlowResizeHelpers.js';
13
+
14
+ function rotateVector(vector, angleDegrees) {
15
+ const angleRad = angleDegrees * Math.PI / 180;
16
+ const cos = Math.cos(angleRad);
17
+ const sin = Math.sin(angleRad);
18
+ return {
19
+ x: vector.x * cos - vector.y * sin,
20
+ y: vector.x * sin + vector.y * cos,
21
+ };
22
+ }
23
+
24
+ export function setupTransformFlow(core) {
25
+ core.eventBus.on(Events.Tool.ResizeStart, (data) => {
26
+ const objects = core.state.getObjects();
27
+ const object = objects.find(obj => obj.id === data.object);
28
+ if (object) {
29
+ core.resizeStartSize = { width: object.width, height: object.height };
30
+ core._activeResize = {
31
+ objectId: data.object,
32
+ handle: data.handle,
33
+ startSize: { width: object.width, height: object.height },
34
+ startPosition: { x: object.position.x, y: object.position.y },
35
+ dominantAxis: null,
36
+ };
37
+ }
38
+ });
39
+
40
+ core.eventBus.on(Events.Tool.GroupResizeStart, (data) => {
41
+ core._groupResizeStart = data.startBounds || null;
42
+ core._groupResizeSnapshot = new Map();
43
+ for (const id of data.objects) {
44
+ const obj = core.state.state.objects.find(o => o.id === id);
45
+ const pixiObj = core.pixi.objects.get(id);
46
+ if (!obj || !pixiObj) continue;
47
+ core._groupResizeSnapshot.set(id, {
48
+ size: { width: obj.width, height: obj.height },
49
+ position: { x: obj.position.x, y: obj.position.y },
50
+ center: {
51
+ x: obj.position.x + obj.width / 2,
52
+ y: obj.position.y + obj.height / 2,
53
+ },
54
+ type: obj.type || null
55
+ });
56
+ }
57
+ });
58
+
59
+ core.eventBus.on(Events.Tool.GroupResizeUpdate, (data) => {
60
+ const { startBounds, newBounds, scale } = data;
61
+ const sx = scale?.x ?? (newBounds.width / startBounds.width);
62
+ const sy = scale?.y ?? (newBounds.height / startBounds.height);
63
+ const startLeft = startBounds.x;
64
+ const startTop = startBounds.y;
65
+ const rotation = data.rotation || 0;
66
+ const startCenter = {
67
+ x: startLeft + startBounds.width / 2,
68
+ y: startTop + startBounds.height / 2,
69
+ };
70
+ const newBoundsCenter = {
71
+ x: newBounds.x + newBounds.width / 2,
72
+ y: newBounds.y + newBounds.height / 2,
73
+ };
74
+ for (const id of data.objects) {
75
+ const snap = core._groupResizeSnapshot?.get(id);
76
+ if (!snap) continue;
77
+ const centerAtStart = snap.center || {
78
+ x: snap.position.x + snap.size.width / 2,
79
+ y: snap.position.y + snap.size.height / 2,
80
+ };
81
+ const relCenterLocal = rotateVector({
82
+ x: centerAtStart.x - startCenter.x,
83
+ y: centerAtStart.y - startCenter.y,
84
+ }, -rotation);
85
+ const scaledRelCenterWorld = rotateVector({
86
+ x: relCenterLocal.x * sx,
87
+ y: relCenterLocal.y * sy,
88
+ }, rotation);
89
+ const newCenter = {
90
+ x: newBoundsCenter.x + scaledRelCenterWorld.x,
91
+ y: newBoundsCenter.y + scaledRelCenterWorld.y
92
+ };
93
+ const newSize = {
94
+ width: Math.max(10, snap.size.width * sx),
95
+ height: Math.max(10, snap.size.height * sy)
96
+ };
97
+ const newPos = { x: newCenter.x - newSize.width / 2, y: newCenter.y - newSize.height / 2 };
98
+ core.updateObjectSizeAndPositionDirect(id, newSize, newPos, snap.type || null);
99
+ }
100
+ });
101
+
102
+ core.eventBus.on(Events.Tool.GroupResizeEnd, (data) => {
103
+ const changes = [];
104
+ for (const id of data.objects) {
105
+ const before = core._groupResizeSnapshot?.get(id);
106
+ const obj = core.state.state.objects.find(o => o.id === id);
107
+ if (!before || !obj) continue;
108
+ const afterSize = { width: obj.width, height: obj.height };
109
+ const afterPos = { x: obj.position.x, y: obj.position.y };
110
+ if (before.size.width !== afterSize.width || before.size.height !== afterSize.height || before.position.x !== afterPos.x || before.position.y !== afterPos.y) {
111
+ changes.push({ id, fromSize: before.size, toSize: afterSize, fromPos: before.position, toPos: afterPos, type: before.type });
112
+ }
113
+ }
114
+ if (changes.length > 0) {
115
+ const cmd = new GroupResizeCommand(core, changes);
116
+ cmd.setEventBus(core.eventBus);
117
+ core.history.executeCommand(cmd);
118
+ }
119
+ core._groupResizeStart = null;
120
+ core._groupResizeSnapshot = null;
121
+ if (core.selectTool && core.selectTool.selectedObjects.size > 1) {
122
+ core.selectTool.updateResizeHandles();
123
+ }
124
+ });
125
+
126
+ core.eventBus.on(Events.Tool.ResizeUpdate, (data) => {
127
+ const objects = core.state.getObjects();
128
+ const object = objects.find(obj => obj.id === data.object);
129
+ const objectType = object ? object.type : null;
130
+ const activeResize = normalizeResizeUpdatePayload(core, object, data);
131
+
132
+ let position = data.position;
133
+ if (!position && activeResize) {
134
+ position = resolveResizePositionFallback(core, data.object, data.size);
135
+ }
136
+
137
+ core.updateObjectSizeAndPositionDirect(data.object, data.size, position, objectType);
138
+ });
139
+
140
+ core.eventBus.on(Events.Tool.ResizeEnd, (data) => {
141
+ if (core.resizeStartSize && data.oldSize && data.newSize) {
142
+ const objects = core.state.getObjects();
143
+ const object = objects.find(obj => obj.id === data.object);
144
+ const activeResize = normalizeResizeEndPayload(core, object, data);
145
+
146
+ if (data.oldSize.width !== data.newSize.width || data.oldSize.height !== data.newSize.height) {
147
+ let oldPos = data.oldPosition;
148
+ let newPos = data.newPosition;
149
+ const activeResize = getActiveResize(core, data.object);
150
+ if ((!oldPos || !newPos) && activeResize) {
151
+ if (!oldPos) oldPos = { x: activeResize.startPosition.x, y: activeResize.startPosition.y };
152
+ if (!newPos) {
153
+ newPos = resolveResizePositionFallback(core, data.object, data.newSize);
154
+ }
155
+ }
156
+ const command = new ResizeObjectCommand(
157
+ core,
158
+ data.object,
159
+ data.oldSize,
160
+ data.newSize,
161
+ oldPos,
162
+ newPos
163
+ );
164
+ command.setEventBus(core.eventBus);
165
+ core.history.executeCommand(command);
166
+ }
167
+ }
168
+ core.resizeStartSize = null;
169
+ core._activeResize = null;
170
+ });
171
+
172
+ core.eventBus.on(Events.Tool.RotateUpdate, (data) => {
173
+ core.pixi.updateObjectRotation(data.object, data.angle);
174
+ });
175
+
176
+ core.eventBus.on(Events.Tool.RotateEnd, (data) => {
177
+ if (data.oldAngle !== undefined && data.newAngle !== undefined) {
178
+ if (Math.abs(data.oldAngle - data.newAngle) > 0.1) {
179
+ import('../commands/RotateObjectCommand.js').then(({ RotateObjectCommand }) => {
180
+ const command = new RotateObjectCommand(
181
+ core,
182
+ data.object,
183
+ data.oldAngle,
184
+ data.newAngle
185
+ );
186
+ command.setEventBus(core.eventBus);
187
+ core.history.executeCommand(command);
188
+ });
189
+ }
190
+ }
191
+ });
192
+
193
+ core.eventBus.on(Events.Tool.GroupRotateStart, (data) => {
194
+ core._groupRotateStart = new Map();
195
+ for (const id of data.objects) {
196
+ const pixiObject = core.pixi.objects.get(id);
197
+ const deg = pixiObject ? (pixiObject.rotation * 180 / Math.PI) : 0;
198
+ const pos = pixiObject ? { x: pixiObject.x, y: pixiObject.y } : { x: 0, y: 0 };
199
+ core._groupRotateStart.set(id, { angle: deg, position: pos });
200
+ }
201
+ core._groupRotateCenter = data.center;
202
+ });
203
+
204
+ core.eventBus.on(Events.Tool.GroupRotateUpdate, (data) => {
205
+ const center = core._groupRotateCenter;
206
+ if (!center) return;
207
+ const rad = (data.angle || 0) * Math.PI / 180;
208
+ const cos = Math.cos(rad);
209
+ const sin = Math.sin(rad);
210
+ for (const id of data.objects) {
211
+ const start = core._groupRotateStart?.get(id);
212
+ if (!start) continue;
213
+ const startAngle = start.angle;
214
+ const newAngle = startAngle + data.angle;
215
+ const relX = start.position.x - center.x;
216
+ const relY = start.position.y - center.y;
217
+ const newX = center.x + relX * cos - relY * sin;
218
+ const newY = center.y + relX * sin + relY * cos;
219
+ const pObj = core.pixi.objects.get(id);
220
+ const halfW = (pObj?.width || 0) / 2;
221
+ const halfH = (pObj?.height || 0) / 2;
222
+ core.updateObjectPositionDirect(id, { x: newX - halfW, y: newY - halfH });
223
+ core.pixi.updateObjectRotation(id, newAngle);
224
+ core.updateObjectRotationDirect(id, newAngle);
225
+ }
226
+ core.eventBus.emit(Events.Object.TransformUpdated, { objectId: '__group__', type: 'rotation' });
227
+ });
228
+
229
+ core.eventBus.on(Events.Tool.GroupRotateEnd, (data) => {
230
+ const center = core._groupRotateCenter;
231
+ if (!center) return;
232
+ const changes = [];
233
+ for (const id of data.objects) {
234
+ const start = core._groupRotateStart?.get(id);
235
+ const pixiObject = core.pixi.objects.get(id);
236
+ if (!start || !pixiObject) continue;
237
+ const toAngle = pixiObject.rotation * 180 / Math.PI;
238
+ const objState = core.state.state.objects.find(o => o.id === id);
239
+ const toPos = objState?.position
240
+ ? { x: objState.position.x, y: objState.position.y }
241
+ : (() => {
242
+ const halfW = (pixiObject.width || 0) / 2;
243
+ const halfH = (pixiObject.height || 0) / 2;
244
+ return { x: pixiObject.x - halfW, y: pixiObject.y - halfH };
245
+ })();
246
+ const halfW = (pixiObject.width || 0) / 2;
247
+ const halfH = (pixiObject.height || 0) / 2;
248
+ const fromPos = { x: start.position.x - halfW, y: start.position.y - halfH };
249
+ if (Math.abs(start.angle - toAngle) > 0.1 || Math.abs(fromPos.x - toPos.x) > 0.1 || Math.abs(fromPos.y - toPos.y) > 0.1) {
250
+ changes.push({ id, fromAngle: start.angle, toAngle, fromPos, toPos });
251
+ }
252
+ }
253
+ if (changes.length > 0) {
254
+ const cmd = new GroupRotateCommand(core, changes);
255
+ cmd.setEventBus(core.eventBus);
256
+ core.history.executeCommand(cmd);
257
+ }
258
+ core._groupRotateStart = null;
259
+ core._groupRotateCenter = null;
260
+ });
261
+
262
+ core.eventBus.on(Events.Object.Rotate, (data) => {
263
+ core.pixi.updateObjectRotation(data.objectId, data.angle);
264
+ core.updateObjectRotationDirect(data.objectId, data.angle);
265
+ core.eventBus.emit(Events.Object.TransformUpdated, {
266
+ objectId: data.objectId,
267
+ type: 'rotation',
268
+ angle: data.angle
269
+ });
270
+ });
271
+
272
+ core.eventBus.on(Events.Object.TransformUpdated, (data) => {
273
+ if (core.selectTool && core.selectTool.selection && core.selectTool.selection.has(data.objectId)) {
274
+ core.selectTool.updateResizeHandles();
275
+ }
276
+ });
277
+ }
@@ -0,0 +1,83 @@
1
+ import {
2
+ normalizeSingleResizeGeometry,
3
+ resolveSingleResizeDominantAxis,
4
+ resolveAnchoredResizePosition,
5
+ } from '../../services/ResizePolicyService.js';
6
+
7
+ export function shouldNormalizeSingleResize(objectType) {
8
+ return objectType === 'image'
9
+ || objectType === 'frame'
10
+ || objectType === 'emoji';
11
+ }
12
+
13
+ export function getActiveResize(core, objectId) {
14
+ return core._activeResize && core._activeResize.objectId === objectId
15
+ ? core._activeResize
16
+ : null;
17
+ }
18
+
19
+ export function normalizeResizeUpdatePayload(core, object, data) {
20
+ const activeResize = getActiveResize(core, data.object);
21
+ if (!data.size || !object || !shouldNormalizeSingleResize(object.type)) {
22
+ return activeResize;
23
+ }
24
+
25
+ if (activeResize && !activeResize.dominantAxis) {
26
+ const dominantAxis = resolveSingleResizeDominantAxis({
27
+ startSize: activeResize.startSize,
28
+ size: data.size,
29
+ objectType: object.type,
30
+ properties: object.properties || {},
31
+ });
32
+ if (dominantAxis === 'width' || dominantAxis === 'height') {
33
+ activeResize.dominantAxis = dominantAxis;
34
+ }
35
+ }
36
+
37
+ const normalized = normalizeSingleResizeGeometry({
38
+ startSize: activeResize?.startSize || { width: object.width, height: object.height },
39
+ startPosition: activeResize?.startPosition || object.position || null,
40
+ handle: activeResize?.handle || '',
41
+ size: data.size,
42
+ position: data.position,
43
+ objectType: object.type,
44
+ properties: object.properties || {},
45
+ preferredDominantAxis: activeResize?.dominantAxis || null,
46
+ });
47
+ data.size = normalized.size;
48
+ data.position = normalized.position;
49
+ return activeResize;
50
+ }
51
+
52
+ export function normalizeResizeEndPayload(core, object, data) {
53
+ const activeResize = getActiveResize(core, data.object);
54
+ if (!object || !shouldNormalizeSingleResize(object.type)) {
55
+ return activeResize;
56
+ }
57
+
58
+ const normalized = normalizeSingleResizeGeometry({
59
+ startSize: activeResize?.startSize || data.oldSize || { width: object.width, height: object.height },
60
+ startPosition: activeResize?.startPosition || data.oldPosition || object.position || null,
61
+ handle: activeResize?.handle || '',
62
+ size: data.newSize,
63
+ position: data.newPosition,
64
+ objectType: object.type,
65
+ properties: object.properties || {},
66
+ preferredDominantAxis: activeResize?.dominantAxis || null,
67
+ });
68
+ data.newSize = normalized.size;
69
+ data.newPosition = normalized.position;
70
+ return activeResize;
71
+ }
72
+
73
+ export function resolveResizePositionFallback(core, objectId, size) {
74
+ const activeResize = getActiveResize(core, objectId);
75
+ if (!activeResize) return null;
76
+
77
+ return resolveAnchoredResizePosition({
78
+ startPosition: activeResize.startPosition,
79
+ startSize: core.optimization?.startSize || activeResize.startSize,
80
+ normalizedSize: size,
81
+ handle: activeResize.handle,
82
+ });
83
+ }