@elixpo/lixsketch 5.6.9 → 5.6.11

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/react/{AIRenderer-R5M2CIDO.js → AIRenderer-JNEZYDYQ.js} +4 -4
  2. package/dist/react/Arrow-QMR77LGQ.js +9 -0
  3. package/dist/react/Circle-5WL5HZA5.js +11 -0
  4. package/dist/react/{CopyPaste-PPDS3AD6.js → CopyPaste-V7AY56H3.js} +74 -30
  5. package/dist/react/CopyPaste-V7AY56H3.js.map +7 -0
  6. package/dist/react/{EventDispatcher-UV7LFSAS.js → EventDispatcher-E4OJCMY6.js} +154 -57
  7. package/dist/react/{EventDispatcher-UV7LFSAS.js.map → EventDispatcher-E4OJCMY6.js.map} +3 -3
  8. package/dist/react/Frame-OZCDVPMI.js +11 -0
  9. package/dist/react/FreehandStroke-QSSYWBFK.js +9 -0
  10. package/dist/react/IconShape-HXUV4VRT.js +10 -0
  11. package/dist/react/ImageShape-JGLT2UGG.js +10 -0
  12. package/dist/react/Line-YONPLUYT.js +11 -0
  13. package/dist/react/{MermaidFlowchartRenderer-EL3Q2MNW.js → MermaidFlowchartRenderer-FSH43RUP.js} +26 -7
  14. package/dist/react/{MermaidFlowchartRenderer-EL3Q2MNW.js.map → MermaidFlowchartRenderer-FSH43RUP.js.map} +2 -2
  15. package/dist/react/{MermaidSequenceRenderer-K4KHHEVC.js → MermaidSequenceRenderer-FRPNOF2V.js} +11 -9
  16. package/dist/react/{MermaidSequenceRenderer-K4KHHEVC.js.map → MermaidSequenceRenderer-FRPNOF2V.js.map} +2 -2
  17. package/dist/react/{MermaidStructuredRenderer-6LN3WISP.js → MermaidStructuredRenderer-BZGQLRIH.js} +13 -6
  18. package/dist/react/{MermaidStructuredRenderer-6LN3WISP.js.map → MermaidStructuredRenderer-BZGQLRIH.js.map} +2 -2
  19. package/dist/react/Rectangle-7KMA3SC6.js +11 -0
  20. package/dist/react/{SceneSerializer-H6KMQCO2.js → SceneSerializer-7O72LEZP.js} +13 -12
  21. package/dist/react/{SceneSerializer-H6KMQCO2.js.map → SceneSerializer-7O72LEZP.js.map} +1 -1
  22. package/dist/react/{Selection-CFWRGVKH.js → Selection-S4FYSZIF.js} +5 -5
  23. package/dist/react/{SketchEngine-UFLZJQXS.js → SketchEngine-VTWURP2K.js} +26 -26
  24. package/dist/react/{UndoRedo-RXO7YHA2.js → UndoRedo-YLQJ6DXW.js} +8 -2
  25. package/dist/react/{ZoomPan-RR7KUYZT.js → ZoomPan-AEKWKUCH.js} +2 -2
  26. package/dist/react/{arrowTool-DO327FKU.js → arrowTool-C4RDWQEX.js} +3 -3
  27. package/dist/react/{chunk-X5ENBMGL.js → chunk-2U47AU6Y.js} +3 -3
  28. package/dist/react/{chunk-X5ENBMGL.js.map → chunk-2U47AU6Y.js.map} +1 -1
  29. package/dist/react/{chunk-RK3NVAER.js → chunk-75OPJOWN.js} +7 -7
  30. package/dist/react/chunk-75OPJOWN.js.map +7 -0
  31. package/dist/react/{chunk-DODPOWNX.js → chunk-CWE5IFG7.js} +5 -5
  32. package/dist/react/{chunk-DODPOWNX.js.map → chunk-CWE5IFG7.js.map} +1 -1
  33. package/dist/react/{chunk-O7KXLFZN.js → chunk-IS2MKWGH.js} +8 -7
  34. package/dist/react/chunk-IS2MKWGH.js.map +7 -0
  35. package/dist/react/{chunk-ZNZAICWY.js → chunk-JEHOEQ6Z.js} +13 -5
  36. package/dist/react/chunk-JEHOEQ6Z.js.map +7 -0
  37. package/dist/react/{chunk-BOZEDUAF.js → chunk-JYBJXTLM.js} +40 -15
  38. package/dist/react/chunk-JYBJXTLM.js.map +7 -0
  39. package/dist/react/{chunk-6LWUR7XB.js → chunk-LXEHYCKH.js} +4 -4
  40. package/dist/react/{chunk-6LWUR7XB.js.map → chunk-LXEHYCKH.js.map} +1 -1
  41. package/dist/react/chunk-M7OYYJC6.js +17 -0
  42. package/dist/react/chunk-M7OYYJC6.js.map +7 -0
  43. package/dist/react/chunk-MS4TIQ6Z.js +131 -0
  44. package/dist/react/chunk-MS4TIQ6Z.js.map +7 -0
  45. package/dist/react/{chunk-2ALS5JGS.js → chunk-OCJN32IL.js} +2 -2
  46. package/dist/react/{chunk-KZBKYHZO.js → chunk-P7VIYR6R.js} +8 -5
  47. package/dist/react/chunk-P7VIYR6R.js.map +7 -0
  48. package/dist/react/{chunk-KC26KJW4.js → chunk-PX2635H5.js} +32 -10
  49. package/dist/react/chunk-PX2635H5.js.map +7 -0
  50. package/dist/react/{chunk-37PF7FG2.js → chunk-SDG4U7TP.js} +7 -6
  51. package/dist/react/chunk-SDG4U7TP.js.map +7 -0
  52. package/dist/react/{chunk-CGMUXYPJ.js → chunk-STJERZ25.js} +8 -4
  53. package/dist/react/chunk-STJERZ25.js.map +7 -0
  54. package/dist/react/{chunk-VZPH7OAM.js → chunk-TCWCC4Z4.js} +7 -3
  55. package/dist/react/chunk-TCWCC4Z4.js.map +7 -0
  56. package/dist/react/{chunk-VZX55VQL.js → chunk-TFCBCWL5.js} +90 -33
  57. package/dist/react/chunk-TFCBCWL5.js.map +7 -0
  58. package/dist/react/{chunk-GQLXUZHQ.js → chunk-TWHJ6PJK.js} +5 -3
  59. package/dist/react/chunk-TWHJ6PJK.js.map +7 -0
  60. package/dist/react/{chunk-NH3NVSWT.js → chunk-UCOK4V5Z.js} +4 -3
  61. package/dist/react/{chunk-NH3NVSWT.js.map → chunk-UCOK4V5Z.js.map} +2 -2
  62. package/dist/react/{chunk-W7XUY4GR.js → chunk-VJDNKJBX.js} +56 -4
  63. package/dist/react/chunk-VJDNKJBX.js.map +7 -0
  64. package/dist/react/{chunk-BT2EIJD4.js → chunk-WCA3FGWE.js} +6 -3
  65. package/dist/react/chunk-WCA3FGWE.js.map +7 -0
  66. package/dist/react/{chunk-I7TVGJFF.js → chunk-Y3FJMYPX.js} +4 -4
  67. package/dist/react/{chunk-I7TVGJFF.js.map → chunk-Y3FJMYPX.js.map} +1 -1
  68. package/dist/react/{chunk-7DD2JRBC.js → chunk-YCGLGY4C.js} +2 -2
  69. package/dist/react/{circleTool-NK4RVDAR.js → circleTool-QQV2QEVF.js} +4 -4
  70. package/dist/react/{codeTool-3WF4HEOW.js → codeTool-PTCPSZ4L.js} +5 -5
  71. package/dist/react/{frameTool-VCNV2NG2.js → frameTool-7GQPLU4Y.js} +4 -4
  72. package/dist/react/{freehandTool-TBAOD46K.js → freehandTool-3RJXTVAK.js} +4 -4
  73. package/dist/react/{iconTool-65JCAKYF.js → iconTool-DW5YJX7P.js} +5 -5
  74. package/dist/react/{imageTool-UQZUBOK2.js → imageTool-7GZQKWYT.js} +5 -5
  75. package/dist/react/index.js +68 -63
  76. package/dist/react/index.js.map +2 -2
  77. package/dist/react/{lineTool-762KBYOM.js → lineTool-5CY7BHND.js} +4 -4
  78. package/dist/react/{rectangleTool-IQK3HZK6.js → rectangleTool-DK4QL4QW.js} +4 -4
  79. package/dist/react/styles.css +4 -0
  80. package/dist/react/{textTool-ITG2SBJK.js → textTool-GP5QQYF3.js} +6 -6
  81. package/package.json +1 -1
  82. package/src/core/CopyPaste.js +66 -18
  83. package/src/core/EventDispatcher.js +71 -47
  84. package/src/core/MermaidFlowchartRenderer.js +34 -8
  85. package/src/core/MermaidSequenceRenderer.js +10 -8
  86. package/src/core/MermaidStructuredRenderer.js +12 -5
  87. package/src/core/ScreenSpaceControls.js +102 -13
  88. package/src/core/Selection.js +26 -7
  89. package/src/core/SelectionGesture.js +50 -0
  90. package/src/core/UndoRedo.js +108 -35
  91. package/src/react/components/sidebars/CircleSidebar.jsx +11 -5
  92. package/src/react/components/sidebars/IconSidebar.jsx +10 -4
  93. package/src/react/components/sidebars/RectangleSidebar.jsx +11 -5
  94. package/src/react/components/sidebars/ShapeSidebar.jsx +29 -37
  95. package/src/react/components/sidebars/TextSidebar.jsx +10 -4
  96. package/src/react/store/useUIStore.js +8 -1
  97. package/src/react/styles.css +13 -0
  98. package/src/react/utils/canvasBackgrounds.js +11 -2
  99. package/src/shapes/Arrow.js +4 -3
  100. package/src/shapes/Circle.js +58 -2
  101. package/src/shapes/Frame.js +11 -4
  102. package/src/shapes/FreehandStroke.js +2 -1
  103. package/src/shapes/Line.js +47 -20
  104. package/src/shapes/Rectangle.js +3 -1
  105. package/src/tools/arrowTool.js +1 -1
  106. package/src/tools/circleTool.js +5 -2
  107. package/src/tools/codeTool.js +1 -1
  108. package/src/tools/frameTool.js +3 -2
  109. package/src/tools/freehandTool.js +1 -1
  110. package/src/tools/iconTool.js +4 -3
  111. package/src/tools/imageTool.js +3 -2
  112. package/src/tools/lineTool.js +5 -1
  113. package/src/tools/rectangleTool.js +1 -1
  114. package/src/tools/shapeRecognitionTool.js +1 -1
  115. package/src/tools/textTool.js +2 -2
  116. package/src/utils/themeColors.js +13 -0
  117. package/dist/react/Arrow-EF7ALH2Y.js +0 -8
  118. package/dist/react/Circle-HMM5PKJ2.js +0 -10
  119. package/dist/react/CopyPaste-PPDS3AD6.js.map +0 -7
  120. package/dist/react/Frame-DELCMYV6.js +0 -11
  121. package/dist/react/FreehandStroke-WXIJKD5I.js +0 -9
  122. package/dist/react/IconShape-PZHMZSLR.js +0 -10
  123. package/dist/react/ImageShape-ZMBZARRI.js +0 -10
  124. package/dist/react/Line-VPVPL6ET.js +0 -10
  125. package/dist/react/Rectangle-4U4CD2ER.js +0 -10
  126. package/dist/react/chunk-37PF7FG2.js.map +0 -7
  127. package/dist/react/chunk-BOZEDUAF.js.map +0 -7
  128. package/dist/react/chunk-BT2EIJD4.js.map +0 -7
  129. package/dist/react/chunk-CGMUXYPJ.js.map +0 -7
  130. package/dist/react/chunk-GQLXUZHQ.js.map +0 -7
  131. package/dist/react/chunk-KC26KJW4.js.map +0 -7
  132. package/dist/react/chunk-KZBKYHZO.js.map +0 -7
  133. package/dist/react/chunk-O7KXLFZN.js.map +0 -7
  134. package/dist/react/chunk-PAKA6HUX.js +0 -59
  135. package/dist/react/chunk-PAKA6HUX.js.map +0 -7
  136. package/dist/react/chunk-RK3NVAER.js.map +0 -7
  137. package/dist/react/chunk-VZPH7OAM.js.map +0 -7
  138. package/dist/react/chunk-VZX55VQL.js.map +0 -7
  139. package/dist/react/chunk-W7XUY4GR.js.map +0 -7
  140. package/dist/react/chunk-ZNZAICWY.js.map +0 -7
  141. /package/dist/react/{AIRenderer-R5M2CIDO.js.map → AIRenderer-JNEZYDYQ.js.map} +0 -0
  142. /package/dist/react/{Arrow-EF7ALH2Y.js.map → Arrow-QMR77LGQ.js.map} +0 -0
  143. /package/dist/react/{Circle-HMM5PKJ2.js.map → Circle-5WL5HZA5.js.map} +0 -0
  144. /package/dist/react/{Frame-DELCMYV6.js.map → Frame-OZCDVPMI.js.map} +0 -0
  145. /package/dist/react/{FreehandStroke-WXIJKD5I.js.map → FreehandStroke-QSSYWBFK.js.map} +0 -0
  146. /package/dist/react/{IconShape-PZHMZSLR.js.map → IconShape-HXUV4VRT.js.map} +0 -0
  147. /package/dist/react/{ImageShape-ZMBZARRI.js.map → ImageShape-JGLT2UGG.js.map} +0 -0
  148. /package/dist/react/{Line-VPVPL6ET.js.map → Line-YONPLUYT.js.map} +0 -0
  149. /package/dist/react/{Rectangle-4U4CD2ER.js.map → Rectangle-7KMA3SC6.js.map} +0 -0
  150. /package/dist/react/{Selection-CFWRGVKH.js.map → Selection-S4FYSZIF.js.map} +0 -0
  151. /package/dist/react/{SketchEngine-UFLZJQXS.js.map → SketchEngine-VTWURP2K.js.map} +0 -0
  152. /package/dist/react/{UndoRedo-RXO7YHA2.js.map → UndoRedo-YLQJ6DXW.js.map} +0 -0
  153. /package/dist/react/{ZoomPan-RR7KUYZT.js.map → ZoomPan-AEKWKUCH.js.map} +0 -0
  154. /package/dist/react/{arrowTool-DO327FKU.js.map → arrowTool-C4RDWQEX.js.map} +0 -0
  155. /package/dist/react/{chunk-2ALS5JGS.js.map → chunk-OCJN32IL.js.map} +0 -0
  156. /package/dist/react/{chunk-7DD2JRBC.js.map → chunk-YCGLGY4C.js.map} +0 -0
  157. /package/dist/react/{circleTool-NK4RVDAR.js.map → circleTool-QQV2QEVF.js.map} +0 -0
  158. /package/dist/react/{codeTool-3WF4HEOW.js.map → codeTool-PTCPSZ4L.js.map} +0 -0
  159. /package/dist/react/{frameTool-VCNV2NG2.js.map → frameTool-7GQPLU4Y.js.map} +0 -0
  160. /package/dist/react/{freehandTool-TBAOD46K.js.map → freehandTool-3RJXTVAK.js.map} +0 -0
  161. /package/dist/react/{iconTool-65JCAKYF.js.map → iconTool-DW5YJX7P.js.map} +0 -0
  162. /package/dist/react/{imageTool-UQZUBOK2.js.map → imageTool-7GZQKWYT.js.map} +0 -0
  163. /package/dist/react/{lineTool-762KBYOM.js.map → lineTool-5CY7BHND.js.map} +0 -0
  164. /package/dist/react/{rectangleTool-IQK3HZK6.js.map → rectangleTool-DK4QL4QW.js.map} +0 -0
  165. /package/dist/react/{textTool-ITG2SBJK.js.map → textTool-GP5QQYF3.js.map} +0 -0
