stickyflow 0.9.3 → 0.11.0

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 (66) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +1 -1
  3. package/dist/binding/index.cjs +9 -9
  4. package/dist/binding/index.d.cts +4 -4
  5. package/dist/binding/index.d.ts +4 -4
  6. package/dist/binding/index.js +3 -3
  7. package/dist/{chunk-EURX7QT3.cjs → chunk-5G3BEXQU.cjs} +1300 -891
  8. package/dist/chunk-5G3BEXQU.cjs.map +1 -0
  9. package/dist/{chunk-AAP24GBG.js → chunk-BFQWCOEC.js} +3 -3
  10. package/dist/chunk-BFQWCOEC.js.map +1 -0
  11. package/dist/{chunk-3EOG34QN.cjs → chunk-F24JURN2.cjs} +561 -258
  12. package/dist/chunk-F24JURN2.cjs.map +1 -0
  13. package/dist/{chunk-2GKXPZRL.cjs → chunk-FXGXUWSI.cjs} +23 -23
  14. package/dist/chunk-FXGXUWSI.cjs.map +1 -0
  15. package/dist/{chunk-Q6FBISNP.js → chunk-G6IW2IX3.js} +601 -350
  16. package/dist/chunk-G6IW2IX3.js.map +1 -0
  17. package/dist/{chunk-G2N3KJYJ.js → chunk-Q6QLU6YQ.js} +662 -253
  18. package/dist/chunk-Q6QLU6YQ.js.map +1 -0
  19. package/dist/{chunk-C3LVKPWQ.js → chunk-RQYZNW2I.js} +532 -229
  20. package/dist/chunk-RQYZNW2I.js.map +1 -0
  21. package/dist/{chunk-XNNNIOJU.js → chunk-UB2ANTWF.js} +5 -5
  22. package/dist/{chunk-XNNNIOJU.js.map → chunk-UB2ANTWF.js.map} +1 -1
  23. package/dist/{chunk-C25NWWIH.cjs → chunk-UHKFJBY5.cjs} +605 -350
  24. package/dist/chunk-UHKFJBY5.cjs.map +1 -0
  25. package/dist/{chunk-MR32IJQO.cjs → chunk-WZA3DJJH.cjs} +15 -15
  26. package/dist/chunk-WZA3DJJH.cjs.map +1 -0
  27. package/dist/index.cjs +36 -36
  28. package/dist/index.d.cts +35 -30
  29. package/dist/index.d.ts +35 -30
  30. package/dist/index.js +5 -5
  31. package/dist/interaction/index.cjs +319 -352
  32. package/dist/interaction/index.cjs.map +1 -1
  33. package/dist/interaction/index.d.cts +3 -3
  34. package/dist/interaction/index.d.ts +3 -3
  35. package/dist/interaction/index.js +94 -127
  36. package/dist/interaction/index.js.map +1 -1
  37. package/dist/{render-DU4lYbRl.d.ts → render-BDO4S5uF.d.cts} +16 -0
  38. package/dist/{render-DU4lYbRl.d.cts → render-BDO4S5uF.d.ts} +16 -0
  39. package/dist/{runtime-DG8X3Fwf.d.cts → runtime-C-C5v9po.d.cts} +2 -2
  40. package/dist/{runtime-kqD1RS17.d.ts → runtime-lCAfU-1Q.d.ts} +2 -2
  41. package/dist/{runtimeTypes-vRaHOIHi.d.ts → runtimeTypes-B7p6b1Bi.d.cts} +2 -2
  42. package/dist/{runtimeTypes-CvjlBZds.d.cts → runtimeTypes-BDA_CfWh.d.ts} +2 -2
  43. package/dist/stickyflow-diagram.global.js +197 -44
  44. package/dist/stickyflow-diagram.global.js.map +1 -1
  45. package/dist/{types-B5jrEEcF.d.cts → types-CZJzycKw.d.cts} +1 -1
  46. package/dist/{types-B7IkZ0w4.d.ts → types-Dp8JVZLB.d.ts} +1 -1
  47. package/dist/viewer/index.cjs +9 -9
  48. package/dist/viewer/index.d.cts +4 -4
  49. package/dist/viewer/index.d.ts +4 -4
  50. package/dist/viewer/index.js +4 -4
  51. package/dist/web-component/index.cjs +6 -6
  52. package/dist/web-component/index.cjs.map +1 -1
  53. package/dist/web-component/index.d.cts +2 -2
  54. package/dist/web-component/index.d.ts +2 -2
  55. package/dist/web-component/index.js +4 -4
  56. package/dist/web-component/index.js.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/chunk-2GKXPZRL.cjs.map +0 -1
  59. package/dist/chunk-3EOG34QN.cjs.map +0 -1
  60. package/dist/chunk-AAP24GBG.js.map +0 -1
  61. package/dist/chunk-C25NWWIH.cjs.map +0 -1
  62. package/dist/chunk-C3LVKPWQ.js.map +0 -1
  63. package/dist/chunk-EURX7QT3.cjs.map +0 -1
  64. package/dist/chunk-G2N3KJYJ.js.map +0 -1
  65. package/dist/chunk-MR32IJQO.cjs.map +0 -1
  66. package/dist/chunk-Q6FBISNP.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { O as OwnerRef, E as Emitter$1, V as Viewer, U as Unsubscribe } from '../types-B5jrEEcF.cjs';
