@elixpo/lixsketch 5.5.8 → 5.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/react/{CopyPaste-4CKJRHJ3.js → CopyPaste-SA72NDFN.js} +2 -2
  2. package/dist/react/{EventDispatcher-FP2RHJGG.js → EventDispatcher-BZQRHROG.js} +7 -7
  3. package/dist/react/{SceneSerializer-4U4B24JM.js → SceneSerializer-ZPHV6IUP.js} +2 -2
  4. package/dist/react/{SketchEngine-WYUPJWK4.js → SketchEngine-BCRJ62CV.js} +11 -7
  5. package/dist/react/SketchEngine-BCRJ62CV.js.map +7 -0
  6. package/dist/react/TextShape-U6ZZKB35.js +8 -0
  7. package/dist/react/{chunk-QXFBG7OM.js → chunk-42O6W7DF.js} +18 -1
  8. package/dist/react/chunk-42O6W7DF.js.map +7 -0
  9. package/dist/react/{chunk-TUMWA4YF.js → chunk-5QIT2WBE.js} +21 -113
  10. package/dist/react/chunk-5QIT2WBE.js.map +7 -0
  11. package/dist/react/index.js +3 -3
  12. package/dist/react/index.js.map +1 -1
  13. package/dist/react/{textTool-QVKV45VD.js → textTool-HY5NMM7H.js} +2 -2
  14. package/package.json +1 -1
  15. package/src/SketchEngine.js +11 -7
  16. package/src/react/components/sidebars/TextSidebar.jsx +1 -1
  17. package/src/shapes/TextShape.js +19 -0
  18. package/src/tools/textTool.js +25 -155
  19. package/dist/react/SketchEngine-WYUPJWK4.js.map +0 -7
  20. package/dist/react/TextShape-54ZJ66E3.js +0 -8
  21. package/dist/react/chunk-QXFBG7OM.js.map +0 -7
  22. package/dist/react/chunk-TUMWA4YF.js.map +0 -7
  23. /package/dist/react/{CopyPaste-4CKJRHJ3.js.map → CopyPaste-SA72NDFN.js.map} +0 -0
  24. /package/dist/react/{EventDispatcher-FP2RHJGG.js.map → EventDispatcher-BZQRHROG.js.map} +0 -0
  25. /package/dist/react/{SceneSerializer-4U4B24JM.js.map → SceneSerializer-ZPHV6IUP.js.map} +0 -0
  26. /package/dist/react/{TextShape-54ZJ66E3.js.map → TextShape-U6ZZKB35.js.map} +0 -0
  27. /package/dist/react/{textTool-QVKV45VD.js.map → textTool-HY5NMM7H.js.map} +0 -0
@@ -36,7 +36,7 @@ import {
36
36
  } from "./chunk-L5OARZJ7.js";
37
37
  import {
38
38
  TextShape
39
- } from "./chunk-QXFBG7OM.js";
39
+ } from "./chunk-42O6W7DF.js";
40
40
 
41
41
  // src/core/CopyPaste.js
42
42
  var clipboard = null;
@@ -566,4 +566,4 @@ export {
566
566
  initCopyPaste,
567
567
  pasteClipboard
568
568
  };
569
- //# sourceMappingURL=CopyPaste-4CKJRHJ3.js.map
569
+ //# sourceMappingURL=CopyPaste-SA72NDFN.js.map
@@ -1,15 +1,10 @@
1
1
  "use client";
