@elixpo/lixsketch 5.5.14 → 5.5.15

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.
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-JQ3IRFDP.js";
11
11
  import {
12
12
  Frame
13
- } from "./chunk-BU4D2WYQ.js";
13
+ } from "./chunk-2AYTBFV5.js";
14
14
  import {
15
15
  FreehandStroke
16
16
  } from "./chunk-HKYUJUD7.js";
@@ -570,4 +570,4 @@ export {
570
570
  initCopyPaste,
571
571
  pasteClipboard
572
572
  };
573
- //# sourceMappingURL=CopyPaste-UTU5MPKY.js.map
573
+ //# sourceMappingURL=CopyPaste-7HWM3IMY.js.map
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  Frame
4
- } from "./chunk-BU4D2WYQ.js";
4
+ } from "./chunk-2AYTBFV5.js";
5
5
  import "./chunk-BZE4CEBG.js";
6
6
  import "./chunk-L5OARZJ7.js";
7
7
  export {
8
8
  Frame
9
9
  };
10
- //# sourceMappingURL=Frame-6UR5XPAX.js.map
10
+ //# sourceMappingURL=Frame-WPQZQLNT.js.map
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-JQ3IRFDP.js";
11
11
  import {
12
12
  Frame
13
- } from "./chunk-BU4D2WYQ.js";
13
+ } from "./chunk-2AYTBFV5.js";
14
14
  import {
15
15
  FreehandStroke
16
16
  } from "./chunk-HKYUJUD7.js";
@@ -736,4 +736,4 @@ export {
736
736
  uploadScene,
737
737
  validateScene
738
738
  };
739
- //# sourceMappingURL=SceneSerializer-34VQFJN7.js.map
739
+ //# sourceMappingURL=SceneSerializer-7UACFCRF.js.map
@@ -169,7 +169,7 @@ var SketchEngine = class {
169
169
  import("./CodeShape-TE74XP5V.js"),
170
170
  import("./ImageShape-CHHGBXUQ.js"),
171
171
  import("./IconShape-KMIA6T2H.js"),
172
- import("./Frame-6UR5XPAX.js"),
172
+ import("./Frame-WPQZQLNT.js"),
173
173
  import("./FreehandStroke-BOWDNAVC.js")
174
174
  ]);
175
175
  window.Rectangle = Rectangle;