2
- import { Z as Side, I as IsometricFace } from '../render-DU4lYbRl.cjs';
1
+ import { O as OwnerRef, E as Emitter$1, V as Viewer, U as Unsubscribe } from '../types-CZJzycKw.cjs';
2
+ import { Z as Side, I as IsometricFace } from '../render-BDO4S5uF.cjs';
3
3
 
4
4
  interface TextChangeEvent {
5
5
  owner: OwnerRef;
@@ -184,7 +184,7 @@ declare function openColorPopover(options: ColorPopoverOptions): ColorPopoverHan
184
184
 
185
185
  interface InsertCanvasObjectOptions {
186
186
  id: string;
187
- kind: 'shape' | 'text' | 'frame' | 'swimlane' | 'isometric';
187
+ kind: 'shape' | 'text' | 'image' | 'frame' | 'swimlane' | 'isometric';
188
188
  text?: string;
189
189
  x: number;
190
190
  y: number;
@@ -1,5 +1,5 @@
1
- import { O as OwnerRef, E as Emitter$1, V as Viewer, U as Unsubscribe } from '../types-B7IkZ0w4.js';
2
- import { Z as Side, I as IsometricFace } from '../render-DU4lYbRl.js';
1
+ import { O as OwnerRef, E as Emitter$1, V as Viewer, U as Unsubscribe } from '../types-Dp8JVZLB.js';
2
+ import { Z as Side, I as IsometricFace } from '../render-BDO4S5uF.js';
3
3
 
4
4
  interface TextChangeEvent {
5
5
  owner: OwnerRef;
@@ -184,7 +184,7 @@ declare function openColorPopover(options: ColorPopoverOptions): ColorPopoverHan
184
184
 
185
185
  interface InsertCanvasObjectOptions {
186
186
  id: string;
187
- kind: 'shape' | 'text' | 'frame' | 'swimlane' | 'isometric';
187
+ kind: 'shape' | 'text' | 'image' | 'frame' | 'swimlane' | 'isometric';
188
188
  text?: string;
189
189
  x: number;
190
190
  y: number;
@@ -1,5 +1,5 @@
1
- import { screenRectOf, Emitter, resolveOwner, isCameraGesture, pointerUserPoint, clearAlignmentGuides, updateAlignmentGuides, pxPerUnit, findOwnerNode, isPrimary, SVG_NAMESPACE, isTextLabel, findSnapCandidateBounds, symbolDeclaredBounds, updateQuickDuplicateBubbles, isometricGeometryOf, ISO_HALO_ATTR, ISO_DUPLICATE_BUBBLES_ATTR, updateHalo, axisArrowPlacements, updateAxisArrowGroup, PATH_HALO_ATTR, findAllOwnerNodes, findIsometricApexCandidates, DERIVED_HEIGHT_ROLES, resizeHandlePositions, pathGeometryOf } from '../chunk-AAP24GBG.js';
2
- import { sflToCanvasState, isIsometricObject, tokenizeSource, roundedOrthogonalPathData, seriesLabelOffsetXProp, seriesLabelOffsetYProp, radarVertexPoint, AXIS_SIN, AXIS_COS, freeformPathData, CORNER_RADIUS_ATTR, isometricFaces, roundedPolygonPath, isometricTopFaceCenter, calculateLinkRoute, pointAtPort, roundedBarPath, barShapePath, formatBarLabel, LABEL_WIDTH, LEADER_INSET, clipSegmentToRect, radarValueAtPoint, radarSeriesPath, estimateTextWidth, wrapText, personLabelArea, isometricFaceCenter, PATH_POINT_INDEX_ATTR, linePathData, barLabelSize, BAR_LABEL, pillPath, getLineMidpoint, labelGapDash, pillCornerRadius, SQUARE_CORNER_ATTR, cornersRoundedRectPath, localShapePath, relativeOffsetOnRectangleSide, edgePointToward, SYMBOL_POINTS_ATTR, SYMBOL_TENSION_ATTR } from '../chunk-Q6FBISNP.js';
1
+ import { screenRectOf, Emitter, resolveOwner, isCameraGesture, pointerUserPoint, clearAlignmentGuides, updateAlignmentGuides, pxPerUnit, findOwnerNode, isPrimary, SVG_NAMESPACE, isTextLabel, findSnapCandidateBounds, symbolDeclaredBounds, updateQuickDuplicateBubbles, isometricGeometryOf, updateHalo, axisArrowPlacements, updateAxisArrowGroup, PATH_HALO_ATTR, findAllOwnerNodes, findIsometricApexCandidates, DERIVED_HEIGHT_ROLES, resizeHandlePositions, ISO_HALO_ATTR, ISO_DUPLICATE_BUBBLES_ATTR, pathGeometryOf } from '../chunk-BFQWCOEC.js';
2
+ import { sflToCanvasState, isIsometricObject, rgbToHex, parseHexRgb, rgbToHsv, tokenizeSource, roundedOrthogonalPathData, seriesLabelOffsetXProp, seriesLabelOffsetYProp, radarVertexPoint, AXIS_SIN, AXIS_COS, freeformPathData, CORNER_RADIUS_ATTR, isometricFaces, roundedPolygonPath, isometricTopFaceCenter, calculateLinkRoute, pointAtPort, roundedBarPath, barShapePath, formatBarLabel, LABEL_WIDTH, LEADER_INSET, clipSegmentToRect, radarValueAtPoint, radarSeriesPath, hsvToRgb, estimateTextWidth, wrapText, personLabelArea, isometricFaceCenter, PATH_POINT_INDEX_ATTR, linePathData, barLabelSize, BAR_LABEL, pillPath, getLineMidpoint, labelGapDash, pillCornerRadius, SQUARE_CORNER_ATTR, cornersRoundedRectPath, localShapePath, relativeOffsetOnRectangleSide, edgePointToward, SYMBOL_POINTS_ATTR, SYMBOL_TENSION_ATTR } from '../chunk-G6IW2IX3.js';
3
3
 
4
4
  // src/runtime/interaction/chartValue/coordinates.ts
5
5
  function pointerUserY(svg, event) {
@@ -455,16 +455,9 @@ function bindChartValueDrag(viewer, emitter) {
455
455
  }
456
456
 
457
457
  // src/runtime/interaction/colorEdit/color.ts
458
- var HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
459
458
  function normalizeHex(value) {
460
- const raw = value.trim();
461
- const withHash = raw.startsWith("#") ? raw : `#${raw}`;
462
- if (!HEX.test(withHash)) {
463
- return null;
464
- }
465
- const body = withHash.slice(1);
466
- const full = body.length === 3 ? body.split("").map((char) => char + char).join("") : body;
467
- return `#${full.toLowerCase()}`;
459
+ const channels = parseHexRgb(value);
460
+ return channels && rgbToHex(...channels);
468
461
  }
469
462
  var COLOR_FUNCTION = /^rgba?\(\s*(\d{1,3})\s*[, ]\s*(\d{1,3})\s*[, ]\s*(\d{1,3})\s*(?:[,/]\s*(\d*\.?\d+)(%?)\s*)?\)$/i;
470
463
  var HEX_WITH_ALPHA = /^#([0-9a-f]{6})([0-9a-f]{2})$/i;
@@ -474,7 +467,7 @@ function parseColorAlpha(value) {
474
467
  if (fn) {
475
468
  const alpha = fn[4] === void 0 ? 1 : Number(fn[4]) / (fn[5] ? 100 : 1);
476
469
  return {
477
- hex: rgbToHex({ r: Number(fn[1]), g: Number(fn[2]), b: Number(fn[3]) }),
470
+ hex: rgbToHex2({ r: Number(fn[1]), g: Number(fn[2]), b: Number(fn[3]) }),
478
471
  alpha: Math.max(0, Math.min(1, alpha))
479
472
  };
480
473
  }
@@ -503,63 +496,28 @@ function clampChannel(value) {
503
496
  return Math.max(0, Math.min(255, Math.round(value)));
504
497
  }
505
498
  function hexToRgb(hex) {
506
- const normalized = normalizeHex(hex) ?? "#000000";
507
- return {
508
- r: Number.parseInt(normalized.slice(1, 3), 16),
509
- g: Number.parseInt(normalized.slice(3, 5), 16),
510
- b: Number.parseInt(normalized.slice(5, 7), 16)
511
- };
512
- }
513
- function rgbToHex(rgb) {
514
- const channel = (value) => clampChannel(value).toString(16).padStart(2, "0");
515
- return `#${channel(rgb.r)}${channel(rgb.g)}${channel(rgb.b)}`;
516
- }
517
- function hsvToRgb(hsv) {
518
- const h = (hsv.h % 360 + 360) % 360;
519
- const s = Math.max(0, Math.min(1, hsv.s));
520
- const v = Math.max(0, Math.min(1, hsv.v));
521
- const c = v * s;
522
- const x = c * (1 - Math.abs(h / 60 % 2 - 1));
523
- const m = v - c;
524
- const sector = Math.floor(h / 60);
525
- const table = [
526
- [c, x, 0],
527
- [x, c, 0],
528
- [0, c, x],
529
- [0, x, c],
530
- [x, 0, c],
531
- [c, 0, x]
532
- ];
533
- const [r, g, b] = table[sector] ?? table[0];
534
- return { r: Math.round((r + m) * 255), g: Math.round((g + m) * 255), b: Math.round((b + m) * 255) };
535
- }
536
- function rgbToHsv(rgb) {
537
- const r = clampChannel(rgb.r) / 255;
538
- const g = clampChannel(rgb.g) / 255;
539
- const b = clampChannel(rgb.b) / 255;
540
- const max = Math.max(r, g, b);
541
- const min = Math.min(r, g, b);
542
- const delta = max - min;
543
- let h = 0;
544
- if (delta !== 0) {
545
- if (max === r) {
546
- h = 60 * ((g - b) / delta % 6);
547
- } else if (max === g) {
548
- h = 60 * ((b - r) / delta + 2);
549
- } else {
550
- h = 60 * ((r - g) / delta + 4);
551
- }
552
- }
553
- if (h < 0) {
554
- h += 360;
555
- }
556
- return { h, s: max === 0 ? 0 : delta / max, v: max };
499
+ const [r, g, b] = parseHexRgb(hex) ?? [0, 0, 0];
500
+ return { r, g, b };
501
+ }
502
+ function rgbToHex2(rgb) {
503
+ return rgbToHex(clampChannel(rgb.r), clampChannel(rgb.g), clampChannel(rgb.b));
504
+ }
505
+ function hsvToRgb2(hsv) {
506
+ const { r, g, b } = hsvToRgb(
507
+ (hsv.h % 360 + 360) % 360,
508
+ Math.max(0, Math.min(1, hsv.s)),
509
+ Math.max(0, Math.min(1, hsv.v))
510
+ );
511
+ return { r, g, b };
512
+ }
513
+ function rgbToHsv2(rgb) {
514
+ return rgbToHsv(clampChannel(rgb.r), clampChannel(rgb.g), clampChannel(rgb.b));
557
515
  }
558
516
  function hexToHsv(hex) {
559
- return rgbToHsv(hexToRgb(hex));
517
+ return rgbToHsv2(hexToRgb(hex));
560
518
  }
561
519
  function hsvToHex(hsv) {
562
- return rgbToHex(hsvToRgb(hsv));
520
+ return rgbToHex2(hsvToRgb2(hsv));
563
521
  }
564
522
 
565
523
  // src/runtime/interaction/colorEdit/gradientValue.ts
@@ -1000,9 +958,9 @@ function bindChannel(picker, channel) {
1000
958
  return;
1001
959
  }
1002
960
  const next = { ...hexToRgb(activeHex(picker)), [channel]: value };
1003
- const nextHsv = rgbToHsv(next);
961
+ const nextHsv = rgbToHsv2(next);
1004
962
  picker.state.hsv = nextHsv.s === 0 ? { ...nextHsv, h: picker.state.hsv.h } : nextHsv;
1005
- setActiveColor(picker, rgbToHex(next));
963
+ setActiveColor(picker, rgbToHex2(next));
1006
964
  picker.render();
1007
965
  };
1008
966
  const read = (event) => event.target.value;
@@ -2268,19 +2226,40 @@ function collectNodes(svg, ownerId) {
2268
2226
  labelGuide: bySuffix("-label-guide")
2269
2227
  };
2270
2228
  }
2271
- function createIsometricAxisDragState(svg, event) {
2229
+ function findResizeHandle(event) {
2272
2230
  const target = event.target;
2273
2231
  const captureTarget = target?.closest?.("[data-sf-resize-handle]");
2274
2232
  const handleAttr = captureTarget?.getAttribute("data-sf-resize-handle");
2275
2233
  if (!captureTarget || !handleAttr?.startsWith("iso-")) {
2276
2234
  return null;
2277
2235
  }
2278
- const axis = handleAttr.slice(4);
2279
2236
  const overlay = captureTarget.closest("[data-sf-selection-overlay]");
2280
2237
  const ownerId = overlay?.getAttribute("data-sf-selection-overlay");
2281
- if (!ownerId) {
2238
+ if (!overlay || !ownerId) {
2239
+ return null;
2240
+ }
2241
+ return { captureTarget, axis: handleAttr.slice(4), overlay, ownerId };
2242
+ }
2243
+ function overlayPartsOf(overlay) {
2244
+ const overlayHalo = overlay.querySelector(`[${ISO_HALO_ATTR}]`) ?? null;
2245
+ const overlayArrows = Object.fromEntries(
2246
+ AXES.map((axis) => [
2247
+ axis,
2248
+ overlay.querySelector(`[data-sf-resize-handle="iso-${axis}"]`) ?? null
2249
+ ])
2250
+ );
2251
+ const overlayDuplicateBubbles = overlay.querySelector(`[${ISO_DUPLICATE_BUBBLES_ATTR}]`) ?? null;
2252
+ if (overlayDuplicateBubbles) {
2253
+ overlayDuplicateBubbles.style.display = "none";
2254
+ }
2255
+ return { overlayHalo, overlayArrows, overlayDuplicateBubbles };
2256
+ }
2257
+ function createIsometricAxisDragState(svg, event) {
2258
+ const handle = findResizeHandle(event);
2259
+ if (!handle) {
2282
2260
  return null;
2283
2261
  }
2262
+ const { captureTarget, axis, overlay, ownerId } = handle;
2284
2263
  const primary = findOwnerNode(svg, ownerId, isPrimary);
2285
2264
  const owner = primary && resolveOwner(primary);
2286
2265
  if (!primary || owner?.role !== "isometric") {
@@ -2297,17 +2276,6 @@ function createIsometricAxisDragState(svg, event) {
2297
2276
  node?.removeAttribute("clip-path");
2298
2277
  });
2299
2278
  captureTarget.setPointerCapture?.(event.pointerId);
2300
- const overlayHalo = overlay?.querySelector(`[${ISO_HALO_ATTR}]`) ?? null;
2301
- const overlayArrows = Object.fromEntries(
2302
- AXES.map((axis2) => [
2303
- axis2,
2304
- overlay?.querySelector(`[data-sf-resize-handle="iso-${axis2}"]`) ?? null
2305
- ])
2306
- );
2307
- const overlayDuplicateBubbles = overlay?.querySelector(`[${ISO_DUPLICATE_BUBBLES_ATTR}]`) ?? null;
2308
- if (overlayDuplicateBubbles) {
2309
- overlayDuplicateBubbles.style.display = "none";
2310
- }
2311
2279
  const start = {
2312
2280
  x: bounds.x,
2313
2281
  y: bounds.y,
@@ -2323,9 +2291,7 @@ function createIsometricAxisDragState(svg, event) {
2323
2291
  start,
2324
2292
  cornerRadius: geometry?.cornerRadius ?? Number(primary.getAttribute(CORNER_RADIUS_ATTR)) ?? 0,
2325
2293
  nodes,
2326
- overlayHalo,
2327
- overlayArrows,
2328
- overlayDuplicateBubbles,
2294
+ ...overlayPartsOf(overlay),
2329
2295
  liveFaceLinks: findLiveFaceLinks(svg, ownerId),
2330
2296
  moved: false,
2331
2297
  current: start
@@ -2686,25 +2652,12 @@ function crossedEndpointDragThreshold(drag, event) {
2686
2652
  }
2687
2653
 
2688
2654
  // src/runtime/interaction/linkEndpoint/preview.ts
2689
- function previewLink2(fromSide, toSide) {
2690
- return {
2691
- id: "preview",
2692
- fromId: "",
2693
- toId: "",
2694
- layerGroup: "",
2695
- orderKey: "",
2696
- isVisible: true,
2697
- isLocked: false,
2698
- fromPoint: { kind: "side", side: fromSide, offset: 0.5 },
2699
- toPoint: { kind: "side", side: toSide, offset: 0.5 }
2700
- };
2701
- }
2702
2655
  function updateEndpointPreview(drag, draggedPoint, draggedSide) {
2703
2656
  const fromPoint = drag.end === "from" ? draggedPoint : drag.fixedPoint;
2704
2657
  const toPoint = drag.end === "to" ? draggedPoint : drag.fixedPoint;
2705
2658
  const fromSide = drag.end === "from" ? draggedSide : drag.fixedSide;
2706
2659
  const toSide = drag.end === "to" ? draggedSide : drag.fixedSide;
2707
- const { points, segments } = calculateLinkRoute(previewLink2(fromSide, toSide), fromPoint, toPoint, drag.pathType);
2660
+ const { points, segments } = calculateLinkRoute(previewLink(fromSide, toSide), fromPoint, toPoint, drag.pathType);
2708
2661
  drag.path.setAttribute("d", previewPathData(points, segments, drag.pathType, drag.strokeWidth));
2709
2662
  }
2710
2663
 
@@ -5007,21 +4960,8 @@ function createDuplicatePreviewPath(svg) {
5007
4960
  path.style.pointerEvents = "none";
5008
4961
  return path;
5009
4962
  }
5010
- function previewLink3(fromSide, toSide) {
5011
- return {
5012
- id: "preview",
5013
- fromId: "",
5014
- toId: "",
5015
- layerGroup: "",
5016
- orderKey: "",
5017
- isVisible: true,
5018
- isLocked: false,
5019
- fromPoint: { kind: "side", side: fromSide, offset: 0.5 },
5020
- toPoint: { kind: "side", side: toSide, offset: 0.5 }
5021
- };
5022
- }
5023
4963
  function updateDuplicatePreview(drag, toPoint, toSide) {
5024
- const link = previewLink3(drag.direction, toSide);
4964
+ const link = previewLink(drag.direction, toSide);
5025
4965
  const { points, segments } = calculateLinkRoute(link, drag.fixedPoint, toPoint, NEW_LINK_PATH_TYPE);
5026
4966
  drag.previewPath.setAttribute("d", previewPathData(points, segments, NEW_LINK_PATH_TYPE, 2));
5027
4967
  }
@@ -6423,7 +6363,7 @@ function braceDelta(masked) {
6423
6363
  }
6424
6364
 
6425
6365
  // src/runtime/interaction/sflPatch/scan/blocks.ts
6426
- var OWNER_HEADER = /^\s*(Entity|Shape|Text|Container|Chart|Path|Link|Isometric|Widget|Component|Connection|Shader)\s+([A-Za-z_][A-Za-z0-9_]*)\b/;
6366
+ var OWNER_HEADER = /^\s*(Entity|Shape|Text|Image|Container|Chart|Path|Link|Isometric|Widget|Component|Connection|Shader)\s+([A-Za-z_][A-Za-z0-9_]*)\b/;
6427
6367
  var VALID_IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
6428
6368
  function blockEndIn(masked, startLine) {
6429
6369
  let depth = 0;
@@ -6690,6 +6630,9 @@ function canvasObjectBlockKind(kind) {
6690
6630
  if (kind === "text") {
6691
6631
  return "Text";
6692
6632
  }
6633
+ if (kind === "image") {
6634
+ return "Image";
6635
+ }
6693
6636
  if (kind === "isometric") {
6694
6637
  return "Isometric";
6695
6638
  }
@@ -6808,18 +6751,7 @@ function findReferencingLinkRanges(lines, canvasObjectId) {
6808
6751
  return ranges;
6809
6752
  }
6810
6753
 
6811
- // src/runtime/interaction/sflPatch/canvasObjectPatch/removalRanges.ts
6812
- function containsRange(container, candidate) {
6813
- const sameRange = container.start === candidate.start && container.end === candidate.end;
6814
- return !sameRange && container.start <= candidate.start && container.end >= candidate.end;
6815
- }
6816
- function outermostRemovalRanges(ranges) {
6817
- return ranges.filter(
6818
- (candidate) => !ranges.some((container) => container !== candidate && containsRange(container, candidate))
6819
- );
6820
- }
6821
-
6822
- // src/runtime/interaction/sflPatch/canvasObjectPatch/repeatCell.ts
6754
+ // src/runtime/interaction/sflPatch/canvasObjectPatch/madeBlocks.ts
6823
6755
  var REPEAT_HEADER = /^(\s*)Repeat\s+[A-Za-z_]\w*\s*\{\s*$/;
6824
6756
  var TEMPLATE_HEADER = /^\s*[A-Z]\w*\s+([A-Za-z_]\w*)\b[^{]*\{/;
6825
6757
  var PROPERTY = /^\s*[A-Za-z_]\w*\s*:/;
@@ -6846,7 +6778,7 @@ function excludeRepeatCell(lines, id) {
6846
6778
  const template = masked[i].match(TEMPLATE_HEADER);
6847
6779
  if (template) {
6848
6780
  seenTemplate = true;
6849
- const made = id.match(new RegExp(`^${escaped(template[1])}_(\\d+)(?:_(\\d+))?$`));
6781
+ const made = id.match(new RegExp(`^${escaped(template[1])}_(\\d+)(?:_(\\d+))?(?:_[A-Za-z]\\w*)?$`));
6850
6782
  if (made) {
6851
6783
  cell = { col: Number(made[1]), row: made[2] === void 0 ? 0 : Number(made[2]) };
6852
6784
  }
@@ -6875,13 +6807,48 @@ function excludeRepeatCell(lines, id) {
6875
6807
  }
6876
6808
  return null;
6877
6809
  }
6810
+ var USE_HEADER = /^\s*Use\s+([A-Za-z_]\w*)\s*:/;
6811
+ function findUseBlock(lines, id) {
6812
+ const masked = maskLines(lines);
6813
+ if (masked === null) {
6814
+ return null;
6815
+ }
6816
+ let found = null;
6817
+ for (let start = 0; start < masked.length; start++) {
6818
+ const header = masked[start].match(USE_HEADER);
6819
+ if (header && id.startsWith(`${header[1]}_`) && (found === null || header[1].length > found.length)) {
6820
+ found = { start, end: blockEndLine(lines, start), length: header[1].length };
6821
+ }
6822
+ }
6823
+ return found && { start: found.start, end: found.end };
6824
+ }
6825
+
6826
+ // src/runtime/interaction/sflPatch/canvasObjectPatch/removalRanges.ts
6827
+ function containsRange(container, candidate) {
6828
+ const sameRange = container.start === candidate.start && container.end === candidate.end;
6829
+ return !sameRange && container.start <= candidate.start && container.end >= candidate.end;
6830
+ }
6831
+ function outermostRemovalRanges(ranges) {
6832
+ return ranges.filter(
6833
+ (candidate) => !ranges.some((container) => container !== candidate && containsRange(container, candidate))
6834
+ );
6835
+ }
6878
6836
 
6879
6837
  // src/runtime/interaction/sflPatch/canvasObjectPatch/remove.ts
6880
6838
  function removeCanvasObject(sfl, id, options = {}) {
6881
6839
  const lines = sfl.split("\n");
6882
6840
  const canvasObjectRange = findOwnerBlock(lines, id);
6883
6841
  if (!canvasObjectRange) {
6884
- return excludeRepeatCell(lines, id)?.join("\n") ?? sfl;
6842
+ const cell = excludeRepeatCell(lines, id);
6843
+ if (cell) {
6844
+ return cell.join("\n");
6845
+ }
6846
+ const use = findUseBlock(lines, id);
6847
+ if (use) {
6848
+ lines.splice(use.start, use.end - use.start + 1);
6849
+ return lines.join("\n");
6850
+ }
6851
+ return sfl;
6885
6852
  }
6886
6853
  const ranges = [canvasObjectRange];
6887
6854
  if (options.alsoRemoveLinks ?? true) {