@elixpo/lixsketch 5.5.12 → 5.5.14

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 (69) hide show
  1. package/dist/react/{AIRenderer-PWWLWI6U.js → AIRenderer-ATIKGFB4.js} +90 -8
  2. package/dist/react/{AIRenderer-PWWLWI6U.js.map → AIRenderer-ATIKGFB4.js.map} +2 -2
  3. package/dist/react/Circle-ZH76FPOR.js +8 -0
  4. package/dist/react/CodeShape-TE74XP5V.js +8 -0
  5. package/dist/react/{CopyPaste-SA72NDFN.js → CopyPaste-UTU5MPKY.js} +14 -10
  6. package/dist/react/{CopyPaste-SA72NDFN.js.map → CopyPaste-UTU5MPKY.js.map} +2 -2
  7. package/dist/react/{EventDispatcher-BZQRHROG.js → EventDispatcher-K4CNNBAU.js} +2 -2
  8. package/dist/react/FreehandStroke-BOWDNAVC.js +8 -0
  9. package/dist/react/{GraphEngine-IHRVGUGG.js → GraphEngine-KQXHNTZQ.js} +39 -1
  10. package/dist/react/{GraphEngine-IHRVGUGG.js.map → GraphEngine-KQXHNTZQ.js.map} +2 -2
  11. package/dist/react/{MermaidStructuredRenderer-GGOOGON5.js → MermaidStructuredRenderer-26WGA6YD.js} +152 -25
  12. package/dist/react/MermaidStructuredRenderer-26WGA6YD.js.map +7 -0
  13. package/dist/react/Rectangle-2F7BAXG4.js +8 -0
  14. package/dist/react/{SceneSerializer-ZPHV6IUP.js → SceneSerializer-34VQFJN7.js} +6 -6
  15. package/dist/react/{Selection-VVUHY5YJ.js → Selection-XLRY6VYO.js} +2 -2
  16. package/dist/react/{SketchEngine-NPF2XN6Z.js → SketchEngine-P3XNZA56.js} +12 -12
  17. package/dist/react/TextShape-QRDG4P7F.js +8 -0
  18. package/dist/react/{chunk-42O6W7DF.js → chunk-62W6XTCZ.js} +13 -9
  19. package/dist/react/{chunk-42O6W7DF.js.map → chunk-62W6XTCZ.js.map} +2 -2
  20. package/dist/react/{chunk-AJAZC37E.js → chunk-GZ6NPDAB.js} +7 -11
  21. package/dist/react/{chunk-AJAZC37E.js.map → chunk-GZ6NPDAB.js.map} +2 -2
  22. package/dist/react/{chunk-YKJUBFHE.js → chunk-HKYUJUD7.js} +34 -2
  23. package/dist/react/chunk-HKYUJUD7.js.map +7 -0
  24. package/dist/react/{chunk-Q2GA4MBZ.js → chunk-IW2NRHNK.js} +11 -2
  25. package/dist/react/{chunk-Q2GA4MBZ.js.map → chunk-IW2NRHNK.js.map} +2 -2
  26. package/dist/react/{chunk-7TZSIR6V.js → chunk-MB7VS6MK.js} +13 -9
  27. package/dist/react/{chunk-7TZSIR6V.js.map → chunk-MB7VS6MK.js.map} +2 -2
  28. package/dist/react/{chunk-T6ZVV5ZO.js → chunk-Z4YVT54E.js} +11 -9
  29. package/dist/react/{chunk-T6ZVV5ZO.js.map → chunk-Z4YVT54E.js.map} +2 -2
  30. package/dist/react/index.js +26 -18
  31. package/dist/react/index.js.map +2 -2
  32. package/dist/react/styles.css +10 -3
  33. package/package.json +1 -1
  34. package/src/core/AIRenderer.js +104 -6
  35. package/src/core/CopyPaste.js +11 -5
  36. package/src/core/GraphEngine.js +45 -0
  37. package/src/core/MermaidStructuredRenderer.js +162 -22
  38. package/src/core/Selection.js +15 -2
  39. package/src/react/LixSketchCanvas.jsx +4 -0
  40. package/src/react/components/AppMenu.jsx +2 -2
  41. package/src/react/components/Toolbar.jsx +1 -1
  42. package/src/react/components/modals/CommandPalette.jsx +3 -3
  43. package/src/react/components/sidebars/FrameSidebar.jsx +1 -1
  44. package/src/react/components/sidebars/IconSidebar.jsx +2 -2
  45. package/src/react/components/sidebars/ShapeSidebar.jsx +1 -1
  46. package/src/react/store/useSketchStore.js +7 -2
  47. package/src/react/store/useUIStore.js +3 -4
  48. package/src/react/styles.css +12 -3
  49. package/src/shapes/Circle.js +8 -12
  50. package/src/shapes/CodeShape.js +17 -12
  51. package/src/shapes/FreehandStroke.js +46 -3
  52. package/src/shapes/Rectangle.js +14 -11
  53. package/src/shapes/TextShape.js +17 -12
  54. package/dist/react/Circle-KPG7TKIX.js +0 -8
  55. package/dist/react/CodeShape-K4DIZAIV.js +0 -8
  56. package/dist/react/FreehandStroke-CK24NUT3.js +0 -8
  57. package/dist/react/MermaidStructuredRenderer-GGOOGON5.js.map +0 -7
  58. package/dist/react/Rectangle-6FE7RN6W.js +0 -8
  59. package/dist/react/TextShape-U6ZZKB35.js +0 -8
  60. package/dist/react/chunk-YKJUBFHE.js.map +0 -7
  61. /package/dist/react/{Circle-KPG7TKIX.js.map → Circle-ZH76FPOR.js.map} +0 -0
  62. /package/dist/react/{CodeShape-K4DIZAIV.js.map → CodeShape-TE74XP5V.js.map} +0 -0
  63. /package/dist/react/{EventDispatcher-BZQRHROG.js.map → EventDispatcher-K4CNNBAU.js.map} +0 -0
  64. /package/dist/react/{FreehandStroke-CK24NUT3.js.map → FreehandStroke-BOWDNAVC.js.map} +0 -0
  65. /package/dist/react/{Rectangle-6FE7RN6W.js.map → Rectangle-2F7BAXG4.js.map} +0 -0
  66. /package/dist/react/{SceneSerializer-ZPHV6IUP.js.map → SceneSerializer-34VQFJN7.js.map} +0 -0
  67. /package/dist/react/{Selection-VVUHY5YJ.js.map → Selection-XLRY6VYO.js.map} +0 -0
  68. /package/dist/react/{SketchEngine-NPF2XN6Z.js.map → SketchEngine-P3XNZA56.js.map} +0 -0
  69. /package/dist/react/{TextShape-U6ZZKB35.js.map → TextShape-QRDG4P7F.js.map} +0 -0
@@ -3,16 +3,26 @@
3
3
  // src/core/MermaidStructuredRenderer.js
4
4
  var NS = "http://www.w3.org/2000/svg";