@@ -165,16 +165,16 @@ var SketchEngine = class {
165
165
  { Frame },
166
166
  { FreehandStroke }
167
167
  ] = await Promise.all([
168
- import("./Rectangle-4U4CD2ER.js"),
169
- import("./Circle-HMM5PKJ2.js"),
170
- import("./Arrow-EF7ALH2Y.js"),
171
- import("./Line-VPVPL6ET.js"),
168
+ import("./Rectangle-7KMA3SC6.js"),
169
+ import("./Circle-5WL5HZA5.js"),
170
+ import("./Arrow-QMR77LGQ.js"),
171
+ import("./Line-YONPLUYT.js"),
172
172
  import("./TextShape-DY77FFI2.js"),
173
173
  import("./CodeShape-TE74XP5V.js"),
174
- import("./ImageShape-ZMBZARRI.js"),
175
- import("./IconShape-PZHMZSLR.js"),
176
- import("./Frame-DELCMYV6.js"),
177
- import("./FreehandStroke-WXIJKD5I.js")
174
+ import("./ImageShape-JGLT2UGG.js"),
175
+ import("./IconShape-HXUV4VRT.js"),
176
+ import("./Frame-OZCDVPMI.js"),
177
+ import("./FreehandStroke-QSSYWBFK.js")
178
178
  ]);
179
179
  window.Rectangle = Rectangle;
180
180
  window.Circle = Circle;
@@ -210,16 +210,16 @@ var SketchEngine = class {
210
210
  frameTool,
211
211
  freehandTool
212
212
  ] = await Promise.all([
213
- import("./rectangleTool-IQK3HZK6.js"),
214
- import("./circleTool-NK4RVDAR.js"),
215
- import("./arrowTool-DO327FKU.js"),
216
- import("./lineTool-762KBYOM.js"),
217
- import("./textTool-ITG2SBJK.js"),
218
- import("./codeTool-3WF4HEOW.js"),
219
- import("./imageTool-UQZUBOK2.js"),
220
- import("./iconTool-65JCAKYF.js"),
221
- import("./frameTool-VCNV2NG2.js"),
222
- import("./freehandTool-TBAOD46K.js")
213
+ import("./rectangleTool-DK4QL4QW.js"),
214
+ import("./circleTool-QQV2QEVF.js"),
215
+ import("./arrowTool-C4RDWQEX.js"),
216
+ import("./lineTool-5CY7BHND.js"),
217
+ import("./textTool-GP5QQYF3.js"),
218
+ import("./codeTool-PTCPSZ4L.js"),
219
+ import("./imageTool-7GZQKWYT.js"),
220
+ import("./iconTool-DW5YJX7P.js"),
221
+ import("./frameTool-7GQPLU4Y.js"),
222
+ import("./freehandTool-3RJXTVAK.js")
223
223
  ]);