2
- import {
3
- handleMouseDown as handleMouseDown3,
4
- handleMouseMove as handleMouseMove3,
5
- handleMouseUp as handleMouseUp3
6
- } from "./chunk-6SFNWGGZ.js";
7
2
  import {
8
3
  enterEditMode,
9
4
  handleTextMouseDown,
10
5
  handleTextMouseMove,
11
6
  handleTextMouseUp
12
- } from "./chunk-TUMWA4YF.js";
7
+ } from "./chunk-5QIT2WBE.js";
13
8
  import {
14
9
  handleCodeMouseDown,
15
10
  handleCodeMouseMove,
@@ -53,6 +48,11 @@ import {
53
48
  handleMouseMove as handleMouseMove2,
54
49
  handleMouseUp as handleMouseUp2
55
50
  } from "./chunk-I6HCCIXB.js";
51
+ import {
52
+ handleMouseDown as handleMouseDown3,
53
+ handleMouseMove as handleMouseMove3,
54
+ handleMouseUp as handleMouseUp3
55
+ } from "./chunk-6SFNWGGZ.js";
56
56
  import "./chunk-DNAG7ML6.js";
57
57
  import {
58
58
  handleMouseDown,
@@ -460,4 +460,4 @@ export {
460
460
  handleMainMouseUp,
461
461
  initEventDispatcher
462
462
  };
463
- //# sourceMappingURL=EventDispatcher-FP2RHJGG.js.map
463
+ //# sourceMappingURL=EventDispatcher-BZQRHROG.js.map
@@ -30,7 +30,7 @@ import "./chunk-BZE4CEBG.js";
30
30
  import "./chunk-L5OARZJ7.js";
31
31
  import {
32
32
  TextShape
33
- } from "./chunk-QXFBG7OM.js";
33
+ } from "./chunk-42O6W7DF.js";
34
34
 
35
35
  // src/core/SceneSerializer.js
36
36
  var FORMAT_VERSION = 1;
@@ -736,4 +736,4 @@ export {
736
736
  uploadScene,
737
737
  validateScene
738
738
  };
739
- //# sourceMappingURL=SceneSerializer-4U4B24JM.js.map
739
+ //# sourceMappingURL=SceneSerializer-ZPHV6IUP.js.map
@@ -41,6 +41,7 @@ var SketchEngine = class {
41
41
  _initGlobals() {
42
42
  window.svg = this.svg;
43
43
  window.freehandCanvas = this.svg;
44
+ window.__sketchInteractionReady = false;
44
45
  window.rough = rough;
45
46
  window.roughCanvas = rough.svg(this.svg);
46
47
  window.roughGenerator = window.roughCanvas.generator;
@@ -164,7 +165,7 @@ var SketchEngine = class {
164
165
  import("./Circle-KPG7TKIX.js"),
165
166
  import("./Arrow-BJDAXPMH.js"),
166
167
  import("./Line-2KOQEEGA.js"),
167
- import("./TextShape-54ZJ66E3.js"),
168
+ import("./TextShape-U6ZZKB35.js"),
168
169
  import("./CodeShape-K4DIZAIV.js"),
169
170
  import("./ImageShape-CHHGBXUQ.js"),
170
171
  import("./IconShape-KMIA6T2H.js"),
@@ -193,8 +194,6 @@ var SketchEngine = class {
193
194
  Frame,
194
195
  FreehandStroke
195
196
  };
196
- const sceneSerializer = await import("./SceneSerializer-4U4B24JM.js");
197
- if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
198
197
  const [
199
198
  rectangleTool,
200
199
  circleTool,
@@ -211,7 +210,7 @@ var SketchEngine = class {
211
210
  import("./circleTool-NUATSEI2.js"),
212
211
  import("./arrowTool-CWEMIRXK.js"),
213
212
  import("./lineTool-WNI5EMZ5.js"),
214
- import("./textTool-QVKV45VD.js"),
213
+ import("./textTool-HY5NMM7H.js"),
215
214
  import("./codeTool-MHCB2FNB.js"),
216
215
  import("./imageTool-D5R4XGEU.js"),
217
216
  import("./iconTool-GPZ7O7NH.js"),
@@ -240,11 +239,11 @@ var SketchEngine = class {
240
239
  resizeShapes,
241
240
  resizeCode
242
241
  ] = await Promise.all([
243
- import("./EventDispatcher-FP2RHJGG.js"),
242
+ import("./EventDispatcher-BZQRHROG.js"),
244
243
  import("./UndoRedo-M2JZUBKN.js"),
245
244
  import("./Selection-VVUHY5YJ.js"),
246
245
  import("./ZoomPan-NYPDJBD5.js"),
247
- import("./CopyPaste-4CKJRHJ3.js"),
246
+ import("./CopyPaste-SA72NDFN.js"),
248
247
  import("./EraserTrail-PA6IQLQN.js"),
249
248
  import("./ResizeShapes-LKEQTITP.js"),
250
249
  import("./ResizeCode-WAMDTKSW.js")
@@ -262,6 +261,9 @@ var SketchEngine = class {
262
261
  if (eventDispatcher.initEventDispatcher) {
263
262
  eventDispatcher.initEventDispatcher(this.svg);
264
263
  }
264
+ window.__sketchInteractionReady = true;
265
+ const sceneSerializer = await import("./SceneSerializer-ZPHV6IUP.js");
266
+ if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
265
267
  await Promise.all([
266
268
  import("./eraserTool-2GS2LQCS.js"),
267
269
  import("./laserTool-XVMV63AV.js")
@@ -400,6 +402,8 @@ var SketchEngine = class {
400
402
  window.shapes = [];
401
403
  window.currentShape = null;
402
404
  window.lastMousePos = null;
405
+ window.__sketchInteractionReady = false;
406
+ delete window.__sceneSerializer;
403
407
  this._modules = {};
404
408
  this._initialized = false;
405
409
  console.log("[SketchEngine] Cleaned up");
@@ -410,4 +414,4 @@ export {
410
414
  SketchEngine,
411
415
  SketchEngine_default as default
412
416
  };
413
- //# sourceMappingURL=SketchEngine-WYUPJWK4.js.map
417
+ //# sourceMappingURL=SketchEngine-BCRJ62CV.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/SketchEngine.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n/**\n * SketchEngine - Main engine entry point\n *\n * Initializes the SVG canvas, sets up global state (including RoughJS from npm),\n * then dynamically imports all tool and shape modules.\n *\n * IMPORTANT: All globals must be set BEFORE importing modules, because many\n * modules run code at the top level (e.g. `const rc = rough.svg(svg)`) that\n * depends on these globals existing.\n */\n\nimport rough from 'roughjs';\n\nclass SketchEngine {\n constructor(svgElement, options = {}) {\n if (!svgElement || svgElement.tagName !== 'svg') {\n throw new Error('SketchEngine requires an SVG element');\n }\n\n this.svg = svgElement;\n // Prevent default touch scrolling/gestures on the canvas to allow for custom pointer events\n this.svg.style.touchAction = 'none';\n\n this.options = {\n initialZoom: 1,\n minZoom: 0.4,\n maxZoom: 30,\n ...options\n };\n\n // Event callback for framework consumers (React, Vue, vanilla, VS Code, etc.)\n this.onEvent = options.onEvent || (() => {});\n\n // Public API surfaces (populated after init)\n this.scene = null;\n this.shapes = null;\n\n this._modules = {};\n this._initialized = false;\n }\n\n /**\n * Emit an event to the consumer callback.\n * @param {string} type - Event type (e.g. 'sidebar:select', 'zoom:change')\n * @param {*} data - Event payload\n */\n emit(type, data) {\n try { this.onEvent(type, data); } catch (e) { console.warn('[SketchEngine] onEvent error:', e); }\n }\n\n /**\n * Set up all the global variables that the tool/shape modules depend on.\n * Must be called BEFORE any module imports.\n */\n _initGlobals() {\n // Core SVG reference\n window.svg = this.svg;\n window.freehandCanvas = this.svg;\n window.__sketchInteractionReady = false;\n\n // RoughJS from npm\n window.rough = rough;\n window.roughCanvas = rough.svg(this.svg);\n window.roughGenerator = window.roughCanvas.generator;\n\n // Shape storage\n window.shapes = window.shapes || [];\n window.currentShape = window.currentShape || null;\n window.lastMousePos = window.lastMousePos || null;\n\n // Zoom state\n window.currentZoom = this.options.initialZoom;\n window.minScale = this.options.minZoom;\n window.maxScale = this.options.maxZoom;\n window.minZoom = this.options.minZoom;\n window.maxZoom = this.options.maxZoom;\n\n // ViewBox state\n window.currentViewBox = window.currentViewBox || {\n x: 0, y: 0,\n width: window.innerWidth,\n height: window.innerHeight\n };\n\n // Tool activation flags\n window.isPaintToolActive = false;\n window.isTextToolActive = false;\n window.isCircleToolActive = false;\n window.isSquareToolActive = false;\n window.isLaserToolActive = false;\n window.isEraserToolActive = false;\n window.isImageToolActive = false;\n window.isArrowToolActive = false;\n window.isLineToolActive = false;\n window.isSelectionToolActive = true;\n window.isPanningToolActive = false;\n window.isFrameToolActive = false;\n window.isIconToolActive = false;\n window.isCodeToolActive = false;\n window.isTextInCodeMode = false;\n\n // Pan state\n window.isPanning = false;\n window.panStart = null;\n window.startCanvasX = 0;\n window.startCanvasY = 0;\n\n // Transform state\n window.currentMatrix = new DOMMatrix();\n window.currentTranslation = { x: 0, y: 0 };\n\n // Action type constants\n window.ACTION_CREATE = 'create';\n window.ACTION_DELETE = 'delete';\n window.ACTION_MODIFY = 'modify';\n window.ACTION_PASTE = 'paste';\n\n // History stacks\n window.historyStack = window.historyStack || [];\n window.redoStack = window.redoStack || [];\n\n // Sidebar element stubs \u2014 React sidebars handle UI, but legacy code\n // queries these at top level. Provide dummy elements so it doesn't crash.\n const dummyEl = document.createElement('div');\n dummyEl.classList.add('hidden');\n window.paintBrushSideBar = document.getElementById('paintBrushToolBar') || dummyEl;\n window.lineSideBar = document.getElementById('lineSideBar') || dummyEl;\n window.squareSideBar = document.getElementById('squareSideBar') || dummyEl;\n window.circleSideBar = document.getElementById('circleSideBar') || dummyEl;\n window.arrowSideBar = document.getElementById('arrowSideBar') || dummyEl;\n window.textSideBar = document.getElementById('textToolBar') || dummyEl;\n window.frameSideBar = document.getElementById('frameSideBar') || dummyEl;\n\n // Zoom control element refs\n window.zoomInBtn = document.getElementById('zoomIn') || dummyEl;\n window.zoomOutBtn = document.getElementById('zoomOut') || dummyEl;\n window.zoomPercentSpan = document.getElementById('zoomPercent') || dummyEl;\n\n // Container\n window.container = document.querySelector('.container') || document.body;\n\n // Sidebar control \u2014 bridge legacy code to consumer UI\n const engine = this;\n window.disableAllSideBars = function() {\n // Hide all legacy sidebar elements\n [window.paintBrushSideBar, window.lineSideBar, window.squareSideBar,\n window.circleSideBar, window.arrowSideBar, window.textSideBar, window.frameSideBar\n ].forEach(el => { if (el) el.classList.add('hidden'); });\n // Notify consumer via onEvent + legacy bridge\n engine.emit('sidebar:clear');\n if (window.__sketchStoreApi) {\n window.__sketchStoreApi.clearSelectedShapeSidebar();\n }\n };\n\n // toolExtraPopup \u2014 legacy UI function, no-op in React\n window.toolExtraPopup = window.toolExtraPopup || function() {};\n\n // updateUndoRedoButtons \u2014 legacy UI function, no-op in React\n window.updateUndoRedoButtons = window.updateUndoRedoButtons || function() {};\n\n // Bridge for shape selection -> consumer UI\n // Maps shape.shapeName to the sidebar key\n window.__showSidebarForShape = function(shapeName) {\n const sidebarMap = {\n 'rectangle': 'rectangle',\n 'circle': 'circle',\n 'arrow': 'arrow',\n 'line': 'line',\n 'freehandStroke': 'paintbrush',\n 'text': 'text',\n 'code': 'text',\n 'frame': 'frame',\n 'image': 'image',\n };\n const sidebar = sidebarMap[shapeName];\n // Emit to consumer callback\n engine.emit('sidebar:select', { sidebar, shapeName });\n // Legacy bridge for React\n if (sidebar && window.__sketchStoreApi) {\n window.__sketchStoreApi.setSelectedShapeSidebar(sidebar);\n }\n window.__selectedShapeIsCode = (shapeName === 'code');\n if (window.__onCodeModeChanged) window.__onCodeModeChanged(shapeName === 'code');\n };\n }\n\n /**\n * Initialize engine: set globals first, then import modules.\n */\n async init() {\n if (this._initialized) return;\n\n // CRITICAL: Set up ALL globals BEFORE importing modules\n this._initGlobals();\n\n try {\n // Import shape classes first\n const [\n { Rectangle },\n { Circle },\n { Arrow },\n { Line },\n { TextShape },\n { CodeShape },\n { ImageShape },\n { IconShape },\n { Frame },\n { FreehandStroke }\n ] = await Promise.all([\n import('./shapes/Rectangle.js'),\n import('./shapes/Circle.js'),\n import('./shapes/Arrow.js'),\n import('./shapes/Line.js'),\n import('./shapes/TextShape.js'),\n import('./shapes/CodeShape.js'),\n import('./shapes/ImageShape.js'),\n import('./shapes/IconShape.js'),\n import('./shapes/Frame.js'),\n import('./shapes/FreehandStroke.js')\n ]);\n\n // Expose shape classes globally\n window.Rectangle = Rectangle;\n window.Circle = Circle;\n window.Arrow = Arrow;\n window.Line = Line;\n window.TextShape = TextShape;\n window.CodeShape = CodeShape;\n window.ImageShape = ImageShape;\n window.IconShape = IconShape;\n window.Frame = Frame;\n window.FreehandStroke = FreehandStroke;\n\n this._modules.shapes = {\n Rectangle, Circle, Arrow, Line,\n TextShape, CodeShape, ImageShape, IconShape,\n Frame, FreehandStroke\n };\n\n // Import tool handlers (they run top-level code that reads globals)\n const [\n rectangleTool, circleTool, arrowTool, lineTool,\n textTool, codeTool, imageTool, iconTool,\n frameTool, freehandTool\n ] = await Promise.all([\n import('./tools/rectangleTool.js'),\n import('./tools/circleTool.js'),\n import('./tools/arrowTool.js'),\n import('./tools/lineTool.js'),\n import('./tools/textTool.js'),\n import('./tools/codeTool.js'),\n import('./tools/imageTool.js'),\n import('./tools/iconTool.js'),\n import('./tools/frameTool.js'),\n import('./tools/freehandTool.js')\n ]);\n\n this._modules.tools = {\n rectangleTool, circleTool, arrowTool, lineTool,\n textTool, codeTool, imageTool, iconTool,\n frameTool, freehandTool\n };\n\n // Import core modules (EventDispatcher attaches SVG listeners at top level)\n const [\n eventDispatcher, undoRedo, selection,\n zoomPan, copyPaste, eraserTrail,\n resizeShapes, resizeCode\n ] = await Promise.all([\n import('./core/EventDispatcher.js'),\n import('./core/UndoRedo.js'),\n import('./core/Selection.js'),\n import('./core/ZoomPan.js'),\n import('./core/CopyPaste.js'),\n import('./core/EraserTrail.js'),\n import('./core/ResizeShapes.js'),\n import('./core/ResizeCode.js')\n ]);\n\n this._modules.core = {\n eventDispatcher, undoRedo, selection,\n zoomPan, copyPaste, eraserTrail,\n resizeShapes, resizeCode\n };\n\n // Re-bind event listeners to the current SVG element\n if (eventDispatcher.initEventDispatcher) {\n eventDispatcher.initEventDispatcher(this.svg);\n }\n window.__sketchInteractionReady = true;\n\n // Restore only after pointer handlers are bound. This still keeps\n // first canvas paint ahead of optional AI/graph/LixScript chunks,\n // while guaranteeing every visible restored shape is immediately\n // selectable and draggable.\n const sceneSerializer = await import('./core/SceneSerializer.js');\n if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();\n\n // Import standalone tools\n await Promise.all([\n import('./tools/eraserTool.js'),\n import('./tools/laserTool.js')\n ]);\n\n // Expose key functions globally\n if (undoRedo.undo) window.undo = undoRedo.undo;\n if (undoRedo.redo) window.redo = undoRedo.redo;\n if (undoRedo.pushCreateAction) window.pushCreateAction = undoRedo.pushCreateAction;\n if (undoRedo.pushDeleteAction) window.pushDeleteAction = undoRedo.pushDeleteAction;\n if (selection.multiSelection) window.multiSelection = selection.multiSelection;\n if (selection.clearAllSelections) window.clearAllSelections = selection.clearAllSelections;\n\n // Initialize centralized copy/paste system\n if (copyPaste.initCopyPaste) copyPaste.initCopyPaste();\n\n // Initialize AI renderer bridge\n const aiRenderer = await import('./core/AIRenderer.js');\n if (aiRenderer.initAIRenderer) aiRenderer.initAIRenderer();\n\n // Initialize graph engine bridge\n const graphEngine = await import('./core/GraphEngine.js');\n if (graphEngine.initGraphEngine) graphEngine.initGraphEngine();\n\n // Initialize layer ordering\n const layerOrder = await import('./core/LayerOrder.js');\n if (layerOrder.initLayerOrder) layerOrder.initLayerOrder();\n\n // Initialize LixScript programmatic diagram engine\n const lixScript = await import('./core/LixScriptParser.js');\n if (lixScript.initLixScriptBridge) lixScript.initLixScriptBridge();\n\n // \u2500\u2500 Public API surfaces \u2500\u2500\n\n // Scene operations (save, load, export, etc.)\n this.scene = window.__sceneSerializer || {\n save: sceneSerializer.saveScene,\n load: sceneSerializer.loadScene,\n download: sceneSerializer.downloadScene,\n upload: sceneSerializer.uploadScene,\n exportPNG: sceneSerializer.exportAsPNG,\n exportPDF: sceneSerializer.exportAsPDF,\n copyAsPNG: sceneSerializer.copyAsPNG,\n copyAsSVG: sceneSerializer.copyAsSVG,\n reset: sceneSerializer.resetCanvas,\n findText: sceneSerializer.findTextOnCanvas,\n };\n\n // Shape array reference\n this.shapes = window.shapes;\n\n // Undo/redo\n this.undo = undoRedo.undo || (() => {});\n this.redo = undoRedo.redo || (() => {});\n\n // LixScript execution\n this.lixscript = {\n parse: lixScript.parseLixScript || (() => null),\n execute: lixScript.executeLixScript || (lixScript.parseLixScript ? (code) => {\n const parsed = lixScript.parseLixScript(code);\n if (parsed && lixScript.resolveShapeRefs) lixScript.resolveShapeRefs(parsed);\n return parsed;\n } : (() => null)),\n };\n\n // Store module refs for advanced consumers\n this._modules.sceneSerializer = sceneSerializer;\n this._modules.lixScript = lixScript;\n\n this._initialized = true;\n console.log('[SketchEngine] Initialized successfully');\n } catch (err) {\n console.error('[SketchEngine] Initialization failed:', err);\n throw err;\n }\n }\n\n /**\n * Sync tool flags from Zustand activeTool value.\n */\n setActiveTool(toolName) {\n // Deselect current shape when switching tools\n if (window.currentShape && typeof window.currentShape.removeSelection === 'function') {\n window.currentShape.removeSelection();\n window.currentShape = null;\n }\n if (typeof window.clearAllSelections === 'function') {\n window.clearAllSelections();\n }\n if (typeof window.disableAllSideBars === 'function') {\n window.disableAllSideBars();\n }\n\n // Force cleanup eraser trail when switching tools\n if (typeof window.forceCleanupEraserTrail === 'function') {\n window.forceCleanupEraserTrail();\n }\n // Clean up any lingering icon miniature/drag state\n if (typeof window.__cleanupIconTool === 'function') {\n window.__cleanupIconTool();\n }\n\n window.isPaintToolActive = false;\n window.isSquareToolActive = false;\n window.isCircleToolActive = false;\n window.isArrowToolActive = false;\n window.isTextToolActive = false;\n window.isLaserToolActive = false;\n window.isLineToolActive = false;\n window.isEraserToolActive = false;\n window.isSelectionToolActive = false;\n window.isImageToolActive = false;\n window.isPanningToolActive = false;\n window.isFrameToolActive = false;\n window.isIconToolActive = false;\n window.isCodeToolActive = false;\n\n const flagMap = {\n select: 'isSelectionToolActive',\n pan: 'isPanningToolActive',\n rectangle: 'isSquareToolActive',\n circle: 'isCircleToolActive',\n line: 'isLineToolActive',\n arrow: 'isArrowToolActive',\n freehand: 'isPaintToolActive',\n text: 'isTextToolActive',\n code: 'isCodeToolActive',\n eraser: 'isEraserToolActive',\n laser: 'isLaserToolActive',\n image: 'isImageToolActive',\n frame: 'isFrameToolActive',\n icon: 'isIconToolActive',\n };\n\n const flag = flagMap[toolName];\n if (flag) window[flag] = true;\n\n if (toolName === 'text' && window.isTextInCodeMode) {\n window.isCodeToolActive = true;\n }\n\n // Show image source picker when image tool is activated\n if (toolName === 'image' && window.__showImageSourcePicker) {\n window.__showImageSourcePicker();\n }\n\n // Set appropriate cursor for the active tool\n const cursorMap = {\n select: 'default',\n pan: 'grab',\n rectangle: 'crosshair',\n circle: 'crosshair',\n line: 'crosshair',\n arrow: 'crosshair',\n freehand: 'crosshair',\n text: 'crosshair',\n code: 'crosshair',\n eraser: 'crosshair',\n laser: 'crosshair',\n image: 'crosshair',\n frame: 'crosshair',\n icon: 'crosshair',\n };\n if (this.svg) {\n this.svg.style.cursor = cursorMap[toolName] || 'default';\n }\n }\n\n cleanup() {\n // Remove event listeners from the SVG element\n if (this._modules.core?.eventDispatcher?.cleanupEventDispatcher) {\n this._modules.core.eventDispatcher.cleanupEventDispatcher();\n }\n window.shapes = [];\n window.currentShape = null;\n window.lastMousePos = null;\n window.__sketchInteractionReady = false;\n delete window.__sceneSerializer;\n this._modules = {};\n this._initialized = false;\n console.log('[SketchEngine] Cleaned up');\n }\n}\n\nexport { SketchEngine };\nexport default SketchEngine;\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import {
3
+ TextShape
4
+ } from "./chunk-42O6W7DF.js";
5
+ export {
6
+ TextShape
7
+ };
8
+ //# sourceMappingURL=TextShape-U6ZZKB35.js.map
@@ -27,9 +27,26 @@ function deselectElement() {
27
27
  function selectElement(el) {
28
28
  selectedElement = el;
29
29
  }
30
+ function removeLegacySoftWrap(groupElement) {
31
+ const textElement = groupElement.querySelector("text");
32
+ if (!textElement || !textElement.hasAttribute("data-wrap-width")) return;
33
+ const source = textElement.getAttribute("data-wrap-source");
34
+ if (source === null) return;
35
+ while (textElement.firstChild) textElement.removeChild(textElement.firstChild);
36
+ const x = textElement.getAttribute("x") || 0;
37
+ source.split("\n").forEach((line, index) => {
38
+ const tspan = textElement.ownerDocument.createElementNS("http://www.w3.org/2000/svg", "tspan");
39
+ tspan.setAttribute("x", x);
40
+ tspan.setAttribute("dy", index === 0 ? "0" : "1.2em");
41
+ tspan.textContent = line || " ";
42
+ textElement.appendChild(tspan);
43
+ });
44
+ textElement.removeAttribute("data-wrap-width");
45
+ }
30
46
  var TextShape = class {
31
47
  constructor(groupElement) {
32
48
  this.group = groupElement;
49
+ removeLegacySoftWrap(groupElement);
33
50
  this.shapeName = "text";
34
51
  this.shapeID = groupElement.getAttribute("id") || `text-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 1e4)}`;
35
52
  this.parentFrame = null;
@@ -188,4 +205,4 @@ var TextShape = class {
188
205
  export {
189
206
  TextShape
190
207
  };
191
- //# sourceMappingURL=chunk-QXFBG7OM.js.map
208
+ //# sourceMappingURL=chunk-42O6W7DF.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shapes/TextShape.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// TextShape class - extracted from writeText.js\n// Depends on globals: svg, shapes, currentShape\n\nfunction extractRotationFromTransform(el) {\n const t = el.getAttribute(\"transform\") || \"\";\n const m = t.match(/rotate\\(([^,)]+)/);\n return m ? parseFloat(m[1]) : 0;\n}\nfunction updateAttachedArrows(wrapper) {\n if (!wrapper || typeof shapes === \"undefined\") return;\n shapes.forEach(s => {\n if (s && s.shapeName === \"arrow\" && typeof s.updateAttachments === \"function\") {\n if ((s.attachedToStart && s.attachedToStart.shape === wrapper) ||\n (s.attachedToEnd && s.attachedToEnd.shape === wrapper)) {\n s.updateAttachments();\n }\n }\n });\n}\nlet isDragging = false;\nlet hoveredFrameText = null;\nlet selectedElement = null;\nfunction updateSelectionFeedback() {}\nfunction deselectElement() { selectedElement = null; }\nfunction selectElement(el) { selectedElement = el; }\n\nfunction removeLegacySoftWrap(groupElement) {\n const textElement = groupElement.querySelector('text');\n if (!textElement || !textElement.hasAttribute('data-wrap-width')) return;\n const source = textElement.getAttribute('data-wrap-source');\n if (source === null) return;\n\n while (textElement.firstChild) textElement.removeChild(textElement.firstChild);\n const x = textElement.getAttribute('x') || 0;\n source.split('\\n').forEach((line, index) => {\n const tspan = textElement.ownerDocument.createElementNS('http://www.w3.org/2000/svg', 'tspan');\n tspan.setAttribute('x', x);\n tspan.setAttribute('dy', index === 0 ? '0' : '1.2em');\n tspan.textContent = line || ' ';\n textElement.appendChild(tspan);\n });\n textElement.removeAttribute('data-wrap-width');\n}\n\nclass TextShape {\n constructor(groupElement) {\n this.group = groupElement;\n removeLegacySoftWrap(groupElement);\n this.shapeName = 'text';\n this.shapeID = groupElement.getAttribute('id') || `text-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n \n // Frame attachment properties\n this.parentFrame = null;\n \n // Update group attributes \u2014 ensure data-type is set for textTool interaction\n this.group.setAttribute('type', 'text');\n this.group.setAttribute('data-type', 'text-group');\n this.group.shapeName = 'text';\n this.group.shapeID = this.shapeID;\n }\n \n // Position and dimension properties for frame compatibility\n get x() {\n const transform = this.group.transform.baseVal.consolidate();\n return transform ? transform.matrix.e : parseFloat(this.group.getAttribute('data-x')) || 0;\n }\n \n set x(value) {\n const transform = this.group.transform.baseVal.consolidate();\n const currentY = transform ? transform.matrix.f : parseFloat(this.group.getAttribute('data-y')) || 0;\n const rotation = extractRotationFromTransform(this.group) || 0;\n const textElement = this.group.querySelector('text');\n if (textElement) {\n const bbox = textElement.getBBox();\n const centerX = bbox.x + bbox.width / 2;\n const centerY = bbox.y + bbox.height / 2;\n this.group.setAttribute('transform', `translate(${value}, ${currentY}) rotate(${rotation}, ${centerX}, ${centerY})`);\n } else {\n this.group.setAttribute('transform', `translate(${value}, ${currentY})`);\n }\n this.group.setAttribute('data-x', value);\n }\n \n get y() {\n const transform = this.group.transform.baseVal.consolidate();\n return transform ? transform.matrix.f : parseFloat(this.group.getAttribute('data-y')) || 0;\n }\n \n set y(value) {\n const transform = this.group.transform.baseVal.consolidate();\n const currentX = transform ? transform.matrix.e : parseFloat(this.group.getAttribute('data-x')) || 0;\n const rotation = extractRotationFromTransform(this.group) || 0;\n const textElement = this.group.querySelector('text');\n if (textElement) {\n const bbox = textElement.getBBox();\n const centerX = bbox.x + bbox.width / 2;\n const centerY = bbox.y + bbox.height / 2;\n this.group.setAttribute('transform', `translate(${currentX}, ${value}) rotate(${rotation}, ${centerX}, ${centerY})`);\n } else {\n this.group.setAttribute('transform', `translate(${currentX}, ${value})`);\n }\n this.group.setAttribute('data-y', value);\n }\n \n get width() {\n const textElement = this.group.querySelector('text');\n if (textElement) {\n return textElement.getBBox().width;\n }\n return 0;\n }\n \n set width(value) {\n // Text width is determined by content and font size, not directly settable\n // This is here for frame compatibility but doesn't change the text\n }\n \n get height() {\n const textElement = this.group.querySelector('text');\n if (textElement) {\n return textElement.getBBox().height;\n }\n return 0;\n }\n \n set height(value) {\n // Text height is determined by content and font size, not directly settable\n // This is here for frame compatibility but doesn't change the text\n }\n \n get rotation() {\n return extractRotationFromTransform(this.group) || 0;\n }\n \n set rotation(value) {\n const currentTransform = this.group.transform.baseVal.consolidate();\n const currentX = currentTransform ? currentTransform.matrix.e : 0;\n const currentY = currentTransform ? currentTransform.matrix.f : 0;\n const textElement = this.group.querySelector('text');\n if (textElement) {\n const bbox = textElement.getBBox();\n const centerX = bbox.x + bbox.width / 2;\n const centerY = bbox.y + bbox.height / 2;\n this.group.setAttribute('transform', `translate(${currentX}, ${currentY}) rotate(${value}, ${centerX}, ${centerY})`);\n }\n }\n\n move(dx, dy) {\n const currentTransform = this.group.transform.baseVal.consolidate();\n const currentX = currentTransform ? currentTransform.matrix.e : 0;\n const currentY = currentTransform ? currentTransform.matrix.f : 0;\n\n this.x = currentX + dx;\n this.y = currentY + dy;\n\n // Only update frame containment if we're actively dragging the shape itself\n // and not being moved by a parent frame\n if (isDragging && !this.isBeingMovedByFrame) {\n this.updateFrameContainment();\n }\n\n this.updateAttachedArrows();\n }\n\n updateAttachedArrows() {\n updateAttachedArrows(this);\n }\n\n updateFrameContainment() {\n // Don't update if we're being moved by a frame\n if (this.isBeingMovedByFrame) return;\n \n let targetFrame = null;\n \n // Find which frame this shape is over\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(shape => {\n if (shape.shapeName === 'frame' && shape.isShapeInFrame(this)) {\n targetFrame = shape;\n }\n });\n }\n \n // If we have a parent frame and we're being dragged, temporarily remove clipping\n if (this.parentFrame && isDragging) {\n this.parentFrame.temporarilyRemoveFromFrame(this);\n }\n \n // Update frame highlighting\n if (hoveredFrameText && hoveredFrameText !== targetFrame) {\n hoveredFrameText.removeHighlight();\n }\n \n if (targetFrame && targetFrame !== hoveredFrameText) {\n targetFrame.highlightFrame();\n }\n \n hoveredFrameText = targetFrame;\n }\n\n contains(x, y) {\n const textElement = this.group.querySelector('text');\n if (!textElement || typeof textElement.getBBox !== 'function') return false;\n\n let bbox;\n try { bbox = textElement.getBBox(); } catch { return false; }\n const padding = 8; // Selection padding\n\n const CTM = this.group.getCTM();\n if (!CTM) return false;\n \n const inverseCTM = CTM.inverse();\n const svgPoint = svg.createSVGPoint();\n svgPoint.x = x;\n svgPoint.y = y;\n const transformedPoint = svgPoint.matrixTransform(inverseCTM);\n \n return transformedPoint.x >= bbox.x - padding && \n transformedPoint.x <= bbox.x + bbox.width + padding &&\n transformedPoint.y >= bbox.y - padding && \n transformedPoint.y <= bbox.y + bbox.height + padding;\n }\n\n // Add draw method for consistency with other shapes\n draw() {\n // Text doesn't need redrawing like other shapes, but we need this method for consistency\n if (selectedElement === this.group) {\n updateSelectionFeedback();\n }\n }\n\n // Add methods for frame compatibility\n removeSelection() {\n if (selectedElement === this.group) {\n deselectElement();\n }\n }\n\n selectShape() {\n // Use the real textTool selectElement (with selection feedback) if available\n if (typeof window !== 'undefined' && window.__selectTextElement) {\n window.__selectTextElement(this.group);\n } else {\n selectElement(this.group);\n }\n }\n}\n\nexport { TextShape };\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -30,7 +30,7 @@ function getThemeStroke() {
30
30
  if (typeof document === "undefined") return "#fff";
31
31
  return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#1a1a2e";
32
32
  }
33
- var textSize = "30px";
33
+ var textSize = "20px";
34
34
  var textFont = "lixFont";
35
35
  var textColor = null;
36
36
  var textAlign = "left";
@@ -156,6 +156,8 @@ function makeTextEditable(textElement, groupElement) {
156
156
  }
157
157
  let input = document.createElement("textarea");
158
158
  input.className = "svg-text-editor";
159
+ input.setAttribute("aria-label", "Edit canvas text");
160
+ input.setAttribute("data-editing", "true");
159
161
  let textContent = "";
160
162
  const storedSource = textElement.getAttribute("data-wrap-source");
161
163
  if (storedSource !== null && storedSource !== "") {
@@ -179,10 +181,9 @@ function makeTextEditable(textElement, groupElement) {
179
181
  input.style.boxSizing = "border-box";
180
182
  input.style.overflow = "hidden";
181
183
  input.style.resize = "none";
182
- input.style.whiteSpace = "pre-wrap";
184
+ input.style.whiteSpace = "pre";
183
185
  input.style.minHeight = "1.2em";
184
186
  input.style.zIndex = "10000";
185
- const svgRect = svg.getBoundingClientRect();
186
187
  const textBBox = textElement.getBBox();
187
188
  let pt = svg.createSVGPoint();
188
189
  pt.x = textBBox.x;
@@ -192,55 +193,42 @@ function makeTextEditable(textElement, groupElement) {
192
193
  input.style.left = `${screenPt.x}px`;
193
194
  input.style.top = `${screenPt.y}px`;
194
195
  const svgZoomFactor = svg.getScreenCTM() ? svg.getScreenCTM().a : 1;
195
- const screenWidth = textBBox.width * svgZoomFactor;
196
196
  input.style.width = "auto";
197
197
  input.style.height = "auto";
198
- const currentFontSize = textElement.getAttribute("font-size") || "30px";
198
+ const currentFontSize = textElement.getAttribute("font-size") || "20px";
199
199
  const currentFontFamily = textElement.getAttribute("font-family") || "lixFont";
200
200
  const currentFill = textElement.getAttribute("fill") || "#fff";
201
201
  const currentAnchor = textElement.getAttribute("text-anchor") || "start";
202
- const rawSize = parseFloat(currentFontSize) || 30;
202
+ const rawSize = parseFloat(currentFontSize) || 20;
203
203
  const scaledFontSize = `${rawSize * svgZoomFactor}px`;
204
204
  input.style.minWidth = "150px";
205
205
  input.style.minHeight = "1.5em";
206
206
  input.style.width = "auto";
207
207
  input.style.height = "auto";
208
208
  input.style.overflow = "visible";
209
- input.style.whiteSpace = "pre-wrap";
210
- input.style.wordBreak = "break-word";
209
+ input.style.whiteSpace = "pre";
210
+ input.style.wordBreak = "normal";
211
+ input.style.overflowWrap = "normal";
211
212
  input.style.fontSize = scaledFontSize;
212
213
  input.style.fontFamily = currentFontFamily;
213
214
  input.style.color = currentFill;
214
215
  input.style.lineHeight = "1.2em";
215
216
  input.style.textAlign = currentAnchor === "middle" ? "center" : currentAnchor === "end" ? "right" : "left";
216
217
  input.style.backgroundColor = "transparent";
217
- const _isDark = typeof document !== "undefined" && document.body && document.body.classList.contains("theme-dark");
218
- input.style.border = _isDark ? "1px dashed rgba(255,255,255,0.55)" : "1px dashed rgba(40,40,60,0.45)";
219
- input.style.borderRadius = "3px";
218
+ input.style.border = "none";
219
+ input.style.boxShadow = "none";
220
220
  input.style.outline = "none";
221
221
  document.body.appendChild(input);
222
222
  const adjustHeight = () => {
223
223
  input.style.height = "auto";
224
224
  input.style.height = input.scrollHeight + "px";
225
- const maxHeight = svgRect.height - screenPt.y;
226
- if (input.scrollHeight > maxHeight) {
227
- input.style.height = maxHeight + "px";
228
- input.style.overflowY = "auto";
229
- } else {
230
- input.style.overflowY = "hidden";
231
- }
225
+ input.style.overflowY = "hidden";
232
226
  };
233
227
  const adjustWidth = () => {
234
228
  input.style.width = "auto";
235
- const maxWidth = svgRect.width - screenPt.x;
236
229
  const contentWidth = Math.max(input.scrollWidth, 150);
237
- if (contentWidth > maxWidth) {
238
- input.style.width = maxWidth + "px";
239
- input.style.overflowX = "auto";
240
- } else {
241
- input.style.width = contentWidth + "px";
242
- input.style.overflowX = "hidden";
243
- }
230
+ input.style.width = contentWidth + "px";
231
+ input.style.overflowX = "hidden";
244
232
  };
245
233
  adjustHeight();
246
234
  adjustWidth();
@@ -273,45 +261,11 @@ function makeTextEditable(textElement, groupElement) {
273
261
  if (textEl) textEl.setAttribute("cursor", "text");
274
262
  groupElement.style.display = "none";
275
263
  }
276
- function measureSegment(text, refTextElement) {
277
- if (!text) return 0;
278
- const NS = "http://www.w3.org/2000/svg";
279
- const probe = document.createElementNS(NS, "tspan");
280
- probe.textContent = text;
281
- refTextElement.appendChild(probe);
282
- let width = 0;
283
- try {
284
- width = probe.getComputedTextLength();
285
- } catch {
286
- }
287
- refTextElement.removeChild(probe);
288
- return width;
289
- }
290
- function paintTextContent(textElement, source, wrapWidth) {
264
+ function paintTextContent(textElement, source) {
291
265
  while (textElement.firstChild) textElement.removeChild(textElement.firstChild);
292
266
  const x = textElement.getAttribute("x") || 0;
293
267
  const NS = "http://www.w3.org/2000/svg";
294
- const paragraphs = (source || "").split("\n");
295
- const finalLines = [];
296
- for (const paragraph of paragraphs) {
297
- const para = paragraph.replace(/ /g, " ");
298
- if (!wrapWidth || wrapWidth <= 0) {
299
- finalLines.push(para || " ");
300
- continue;
301
- }
302
- const words = para.split(/(\s+)/);
303
- let cur = "";
304
- for (const token of words) {
305
- const candidate = cur + token;
306
- if (measureSegment(candidate, textElement) > wrapWidth && cur.trim().length > 0) {
307
- finalLines.push(cur);
308
- cur = token.replace(/^\s+/, "");
309
- } else {
310
- cur = candidate;
311
- }
312
- }
313
- finalLines.push(cur.length ? cur : " ");
314
- }
268
+ const finalLines = (source || "").split("\n").map((line) => line.replace(/ /g, " "));
315
269
  finalLines.forEach((line, i) => {
316
270
  const tspan = document.createElementNS(NS, "tspan");
317
271
  tspan.setAttribute("x", x);
@@ -320,17 +274,6 @@ function paintTextContent(textElement, source, wrapWidth) {
320
274
  textElement.appendChild(tspan);
321
275
  });
322
276
  }
323
- function getWrapSource(textElement) {
324
- const stored = textElement.getAttribute("data-wrap-source");
325
- if (stored !== null && stored !== "") return stored;
326
- const tspans = textElement.querySelectorAll("tspan");
327
- if (tspans.length === 0) return textElement.textContent || "";
328
- return Array.from(tspans).map((t) => (t.textContent || "").replace(/ /g, " ")).join("\n");
329
- }
330
- function getWrapWidth(textElement) {
331
- const v = parseFloat(textElement.getAttribute("data-wrap-width") || "");
332
- return Number.isFinite(v) && v > 0 ? v : 0;
333
- }
334
277
  function renderText(input, textElement, deleteIfEmpty = false) {
335
278
  if (!input || !document.body.contains(input)) {
336
279
  return;
@@ -376,7 +319,8 @@ function renderText(input, textElement, deleteIfEmpty = false) {
376
319
  } else {
377
320
  const cleanSource = text.replace(/\u00A0/g, " ");
378
321
  textElement.setAttribute("data-wrap-source", cleanSource);
379
- paintTextContent(textElement, cleanSource, getWrapWidth(textElement));
322
+ textElement.removeAttribute("data-wrap-width");
323
+ paintTextContent(textElement, cleanSource);
380
324
  gElement.style.display = "block";
381
325
  updateAttachedArrows(gElement);
382
326
  if (selectedElement === gElement) {
@@ -427,9 +371,7 @@ function createSelectionFeedback(groupElement) {
427
371
  { name: "nw", x: selX, y: selY, cursor: "nwse-resize" },
428
372
  { name: "ne", x: selX + selWidth, y: selY, cursor: "nesw-resize" },
429
373
  { name: "sw", x: selX, y: selY + selHeight, cursor: "nesw-resize" },
430
- { name: "se", x: selX + selWidth, y: selY + selHeight, cursor: "nwse-resize" },
431
- { name: "e", x: selX + selWidth, y: selY + selHeight / 2, cursor: "ew-resize" },
432
- { name: "w", x: selX, y: selY + selHeight / 2, cursor: "ew-resize" }
374
+ { name: "se", x: selX + selWidth, y: selY + selHeight, cursor: "nwse-resize" }
433
375
  ];
434
376
  resizeHandles = {};
435
377
  handlesData.forEach((handle) => {
@@ -516,11 +458,7 @@ function updateSelectionFeedback() {
516
458
  { name: "nw", x: selX, y: selY },
517
459
  { name: "ne", x: selX + selWidth, y: selY },
518
460
  { name: "sw", x: selX, y: selY + selHeight },
519
- { name: "se", x: selX + selWidth, y: selY + selHeight },
520
- // Issue #48 bug #5: keep E/W midpoint handles aligned with the
521
- // resize so they follow the box as it scales.
522
- { name: "e", x: selX + selWidth, y: selY + selHeight / 2 },
523
- { name: "w", x: selX, y: selY + selHeight / 2 }
461
+ { name: "se", x: selX + selWidth, y: selY + selHeight }
524
462
  ];
525
463
  handlesData.forEach((handle) => {
526
464
  const handleRect = resizeHandles[handle.name];
@@ -742,7 +680,6 @@ var handleMouseMove = (event) => {
742
680
  const startWidth = startBBox.width;
743
681
  const startHeight = startBBox.height;
744
682
  let anchorX, anchorY;
745
- const isEdgeWidth = currentResizeHandle === "e" || currentResizeHandle === "w";
746
683
  switch (currentResizeHandle) {
747
684
  case "nw":
748
685
  anchorX = startX + startWidth;
@@ -760,28 +697,7 @@ var handleMouseMove = (event) => {
760
697
  anchorX = startX;
761
698
  anchorY = startY;
762
699
  break;
763
- case "e":
764
- anchorX = startX;
765
- anchorY = startY + startHeight / 2;
766
- break;
767
- case "w":
768
- anchorX = startX + startWidth;
769
- anchorY = startY + startHeight / 2;
770
- break;
771
- }
772
- if (isEdgeWidth) {
773
- const newWrap = Math.abs(currentPoint.x - anchorX);
774
- const minWrap = startFontSize * 2;
775
- const clampedWrap = Math.max(minWrap, newWrap);
776
- textElement.setAttribute("data-wrap-width", String(clampedWrap));
777
- const source = getWrapSource(textElement);
778
- paintTextContent(textElement, source, clampedWrap);
779
- if (typeof updateSelectionFeedback === "function") {
780
- setTimeout(updateSelectionFeedback, 0);
781
- }
782
- return;
783
700
  }
784
- const newWidth = Math.abs(currentPoint.x - anchorX);
785
701
  const newHeight = Math.abs(currentPoint.y - anchorY);
786
702
  const chosenScale = newHeight / startHeight;
787
703
  const minScale = 0.1;
@@ -810,14 +726,6 @@ var handleMouseMove = (event) => {
810
726
  newAnchorX = currentBBox.x;
811
727
  newAnchorY = currentBBox.y;
812
728
  break;
813
- case "e":
814
- newAnchorX = currentBBox.x;
815
- newAnchorY = currentBBox.y + currentBBox.height / 2;
816
- break;
817
- case "w":
818
- newAnchorX = currentBBox.x + currentBBox.width;
819
- newAnchorY = currentBBox.y + currentBBox.height / 2;
820
- break;
821
729
  }
822
730
  const deltaX = anchorX - newAnchorX;
823
731
  const deltaY = anchorY - newAnchorY;
@@ -1572,4 +1480,4 @@ export {
1572
1480
  handleTextMouseUp,
1573
1481
  updateCodeToggleForShape
1574
1482
  };
1575
- //# sourceMappingURL=chunk-TUMWA4YF.js.map
1483
+ //# sourceMappingURL=chunk-5QIT2WBE.js.map