5
5
  var PALETTE = [
6
- { fill: "#dfeee4", stroke: "#5f836c" },
7
- { fill: "#f4e3d4", stroke: "#a97852" },
8
- { fill: "#e9e1ef", stroke: "#7e6b91" },
9
- { fill: "#f3edc9", stroke: "#9a8745" },
10
- { fill: "#dcebed", stroke: "#5d7f82" },
11
- { fill: "#f1dedc", stroke: "#9a6863" }
6
+ { fill: "#8b7abb", stroke: "#665793" },
7
+ { fill: "#a992cf", stroke: "#7762a6" },
8
+ { fill: "#c2addc", stroke: "#8974aa" },
9
+ { fill: "#7765a6", stroke: "#584883" },
10
+ { fill: "#9d83c1", stroke: "#725b9a" },
11
+ { fill: "#d1c3e7", stroke: "#927daf" }
12
12
  ];
13
13
  function escapeXml(value) {
14
14
  return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
15
15
  }
16
+ function contrastText(fill) {
17
+ const raw = String(fill || "").replace("#", "");
18
+ const hex = raw.length === 3 ? raw.split("").map((char) => char + char).join("") : raw;
19
+ if (!/^[0-9a-f]{6}$/i.test(hex)) return theme().text;
20
+ const red = parseInt(hex.slice(0, 2), 16);
21
+ const green = parseInt(hex.slice(2, 4), 16);
22
+ const blue = parseInt(hex.slice(4, 6), 16);
23
+ const luminance = 0.299 * red + 0.587 * green + 0.114 * blue;
24
+ return luminance > 145 ? "#34304a" : "#ffffff";
25
+ }
16
26
  function isDark() {
17
27
  return typeof document !== "undefined" && document.body?.classList.contains("theme-dark");
18
28
  }