224
224
  this._modules.tools = {
225
225
  rectangleTool,
@@ -243,11 +243,11 @@ var SketchEngine = class {
243
243
  resizeShapes,
244
244
  resizeCode
245
245
  ] = await Promise.all([
246
- import("./EventDispatcher-UV7LFSAS.js"),
247
- import("./UndoRedo-RXO7YHA2.js"),
248
- import("./Selection-CFWRGVKH.js"),
249
- import("./ZoomPan-RR7KUYZT.js"),
250
- import("./CopyPaste-PPDS3AD6.js"),
246
+ import("./EventDispatcher-E4OJCMY6.js"),
247
+ import("./UndoRedo-YLQJ6DXW.js"),
248
+ import("./Selection-S4FYSZIF.js"),
249
+ import("./ZoomPan-AEKWKUCH.js"),
250
+ import("./CopyPaste-V7AY56H3.js"),
251
251
  import("./EraserTrail-PA6IQLQN.js"),
252
252
  import("./ResizeShapes-LKEQTITP.js"),
253
253
  import("./ResizeCode-WAMDTKSW.js")
@@ -266,7 +266,7 @@ var SketchEngine = class {
266
266
  eventDispatcher.initEventDispatcher(this.svg);
267
267
  }
268
268
  window.__sketchInteractionReady = true;
269
- const sceneSerializer = await import("./SceneSerializer-H6KMQCO2.js");
269
+ const sceneSerializer = await import("./SceneSerializer-7O72LEZP.js");
270
270
  if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
271
271
  await Promise.all([
272
272
  import("./eraserTool-2GS2LQCS.js"),
@@ -279,7 +279,7 @@ var SketchEngine = class {
279
279
  if (selection.multiSelection) window.multiSelection = selection.multiSelection;
280
280
  if (selection.clearAllSelections) window.clearAllSelections = selection.clearAllSelections;
281
281
  if (copyPaste.initCopyPaste) copyPaste.initCopyPaste();
282
- const aiRenderer = await import("./AIRenderer-R5M2CIDO.js");
282
+ const aiRenderer = await import("./AIRenderer-JNEZYDYQ.js");
283
283
  if (aiRenderer.initAIRenderer) aiRenderer.initAIRenderer();
284
284
  const graphEngine = await import("./GraphEngine-XH3RPYO4.js");
285
285
  if (graphEngine.initGraphEngine) graphEngine.initGraphEngine();
@@ -441,4 +441,4 @@ export {
441
441
  SketchEngine,
442
442
  SketchEngine_default as default
443
443
  };
444
- //# sourceMappingURL=SketchEngine-UFLZJQXS.js.map
444
+ //# sourceMappingURL=SketchEngine-VTWURP2K.js.map
@@ -1,6 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  beginUndoBatch,
4
+ captureFrameChildStates,
5
+ captureShapeGeometry,
4
6
  clearUndoHistory,
5
7
  endUndoBatch,
6
8
  getCurrentSelectedElement,
@@ -13,13 +15,16 @@ import {
13
15
  pushFrameAttachmentAction,
14
16
  pushOptionsChangeAction,
15
17
  pushTransformAction,
18
+ rebindUndoHistory,
16
19
  redo,
17
20
  setTextReferences,
18
21
  undo,
19
22
  updateSelectedElement
20
- } from "./chunk-VZX55VQL.js";
23
+ } from "./chunk-TFCBCWL5.js";
21
24
  export {
22
25
  beginUndoBatch,
26
+ captureFrameChildStates,
27
+ captureShapeGeometry,
23
28
  clearUndoHistory,
24
29
  endUndoBatch,
25
30
  getCurrentSelectedElement,
@@ -32,9 +37,10 @@ export {
32
37
  pushFrameAttachmentAction,
33
38
  pushOptionsChangeAction,
34
39
  pushTransformAction,
40
+ rebindUndoHistory,
35
41
  redo,
36
42
  setTextReferences,
37
43
  undo,
38
44
  updateSelectedElement
39
45
  };
40
- //# sourceMappingURL=UndoRedo-RXO7YHA2.js.map
46
+ //# sourceMappingURL=UndoRedo-YLQJ6DXW.js.map
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  installScreenSpaceControlSync
4
- } from "./chunk-PAKA6HUX.js";
4
+ } from "./chunk-MS4TIQ6Z.js";
5
5
 
6
6
  // src/core/ZoomPan.js
7
7
  installScreenSpaceControlSync(freehandCanvas);
@@ -296,4 +296,4 @@ svg.addEventListener("wheel", (e) => {
296
296
  `${currentViewBox.x} ${currentViewBox.y} ${currentViewBox.width} ${currentViewBox.height}`
297
297
  );
298
298
  });
299
- //# sourceMappingURL=ZoomPan-RR7KUYZT.js.map
299
+ //# sourceMappingURL=ZoomPan-AEKWKUCH.js.map
@@ -5,8 +5,8 @@ import {
5
5
  handleMouseMove,
6
6
  handleMouseUp,
7
7
  updateAttachedArrows
8
- } from "./chunk-X5ENBMGL.js";
9
- import "./chunk-VZX55VQL.js";
8
+ } from "./chunk-2U47AU6Y.js";
9
+ import "./chunk-TFCBCWL5.js";
10
10
  export {
11
11
  cleanupAttachments,
12
12
  handleMouseDown as handleMouseDownArrow,
@@ -14,4 +14,4 @@ export {
14
14
  handleMouseUp as handleMouseUpArrow,
15
15
  updateAttachedArrows
16
16
  };
17
- //# sourceMappingURL=arrowTool-DO327FKU.js.map
17
+ //# sourceMappingURL=arrowTool-C4RDWQEX.js.map
@@ -5,7 +5,7 @@ import {
5
5
  pushFrameAttachmentAction,
6
6
  pushOptionsChangeAction,
7
7
  pushTransformAction
8
- } from "./chunk-VZX55VQL.js";
8
+ } from "./chunk-TFCBCWL5.js";
9
9
 
10
10
  // src/core/SnapGuides.js
11
11
  var SNAP_THRESHOLD = 6;
@@ -230,7 +230,7 @@ function clearSnapGuides() {
230
230
  // src/tools/arrowTool.js
231
231
  function getThemeStroke() {
232
232
  if (typeof document === "undefined") return "#fff";
233
- return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#1a1a2e";
233
+ return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#000000";
234
234
  }
235
235
  var currentArrow = null;
236
236
  var isResizing = false;
@@ -744,4 +744,4 @@ export {
744
744
  updateAttachedArrows,
745
745
  cleanupAttachments
746
746
  };
747
- //# sourceMappingURL=chunk-X5ENBMGL.js.map
747
+ //# sourceMappingURL=chunk-2U47AU6Y.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/SnapGuides.js", "../../src/tools/arrowTool.js"],
4
- "sourcesContent": ["/**\n * SnapGuides - Shows thin red alignment guides when moving shapes\n * to help users align shapes with each other and the viewport.\n */\n\nconst SNAP_THRESHOLD = 6; // pixels \u2014 how close before snapping\nconst BREAK_THRESHOLD = 12; // pixels \u2014 how far mouse must move to break free\nconst GUIDE_COLOR = '#ff4444';\nconst GUIDE_WIDTH = 1;\n\nlet guideLayer = null;\n\n// Track active snaps so we can implement break-out\nlet activeSnapX = null; // { guideValue, mouseAtSnap }\nlet activeSnapY = null;\n\nfunction ensureGuideLayer() {\n if (guideLayer && guideLayer.parentNode) return guideLayer;\n const svg = window.svg;\n if (!svg) return null;\n\n guideLayer = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n guideLayer.setAttribute('id', 'snap-guides');\n guideLayer.setAttribute('pointer-events', 'none');\n svg.appendChild(guideLayer);\n return guideLayer;\n}\n\nfunction clearGuides() {\n if (guideLayer) {\n while (guideLayer.firstChild) guideLayer.removeChild(guideLayer.firstChild);\n }\n}\n\nfunction drawGuide(x1, y1, x2, y2) {\n const layer = ensureGuideLayer();\n if (!layer) return;\n\n const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n line.setAttribute('x1', x1);\n line.setAttribute('y1', y1);\n line.setAttribute('x2', x2);\n line.setAttribute('y2', y2);\n line.setAttribute('stroke', GUIDE_COLOR);\n line.setAttribute('stroke-width', GUIDE_WIDTH);\n line.setAttribute('stroke-dasharray', '4 2');\n layer.appendChild(line);\n}\n\n/**\n * Get the bounding box of a shape in canvas coordinates\n */\nfunction getShapeBounds(shape) {\n if (!shape) return null;\n\n const name = shape.shapeName;\n if (name === 'rectangle' || name === 'frame') {\n return {\n left: shape.x,\n top: shape.y,\n right: shape.x + shape.width,\n bottom: shape.y + shape.height,\n cx: shape.x + shape.width / 2,\n cy: shape.y + shape.height / 2,\n };\n }\n if (name === 'circle') {\n return {\n left: shape.x - shape.rx,\n top: shape.y - shape.ry,\n right: shape.x + shape.rx,\n bottom: shape.y + shape.ry,\n cx: shape.x,\n cy: shape.y,\n };\n }\n if (name === 'text' || name === 'code' || name === 'image' || name === 'icon') {\n const el = shape.group || shape.element;\n if (!el) return null;\n const bbox = el.getBBox();\n return {\n left: bbox.x,\n top: bbox.y,\n right: bbox.x + bbox.width,\n bottom: bbox.y + bbox.height,\n cx: bbox.x + bbox.width / 2,\n cy: bbox.y + bbox.height / 2,\n };\n }\n if (name === 'line' || name === 'arrow') {\n const sx = shape.startPoint?.x ?? 0;\n const sy = shape.startPoint?.y ?? 0;\n const ex = shape.endPoint?.x ?? 0;\n const ey = shape.endPoint?.y ?? 0;\n return {\n left: Math.min(sx, ex),\n top: Math.min(sy, ey),\n right: Math.max(sx, ex),\n bottom: Math.max(sy, ey),\n cx: (sx + ex) / 2,\n cy: (sy + ey) / 2,\n };\n }\n return null;\n}\n\n/**\n * Get the canvas viewport reference points for global alignment.\n */\nfunction getCanvasGuides() {\n const vb = window.currentViewBox;\n if (!vb) return [];\n\n return [\n { // Viewport center\n left: vb.x + vb.width / 2,\n top: vb.y + vb.height / 2,\n right: vb.x + vb.width / 2,\n bottom: vb.y + vb.height / 2,\n cx: vb.x + vb.width / 2,\n cy: vb.y + vb.height / 2,\n },\n { // Viewport edges\n left: vb.x,\n top: vb.y,\n right: vb.x + vb.width,\n bottom: vb.y + vb.height,\n cx: vb.x + vb.width / 2,\n cy: vb.y + vb.height / 2,\n },\n ];\n}\n\n/**\n * Calculate snap offsets and draw guides.\n * Returns { dx, dy } snap offset to apply.\n *\n * Uses a break-out system: once snapped, the shape stays on the guide\n * until the mouse moves BREAK_THRESHOLD away, then it breaks free.\n */\nexport function calculateSnap(movingShape, shiftKey = false, mouseX, mouseY) {\n clearGuides();\n\n const shapes = window.shapes;\n if (!shapes || !movingShape) return { dx: 0, dy: 0 };\n\n const moving = getShapeBounds(movingShape);\n if (!moving) return { dx: 0, dy: 0 };\n\n // Check if we should break out of an active snap\n if (activeSnapX && mouseX !== undefined) {\n if (Math.abs(mouseX - activeSnapX.mouseAtSnap) > BREAK_THRESHOLD) {\n activeSnapX = null;\n }\n }\n if (activeSnapY && mouseY !== undefined) {\n if (Math.abs(mouseY - activeSnapY.mouseAtSnap) > BREAK_THRESHOLD) {\n activeSnapY = null;\n }\n }\n\n let snapX = null;\n let snapY = null;\n let bestDistX = SNAP_THRESHOLD;\n let bestDistY = SNAP_THRESHOLD;\n\n const movingXs = [moving.left, moving.cx, moving.right];\n const movingYs = [moving.top, moving.cy, moving.bottom];\n\n const vb = window.currentViewBox;\n const extendY1 = vb ? vb.y : 0;\n const extendY2 = vb ? vb.y + vb.height : 10000;\n const extendX1 = vb ? vb.x : 0;\n const extendX2 = vb ? vb.x + vb.width : 10000;\n\n let otherShapeCount = 0;\n\n for (const shape of shapes) {\n if (shape === movingShape) continue;\n if (window.multiSelection && window.multiSelection.selectedShapes?.has(shape)) continue;\n\n const other = getShapeBounds(shape);\n if (!other) continue;\n otherShapeCount++;\n\n const otherXs = [other.left, other.cx, other.right];\n const otherYs = [other.top, other.cy, other.bottom];\n\n for (const mx of movingXs) {\n for (const ox of otherXs) {\n const dist = Math.abs(mx - ox);\n if (dist < bestDistX) {\n bestDistX = dist;\n snapX = { offset: ox - mx, x: ox, extendY1, extendY2 };\n }\n }\n }\n\n for (const my of movingYs) {\n for (const oy of otherYs) {\n const dist = Math.abs(my - oy);\n if (dist < bestDistY) {\n bestDistY = dist;\n snapY = { offset: oy - my, y: oy, extendX1, extendX2 };\n }\n }\n }\n }\n\n // Viewport guides when alone, no snap found, or shift held\n if (shiftKey || otherShapeCount === 0 || (!snapX && !snapY)) {\n const canvasGuides = getCanvasGuides();\n for (const guide of canvasGuides) {\n const guideXs = [guide.left, guide.cx, guide.right];\n const guideYs = [guide.top, guide.cy, guide.bottom];\n\n for (const mx of movingXs) {\n for (const gx of guideXs) {\n const dist = Math.abs(mx - gx);\n if (dist < bestDistX) {\n bestDistX = dist;\n snapX = { offset: gx - mx, x: gx, extendY1, extendY2 };\n }\n }\n }\n for (const my of movingYs) {\n for (const gy of guideYs) {\n const dist = Math.abs(my - gy);\n if (dist < bestDistY) {\n bestDistY = dist;\n snapY = { offset: gy - my, y: gy, extendX1, extendX2 };\n }\n }\n }\n }\n }\n\n let dx = 0;\n let dy = 0;\n\n // Apply X snap only if not broken out of a previous X snap\n if (snapX && !activeSnapX) {\n dx = snapX.offset;\n drawGuide(snapX.x, snapX.extendY1, snapX.x, snapX.extendY2);\n if (mouseX !== undefined) {\n activeSnapX = { guideValue: snapX.x, mouseAtSnap: mouseX };\n }\n } else if (activeSnapX) {\n // Still in an active snap \u2014 hold position by drawing guide but no offset\n drawGuide(activeSnapX.guideValue, extendY1, activeSnapX.guideValue, extendY2);\n }\n\n if (snapY && !activeSnapY) {\n dy = snapY.offset;\n drawGuide(snapY.extendX1, snapY.y, snapY.extendX2, snapY.y);\n if (mouseY !== undefined) {\n activeSnapY = { guideValue: snapY.y, mouseAtSnap: mouseY };\n }\n } else if (activeSnapY) {\n drawGuide(extendX1, activeSnapY.guideValue, extendX2, activeSnapY.guideValue);\n }\n\n return { dx, dy };\n}\n\n/**\n * Clear all snap guides and reset snap state. Call on mouseUp.\n */\nexport function clearSnapGuides() {\n clearGuides();\n activeSnapX = null;\n activeSnapY = null;\n}\n", "/* eslint-disable */\n// Arrow tool event handlers - extracted from drawArrow.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#1a1a2e\"; }\n\nlet arrowStartX, arrowStartY;\nlet currentArrow = null;\nlet isResizing = false;\nlet isDragging = false;\nlet activeAnchor = null;\nlet isDrawingArrow = false;\nlet arrowStrokeColor = null;\nlet arrowStrokeThickness = 2;\nlet arrowOutlineStyle = \"solid\";\nlet arrowCurved = \"straight\";\nlet arrowCurveAmount = 20;\nlet arrowHeadLength = 10;\nlet arrowHeadAngleDeg = 30;\nlet arrowHeadStyle = \"default\";\nlet startX, startY;\nlet dragOldPosArrow = null;\nlet draggedShapeInitialFrameArrow = null;\nlet hoveredFrameArrow = null;\nlet arrowStrokeColorOptions = document.querySelectorAll(\".arrowStrokeSpan\");\nlet arrowStrokeThicknessValue = document.querySelectorAll(\".arrowStrokeThickSpan\");\nlet arrowOutlineStyleValue = document.querySelectorAll(\".arrowOutlineStyle\");\nlet arrowTypeStyleValue = document.querySelectorAll(\".arrowTypeStyle\");\nlet arrowHeadStyleValue = document.querySelectorAll(\".arrowHeadStyleSpan\");\nlet arrowCurveAmountOptions = document.querySelectorAll(\".arrowCurveSpan\");\n\n\nfunction getSVGCoordsFromMouse(e) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n const svgX = viewBox.x + (mouseX / rect.width) * viewBox.width;\n const svgY = viewBox.y + (mouseY / rect.height) * viewBox.height;\n return { x: svgX, y: svgY };\n}\n\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'arrow') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'arrow') {\n deleteCurrentShape();\n }\n});\n\n\nconst handleMouseDown = (e) => {\n if (!isArrowToolActive && !isSelectionToolActive) return;\n\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isArrowToolActive) {\n isDrawingArrow = true;\n currentArrow = new Arrow({ x, y }, { x, y }, {\n stroke: arrowStrokeColor ?? getThemeStroke(),\n strokeWidth: arrowStrokeThickness,\n arrowOutlineStyle: arrowOutlineStyle,\n arrowHeadStyle: arrowHeadStyle,\n arrowCurved: arrowCurved,\n arrowCurveAmount: arrowCurveAmount\n });\n shapes.push(currentArrow);\n currentShape = currentArrow;\n } else if (isSelectionToolActive) {\n let clickedOnShape = false;\n let clickedOnAnchor = false;\n\n if (currentShape && currentShape.shapeName === 'arrow' && currentShape.isSelected) {\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo && anchorInfo.type === 'anchor') {\n clickedOnAnchor = true;\n clickedOnShape = true;\n } \n if (currentShape.contains(x, y)) {\n isDragging = true;\n dragOldPosArrow = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint1: currentShape.controlPoint1 ? { x: currentShape.controlPoint1.x, y: currentShape.controlPoint1.y } : null,\n controlPoint2: currentShape.controlPoint2 ? { x: currentShape.controlPoint2.x, y: currentShape.controlPoint2.y } : null,\n parentFrame: currentShape.parentFrame // Add this line\n };\n \n // Store initial frame state\n draggedShapeInitialFrameArrow = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape) {\n let shapeToSelect = null;\n\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof Arrow && shape.contains(x, y)) {\n shapeToSelect = shape;\n break;\n }\n }\n\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.removeSelection();\n currentShape = null;\n }\n\n if (shapeToSelect) {\n currentShape = shapeToSelect;\n currentShape.selectArrow();\n\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo && anchorInfo.type === 'anchor') {\n clickedOnAnchor = true;\n } else {\n isDragging = true;\n dragOldPosArrow = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint1: currentShape.controlPoint1 ? { x: currentShape.controlPoint1.x, y: currentShape.controlPoint1.y } : null,\n controlPoint2: currentShape.controlPoint2 ? { x: currentShape.controlPoint2.x, y: currentShape.controlPoint2.y } : null\n };\n startX = x;\n startY = y;\n }\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape && !clickedOnAnchor && currentShape) {\n currentShape.removeSelection();\n currentShape = null;\n }\n }\n};\n\n// Enhanced mouse move with better cursor feedback\nconst handleMouseMove = (e) => {\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isDrawingArrow && currentArrow) {\n let endX = x, endY = y;\n if (e.shiftKey) {\n const dx = x - currentArrow.startPoint.x;\n const dy = y - currentArrow.startPoint.y;\n const angle = Math.atan2(dy, dx);\n const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);\n const dist = Math.sqrt(dx * dx + dy * dy);\n endX = currentArrow.startPoint.x + dist * Math.cos(snapAngle);\n endY = currentArrow.startPoint.y + dist * Math.sin(snapAngle);\n }\n currentArrow.endPoint = { x: endX, y: endY };\n\n // Check for potential attachment and show preview\n const nearbyShape = Arrow.findNearbyShape({ x: endX, y: endY });\n if (nearbyShape) {\n // Snap to attachment point\n currentArrow.endPoint = nearbyShape.attachment.point;\n svg.style.cursor = 'crosshair';\n\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n const preview = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n preview.setAttribute(\"cx\", nearbyShape.attachment.point.x);\n preview.setAttribute(\"cy\", nearbyShape.attachment.point.y);\n preview.setAttribute(\"r\", 6);\n preview.setAttribute(\"fill\", \"none\");\n preview.setAttribute(\"stroke\", \"#5B57D1\");\n preview.setAttribute(\"stroke-width\", 2);\n preview.setAttribute(\"class\", \"attachment-preview\");\n preview.setAttribute(\"opacity\", \"0.7\");\n svg.appendChild(preview);\n } else {\n // Remove preview if no nearby shape\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n }\n\n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentArrow)) {\n frame.highlightFrame();\n hoveredFrameArrow = frame;\n } else if (hoveredFrameArrow === frame) {\n frame.removeHighlight();\n hoveredFrameArrow = null;\n }\n }\n });\n\n // Update control points for curved arrows during drawing\n if (currentArrow.arrowCurved) {\n currentArrow.initializeCurveControlPoints();\n }\n currentArrow.draw();\n }\n\n else if (isDragging && currentShape && currentShape.isSelected) {\n const dx = x - startX;\n const dy = y - startY;\n currentShape.move(dx, dy);\n startX = x;\n startY = y;\n\n // Issue #24 bug #4: track containing frame during drag of an\n // existing arrow so mouseUp re-parents correctly. Without this\n // hoveredFrameArrow stays null and the arrow is detached the\n // moment the user nudges it inside its own parent frame.\n let newHover = null;\n for (const f of shapes) {\n if (f.shapeName !== 'frame') continue;\n if (f === currentShape) continue;\n if (typeof f.isShapeInFrame === 'function' && f.isShapeInFrame(currentShape)) {\n newHover = f;\n break;\n }\n }\n if (hoveredFrameArrow && hoveredFrameArrow !== newHover && typeof hoveredFrameArrow.removeHighlight === 'function') {\n hoveredFrameArrow.removeHighlight();\n }\n if (newHover && newHover !== hoveredFrameArrow && typeof newHover.highlightFrame === 'function') {\n newHover.highlightFrame();\n }\n hoveredFrameArrow = newHover;\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n\n svg.style.cursor = 'grabbing';\n } else if (isSelectionToolActive && currentShape && currentShape.isSelected) {\n // Provide visual feedback when hovering over anchors or the arrow\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo) {\n svg.style.cursor = 'grab';\n } else if (currentShape.contains(x, y)) {\n svg.style.cursor = 'move';\n } else {\n svg.style.cursor = 'default';\n }\n } else if (isSelectionToolActive) {\n // Check if hovering over any selectable arrow\n let hoveringOverArrow = false;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof Arrow && shape.contains(x, y)) {\n hoveringOverArrow = true;\n break;\n }\n }\n svg.style.cursor = hoveringOverArrow ? 'pointer' : 'default';\n }\n};\n\nconst handleMouseUp = (e) => {\nif (isDrawingArrow && currentArrow) {\n // Remove any attachment preview that might still be visible\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n // Check if arrow is too small\n const dx = currentArrow.endPoint.x - currentArrow.startPoint.x;\n const dy = currentArrow.endPoint.y - currentArrow.startPoint.y;\n const lengthSq = dx * dx + dy * dy;\n\n if (lengthSq < (5 / currentZoom) ** 2) {\n shapes.pop();\n if (currentArrow.group.parentNode) {\n currentArrow.group.parentNode.removeChild(currentArrow.group);\n }\n currentArrow = null;\n currentShape = null;\n } else {\n const startAttachment = Arrow.findNearbyShape(currentArrow.startPoint);\n const endAttachment = Arrow.findNearbyShape(currentArrow.endPoint);\n\n if (startAttachment) {\n currentArrow.attachToShape(true, startAttachment.shape, startAttachment.attachment);\n }\n\n if (endAttachment) {\n currentArrow.attachToShape(false, endAttachment.shape, endAttachment.attachment);\n }\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameArrow;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentArrow);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentArrow, 'attach', null);\n }\n\n // Push create action for undo/redo\n pushCreateAction(currentArrow);\n\n // Auto-select the drawn arrow and switch to selection tool\n const drawnArrow = currentArrow;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnArrow;\n drawnArrow.selectArrow();\n }\n\n // Clear frame highlighting\n if (hoveredFrameArrow) {\n hoveredFrameArrow.removeHighlight();\n hoveredFrameArrow = null;\n }\n\n currentArrow = null;\n}\n\nif (isDragging && dragOldPosArrow && currentShape) {\n // Issue #34 bug #2: containment transfer happens later in this block,\n // so currentShape.parentFrame is still the OLD frame here. hoveredFrameArrow\n // tracks the actual destination during mousemove \u2014 use that as the truth.\n const newPos = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n parentFrame: hoveredFrameArrow || null,\n };\n const oldPos = {\n ...dragOldPosArrow,\n parentFrame: draggedShapeInitialFrameArrow // Add this line\n };\n \n const stateChanged = dragOldPosArrow.startPoint.x !== newPos.startPoint.x ||\n dragOldPosArrow.startPoint.y !== newPos.startPoint.y ||\n dragOldPosArrow.endPoint.x !== newPos.endPoint.x ||\n dragOldPosArrow.endPoint.y !== newPos.endPoint.y;\n \n const frameChanged = oldPos.parentFrame !== newPos.parentFrame;\n\n if (stateChanged || frameChanged) {\n pushTransformAction(currentShape, oldPos, newPos);\n }\n \n // Handle frame containment changes after drag\n if (isDragging) {\n const finalFrame = hoveredFrameArrow;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameArrow !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameArrow) {\n draggedShapeInitialFrameArrow.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameArrow, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameArrow);\n }\n } else if (draggedShapeInitialFrameArrow) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameArrow.restoreToFrame(currentShape);\n }\n }\n \n draggedShapeInitialFrameArrow = null;\n dragOldPosArrow = null;\n}\n\n// Clear frame highlighting\nif (hoveredFrameArrow) {\n hoveredFrameArrow.removeHighlight();\n hoveredFrameArrow = null;\n}\n\nclearSnapGuides();\nisDrawingArrow = false;\nisResizing = false;\nisDragging = false;\nactiveAnchor = null;\nsvg.style.cursor = 'default';\n};\n\n// Remove old event listeners and add new ones\nsvg.removeEventListener('pointerdown', handleMouseDown);\nsvg.removeEventListener('pointermove', handleMouseMove);\nsvg.removeEventListener('pointerup', handleMouseUp);\n\n\n// Updated style handlers with undo/redo support\nconst updateSelectedArrowStyle = (styleChanges) => {\n if (currentShape instanceof Arrow && currentShape.isSelected) {\n const oldOptions = {\n ...currentShape.options,\n arrowOutlineStyle: currentShape.arrowOutlineStyle,\n arrowHeadStyle: currentShape.arrowHeadStyle,\n arrowCurved: currentShape.arrowCurved,\n arrowCurveAmount: currentShape.arrowCurveAmount\n };\n currentShape.updateStyle(styleChanges);\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n if (styleChanges.stroke !== undefined) arrowStrokeColor = styleChanges.stroke;\n if (styleChanges.strokeWidth !== undefined) arrowStrokeThickness = styleChanges.strokeWidth;\n if (styleChanges.arrowOutlineStyle !== undefined) arrowOutlineStyle = styleChanges.arrowOutlineStyle;\n if (styleChanges.arrowHeadStyle !== undefined) arrowHeadStyle = styleChanges.arrowHeadStyle;\n if (styleChanges.arrowCurved !== undefined) arrowCurved = styleChanges.arrowCurved;\n if (styleChanges.arrowCurveAmount !== undefined) arrowCurveAmount = styleChanges.arrowCurveAmount;\n }\n};\n\narrowStrokeColorOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowStrokeColorOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newColor = span.getAttribute(\"data-id\");\n updateSelectedArrowStyle({ stroke: newColor });\n });\n});\n\narrowStrokeThicknessValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowStrokeThicknessValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newThickness = parseInt(span.getAttribute(\"data-id\"));\n updateSelectedArrowStyle({ strokeWidth: newThickness });\n });\n});\n\narrowOutlineStyleValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowOutlineStyleValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newStyle = span.getAttribute(\"data-id\");\n updateSelectedArrowStyle({ arrowOutlineStyle: newStyle });\n });\n});\n\narrowTypeStyleValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowTypeStyleValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n updateSelectedArrowStyle({ arrowCurved: span.getAttribute(\"data-id\") });\n });\n});\n\narrowCurveAmountOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowCurveAmountOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n updateSelectedArrowStyle({ arrowCurveAmount: parseInt(span.getAttribute(\"data-id\")) });\n });\n});\n\narrowHeadStyleValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowHeadStyleValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newHeadStyle = span.getAttribute(\"data-id\");\n updateSelectedArrowStyle({ arrowHeadStyle: newHeadStyle });\n });\n});\n\nfunction detachSelectedArrow() {\n if (currentShape instanceof Arrow && currentShape.isSelected) {\n if (currentShape.attachedToStart || currentShape.attachedToEnd) {\n const oldState = {\n attachedToStart: currentShape.attachedToStart,\n attachedToEnd: currentShape.attachedToEnd,\n startPoint: { ...currentShape.startPoint },\n endPoint: { ...currentShape.endPoint }\n };\n\n currentShape.detachFromShape(true);\n currentShape.detachFromShape(false);\n currentShape.draw();\n\n // Add to undo/redo if needed\n }\n }\n}\n\nfunction updateAttachedArrows(shape) {\n if (!shape) return;\n\n // If a DOM element was passed (e.g. from text/code/image move), find the wrapper\n let targetShape = shape;\n if (shape.nodeType) {\n targetShape = shapes.find(s => s.group === shape || s.element === shape) || shape;\n }\n\n shapes.forEach(arrowShape => {\n if (arrowShape instanceof Arrow) {\n let needsUpdate = false;\n if (arrowShape.attachedToStart && arrowShape.attachedToStart.shape === targetShape) {\n needsUpdate = true;\n }\n if (arrowShape.attachedToEnd && arrowShape.attachedToEnd.shape === targetShape) {\n needsUpdate = true;\n }\n\n if (needsUpdate) {\n arrowShape.updateAttachments();\n }\n }\n });\n}\n\nfunction cleanupAttachments(deletedShape) {\n if (!deletedShape) return;\n\n // If a DOM element was passed, find the wrapper\n let targetShape = deletedShape;\n if (deletedShape.nodeType) {\n targetShape = shapes.find(s => s.group === deletedShape || s.element === deletedShape) || deletedShape;\n }\n\n shapes.forEach(shape => {\n if (shape instanceof Arrow) {\n let needsDraw = false;\n if (shape.attachedToStart && shape.attachedToStart.shape === targetShape) {\n shape.detachFromShape(true);\n needsDraw = true;\n }\n if (shape.attachedToEnd && shape.attachedToEnd.shape === targetShape) {\n shape.detachFromShape(false);\n needsDraw = true;\n }\n if (needsDraw) {\n shape.draw();\n }\n }\n });\n}\n\n// Add keyboard shortcut to detach arrows\ndocument.addEventListener('keydown', (e) => {\n if (e.key.toLowerCase() === 'd' && e.ctrlKey) {\n e.preventDefault();\n detachSelectedArrow();\n }\n});\n\n// Expose arrow tool settings on window for React sidebar bridge\nwindow.arrowToolSettings = {\n get strokeColor() { return arrowStrokeColor; },\n set strokeColor(v) { arrowStrokeColor = v; },\n get strokeWidth() { return arrowStrokeThickness; },\n set strokeWidth(v) { arrowStrokeThickness = v; },\n get outlineStyle() { return arrowOutlineStyle; },\n set outlineStyle(v) { arrowOutlineStyle = v; },\n get headStyle() { return arrowHeadStyle; },\n set headStyle(v) { arrowHeadStyle = v; },\n get arrowCurved() { return arrowCurved; },\n set arrowCurved(v) { arrowCurved = v; },\n get curveAmount() { return arrowCurveAmount; },\n set curveAmount(v) { arrowCurveAmount = v; },\n};\nwindow.updateSelectedArrowStyle = updateSelectedArrowStyle;\n\n// Export the cleanup function\n// Expose cleanupAttachments globally for centralized delete\nwindow.cleanupAttachments = cleanupAttachments;\n\nexport {\n handleMouseDown as handleMouseDownArrow,\n handleMouseMove as handleMouseMoveArrow,\n handleMouseUp as handleMouseUpArrow,\n cleanupAttachments,\n updateAttachedArrows\n};\n"],
4
+ "sourcesContent": ["/**\n * SnapGuides - Shows thin red alignment guides when moving shapes\n * to help users align shapes with each other and the viewport.\n */\n\nconst SNAP_THRESHOLD = 6; // pixels \u2014 how close before snapping\nconst BREAK_THRESHOLD = 12; // pixels \u2014 how far mouse must move to break free\nconst GUIDE_COLOR = '#ff4444';\nconst GUIDE_WIDTH = 1;\n\nlet guideLayer = null;\n\n// Track active snaps so we can implement break-out\nlet activeSnapX = null; // { guideValue, mouseAtSnap }\nlet activeSnapY = null;\n\nfunction ensureGuideLayer() {\n if (guideLayer && guideLayer.parentNode) return guideLayer;\n const svg = window.svg;\n if (!svg) return null;\n\n guideLayer = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n guideLayer.setAttribute('id', 'snap-guides');\n guideLayer.setAttribute('pointer-events', 'none');\n svg.appendChild(guideLayer);\n return guideLayer;\n}\n\nfunction clearGuides() {\n if (guideLayer) {\n while (guideLayer.firstChild) guideLayer.removeChild(guideLayer.firstChild);\n }\n}\n\nfunction drawGuide(x1, y1, x2, y2) {\n const layer = ensureGuideLayer();\n if (!layer) return;\n\n const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n line.setAttribute('x1', x1);\n line.setAttribute('y1', y1);\n line.setAttribute('x2', x2);\n line.setAttribute('y2', y2);\n line.setAttribute('stroke', GUIDE_COLOR);\n line.setAttribute('stroke-width', GUIDE_WIDTH);\n line.setAttribute('stroke-dasharray', '4 2');\n layer.appendChild(line);\n}\n\n/**\n * Get the bounding box of a shape in canvas coordinates\n */\nfunction getShapeBounds(shape) {\n if (!shape) return null;\n\n const name = shape.shapeName;\n if (name === 'rectangle' || name === 'frame') {\n return {\n left: shape.x,\n top: shape.y,\n right: shape.x + shape.width,\n bottom: shape.y + shape.height,\n cx: shape.x + shape.width / 2,\n cy: shape.y + shape.height / 2,\n };\n }\n if (name === 'circle') {\n return {\n left: shape.x - shape.rx,\n top: shape.y - shape.ry,\n right: shape.x + shape.rx,\n bottom: shape.y + shape.ry,\n cx: shape.x,\n cy: shape.y,\n };\n }\n if (name === 'text' || name === 'code' || name === 'image' || name === 'icon') {\n const el = shape.group || shape.element;\n if (!el) return null;\n const bbox = el.getBBox();\n return {\n left: bbox.x,\n top: bbox.y,\n right: bbox.x + bbox.width,\n bottom: bbox.y + bbox.height,\n cx: bbox.x + bbox.width / 2,\n cy: bbox.y + bbox.height / 2,\n };\n }\n if (name === 'line' || name === 'arrow') {\n const sx = shape.startPoint?.x ?? 0;\n const sy = shape.startPoint?.y ?? 0;\n const ex = shape.endPoint?.x ?? 0;\n const ey = shape.endPoint?.y ?? 0;\n return {\n left: Math.min(sx, ex),\n top: Math.min(sy, ey),\n right: Math.max(sx, ex),\n bottom: Math.max(sy, ey),\n cx: (sx + ex) / 2,\n cy: (sy + ey) / 2,\n };\n }\n return null;\n}\n\n/**\n * Get the canvas viewport reference points for global alignment.\n */\nfunction getCanvasGuides() {\n const vb = window.currentViewBox;\n if (!vb) return [];\n\n return [\n { // Viewport center\n left: vb.x + vb.width / 2,\n top: vb.y + vb.height / 2,\n right: vb.x + vb.width / 2,\n bottom: vb.y + vb.height / 2,\n cx: vb.x + vb.width / 2,\n cy: vb.y + vb.height / 2,\n },\n { // Viewport edges\n left: vb.x,\n top: vb.y,\n right: vb.x + vb.width,\n bottom: vb.y + vb.height,\n cx: vb.x + vb.width / 2,\n cy: vb.y + vb.height / 2,\n },\n ];\n}\n\n/**\n * Calculate snap offsets and draw guides.\n * Returns { dx, dy } snap offset to apply.\n *\n * Uses a break-out system: once snapped, the shape stays on the guide\n * until the mouse moves BREAK_THRESHOLD away, then it breaks free.\n */\nexport function calculateSnap(movingShape, shiftKey = false, mouseX, mouseY) {\n clearGuides();\n\n const shapes = window.shapes;\n if (!shapes || !movingShape) return { dx: 0, dy: 0 };\n\n const moving = getShapeBounds(movingShape);\n if (!moving) return { dx: 0, dy: 0 };\n\n // Check if we should break out of an active snap\n if (activeSnapX && mouseX !== undefined) {\n if (Math.abs(mouseX - activeSnapX.mouseAtSnap) > BREAK_THRESHOLD) {\n activeSnapX = null;\n }\n }\n if (activeSnapY && mouseY !== undefined) {\n if (Math.abs(mouseY - activeSnapY.mouseAtSnap) > BREAK_THRESHOLD) {\n activeSnapY = null;\n }\n }\n\n let snapX = null;\n let snapY = null;\n let bestDistX = SNAP_THRESHOLD;\n let bestDistY = SNAP_THRESHOLD;\n\n const movingXs = [moving.left, moving.cx, moving.right];\n const movingYs = [moving.top, moving.cy, moving.bottom];\n\n const vb = window.currentViewBox;\n const extendY1 = vb ? vb.y : 0;\n const extendY2 = vb ? vb.y + vb.height : 10000;\n const extendX1 = vb ? vb.x : 0;\n const extendX2 = vb ? vb.x + vb.width : 10000;\n\n let otherShapeCount = 0;\n\n for (const shape of shapes) {\n if (shape === movingShape) continue;\n if (window.multiSelection && window.multiSelection.selectedShapes?.has(shape)) continue;\n\n const other = getShapeBounds(shape);\n if (!other) continue;\n otherShapeCount++;\n\n const otherXs = [other.left, other.cx, other.right];\n const otherYs = [other.top, other.cy, other.bottom];\n\n for (const mx of movingXs) {\n for (const ox of otherXs) {\n const dist = Math.abs(mx - ox);\n if (dist < bestDistX) {\n bestDistX = dist;\n snapX = { offset: ox - mx, x: ox, extendY1, extendY2 };\n }\n }\n }\n\n for (const my of movingYs) {\n for (const oy of otherYs) {\n const dist = Math.abs(my - oy);\n if (dist < bestDistY) {\n bestDistY = dist;\n snapY = { offset: oy - my, y: oy, extendX1, extendX2 };\n }\n }\n }\n }\n\n // Viewport guides when alone, no snap found, or shift held\n if (shiftKey || otherShapeCount === 0 || (!snapX && !snapY)) {\n const canvasGuides = getCanvasGuides();\n for (const guide of canvasGuides) {\n const guideXs = [guide.left, guide.cx, guide.right];\n const guideYs = [guide.top, guide.cy, guide.bottom];\n\n for (const mx of movingXs) {\n for (const gx of guideXs) {\n const dist = Math.abs(mx - gx);\n if (dist < bestDistX) {\n bestDistX = dist;\n snapX = { offset: gx - mx, x: gx, extendY1, extendY2 };\n }\n }\n }\n for (const my of movingYs) {\n for (const gy of guideYs) {\n const dist = Math.abs(my - gy);\n if (dist < bestDistY) {\n bestDistY = dist;\n snapY = { offset: gy - my, y: gy, extendX1, extendX2 };\n }\n }\n }\n }\n }\n\n let dx = 0;\n let dy = 0;\n\n // Apply X snap only if not broken out of a previous X snap\n if (snapX && !activeSnapX) {\n dx = snapX.offset;\n drawGuide(snapX.x, snapX.extendY1, snapX.x, snapX.extendY2);\n if (mouseX !== undefined) {\n activeSnapX = { guideValue: snapX.x, mouseAtSnap: mouseX };\n }\n } else if (activeSnapX) {\n // Still in an active snap \u2014 hold position by drawing guide but no offset\n drawGuide(activeSnapX.guideValue, extendY1, activeSnapX.guideValue, extendY2);\n }\n\n if (snapY && !activeSnapY) {\n dy = snapY.offset;\n drawGuide(snapY.extendX1, snapY.y, snapY.extendX2, snapY.y);\n if (mouseY !== undefined) {\n activeSnapY = { guideValue: snapY.y, mouseAtSnap: mouseY };\n }\n } else if (activeSnapY) {\n drawGuide(extendX1, activeSnapY.guideValue, extendX2, activeSnapY.guideValue);\n }\n\n return { dx, dy };\n}\n\n/**\n * Clear all snap guides and reset snap state. Call on mouseUp.\n */\nexport function clearSnapGuides() {\n clearGuides();\n activeSnapX = null;\n activeSnapY = null;\n}\n", "/* eslint-disable */\n// Arrow tool event handlers - extracted from drawArrow.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#000000\"; }\n\nlet arrowStartX, arrowStartY;\nlet currentArrow = null;\nlet isResizing = false;\nlet isDragging = false;\nlet activeAnchor = null;\nlet isDrawingArrow = false;\nlet arrowStrokeColor = null;\nlet arrowStrokeThickness = 2;\nlet arrowOutlineStyle = \"solid\";\nlet arrowCurved = \"straight\";\nlet arrowCurveAmount = 20;\nlet arrowHeadLength = 10;\nlet arrowHeadAngleDeg = 30;\nlet arrowHeadStyle = \"default\";\nlet startX, startY;\nlet dragOldPosArrow = null;\nlet draggedShapeInitialFrameArrow = null;\nlet hoveredFrameArrow = null;\nlet arrowStrokeColorOptions = document.querySelectorAll(\".arrowStrokeSpan\");\nlet arrowStrokeThicknessValue = document.querySelectorAll(\".arrowStrokeThickSpan\");\nlet arrowOutlineStyleValue = document.querySelectorAll(\".arrowOutlineStyle\");\nlet arrowTypeStyleValue = document.querySelectorAll(\".arrowTypeStyle\");\nlet arrowHeadStyleValue = document.querySelectorAll(\".arrowHeadStyleSpan\");\nlet arrowCurveAmountOptions = document.querySelectorAll(\".arrowCurveSpan\");\n\n\nfunction getSVGCoordsFromMouse(e) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n const svgX = viewBox.x + (mouseX / rect.width) * viewBox.width;\n const svgY = viewBox.y + (mouseY / rect.height) * viewBox.height;\n return { x: svgX, y: svgY };\n}\n\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'arrow') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'arrow') {\n deleteCurrentShape();\n }\n});\n\n\nconst handleMouseDown = (e) => {\n if (!isArrowToolActive && !isSelectionToolActive) return;\n\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isArrowToolActive) {\n isDrawingArrow = true;\n currentArrow = new Arrow({ x, y }, { x, y }, {\n stroke: arrowStrokeColor ?? getThemeStroke(),\n strokeWidth: arrowStrokeThickness,\n arrowOutlineStyle: arrowOutlineStyle,\n arrowHeadStyle: arrowHeadStyle,\n arrowCurved: arrowCurved,\n arrowCurveAmount: arrowCurveAmount\n });\n shapes.push(currentArrow);\n currentShape = currentArrow;\n } else if (isSelectionToolActive) {\n let clickedOnShape = false;\n let clickedOnAnchor = false;\n\n if (currentShape && currentShape.shapeName === 'arrow' && currentShape.isSelected) {\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo && anchorInfo.type === 'anchor') {\n clickedOnAnchor = true;\n clickedOnShape = true;\n } \n if (currentShape.contains(x, y)) {\n isDragging = true;\n dragOldPosArrow = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint1: currentShape.controlPoint1 ? { x: currentShape.controlPoint1.x, y: currentShape.controlPoint1.y } : null,\n controlPoint2: currentShape.controlPoint2 ? { x: currentShape.controlPoint2.x, y: currentShape.controlPoint2.y } : null,\n parentFrame: currentShape.parentFrame // Add this line\n };\n \n // Store initial frame state\n draggedShapeInitialFrameArrow = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape) {\n let shapeToSelect = null;\n\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof Arrow && shape.contains(x, y)) {\n shapeToSelect = shape;\n break;\n }\n }\n\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.removeSelection();\n currentShape = null;\n }\n\n if (shapeToSelect) {\n currentShape = shapeToSelect;\n currentShape.selectArrow();\n\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo && anchorInfo.type === 'anchor') {\n clickedOnAnchor = true;\n } else {\n isDragging = true;\n dragOldPosArrow = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint1: currentShape.controlPoint1 ? { x: currentShape.controlPoint1.x, y: currentShape.controlPoint1.y } : null,\n controlPoint2: currentShape.controlPoint2 ? { x: currentShape.controlPoint2.x, y: currentShape.controlPoint2.y } : null\n };\n startX = x;\n startY = y;\n }\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape && !clickedOnAnchor && currentShape) {\n currentShape.removeSelection();\n currentShape = null;\n }\n }\n};\n\n// Enhanced mouse move with better cursor feedback\nconst handleMouseMove = (e) => {\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isDrawingArrow && currentArrow) {\n let endX = x, endY = y;\n if (e.shiftKey) {\n const dx = x - currentArrow.startPoint.x;\n const dy = y - currentArrow.startPoint.y;\n const angle = Math.atan2(dy, dx);\n const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);\n const dist = Math.sqrt(dx * dx + dy * dy);\n endX = currentArrow.startPoint.x + dist * Math.cos(snapAngle);\n endY = currentArrow.startPoint.y + dist * Math.sin(snapAngle);\n }\n currentArrow.endPoint = { x: endX, y: endY };\n\n // Check for potential attachment and show preview\n const nearbyShape = Arrow.findNearbyShape({ x: endX, y: endY });\n if (nearbyShape) {\n // Snap to attachment point\n currentArrow.endPoint = nearbyShape.attachment.point;\n svg.style.cursor = 'crosshair';\n\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n const preview = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n preview.setAttribute(\"cx\", nearbyShape.attachment.point.x);\n preview.setAttribute(\"cy\", nearbyShape.attachment.point.y);\n preview.setAttribute(\"r\", 6);\n preview.setAttribute(\"fill\", \"none\");\n preview.setAttribute(\"stroke\", \"#5B57D1\");\n preview.setAttribute(\"stroke-width\", 2);\n preview.setAttribute(\"class\", \"attachment-preview\");\n preview.setAttribute(\"opacity\", \"0.7\");\n svg.appendChild(preview);\n } else {\n // Remove preview if no nearby shape\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n }\n\n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentArrow)) {\n frame.highlightFrame();\n hoveredFrameArrow = frame;\n } else if (hoveredFrameArrow === frame) {\n frame.removeHighlight();\n hoveredFrameArrow = null;\n }\n }\n });\n\n // Update control points for curved arrows during drawing\n if (currentArrow.arrowCurved) {\n currentArrow.initializeCurveControlPoints();\n }\n currentArrow.draw();\n }\n\n else if (isDragging && currentShape && currentShape.isSelected) {\n const dx = x - startX;\n const dy = y - startY;\n currentShape.move(dx, dy);\n startX = x;\n startY = y;\n\n // Issue #24 bug #4: track containing frame during drag of an\n // existing arrow so mouseUp re-parents correctly. Without this\n // hoveredFrameArrow stays null and the arrow is detached the\n // moment the user nudges it inside its own parent frame.\n let newHover = null;\n for (const f of shapes) {\n if (f.shapeName !== 'frame') continue;\n if (f === currentShape) continue;\n if (typeof f.isShapeInFrame === 'function' && f.isShapeInFrame(currentShape)) {\n newHover = f;\n break;\n }\n }\n if (hoveredFrameArrow && hoveredFrameArrow !== newHover && typeof hoveredFrameArrow.removeHighlight === 'function') {\n hoveredFrameArrow.removeHighlight();\n }\n if (newHover && newHover !== hoveredFrameArrow && typeof newHover.highlightFrame === 'function') {\n newHover.highlightFrame();\n }\n hoveredFrameArrow = newHover;\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n\n svg.style.cursor = 'grabbing';\n } else if (isSelectionToolActive && currentShape && currentShape.isSelected) {\n // Provide visual feedback when hovering over anchors or the arrow\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo) {\n svg.style.cursor = 'grab';\n } else if (currentShape.contains(x, y)) {\n svg.style.cursor = 'move';\n } else {\n svg.style.cursor = 'default';\n }\n } else if (isSelectionToolActive) {\n // Check if hovering over any selectable arrow\n let hoveringOverArrow = false;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof Arrow && shape.contains(x, y)) {\n hoveringOverArrow = true;\n break;\n }\n }\n svg.style.cursor = hoveringOverArrow ? 'pointer' : 'default';\n }\n};\n\nconst handleMouseUp = (e) => {\nif (isDrawingArrow && currentArrow) {\n // Remove any attachment preview that might still be visible\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n // Check if arrow is too small\n const dx = currentArrow.endPoint.x - currentArrow.startPoint.x;\n const dy = currentArrow.endPoint.y - currentArrow.startPoint.y;\n const lengthSq = dx * dx + dy * dy;\n\n if (lengthSq < (5 / currentZoom) ** 2) {\n shapes.pop();\n if (currentArrow.group.parentNode) {\n currentArrow.group.parentNode.removeChild(currentArrow.group);\n }\n currentArrow = null;\n currentShape = null;\n } else {\n const startAttachment = Arrow.findNearbyShape(currentArrow.startPoint);\n const endAttachment = Arrow.findNearbyShape(currentArrow.endPoint);\n\n if (startAttachment) {\n currentArrow.attachToShape(true, startAttachment.shape, startAttachment.attachment);\n }\n\n if (endAttachment) {\n currentArrow.attachToShape(false, endAttachment.shape, endAttachment.attachment);\n }\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameArrow;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentArrow);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentArrow, 'attach', null);\n }\n\n // Push create action for undo/redo\n pushCreateAction(currentArrow);\n\n // Auto-select the drawn arrow and switch to selection tool\n const drawnArrow = currentArrow;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnArrow;\n drawnArrow.selectArrow();\n }\n\n // Clear frame highlighting\n if (hoveredFrameArrow) {\n hoveredFrameArrow.removeHighlight();\n hoveredFrameArrow = null;\n }\n\n currentArrow = null;\n}\n\nif (isDragging && dragOldPosArrow && currentShape) {\n // Issue #34 bug #2: containment transfer happens later in this block,\n // so currentShape.parentFrame is still the OLD frame here. hoveredFrameArrow\n // tracks the actual destination during mousemove \u2014 use that as the truth.\n const newPos = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n parentFrame: hoveredFrameArrow || null,\n };\n const oldPos = {\n ...dragOldPosArrow,\n parentFrame: draggedShapeInitialFrameArrow // Add this line\n };\n \n const stateChanged = dragOldPosArrow.startPoint.x !== newPos.startPoint.x ||\n dragOldPosArrow.startPoint.y !== newPos.startPoint.y ||\n dragOldPosArrow.endPoint.x !== newPos.endPoint.x ||\n dragOldPosArrow.endPoint.y !== newPos.endPoint.y;\n \n const frameChanged = oldPos.parentFrame !== newPos.parentFrame;\n\n if (stateChanged || frameChanged) {\n pushTransformAction(currentShape, oldPos, newPos);\n }\n \n // Handle frame containment changes after drag\n if (isDragging) {\n const finalFrame = hoveredFrameArrow;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameArrow !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameArrow) {\n draggedShapeInitialFrameArrow.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameArrow, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameArrow);\n }\n } else if (draggedShapeInitialFrameArrow) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameArrow.restoreToFrame(currentShape);\n }\n }\n \n draggedShapeInitialFrameArrow = null;\n dragOldPosArrow = null;\n}\n\n// Clear frame highlighting\nif (hoveredFrameArrow) {\n hoveredFrameArrow.removeHighlight();\n hoveredFrameArrow = null;\n}\n\nclearSnapGuides();\nisDrawingArrow = false;\nisResizing = false;\nisDragging = false;\nactiveAnchor = null;\nsvg.style.cursor = 'default';\n};\n\n// Remove old event listeners and add new ones\nsvg.removeEventListener('pointerdown', handleMouseDown);\nsvg.removeEventListener('pointermove', handleMouseMove);\nsvg.removeEventListener('pointerup', handleMouseUp);\n\n\n// Updated style handlers with undo/redo support\nconst updateSelectedArrowStyle = (styleChanges) => {\n if (currentShape instanceof Arrow && currentShape.isSelected) {\n const oldOptions = {\n ...currentShape.options,\n arrowOutlineStyle: currentShape.arrowOutlineStyle,\n arrowHeadStyle: currentShape.arrowHeadStyle,\n arrowCurved: currentShape.arrowCurved,\n arrowCurveAmount: currentShape.arrowCurveAmount\n };\n currentShape.updateStyle(styleChanges);\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n if (styleChanges.stroke !== undefined) arrowStrokeColor = styleChanges.stroke;\n if (styleChanges.strokeWidth !== undefined) arrowStrokeThickness = styleChanges.strokeWidth;\n if (styleChanges.arrowOutlineStyle !== undefined) arrowOutlineStyle = styleChanges.arrowOutlineStyle;\n if (styleChanges.arrowHeadStyle !== undefined) arrowHeadStyle = styleChanges.arrowHeadStyle;\n if (styleChanges.arrowCurved !== undefined) arrowCurved = styleChanges.arrowCurved;\n if (styleChanges.arrowCurveAmount !== undefined) arrowCurveAmount = styleChanges.arrowCurveAmount;\n }\n};\n\narrowStrokeColorOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowStrokeColorOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newColor = span.getAttribute(\"data-id\");\n updateSelectedArrowStyle({ stroke: newColor });\n });\n});\n\narrowStrokeThicknessValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowStrokeThicknessValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newThickness = parseInt(span.getAttribute(\"data-id\"));\n updateSelectedArrowStyle({ strokeWidth: newThickness });\n });\n});\n\narrowOutlineStyleValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowOutlineStyleValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newStyle = span.getAttribute(\"data-id\");\n updateSelectedArrowStyle({ arrowOutlineStyle: newStyle });\n });\n});\n\narrowTypeStyleValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowTypeStyleValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n updateSelectedArrowStyle({ arrowCurved: span.getAttribute(\"data-id\") });\n });\n});\n\narrowCurveAmountOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowCurveAmountOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n updateSelectedArrowStyle({ arrowCurveAmount: parseInt(span.getAttribute(\"data-id\")) });\n });\n});\n\narrowHeadStyleValue.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n arrowHeadStyleValue.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const newHeadStyle = span.getAttribute(\"data-id\");\n updateSelectedArrowStyle({ arrowHeadStyle: newHeadStyle });\n });\n});\n\nfunction detachSelectedArrow() {\n if (currentShape instanceof Arrow && currentShape.isSelected) {\n if (currentShape.attachedToStart || currentShape.attachedToEnd) {\n const oldState = {\n attachedToStart: currentShape.attachedToStart,\n attachedToEnd: currentShape.attachedToEnd,\n startPoint: { ...currentShape.startPoint },\n endPoint: { ...currentShape.endPoint }\n };\n\n currentShape.detachFromShape(true);\n currentShape.detachFromShape(false);\n currentShape.draw();\n\n // Add to undo/redo if needed\n }\n }\n}\n\nfunction updateAttachedArrows(shape) {\n if (!shape) return;\n\n // If a DOM element was passed (e.g. from text/code/image move), find the wrapper\n let targetShape = shape;\n if (shape.nodeType) {\n targetShape = shapes.find(s => s.group === shape || s.element === shape) || shape;\n }\n\n shapes.forEach(arrowShape => {\n if (arrowShape instanceof Arrow) {\n let needsUpdate = false;\n if (arrowShape.attachedToStart && arrowShape.attachedToStart.shape === targetShape) {\n needsUpdate = true;\n }\n if (arrowShape.attachedToEnd && arrowShape.attachedToEnd.shape === targetShape) {\n needsUpdate = true;\n }\n\n if (needsUpdate) {\n arrowShape.updateAttachments();\n }\n }\n });\n}\n\nfunction cleanupAttachments(deletedShape) {\n if (!deletedShape) return;\n\n // If a DOM element was passed, find the wrapper\n let targetShape = deletedShape;\n if (deletedShape.nodeType) {\n targetShape = shapes.find(s => s.group === deletedShape || s.element === deletedShape) || deletedShape;\n }\n\n shapes.forEach(shape => {\n if (shape instanceof Arrow) {\n let needsDraw = false;\n if (shape.attachedToStart && shape.attachedToStart.shape === targetShape) {\n shape.detachFromShape(true);\n needsDraw = true;\n }\n if (shape.attachedToEnd && shape.attachedToEnd.shape === targetShape) {\n shape.detachFromShape(false);\n needsDraw = true;\n }\n if (needsDraw) {\n shape.draw();\n }\n }\n });\n}\n\n// Add keyboard shortcut to detach arrows\ndocument.addEventListener('keydown', (e) => {\n if (e.key.toLowerCase() === 'd' && e.ctrlKey) {\n e.preventDefault();\n detachSelectedArrow();\n }\n});\n\n// Expose arrow tool settings on window for React sidebar bridge\nwindow.arrowToolSettings = {\n get strokeColor() { return arrowStrokeColor; },\n set strokeColor(v) { arrowStrokeColor = v; },\n get strokeWidth() { return arrowStrokeThickness; },\n set strokeWidth(v) { arrowStrokeThickness = v; },\n get outlineStyle() { return arrowOutlineStyle; },\n set outlineStyle(v) { arrowOutlineStyle = v; },\n get headStyle() { return arrowHeadStyle; },\n set headStyle(v) { arrowHeadStyle = v; },\n get arrowCurved() { return arrowCurved; },\n set arrowCurved(v) { arrowCurved = v; },\n get curveAmount() { return arrowCurveAmount; },\n set curveAmount(v) { arrowCurveAmount = v; },\n};\nwindow.updateSelectedArrowStyle = updateSelectedArrowStyle;\n\n// Export the cleanup function\n// Expose cleanupAttachments globally for centralized delete\nwindow.cleanupAttachments = cleanupAttachments;\n\nexport {\n handleMouseDown as handleMouseDownArrow,\n handleMouseMove as handleMouseMoveArrow,\n handleMouseUp as handleMouseUpArrow,\n cleanupAttachments,\n updateAttachedArrows\n};\n"],
5
5
  "mappings": "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",
6
6
  "names": ["svg", "shapes"]
7
7
  }
@@ -10,14 +10,14 @@ import {
10
10
  setCodeLanguage,
11
11
  updateCodeBackground,
12
12
  wrapCodeElement
13
- } from "./chunk-DODPOWNX.js";
13
+ } from "./chunk-CWE5IFG7.js";
14
14
  import {
15
15
  registerRotationAnchor
16
- } from "./chunk-PAKA6HUX.js";
16
+ } from "./chunk-MS4TIQ6Z.js";
17
17
  import {
18
18
  cleanupAttachments,
19
19
  updateAttachedArrows
20
- } from "./chunk-X5ENBMGL.js";
20
+ } from "./chunk-2U47AU6Y.js";
21
21
  import {
22
22
  pushCreateAction,
23
23
  pushDeleteActionWithAttachments,
@@ -26,12 +26,12 @@ import {
26
26
  pushTransformAction,
27
27
  setTextReferences,
28
28
  updateSelectedElement
29
- } from "./chunk-VZX55VQL.js";
29
+ } from "./chunk-TFCBCWL5.js";
30
30
 
