system-canvas-standalone 0.2.40 → 0.2.42

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
  ]);
@@ -15835,10 +15841,10 @@ var SystemCanvas = (() => {
15835
15841
  // ../react/dist/hooks/useMultiSelect.js
15836
15842
  var import_react7 = __toESM(require_react(), 1);
15837
15843
  function useMultiSelect(options) {
15838
- const { svgRef, viewport, nodesRef, containerRef, enabled } = options;
15844
+ const { svgRef, viewport, nodesRef, containerRef, enabled, activationKey = "space" } = options;
15839
15845
  const [selectedIds, setSelectedIds] = (0, import_react7.useState)(() => /* @__PURE__ */ new Set());
15840
15846
  const [marqueeRect, setMarqueeRect] = (0, import_react7.useState)(null);
15841
- const marqueeActiveRef = (0, import_react7.useRef)(false);
15847
+ const marqueeActiveRef = (0, import_react7.useRef)(activationKey === "none");
15842
15848
  const isDrawingRef = (0, import_react7.useRef)(false);
15843
15849
  const startScreenRef = (0, import_react7.useRef)(null);
15844
15850
  const pointerIdRef = (0, import_react7.useRef)(null);
@@ -15873,28 +15879,47 @@ var SystemCanvas = (() => {
15873
15879
  (0, import_react7.useEffect)(() => {
15874
15880
  if (!enabled)
15875
15881
  return;
15882
+ if (activationKey === "none") {
15883
+ marqueeActiveRef.current = true;
15884
+ return;
15885
+ }
15876
15886
  const container = containerRef.current;
15877
15887
  if (!container)
15878
15888
  return;
15889
+ const matchesKey = (e) => {
15890
+ switch (activationKey) {
15891
+ case "space":
15892
+ return e.code === "Space";
15893
+ case "shift":
15894
+ return e.key === "Shift";
15895
+ case "alt":
15896
+ return e.key === "Alt";
15897
+ case "meta":
15898
+ return e.key === "Meta";
15899
+ default:
15900
+ return false;
15901
+ }
15902
+ };
15879
15903
  const onKeyDown = (e) => {
15880
- if (e.code === "Space" && !e.repeat) {
15881
- const active = document.activeElement;
15882
- if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable) {
15883
- return;
15884
- }
15885
- e.preventDefault();
15886
- marqueeActiveRef.current = true;
15904
+ if (!matchesKey(e) || e.repeat)
15905
+ return;
15906
+ const active = document.activeElement;
15907
+ if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable) {
15908
+ return;
15887
15909
  }
15910
+ if (activationKey === "space")
15911
+ e.preventDefault();
15912
+ marqueeActiveRef.current = true;
15888
15913
  };
15889
15914
  const onKeyUp = (e) => {
15890
- if (e.code === "Space") {
15891
- marqueeActiveRef.current = false;
15892
- if (isDrawingRef.current) {
15893
- isDrawingRef.current = false;
15894
- startScreenRef.current = null;
15895
- pointerIdRef.current = null;
15896
- setMarqueeRect(null);
15897
- }
15915
+ if (!matchesKey(e))
15916
+ return;
15917
+ marqueeActiveRef.current = false;
15918
+ if (isDrawingRef.current) {
15919
+ isDrawingRef.current = false;
15920
+ startScreenRef.current = null;
15921
+ pointerIdRef.current = null;
15922
+ setMarqueeRect(null);
15898
15923
  }
15899
15924
  };
15900
15925
  container.addEventListener("keydown", onKeyDown);
@@ -15903,7 +15928,7 @@ var SystemCanvas = (() => {
15903
15928
  container.removeEventListener("keydown", onKeyDown);
15904
15929
  container.removeEventListener("keyup", onKeyUp);
15905
15930
  };
15906
- }, [enabled, containerRef]);
15931
+ }, [enabled, containerRef, activationKey]);
15907
15932
  (0, import_react7.useEffect)(() => {
15908
15933
  if (!enabled)
15909
15934
  return;
@@ -15940,6 +15965,10 @@ var SystemCanvas = (() => {
15940
15965
  if (target && typeof target.closest === "function") {
15941
15966
  if (target.closest(".system-canvas-node"))
15942
15967
  return;
15968
+ if (target.closest(".system-canvas-resize-handles"))
15969
+ return;
15970
+ if (target.closest(".system-canvas-connection-handles"))
15971
+ return;
15943
15972
  }
15944
15973
  const svg = svgRef.current;
15945
15974
  if (!svg)
@@ -22249,12 +22278,120 @@ var SystemCanvas = (() => {
22249
22278
  }) });
22250
22279
  }
22251
22280
 
22252
- // ../react/dist/components/SearchOverlay.js
22281
+ // ../react/dist/components/CanvasContextMenuOverlay.js
22253
22282
  var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
22254
22283
  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);
22284
+ var ESTIMATED_MENU_WIDTH3 = 200;
22285
+ var MIN_MENU_WIDTH3 = 160;
22286
+ var VIEWPORT_MARGIN3 = 8;
22287
+ function CanvasContextMenuOverlay({ state, config, theme, onClose }) {
22288
+ const rootRef = (0, import_react30.useRef)(null);
22289
+ const [hoveredId, setHoveredId] = (0, import_react30.useState)(null);
22290
+ (0, import_react30.useEffect)(() => {
22291
+ if (state)
22292
+ setHoveredId(null);
22293
+ }, [state]);
22257
22294
  (0, import_react30.useEffect)(() => {
22295
+ if (!state)
22296
+ return;
22297
+ function onDown(e) {
22298
+ const root2 = rootRef.current;
22299
+ if (!root2)
22300
+ return;
22301
+ if (root2.contains(e.target))
22302
+ return;
22303
+ onClose();
22304
+ }
22305
+ function onKey(e) {
22306
+ if (e.key === "Escape") {
22307
+ e.stopPropagation();
22308
+ onClose();
22309
+ }
22310
+ }
22311
+ function onScroll() {
22312
+ onClose();
22313
+ }
22314
+ window.addEventListener("mousedown", onDown);
22315
+ window.addEventListener("keydown", onKey);
22316
+ window.addEventListener("scroll", onScroll, true);
22317
+ window.addEventListener("blur", onClose);
22318
+ return () => {
22319
+ window.removeEventListener("mousedown", onDown);
22320
+ window.removeEventListener("keydown", onKey);
22321
+ window.removeEventListener("scroll", onScroll, true);
22322
+ window.removeEventListener("blur", onClose);
22323
+ };
22324
+ }, [state, onClose]);
22325
+ if (!state)
22326
+ return null;
22327
+ const cm = theme.contextMenu;
22328
+ if (!cm)
22329
+ return null;
22330
+ const vw = typeof window !== "undefined" ? window.innerWidth : 0;
22331
+ const vh = typeof window !== "undefined" ? window.innerHeight : 0;
22332
+ const sepCount = state.items.filter((i) => i.id === "__sep__").length;
22333
+ const rowCount = state.items.length - sepCount;
22334
+ const itemHeight = cm.itemPaddingY * 2 + cm.fontSize + 4;
22335
+ const estimatedHeight = rowCount * itemHeight + sepCount * 9 + cm.paddingY * 2;
22336
+ const left = vw ? Math.min(state.screenPosition.x, vw - ESTIMATED_MENU_WIDTH3 - VIEWPORT_MARGIN3) : state.screenPosition.x;
22337
+ const top = vh ? Math.min(state.screenPosition.y, vh - estimatedHeight - VIEWPORT_MARGIN3) : state.screenPosition.y;
22338
+ const anyIcon = state.items.some((item) => item.id !== "__sep__" && !!item.icon);
22339
+ return (0, import_jsx_runtime31.jsx)("div", { ref: rootRef, role: "menu", onContextMenu: (e) => {
22340
+ e.preventDefault();
22341
+ e.stopPropagation();
22342
+ }, style: {
22343
+ position: "fixed",
22344
+ left,
22345
+ top,
22346
+ zIndex: 1e3,
22347
+ minWidth: MIN_MENU_WIDTH3,
22348
+ padding: `${cm.paddingY}px ${cm.paddingX}px`,
22349
+ background: cm.background,
22350
+ color: cm.itemColor,
22351
+ border: `1px solid ${cm.borderColor}`,
22352
+ borderRadius: cm.borderRadius,
22353
+ boxShadow: cm.shadow,
22354
+ fontFamily: cm.fontFamily,
22355
+ fontSize: cm.fontSize,
22356
+ backdropFilter: "blur(10px)",
22357
+ userSelect: "none",
22358
+ pointerEvents: "auto"
22359
+ }, children: state.items.map((item, idx) => {
22360
+ if (item.id === "__sep__") {
22361
+ return (0, import_jsx_runtime31.jsx)("hr", { style: {
22362
+ border: "none",
22363
+ borderTop: `1px solid ${theme.breadcrumbs?.separatorColor ?? cm.borderColor}`,
22364
+ margin: `4px 0`
22365
+ } }, `__sep__${idx}`);
22366
+ }
22367
+ const isHovered = hoveredId === item.id;
22368
+ const color2 = item.destructive ? cm.destructiveItemColor : cm.itemColor;
22369
+ return (0, import_jsx_runtime31.jsxs)("div", { role: "menuitem", onMouseEnter: () => setHoveredId(item.id), onMouseLeave: () => setHoveredId((id2) => id2 === item.id ? null : id2), onClick: () => {
22370
+ config.onSelect(item.id, {
22371
+ canvasRef: state.canvasRef,
22372
+ position: state.position,
22373
+ screenPosition: state.screenPosition
22374
+ });
22375
+ onClose();
22376
+ }, style: {
22377
+ display: "flex",
22378
+ alignItems: "center",
22379
+ gap: 10,
22380
+ padding: `${cm.itemPaddingY}px ${cm.itemPaddingX}px`,
22381
+ borderRadius: Math.max(0, cm.borderRadius - 4),
22382
+ cursor: "pointer",
22383
+ background: isHovered ? cm.itemHoverBackground : "transparent",
22384
+ color: color2
22385
+ }, 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);
22386
+ }) });
22387
+ }
22388
+
22389
+ // ../react/dist/components/SearchOverlay.js
22390
+ var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
22391
+ var import_react31 = __toESM(require_react(), 1);
22392
+ function SearchOverlay({ open, query, onQueryChange, theme, hiddenCategories, onToggleCategory, matchCount, matchIndex, onNext, onPrev, onClose }) {
22393
+ const inputRef = (0, import_react31.useRef)(null);
22394
+ (0, import_react31.useEffect)(() => {
22258
22395
  if (open) {
22259
22396
  inputRef.current?.focus();
22260
22397
  }
@@ -22278,7 +22415,7 @@ var SystemCanvas = (() => {
22278
22415
  onPrev();
22279
22416
  }
22280
22417
  };
22281
- return (0, import_jsx_runtime31.jsxs)("div", { style: {
22418
+ return (0, import_jsx_runtime32.jsxs)("div", { style: {
22282
22419
  position: "absolute",
22283
22420
  top: 12,
22284
22421
  left: "50%",
@@ -22289,7 +22426,7 @@ var SystemCanvas = (() => {
22289
22426
  alignItems: "center",
22290
22427
  gap: 6,
22291
22428
  pointerEvents: "none"
22292
- }, children: [(0, import_jsx_runtime31.jsxs)("div", { style: {
22429
+ }, children: [(0, import_jsx_runtime32.jsxs)("div", { style: {
22293
22430
  display: "flex",
22294
22431
  alignItems: "center",
22295
22432
  gap: 8,
@@ -22300,7 +22437,7 @@ var SystemCanvas = (() => {
22300
22437
  boxShadow: "0 2px 12px rgba(0,0,0,0.25)",
22301
22438
  pointerEvents: "all",
22302
22439
  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: {
22440
+ }, 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
22441
  background: "transparent",
22305
22442
  border: "none",
22306
22443
  outline: "none",
@@ -22309,7 +22446,7 @@ var SystemCanvas = (() => {
22309
22446
  fontSize: 13,
22310
22447
  width: 160,
22311
22448
  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: {
22449
+ } }), 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
22450
  background: "transparent",
22314
22451
  border: "none",
22315
22452
  cursor: "pointer",
@@ -22319,14 +22456,14 @@ var SystemCanvas = (() => {
22319
22456
  color: textColor,
22320
22457
  opacity: 0.7,
22321
22458
  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: {
22459
+ }, 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
22460
  fontSize: 11,
22324
22461
  fontFamily,
22325
22462
  color: textColor,
22326
22463
  opacity: 0.7,
22327
22464
  whiteSpace: "nowrap",
22328
22465
  flexShrink: 0
22329
- }, children: [matchIndex + 1, "/", matchCount] }), (0, import_jsx_runtime31.jsx)("button", { onClick: onNext, style: {
22466
+ }, children: [matchIndex + 1, "/", matchCount] }), (0, import_jsx_runtime32.jsx)("button", { onClick: onNext, style: {
22330
22467
  background: "transparent",
22331
22468
  border: "none",
22332
22469
  cursor: "pointer",
@@ -22336,14 +22473,14 @@ var SystemCanvas = (() => {
22336
22473
  color: textColor,
22337
22474
  opacity: 0.7,
22338
22475
  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: {
22476
+ }, 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
22477
  fontSize: 11,
22341
22478
  fontFamily,
22342
22479
  color: textColor,
22343
22480
  opacity: 0.5,
22344
22481
  whiteSpace: "nowrap",
22345
22482
  flexShrink: 0
22346
- }, children: "No matches" }), (0, import_jsx_runtime31.jsx)("button", { onClick: onClose, style: {
22483
+ }, children: "No matches" }), (0, import_jsx_runtime32.jsx)("button", { onClick: onClose, style: {
22347
22484
  background: "transparent",
22348
22485
  border: "none",
22349
22486
  cursor: "pointer",
@@ -22353,7 +22490,7 @@ var SystemCanvas = (() => {
22353
22490
  color: textColor,
22354
22491
  opacity: 0.6,
22355
22492
  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: {
22493
+ }, 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
22494
  display: "flex",
22358
22495
  gap: 6,
22359
22496
  flexWrap: "wrap",
@@ -22362,7 +22499,7 @@ var SystemCanvas = (() => {
22362
22499
  }, children: Object.entries(categories).map(([key, def]) => {
22363
22500
  const isHidden = hiddenCategories.has(key);
22364
22501
  const accentColor = def.fill ?? def.stroke ?? textColor;
22365
- return (0, import_jsx_runtime31.jsx)("button", { onClick: () => onToggleCategory(key), style: {
22502
+ return (0, import_jsx_runtime32.jsx)("button", { onClick: () => onToggleCategory(key), style: {
22366
22503
  padding: "3px 10px",
22367
22504
  borderRadius: 12,
22368
22505
  border: `1.5px solid ${accentColor}`,
@@ -22380,8 +22517,8 @@ var SystemCanvas = (() => {
22380
22517
  }
22381
22518
 
22382
22519
  // ../react/dist/components/CollaboratorsOverlay.js
22383
- var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
22384
- var import_react31 = __toESM(require_react(), 1);
22520
+ var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
22521
+ var import_react32 = __toESM(require_react(), 1);
22385
22522
  var CLIP_GUARD_MARGIN = 100;
22386
22523
  var STYLE_ID = "system-canvas-collab-keyframes";
22387
22524
  function ensureKeyframes() {
@@ -22404,7 +22541,7 @@ var SystemCanvas = (() => {
22404
22541
  document.head.appendChild(style);
22405
22542
  }
22406
22543
  function CollaboratorsOverlay({ collaborators, viewport, nodeMap, flashNodeIds, containerWidth = Infinity, containerHeight = Infinity }) {
22407
- const keyframesInjected = (0, import_react31.useRef)(false);
22544
+ const keyframesInjected = (0, import_react32.useRef)(false);
22408
22545
  if (!keyframesInjected.current) {
22409
22546
  ensureKeyframes();
22410
22547
  keyframesInjected.current = true;
@@ -22419,7 +22556,7 @@ var SystemCanvas = (() => {
22419
22556
  halosByNode.set(collab.selectedNodeId, arr);
22420
22557
  }
22421
22558
  }
22422
- return (0, import_jsx_runtime32.jsxs)("div", { style: {
22559
+ return (0, import_jsx_runtime33.jsxs)("div", { style: {
22423
22560
  position: "absolute",
22424
22561
  inset: 0,
22425
22562
  pointerEvents: "none",
@@ -22432,7 +22569,7 @@ var SystemCanvas = (() => {
22432
22569
  const screenRect = canvasRectToScreenRect({ x: node.x, y: node.y, width: node.width, height: node.height }, viewport);
22433
22570
  return collabList.map((collab, idx) => {
22434
22571
  const outset = 3 + idx * 2;
22435
- return (0, import_jsx_runtime32.jsxs)("div", { children: [(0, import_jsx_runtime32.jsx)("div", { style: {
22572
+ return (0, import_jsx_runtime33.jsxs)("div", { children: [(0, import_jsx_runtime33.jsx)("div", { style: {
22436
22573
  position: "absolute",
22437
22574
  left: screenRect.x - outset,
22438
22575
  top: screenRect.y - outset,
@@ -22442,7 +22579,7 @@ var SystemCanvas = (() => {
22442
22579
  borderRadius: 6 + outset,
22443
22580
  opacity: 0.55,
22444
22581
  boxSizing: "border-box"
22445
- } }), (0, import_jsx_runtime32.jsx)("div", { style: {
22582
+ } }), (0, import_jsx_runtime33.jsx)("div", { style: {
22446
22583
  position: "absolute",
22447
22584
  left: screenRect.x - outset,
22448
22585
  top: screenRect.y - outset - 18,
@@ -22464,13 +22601,13 @@ var SystemCanvas = (() => {
22464
22601
  if (screen.x < -CLIP_GUARD_MARGIN || screen.x > containerWidth + CLIP_GUARD_MARGIN || screen.y < -CLIP_GUARD_MARGIN || screen.y > containerHeight + CLIP_GUARD_MARGIN) {
22465
22602
  return null;
22466
22603
  }
22467
- return (0, import_jsx_runtime32.jsxs)("div", { style: {
22604
+ return (0, import_jsx_runtime33.jsxs)("div", { style: {
22468
22605
  position: "absolute",
22469
22606
  left: screen.x,
22470
22607
  top: screen.y,
22471
22608
  transform: "translate(0, 0)",
22472
22609
  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: {
22610
+ }, 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
22611
  position: "absolute",
22475
22612
  top: 18,
22476
22613
  left: 8,
@@ -22483,7 +22620,7 @@ var SystemCanvas = (() => {
22483
22620
  boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
22484
22621
  whiteSpace: "nowrap",
22485
22622
  fontFamily: "sans-serif"
22486
- }, children: [(0, import_jsx_runtime32.jsx)("div", { style: {
22623
+ }, children: [(0, import_jsx_runtime33.jsx)("div", { style: {
22487
22624
  width: 16,
22488
22625
  height: 16,
22489
22626
  borderRadius: "50%",
@@ -22493,7 +22630,7 @@ var SystemCanvas = (() => {
22493
22630
  alignItems: "center",
22494
22631
  justifyContent: "center",
22495
22632
  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: {
22633
+ }, 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
22634
  width: 16,
22498
22635
  height: 16,
22499
22636
  display: "flex",
@@ -22503,7 +22640,7 @@ var SystemCanvas = (() => {
22503
22640
  color: "#fff",
22504
22641
  fontSize: 9,
22505
22642
  fontWeight: 700
22506
- }, children: collab.name ? collab.name[0].toUpperCase() : "?" }) }), (0, import_jsx_runtime32.jsx)("span", { style: {
22643
+ }, children: collab.name ? collab.name[0].toUpperCase() : "?" }) }), (0, import_jsx_runtime33.jsx)("span", { style: {
22507
22644
  fontSize: 11,
22508
22645
  lineHeight: "16px",
22509
22646
  color: "#fff",
@@ -22514,7 +22651,7 @@ var SystemCanvas = (() => {
22514
22651
  if (!node)
22515
22652
  return null;
22516
22653
  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: {
22654
+ return (0, import_jsx_runtime33.jsx)("div", { style: {
22518
22655
  position: "absolute",
22519
22656
  left: screenRect.x,
22520
22657
  top: screenRect.y,
@@ -22528,12 +22665,12 @@ var SystemCanvas = (() => {
22528
22665
  }
22529
22666
 
22530
22667
  // ../react/dist/components/ExportButton.js
22531
- var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
22532
- var import_react32 = __toESM(require_react(), 1);
22668
+ var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
22669
+ var import_react33 = __toESM(require_react(), 1);
22533
22670
  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)(() => {
22671
+ const [open, setOpen] = (0, import_react33.useState)(false);
22672
+ const rootRef = (0, import_react33.useRef)(null);
22673
+ (0, import_react33.useEffect)(() => {
22537
22674
  if (!open)
22538
22675
  return;
22539
22676
  function onDocClick(e) {
@@ -22580,12 +22717,12 @@ var SystemCanvas = (() => {
22580
22717
  }
22581
22718
  });
22582
22719
  }
22583
- return (0, import_jsx_runtime33.jsxs)("div", { ref: rootRef, className: "system-canvas-export-button", style: {
22720
+ return (0, import_jsx_runtime34.jsxs)("div", { ref: rootRef, className: "system-canvas-export-button", style: {
22584
22721
  position: "relative",
22585
22722
  fontFamily: theme.breadcrumbs.fontFamily,
22586
22723
  fontSize: theme.breadcrumbs.fontSize,
22587
22724
  userSelect: "none"
22588
- }, children: [open && (0, import_jsx_runtime33.jsx)("div", { style: {
22725
+ }, children: [open && (0, import_jsx_runtime34.jsx)("div", { style: {
22589
22726
  position: "absolute",
22590
22727
  bottom: 52,
22591
22728
  right: 0,
@@ -22596,7 +22733,7 @@ var SystemCanvas = (() => {
22596
22733
  borderRadius: 10,
22597
22734
  boxShadow: "0 8px 24px rgba(0,0,0,0.35)",
22598
22735
  backdropFilter: "blur(10px)"
22599
- }, children: rows.map((row) => (0, import_jsx_runtime33.jsx)("button", { type: "button", onClick: () => void row.onClick(), style: {
22736
+ }, children: rows.map((row) => (0, import_jsx_runtime34.jsx)("button", { type: "button", onClick: () => void row.onClick(), style: {
22600
22737
  display: "block",
22601
22738
  width: "100%",
22602
22739
  textAlign: "left",
@@ -22614,7 +22751,7 @@ var SystemCanvas = (() => {
22614
22751
  }, onMouseLeave: (e) => {
22615
22752
  ;
22616
22753
  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: {
22754
+ }, 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
22755
  width: 44,
22619
22756
  height: 44,
22620
22757
  borderRadius: 22,
@@ -22629,7 +22766,7 @@ var SystemCanvas = (() => {
22629
22766
  alignItems: "center",
22630
22767
  justifyContent: "center",
22631
22768
  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" })] }) })] });
22769
+ }, 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
22770
  }
22634
22771
 
22635
22772
  // ../react/dist/export/utils.js
@@ -22801,8 +22938,8 @@ var SystemCanvas = (() => {
22801
22938
  // ../react/dist/components/SystemCanvas.js
22802
22939
  var CASCADE_WINDOW_MS = 1500;
22803
22940
  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)(() => {
22941
+ 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", multiSelectKey = "auto", autoFit = "canvas-change", laneHeaders = "pinned", snapToLanes = false, zoomNavigation = false, snapGrid, guideThreshold, alignDistributeMenu, historyDepth, onUndo, onRedo, collaborators = [], className, style }, forwardedRef) {
22942
+ const zoomNavConfig = (0, import_react34.useMemo)(() => {
22806
22943
  const defaults = {
22807
22944
  enterThreshold: 0.66,
22808
22945
  exitThreshold: 0.33,
@@ -22827,16 +22964,16 @@ var SystemCanvas = (() => {
22827
22964
  }, [zoomNavigation]);
22828
22965
  const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
22829
22966
  const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
22830
- (0, import_react33.useEffect)(() => {
22967
+ (0, import_react34.useEffect)(() => {
22831
22968
  const env = globalThis.process?.env?.NODE_ENV;
22832
22969
  if (editable && !canvases && env !== "production") {
22833
22970
  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
22971
  }
22835
22972
  }, [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) => {
22973
+ const [parentFrames, setParentFrames] = (0, import_react34.useState)([]);
22974
+ const [pendingHandoff, setPendingHandoff] = (0, import_react34.useState)(null);
22975
+ const suppressNextHandoffClearRef = (0, import_react34.useRef)(false);
22976
+ const handleBreadcrumbClick = (0, import_react34.useCallback)((index) => {
22840
22977
  setParentFrames((prev) => prev.slice(0, index));
22841
22978
  if (suppressNextHandoffClearRef.current) {
22842
22979
  suppressNextHandoffClearRef.current = false;
@@ -22853,10 +22990,10 @@ var SystemCanvas = (() => {
22853
22990
  onNavigate,
22854
22991
  onBreadcrumbClick: handleBreadcrumbClick
22855
22992
  });
22856
- (0, import_react33.useEffect)(() => {
22993
+ (0, import_react34.useEffect)(() => {
22857
22994
  onBreadcrumbsChange?.(breadcrumbs);
22858
22995
  }, [breadcrumbs, onBreadcrumbsChange]);
22859
- const theme = (0, import_react33.useMemo)(() => {
22996
+ const theme = (0, import_react34.useMemo)(() => {
22860
22997
  const registry = { ...themes, ...customThemes };
22861
22998
  const resolveByName = (name) => name && registry[name] ? registry[name] : null;
22862
22999
  if (themeProp) {
@@ -22868,24 +23005,24 @@ var SystemCanvas = (() => {
22868
23005
  return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
22869
23006
  }, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
22870
23007
  const snapGridSize = snapGrid === true ? theme.grid.size : typeof snapGrid === "number" ? snapGrid : 0;
22871
- const { nodes, edges, nodeMap } = (0, import_react33.useMemo)(() => {
23008
+ const { nodes, edges, nodeMap } = (0, import_react34.useMemo)(() => {
22872
23009
  const resolved = resolveCanvas(currentCanvas, theme);
22873
23010
  const map = buildNodeMap(resolved.nodes);
22874
23011
  return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
22875
23012
  }, [currentCanvas, theme]);
22876
- const nodesRef = (0, import_react33.useRef)(nodes);
23013
+ const nodesRef = (0, import_react34.useRef)(nodes);
22877
23014
  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);
23015
+ const viewportStateRef = (0, import_react34.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
23016
+ const viewportHandleRef = (0, import_react34.useRef)(null);
23017
+ const [collaboratorViewport, setCollaboratorViewport] = (0, import_react34.useState)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
23018
+ const [flashNodeIds, setFlashNodeIds] = (0, import_react34.useState)(/* @__PURE__ */ new Map());
23019
+ const navigateToRefRef = (0, import_react34.useRef)(navigateToRef);
22883
23020
  navigateToRefRef.current = navigateToRef;
22884
- const navigateToBreadcrumbRef = (0, import_react33.useRef)(navigateToBreadcrumb);
23021
+ const navigateToBreadcrumbRef = (0, import_react34.useRef)(navigateToBreadcrumb);
22885
23022
  navigateToBreadcrumbRef.current = navigateToBreadcrumb;
22886
- const breadcrumbsRef = (0, import_react33.useRef)(breadcrumbs);
23023
+ const breadcrumbsRef = (0, import_react34.useRef)(breadcrumbs);
22887
23024
  breadcrumbsRef.current = breadcrumbs;
22888
- (0, import_react33.useImperativeHandle)(forwardedRef, () => ({
23025
+ (0, import_react34.useImperativeHandle)(forwardedRef, () => ({
22889
23026
  zoomIntoNode: (nodeId, options) => {
22890
23027
  return new Promise((resolve) => {
22891
23028
  const node = nodesRef.current.find((n) => n.id === nodeId);
@@ -22919,29 +23056,31 @@ var SystemCanvas = (() => {
22919
23056
  getViewport: () => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 },
22920
23057
  getSvgElement: () => viewportHandleRef.current?.getSvgElement() ?? null
22921
23058
  }), [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);
23059
+ const [editingId, setEditingId] = (0, import_react34.useState)(null);
23060
+ const [selectedEdgeId, setSelectedEdgeId] = (0, import_react34.useState)(null);
23061
+ const [editingEdgeId, setEditingEdgeId] = (0, import_react34.useState)(null);
23062
+ const [searchOpen, setSearchOpen] = (0, import_react34.useState)(false);
23063
+ const [searchQuery, setSearchQuery] = (0, import_react34.useState)("");
23064
+ const [hiddenCategories, setHiddenCategories] = (0, import_react34.useState)(/* @__PURE__ */ new Set());
23065
+ const [searchIndex, setSearchIndex] = (0, import_react34.useState)(0);
23066
+ const [importError, setImportError] = (0, import_react34.useState)(null);
23067
+ const svgProxyRef = (0, import_react34.useRef)(null);
23068
+ const containerRef = (0, import_react34.useRef)(null);
23069
+ const resolvedMultiSelectKey = multiSelectKey === "auto" ? panMode === "trackpad" ? "none" : "space" : multiSelectKey;
22932
23070
  const { selectedIds, selectNode, toggleNode, selectAll, clearSelection, selectMultiple, marqueeRect, marqueeActiveRef } = useMultiSelect({
22933
23071
  svgRef: svgProxyRef,
22934
23072
  viewport: viewportStateRef,
22935
23073
  nodesRef,
22936
23074
  containerRef,
22937
- enabled: editable
23075
+ enabled: editable,
23076
+ activationKey: resolvedMultiSelectKey
22938
23077
  });
22939
- const selectedIdsRef = (0, import_react33.useRef)(selectedIds);
22940
- (0, import_react33.useEffect)(() => {
23078
+ const selectedIdsRef = (0, import_react34.useRef)(selectedIds);
23079
+ (0, import_react34.useEffect)(() => {
22941
23080
  selectedIdsRef.current = selectedIds;
22942
23081
  }, [selectedIds]);
22943
- const edgesRef = (0, import_react33.useRef)(edges);
22944
- (0, import_react33.useEffect)(() => {
23082
+ const edgesRef = (0, import_react34.useRef)(edges);
23083
+ (0, import_react34.useEffect)(() => {
22945
23084
  edgesRef.current = edges;
22946
23085
  }, [edges]);
22947
23086
  const { wrappedOnNodeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeAdd, wrappedOnEdgeUpdate, wrappedOnEdgeDelete, beginBatch, endBatch, undo, redo } = useCommandHistory({
@@ -22973,7 +23112,7 @@ var SystemCanvas = (() => {
22973
23112
  onBeginBatch: beginBatch,
22974
23113
  onEndBatch: endBatch
22975
23114
  });
22976
- (0, import_react33.useEffect)(() => {
23115
+ (0, import_react34.useEffect)(() => {
22977
23116
  clearSelection();
22978
23117
  setEditingId(null);
22979
23118
  setSelectedEdgeId(null);
@@ -22982,7 +23121,7 @@ var SystemCanvas = (() => {
22982
23121
  setSearchQuery("");
22983
23122
  setHiddenCategories(/* @__PURE__ */ new Set());
22984
23123
  }, [currentCanvasRef]);
22985
- (0, import_react33.useEffect)(() => {
23124
+ (0, import_react34.useEffect)(() => {
22986
23125
  const onKey = (e) => {
22987
23126
  if ((e.metaKey || e.ctrlKey) && e.key === "f") {
22988
23127
  e.preventDefault();
@@ -22992,7 +23131,7 @@ var SystemCanvas = (() => {
22992
23131
  window.addEventListener("keydown", onKey);
22993
23132
  return () => window.removeEventListener("keydown", onKey);
22994
23133
  }, []);
22995
- (0, import_react33.useEffect)(() => {
23134
+ (0, import_react34.useEffect)(() => {
22996
23135
  const onKey = async (e) => {
22997
23136
  if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === "c") {
22998
23137
  e.preventDefault();
@@ -23006,12 +23145,12 @@ var SystemCanvas = (() => {
23006
23145
  window.addEventListener("keydown", onKey);
23007
23146
  return () => window.removeEventListener("keydown", onKey);
23008
23147
  }, [selectedIds, nodes]);
23009
- const onSelectionChangeRef = (0, import_react33.useRef)(onSelectionChange);
23010
- (0, import_react33.useEffect)(() => {
23148
+ const onSelectionChangeRef = (0, import_react34.useRef)(onSelectionChange);
23149
+ (0, import_react34.useEffect)(() => {
23011
23150
  onSelectionChangeRef.current = onSelectionChange;
23012
23151
  }, [onSelectionChange]);
23013
- const lastEmittedSelectionRef = (0, import_react33.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
23014
- (0, import_react33.useEffect)(() => {
23152
+ const lastEmittedSelectionRef = (0, import_react34.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
23153
+ (0, import_react34.useEffect)(() => {
23015
23154
  const cb = onSelectionChangeRef.current;
23016
23155
  let next = null;
23017
23156
  if (selectedIds.size > 1) {
@@ -23053,8 +23192,8 @@ var SystemCanvas = (() => {
23053
23192
  }
23054
23193
  cb?.(next);
23055
23194
  }, [selectedIds, selectedEdgeId, currentCanvasRef, nodeMap, edges]);
23056
- const [containerSize, setContainerSize] = (0, import_react33.useState)({ width: 0, height: 0 });
23057
- (0, import_react33.useEffect)(() => {
23195
+ const [containerSize, setContainerSize] = (0, import_react34.useState)({ width: 0, height: 0 });
23196
+ (0, import_react34.useEffect)(() => {
23058
23197
  const el = containerRef.current;
23059
23198
  if (!el)
23060
23199
  return;
@@ -23069,14 +23208,14 @@ var SystemCanvas = (() => {
23069
23208
  }, []);
23070
23209
  const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
23071
23210
  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]);
23211
+ const getViewportState = (0, import_react34.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
23212
+ const { matchingIds, dimmedIds } = (0, import_react34.useMemo)(() => computeNodeFilter(nodes, searchOpen ? searchQuery : "", hiddenCategories), [nodes, searchQuery, searchOpen, hiddenCategories]);
23213
+ const matchingIdsArray = (0, import_react34.useMemo)(() => Array.from(matchingIds), [matchingIds]);
23075
23214
  const activeMatchId = matchingIdsArray[searchIndex];
23076
- (0, import_react33.useEffect)(() => {
23215
+ (0, import_react34.useEffect)(() => {
23077
23216
  setSearchIndex(0);
23078
23217
  }, [matchingIds]);
23079
- const panToMatch = (0, import_react33.useCallback)((index) => {
23218
+ const panToMatch = (0, import_react34.useCallback)((index) => {
23080
23219
  const id2 = matchingIdsArray[index];
23081
23220
  if (!id2)
23082
23221
  return;
@@ -23090,21 +23229,21 @@ var SystemCanvas = (() => {
23090
23229
  durationMs: 400
23091
23230
  });
23092
23231
  }, [matchingIdsArray]);
23093
- const goNextMatch = (0, import_react33.useCallback)(() => {
23232
+ const goNextMatch = (0, import_react34.useCallback)(() => {
23094
23233
  if (matchingIdsArray.length === 0)
23095
23234
  return;
23096
23235
  const next = (searchIndex + 1) % matchingIdsArray.length;
23097
23236
  setSearchIndex(next);
23098
23237
  panToMatch(next);
23099
23238
  }, [matchingIdsArray, searchIndex, panToMatch]);
23100
- const goPrevMatch = (0, import_react33.useCallback)(() => {
23239
+ const goPrevMatch = (0, import_react34.useCallback)(() => {
23101
23240
  if (matchingIdsArray.length === 0)
23102
23241
  return;
23103
23242
  const prev = (searchIndex - 1 + matchingIdsArray.length) % matchingIdsArray.length;
23104
23243
  setSearchIndex(prev);
23105
23244
  panToMatch(prev);
23106
23245
  }, [matchingIdsArray, searchIndex, panToMatch]);
23107
- const applyLaneSnap = (0, import_react33.useCallback)((id2, patch) => {
23246
+ const applyLaneSnap = (0, import_react34.useCallback)((id2, patch) => {
23108
23247
  if (!snapToLanes)
23109
23248
  return patch;
23110
23249
  const cols = currentCanvas.columns;
@@ -23129,10 +23268,10 @@ var SystemCanvas = (() => {
23129
23268
  }
23130
23269
  return final;
23131
23270
  }, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
23132
- const commitResize = (0, import_react33.useCallback)((id2, patch) => {
23271
+ const commitResize = (0, import_react34.useCallback)((id2, patch) => {
23133
23272
  wrappedOnNodeUpdate(id2, applyLaneSnap(id2, patch), currentCanvasRef);
23134
23273
  }, [wrappedOnNodeUpdate, currentCanvasRef, applyLaneSnap]);
23135
- const commitDragBatch = (0, import_react33.useCallback)((updates) => {
23274
+ const commitDragBatch = (0, import_react34.useCallback)((updates) => {
23136
23275
  const final = updates.map((u) => ({
23137
23276
  id: u.id,
23138
23277
  patch: applyLaneSnap(u.id, u.patch)
@@ -23147,7 +23286,7 @@ var SystemCanvas = (() => {
23147
23286
  wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
23148
23287
  }
23149
23288
  }, [wrappedOnNodeUpdate, wrappedOnNodesUpdate, onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
23150
- const handleNodeDrop = (0, import_react33.useCallback)((sources, target) => {
23289
+ const handleNodeDrop = (0, import_react34.useCallback)((sources, target) => {
23151
23290
  onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
23152
23291
  }, [onNodeDrop, currentCanvasRef]);
23153
23292
  const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown, cancelDrag, isDragging } = useNodeDrag({
@@ -23172,7 +23311,7 @@ var SystemCanvas = (() => {
23172
23311
  threshold: guideThreshold ?? 4
23173
23312
  });
23174
23313
  const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
23175
- const selectedResolvedNode = (0, import_react33.useMemo)(() => {
23314
+ const selectedResolvedNode = (0, import_react34.useMemo)(() => {
23176
23315
  if (!singleSelectedId)
23177
23316
  return null;
23178
23317
  const base = nodeMap.get(singleSelectedId);
@@ -23189,7 +23328,7 @@ var SystemCanvas = (() => {
23189
23328
  return base;
23190
23329
  }, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
23191
23330
  svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
23192
- const handleEdgeCreated = (0, import_react33.useCallback)((edge) => {
23331
+ const handleEdgeCreated = (0, import_react34.useCallback)((edge) => {
23193
23332
  wrappedOnEdgeAdd(edge, currentCanvasRef);
23194
23333
  }, [wrappedOnEdgeAdd, currentCanvasRef]);
23195
23334
  const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
@@ -23198,7 +23337,7 @@ var SystemCanvas = (() => {
23198
23337
  nodesRef,
23199
23338
  onCreate: handleEdgeCreated
23200
23339
  });
23201
- const handleNavigableNodeClick = (0, import_react33.useCallback)((node) => {
23340
+ const handleNavigableNodeClick = (0, import_react34.useCallback)((node) => {
23202
23341
  if (externalNavigation) {
23203
23342
  if (node.ref)
23204
23343
  onNavigate?.(node.ref);
@@ -23230,7 +23369,7 @@ var SystemCanvas = (() => {
23230
23369
  navigateToRef(node);
23231
23370
  }
23232
23371
  }, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled, externalNavigation, onNavigate]);
23233
- const handleZoomEnter = (0, import_react33.useCallback)((node, targetTransform) => {
23372
+ const handleZoomEnter = (0, import_react34.useCallback)((node, targetTransform) => {
23234
23373
  const frame2 = {
23235
23374
  parentCanvasRef: currentCanvasRef,
23236
23375
  parentNodeRect: {
@@ -23244,7 +23383,7 @@ var SystemCanvas = (() => {
23244
23383
  setPendingHandoff(targetTransform);
23245
23384
  navigateToRef(node);
23246
23385
  }, [currentCanvasRef, navigateToRef]);
23247
- const handleZoomExit = (0, import_react33.useCallback)((targetTransform) => {
23386
+ const handleZoomExit = (0, import_react34.useCallback)((targetTransform) => {
23248
23387
  setPendingHandoff(targetTransform);
23249
23388
  suppressNextHandoffClearRef.current = true;
23250
23389
  navigateToBreadcrumb(breadcrumbs.length - 2);
@@ -23271,41 +23410,43 @@ var SystemCanvas = (() => {
23271
23410
  onEnter: handleZoomEnter,
23272
23411
  onExit: handleZoomExit
23273
23412
  });
23274
- const handleViewportChange = (0, import_react33.useCallback)((vp) => {
23413
+ const handleViewportChange = (0, import_react34.useCallback)((vp) => {
23275
23414
  viewportStateRef.current = vp;
23276
23415
  setCollaboratorViewport(vp);
23277
23416
  handleZoomNavViewportChange(vp);
23278
23417
  onViewportChange?.(vp);
23279
23418
  }, [handleZoomNavViewportChange, onViewportChange]);
23280
- const handleHandoffApplied = (0, import_react33.useCallback)(() => {
23419
+ const handleHandoffApplied = (0, import_react34.useCallback)(() => {
23281
23420
  setPendingHandoff(null);
23282
23421
  clearZoomNavCommitting();
23283
23422
  }, [clearZoomNavCommitting]);
23284
- const handleBeginEdit = (0, import_react33.useCallback)((node) => {
23423
+ const handleBeginEdit = (0, import_react34.useCallback)((node) => {
23285
23424
  setEditingId(node.id);
23286
23425
  }, []);
23287
- const handleBeginEditEdge = (0, import_react33.useCallback)((edge) => {
23426
+ const handleBeginEditEdge = (0, import_react34.useCallback)((edge) => {
23288
23427
  setEditingEdgeId(edge.id);
23289
23428
  }, []);
23290
- const handleAlign = (0, import_react33.useCallback)((direction) => {
23429
+ const handleAlign = (0, import_react34.useCallback)((direction) => {
23291
23430
  const selectedNodes = Array.from(selectedIds).map((id2) => nodesRef.current.find((n) => n.id === id2)).filter((n) => n != null);
23292
23431
  const updates = alignNodes(selectedNodes, direction);
23293
23432
  if (updates.length > 0)
23294
23433
  wrappedOnNodesUpdate(updates, currentCanvasRef);
23295
23434
  }, [selectedIds, nodesRef, wrappedOnNodesUpdate, currentCanvasRef]);
23296
- const handleDistribute = (0, import_react33.useCallback)((axis) => {
23435
+ const handleDistribute = (0, import_react34.useCallback)((axis) => {
23297
23436
  const selectedNodes = Array.from(selectedIds).map((id2) => nodesRef.current.find((n) => n.id === id2)).filter((n) => n != null);
23298
23437
  const updates = distributeNodes(selectedNodes, axis);
23299
23438
  if (updates.length > 0)
23300
23439
  wrappedOnNodesUpdate(updates, currentCanvasRef);
23301
23440
  }, [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)(() => {
23441
+ const [contextMenuState, setContextMenuState] = (0, import_react34.useState)(null);
23442
+ const [edgeContextMenuState, setEdgeContextMenuState] = (0, import_react34.useState)(null);
23443
+ const [canvasContextMenuState, setCanvasContextMenuState] = (0, import_react34.useState)(null);
23444
+ (0, import_react34.useEffect)(() => {
23305
23445
  setContextMenuState(null);
23306
23446
  setEdgeContextMenuState(null);
23447
+ setCanvasContextMenuState(null);
23307
23448
  }, [currentCanvasRef]);
23308
- const handleContextMenu = (0, import_react33.useCallback)((event) => {
23449
+ const handleContextMenu = (0, import_react34.useCallback)((event) => {
23309
23450
  onContextMenu?.(event);
23310
23451
  if (event.type === "node") {
23311
23452
  if (!nodeContextMenu && !alignDistributeMenu)
@@ -23363,9 +23504,16 @@ var SystemCanvas = (() => {
23363
23504
  screenPosition: event.screenPosition,
23364
23505
  canvasRef: currentCanvasRef ?? null
23365
23506
  });
23507
+ } else if (event.type === "canvas" && canvasContextMenu && canvasContextMenu.items.length > 0) {
23508
+ setCanvasContextMenuState({
23509
+ items: canvasContextMenu.items,
23510
+ screenPosition: event.screenPosition,
23511
+ position: event.position,
23512
+ canvasRef: currentCanvasRef ?? null
23513
+ });
23366
23514
  }
23367
- }, [onContextMenu, nodeContextMenu, edgeContextMenu, currentCanvasRef, alignDistributeMenu, selectedIds]);
23368
- const effectiveNodeContextMenu = (0, import_react33.useMemo)(() => {
23515
+ }, [onContextMenu, nodeContextMenu, edgeContextMenu, canvasContextMenu, currentCanvasRef, alignDistributeMenu, selectedIds]);
23516
+ const effectiveNodeContextMenu = (0, import_react34.useMemo)(() => {
23369
23517
  if (!nodeContextMenu && !alignDistributeMenu)
23370
23518
  return null;
23371
23519
  const baseItems = nodeContextMenu?.items ?? [];
@@ -23426,30 +23574,30 @@ var SystemCanvas = (() => {
23426
23574
  onSelectEdge: setSelectedEdgeId,
23427
23575
  onBeginEditEdge: handleBeginEditEdge
23428
23576
  });
23429
- const handleEditorCommit = (0, import_react33.useCallback)((patch) => {
23577
+ const handleEditorCommit = (0, import_react34.useCallback)((patch) => {
23430
23578
  if (editingId) {
23431
23579
  wrappedOnNodeUpdate(editingId, patch, currentCanvasRef);
23432
23580
  }
23433
23581
  setEditingId(null);
23434
23582
  }, [editingId, wrappedOnNodeUpdate, currentCanvasRef]);
23435
- const handleEditorCancel = (0, import_react33.useCallback)(() => {
23583
+ const handleEditorCancel = (0, import_react34.useCallback)(() => {
23436
23584
  setEditingId(null);
23437
23585
  }, []);
23438
- const handleEdgeEditorCommit = (0, import_react33.useCallback)((patch) => {
23586
+ const handleEdgeEditorCommit = (0, import_react34.useCallback)((patch) => {
23439
23587
  if (editingEdgeId) {
23440
23588
  wrappedOnEdgeUpdate(editingEdgeId, patch, currentCanvasRef);
23441
23589
  }
23442
23590
  setEditingEdgeId(null);
23443
23591
  }, [editingEdgeId, wrappedOnEdgeUpdate, currentCanvasRef]);
23444
- const handleEdgeEditorCancel = (0, import_react33.useCallback)(() => {
23592
+ const handleEdgeEditorCancel = (0, import_react34.useCallback)(() => {
23445
23593
  setEditingEdgeId(null);
23446
23594
  }, []);
23447
- const handleEdgeWaypointUpdate = (0, import_react33.useCallback)((edgeId, patch) => {
23595
+ const handleEdgeWaypointUpdate = (0, import_react34.useCallback)((edgeId, patch) => {
23448
23596
  wrappedOnEdgeUpdate(edgeId, patch, currentCanvasRef);
23449
23597
  }, [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) => {
23598
+ const lastAddRef = (0, import_react34.useRef)(null);
23599
+ const menuOptions = (0, import_react34.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
23600
+ const addNode2 = (0, import_react34.useCallback)((option, position) => {
23453
23601
  let x, y;
23454
23602
  if (position) {
23455
23603
  x = position.x;
@@ -23481,7 +23629,7 @@ var SystemCanvas = (() => {
23481
23629
  const node = createNodeFromOption(option, Math.round(x), Math.round(y), void 0, theme);
23482
23630
  wrappedOnNodeAdd(node, currentCanvasRef);
23483
23631
  }, [wrappedOnNodeAdd, currentCanvasRef, theme]);
23484
- const fitSelection = (0, import_react33.useCallback)(() => {
23632
+ const fitSelection = (0, import_react34.useCallback)(() => {
23485
23633
  const handle = viewportHandleRef.current;
23486
23634
  if (!handle)
23487
23635
  return;
@@ -23529,6 +23677,8 @@ var SystemCanvas = (() => {
23529
23677
  setEditingId,
23530
23678
  setEditingEdgeId,
23531
23679
  setSelectedEdgeId,
23680
+ canvasContextMenuState,
23681
+ setCanvasContextMenuState,
23532
23682
  cancelDrag,
23533
23683
  fitSelection
23534
23684
  });
@@ -23547,8 +23697,8 @@ var SystemCanvas = (() => {
23547
23697
  },
23548
23698
  theme
23549
23699
  };
23550
- const prevNodePositionsRef = (0, import_react33.useRef)(/* @__PURE__ */ new Map());
23551
- (0, import_react33.useEffect)(() => {
23700
+ const prevNodePositionsRef = (0, import_react34.useRef)(/* @__PURE__ */ new Map());
23701
+ (0, import_react34.useEffect)(() => {
23552
23702
  const collaboratorSelectedNodeIds = new Set(collaborators.map((c) => c.selectedNodeId).filter((id2) => !!id2));
23553
23703
  if (collaboratorSelectedNodeIds.size === 0) {
23554
23704
  prevNodePositionsRef.current = new Map(nodes.map((n) => [n.id, { x: n.x, y: n.y }]));
@@ -23586,7 +23736,7 @@ var SystemCanvas = (() => {
23586
23736
  }, 620);
23587
23737
  }
23588
23738
  }, [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) => {
23739
+ 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
23740
  e.preventDefault();
23591
23741
  const file = e.dataTransfer.files?.[0];
23592
23742
  if (!file)
@@ -23604,7 +23754,7 @@ var SystemCanvas = (() => {
23604
23754
  overflow: "hidden",
23605
23755
  outline: "none",
23606
23756
  ...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: {
23757
+ }, 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
23758
  position: "absolute",
23609
23759
  top: 12,
23610
23760
  left: 12,
@@ -23620,7 +23770,7 @@ var SystemCanvas = (() => {
23620
23770
  fontSize: 12,
23621
23771
  backdropFilter: "blur(8px)",
23622
23772
  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: {
23773
+ }, 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
23774
  background: "none",
23625
23775
  border: "none",
23626
23776
  cursor: "pointer",
@@ -23629,7 +23779,7 @@ var SystemCanvas = (() => {
23629
23779
  fontSize: 14,
23630
23780
  lineHeight: 1,
23631
23781
  opacity: 0.7
23632
- }, children: "\xD7" })] }), isLoading && (0, import_jsx_runtime34.jsx)("div", { className: "system-canvas-loading", style: {
23782
+ }, children: "\xD7" })] }), isLoading && (0, import_jsx_runtime35.jsx)("div", { className: "system-canvas-loading", style: {
23633
23783
  position: "absolute",
23634
23784
  top: 12,
23635
23785
  right: 12,
@@ -23641,7 +23791,7 @@ var SystemCanvas = (() => {
23641
23791
  fontFamily: theme.node.fontFamily,
23642
23792
  fontSize: 12,
23643
23793
  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) => {
23794
+ }, 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
23795
  wrappedOnNodeUpdate(selectedResolvedNode.id, update, currentCanvasRef);
23646
23796
  }, onDelete: () => {
23647
23797
  wrappedOnNodeDelete(selectedResolvedNode.id, currentCanvasRef);
@@ -23651,7 +23801,7 @@ var SystemCanvas = (() => {
23651
23801
  if (selectedResolvedNodes.length === 0)
23652
23802
  return null;
23653
23803
  const anchorNode = selectedResolvedNodes[0];
23654
- return (0, import_jsx_runtime34.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
23804
+ return (0, import_jsx_runtime35.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
23655
23805
  }, onMultiPatch: (patch) => {
23656
23806
  const updates = Array.from(selectedIds).map((id2) => ({ id: id2, patch }));
23657
23807
  wrappedOnNodesUpdate(updates, currentCanvasRef);
@@ -23659,7 +23809,7 @@ var SystemCanvas = (() => {
23659
23809
  wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
23660
23810
  clearSelection();
23661
23811
  }, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, onAlign: handleAlign, onDistribute: handleDistribute });
23662
- })(), (0, import_jsx_runtime34.jsxs)("div", { style: {
23812
+ })(), (0, import_jsx_runtime35.jsxs)("div", { style: {
23663
23813
  position: "absolute",
23664
23814
  bottom: 16,
23665
23815
  right: 16,
@@ -23669,7 +23819,7 @@ var SystemCanvas = (() => {
23669
23819
  gap: 8,
23670
23820
  zIndex: 15,
23671
23821
  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) => {
23822
+ }, 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
23823
  const next = new Set(prev);
23674
23824
  next.has(cat) ? next.delete(cat) : next.add(cat);
23675
23825
  return next;
@@ -23784,7 +23934,7 @@ var SystemCanvas = (() => {
23784
23934
  onEdgeUpdate: handleEdgeUpdate,
23785
23935
  onEdgeDelete: handleEdgeDelete
23786
23936
  };
23787
- root2.render(import_react34.default.createElement(SystemCanvas, props));
23937
+ root2.render(import_react35.default.createElement(SystemCanvas, props));
23788
23938
  };
23789
23939
  doRender();
23790
23940
  return {