@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
@@ -41,6 +41,12 @@ function pushCreateAction(shape, meta = null) {
41
41
  type: "create",
42
42
  shape
43
43
  };
44
+ const parentFrame = meta?.parentFrame || shape?.parentFrame || null;
45
+ if (parentFrame) {
46
+ action.parentFrame = parentFrame;
47
+ const frameIndex = Number.isInteger(meta?.frameIndex) ? meta.frameIndex : parentFrame.containedShapes?.indexOf(shape);
48
+ if (Number.isInteger(frameIndex) && frameIndex >= 0) action.frameIndex = frameIndex;
49
+ }
44
50
  if (meta?.frameCreation && shape?.shapeName === "frame") {
45
51
  action.frameCreation = true;
46
52
  action.containedShapes = [...meta.containedShapes || shape.containedShapes || []];
@@ -78,6 +84,27 @@ function clearUndoHistory() {
78
84
  undoStack.length = 0;
79
85
  redoStack.length = 0;
80
86
  }
87
+ function rebindUndoHistory(currentShapes = []) {
88
+ const shapeById = new Map(currentShapes.filter((shape) => shape?.shapeID).map((shape) => [shape.shapeID, shape]));
89
+ const visited = /* @__PURE__ */ new WeakSet();
90
+ const rebind = (value) => {
91
+ if (!value || typeof value !== "object") return value;
92
+ if (value.shapeID) return shapeById.get(value.shapeID) || value;
93
+ if (visited.has(value)) return value;
94
+ visited.add(value);
95
+ if (Array.isArray(value)) {
96
+ for (let index = 0; index < value.length; index += 1) value[index] = rebind(value[index]);
97
+ return value;
98
+ }
99
+ for (const key of Object.keys(value)) {
100
+ const child = value[key];
101
+ if (child && typeof child === "object") value[key] = rebind(child);
102
+ }
103
+ return value;
104
+ };
105
+ undoStack.forEach(rebind);
106
+ redoStack.forEach(rebind);
107
+ }
81
108
  function pushDeleteActionWithAttachments(shape) {
82
109
  let affectedArrows = [];
83
110
  if (shape.type === "text" || shape.shapeName === "text") {
@@ -131,22 +158,15 @@ function pushCreateActionWithAttachments(shape) {
131
158
  }
132
159
  function pushTransformAction(shape, oldPos, newPos) {
133
160
  if (shape.shapeName === "frame") {
161
+ const oldSnapshots = new Map((oldPos.containedShapes || []).map((entry) => [entry.shape, entry.state]));
134
162
  const containedShapesStates = shape.containedShapes.map((containedShape) => ({
135
163
  shape: containedShape,
136
- oldState: {
137
- x: containedShape.x - (newPos.x - oldPos.x),
138
- y: containedShape.y - (newPos.y - oldPos.y),
139
- width: containedShape.width || 0,
140
- height: containedShape.height || 0,
141
- rotation: containedShape.rotation || 0
164
+ oldState: oldSnapshots.get(containedShape) || {
165
+ ...captureShapeGeometry(containedShape),
166
+ x: typeof containedShape.x === "number" ? containedShape.x - (newPos.x - oldPos.x) : containedShape.x,
167
+ y: typeof containedShape.y === "number" ? containedShape.y - (newPos.y - oldPos.y) : containedShape.y
142
168
  },
143
- newState: {
144
- x: containedShape.x,
145
- y: containedShape.y,
146
- width: containedShape.width || 0,
147
- height: containedShape.height || 0,
148
- rotation: containedShape.rotation || 0
149
- }
169
+ newState: captureShapeGeometry(containedShape)
150
170
  }));
151
171
  undoStack.push({
152
172
  type: "frameTransform",
@@ -396,6 +416,43 @@ function pushTransformAction(shape, oldPos, newPos) {
396
416
  redoStack.length = 0;
397
417
  notifyCollaboration();
398
418
  }
419
+ function clonePoint(point) {
420
+ return point ? { ...point } : point;
421
+ }
422
+ function captureShapeGeometry(shape) {
423
+ const state = {
424
+ x: shape.x,
425
+ y: shape.y,
426
+ width: shape.width,
427
+ height: shape.height,
428
+ rotation: shape.rotation || 0
429
+ };
430
+ if (typeof shape.rx === "number") state.rx = shape.rx;
431
+ if (typeof shape.ry === "number") state.ry = shape.ry;
432
+ if (shape.startPoint) state.startPoint = clonePoint(shape.startPoint);
433
+ if (shape.endPoint) state.endPoint = clonePoint(shape.endPoint);
434
+ if (shape.controlPoint1) state.controlPoint1 = clonePoint(shape.controlPoint1);
435
+ if (shape.controlPoint2) state.controlPoint2 = clonePoint(shape.controlPoint2);
436
+ if (Array.isArray(shape.points)) state.points = shape.points.map((point) => Array.isArray(point) ? [...point] : point);
437
+ if (typeof shape._moveOffsetX === "number") state._moveOffsetX = shape._moveOffsetX;
438
+ if (typeof shape._moveOffsetY === "number") state._moveOffsetY = shape._moveOffsetY;
439
+ return state;
440
+ }
441
+ function captureFrameChildStates(frame) {
442
+ return (frame?.containedShapes || []).map((shape) => ({ shape, state: captureShapeGeometry(shape) }));
443
+ }
444
+ function restoreShapeGeometry(shape, state) {
445
+ if (!shape || !state) return;
446
+ for (const key of ["x", "y", "width", "height", "rotation", "rx", "ry", "_moveOffsetX", "_moveOffsetY"]) {
447
+ if (state[key] !== void 0) shape[key] = state[key];
448
+ }
449
+ for (const key of ["startPoint", "endPoint", "controlPoint1", "controlPoint2"]) {
450
+ if (state[key] !== void 0) shape[key] = clonePoint(state[key]);
451
+ }
452
+ if (state.points) shape.points = state.points.map((point) => Array.isArray(point) ? [...point] : point);
453
+ if (typeof shape.updateBoundingBox === "function") shape.updateBoundingBox();
454
+ if (typeof shape.draw === "function") shape.draw();
455
+ }
399
456
  function pushOptionsChangeAction(shape, oldOptions, newOptions = null) {
400
457
  undoStack.push({
401
458
  type: "optionsChange",
@@ -450,6 +507,14 @@ function detachDeletedShapeFrame(action) {
450
507
  frame.removeShapeFromFrame(shape);
451
508
  }
452
509
  }
510
+ function restoreCreatedShapeFrame(action) {
511
+ if (!action.parentFrame) return;
512
+ restoreDeletedShapeFrame(action);
513
+ }
514
+ function detachCreatedShapeFrame(action) {
515
+ if (!action.parentFrame) return;
516
+ detachDeletedShapeFrame(action);
517
+ }
453
518
  function undo() {
454
519
  if (undoStack.length === 0) return;
455
520
  const action = undoStack.pop();
@@ -477,15 +542,7 @@ function undo() {
477
542
  action.shape.rotation = action.oldPos.rotation;
478
543
  action.shape.frameName = action.oldPos.frameName;
479
544
  action.containedShapes.forEach((shapeData) => {
480
- const shape = shapeData.shape;
481
- shape.x = shapeData.oldState.x;
482
- shape.y = shapeData.oldState.y;
483
- shape.width = shapeData.oldState.width;
484
- shape.height = shapeData.oldState.height;
485
- shape.rotation = shapeData.oldState.rotation;
486
- if (typeof shape.draw === "function") {
487
- shape.draw();
488
- }
545
+ restoreShapeGeometry(shapeData.shape, shapeData.oldState);
489
546
  });
490
547
  action.shape.isSelected = false;
491
548
  if (typeof action.shape.removeSelection === "function") action.shape.removeSelection();
@@ -554,6 +611,7 @@ function undo() {
554
611
  return;
555
612
  }
556
613
  if (action.type === "create") {
614
+ detachCreatedShapeFrame(action);
557
615
  if (action.frameCreation && action.shape.shapeName === "frame") {
558
616
  for (const child of action.containedShapes || []) {
559
617
  if (child?.parentFrame === action.shape) action.shape.removeShapeFromFrame(child);
@@ -884,15 +942,7 @@ function redo() {
884
942
  action.shape.rotation = action.newPos.rotation;
885
943
  action.shape.frameName = action.newPos.frameName;
886
944
  action.containedShapes.forEach((shapeData) => {
887
- const shape = shapeData.shape;
888
- shape.x = shapeData.newState.x;
889
- shape.y = shapeData.newState.y;
890
- shape.width = shapeData.newState.width;
891
- shape.height = shapeData.newState.height;
892
- shape.rotation = shapeData.newState.rotation;
893
- if (typeof shape.draw === "function") {
894
- shape.draw();
895
- }
945
+ restoreShapeGeometry(shapeData.shape, shapeData.newState);
896
946
  });
897
947
  action.shape.isSelected = false;
898
948
  if (typeof action.shape.removeSelection === "function") action.shape.removeSelection();
@@ -993,11 +1043,12 @@ function redo() {
993
1043
  shapes.push(action.shape);
994
1044
  }
995
1045
  } else {
996
- shapes.push(action.shape);
1046
+ if (!shapes.includes(action.shape)) shapes.push(action.shape);
997
1047
  if (svg) {
998
1048
  svg.appendChild(action.shape.group);
999
1049
  }
1000
1050
  }
1051
+ restoreCreatedShapeFrame(action);
1001
1052
  undoStack.push(action);
1002
1053
  return;
1003
1054
  }
@@ -1270,10 +1321,13 @@ document.addEventListener("keydown", (e) => {
1270
1321
  document.getElementById("undo")?.addEventListener("click", undo);
1271
1322
  document.getElementById("redo")?.addEventListener("click", redo);
1272
1323
  window.pushCreateAction = pushCreateAction;
1324
+ window.beginUndoBatch = beginUndoBatch;
1325
+ window.endUndoBatch = endUndoBatch;
1273
1326
  window.pushDeleteAction = pushDeleteAction;
1274
1327
  window.pushCanvasResetAction = pushCanvasResetAction;
1275
1328
  window.invalidateCanvasResetUndo = invalidateCanvasResetUndo;
1276
1329
  window.clearUndoHistory = clearUndoHistory;
1330
+ window.rebindUndoHistory = rebindUndoHistory;
1277
1331
  window.pushDeleteActionWithAttachments = pushDeleteActionWithAttachments;
1278
1332
  window.pushTransformAction = pushTransformAction;
1279
1333
  window.pushOptionsChangeAction = pushOptionsChangeAction;
@@ -1292,12 +1346,15 @@ export {
1292
1346
  pushCanvasResetAction,
1293
1347
  invalidateCanvasResetUndo,
1294
1348
  clearUndoHistory,
1349
+ rebindUndoHistory,
1295
1350
  pushDeleteActionWithAttachments,
1296
1351
  pushFrameAttachmentAction,
1297
1352
  pushCreateActionWithAttachments,
1298
1353
  pushTransformAction,
1354
+ captureShapeGeometry,
1355
+ captureFrameChildStates,
1299
1356
  pushOptionsChangeAction,
1300
1357
  undo,
1301
1358
  redo
1302
1359
  };
1303
- //# sourceMappingURL=chunk-VZX55VQL.js.map
1360
+ //# sourceMappingURL=chunk-TFCBCWL5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/UndoRedo.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// Undo/Redo system - copied from undoAndRedo.js\n\n// Stacks for undo/redo\nconst undoStack = [];\nconst redoStack = [];\n\nexport function beginUndoBatch() {\n return { startIndex: undoStack.length };\n}\n\nexport function endUndoBatch(batch, label = 'batch') {\n if (!batch || !Number.isInteger(batch.startIndex)) return;\n const startIndex = Math.min(Math.max(batch.startIndex, 0), undoStack.length);\n let actions = undoStack.splice(startIndex);\n if (actions.length === 0) return;\n const groupedAction = actions.length === 1 ? actions[0] : { type: 'batch', label, actions };\n undoStack.push(groupedAction);\n redoStack.length = 0;\n notifyCollaboration();\n return groupedAction;\n}\n\n// Import references to text-related variables and functions\nlet selectedElement = null;\nlet updateSelectionFeedback = null;\nlet svg = null;\n\nfunction notifyCollaboration() {\n if (typeof window !== 'undefined' && typeof window.__collabSceneChanged === 'function') {\n window.__collabSceneChanged();\n }\n}\n\n// Function to set references from other modules\nexport function setTextReferences(element, updateFn, svgElement) {\n selectedElement = element;\n updateSelectionFeedback = updateFn;\n svg = svgElement;\n}\n\n// Function to get current selectedElement (called from other modules)\nexport function getCurrentSelectedElement() {\n return selectedElement;\n}\n\n// Function to update selectedElement reference (called from other modules)\nexport function updateSelectedElement(element) {\n selectedElement = element;\n}\n\n// Call this after creating a new shape (e.g., Rectangle)\nexport function pushCreateAction(shape, meta = null) {\n const action = {\n type: 'create',\n shape: shape\n };\n const parentFrame = meta?.parentFrame || shape?.parentFrame || null;\n if (parentFrame) {\n action.parentFrame = parentFrame;\n const frameIndex = Number.isInteger(meta?.frameIndex)\n ? meta.frameIndex\n : parentFrame.containedShapes?.indexOf(shape);\n if (Number.isInteger(frameIndex) && frameIndex >= 0) action.frameIndex = frameIndex;\n }\n if (meta?.frameCreation && shape?.shapeName === 'frame') {\n action.frameCreation = true;\n action.containedShapes = [...(meta.containedShapes || shape.containedShapes || [])];\n action.shapeIndex = Array.isArray(shapes) ? shapes.indexOf(shape) : -1;\n }\n undoStack.push(action);\n \n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nexport function pushDeleteAction(shape, meta = null) {\n // Issue #24 bug #7: when the deleted shape is a frame, the caller may\n // pass `meta.childSnapshot` \u2014 the contained shape REFERENCES at the\n // time of delete. The undo branch uses this to re-attach the children\n // when the frame is restored, instead of leaving an empty box.\n const action = { type: 'delete', shape };\n if (meta && meta.childSnapshot) action.childSnapshot = meta.childSnapshot;\n if (Number.isInteger(meta?.shapeIndex)) action.shapeIndex = meta.shapeIndex;\n if (meta?.parentFrame) action.parentFrame = meta.parentFrame;\n if (Number.isInteger(meta?.frameIndex)) action.frameIndex = meta.frameIndex;\n undoStack.push(action);\n\n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nexport function pushCanvasResetAction(snapshot, restore, reset) {\n if (!snapshot || typeof restore !== 'function' || typeof reset !== 'function') return;\n // A reset is a new history boundary. Older per-shape actions reference\n // objects that the scene loader will replace, so only the atomic reset\n // snapshot remains undoable.\n undoStack.length = 0;\n redoStack.length = 0;\n undoStack.push({ type: 'canvasReset', snapshot, restore, reset });\n}\n\nexport function invalidateCanvasResetUndo() {\n for (let index = undoStack.length - 1; index >= 0; index -= 1) {\n if (undoStack[index]?.type === 'canvasReset') undoStack.splice(index, 1);\n }\n for (let index = redoStack.length - 1; index >= 0; index -= 1) {\n if (redoStack[index]?.type === 'canvasReset') redoStack.splice(index, 1);\n }\n}\n\nexport function clearUndoHistory() {\n undoStack.length = 0;\n redoStack.length = 0;\n}\n\n// Collaboration scene loads rebuild shape instances. Keep this client's\n// history private, but point its actions at the newly materialized objects so\n// Ctrl+Z never mutates detached SVG nodes after a peer update.\nexport function rebindUndoHistory(currentShapes = []) {\n const shapeById = new Map(currentShapes\n .filter(shape => shape?.shapeID)\n .map(shape => [shape.shapeID, shape]));\n const visited = new WeakSet();\n\n const rebind = (value) => {\n if (!value || typeof value !== 'object') return value;\n if (value.shapeID) return shapeById.get(value.shapeID) || value;\n if (visited.has(value)) return value;\n visited.add(value);\n if (Array.isArray(value)) {\n for (let index = 0; index < value.length; index += 1) value[index] = rebind(value[index]);\n return value;\n }\n for (const key of Object.keys(value)) {\n const child = value[key];\n if (child && typeof child === 'object') value[key] = rebind(child);\n }\n return value;\n };\n\n undoStack.forEach(rebind);\n redoStack.forEach(rebind);\n}\n\n// Enhanced delete action to clean up attached arrows\nexport function pushDeleteActionWithAttachments(shape) {\n let affectedArrows = [];\n \n // If deleting a text element, find all attached arrows\n if (shape.type === 'text' || shape.shapeName === 'text') {\n affectedArrows = shapes.filter(s => s.shapeName === 'arrow' && \n (s.attachedToStart?.shape === shape || s.attachedToEnd?.shape === shape))\n .map(arrow => ({\n arrow: arrow,\n oldAttachments: arrow.getAttachmentState(),\n oldPoints: {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n }\n }));\n }\n \n undoStack.push({\n type: 'delete',\n shape: shape,\n affectedArrows: affectedArrows\n });\n \n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nexport function pushFrameAttachmentAction(frame, shape, action, oldFrame = null) {\n undoStack.push({\n type: 'frameAttachment',\n frame: frame,\n shape: shape,\n action: action, // 'attach' or 'detach'\n oldFrame: oldFrame, // Previous frame if shape was moved between frames\n // Store shape position for potential restoration\n shapeState: {\n x: shape.x,\n y: shape.y,\n width: shape.width || 0,\n height: shape.height || 0,\n rotation: shape.rotation || 0\n }\n });\n \n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nexport function pushCreateActionWithAttachments(shape) {\n undoStack.push({\n type: 'create',\n shape: shape,\n // Store any arrows that might need to reattach when this is undone\n potentialAttachments: []\n });\n \n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nexport function pushTransformAction(shape, oldPos, newPos) {\n if (shape.shapeName === 'frame') {\n // Frame transforms can resize and rotate heterogeneous children.\n // Reconstructing their old geometry from the frame delta loses arrow\n // endpoints, circle radii and freehand points. Prefer the snapshot\n // captured at pointer-down, with a translation-only fallback for old\n // callers that have not supplied one yet.\n const oldSnapshots = new Map((oldPos.containedShapes || []).map(entry => [entry.shape, entry.state]));\n const containedShapesStates = shape.containedShapes.map(containedShape => ({\n shape: containedShape,\n oldState: oldSnapshots.get(containedShape) || {\n ...captureShapeGeometry(containedShape),\n x: typeof containedShape.x === 'number' ? containedShape.x - (newPos.x - oldPos.x) : containedShape.x,\n y: typeof containedShape.y === 'number' ? containedShape.y - (newPos.y - oldPos.y) : containedShape.y,\n },\n newState: captureShapeGeometry(containedShape),\n }));\n\n undoStack.push({\n type: 'frameTransform',\n shape: shape,\n oldPos: {\n x: oldPos.x,\n y: oldPos.y,\n width: oldPos.width,\n height: oldPos.height,\n rotation: oldPos.rotation,\n frameName: oldPos.frameName || shape.frameName\n },\n newPos: {\n x: newPos.x,\n y: newPos.y,\n width: newPos.width,\n height: newPos.height,\n rotation: newPos.rotation,\n frameName: newPos.frameName || shape.frameName\n },\n containedShapes: containedShapesStates\n });\n } else if (shape.type === 'text') {\n // Enhanced text handling - also track frame attachment changes\n const currentFrame = shape.parentFrame || null;\n \n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n x: oldPos.x,\n y: oldPos.y,\n rotation: oldPos.rotation,\n fontSize: oldPos.fontSize\n },\n newPos: {\n x: newPos.x,\n y: newPos.y,\n rotation: newPos.rotation,\n fontSize: newPos.fontSize\n },\n // Track frame attachment state\n frameAttachment: {\n oldFrame: oldPos.parentFrame || null,\n newFrame: currentFrame\n },\n // Store affected arrows with their attachment states\n affectedArrows: shapes.filter(s => s.shapeName === 'arrow' && \n (s.attachedToStart?.shape === shape || s.attachedToEnd?.shape === shape))\n .map(arrow => ({\n arrow: arrow,\n oldAttachments: arrow.getAttachmentState(),\n oldPoints: {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n }\n }))\n });\n } else if (shape.type === 'image') {\n // Enhanced image handling - also track frame attachment changes\n const currentFrame = shape.parentFrame || null;\n \n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n x: oldPos.x,\n y: oldPos.y,\n width: oldPos.width,\n height: oldPos.height,\n rotation: oldPos.rotation\n },\n newPos: {\n x: newPos.x,\n y: newPos.y,\n width: newPos.width,\n height: newPos.height,\n rotation: newPos.rotation\n },\n // Track frame attachment state\n frameAttachment: {\n oldFrame: oldPos.parentFrame || null,\n newFrame: currentFrame\n },\n // Store affected arrows with their attachment states\n affectedArrows: shapes.filter(s => s.shapeName === 'arrow' && \n (s.attachedToStart?.shape === shape || s.attachedToEnd?.shape === shape))\n .map(arrow => ({\n arrow: arrow,\n oldAttachments: arrow.getAttachmentState(),\n oldPoints: {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n }\n }))\n });\n } else if (shape.shapeName === 'circle') {\n // Enhanced circle handling - also track frame attachment changes\n const currentFrame = shape.parentFrame || null;\n \n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n x: oldPos.x,\n y: oldPos.y,\n rx: oldPos.rx,\n ry: oldPos.ry,\n rotation: oldPos.rotation\n },\n newPos: {\n x: newPos.x,\n y: newPos.y,\n rx: newPos.rx,\n ry: newPos.ry,\n rotation: newPos.rotation\n },\n // Track frame attachment state\n frameAttachment: {\n oldFrame: oldPos.parentFrame || null,\n newFrame: currentFrame\n },\n // Store affected arrows with their attachment states\n affectedArrows: shapes.filter(s => s.shapeName === 'arrow' && \n (s.attachedToStart?.shape === shape || s.attachedToEnd?.shape === shape))\n .map(arrow => ({\n arrow: arrow,\n oldAttachments: arrow.getAttachmentState(),\n oldPoints: {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n }\n }))\n });\n } else if (shape.shapeName === \"rectangle\") {\n // Enhanced rectangle handling - also track frame attachment changes\n const currentFrame = shape.parentFrame || null;\n \n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: { \n x: oldPos.x, \n y: oldPos.y, \n width: oldPos.width, \n height: oldPos.height, \n rotation: oldPos.rotation\n },\n newPos: { \n x: newPos.x, \n y: newPos.y, \n width: newPos.width, \n height: newPos.height, \n rotation: newPos.rotation\n },\n // Track frame attachment state\n frameAttachment: {\n oldFrame: oldPos.parentFrame || null,\n newFrame: currentFrame\n },\n // Store affected arrows with their attachment states\n affectedArrows: shapes.filter(s => s.shapeName === 'arrow' && \n (s.attachedToStart?.shape === shape || s.attachedToEnd?.shape === shape))\n .map(arrow => ({\n arrow: arrow,\n oldAttachments: arrow.getAttachmentState(),\n oldPoints: {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n }\n }))\n });\n } \n else if (shape.shapeName === 'line') {\n // Enhanced line handling with curve support\n const currentFrame = shape.parentFrame || null;\n \n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n startPoint: { x: oldPos.startPoint.x, y: oldPos.startPoint.y },\n endPoint: { x: oldPos.endPoint.x, y: oldPos.endPoint.y },\n controlPoint: oldPos.controlPoint ? { x: oldPos.controlPoint.x, y: oldPos.controlPoint.y } : null,\n isCurved: oldPos.isCurved || false\n },\n newPos: {\n startPoint: { x: newPos.startPoint.x, y: newPos.startPoint.y },\n endPoint: { x: newPos.endPoint.x, y: newPos.endPoint.y },\n controlPoint: newPos.controlPoint ? { x: newPos.controlPoint.x, y: newPos.controlPoint.y } : null,\n isCurved: newPos.isCurved || false\n },\n // Track frame attachment state\n frameAttachment: {\n oldFrame: oldPos.parentFrame || null,\n newFrame: currentFrame\n }\n });\n }\n else if (shape.shapeName === 'arrow') {\n // Handle arrow transform with attachment state\n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n startPoint: { x: oldPos.startPoint.x, y: oldPos.startPoint.y },\n endPoint: { x: oldPos.endPoint.x, y: oldPos.endPoint.y },\n controlPoint1: oldPos.controlPoint1 ? { x: oldPos.controlPoint1.x, y: oldPos.controlPoint1.y } : null,\n controlPoint2: oldPos.controlPoint2 ? { x: oldPos.controlPoint2.x, y: oldPos.controlPoint2.y } : null,\n attachments: oldPos.attachments || shape.getAttachmentState()\n },\n newPos: {\n startPoint: { x: newPos.startPoint.x, y: newPos.startPoint.y },\n endPoint: { x: newPos.endPoint.x, y: newPos.endPoint.y },\n controlPoint1: newPos.controlPoint1 ? { x: newPos.controlPoint1.x, y: newPos.controlPoint1.y } : null,\n controlPoint2: newPos.controlPoint2 ? { x: newPos.controlPoint2.x, y: newPos.controlPoint2.y } : null,\n attachments: newPos.attachments || shape.getAttachmentState()\n }\n });\n } \n else if (shape.type === 'icon') {\n // Enhanced icon handling - also track frame attachment changes\n const currentFrame = shape.parentFrame || null;\n \n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n x: oldPos.x,\n y: oldPos.y,\n width: oldPos.width,\n height: oldPos.height,\n rotation: oldPos.rotation\n },\n newPos: {\n x: newPos.x,\n y: newPos.y,\n width: newPos.width,\n height: newPos.height,\n rotation: newPos.rotation\n },\n // Track frame attachment state\n frameAttachment: {\n oldFrame: oldPos.parentFrame || null,\n newFrame: currentFrame\n },\n // Store affected arrows with their attachment states\n affectedArrows: shapes.filter(s => s.shapeName === 'arrow' && \n (s.attachedToStart?.shape === shape || s.attachedToEnd?.shape === shape))\n .map(arrow => ({\n arrow: arrow,\n oldAttachments: arrow.getAttachmentState(),\n oldPoints: {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n }\n }))\n });\n}\n\n else if (shape.shapeName === 'freehandStroke') {\n // Handle freehand stroke transform\n undoStack.push({\n type: 'transform',\n shape: shape,\n oldPos: {\n points: JSON.parse(JSON.stringify(oldPos.points)),\n rotation: oldPos.rotation\n },\n newPos: {\n points: JSON.parse(JSON.stringify(newPos.points)),\n rotation: newPos.rotation\n }\n });\n }\n \n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nfunction clonePoint(point) {\n return point ? { ...point } : point;\n}\n\nexport function captureShapeGeometry(shape) {\n const state = {\n x: shape.x,\n y: shape.y,\n width: shape.width,\n height: shape.height,\n rotation: shape.rotation || 0,\n };\n if (typeof shape.rx === 'number') state.rx = shape.rx;\n if (typeof shape.ry === 'number') state.ry = shape.ry;\n if (shape.startPoint) state.startPoint = clonePoint(shape.startPoint);\n if (shape.endPoint) state.endPoint = clonePoint(shape.endPoint);\n if (shape.controlPoint1) state.controlPoint1 = clonePoint(shape.controlPoint1);\n if (shape.controlPoint2) state.controlPoint2 = clonePoint(shape.controlPoint2);\n if (Array.isArray(shape.points)) state.points = shape.points.map(point => Array.isArray(point) ? [...point] : point);\n if (typeof shape._moveOffsetX === 'number') state._moveOffsetX = shape._moveOffsetX;\n if (typeof shape._moveOffsetY === 'number') state._moveOffsetY = shape._moveOffsetY;\n return state;\n}\n\nexport function captureFrameChildStates(frame) {\n return (frame?.containedShapes || []).map(shape => ({ shape, state: captureShapeGeometry(shape) }));\n}\n\nfunction restoreShapeGeometry(shape, state) {\n if (!shape || !state) return;\n for (const key of ['x', 'y', 'width', 'height', 'rotation', 'rx', 'ry', '_moveOffsetX', '_moveOffsetY']) {\n if (state[key] !== undefined) shape[key] = state[key];\n }\n for (const key of ['startPoint', 'endPoint', 'controlPoint1', 'controlPoint2']) {\n if (state[key] !== undefined) shape[key] = clonePoint(state[key]);\n }\n if (state.points) shape.points = state.points.map(point => Array.isArray(point) ? [...point] : point);\n if (typeof shape.updateBoundingBox === 'function') shape.updateBoundingBox();\n if (typeof shape.draw === 'function') shape.draw();\n}\n\nexport function pushOptionsChangeAction(shape, oldOptions, newOptions = null) {\n undoStack.push({\n type: 'optionsChange',\n shape: shape,\n oldOptions: oldOptions,\n newOptions: newOptions\n });\n \n // Clear redo stack when new action is performed\n redoStack.length = 0;\n notifyCollaboration();\n}\n\nfunction applyOptionsSnapshot(shape, options) {\n shape.options = { ...options };\n if (shape.shapeName === 'frame') {\n shape.fillColor = options.fillColor;\n shape.fillStyle = options.fillStyle;\n }\n shape.draw();\n}\n\n// Issue #34 bug #4: refresh the multi-selection outline + handles so it\n// follows the reverted geometry. Without this the selection rect stays\n// pinned to the pre-undo coordinates and the user sees a ghost rect\n// floating away from the shapes it claims to wrap.\nfunction refreshSelectionAfterAction() {\n const ms = (typeof window !== 'undefined') ? window.multiSelection : null;\n if (!ms) return;\n if (typeof ms.updateControls !== 'function') return;\n if (!ms.selectedShapes || ms.selectedShapes.size === 0) return;\n try { ms.updateControls(); } catch (err) { console.warn('[UndoRedo] selection refresh failed:', err); }\n}\n\nfunction restoreDeletedShapeFrame(action) {\n const frame = action.parentFrame;\n const shape = action.shape;\n if (!frame || !shape || typeof frame.addShapeToFrame !== 'function') return;\n frame.addShapeToFrame(shape);\n if (Number.isInteger(action.frameIndex) && Array.isArray(frame.containedShapes)) {\n const currentIndex = frame.containedShapes.indexOf(shape);\n if (currentIndex >= 0) frame.containedShapes.splice(currentIndex, 1);\n const targetIndex = Math.min(Math.max(action.frameIndex, 0), frame.containedShapes.length);\n frame.containedShapes.splice(targetIndex, 0, shape);\n const element = shape.group || shape.element;\n const nextShape = frame.containedShapes[targetIndex + 1];\n const nextElement = nextShape?.group || nextShape?.element;\n if (element && frame.clipGroup && nextElement?.parentNode === frame.clipGroup) {\n frame.clipGroup.insertBefore(element, nextElement);\n }\n }\n}\n\nfunction detachDeletedShapeFrame(action) {\n const frame = action.parentFrame;\n const shape = action.shape;\n if (frame && shape && typeof frame.removeShapeFromFrame === 'function' && shape.parentFrame === frame) {\n frame.removeShapeFromFrame(shape);\n }\n}\n\nfunction restoreCreatedShapeFrame(action) {\n if (!action.parentFrame) return;\n restoreDeletedShapeFrame(action);\n}\n\nfunction detachCreatedShapeFrame(action) {\n if (!action.parentFrame) return;\n detachDeletedShapeFrame(action);\n}\n\nexport function undo() {\n if (undoStack.length === 0) return;\n const action = undoStack.pop();\n try {\n if (action.type === 'batch') {\n for (let index = action.actions.length - 1; index >= 0; index -= 1) {\n undoStack.push(action.actions[index]);\n undo();\n redoStack.pop();\n }\n redoStack.push(action);\n return;\n }\n\n if (action.type === 'canvasReset') {\n action.restore(action.snapshot);\n redoStack.push(action);\n notifyCollaboration();\n return;\n }\n\n if (action.type === 'frameTransform') {\n // Handle frame transformation undo\n action.shape.x = action.oldPos.x;\n action.shape.y = action.oldPos.y;\n action.shape.width = action.oldPos.width;\n action.shape.height = action.oldPos.height;\n action.shape.rotation = action.oldPos.rotation;\n action.shape.frameName = action.oldPos.frameName;\n \n // Restore contained shapes to their old positions\n action.containedShapes.forEach(shapeData => {\n restoreShapeGeometry(shapeData.shape, shapeData.oldState);\n });\n \n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n action.shape.updateClipPath();\n \n redoStack.push(action);\n return;\n }\n \n if (action.type === 'frameAttachment') {\n // Handle frame attachment/detachment undo WITHOUT calling the methods that track undo\n if (action.action === 'attach') {\n // Undo attach: manually remove shape from frame\n const frameIndex = action.frame.containedShapes.indexOf(action.shape);\n if (frameIndex > -1) {\n action.frame.containedShapes.splice(frameIndex, 1);\n action.shape.parentFrame = null;\n \n // Move shape back to main SVG\n if (action.shape.group && action.shape.group.parentNode === action.frame.clipGroup) {\n action.frame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n \n // If shape was moved from another frame, restore it there\n if (action.oldFrame) {\n action.oldFrame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.oldFrame;\n \n // Move to old frame's clipped group\n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.oldFrame.clipGroup.appendChild(action.shape.group);\n }\n }\n } else if (action.action === 'detach') {\n // Undo detach: manually add shape back to frame\n if (!action.frame.containedShapes.includes(action.shape)) {\n action.frame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.frame;\n \n // Move to frame's clipped group\n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.frame.clipGroup.appendChild(action.shape.group);\n }\n }\n }\n \n // Restore shape state\n action.shape.x = action.shapeState.x;\n action.shape.y = action.shapeState.y;\n action.shape.width = action.shapeState.width;\n action.shape.height = action.shapeState.height;\n action.shape.rotation = action.shapeState.rotation;\n \n if (typeof action.shape.draw === 'function') {\n action.shape.draw();\n }\n \n redoStack.push(action);\n return;\n }\n\n // Handle mode conversion undo (code \u2194 text)\n if (action.type === 'create' && action.shape.type === 'modeConvert') {\n // Undo: remove the new shape, restore the old shape\n const newShape = action.shape.newShape;\n const newElement = action.shape.newElement;\n const oldShape = action.shape.oldShape;\n const oldElement = action.shape.oldElement;\n\n // Remove new shape from DOM and shapes array\n if (newElement && newElement.parentNode) {\n newElement.parentNode.removeChild(newElement);\n }\n const newIdx = shapes.indexOf(newShape);\n if (newIdx !== -1) shapes.splice(newIdx, 1);\n\n // Restore old shape to DOM and shapes array\n if (svg && oldElement) {\n svg.appendChild(oldElement);\n }\n if (oldShape) {\n shapes.push(oldShape);\n }\n\n redoStack.push(action);\n return;\n }\n\n if (action.type === 'create') {\n detachCreatedShapeFrame(action);\n if (action.frameCreation && action.shape.shapeName === 'frame') {\n // Treat a manually-created frame and its initial membership as one\n // atomic action. Children remain on the canvas when the frame is\n // undone and are clipped back into it on redo.\n for (const child of action.containedShapes || []) {\n if (child?.parentFrame === action.shape) action.shape.removeShapeFromFrame(child);\n }\n if (currentShape === action.shape) {\n action.shape.removeSelection?.();\n currentShape = null;\n }\n const idx = shapes.indexOf(action.shape);\n if (idx !== -1) shapes.splice(idx, 1);\n action.shape.group?.remove();\n action.shape.clipGroup?.remove();\n action.shape.clipPath?.remove();\n } else\n if (action.shape.type === 'text') {\n // Handle text creation undo\n if (action.shape.element && action.shape.element.parentNode) {\n action.shape.element.parentNode.removeChild(action.shape.element);\n } else if (action.shape.parentNode) {\n action.shape.parentNode.removeChild(action.shape);\n }\n\n // Remove from shapes array\n const idx = shapes.indexOf(action.shape.element || action.shape);\n if (idx !== -1) shapes.splice(idx, 1);\n\n // Clean up any arrow attachments to this text\n if (typeof cleanupAttachments === 'function') {\n cleanupAttachments(action.shape.element || action.shape);\n }\n } else if (action.shape.type === 'image') {\n // Handle image creation undo\n action.shape.remove();\n } else if (action.shape.type === 'icon') {\n // Handle icon creation undo - call the remove method\n action.shape.remove();\n } else {\n // Handle other shape creation undo\n const idx = shapes.indexOf(action.shape);\n if (idx !== -1) shapes.splice(idx, 1);\n if (action.shape.group && action.shape.group.parentNode) {\n action.shape.group.parentNode.removeChild(action.shape.group);\n }\n \n // Handle frame cleanup\n if (action.shape.shapeName === 'frame') {\n action.shape.destroy();\n }\n }\n redoStack.push(action);\n return;\n}\n \n if (action.type === 'delete') {\n if (action.shape.type === 'text') {\n // Handle text deletion undo\n if (svg) {\n svg.appendChild(action.shape.element || action.shape);\n // Add back to shapes array\n shapes.push(action.shape.element || action.shape);\n }\n \n // Restore arrow attachments if any existed\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore the old attachment state\n arrow.restoreAttachmentState(arrowData.oldAttachments);\n });\n }\n } else if (action.shape.type === 'image') {\n // Handle image deletion undo\n action.shape.restore();\n } else {\n // Handle other shape deletion undo\n if (shapes.indexOf(action.shape) === -1) {\n const index = Number.isInteger(action.shapeIndex)\n ? Math.min(Math.max(action.shapeIndex, 0), shapes.length)\n : shapes.length;\n shapes.splice(index, 0, action.shape);\n }\n if (svg) {\n svg.appendChild(action.shape.group);\n }\n\n // Issue #24 bug #7: rehydrate frame state. The delete path\n // orphaned the frame (removed <g>, clipGroup, clipPath from\n // DOM) but kept the JS object intact. Re-attach clipGroup +\n // clipPath, then re-parent every child from the snapshot via\n // addShapeToFrame. Skip children that were subsequently\n // deleted (they'll get re-added when their own delete action\n // is undone in turn).\n if (action.shape.shapeName === 'frame' && svg) {\n if (action.shape.clipGroup && !action.shape.clipGroup.parentNode) {\n svg.appendChild(action.shape.clipGroup);\n }\n if (action.shape.clipPath && !action.shape.clipPath.parentNode) {\n const defs = svg.querySelector('defs');\n if (defs) defs.appendChild(action.shape.clipPath);\n else svg.insertBefore(action.shape.clipPath, svg.firstChild);\n }\n if (action.childSnapshot && Array.isArray(action.childSnapshot)) {\n for (const child of action.childSnapshot) {\n if (!child) continue;\n if (shapes.indexOf(child) === -1) continue;\n if (typeof action.shape.addShapeToFrame === 'function') {\n action.shape.addShapeToFrame(child);\n }\n }\n }\n }\n }\n restoreDeletedShapeFrame(action);\n redoStack.push(action);\n return;\n }\n \n if (action.type === 'transform') {\n // Handle frame attachment changes first\n if (action.frameAttachment) {\n // Use manual frame operations to avoid undo recursion\n if (action.frameAttachment.newFrame) {\n const frameIndex = action.frameAttachment.newFrame.containedShapes.indexOf(action.shape);\n if (frameIndex > -1) {\n action.frameAttachment.newFrame.containedShapes.splice(frameIndex, 1);\n if (action.shape.group && action.shape.group.parentNode === action.frameAttachment.newFrame.clipGroup) {\n action.frameAttachment.newFrame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n }\n if (action.frameAttachment.oldFrame) {\n if (!action.frameAttachment.oldFrame.containedShapes.includes(action.shape)) {\n action.frameAttachment.oldFrame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.frameAttachment.oldFrame;\n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.frameAttachment.oldFrame.clipGroup.appendChild(action.shape.group);\n }\n }\n } else {\n action.shape.parentFrame = null;\n }\n }\n \n if (action.shape.type === 'text') {\n // Enhanced text transform undo\n const textElement = (action.shape.element || action.shape).querySelector('text');\n if (textElement && action.oldPos.fontSize !== undefined) {\n textElement.setAttribute('font-size', action.oldPos.fontSize + 'px');\n }\n \n // Restore position and rotation\n const centerX = textElement ? textElement.getBBox().x + textElement.getBBox().width / 2 : 0;\n const centerY = textElement ? textElement.getBBox().y + textElement.getBBox().height / 2 : 0;\n \n (action.shape.element || action.shape).setAttribute('transform', \n `translate(${action.oldPos.x}, ${action.oldPos.y}) rotate(${action.oldPos.rotation}, ${centerX}, ${centerY})`\n );\n \n (action.shape.element || action.shape).setAttribute('data-x', action.oldPos.x);\n (action.shape.element || action.shape).setAttribute('data-y', action.oldPos.y);\n \n // Update attached arrows after text undo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to old state\n arrow.restoreAttachmentState(arrowData.oldAttachments);\n \n // Store current state for redo\n arrowData.newPoints = {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n };\n arrowData.newAttachments = arrow.getAttachmentState();\n });\n }\n \n // Update feedback if selected\n if (selectedElement === (action.shape.element || action.shape) && updateSelectionFeedback) {\n setTimeout(updateSelectionFeedback, 0);\n }\n } else if (action.shape.type === 'image') {\n // Enhanced image transform undo\n action.shape.restore(action.oldPos);\n \n // Update attached arrows after image undo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to old state\n arrow.restoreAttachmentState(arrowData.oldAttachments);\n \n // Store current state for redo\n arrowData.newPoints = {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n };\n arrowData.newAttachments = arrow.getAttachmentState();\n });\n }\n } else if (action.shape.shapeName === 'circle') {\n // Enhanced circle transform undo\n action.shape.x = action.oldPos.x;\n action.shape.y = action.oldPos.y;\n action.shape.rx = action.oldPos.rx;\n action.shape.ry = action.oldPos.ry;\n action.shape.rotation = action.oldPos.rotation;\n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n\n // Update attached arrows after circle undo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to old state\n arrow.restoreAttachmentState(arrowData.oldAttachments);\n \n // Store current state for redo\n arrowData.newPoints = {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n };\n arrowData.newAttachments = arrow.getAttachmentState();\n });\n }\n } else if (action.shape.shapeName === 'line') {\n // Enhanced line transform undo with curve support\n action.shape.startPoint = { x: action.oldPos.startPoint.x, y: action.oldPos.startPoint.y };\n action.shape.endPoint = { x: action.oldPos.endPoint.x, y: action.oldPos.endPoint.y };\n \n // Restore curve state\n action.shape.isCurved = action.oldPos.isCurved || false;\n if (action.oldPos.controlPoint) {\n action.shape.controlPoint = { x: action.oldPos.controlPoint.x, y: action.oldPos.controlPoint.y };\n } else {\n action.shape.controlPoint = null;\n }\n \n // Handle frame attachment changes\n if (action.frameAttachment) {\n // Remove from new frame if it exists\n if (action.frameAttachment.newFrame) {\n const frameIndex = action.frameAttachment.newFrame.containedShapes.indexOf(action.shape);\n if (frameIndex > -1) {\n action.frameAttachment.newFrame.containedShapes.splice(frameIndex, 1);\n if (action.shape.group && action.shape.group.parentNode === action.frameAttachment.newFrame.clipGroup) {\n action.frameAttachment.newFrame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n }\n \n // Add back to old frame if it exists\n if (action.frameAttachment.oldFrame) {\n if (!action.frameAttachment.oldFrame.containedShapes.includes(action.shape)) {\n action.frameAttachment.oldFrame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.frameAttachment.oldFrame;\n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.frameAttachment.oldFrame.clipGroup.appendChild(action.shape.group);\n }\n }\n } else {\n action.shape.parentFrame = null;\n }\n }\n \n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n }\n else if (action.shape.shapeName === 'arrow') {\n // Enhanced arrow transform undo with attachment restoration\n action.shape.startPoint = { x: action.oldPos.startPoint.x, y: action.oldPos.startPoint.y };\n action.shape.endPoint = { x: action.oldPos.endPoint.x, y: action.oldPos.endPoint.y };\n action.shape.controlPoint1 = action.oldPos.controlPoint1 ? \n { x: action.oldPos.controlPoint1.x, y: action.oldPos.controlPoint1.y } : null;\n action.shape.controlPoint2 = action.oldPos.controlPoint2 ? \n { x: action.oldPos.controlPoint2.x, y: action.oldPos.controlPoint2.y } : null;\n \n // Restore attachment state\n if (action.oldPos.attachments) {\n action.shape.restoreAttachmentState(action.oldPos.attachments);\n } else {\n // Clear attachments if none existed before\n action.shape.attachedToStart = null;\n action.shape.attachedToEnd = null;\n }\n \n action.shape.isSelected = false;\n action.shape.draw();\n \n\n \n } \n else if (action.shape.type === 'icon') {\n \n action.shape.restore(action.oldPos);\n \n // Update attached arrows after icon undo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to old state\n arrow.restoreAttachmentState(arrowData.oldAttachments);\n \n // Store current state for redo\n arrowData.newPoints = {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n };\n arrowData.newAttachments = arrow.getAttachmentState();\n });\n }\n }\n else if (action.shape.shapeName === 'freehandStroke') {\n // Handle freehand stroke transform undo\n action.shape.points = JSON.parse(JSON.stringify(action.oldPos.points));\n action.shape.rotation = action.oldPos.rotation;\n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n } else if (action.shape.shapeName === \"rectangle\") {\n action.shape.x = action.oldPos.x;\n action.shape.y = action.oldPos.y;\n action.shape.height = action.oldPos.height;\n action.shape.width = action.oldPos.width;\n action.shape.rotation = action.oldPos.rotation;\n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n\n // Update attached arrows after rectangle undo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n arrow.restoreAttachmentState(arrowData.oldAttachments);\n arrowData.newPoints = {\n startPoint: { ...arrow.startPoint },\n endPoint: { ...arrow.endPoint }\n };\n arrowData.newAttachments = arrow.getAttachmentState();\n });\n }\n }\n redoStack.push(action);\n return;\n }\n \n if (action.type === 'optionsChange') {\n if (!action.newOptions && action.shape?.options) {\n action.newOptions = action.shape.shapeName === 'arrow'\n ? {\n ...action.shape.options,\n arrowOutlineStyle: action.shape.arrowOutlineStyle,\n arrowHeadStyle: action.shape.arrowHeadStyle,\n arrowCurved: action.shape.arrowCurved,\n arrowCurveAmount: action.shape.arrowCurveAmount,\n }\n : { ...action.shape.options };\n }\n if (action.shape.type === 'text') {\n // Handle text options change undo\n const textElement = (action.shape.element || action.shape).querySelector('text');\n if (textElement) {\n if (action.oldOptions.color) textElement.setAttribute('fill', action.oldOptions.color);\n if (action.oldOptions.font) textElement.setAttribute('font-family', action.oldOptions.font);\n if (action.oldOptions.size) textElement.setAttribute('font-size', action.oldOptions.size);\n if (action.oldOptions.align) textElement.setAttribute('text-anchor', action.oldOptions.align);\n \n // Update feedback if selected\n if (selectedElement === (action.shape.element || action.shape) && updateSelectionFeedback) {\n setTimeout(updateSelectionFeedback, 0);\n }\n }\n } else if (action.shape.shapeName === 'arrow') {\n // Handle arrow options change undo\n action.shape.options = { ...action.oldOptions };\n action.shape.arrowOutlineStyle = action.oldOptions.arrowOutlineStyle;\n action.shape.arrowHeadStyle = action.oldOptions.arrowHeadStyle;\n action.shape.arrowCurved = action.oldOptions.arrowCurved;\n action.shape.arrowCurveAmount = action.oldOptions.arrowCurveAmount;\n action.shape.draw();\n } else {\n // Handle other shape options change undo\n applyOptionsSnapshot(action.shape, action.oldOptions);\n }\n redoStack.push(action);\n return;\n }\n } finally {\n refreshSelectionAfterAction();\n notifyCollaboration();\n }\n}\n\nexport function redo() {\n if (redoStack.length === 0) return;\n const action = redoStack.pop();\n try {\n if (action.type === 'batch') {\n for (const childAction of action.actions) {\n redoStack.push(childAction);\n redo();\n undoStack.pop();\n }\n undoStack.push(action);\n return;\n }\n\n if (action.type === 'canvasReset') {\n action.reset();\n undoStack.push(action);\n notifyCollaboration();\n return;\n }\n\n if (action.type === 'frameTransform') {\n // Handle frame transformation redo\n action.shape.x = action.newPos.x;\n action.shape.y = action.newPos.y;\n action.shape.width = action.newPos.width;\n action.shape.height = action.newPos.height;\n action.shape.rotation = action.newPos.rotation;\n action.shape.frameName = action.newPos.frameName;\n \n // Restore contained shapes to their new positions\n action.containedShapes.forEach(shapeData => {\n restoreShapeGeometry(shapeData.shape, shapeData.newState);\n });\n \n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n action.shape.updateClipPath();\n \n undoStack.push(action);\n return;\n }\n\n \n if (action.type === 'frameAttachment') {\n // Handle frame attachment/detachment redo WITHOUT calling the methods that track undo\n if (action.action === 'attach') {\n // Redo attach: manually add shape to frame\n if (action.oldFrame) {\n // Remove from old frame\n const oldFrameIndex = action.oldFrame.containedShapes.indexOf(action.shape);\n if (oldFrameIndex > -1) {\n action.oldFrame.containedShapes.splice(oldFrameIndex, 1);\n if (action.shape.group && action.shape.group.parentNode === action.oldFrame.clipGroup) {\n action.oldFrame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n }\n \n // Add to new frame\n if (!action.frame.containedShapes.includes(action.shape)) {\n action.frame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.frame;\n \n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.frame.clipGroup.appendChild(action.shape.group);\n }\n }\n } else if (action.action === 'detach') {\n // Redo detach: manually remove shape from frame\n const frameIndex = action.frame.containedShapes.indexOf(action.shape);\n if (frameIndex > -1) {\n action.frame.containedShapes.splice(frameIndex, 1);\n action.shape.parentFrame = null;\n \n if (action.shape.group && action.shape.group.parentNode === action.frame.clipGroup) {\n action.frame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n }\n \n if (typeof action.shape.draw === 'function') {\n action.shape.draw();\n }\n \n undoStack.push(action);\n return;\n }\n\n // Handle mode conversion redo (code \u2194 text)\n if (action.type === 'create' && action.shape.type === 'modeConvert') {\n // Redo: remove the old shape, restore the new shape\n const newShape = action.shape.newShape;\n const newElement = action.shape.newElement;\n const oldShape = action.shape.oldShape;\n const oldElement = action.shape.oldElement;\n\n // Remove old shape from DOM and shapes array\n if (oldElement && oldElement.parentNode) {\n oldElement.parentNode.removeChild(oldElement);\n }\n const oldIdx = shapes.indexOf(oldShape);\n if (oldIdx !== -1) shapes.splice(oldIdx, 1);\n\n // Restore new shape to DOM and shapes array\n if (svg && newElement) {\n svg.appendChild(newElement);\n }\n if (newShape) {\n shapes.push(newShape);\n }\n\n undoStack.push(action);\n return;\n }\n\n if (action.type === 'create') {\n if (action.frameCreation && action.shape.shapeName === 'frame') {\n const frame = action.shape;\n let defs = svg?.querySelector('defs');\n if (!defs && svg) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n if (defs && frame.clipPath && !frame.clipPath.parentNode) defs.appendChild(frame.clipPath);\n if (svg && frame.group && !frame.group.parentNode) svg.appendChild(frame.group);\n if (svg && frame.clipGroup && !frame.clipGroup.parentNode) svg.appendChild(frame.clipGroup);\n if (shapes.indexOf(frame) === -1) {\n const index = action.shapeIndex >= 0 ? Math.min(action.shapeIndex, shapes.length) : shapes.length;\n shapes.splice(index, 0, frame);\n }\n frame.containedShapes = [];\n frame.draw();\n frame.updateClipPath();\n for (const child of action.containedShapes || []) {\n if (child && shapes.includes(child)) frame.addShapeToFrame(child);\n }\n } else\n if (action.shape.type === 'text') {\n // Handle text creation redo\n if (svg) {\n svg.appendChild(action.shape.element || action.shape);\n // Add back to shapes array\n shapes.push(action.shape.element || action.shape);\n }\n }\n else if (action.shape.type === 'image') {\n // Handle image creation redo\n action.shape.restore();\n } else if (action.shape.type === 'icon') {\n // Handle icon creation redo - append the group, not the shape object\n if (svg && action.shape.group) {\n svg.appendChild(action.shape.group);\n }\n // Add back to shapes array\n if (shapes.indexOf(action.shape) === -1) {\n shapes.push(action.shape);\n }\n } else {\n // Handle other shape creation redo\n if (!shapes.includes(action.shape)) shapes.push(action.shape);\n if (svg) {\n svg.appendChild(action.shape.group);\n }\n }\n restoreCreatedShapeFrame(action);\n undoStack.push(action);\n return;\n}\n \n if (action.type === 'delete') {\n detachDeletedShapeFrame(action);\n if (action.shape.type === 'text') {\n // Handle text deletion redo\n if ((action.shape.element || action.shape).parentNode) {\n (action.shape.element || action.shape).parentNode.removeChild(action.shape.element || action.shape);\n }\n // Remove from shapes array\n const idx = shapes.indexOf(action.shape.element || action.shape);\n if (idx !== -1) shapes.splice(idx, 1);\n \n // Clean up arrow attachments again\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Detach from the deleted text\n if (arrow.attachedToStart && arrow.attachedToStart.shape === (action.shape.element || action.shape)) {\n arrow.detachFromShape(true);\n }\n if (arrow.attachedToEnd && arrow.attachedToEnd.shape === (action.shape.element || action.shape)) {\n arrow.detachFromShape(false);\n }\n arrow.draw();\n });\n }\n }\n else if (action.shape.type === 'image') {\n // Handle image deletion redo\n action.shape.remove();\n } else {\n // Handle other shape deletion redo\n const idx = shapes.indexOf(action.shape);\n if (idx !== -1) shapes.splice(idx, 1);\n\n // Issue #24 bug #7: for a regular frame, re-orphan instead of\n // destroy() \u2014 releases children visually, detaches the frame's\n // own DOM bits, but keeps the JS object and child references\n // intact so a subsequent undo can rehydrate again.\n if (action.shape.shapeName === 'frame' && !action.shape._diagramType && action.childSnapshot) {\n for (const child of action.childSnapshot) {\n if (!child) continue;\n const el = child.group || child.element;\n if (el && svg) {\n if (action.shape.clipGroup && el.parentNode === action.shape.clipGroup) {\n action.shape.clipGroup.removeChild(el);\n }\n if (el.parentNode !== svg) svg.appendChild(el);\n }\n child.parentFrame = null;\n delete child.isBeingMovedByFrame;\n }\n action.shape.containedShapes = [];\n if (action.shape.group && action.shape.group.parentNode) action.shape.group.parentNode.removeChild(action.shape.group);\n if (action.shape.clipGroup && action.shape.clipGroup.parentNode) action.shape.clipGroup.parentNode.removeChild(action.shape.clipGroup);\n if (action.shape.clipPath && action.shape.clipPath.parentNode) action.shape.clipPath.parentNode.removeChild(action.shape.clipPath);\n } else {\n if (action.shape.group && action.shape.group.parentNode) {\n action.shape.group.parentNode.removeChild(action.shape.group);\n }\n // Diagram frame OR no snapshot \u2192 fall back to destroy().\n if (action.shape.shapeName === 'frame' && typeof action.shape.destroy === 'function') {\n action.shape.destroy();\n }\n }\n }\n undoStack.push(action);\n return;\n }\n \n if (action.type === 'transform') {\n // Handle frame attachment changes first\n if (action.frameAttachment) {\n // Use manual frame operations to avoid undo recursion\n if (action.frameAttachment.oldFrame) {\n const oldFrameIndex = action.frameAttachment.oldFrame.containedShapes.indexOf(action.shape);\n if (oldFrameIndex > -1) {\n action.frameAttachment.oldFrame.containedShapes.splice(oldFrameIndex, 1);\n if (action.shape.group && action.shape.group.parentNode === action.frameAttachment.oldFrame.clipGroup) {\n action.frameAttachment.oldFrame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n }\n if (action.frameAttachment.newFrame) {\n if (!action.frameAttachment.newFrame.containedShapes.includes(action.shape)) {\n action.frameAttachment.newFrame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.frameAttachment.newFrame;\n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.frameAttachment.newFrame.clipGroup.appendChild(action.shape.group);\n }\n }\n } else {\n action.shape.parentFrame = null;\n }\n }\n \n if (action.shape.type === 'text') {\n // Enhanced text transform redo\n const textElement = (action.shape.element || action.shape).querySelector('text');\n if (textElement && action.newPos.fontSize !== undefined) {\n textElement.setAttribute('font-size', action.newPos.fontSize + 'px');\n }\n \n // Restore position and rotation\n const centerX = textElement ? textElement.getBBox().x + textElement.getBBox().width / 2 : 0;\n const centerY = textElement ? textElement.getBBox().y + textElement.getBBox().height / 2 : 0;\n \n (action.shape.element || action.shape).setAttribute('transform', \n `translate(${action.newPos.x}, ${action.newPos.y}) rotate(${action.newPos.rotation}, ${centerX}, ${centerY})`\n );\n \n (action.shape.element || action.shape).setAttribute('data-x', action.newPos.x);\n (action.shape.element || action.shape).setAttribute('data-y', action.newPos.y);\n \n // Update attached arrows after text redo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to new state\n if (arrowData.newAttachments) {\n arrow.restoreAttachmentState(arrowData.newAttachments);\n } else {\n // If no new attachments stored, recalculate based on current text position\n arrow.updateAttachments();\n }\n });\n }\n \n // Update feedback if selected\n if (selectedElement === (action.shape.element || action.shape) && updateSelectionFeedback) {\n setTimeout(updateSelectionFeedback, 0);\n }\n } else if (action.shape.type === 'image') {\n // Enhanced image transform redo\n action.shape.restore(action.newPos);\n \n // Update attached arrows after image redo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to new state\n if (arrowData.newAttachments) {\n arrow.restoreAttachmentState(arrowData.newAttachments);\n } else {\n // If no new attachments stored, recalculate based on current image position\n arrow.updateAttachments();\n }\n });\n }\n } else if (action.shape.shapeName === 'circle') {\n // Enhanced circle transform redo\n action.shape.x = action.newPos.x;\n action.shape.y = action.newPos.y;\n action.shape.rx = action.newPos.rx;\n action.shape.ry = action.newPos.ry;\n action.shape.rotation = action.newPos.rotation;\n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n\n // Update attached arrows after circle redo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to new state\n if (arrowData.newAttachments) {\n arrow.restoreAttachmentState(arrowData.newAttachments);\n } else {\n // If no new attachments stored, recalculate based on current circle position\n arrow.updateAttachments();\n }\n });\n }\n } else if (action.shape.shapeName === 'line') {\n // Enhanced line transform redo with curve support\n action.shape.startPoint = { x: action.newPos.startPoint.x, y: action.newPos.startPoint.y };\n action.shape.endPoint = { x: action.newPos.endPoint.x, y: action.newPos.endPoint.y };\n \n // Restore curve state\n action.shape.isCurved = action.newPos.isCurved || false;\n if (action.newPos.controlPoint) {\n action.shape.controlPoint = { x: action.newPos.controlPoint.x, y: action.newPos.controlPoint.y };\n } else {\n action.shape.controlPoint = null;\n }\n \n // Handle frame attachment changes\n if (action.frameAttachment) {\n // Remove from old frame if it exists\n if (action.frameAttachment.oldFrame) {\n const oldFrameIndex = action.frameAttachment.oldFrame.containedShapes.indexOf(action.shape);\n if (oldFrameIndex > -1) {\n action.frameAttachment.oldFrame.containedShapes.splice(oldFrameIndex, 1);\n if (action.shape.group && action.shape.group.parentNode === action.frameAttachment.oldFrame.clipGroup) {\n action.frameAttachment.oldFrame.clipGroup.removeChild(action.shape.group);\n svg.appendChild(action.shape.group);\n }\n }\n }\n \n // Add to new frame if it exists\n if (action.frameAttachment.newFrame) {\n if (!action.frameAttachment.newFrame.containedShapes.includes(action.shape)) {\n action.frameAttachment.newFrame.containedShapes.push(action.shape);\n action.shape.parentFrame = action.frameAttachment.newFrame;\n if (action.shape.group && action.shape.group.parentNode === svg) {\n svg.removeChild(action.shape.group);\n action.frameAttachment.newFrame.clipGroup.appendChild(action.shape.group);\n }\n }\n } else {\n action.shape.parentFrame = null;\n }\n }\n \n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n }\n else if (action.shape.shapeName === 'arrow') {\n // Enhanced arrow transform redo with attachment restoration\n action.shape.startPoint = { x: action.newPos.startPoint.x, y: action.newPos.startPoint.y };\n action.shape.endPoint = { x: action.newPos.endPoint.x, y: action.newPos.endPoint.y };\n action.shape.controlPoint1 = action.newPos.controlPoint1 ? \n { x: action.newPos.controlPoint1.x, y: action.newPos.controlPoint1.y } : null;\n action.shape.controlPoint2 = action.newPos.controlPoint2 ? \n { x: action.newPos.controlPoint2.x, y: action.newPos.controlPoint2.y } : null;\n \n // Restore attachment state\n if (action.newPos.attachments) {\n action.shape.restoreAttachmentState(action.newPos.attachments);\n } else {\n // Clear attachments if none should exist\n action.shape.attachedToStart = null;\n action.shape.attachedToEnd = null;\n }\n \n action.shape.isSelected = false;\n action.shape.draw();\n \n } \n else if (action.shape.type === 'icon') {\n action.shape.restore(action.newPos);\n \n // Update attached arrows after icon redo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to new state\n if (arrowData.newAttachments) {\n arrow.restoreAttachmentState(arrowData.newAttachments);\n } else {\n // If no new attachments stored, recalculate based on current icon position\n arrow.updateAttachments();\n }\n });\n }\n }\n else if (action.shape.shapeName === 'freehandStroke') {\n // Handle freehand stroke transform redo\n action.shape.points = JSON.parse(JSON.stringify(action.newPos.points));\n action.shape.rotation = action.newPos.rotation;\n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n } else if (action.shape.shapeName === \"rectangle\") {\n // Enhanced rectangle transform redo\n action.shape.x = action.newPos.x;\n action.shape.y = action.newPos.y;\n action.shape.height = action.newPos.height;\n action.shape.width = action.newPos.width;\n action.shape.rotation = action.newPos.rotation;\n action.shape.isSelected = false;\n if (typeof action.shape.removeSelection === 'function') action.shape.removeSelection();\n action.shape.draw();\n\n // Update attached arrows after rectangle redo\n if (action.affectedArrows) {\n action.affectedArrows.forEach(arrowData => {\n const arrow = arrowData.arrow;\n // Restore arrow attachments to new state\n if (arrowData.newAttachments) {\n arrow.restoreAttachmentState(arrowData.newAttachments);\n } else {\n // If no new attachments stored, recalculate based on current rectangle position\n arrow.updateAttachments();\n }\n });\n }\n }\n undoStack.push(action);\n return;\n }\n \n if (action.type === 'optionsChange') {\n if (action.shape.type === 'text') {\n // Handle text options change redo\n const textElement = (action.shape.element || action.shape).querySelector('text');\n if (textElement) {\n if (action.newOptions.color) textElement.setAttribute('fill', action.newOptions.color);\n if (action.newOptions.font) textElement.setAttribute('font-family', action.newOptions.font);\n if (action.newOptions.size) textElement.setAttribute('font-size', action.newOptions.size);\n if (action.newOptions.align) textElement.setAttribute('text-anchor', action.newOptions.align);\n \n // Update feedback if selected\n if (selectedElement === (action.shape.element || action.shape) && updateSelectionFeedback) {\n setTimeout(updateSelectionFeedback, 0);\n }\n }\n } else if (action.shape.shapeName === 'arrow') {\n action.shape.options = { ...action.newOptions };\n action.shape.arrowOutlineStyle = action.newOptions.arrowOutlineStyle;\n action.shape.arrowHeadStyle = action.newOptions.arrowHeadStyle;\n action.shape.arrowCurved = action.newOptions.arrowCurved;\n action.shape.arrowCurveAmount = action.newOptions.arrowCurveAmount;\n action.shape.draw();\n } else {\n applyOptionsSnapshot(action.shape, action.newOptions);\n }\n undoStack.push(action);\n return;\n }\n } finally {\n refreshSelectionAfterAction();\n notifyCollaboration();\n }\n}\n\n// Optional: Keyboard shortcuts\ndocument.addEventListener('keydown', (e) => {\n if ((e.ctrlKey || e.metaKey) && e.key === 'z') {\n e.preventDefault();\n undo();\n }\n if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.shiftKey && e.key === 'z'))) {\n e.preventDefault();\n redo();\n }\n});\n\n// Attach to buttons\ndocument.getElementById('undo')?.addEventListener('click', undo);\ndocument.getElementById('redo')?.addEventListener('click', redo);\n\n// Expose globally for plain scripts\nwindow.pushCreateAction = pushCreateAction;\nwindow.beginUndoBatch = beginUndoBatch;\nwindow.endUndoBatch = endUndoBatch;\nwindow.pushDeleteAction = pushDeleteAction;\nwindow.pushCanvasResetAction = pushCanvasResetAction;\nwindow.invalidateCanvasResetUndo = invalidateCanvasResetUndo;\nwindow.clearUndoHistory = clearUndoHistory;\nwindow.rebindUndoHistory = rebindUndoHistory;\nwindow.pushDeleteActionWithAttachments = pushDeleteActionWithAttachments;\nwindow.pushTransformAction = pushTransformAction;\nwindow.pushOptionsChangeAction = pushOptionsChangeAction;\nwindow.pushCreateActionWithAttachments = pushCreateActionWithAttachments;\nwindow.undo = undo;\nwindow.redo = redo;\n"],
5
+ "mappings": ";;;AAIA,IAAM,YAAY,CAAC;AACnB,IAAM,YAAY,CAAC;AAEZ,SAAS,iBAAiB;AAC7B,SAAO,EAAE,YAAY,UAAU,OAAO;AAC1C;AAEO,SAAS,aAAa,OAAO,QAAQ,SAAS;AACjD,MAAI,CAAC,SAAS,CAAC,OAAO,UAAU,MAAM,UAAU,EAAG;AACnD,QAAM,aAAa,KAAK,IAAI,KAAK,IAAI,MAAM,YAAY,CAAC,GAAG,UAAU,MAAM;AAC3E,MAAI,UAAU,UAAU,OAAO,UAAU;AACzC,MAAI,QAAQ,WAAW,EAAG;AAC1B,QAAM,gBAAgB,QAAQ,WAAW,IAAI,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,OAAO,QAAQ;AAC1F,YAAU,KAAK,aAAa;AAC5B,YAAU,SAAS;AACnB,sBAAoB;AACpB,SAAO;AACX;AAGA,IAAI,kBAAkB;AACtB,IAAI,0BAA0B;AAC9B,IAAI,MAAM;AAEV,SAAS,sBAAsB;AAC3B,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,yBAAyB,YAAY;AACpF,WAAO,qBAAqB;AAAA,EAChC;AACJ;AAGO,SAAS,kBAAkB,SAAS,UAAU,YAAY;AAC7D,oBAAkB;AAClB,4BAA0B;AAC1B,QAAM;AACV;AAGO,SAAS,4BAA4B;AACxC,SAAO;AACX;AAGO,SAAS,sBAAsB,SAAS;AAC3C,oBAAkB;AACtB;AAGO,SAAS,iBAAiB,OAAO,OAAO,MAAM;AACjD,QAAM,SAAS;AAAA,IACX,MAAM;AAAA,IACN;AAAA,EACJ;AACA,QAAM,cAAc,MAAM,eAAe,OAAO,eAAe;AAC/D,MAAI,aAAa;AACb,WAAO,cAAc;AACrB,UAAM,aAAa,OAAO,UAAU,MAAM,UAAU,IAC9C,KAAK,aACL,YAAY,iBAAiB,QAAQ,KAAK;AAChD,QAAI,OAAO,UAAU,UAAU,KAAK,cAAc,EAAG,QAAO,aAAa;AAAA,EAC7E;AACA,MAAI,MAAM,iBAAiB,OAAO,cAAc,SAAS;AACrD,WAAO,gBAAgB;AACvB,WAAO,kBAAkB,CAAC,GAAI,KAAK,mBAAmB,MAAM,mBAAmB,CAAC,CAAE;AAClF,WAAO,aAAa,MAAM,QAAQ,MAAM,IAAI,OAAO,QAAQ,KAAK,IAAI;AAAA,EACxE;AACA,YAAU,KAAK,MAAM;AAGrB,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEO,SAAS,iBAAiB,OAAO,OAAO,MAAM;AAKjD,QAAM,SAAS,EAAE,MAAM,UAAU,MAAM;AACvC,MAAI,QAAQ,KAAK,cAAe,QAAO,gBAAgB,KAAK;AAC5D,MAAI,OAAO,UAAU,MAAM,UAAU,EAAG,QAAO,aAAa,KAAK;AACjE,MAAI,MAAM,YAAa,QAAO,cAAc,KAAK;AACjD,MAAI,OAAO,UAAU,MAAM,UAAU,EAAG,QAAO,aAAa,KAAK;AACjE,YAAU,KAAK,MAAM;AAGrB,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEO,SAAS,sBAAsB,UAAU,SAAS,OAAO;AAC5D,MAAI,CAAC,YAAY,OAAO,YAAY,cAAc,OAAO,UAAU,WAAY;AAI/E,YAAU,SAAS;AACnB,YAAU,SAAS;AACnB,YAAU,KAAK,EAAE,MAAM,eAAe,UAAU,SAAS,MAAM,CAAC;AACpE;AAEO,SAAS,4BAA4B;AACxC,WAAS,QAAQ,UAAU,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAC3D,QAAI,UAAU,KAAK,GAAG,SAAS,cAAe,WAAU,OAAO,OAAO,CAAC;AAAA,EAC3E;AACA,WAAS,QAAQ,UAAU,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAC3D,QAAI,UAAU,KAAK,GAAG,SAAS,cAAe,WAAU,OAAO,OAAO,CAAC;AAAA,EAC3E;AACJ;AAEO,SAAS,mBAAmB;AAC/B,YAAU,SAAS;AACnB,YAAU,SAAS;AACvB;AAKO,SAAS,kBAAkB,gBAAgB,CAAC,GAAG;AAClD,QAAM,YAAY,IAAI,IAAI,cACrB,OAAO,WAAS,OAAO,OAAO,EAC9B,IAAI,WAAS,CAAC,MAAM,SAAS,KAAK,CAAC,CAAC;AACzC,QAAM,UAAU,oBAAI,QAAQ;AAE5B,QAAM,SAAS,CAAC,UAAU;AACtB,QAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAI,MAAM,QAAS,QAAO,UAAU,IAAI,MAAM,OAAO,KAAK;AAC1D,QAAI,QAAQ,IAAI,KAAK,EAAG,QAAO;AAC/B,YAAQ,IAAI,KAAK;AACjB,QAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,eAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,EAAG,OAAM,KAAK,IAAI,OAAO,MAAM,KAAK,CAAC;AACxF,aAAO;AAAA,IACX;AACA,eAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAClC,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,SAAS,OAAO,UAAU,SAAU,OAAM,GAAG,IAAI,OAAO,KAAK;AAAA,IACrE;AACA,WAAO;AAAA,EACX;AAEA,YAAU,QAAQ,MAAM;AACxB,YAAU,QAAQ,MAAM;AAC5B;AAGO,SAAS,gCAAgC,OAAO;AACnD,MAAI,iBAAiB,CAAC;AAGtB,MAAI,MAAM,SAAS,UAAU,MAAM,cAAc,QAAQ;AACrD,qBAAiB,OAAO,OAAO,OAAK,EAAE,cAAc,YAC/C,EAAE,iBAAiB,UAAU,SAAS,EAAE,eAAe,UAAU,MAAM,EACvE,IAAI,YAAU;AAAA,MACX;AAAA,MACA,gBAAgB,MAAM,mBAAmB;AAAA,MACzC,WAAW;AAAA,QACP,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,QAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,MAClC;AAAA,IACJ,EAAE;AAAA,EACV;AAEA,YAAU,KAAK;AAAA,IACX,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACJ,CAAC;AAGD,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEO,SAAS,0BAA0B,OAAO,OAAO,QAAQ,WAAW,MAAM;AAC7E,YAAU,KAAK;AAAA,IACX,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAEA,YAAY;AAAA,MACR,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,OAAO,MAAM,SAAS;AAAA,MACtB,QAAQ,MAAM,UAAU;AAAA,MACxB,UAAU,MAAM,YAAY;AAAA,IAChC;AAAA,EACJ,CAAC;AAGD,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEO,SAAS,gCAAgC,OAAO;AACnD,YAAU,KAAK;AAAA,IACX,MAAM;AAAA,IACN;AAAA;AAAA,IAEA,sBAAsB,CAAC;AAAA,EAC3B,CAAC;AAGD,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEO,SAAS,oBAAoB,OAAO,QAAQ,QAAQ;AACvD,MAAI,MAAM,cAAc,SAAS;AAM7B,UAAM,eAAe,IAAI,KAAK,OAAO,mBAAmB,CAAC,GAAG,IAAI,WAAS,CAAC,MAAM,OAAO,MAAM,KAAK,CAAC,CAAC;AACpG,UAAM,wBAAwB,MAAM,gBAAgB,IAAI,qBAAmB;AAAA,MACvE,OAAO;AAAA,MACP,UAAU,aAAa,IAAI,cAAc,KAAK;AAAA,QAC1C,GAAG,qBAAqB,cAAc;AAAA,QACtC,GAAG,OAAO,eAAe,MAAM,WAAW,eAAe,KAAK,OAAO,IAAI,OAAO,KAAK,eAAe;AAAA,QACpG,GAAG,OAAO,eAAe,MAAM,WAAW,eAAe,KAAK,OAAO,IAAI,OAAO,KAAK,eAAe;AAAA,MACxG;AAAA,MACA,UAAU,qBAAqB,cAAc;AAAA,IACjD,EAAE;AAEF,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,QACjB,WAAW,OAAO,aAAa,MAAM;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,QACjB,WAAW,OAAO,aAAa,MAAM;AAAA,MACzC;AAAA,MACA,iBAAiB;AAAA,IACrB,CAAC;AAAA,EACL,WAAW,MAAM,SAAS,QAAQ;AAE9B,UAAM,eAAe,MAAM,eAAe;AAE1C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,MACrB;AAAA;AAAA,MAEA,iBAAiB;AAAA,QACb,UAAU,OAAO,eAAe;AAAA,QAChC,UAAU;AAAA,MACd;AAAA;AAAA,MAEA,gBAAgB,OAAO,OAAO,OAAK,EAAE,cAAc,YAC9C,EAAE,iBAAiB,UAAU,SAAS,EAAE,eAAe,UAAU,MAAM,EACvE,IAAI,YAAU;AAAA,QACX;AAAA,QACA,gBAAgB,MAAM,mBAAmB;AAAA,QACzC,WAAW;AAAA,UACP,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,UAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,QAClC;AAAA,MACJ,EAAE;AAAA,IACV,CAAC;AAAA,EACL,WAAW,MAAM,SAAS,SAAS;AAE/B,UAAM,eAAe,MAAM,eAAe;AAE1C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,MACrB;AAAA;AAAA,MAEA,iBAAiB;AAAA,QACb,UAAU,OAAO,eAAe;AAAA,QAChC,UAAU;AAAA,MACd;AAAA;AAAA,MAEA,gBAAgB,OAAO,OAAO,OAAK,EAAE,cAAc,YAC9C,EAAE,iBAAiB,UAAU,SAAS,EAAE,eAAe,UAAU,MAAM,EACvE,IAAI,YAAU;AAAA,QACX;AAAA,QACA,gBAAgB,MAAM,mBAAmB;AAAA,QACzC,WAAW;AAAA,UACP,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,UAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,QAClC;AAAA,MACJ,EAAE;AAAA,IACV,CAAC;AAAA,EACL,WAAW,MAAM,cAAc,UAAU;AAErC,UAAM,eAAe,MAAM,eAAe;AAE1C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,IAAI,OAAO;AAAA,QACX,IAAI,OAAO;AAAA,QACX,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,IAAI,OAAO;AAAA,QACX,IAAI,OAAO;AAAA,QACX,UAAU,OAAO;AAAA,MACrB;AAAA;AAAA,MAEA,iBAAiB;AAAA,QACb,UAAU,OAAO,eAAe;AAAA,QAChC,UAAU;AAAA,MACd;AAAA;AAAA,MAEA,gBAAgB,OAAO,OAAO,OAAK,EAAE,cAAc,YAC9C,EAAE,iBAAiB,UAAU,SAAS,EAAE,eAAe,UAAU,MAAM,EACvE,IAAI,YAAU;AAAA,QACX;AAAA,QACA,gBAAgB,MAAM,mBAAmB;AAAA,QACzC,WAAW;AAAA,UACP,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,UAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,QAClC;AAAA,MACJ,EAAE;AAAA,IACV,CAAC;AAAA,EACL,WAAW,MAAM,cAAc,aAAa;AAExC,UAAM,eAAe,MAAM,eAAe;AAE1C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,MACrB;AAAA;AAAA,MAEA,iBAAiB;AAAA,QACb,UAAU,OAAO,eAAe;AAAA,QAChC,UAAU;AAAA,MACd;AAAA;AAAA,MAEA,gBAAgB,OAAO,OAAO,OAAK,EAAE,cAAc,YAC9C,EAAE,iBAAiB,UAAU,SAAS,EAAE,eAAe,UAAU,MAAM,EACvE,IAAI,YAAU;AAAA,QACX;AAAA,QACA,gBAAgB,MAAM,mBAAmB;AAAA,QACzC,WAAW;AAAA,UACP,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,UAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,QAClC;AAAA,MACJ,EAAE;AAAA,IACV,CAAC;AAAA,EACL,WACS,MAAM,cAAc,QAAQ;AAEjC,UAAM,eAAe,MAAM,eAAe;AAE1C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,YAAY,EAAE,GAAG,OAAO,WAAW,GAAG,GAAG,OAAO,WAAW,EAAE;AAAA,QAC7D,UAAU,EAAE,GAAG,OAAO,SAAS,GAAG,GAAG,OAAO,SAAS,EAAE;AAAA,QACvD,cAAc,OAAO,eAAe,EAAE,GAAG,OAAO,aAAa,GAAG,GAAG,OAAO,aAAa,EAAE,IAAI;AAAA,QAC7F,UAAU,OAAO,YAAY;AAAA,MACjC;AAAA,MACA,QAAQ;AAAA,QACJ,YAAY,EAAE,GAAG,OAAO,WAAW,GAAG,GAAG,OAAO,WAAW,EAAE;AAAA,QAC7D,UAAU,EAAE,GAAG,OAAO,SAAS,GAAG,GAAG,OAAO,SAAS,EAAE;AAAA,QACvD,cAAc,OAAO,eAAe,EAAE,GAAG,OAAO,aAAa,GAAG,GAAG,OAAO,aAAa,EAAE,IAAI;AAAA,QAC7F,UAAU,OAAO,YAAY;AAAA,MACjC;AAAA;AAAA,MAEA,iBAAiB;AAAA,QACb,UAAU,OAAO,eAAe;AAAA,QAChC,UAAU;AAAA,MACd;AAAA,IACJ,CAAC;AAAA,EACL,WACU,MAAM,cAAc,SAAS;AAEnC,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,YAAY,EAAE,GAAG,OAAO,WAAW,GAAG,GAAG,OAAO,WAAW,EAAE;AAAA,QAC7D,UAAU,EAAE,GAAG,OAAO,SAAS,GAAG,GAAG,OAAO,SAAS,EAAE;AAAA,QACvD,eAAe,OAAO,gBAAgB,EAAE,GAAG,OAAO,cAAc,GAAG,GAAG,OAAO,cAAc,EAAE,IAAI;AAAA,QACjG,eAAe,OAAO,gBAAgB,EAAE,GAAG,OAAO,cAAc,GAAG,GAAG,OAAO,cAAc,EAAE,IAAI;AAAA,QACjG,aAAa,OAAO,eAAe,MAAM,mBAAmB;AAAA,MAChE;AAAA,MACA,QAAQ;AAAA,QACJ,YAAY,EAAE,GAAG,OAAO,WAAW,GAAG,GAAG,OAAO,WAAW,EAAE;AAAA,QAC7D,UAAU,EAAE,GAAG,OAAO,SAAS,GAAG,GAAG,OAAO,SAAS,EAAE;AAAA,QACvD,eAAe,OAAO,gBAAgB,EAAE,GAAG,OAAO,cAAc,GAAG,GAAG,OAAO,cAAc,EAAE,IAAI;AAAA,QACjG,eAAe,OAAO,gBAAgB,EAAE,GAAG,OAAO,cAAc,GAAG,GAAG,OAAO,cAAc,EAAE,IAAI;AAAA,QACjG,aAAa,OAAO,eAAe,MAAM,mBAAmB;AAAA,MAChE;AAAA,IACJ,CAAC;AAAA,EACL,WACS,MAAM,SAAS,QAAQ;AAEhC,UAAM,eAAe,MAAM,eAAe;AAE1C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,QACJ,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,MACrB;AAAA;AAAA,MAEA,iBAAiB;AAAA,QACb,UAAU,OAAO,eAAe;AAAA,QAChC,UAAU;AAAA,MACd;AAAA;AAAA,MAEA,gBAAgB,OAAO,OAAO,OAAK,EAAE,cAAc,YAC9C,EAAE,iBAAiB,UAAU,SAAS,EAAE,eAAe,UAAU,MAAM,EACvE,IAAI,YAAU;AAAA,QACX;AAAA,QACA,gBAAgB,MAAM,mBAAmB;AAAA,QACzC,WAAW;AAAA,UACP,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,UAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,QAClC;AAAA,MACJ,EAAE;AAAA,IACV,CAAC;AAAA,EACL,WAEa,MAAM,cAAc,kBAAkB;AAE3C,cAAU,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACJ,QAAQ,KAAK,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,QAChD,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,QACJ,QAAQ,KAAK,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,QAChD,UAAU,OAAO;AAAA,MACrB;AAAA,IACJ,CAAC;AAAA,EACL;AAGA,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEA,SAAS,WAAW,OAAO;AACvB,SAAO,QAAQ,EAAE,GAAG,MAAM,IAAI;AAClC;AAEO,SAAS,qBAAqB,OAAO;AACxC,QAAM,QAAQ;AAAA,IACV,GAAG,MAAM;AAAA,IACT,GAAG,MAAM;AAAA,IACT,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM;AAAA,IACd,UAAU,MAAM,YAAY;AAAA,EAChC;AACA,MAAI,OAAO,MAAM,OAAO,SAAU,OAAM,KAAK,MAAM;AACnD,MAAI,OAAO,MAAM,OAAO,SAAU,OAAM,KAAK,MAAM;AACnD,MAAI,MAAM,WAAY,OAAM,aAAa,WAAW,MAAM,UAAU;AACpE,MAAI,MAAM,SAAU,OAAM,WAAW,WAAW,MAAM,QAAQ;AAC9D,MAAI,MAAM,cAAe,OAAM,gBAAgB,WAAW,MAAM,aAAa;AAC7E,MAAI,MAAM,cAAe,OAAM,gBAAgB,WAAW,MAAM,aAAa;AAC7E,MAAI,MAAM,QAAQ,MAAM,MAAM,EAAG,OAAM,SAAS,MAAM,OAAO,IAAI,WAAS,MAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,KAAK;AACnH,MAAI,OAAO,MAAM,iBAAiB,SAAU,OAAM,eAAe,MAAM;AACvE,MAAI,OAAO,MAAM,iBAAiB,SAAU,OAAM,eAAe,MAAM;AACvE,SAAO;AACX;AAEO,SAAS,wBAAwB,OAAO;AAC3C,UAAQ,OAAO,mBAAmB,CAAC,GAAG,IAAI,YAAU,EAAE,OAAO,OAAO,qBAAqB,KAAK,EAAE,EAAE;AACtG;AAEA,SAAS,qBAAqB,OAAO,OAAO;AACxC,MAAI,CAAC,SAAS,CAAC,MAAO;AACtB,aAAW,OAAO,CAAC,KAAK,KAAK,SAAS,UAAU,YAAY,MAAM,MAAM,gBAAgB,cAAc,GAAG;AACrG,QAAI,MAAM,GAAG,MAAM,OAAW,OAAM,GAAG,IAAI,MAAM,GAAG;AAAA,EACxD;AACA,aAAW,OAAO,CAAC,cAAc,YAAY,iBAAiB,eAAe,GAAG;AAC5E,QAAI,MAAM,GAAG,MAAM,OAAW,OAAM,GAAG,IAAI,WAAW,MAAM,GAAG,CAAC;AAAA,EACpE;AACA,MAAI,MAAM,OAAQ,OAAM,SAAS,MAAM,OAAO,IAAI,WAAS,MAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,KAAK;AACpG,MAAI,OAAO,MAAM,sBAAsB,WAAY,OAAM,kBAAkB;AAC3E,MAAI,OAAO,MAAM,SAAS,WAAY,OAAM,KAAK;AACrD;AAEO,SAAS,wBAAwB,OAAO,YAAY,aAAa,MAAM;AAC1E,YAAU,KAAK;AAAA,IACX,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACJ,CAAC;AAGD,YAAU,SAAS;AACnB,sBAAoB;AACxB;AAEA,SAAS,qBAAqB,OAAO,SAAS;AAC1C,QAAM,UAAU,EAAE,GAAG,QAAQ;AAC7B,MAAI,MAAM,cAAc,SAAS;AAC7B,UAAM,YAAY,QAAQ;AAC1B,UAAM,YAAY,QAAQ;AAAA,EAC9B;AACA,QAAM,KAAK;AACf;AAMA,SAAS,8BAA8B;AACnC,QAAM,KAAM,OAAO,WAAW,cAAe,OAAO,iBAAiB;AACrE,MAAI,CAAC,GAAI;AACT,MAAI,OAAO,GAAG,mBAAmB,WAAY;AAC7C,MAAI,CAAC,GAAG,kBAAkB,GAAG,eAAe,SAAS,EAAG;AACxD,MAAI;AAAE,OAAG,eAAe;AAAA,EAAG,SAAS,KAAK;AAAE,YAAQ,KAAK,wCAAwC,GAAG;AAAA,EAAG;AAC1G;AAEA,SAAS,yBAAyB,QAAQ;AACtC,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,SAAS,CAAC,SAAS,OAAO,MAAM,oBAAoB,WAAY;AACrE,QAAM,gBAAgB,KAAK;AAC3B,MAAI,OAAO,UAAU,OAAO,UAAU,KAAK,MAAM,QAAQ,MAAM,eAAe,GAAG;AAC7E,UAAM,eAAe,MAAM,gBAAgB,QAAQ,KAAK;AACxD,QAAI,gBAAgB,EAAG,OAAM,gBAAgB,OAAO,cAAc,CAAC;AACnE,UAAM,cAAc,KAAK,IAAI,KAAK,IAAI,OAAO,YAAY,CAAC,GAAG,MAAM,gBAAgB,MAAM;AACzF,UAAM,gBAAgB,OAAO,aAAa,GAAG,KAAK;AAClD,UAAM,UAAU,MAAM,SAAS,MAAM;AACrC,UAAM,YAAY,MAAM,gBAAgB,cAAc,CAAC;AACvD,UAAM,cAAc,WAAW,SAAS,WAAW;AACnD,QAAI,WAAW,MAAM,aAAa,aAAa,eAAe,MAAM,WAAW;AAC3E,YAAM,UAAU,aAAa,SAAS,WAAW;AAAA,IACrD;AAAA,EACJ;AACJ;AAEA,SAAS,wBAAwB,QAAQ;AACrC,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,OAAO;AACrB,MAAI,SAAS,SAAS,OAAO,MAAM,yBAAyB,cAAc,MAAM,gBAAgB,OAAO;AACnG,UAAM,qBAAqB,KAAK;AAAA,EACpC;AACJ;AAEA,SAAS,yBAAyB,QAAQ;AACtC,MAAI,CAAC,OAAO,YAAa;AACzB,2BAAyB,MAAM;AACnC;AAEA,SAAS,wBAAwB,QAAQ;AACrC,MAAI,CAAC,OAAO,YAAa;AACzB,0BAAwB,MAAM;AAClC;AAEO,SAAS,OAAO;AACnB,MAAI,UAAU,WAAW,EAAG;AAC5B,QAAM,SAAS,UAAU,IAAI;AAC7B,MAAI;AACJ,QAAI,OAAO,SAAS,SAAS;AACzB,eAAS,QAAQ,OAAO,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAChE,kBAAU,KAAK,OAAO,QAAQ,KAAK,CAAC;AACpC,aAAK;AACL,kBAAU,IAAI;AAAA,MAClB;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,eAAe;AAC/B,aAAO,QAAQ,OAAO,QAAQ;AAC9B,gBAAU,KAAK,MAAM;AACrB,0BAAoB;AACpB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,kBAAkB;AAElC,aAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,aAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,aAAO,MAAM,QAAQ,OAAO,OAAO;AACnC,aAAO,MAAM,SAAS,OAAO,OAAO;AACpC,aAAO,MAAM,WAAW,OAAO,OAAO;AACtC,aAAO,MAAM,YAAY,OAAO,OAAO;AAGvC,aAAO,gBAAgB,QAAQ,eAAa;AACxC,6BAAqB,UAAU,OAAO,UAAU,QAAQ;AAAA,MAC5D,CAAC;AAED,aAAO,MAAM,aAAa;AAC1B,UAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,aAAO,MAAM,KAAK;AAClB,aAAO,MAAM,eAAe;AAE5B,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,mBAAmB;AAEnC,UAAI,OAAO,WAAW,UAAU;AAE5B,cAAM,aAAa,OAAO,MAAM,gBAAgB,QAAQ,OAAO,KAAK;AACpE,YAAI,aAAa,IAAI;AACjB,iBAAO,MAAM,gBAAgB,OAAO,YAAY,CAAC;AACjD,iBAAO,MAAM,cAAc;AAG3B,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,MAAM,WAAW;AAChF,mBAAO,MAAM,UAAU,YAAY,OAAO,MAAM,KAAK;AACrD,gBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,UACtC;AAAA,QACJ;AAGA,YAAI,OAAO,UAAU;AACjB,iBAAO,SAAS,gBAAgB,KAAK,OAAO,KAAK;AACjD,iBAAO,MAAM,cAAc,OAAO;AAGlC,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,gBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,mBAAO,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,UAC5D;AAAA,QACJ;AAAA,MACJ,WAAW,OAAO,WAAW,UAAU;AAEnC,YAAI,CAAC,OAAO,MAAM,gBAAgB,SAAS,OAAO,KAAK,GAAG;AACtD,iBAAO,MAAM,gBAAgB,KAAK,OAAO,KAAK;AAC9C,iBAAO,MAAM,cAAc,OAAO;AAGlC,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,gBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,mBAAO,MAAM,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,UACzD;AAAA,QACJ;AAAA,MACJ;AAGA,aAAO,MAAM,IAAI,OAAO,WAAW;AACnC,aAAO,MAAM,IAAI,OAAO,WAAW;AACnC,aAAO,MAAM,QAAQ,OAAO,WAAW;AACvC,aAAO,MAAM,SAAS,OAAO,WAAW;AACxC,aAAO,MAAM,WAAW,OAAO,WAAW;AAE1C,UAAI,OAAO,OAAO,MAAM,SAAS,YAAY;AACzC,eAAO,MAAM,KAAK;AAAA,MACtB;AAEA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAGA,QAAI,OAAO,SAAS,YAAY,OAAO,MAAM,SAAS,eAAe;AAEjE,YAAM,WAAW,OAAO,MAAM;AAC9B,YAAM,aAAa,OAAO,MAAM;AAChC,YAAM,WAAW,OAAO,MAAM;AAC9B,YAAM,aAAa,OAAO,MAAM;AAGhC,UAAI,cAAc,WAAW,YAAY;AACrC,mBAAW,WAAW,YAAY,UAAU;AAAA,MAChD;AACA,YAAM,SAAS,OAAO,QAAQ,QAAQ;AACtC,UAAI,WAAW,GAAI,QAAO,OAAO,QAAQ,CAAC;AAG1C,UAAI,OAAO,YAAY;AACnB,YAAI,YAAY,UAAU;AAAA,MAC9B;AACA,UAAI,UAAU;AACV,eAAO,KAAK,QAAQ;AAAA,MACxB;AAEA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,UAAU;AAC9B,8BAAwB,MAAM;AAC9B,UAAI,OAAO,iBAAiB,OAAO,MAAM,cAAc,SAAS;AAI5D,mBAAW,SAAS,OAAO,mBAAmB,CAAC,GAAG;AAC9C,cAAI,OAAO,gBAAgB,OAAO,MAAO,QAAO,MAAM,qBAAqB,KAAK;AAAA,QACpF;AACA,YAAI,iBAAiB,OAAO,OAAO;AAC/B,iBAAO,MAAM,kBAAkB;AAC/B,yBAAe;AAAA,QACnB;AACA,cAAM,MAAM,OAAO,QAAQ,OAAO,KAAK;AACvC,YAAI,QAAQ,GAAI,QAAO,OAAO,KAAK,CAAC;AACpC,eAAO,MAAM,OAAO,OAAO;AAC3B,eAAO,MAAM,WAAW,OAAO;AAC/B,eAAO,MAAM,UAAU,OAAO;AAAA,MAClC,WACI,OAAO,MAAM,SAAS,QAAQ;AAE9B,YAAI,OAAO,MAAM,WAAW,OAAO,MAAM,QAAQ,YAAY;AACzD,iBAAO,MAAM,QAAQ,WAAW,YAAY,OAAO,MAAM,OAAO;AAAA,QACpE,WAAW,OAAO,MAAM,YAAY;AAChC,iBAAO,MAAM,WAAW,YAAY,OAAO,KAAK;AAAA,QACpD;AAGA,cAAM,MAAM,OAAO,QAAQ,OAAO,MAAM,WAAW,OAAO,KAAK;AAC/D,YAAI,QAAQ,GAAI,QAAO,OAAO,KAAK,CAAC;AAGpC,YAAI,OAAO,uBAAuB,YAAY;AAC1C,6BAAmB,OAAO,MAAM,WAAW,OAAO,KAAK;AAAA,QAC3D;AAAA,MACJ,WAAW,OAAO,MAAM,SAAS,SAAS;AAEtC,eAAO,MAAM,OAAO;AAAA,MACxB,WAAW,OAAO,MAAM,SAAS,QAAQ;AAErC,eAAO,MAAM,OAAO;AAAA,MACxB,OAAO;AAEH,cAAM,MAAM,OAAO,QAAQ,OAAO,KAAK;AACvC,YAAI,QAAQ,GAAI,QAAO,OAAO,KAAK,CAAC;AACpC,YAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,YAAY;AACrD,iBAAO,MAAM,MAAM,WAAW,YAAY,OAAO,MAAM,KAAK;AAAA,QAChE;AAGA,YAAI,OAAO,MAAM,cAAc,SAAS;AACpC,iBAAO,MAAM,QAAQ;AAAA,QACzB;AAAA,MACJ;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEI,QAAI,OAAO,SAAS,UAAU;AAC1B,UAAI,OAAO,MAAM,SAAS,QAAQ;AAE9B,YAAI,KAAK;AACL,cAAI,YAAY,OAAO,MAAM,WAAW,OAAO,KAAK;AAEpD,iBAAO,KAAK,OAAO,MAAM,WAAW,OAAO,KAAK;AAAA,QACpD;AAGA,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,kBAAM,uBAAuB,UAAU,cAAc;AAAA,UACzD,CAAC;AAAA,QACL;AAAA,MACJ,WAAW,OAAO,MAAM,SAAS,SAAS;AAEtC,eAAO,MAAM,QAAQ;AAAA,MACzB,OAAO;AAEH,YAAI,OAAO,QAAQ,OAAO,KAAK,MAAM,IAAI;AACrC,gBAAM,QAAQ,OAAO,UAAU,OAAO,UAAU,IAC1C,KAAK,IAAI,KAAK,IAAI,OAAO,YAAY,CAAC,GAAG,OAAO,MAAM,IACtD,OAAO;AACb,iBAAO,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,QACxC;AACA,YAAI,KAAK;AACL,cAAI,YAAY,OAAO,MAAM,KAAK;AAAA,QACtC;AASA,YAAI,OAAO,MAAM,cAAc,WAAW,KAAK;AAC3C,cAAI,OAAO,MAAM,aAAa,CAAC,OAAO,MAAM,UAAU,YAAY;AAC9D,gBAAI,YAAY,OAAO,MAAM,SAAS;AAAA,UAC1C;AACA,cAAI,OAAO,MAAM,YAAY,CAAC,OAAO,MAAM,SAAS,YAAY;AAC5D,kBAAM,OAAO,IAAI,cAAc,MAAM;AACrC,gBAAI,KAAM,MAAK,YAAY,OAAO,MAAM,QAAQ;AAAA,gBAC3C,KAAI,aAAa,OAAO,MAAM,UAAU,IAAI,UAAU;AAAA,UAC/D;AACA,cAAI,OAAO,iBAAiB,MAAM,QAAQ,OAAO,aAAa,GAAG;AAC7D,uBAAW,SAAS,OAAO,eAAe;AACtC,kBAAI,CAAC,MAAO;AACZ,kBAAI,OAAO,QAAQ,KAAK,MAAM,GAAI;AAClC,kBAAI,OAAO,OAAO,MAAM,oBAAoB,YAAY;AACpD,uBAAO,MAAM,gBAAgB,KAAK;AAAA,cACtC;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AACA,+BAAyB,MAAM;AAC/B,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,aAAa;AAE7B,UAAI,OAAO,iBAAiB;AAExB,YAAI,OAAO,gBAAgB,UAAU;AACjC,gBAAM,aAAa,OAAO,gBAAgB,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AACvF,cAAI,aAAa,IAAI;AACjB,mBAAO,gBAAgB,SAAS,gBAAgB,OAAO,YAAY,CAAC;AACpE,gBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,gBAAgB,SAAS,WAAW;AACnG,qBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AACxE,kBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,YACtC;AAAA,UACJ;AAAA,QACJ;AACA,YAAI,OAAO,gBAAgB,UAAU;AACjC,cAAI,CAAC,OAAO,gBAAgB,SAAS,gBAAgB,SAAS,OAAO,KAAK,GAAG;AACzE,mBAAO,gBAAgB,SAAS,gBAAgB,KAAK,OAAO,KAAK;AACjE,mBAAO,MAAM,cAAc,OAAO,gBAAgB;AAClD,gBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,kBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,qBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,YAC5E;AAAA,UACJ;AAAA,QACJ,OAAO;AACH,iBAAO,MAAM,cAAc;AAAA,QAC/B;AAAA,MACJ;AAEA,UAAI,OAAO,MAAM,SAAS,QAAQ;AAE9B,cAAM,eAAe,OAAO,MAAM,WAAW,OAAO,OAAO,cAAc,MAAM;AAC/E,YAAI,eAAe,OAAO,OAAO,aAAa,QAAW;AACrD,sBAAY,aAAa,aAAa,OAAO,OAAO,WAAW,IAAI;AAAA,QACvE;AAGA,cAAM,UAAU,cAAc,YAAY,QAAQ,EAAE,IAAI,YAAY,QAAQ,EAAE,QAAQ,IAAI;AAC1F,cAAM,UAAU,cAAc,YAAY,QAAQ,EAAE,IAAI,YAAY,QAAQ,EAAE,SAAS,IAAI;AAE3F,SAAC,OAAO,MAAM,WAAW,OAAO,OAAO;AAAA,UAAa;AAAA,UAChD,aAAa,OAAO,OAAO,CAAC,KAAK,OAAO,OAAO,CAAC,YAAY,OAAO,OAAO,QAAQ,KAAK,OAAO,KAAK,OAAO;AAAA,QAC9G;AAEA,SAAC,OAAO,MAAM,WAAW,OAAO,OAAO,aAAa,UAAU,OAAO,OAAO,CAAC;AAC7E,SAAC,OAAO,MAAM,WAAW,OAAO,OAAO,aAAa,UAAU,OAAO,OAAO,CAAC;AAG7E,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,kBAAM,uBAAuB,UAAU,cAAc;AAGrD,sBAAU,YAAY;AAAA,cAClB,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,cAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,YAClC;AACA,sBAAU,iBAAiB,MAAM,mBAAmB;AAAA,UACxD,CAAC;AAAA,QACL;AAGA,YAAI,qBAAqB,OAAO,MAAM,WAAW,OAAO,UAAU,yBAAyB;AACvF,qBAAW,yBAAyB,CAAC;AAAA,QACzC;AAAA,MACJ,WAAW,OAAO,MAAM,SAAS,SAAS;AAEtC,eAAO,MAAM,QAAQ,OAAO,MAAM;AAGlC,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,kBAAM,uBAAuB,UAAU,cAAc;AAGrD,sBAAU,YAAY;AAAA,cAClB,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,cAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,YAClC;AACA,sBAAU,iBAAiB,MAAM,mBAAmB;AAAA,UACxD,CAAC;AAAA,QACL;AAAA,MACJ,WAAW,OAAO,MAAM,cAAc,UAAU;AAE5C,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,KAAK,OAAO,OAAO;AAChC,eAAO,MAAM,KAAK,OAAO,OAAO;AAChC,eAAO,MAAM,WAAW,OAAO,OAAO;AACtC,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAGlB,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,kBAAM,uBAAuB,UAAU,cAAc;AAGrD,sBAAU,YAAY;AAAA,cAClB,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,cAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,YAClC;AACA,sBAAU,iBAAiB,MAAM,mBAAmB;AAAA,UACxD,CAAC;AAAA,QACL;AAAA,MACJ,WAAW,OAAO,MAAM,cAAc,QAAQ;AAE1C,eAAO,MAAM,aAAa,EAAE,GAAG,OAAO,OAAO,WAAW,GAAG,GAAG,OAAO,OAAO,WAAW,EAAE;AACzF,eAAO,MAAM,WAAW,EAAE,GAAG,OAAO,OAAO,SAAS,GAAG,GAAG,OAAO,OAAO,SAAS,EAAE;AAGnF,eAAO,MAAM,WAAW,OAAO,OAAO,YAAY;AAClD,YAAI,OAAO,OAAO,cAAc;AAC5B,iBAAO,MAAM,eAAe,EAAE,GAAG,OAAO,OAAO,aAAa,GAAG,GAAG,OAAO,OAAO,aAAa,EAAE;AAAA,QACnG,OAAO;AACH,iBAAO,MAAM,eAAe;AAAA,QAChC;AAGA,YAAI,OAAO,iBAAiB;AAExB,cAAI,OAAO,gBAAgB,UAAU;AACjC,kBAAM,aAAa,OAAO,gBAAgB,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AACvF,gBAAI,aAAa,IAAI;AACjB,qBAAO,gBAAgB,SAAS,gBAAgB,OAAO,YAAY,CAAC;AACpE,kBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,gBAAgB,SAAS,WAAW;AACnG,uBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AACxE,oBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,cACtC;AAAA,YACJ;AAAA,UACJ;AAGA,cAAI,OAAO,gBAAgB,UAAU;AACjC,gBAAI,CAAC,OAAO,gBAAgB,SAAS,gBAAgB,SAAS,OAAO,KAAK,GAAG;AACzE,qBAAO,gBAAgB,SAAS,gBAAgB,KAAK,OAAO,KAAK;AACjE,qBAAO,MAAM,cAAc,OAAO,gBAAgB;AAClD,kBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,oBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,uBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,cAC5E;AAAA,YACJ;AAAA,UACJ,OAAO;AACH,mBAAO,MAAM,cAAc;AAAA,UAC/B;AAAA,QACJ;AAEA,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAAA,MACtB,WACU,OAAO,MAAM,cAAc,SAAS;AAE1C,eAAO,MAAM,aAAa,EAAE,GAAG,OAAO,OAAO,WAAW,GAAG,GAAG,OAAO,OAAO,WAAW,EAAE;AACzF,eAAO,MAAM,WAAW,EAAE,GAAG,OAAO,OAAO,SAAS,GAAG,GAAG,OAAO,OAAO,SAAS,EAAE;AACnF,eAAO,MAAM,gBAAgB,OAAO,OAAO,gBACvC,EAAE,GAAG,OAAO,OAAO,cAAc,GAAG,GAAG,OAAO,OAAO,cAAc,EAAE,IAAI;AAC7E,eAAO,MAAM,gBAAgB,OAAO,OAAO,gBACvC,EAAE,GAAG,OAAO,OAAO,cAAc,GAAG,GAAG,OAAO,OAAO,cAAc,EAAE,IAAI;AAG7E,YAAI,OAAO,OAAO,aAAa;AAC3B,iBAAO,MAAM,uBAAuB,OAAO,OAAO,WAAW;AAAA,QACjE,OAAO;AAEH,iBAAO,MAAM,kBAAkB;AAC/B,iBAAO,MAAM,gBAAgB;AAAA,QACjC;AAEA,eAAO,MAAM,aAAa;AAC1B,eAAO,MAAM,KAAK;AAAA,MAItB,WACS,OAAO,MAAM,SAAS,QAAQ;AAEnC,eAAO,MAAM,QAAQ,OAAO,MAAM;AAGlC,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,kBAAM,uBAAuB,UAAU,cAAc;AAGrD,sBAAU,YAAY;AAAA,cAClB,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,cAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,YAClC;AACA,sBAAU,iBAAiB,MAAM,mBAAmB;AAAA,UACxD,CAAC;AAAA,QACL;AAAA,MACJ,WACS,OAAO,MAAM,cAAc,kBAAkB;AAElD,eAAO,MAAM,SAAS,KAAK,MAAM,KAAK,UAAU,OAAO,OAAO,MAAM,CAAC;AACrE,eAAO,MAAM,WAAW,OAAO,OAAO;AACtC,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAAA,MACtB,WAAW,OAAO,MAAM,cAAc,aAAa;AAC/C,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,SAAS,OAAO,OAAO;AACpC,eAAO,MAAM,QAAQ,OAAO,OAAO;AACnC,eAAO,MAAM,WAAW,OAAO,OAAO;AACtC,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAGlB,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AACxB,kBAAM,uBAAuB,UAAU,cAAc;AACrD,sBAAU,YAAY;AAAA,cAClB,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,cAClC,UAAU,EAAE,GAAG,MAAM,SAAS;AAAA,YAClC;AACA,sBAAU,iBAAiB,MAAM,mBAAmB;AAAA,UACxD,CAAC;AAAA,QACL;AAAA,MACJ;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,iBAAiB;AACjC,UAAI,CAAC,OAAO,cAAc,OAAO,OAAO,SAAS;AAC7C,eAAO,aAAa,OAAO,MAAM,cAAc,UACzC;AAAA,UACE,GAAG,OAAO,MAAM;AAAA,UAChB,mBAAmB,OAAO,MAAM;AAAA,UAChC,gBAAgB,OAAO,MAAM;AAAA,UAC7B,aAAa,OAAO,MAAM;AAAA,UAC1B,kBAAkB,OAAO,MAAM;AAAA,QACnC,IACE,EAAE,GAAG,OAAO,MAAM,QAAQ;AAAA,MACpC;AACA,UAAI,OAAO,MAAM,SAAS,QAAQ;AAE9B,cAAM,eAAe,OAAO,MAAM,WAAW,OAAO,OAAO,cAAc,MAAM;AAC/E,YAAI,aAAa;AACb,cAAI,OAAO,WAAW,MAAO,aAAY,aAAa,QAAQ,OAAO,WAAW,KAAK;AACrF,cAAI,OAAO,WAAW,KAAM,aAAY,aAAa,eAAe,OAAO,WAAW,IAAI;AAC1F,cAAI,OAAO,WAAW,KAAM,aAAY,aAAa,aAAa,OAAO,WAAW,IAAI;AACxF,cAAI,OAAO,WAAW,MAAO,aAAY,aAAa,eAAe,OAAO,WAAW,KAAK;AAG5F,cAAI,qBAAqB,OAAO,MAAM,WAAW,OAAO,UAAU,yBAAyB;AACvF,uBAAW,yBAAyB,CAAC;AAAA,UACzC;AAAA,QACJ;AAAA,MACJ,WAAW,OAAO,MAAM,cAAc,SAAS;AAE3C,eAAO,MAAM,UAAU,EAAE,GAAG,OAAO,WAAW;AAC9C,eAAO,MAAM,oBAAoB,OAAO,WAAW;AACnD,eAAO,MAAM,iBAAiB,OAAO,WAAW;AAChD,eAAO,MAAM,cAAc,OAAO,WAAW;AAC7C,eAAO,MAAM,mBAAmB,OAAO,WAAW;AAClD,eAAO,MAAM,KAAK;AAAA,MACtB,OAAO;AAEH,6BAAqB,OAAO,OAAO,OAAO,UAAU;AAAA,MACxD;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAAA,EACA,UAAE;AACE,gCAA4B;AAC5B,wBAAoB;AAAA,EACxB;AACJ;AAEO,SAAS,OAAO;AACnB,MAAI,UAAU,WAAW,EAAG;AAC5B,QAAM,SAAS,UAAU,IAAI;AAC7B,MAAI;AACJ,QAAI,OAAO,SAAS,SAAS;AACzB,iBAAW,eAAe,OAAO,SAAS;AACtC,kBAAU,KAAK,WAAW;AAC1B,aAAK;AACL,kBAAU,IAAI;AAAA,MAClB;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,eAAe;AAC/B,aAAO,MAAM;AACb,gBAAU,KAAK,MAAM;AACrB,0BAAoB;AACpB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,kBAAkB;AAElC,aAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,aAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,aAAO,MAAM,QAAQ,OAAO,OAAO;AACnC,aAAO,MAAM,SAAS,OAAO,OAAO;AACpC,aAAO,MAAM,WAAW,OAAO,OAAO;AACtC,aAAO,MAAM,YAAY,OAAO,OAAO;AAGvC,aAAO,gBAAgB,QAAQ,eAAa;AACxC,6BAAqB,UAAU,OAAO,UAAU,QAAQ;AAAA,MAC5D,CAAC;AAED,aAAO,MAAM,aAAa;AAC1B,UAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,aAAO,MAAM,KAAK;AAClB,aAAO,MAAM,eAAe;AAE5B,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAGA,QAAI,OAAO,SAAS,mBAAmB;AAEnC,UAAI,OAAO,WAAW,UAAU;AAE5B,YAAI,OAAO,UAAU;AAEjB,gBAAM,gBAAgB,OAAO,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AAC1E,cAAI,gBAAgB,IAAI;AACpB,mBAAO,SAAS,gBAAgB,OAAO,eAAe,CAAC;AACvD,gBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,SAAS,WAAW;AACnF,qBAAO,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AACxD,kBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,YACtC;AAAA,UACJ;AAAA,QACJ;AAGA,YAAI,CAAC,OAAO,MAAM,gBAAgB,SAAS,OAAO,KAAK,GAAG;AACtD,iBAAO,MAAM,gBAAgB,KAAK,OAAO,KAAK;AAC9C,iBAAO,MAAM,cAAc,OAAO;AAElC,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,gBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,mBAAO,MAAM,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,UACzD;AAAA,QACJ;AAAA,MACJ,WAAW,OAAO,WAAW,UAAU;AAEnC,cAAM,aAAa,OAAO,MAAM,gBAAgB,QAAQ,OAAO,KAAK;AACpE,YAAI,aAAa,IAAI;AACjB,iBAAO,MAAM,gBAAgB,OAAO,YAAY,CAAC;AACjD,iBAAO,MAAM,cAAc;AAE3B,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,MAAM,WAAW;AAChF,mBAAO,MAAM,UAAU,YAAY,OAAO,MAAM,KAAK;AACrD,gBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,UACtC;AAAA,QACJ;AAAA,MACJ;AAEA,UAAI,OAAO,OAAO,MAAM,SAAS,YAAY;AACzC,eAAO,MAAM,KAAK;AAAA,MACtB;AAEA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAGA,QAAI,OAAO,SAAS,YAAY,OAAO,MAAM,SAAS,eAAe;AAEjE,YAAM,WAAW,OAAO,MAAM;AAC9B,YAAM,aAAa,OAAO,MAAM;AAChC,YAAM,WAAW,OAAO,MAAM;AAC9B,YAAM,aAAa,OAAO,MAAM;AAGhC,UAAI,cAAc,WAAW,YAAY;AACrC,mBAAW,WAAW,YAAY,UAAU;AAAA,MAChD;AACA,YAAM,SAAS,OAAO,QAAQ,QAAQ;AACtC,UAAI,WAAW,GAAI,QAAO,OAAO,QAAQ,CAAC;AAG1C,UAAI,OAAO,YAAY;AACnB,YAAI,YAAY,UAAU;AAAA,MAC9B;AACA,UAAI,UAAU;AACV,eAAO,KAAK,QAAQ;AAAA,MACxB;AAEA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,UAAU;AAC9B,UAAI,OAAO,iBAAiB,OAAO,MAAM,cAAc,SAAS;AAC5D,cAAM,QAAQ,OAAO;AACrB,YAAI,OAAO,KAAK,cAAc,MAAM;AACpC,YAAI,CAAC,QAAQ,KAAK;AACd,iBAAO,SAAS,gBAAgB,8BAA8B,MAAM;AACpE,cAAI,YAAY,IAAI;AAAA,QACxB;AACA,YAAI,QAAQ,MAAM,YAAY,CAAC,MAAM,SAAS,WAAY,MAAK,YAAY,MAAM,QAAQ;AACzF,YAAI,OAAO,MAAM,SAAS,CAAC,MAAM,MAAM,WAAY,KAAI,YAAY,MAAM,KAAK;AAC9E,YAAI,OAAO,MAAM,aAAa,CAAC,MAAM,UAAU,WAAY,KAAI,YAAY,MAAM,SAAS;AAC1F,YAAI,OAAO,QAAQ,KAAK,MAAM,IAAI;AAC9B,gBAAM,QAAQ,OAAO,cAAc,IAAI,KAAK,IAAI,OAAO,YAAY,OAAO,MAAM,IAAI,OAAO;AAC3F,iBAAO,OAAO,OAAO,GAAG,KAAK;AAAA,QACjC;AACA,cAAM,kBAAkB,CAAC;AACzB,cAAM,KAAK;AACX,cAAM,eAAe;AACrB,mBAAW,SAAS,OAAO,mBAAmB,CAAC,GAAG;AAC9C,cAAI,SAAS,OAAO,SAAS,KAAK,EAAG,OAAM,gBAAgB,KAAK;AAAA,QACpE;AAAA,MACJ,WACI,OAAO,MAAM,SAAS,QAAQ;AAE9B,YAAI,KAAK;AACL,cAAI,YAAY,OAAO,MAAM,WAAW,OAAO,KAAK;AAEpD,iBAAO,KAAK,OAAO,MAAM,WAAW,OAAO,KAAK;AAAA,QACpD;AAAA,MACJ,WACS,OAAO,MAAM,SAAS,SAAS;AAEpC,eAAO,MAAM,QAAQ;AAAA,MACzB,WAAW,OAAO,MAAM,SAAS,QAAQ;AAErC,YAAI,OAAO,OAAO,MAAM,OAAO;AAC3B,cAAI,YAAY,OAAO,MAAM,KAAK;AAAA,QACtC;AAEA,YAAI,OAAO,QAAQ,OAAO,KAAK,MAAM,IAAI;AACrC,iBAAO,KAAK,OAAO,KAAK;AAAA,QAC5B;AAAA,MACJ,OAAO;AAEH,YAAI,CAAC,OAAO,SAAS,OAAO,KAAK,EAAG,QAAO,KAAK,OAAO,KAAK;AAC5D,YAAI,KAAK;AACL,cAAI,YAAY,OAAO,MAAM,KAAK;AAAA,QACtC;AAAA,MACJ;AACA,+BAAyB,MAAM;AAC/B,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEI,QAAI,OAAO,SAAS,UAAU;AAC1B,8BAAwB,MAAM;AAC9B,UAAI,OAAO,MAAM,SAAS,QAAQ;AAE9B,aAAK,OAAO,MAAM,WAAW,OAAO,OAAO,YAAY;AACnD,WAAC,OAAO,MAAM,WAAW,OAAO,OAAO,WAAW,YAAY,OAAO,MAAM,WAAW,OAAO,KAAK;AAAA,QACtG;AAEA,cAAM,MAAM,OAAO,QAAQ,OAAO,MAAM,WAAW,OAAO,KAAK;AAC/D,YAAI,QAAQ,GAAI,QAAO,OAAO,KAAK,CAAC;AAGpC,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,gBAAI,MAAM,mBAAmB,MAAM,gBAAgB,WAAW,OAAO,MAAM,WAAW,OAAO,QAAQ;AACjG,oBAAM,gBAAgB,IAAI;AAAA,YAC9B;AACA,gBAAI,MAAM,iBAAiB,MAAM,cAAc,WAAW,OAAO,MAAM,WAAW,OAAO,QAAQ;AAC7F,oBAAM,gBAAgB,KAAK;AAAA,YAC/B;AACA,kBAAM,KAAK;AAAA,UACf,CAAC;AAAA,QACL;AAAA,MACJ,WACS,OAAO,MAAM,SAAS,SAAS;AAEpC,eAAO,MAAM,OAAO;AAAA,MACxB,OAAO;AAEH,cAAM,MAAM,OAAO,QAAQ,OAAO,KAAK;AACvC,YAAI,QAAQ,GAAI,QAAO,OAAO,KAAK,CAAC;AAMpC,YAAI,OAAO,MAAM,cAAc,WAAW,CAAC,OAAO,MAAM,gBAAgB,OAAO,eAAe;AAC1F,qBAAW,SAAS,OAAO,eAAe;AACtC,gBAAI,CAAC,MAAO;AACZ,kBAAM,KAAK,MAAM,SAAS,MAAM;AAChC,gBAAI,MAAM,KAAK;AACX,kBAAI,OAAO,MAAM,aAAa,GAAG,eAAe,OAAO,MAAM,WAAW;AACpE,uBAAO,MAAM,UAAU,YAAY,EAAE;AAAA,cACzC;AACA,kBAAI,GAAG,eAAe,IAAK,KAAI,YAAY,EAAE;AAAA,YACjD;AACA,kBAAM,cAAc;AACpB,mBAAO,MAAM;AAAA,UACjB;AACA,iBAAO,MAAM,kBAAkB,CAAC;AAChC,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,WAAY,QAAO,MAAM,MAAM,WAAW,YAAY,OAAO,MAAM,KAAK;AACrH,cAAI,OAAO,MAAM,aAAa,OAAO,MAAM,UAAU,WAAY,QAAO,MAAM,UAAU,WAAW,YAAY,OAAO,MAAM,SAAS;AACrI,cAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAS,WAAY,QAAO,MAAM,SAAS,WAAW,YAAY,OAAO,MAAM,QAAQ;AAAA,QACrI,OAAO;AACH,cAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,YAAY;AACrD,mBAAO,MAAM,MAAM,WAAW,YAAY,OAAO,MAAM,KAAK;AAAA,UAChE;AAEA,cAAI,OAAO,MAAM,cAAc,WAAW,OAAO,OAAO,MAAM,YAAY,YAAY;AAClF,mBAAO,MAAM,QAAQ;AAAA,UACzB;AAAA,QACJ;AAAA,MACJ;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,aAAa;AAE7B,UAAI,OAAO,iBAAiB;AAExB,YAAI,OAAO,gBAAgB,UAAU;AACjC,gBAAM,gBAAgB,OAAO,gBAAgB,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AAC1F,cAAI,gBAAgB,IAAI;AACpB,mBAAO,gBAAgB,SAAS,gBAAgB,OAAO,eAAe,CAAC;AACvE,gBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,gBAAgB,SAAS,WAAW;AACnG,qBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AACxE,kBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,YACtC;AAAA,UACJ;AAAA,QACJ;AACA,YAAI,OAAO,gBAAgB,UAAU;AACjC,cAAI,CAAC,OAAO,gBAAgB,SAAS,gBAAgB,SAAS,OAAO,KAAK,GAAG;AACzE,mBAAO,gBAAgB,SAAS,gBAAgB,KAAK,OAAO,KAAK;AACjE,mBAAO,MAAM,cAAc,OAAO,gBAAgB;AAClD,gBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,kBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,qBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,YAC5E;AAAA,UACJ;AAAA,QACJ,OAAO;AACH,iBAAO,MAAM,cAAc;AAAA,QAC/B;AAAA,MACJ;AAEA,UAAI,OAAO,MAAM,SAAS,QAAQ;AAE9B,cAAM,eAAe,OAAO,MAAM,WAAW,OAAO,OAAO,cAAc,MAAM;AAC/E,YAAI,eAAe,OAAO,OAAO,aAAa,QAAW;AACrD,sBAAY,aAAa,aAAa,OAAO,OAAO,WAAW,IAAI;AAAA,QACvE;AAGA,cAAM,UAAU,cAAc,YAAY,QAAQ,EAAE,IAAI,YAAY,QAAQ,EAAE,QAAQ,IAAI;AAC1F,cAAM,UAAU,cAAc,YAAY,QAAQ,EAAE,IAAI,YAAY,QAAQ,EAAE,SAAS,IAAI;AAE3F,SAAC,OAAO,MAAM,WAAW,OAAO,OAAO;AAAA,UAAa;AAAA,UAChD,aAAa,OAAO,OAAO,CAAC,KAAK,OAAO,OAAO,CAAC,YAAY,OAAO,OAAO,QAAQ,KAAK,OAAO,KAAK,OAAO;AAAA,QAC9G;AAEA,SAAC,OAAO,MAAM,WAAW,OAAO,OAAO,aAAa,UAAU,OAAO,OAAO,CAAC;AAC7E,SAAC,OAAO,MAAM,WAAW,OAAO,OAAO,aAAa,UAAU,OAAO,OAAO,CAAC;AAG7E,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,gBAAI,UAAU,gBAAgB;AAC1B,oBAAM,uBAAuB,UAAU,cAAc;AAAA,YACzD,OAAO;AAEH,oBAAM,kBAAkB;AAAA,YAC5B;AAAA,UACJ,CAAC;AAAA,QACL;AAGA,YAAI,qBAAqB,OAAO,MAAM,WAAW,OAAO,UAAU,yBAAyB;AACvF,qBAAW,yBAAyB,CAAC;AAAA,QACzC;AAAA,MACJ,WAAW,OAAO,MAAM,SAAS,SAAS;AAEtC,eAAO,MAAM,QAAQ,OAAO,MAAM;AAGlC,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,gBAAI,UAAU,gBAAgB;AAC1B,oBAAM,uBAAuB,UAAU,cAAc;AAAA,YACzD,OAAO;AAEH,oBAAM,kBAAkB;AAAA,YAC5B;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ,WAAW,OAAO,MAAM,cAAc,UAAU;AAE5C,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,KAAK,OAAO,OAAO;AAChC,eAAO,MAAM,KAAK,OAAO,OAAO;AAChC,eAAO,MAAM,WAAW,OAAO,OAAO;AACtC,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAGlB,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,gBAAI,UAAU,gBAAgB;AAC1B,oBAAM,uBAAuB,UAAU,cAAc;AAAA,YACzD,OAAO;AAEH,oBAAM,kBAAkB;AAAA,YAC5B;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ,WAAW,OAAO,MAAM,cAAc,QAAQ;AAE1C,eAAO,MAAM,aAAa,EAAE,GAAG,OAAO,OAAO,WAAW,GAAG,GAAG,OAAO,OAAO,WAAW,EAAE;AACzF,eAAO,MAAM,WAAW,EAAE,GAAG,OAAO,OAAO,SAAS,GAAG,GAAG,OAAO,OAAO,SAAS,EAAE;AAGnF,eAAO,MAAM,WAAW,OAAO,OAAO,YAAY;AAClD,YAAI,OAAO,OAAO,cAAc;AAC5B,iBAAO,MAAM,eAAe,EAAE,GAAG,OAAO,OAAO,aAAa,GAAG,GAAG,OAAO,OAAO,aAAa,EAAE;AAAA,QACnG,OAAO;AACH,iBAAO,MAAM,eAAe;AAAA,QAChC;AAGA,YAAI,OAAO,iBAAiB;AAExB,cAAI,OAAO,gBAAgB,UAAU;AACjC,kBAAM,gBAAgB,OAAO,gBAAgB,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AAC1F,gBAAI,gBAAgB,IAAI;AACpB,qBAAO,gBAAgB,SAAS,gBAAgB,OAAO,eAAe,CAAC;AACvE,kBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,OAAO,gBAAgB,SAAS,WAAW;AACnG,uBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AACxE,oBAAI,YAAY,OAAO,MAAM,KAAK;AAAA,cACtC;AAAA,YACJ;AAAA,UACJ;AAGA,cAAI,OAAO,gBAAgB,UAAU;AACjC,gBAAI,CAAC,OAAO,gBAAgB,SAAS,gBAAgB,SAAS,OAAO,KAAK,GAAG;AACzE,qBAAO,gBAAgB,SAAS,gBAAgB,KAAK,OAAO,KAAK;AACjE,qBAAO,MAAM,cAAc,OAAO,gBAAgB;AAClD,kBAAI,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,KAAK;AAC7D,oBAAI,YAAY,OAAO,MAAM,KAAK;AAClC,uBAAO,gBAAgB,SAAS,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,cAC5E;AAAA,YACJ;AAAA,UACJ,OAAO;AACH,mBAAO,MAAM,cAAc;AAAA,UAC/B;AAAA,QACJ;AAEA,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAAA,MACtB,WACU,OAAO,MAAM,cAAc,SAAS;AAE1C,eAAO,MAAM,aAAa,EAAE,GAAG,OAAO,OAAO,WAAW,GAAG,GAAG,OAAO,OAAO,WAAW,EAAE;AACzF,eAAO,MAAM,WAAW,EAAE,GAAG,OAAO,OAAO,SAAS,GAAG,GAAG,OAAO,OAAO,SAAS,EAAE;AACnF,eAAO,MAAM,gBAAgB,OAAO,OAAO,gBACvC,EAAE,GAAG,OAAO,OAAO,cAAc,GAAG,GAAG,OAAO,OAAO,cAAc,EAAE,IAAI;AAC7E,eAAO,MAAM,gBAAgB,OAAO,OAAO,gBACvC,EAAE,GAAG,OAAO,OAAO,cAAc,GAAG,GAAG,OAAO,OAAO,cAAc,EAAE,IAAI;AAG7E,YAAI,OAAO,OAAO,aAAa;AAC3B,iBAAO,MAAM,uBAAuB,OAAO,OAAO,WAAW;AAAA,QACjE,OAAO;AAEH,iBAAO,MAAM,kBAAkB;AAC/B,iBAAO,MAAM,gBAAgB;AAAA,QACjC;AAEA,eAAO,MAAM,aAAa;AAC1B,eAAO,MAAM,KAAK;AAAA,MAEtB,WACS,OAAO,MAAM,SAAS,QAAQ;AACnC,eAAO,MAAM,QAAQ,OAAO,MAAM;AAGlC,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,gBAAI,UAAU,gBAAgB;AAC1B,oBAAM,uBAAuB,UAAU,cAAc;AAAA,YACzD,OAAO;AAEH,oBAAM,kBAAkB;AAAA,YAC5B;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ,WACS,OAAO,MAAM,cAAc,kBAAkB;AAElD,eAAO,MAAM,SAAS,KAAK,MAAM,KAAK,UAAU,OAAO,OAAO,MAAM,CAAC;AACrE,eAAO,MAAM,WAAW,OAAO,OAAO;AACtC,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAAA,MACtB,WAAW,OAAO,MAAM,cAAc,aAAa;AAE/C,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,IAAI,OAAO,OAAO;AAC/B,eAAO,MAAM,SAAS,OAAO,OAAO;AACpC,eAAO,MAAM,QAAQ,OAAO,OAAO;AACnC,eAAO,MAAM,WAAW,OAAO,OAAO;AACtC,eAAO,MAAM,aAAa;AAC1B,YAAI,OAAO,OAAO,MAAM,oBAAoB,WAAY,QAAO,MAAM,gBAAgB;AACrF,eAAO,MAAM,KAAK;AAGlB,YAAI,OAAO,gBAAgB;AACvB,iBAAO,eAAe,QAAQ,eAAa;AACvC,kBAAM,QAAQ,UAAU;AAExB,gBAAI,UAAU,gBAAgB;AAC1B,oBAAM,uBAAuB,UAAU,cAAc;AAAA,YACzD,OAAO;AAEH,oBAAM,kBAAkB;AAAA,YAC5B;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAEA,QAAI,OAAO,SAAS,iBAAiB;AACjC,UAAI,OAAO,MAAM,SAAS,QAAQ;AAE9B,cAAM,eAAe,OAAO,MAAM,WAAW,OAAO,OAAO,cAAc,MAAM;AAC/E,YAAI,aAAa;AACb,cAAI,OAAO,WAAW,MAAO,aAAY,aAAa,QAAQ,OAAO,WAAW,KAAK;AACrF,cAAI,OAAO,WAAW,KAAM,aAAY,aAAa,eAAe,OAAO,WAAW,IAAI;AAC1F,cAAI,OAAO,WAAW,KAAM,aAAY,aAAa,aAAa,OAAO,WAAW,IAAI;AACxF,cAAI,OAAO,WAAW,MAAO,aAAY,aAAa,eAAe,OAAO,WAAW,KAAK;AAG5F,cAAI,qBAAqB,OAAO,MAAM,WAAW,OAAO,UAAU,yBAAyB;AACvF,uBAAW,yBAAyB,CAAC;AAAA,UACzC;AAAA,QACJ;AAAA,MACJ,WAAW,OAAO,MAAM,cAAc,SAAS;AAC3C,eAAO,MAAM,UAAU,EAAE,GAAG,OAAO,WAAW;AAC9C,eAAO,MAAM,oBAAoB,OAAO,WAAW;AACnD,eAAO,MAAM,iBAAiB,OAAO,WAAW;AAChD,eAAO,MAAM,cAAc,OAAO,WAAW;AAC7C,eAAO,MAAM,mBAAmB,OAAO,WAAW;AAClD,eAAO,MAAM,KAAK;AAAA,MACtB,OAAO;AACH,6BAAqB,OAAO,OAAO,OAAO,UAAU;AAAA,MACxD;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACJ;AAAA,EACA,UAAE;AACE,gCAA4B;AAC5B,wBAAoB;AAAA,EACxB;AACJ;AAGA,SAAS,iBAAiB,WAAW,CAAC,MAAM;AACxC,OAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;AAC3C,MAAE,eAAe;AACjB,SAAK;AAAA,EACT;AACA,OAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,OAAQ,EAAE,YAAY,EAAE,QAAQ,MAAO;AAC9E,MAAE,eAAe;AACjB,SAAK;AAAA,EACT;AACJ,CAAC;AAGD,SAAS,eAAe,MAAM,GAAG,iBAAiB,SAAS,IAAI;AAC/D,SAAS,eAAe,MAAM,GAAG,iBAAiB,SAAS,IAAI;AAG/D,OAAO,mBAAmB;AAC1B,OAAO,iBAAiB;AACxB,OAAO,eAAe;AACtB,OAAO,mBAAmB;AAC1B,OAAO,wBAAwB;AAC/B,OAAO,4BAA4B;AACnC,OAAO,mBAAmB;AAC1B,OAAO,oBAAoB;AAC3B,OAAO,kCAAkC;AACzC,OAAO,sBAAsB;AAC7B,OAAO,0BAA0B;AACjC,OAAO,kCAAkC;AACzC,OAAO,OAAO;AACd,OAAO,OAAO;",
6
+ "names": []
7
+ }
@@ -1,10 +1,11 @@
1
1
  "use client";
2
2
  import {
3
+ captureFrameChildStates,
3
4
  pushCreateAction,
4
5
  pushDeleteAction,
5
6
  pushFrameAttachmentAction,
6
7
  pushTransformAction
7
- } from "./chunk-VZX55VQL.js";
8
+ } from "./chunk-TFCBCWL5.js";
8
9
 
9
10
  // src/tools/frameTool.js
10
11
  var currentFrame = null;
@@ -82,7 +83,8 @@ var handleMouseDown = (e) => {
82
83
  y: currentShape.y,
83
84
  width: currentShape.width,
84
85
  height: currentShape.height,
85
- rotation: currentShape.rotation
86
+ rotation: currentShape.rotation,
87
+ containedShapes: captureFrameChildStates(currentShape)
86
88
  };
87
89
  }
88
90
  return;
@@ -241,4 +243,4 @@ export {
241
243
  handleMouseMove,
242
244
  handleMouseUp
243
245
  };
244
- //# sourceMappingURL=chunk-GQLXUZHQ.js.map
246
+ //# sourceMappingURL=chunk-TWHJ6PJK.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/tools/frameTool.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// Frame tool event handlers - extracted from frameHolder.js\nimport { captureFrameChildStates, pushCreateAction, pushDeleteAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { updateAttachedArrows, cleanupAttachments } from './arrowTool.js';\n\nlet currentFrame = null;\nlet isResizing = false;\nlet isDragging = false;\nlet activeAnchor = null;\nlet isDrawingFrame = false;\nlet frameStrokeColor = \"#888\";\nlet frameStrokeThickness = 2;\nlet frameFillColor = \"transparent\";\nlet frameOpacity = 1;\nlet startX, startY;\nlet dragOldPosFrame = null;\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\n\n// Event handlers for frame tool\nconst handleMouseDown = (e) => {\n if (!isFrameToolActive && !isSelectionToolActive) return;\n\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isFrameToolActive) {\n isDrawingFrame = true;\n startX = x;\n startY = y;\n currentFrame = new Frame(x, y, 0, 0, {\n stroke: frameStrokeColor,\n strokeWidth: frameStrokeThickness,\n fill: frameFillColor,\n opacity: frameOpacity\n });\n shapes.push(currentFrame);\n currentShape = currentFrame;\n } else if (isSelectionToolActive) {\n // Handle frame selection \u2014 but first check if a contained shape was clicked\n for (let i = shapes.length - 1; i >= 0; i--) {\n if (shapes[i].shapeName === 'frame' && shapes[i].contains(x, y)) {\n const clickedFrame = shapes[i];\n\n // Check if click is on a shape inside this frame \u2014 let shape handlers deal with it\n let clickedContainedShape = false;\n if (clickedFrame.containedShapes && clickedFrame.containedShapes.length > 0) {\n for (let j = clickedFrame.containedShapes.length - 1; j >= 0; j--) {\n const inner = clickedFrame.containedShapes[j];\n if (inner.contains && inner.contains(x, y)) {\n clickedContainedShape = true;\n break;\n }\n }\n }\n // If a contained shape was clicked, don't select the frame \u2014\n // and crucially, clear `currentShape` so the EventDispatcher's\n // `if (handled && prevShape && !currentShape) handled=false` gate\n // triggers and the dispatcher falls through to shape-specific\n // handlers. Without this clear, the dispatcher returns with\n // `handled=true` and the child shape is never selected (Issue\n // #22, bug #2).\n if (clickedContainedShape) {\n if (currentShape && currentShape.shapeName === 'frame'\n && typeof currentShape.removeSelection === 'function') {\n currentShape.removeSelection();\n }\n currentShape = null;\n return;\n }\n\n if (currentShape && currentShape !== clickedFrame) {\n currentShape.removeSelection();\n }\n currentShape = clickedFrame;\n currentShape.selectFrame();\n\n // Check for anchor interaction\n const anchorIndex = typeof currentShape.isNearAnchor === 'function' ? currentShape.isNearAnchor(x, y) : null;\n if (anchorIndex !== null) {\n activeAnchor = anchorIndex;\n isResizing = true;\n } else {\n isDragging = true;\n startX = x;\n startY = y;\n dragOldPosFrame = {\n x: currentShape.x,\n y: currentShape.y,\n width: currentShape.width,\n height: currentShape.height,\n rotation: currentShape.rotation,\n containedShapes: captureFrameChildStates(currentShape),\n };\n }\n return;\n }\n }\n\n // If no frame was clicked, deselect current\n if (currentShape && currentShape.shapeName === 'frame') {\n currentShape.removeSelection();\n currentShape = null;\n }\n }\n};\n\n const handleMouseMove = (e) => {\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isDrawingFrame && currentFrame) {\n const width = Math.abs(x - startX);\n const height = Math.abs(y - startY);\n currentFrame.x = Math.min(startX, x);\n currentFrame.y = Math.min(startY, y);\n currentFrame.width = width;\n currentFrame.height = height;\n currentFrame.draw();\n } else if (isDragging && currentShape && currentShape.shapeName === 'frame') {\n const dx = x - startX;\n const dy = y - startY;\n \n // Use the frame's move method which properly handles contained shapes\n currentShape.move(dx, dy);\n \n startX = x;\n startY = y;\n }\n};\n\n const handleMouseUp = (e) => {\n if (isDrawingFrame && currentFrame) {\n // Check if frame is too small\n if (currentFrame.width < 10 || currentFrame.height < 10) {\n currentFrame.destroy();\n currentFrame = null;\n currentShape = null;\n } else {\n // Check for shapes that should be contained in the new frame\n currentFrame.updateContainedShapes(true); // Apply clipping immediately for new frames\n pushCreateAction(currentFrame, {\n frameCreation: true,\n containedShapes: [...currentFrame.containedShapes]\n });\n\n // Auto-select the new frame and switch to selection tool\n const placedFrame = currentFrame;\n if (window.__sketchStoreApi) {\n window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n } else {\n window.isSelectionToolActive = true;\n }\n currentShape = placedFrame;\n placedFrame.selectFrame();\n }\n isDrawingFrame = false;\n }\n\n if (isDragging && dragOldPosFrame && currentShape) {\n const newPos = {\n x: currentShape.x,\n y: currentShape.y,\n width: currentShape.width,\n height: currentShape.height,\n rotation: currentShape.rotation\n };\n pushTransformAction(currentShape, dragOldPosFrame, newPos);\n dragOldPosFrame = null;\n \n // Update frame containment after moving frame (but don't re-move contained shapes)\n if (currentShape.shapeName === 'frame') {\n currentShape.updateClipPath();\n }\n }\n\n // Only check frame containment for shapes that aren't already in frames.\n // Record this fallback attachment too; individual shape tools normally do\n // it themselves, but restored/imported shapes can reach this path.\n if (!isDragging) {\n shapes.forEach(shape => {\n if (shape.shapeName !== 'frame' && !shape.parentFrame) {\n let targetFrame = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const frame = shapes[i];\n if (frame.shapeName === 'frame' && frame.isShapeInFrame(shape)) {\n targetFrame = frame;\n break;\n }\n }\n if (targetFrame) {\n targetFrame.addShapeToFrame(shape);\n pushFrameAttachmentAction(targetFrame, shape, 'attach', null);\n }\n }\n });\n }\n\n isDrawingFrame = false;\n isDragging = false;\n isResizing = false;\n activeAnchor = null;\n svg.style.cursor = 'default';\n};\n\nFrame.prototype.isNearAnchor = function(x, y) {\n const anchorSize = 10 / currentZoom;\n \n // Define anchor positions\n const anchorPositions = [\n { x: this.x, y: this.y },\n { x: this.x + this.width / 2, y: this.y },\n { x: this.x + this.width, y: this.y },\n { x: this.x + this.width, y: this.y + this.height / 2 },\n { x: this.x + this.width, y: this.y + this.height },\n { x: this.x + this.width / 2, y: this.y + this.height },\n { x: this.x, y: this.y + this.height },\n { x: this.x, y: this.y + this.height / 2 },\n { x: this.x + this.width / 2, y: this.y - 30 / currentZoom } // Rotation handle\n ];\n\n for (let i = 0; i < anchorPositions.length; i++) {\n const pos = anchorPositions[i];\n const distance = Math.sqrt((x - pos.x) ** 2 + (y - pos.y) ** 2);\n if (distance <= anchorSize) {\n return i;\n }\n }\n return null;\n};\n\n// Delete functionality\nfunction deleteCurrentFrame() {\n if (currentShape && currentShape.shapeName === 'frame') {\n const frame = currentShape;\n const isDiagramFrame = !!frame._diagramType;\n\n // Issue #24 bug #7: regular frame \u2192 orphan children + snapshot\n // (mirrors deleteSelectedShapes / EngineShortcuts).\n let childSnapshot = null;\n if (!isDiagramFrame) {\n childSnapshot = [...(frame.containedShapes || [])];\n for (const child of childSnapshot) {\n if (!child || child === frame) continue;\n const el = child.group || child.element;\n if (el) {\n if (frame.clipGroup && el.parentNode === frame.clipGroup) frame.clipGroup.removeChild(el);\n if (window.svg && el.parentNode !== window.svg) window.svg.appendChild(el);\n }\n child.parentFrame = null;\n delete child.isBeingMovedByFrame;\n }\n frame.containedShapes = [];\n }\n\n const idx = shapes.indexOf(frame);\n if (idx !== -1) shapes.splice(idx, 1);\n\n if (!isDiagramFrame) {\n if (frame.group && frame.group.parentNode) frame.group.parentNode.removeChild(frame.group);\n if (frame.clipGroup && frame.clipGroup.parentNode) frame.clipGroup.parentNode.removeChild(frame.clipGroup);\n if (frame.clipPath && frame.clipPath.parentNode) frame.clipPath.parentNode.removeChild(frame.clipPath);\n } else if (frame.group && frame.group.parentNode) {\n frame.group.parentNode.removeChild(frame.group);\n }\n\n if (childSnapshot) pushDeleteAction(frame, { childSnapshot });\n else pushDeleteAction(frame);\n currentShape = null;\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'frame') {\n deleteCurrentFrame();\n }\n});\n\nwindow.Frame = Frame;\n\nexport {\n handleMouseDown as handleMouseDownFrame,\n handleMouseMove as handleMouseMoveFrame,\n handleMouseUp as handleMouseUpFrame\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  registerRotationAnchor
4
- } from "./chunk-PAKA6HUX.js";
4
+ } from "./chunk-MS4TIQ6Z.js";
5
5
 
6
6
  // src/shapes/FreehandStroke.js
7
7
  import { getStroke } from "perfect-freehand";
@@ -452,7 +452,7 @@ var FreehandStroke = class {
452
452
  }
453
453
  addAnchors() {
454
454
  const anchorSize = 10 / currentZoom;
455
- const anchorStrokeWidth = 2 / currentZoom;
455
+ const anchorStrokeWidth = 2;
456
456
  const expandedX = this.boundingBox.x - this.selectionPadding;
457
457
  const expandedY = this.boundingBox.y - this.selectionPadding;
458
458
  const expandedWidth = this.boundingBox.width + 2 * this.selectionPadding;
@@ -518,6 +518,7 @@ var FreehandStroke = class {
518
518
  [expandedX, expandedY]
519
519
  ];
520
520
  const outline = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
521
+ outline.setAttribute("class", "selection-outline");
521
522
  outline.setAttribute("points", outlinePoints.map((p) => p.join(",")).join(" "));
522
523
  outline.setAttribute("fill", "none");
523
524
  outline.setAttribute("stroke", "#5B57D1");
@@ -624,4 +625,4 @@ var FreehandStroke = class {
624
625
  export {
625
626
  FreehandStroke
626
627
  };
627
- //# sourceMappingURL=chunk-NH3NVSWT.js.map
628
+ //# sourceMappingURL=chunk-UCOK4V5Z.js.map