31
31
  // src/tools/textTool.js
32
32
  function getThemeStroke() {
33
33
  if (typeof document === "undefined") return "#fff";
34
- return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#1a1a2e";
34
+ return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#000000";
35
35
  }
36
36
  var textSize = "20px";
37
37
  var textFont = "lixFont";
@@ -372,7 +372,7 @@ function createSelectionFeedback(groupElement) {
372
372
  selectionBox.setAttribute("fill", "none");
373
373
  selectionBox.setAttribute("stroke", "#5B57D1");
374
374
  selectionBox.setAttribute("stroke-width", "1.5");
375
- selectionBox.setAttribute("stroke-dasharray", `${4 / zoom} ${2 / zoom}`);
375
+ selectionBox.setAttribute("stroke-dasharray", "4 2");
376
376
  selectionBox.setAttribute("vector-effect", "non-scaling-stroke");
377
377
  selectionBox.setAttribute("pointer-events", "none");
378
378
  groupElement.appendChild(selectionBox);
@@ -1516,4 +1516,4 @@ export {
1516
1516
  handleTextMouseUp,
1517
1517
  updateCodeToggleForShape
1518
1518
  };
1519
- //# sourceMappingURL=chunk-RK3NVAER.js.map
1519
+ //# sourceMappingURL=chunk-75OPJOWN.js.map