@@ -117,7 +127,7 @@ function renderERPreviewSVG(diagram) {
117
127
  for (const entity of entities) {
118
128
  content += `<g><rect x="${entity.x}" y="${entity.y}" width="${entity.width}" height="${entity.height}" rx="8" fill="${TK.panel}" stroke="${entity.color.stroke}" stroke-width="1.5"/>`;
119
129
  content += `<rect x="${entity.x}" y="${entity.y}" width="${entity.width}" height="${entity.headerHeight}" rx="8" fill="${entity.color.fill}" stroke="${entity.color.stroke}" stroke-width="1.5"/>`;
120
- content += `<text x="${entity.x + entity.width / 2}" y="${entity.y + 27}" text-anchor="middle" fill="#343832" font-size="14" font-weight="600" font-family="lixFont">${escapeXml(entity.name)}</text>`;
130
+ content += `<text x="${entity.x + entity.width / 2}" y="${entity.y + 27}" text-anchor="middle" fill="${contrastText(entity.color.fill)}" font-size="14" font-weight="600" font-family="lixFont">${escapeXml(entity.name)}</text>`;
121
131
  const attributes = entity.attributes.length ? entity.attributes : [{ type: "", name: "No attributes", key: "" }];
122
132
  attributes.forEach((attribute, row) => {
123
133
  const y = entity.y + entity.headerHeight + row * entity.rowHeight;
@@ -169,6 +179,31 @@ function renderChartPreviewSVG(chart) {
169
179
  const TK = theme();
170
180
  const width = 720;
171
181
  const height = 450;
182
+ if (chart.kind === "pie") {
183
+ const values2 = chart.series[0].values.map((value) => Math.max(0, value));
184
+ const total = values2.reduce((sum, value) => sum + value, 0);
185
+ if (total <= 0) return "";
186
+ const cx = 255;
187
+ const cy = 235;
188
+ const radius = 145;
189
+ let startAngle = -Math.PI / 2;
190
+ let content2 = `<rect width="${width}" height="${height}" rx="10" fill="${TK.bg}"/><text x="${width / 2}" y="32" text-anchor="middle" fill="${TK.text}" font-size="18" font-family="lixFont">${escapeXml(chart.title)}</text>`;
191
+ values2.forEach((value, index) => {
192
+ const endAngle = startAngle + value / total * Math.PI * 2;
193
+ const x1 = cx + Math.cos(startAngle) * radius;
194
+ const y1 = cy + Math.sin(startAngle) * radius;
195
+ const x2 = cx + Math.cos(endAngle) * radius;
196
+ const y2 = cy + Math.sin(endAngle) * radius;
197
+ const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
198
+ const color = PALETTE[index % PALETTE.length];
199
+ content2 += `<path d="M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z" fill="${color.fill}" stroke="${TK.bg}" stroke-width="3"/>`;
200
+ const percent = Math.round(value / total * 100);
201
+ const legendY = 125 + index * 42;
202
+ content2 += `<rect x="460" y="${legendY - 14}" width="18" height="18" rx="4" fill="${color.fill}" stroke="${color.stroke}"/><text x="488" y="${legendY}" fill="${TK.text}" font-size="12" font-family="lixFont">${escapeXml(chart.categories[index] || index + 1)} \u2014 ${value} (${percent}%)</text>`;
203
+ startAngle = endAngle;
204
+ });
205
+ return `<svg xmlns="${NS}" width="600" height="450" viewBox="0 0 ${width} ${height}">${content2}</svg>`;
206
+ }
172
207
  const left = 70;
173
208
  const top = 60;
174
209
  const plotWidth = 580;
@@ -206,6 +241,28 @@ function push(shape, frame) {
206
241
  if (frame?.addShapeToFrame) frame.addShapeToFrame(shape);
207
242
  return shape;
208
243
  }
244
+ function pushText(text, x, y, fontSize, fill, frame) {
245
+ if (!window.TextShape || !window.svg) return null;
246
+ const group = document.createElementNS(NS, "g");
247
+ group.setAttribute("data-type", "text-group");
248
+ group.setAttribute("transform", `translate(${x}, ${y})`);
249
+ group.setAttribute("data-x", x);
250
+ group.setAttribute("data-y", y);
251
+ const element = document.createElementNS(NS, "text");
252
+ element.setAttribute("x", 0);
253
+ element.setAttribute("y", 0);
254
+ element.setAttribute("dominant-baseline", "central");
255
+ element.setAttribute("fill", fill);
256
+ element.setAttribute("font-size", fontSize);
257
+ element.setAttribute("font-family", "lixFont, sans-serif");
258
+ element.setAttribute("data-initial-font", "lixFont");
259
+ element.setAttribute("data-initial-color", fill);
260
+ element.setAttribute("data-initial-size", `${fontSize}px`);
261
+ element.textContent = text;
262
+ group.appendChild(element);
263
+ window.svg.appendChild(group);
264
+ return push(new window.TextShape(group), frame);
265
+ }
209
266
  function canvasOrigin(width, height) {
210
267
  const vb = window.currentViewBox || { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight };
211
268
  return { x: vb.x + vb.width / 2 - width / 2, y: vb.y + vb.height / 2 - height / 2 };
@@ -223,6 +280,16 @@ function createFrame(x, y, width, height, name, type) {
223
280
  push(frame);
224
281
  return frame;
225
282
  }
283
+ function selectOnlyFrame(frame) {
284
+ if (!frame) return;
285
+ if (window.multiSelection?.clearSelection) window.multiSelection.clearSelection();
286
+ if (window.currentShape && window.currentShape !== frame && typeof window.currentShape.removeSelection === "function") {
287
+ window.currentShape.removeSelection();
288
+ }
289
+ if (window.__deselectTextElement) window.__deselectTextElement();
290
+ window.currentShape = frame;
291
+ if (typeof frame.selectFrame === "function") frame.selectFrame();
292
+ }
226
293
  function renderEROnCanvas(diagram) {
227
294
  if (!diagram?.entities?.length || !window.Rectangle || !window.Arrow || !window.Frame) return false;
228
295
  const TK = theme();
@@ -243,7 +310,7 @@ function renderEROnCanvas(diagram) {
243
310
  fillStyle: "solid",
244
311
  roughness: 1,
245
312
  label: entity.name,
246
- labelColor: "#343832",
313
+ labelColor: contrastText(entity.color.fill),
247
314
  labelFontSize: 15
248
315
  }), frame);
249
316
  if (!first) first = header;
@@ -291,7 +358,8 @@ function renderEROnCanvas(diagram) {
291
358
  return true;
292
359
  }
293
360
  function renderChartOnCanvas(chart) {
294
- if (!chart?.series?.length || !window.Rectangle || !window.Circle || !window.Line || !window.Frame) return false;
361
+ if (!chart?.series?.length || !window.Rectangle || !window.Circle || !window.Line || !window.FreehandStroke || !window.Frame) return false;
362
+ if (chart.kind === "pie") return renderPieOnCanvas(chart);
295
363
  const TK = theme();
296
364
  const width = 720;
297
365
  const height = 450;
@@ -304,35 +372,40 @@ function renderChartOnCanvas(chart) {
304
372
  const values = chart.series.flatMap((series) => series.values);
305
373
  const maximum = Math.max(1, ...values.map(Math.abs));
306
374
  const slot = plotWidth / Math.max(1, chart.categories.length);
307
- let first = null;
308
375
  push(new window.Line({ x: left, y: top }, { x: left, y: top + plotHeight }, { stroke: TK.line, strokeWidth: 1.5, roughness: 0 }), frame);
309
376
  push(new window.Line({ x: left, y: top + plotHeight }, { x: left + plotWidth, y: top + plotHeight }, { stroke: TK.line, strokeWidth: 1.5, roughness: 0 }), frame);
310
377
  chart.series.forEach((series, seriesIndex) => {
311
378
  const color = PALETTE[seriesIndex % PALETTE.length];
312
379
  if (series.kind === "line") {
313
- let previous = null;
314
- series.values.forEach((value, index) => {
380
+ const linePoints = series.values.map((value, index) => {
315
381
  const point = { x: left + slot * (index + 0.5), y: top + plotHeight - Math.abs(value) / maximum * plotHeight };
316
- const dot = push(new window.Circle(point.x, point.y, 8, 8, {
382
+ push(new window.Circle(point.x, point.y, 8, 8, {
317
383
  stroke: color.stroke,
318
384
  strokeWidth: 2,
319
385
  fill: color.fill,
320
386
  fillStyle: "solid",
321
387
  roughness: 0.5,
322
388
  label: String(value),
323
- labelColor: TK.text,
389
+ labelColor: contrastText(color.fill),
324
390
  labelFontSize: 9
325
391
  }), frame);
326
- if (!first) first = dot;
327
- if (previous) push(new window.Line(previous, point, { stroke: color.stroke, strokeWidth: 3, roughness: 0.5 }), frame);
328
- previous = point;
392
+ return [point.x, point.y, 0.5];
329
393
  });
394
+ if (linePoints.length > 1) {
395
+ push(new window.FreehandStroke(linePoints, {
396
+ stroke: color.stroke,
397
+ strokeWidth: 3,
398
+ thinning: 0,
399
+ roughness: 0,
400
+ strokeStyle: "solid"
401
+ }), frame);
402
+ }
330
403
  } else {
331
404
  const barWidth = Math.max(18, slot * 0.7 / chart.series.length);
332
405
  series.values.forEach((value, index) => {
333
406
  const barHeight = Math.max(8, Math.abs(value) / maximum * plotHeight);
334
407
  const x = left + slot * index + slot * 0.15 + seriesIndex * barWidth;
335
- const bar = push(new window.Rectangle(x, top + plotHeight - barHeight, barWidth, barHeight, {
408
+ push(new window.Rectangle(x, top + plotHeight - barHeight, barWidth, barHeight, {
336
409
  stroke: color.stroke,
337
410
  strokeWidth: 1.5,
338
411
  fill: color.fill,
@@ -340,17 +413,71 @@ function renderChartOnCanvas(chart) {
340
413
  roughness: 0.7,
341
414
  label: `${chart.categories[index] || index + 1}
342
415
  ${value}`,
343
- labelColor: "#343832",
416
+ labelColor: contrastText(color.fill),
344
417
  labelFontSize: 11
345
418
  }), frame);
346
- if (!first) first = bar;
347
419
  });
348
420
  }
349
421
  });
350
- if (first?.selectShape) {
351
- window.currentShape = first;
352
- first.selectShape();
353
- }
422
+ selectOnlyFrame(frame);
423
+ return true;
424
+ }
425
+ function renderPieOnCanvas(chart) {
426
+ if (!window.FreehandStroke || !window.TextShape) return false;
427
+ const width = 720;
428
+ const height = 450;
429
+ const origin = canvasOrigin(width, height);
430
+ const frame = createFrame(origin.x, origin.y, width, height, chart.title, "mermaid-pie");
431
+ const values = chart.series[0].values.map((value) => Math.max(0, value));
432
+ const total = values.reduce((sum, value) => sum + value, 0);
433
+ if (total <= 0) return false;
434
+ const cx = origin.x + 255;
435
+ const cy = origin.y + 235;
436
+ const radius = 145;
437
+ let startAngle = -Math.PI / 2;
438
+ values.forEach((value, index) => {
439
+ const sweep = value / total * Math.PI * 2;
440
+ const endAngle = startAngle + sweep;
441
+ const steps = Math.max(6, Math.ceil(sweep / (Math.PI / 60)));
442
+ const points = [[cx, cy, 0.5]];
443
+ for (let step = 0; step <= steps; step++) {
444
+ const angle = startAngle + sweep * (step / steps);
445
+ points.push([
446
+ cx + Math.cos(angle) * radius,
447
+ cy + Math.sin(angle) * radius,
448
+ 0.5
449
+ ]);
450
+ }
451
+ const color = PALETTE[index % PALETTE.length];
452
+ push(new window.FreehandStroke(points, {
453
+ stroke: color.fill,
454
+ strokeWidth: 3,
455
+ outlineStroke: theme().bg,
456
+ outlineWidth: 3,
457
+ closedFill: true,
458
+ roughness: 0,
459
+ strokeStyle: "solid"
460
+ }), frame);
461
+ const percent = Math.round(value / total * 100);
462
+ const legendY = origin.y + 125 + index * 42;
463
+ push(new window.Rectangle(origin.x + 460, legendY - 14, 18, 18, {
464
+ stroke: color.stroke,
465
+ strokeWidth: 1,
466
+ fill: color.fill,
467
+ fillStyle: "solid",
468
+ roughness: 0.5
469
+ }), frame);
470
+ pushText(
471
+ `${chart.categories[index] || index + 1} \u2014 ${value} (${percent}%)`,
472
+ origin.x + 488,
473
+ legendY,
474
+ 12,
475
+ theme().text,
476
+ frame
477
+ );
478
+ startAngle = endAngle;
479
+ });
480
+ selectOnlyFrame(frame);
354
481
  return true;
355
482
  }
356
483
  export {
@@ -362,4 +489,4 @@ export {
362
489
  renderEROnCanvas,
363
490
  renderERPreviewSVG
364
491
  };
365
- //# sourceMappingURL=MermaidStructuredRenderer-GGOOGON5.js.map
492
+ //# sourceMappingURL=MermaidStructuredRenderer-26WGA6YD.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/MermaidStructuredRenderer.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n/**\n * Native renderers for Mermaid ER and chart diagrams.\n *\n * Preview is SVG, while canvas placement deliberately creates ordinary\n * LixSketch shapes. That keeps entities, attributes, relationships, bars,\n * points, and legend items independently selectable and editable.\n */\n\nconst NS = 'http://www.w3.org/2000/svg';\nconst PALETTE = [\n { fill: '#8b7abb', stroke: '#665793' },\n { fill: '#a992cf', stroke: '#7762a6' },\n { fill: '#c2addc', stroke: '#8974aa' },\n { fill: '#7765a6', stroke: '#584883' },\n { fill: '#9d83c1', stroke: '#725b9a' },\n { fill: '#d1c3e7', stroke: '#927daf' },\n];\n\nfunction escapeXml(value) {\n return String(value ?? '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction contrastText(fill) {\n const raw = String(fill || '').replace('#', '');\n const hex = raw.length === 3 ? raw.split('').map(char => char + char).join('') : raw;\n if (!/^[0-9a-f]{6}$/i.test(hex)) return theme().text;\n const red = parseInt(hex.slice(0, 2), 16);\n const green = parseInt(hex.slice(2, 4), 16);\n const blue = parseInt(hex.slice(4, 6), 16);\n const luminance = .299 * red + .587 * green + .114 * blue;\n return luminance > 145 ? '#34304a' : '#ffffff';\n}\n\nfunction isDark() {\n return typeof document !== 'undefined' && document.body?.classList.contains('theme-dark');\n}\n\nfunction theme() {\n return isDark()\n ? { bg: '#20232a', text: '#f0eee8', line: '#aaa89f', frame: '#77766f', panel: '#292d34' }\n : { bg: '#fbfaf6', text: '#343832', line: '#6e746c', frame: '#b9b7ac', panel: '#f5f2ea' };\n}\n\nfunction sourceLines(src) {\n return src.split('\\n').map(line => line.trim()).filter(line => line && !line.startsWith('%%'));\n}\n\nexport function detectStructuredMermaid(src) {\n const header = sourceLines(src)[0]?.toLowerCase() || '';\n if (header === 'erdiagram') return 'er';\n if (/^pie(?:\\s|$)/.test(header) || /^xychart(?:-beta)?(?:\\s|$)/.test(header)) return 'chart';\n return null;\n}\n\n// ---------------------------------------------------------------------\n// Entity relationship diagrams\n// ---------------------------------------------------------------------\n\nexport function parseERDiagram(src) {\n const lines = sourceLines(src);\n if (lines[0]?.toLowerCase() !== 'erdiagram') return null;\n\n const entityMap = new Map();\n const relationships = [];\n let current = null;\n\n const ensureEntity = (name) => {\n if (!entityMap.has(name)) entityMap.set(name, { name, attributes: [] });\n return entityMap.get(name);\n };\n\n for (let index = 1; index < lines.length; index++) {\n const line = lines[index];\n const entityStart = line.match(/^([\\w-]+)\\s*\\{$/);\n if (entityStart) {\n current = ensureEntity(entityStart[1]);\n continue;\n }\n if (line === '}') {\n current = null;\n continue;\n }\n if (current) {\n const attribute = line.match(/^(\\S+)\\s+(\\S+)(?:\\s+(.+))?$/);\n if (attribute) {\n current.attributes.push({\n type: attribute[1],\n name: attribute[2],\n key: attribute[3] || '',\n });\n }\n continue;\n }\n\n // CUSTOMER ||--o{ ORDER : places\n const relation = line.match(/^([\\w-]+)\\s+([|o}{.]+)(?:--|\\.\\.)([|o}{.]+)\\s+([\\w-]+)\\s*:\\s*(.+)$/);\n if (relation) {\n ensureEntity(relation[1]);\n ensureEntity(relation[4]);\n relationships.push({\n from: relation[1],\n fromCardinality: relation[2],\n toCardinality: relation[3],\n to: relation[4],\n label: relation[5],\n });\n }\n }\n\n if (entityMap.size === 0) return null;\n return { type: 'erDiagram', title: 'Entity relationship diagram', entities: [...entityMap.values()], relationships };\n}\n\nfunction layoutER(diagram) {\n const width = 230;\n const headerHeight = 44;\n const rowHeight = 30;\n const columns = Math.max(1, Math.ceil(Math.sqrt(diagram.entities.length)));\n return diagram.entities.map((entity, index) => ({\n ...entity,\n x: 60 + (index % columns) * 330,\n y: 55 + Math.floor(index / columns) * 270,\n width,\n headerHeight,\n rowHeight,\n height: headerHeight + Math.max(1, entity.attributes.length) * rowHeight,\n color: PALETTE[index % PALETTE.length],\n }));\n}\n\nexport function renderERPreviewSVG(diagram) {\n if (!diagram?.entities?.length) return '';\n const TK = theme();\n const entities = layoutER(diagram);\n const byName = new Map(entities.map(entity => [entity.name, entity]));\n const maxX = Math.max(...entities.map(entity => entity.x + entity.width)) + 60;\n const maxY = Math.max(...entities.map(entity => entity.y + entity.height)) + 55;\n let content = `<rect width=\"${maxX}\" height=\"${maxY}\" rx=\"10\" fill=\"${TK.bg}\"/>`;\n content += `<defs><marker id=\"er-arrow\" markerWidth=\"9\" markerHeight=\"7\" refX=\"8\" refY=\"3.5\" orient=\"auto\"><path d=\"M1 1 L8 3.5 L1 6\" fill=\"none\" stroke=\"${TK.line}\" stroke-width=\"1.4\"/></marker></defs>`;\n\n for (const relation of diagram.relationships) {\n const from = byName.get(relation.from);\n const to = byName.get(relation.to);\n if (!from || !to) continue;\n const x1 = from.x + from.width / 2;\n const y1 = from.y + from.height / 2;\n const x2 = to.x + to.width / 2;\n const y2 = to.y + to.height / 2;\n const mx = (x1 + x2) / 2;\n const my = (y1 + y2) / 2;\n content += `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${TK.line}\" stroke-width=\"1.6\" marker-end=\"url(#er-arrow)\"/>`;\n content += `<text x=\"${mx}\" y=\"${my - 8}\" text-anchor=\"middle\" fill=\"${TK.text}\" font-size=\"12\" font-family=\"lixFont\">${escapeXml(`${relation.fromCardinality} ${relation.label} ${relation.toCardinality}`)}</text>`;\n }\n\n for (const entity of entities) {\n content += `<g><rect x=\"${entity.x}\" y=\"${entity.y}\" width=\"${entity.width}\" height=\"${entity.height}\" rx=\"8\" fill=\"${TK.panel}\" stroke=\"${entity.color.stroke}\" stroke-width=\"1.5\"/>`;\n content += `<rect x=\"${entity.x}\" y=\"${entity.y}\" width=\"${entity.width}\" height=\"${entity.headerHeight}\" rx=\"8\" fill=\"${entity.color.fill}\" stroke=\"${entity.color.stroke}\" stroke-width=\"1.5\"/>`;\n content += `<text x=\"${entity.x + entity.width / 2}\" y=\"${entity.y + 27}\" text-anchor=\"middle\" fill=\"${contrastText(entity.color.fill)}\" font-size=\"14\" font-weight=\"600\" font-family=\"lixFont\">${escapeXml(entity.name)}</text>`;\n const attributes = entity.attributes.length ? entity.attributes : [{ type: '', name: 'No attributes', key: '' }];\n attributes.forEach((attribute, row) => {\n const y = entity.y + entity.headerHeight + row * entity.rowHeight;\n content += `<line x1=\"${entity.x}\" y1=\"${y}\" x2=\"${entity.x + entity.width}\" y2=\"${y}\" stroke=\"${TK.frame}\" stroke-width=\"0.8\"/>`;\n content += `<text x=\"${entity.x + 10}\" y=\"${y + 20}\" fill=\"${TK.text}\" font-size=\"11\" font-family=\"lixCode\">${escapeXml([attribute.type, attribute.name, attribute.key].filter(Boolean).join(' '))}</text>`;\n });\n content += '</g>';\n }\n return `<svg xmlns=\"${NS}\" width=\"600\" height=\"450\" viewBox=\"0 0 ${maxX} ${maxY}\">${content}</svg>`;\n}\n\n// ---------------------------------------------------------------------\n// Pie and XY charts\n// ---------------------------------------------------------------------\n\nfunction numberList(value) {\n return value.replace(/^\\[|\\]$/g, '').split(',').map(item => Number(item.trim())).filter(Number.isFinite);\n}\n\nexport function parseChartDiagram(src) {\n const lines = sourceLines(src);\n const header = lines[0]?.toLowerCase() || '';\n if (/^pie(?:\\s|$)/.test(header)) {\n let title = lines[0].replace(/^pie(?:\\s+showData)?\\s*/i, '').replace(/^title\\s+/i, '').trim() || 'Pie chart';\n const values = [];\n for (let index = 1; index < lines.length; index++) {\n const titleMatch = lines[index].match(/^title\\s+(.+)$/i);\n if (titleMatch) { title = titleMatch[1]; continue; }\n const item = lines[index].match(/^\"?(.+?)\"?\\s*:\\s*(-?\\d+(?:\\.\\d+)?)$/);\n if (item) values.push({ label: item[1], value: Number(item[2]) });\n }\n return values.length ? { type: 'chart', kind: 'pie', title, categories: values.map(v => v.label), series: [{ name: title, values: values.map(v => v.value) }] } : null;\n }\n if (!/^xychart(?:-beta)?(?:\\s|$)/.test(header)) return null;\n let title = 'Chart';\n let categories = [];\n const series = [];\n for (let index = 1; index < lines.length; index++) {\n const titleMatch = lines[index].match(/^title\\s+\"?(.+?)\"?$/i);\n const axisMatch = lines[index].match(/^x-axis(?:\\s+\".*?\")?\\s+(\\[.+\\])/i);\n const seriesMatch = lines[index].match(/^(bar|line)(?:\\s+\"?([^\"\\[]+)\"?)?\\s+(\\[.+\\])$/i);\n if (titleMatch) title = titleMatch[1];\n else if (axisMatch) categories = axisMatch[1].replace(/^\\[|\\]$/g, '').split(',').map(v => v.trim().replace(/^\"|\"$/g, ''));\n else if (seriesMatch) series.push({ kind: seriesMatch[1].toLowerCase(), name: seriesMatch[2]?.trim() || seriesMatch[1], values: numberList(seriesMatch[3]) });\n }\n const maxItems = Math.max(0, ...series.map(item => item.values.length));\n if (!categories.length) categories = Array.from({ length: maxItems }, (_, index) => String(index + 1));\n return series.length ? { type: 'chart', kind: 'xy', title, categories, series } : null;\n}\n\nexport function renderChartPreviewSVG(chart) {\n if (!chart?.series?.length) return '';\n const TK = theme();\n const width = 720;\n const height = 450;\n\n if (chart.kind === 'pie') {\n const values = chart.series[0].values.map(value => Math.max(0, value));\n const total = values.reduce((sum, value) => sum + value, 0);\n if (total <= 0) return '';\n const cx = 255;\n const cy = 235;\n const radius = 145;\n let startAngle = -Math.PI / 2;\n let content = `<rect width=\"${width}\" height=\"${height}\" rx=\"10\" fill=\"${TK.bg}\"/><text x=\"${width / 2}\" y=\"32\" text-anchor=\"middle\" fill=\"${TK.text}\" font-size=\"18\" font-family=\"lixFont\">${escapeXml(chart.title)}</text>`;\n\n values.forEach((value, index) => {\n const endAngle = startAngle + value / total * Math.PI * 2;\n const x1 = cx + Math.cos(startAngle) * radius;\n const y1 = cy + Math.sin(startAngle) * radius;\n const x2 = cx + Math.cos(endAngle) * radius;\n const y2 = cy + Math.sin(endAngle) * radius;\n const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;\n const color = PALETTE[index % PALETTE.length];\n content += `<path d=\"M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z\" fill=\"${color.fill}\" stroke=\"${TK.bg}\" stroke-width=\"3\"/>`;\n const percent = Math.round(value / total * 100);\n const legendY = 125 + index * 42;\n content += `<rect x=\"460\" y=\"${legendY - 14}\" width=\"18\" height=\"18\" rx=\"4\" fill=\"${color.fill}\" stroke=\"${color.stroke}\"/><text x=\"488\" y=\"${legendY}\" fill=\"${TK.text}\" font-size=\"12\" font-family=\"lixFont\">${escapeXml(chart.categories[index] || index + 1)} \u2014 ${value} (${percent}%)</text>`;\n startAngle = endAngle;\n });\n return `<svg xmlns=\"${NS}\" width=\"600\" height=\"450\" viewBox=\"0 0 ${width} ${height}\">${content}</svg>`;\n }\n\n const left = 70;\n const top = 60;\n const plotWidth = 580;\n const plotHeight = 300;\n const values = chart.series.flatMap(series => series.values);\n const maximum = Math.max(1, ...values.map(Math.abs));\n const categoryCount = Math.max(1, chart.categories.length);\n const slot = plotWidth / categoryCount;\n let content = `<rect width=\"${width}\" height=\"${height}\" rx=\"10\" fill=\"${TK.bg}\"/><text x=\"${width / 2}\" y=\"32\" text-anchor=\"middle\" fill=\"${TK.text}\" font-size=\"18\" font-family=\"lixFont\">${escapeXml(chart.title)}</text>`;\n content += `<line x1=\"${left}\" y1=\"${top}\" x2=\"${left}\" y2=\"${top + plotHeight}\" stroke=\"${TK.line}\"/><line x1=\"${left}\" y1=\"${top + plotHeight}\" x2=\"${left + plotWidth}\" y2=\"${top + plotHeight}\" stroke=\"${TK.line}\"/>`;\n\n chart.categories.forEach((category, index) => {\n content += `<text x=\"${left + slot * (index + .5)}\" y=\"${top + plotHeight + 24}\" text-anchor=\"middle\" fill=\"${TK.text}\" font-size=\"11\" font-family=\"lixFont\">${escapeXml(category)}</text>`;\n });\n\n chart.series.forEach((series, seriesIndex) => {\n const color = PALETTE[seriesIndex % PALETTE.length];\n if (series.kind === 'line') {\n const points = series.values.map((value, index) => `${left + slot * (index + .5)},${top + plotHeight - Math.abs(value) / maximum * plotHeight}`).join(' ');\n content += `<polyline points=\"${points}\" fill=\"none\" stroke=\"${color.stroke}\" stroke-width=\"3\"/>`;\n series.values.forEach((value, index) => content += `<circle cx=\"${left + slot * (index + .5)}\" cy=\"${top + plotHeight - Math.abs(value) / maximum * plotHeight}\" r=\"5\" fill=\"${color.fill}\" stroke=\"${color.stroke}\" stroke-width=\"2\"/>`);\n } else {\n const barWidth = Math.max(12, slot * .7 / chart.series.length);\n series.values.forEach((value, index) => {\n const barHeight = Math.abs(value) / maximum * plotHeight;\n const x = left + slot * index + slot * .15 + seriesIndex * barWidth;\n content += `<rect x=\"${x}\" y=\"${top + plotHeight - barHeight}\" width=\"${barWidth}\" height=\"${barHeight}\" rx=\"4\" fill=\"${color.fill}\" stroke=\"${color.stroke}\" stroke-width=\"1.5\"/><text x=\"${x + barWidth / 2}\" y=\"${top + plotHeight - barHeight - 7}\" text-anchor=\"middle\" fill=\"${TK.text}\" font-size=\"10\" font-family=\"lixFont\">${value}</text>`;\n });\n }\n });\n return `<svg xmlns=\"${NS}\" width=\"600\" height=\"450\" viewBox=\"0 0 ${width} ${height}\">${content}</svg>`;\n}\n\n// ---------------------------------------------------------------------\n// Native canvas placement helpers\n// ---------------------------------------------------------------------\n\nfunction push(shape, frame) {\n if (!shape) return null;\n window.shapes.push(shape);\n if (window.pushCreateAction) window.pushCreateAction(shape);\n if (frame?.addShapeToFrame) frame.addShapeToFrame(shape);\n return shape;\n}\n\nfunction pushText(text, x, y, fontSize, fill, frame) {\n if (!window.TextShape || !window.svg) return null;\n const group = document.createElementNS(NS, 'g');\n group.setAttribute('data-type', 'text-group');\n group.setAttribute('transform', `translate(${x}, ${y})`);\n group.setAttribute('data-x', x);\n group.setAttribute('data-y', y);\n\n const element = document.createElementNS(NS, 'text');\n element.setAttribute('x', 0);\n element.setAttribute('y', 0);\n element.setAttribute('dominant-baseline', 'central');\n element.setAttribute('fill', fill);\n element.setAttribute('font-size', fontSize);\n element.setAttribute('font-family', 'lixFont, sans-serif');\n element.setAttribute('data-initial-font', 'lixFont');\n element.setAttribute('data-initial-color', fill);\n element.setAttribute('data-initial-size', `${fontSize}px`);\n element.textContent = text;\n group.appendChild(element);\n window.svg.appendChild(group);\n return push(new window.TextShape(group), frame);\n}\n\nfunction canvasOrigin(width, height) {\n const vb = window.currentViewBox || { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight };\n return { x: vb.x + vb.width / 2 - width / 2, y: vb.y + vb.height / 2 - height / 2 };\n}\n\nfunction createFrame(x, y, width, height, name, type) {\n const TK = theme();\n const frame = new window.Frame(x - 45, y - 45, width + 90, height + 90, {\n stroke: TK.frame, strokeWidth: 1, fill: 'transparent', opacity: .75, frameName: name,\n });\n frame._diagramType = type;\n push(frame);\n return frame;\n}\n\nfunction selectOnlyFrame(frame) {\n if (!frame) return;\n if (window.multiSelection?.clearSelection) window.multiSelection.clearSelection();\n if (window.currentShape && window.currentShape !== frame && typeof window.currentShape.removeSelection === 'function') {\n window.currentShape.removeSelection();\n }\n if (window.__deselectTextElement) window.__deselectTextElement();\n window.currentShape = frame;\n if (typeof frame.selectFrame === 'function') frame.selectFrame();\n}\n\nexport function renderEROnCanvas(diagram) {\n if (!diagram?.entities?.length || !window.Rectangle || !window.Arrow || !window.Frame) return false;\n const TK = theme();\n const entities = layoutER(diagram);\n const width = Math.max(...entities.map(entity => entity.x + entity.width)) + 40;\n const height = Math.max(...entities.map(entity => entity.y + entity.height)) + 40;\n const origin = canvasOrigin(width, height);\n const frame = createFrame(origin.x, origin.y, width, height, diagram.title, 'mermaid-er');\n const entityShapes = new Map();\n let first = null;\n\n for (const entity of entities) {\n const x = origin.x + entity.x;\n const y = origin.y + entity.y;\n const header = push(new window.Rectangle(x, y, entity.width, entity.headerHeight, {\n stroke: entity.color.stroke, strokeWidth: 1.5, fill: entity.color.fill, fillStyle: 'solid', roughness: 1,\n label: entity.name, labelColor: contrastText(entity.color.fill), labelFontSize: 15,\n }), frame);\n if (!first) first = header;\n entityShapes.set(entity.name, { shape: header, x, y, width: entity.width, height: entity.headerHeight });\n const attributes = entity.attributes.length ? entity.attributes : [{ type: '', name: 'No attributes', key: '' }];\n attributes.forEach((attribute, row) => push(new window.Rectangle(\n x, y + entity.headerHeight + row * entity.rowHeight, entity.width, entity.rowHeight,\n { stroke: TK.frame, strokeWidth: 1, fill: TK.panel, fillStyle: 'solid', roughness: .4,\n label: [attribute.type, attribute.name, attribute.key].filter(Boolean).join(' '), labelColor: TK.text, labelFontSize: 11 }\n ), frame));\n }\n\n for (const relation of diagram.relationships) {\n const from = entityShapes.get(relation.from);\n const to = entityShapes.get(relation.to);\n if (!from || !to) continue;\n const start = { x: from.x + from.width / 2, y: from.y + from.height / 2 };\n const end = { x: to.x + to.width / 2, y: to.y + to.height / 2 };\n const arrow = push(new window.Arrow(start, end, {\n stroke: TK.line, strokeWidth: 1.5, roughness: 1,\n label: `${relation.fromCardinality} ${relation.label} ${relation.toCardinality}`, labelColor: TK.text,\n }), frame);\n if (arrow && window.__autoAttach) {\n window.__autoAttach(arrow, from.shape, true, start);\n window.__autoAttach(arrow, to.shape, false, end);\n }\n }\n if (first?.selectShape) { window.currentShape = first; first.selectShape(); }\n return true;\n}\n\nexport function renderChartOnCanvas(chart) {\n if (!chart?.series?.length || !window.Rectangle || !window.Circle || !window.Line || !window.FreehandStroke || !window.Frame) return false;\n if (chart.kind === 'pie') return renderPieOnCanvas(chart);\n const TK = theme();\n const width = 720;\n const height = 450;\n const origin = canvasOrigin(width, height);\n const frame = createFrame(origin.x, origin.y, width, height, chart.title, 'mermaid-chart');\n const left = origin.x + 70;\n const top = origin.y + 65;\n const plotWidth = 580;\n const plotHeight = 300;\n const values = chart.series.flatMap(series => series.values);\n const maximum = Math.max(1, ...values.map(Math.abs));\n const slot = plotWidth / Math.max(1, chart.categories.length);\n push(new window.Line({ x: left, y: top }, { x: left, y: top + plotHeight }, { stroke: TK.line, strokeWidth: 1.5, roughness: 0 }), frame);\n push(new window.Line({ x: left, y: top + plotHeight }, { x: left + plotWidth, y: top + plotHeight }, { stroke: TK.line, strokeWidth: 1.5, roughness: 0 }), frame);\n\n chart.series.forEach((series, seriesIndex) => {\n const color = PALETTE[seriesIndex % PALETTE.length];\n if (series.kind === 'line') {\n const linePoints = series.values.map((value, index) => {\n const point = { x: left + slot * (index + .5), y: top + plotHeight - Math.abs(value) / maximum * plotHeight };\n push(new window.Circle(point.x, point.y, 8, 8, {\n stroke: color.stroke, strokeWidth: 2, fill: color.fill, fillStyle: 'solid', roughness: .5,\n label: String(value), labelColor: contrastText(color.fill), labelFontSize: 9,\n }), frame);\n return [point.x, point.y, .5];\n });\n if (linePoints.length > 1) {\n push(new window.FreehandStroke(linePoints, {\n stroke: color.stroke,\n strokeWidth: 3,\n thinning: 0,\n roughness: 0,\n strokeStyle: 'solid',\n }), frame);\n }\n } else {\n const barWidth = Math.max(18, slot * .7 / chart.series.length);\n series.values.forEach((value, index) => {\n const barHeight = Math.max(8, Math.abs(value) / maximum * plotHeight);\n const x = left + slot * index + slot * .15 + seriesIndex * barWidth;\n push(new window.Rectangle(x, top + plotHeight - barHeight, barWidth, barHeight, {\n stroke: color.stroke, strokeWidth: 1.5, fill: color.fill, fillStyle: 'solid', roughness: .7,\n label: `${chart.categories[index] || index + 1}\\n${value}`, labelColor: contrastText(color.fill), labelFontSize: 11,\n }), frame);\n });\n }\n });\n selectOnlyFrame(frame);\n return true;\n}\n\nfunction renderPieOnCanvas(chart) {\n if (!window.FreehandStroke || !window.TextShape) return false;\n const width = 720;\n const height = 450;\n const origin = canvasOrigin(width, height);\n const frame = createFrame(origin.x, origin.y, width, height, chart.title, 'mermaid-pie');\n const values = chart.series[0].values.map(value => Math.max(0, value));\n const total = values.reduce((sum, value) => sum + value, 0);\n if (total <= 0) return false;\n\n const cx = origin.x + 255;\n const cy = origin.y + 235;\n const radius = 145;\n let startAngle = -Math.PI / 2;\n\n values.forEach((value, index) => {\n const sweep = value / total * Math.PI * 2;\n const endAngle = startAngle + sweep;\n const steps = Math.max(6, Math.ceil(sweep / (Math.PI / 60)));\n const points = [[cx, cy, .5]];\n for (let step = 0; step <= steps; step++) {\n const angle = startAngle + sweep * (step / steps);\n points.push([\n cx + Math.cos(angle) * radius,\n cy + Math.sin(angle) * radius,\n .5,\n ]);\n }\n const color = PALETTE[index % PALETTE.length];\n push(new window.FreehandStroke(points, {\n stroke: color.fill,\n strokeWidth: 3,\n outlineStroke: theme().bg,\n outlineWidth: 3,\n closedFill: true,\n roughness: 0,\n strokeStyle: 'solid',\n }), frame);\n const percent = Math.round(value / total * 100);\n const legendY = origin.y + 125 + index * 42;\n push(new window.Rectangle(origin.x + 460, legendY - 14, 18, 18, {\n stroke: color.stroke,\n strokeWidth: 1,\n fill: color.fill,\n fillStyle: 'solid',\n roughness: .5,\n }), frame);\n pushText(\n `${chart.categories[index] || index + 1} \u2014 ${value} (${percent}%)`,\n origin.x + 488,\n legendY,\n 12,\n theme().text,\n frame,\n );\n startAngle = endAngle;\n });\n\n selectOnlyFrame(frame);\n return true;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["title", "values", "content"]
7
+ }
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import {
3
+ Rectangle
4
+ } from "./chunk-Z4YVT54E.js";
5
+ export {
6
+ Rectangle
7
+ };
8
+ //# sourceMappingURL=Rectangle-2F7BAXG4.js.map
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  CodeShape
4
- } from "./chunk-7TZSIR6V.js";
4
+ } from "./chunk-MB7VS6MK.js";
5
5
  import {
6
6
  ImageShape
7
7
  } from "./chunk-CB2RANCB.js";
@@ -13,13 +13,13 @@ import {
13
13
  } from "./chunk-BU4D2WYQ.js";
14
14
  import {
15
15
  FreehandStroke
16
- } from "./chunk-YKJUBFHE.js";
16
+ } from "./chunk-HKYUJUD7.js";
17
17
  import {
18
18
  Rectangle
19
- } from "./chunk-T6ZVV5ZO.js";
19
+ } from "./chunk-Z4YVT54E.js";
20
20
  import {
21
21
  Circle
22
- } from "./chunk-AJAZC37E.js";
22
+ } from "./chunk-GZ6NPDAB.js";
23
23
  import {
24
24
  Arrow
25
25
  } from "./chunk-XISEAGBV.js";
@@ -30,7 +30,7 @@ import "./chunk-BZE4CEBG.js";
30
30
  import "./chunk-L5OARZJ7.js";
31
31
  import {
32
32
  TextShape
33
- } from "./chunk-42O6W7DF.js";
33
+ } from "./chunk-62W6XTCZ.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-ZPHV6IUP.js.map
739
+ //# sourceMappingURL=SceneSerializer-34VQFJN7.js.map
@@ -13,7 +13,7 @@ import {
13
13
  removeMultiSelectionControls,
14
14
  removeMultiSelectionRect,
15
15
  selectShapesInRect
16
- } from "./chunk-Q2GA4MBZ.js";
16
+ } from "./chunk-IW2NRHNK.js";
17
17
  import "./chunk-BZE4CEBG.js";
18
18
  import "./chunk-L5OARZJ7.js";
19
19
  export {
@@ -31,4 +31,4 @@ export {
31
31
  removeMultiSelectionRect,
32
32
  selectShapesInRect
33
33
  };
34
- //# sourceMappingURL=Selection-VVUHY5YJ.js.map
34
+ //# sourceMappingURL=Selection-XLRY6VYO.js.map
@@ -161,16 +161,16 @@ var SketchEngine = class {
161
161
  { Frame },
162
162
  { FreehandStroke }
163
163
  ] = await Promise.all([
164
- import("./Rectangle-6FE7RN6W.js"),
165
- import("./Circle-KPG7TKIX.js"),
164
+ import("./Rectangle-2F7BAXG4.js"),
165
+ import("./Circle-ZH76FPOR.js"),
166
166
  import("./Arrow-BJDAXPMH.js"),
167
167
  import("./Line-2KOQEEGA.js"),
168
- import("./TextShape-U6ZZKB35.js"),
169
- import("./CodeShape-K4DIZAIV.js"),
168
+ import("./TextShape-QRDG4P7F.js"),
169
+ import("./CodeShape-TE74XP5V.js"),
170
170
  import("./ImageShape-CHHGBXUQ.js"),
171
171
  import("./IconShape-KMIA6T2H.js"),
172
172
  import("./Frame-6UR5XPAX.js"),
173
- import("./FreehandStroke-CK24NUT3.js")
173
+ import("./FreehandStroke-BOWDNAVC.js")
174
174
  ]);
175
175
  window.Rectangle = Rectangle;
176
176
  window.Circle = Circle;
@@ -239,11 +239,11 @@ var SketchEngine = class {
239
239
  resizeShapes,
240
240
  resizeCode
241
241
  ] = await Promise.all([
242
- import("./EventDispatcher-BZQRHROG.js"),
242
+ import("./EventDispatcher-K4CNNBAU.js"),
243
243
  import("./UndoRedo-M2JZUBKN.js"),
244
- import("./Selection-VVUHY5YJ.js"),
244
+ import("./Selection-XLRY6VYO.js"),
245
245
  import("./ZoomPan-NYPDJBD5.js"),
246
- import("./CopyPaste-SA72NDFN.js"),
246
+ import("./CopyPaste-UTU5MPKY.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-ZPHV6IUP.js");
265
+ const sceneSerializer = await import("./SceneSerializer-34VQFJN7.js");
266
266
  if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
267
267
  await Promise.all([
268
268
  import("./eraserTool-2GS2LQCS.js"),
@@ -275,9 +275,9 @@ var SketchEngine = class {
275
275
  if (selection.multiSelection) window.multiSelection = selection.multiSelection;
276
276
  if (selection.clearAllSelections) window.clearAllSelections = selection.clearAllSelections;
277
277
  if (copyPaste.initCopyPaste) copyPaste.initCopyPaste();
278
- const aiRenderer = await import("./AIRenderer-PWWLWI6U.js");
278
+ const aiRenderer = await import("./AIRenderer-ATIKGFB4.js");
279
279
  if (aiRenderer.initAIRenderer) aiRenderer.initAIRenderer();
280
- const graphEngine = await import("./GraphEngine-IHRVGUGG.js");
280
+ const graphEngine = await import("./GraphEngine-KQXHNTZQ.js");
281
281
  if (graphEngine.initGraphEngine) graphEngine.initGraphEngine();
282
282
  const layerOrder = await import("./LayerOrder-XCHF4MSS.js");
283
283
  if (layerOrder.initLayerOrder) layerOrder.initLayerOrder();
@@ -414,4 +414,4 @@ export {
414
414
  SketchEngine,
415
415
  SketchEngine_default as default
416
416
  };
417
- //# sourceMappingURL=SketchEngine-NPF2XN6Z.js.map
417
+ //# sourceMappingURL=SketchEngine-P3XNZA56.js.map
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import {
3
+ TextShape
4
+ } from "./chunk-62W6XTCZ.js";
5
+ export {
6
+ TextShape
7
+ };
8
+ //# sourceMappingURL=TextShape-QRDG4P7F.js.map
@@ -172,14 +172,18 @@ var TextShape = class {
172
172
  return false;
173
173
  }
174
174
  const padding = 8;
175
- const CTM = this.group.getCTM();
176
- if (!CTM) return false;
177
- const inverseCTM = CTM.inverse();
178
- const svgPoint = svg.createSVGPoint();
179
- svgPoint.x = x;
180
- svgPoint.y = y;
181
- const transformedPoint = svgPoint.matrixTransform(inverseCTM);
182
- return transformedPoint.x >= bbox.x - padding && transformedPoint.x <= bbox.x + bbox.width + padding && transformedPoint.y >= bbox.y - padding && transformedPoint.y <= bbox.y + bbox.height + padding;
175
+ const transform = this.group.getAttribute("transform") || "";
176
+ const translate = transform.match(/translate\(\s*([^,\s)]+)[,\s]+([^\s)]+)/);
177
+ const tx = Number.isFinite(parseFloat(this.group.getAttribute("data-x"))) ? parseFloat(this.group.getAttribute("data-x")) : parseFloat(translate?.[1]) || 0;
178
+ const ty = Number.isFinite(parseFloat(this.group.getAttribute("data-y"))) ? parseFloat(this.group.getAttribute("data-y")) : parseFloat(translate?.[2]) || 0;
179
+ const centerX = bbox.x + bbox.width / 2;
180
+ const centerY = bbox.y + bbox.height / 2;
181
+ const angle = -extractRotationFromTransform(this.group) * Math.PI / 180;
182
+ const dx = x - tx - centerX;
183
+ const dy = y - ty - centerY;
184
+ const localX = dx * Math.cos(angle) - dy * Math.sin(angle) + centerX;
185
+ const localY = dx * Math.sin(angle) + dy * Math.cos(angle) + centerY;
186
+ return localX >= bbox.x - padding && localX <= bbox.x + bbox.width + padding && localY >= bbox.y - padding && localY <= bbox.y + bbox.height + padding;
183
187
  }
184
188
  // Add draw method for consistency with other shapes
185
189
  draw() {
@@ -205,4 +209,4 @@ var TextShape = class {
205
209
  export {
206
210
  TextShape
207
211
  };
208
- //# sourceMappingURL=chunk-42O6W7DF.js.map
212
+ //# sourceMappingURL=chunk-62W6XTCZ.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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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",
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 transform = this.group.getAttribute('transform') || '';\n const translate = transform.match(/translate\\(\\s*([^,\\s)]+)[,\\s]+([^\\s)]+)/);\n const tx = Number.isFinite(parseFloat(this.group.getAttribute('data-x')))\n ? parseFloat(this.group.getAttribute('data-x')) : parseFloat(translate?.[1]) || 0;\n const ty = Number.isFinite(parseFloat(this.group.getAttribute('data-y')))\n ? parseFloat(this.group.getAttribute('data-y')) : parseFloat(translate?.[2]) || 0;\n const centerX = bbox.x + bbox.width / 2;\n const centerY = bbox.y + bbox.height / 2;\n const angle = -extractRotationFromTransform(this.group) * Math.PI / 180;\n const dx = x - tx - centerX;\n const dy = y - ty - centerY;\n const localX = dx * Math.cos(angle) - dy * Math.sin(angle) + centerX;\n const localY = dx * Math.sin(angle) + dy * Math.cos(angle) + centerY;\n \n return localX >= bbox.x - padding &&\n localX <= bbox.x + bbox.width + padding &&\n localY >= bbox.y - padding &&\n localY <= 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
6
  "names": []
7
7
  }