system-canvas-standalone 0.2.40 → 0.2.41

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.
@@ -12759,12 +12759,12 @@ var SystemCanvas = (() => {
12759
12759
  render: () => render,
12760
12760
  themes: () => themes
12761
12761
  });
12762
- var import_react34 = __toESM(require_react(), 1);
12762
+ var import_react35 = __toESM(require_react(), 1);
12763
12763
  var import_client = __toESM(require_client(), 1);
12764
12764
 
12765
12765
  // ../react/dist/components/SystemCanvas.js
12766
- var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
12767
- var import_react33 = __toESM(require_react(), 1);
12766
+ var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
12767
+ var import_react34 = __toESM(require_react(), 1);
12768
12768
 
12769
12769
  // ../core/dist/themes/dark.js
12770
12770
  var darkTheme = {
@@ -15068,7 +15068,7 @@ var SystemCanvas = (() => {
15068
15068
  // ../react/dist/hooks/useKeyboardShortcuts.js
15069
15069
  var import_react2 = __toESM(require_react(), 1);
15070
15070
  function useKeyboardShortcuts(options) {
15071
- const { editable, editingId, editingEdgeId, selectedIds, selectedEdgeId, nodesRef, edgesRef, theme, currentCanvasRef, contextMenuState, wrappedOnNodeAdd, wrappedOnEdgeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeDelete, onNodesUpdate, beginBatch, endBatch, undo, redo, selectNode, selectMultiple, selectAll, clearSelection, setEditingId, setEditingEdgeId, setSelectedEdgeId, setContextMenuState, edgeContextMenuState, setEdgeContextMenuState, cancelDrag, fitSelection } = options;
15071
+ const { editable, editingId, editingEdgeId, selectedIds, selectedEdgeId, nodesRef, edgesRef, theme, currentCanvasRef, contextMenuState, wrappedOnNodeAdd, wrappedOnEdgeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeDelete, onNodesUpdate, beginBatch, endBatch, undo, redo, selectNode, selectMultiple, selectAll, clearSelection, setEditingId, setEditingEdgeId, setSelectedEdgeId, setContextMenuState, edgeContextMenuState, setEdgeContextMenuState, canvasContextMenuState, setCanvasContextMenuState, cancelDrag, fitSelection } = options;
15072
15072
  const handleKeyDown = (0, import_react2.useCallback)((e) => {
15073
15073
  const meta = e.metaKey;
15074
15074
  const ctrl = e.ctrlKey;
@@ -15084,6 +15084,10 @@ var SystemCanvas = (() => {
15084
15084
  if (!editable)
15085
15085
  return;
15086
15086
  if (e.key === "Escape") {
15087
+ if (canvasContextMenuState) {
15088
+ setCanvasContextMenuState(null);
15089
+ return;
15090
+ }
15087
15091
  if (contextMenuState) {
15088
15092
  setContextMenuState(null);
15089
15093
  return;
@@ -15308,6 +15312,8 @@ var SystemCanvas = (() => {
15308
15312
  setEditingEdgeId,
15309
15313
  setSelectedEdgeId,
15310
15314
  setContextMenuState,
15315
+ canvasContextMenuState,
15316
+ setCanvasContextMenuState,
15311
15317
  cancelDrag,
15312
15318
  fitSelection
15313
15319
  ]);
@@ -22249,12 +22255,120 @@ var SystemCanvas = (() => {
22249
22255
  }) });
22250
22256
  }
22251
22257
 
22252
- // ../react/dist/components/SearchOverlay.js
22258
+ // ../react/dist/components/CanvasContextMenuOverlay.js
22253
22259
  var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
22254
22260
  var import_react30 = __toESM(require_react(), 1);
22255
- function SearchOverlay({ open, query, onQueryChange, theme, hiddenCategories, onToggleCategory, matchCount, matchIndex, onNext, onPrev, onClose }) {
22256
- const inputRef = (0, import_react30.useRef)(null);
22261
+ var ESTIMATED_MENU_WIDTH3 = 200;
22262
+ var MIN_MENU_WIDTH3 = 160;
22263
+ var VIEWPORT_MARGIN3 = 8;
22264
+ function CanvasContextMenuOverlay({ state, config, theme, onClose }) {
22265
+ const rootRef = (0, import_react30.useRef)(null);
22266
+ const [hoveredId, setHoveredId] = (0, import_react30.useState)(null);
22257
22267
  (0, import_react30.useEffect)(() => {
22268
+ if (state)
22269
+ setHoveredId(null);
22270
+ }, [state]);
22271
+ (0, import_react30.useEffect)(() => {
22272
+ if (!state)
22273
+ return;
22274
+ function onDown(e) {
22275
+ const root2 = rootRef.current;
22276
+ if (!root2)
22277
+ return;
22278
+ if (root2.contains(e.target))
22279
+ return;
22280
+ onClose();
22281
+ }
22282
+ function onKey(e) {
22283
+ if (e.key === "Escape") {
22284
+ e.stopPropagation();
22285
+ onClose();
22286
+ }
22287
+ }
22288
+ function onScroll() {
22289
+ onClose();
22290
+ }
22291
+ window.addEventListener("mousedown", onDown);
22292
+ window.addEventListener("keydown", onKey);
22293
+ window.addEventListener("scroll", onScroll, true);
22294
+ window.addEventListener("blur", onClose);
22295
+ return () => {
22296
+ window.removeEventListener("mousedown", onDown);
22297
+ window.removeEventListener("keydown", onKey);
22298
+ window.removeEventListener("scroll", onScroll, true);
22299
+ window.removeEventListener("blur", onClose);
22300
+ };
22301
+ }, [state, onClose]);
22302
+ if (!state)
22303
+ return null;
22304
+ const cm = theme.contextMenu;
22305
+ if (!cm)
22306
+ return null;
22307
+ const vw = typeof window !== "undefined" ? window.innerWidth : 0;
22308
+ const vh = typeof window !== "undefined" ? window.innerHeight : 0;
22309
+ const sepCount = state.items.filter((i) => i.id === "__sep__").length;
22310
+ const rowCount = state.items.length - sepCount;
22311
+ const itemHeight = cm.itemPaddingY * 2 + cm.fontSize + 4;
22312
+ const estimatedHeight = rowCount * itemHeight + sepCount * 9 + cm.paddingY * 2;
22313
+ const left = vw ? Math.min(state.screenPosition.x, vw - ESTIMATED_MENU_WIDTH3 - VIEWPORT_MARGIN3) : state.screenPosition.x;
22314
+ const top = vh ? Math.min(state.screenPosition.y, vh - estimatedHeight - VIEWPORT_MARGIN3) : state.screenPosition.y;
22315
+ const anyIcon = state.items.some((item) => item.id !== "__sep__" && !!item.icon);
22316
+ return (0, import_jsx_runtime31.jsx)("div", { ref: rootRef, role: "menu", onContextMenu: (e) => {
22317
+ e.preventDefault();
22318
+ e.stopPropagation();
22319
+ }, style: {
22320
+ position: "fixed",
22321
+ left,
22322
+ top,
22323
+ zIndex: 1e3,
22324
+ minWidth: MIN_MENU_WIDTH3,
22325
+ padding: `${cm.paddingY}px ${cm.paddingX}px`,
22326
+ background: cm.background,
22327
+ color: cm.itemColor,
22328
+ border: `1px solid ${cm.borderColor}`,
22329
+ borderRadius: cm.borderRadius,
22330
+ boxShadow: cm.shadow,
22331
+ fontFamily: cm.fontFamily,
22332
+ fontSize: cm.fontSize,
22333
+ backdropFilter: "blur(10px)",
22334
+ userSelect: "none",
22335
+ pointerEvents: "auto"
22336
+ }, children: state.items.map((item, idx) => {
22337
+ if (item.id === "__sep__") {
22338
+ return (0, import_jsx_runtime31.jsx)("hr", { style: {
22339
+ border: "none",
22340
+ borderTop: `1px solid ${theme.breadcrumbs?.separatorColor ?? cm.borderColor}`,
22341
+ margin: `4px 0`
22342
+ } }, `__sep__${idx}`);
22343
+ }
22344
+ const isHovered = hoveredId === item.id;
22345
+ const color2 = item.destructive ? cm.destructiveItemColor : cm.itemColor;
22346
+ return (0, import_jsx_runtime31.jsxs)("div", { role: "menuitem", onMouseEnter: () => setHoveredId(item.id), onMouseLeave: () => setHoveredId((id2) => id2 === item.id ? null : id2), onClick: () => {
22347
+ config.onSelect(item.id, {
22348
+ canvasRef: state.canvasRef,
22349
+ position: state.position,
22350
+ screenPosition: state.screenPosition
22351
+ });
22352
+ onClose();
22353
+ }, style: {
22354
+ display: "flex",
22355
+ alignItems: "center",
22356
+ gap: 10,
22357
+ padding: `${cm.itemPaddingY}px ${cm.itemPaddingX}px`,
22358
+ borderRadius: Math.max(0, cm.borderRadius - 4),
22359
+ cursor: "pointer",
22360
+ background: isHovered ? cm.itemHoverBackground : "transparent",
22361
+ color: color2
22362
+ }, children: [item.icon ? (0, import_jsx_runtime31.jsx)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", style: { flexShrink: 0, overflow: "visible" }, children: (0, import_jsx_runtime31.jsx)(NodeIcon, { icon: item.icon, x: 0, y: 0, size: 14, color: color2, opacity: 1, customIcons: theme.icons }) }) : anyIcon ? (0, import_jsx_runtime31.jsx)("span", { style: { width: 14, flexShrink: 0 }, "aria-hidden": true }) : null, (0, import_jsx_runtime31.jsx)("span", { children: item.label })] }, item.id);
22363
+ }) });
22364
+ }
22365
+
22366
+ // ../react/dist/components/SearchOverlay.js
22367
+ var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
22368
+ var import_react31 = __toESM(require_react(), 1);
22369
+ function SearchOverlay({ open, query, onQueryChange, theme, hiddenCategories, onToggleCategory, matchCount, matchIndex, onNext, onPrev, onClose }) {
22370
+ const inputRef = (0, import_react31.useRef)(null);
22371
+ (0, import_react31.useEffect)(() => {
22258
22372
  if (open) {
22259
22373
  inputRef.current?.focus();
22260
22374
  }
@@ -22278,7 +22392,7 @@ var SystemCanvas = (() => {
22278
22392
  onPrev();
22279
22393
  }
22280
22394
  };
22281
- return (0, import_jsx_runtime31.jsxs)("div", { style: {
22395
+ return (0, import_jsx_runtime32.jsxs)("div", { style: {
22282
22396
  position: "absolute",
22283
22397
  top: 12,
22284
22398
  left: "50%",
@@ -22289,7 +22403,7 @@ var SystemCanvas = (() => {
22289
22403
  alignItems: "center",
22290
22404
  gap: 6,
22291
22405
  pointerEvents: "none"
22292
- }, children: [(0, import_jsx_runtime31.jsxs)("div", { style: {
22406
+ }, children: [(0, import_jsx_runtime32.jsxs)("div", { style: {
22293
22407
  display: "flex",
22294
22408
  alignItems: "center",
22295
22409
  gap: 8,
@@ -22300,7 +22414,7 @@ var SystemCanvas = (() => {
22300
22414
  boxShadow: "0 2px 12px rgba(0,0,0,0.25)",
22301
22415
  pointerEvents: "all",
22302
22416
  minWidth: 220
22303
- }, children: [(0, import_jsx_runtime31.jsxs)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", fill: "none", stroke: textColor, strokeWidth: 1.5, style: { opacity: 0.6, flexShrink: 0 }, children: [(0, import_jsx_runtime31.jsx)("circle", { cx: 6.5, cy: 6.5, r: 5 }), (0, import_jsx_runtime31.jsx)("line", { x1: 10.5, y1: 10.5, x2: 14, y2: 14 })] }), (0, import_jsx_runtime31.jsx)("input", { ref: inputRef, value: query, onChange: (e) => onQueryChange(e.target.value), onKeyDown: handleKeyDown, placeholder: "Search nodes\\u2026", style: {
22417
+ }, children: [(0, import_jsx_runtime32.jsxs)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", fill: "none", stroke: textColor, strokeWidth: 1.5, style: { opacity: 0.6, flexShrink: 0 }, children: [(0, import_jsx_runtime32.jsx)("circle", { cx: 6.5, cy: 6.5, r: 5 }), (0, import_jsx_runtime32.jsx)("line", { x1: 10.5, y1: 10.5, x2: 14, y2: 14 })] }), (0, import_jsx_runtime32.jsx)("input", { ref: inputRef, value: query, onChange: (e) => onQueryChange(e.target.value), onKeyDown: handleKeyDown, placeholder: "Search nodes\\u2026", style: {
22304
22418
  background: "transparent",
22305
22419
  border: "none",
22306
22420
  outline: "none",
@@ -22309,7 +22423,7 @@ var SystemCanvas = (() => {
22309
22423
  fontSize: 13,
22310
22424
  width: 160,
22311
22425
  caretColor: textColor
22312
- } }), query.length > 0 && matchCount > 0 && (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [(0, import_jsx_runtime31.jsx)("button", { onClick: onPrev, style: {
22426
+ } }), query.length > 0 && matchCount > 0 && (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [(0, import_jsx_runtime32.jsx)("button", { onClick: onPrev, style: {
22313
22427
  background: "transparent",
22314
22428
  border: "none",
22315
22429
  cursor: "pointer",
@@ -22319,14 +22433,14 @@ var SystemCanvas = (() => {
22319
22433
  color: textColor,
22320
22434
  opacity: 0.7,
22321
22435
  flexShrink: 0
22322
- }, title: "Previous match (\u2191)", children: (0, import_jsx_runtime31.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: (0, import_jsx_runtime31.jsx)("polyline", { points: "2,7 5,3 8,7" }) }) }), (0, import_jsx_runtime31.jsxs)("span", { style: {
22436
+ }, title: "Previous match (\u2191)", children: (0, import_jsx_runtime32.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: (0, import_jsx_runtime32.jsx)("polyline", { points: "2,7 5,3 8,7" }) }) }), (0, import_jsx_runtime32.jsxs)("span", { style: {
22323
22437
  fontSize: 11,
22324
22438
  fontFamily,
22325
22439
  color: textColor,
22326
22440
  opacity: 0.7,
22327
22441
  whiteSpace: "nowrap",
22328
22442
  flexShrink: 0
22329
- }, children: [matchIndex + 1, "/", matchCount] }), (0, import_jsx_runtime31.jsx)("button", { onClick: onNext, style: {
22443
+ }, children: [matchIndex + 1, "/", matchCount] }), (0, import_jsx_runtime32.jsx)("button", { onClick: onNext, style: {
22330
22444
  background: "transparent",
22331
22445
  border: "none",
22332
22446
  cursor: "pointer",
@@ -22336,14 +22450,14 @@ var SystemCanvas = (() => {
22336
22450
  color: textColor,
22337
22451
  opacity: 0.7,
22338
22452
  flexShrink: 0
22339
- }, title: "Next match (\u2193)", children: (0, import_jsx_runtime31.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: (0, import_jsx_runtime31.jsx)("polyline", { points: "2,3 5,7 8,3" }) }) })] }), query.length > 0 && matchCount === 0 && (0, import_jsx_runtime31.jsx)("span", { style: {
22453
+ }, title: "Next match (\u2193)", children: (0, import_jsx_runtime32.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: (0, import_jsx_runtime32.jsx)("polyline", { points: "2,3 5,7 8,3" }) }) })] }), query.length > 0 && matchCount === 0 && (0, import_jsx_runtime32.jsx)("span", { style: {
22340
22454
  fontSize: 11,
22341
22455
  fontFamily,
22342
22456
  color: textColor,
22343
22457
  opacity: 0.5,
22344
22458
  whiteSpace: "nowrap",
22345
22459
  flexShrink: 0
22346
- }, children: "No matches" }), (0, import_jsx_runtime31.jsx)("button", { onClick: onClose, style: {
22460
+ }, children: "No matches" }), (0, import_jsx_runtime32.jsx)("button", { onClick: onClose, style: {
22347
22461
  background: "transparent",
22348
22462
  border: "none",
22349
22463
  cursor: "pointer",
@@ -22353,7 +22467,7 @@ var SystemCanvas = (() => {
22353
22467
  color: textColor,
22354
22468
  opacity: 0.6,
22355
22469
  flexShrink: 0
22356
- }, title: "Close search (Esc)", children: (0, import_jsx_runtime31.jsxs)("svg", { width: 12, height: 12, viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: [(0, import_jsx_runtime31.jsx)("line", { x1: 1, y1: 1, x2: 11, y2: 11 }), (0, import_jsx_runtime31.jsx)("line", { x1: 11, y1: 1, x2: 1, y2: 11 })] }) })] }), hasCats && (0, import_jsx_runtime31.jsx)("div", { style: {
22470
+ }, title: "Close search (Esc)", children: (0, import_jsx_runtime32.jsxs)("svg", { width: 12, height: 12, viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: [(0, import_jsx_runtime32.jsx)("line", { x1: 1, y1: 1, x2: 11, y2: 11 }), (0, import_jsx_runtime32.jsx)("line", { x1: 11, y1: 1, x2: 1, y2: 11 })] }) })] }), hasCats && (0, import_jsx_runtime32.jsx)("div", { style: {
22357
22471
  display: "flex",
22358
22472
  gap: 6,
22359
22473
  flexWrap: "wrap",
@@ -22362,7 +22476,7 @@ var SystemCanvas = (() => {
22362
22476
  }, children: Object.entries(categories).map(([key, def]) => {
22363
22477
  const isHidden = hiddenCategories.has(key);
22364
22478
  const accentColor = def.fill ?? def.stroke ?? textColor;
22365
- return (0, import_jsx_runtime31.jsx)("button", { onClick: () => onToggleCategory(key), style: {
22479
+ return (0, import_jsx_runtime32.jsx)("button", { onClick: () => onToggleCategory(key), style: {
22366
22480
  padding: "3px 10px",
22367
22481
  borderRadius: 12,
22368
22482
  border: `1.5px solid ${accentColor}`,
@@ -22380,8 +22494,8 @@ var SystemCanvas = (() => {
22380
22494
  }
22381
22495
 
22382
22496
  // ../react/dist/components/CollaboratorsOverlay.js
22383
- var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
22384
- var import_react31 = __toESM(require_react(), 1);
22497
+ var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
22498
+ var import_react32 = __toESM(require_react(), 1);
22385
22499
  var CLIP_GUARD_MARGIN = 100;
22386
22500
  var STYLE_ID = "system-canvas-collab-keyframes";
22387
22501
  function ensureKeyframes() {
@@ -22404,7 +22518,7 @@ var SystemCanvas = (() => {
22404
22518
  document.head.appendChild(style);
22405
22519
  }
22406
22520
  function CollaboratorsOverlay({ collaborators, viewport, nodeMap, flashNodeIds, containerWidth = Infinity, containerHeight = Infinity }) {
22407
- const keyframesInjected = (0, import_react31.useRef)(false);
22521
+ const keyframesInjected = (0, import_react32.useRef)(false);
22408
22522
  if (!keyframesInjected.current) {
22409
22523
  ensureKeyframes();
22410
22524
  keyframesInjected.current = true;
@@ -22419,7 +22533,7 @@ var SystemCanvas = (() => {
22419
22533
  halosByNode.set(collab.selectedNodeId, arr);
22420
22534
  }
22421
22535
  }
22422
- return (0, import_jsx_runtime32.jsxs)("div", { style: {
22536
+ return (0, import_jsx_runtime33.jsxs)("div", { style: {
22423
22537
  position: "absolute",
22424
22538
  inset: 0,
22425
22539
  pointerEvents: "none",
@@ -22432,7 +22546,7 @@ var SystemCanvas = (() => {
22432
22546
  const screenRect = canvasRectToScreenRect({ x: node.x, y: node.y, width: node.width, height: node.height }, viewport);
22433
22547
  return collabList.map((collab, idx) => {
22434
22548
  const outset = 3 + idx * 2;
22435
- return (0, import_jsx_runtime32.jsxs)("div", { children: [(0, import_jsx_runtime32.jsx)("div", { style: {
22549
+ return (0, import_jsx_runtime33.jsxs)("div", { children: [(0, import_jsx_runtime33.jsx)("div", { style: {
22436
22550
  position: "absolute",
22437
22551
  left: screenRect.x - outset,
22438
22552
  top: screenRect.y - outset,
@@ -22442,7 +22556,7 @@ var SystemCanvas = (() => {
22442
22556
  borderRadius: 6 + outset,
22443
22557
  opacity: 0.55,
22444
22558
  boxSizing: "border-box"
22445
- } }), (0, import_jsx_runtime32.jsx)("div", { style: {
22559
+ } }), (0, import_jsx_runtime33.jsx)("div", { style: {
22446
22560
  position: "absolute",
22447
22561
  left: screenRect.x - outset,
22448
22562
  top: screenRect.y - outset - 18,
@@ -22464,13 +22578,13 @@ var SystemCanvas = (() => {
22464
22578
  if (screen.x < -CLIP_GUARD_MARGIN || screen.x > containerWidth + CLIP_GUARD_MARGIN || screen.y < -CLIP_GUARD_MARGIN || screen.y > containerHeight + CLIP_GUARD_MARGIN) {
22465
22579
  return null;
22466
22580
  }
22467
- return (0, import_jsx_runtime32.jsxs)("div", { style: {
22581
+ return (0, import_jsx_runtime33.jsxs)("div", { style: {
22468
22582
  position: "absolute",
22469
22583
  left: screen.x,
22470
22584
  top: screen.y,
22471
22585
  transform: "translate(0, 0)",
22472
22586
  userSelect: "none"
22473
- }, children: [(0, import_jsx_runtime32.jsx)("svg", { width: "16", height: "20", viewBox: "0 0 16 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: (0, import_jsx_runtime32.jsx)("path", { d: "M1 1L1 15L5 11L8 18L10 17L7 10L13 10L1 1Z", fill: collab.color, stroke: "#fff", strokeWidth: "1.5", strokeLinejoin: "round" }) }), (0, import_jsx_runtime32.jsxs)("div", { style: {
22587
+ }, children: [(0, import_jsx_runtime33.jsx)("svg", { width: "16", height: "20", viewBox: "0 0 16 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: (0, import_jsx_runtime33.jsx)("path", { d: "M1 1L1 15L5 11L8 18L10 17L7 10L13 10L1 1Z", fill: collab.color, stroke: "#fff", strokeWidth: "1.5", strokeLinejoin: "round" }) }), (0, import_jsx_runtime33.jsxs)("div", { style: {
22474
22588
  position: "absolute",
22475
22589
  top: 18,
22476
22590
  left: 8,
@@ -22483,7 +22597,7 @@ var SystemCanvas = (() => {
22483
22597
  boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
22484
22598
  whiteSpace: "nowrap",
22485
22599
  fontFamily: "sans-serif"
22486
- }, children: [(0, import_jsx_runtime32.jsx)("div", { style: {
22600
+ }, children: [(0, import_jsx_runtime33.jsx)("div", { style: {
22487
22601
  width: 16,
22488
22602
  height: 16,
22489
22603
  borderRadius: "50%",
@@ -22493,7 +22607,7 @@ var SystemCanvas = (() => {
22493
22607
  alignItems: "center",
22494
22608
  justifyContent: "center",
22495
22609
  background: collab.image ? "transparent" : collab.color
22496
- }, children: collab.image ? (0, import_jsx_runtime32.jsx)("img", { src: collab.image, width: 16, height: 16, style: { objectFit: "cover", borderRadius: "50%" } }) : (0, import_jsx_runtime32.jsx)("div", { style: {
22610
+ }, children: collab.image ? (0, import_jsx_runtime33.jsx)("img", { src: collab.image, width: 16, height: 16, style: { objectFit: "cover", borderRadius: "50%" } }) : (0, import_jsx_runtime33.jsx)("div", { style: {
22497
22611
  width: 16,
22498
22612
  height: 16,
22499
22613
  display: "flex",
@@ -22503,7 +22617,7 @@ var SystemCanvas = (() => {
22503
22617
  color: "#fff",
22504
22618
  fontSize: 9,
22505
22619
  fontWeight: 700
22506
- }, children: collab.name ? collab.name[0].toUpperCase() : "?" }) }), (0, import_jsx_runtime32.jsx)("span", { style: {
22620
+ }, children: collab.name ? collab.name[0].toUpperCase() : "?" }) }), (0, import_jsx_runtime33.jsx)("span", { style: {
22507
22621
  fontSize: 11,
22508
22622
  lineHeight: "16px",
22509
22623
  color: "#fff",
@@ -22514,7 +22628,7 @@ var SystemCanvas = (() => {
22514
22628
  if (!node)
22515
22629
  return null;
22516
22630
  const screenRect = canvasRectToScreenRect({ x: node.x, y: node.y, width: node.width, height: node.height }, viewport);
22517
- return (0, import_jsx_runtime32.jsx)("div", { style: {
22631
+ return (0, import_jsx_runtime33.jsx)("div", { style: {
22518
22632
  position: "absolute",
22519
22633
  left: screenRect.x,
22520
22634
  top: screenRect.y,
@@ -22528,12 +22642,12 @@ var SystemCanvas = (() => {
22528
22642
  }
22529
22643
 
22530
22644
  // ../react/dist/components/ExportButton.js
22531
- var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
22532
- var import_react32 = __toESM(require_react(), 1);
22645
+ var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
22646
+ var import_react33 = __toESM(require_react(), 1);
22533
22647
  function ExportButton({ onExportJSON, onExportPNG, onExportSVG, theme }) {
22534
- const [open, setOpen] = (0, import_react32.useState)(false);
22535
- const rootRef = (0, import_react32.useRef)(null);
22536
- (0, import_react32.useEffect)(() => {
22648
+ const [open, setOpen] = (0, import_react33.useState)(false);
22649
+ const rootRef = (0, import_react33.useRef)(null);
22650
+ (0, import_react33.useEffect)(() => {
22537
22651
  if (!open)
22538
22652
  return;
22539
22653
  function onDocClick(e) {
@@ -22580,12 +22694,12 @@ var SystemCanvas = (() => {
22580
22694
  }
22581
22695
  });
22582
22696
  }
22583
- return (0, import_jsx_runtime33.jsxs)("div", { ref: rootRef, className: "system-canvas-export-button", style: {
22697
+ return (0, import_jsx_runtime34.jsxs)("div", { ref: rootRef, className: "system-canvas-export-button", style: {
22584
22698
  position: "relative",
22585
22699
  fontFamily: theme.breadcrumbs.fontFamily,
22586
22700
  fontSize: theme.breadcrumbs.fontSize,
22587
22701
  userSelect: "none"
22588
- }, children: [open && (0, import_jsx_runtime33.jsx)("div", { style: {
22702
+ }, children: [open && (0, import_jsx_runtime34.jsx)("div", { style: {
22589
22703
  position: "absolute",
22590
22704
  bottom: 52,
22591
22705
  right: 0,
@@ -22596,7 +22710,7 @@ var SystemCanvas = (() => {
22596
22710
  borderRadius: 10,
22597
22711
  boxShadow: "0 8px 24px rgba(0,0,0,0.35)",
22598
22712
  backdropFilter: "blur(10px)"
22599
- }, children: rows.map((row) => (0, import_jsx_runtime33.jsx)("button", { type: "button", onClick: () => void row.onClick(), style: {
22713
+ }, children: rows.map((row) => (0, import_jsx_runtime34.jsx)("button", { type: "button", onClick: () => void row.onClick(), style: {
22600
22714
  display: "block",
22601
22715
  width: "100%",
22602
22716
  textAlign: "left",
@@ -22614,7 +22728,7 @@ var SystemCanvas = (() => {
22614
22728
  }, onMouseLeave: (e) => {
22615
22729
  ;
22616
22730
  e.currentTarget.style.background = "transparent";
22617
- }, children: row.label }, row.label)) }), (0, import_jsx_runtime33.jsx)("button", { type: "button", "aria-label": open ? "Close export menu" : "Export canvas", onClick: () => setOpen((v) => !v), style: {
22731
+ }, children: row.label }, row.label)) }), (0, import_jsx_runtime34.jsx)("button", { type: "button", "aria-label": open ? "Close export menu" : "Export canvas", onClick: () => setOpen((v) => !v), style: {
22618
22732
  width: 44,
22619
22733
  height: 44,
22620
22734
  borderRadius: 22,
@@ -22629,7 +22743,7 @@ var SystemCanvas = (() => {
22629
22743
  alignItems: "center",
22630
22744
  justifyContent: "center",
22631
22745
  backdropFilter: "blur(10px)"
22632
- }, children: (0, import_jsx_runtime33.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, import_jsx_runtime33.jsx)("line", { x1: "10", y1: "15", x2: "10", y2: "5" }), (0, import_jsx_runtime33.jsx)("polyline", { points: "5,10 10,5 15,10" })] }) })] });
22746
+ }, children: (0, import_jsx_runtime34.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, import_jsx_runtime34.jsx)("line", { x1: "10", y1: "15", x2: "10", y2: "5" }), (0, import_jsx_runtime34.jsx)("polyline", { points: "5,10 10,5 15,10" })] }) })] });
22633
22747
  }
22634
22748
 
22635
22749
  // ../react/dist/export/utils.js
@@ -22801,8 +22915,8 @@ var SystemCanvas = (() => {
22801
22915
  // ../react/dist/components/SystemCanvas.js
22802
22916
  var CASCADE_WINDOW_MS = 1500;
22803
22917
  var CASCADE_OFFSET = 20;
22804
- var SystemCanvas = (0, import_react33.forwardRef)(function SystemCanvas2({ canvas, onResolveCanvas, canvases, rootLabel = "Home", onNavigate, externalNavigation = false, onBreadcrumbClick, onBreadcrumbsChange, onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onSelectionChange, nodeContextMenu, edgeContextMenu, editable = false, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeUpdate, onEdgeDelete, onEdgeAdd, canDropNodeOn, onNodeDrop, renderAddNodeButton, showExportButton = false, renderExportButton, onImport, showNodeToolbar = true, renderNodeToolbar, theme: themeProp, themes: customThemes, edgeStyle = "bezier", defaultViewport, minZoom: minZoomProp, maxZoom, onViewportChange, panMode = "drag", autoFit = "canvas-change", laneHeaders = "pinned", snapToLanes = false, zoomNavigation = false, snapGrid, guideThreshold, alignDistributeMenu, historyDepth, onUndo, onRedo, collaborators = [], className, style }, forwardedRef) {
22805
- const zoomNavConfig = (0, import_react33.useMemo)(() => {
22918
+ var SystemCanvas = (0, import_react34.forwardRef)(function SystemCanvas2({ canvas, onResolveCanvas, canvases, rootLabel = "Home", onNavigate, externalNavigation = false, onBreadcrumbClick, onBreadcrumbsChange, onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onSelectionChange, nodeContextMenu, edgeContextMenu, canvasContextMenu, editable = false, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeUpdate, onEdgeDelete, onEdgeAdd, canDropNodeOn, onNodeDrop, renderAddNodeButton, showExportButton = false, renderExportButton, onImport, showNodeToolbar = true, renderNodeToolbar, theme: themeProp, themes: customThemes, edgeStyle = "bezier", defaultViewport, minZoom: minZoomProp, maxZoom, onViewportChange, panMode = "drag", autoFit = "canvas-change", laneHeaders = "pinned", snapToLanes = false, zoomNavigation = false, snapGrid, guideThreshold, alignDistributeMenu, historyDepth, onUndo, onRedo, collaborators = [], className, style }, forwardedRef) {
22919
+ const zoomNavConfig = (0, import_react34.useMemo)(() => {
22806
22920
  const defaults = {
22807
22921
  enterThreshold: 0.66,
22808
22922
  exitThreshold: 0.33,
@@ -22827,16 +22941,16 @@ var SystemCanvas = (() => {
22827
22941
  }, [zoomNavigation]);
22828
22942
  const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
22829
22943
  const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
22830
- (0, import_react33.useEffect)(() => {
22944
+ (0, import_react34.useEffect)(() => {
22831
22945
  const env = globalThis.process?.env?.NODE_ENV;
22832
22946
  if (editable && !canvases && env !== "production") {
22833
22947
  console.warn("[system-canvas] `editable` is enabled but `canvases` prop is missing. Edits to sub-canvases will not be reflected without a synchronous ref \u2192 CanvasData map.");
22834
22948
  }
22835
22949
  }, [editable, canvases]);
22836
- const [parentFrames, setParentFrames] = (0, import_react33.useState)([]);
22837
- const [pendingHandoff, setPendingHandoff] = (0, import_react33.useState)(null);
22838
- const suppressNextHandoffClearRef = (0, import_react33.useRef)(false);
22839
- const handleBreadcrumbClick = (0, import_react33.useCallback)((index) => {
22950
+ const [parentFrames, setParentFrames] = (0, import_react34.useState)([]);
22951
+ const [pendingHandoff, setPendingHandoff] = (0, import_react34.useState)(null);
22952
+ const suppressNextHandoffClearRef = (0, import_react34.useRef)(false);
22953
+ const handleBreadcrumbClick = (0, import_react34.useCallback)((index) => {
22840
22954
  setParentFrames((prev) => prev.slice(0, index));
22841
22955
  if (suppressNextHandoffClearRef.current) {
22842
22956
  suppressNextHandoffClearRef.current = false;
@@ -22853,10 +22967,10 @@ var SystemCanvas = (() => {
22853
22967
  onNavigate,
22854
22968
  onBreadcrumbClick: handleBreadcrumbClick
22855
22969
  });
22856
- (0, import_react33.useEffect)(() => {
22970
+ (0, import_react34.useEffect)(() => {
22857
22971
  onBreadcrumbsChange?.(breadcrumbs);
22858
22972
  }, [breadcrumbs, onBreadcrumbsChange]);
22859
- const theme = (0, import_react33.useMemo)(() => {
22973
+ const theme = (0, import_react34.useMemo)(() => {
22860
22974
  const registry = { ...themes, ...customThemes };
22861
22975
  const resolveByName = (name) => name && registry[name] ? registry[name] : null;
22862
22976
  if (themeProp) {
@@ -22868,24 +22982,24 @@ var SystemCanvas = (() => {
22868
22982
  return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
22869
22983
  }, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
22870
22984
  const snapGridSize = snapGrid === true ? theme.grid.size : typeof snapGrid === "number" ? snapGrid : 0;
22871
- const { nodes, edges, nodeMap } = (0, import_react33.useMemo)(() => {
22985
+ const { nodes, edges, nodeMap } = (0, import_react34.useMemo)(() => {
22872
22986
  const resolved = resolveCanvas(currentCanvas, theme);
22873
22987
  const map = buildNodeMap(resolved.nodes);
22874
22988
  return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
22875
22989
  }, [currentCanvas, theme]);
22876
- const nodesRef = (0, import_react33.useRef)(nodes);
22990
+ const nodesRef = (0, import_react34.useRef)(nodes);
22877
22991
  nodesRef.current = nodes;
22878
- const viewportStateRef = (0, import_react33.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
22879
- const viewportHandleRef = (0, import_react33.useRef)(null);
22880
- const [collaboratorViewport, setCollaboratorViewport] = (0, import_react33.useState)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
22881
- const [flashNodeIds, setFlashNodeIds] = (0, import_react33.useState)(/* @__PURE__ */ new Map());
22882
- const navigateToRefRef = (0, import_react33.useRef)(navigateToRef);
22992
+ const viewportStateRef = (0, import_react34.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
22993
+ const viewportHandleRef = (0, import_react34.useRef)(null);
22994
+ const [collaboratorViewport, setCollaboratorViewport] = (0, import_react34.useState)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
22995
+ const [flashNodeIds, setFlashNodeIds] = (0, import_react34.useState)(/* @__PURE__ */ new Map());
22996
+ const navigateToRefRef = (0, import_react34.useRef)(navigateToRef);
22883
22997
  navigateToRefRef.current = navigateToRef;
22884
- const navigateToBreadcrumbRef = (0, import_react33.useRef)(navigateToBreadcrumb);
22998
+ const navigateToBreadcrumbRef = (0, import_react34.useRef)(navigateToBreadcrumb);
22885
22999
  navigateToBreadcrumbRef.current = navigateToBreadcrumb;
22886
- const breadcrumbsRef = (0, import_react33.useRef)(breadcrumbs);
23000
+ const breadcrumbsRef = (0, import_react34.useRef)(breadcrumbs);
22887
23001
  breadcrumbsRef.current = breadcrumbs;
22888
- (0, import_react33.useImperativeHandle)(forwardedRef, () => ({
23002
+ (0, import_react34.useImperativeHandle)(forwardedRef, () => ({
22889
23003
  zoomIntoNode: (nodeId, options) => {
22890
23004
  return new Promise((resolve) => {
22891
23005
  const node = nodesRef.current.find((n) => n.id === nodeId);
@@ -22919,16 +23033,16 @@ var SystemCanvas = (() => {
22919
23033
  getViewport: () => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 },
22920
23034
  getSvgElement: () => viewportHandleRef.current?.getSvgElement() ?? null
22921
23035
  }), [forwardedRef]);
22922
- const [editingId, setEditingId] = (0, import_react33.useState)(null);
22923
- const [selectedEdgeId, setSelectedEdgeId] = (0, import_react33.useState)(null);
22924
- const [editingEdgeId, setEditingEdgeId] = (0, import_react33.useState)(null);
22925
- const [searchOpen, setSearchOpen] = (0, import_react33.useState)(false);
22926
- const [searchQuery, setSearchQuery] = (0, import_react33.useState)("");
22927
- const [hiddenCategories, setHiddenCategories] = (0, import_react33.useState)(/* @__PURE__ */ new Set());
22928
- const [searchIndex, setSearchIndex] = (0, import_react33.useState)(0);
22929
- const [importError, setImportError] = (0, import_react33.useState)(null);
22930
- const svgProxyRef = (0, import_react33.useRef)(null);
22931
- const containerRef = (0, import_react33.useRef)(null);
23036
+ const [editingId, setEditingId] = (0, import_react34.useState)(null);
23037
+ const [selectedEdgeId, setSelectedEdgeId] = (0, import_react34.useState)(null);
23038
+ const [editingEdgeId, setEditingEdgeId] = (0, import_react34.useState)(null);
23039
+ const [searchOpen, setSearchOpen] = (0, import_react34.useState)(false);
23040
+ const [searchQuery, setSearchQuery] = (0, import_react34.useState)("");
23041
+ const [hiddenCategories, setHiddenCategories] = (0, import_react34.useState)(/* @__PURE__ */ new Set());
23042
+ const [searchIndex, setSearchIndex] = (0, import_react34.useState)(0);
23043
+ const [importError, setImportError] = (0, import_react34.useState)(null);
23044
+ const svgProxyRef = (0, import_react34.useRef)(null);
23045
+ const containerRef = (0, import_react34.useRef)(null);
22932
23046
  const { selectedIds, selectNode, toggleNode, selectAll, clearSelection, selectMultiple, marqueeRect, marqueeActiveRef } = useMultiSelect({
22933
23047
  svgRef: svgProxyRef,
22934
23048
  viewport: viewportStateRef,
@@ -22936,12 +23050,12 @@ var SystemCanvas = (() => {
22936
23050
  containerRef,
22937
23051
  enabled: editable
22938
23052
  });
22939
- const selectedIdsRef = (0, import_react33.useRef)(selectedIds);
22940
- (0, import_react33.useEffect)(() => {
23053
+ const selectedIdsRef = (0, import_react34.useRef)(selectedIds);
23054
+ (0, import_react34.useEffect)(() => {
22941
23055
  selectedIdsRef.current = selectedIds;
22942
23056
  }, [selectedIds]);
22943
- const edgesRef = (0, import_react33.useRef)(edges);
22944
- (0, import_react33.useEffect)(() => {
23057
+ const edgesRef = (0, import_react34.useRef)(edges);
23058
+ (0, import_react34.useEffect)(() => {
22945
23059
  edgesRef.current = edges;
22946
23060
  }, [edges]);
22947
23061
  const { wrappedOnNodeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeAdd, wrappedOnEdgeUpdate, wrappedOnEdgeDelete, beginBatch, endBatch, undo, redo } = useCommandHistory({
@@ -22973,7 +23087,7 @@ var SystemCanvas = (() => {
22973
23087
  onBeginBatch: beginBatch,
22974
23088
  onEndBatch: endBatch
22975
23089
  });
22976
- (0, import_react33.useEffect)(() => {
23090
+ (0, import_react34.useEffect)(() => {
22977
23091
  clearSelection();
22978
23092
  setEditingId(null);
22979
23093
  setSelectedEdgeId(null);
@@ -22982,7 +23096,7 @@ var SystemCanvas = (() => {
22982
23096
  setSearchQuery("");
22983
23097
  setHiddenCategories(/* @__PURE__ */ new Set());
22984
23098
  }, [currentCanvasRef]);
22985
- (0, import_react33.useEffect)(() => {
23099
+ (0, import_react34.useEffect)(() => {
22986
23100
  const onKey = (e) => {
22987
23101
  if ((e.metaKey || e.ctrlKey) && e.key === "f") {
22988
23102
  e.preventDefault();
@@ -22992,7 +23106,7 @@ var SystemCanvas = (() => {
22992
23106
  window.addEventListener("keydown", onKey);
22993
23107
  return () => window.removeEventListener("keydown", onKey);
22994
23108
  }, []);
22995
- (0, import_react33.useEffect)(() => {
23109
+ (0, import_react34.useEffect)(() => {
22996
23110
  const onKey = async (e) => {
22997
23111
  if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === "c") {
22998
23112
  e.preventDefault();
@@ -23006,12 +23120,12 @@ var SystemCanvas = (() => {
23006
23120
  window.addEventListener("keydown", onKey);
23007
23121
  return () => window.removeEventListener("keydown", onKey);
23008
23122
  }, [selectedIds, nodes]);
23009
- const onSelectionChangeRef = (0, import_react33.useRef)(onSelectionChange);
23010
- (0, import_react33.useEffect)(() => {
23123
+ const onSelectionChangeRef = (0, import_react34.useRef)(onSelectionChange);
23124
+ (0, import_react34.useEffect)(() => {
23011
23125
  onSelectionChangeRef.current = onSelectionChange;
23012
23126
  }, [onSelectionChange]);
23013
- const lastEmittedSelectionRef = (0, import_react33.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
23014
- (0, import_react33.useEffect)(() => {
23127
+ const lastEmittedSelectionRef = (0, import_react34.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
23128
+ (0, import_react34.useEffect)(() => {
23015
23129
  const cb = onSelectionChangeRef.current;
23016
23130
  let next = null;
23017
23131
  if (selectedIds.size > 1) {
@@ -23053,8 +23167,8 @@ var SystemCanvas = (() => {
23053
23167
  }
23054
23168
  cb?.(next);
23055
23169
  }, [selectedIds, selectedEdgeId, currentCanvasRef, nodeMap, edges]);
23056
- const [containerSize, setContainerSize] = (0, import_react33.useState)({ width: 0, height: 0 });
23057
- (0, import_react33.useEffect)(() => {
23170
+ const [containerSize, setContainerSize] = (0, import_react34.useState)({ width: 0, height: 0 });
23171
+ (0, import_react34.useEffect)(() => {
23058
23172
  const el = containerRef.current;
23059
23173
  if (!el)
23060
23174
  return;
@@ -23069,14 +23183,14 @@ var SystemCanvas = (() => {
23069
23183
  }, []);
23070
23184
  const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
23071
23185
  const showLaneHeaders = hasLanes && laneHeaders !== "none";
23072
- const getViewportState = (0, import_react33.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
23073
- const { matchingIds, dimmedIds } = (0, import_react33.useMemo)(() => computeNodeFilter(nodes, searchOpen ? searchQuery : "", hiddenCategories), [nodes, searchQuery, searchOpen, hiddenCategories]);
23074
- const matchingIdsArray = (0, import_react33.useMemo)(() => Array.from(matchingIds), [matchingIds]);
23186
+ const getViewportState = (0, import_react34.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
23187
+ const { matchingIds, dimmedIds } = (0, import_react34.useMemo)(() => computeNodeFilter(nodes, searchOpen ? searchQuery : "", hiddenCategories), [nodes, searchQuery, searchOpen, hiddenCategories]);
23188
+ const matchingIdsArray = (0, import_react34.useMemo)(() => Array.from(matchingIds), [matchingIds]);
23075
23189
  const activeMatchId = matchingIdsArray[searchIndex];
23076
- (0, import_react33.useEffect)(() => {
23190
+ (0, import_react34.useEffect)(() => {
23077
23191
  setSearchIndex(0);
23078
23192
  }, [matchingIds]);
23079
- const panToMatch = (0, import_react33.useCallback)((index) => {
23193
+ const panToMatch = (0, import_react34.useCallback)((index) => {
23080
23194
  const id2 = matchingIdsArray[index];
23081
23195
  if (!id2)
23082
23196
  return;
@@ -23090,21 +23204,21 @@ var SystemCanvas = (() => {
23090
23204
  durationMs: 400
23091
23205
  });
23092
23206
  }, [matchingIdsArray]);
23093
- const goNextMatch = (0, import_react33.useCallback)(() => {
23207
+ const goNextMatch = (0, import_react34.useCallback)(() => {
23094
23208
  if (matchingIdsArray.length === 0)
23095
23209
  return;
23096
23210
  const next = (searchIndex + 1) % matchingIdsArray.length;
23097
23211
  setSearchIndex(next);
23098
23212
  panToMatch(next);
23099
23213
  }, [matchingIdsArray, searchIndex, panToMatch]);
23100
- const goPrevMatch = (0, import_react33.useCallback)(() => {
23214
+ const goPrevMatch = (0, import_react34.useCallback)(() => {
23101
23215
  if (matchingIdsArray.length === 0)
23102
23216
  return;
23103
23217
  const prev = (searchIndex - 1 + matchingIdsArray.length) % matchingIdsArray.length;
23104
23218
  setSearchIndex(prev);
23105
23219
  panToMatch(prev);
23106
23220
  }, [matchingIdsArray, searchIndex, panToMatch]);
23107
- const applyLaneSnap = (0, import_react33.useCallback)((id2, patch) => {
23221
+ const applyLaneSnap = (0, import_react34.useCallback)((id2, patch) => {
23108
23222
  if (!snapToLanes)
23109
23223
  return patch;
23110
23224
  const cols = currentCanvas.columns;
@@ -23129,10 +23243,10 @@ var SystemCanvas = (() => {
23129
23243
  }
23130
23244
  return final;
23131
23245
  }, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
23132
- const commitResize = (0, import_react33.useCallback)((id2, patch) => {
23246
+ const commitResize = (0, import_react34.useCallback)((id2, patch) => {
23133
23247
  wrappedOnNodeUpdate(id2, applyLaneSnap(id2, patch), currentCanvasRef);
23134
23248
  }, [wrappedOnNodeUpdate, currentCanvasRef, applyLaneSnap]);
23135
- const commitDragBatch = (0, import_react33.useCallback)((updates) => {
23249
+ const commitDragBatch = (0, import_react34.useCallback)((updates) => {
23136
23250
  const final = updates.map((u) => ({
23137
23251
  id: u.id,
23138
23252
  patch: applyLaneSnap(u.id, u.patch)
@@ -23147,7 +23261,7 @@ var SystemCanvas = (() => {
23147
23261
  wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
23148
23262
  }
23149
23263
  }, [wrappedOnNodeUpdate, wrappedOnNodesUpdate, onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
23150
- const handleNodeDrop = (0, import_react33.useCallback)((sources, target) => {
23264
+ const handleNodeDrop = (0, import_react34.useCallback)((sources, target) => {
23151
23265
  onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
23152
23266
  }, [onNodeDrop, currentCanvasRef]);
23153
23267
  const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown, cancelDrag, isDragging } = useNodeDrag({
@@ -23172,7 +23286,7 @@ var SystemCanvas = (() => {
23172
23286
  threshold: guideThreshold ?? 4
23173
23287
  });
23174
23288
  const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
23175
- const selectedResolvedNode = (0, import_react33.useMemo)(() => {
23289
+ const selectedResolvedNode = (0, import_react34.useMemo)(() => {
23176
23290
  if (!singleSelectedId)
23177
23291
  return null;
23178
23292
  const base = nodeMap.get(singleSelectedId);
@@ -23189,7 +23303,7 @@ var SystemCanvas = (() => {
23189
23303
  return base;
23190
23304
  }, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
23191
23305
  svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
23192
- const handleEdgeCreated = (0, import_react33.useCallback)((edge) => {
23306
+ const handleEdgeCreated = (0, import_react34.useCallback)((edge) => {
23193
23307
  wrappedOnEdgeAdd(edge, currentCanvasRef);
23194
23308
  }, [wrappedOnEdgeAdd, currentCanvasRef]);
23195
23309
  const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
@@ -23198,7 +23312,7 @@ var SystemCanvas = (() => {
23198
23312
  nodesRef,
23199
23313
  onCreate: handleEdgeCreated
23200
23314
  });
23201
- const handleNavigableNodeClick = (0, import_react33.useCallback)((node) => {
23315
+ const handleNavigableNodeClick = (0, import_react34.useCallback)((node) => {
23202
23316
  if (externalNavigation) {
23203
23317
  if (node.ref)
23204
23318
  onNavigate?.(node.ref);
@@ -23230,7 +23344,7 @@ var SystemCanvas = (() => {
23230
23344
  navigateToRef(node);
23231
23345
  }
23232
23346
  }, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled, externalNavigation, onNavigate]);
23233
- const handleZoomEnter = (0, import_react33.useCallback)((node, targetTransform) => {
23347
+ const handleZoomEnter = (0, import_react34.useCallback)((node, targetTransform) => {
23234
23348
  const frame2 = {
23235
23349
  parentCanvasRef: currentCanvasRef,
23236
23350
  parentNodeRect: {
@@ -23244,7 +23358,7 @@ var SystemCanvas = (() => {
23244
23358
  setPendingHandoff(targetTransform);
23245
23359
  navigateToRef(node);
23246
23360
  }, [currentCanvasRef, navigateToRef]);
23247
- const handleZoomExit = (0, import_react33.useCallback)((targetTransform) => {
23361
+ const handleZoomExit = (0, import_react34.useCallback)((targetTransform) => {
23248
23362
  setPendingHandoff(targetTransform);
23249
23363
  suppressNextHandoffClearRef.current = true;
23250
23364
  navigateToBreadcrumb(breadcrumbs.length - 2);
@@ -23271,41 +23385,43 @@ var SystemCanvas = (() => {
23271
23385
  onEnter: handleZoomEnter,
23272
23386
  onExit: handleZoomExit
23273
23387
  });
23274
- const handleViewportChange = (0, import_react33.useCallback)((vp) => {
23388
+ const handleViewportChange = (0, import_react34.useCallback)((vp) => {
23275
23389
  viewportStateRef.current = vp;
23276
23390
  setCollaboratorViewport(vp);
23277
23391
  handleZoomNavViewportChange(vp);
23278
23392
  onViewportChange?.(vp);
23279
23393
  }, [handleZoomNavViewportChange, onViewportChange]);
23280
- const handleHandoffApplied = (0, import_react33.useCallback)(() => {
23394
+ const handleHandoffApplied = (0, import_react34.useCallback)(() => {
23281
23395
  setPendingHandoff(null);
23282
23396
  clearZoomNavCommitting();
23283
23397
  }, [clearZoomNavCommitting]);
23284
- const handleBeginEdit = (0, import_react33.useCallback)((node) => {
23398
+ const handleBeginEdit = (0, import_react34.useCallback)((node) => {
23285
23399
  setEditingId(node.id);
23286
23400
  }, []);
23287
- const handleBeginEditEdge = (0, import_react33.useCallback)((edge) => {
23401
+ const handleBeginEditEdge = (0, import_react34.useCallback)((edge) => {
23288
23402
  setEditingEdgeId(edge.id);
23289
23403
  }, []);
23290
- const handleAlign = (0, import_react33.useCallback)((direction) => {
23404
+ const handleAlign = (0, import_react34.useCallback)((direction) => {
23291
23405
  const selectedNodes = Array.from(selectedIds).map((id2) => nodesRef.current.find((n) => n.id === id2)).filter((n) => n != null);
23292
23406
  const updates = alignNodes(selectedNodes, direction);
23293
23407
  if (updates.length > 0)
23294
23408
  wrappedOnNodesUpdate(updates, currentCanvasRef);
23295
23409
  }, [selectedIds, nodesRef, wrappedOnNodesUpdate, currentCanvasRef]);
23296
- const handleDistribute = (0, import_react33.useCallback)((axis) => {
23410
+ const handleDistribute = (0, import_react34.useCallback)((axis) => {
23297
23411
  const selectedNodes = Array.from(selectedIds).map((id2) => nodesRef.current.find((n) => n.id === id2)).filter((n) => n != null);
23298
23412
  const updates = distributeNodes(selectedNodes, axis);
23299
23413
  if (updates.length > 0)
23300
23414
  wrappedOnNodesUpdate(updates, currentCanvasRef);
23301
23415
  }, [selectedIds, nodesRef, wrappedOnNodesUpdate, currentCanvasRef]);
23302
- const [contextMenuState, setContextMenuState] = (0, import_react33.useState)(null);
23303
- const [edgeContextMenuState, setEdgeContextMenuState] = (0, import_react33.useState)(null);
23304
- (0, import_react33.useEffect)(() => {
23416
+ const [contextMenuState, setContextMenuState] = (0, import_react34.useState)(null);
23417
+ const [edgeContextMenuState, setEdgeContextMenuState] = (0, import_react34.useState)(null);
23418
+ const [canvasContextMenuState, setCanvasContextMenuState] = (0, import_react34.useState)(null);
23419
+ (0, import_react34.useEffect)(() => {
23305
23420
  setContextMenuState(null);
23306
23421
  setEdgeContextMenuState(null);
23422
+ setCanvasContextMenuState(null);
23307
23423
  }, [currentCanvasRef]);
23308
- const handleContextMenu = (0, import_react33.useCallback)((event) => {
23424
+ const handleContextMenu = (0, import_react34.useCallback)((event) => {
23309
23425
  onContextMenu?.(event);
23310
23426
  if (event.type === "node") {
23311
23427
  if (!nodeContextMenu && !alignDistributeMenu)
@@ -23363,9 +23479,16 @@ var SystemCanvas = (() => {
23363
23479
  screenPosition: event.screenPosition,
23364
23480
  canvasRef: currentCanvasRef ?? null
23365
23481
  });
23482
+ } else if (event.type === "canvas" && canvasContextMenu && canvasContextMenu.items.length > 0) {
23483
+ setCanvasContextMenuState({
23484
+ items: canvasContextMenu.items,
23485
+ screenPosition: event.screenPosition,
23486
+ position: event.position,
23487
+ canvasRef: currentCanvasRef ?? null
23488
+ });
23366
23489
  }
23367
- }, [onContextMenu, nodeContextMenu, edgeContextMenu, currentCanvasRef, alignDistributeMenu, selectedIds]);
23368
- const effectiveNodeContextMenu = (0, import_react33.useMemo)(() => {
23490
+ }, [onContextMenu, nodeContextMenu, edgeContextMenu, canvasContextMenu, currentCanvasRef, alignDistributeMenu, selectedIds]);
23491
+ const effectiveNodeContextMenu = (0, import_react34.useMemo)(() => {
23369
23492
  if (!nodeContextMenu && !alignDistributeMenu)
23370
23493
  return null;
23371
23494
  const baseItems = nodeContextMenu?.items ?? [];
@@ -23426,30 +23549,30 @@ var SystemCanvas = (() => {
23426
23549
  onSelectEdge: setSelectedEdgeId,
23427
23550
  onBeginEditEdge: handleBeginEditEdge
23428
23551
  });
23429
- const handleEditorCommit = (0, import_react33.useCallback)((patch) => {
23552
+ const handleEditorCommit = (0, import_react34.useCallback)((patch) => {
23430
23553
  if (editingId) {
23431
23554
  wrappedOnNodeUpdate(editingId, patch, currentCanvasRef);
23432
23555
  }
23433
23556
  setEditingId(null);
23434
23557
  }, [editingId, wrappedOnNodeUpdate, currentCanvasRef]);
23435
- const handleEditorCancel = (0, import_react33.useCallback)(() => {
23558
+ const handleEditorCancel = (0, import_react34.useCallback)(() => {
23436
23559
  setEditingId(null);
23437
23560
  }, []);
23438
- const handleEdgeEditorCommit = (0, import_react33.useCallback)((patch) => {
23561
+ const handleEdgeEditorCommit = (0, import_react34.useCallback)((patch) => {
23439
23562
  if (editingEdgeId) {
23440
23563
  wrappedOnEdgeUpdate(editingEdgeId, patch, currentCanvasRef);
23441
23564
  }
23442
23565
  setEditingEdgeId(null);
23443
23566
  }, [editingEdgeId, wrappedOnEdgeUpdate, currentCanvasRef]);
23444
- const handleEdgeEditorCancel = (0, import_react33.useCallback)(() => {
23567
+ const handleEdgeEditorCancel = (0, import_react34.useCallback)(() => {
23445
23568
  setEditingEdgeId(null);
23446
23569
  }, []);
23447
- const handleEdgeWaypointUpdate = (0, import_react33.useCallback)((edgeId, patch) => {
23570
+ const handleEdgeWaypointUpdate = (0, import_react34.useCallback)((edgeId, patch) => {
23448
23571
  wrappedOnEdgeUpdate(edgeId, patch, currentCanvasRef);
23449
23572
  }, [wrappedOnEdgeUpdate, currentCanvasRef]);
23450
- const lastAddRef = (0, import_react33.useRef)(null);
23451
- const menuOptions = (0, import_react33.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
23452
- const addNode2 = (0, import_react33.useCallback)((option, position) => {
23573
+ const lastAddRef = (0, import_react34.useRef)(null);
23574
+ const menuOptions = (0, import_react34.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
23575
+ const addNode2 = (0, import_react34.useCallback)((option, position) => {
23453
23576
  let x, y;
23454
23577
  if (position) {
23455
23578
  x = position.x;
@@ -23481,7 +23604,7 @@ var SystemCanvas = (() => {
23481
23604
  const node = createNodeFromOption(option, Math.round(x), Math.round(y), void 0, theme);
23482
23605
  wrappedOnNodeAdd(node, currentCanvasRef);
23483
23606
  }, [wrappedOnNodeAdd, currentCanvasRef, theme]);
23484
- const fitSelection = (0, import_react33.useCallback)(() => {
23607
+ const fitSelection = (0, import_react34.useCallback)(() => {
23485
23608
  const handle = viewportHandleRef.current;
23486
23609
  if (!handle)
23487
23610
  return;
@@ -23529,6 +23652,8 @@ var SystemCanvas = (() => {
23529
23652
  setEditingId,
23530
23653
  setEditingEdgeId,
23531
23654
  setSelectedEdgeId,
23655
+ canvasContextMenuState,
23656
+ setCanvasContextMenuState,
23532
23657
  cancelDrag,
23533
23658
  fitSelection
23534
23659
  });
@@ -23547,8 +23672,8 @@ var SystemCanvas = (() => {
23547
23672
  },
23548
23673
  theme
23549
23674
  };
23550
- const prevNodePositionsRef = (0, import_react33.useRef)(/* @__PURE__ */ new Map());
23551
- (0, import_react33.useEffect)(() => {
23675
+ const prevNodePositionsRef = (0, import_react34.useRef)(/* @__PURE__ */ new Map());
23676
+ (0, import_react34.useEffect)(() => {
23552
23677
  const collaboratorSelectedNodeIds = new Set(collaborators.map((c) => c.selectedNodeId).filter((id2) => !!id2));
23553
23678
  if (collaboratorSelectedNodeIds.size === 0) {
23554
23679
  prevNodePositionsRef.current = new Map(nodes.map((n) => [n.id, { x: n.x, y: n.y }]));
@@ -23586,7 +23711,7 @@ var SystemCanvas = (() => {
23586
23711
  }, 620);
23587
23712
  }
23588
23713
  }, [nodes, collaborators]);
23589
- return (0, import_jsx_runtime34.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, onDragOver: onImport ? (e) => e.preventDefault() : void 0, onDrop: onImport ? (e) => {
23714
+ return (0, import_jsx_runtime35.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, onDragOver: onImport ? (e) => e.preventDefault() : void 0, onDrop: onImport ? (e) => {
23590
23715
  e.preventDefault();
23591
23716
  const file = e.dataTransfer.files?.[0];
23592
23717
  if (!file)
@@ -23604,7 +23729,7 @@ var SystemCanvas = (() => {
23604
23729
  overflow: "hidden",
23605
23730
  outline: "none",
23606
23731
  ...style
23607
- }, children: [(0, import_jsx_runtime34.jsx)(Breadcrumbs, { breadcrumbs, theme: theme.breadcrumbs, onNavigate: navigateToBreadcrumb }), importError && (0, import_jsx_runtime34.jsxs)("div", { className: "system-canvas-import-error", style: {
23732
+ }, children: [(0, import_jsx_runtime35.jsx)(Breadcrumbs, { breadcrumbs, theme: theme.breadcrumbs, onNavigate: navigateToBreadcrumb }), importError && (0, import_jsx_runtime35.jsxs)("div", { className: "system-canvas-import-error", style: {
23608
23733
  position: "absolute",
23609
23734
  top: 12,
23610
23735
  left: 12,
@@ -23620,7 +23745,7 @@ var SystemCanvas = (() => {
23620
23745
  fontSize: 12,
23621
23746
  backdropFilter: "blur(8px)",
23622
23747
  maxWidth: 320
23623
- }, children: [(0, import_jsx_runtime34.jsx)("span", { style: { flex: 1 }, children: importError }), (0, import_jsx_runtime34.jsx)("button", { type: "button", "aria-label": "Dismiss", onClick: () => setImportError(null), style: {
23748
+ }, children: [(0, import_jsx_runtime35.jsx)("span", { style: { flex: 1 }, children: importError }), (0, import_jsx_runtime35.jsx)("button", { type: "button", "aria-label": "Dismiss", onClick: () => setImportError(null), style: {
23624
23749
  background: "none",
23625
23750
  border: "none",
23626
23751
  cursor: "pointer",
@@ -23629,7 +23754,7 @@ var SystemCanvas = (() => {
23629
23754
  fontSize: 14,
23630
23755
  lineHeight: 1,
23631
23756
  opacity: 0.7
23632
- }, children: "\xD7" })] }), isLoading && (0, import_jsx_runtime34.jsx)("div", { className: "system-canvas-loading", style: {
23757
+ }, children: "\xD7" })] }), isLoading && (0, import_jsx_runtime35.jsx)("div", { className: "system-canvas-loading", style: {
23633
23758
  position: "absolute",
23634
23759
  top: 12,
23635
23760
  right: 12,
@@ -23641,7 +23766,7 @@ var SystemCanvas = (() => {
23641
23766
  fontFamily: theme.node.fontFamily,
23642
23767
  fontSize: 12,
23643
23768
  backdropFilter: "blur(8px)"
23644
- }, children: "Loading..." }), (0, import_jsx_runtime34.jsx)(Viewport, { ref: viewportHandleRef, nodes, edges, nodeMap, theme, edgeStyle, columns: currentCanvas.columns, rows: currentCanvas.rows, canvases, minZoom: effectiveMinZoom, maxZoom: effectiveMaxZoom, defaultViewport, panMode, autoFit, canvasRef: currentCanvasRef, handoffTransform: pendingHandoff, onHandoffApplied: handleHandoffApplied, handoffFadeMs: zoomNavConfig.fadeDuration, onViewportChange: handleViewportChange, onNodeClick: handleNodeClick, onNodeDoubleClick: handleNodeDoubleClick, onNodeNavigate: handleNodeNavigate, onEdgeClick: handleEdgeClick, onEdgeDoubleClick: handleEdgeDoubleClick, onCanvasClick: editable ? handleCanvasClick : void 0, onCanvasContextMenu: handleCanvasContextMenu, onNodeContextMenu: handleNodeContextMenu, onEdgeContextMenu: handleEdgeContextMenu, onNodePointerDown: editable ? onNodePointerDown : void 0, selectedIds: editable ? selectedIds : void 0, marqueeRect: editable ? marqueeRect : null, marqueeActiveRef: editable ? marqueeActiveRef : void 0, editingId: editable ? editingId : null, selectedEdgeId: editable ? selectedEdgeId : null, editingEdgeId: editable ? editingEdgeId : null, dragOverrides, dropTargetId, resizeOverrides, onResizeHandlePointerDown: editable ? onResizeHandlePointerDown : void 0, onEditorCommit: handleEditorCommit, onEditorCancel: handleEditorCancel, onEdgeEditorCommit: handleEdgeEditorCommit, onEdgeEditorCancel: handleEdgeEditorCancel, onEdgeWaypointUpdate: editable ? handleEdgeWaypointUpdate : void 0, pendingEdge: editable ? pendingEdge : null, onConnectionHandlePointerDown: editable ? onConnectionHandlePointerDown : void 0, edgeCreateEnabled: editable, alignmentGuides: editable ? alignmentGuides : void 0, dimmedNodeIds: dimmedIds, highlightedNodeIds: matchingIds, activeMatchNodeId: activeMatchId, viewportState: collaboratorViewport }), collaborators.length > 0 || flashNodeIds.size > 0 ? (0, import_jsx_runtime34.jsx)(CollaboratorsOverlay, { collaborators, viewport: collaboratorViewport, nodeMap, flashNodeIds, containerWidth: containerSize.width, containerHeight: containerSize.height }) : null, showLaneHeaders && (0, import_jsx_runtime34.jsx)(LaneHeaders, { columns: currentCanvas.columns, rows: currentCanvas.rows, theme, getViewport: getViewportState, width: containerSize.width, height: containerSize.height, pinned: laneHeaders === "pinned" }), editable && showNodeToolbar && selectedIds.size === 1 && selectedResolvedNode && !editingId && (0, import_jsx_runtime34.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
23769
+ }, children: "Loading..." }), (0, import_jsx_runtime35.jsx)(Viewport, { ref: viewportHandleRef, nodes, edges, nodeMap, theme, edgeStyle, columns: currentCanvas.columns, rows: currentCanvas.rows, canvases, minZoom: effectiveMinZoom, maxZoom: effectiveMaxZoom, defaultViewport, panMode, autoFit, canvasRef: currentCanvasRef, handoffTransform: pendingHandoff, onHandoffApplied: handleHandoffApplied, handoffFadeMs: zoomNavConfig.fadeDuration, onViewportChange: handleViewportChange, onNodeClick: handleNodeClick, onNodeDoubleClick: handleNodeDoubleClick, onNodeNavigate: handleNodeNavigate, onEdgeClick: handleEdgeClick, onEdgeDoubleClick: handleEdgeDoubleClick, onCanvasClick: editable ? handleCanvasClick : void 0, onCanvasContextMenu: handleCanvasContextMenu, onNodeContextMenu: handleNodeContextMenu, onEdgeContextMenu: handleEdgeContextMenu, onNodePointerDown: editable ? onNodePointerDown : void 0, selectedIds: editable ? selectedIds : void 0, marqueeRect: editable ? marqueeRect : null, marqueeActiveRef: editable ? marqueeActiveRef : void 0, editingId: editable ? editingId : null, selectedEdgeId: editable ? selectedEdgeId : null, editingEdgeId: editable ? editingEdgeId : null, dragOverrides, dropTargetId, resizeOverrides, onResizeHandlePointerDown: editable ? onResizeHandlePointerDown : void 0, onEditorCommit: handleEditorCommit, onEditorCancel: handleEditorCancel, onEdgeEditorCommit: handleEdgeEditorCommit, onEdgeEditorCancel: handleEdgeEditorCancel, onEdgeWaypointUpdate: editable ? handleEdgeWaypointUpdate : void 0, pendingEdge: editable ? pendingEdge : null, onConnectionHandlePointerDown: editable ? onConnectionHandlePointerDown : void 0, edgeCreateEnabled: editable, alignmentGuides: editable ? alignmentGuides : void 0, dimmedNodeIds: dimmedIds, highlightedNodeIds: matchingIds, activeMatchNodeId: activeMatchId, viewportState: collaboratorViewport }), collaborators.length > 0 || flashNodeIds.size > 0 ? (0, import_jsx_runtime35.jsx)(CollaboratorsOverlay, { collaborators, viewport: collaboratorViewport, nodeMap, flashNodeIds, containerWidth: containerSize.width, containerHeight: containerSize.height }) : null, showLaneHeaders && (0, import_jsx_runtime35.jsx)(LaneHeaders, { columns: currentCanvas.columns, rows: currentCanvas.rows, theme, getViewport: getViewportState, width: containerSize.width, height: containerSize.height, pinned: laneHeaders === "pinned" }), editable && showNodeToolbar && selectedIds.size === 1 && selectedResolvedNode && !editingId && (0, import_jsx_runtime35.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
23645
23770
  wrappedOnNodeUpdate(selectedResolvedNode.id, update, currentCanvasRef);
23646
23771
  }, onDelete: () => {
23647
23772
  wrappedOnNodeDelete(selectedResolvedNode.id, currentCanvasRef);
@@ -23651,7 +23776,7 @@ var SystemCanvas = (() => {
23651
23776
  if (selectedResolvedNodes.length === 0)
23652
23777
  return null;
23653
23778
  const anchorNode = selectedResolvedNodes[0];
23654
- return (0, import_jsx_runtime34.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
23779
+ return (0, import_jsx_runtime35.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
23655
23780
  }, onMultiPatch: (patch) => {
23656
23781
  const updates = Array.from(selectedIds).map((id2) => ({ id: id2, patch }));
23657
23782
  wrappedOnNodesUpdate(updates, currentCanvasRef);
@@ -23659,7 +23784,7 @@ var SystemCanvas = (() => {
23659
23784
  wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
23660
23785
  clearSelection();
23661
23786
  }, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, onAlign: handleAlign, onDistribute: handleDistribute });
23662
- })(), (0, import_jsx_runtime34.jsxs)("div", { style: {
23787
+ })(), (0, import_jsx_runtime35.jsxs)("div", { style: {
23663
23788
  position: "absolute",
23664
23789
  bottom: 16,
23665
23790
  right: 16,
@@ -23669,7 +23794,7 @@ var SystemCanvas = (() => {
23669
23794
  gap: 8,
23670
23795
  zIndex: 15,
23671
23796
  pointerEvents: "none"
23672
- }, children: [editable && (renderAddNodeButton ? (0, import_jsx_runtime34.jsx)("div", { style: { pointerEvents: "auto" }, children: renderAddNodeButton(renderProps) }) : (0, import_jsx_runtime34.jsx)("div", { style: { pointerEvents: "auto" }, children: (0, import_jsx_runtime34.jsx)(AddNodeButton, { ...renderProps }) })), showExportButton && (renderExportButton ? (0, import_jsx_runtime34.jsx)("div", { style: { pointerEvents: "auto" }, children: renderExportButton(exportRenderProps) }) : (0, import_jsx_runtime34.jsx)("div", { style: { pointerEvents: "auto" }, children: (0, import_jsx_runtime34.jsx)(ExportButton, { ...exportRenderProps }) }))] }), effectiveNodeContextMenu && (0, import_jsx_runtime34.jsx)(NodeContextMenuOverlay, { state: contextMenuState, config: effectiveNodeContextMenu, theme, onClose: () => setContextMenuState(null) }), edgeContextMenu && (0, import_jsx_runtime34.jsx)(EdgeContextMenuOverlay, { state: edgeContextMenuState, config: edgeContextMenu, theme, onClose: () => setEdgeContextMenuState(null) }), (0, import_jsx_runtime34.jsx)(SearchOverlay, { open: searchOpen, query: searchQuery, onQueryChange: setSearchQuery, theme, hiddenCategories, onToggleCategory: (cat) => setHiddenCategories((prev) => {
23797
+ }, children: [editable && (renderAddNodeButton ? (0, import_jsx_runtime35.jsx)("div", { style: { pointerEvents: "auto" }, children: renderAddNodeButton(renderProps) }) : (0, import_jsx_runtime35.jsx)("div", { style: { pointerEvents: "auto" }, children: (0, import_jsx_runtime35.jsx)(AddNodeButton, { ...renderProps }) })), showExportButton && (renderExportButton ? (0, import_jsx_runtime35.jsx)("div", { style: { pointerEvents: "auto" }, children: renderExportButton(exportRenderProps) }) : (0, import_jsx_runtime35.jsx)("div", { style: { pointerEvents: "auto" }, children: (0, import_jsx_runtime35.jsx)(ExportButton, { ...exportRenderProps }) }))] }), effectiveNodeContextMenu && (0, import_jsx_runtime35.jsx)(NodeContextMenuOverlay, { state: contextMenuState, config: effectiveNodeContextMenu, theme, onClose: () => setContextMenuState(null) }), edgeContextMenu && (0, import_jsx_runtime35.jsx)(EdgeContextMenuOverlay, { state: edgeContextMenuState, config: edgeContextMenu, theme, onClose: () => setEdgeContextMenuState(null) }), canvasContextMenu && (0, import_jsx_runtime35.jsx)(CanvasContextMenuOverlay, { state: canvasContextMenuState, config: canvasContextMenu, theme, onClose: () => setCanvasContextMenuState(null) }), (0, import_jsx_runtime35.jsx)(SearchOverlay, { open: searchOpen, query: searchQuery, onQueryChange: setSearchQuery, theme, hiddenCategories, onToggleCategory: (cat) => setHiddenCategories((prev) => {
23673
23798
  const next = new Set(prev);
23674
23799
  next.has(cat) ? next.delete(cat) : next.add(cat);
23675
23800
  return next;
@@ -23784,7 +23909,7 @@ var SystemCanvas = (() => {
23784
23909
  onEdgeUpdate: handleEdgeUpdate,
23785
23910
  onEdgeDelete: handleEdgeDelete
23786
23911
  };
23787
- root2.render(import_react34.default.createElement(SystemCanvas, props));
23912
+ root2.render(import_react35.default.createElement(SystemCanvas, props));
23788
23913
  };
23789
23914
  doRender();
23790
23915
  return {