@@ -243,7 +243,7 @@ var SketchEngine = class {
243
243
  import("./UndoRedo-M2JZUBKN.js"),
244
244
  import("./Selection-XLRY6VYO.js"),
245
245
  import("./ZoomPan-NYPDJBD5.js"),
246
- import("./CopyPaste-UTU5MPKY.js"),
246
+ import("./CopyPaste-7HWM3IMY.js"),
247
247
  import("./EraserTrail-PA6IQLQN.js"),
248
248
  import("./ResizeShapes-LKEQTITP.js"),
249
249
  import("./ResizeCode-WAMDTKSW.js")
@@ -262,7 +262,7 @@ var SketchEngine = class {
262
262
  eventDispatcher.initEventDispatcher(this.svg);
263
263
  }
264
264
  window.__sketchInteractionReady = true;
265
- const sceneSerializer = await import("./SceneSerializer-34VQFJN7.js");
265
+ const sceneSerializer = await import("./SceneSerializer-7UACFCRF.js");
266
266
  if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
267
267
  await Promise.all([
268
268
  import("./eraserTool-2GS2LQCS.js"),
@@ -414,4 +414,4 @@ export {
414
414
  SketchEngine,
415
415
  SketchEngine_default as default
416
416
  };
417
- //# sourceMappingURL=SketchEngine-P3XNZA56.js.map
417
+ //# sourceMappingURL=SketchEngine-UYMJJEVW.js.map
@@ -999,6 +999,24 @@ var Frame = class {
999
999
  shape.y = this.y + relTY * this.height;
1000
1000
  break;
1001
1001
  }
1002
+ case "freehandStroke": {
1003
+ if (Array.isArray(shape.points)) {
1004
+ shape.points = shape.points.map((point) => {
1005
+ if (!Array.isArray(point) || point.length < 2) return point;
1006
+ const relPX = (point[0] - oldX) / oldW;
1007
+ const relPY = (point[1] - oldY) / oldH;
1008
+ return [
1009
+ this.x + relPX * this.width,
1010
+ this.y + relPY * this.height,
1011
+ point[2] || 0.5
1012
+ ];
1013
+ });
1014
+ shape._moveOffsetX = 0;
1015
+ shape._moveOffsetY = 0;
1016
+ if (typeof shape.draw === "function") shape.draw();
1017
+ }
1018
+ break;
1019
+ }
1002
1020
  }
1003
1021
  if (typeof shape.updateAttachedArrows === "function") {
1004
1022
  shape.updateAttachedArrows();
@@ -1210,4 +1228,4 @@ var Frame = class {
1210
1228
  export {
1211
1229
  Frame
1212
1230
  };
1213
- //# sourceMappingURL=chunk-BU4D2WYQ.js.map
1231
+ //# sourceMappingURL=chunk-2AYTBFV5.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shapes/Frame.js"],
4
- "sourcesContent": ["/* eslint-disable */\n// Frame shape class - extracted from frameHolder.js\n// Depends on globals: svg, shapes, currentShape, currentZoom\n\nimport { cleanupAttachments } from '../tools/arrowTool.js';\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\nlet dragOldPosFrame = null;\n\nclass Frame {\n constructor(x, y, width, height, options = {}) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n this.rotation = options.rotation || 0;\n this.frameName = options.frameName || \"Frame\";\n this.fillStyle = options.fillStyle || \"transparent\"; // 'transparent' | 'solid' | 'grid'\n this.fillColor = options.fillColor || \"#1e1e28\";\n this.gridSize = options.gridSize || 20;\n // Issue #38 follow-up: read the grid stroke from a CSS custom\n // property so the frame grid stays visible in both themes. The\n // var is defined in globals.css for both `body.canvas-mode`\n // (dark-on-light) and `body.canvas-mode.theme-dark` (light-on-dark).\n // The literal here is the dark-theme fallback for environments\n // (tests, embeds) without the canvas-mode CSS in scope.\n this.gridColor = options.gridColor || \"var(--lixsketch-grid-fine, rgba(255,255,255,0.06))\";\n this.options = {\n stroke: options.stroke || \"#555\",\n strokeWidth: options.strokeWidth || 1,\n fill: options.fill || \"transparent\",\n opacity: options.opacity || 1,\n ...options\n };\n\n this.element = null;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.isSelected = false;\n this.anchors = [];\n this.shapeName = \"frame\";\n this.shapeID = `frame-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n this.group.setAttribute('id', this.shapeID);\n\n // Create clipping group for contained shapes\n this.clipGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.clipPath = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath');\n this.clipRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n \n // Set up clipping\n this.clipId = `clip-${this.shapeID}`;\n this.clipPath.setAttribute('id', this.clipId);\n this.clipPath.appendChild(this.clipRect);\n this.clipGroup.setAttribute('clip-path', `url(#${this.clipId})`);\n \n // Add clip path to defs\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n defs.appendChild(this.clipPath);\n\n // Array to hold shapes inside this frame\n this.containedShapes = [];\n\n svg.appendChild(this.group);\n svg.appendChild(this.clipGroup);\n this.draw();\n this.updateClipPath();\n }\n\n draw() {\n // Clear previous elements\n while (this.group.firstChild) {\n this.group.removeChild(this.group.firstChild);\n }\n this.anchors = [];\n\n // Ensure defs exists for grid pattern\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n\n // Determine fill based on fillStyle\n let fillValue = \"transparent\";\n if (this.fillStyle === 'solid') {\n fillValue = this.fillColor;\n } else if (this.fillStyle === 'grid') {\n // Create or update a grid pattern unique to this frame\n const patternId = `frame-grid-${this.shapeID}`;\n let pattern = defs.querySelector(`#${patternId}`);\n if (!pattern) {\n pattern = document.createElementNS('http://www.w3.org/2000/svg', 'pattern');\n pattern.setAttribute('id', patternId);\n pattern.setAttribute('patternUnits', 'userSpaceOnUse');\n defs.appendChild(pattern);\n }\n // Update pattern attributes\n pattern.setAttribute('x', this.x);\n pattern.setAttribute('y', this.y);\n pattern.setAttribute('width', this.gridSize);\n pattern.setAttribute('height', this.gridSize);\n // Clear and rebuild pattern content\n while (pattern.firstChild) pattern.removeChild(pattern.firstChild);\n // Background fill\n const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n bgRect.setAttribute('width', this.gridSize);\n bgRect.setAttribute('height', this.gridSize);\n bgRect.setAttribute('fill', this.fillColor);\n pattern.appendChild(bgRect);\n // Grid lines\n const gridPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n gridPath.setAttribute('d', `M ${this.gridSize} 0 L 0 0 0 ${this.gridSize}`);\n gridPath.setAttribute('fill', 'none');\n gridPath.setAttribute('stroke', this.gridColor);\n gridPath.setAttribute('stroke-width', '0.5');\n pattern.appendChild(gridPath);\n fillValue = `url(#${patternId})`;\n }\n\n // Create the frame rectangle\n const frameRect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n frameRect.setAttribute(\"x\", this.x);\n frameRect.setAttribute(\"y\", this.y);\n frameRect.setAttribute(\"width\", this.width);\n frameRect.setAttribute(\"height\", this.height);\n frameRect.setAttribute(\"stroke\", this.options.stroke);\n frameRect.setAttribute(\"stroke-width\", this.options.strokeWidth);\n frameRect.setAttribute(\"fill\", fillValue);\n frameRect.setAttribute(\"opacity\", this.options.opacity);\n frameRect.setAttribute(\"stroke-dasharray\", \"5,5\");\n frameRect.classList.add(\"frame-rect\");\n\n // Apply rotation\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n frameRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.element = frameRect;\n this.group.appendChild(this.element);\n\n // Add label\n this.addFrameLabel();\n\n // Re-attach frame image if present\n if (this._frameImageURL) {\n this.setImageFromURL(this._frameImageURL, this._frameImageFit || 'cover');\n }\n\n // Add selection anchors if selected\n if (this.isSelected) {\n this.addAnchors();\n }\n\n // Update clip path\n this.updateClipPath();\n }\n\n updateAttachedArrows() {\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(shape => {\n if (shape.shapeName === 'arrow') {\n let needsUpdate = false;\n \n // Check if arrow is attached to this frame\n if (shape.attachedToStart && shape.attachedToStart.shape === this) {\n needsUpdate = true;\n }\n if (shape.attachedToEnd && shape.attachedToEnd.shape === this) {\n needsUpdate = true;\n }\n \n if (needsUpdate) {\n shape.updateAttachments();\n }\n }\n });\n }\n }\n\n updateClipPath() {\n // Update the clipping rectangle to match frame dimensions\n this.clipRect.setAttribute(\"x\", this.x);\n this.clipRect.setAttribute(\"y\", this.y);\n this.clipRect.setAttribute(\"width\", this.width);\n this.clipRect.setAttribute(\"height\", this.height);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this.clipRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this.clipRect.removeAttribute(\"transform\");\n }\n }\n\n addShapeToFrame(shape) {\n if (shape && !this.containedShapes.includes(shape)) {\n const oldFrame = shape.parentFrame;\n\n // Remove from other frames first\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(otherFrame => {\n if (otherFrame.shapeName === 'frame' && otherFrame !== this) {\n otherFrame.removeShapeFromFrame(shape);\n }\n });\n }\n\n this.containedShapes.push(shape);\n shape.parentFrame = this;\n\n // Only move to clipped group if not currently being dragged\n const el = shape.group || shape.element;\n if (el && el.parentNode && !shape.isDraggedOutTemporarily) {\n el.parentNode.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup into our clipGroup\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n this.clipGroup.appendChild(shape.clipGroup);\n }\n }\n}\n\n removeShapeFromFrame(shape) {\n const index = this.containedShapes.indexOf(shape);\n if (index > -1) {\n this.containedShapes.splice(index, 1);\n if (shape.parentFrame === this) {\n shape.parentFrame = null;\n }\n\n // Move shape's group/element back to main SVG if it's in the clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup back to main SVG\n if (shape.shapeName === 'frame' && shape.clipGroup && shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n svg.appendChild(shape.clipGroup);\n }\n\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n // Check if a point is inside the frame bounds\n isPointInFrame(x, y) {\n // Simple bounding box check (can be enhanced for rotation)\n return x >= this.x && x <= this.x + this.width &&\n y >= this.y && y <= this.y + this.height;\n }\n\n // Check if a shape overlaps with this frame\n isShapeInFrame(shape) {\n if (!shape || shape === this) return false;\n \n const shapeX = shape.x || 0;\n const shapeY = shape.y || 0;\n const shapeWidth = shape.width || 0;\n const shapeHeight = shape.height || 0;\n \n // Check if the center of the shape is inside the frame (for better UX)\n const shapeCenterX = shapeX + shapeWidth / 2;\n const shapeCenterY = shapeY + shapeHeight / 2;\n \n return shapeCenterX >= this.x && shapeCenterX <= this.x + this.width &&\n shapeCenterY >= this.y && shapeCenterY <= this.y + this.height;\n}\n\nupdateContainedShapes(applyClipping = true) {\n // Check all shapes to see if they should be in this frame\n if (typeof shapes === 'undefined' || !Array.isArray(shapes)) return;\n shapes.forEach(shape => {\n if (shape !== this) {\n // Skip frames that are larger than or equal to this frame (prevent parent containing child loops)\n if (shape.shapeName === 'frame') {\n const shapeArea = (shape.width || 0) * (shape.height || 0);\n const thisArea = (this.width || 0) * (this.height || 0);\n if (shapeArea >= thisArea) return;\n }\n const isInFrame = this.isShapeInFrame(shape);\n const isAlreadyContained = this.containedShapes.includes(shape);\n\n if (isInFrame && !isAlreadyContained) {\n this.addShapeToFrame(shape);\n // Don't apply clipping if we're not supposed to\n if (!applyClipping) {\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n shape.isDraggedOutTemporarily = true;\n }\n }\n } else if (!isInFrame && isAlreadyContained) {\n this.removeShapeFromFrame(shape);\n }\n }\n });\n \n // Update clip path\n this.updateClipPath();\n}\n\nhighlightFrame() {\n if (this.element) {\n this.element.setAttribute('stroke', '#5B57D1');\n this.element.setAttribute('stroke-width', '3');\n this.element.setAttribute('opacity', '0.7');\n }\n}\n\n// Remove frame highlight\nremoveHighlight() {\n if (this.element) {\n this.element.setAttribute('stroke', this.options.stroke);\n this.element.setAttribute('stroke-width', this.options.strokeWidth);\n this.element.setAttribute('opacity', this.options.opacity);\n }\n}\n \n\nmove(dx, dy) {\n this.x += dx;\n this.y += dy;\n\n // Move all contained shapes with the frame\n this.containedShapes.forEach(shape => {\n if (shape) {\n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n\n // Use shape's own move method for proper handling of all shape types\n if (typeof shape.move === 'function') {\n shape.move(dx, dy);\n } else {\n shape.x += dx;\n shape.y += dy;\n }\n\n // Force redraw for shapes whose move() doesn't auto-redraw\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n\n // Update bounding box for freehand strokes\n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n\n // Remove the flag after movement\n delete shape.isBeingMovedByFrame;\n }\n });\n\n // Update arrows attached to this frame\n this.updateAttachedArrows();\n\n this.draw();\n this.updateClipPath();\n}\n\n handleResizeLegacy(anchorIndex, currentPos, startPos, initialFrame) {\n // Legacy version - superseded by the handleResize below with contained shapes scaling\n const dx = currentPos.x - startPos.x;\n const dy = currentPos.y - startPos.y;\n\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + dx; this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 1: this.y = initialFrame.y + dy; this.height = Math.max(10, initialFrame.height - dy); break;\n case 2: this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 3: this.width = Math.max(10, initialFrame.width + dx); break;\n case 4: this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 5: this.height = Math.max(10, initialFrame.height + dy); break;\n case 6: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 7: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); break;\n }\n this.updateAttachedArrows();\n this.updateContainedShapes();\n}\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n addFrameLabel() {\n const labelText = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n labelText.setAttribute(\"x\", this.x + 5);\n labelText.setAttribute(\"y\", this.y - 10);\n labelText.setAttribute(\"font-size\", `${16 / currentZoom}px`);\n labelText.setAttribute(\"fill\", this.options.stroke);\n labelText.setAttribute(\"font-family\", \"lixFont\");\n labelText.textContent = this.frameName || \"Frame\";\n labelText.style.cursor = \"pointer\";\n labelText.style.userSelect = \"none\";\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n labelText.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Add double-click event for renaming\n labelText.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n this.startLabelEdit(labelText);\n });\n \n this.group.appendChild(labelText);\n this.labelElement = labelText;\n}\n\nstartLabelEdit(labelElement) {\n // Create a foreignObject to hold an HTML input\n const foreignObject = document.createElementNS(\"http://www.w3.org/2000/svg\", \"foreignObject\");\n foreignObject.setAttribute(\"x\", this.x + 5);\n foreignObject.setAttribute(\"y\", this.y - 20);\n foreignObject.setAttribute(\"width\", Math.max(100, this.width - 10));\n foreignObject.setAttribute(\"height\", 20);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n foreignObject.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Create input element\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = this.frameName || \"Frame\";\n const oldName = this.frameName; // Store old name for undo\n \n input.style.cssText = `\n position: absolute;\n width: 100%;\n height: 20px;\n border: 1px solid #5B57D1;\n background: transparent;\n color: ${this.options.stroke};\n font-family: \"lixFont\";\n font-size: ${15 / currentZoom}px;\n padding: 2px 10px;\n margin: 0;\n outline: none;\n border-radius: 2px;\n box-sizing: border-box;\n `;\n \n foreignObject.appendChild(input);\n this.group.appendChild(foreignObject);\n \n // Hide the original label\n labelElement.style.display = \"none\";\n \n // Focus and select the text\n setTimeout(() => {\n input.focus();\n input.select();\n }, 10);\n \n const finishEdit = () => {\n const newName = input.value.trim() || \"Frame\";\n \n // Track name change in undo system if it actually changed\n if (newName !== oldName) {\n pushTransformAction(this, \n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: oldName \n },\n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: newName \n }\n );\n }\n \n this.frameName = newName;\n \n // Remove the input\n this.group.removeChild(foreignObject);\n \n // Show and update the label\n labelElement.style.display = \"block\";\n labelElement.textContent = this.frameName;\n \n this.labelElement = labelElement;\n };\n \n // Handle input events\n input.addEventListener('blur', finishEdit);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n finishEdit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n // Cancel edit - restore original name\n this.group.removeChild(foreignObject);\n labelElement.style.display = \"block\";\n }\n });\n \n // Prevent the input from interfering with other interactions\n input.addEventListener('pointerdown', (e) => e.stopPropagation());\n input.addEventListener('pointermove', (e) => e.stopPropagation());\n input.addEventListener('pointerup', (e) => e.stopPropagation());\n}\n selectFrame() {\n this.isSelected = true;\n this.draw();\n this._showSidebar();\n }\n\n _showSidebar() {\n // React sidebar bridge\n if (window.__showSidebarForShape) {\n window.__showSidebarForShape('frame');\n }\n\n const sidebar = document.getElementById('frameSideBar');\n const renameInput = document.getElementById('frameRenameInput');\n const resizeBtn = document.getElementById('frameResizeToFit');\n if (!sidebar) return;\n\n sidebar.classList.remove('hidden');\n\n if (renameInput) {\n renameInput.value = this.frameName || 'Frame';\n // Replace old listener by cloning\n const newInput = renameInput.cloneNode(true);\n renameInput.parentNode.replaceChild(newInput, renameInput);\n newInput.addEventListener('input', () => {\n const val = newInput.value.trim() || 'Frame';\n this.frameName = val;\n if (this.labelElement) this.labelElement.textContent = val;\n });\n newInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') newInput.blur();\n });\n newInput.addEventListener('pointerdown', (e) => e.stopPropagation());\n }\n\n if (resizeBtn) {\n const newBtn = resizeBtn.cloneNode(true);\n resizeBtn.parentNode.replaceChild(newBtn, resizeBtn);\n newBtn.addEventListener('click', () => this.resizeToFit());\n }\n }\n\n resizeToFit() {\n if (this.containedShapes.length === 0) return;\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n this.containedShapes.forEach(shape => {\n if (shape.shapeName === 'arrow' || shape.shapeName === 'line') {\n [shape.startPoint, shape.endPoint].filter(Boolean).forEach(p => {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n });\n } else if (typeof shape.x === 'number' && typeof shape.y === 'number') {\n const w = shape.width || 0;\n const h = shape.height || 0;\n minX = Math.min(minX, shape.x);\n minY = Math.min(minY, shape.y);\n maxX = Math.max(maxX, shape.x + w);\n maxY = Math.max(maxY, shape.y + h);\n }\n });\n\n if (!isFinite(minX)) return;\n\n const padding = 20;\n const oldState = { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation };\n\n this.x = minX - padding;\n this.y = minY - padding;\n this.width = (maxX - minX) + padding * 2;\n this.height = (maxY - minY) + padding * 2;\n\n pushTransformAction(this, oldState, { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation });\n this.draw();\n this.updateClipPath();\n this.updateContainedShapes();\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode) {\n anchor.parentNode.removeChild(anchor);\n }\n });\n this.anchors = [];\n this.isSelected = false;\n this.draw();\n const sidebar = document.getElementById('frameSideBar');\n if (sidebar) sidebar.classList.add('hidden');\n }\n\n addAnchors() {\n const anchorSize = 8 / currentZoom;\n const anchorStrokeWidth = 2 / currentZoom;\n\n // Calculate anchor positions (corners + midpoints + rotation handle)\n const anchorPositions = [\n { x: this.x, y: this.y, cursor: 'nw-resize', type: 'corner' }, // Top-left\n { x: this.x + this.width / 2, y: this.y, cursor: 'n-resize', type: 'edge' }, // Top-middle\n { x: this.x + this.width, y: this.y, cursor: 'ne-resize', type: 'corner' }, // Top-right\n { x: this.x + this.width, y: this.y + this.height / 2, cursor: 'e-resize', type: 'edge' }, // Right-middle\n { x: this.x + this.width, y: this.y + this.height, cursor: 'se-resize', type: 'corner' }, // Bottom-right\n { x: this.x + this.width / 2, y: this.y + this.height, cursor: 's-resize', type: 'edge' }, // Bottom-middle\n { x: this.x, y: this.y + this.height, cursor: 'sw-resize', type: 'corner' }, // Bottom-left\n { x: this.x, y: this.y + this.height / 2, cursor: 'w-resize', type: 'edge' }, // Left-middle\n ];\n\n // Add rotation handle\n const rotationHandleDistance = 30 / currentZoom;\n const rotationHandle = {\n x: this.x + this.width / 2,\n y: this.y - rotationHandleDistance,\n cursor: 'grab',\n type: 'rotation'\n };\n anchorPositions.push(rotationHandle);\n\n // Create selection outline first (behind anchors)\n const outline = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n outline.setAttribute('x', this.x);\n outline.setAttribute('y', this.y);\n outline.setAttribute('width', this.width);\n outline.setAttribute('height', this.height);\n outline.setAttribute('fill', 'none');\n outline.setAttribute('stroke', '#5B57D1');\n outline.setAttribute('stroke-width', 1.5);\n outline.setAttribute('vector-effect', 'non-scaling-stroke');\n outline.setAttribute('stroke-dasharray', '4 2');\n outline.setAttribute('style', 'pointer-events: none;');\n\n // Apply rotation to outline if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n outline.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.group.appendChild(outline);\n this.selectionOutline = outline;\n\n anchorPositions.forEach((position, index) => {\n let anchor;\n \n if (position.type === 'rotation') {\n // Create rotation handle (circle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n anchor.setAttribute(\"cx\", position.x);\n anchor.setAttribute(\"cy\", position.y);\n anchor.setAttribute(\"r\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Add rotation line\n const rotationLine = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n rotationLine.setAttribute(\"x1\", this.x + this.width / 2);\n rotationLine.setAttribute(\"y1\", this.y);\n rotationLine.setAttribute(\"x2\", position.x);\n rotationLine.setAttribute(\"y2\", position.y);\n rotationLine.setAttribute(\"stroke\", \"#5B57D1\"); \n rotationLine.setAttribute(\"stroke-width\", anchorStrokeWidth);\n rotationLine.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Apply rotation to rotation line if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n rotationLine.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n this.group.appendChild(rotationLine);\n } else {\n // Create resize handle (rectangle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n anchor.setAttribute(\"x\", position.x - anchorSize / 2);\n anchor.setAttribute(\"y\", position.y - anchorSize / 2);\n anchor.setAttribute(\"width\", anchorSize);\n anchor.setAttribute(\"height\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n }\n\n // Apply rotation to anchor if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n anchor.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n anchor.style.cursor = position.cursor;\n anchor.addEventListener('pointerdown', (e) => this.startAnchorDrag(e, index));\n \n this.anchors.push(anchor);\n this.group.appendChild(anchor);\n });\n }\n\n startAnchorDrag(e, index) {\n e.stopPropagation();\n e.preventDefault();\n\n // Store initial state for undo\n dragOldPosFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const startMousePos = getSVGCoordsFromMouse(e);\n const initialFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const onPointerMove = (event) => {\n const currentMousePos = getSVGCoordsFromMouse(event);\n \n if (index === 8) { // Rotation handle\n this.handleRotation(currentMousePos, initialFrame);\n } else {\n this.handleResize(index, currentMousePos, startMousePos, initialFrame);\n }\n \n this.draw();\n this.updateContainedShapes();\n };\n\n const onPointerUp = () => {\n if (dragOldPosFrame) {\n const newPos = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n pushTransformAction(this, dragOldPosFrame, newPos);\n dragOldPosFrame = null;\n }\n \n svg.removeEventListener('pointermove', onPointerMove);\n svg.removeEventListener('pointerup', onPointerUp);\n svg.style.cursor = 'default';\n };\n\n svg.addEventListener('pointermove', onPointerMove);\n svg.addEventListener('pointerup', onPointerUp);\n }\n\n handleRotation(mousePos, initialFrame) {\n const centerX = initialFrame.x + initialFrame.width / 2;\n const centerY = initialFrame.y + initialFrame.height / 2;\n \n const angle = Math.atan2(mousePos.y - centerY, mousePos.x - centerX);\n const newRotation = (angle * 180 / Math.PI + 90) % 360;\n const angleDiff = newRotation - this.rotation;\n const angleRad = angleDiff * Math.PI / 180;\n const cosAngle = Math.cos(angleRad);\n const sinAngle = Math.sin(angleRad);\n \n // Store the rotation center for contained shapes\n const rotationCenter = { x: centerX, y: centerY };\n \n // Rotate all contained shapes around the frame's center\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n \n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n \n switch (shape.shapeName) {\n case 'rectangle':\n case 'frame':\n case 'image':\n case 'icon':\n // Get shape's current center\n const shapeCenterX = shape.x + shape.width / 2;\n const shapeCenterY = shape.y + shape.height / 2;\n \n // Calculate relative position from rotation center\n const relativeX = shapeCenterX - rotationCenter.x;\n const relativeY = shapeCenterY - rotationCenter.y;\n \n // Apply rotation to get new center position\n const newCenterX = rotationCenter.x + (relativeX * cosAngle - relativeY * sinAngle);\n const newCenterY = rotationCenter.y + (relativeX * sinAngle + relativeY * cosAngle);\n \n // Update shape position\n shape.x = newCenterX - shape.width / 2;\n shape.y = newCenterY - shape.height / 2;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'circle':\n // Get circle's center\n const circleCenterX = shape.x;\n const circleCenterY = shape.y;\n \n // Calculate relative position from rotation center\n const relativeCircleX = circleCenterX - rotationCenter.x;\n const relativeCircleY = circleCenterY - rotationCenter.y;\n \n // Apply rotation\n const newCircleCenterX = rotationCenter.x + (relativeCircleX * cosAngle - relativeCircleY * sinAngle);\n const newCircleCenterY = rotationCenter.y + (relativeCircleX * sinAngle + relativeCircleY * cosAngle);\n \n shape.x = newCircleCenterX;\n shape.y = newCircleCenterY;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'line':\n case 'arrow':\n // Calculate relative positions for start and end points\n const relativeStartX = shape.startPoint.x - rotationCenter.x;\n const relativeStartY = shape.startPoint.y - rotationCenter.y;\n const relativeEndX = shape.endPoint.x - rotationCenter.x;\n const relativeEndY = shape.endPoint.y - rotationCenter.y;\n \n // Apply rotation to both points\n const newStartX = rotationCenter.x + (relativeStartX * cosAngle - relativeStartY * sinAngle);\n const newStartY = rotationCenter.y + (relativeStartX * sinAngle + relativeStartY * cosAngle);\n const newEndX = rotationCenter.x + (relativeEndX * cosAngle - relativeEndY * sinAngle);\n const newEndY = rotationCenter.y + (relativeEndX * sinAngle + relativeEndY * cosAngle);\n \n shape.startPoint.x = newStartX;\n shape.startPoint.y = newStartY;\n shape.endPoint.x = newEndX;\n shape.endPoint.y = newEndY;\n \n if (shape.shapeName === 'arrow' && shape.arrowCurved && typeof shape.initializeCurveControlPoints === 'function') {\n shape.initializeCurveControlPoints();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'text':\n case 'code':\n // Get text/code bounds for center calculation\n const textOrCodeEl = shape.group ? (shape.group.querySelector('text') || shape.group.querySelector('foreignObject')) : null;\n if (textOrCodeEl) {\n const bbox = textOrCodeEl.getBBox();\n const transform = shape.group.transform.baseVal.consolidate();\n const matrix = transform ? transform.matrix : { e: 0, f: 0 };\n\n const textCenterX = bbox.x + matrix.e + bbox.width / 2;\n const textCenterY = bbox.y + matrix.f + bbox.height / 2;\n\n // Calculate relative position\n const relativeTextX = textCenterX - rotationCenter.x;\n const relativeTextY = textCenterY - rotationCenter.y;\n\n // Apply rotation\n const newTextCenterX = rotationCenter.x + (relativeTextX * cosAngle - relativeTextY * sinAngle);\n const newTextCenterY = rotationCenter.y + (relativeTextX * sinAngle + relativeTextY * cosAngle);\n\n // Update position\n const newTransformX = newTextCenterX - bbox.width / 2;\n const newTransformY = newTextCenterY - bbox.height / 2;\n const newShapeRotation = (shape.rotation || 0) + angleDiff;\n\n const textCenterRelativeX = bbox.width / 2;\n const textCenterRelativeY = bbox.height / 2;\n\n shape.group.setAttribute('transform',\n `translate(${newTransformX}, ${newTransformY}) rotate(${newShapeRotation}, ${textCenterRelativeX}, ${textCenterRelativeY})`\n );\n\n shape.x = newTransformX;\n shape.y = newTransformY;\n shape.rotation = newShapeRotation;\n }\n break;\n \n case 'freehandStroke':\n if (shape.points && Array.isArray(shape.points)) {\n // Rotate each point in the stroke\n shape.points = shape.points.map(point => {\n if (!Array.isArray(point) || point.length < 2) return point;\n \n const relativePointX = point[0] - rotationCenter.x;\n const relativePointY = point[1] - rotationCenter.y;\n \n const newPointX = rotationCenter.x + (relativePointX * cosAngle - relativePointY * sinAngle);\n const newPointY = rotationCenter.y + (relativePointX * sinAngle + relativePointY * cosAngle);\n \n return [newPointX, newPointY, point[2] || 0.5];\n });\n \n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n }\n break;\n }\n \n // Update arrows attached to the contained shape\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n \n // Remove the flag after rotation\n delete shape.isBeingMovedByFrame;\n });\n \n // Update the frame's rotation\n this.rotation = newRotation;\n \n // Update arrows attached to this frame\n this.updateAttachedArrows();\n }\n\n handleResize(anchorIndex, currentPos, startPos, initialFrame) {\n const rawDx = currentPos.x - startPos.x;\n const rawDy = currentPos.y - startPos.y;\n\n // Rotate delta to local (unrotated) space when frame is rotated\n const rad = (this.rotation || 0) * Math.PI / 180;\n const cosR = Math.cos(rad);\n const sinR = Math.sin(rad);\n const dx = rawDx * cosR + rawDy * sinR;\n const dy = -rawDx * sinR + rawDy * cosR;\n\n // Store old frame for scale calculation\n const oldX = this.x, oldY = this.y, oldW = this.width, oldH = this.height;\n\n // Compute new dimensions using local-space deltas\n let newW, newH;\n // Fixed corner relative to initial frame origin: (fixRelX, fixRelY)\n let fixRelX, fixRelY;\n\n switch (anchorIndex) {\n case 0: // Top-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = initialFrame.width; fixRelY = initialFrame.height;\n break;\n case 1: // Top-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 2: // Top-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 3: // Right-middle\n newW = Math.max(10, initialFrame.width + dx);\n newH = initialFrame.height;\n fixRelX = 0; fixRelY = 0;\n break;\n case 4: // Bottom-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 5: // Bottom-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 6: // Bottom-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n case 7: // Left-middle\n newW = Math.max(10, initialFrame.width - dx);\n newH = initialFrame.height;\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n }\n\n // Compute new position using fixed-corner constraint\n if (this.rotation && this.rotation !== 0) {\n // Compute rotated world position of the fixed corner in the initial frame\n const iCX = initialFrame.x + initialFrame.width / 2;\n const iCY = initialFrame.y + initialFrame.height / 2;\n const odx = (initialFrame.x + fixRelX) - iCX;\n const ody = (initialFrame.y + fixRelY) - iCY;\n const fixedWorldX = iCX + odx * cosR - ody * sinR;\n const fixedWorldY = iCY + odx * sinR + ody * cosR;\n\n // Where the fixed corner sits in new rect (relative to new origin)\n const fixNewRelX = (fixRelX === 0) ? 0 : newW;\n const fixNewRelY = (fixRelY === 0) ? 0 : newH;\n\n // Solve for new origin\n const ncx = newW / 2;\n const ncy = newH / 2;\n const ndx = fixNewRelX - ncx;\n const ndy = fixNewRelY - ncy;\n const rotX = ncx + ndx * cosR - ndy * sinR;\n const rotY = ncy + ndx * sinR + ndy * cosR;\n\n this.x = fixedWorldX - rotX;\n this.y = fixedWorldY - rotY;\n } else {\n // No rotation - use simple axis-aligned position calculation\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + (initialFrame.width - newW); this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 1: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 2: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 3: break;\n case 4: break;\n case 5: break;\n case 6: this.x = initialFrame.x + (initialFrame.width - newW); break;\n case 7: this.x = initialFrame.x + (initialFrame.width - newW); break;\n }\n }\n\n this.width = newW;\n this.height = newH;\n\n // Scale contained shapes proportionally so nothing falls out\n if (oldW > 0 && oldH > 0) {\n const scaleX = this.width / oldW;\n const scaleY = this.height / oldH;\n\n if (Math.abs(scaleX - 1) > 0.001 || Math.abs(scaleY - 1) > 0.001) {\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n shape.isBeingMovedByFrame = true;\n\n switch (shape.shapeName) {\n case 'rectangle':\n case 'image':\n case 'icon':\n case 'code': {\n const relX = (shape.x - oldX) / oldW;\n const relY = (shape.y - oldY) / oldH;\n const relW = shape.width / oldW;\n const relH = shape.height / oldH;\n shape.x = this.x + relX * this.width;\n shape.y = this.y + relY * this.height;\n shape.width = relW * this.width;\n shape.height = relH * this.height;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'circle': {\n const relCX = (shape.x - oldX) / oldW;\n const relCY = (shape.y - oldY) / oldH;\n shape.x = this.x + relCX * this.width;\n shape.y = this.y + relCY * this.height;\n shape.rx = (shape.rx / oldW) * this.width;\n shape.ry = (shape.ry / oldH) * this.height;\n shape.width = shape.rx * 2;\n shape.height = shape.ry * 2;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'arrow':\n case 'line': {\n const relSX = (shape.startPoint.x - oldX) / oldW;\n const relSY = (shape.startPoint.y - oldY) / oldH;\n const relEX = (shape.endPoint.x - oldX) / oldW;\n const relEY = (shape.endPoint.y - oldY) / oldH;\n shape.startPoint.x = this.x + relSX * this.width;\n shape.startPoint.y = this.y + relSY * this.height;\n shape.endPoint.x = this.x + relEX * this.width;\n shape.endPoint.y = this.y + relEY * this.height;\n if (shape.controlPoint1) {\n const relC1X = (shape.controlPoint1.x - oldX) / oldW;\n const relC1Y = (shape.controlPoint1.y - oldY) / oldH;\n shape.controlPoint1.x = this.x + relC1X * this.width;\n shape.controlPoint1.y = this.y + relC1Y * this.height;\n }\n if (shape.controlPoint2) {\n const relC2X = (shape.controlPoint2.x - oldX) / oldW;\n const relC2Y = (shape.controlPoint2.y - oldY) / oldH;\n shape.controlPoint2.x = this.x + relC2X * this.width;\n shape.controlPoint2.y = this.y + relC2Y * this.height;\n }\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'text': {\n const tx = shape.x || 0;\n const ty = shape.y || 0;\n const relTX = (tx - oldX) / oldW;\n const relTY = (ty - oldY) / oldH;\n shape.x = this.x + relTX * this.width;\n shape.y = this.y + relTY * this.height;\n break;\n }\n }\n\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n delete shape.isBeingMovedByFrame;\n });\n }\n }\n\n // Update contained shapes visibility\n this.updateContainedShapes();\n }\n \n temporarilyRemoveFromFrame(shape) {\n if (shape && shape.parentFrame === this) {\n // Move shape back to main SVG temporarily (without removing from containedShapes array)\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n shape.isDraggedOutTemporarily = true;\n }\n}\n\n// Add a method to restore clipping for a shape after drag\nrestoreToFrame(shape) {\n if (shape && shape.parentFrame === this && shape.isDraggedOutTemporarily) {\n // Move shape back to clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === svg) {\n svg.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n\n contains(viewBoxX, viewBoxY) {\n // Simple point-in-rectangle test (without rotation for now)\n return viewBoxX >= this.x && viewBoxX <= this.x + this.width &&\n viewBoxY >= this.y && viewBoxY <= this.y + this.height;\n }\n\n // Arrow attachment support (similar to other shapes)\n getAttachmentPoint(point, tolerance = 20) {\n const rect = {\n left: this.x,\n right: this.x + this.width,\n top: this.y,\n bottom: this.y + this.height\n };\n\n const distances = {\n top: Math.abs(point.y - rect.top),\n bottom: Math.abs(point.y - rect.bottom),\n left: Math.abs(point.x - rect.left),\n right: Math.abs(point.x - rect.right)\n };\n\n let closestSide = null;\n let minDistance = tolerance;\n\n for (let side in distances) {\n if (distances[side] < minDistance &&\n ((side === 'top' || side === 'bottom') && point.x >= rect.left && point.x <= rect.right) ||\n ((side === 'left' || side === 'right') && point.y >= rect.top && point.y <= rect.bottom)) {\n minDistance = distances[side];\n closestSide = side;\n }\n }\n\n if (closestSide) {\n let attachPoint;\n const offset = { x: 0, y: 0 };\n\n switch (closestSide) {\n case 'top':\n attachPoint = { x: point.x, y: rect.top };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'bottom':\n attachPoint = { x: point.x, y: rect.bottom };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'left':\n attachPoint = { x: rect.left, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n case 'right':\n attachPoint = { x: rect.right, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n }\n\n return { point: attachPoint, side: closestSide, offset, shape: this };\n }\n\n return null;\n }\n\n updateStyle(newOptions) {\n Object.keys(newOptions).forEach(key => newOptions[key] === undefined && delete newOptions[key]);\n this.options = { ...this.options, ...newOptions };\n this.draw();\n }\n\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n /**\n * Set a background image for this frame from a URL.\n * The image will fit/cover the frame dimensions.\n * @param {string} url - Image URL\n * @param {string} fit - 'cover' (default) | 'contain' | 'fill'\n */\n setImageFromURL(url, fit = 'cover') {\n if (!url) {\n // Remove existing frame image\n if (this._frameImage && this._frameImage.parentNode) {\n this._frameImage.parentNode.removeChild(this._frameImage);\n this._frameImage = null;\n }\n this._frameImageURL = null;\n return;\n }\n\n this._frameImageURL = url;\n this._frameImageFit = fit;\n\n if (!this._frameImage) {\n this._frameImage = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n this._frameImage.setAttribute('pointer-events', 'none');\n }\n // Always update preserveAspectRatio when fit changes\n this._frameImage.setAttribute('preserveAspectRatio',\n fit === 'cover' ? 'xMidYMid slice' :\n fit === 'contain' ? 'xMidYMid meet' :\n fit === 'center' ? 'xMidYMid meet' : 'none'\n );\n\n this._frameImage.setAttribute('href', url);\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n // Insert image right after the frame rect (below contained shapes)\n if (this._frameImage.parentNode === this.group) {\n this.group.removeChild(this._frameImage);\n }\n if (this.element && this.element.nextSibling) {\n this.group.insertBefore(this._frameImage, this.element.nextSibling);\n } else {\n this.group.appendChild(this._frameImage);\n }\n }\n\n /**\n * Update frame image position/size (called during move/resize)\n */\n _updateFrameImage() {\n if (!this._frameImage) return;\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this._frameImage.removeAttribute('transform');\n }\n }\n}\n\nexport { Frame };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable */\n// Frame shape class - extracted from frameHolder.js\n// Depends on globals: svg, shapes, currentShape, currentZoom\n\nimport { cleanupAttachments } from '../tools/arrowTool.js';\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\nlet dragOldPosFrame = null;\n\nclass Frame {\n constructor(x, y, width, height, options = {}) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n this.rotation = options.rotation || 0;\n this.frameName = options.frameName || \"Frame\";\n this.fillStyle = options.fillStyle || \"transparent\"; // 'transparent' | 'solid' | 'grid'\n this.fillColor = options.fillColor || \"#1e1e28\";\n this.gridSize = options.gridSize || 20;\n // Issue #38 follow-up: read the grid stroke from a CSS custom\n // property so the frame grid stays visible in both themes. The\n // var is defined in globals.css for both `body.canvas-mode`\n // (dark-on-light) and `body.canvas-mode.theme-dark` (light-on-dark).\n // The literal here is the dark-theme fallback for environments\n // (tests, embeds) without the canvas-mode CSS in scope.\n this.gridColor = options.gridColor || \"var(--lixsketch-grid-fine, rgba(255,255,255,0.06))\";\n this.options = {\n stroke: options.stroke || \"#555\",\n strokeWidth: options.strokeWidth || 1,\n fill: options.fill || \"transparent\",\n opacity: options.opacity || 1,\n ...options\n };\n\n this.element = null;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.isSelected = false;\n this.anchors = [];\n this.shapeName = \"frame\";\n this.shapeID = `frame-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n this.group.setAttribute('id', this.shapeID);\n\n // Create clipping group for contained shapes\n this.clipGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.clipPath = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath');\n this.clipRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n \n // Set up clipping\n this.clipId = `clip-${this.shapeID}`;\n this.clipPath.setAttribute('id', this.clipId);\n this.clipPath.appendChild(this.clipRect);\n this.clipGroup.setAttribute('clip-path', `url(#${this.clipId})`);\n \n // Add clip path to defs\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n defs.appendChild(this.clipPath);\n\n // Array to hold shapes inside this frame\n this.containedShapes = [];\n\n svg.appendChild(this.group);\n svg.appendChild(this.clipGroup);\n this.draw();\n this.updateClipPath();\n }\n\n draw() {\n // Clear previous elements\n while (this.group.firstChild) {\n this.group.removeChild(this.group.firstChild);\n }\n this.anchors = [];\n\n // Ensure defs exists for grid pattern\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n\n // Determine fill based on fillStyle\n let fillValue = \"transparent\";\n if (this.fillStyle === 'solid') {\n fillValue = this.fillColor;\n } else if (this.fillStyle === 'grid') {\n // Create or update a grid pattern unique to this frame\n const patternId = `frame-grid-${this.shapeID}`;\n let pattern = defs.querySelector(`#${patternId}`);\n if (!pattern) {\n pattern = document.createElementNS('http://www.w3.org/2000/svg', 'pattern');\n pattern.setAttribute('id', patternId);\n pattern.setAttribute('patternUnits', 'userSpaceOnUse');\n defs.appendChild(pattern);\n }\n // Update pattern attributes\n pattern.setAttribute('x', this.x);\n pattern.setAttribute('y', this.y);\n pattern.setAttribute('width', this.gridSize);\n pattern.setAttribute('height', this.gridSize);\n // Clear and rebuild pattern content\n while (pattern.firstChild) pattern.removeChild(pattern.firstChild);\n // Background fill\n const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n bgRect.setAttribute('width', this.gridSize);\n bgRect.setAttribute('height', this.gridSize);\n bgRect.setAttribute('fill', this.fillColor);\n pattern.appendChild(bgRect);\n // Grid lines\n const gridPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n gridPath.setAttribute('d', `M ${this.gridSize} 0 L 0 0 0 ${this.gridSize}`);\n gridPath.setAttribute('fill', 'none');\n gridPath.setAttribute('stroke', this.gridColor);\n gridPath.setAttribute('stroke-width', '0.5');\n pattern.appendChild(gridPath);\n fillValue = `url(#${patternId})`;\n }\n\n // Create the frame rectangle\n const frameRect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n frameRect.setAttribute(\"x\", this.x);\n frameRect.setAttribute(\"y\", this.y);\n frameRect.setAttribute(\"width\", this.width);\n frameRect.setAttribute(\"height\", this.height);\n frameRect.setAttribute(\"stroke\", this.options.stroke);\n frameRect.setAttribute(\"stroke-width\", this.options.strokeWidth);\n frameRect.setAttribute(\"fill\", fillValue);\n frameRect.setAttribute(\"opacity\", this.options.opacity);\n frameRect.setAttribute(\"stroke-dasharray\", \"5,5\");\n frameRect.classList.add(\"frame-rect\");\n\n // Apply rotation\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n frameRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.element = frameRect;\n this.group.appendChild(this.element);\n\n // Add label\n this.addFrameLabel();\n\n // Re-attach frame image if present\n if (this._frameImageURL) {\n this.setImageFromURL(this._frameImageURL, this._frameImageFit || 'cover');\n }\n\n // Add selection anchors if selected\n if (this.isSelected) {\n this.addAnchors();\n }\n\n // Update clip path\n this.updateClipPath();\n }\n\n updateAttachedArrows() {\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(shape => {\n if (shape.shapeName === 'arrow') {\n let needsUpdate = false;\n \n // Check if arrow is attached to this frame\n if (shape.attachedToStart && shape.attachedToStart.shape === this) {\n needsUpdate = true;\n }\n if (shape.attachedToEnd && shape.attachedToEnd.shape === this) {\n needsUpdate = true;\n }\n \n if (needsUpdate) {\n shape.updateAttachments();\n }\n }\n });\n }\n }\n\n updateClipPath() {\n // Update the clipping rectangle to match frame dimensions\n this.clipRect.setAttribute(\"x\", this.x);\n this.clipRect.setAttribute(\"y\", this.y);\n this.clipRect.setAttribute(\"width\", this.width);\n this.clipRect.setAttribute(\"height\", this.height);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this.clipRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this.clipRect.removeAttribute(\"transform\");\n }\n }\n\n addShapeToFrame(shape) {\n if (shape && !this.containedShapes.includes(shape)) {\n const oldFrame = shape.parentFrame;\n\n // Remove from other frames first\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(otherFrame => {\n if (otherFrame.shapeName === 'frame' && otherFrame !== this) {\n otherFrame.removeShapeFromFrame(shape);\n }\n });\n }\n\n this.containedShapes.push(shape);\n shape.parentFrame = this;\n\n // Only move to clipped group if not currently being dragged\n const el = shape.group || shape.element;\n if (el && el.parentNode && !shape.isDraggedOutTemporarily) {\n el.parentNode.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup into our clipGroup\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n this.clipGroup.appendChild(shape.clipGroup);\n }\n }\n}\n\n removeShapeFromFrame(shape) {\n const index = this.containedShapes.indexOf(shape);\n if (index > -1) {\n this.containedShapes.splice(index, 1);\n if (shape.parentFrame === this) {\n shape.parentFrame = null;\n }\n\n // Move shape's group/element back to main SVG if it's in the clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup back to main SVG\n if (shape.shapeName === 'frame' && shape.clipGroup && shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n svg.appendChild(shape.clipGroup);\n }\n\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n // Check if a point is inside the frame bounds\n isPointInFrame(x, y) {\n // Simple bounding box check (can be enhanced for rotation)\n return x >= this.x && x <= this.x + this.width &&\n y >= this.y && y <= this.y + this.height;\n }\n\n // Check if a shape overlaps with this frame\n isShapeInFrame(shape) {\n if (!shape || shape === this) return false;\n \n const shapeX = shape.x || 0;\n const shapeY = shape.y || 0;\n const shapeWidth = shape.width || 0;\n const shapeHeight = shape.height || 0;\n \n // Check if the center of the shape is inside the frame (for better UX)\n const shapeCenterX = shapeX + shapeWidth / 2;\n const shapeCenterY = shapeY + shapeHeight / 2;\n \n return shapeCenterX >= this.x && shapeCenterX <= this.x + this.width &&\n shapeCenterY >= this.y && shapeCenterY <= this.y + this.height;\n}\n\nupdateContainedShapes(applyClipping = true) {\n // Check all shapes to see if they should be in this frame\n if (typeof shapes === 'undefined' || !Array.isArray(shapes)) return;\n shapes.forEach(shape => {\n if (shape !== this) {\n // Skip frames that are larger than or equal to this frame (prevent parent containing child loops)\n if (shape.shapeName === 'frame') {\n const shapeArea = (shape.width || 0) * (shape.height || 0);\n const thisArea = (this.width || 0) * (this.height || 0);\n if (shapeArea >= thisArea) return;\n }\n const isInFrame = this.isShapeInFrame(shape);\n const isAlreadyContained = this.containedShapes.includes(shape);\n\n if (isInFrame && !isAlreadyContained) {\n this.addShapeToFrame(shape);\n // Don't apply clipping if we're not supposed to\n if (!applyClipping) {\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n shape.isDraggedOutTemporarily = true;\n }\n }\n } else if (!isInFrame && isAlreadyContained) {\n this.removeShapeFromFrame(shape);\n }\n }\n });\n \n // Update clip path\n this.updateClipPath();\n}\n\nhighlightFrame() {\n if (this.element) {\n this.element.setAttribute('stroke', '#5B57D1');\n this.element.setAttribute('stroke-width', '3');\n this.element.setAttribute('opacity', '0.7');\n }\n}\n\n// Remove frame highlight\nremoveHighlight() {\n if (this.element) {\n this.element.setAttribute('stroke', this.options.stroke);\n this.element.setAttribute('stroke-width', this.options.strokeWidth);\n this.element.setAttribute('opacity', this.options.opacity);\n }\n}\n \n\nmove(dx, dy) {\n this.x += dx;\n this.y += dy;\n\n // Move all contained shapes with the frame\n this.containedShapes.forEach(shape => {\n if (shape) {\n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n\n // Use shape's own move method for proper handling of all shape types\n if (typeof shape.move === 'function') {\n shape.move(dx, dy);\n } else {\n shape.x += dx;\n shape.y += dy;\n }\n\n // Force redraw for shapes whose move() doesn't auto-redraw\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n\n // Update bounding box for freehand strokes\n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n\n // Remove the flag after movement\n delete shape.isBeingMovedByFrame;\n }\n });\n\n // Update arrows attached to this frame\n this.updateAttachedArrows();\n\n this.draw();\n this.updateClipPath();\n}\n\n handleResizeLegacy(anchorIndex, currentPos, startPos, initialFrame) {\n // Legacy version - superseded by the handleResize below with contained shapes scaling\n const dx = currentPos.x - startPos.x;\n const dy = currentPos.y - startPos.y;\n\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + dx; this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 1: this.y = initialFrame.y + dy; this.height = Math.max(10, initialFrame.height - dy); break;\n case 2: this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 3: this.width = Math.max(10, initialFrame.width + dx); break;\n case 4: this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 5: this.height = Math.max(10, initialFrame.height + dy); break;\n case 6: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 7: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); break;\n }\n this.updateAttachedArrows();\n this.updateContainedShapes();\n}\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n addFrameLabel() {\n const labelText = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n labelText.setAttribute(\"x\", this.x + 5);\n labelText.setAttribute(\"y\", this.y - 10);\n labelText.setAttribute(\"font-size\", `${16 / currentZoom}px`);\n labelText.setAttribute(\"fill\", this.options.stroke);\n labelText.setAttribute(\"font-family\", \"lixFont\");\n labelText.textContent = this.frameName || \"Frame\";\n labelText.style.cursor = \"pointer\";\n labelText.style.userSelect = \"none\";\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n labelText.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Add double-click event for renaming\n labelText.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n this.startLabelEdit(labelText);\n });\n \n this.group.appendChild(labelText);\n this.labelElement = labelText;\n}\n\nstartLabelEdit(labelElement) {\n // Create a foreignObject to hold an HTML input\n const foreignObject = document.createElementNS(\"http://www.w3.org/2000/svg\", \"foreignObject\");\n foreignObject.setAttribute(\"x\", this.x + 5);\n foreignObject.setAttribute(\"y\", this.y - 20);\n foreignObject.setAttribute(\"width\", Math.max(100, this.width - 10));\n foreignObject.setAttribute(\"height\", 20);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n foreignObject.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Create input element\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = this.frameName || \"Frame\";\n const oldName = this.frameName; // Store old name for undo\n \n input.style.cssText = `\n position: absolute;\n width: 100%;\n height: 20px;\n border: 1px solid #5B57D1;\n background: transparent;\n color: ${this.options.stroke};\n font-family: \"lixFont\";\n font-size: ${15 / currentZoom}px;\n padding: 2px 10px;\n margin: 0;\n outline: none;\n border-radius: 2px;\n box-sizing: border-box;\n `;\n \n foreignObject.appendChild(input);\n this.group.appendChild(foreignObject);\n \n // Hide the original label\n labelElement.style.display = \"none\";\n \n // Focus and select the text\n setTimeout(() => {\n input.focus();\n input.select();\n }, 10);\n \n const finishEdit = () => {\n const newName = input.value.trim() || \"Frame\";\n \n // Track name change in undo system if it actually changed\n if (newName !== oldName) {\n pushTransformAction(this, \n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: oldName \n },\n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: newName \n }\n );\n }\n \n this.frameName = newName;\n \n // Remove the input\n this.group.removeChild(foreignObject);\n \n // Show and update the label\n labelElement.style.display = \"block\";\n labelElement.textContent = this.frameName;\n \n this.labelElement = labelElement;\n };\n \n // Handle input events\n input.addEventListener('blur', finishEdit);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n finishEdit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n // Cancel edit - restore original name\n this.group.removeChild(foreignObject);\n labelElement.style.display = \"block\";\n }\n });\n \n // Prevent the input from interfering with other interactions\n input.addEventListener('pointerdown', (e) => e.stopPropagation());\n input.addEventListener('pointermove', (e) => e.stopPropagation());\n input.addEventListener('pointerup', (e) => e.stopPropagation());\n}\n selectFrame() {\n this.isSelected = true;\n this.draw();\n this._showSidebar();\n }\n\n _showSidebar() {\n // React sidebar bridge\n if (window.__showSidebarForShape) {\n window.__showSidebarForShape('frame');\n }\n\n const sidebar = document.getElementById('frameSideBar');\n const renameInput = document.getElementById('frameRenameInput');\n const resizeBtn = document.getElementById('frameResizeToFit');\n if (!sidebar) return;\n\n sidebar.classList.remove('hidden');\n\n if (renameInput) {\n renameInput.value = this.frameName || 'Frame';\n // Replace old listener by cloning\n const newInput = renameInput.cloneNode(true);\n renameInput.parentNode.replaceChild(newInput, renameInput);\n newInput.addEventListener('input', () => {\n const val = newInput.value.trim() || 'Frame';\n this.frameName = val;\n if (this.labelElement) this.labelElement.textContent = val;\n });\n newInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') newInput.blur();\n });\n newInput.addEventListener('pointerdown', (e) => e.stopPropagation());\n }\n\n if (resizeBtn) {\n const newBtn = resizeBtn.cloneNode(true);\n resizeBtn.parentNode.replaceChild(newBtn, resizeBtn);\n newBtn.addEventListener('click', () => this.resizeToFit());\n }\n }\n\n resizeToFit() {\n if (this.containedShapes.length === 0) return;\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n this.containedShapes.forEach(shape => {\n if (shape.shapeName === 'arrow' || shape.shapeName === 'line') {\n [shape.startPoint, shape.endPoint].filter(Boolean).forEach(p => {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n });\n } else if (typeof shape.x === 'number' && typeof shape.y === 'number') {\n const w = shape.width || 0;\n const h = shape.height || 0;\n minX = Math.min(minX, shape.x);\n minY = Math.min(minY, shape.y);\n maxX = Math.max(maxX, shape.x + w);\n maxY = Math.max(maxY, shape.y + h);\n }\n });\n\n if (!isFinite(minX)) return;\n\n const padding = 20;\n const oldState = { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation };\n\n this.x = minX - padding;\n this.y = minY - padding;\n this.width = (maxX - minX) + padding * 2;\n this.height = (maxY - minY) + padding * 2;\n\n pushTransformAction(this, oldState, { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation });\n this.draw();\n this.updateClipPath();\n this.updateContainedShapes();\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode) {\n anchor.parentNode.removeChild(anchor);\n }\n });\n this.anchors = [];\n this.isSelected = false;\n this.draw();\n const sidebar = document.getElementById('frameSideBar');\n if (sidebar) sidebar.classList.add('hidden');\n }\n\n addAnchors() {\n const anchorSize = 8 / currentZoom;\n const anchorStrokeWidth = 2 / currentZoom;\n\n // Calculate anchor positions (corners + midpoints + rotation handle)\n const anchorPositions = [\n { x: this.x, y: this.y, cursor: 'nw-resize', type: 'corner' }, // Top-left\n { x: this.x + this.width / 2, y: this.y, cursor: 'n-resize', type: 'edge' }, // Top-middle\n { x: this.x + this.width, y: this.y, cursor: 'ne-resize', type: 'corner' }, // Top-right\n { x: this.x + this.width, y: this.y + this.height / 2, cursor: 'e-resize', type: 'edge' }, // Right-middle\n { x: this.x + this.width, y: this.y + this.height, cursor: 'se-resize', type: 'corner' }, // Bottom-right\n { x: this.x + this.width / 2, y: this.y + this.height, cursor: 's-resize', type: 'edge' }, // Bottom-middle\n { x: this.x, y: this.y + this.height, cursor: 'sw-resize', type: 'corner' }, // Bottom-left\n { x: this.x, y: this.y + this.height / 2, cursor: 'w-resize', type: 'edge' }, // Left-middle\n ];\n\n // Add rotation handle\n const rotationHandleDistance = 30 / currentZoom;\n const rotationHandle = {\n x: this.x + this.width / 2,\n y: this.y - rotationHandleDistance,\n cursor: 'grab',\n type: 'rotation'\n };\n anchorPositions.push(rotationHandle);\n\n // Create selection outline first (behind anchors)\n const outline = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n outline.setAttribute('x', this.x);\n outline.setAttribute('y', this.y);\n outline.setAttribute('width', this.width);\n outline.setAttribute('height', this.height);\n outline.setAttribute('fill', 'none');\n outline.setAttribute('stroke', '#5B57D1');\n outline.setAttribute('stroke-width', 1.5);\n outline.setAttribute('vector-effect', 'non-scaling-stroke');\n outline.setAttribute('stroke-dasharray', '4 2');\n outline.setAttribute('style', 'pointer-events: none;');\n\n // Apply rotation to outline if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n outline.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.group.appendChild(outline);\n this.selectionOutline = outline;\n\n anchorPositions.forEach((position, index) => {\n let anchor;\n \n if (position.type === 'rotation') {\n // Create rotation handle (circle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n anchor.setAttribute(\"cx\", position.x);\n anchor.setAttribute(\"cy\", position.y);\n anchor.setAttribute(\"r\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Add rotation line\n const rotationLine = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n rotationLine.setAttribute(\"x1\", this.x + this.width / 2);\n rotationLine.setAttribute(\"y1\", this.y);\n rotationLine.setAttribute(\"x2\", position.x);\n rotationLine.setAttribute(\"y2\", position.y);\n rotationLine.setAttribute(\"stroke\", \"#5B57D1\"); \n rotationLine.setAttribute(\"stroke-width\", anchorStrokeWidth);\n rotationLine.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Apply rotation to rotation line if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n rotationLine.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n this.group.appendChild(rotationLine);\n } else {\n // Create resize handle (rectangle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n anchor.setAttribute(\"x\", position.x - anchorSize / 2);\n anchor.setAttribute(\"y\", position.y - anchorSize / 2);\n anchor.setAttribute(\"width\", anchorSize);\n anchor.setAttribute(\"height\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n }\n\n // Apply rotation to anchor if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n anchor.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n anchor.style.cursor = position.cursor;\n anchor.addEventListener('pointerdown', (e) => this.startAnchorDrag(e, index));\n \n this.anchors.push(anchor);\n this.group.appendChild(anchor);\n });\n }\n\n startAnchorDrag(e, index) {\n e.stopPropagation();\n e.preventDefault();\n\n // Store initial state for undo\n dragOldPosFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const startMousePos = getSVGCoordsFromMouse(e);\n const initialFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const onPointerMove = (event) => {\n const currentMousePos = getSVGCoordsFromMouse(event);\n \n if (index === 8) { // Rotation handle\n this.handleRotation(currentMousePos, initialFrame);\n } else {\n this.handleResize(index, currentMousePos, startMousePos, initialFrame);\n }\n \n this.draw();\n this.updateContainedShapes();\n };\n\n const onPointerUp = () => {\n if (dragOldPosFrame) {\n const newPos = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n pushTransformAction(this, dragOldPosFrame, newPos);\n dragOldPosFrame = null;\n }\n \n svg.removeEventListener('pointermove', onPointerMove);\n svg.removeEventListener('pointerup', onPointerUp);\n svg.style.cursor = 'default';\n };\n\n svg.addEventListener('pointermove', onPointerMove);\n svg.addEventListener('pointerup', onPointerUp);\n }\n\n handleRotation(mousePos, initialFrame) {\n const centerX = initialFrame.x + initialFrame.width / 2;\n const centerY = initialFrame.y + initialFrame.height / 2;\n \n const angle = Math.atan2(mousePos.y - centerY, mousePos.x - centerX);\n const newRotation = (angle * 180 / Math.PI + 90) % 360;\n const angleDiff = newRotation - this.rotation;\n const angleRad = angleDiff * Math.PI / 180;\n const cosAngle = Math.cos(angleRad);\n const sinAngle = Math.sin(angleRad);\n \n // Store the rotation center for contained shapes\n const rotationCenter = { x: centerX, y: centerY };\n \n // Rotate all contained shapes around the frame's center\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n \n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n \n switch (shape.shapeName) {\n case 'rectangle':\n case 'frame':\n case 'image':\n case 'icon':\n // Get shape's current center\n const shapeCenterX = shape.x + shape.width / 2;\n const shapeCenterY = shape.y + shape.height / 2;\n \n // Calculate relative position from rotation center\n const relativeX = shapeCenterX - rotationCenter.x;\n const relativeY = shapeCenterY - rotationCenter.y;\n \n // Apply rotation to get new center position\n const newCenterX = rotationCenter.x + (relativeX * cosAngle - relativeY * sinAngle);\n const newCenterY = rotationCenter.y + (relativeX * sinAngle + relativeY * cosAngle);\n \n // Update shape position\n shape.x = newCenterX - shape.width / 2;\n shape.y = newCenterY - shape.height / 2;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'circle':\n // Get circle's center\n const circleCenterX = shape.x;\n const circleCenterY = shape.y;\n \n // Calculate relative position from rotation center\n const relativeCircleX = circleCenterX - rotationCenter.x;\n const relativeCircleY = circleCenterY - rotationCenter.y;\n \n // Apply rotation\n const newCircleCenterX = rotationCenter.x + (relativeCircleX * cosAngle - relativeCircleY * sinAngle);\n const newCircleCenterY = rotationCenter.y + (relativeCircleX * sinAngle + relativeCircleY * cosAngle);\n \n shape.x = newCircleCenterX;\n shape.y = newCircleCenterY;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'line':\n case 'arrow':\n // Calculate relative positions for start and end points\n const relativeStartX = shape.startPoint.x - rotationCenter.x;\n const relativeStartY = shape.startPoint.y - rotationCenter.y;\n const relativeEndX = shape.endPoint.x - rotationCenter.x;\n const relativeEndY = shape.endPoint.y - rotationCenter.y;\n \n // Apply rotation to both points\n const newStartX = rotationCenter.x + (relativeStartX * cosAngle - relativeStartY * sinAngle);\n const newStartY = rotationCenter.y + (relativeStartX * sinAngle + relativeStartY * cosAngle);\n const newEndX = rotationCenter.x + (relativeEndX * cosAngle - relativeEndY * sinAngle);\n const newEndY = rotationCenter.y + (relativeEndX * sinAngle + relativeEndY * cosAngle);\n \n shape.startPoint.x = newStartX;\n shape.startPoint.y = newStartY;\n shape.endPoint.x = newEndX;\n shape.endPoint.y = newEndY;\n \n if (shape.shapeName === 'arrow' && shape.arrowCurved && typeof shape.initializeCurveControlPoints === 'function') {\n shape.initializeCurveControlPoints();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'text':\n case 'code':\n // Get text/code bounds for center calculation\n const textOrCodeEl = shape.group ? (shape.group.querySelector('text') || shape.group.querySelector('foreignObject')) : null;\n if (textOrCodeEl) {\n const bbox = textOrCodeEl.getBBox();\n const transform = shape.group.transform.baseVal.consolidate();\n const matrix = transform ? transform.matrix : { e: 0, f: 0 };\n\n const textCenterX = bbox.x + matrix.e + bbox.width / 2;\n const textCenterY = bbox.y + matrix.f + bbox.height / 2;\n\n // Calculate relative position\n const relativeTextX = textCenterX - rotationCenter.x;\n const relativeTextY = textCenterY - rotationCenter.y;\n\n // Apply rotation\n const newTextCenterX = rotationCenter.x + (relativeTextX * cosAngle - relativeTextY * sinAngle);\n const newTextCenterY = rotationCenter.y + (relativeTextX * sinAngle + relativeTextY * cosAngle);\n\n // Update position\n const newTransformX = newTextCenterX - bbox.width / 2;\n const newTransformY = newTextCenterY - bbox.height / 2;\n const newShapeRotation = (shape.rotation || 0) + angleDiff;\n\n const textCenterRelativeX = bbox.width / 2;\n const textCenterRelativeY = bbox.height / 2;\n\n shape.group.setAttribute('transform',\n `translate(${newTransformX}, ${newTransformY}) rotate(${newShapeRotation}, ${textCenterRelativeX}, ${textCenterRelativeY})`\n );\n\n shape.x = newTransformX;\n shape.y = newTransformY;\n shape.rotation = newShapeRotation;\n }\n break;\n \n case 'freehandStroke':\n if (shape.points && Array.isArray(shape.points)) {\n // Rotate each point in the stroke\n shape.points = shape.points.map(point => {\n if (!Array.isArray(point) || point.length < 2) return point;\n \n const relativePointX = point[0] - rotationCenter.x;\n const relativePointY = point[1] - rotationCenter.y;\n \n const newPointX = rotationCenter.x + (relativePointX * cosAngle - relativePointY * sinAngle);\n const newPointY = rotationCenter.y + (relativePointX * sinAngle + relativePointY * cosAngle);\n \n return [newPointX, newPointY, point[2] || 0.5];\n });\n \n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n }\n break;\n }\n \n // Update arrows attached to the contained shape\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n \n // Remove the flag after rotation\n delete shape.isBeingMovedByFrame;\n });\n \n // Update the frame's rotation\n this.rotation = newRotation;\n \n // Update arrows attached to this frame\n this.updateAttachedArrows();\n }\n\n handleResize(anchorIndex, currentPos, startPos, initialFrame) {\n const rawDx = currentPos.x - startPos.x;\n const rawDy = currentPos.y - startPos.y;\n\n // Rotate delta to local (unrotated) space when frame is rotated\n const rad = (this.rotation || 0) * Math.PI / 180;\n const cosR = Math.cos(rad);\n const sinR = Math.sin(rad);\n const dx = rawDx * cosR + rawDy * sinR;\n const dy = -rawDx * sinR + rawDy * cosR;\n\n // Store old frame for scale calculation\n const oldX = this.x, oldY = this.y, oldW = this.width, oldH = this.height;\n\n // Compute new dimensions using local-space deltas\n let newW, newH;\n // Fixed corner relative to initial frame origin: (fixRelX, fixRelY)\n let fixRelX, fixRelY;\n\n switch (anchorIndex) {\n case 0: // Top-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = initialFrame.width; fixRelY = initialFrame.height;\n break;\n case 1: // Top-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 2: // Top-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 3: // Right-middle\n newW = Math.max(10, initialFrame.width + dx);\n newH = initialFrame.height;\n fixRelX = 0; fixRelY = 0;\n break;\n case 4: // Bottom-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 5: // Bottom-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 6: // Bottom-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n case 7: // Left-middle\n newW = Math.max(10, initialFrame.width - dx);\n newH = initialFrame.height;\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n }\n\n // Compute new position using fixed-corner constraint\n if (this.rotation && this.rotation !== 0) {\n // Compute rotated world position of the fixed corner in the initial frame\n const iCX = initialFrame.x + initialFrame.width / 2;\n const iCY = initialFrame.y + initialFrame.height / 2;\n const odx = (initialFrame.x + fixRelX) - iCX;\n const ody = (initialFrame.y + fixRelY) - iCY;\n const fixedWorldX = iCX + odx * cosR - ody * sinR;\n const fixedWorldY = iCY + odx * sinR + ody * cosR;\n\n // Where the fixed corner sits in new rect (relative to new origin)\n const fixNewRelX = (fixRelX === 0) ? 0 : newW;\n const fixNewRelY = (fixRelY === 0) ? 0 : newH;\n\n // Solve for new origin\n const ncx = newW / 2;\n const ncy = newH / 2;\n const ndx = fixNewRelX - ncx;\n const ndy = fixNewRelY - ncy;\n const rotX = ncx + ndx * cosR - ndy * sinR;\n const rotY = ncy + ndx * sinR + ndy * cosR;\n\n this.x = fixedWorldX - rotX;\n this.y = fixedWorldY - rotY;\n } else {\n // No rotation - use simple axis-aligned position calculation\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + (initialFrame.width - newW); this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 1: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 2: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 3: break;\n case 4: break;\n case 5: break;\n case 6: this.x = initialFrame.x + (initialFrame.width - newW); break;\n case 7: this.x = initialFrame.x + (initialFrame.width - newW); break;\n }\n }\n\n this.width = newW;\n this.height = newH;\n\n // Scale contained shapes proportionally so nothing falls out\n if (oldW > 0 && oldH > 0) {\n const scaleX = this.width / oldW;\n const scaleY = this.height / oldH;\n\n if (Math.abs(scaleX - 1) > 0.001 || Math.abs(scaleY - 1) > 0.001) {\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n shape.isBeingMovedByFrame = true;\n\n switch (shape.shapeName) {\n case 'rectangle':\n case 'image':\n case 'icon':\n case 'code': {\n const relX = (shape.x - oldX) / oldW;\n const relY = (shape.y - oldY) / oldH;\n const relW = shape.width / oldW;\n const relH = shape.height / oldH;\n shape.x = this.x + relX * this.width;\n shape.y = this.y + relY * this.height;\n shape.width = relW * this.width;\n shape.height = relH * this.height;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'circle': {\n const relCX = (shape.x - oldX) / oldW;\n const relCY = (shape.y - oldY) / oldH;\n shape.x = this.x + relCX * this.width;\n shape.y = this.y + relCY * this.height;\n shape.rx = (shape.rx / oldW) * this.width;\n shape.ry = (shape.ry / oldH) * this.height;\n shape.width = shape.rx * 2;\n shape.height = shape.ry * 2;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'arrow':\n case 'line': {\n const relSX = (shape.startPoint.x - oldX) / oldW;\n const relSY = (shape.startPoint.y - oldY) / oldH;\n const relEX = (shape.endPoint.x - oldX) / oldW;\n const relEY = (shape.endPoint.y - oldY) / oldH;\n shape.startPoint.x = this.x + relSX * this.width;\n shape.startPoint.y = this.y + relSY * this.height;\n shape.endPoint.x = this.x + relEX * this.width;\n shape.endPoint.y = this.y + relEY * this.height;\n if (shape.controlPoint1) {\n const relC1X = (shape.controlPoint1.x - oldX) / oldW;\n const relC1Y = (shape.controlPoint1.y - oldY) / oldH;\n shape.controlPoint1.x = this.x + relC1X * this.width;\n shape.controlPoint1.y = this.y + relC1Y * this.height;\n }\n if (shape.controlPoint2) {\n const relC2X = (shape.controlPoint2.x - oldX) / oldW;\n const relC2Y = (shape.controlPoint2.y - oldY) / oldH;\n shape.controlPoint2.x = this.x + relC2X * this.width;\n shape.controlPoint2.y = this.y + relC2Y * this.height;\n }\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'text': {\n const tx = shape.x || 0;\n const ty = shape.y || 0;\n const relTX = (tx - oldX) / oldW;\n const relTY = (ty - oldY) / oldH;\n shape.x = this.x + relTX * this.width;\n shape.y = this.y + relTY * this.height;\n break;\n }\n case 'freehandStroke': {\n // Pie sectors are editable closed freehand polygons.\n // Scale their source points with the frame so their\n // geometry stays attached instead of being clipped\n // at its previous canvas coordinates.\n if (Array.isArray(shape.points)) {\n shape.points = shape.points.map(point => {\n if (!Array.isArray(point) || point.length < 2) return point;\n const relPX = (point[0] - oldX) / oldW;\n const relPY = (point[1] - oldY) / oldH;\n return [\n this.x + relPX * this.width,\n this.y + relPY * this.height,\n point[2] || 0.5\n ];\n });\n shape._moveOffsetX = 0;\n shape._moveOffsetY = 0;\n if (typeof shape.draw === 'function') shape.draw();\n }\n break;\n }\n }\n\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n delete shape.isBeingMovedByFrame;\n });\n }\n }\n\n // Update contained shapes visibility\n this.updateContainedShapes();\n }\n \n temporarilyRemoveFromFrame(shape) {\n if (shape && shape.parentFrame === this) {\n // Move shape back to main SVG temporarily (without removing from containedShapes array)\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n shape.isDraggedOutTemporarily = true;\n }\n}\n\n// Add a method to restore clipping for a shape after drag\nrestoreToFrame(shape) {\n if (shape && shape.parentFrame === this && shape.isDraggedOutTemporarily) {\n // Move shape back to clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === svg) {\n svg.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n\n contains(viewBoxX, viewBoxY) {\n // Simple point-in-rectangle test (without rotation for now)\n return viewBoxX >= this.x && viewBoxX <= this.x + this.width &&\n viewBoxY >= this.y && viewBoxY <= this.y + this.height;\n }\n\n // Arrow attachment support (similar to other shapes)\n getAttachmentPoint(point, tolerance = 20) {\n const rect = {\n left: this.x,\n right: this.x + this.width,\n top: this.y,\n bottom: this.y + this.height\n };\n\n const distances = {\n top: Math.abs(point.y - rect.top),\n bottom: Math.abs(point.y - rect.bottom),\n left: Math.abs(point.x - rect.left),\n right: Math.abs(point.x - rect.right)\n };\n\n let closestSide = null;\n let minDistance = tolerance;\n\n for (let side in distances) {\n if (distances[side] < minDistance &&\n ((side === 'top' || side === 'bottom') && point.x >= rect.left && point.x <= rect.right) ||\n ((side === 'left' || side === 'right') && point.y >= rect.top && point.y <= rect.bottom)) {\n minDistance = distances[side];\n closestSide = side;\n }\n }\n\n if (closestSide) {\n let attachPoint;\n const offset = { x: 0, y: 0 };\n\n switch (closestSide) {\n case 'top':\n attachPoint = { x: point.x, y: rect.top };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'bottom':\n attachPoint = { x: point.x, y: rect.bottom };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'left':\n attachPoint = { x: rect.left, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n case 'right':\n attachPoint = { x: rect.right, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n }\n\n return { point: attachPoint, side: closestSide, offset, shape: this };\n }\n\n return null;\n }\n\n updateStyle(newOptions) {\n Object.keys(newOptions).forEach(key => newOptions[key] === undefined && delete newOptions[key]);\n this.options = { ...this.options, ...newOptions };\n this.draw();\n }\n\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n /**\n * Set a background image for this frame from a URL.\n * The image will fit/cover the frame dimensions.\n * @param {string} url - Image URL\n * @param {string} fit - 'cover' (default) | 'contain' | 'fill'\n */\n setImageFromURL(url, fit = 'cover') {\n if (!url) {\n // Remove existing frame image\n if (this._frameImage && this._frameImage.parentNode) {\n this._frameImage.parentNode.removeChild(this._frameImage);\n this._frameImage = null;\n }\n this._frameImageURL = null;\n return;\n }\n\n this._frameImageURL = url;\n this._frameImageFit = fit;\n\n if (!this._frameImage) {\n this._frameImage = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n this._frameImage.setAttribute('pointer-events', 'none');\n }\n // Always update preserveAspectRatio when fit changes\n this._frameImage.setAttribute('preserveAspectRatio',\n fit === 'cover' ? 'xMidYMid slice' :\n fit === 'contain' ? 'xMidYMid meet' :\n fit === 'center' ? 'xMidYMid meet' : 'none'\n );\n\n this._frameImage.setAttribute('href', url);\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n // Insert image right after the frame rect (below contained shapes)\n if (this._frameImage.parentNode === this.group) {\n this.group.removeChild(this._frameImage);\n }\n if (this.element && this.element.nextSibling) {\n this.group.insertBefore(this._frameImage, this.element.nextSibling);\n } else {\n this.group.appendChild(this._frameImage);\n }\n }\n\n /**\n * Update frame image position/size (called during move/resize)\n */\n _updateFrameImage() {\n if (!this._frameImage) return;\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this._frameImage.removeAttribute('transform');\n }\n }\n}\n\nexport { Frame };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -431,7 +431,7 @@ function useSketchEngine(svgRef, ready = true) {
431
431
  setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
432
432
  getState: () => useSketchStore_default.getState()
433
433
  };
434
- const { SketchEngine } = await import("./SketchEngine-P3XNZA56.js");
434
+ const { SketchEngine } = await import("./SketchEngine-UYMJJEVW.js");
435
435
  if (cancelled) return;
436
436
  const engine = new SketchEngine(svgRef.current);
437
437
  await engine.init();
@@ -4741,7 +4741,7 @@ var _saveScene = null;
4741
4741
  var _loadScene = null;
4742
4742
  async function ensureSceneSerializer() {
4743
4743
  if (_saveScene && _loadScene) return;
4744
- const m = await import("./SceneSerializer-34VQFJN7.js");
4744
+ const m = await import("./SceneSerializer-7UACFCRF.js");
4745
4745
  _saveScene = m.saveScene;
4746
4746
  _loadScene = m.loadScene;
4747
4747
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elixpo/lixsketch",
3
- "version": "5.5.14",
3
+ "version": "5.5.15",
4
4
  "description": "Open-source SVG whiteboard engine + React canvas component with hand-drawn aesthetics — the core of LixSketch",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -1211,6 +1211,28 @@ startLabelEdit(labelElement) {
1211
1211
  shape.y = this.y + relTY * this.height;
1212
1212
  break;
1213
1213
  }
1214
+ case 'freehandStroke': {
1215
+ // Pie sectors are editable closed freehand polygons.
1216
+ // Scale their source points with the frame so their
1217
+ // geometry stays attached instead of being clipped
1218
+ // at its previous canvas coordinates.
1219
+ if (Array.isArray(shape.points)) {
1220
+ shape.points = shape.points.map(point => {
1221
+ if (!Array.isArray(point) || point.length < 2) return point;
1222
+ const relPX = (point[0] - oldX) / oldW;
1223
+ const relPY = (point[1] - oldY) / oldH;
1224
+ return [
1225
+ this.x + relPX * this.width,
1226
+ this.y + relPY * this.height,
1227
+ point[2] || 0.5
1228
+ ];
1229
+ });
1230
+ shape._moveOffsetX = 0;
1231
+ shape._moveOffsetY = 0;
1232
+ if (typeof shape.draw === 'function') shape.draw();
1233
+ }
1234
+ break;
1235
+ }
1214
1236
  }
1215
1237
 
1216
1238
  if (typeof shape.updateAttachedArrows === 'function') {