@pipelex/mthds-ui 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,22 +13,22 @@ import {
13
13
  findStuffByDigest,
14
14
  fitRoute,
15
15
  getLayoutedElements,
16
- getPipeBlueprint,
17
16
  resolveConceptRef,
18
17
  resolveGraphStyle,
19
18
  resolveIssueTargetNodeId,
19
+ resolveNodeBlueprint,
20
20
  resolveStyleMenu,
21
21
  roundedPolylinePath,
22
22
  routeLabelCenter,
23
23
  validateGraphSpec
24
- } from "../../chunk-BXRVND2C.js";
24
+ } from "../../chunk-ABUDTHWF.js";
25
25
  import {
26
26
  parsePipeRef
27
27
  } from "../../chunk-2N65P32H.js";
28
28
  import {
29
29
  DEFAULT_GRAPH_CONFIG,
30
30
  getPaletteForTheme
31
- } from "../../chunk-7H3RHOYA.js";
31
+ } from "../../chunk-K2C5FU4W.js";
32
32
  import {
33
33
  BINDING_STEP_TYPE,
34
34
  EDGE_TYPE,
@@ -55,7 +55,7 @@ import {
55
55
  stuffDigestFromId,
56
56
  toolbarOrientation,
57
57
  toolbarSide
58
- } from "../../chunk-QRO3TYZE.js";
58
+ } from "../../chunk-TMZ2JR2J.js";
59
59
  import {
60
60
  __spreadProps,
61
61
  __spreadValues
@@ -68,7 +68,7 @@ import "./viewer/GraphToolbar.css";
68
68
  import "./styles/simple/SimpleStyle.css";
69
69
 
70
70
  // src/graph/react/viewer/GraphViewer.tsx
71
- import React12 from "react";
71
+ import React13 from "react";
72
72
  import {
73
73
  ReactFlow,
74
74
  useNodesState,
@@ -477,20 +477,52 @@ function ModelRows({
477
477
  handle,
478
478
  label = "Model"
479
479
  }) {
480
+ var _a, _b, _c;
480
481
  const ran = modelsRan != null ? modelsRan : [];
481
- const ranLabels = ran.map(
482
- (entry) => ran.length > 1 ? `${entry.inference_model_name} (${entry.inference_calls})` : entry.inference_model_name
483
- );
484
- const chain = [];
485
- for (const rung of [authored, handle, ...ranLabels]) {
486
- if (rung && rung !== chain[chain.length - 1]) chain.push(rung);
482
+ const nameCounts = /* @__PURE__ */ new Map();
483
+ for (const entry of ran) {
484
+ nameCounts.set(
485
+ entry.inference_model_name,
486
+ ((_a = nameCounts.get(entry.inference_model_name)) != null ? _a : 0) + 1
487
+ );
488
+ }
489
+ const ranRungs = ran.map((entry, index) => {
490
+ var _a2;
491
+ const name = ((_a2 = nameCounts.get(entry.inference_model_name)) != null ? _a2 : 0) > 1 ? `${entry.inference_model_name} \xB7 ${modelTypeLabel(entry.model_type)}` : entry.inference_model_name;
492
+ return {
493
+ key: `ran-${index}`,
494
+ text: ran.length > 1 ? `${name} (${entry.inference_calls})` : name
495
+ };
496
+ });
497
+ const requested = [];
498
+ const requestedRungs = [
499
+ { key: "authored", text: authored != null ? authored : "" },
500
+ { key: "handle", text: handle != null ? handle : "" }
501
+ ];
502
+ for (const rung of requestedRungs) {
503
+ if (rung.text && rung.text !== ((_b = requested[requested.length - 1]) == null ? void 0 : _b.text)) requested.push(rung);
504
+ }
505
+ if (ranRungs.length > 0 && ((_c = requested[requested.length - 1]) == null ? void 0 : _c.text) === ranRungs[0].text) {
506
+ requested.pop();
487
507
  }
508
+ const chain = [...requested, ...ranRungs];
488
509
  if (chain.length === 0) return null;
489
510
  return /* @__PURE__ */ jsxs3("div", { className: "detail-kv-row", children: [
490
511
  /* @__PURE__ */ jsx3("span", { className: "detail-kv-key", children: label }),
491
- /* @__PURE__ */ jsx3("span", { className: "detail-kv-value detail-model-value", children: chain.map((rung, index) => /* @__PURE__ */ jsx3("span", { className: index === 0 ? void 0 : "detail-model-resolved", children: rung }, rung)) })
512
+ /* @__PURE__ */ jsx3("span", { className: "detail-kv-value detail-model-value", children: chain.map((rung, index) => /* @__PURE__ */ jsx3("span", { className: index === 0 ? void 0 : "detail-model-resolved", children: rung.text }, rung.key)) })
492
513
  ] });
493
514
  }
515
+ var MODEL_TYPE_LABELS = {
516
+ llm: "LLM",
517
+ extract: "extraction",
518
+ img_gen: "image generation",
519
+ search: "search",
520
+ judgment: "judgment"
521
+ };
522
+ function modelTypeLabel(modelType) {
523
+ var _a;
524
+ return (_a = MODEL_TYPE_LABELS[modelType]) != null ? _a : modelType.replaceAll("_", " ");
525
+ }
494
526
 
495
527
  // src/graph/usageFormat.ts
496
528
  function scopeUsage(usage, scope) {
@@ -529,8 +561,9 @@ function formatCost(cost) {
529
561
  if (cost > 0 && cost < 1e-4) return "<$0.0001";
530
562
  return `$${cost.toFixed(4)}`;
531
563
  }
564
+ var TOKEN_BILLED_MODEL_TYPES = /* @__PURE__ */ new Set(["llm", "judgment"]);
532
565
  function hasRealTokenCounts(scoped) {
533
- return scoped.models.length > 0 && scoped.models.every((entry) => entry.model_type === "llm");
566
+ return scoped.models.length > 0 && scoped.models.every((entry) => TOKEN_BILLED_MODEL_TYPES.has(entry.model_type));
534
567
  }
535
568
 
536
569
  // src/graph/react/detail/sections/UsageSection.tsx
@@ -979,27 +1012,74 @@ function PipeComposeSection({
979
1012
  ] });
980
1013
  }
981
1014
 
982
- // src/graph/react/detail/sections/PipeConditionDetail.tsx
1015
+ // src/graph/react/detail/sections/PipeDocGenDetail.tsx
983
1016
  import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1017
+ var DOC_GEN_SOURCE_LABELS = {
1018
+ layout: "auto-layout",
1019
+ html: "HTML template",
1020
+ template_file: "template file"
1021
+ };
1022
+ function declaredSource(blueprint) {
1023
+ if (blueprint.template == null && blueprint.template_file == null) return "layout";
1024
+ if (blueprint.template != null || blueprint.doc_gen_format === "pdf") return "html";
1025
+ return "template_file";
1026
+ }
1027
+ function nonEmpty(value) {
1028
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
1029
+ }
1030
+ function PipeDocGenSection({
1031
+ blueprint,
1032
+ executionData,
1033
+ modelsRan,
1034
+ modelHandles
1035
+ }) {
1036
+ var _a, _b, _c;
1037
+ const format = nonEmpty(blueprint.doc_gen_format);
1038
+ const authoredEngine = labelFromLlmChoice(blueprint.doc_gen_choice);
1039
+ const resolvedEngine = nonEmpty(modelHandles == null ? void 0 : modelHandles.resolved_model);
1040
+ const hasEngine = !!authoredEngine || !!resolvedEngine || ((_a = modelsRan == null ? void 0 : modelsRan.length) != null ? _a : 0) > 0;
1041
+ const source = (_b = nonEmpty(modelHandles == null ? void 0 : modelHandles.source)) != null ? _b : declaredSource(blueprint);
1042
+ const renderedFilename = nonEmpty(executionData == null ? void 0 : executionData.filename);
1043
+ return /* @__PURE__ */ jsxs11(Fragment7, { children: [
1044
+ /* @__PURE__ */ jsx11(KV, { label: "Format", value: format == null ? void 0 : format.toUpperCase() }),
1045
+ hasEngine ? /* @__PURE__ */ jsx11(
1046
+ ModelRows,
1047
+ {
1048
+ label: "Engine",
1049
+ modelsRan,
1050
+ authored: authoredEngine,
1051
+ handle: resolvedEngine
1052
+ }
1053
+ ) : /* @__PURE__ */ jsx11(KV, { label: "Engine", value: "deck default" }),
1054
+ /* @__PURE__ */ jsx11(KV, { label: "Source", value: (_c = DOC_GEN_SOURCE_LABELS[source]) != null ? _c : source }),
1055
+ /* @__PURE__ */ jsx11(KV, { label: "Template File", value: blueprint.template_file }),
1056
+ /* @__PURE__ */ jsx11(KV, { label: "File Name", value: blueprint.filename }),
1057
+ renderedFilename && renderedFilename !== blueprint.filename && /* @__PURE__ */ jsx11(KV, { label: "Stored As", value: renderedFilename }),
1058
+ blueprint.template && /* @__PURE__ */ jsx11(PromptToggle, { label: "Template", templateText: blueprint.template, renderedText: null })
1059
+ ] });
1060
+ }
1061
+
1062
+ // src/graph/react/detail/sections/PipeConditionDetail.tsx
1063
+ import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
984
1064
  function PipeConditionSection({
985
1065
  blueprint,
986
1066
  executionData
987
1067
  }) {
988
1068
  const evaluatedExpression = executionData == null ? void 0 : executionData.evaluated_expression;
989
1069
  const selectedOutcome = executionData == null ? void 0 : executionData.selected_outcome;
990
- return /* @__PURE__ */ jsxs11(Fragment7, { children: [
991
- /* @__PURE__ */ jsx11(PromptBlock, { label: "Expression", text: blueprint.expression }),
992
- evaluatedExpression && /* @__PURE__ */ jsx11(KV, { label: "Expression Result", value: evaluatedExpression }),
993
- /* @__PURE__ */ jsxs11("div", { children: [
994
- /* @__PURE__ */ jsx11("div", { className: "detail-section-label", children: "Outcomes" }),
995
- Object.entries(blueprint.outcome_map).map(([outcome, pipeCode]) => /* @__PURE__ */ jsxs11(
1070
+ return /* @__PURE__ */ jsxs12(Fragment8, { children: [
1071
+ /* @__PURE__ */ jsx12(PromptBlock, { label: "Expression", text: blueprint.expression }),
1072
+ evaluatedExpression && /* @__PURE__ */ jsx12(KV, { label: "Expression Result", value: evaluatedExpression }),
1073
+ /* @__PURE__ */ jsxs12("div", { children: [
1074
+ /* @__PURE__ */ jsx12("div", { className: "detail-section-label", children: "Outcomes" }),
1075
+ Object.entries(blueprint.outcome_map).map(([outcome, pipeCode]) => /* @__PURE__ */ jsxs12(
996
1076
  "div",
997
1077
  {
998
1078
  className: "detail-kv-row",
999
1079
  style: selectedOutcome === pipeCode ? { background: "rgba(80,250,123,0.08)" } : void 0,
1000
1080
  children: [
1001
- /* @__PURE__ */ jsx11("span", { className: "detail-kv-key", children: outcome }),
1002
- /* @__PURE__ */ jsx11(
1081
+ /* @__PURE__ */ jsx12("span", { className: "detail-kv-key", children: outcome }),
1082
+ /* @__PURE__ */ jsx12(
1003
1083
  "span",
1004
1084
  {
1005
1085
  className: "detail-kv-value",
@@ -1011,32 +1091,32 @@ function PipeConditionSection({
1011
1091
  },
1012
1092
  outcome
1013
1093
  )),
1014
- /* @__PURE__ */ jsxs11("div", { className: "detail-kv-row", children: [
1015
- /* @__PURE__ */ jsx11("span", { className: "detail-kv-key", children: "default" }),
1016
- /* @__PURE__ */ jsx11("span", { className: "detail-kv-value", children: blueprint.default_outcome })
1094
+ /* @__PURE__ */ jsxs12("div", { className: "detail-kv-row", children: [
1095
+ /* @__PURE__ */ jsx12("span", { className: "detail-kv-key", children: "default" }),
1096
+ /* @__PURE__ */ jsx12("span", { className: "detail-kv-value", children: blueprint.default_outcome })
1017
1097
  ] })
1018
1098
  ] }),
1019
- /* @__PURE__ */ jsx11(KV, { label: "Alias Expression To", value: blueprint.add_alias_from_expression_to })
1099
+ /* @__PURE__ */ jsx12(KV, { label: "Alias Expression To", value: blueprint.add_alias_from_expression_to })
1020
1100
  ] });
1021
1101
  }
1022
1102
 
1023
1103
  // src/graph/react/detail/sections/PipeSequenceDetail.tsx
1024
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1104
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1025
1105
  function PipeSequenceSection({
1026
1106
  blueprint
1027
1107
  }) {
1028
- return /* @__PURE__ */ jsxs12("div", { children: [
1029
- /* @__PURE__ */ jsx12("div", { className: "detail-section-label", children: "Steps" }),
1030
- /* @__PURE__ */ jsx12("div", { className: "detail-steps-list", children: blueprint.sequential_sub_pipes.map((step, idx) => /* @__PURE__ */ jsxs12("div", { className: "detail-step-item", children: [
1031
- /* @__PURE__ */ jsx12("span", { className: "detail-step-index", children: idx + 1 }),
1108
+ return /* @__PURE__ */ jsxs13("div", { children: [
1109
+ /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Steps" }),
1110
+ /* @__PURE__ */ jsx13("div", { className: "detail-steps-list", children: blueprint.sequential_sub_pipes.map((step, idx) => /* @__PURE__ */ jsxs13("div", { className: "detail-step-item", children: [
1111
+ /* @__PURE__ */ jsx13("span", { className: "detail-step-index", children: idx + 1 }),
1032
1112
  isBindingStepSpec(step) ? (
1033
1113
  // A binding step runs no pipe: it names the path it binds.
1034
- /* @__PURE__ */ jsxs12("span", { className: "detail-step-code", title: "Binding step", children: [
1114
+ /* @__PURE__ */ jsxs13("span", { className: "detail-step-code", title: "Binding step", children: [
1035
1115
  "from ",
1036
1116
  step.from_path
1037
1117
  ] })
1038
- ) : /* @__PURE__ */ jsx12("span", { className: "detail-step-code", children: step.pipe_code }),
1039
- step.output_name && /* @__PURE__ */ jsxs12("span", { className: "detail-io-concept", children: [
1118
+ ) : /* @__PURE__ */ jsx13("span", { className: "detail-step-code", children: step.pipe_code }),
1119
+ step.output_name && /* @__PURE__ */ jsxs13("span", { className: "detail-io-concept", children: [
1040
1120
  "-> ",
1041
1121
  step.output_name
1042
1122
  ] })
@@ -1045,52 +1125,52 @@ function PipeSequenceSection({
1045
1125
  }
1046
1126
 
1047
1127
  // src/graph/react/detail/sections/PipeParallelDetail.tsx
1048
- import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1128
+ import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1049
1129
  function PipeParallelSection({
1050
1130
  blueprint
1051
1131
  }) {
1052
- return /* @__PURE__ */ jsxs13(Fragment8, { children: [
1053
- /* @__PURE__ */ jsxs13("div", { children: [
1054
- /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Branches" }),
1055
- /* @__PURE__ */ jsx13("div", { className: "detail-steps-list", children: blueprint.parallel_sub_pipes.map((branch, idx) => /* @__PURE__ */ jsxs13("div", { className: "detail-step-item", children: [
1056
- /* @__PURE__ */ jsx13("span", { className: "detail-step-code", children: branch.pipe_code }),
1057
- branch.output_name && /* @__PURE__ */ jsxs13("span", { className: "detail-io-concept", children: [
1132
+ return /* @__PURE__ */ jsxs14(Fragment9, { children: [
1133
+ /* @__PURE__ */ jsxs14("div", { children: [
1134
+ /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Branches" }),
1135
+ /* @__PURE__ */ jsx14("div", { className: "detail-steps-list", children: blueprint.parallel_sub_pipes.map((branch, idx) => /* @__PURE__ */ jsxs14("div", { className: "detail-step-item", children: [
1136
+ /* @__PURE__ */ jsx14("span", { className: "detail-step-code", children: branch.pipe_code }),
1137
+ branch.output_name && /* @__PURE__ */ jsxs14("span", { className: "detail-io-concept", children: [
1058
1138
  "-> ",
1059
1139
  branch.output_name
1060
1140
  ] })
1061
1141
  ] }, idx)) })
1062
1142
  ] }),
1063
- /* @__PURE__ */ jsx13(KV, { label: "Add Each Output", value: blueprint.add_each_output }),
1064
- /* @__PURE__ */ jsx13(KV, { label: "Combined Output", value: blueprint.combined_output })
1143
+ /* @__PURE__ */ jsx14(KV, { label: "Add Each Output", value: blueprint.add_each_output }),
1144
+ /* @__PURE__ */ jsx14(KV, { label: "Combined Output", value: blueprint.combined_output })
1065
1145
  ] });
1066
1146
  }
1067
1147
 
1068
1148
  // src/graph/react/detail/sections/PipeBatchDetail.tsx
1069
- import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1149
+ import { Fragment as Fragment10, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1070
1150
  function PipeBatchSection({
1071
1151
  blueprint,
1072
1152
  executionData
1073
1153
  }) {
1074
1154
  const itemCount = executionData == null ? void 0 : executionData.item_count;
1075
- return /* @__PURE__ */ jsxs14(Fragment9, { children: [
1076
- /* @__PURE__ */ jsx14(KV, { label: "Branch Pipe", value: blueprint.branch_pipe_code }),
1077
- /* @__PURE__ */ jsx14(KV, { label: "Input List Variable", value: blueprint.batch_params.input_list_stuff_name }),
1078
- /* @__PURE__ */ jsx14(KV, { label: "Input Item Variable", value: blueprint.batch_params.input_item_stuff_name }),
1079
- itemCount != null && /* @__PURE__ */ jsx14(KV, { label: "Items Processed", value: itemCount })
1155
+ return /* @__PURE__ */ jsxs15(Fragment10, { children: [
1156
+ /* @__PURE__ */ jsx15(KV, { label: "Branch Pipe", value: blueprint.branch_pipe_code }),
1157
+ /* @__PURE__ */ jsx15(KV, { label: "Input List Variable", value: blueprint.batch_params.input_list_stuff_name }),
1158
+ /* @__PURE__ */ jsx15(KV, { label: "Input Item Variable", value: blueprint.batch_params.input_item_stuff_name }),
1159
+ itemCount != null && /* @__PURE__ */ jsx15(KV, { label: "Items Processed", value: itemCount })
1080
1160
  ] });
1081
1161
  }
1082
1162
 
1083
1163
  // src/graph/react/detail/sections/BindingStepDetail.tsx
1084
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1164
+ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
1085
1165
  function BindingStepSection({ node }) {
1086
1166
  var _a, _b;
1087
1167
  const executionData = (_a = node.execution_data) != null ? _a : {};
1088
1168
  const fromPath = typeof executionData.from === "string" ? executionData.from : node.pipe_code;
1089
1169
  const result = typeof executionData.result === "string" ? executionData.result : (_b = node.io.outputs[0]) == null ? void 0 : _b.name;
1090
- return /* @__PURE__ */ jsxs15("div", { children: [
1091
- /* @__PURE__ */ jsx15("div", { className: "detail-section-label", children: "Binding" }),
1092
- /* @__PURE__ */ jsx15(KV, { label: "From", value: fromPath }),
1093
- /* @__PURE__ */ jsx15(KV, { label: "Result", value: result })
1170
+ return /* @__PURE__ */ jsxs16("div", { children: [
1171
+ /* @__PURE__ */ jsx16("div", { className: "detail-section-label", children: "Binding" }),
1172
+ /* @__PURE__ */ jsx16(KV, { label: "From", value: fromPath }),
1173
+ /* @__PURE__ */ jsx16(KV, { label: "Result", value: result })
1094
1174
  ] });
1095
1175
  }
1096
1176
 
@@ -1102,18 +1182,27 @@ var MERGED_EXECUTION_DATA_TYPES = /* @__PURE__ */ new Set([
1102
1182
  "PipeSearch",
1103
1183
  "PipeStructure",
1104
1184
  "PipeCompose",
1185
+ "PipeDocGen",
1105
1186
  "PipeSequence",
1106
1187
  "PipeParallel",
1107
1188
  "PipeCondition",
1108
1189
  "PipeBatch"
1109
1190
  ]);
1191
+ var UNDUMPED_EXECUTION_DATA_KEYS = {
1192
+ PipeDocGen: /* @__PURE__ */ new Set(["url"])
1193
+ };
1110
1194
  function shouldDumpExecutionData(pipeType, hasBlueprint) {
1111
1195
  if (MERGED_EXECUTION_DATA_TYPES.has(pipeType)) return !hasBlueprint;
1112
1196
  return true;
1113
1197
  }
1198
+ function dumpableExecutionData(pipeType, executionData) {
1199
+ const undumped = UNDUMPED_EXECUTION_DATA_KEYS[pipeType];
1200
+ const entries = Object.entries(executionData);
1201
+ return undumped ? entries.filter(([key]) => !undumped.has(key)) : entries;
1202
+ }
1114
1203
 
1115
1204
  // src/graph/react/detail/PipeDetailPanel.tsx
1116
- import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
1205
+ import { Fragment as Fragment11, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
1117
1206
  var PIPE_TYPE_BADGES = {
1118
1207
  PipeLLM: "LLM",
1119
1208
  PipeExtract: "Extract",
@@ -1155,32 +1244,22 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1155
1244
  const badge = PIPE_TYPE_BADGES[pipeType];
1156
1245
  const status = node.status;
1157
1246
  const statusColor = (_a = STATUS_COLORS[status]) != null ? _a : "#6272a4";
1158
- const blueprint = React6.useMemo(() => {
1159
- var _a2, _b2;
1160
- if (isBinding || !node.pipe_code || !spec.pipe_registry) return void 0;
1161
- const directKey = `${(_b2 = (_a2 = spec.pipeline_ref) == null ? void 0 : _a2.domain) != null ? _b2 : ""}.${node.pipe_code}`;
1162
- const direct = getPipeBlueprint(spec, directKey);
1163
- if (direct) return direct;
1164
- for (const [ref, pipe] of Object.entries(spec.pipe_registry)) {
1165
- if (ref.endsWith(`.${node.pipe_code}`)) return pipe;
1166
- }
1167
- return void 0;
1168
- }, [isBinding, node.pipe_code, spec]);
1247
+ const blueprint = React6.useMemo(() => resolveNodeBlueprint(spec, node), [spec, node]);
1169
1248
  const [usageExpanded, setUsageExpanded] = React6.useState(false);
1170
1249
  const inputs = (_c = (_b = node.io) == null ? void 0 : _b.inputs) != null ? _c : [];
1171
1250
  const outputs = (_e = (_d = node.io) == null ? void 0 : _d.outputs) != null ? _e : [];
1172
1251
  const description = (_f = blueprint == null ? void 0 : blueprint.description) != null ? _f : node.description;
1173
- return /* @__PURE__ */ jsxs16(Fragment10, { children: [
1174
- /* @__PURE__ */ jsxs16("div", { className: "detail-sticky-header", children: [
1175
- /* @__PURE__ */ jsxs16("div", { className: "detail-header", children: [
1176
- /* @__PURE__ */ jsx16(
1252
+ return /* @__PURE__ */ jsxs17(Fragment11, { children: [
1253
+ /* @__PURE__ */ jsxs17("div", { className: "detail-sticky-header", children: [
1254
+ /* @__PURE__ */ jsxs17("div", { className: "detail-header", children: [
1255
+ /* @__PURE__ */ jsx17(
1177
1256
  "span",
1178
1257
  {
1179
1258
  className: `detail-badge ${isController ? "detail-badge--controller" : "detail-badge--operator"}`,
1180
1259
  children: badge
1181
1260
  }
1182
1261
  ),
1183
- /* @__PURE__ */ jsx16(
1262
+ /* @__PURE__ */ jsx17(
1184
1263
  "span",
1185
1264
  {
1186
1265
  className: `detail-pipe-code ${isController ? "detail-pipe-code--controller" : ""}`,
@@ -1188,11 +1267,11 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1188
1267
  }
1189
1268
  )
1190
1269
  ] }),
1191
- !isStatic && /* @__PURE__ */ jsxs16("div", { className: "detail-status", children: [
1192
- /* @__PURE__ */ jsx16("span", { className: "detail-status-dot", style: { background: statusColor } }),
1193
- /* @__PURE__ */ jsx16("span", { className: "detail-status-label", style: { color: statusColor }, children: status }),
1194
- ((_g = node.timing) == null ? void 0 : _g.duration) != null && /* @__PURE__ */ jsx16("span", { className: "detail-duration", children: formatDuration(node.timing.duration) }),
1195
- showsGeneratedData && node.usage && /* @__PURE__ */ jsx16(
1270
+ !isStatic && /* @__PURE__ */ jsxs17("div", { className: "detail-status", children: [
1271
+ /* @__PURE__ */ jsx17("span", { className: "detail-status-dot", style: { background: statusColor } }),
1272
+ /* @__PURE__ */ jsx17("span", { className: "detail-status-label", style: { color: statusColor }, children: status }),
1273
+ ((_g = node.timing) == null ? void 0 : _g.duration) != null && /* @__PURE__ */ jsx17("span", { className: "detail-duration", children: formatDuration(node.timing.duration) }),
1274
+ showsGeneratedData && node.usage && /* @__PURE__ */ jsx17(
1196
1275
  UsageCostInline,
1197
1276
  {
1198
1277
  usage: node.usage,
@@ -1202,44 +1281,44 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1202
1281
  }
1203
1282
  )
1204
1283
  ] }),
1205
- showsGeneratedData && node.usage && usageExpanded && /* @__PURE__ */ jsx16(UsageDetails, { usage: node.usage, isController }),
1206
- description && /* @__PURE__ */ jsx16("div", { className: "detail-description", children: description }),
1207
- inputs.length > 0 && /* @__PURE__ */ jsxs16("div", { children: [
1208
- /* @__PURE__ */ jsx16("div", { className: "detail-section-label", children: "Inputs" }),
1209
- /* @__PURE__ */ jsx16("div", { className: "detail-io-list", children: inputs.map((input, idx) => /* @__PURE__ */ jsxs16(
1284
+ showsGeneratedData && node.usage && usageExpanded && /* @__PURE__ */ jsx17(UsageDetails, { usage: node.usage, isController }),
1285
+ description && /* @__PURE__ */ jsx17("div", { className: "detail-description", children: description }),
1286
+ inputs.length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
1287
+ /* @__PURE__ */ jsx17("div", { className: "detail-section-label", children: "Inputs" }),
1288
+ /* @__PURE__ */ jsx17("div", { className: "detail-io-list", children: inputs.map((input, idx) => /* @__PURE__ */ jsxs17(
1210
1289
  "div",
1211
1290
  {
1212
1291
  className: "detail-io-pill",
1213
1292
  style: { cursor: input.concept && onConceptClick ? "pointer" : void 0 },
1214
1293
  onClick: () => input.concept && (onConceptClick == null ? void 0 : onConceptClick(input.concept)),
1215
1294
  children: [
1216
- /* @__PURE__ */ jsx16("span", { className: "detail-io-name", children: input.name }),
1217
- input.concept && /* @__PURE__ */ jsx16("span", { className: "detail-io-concept", children: input.concept + multiplicitySuffix(input.multiplicity) })
1295
+ /* @__PURE__ */ jsx17("span", { className: "detail-io-name", children: input.name }),
1296
+ input.concept && /* @__PURE__ */ jsx17("span", { className: "detail-io-concept", children: input.concept + multiplicitySuffix(input.multiplicity) })
1218
1297
  ]
1219
1298
  },
1220
1299
  idx
1221
1300
  )) })
1222
1301
  ] }),
1223
- outputs.length > 0 && /* @__PURE__ */ jsxs16("div", { children: [
1224
- /* @__PURE__ */ jsx16("div", { className: "detail-section-label", children: "Output" }),
1225
- /* @__PURE__ */ jsx16("div", { className: "detail-io-list", children: outputs.map((output, idx) => /* @__PURE__ */ jsxs16(
1302
+ outputs.length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
1303
+ /* @__PURE__ */ jsx17("div", { className: "detail-section-label", children: "Output" }),
1304
+ /* @__PURE__ */ jsx17("div", { className: "detail-io-list", children: outputs.map((output, idx) => /* @__PURE__ */ jsxs17(
1226
1305
  "div",
1227
1306
  {
1228
1307
  className: "detail-io-pill",
1229
1308
  style: { cursor: output.concept && onConceptClick ? "pointer" : void 0 },
1230
1309
  onClick: () => output.concept && (onConceptClick == null ? void 0 : onConceptClick(output.concept)),
1231
1310
  children: [
1232
- /* @__PURE__ */ jsx16("span", { className: "detail-io-name", children: output.name }),
1233
- output.concept && /* @__PURE__ */ jsx16("span", { className: "detail-io-concept", children: output.concept + multiplicitySuffix(output.multiplicity) })
1311
+ /* @__PURE__ */ jsx17("span", { className: "detail-io-name", children: output.name }),
1312
+ output.concept && /* @__PURE__ */ jsx17("span", { className: "detail-io-concept", children: output.concept + multiplicitySuffix(output.multiplicity) })
1234
1313
  ]
1235
1314
  },
1236
1315
  idx
1237
1316
  )) })
1238
1317
  ] }),
1239
- (inputs.length > 0 || outputs.length > 0) && /* @__PURE__ */ jsx16("div", { style: { borderTop: "1px solid rgba(255,255,255,0.06)", margin: "4px 0" } })
1318
+ (inputs.length > 0 || outputs.length > 0) && /* @__PURE__ */ jsx17("div", { style: { borderTop: "1px solid rgba(255,255,255,0.06)", margin: "4px 0" } })
1240
1319
  ] }),
1241
- isBinding && /* @__PURE__ */ jsx16(BindingStepSection, { node }),
1242
- blueprint && /* @__PURE__ */ jsx16(
1320
+ isBinding && /* @__PURE__ */ jsx17(BindingStepSection, { node }),
1321
+ blueprint && /* @__PURE__ */ jsx17(
1243
1322
  BlueprintSection,
1244
1323
  {
1245
1324
  blueprint,
@@ -1248,7 +1327,7 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1248
1327
  modelHandles: node.execution_data
1249
1328
  }
1250
1329
  ),
1251
- showsGeneratedData && !isBinding && node.execution_data && Object.keys(node.execution_data).length > 0 && /* @__PURE__ */ jsx16(
1330
+ showsGeneratedData && !isBinding && node.execution_data && Object.keys(node.execution_data).length > 0 && /* @__PURE__ */ jsx17(
1252
1331
  ExecutionDataSection,
1253
1332
  {
1254
1333
  executionData: node.execution_data,
@@ -1256,14 +1335,14 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1256
1335
  hasBlueprint: !!blueprint
1257
1336
  }
1258
1337
  ),
1259
- node.error && /* @__PURE__ */ jsxs16("div", { className: "detail-error", children: [
1260
- /* @__PURE__ */ jsx16("div", { className: "detail-error-type", children: node.error.error_type }),
1261
- /* @__PURE__ */ jsx16("div", { className: "detail-error-message", children: node.error.message }),
1262
- node.error.stack && /* @__PURE__ */ jsx16("div", { className: "detail-error-stack", children: node.error.stack })
1338
+ node.error && /* @__PURE__ */ jsxs17("div", { className: "detail-error", children: [
1339
+ /* @__PURE__ */ jsx17("div", { className: "detail-error-type", children: node.error.error_type }),
1340
+ /* @__PURE__ */ jsx17("div", { className: "detail-error-message", children: node.error.message }),
1341
+ node.error.stack && /* @__PURE__ */ jsx17("div", { className: "detail-error-stack", children: node.error.stack })
1263
1342
  ] }),
1264
- showsGeneratedData && node.metrics && Object.keys(node.metrics).length > 0 && /* @__PURE__ */ jsxs16("div", { children: [
1265
- /* @__PURE__ */ jsx16("div", { className: "detail-section-label", children: "Metrics" }),
1266
- Object.entries(node.metrics).map(([key, value]) => /* @__PURE__ */ jsx16(
1343
+ showsGeneratedData && node.metrics && Object.keys(node.metrics).length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
1344
+ /* @__PURE__ */ jsx17("div", { className: "detail-section-label", children: "Metrics" }),
1345
+ Object.entries(node.metrics).map(([key, value]) => /* @__PURE__ */ jsx17(
1267
1346
  KV,
1268
1347
  {
1269
1348
  label: key,
@@ -1272,17 +1351,17 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1272
1351
  key
1273
1352
  ))
1274
1353
  ] }),
1275
- node.tags && Object.keys(node.tags).length > 0 && /* @__PURE__ */ jsxs16("div", { children: [
1276
- /* @__PURE__ */ jsx16("div", { className: "detail-section-label", children: "Tags" }),
1277
- /* @__PURE__ */ jsx16("div", { className: "detail-tags", children: Object.entries(node.tags).map(([key, value]) => /* @__PURE__ */ jsxs16("span", { className: "detail-tag", children: [
1278
- /* @__PURE__ */ jsxs16("span", { className: "detail-tag-key", children: [
1354
+ node.tags && Object.keys(node.tags).length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
1355
+ /* @__PURE__ */ jsx17("div", { className: "detail-section-label", children: "Tags" }),
1356
+ /* @__PURE__ */ jsx17("div", { className: "detail-tags", children: Object.entries(node.tags).map(([key, value]) => /* @__PURE__ */ jsxs17("span", { className: "detail-tag", children: [
1357
+ /* @__PURE__ */ jsxs17("span", { className: "detail-tag-key", children: [
1279
1358
  key,
1280
1359
  ": "
1281
1360
  ] }),
1282
- /* @__PURE__ */ jsx16("span", { className: "detail-tag-value", children: value })
1361
+ /* @__PURE__ */ jsx17("span", { className: "detail-tag-value", children: value })
1283
1362
  ] }, key)) })
1284
1363
  ] }),
1285
- !blueprint && !isBinding && /* @__PURE__ */ jsx16("div", { className: "detail-not-available", children: "Blueprint not available" })
1364
+ !blueprint && !isBinding && /* @__PURE__ */ jsx17("div", { className: "detail-not-available", children: "Blueprint not available" })
1286
1365
  ] });
1287
1366
  }
1288
1367
  function BlueprintSection({
@@ -1293,7 +1372,7 @@ function BlueprintSection({
1293
1372
  }) {
1294
1373
  switch (blueprint.type) {
1295
1374
  case "PipeLLM":
1296
- return /* @__PURE__ */ jsx16(
1375
+ return /* @__PURE__ */ jsx17(
1297
1376
  PipeLLMSection,
1298
1377
  {
1299
1378
  blueprint,
@@ -1303,7 +1382,7 @@ function BlueprintSection({
1303
1382
  }
1304
1383
  );
1305
1384
  case "PipeImgGen":
1306
- return /* @__PURE__ */ jsx16(
1385
+ return /* @__PURE__ */ jsx17(
1307
1386
  PipeImgGenSection,
1308
1387
  {
1309
1388
  blueprint,
@@ -1313,9 +1392,19 @@ function BlueprintSection({
1313
1392
  }
1314
1393
  );
1315
1394
  case "PipeCompose":
1316
- return /* @__PURE__ */ jsx16(PipeComposeSection, { blueprint, executionData });
1395
+ return /* @__PURE__ */ jsx17(PipeComposeSection, { blueprint, executionData });
1396
+ case "PipeDocGen":
1397
+ return /* @__PURE__ */ jsx17(
1398
+ PipeDocGenSection,
1399
+ {
1400
+ blueprint,
1401
+ executionData,
1402
+ modelsRan,
1403
+ modelHandles
1404
+ }
1405
+ );
1317
1406
  case "PipeExtract":
1318
- return /* @__PURE__ */ jsx16(
1407
+ return /* @__PURE__ */ jsx17(
1319
1408
  PipeExtractSection,
1320
1409
  {
1321
1410
  blueprint,
@@ -1324,7 +1413,7 @@ function BlueprintSection({
1324
1413
  }
1325
1414
  );
1326
1415
  case "PipeSearch":
1327
- return /* @__PURE__ */ jsx16(
1416
+ return /* @__PURE__ */ jsx17(
1328
1417
  PipeSearchSection,
1329
1418
  {
1330
1419
  blueprint,
@@ -1334,7 +1423,7 @@ function BlueprintSection({
1334
1423
  }
1335
1424
  );
1336
1425
  case "PipeStructure":
1337
- return /* @__PURE__ */ jsx16(
1426
+ return /* @__PURE__ */ jsx17(
1338
1427
  PipeStructureSection,
1339
1428
  {
1340
1429
  blueprint,
@@ -1344,19 +1433,24 @@ function BlueprintSection({
1344
1433
  }
1345
1434
  );
1346
1435
  case "PipeSequence":
1347
- return /* @__PURE__ */ jsx16(PipeSequenceSection, { blueprint, executionData });
1436
+ return /* @__PURE__ */ jsx17(PipeSequenceSection, { blueprint, executionData });
1348
1437
  case "PipeParallel":
1349
- return /* @__PURE__ */ jsx16(PipeParallelSection, { blueprint, executionData });
1438
+ return /* @__PURE__ */ jsx17(PipeParallelSection, { blueprint, executionData });
1350
1439
  case "PipeCondition":
1351
- return /* @__PURE__ */ jsx16(PipeConditionSection, { blueprint, executionData });
1440
+ return /* @__PURE__ */ jsx17(PipeConditionSection, { blueprint, executionData });
1352
1441
  case "PipeBatch":
1353
- return /* @__PURE__ */ jsx16(PipeBatchSection, { blueprint, executionData });
1442
+ return /* @__PURE__ */ jsx17(PipeBatchSection, { blueprint, executionData });
1354
1443
  case "PipeFunc":
1355
1444
  return null;
1445
+ case "PipeJudge":
1446
+ return null;
1356
1447
  case "PipeSignature":
1357
- return /* @__PURE__ */ jsx16("div", { className: "detail-not-available", children: "Signature stub \u2014 declared but not yet implemented." });
1358
- default:
1448
+ return /* @__PURE__ */ jsx17("div", { className: "detail-not-available", children: "Signature stub \u2014 declared but not yet implemented." });
1449
+ default: {
1450
+ const _unhandled = blueprint;
1451
+ void _unhandled;
1359
1452
  return null;
1453
+ }
1360
1454
  }
1361
1455
  }
1362
1456
  function ExecutionDataSection({
@@ -1365,20 +1459,19 @@ function ExecutionDataSection({
1365
1459
  hasBlueprint
1366
1460
  }) {
1367
1461
  if (!shouldDumpExecutionData(pipeType, hasBlueprint)) return null;
1368
- return /* @__PURE__ */ jsx16(GenericExecutionData, { data: executionData });
1462
+ return /* @__PURE__ */ jsx17(GenericExecutionData, { entries: dumpableExecutionData(pipeType, executionData) });
1369
1463
  }
1370
- function GenericExecutionData({ data }) {
1371
- const entries = Object.entries(data);
1464
+ function GenericExecutionData({ entries }) {
1372
1465
  if (entries.length === 0) return null;
1373
- return /* @__PURE__ */ jsxs16(Fragment10, { children: [
1374
- /* @__PURE__ */ jsx16("div", { className: "detail-section-label", children: "Execution" }),
1375
- entries.map(([key, value]) => /* @__PURE__ */ jsx16(KV, { label: key, value: String(value) }, key))
1466
+ return /* @__PURE__ */ jsxs17(Fragment11, { children: [
1467
+ /* @__PURE__ */ jsx17("div", { className: "detail-section-label", children: "Execution" }),
1468
+ entries.map(([key, value]) => /* @__PURE__ */ jsx17(KV, { label: key, value: String(value) }, key))
1376
1469
  ] });
1377
1470
  }
1378
1471
 
1379
1472
  // src/graph/react/detail/ConceptDetailPanel.tsx
1380
1473
  import React7 from "react";
1381
- import { Fragment as Fragment11, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
1474
+ import { Fragment as Fragment12, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
1382
1475
  function ConceptDetailPanel({
1383
1476
  concept,
1384
1477
  ioData,
@@ -1388,18 +1481,18 @@ function ConceptDetailPanel({
1388
1481
  }) {
1389
1482
  var _a;
1390
1483
  const multiplicity = ioData == null ? void 0 : ioData.multiplicity;
1391
- return /* @__PURE__ */ jsxs17(Fragment11, { children: [
1392
- /* @__PURE__ */ jsxs17("div", { className: "detail-header", children: [
1393
- /* @__PURE__ */ jsx17("span", { className: "detail-concept-code", children: concept.code + multiplicitySuffix(multiplicity) }),
1394
- /* @__PURE__ */ jsx17("span", { className: "detail-concept-domain", children: concept.domain_code })
1484
+ return /* @__PURE__ */ jsxs18(Fragment12, { children: [
1485
+ /* @__PURE__ */ jsxs18("div", { className: "detail-header", children: [
1486
+ /* @__PURE__ */ jsx18("span", { className: "detail-concept-code", children: concept.code + multiplicitySuffix(multiplicity) }),
1487
+ /* @__PURE__ */ jsx18("span", { className: "detail-concept-domain", children: concept.domain_code })
1395
1488
  ] }),
1396
- isPluralMultiplicity(multiplicity) && /* @__PURE__ */ jsx17("div", { className: "detail-multiplicity", children: multiplicity === true ? `A variable-length list of ${concept.code} items` : `A fixed-length list of exactly ${multiplicity} ${concept.code} items` }),
1397
- concept.description && /* @__PURE__ */ jsx17("div", { className: "detail-description", children: concept.description }),
1398
- concept.refines && /* @__PURE__ */ jsxs17("div", { className: "detail-refines", children: [
1489
+ isPluralMultiplicity(multiplicity) && /* @__PURE__ */ jsx18("div", { className: "detail-multiplicity", children: multiplicity === true ? `A variable-length list of ${concept.code} items` : `A fixed-length list of exactly ${multiplicity} ${concept.code} items` }),
1490
+ concept.description && /* @__PURE__ */ jsx18("div", { className: "detail-description", children: concept.description }),
1491
+ concept.refines && /* @__PURE__ */ jsxs18("div", { className: "detail-refines", children: [
1399
1492
  "refines ",
1400
- /* @__PURE__ */ jsx17("span", { className: "detail-refines-code", children: concept.refines })
1493
+ /* @__PURE__ */ jsx18("span", { className: "detail-refines-code", children: concept.refines })
1401
1494
  ] }),
1402
- /* @__PURE__ */ jsx17(
1495
+ /* @__PURE__ */ jsx18(
1403
1496
  ConceptBody,
1404
1497
  {
1405
1498
  concept,
@@ -1418,10 +1511,10 @@ function ConceptBody({ concept, ioData, isDryRun, renderData }) {
1418
1511
  const baseId = React7.useId();
1419
1512
  const tabId = (tab) => `${baseId}-tab-${tab}`;
1420
1513
  const panelId = (tab) => `${baseId}-tabpanel-${tab}`;
1421
- const structure = concept.json_schema ? /* @__PURE__ */ jsxs17("div", { children: [
1422
- /* @__PURE__ */ jsx17("div", { className: "detail-section-label", children: "Structure" }),
1423
- /* @__PURE__ */ jsx17(SchemaTable, { schema: concept.json_schema })
1424
- ] }) : /* @__PURE__ */ jsx17("div", { className: "detail-not-available", children: "Schema not available" });
1514
+ const structure = concept.json_schema ? /* @__PURE__ */ jsxs18("div", { children: [
1515
+ /* @__PURE__ */ jsx18("div", { className: "detail-section-label", children: "Structure" }),
1516
+ /* @__PURE__ */ jsx18(SchemaTable, { schema: concept.json_schema })
1517
+ ] }) : /* @__PURE__ */ jsx18("div", { className: "detail-not-available", children: "Schema not available" });
1425
1518
  if (!hasData) return structure;
1426
1519
  const onTabKeyDown = (event) => {
1427
1520
  var _a;
@@ -1444,7 +1537,7 @@ function ConceptBody({ concept, ioData, isDryRun, renderData }) {
1444
1537
  setActiveTab(next);
1445
1538
  (_a = document.getElementById(tabId(next))) == null ? void 0 : _a.focus();
1446
1539
  };
1447
- const renderTab = (tab, label) => /* @__PURE__ */ jsx17(
1540
+ const renderTab = (tab, label) => /* @__PURE__ */ jsx18(
1448
1541
  "button",
1449
1542
  {
1450
1543
  type: "button",
@@ -1459,12 +1552,12 @@ function ConceptBody({ concept, ioData, isDryRun, renderData }) {
1459
1552
  children: label
1460
1553
  }
1461
1554
  );
1462
- return /* @__PURE__ */ jsxs17(Fragment11, { children: [
1463
- /* @__PURE__ */ jsxs17("div", { className: "detail-tabs", role: "tablist", "aria-label": "Concept views", children: [
1555
+ return /* @__PURE__ */ jsxs18(Fragment12, { children: [
1556
+ /* @__PURE__ */ jsxs18("div", { className: "detail-tabs", role: "tablist", "aria-label": "Concept views", children: [
1464
1557
  renderTab("data", "Data"),
1465
1558
  renderTab("structure", "Structure")
1466
1559
  ] }),
1467
- /* @__PURE__ */ jsx17("div", { role: "tabpanel", id: panelId(activeTab), "aria-labelledby": tabId(activeTab), children: activeTab === "data" ? dataView : structure })
1560
+ /* @__PURE__ */ jsx18("div", { role: "tabpanel", id: panelId(activeTab), "aria-labelledby": tabId(activeTab), children: activeTab === "data" ? dataView : structure })
1468
1561
  ] });
1469
1562
  }
1470
1563
  function SchemaTable({ schema }) {
@@ -1472,23 +1565,23 @@ function SchemaTable({ schema }) {
1472
1565
  const properties = schema.properties;
1473
1566
  const required = new Set((_a = schema.required) != null ? _a : []);
1474
1567
  if (!properties || Object.keys(properties).length === 0) {
1475
- return /* @__PURE__ */ jsx17("div", { className: "detail-not-available", children: "No fields defined" });
1568
+ return /* @__PURE__ */ jsx18("div", { className: "detail-not-available", children: "No fields defined" });
1476
1569
  }
1477
1570
  const fields = Object.entries(properties);
1478
- return /* @__PURE__ */ jsxs17("table", { className: "detail-schema-table", children: [
1479
- /* @__PURE__ */ jsx17("thead", { children: /* @__PURE__ */ jsxs17("tr", { children: [
1480
- /* @__PURE__ */ jsx17("th", { children: "Field" }),
1481
- /* @__PURE__ */ jsx17("th", { children: "Type" }),
1482
- /* @__PURE__ */ jsx17("th", {}),
1483
- /* @__PURE__ */ jsx17("th", { children: "Description" })
1571
+ return /* @__PURE__ */ jsxs18("table", { className: "detail-schema-table", children: [
1572
+ /* @__PURE__ */ jsx18("thead", { children: /* @__PURE__ */ jsxs18("tr", { children: [
1573
+ /* @__PURE__ */ jsx18("th", { children: "Field" }),
1574
+ /* @__PURE__ */ jsx18("th", { children: "Type" }),
1575
+ /* @__PURE__ */ jsx18("th", {}),
1576
+ /* @__PURE__ */ jsx18("th", { children: "Description" })
1484
1577
  ] }) }),
1485
- /* @__PURE__ */ jsx17("tbody", { children: fields.map(([fieldName, fieldSchema]) => {
1578
+ /* @__PURE__ */ jsx18("tbody", { children: fields.map(([fieldName, fieldSchema]) => {
1486
1579
  var _a2;
1487
- return /* @__PURE__ */ jsxs17("tr", { children: [
1488
- /* @__PURE__ */ jsx17("td", { className: "detail-schema-field", children: fieldName }),
1489
- /* @__PURE__ */ jsx17("td", { className: "detail-schema-type", children: extractType(fieldSchema) }),
1490
- /* @__PURE__ */ jsx17("td", { children: required.has(fieldName) && /* @__PURE__ */ jsx17("span", { className: "detail-schema-required", children: "req" }) }),
1491
- /* @__PURE__ */ jsx17("td", { children: (_a2 = fieldSchema.description) != null ? _a2 : "" })
1580
+ return /* @__PURE__ */ jsxs18("tr", { children: [
1581
+ /* @__PURE__ */ jsx18("td", { className: "detail-schema-field", children: fieldName }),
1582
+ /* @__PURE__ */ jsx18("td", { className: "detail-schema-type", children: extractType(fieldSchema) }),
1583
+ /* @__PURE__ */ jsx18("td", { children: required.has(fieldName) && /* @__PURE__ */ jsx18("span", { className: "detail-schema-required", children: "req" }) }),
1584
+ /* @__PURE__ */ jsx18("td", { children: (_a2 = fieldSchema.description) != null ? _a2 : "" })
1492
1585
  ] }, fieldName);
1493
1586
  }) })
1494
1587
  ] });
@@ -1539,10 +1632,10 @@ function toAppEdges(edges) {
1539
1632
  }
1540
1633
 
1541
1634
  // src/graph/react/viewer/renderLabel.tsx
1542
- import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
1635
+ import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
1543
1636
  function renderLabel(desc) {
1544
1637
  if (desc.kind === "pipe") {
1545
- return /* @__PURE__ */ jsx18(
1638
+ return /* @__PURE__ */ jsx19(
1546
1639
  "div",
1547
1640
  {
1548
1641
  style: {
@@ -1556,7 +1649,7 @@ function renderLabel(desc) {
1556
1649
  minWidth: 0
1557
1650
  },
1558
1651
  title: desc.label,
1559
- children: /* @__PURE__ */ jsx18(
1652
+ children: /* @__PURE__ */ jsx19(
1560
1653
  "span",
1561
1654
  {
1562
1655
  style: {
@@ -1575,7 +1668,7 @@ function renderLabel(desc) {
1575
1668
  }
1576
1669
  );
1577
1670
  }
1578
- return /* @__PURE__ */ jsxs18(
1671
+ return /* @__PURE__ */ jsxs19(
1579
1672
  "div",
1580
1673
  {
1581
1674
  style: {
@@ -1591,7 +1684,7 @@ function renderLabel(desc) {
1591
1684
  },
1592
1685
  title: desc.concept ? `${desc.label}: ${desc.concept}` : desc.label,
1593
1686
  children: [
1594
- /* @__PURE__ */ jsx18(
1687
+ /* @__PURE__ */ jsx19(
1595
1688
  "span",
1596
1689
  {
1597
1690
  style: {
@@ -1607,7 +1700,7 @@ function renderLabel(desc) {
1607
1700
  children: desc.label
1608
1701
  }
1609
1702
  ),
1610
- desc.concept && /* @__PURE__ */ jsx18(
1703
+ desc.concept && /* @__PURE__ */ jsx19(
1611
1704
  "span",
1612
1705
  {
1613
1706
  style: {
@@ -1641,7 +1734,7 @@ import React10 from "react";
1641
1734
  import { Panel } from "@xyflow/react";
1642
1735
 
1643
1736
  // src/graph/react/viewer/ValidationPanel.tsx
1644
- import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
1737
+ import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
1645
1738
  function validationLabel(state, issueCount) {
1646
1739
  const issues = issueCount === 1 ? "1 issue" : `${issueCount} issues`;
1647
1740
  switch (state) {
@@ -1708,7 +1801,7 @@ function ValidationPanel({
1708
1801
  placement,
1709
1802
  id
1710
1803
  }) {
1711
- return /* @__PURE__ */ jsxs19(
1804
+ return /* @__PURE__ */ jsxs20(
1712
1805
  "div",
1713
1806
  {
1714
1807
  id,
@@ -1716,18 +1809,18 @@ function ValidationPanel({
1716
1809
  role: "region",
1717
1810
  "aria-label": "Validation issues",
1718
1811
  children: [
1719
- /* @__PURE__ */ jsx19("div", { className: "graph-validation-panel-header", children: validationLabel(state, issues.length) }),
1720
- issues.length === 0 ? /* @__PURE__ */ jsx19("div", { className: "graph-validation-empty", children: validationEmptyText(state) }) : /* @__PURE__ */ jsx19("ul", { className: "graph-validation-issues", role: "list", children: issues.map((issue, index) => {
1812
+ /* @__PURE__ */ jsx20("div", { className: "graph-validation-panel-header", children: validationLabel(state, issues.length) }),
1813
+ issues.length === 0 ? /* @__PURE__ */ jsx20("div", { className: "graph-validation-empty", children: validationEmptyText(state) }) : /* @__PURE__ */ jsx20("ul", { className: "graph-validation-issues", role: "list", children: issues.map((issue, index) => {
1721
1814
  const clickable = onIssueClick !== void 0;
1722
- const meta = (issue.context || issue.file) && /* @__PURE__ */ jsxs19("div", { className: "graph-validation-issue-meta", children: [
1723
- issue.context && /* @__PURE__ */ jsx19("span", { className: "graph-validation-issue-context", children: issue.context }),
1724
- issue.file && /* @__PURE__ */ jsx19("span", { className: "graph-validation-issue-file", children: issue.file })
1815
+ const meta = (issue.context || issue.file) && /* @__PURE__ */ jsxs20("div", { className: "graph-validation-issue-meta", children: [
1816
+ issue.context && /* @__PURE__ */ jsx20("span", { className: "graph-validation-issue-context", children: issue.context }),
1817
+ issue.file && /* @__PURE__ */ jsx20("span", { className: "graph-validation-issue-file", children: issue.file })
1725
1818
  ] });
1726
- return /* @__PURE__ */ jsx19(
1819
+ return /* @__PURE__ */ jsx20(
1727
1820
  "li",
1728
1821
  {
1729
1822
  className: `graph-validation-issue graph-validation-issue--${issue.severity}` + (clickable ? " graph-validation-issue--clickable" : ""),
1730
- children: /* @__PURE__ */ jsxs19(
1823
+ children: /* @__PURE__ */ jsxs20(
1731
1824
  "div",
1732
1825
  {
1733
1826
  className: "graph-validation-issue-body",
@@ -1742,8 +1835,8 @@ function ValidationPanel({
1742
1835
  } : void 0,
1743
1836
  children: [
1744
1837
  meta,
1745
- /* @__PURE__ */ jsx19("div", { className: "graph-validation-issue-message", children: issue.message }),
1746
- issue.suggestedFix && /* @__PURE__ */ jsx19("div", { className: "graph-validation-issue-fix", children: issue.suggestedFix })
1838
+ /* @__PURE__ */ jsx20("div", { className: "graph-validation-issue-message", children: issue.message }),
1839
+ issue.suggestedFix && /* @__PURE__ */ jsx20("div", { className: "graph-validation-issue-fix", children: issue.suggestedFix })
1747
1840
  ]
1748
1841
  }
1749
1842
  )
@@ -1785,7 +1878,7 @@ function usePopoverDismiss(open, wrapperRef, onDismiss) {
1785
1878
  }
1786
1879
 
1787
1880
  // src/graph/react/viewer/StyleMenu.tsx
1788
- import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
1881
+ import { jsx as jsx21, jsxs as jsxs21 } from "react/jsx-runtime";
1789
1882
  var ICON_PROPS = {
1790
1883
  viewBox: "0 0 24 24",
1791
1884
  width: 14,
@@ -1798,22 +1891,22 @@ var ICON_PROPS = {
1798
1891
  };
1799
1892
  var STYLE_ICONS = {
1800
1893
  // Cards with their rows: every pipe with its slots.
1801
- [GRAPH_STYLE.DETAILED]: /* @__PURE__ */ jsxs20("svg", __spreadProps(__spreadValues({}, ICON_PROPS), { children: [
1802
- /* @__PURE__ */ jsx20("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
1803
- /* @__PURE__ */ jsx20("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
1804
- /* @__PURE__ */ jsx20("line", { x1: "14", y1: "4", x2: "21", y2: "4" }),
1805
- /* @__PURE__ */ jsx20("line", { x1: "14", y1: "9", x2: "21", y2: "9" }),
1806
- /* @__PURE__ */ jsx20("line", { x1: "14", y1: "15", x2: "21", y2: "15" }),
1807
- /* @__PURE__ */ jsx20("line", { x1: "14", y1: "20", x2: "21", y2: "20" })
1894
+ [GRAPH_STYLE.DETAILED]: /* @__PURE__ */ jsxs21("svg", __spreadProps(__spreadValues({}, ICON_PROPS), { children: [
1895
+ /* @__PURE__ */ jsx21("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
1896
+ /* @__PURE__ */ jsx21("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
1897
+ /* @__PURE__ */ jsx21("line", { x1: "14", y1: "4", x2: "21", y2: "4" }),
1898
+ /* @__PURE__ */ jsx21("line", { x1: "14", y1: "9", x2: "21", y2: "9" }),
1899
+ /* @__PURE__ */ jsx21("line", { x1: "14", y1: "15", x2: "21", y2: "15" }),
1900
+ /* @__PURE__ */ jsx21("line", { x1: "14", y1: "20", x2: "21", y2: "20" })
1808
1901
  ] })),
1809
1902
  // Two steps and the arrow between them: a flowchart.
1810
- [GRAPH_STYLE.SIMPLE]: /* @__PURE__ */ jsxs20("svg", __spreadProps(__spreadValues({}, ICON_PROPS), { children: [
1811
- /* @__PURE__ */ jsx20("rect", { x: "3", y: "3", width: "8", height: "8", rx: "2" }),
1812
- /* @__PURE__ */ jsx20("path", { d: "M7 11v4a2 2 0 0 0 2 2h4" }),
1813
- /* @__PURE__ */ jsx20("rect", { x: "13", y: "13", width: "8", height: "8", rx: "2" })
1903
+ [GRAPH_STYLE.SIMPLE]: /* @__PURE__ */ jsxs21("svg", __spreadProps(__spreadValues({}, ICON_PROPS), { children: [
1904
+ /* @__PURE__ */ jsx21("rect", { x: "3", y: "3", width: "8", height: "8", rx: "2" }),
1905
+ /* @__PURE__ */ jsx21("path", { d: "M7 11v4a2 2 0 0 0 2 2h4" }),
1906
+ /* @__PURE__ */ jsx21("rect", { x: "13", y: "13", width: "8", height: "8", rx: "2" })
1814
1907
  ] }))
1815
1908
  };
1816
- var CHECK_ICON2 = /* @__PURE__ */ jsx20("svg", __spreadProps(__spreadValues({}, ICON_PROPS), { children: /* @__PURE__ */ jsx20("polyline", { points: "20 6 9 17 4 12" }) }));
1909
+ var CHECK_ICON2 = /* @__PURE__ */ jsx21("svg", __spreadProps(__spreadValues({}, ICON_PROPS), { children: /* @__PURE__ */ jsx21("polyline", { points: "20 6 9 17 4 12" }) }));
1817
1910
  function graphStyleIcon(style) {
1818
1911
  return STYLE_ICONS[style];
1819
1912
  }
@@ -1878,8 +1971,8 @@ function StyleMenu({ value, options, onChange, placement }) {
1878
1971
  if (style !== value) onChange(style);
1879
1972
  };
1880
1973
  const label = styleMenuLabel(value);
1881
- return /* @__PURE__ */ jsxs20("div", { className: "graph-toolbar-style", ref: wrapperRef, children: [
1882
- /* @__PURE__ */ jsx20(
1974
+ return /* @__PURE__ */ jsxs21("div", { className: "graph-toolbar-style", ref: wrapperRef, children: [
1975
+ /* @__PURE__ */ jsx21(
1883
1976
  "button",
1884
1977
  {
1885
1978
  ref: buttonRef,
@@ -1900,7 +1993,7 @@ function StyleMenu({ value, options, onChange, placement }) {
1900
1993
  children: graphStyleIcon(value)
1901
1994
  }
1902
1995
  ),
1903
- open && /* @__PURE__ */ jsx20(
1996
+ open && /* @__PURE__ */ jsx21(
1904
1997
  "div",
1905
1998
  {
1906
1999
  id: menuId,
@@ -1911,7 +2004,7 @@ function StyleMenu({ value, options, onChange, placement }) {
1911
2004
  children: options.map((style, index) => {
1912
2005
  const descriptor = GRAPH_STYLES[style];
1913
2006
  const checked = style === value;
1914
- return /* @__PURE__ */ jsxs20(
2007
+ return /* @__PURE__ */ jsxs21(
1915
2008
  "button",
1916
2009
  {
1917
2010
  ref: (el) => {
@@ -1924,12 +2017,12 @@ function StyleMenu({ value, options, onChange, placement }) {
1924
2017
  className: `graph-style-menu-item${checked ? " graph-style-menu-item--checked" : ""}`,
1925
2018
  onClick: () => choose(style),
1926
2019
  children: [
1927
- /* @__PURE__ */ jsx20("span", { className: "graph-style-menu-icon", "aria-hidden": "true", children: graphStyleIcon(style) }),
1928
- /* @__PURE__ */ jsxs20("span", { className: "graph-style-menu-text", children: [
1929
- /* @__PURE__ */ jsx20("span", { className: "graph-style-menu-name", children: descriptor.name }),
1930
- /* @__PURE__ */ jsx20("span", { className: "graph-style-menu-description", children: descriptor.description })
2020
+ /* @__PURE__ */ jsx21("span", { className: "graph-style-menu-icon", "aria-hidden": "true", children: graphStyleIcon(style) }),
2021
+ /* @__PURE__ */ jsxs21("span", { className: "graph-style-menu-text", children: [
2022
+ /* @__PURE__ */ jsx21("span", { className: "graph-style-menu-name", children: descriptor.name }),
2023
+ /* @__PURE__ */ jsx21("span", { className: "graph-style-menu-description", children: descriptor.description })
1931
2024
  ] }),
1932
- /* @__PURE__ */ jsx20("span", { className: "graph-style-menu-check", "aria-hidden": "true", children: checked ? CHECK_ICON2 : null })
2025
+ /* @__PURE__ */ jsx21("span", { className: "graph-style-menu-check", "aria-hidden": "true", children: checked ? CHECK_ICON2 : null })
1933
2026
  ]
1934
2027
  },
1935
2028
  style
@@ -1941,9 +2034,9 @@ function StyleMenu({ value, options, onChange, placement }) {
1941
2034
  }
1942
2035
 
1943
2036
  // src/graph/react/viewer/GraphToolbar.tsx
1944
- import { Fragment as Fragment12, jsx as jsx21, jsxs as jsxs21 } from "react/jsx-runtime";
2037
+ import { Fragment as Fragment13, jsx as jsx22, jsxs as jsxs22 } from "react/jsx-runtime";
1945
2038
  var REACTFLOW_PANEL_MARGIN = 15;
1946
- var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs21(
2039
+ var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs22(
1947
2040
  "svg",
1948
2041
  {
1949
2042
  viewBox: "0 0 24 24",
@@ -1955,12 +2048,12 @@ var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs21(
1955
2048
  strokeLinecap: "round",
1956
2049
  strokeLinejoin: "round",
1957
2050
  children: [
1958
- /* @__PURE__ */ jsx21("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
1959
- /* @__PURE__ */ jsx21("polyline", { points: "12 5 19 12 12 19" })
2051
+ /* @__PURE__ */ jsx22("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
2052
+ /* @__PURE__ */ jsx22("polyline", { points: "12 5 19 12 12 19" })
1960
2053
  ]
1961
2054
  }
1962
2055
  );
1963
- var ARROW_DOWN_ICON = /* @__PURE__ */ jsxs21(
2056
+ var ARROW_DOWN_ICON = /* @__PURE__ */ jsxs22(
1964
2057
  "svg",
1965
2058
  {
1966
2059
  viewBox: "0 0 24 24",
@@ -1972,12 +2065,12 @@ var ARROW_DOWN_ICON = /* @__PURE__ */ jsxs21(
1972
2065
  strokeLinecap: "round",
1973
2066
  strokeLinejoin: "round",
1974
2067
  children: [
1975
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1976
- /* @__PURE__ */ jsx21("polyline", { points: "19 12 12 19 5 12" })
2068
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
2069
+ /* @__PURE__ */ jsx22("polyline", { points: "19 12 12 19 5 12" })
1977
2070
  ]
1978
2071
  }
1979
2072
  );
1980
- var MINUS_ICON = /* @__PURE__ */ jsx21(
2073
+ var MINUS_ICON = /* @__PURE__ */ jsx22(
1981
2074
  "svg",
1982
2075
  {
1983
2076
  viewBox: "0 0 24 24",
@@ -1988,10 +2081,10 @@ var MINUS_ICON = /* @__PURE__ */ jsx21(
1988
2081
  strokeWidth: "2",
1989
2082
  strokeLinecap: "round",
1990
2083
  strokeLinejoin: "round",
1991
- children: /* @__PURE__ */ jsx21("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
2084
+ children: /* @__PURE__ */ jsx22("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1992
2085
  }
1993
2086
  );
1994
- var PLUS_ICON = /* @__PURE__ */ jsxs21(
2087
+ var PLUS_ICON = /* @__PURE__ */ jsxs22(
1995
2088
  "svg",
1996
2089
  {
1997
2090
  viewBox: "0 0 24 24",
@@ -2003,12 +2096,12 @@ var PLUS_ICON = /* @__PURE__ */ jsxs21(
2003
2096
  strokeLinecap: "round",
2004
2097
  strokeLinejoin: "round",
2005
2098
  children: [
2006
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
2007
- /* @__PURE__ */ jsx21("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
2099
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
2100
+ /* @__PURE__ */ jsx22("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
2008
2101
  ]
2009
2102
  }
2010
2103
  );
2011
- var FIT_VIEW_ICON = /* @__PURE__ */ jsxs21(
2104
+ var FIT_VIEW_ICON = /* @__PURE__ */ jsxs22(
2012
2105
  "svg",
2013
2106
  {
2014
2107
  viewBox: "0 0 24 24",
@@ -2020,14 +2113,14 @@ var FIT_VIEW_ICON = /* @__PURE__ */ jsxs21(
2020
2113
  strokeLinecap: "round",
2021
2114
  strokeLinejoin: "round",
2022
2115
  children: [
2023
- /* @__PURE__ */ jsx21("polyline", { points: "15 3 21 3 21 9" }),
2024
- /* @__PURE__ */ jsx21("polyline", { points: "9 21 3 21 3 15" }),
2025
- /* @__PURE__ */ jsx21("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
2026
- /* @__PURE__ */ jsx21("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
2116
+ /* @__PURE__ */ jsx22("polyline", { points: "15 3 21 3 21 9" }),
2117
+ /* @__PURE__ */ jsx22("polyline", { points: "9 21 3 21 3 15" }),
2118
+ /* @__PURE__ */ jsx22("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
2119
+ /* @__PURE__ */ jsx22("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
2027
2120
  ]
2028
2121
  }
2029
2122
  );
2030
- var BOXES_ICON = /* @__PURE__ */ jsxs21(
2123
+ var BOXES_ICON = /* @__PURE__ */ jsxs22(
2031
2124
  "svg",
2032
2125
  {
2033
2126
  viewBox: "0 0 24 24",
@@ -2039,22 +2132,22 @@ var BOXES_ICON = /* @__PURE__ */ jsxs21(
2039
2132
  strokeLinecap: "round",
2040
2133
  strokeLinejoin: "round",
2041
2134
  children: [
2042
- /* @__PURE__ */ jsx21("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
2043
- /* @__PURE__ */ jsx21("path", { d: "m7 16.5-4.74-2.85" }),
2044
- /* @__PURE__ */ jsx21("path", { d: "m7 16.5 5-3" }),
2045
- /* @__PURE__ */ jsx21("path", { d: "M7 16.5v5.17" }),
2046
- /* @__PURE__ */ jsx21("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
2047
- /* @__PURE__ */ jsx21("path", { d: "m17 16.5-5-3" }),
2048
- /* @__PURE__ */ jsx21("path", { d: "m17 16.5 4.74-2.85" }),
2049
- /* @__PURE__ */ jsx21("path", { d: "M17 16.5v5.17" }),
2050
- /* @__PURE__ */ jsx21("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
2051
- /* @__PURE__ */ jsx21("path", { d: "M12 8 7.26 5.15" }),
2052
- /* @__PURE__ */ jsx21("path", { d: "m12 8 4.74-2.85" }),
2053
- /* @__PURE__ */ jsx21("path", { d: "M12 13.5V8" })
2135
+ /* @__PURE__ */ jsx22("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
2136
+ /* @__PURE__ */ jsx22("path", { d: "m7 16.5-4.74-2.85" }),
2137
+ /* @__PURE__ */ jsx22("path", { d: "m7 16.5 5-3" }),
2138
+ /* @__PURE__ */ jsx22("path", { d: "M7 16.5v5.17" }),
2139
+ /* @__PURE__ */ jsx22("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
2140
+ /* @__PURE__ */ jsx22("path", { d: "m17 16.5-5-3" }),
2141
+ /* @__PURE__ */ jsx22("path", { d: "m17 16.5 4.74-2.85" }),
2142
+ /* @__PURE__ */ jsx22("path", { d: "M17 16.5v5.17" }),
2143
+ /* @__PURE__ */ jsx22("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
2144
+ /* @__PURE__ */ jsx22("path", { d: "M12 8 7.26 5.15" }),
2145
+ /* @__PURE__ */ jsx22("path", { d: "m12 8 4.74-2.85" }),
2146
+ /* @__PURE__ */ jsx22("path", { d: "M12 13.5V8" })
2054
2147
  ]
2055
2148
  }
2056
2149
  );
2057
- var FOLD_ALL_ICON = /* @__PURE__ */ jsxs21(
2150
+ var FOLD_ALL_ICON = /* @__PURE__ */ jsxs22(
2058
2151
  "svg",
2059
2152
  {
2060
2153
  viewBox: "0 0 24 24",
@@ -2066,15 +2159,15 @@ var FOLD_ALL_ICON = /* @__PURE__ */ jsxs21(
2066
2159
  strokeLinecap: "round",
2067
2160
  strokeLinejoin: "round",
2068
2161
  children: [
2069
- /* @__PURE__ */ jsx21("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }),
2070
- /* @__PURE__ */ jsx21("polyline", { points: "2 2 6 6 2 6" }),
2071
- /* @__PURE__ */ jsx21("polyline", { points: "22 2 18 6 22 6" }),
2072
- /* @__PURE__ */ jsx21("polyline", { points: "2 22 6 18 2 18" }),
2073
- /* @__PURE__ */ jsx21("polyline", { points: "22 22 18 18 22 18" })
2162
+ /* @__PURE__ */ jsx22("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }),
2163
+ /* @__PURE__ */ jsx22("polyline", { points: "2 2 6 6 2 6" }),
2164
+ /* @__PURE__ */ jsx22("polyline", { points: "22 2 18 6 22 6" }),
2165
+ /* @__PURE__ */ jsx22("polyline", { points: "2 22 6 18 2 18" }),
2166
+ /* @__PURE__ */ jsx22("polyline", { points: "22 22 18 18 22 18" })
2074
2167
  ]
2075
2168
  }
2076
2169
  );
2077
- var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs21(
2170
+ var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs22(
2078
2171
  "svg",
2079
2172
  {
2080
2173
  viewBox: "0 0 24 24",
@@ -2086,15 +2179,15 @@ var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs21(
2086
2179
  strokeLinecap: "round",
2087
2180
  strokeLinejoin: "round",
2088
2181
  children: [
2089
- /* @__PURE__ */ jsx21("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" }),
2090
- /* @__PURE__ */ jsx21("polyline", { points: "3 3 7 7 3 7" }),
2091
- /* @__PURE__ */ jsx21("polyline", { points: "21 3 17 7 21 7" }),
2092
- /* @__PURE__ */ jsx21("polyline", { points: "3 21 7 17 3 17" }),
2093
- /* @__PURE__ */ jsx21("polyline", { points: "21 21 17 17 21 17" })
2182
+ /* @__PURE__ */ jsx22("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" }),
2183
+ /* @__PURE__ */ jsx22("polyline", { points: "3 3 7 7 3 7" }),
2184
+ /* @__PURE__ */ jsx22("polyline", { points: "21 3 17 7 21 7" }),
2185
+ /* @__PURE__ */ jsx22("polyline", { points: "3 21 7 17 3 17" }),
2186
+ /* @__PURE__ */ jsx22("polyline", { points: "21 21 17 17 21 17" })
2094
2187
  ]
2095
2188
  }
2096
2189
  );
2097
- var SUN_ICON = /* @__PURE__ */ jsxs21(
2190
+ var SUN_ICON = /* @__PURE__ */ jsxs22(
2098
2191
  "svg",
2099
2192
  {
2100
2193
  viewBox: "0 0 24 24",
@@ -2106,19 +2199,19 @@ var SUN_ICON = /* @__PURE__ */ jsxs21(
2106
2199
  strokeLinecap: "round",
2107
2200
  strokeLinejoin: "round",
2108
2201
  children: [
2109
- /* @__PURE__ */ jsx21("circle", { cx: "12", cy: "12", r: "4" }),
2110
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
2111
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
2112
- /* @__PURE__ */ jsx21("line", { x1: "4.93", y1: "4.93", x2: "6.34", y2: "6.34" }),
2113
- /* @__PURE__ */ jsx21("line", { x1: "17.66", y1: "17.66", x2: "19.07", y2: "19.07" }),
2114
- /* @__PURE__ */ jsx21("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
2115
- /* @__PURE__ */ jsx21("line", { x1: "20", y1: "12", x2: "22", y2: "12" }),
2116
- /* @__PURE__ */ jsx21("line", { x1: "4.93", y1: "19.07", x2: "6.34", y2: "17.66" }),
2117
- /* @__PURE__ */ jsx21("line", { x1: "17.66", y1: "6.34", x2: "19.07", y2: "4.93" })
2202
+ /* @__PURE__ */ jsx22("circle", { cx: "12", cy: "12", r: "4" }),
2203
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
2204
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
2205
+ /* @__PURE__ */ jsx22("line", { x1: "4.93", y1: "4.93", x2: "6.34", y2: "6.34" }),
2206
+ /* @__PURE__ */ jsx22("line", { x1: "17.66", y1: "17.66", x2: "19.07", y2: "19.07" }),
2207
+ /* @__PURE__ */ jsx22("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
2208
+ /* @__PURE__ */ jsx22("line", { x1: "20", y1: "12", x2: "22", y2: "12" }),
2209
+ /* @__PURE__ */ jsx22("line", { x1: "4.93", y1: "19.07", x2: "6.34", y2: "17.66" }),
2210
+ /* @__PURE__ */ jsx22("line", { x1: "17.66", y1: "6.34", x2: "19.07", y2: "4.93" })
2118
2211
  ]
2119
2212
  }
2120
2213
  );
2121
- var MOON_ICON = /* @__PURE__ */ jsx21(
2214
+ var MOON_ICON = /* @__PURE__ */ jsx22(
2122
2215
  "svg",
2123
2216
  {
2124
2217
  viewBox: "0 0 24 24",
@@ -2129,10 +2222,10 @@ var MOON_ICON = /* @__PURE__ */ jsx21(
2129
2222
  strokeWidth: "2",
2130
2223
  strokeLinecap: "round",
2131
2224
  strokeLinejoin: "round",
2132
- children: /* @__PURE__ */ jsx21("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
2225
+ children: /* @__PURE__ */ jsx22("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
2133
2226
  }
2134
2227
  );
2135
- var MONITOR_ICON = /* @__PURE__ */ jsxs21(
2228
+ var MONITOR_ICON = /* @__PURE__ */ jsxs22(
2136
2229
  "svg",
2137
2230
  {
2138
2231
  viewBox: "0 0 24 24",
@@ -2144,13 +2237,13 @@ var MONITOR_ICON = /* @__PURE__ */ jsxs21(
2144
2237
  strokeLinecap: "round",
2145
2238
  strokeLinejoin: "round",
2146
2239
  children: [
2147
- /* @__PURE__ */ jsx21("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
2148
- /* @__PURE__ */ jsx21("line", { x1: "8", y1: "21", x2: "16", y2: "21" }),
2149
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "17", x2: "12", y2: "21" })
2240
+ /* @__PURE__ */ jsx22("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
2241
+ /* @__PURE__ */ jsx22("line", { x1: "8", y1: "21", x2: "16", y2: "21" }),
2242
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "17", x2: "12", y2: "21" })
2150
2243
  ]
2151
2244
  }
2152
2245
  );
2153
- var SPINNER_ICON = /* @__PURE__ */ jsx21(
2246
+ var SPINNER_ICON = /* @__PURE__ */ jsx22(
2154
2247
  "svg",
2155
2248
  {
2156
2249
  className: "graph-toolbar-validation-spin",
@@ -2162,10 +2255,10 @@ var SPINNER_ICON = /* @__PURE__ */ jsx21(
2162
2255
  strokeWidth: "2",
2163
2256
  strokeLinecap: "round",
2164
2257
  strokeLinejoin: "round",
2165
- children: /* @__PURE__ */ jsx21("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
2258
+ children: /* @__PURE__ */ jsx22("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
2166
2259
  }
2167
2260
  );
2168
- var CHECK_ICON3 = /* @__PURE__ */ jsx21(
2261
+ var CHECK_ICON3 = /* @__PURE__ */ jsx22(
2169
2262
  "svg",
2170
2263
  {
2171
2264
  viewBox: "0 0 24 24",
@@ -2176,10 +2269,10 @@ var CHECK_ICON3 = /* @__PURE__ */ jsx21(
2176
2269
  strokeWidth: "2",
2177
2270
  strokeLinecap: "round",
2178
2271
  strokeLinejoin: "round",
2179
- children: /* @__PURE__ */ jsx21("polyline", { points: "20 6 9 17 4 12" })
2272
+ children: /* @__PURE__ */ jsx22("polyline", { points: "20 6 9 17 4 12" })
2180
2273
  }
2181
2274
  );
2182
- var X_CIRCLE_ICON = /* @__PURE__ */ jsxs21(
2275
+ var X_CIRCLE_ICON = /* @__PURE__ */ jsxs22(
2183
2276
  "svg",
2184
2277
  {
2185
2278
  viewBox: "0 0 24 24",
@@ -2191,13 +2284,13 @@ var X_CIRCLE_ICON = /* @__PURE__ */ jsxs21(
2191
2284
  strokeLinecap: "round",
2192
2285
  strokeLinejoin: "round",
2193
2286
  children: [
2194
- /* @__PURE__ */ jsx21("circle", { cx: "12", cy: "12", r: "10" }),
2195
- /* @__PURE__ */ jsx21("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
2196
- /* @__PURE__ */ jsx21("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
2287
+ /* @__PURE__ */ jsx22("circle", { cx: "12", cy: "12", r: "10" }),
2288
+ /* @__PURE__ */ jsx22("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
2289
+ /* @__PURE__ */ jsx22("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
2197
2290
  ]
2198
2291
  }
2199
2292
  );
2200
- var ALERT_TRIANGLE_ICON = /* @__PURE__ */ jsxs21(
2293
+ var ALERT_TRIANGLE_ICON = /* @__PURE__ */ jsxs22(
2201
2294
  "svg",
2202
2295
  {
2203
2296
  viewBox: "0 0 24 24",
@@ -2209,13 +2302,13 @@ var ALERT_TRIANGLE_ICON = /* @__PURE__ */ jsxs21(
2209
2302
  strokeLinecap: "round",
2210
2303
  strokeLinejoin: "round",
2211
2304
  children: [
2212
- /* @__PURE__ */ jsx21("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" }),
2213
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
2214
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2305
+ /* @__PURE__ */ jsx22("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" }),
2306
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
2307
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2215
2308
  ]
2216
2309
  }
2217
2310
  );
2218
- var INFO_CIRCLE_ICON = /* @__PURE__ */ jsxs21(
2311
+ var INFO_CIRCLE_ICON = /* @__PURE__ */ jsxs22(
2219
2312
  "svg",
2220
2313
  {
2221
2314
  viewBox: "0 0 24 24",
@@ -2227,9 +2320,9 @@ var INFO_CIRCLE_ICON = /* @__PURE__ */ jsxs21(
2227
2320
  strokeLinecap: "round",
2228
2321
  strokeLinejoin: "round",
2229
2322
  children: [
2230
- /* @__PURE__ */ jsx21("circle", { cx: "12", cy: "12", r: "10" }),
2231
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
2232
- /* @__PURE__ */ jsx21("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
2323
+ /* @__PURE__ */ jsx22("circle", { cx: "12", cy: "12", r: "10" }),
2324
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
2325
+ /* @__PURE__ */ jsx22("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
2233
2326
  ]
2234
2327
  }
2235
2328
  );
@@ -2320,10 +2413,10 @@ function GraphToolbar({
2320
2413
  const foldAllSection = onFoldAll || onExpandAll;
2321
2414
  const foldAllTitle = foldAllDisabled ? "Fold all controllers (nothing to fold)" : "Fold all controllers";
2322
2415
  const expandAllTitle = expandAllDisabled ? "Expand all controllers (nothing to expand)" : "Expand all controllers";
2323
- return /* @__PURE__ */ jsx21(Panel, { position, className: "graph-toolbar-panel", style: panelStyle, children: /* @__PURE__ */ jsxs21("div", { className: `graph-toolbar graph-toolbar--${orientation}`, children: [
2324
- validationState !== void 0 && /* @__PURE__ */ jsxs21(Fragment12, { children: [
2325
- /* @__PURE__ */ jsxs21("div", { className: "graph-toolbar-validation", ref: validationRef, children: [
2326
- /* @__PURE__ */ jsxs21(
2416
+ return /* @__PURE__ */ jsx22(Panel, { position, className: "graph-toolbar-panel", style: panelStyle, children: /* @__PURE__ */ jsxs22("div", { className: `graph-toolbar graph-toolbar--${orientation}`, children: [
2417
+ validationState !== void 0 && /* @__PURE__ */ jsxs22(Fragment13, { children: [
2418
+ /* @__PURE__ */ jsxs22("div", { className: "graph-toolbar-validation", ref: validationRef, children: [
2419
+ /* @__PURE__ */ jsxs22(
2327
2420
  "button",
2328
2421
  {
2329
2422
  type: "button",
@@ -2336,11 +2429,11 @@ function GraphToolbar({
2336
2429
  "aria-controls": validationPanelId,
2337
2430
  children: [
2338
2431
  validationIcon(validationState),
2339
- validationIssues.length > 0 && /* @__PURE__ */ jsx21("span", { className: "graph-toolbar-validation-badge", children: validationIssues.length > 99 ? "99+" : validationIssues.length })
2432
+ validationIssues.length > 0 && /* @__PURE__ */ jsx22("span", { className: "graph-toolbar-validation-badge", children: validationIssues.length > 99 ? "99+" : validationIssues.length })
2340
2433
  ]
2341
2434
  }
2342
2435
  ),
2343
- validationOpen && /* @__PURE__ */ jsx21(
2436
+ validationOpen && /* @__PURE__ */ jsx22(
2344
2437
  ValidationPanel,
2345
2438
  {
2346
2439
  id: validationPanelId,
@@ -2351,10 +2444,10 @@ function GraphToolbar({
2351
2444
  }
2352
2445
  )
2353
2446
  ] }),
2354
- /* @__PURE__ */ jsx21("div", { className: "graph-toolbar-separator" })
2447
+ /* @__PURE__ */ jsx22("div", { className: "graph-toolbar-separator" })
2355
2448
  ] }),
2356
- styleMenuEnabled && /* @__PURE__ */ jsxs21(Fragment12, { children: [
2357
- /* @__PURE__ */ jsx21(
2449
+ styleMenuEnabled && /* @__PURE__ */ jsxs22(Fragment13, { children: [
2450
+ /* @__PURE__ */ jsx22(
2358
2451
  StyleMenu,
2359
2452
  {
2360
2453
  value: graphStyle,
@@ -2363,9 +2456,9 @@ function GraphToolbar({
2363
2456
  placement: validationPanelPlacement(position)
2364
2457
  }
2365
2458
  ),
2366
- /* @__PURE__ */ jsx21("div", { className: "graph-toolbar-separator" })
2459
+ /* @__PURE__ */ jsx22("div", { className: "graph-toolbar-separator" })
2367
2460
  ] }),
2368
- onFoldAll && /* @__PURE__ */ jsx21(
2461
+ onFoldAll && /* @__PURE__ */ jsx22(
2369
2462
  "button",
2370
2463
  {
2371
2464
  type: "button",
@@ -2377,7 +2470,7 @@ function GraphToolbar({
2377
2470
  children: FOLD_ALL_ICON
2378
2471
  }
2379
2472
  ),
2380
- onExpandAll && /* @__PURE__ */ jsx21(
2473
+ onExpandAll && /* @__PURE__ */ jsx22(
2381
2474
  "button",
2382
2475
  {
2383
2476
  type: "button",
@@ -2389,8 +2482,8 @@ function GraphToolbar({
2389
2482
  children: EXPAND_ALL_ICON
2390
2483
  }
2391
2484
  ),
2392
- foldAllSection && /* @__PURE__ */ jsx21("div", { className: "graph-toolbar-separator" }),
2393
- onShowControllersChange && /* @__PURE__ */ jsx21(
2485
+ foldAllSection && /* @__PURE__ */ jsx22("div", { className: "graph-toolbar-separator" }),
2486
+ onShowControllersChange && /* @__PURE__ */ jsx22(
2394
2487
  "button",
2395
2488
  {
2396
2489
  type: "button",
@@ -2401,7 +2494,7 @@ function GraphToolbar({
2401
2494
  children: BOXES_ICON
2402
2495
  }
2403
2496
  ),
2404
- /* @__PURE__ */ jsx21(
2497
+ /* @__PURE__ */ jsx22(
2405
2498
  "button",
2406
2499
  {
2407
2500
  type: "button",
@@ -2412,8 +2505,8 @@ function GraphToolbar({
2412
2505
  children: isVertical ? ARROW_RIGHT_ICON : ARROW_DOWN_ICON
2413
2506
  }
2414
2507
  ),
2415
- (onZoomOut || onZoomIn || onFitView) && /* @__PURE__ */ jsx21("div", { className: "graph-toolbar-separator" }),
2416
- onZoomOut && /* @__PURE__ */ jsx21(
2508
+ (onZoomOut || onZoomIn || onFitView) && /* @__PURE__ */ jsx22("div", { className: "graph-toolbar-separator" }),
2509
+ onZoomOut && /* @__PURE__ */ jsx22(
2417
2510
  "button",
2418
2511
  {
2419
2512
  type: "button",
@@ -2424,7 +2517,7 @@ function GraphToolbar({
2424
2517
  children: MINUS_ICON
2425
2518
  }
2426
2519
  ),
2427
- onZoomIn && /* @__PURE__ */ jsx21(
2520
+ onZoomIn && /* @__PURE__ */ jsx22(
2428
2521
  "button",
2429
2522
  {
2430
2523
  type: "button",
@@ -2435,7 +2528,7 @@ function GraphToolbar({
2435
2528
  children: PLUS_ICON
2436
2529
  }
2437
2530
  ),
2438
- onFitView && /* @__PURE__ */ jsx21(
2531
+ onFitView && /* @__PURE__ */ jsx22(
2439
2532
  "button",
2440
2533
  {
2441
2534
  type: "button",
@@ -2446,9 +2539,9 @@ function GraphToolbar({
2446
2539
  children: FIT_VIEW_ICON
2447
2540
  }
2448
2541
  ),
2449
- themeToggleEnabled && /* @__PURE__ */ jsxs21(Fragment12, { children: [
2450
- /* @__PURE__ */ jsx21("div", { className: "graph-toolbar-separator" }),
2451
- /* @__PURE__ */ jsx21(
2542
+ themeToggleEnabled && /* @__PURE__ */ jsxs22(Fragment13, { children: [
2543
+ /* @__PURE__ */ jsx22("div", { className: "graph-toolbar-separator" }),
2544
+ /* @__PURE__ */ jsx22(
2452
2545
  "button",
2453
2546
  {
2454
2547
  type: "button",
@@ -2463,8 +2556,73 @@ function GraphToolbar({
2463
2556
  ] }) });
2464
2557
  }
2465
2558
 
2559
+ // src/graph/react/viewer/StillFit.tsx
2560
+ import React11 from "react";
2561
+ import { useEdges, useNodes, useNodesInitialized, useReactFlow, useStore } from "@xyflow/react";
2562
+
2563
+ // src/graph/react/viewer/stillViewport.ts
2564
+ var STILL_PADDING_PX = 16;
2565
+ var STILL_PLACEHOLDER_HEIGHT_PX = 120;
2566
+ function stillContentBounds(nodeBounds, routes) {
2567
+ let minX = nodeBounds.x;
2568
+ let minY = nodeBounds.y;
2569
+ let maxX = nodeBounds.x + nodeBounds.width;
2570
+ let maxY = nodeBounds.y + nodeBounds.height;
2571
+ const take = (x, y) => {
2572
+ if (!Number.isFinite(x) || !Number.isFinite(y)) return;
2573
+ minX = Math.min(minX, x);
2574
+ minY = Math.min(minY, y);
2575
+ maxX = Math.max(maxX, x);
2576
+ maxY = Math.max(maxY, y);
2577
+ };
2578
+ for (const route of routes) {
2579
+ if (!route) continue;
2580
+ for (const point of route.points) take(point.x, point.y);
2581
+ if (route.label) {
2582
+ take(route.label.x, route.label.y);
2583
+ take(route.label.x + route.label.width, route.label.y + route.label.height);
2584
+ }
2585
+ }
2586
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
2587
+ }
2588
+ function stillViewport(bounds, containerWidth, padding = STILL_PADDING_PX) {
2589
+ if (!(containerWidth > 0) || !(bounds.width > 0) || !(bounds.height > 0)) return null;
2590
+ const room = Math.max(containerWidth - 2 * padding, 1);
2591
+ const zoom = Math.min(1, room / bounds.width);
2592
+ return {
2593
+ x: (containerWidth - bounds.width * zoom) / 2 - bounds.x * zoom,
2594
+ y: padding - bounds.y * zoom,
2595
+ zoom,
2596
+ height: Math.ceil(bounds.height * zoom + 2 * padding)
2597
+ };
2598
+ }
2599
+
2600
+ // src/graph/react/viewer/StillFit.tsx
2601
+ function StillFit({ onHeight }) {
2602
+ const width = useStore((s) => s.width);
2603
+ const nodesInitialized = useNodesInitialized();
2604
+ const nodes = useNodes();
2605
+ const edges = useEdges();
2606
+ const { getNodesBounds, setViewport } = useReactFlow();
2607
+ React11.useLayoutEffect(() => {
2608
+ if (!nodesInitialized || nodes.length === 0) return;
2609
+ const bounds = stillContentBounds(
2610
+ getNodesBounds(nodes),
2611
+ edges.map((e) => {
2612
+ var _a;
2613
+ return (_a = e.data) == null ? void 0 : _a.route;
2614
+ })
2615
+ );
2616
+ const view = stillViewport(bounds, width);
2617
+ if (!view) return;
2618
+ void setViewport({ x: view.x, y: view.y, zoom: view.zoom });
2619
+ onHeight(view.height);
2620
+ }, [nodesInitialized, nodes, edges, width, getNodesBounds, setViewport, onHeight]);
2621
+ return null;
2622
+ }
2623
+
2466
2624
  // src/graph/react/nodes/NodeValidationBadge.tsx
2467
- import { jsx as jsx22 } from "react/jsx-runtime";
2625
+ import { jsx as jsx23 } from "react/jsx-runtime";
2468
2626
  function NodeValidationBadge({
2469
2627
  validation,
2470
2628
  onClick
@@ -2474,9 +2632,9 @@ function NodeValidationBadge({
2474
2632
  const className = `node-validation-badge node-validation-badge--${validation.severity}`;
2475
2633
  const text = validation.count > 99 ? "99+" : String(validation.count);
2476
2634
  if (!onClick) {
2477
- return /* @__PURE__ */ jsx22("span", { className, title: tooltip, "aria-label": label, children: text });
2635
+ return /* @__PURE__ */ jsx23("span", { className, title: tooltip, "aria-label": label, children: text });
2478
2636
  }
2479
- return /* @__PURE__ */ jsx22(
2637
+ return /* @__PURE__ */ jsx23(
2480
2638
  "button",
2481
2639
  {
2482
2640
  type: "button",
@@ -2496,7 +2654,7 @@ function validationRingClass(validation) {
2496
2654
  }
2497
2655
 
2498
2656
  // src/graph/react/nodes/controller/ControllerGroupNode.tsx
2499
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
2657
+ import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
2500
2658
  var CONTROLLER_CONFIG = {
2501
2659
  PipeSequence: { badge: "Sequence", icon: "\u2192" },
2502
2660
  PipeParallel: { badge: "Parallel", icon: "//" },
@@ -2518,12 +2676,12 @@ function ControllerGroupNode({ data }) {
2518
2676
  const modifier = getControllerModifier(data.pipeType);
2519
2677
  const isCollapsible = (data.pipeType === "PipeParallel" || data.pipeType === "PipeBatch") && ((_a = data.childCount) != null ? _a : 0) > MAX_VISIBLE_CONTROLLER_CHILDREN;
2520
2678
  const hiddenCount = isCollapsible ? ((_b = data.childCount) != null ? _b : 0) - MAX_VISIBLE_CONTROLLER_CHILDREN : 0;
2521
- return /* @__PURE__ */ jsxs22("div", { className: `controller-group-node ${modifier}${validationRingClass(data.validation)}`, children: [
2522
- /* @__PURE__ */ jsxs22("div", { className: "controller-group-header", children: [
2523
- /* @__PURE__ */ jsx23("span", { className: "controller-group-icon", children: config.icon }),
2524
- /* @__PURE__ */ jsx23("span", { className: "controller-group-badge", children: config.badge }),
2525
- data.label && /* @__PURE__ */ jsx23("span", { className: "controller-group-label", children: data.label }),
2526
- data.onToggleFold && /* @__PURE__ */ jsx23(
2679
+ return /* @__PURE__ */ jsxs23("div", { className: `controller-group-node ${modifier}${validationRingClass(data.validation)}`, children: [
2680
+ /* @__PURE__ */ jsxs23("div", { className: "controller-group-header", children: [
2681
+ /* @__PURE__ */ jsx24("span", { className: "controller-group-icon", children: config.icon }),
2682
+ /* @__PURE__ */ jsx24("span", { className: "controller-group-badge", children: config.badge }),
2683
+ data.label && /* @__PURE__ */ jsx24("span", { className: "controller-group-label", children: data.label }),
2684
+ data.onToggleFold && /* @__PURE__ */ jsx24(
2527
2685
  "button",
2528
2686
  {
2529
2687
  type: "button",
@@ -2538,9 +2696,9 @@ function ControllerGroupNode({ data }) {
2538
2696
  children: "\u2921"
2539
2697
  }
2540
2698
  ),
2541
- data.validation && /* @__PURE__ */ jsx23(NodeValidationBadge, { validation: data.validation, onClick: data.onValidationBadgeClick })
2699
+ data.validation && /* @__PURE__ */ jsx24(NodeValidationBadge, { validation: data.validation, onClick: data.onValidationBadgeClick })
2542
2700
  ] }),
2543
- isCollapsible && /* @__PURE__ */ jsx23(
2701
+ isCollapsible && /* @__PURE__ */ jsx24(
2544
2702
  "button",
2545
2703
  {
2546
2704
  className: "controller-group-collapse",
@@ -2561,7 +2719,7 @@ import { Handle, Position } from "@xyflow/react";
2561
2719
 
2562
2720
  // src/graph/react/nodes/pipe/PipeCardBase.tsx
2563
2721
  import { useState as useState2 } from "react";
2564
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
2722
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
2565
2723
  var PIPE_TYPE_BADGES2 = {
2566
2724
  PipeLLM: "LLM",
2567
2725
  PipeExtract: "Extract",
@@ -2622,21 +2780,22 @@ function PipeCardBase({ data, children }) {
2622
2780
  const staticClass = isStatic ? " pipe-card--static" : "";
2623
2781
  const badgeClass = isController ? "pipe-card-badge pipe-card-badge--controller" : isSignature ? "pipe-card-badge pipe-card-badge--signature" : isBinding ? "pipe-card-badge pipe-card-badge--binding" : "pipe-card-badge";
2624
2782
  const ringClass = validationRingClass(data.validation);
2625
- return /* @__PURE__ */ jsxs23(
2783
+ return /* @__PURE__ */ jsxs24(
2626
2784
  "div",
2627
2785
  {
2628
2786
  className: `pipe-card ${dirClass}${controllerClass}${signatureClass}${bindingClass}${staticClass}${ringClass}`,
2629
2787
  children: [
2630
- /* @__PURE__ */ jsxs23("div", { className: "pipe-card-header", children: [
2631
- /* @__PURE__ */ jsx24("span", { className: badgeClass, children: badge }),
2632
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-code", title: data.pipeCode, children: data.pipeCode }),
2633
- !isStatic && /* @__PURE__ */ jsx24(
2788
+ /* @__PURE__ */ jsxs24("div", { className: "pipe-card-header", children: [
2789
+ /* @__PURE__ */ jsx25("span", { className: badgeClass, children: badge }),
2790
+ data.docGenFormat && /* @__PURE__ */ jsx25("span", { className: "pipe-card-format", title: `Document format: ${data.docGenFormat}`, children: data.docGenFormat.toUpperCase() }),
2791
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-code", title: data.pipeCode, children: data.pipeCode }),
2792
+ !isStatic && /* @__PURE__ */ jsx25(
2634
2793
  "span",
2635
2794
  {
2636
2795
  className: "pipe-card-status",
2637
2796
  style: { color: statusConfig.color },
2638
2797
  title: statusConfig.label,
2639
- children: /* @__PURE__ */ jsx24(
2798
+ children: /* @__PURE__ */ jsx25(
2640
2799
  "span",
2641
2800
  {
2642
2801
  className: `pipe-card-status-dot ${isRunning ? "pipe-card-status-dot--pulse" : ""}`,
@@ -2645,7 +2804,7 @@ function PipeCardBase({ data, children }) {
2645
2804
  )
2646
2805
  }
2647
2806
  ),
2648
- data.onExpand && /* @__PURE__ */ jsx24(
2807
+ data.onExpand && /* @__PURE__ */ jsx25(
2649
2808
  "button",
2650
2809
  {
2651
2810
  type: "button",
@@ -2660,32 +2819,32 @@ function PipeCardBase({ data, children }) {
2660
2819
  children: "\u2922"
2661
2820
  }
2662
2821
  ),
2663
- data.validation && /* @__PURE__ */ jsx24(NodeValidationBadge, { validation: data.validation, onClick: data.onValidationBadgeClick })
2822
+ data.validation && /* @__PURE__ */ jsx25(NodeValidationBadge, { validation: data.validation, onClick: data.onValidationBadgeClick })
2664
2823
  ] }),
2665
- (outcome || batchMultiplicity) && /* @__PURE__ */ jsxs23("div", { className: "pipe-card-annotations", children: [
2666
- outcome && /* @__PURE__ */ jsxs23("span", { className: "pipe-card-annotation pipe-card-annotation--outcome", children: [
2824
+ (outcome || batchMultiplicity) && /* @__PURE__ */ jsxs24("div", { className: "pipe-card-annotations", children: [
2825
+ outcome && /* @__PURE__ */ jsxs24("span", { className: "pipe-card-annotation pipe-card-annotation--outcome", children: [
2667
2826
  "outcome: ",
2668
2827
  outcome
2669
2828
  ] }),
2670
- batchMultiplicity && /* @__PURE__ */ jsx24("span", { className: "pipe-card-annotation pipe-card-annotation--batch", children: batchMultiplicity })
2829
+ batchMultiplicity && /* @__PURE__ */ jsx25("span", { className: "pipe-card-annotation pipe-card-annotation--batch", children: batchMultiplicity })
2671
2830
  ] }),
2672
- data.description && /* @__PURE__ */ jsx24("span", { className: "pipe-card-description", title: data.description, children: data.description }),
2673
- data.inputs.length > 0 && /* @__PURE__ */ jsxs23("div", { className: "pipe-card-io", children: [
2674
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-io-label", children: "INPUTS" }),
2675
- /* @__PURE__ */ jsxs23("div", { className: "pipe-card-io-pills", children: [
2676
- visibleInputs.map((input) => /* @__PURE__ */ jsxs23(
2831
+ data.description && /* @__PURE__ */ jsx25("span", { className: "pipe-card-description", title: data.description, children: data.description }),
2832
+ data.inputs.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "pipe-card-io", children: [
2833
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-io-label", children: "INPUTS" }),
2834
+ /* @__PURE__ */ jsxs24("div", { className: "pipe-card-io-pills", children: [
2835
+ visibleInputs.map((input) => /* @__PURE__ */ jsxs24(
2677
2836
  "span",
2678
2837
  {
2679
2838
  className: "pipe-card-io-pill",
2680
2839
  title: `${input.name}: ${input.concept}`,
2681
2840
  children: [
2682
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-io-pill-name", children: input.name }),
2683
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-io-pill-concept", children: input.concept })
2841
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-io-pill-name", children: input.name }),
2842
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-io-pill-concept", children: input.concept })
2684
2843
  ]
2685
2844
  },
2686
2845
  input.name
2687
2846
  )),
2688
- hasMany && /* @__PURE__ */ jsx24(
2847
+ hasMany && /* @__PURE__ */ jsx25(
2689
2848
  "button",
2690
2849
  {
2691
2850
  className: "pipe-card-io-more",
@@ -2698,16 +2857,16 @@ function PipeCardBase({ data, children }) {
2698
2857
  )
2699
2858
  ] })
2700
2859
  ] }),
2701
- data.outputs.length > 0 && /* @__PURE__ */ jsxs23("div", { className: "pipe-card-io", children: [
2702
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-io-label", children: "OUTPUT" }),
2703
- /* @__PURE__ */ jsx24("div", { className: "pipe-card-io-pills", children: data.outputs.map((output) => /* @__PURE__ */ jsxs23(
2860
+ data.outputs.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "pipe-card-io", children: [
2861
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-io-label", children: "OUTPUT" }),
2862
+ /* @__PURE__ */ jsx25("div", { className: "pipe-card-io-pills", children: data.outputs.map((output) => /* @__PURE__ */ jsxs24(
2704
2863
  "span",
2705
2864
  {
2706
2865
  className: "pipe-card-io-pill",
2707
2866
  title: `${output.name}: ${output.concept}`,
2708
2867
  children: [
2709
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-io-pill-name", children: output.name }),
2710
- /* @__PURE__ */ jsx24("span", { className: "pipe-card-io-pill-concept", children: output.concept })
2868
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-io-pill-name", children: output.name }),
2869
+ /* @__PURE__ */ jsx25("span", { className: "pipe-card-io-pill-concept", children: output.concept })
2711
2870
  ]
2712
2871
  },
2713
2872
  output.name
@@ -2742,11 +2901,11 @@ function getPipeCardComponent(pipeType) {
2742
2901
  }
2743
2902
 
2744
2903
  // src/graph/react/nodes/pipe/PipeCardNode.tsx
2745
- import { Fragment as Fragment13, jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
2904
+ import { Fragment as Fragment14, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
2746
2905
  function PipeCardNode({ data }) {
2747
2906
  var _a;
2748
2907
  const Card = (_a = getPipeCardComponent(data.pipeType)) != null ? _a : PipeCardBase;
2749
- return /* @__PURE__ */ jsx25(Card, { data });
2908
+ return /* @__PURE__ */ jsx26(Card, { data });
2750
2909
  }
2751
2910
  function PipeCardRFNode({
2752
2911
  data,
@@ -2755,16 +2914,16 @@ function PipeCardRFNode({
2755
2914
  }) {
2756
2915
  const payload = data.pipeCardData;
2757
2916
  if (!payload) return null;
2758
- return /* @__PURE__ */ jsxs24(Fragment13, { children: [
2759
- /* @__PURE__ */ jsx25(Handle, { type: "target", position: targetPosition }),
2760
- /* @__PURE__ */ jsx25(PipeCardNode, { data: payload }),
2761
- /* @__PURE__ */ jsx25(Handle, { type: "source", position: sourcePosition })
2917
+ return /* @__PURE__ */ jsxs25(Fragment14, { children: [
2918
+ /* @__PURE__ */ jsx26(Handle, { type: "target", position: targetPosition }),
2919
+ /* @__PURE__ */ jsx26(PipeCardNode, { data: payload }),
2920
+ /* @__PURE__ */ jsx26(Handle, { type: "source", position: sourcePosition })
2762
2921
  ] });
2763
2922
  }
2764
2923
 
2765
2924
  // src/graph/react/styles/simple/SimpleNodes.tsx
2766
2925
  import { Handle as Handle2, Position as Position2 } from "@xyflow/react";
2767
- import { Fragment as Fragment14, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
2926
+ import { Fragment as Fragment15, jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
2768
2927
  var ICON_PROPS2 = {
2769
2928
  viewBox: "0 0 24 24",
2770
2929
  fill: "none",
@@ -2775,90 +2934,90 @@ var ICON_PROPS2 = {
2775
2934
  "aria-hidden": true
2776
2935
  };
2777
2936
  function Icon({ size = 13, children }) {
2778
- return /* @__PURE__ */ jsx26("svg", __spreadProps(__spreadValues({}, ICON_PROPS2), { width: size, height: size, children }));
2937
+ return /* @__PURE__ */ jsx27("svg", __spreadProps(__spreadValues({}, ICON_PROPS2), { width: size, height: size, children }));
2779
2938
  }
2780
2939
  var CATEGORY_ICONS = {
2781
- ai: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2782
- /* @__PURE__ */ jsx26("path", { d: "M9.94 15.5a2 2 0 0 0-1.44-1.44l-6.13-1.58a.5.5 0 0 1 0-.96L8.5 9.94A2 2 0 0 0 9.94 8.5l1.58-6.14a.5.5 0 0 1 .96 0l1.58 6.14a2 2 0 0 0 1.44 1.44l6.14 1.58a.5.5 0 0 1 0 .96l-6.14 1.58a2 2 0 0 0-1.44 1.44l-1.58 6.13a.5.5 0 0 1-.96 0z" }),
2783
- /* @__PURE__ */ jsx26("path", { d: "M20 3v4" }),
2784
- /* @__PURE__ */ jsx26("path", { d: "M22 5h-4" })
2940
+ ai: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2941
+ /* @__PURE__ */ jsx27("path", { d: "M9.94 15.5a2 2 0 0 0-1.44-1.44l-6.13-1.58a.5.5 0 0 1 0-.96L8.5 9.94A2 2 0 0 0 9.94 8.5l1.58-6.14a.5.5 0 0 1 .96 0l1.58 6.14a2 2 0 0 0 1.44 1.44l6.14 1.58a.5.5 0 0 1 0 .96l-6.14 1.58a2 2 0 0 0-1.44 1.44l-1.58 6.13a.5.5 0 0 1-.96 0z" }),
2942
+ /* @__PURE__ */ jsx27("path", { d: "M20 3v4" }),
2943
+ /* @__PURE__ */ jsx27("path", { d: "M22 5h-4" })
2785
2944
  ] }),
2786
- extract: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2787
- /* @__PURE__ */ jsx26("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }),
2788
- /* @__PURE__ */ jsx26("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }),
2789
- /* @__PURE__ */ jsx26("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }),
2790
- /* @__PURE__ */ jsx26("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" }),
2791
- /* @__PURE__ */ jsx26("path", { d: "M7 8h8" }),
2792
- /* @__PURE__ */ jsx26("path", { d: "M7 12h10" }),
2793
- /* @__PURE__ */ jsx26("path", { d: "M7 16h6" })
2945
+ extract: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2946
+ /* @__PURE__ */ jsx27("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }),
2947
+ /* @__PURE__ */ jsx27("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }),
2948
+ /* @__PURE__ */ jsx27("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }),
2949
+ /* @__PURE__ */ jsx27("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" }),
2950
+ /* @__PURE__ */ jsx27("path", { d: "M7 8h8" }),
2951
+ /* @__PURE__ */ jsx27("path", { d: "M7 12h10" }),
2952
+ /* @__PURE__ */ jsx27("path", { d: "M7 16h6" })
2794
2953
  ] }),
2795
- image: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2796
- /* @__PURE__ */ jsx26("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2797
- /* @__PURE__ */ jsx26("circle", { cx: "9", cy: "9", r: "2" }),
2798
- /* @__PURE__ */ jsx26("path", { d: "m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21" })
2954
+ image: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2955
+ /* @__PURE__ */ jsx27("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2956
+ /* @__PURE__ */ jsx27("circle", { cx: "9", cy: "9", r: "2" }),
2957
+ /* @__PURE__ */ jsx27("path", { d: "m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21" })
2799
2958
  ] }),
2800
- search: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2801
- /* @__PURE__ */ jsx26("circle", { cx: "11", cy: "11", r: "8" }),
2802
- /* @__PURE__ */ jsx26("path", { d: "m21 21-4.3-4.3" })
2959
+ search: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2960
+ /* @__PURE__ */ jsx27("circle", { cx: "11", cy: "11", r: "8" }),
2961
+ /* @__PURE__ */ jsx27("path", { d: "m21 21-4.3-4.3" })
2803
2962
  ] }),
2804
- code: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2805
- /* @__PURE__ */ jsx26("polyline", { points: "16 18 22 12 16 6" }),
2806
- /* @__PURE__ */ jsx26("polyline", { points: "8 6 2 12 8 18" })
2963
+ code: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2964
+ /* @__PURE__ */ jsx27("polyline", { points: "16 18 22 12 16 6" }),
2965
+ /* @__PURE__ */ jsx27("polyline", { points: "8 6 2 12 8 18" })
2807
2966
  ] }),
2808
- template: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2809
- /* @__PURE__ */ jsx26("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
2810
- /* @__PURE__ */ jsx26("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
2811
- /* @__PURE__ */ jsx26("path", { d: "M16 13H8" }),
2812
- /* @__PURE__ */ jsx26("path", { d: "M16 17H8" })
2967
+ template: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2968
+ /* @__PURE__ */ jsx27("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
2969
+ /* @__PURE__ */ jsx27("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
2970
+ /* @__PURE__ */ jsx27("path", { d: "M16 13H8" }),
2971
+ /* @__PURE__ */ jsx27("path", { d: "M16 17H8" })
2813
2972
  ] }),
2814
- document: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2815
- /* @__PURE__ */ jsx26("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
2816
- /* @__PURE__ */ jsx26("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
2817
- /* @__PURE__ */ jsx26("path", { d: "M12 18v-6" }),
2818
- /* @__PURE__ */ jsx26("path", { d: "m9 15 3 3 3-3" })
2973
+ document: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2974
+ /* @__PURE__ */ jsx27("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
2975
+ /* @__PURE__ */ jsx27("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
2976
+ /* @__PURE__ */ jsx27("path", { d: "M12 18v-6" }),
2977
+ /* @__PURE__ */ jsx27("path", { d: "m9 15 3 3 3-3" })
2819
2978
  ] }),
2820
- judge: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2821
- /* @__PURE__ */ jsx26("path", { d: "m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" }),
2822
- /* @__PURE__ */ jsx26("path", { d: "m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" }),
2823
- /* @__PURE__ */ jsx26("path", { d: "M7 21h10" }),
2824
- /* @__PURE__ */ jsx26("path", { d: "M12 3v18" }),
2825
- /* @__PURE__ */ jsx26("path", { d: "M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2" })
2979
+ judge: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2980
+ /* @__PURE__ */ jsx27("path", { d: "m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" }),
2981
+ /* @__PURE__ */ jsx27("path", { d: "m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" }),
2982
+ /* @__PURE__ */ jsx27("path", { d: "M7 21h10" }),
2983
+ /* @__PURE__ */ jsx27("path", { d: "M12 3v18" }),
2984
+ /* @__PURE__ */ jsx27("path", { d: "M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2" })
2826
2985
  ] }),
2827
- planned: /* @__PURE__ */ jsx26("circle", { cx: "12", cy: "12", r: "9", strokeDasharray: "3 3" }),
2828
- steps: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2829
- /* @__PURE__ */ jsx26("path", { d: "m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z" }),
2830
- /* @__PURE__ */ jsx26("path", { d: "m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65" }),
2831
- /* @__PURE__ */ jsx26("path", { d: "m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65" })
2986
+ planned: /* @__PURE__ */ jsx27("circle", { cx: "12", cy: "12", r: "9", strokeDasharray: "3 3" }),
2987
+ steps: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2988
+ /* @__PURE__ */ jsx27("path", { d: "m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z" }),
2989
+ /* @__PURE__ */ jsx27("path", { d: "m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65" }),
2990
+ /* @__PURE__ */ jsx27("path", { d: "m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65" })
2832
2991
  ] }),
2833
- parallel: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2834
- /* @__PURE__ */ jsx26("path", { d: "M16 3h5v5" }),
2835
- /* @__PURE__ */ jsx26("path", { d: "M8 3H3v5" }),
2836
- /* @__PURE__ */ jsx26("path", { d: "M12 22v-8.3a4 4 0 0 0-1.17-2.87L3 3" }),
2837
- /* @__PURE__ */ jsx26("path", { d: "m15 9 6-6" })
2992
+ parallel: /* @__PURE__ */ jsxs26(Fragment15, { children: [
2993
+ /* @__PURE__ */ jsx27("path", { d: "M16 3h5v5" }),
2994
+ /* @__PURE__ */ jsx27("path", { d: "M8 3H3v5" }),
2995
+ /* @__PURE__ */ jsx27("path", { d: "M12 22v-8.3a4 4 0 0 0-1.17-2.87L3 3" }),
2996
+ /* @__PURE__ */ jsx27("path", { d: "m15 9 6-6" })
2838
2997
  ] }),
2839
- decision: /* @__PURE__ */ jsx26("path", { d: "M12 2 22 12 12 22 2 12Z" }),
2840
- repeat: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2841
- /* @__PURE__ */ jsx26("path", { d: "m17 2 4 4-4 4" }),
2842
- /* @__PURE__ */ jsx26("path", { d: "M3 11v-1a4 4 0 0 1 4-4h14" }),
2843
- /* @__PURE__ */ jsx26("path", { d: "m7 22-4-4 4-4" }),
2844
- /* @__PURE__ */ jsx26("path", { d: "M21 13v1a4 4 0 0 1-4 4H3" })
2998
+ decision: /* @__PURE__ */ jsx27("path", { d: "M12 2 22 12 12 22 2 12Z" }),
2999
+ repeat: /* @__PURE__ */ jsxs26(Fragment15, { children: [
3000
+ /* @__PURE__ */ jsx27("path", { d: "m17 2 4 4-4 4" }),
3001
+ /* @__PURE__ */ jsx27("path", { d: "M3 11v-1a4 4 0 0 1 4-4h14" }),
3002
+ /* @__PURE__ */ jsx27("path", { d: "m7 22-4-4 4-4" }),
3003
+ /* @__PURE__ */ jsx27("path", { d: "M21 13v1a4 4 0 0 1-4 4H3" })
2845
3004
  ] }),
2846
- pick: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2847
- /* @__PURE__ */ jsx26("polyline", { points: "15 10 20 15 15 20" }),
2848
- /* @__PURE__ */ jsx26("path", { d: "M4 4v7a4 4 0 0 0 4 4h12" })
3005
+ pick: /* @__PURE__ */ jsxs26(Fragment15, { children: [
3006
+ /* @__PURE__ */ jsx27("polyline", { points: "15 10 20 15 15 20" }),
3007
+ /* @__PURE__ */ jsx27("path", { d: "M4 4v7a4 4 0 0 0 4 4h12" })
2849
3008
  ] })
2850
3009
  };
2851
- var EXPAND_ICON2 = /* @__PURE__ */ jsxs25(Icon, { size: 12, children: [
2852
- /* @__PURE__ */ jsx26("polyline", { points: "15 3 21 3 21 9" }),
2853
- /* @__PURE__ */ jsx26("polyline", { points: "9 21 3 21 3 15" }),
2854
- /* @__PURE__ */ jsx26("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
2855
- /* @__PURE__ */ jsx26("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
3010
+ var EXPAND_ICON2 = /* @__PURE__ */ jsxs26(Icon, { size: 12, children: [
3011
+ /* @__PURE__ */ jsx27("polyline", { points: "15 3 21 3 21 9" }),
3012
+ /* @__PURE__ */ jsx27("polyline", { points: "9 21 3 21 3 15" }),
3013
+ /* @__PURE__ */ jsx27("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
3014
+ /* @__PURE__ */ jsx27("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
2856
3015
  ] });
2857
- var COLLAPSE_ICON2 = /* @__PURE__ */ jsxs25(Icon, { size: 12, children: [
2858
- /* @__PURE__ */ jsx26("polyline", { points: "4 14 10 14 10 20" }),
2859
- /* @__PURE__ */ jsx26("polyline", { points: "20 10 14 10 14 4" }),
2860
- /* @__PURE__ */ jsx26("line", { x1: "14", y1: "10", x2: "21", y2: "3" }),
2861
- /* @__PURE__ */ jsx26("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
3016
+ var COLLAPSE_ICON2 = /* @__PURE__ */ jsxs26(Icon, { size: 12, children: [
3017
+ /* @__PURE__ */ jsx27("polyline", { points: "4 14 10 14 10 20" }),
3018
+ /* @__PURE__ */ jsx27("polyline", { points: "20 10 14 10 14 4" }),
3019
+ /* @__PURE__ */ jsx27("line", { x1: "14", y1: "10", x2: "21", y2: "3" }),
3020
+ /* @__PURE__ */ jsx27("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
2862
3021
  ] });
2863
3022
  var STATUS_LABELS = {
2864
3023
  succeeded: "Done",
@@ -2869,25 +3028,25 @@ var STATUS_LABELS = {
2869
3028
  canceled: "Canceled"
2870
3029
  };
2871
3030
  var STATUS_ICONS = {
2872
- succeeded: /* @__PURE__ */ jsx26("polyline", { points: "20 6 9 17 4 12" }),
2873
- failed: /* @__PURE__ */ jsxs25(Fragment14, { children: [
2874
- /* @__PURE__ */ jsx26("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2875
- /* @__PURE__ */ jsx26("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
3031
+ succeeded: /* @__PURE__ */ jsx27("polyline", { points: "20 6 9 17 4 12" }),
3032
+ failed: /* @__PURE__ */ jsxs26(Fragment15, { children: [
3033
+ /* @__PURE__ */ jsx27("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
3034
+ /* @__PURE__ */ jsx27("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2876
3035
  ] }),
2877
- running: /* @__PURE__ */ jsx26("path", { d: "M21 12a9 9 0 1 1-6.22-8.56" }),
2878
- scheduled: /* @__PURE__ */ jsx26("circle", { cx: "12", cy: "12", r: "8" }),
2879
- skipped: /* @__PURE__ */ jsx26("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
2880
- canceled: /* @__PURE__ */ jsx26("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
3036
+ running: /* @__PURE__ */ jsx27("path", { d: "M21 12a9 9 0 1 1-6.22-8.56" }),
3037
+ scheduled: /* @__PURE__ */ jsx27("circle", { cx: "12", cy: "12", r: "8" }),
3038
+ skipped: /* @__PURE__ */ jsx27("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
3039
+ canceled: /* @__PURE__ */ jsx27("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
2881
3040
  };
2882
3041
  function StatusMark({ status, graphMode }) {
2883
3042
  if (graphMode === "static") return null;
2884
- return /* @__PURE__ */ jsx26(
3043
+ return /* @__PURE__ */ jsx27(
2885
3044
  "span",
2886
3045
  {
2887
3046
  className: `simple-status simple-status--${status}`,
2888
3047
  title: STATUS_LABELS[status],
2889
3048
  "aria-label": STATUS_LABELS[status],
2890
- children: /* @__PURE__ */ jsx26(Icon, { size: 11, children: STATUS_ICONS[status] })
3049
+ children: /* @__PURE__ */ jsx27(Icon, { size: 11, children: STATUS_ICONS[status] })
2891
3050
  }
2892
3051
  );
2893
3052
  }
@@ -2896,17 +3055,17 @@ function Handles({
2896
3055
  targetPosition = Position2.Left,
2897
3056
  children
2898
3057
  }) {
2899
- return /* @__PURE__ */ jsxs25(Fragment14, { children: [
2900
- /* @__PURE__ */ jsx26(Handle2, { type: "target", position: targetPosition, className: "simple-handle" }),
3058
+ return /* @__PURE__ */ jsxs26(Fragment15, { children: [
3059
+ /* @__PURE__ */ jsx27(Handle2, { type: "target", position: targetPosition, className: "simple-handle" }),
2901
3060
  children,
2902
- /* @__PURE__ */ jsx26(Handle2, { type: "source", position: sourcePosition, className: "simple-handle" })
3061
+ /* @__PURE__ */ jsx27(Handle2, { type: "source", position: sourcePosition, className: "simple-handle" })
2903
3062
  ] });
2904
3063
  }
2905
3064
  function ValidationMark({
2906
3065
  validation,
2907
3066
  onClick
2908
3067
  }) {
2909
- return validation ? /* @__PURE__ */ jsx26(NodeValidationBadge, { validation, onClick }) : null;
3068
+ return validation ? /* @__PURE__ */ jsx27(NodeValidationBadge, { validation, onClick }) : null;
2910
3069
  }
2911
3070
  function payloadOf(data, kinds) {
2912
3071
  const simple = data.simple;
@@ -2917,20 +3076,20 @@ function SimpleStepNode({ data, sourcePosition, targetPosition }) {
2917
3076
  const step = payloadOf(data, ["step"]);
2918
3077
  if (!step) return null;
2919
3078
  const statusClass = step.graphMode !== "static" ? ` simple-step--${step.status}` : "";
2920
- return /* @__PURE__ */ jsx26(Handles, { sourcePosition, targetPosition, children: /* @__PURE__ */ jsxs25(
3079
+ return /* @__PURE__ */ jsx27(Handles, { sourcePosition, targetPosition, children: /* @__PURE__ */ jsxs26(
2921
3080
  "div",
2922
3081
  {
2923
3082
  className: `simple-step simple-step--${step.category}${statusClass}${validationRingClass(data.validation)}`,
2924
3083
  children: [
2925
- /* @__PURE__ */ jsxs25("div", { className: "simple-step-header", children: [
2926
- /* @__PURE__ */ jsxs25("span", { className: "simple-step-category", children: [
2927
- /* @__PURE__ */ jsx26(Icon, { children: CATEGORY_ICONS[step.category] }),
3084
+ /* @__PURE__ */ jsxs26("div", { className: "simple-step-header", children: [
3085
+ /* @__PURE__ */ jsxs26("span", { className: "simple-step-category", children: [
3086
+ /* @__PURE__ */ jsx27(Icon, { children: CATEGORY_ICONS[step.category] }),
2928
3087
  STEP_CATEGORY_WORDS[step.category]
2929
3088
  ] }),
2930
- /* @__PURE__ */ jsx26(StatusMark, { status: step.status, graphMode: step.graphMode }),
2931
- /* @__PURE__ */ jsx26(ValidationMark, { validation: data.validation, onClick: data.onValidationBadgeClick })
3089
+ /* @__PURE__ */ jsx27(StatusMark, { status: step.status, graphMode: step.graphMode }),
3090
+ /* @__PURE__ */ jsx27(ValidationMark, { validation: data.validation, onClick: data.onValidationBadgeClick })
2932
3091
  ] }),
2933
- /* @__PURE__ */ jsx26(
3092
+ /* @__PURE__ */ jsx27(
2934
3093
  "div",
2935
3094
  {
2936
3095
  className: "simple-step-title",
@@ -2943,11 +3102,11 @@ function SimpleStepNode({ data, sourcePosition, targetPosition }) {
2943
3102
  children: step.title
2944
3103
  }
2945
3104
  ),
2946
- step.forEach && /* @__PURE__ */ jsxs25("span", { className: "simple-step-foreach", children: [
2947
- /* @__PURE__ */ jsx26(Icon, { size: 11, children: CATEGORY_ICONS.repeat }),
3105
+ step.forEach && /* @__PURE__ */ jsxs26("span", { className: "simple-step-foreach", children: [
3106
+ /* @__PURE__ */ jsx27(Icon, { size: 11, children: CATEGORY_ICONS.repeat }),
2948
3107
  step.forEach
2949
3108
  ] }),
2950
- step.innerStepCount !== void 0 && /* @__PURE__ */ jsxs25(
3109
+ step.innerStepCount !== void 0 && /* @__PURE__ */ jsxs26(
2951
3110
  "button",
2952
3111
  {
2953
3112
  type: "button",
@@ -2971,24 +3130,24 @@ function SimpleStepNode({ data, sourcePosition, targetPosition }) {
2971
3130
  }
2972
3131
  var DOCUMENT_PATH = "M1 1 H99 V84 C80 98 62 74 44 86 C28 96 14 96 1 88 Z";
2973
3132
  function DocumentShape({ className }) {
2974
- return /* @__PURE__ */ jsx26("svg", { className, viewBox: "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx26("path", { d: DOCUMENT_PATH, vectorEffect: "non-scaling-stroke" }) });
3133
+ return /* @__PURE__ */ jsx27("svg", { className, viewBox: "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx27("path", { d: DOCUMENT_PATH, vectorEffect: "non-scaling-stroke" }) });
2975
3134
  }
2976
3135
  function SimpleTerminalNode({ data, sourcePosition, targetPosition }) {
2977
3136
  const terminal = payloadOf(data, ["input", "output"]);
2978
3137
  if (!terminal) return null;
2979
- return /* @__PURE__ */ jsx26(Handles, { sourcePosition, targetPosition, children: /* @__PURE__ */ jsxs25(
3138
+ return /* @__PURE__ */ jsx27(Handles, { sourcePosition, targetPosition, children: /* @__PURE__ */ jsxs26(
2980
3139
  "div",
2981
3140
  {
2982
3141
  className: `simple-terminal simple-terminal--${terminal.kind}${terminal.isList ? " simple-terminal--list" : ""}`,
2983
3142
  children: [
2984
- terminal.isList && /* @__PURE__ */ jsxs25(Fragment14, { children: [
2985
- /* @__PURE__ */ jsx26(DocumentShape, { className: "simple-terminal-shape simple-terminal-shape--back2" }),
2986
- /* @__PURE__ */ jsx26(DocumentShape, { className: "simple-terminal-shape simple-terminal-shape--back1" })
3143
+ terminal.isList && /* @__PURE__ */ jsxs26(Fragment15, { children: [
3144
+ /* @__PURE__ */ jsx27(DocumentShape, { className: "simple-terminal-shape simple-terminal-shape--back2" }),
3145
+ /* @__PURE__ */ jsx27(DocumentShape, { className: "simple-terminal-shape simple-terminal-shape--back1" })
2987
3146
  ] }),
2988
- /* @__PURE__ */ jsx26(DocumentShape, { className: "simple-terminal-shape" }),
2989
- /* @__PURE__ */ jsxs25("div", { className: "simple-terminal-text", children: [
2990
- /* @__PURE__ */ jsx26("span", { className: "simple-terminal-title", title: terminal.title, children: terminal.title }),
2991
- terminal.subtitle && /* @__PURE__ */ jsx26("span", { className: "simple-terminal-subtitle", children: terminal.subtitle })
3147
+ /* @__PURE__ */ jsx27(DocumentShape, { className: "simple-terminal-shape" }),
3148
+ /* @__PURE__ */ jsxs26("div", { className: "simple-terminal-text", children: [
3149
+ /* @__PURE__ */ jsx27("span", { className: "simple-terminal-title", title: terminal.title, children: terminal.title }),
3150
+ terminal.subtitle && /* @__PURE__ */ jsx27("span", { className: "simple-terminal-subtitle", children: terminal.subtitle })
2992
3151
  ] })
2993
3152
  ]
2994
3153
  }
@@ -2998,35 +3157,35 @@ function SimpleDecisionNode({ data, sourcePosition, targetPosition }) {
2998
3157
  const decision = payloadOf(data, ["decision"]);
2999
3158
  if (!decision) return null;
3000
3159
  const statusClass = decision.graphMode !== "static" ? ` simple-decision--${decision.status}` : "";
3001
- return /* @__PURE__ */ jsx26(Handles, { sourcePosition, targetPosition, children: /* @__PURE__ */ jsxs25("div", { className: `simple-decision${statusClass}${validationRingClass(data.validation)}`, children: [
3002
- /* @__PURE__ */ jsx26(
3160
+ return /* @__PURE__ */ jsx27(Handles, { sourcePosition, targetPosition, children: /* @__PURE__ */ jsxs26("div", { className: `simple-decision${statusClass}${validationRingClass(data.validation)}`, children: [
3161
+ /* @__PURE__ */ jsx27(
3003
3162
  "svg",
3004
3163
  {
3005
3164
  className: "simple-decision-shape",
3006
3165
  viewBox: "0 0 100 100",
3007
3166
  preserveAspectRatio: "none",
3008
3167
  "aria-hidden": "true",
3009
- children: /* @__PURE__ */ jsx26("path", { d: "M50 1 L99 50 L50 99 L1 50 Z", vectorEffect: "non-scaling-stroke" })
3168
+ children: /* @__PURE__ */ jsx27("path", { d: "M50 1 L99 50 L50 99 L1 50 Z", vectorEffect: "non-scaling-stroke" })
3010
3169
  }
3011
3170
  ),
3012
- /* @__PURE__ */ jsx26("div", { className: "simple-decision-text", title: decision.title, children: decision.title }),
3013
- /* @__PURE__ */ jsxs25("div", { className: "simple-decision-marks", children: [
3014
- /* @__PURE__ */ jsx26(StatusMark, { status: decision.status, graphMode: decision.graphMode }),
3015
- /* @__PURE__ */ jsx26(ValidationMark, { validation: data.validation, onClick: data.onValidationBadgeClick })
3171
+ /* @__PURE__ */ jsx27("div", { className: "simple-decision-text", title: decision.title, children: decision.title }),
3172
+ /* @__PURE__ */ jsxs26("div", { className: "simple-decision-marks", children: [
3173
+ /* @__PURE__ */ jsx27(StatusMark, { status: decision.status, graphMode: decision.graphMode }),
3174
+ /* @__PURE__ */ jsx27(ValidationMark, { validation: data.validation, onClick: data.onValidationBadgeClick })
3016
3175
  ] })
3017
3176
  ] }) });
3018
3177
  }
3019
3178
  function SimpleFrameNode({ data }) {
3020
3179
  const frame = payloadOf(data, ["frame"]);
3021
3180
  if (!frame) return null;
3022
- return /* @__PURE__ */ jsx26("div", { className: `simple-frame${validationRingClass(data.validation)}`, children: /* @__PURE__ */ jsxs25("div", { className: "simple-frame-header", children: [
3023
- /* @__PURE__ */ jsxs25("span", { className: "simple-frame-title", children: [
3024
- /* @__PURE__ */ jsx26(Icon, { size: 12, children: CATEGORY_ICONS.repeat }),
3181
+ return /* @__PURE__ */ jsx27("div", { className: `simple-frame${validationRingClass(data.validation)}`, children: /* @__PURE__ */ jsxs26("div", { className: "simple-frame-header", children: [
3182
+ /* @__PURE__ */ jsxs26("span", { className: "simple-frame-title", children: [
3183
+ /* @__PURE__ */ jsx27(Icon, { size: 12, children: CATEGORY_ICONS.repeat }),
3025
3184
  frame.title
3026
3185
  ] }),
3027
- /* @__PURE__ */ jsx26(StatusMark, { status: frame.status, graphMode: frame.graphMode }),
3028
- /* @__PURE__ */ jsx26(ValidationMark, { validation: data.validation, onClick: data.onValidationBadgeClick }),
3029
- frame.onFold && /* @__PURE__ */ jsx26(
3186
+ /* @__PURE__ */ jsx27(StatusMark, { status: frame.status, graphMode: frame.graphMode }),
3187
+ /* @__PURE__ */ jsx27(ValidationMark, { validation: data.validation, onClick: data.onValidationBadgeClick }),
3188
+ frame.onFold && /* @__PURE__ */ jsx27(
3030
3189
  "button",
3031
3190
  {
3032
3191
  type: "button",
@@ -3052,7 +3211,7 @@ var simpleNodeTypes = {
3052
3211
 
3053
3212
  // src/graph/react/edges/RoutedEdge.tsx
3054
3213
  import { BaseEdge, getSmoothStepPath } from "@xyflow/react";
3055
- import { jsx as jsx27 } from "react/jsx-runtime";
3214
+ import { jsx as jsx28 } from "react/jsx-runtime";
3056
3215
  function RoutedEdge({
3057
3216
  id,
3058
3217
  sourceX,
@@ -3092,7 +3251,7 @@ function RoutedEdge({
3092
3251
  borderRadius: 8
3093
3252
  });
3094
3253
  }
3095
- return /* @__PURE__ */ jsx27(
3254
+ return /* @__PURE__ */ jsx28(
3096
3255
  BaseEdge,
3097
3256
  {
3098
3257
  id,
@@ -3114,11 +3273,24 @@ function RoutedEdge({
3114
3273
  }
3115
3274
 
3116
3275
  // src/graph/react/viewer/GraphViewer.tsx
3117
- import { Fragment as Fragment15, jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
3276
+ import { Fragment as Fragment16, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
3118
3277
  var nodeTypes = __spreadValues(__spreadProps(__spreadValues({}, controllerNodeTypes), {
3119
3278
  pipeCard: PipeCardRFNode
3120
3279
  }), simpleNodeTypes);
3121
3280
  var edgeTypes = { [EDGE_TYPE_ROUTED]: RoutedEdge };
3281
+ var STILL_FLOW_PROPS = {
3282
+ panOnDrag: false,
3283
+ zoomOnScroll: false,
3284
+ zoomOnPinch: false,
3285
+ zoomOnDoubleClick: false,
3286
+ preventScrolling: false,
3287
+ nodesDraggable: false,
3288
+ nodesConnectable: false,
3289
+ nodesFocusable: false,
3290
+ edgesFocusable: false,
3291
+ elementsSelectable: false,
3292
+ disableKeyboardA11y: true
3293
+ };
3122
3294
  function StuffNodeDetail({
3123
3295
  nodeId,
3124
3296
  stuffData,
@@ -3136,7 +3308,7 @@ function StuffNodeDetail({
3136
3308
  const conceptInfo = stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : void 0;
3137
3309
  const isDryRun = graphSpecMode(graphspec) === GRAPH_SPEC_MODE.DRY;
3138
3310
  const descriptors = resultDescriptors(artifacts);
3139
- const renderData = descriptors ? () => /* @__PURE__ */ jsx28(
3311
+ const renderData = descriptors ? () => /* @__PURE__ */ jsx29(
3140
3312
  StuffResultPanel,
3141
3313
  __spreadProps(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadProps(__spreadValues({}, descriptors), {
3142
3314
  stuff: stuffData
@@ -3145,7 +3317,7 @@ function StuffNodeDetail({
3145
3317
  })
3146
3318
  ) : void 0;
3147
3319
  if (conceptInfo) {
3148
- return /* @__PURE__ */ jsx28(
3320
+ return /* @__PURE__ */ jsx29(
3149
3321
  ConceptDetailPanel,
3150
3322
  {
3151
3323
  concept: conceptInfo,
@@ -3156,8 +3328,8 @@ function StuffNodeDetail({
3156
3328
  }
3157
3329
  );
3158
3330
  }
3159
- if (isDryRun) return /* @__PURE__ */ jsx28("div", { className: "detail-not-available", children: "Dry run data hidden" });
3160
- return /* @__PURE__ */ jsx28(Fragment15, { children: (_a = renderData == null ? void 0 : renderData()) != null ? _a : /* @__PURE__ */ jsx28("div", { className: "detail-not-available", children: "No data" }) });
3331
+ if (isDryRun) return /* @__PURE__ */ jsx29("div", { className: "detail-not-available", children: "Dry run data hidden" });
3332
+ return /* @__PURE__ */ jsx29(Fragment16, { children: (_a = renderData == null ? void 0 : renderData()) != null ? _a : /* @__PURE__ */ jsx29("div", { className: "detail-not-available", children: "No data" }) });
3161
3333
  }
3162
3334
  function seedFoldedControllers(mode, controllerIds) {
3163
3335
  if (mode === FOLD_MODE.FOLDED) return new Set(controllerIds);
@@ -3222,6 +3394,7 @@ function GraphViewer(props) {
3222
3394
  initialShowControllers,
3223
3395
  initialFoldMode,
3224
3396
  hideToolbar = false,
3397
+ interactive = true,
3225
3398
  theme: themeProp,
3226
3399
  graphStyle: graphStyleProp,
3227
3400
  onGraphStyleChange,
@@ -3246,20 +3419,20 @@ function GraphViewer(props) {
3246
3419
  onValidationIssueClick
3247
3420
  } = props;
3248
3421
  const graphspecProp = (_a = graph == null ? void 0 : graph.graphSpec) != null ? _a : null;
3249
- const graphspec = React12.useMemo(
3422
+ const graphspec = React13.useMemo(
3250
3423
  () => graphspecProp === null ? null : validateGraphSpec(graphspecProp),
3251
3424
  [graphspecProp]
3252
3425
  );
3253
- const [direction, setDirection] = React12.useState(
3426
+ const [direction, setDirection] = React13.useState(
3254
3427
  () => {
3255
3428
  var _a2, _b2;
3256
3429
  return (_b2 = (_a2 = initialDirection != null ? initialDirection : config.direction) != null ? _a2 : DEFAULT_GRAPH_CONFIG.direction) != null ? _b2 : GRAPH_DIRECTION.TB;
3257
3430
  }
3258
3431
  );
3259
3432
  const externalMode = resolveExternalThemeMode(themeProp, config.theme);
3260
- const [mode, setMode] = React12.useState(externalMode);
3261
- const prevExternalModeRef = React12.useRef(externalMode);
3262
- React12.useEffect(() => {
3433
+ const [mode, setMode] = React13.useState(externalMode);
3434
+ const prevExternalModeRef = React13.useRef(externalMode);
3435
+ React13.useEffect(() => {
3263
3436
  if (externalMode !== prevExternalModeRef.current) {
3264
3437
  prevExternalModeRef.current = externalMode;
3265
3438
  setMode(externalMode);
@@ -3267,13 +3440,13 @@ function GraphViewer(props) {
3267
3440
  }, [externalMode]);
3268
3441
  const systemTheme = useSystemTheme(systemThemeProp);
3269
3442
  const resolvedTheme = resolveActiveTheme(mode, systemTheme);
3270
- const onThemeChangeRef = React12.useRef(onThemeChange);
3443
+ const onThemeChangeRef = React13.useRef(onThemeChange);
3271
3444
  onThemeChangeRef.current = onThemeChange;
3272
- const prevReportedRef = React12.useRef({
3445
+ const prevReportedRef = React13.useRef({
3273
3446
  mode,
3274
3447
  resolvedTheme
3275
3448
  });
3276
- React12.useEffect(() => {
3449
+ React13.useEffect(() => {
3277
3450
  var _a2;
3278
3451
  const prev = prevReportedRef.current;
3279
3452
  if (prev.mode !== mode || prev.resolvedTheme !== resolvedTheme) {
@@ -3282,48 +3455,48 @@ function GraphViewer(props) {
3282
3455
  }
3283
3456
  }, [mode, resolvedTheme]);
3284
3457
  const externalStyle = resolveGraphStyle(graphStyleProp, config.graphStyle);
3285
- const [graphStyle, setGraphStyle] = React12.useState(externalStyle);
3286
- const prevExternalStyleRef = React12.useRef(externalStyle);
3287
- React12.useEffect(() => {
3458
+ const [graphStyle, setGraphStyle] = React13.useState(externalStyle);
3459
+ const prevExternalStyleRef = React13.useRef(externalStyle);
3460
+ React13.useEffect(() => {
3288
3461
  if (externalStyle !== prevExternalStyleRef.current) {
3289
3462
  prevExternalStyleRef.current = externalStyle;
3290
3463
  setGraphStyle(externalStyle);
3291
3464
  }
3292
3465
  }, [externalStyle]);
3293
- const onGraphStyleChangeRef = React12.useRef(onGraphStyleChange);
3466
+ const onGraphStyleChangeRef = React13.useRef(onGraphStyleChange);
3294
3467
  onGraphStyleChangeRef.current = onGraphStyleChange;
3295
- const prevReportedStyleRef = React12.useRef(graphStyle);
3296
- React12.useEffect(() => {
3468
+ const prevReportedStyleRef = React13.useRef(graphStyle);
3469
+ React13.useEffect(() => {
3297
3470
  var _a2;
3298
3471
  if (prevReportedStyleRef.current !== graphStyle) {
3299
3472
  prevReportedStyleRef.current = graphStyle;
3300
3473
  (_a2 = onGraphStyleChangeRef.current) == null ? void 0 : _a2.call(onGraphStyleChangeRef, graphStyle);
3301
3474
  }
3302
3475
  }, [graphStyle]);
3303
- const graphStyleRef = React12.useRef(graphStyle);
3476
+ const graphStyleRef = React13.useRef(graphStyle);
3304
3477
  graphStyleRef.current = graphStyle;
3305
3478
  const styleCapabilities = GRAPH_STYLES[graphStyle].capabilities;
3306
3479
  const effectiveFoldMode = (_c = (_b = initialFoldMode != null ? initialFoldMode : config.foldMode) != null ? _b : DEFAULT_GRAPH_CONFIG.foldMode) != null ? _c : FOLD_MODE.EXPANDED;
3307
- const [showControllers, setShowControllers] = React12.useState(() => {
3480
+ const [showControllers, setShowControllers] = React13.useState(() => {
3308
3481
  var _a2, _b2;
3309
3482
  if (effectiveFoldMode === FOLD_MODE.FOLDED) return true;
3310
3483
  return (_b2 = (_a2 = initialShowControllers != null ? initialShowControllers : config.showControllers) != null ? _a2 : DEFAULT_GRAPH_CONFIG.showControllers) != null ? _b2 : false;
3311
3484
  });
3312
- const foldModeRef = React12.useRef(effectiveFoldMode);
3485
+ const foldModeRef = React13.useRef(effectiveFoldMode);
3313
3486
  foldModeRef.current = effectiveFoldMode;
3314
- const containerRef = React12.useRef(null);
3315
- const [detailSelection, setDetailSelection] = React12.useState(null);
3316
- const [conceptOverride, setConceptOverride] = React12.useState(null);
3487
+ const containerRef = React13.useRef(null);
3488
+ const [detailSelection, setDetailSelection] = React13.useState(null);
3489
+ const [conceptOverride, setConceptOverride] = React13.useState(null);
3317
3490
  const {
3318
3491
  width: panelWidth,
3319
3492
  isDragging: isPanelDragging,
3320
3493
  handleMouseDown: onResizeMouseDown
3321
3494
  } = useResizable({ defaultWidth: 380, minWidth: 280, maxWidth: 800, containerRef });
3322
- React12.useEffect(() => {
3495
+ React13.useEffect(() => {
3323
3496
  setDetailSelection(null);
3324
3497
  setConceptOverride(null);
3325
3498
  }, [graphspec]);
3326
- React12.useEffect(() => {
3499
+ React13.useEffect(() => {
3327
3500
  const el = containerRef.current;
3328
3501
  if (!el) return;
3329
3502
  const themePalette = getPaletteForTheme(resolvedTheme);
@@ -3338,14 +3511,15 @@ function GraphViewer(props) {
3338
3511
  }
3339
3512
  };
3340
3513
  }, [config.paletteColors, resolvedTheme]);
3514
+ const [stillHeight, setStillHeight] = React13.useState(STILL_PLACEHOLDER_HEIGHT_PX);
3341
3515
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
3342
3516
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
3343
- const reactFlowRef = React12.useRef(null);
3344
- const initialDataRef = React12.useRef(null);
3345
- const rawGraphDataRef = React12.useRef(null);
3346
- const layoutCacheRef = React12.useRef(null);
3347
- const [expandedControllers, setExpandedControllers] = React12.useState(/* @__PURE__ */ new Set());
3348
- const toggleCollapse = React12.useCallback((controllerId) => {
3517
+ const reactFlowRef = React13.useRef(null);
3518
+ const initialDataRef = React13.useRef(null);
3519
+ const rawGraphDataRef = React13.useRef(null);
3520
+ const layoutCacheRef = React13.useRef(null);
3521
+ const [expandedControllers, setExpandedControllers] = React13.useState(/* @__PURE__ */ new Set());
3522
+ const toggleCollapse = React13.useCallback((controllerId) => {
3349
3523
  setExpandedControllers((prev) => {
3350
3524
  const next = new Set(prev);
3351
3525
  if (next.has(controllerId)) next.delete(controllerId);
@@ -3353,17 +3527,17 @@ function GraphViewer(props) {
3353
3527
  return next;
3354
3528
  });
3355
3529
  }, []);
3356
- const [foldedControllers, setFoldedControllers] = React12.useState(/* @__PURE__ */ new Set());
3357
- const styleDefaultFoldsRef = React12.useRef(/* @__PURE__ */ new Set());
3358
- const readerOpenedRef = React12.useRef(/* @__PURE__ */ new Set());
3359
- const markReaderFolds = React12.useCallback((ids, folded) => {
3530
+ const [foldedControllers, setFoldedControllers] = React13.useState(/* @__PURE__ */ new Set());
3531
+ const styleDefaultFoldsRef = React13.useRef(/* @__PURE__ */ new Set());
3532
+ const readerOpenedRef = React13.useRef(/* @__PURE__ */ new Set());
3533
+ const markReaderFolds = React13.useCallback((ids, folded) => {
3360
3534
  for (const id of ids) {
3361
3535
  styleDefaultFoldsRef.current.delete(id);
3362
3536
  if (folded) readerOpenedRef.current.delete(id);
3363
3537
  else readerOpenedRef.current.add(id);
3364
3538
  }
3365
3539
  }, []);
3366
- const toggleFold = React12.useCallback(
3540
+ const toggleFold = React13.useCallback(
3367
3541
  (controllerId, options) => {
3368
3542
  setFoldedControllers((prev) => {
3369
3543
  const next = new Set(prev);
@@ -3381,43 +3555,45 @@ function GraphViewer(props) {
3381
3555
  [markReaderFolds]
3382
3556
  );
3383
3557
  const edgeType = config.edgeType || EDGE_TYPE.DEFAULT;
3384
- const layoutConfig = React12.useMemo(
3558
+ const layoutConfig = React13.useMemo(
3385
3559
  () => ({ nodesep: config.nodesep, ranksep: config.ranksep }),
3386
3560
  [config.nodesep, config.ranksep]
3387
3561
  );
3388
- const showControllersRef = React12.useRef(showControllers);
3562
+ const showControllersRef = React13.useRef(showControllers);
3389
3563
  showControllersRef.current = showControllers;
3390
- const directionRef = React12.useRef(direction);
3564
+ const directionRef = React13.useRef(direction);
3391
3565
  directionRef.current = direction;
3392
- const layoutConfigRef = React12.useRef(layoutConfig);
3566
+ const layoutConfigRef = React13.useRef(layoutConfig);
3393
3567
  layoutConfigRef.current = layoutConfig;
3394
- const initialZoomRef = React12.useRef(config.initialZoom);
3568
+ const initialZoomRef = React13.useRef(config.initialZoom);
3395
3569
  initialZoomRef.current = config.initialZoom;
3396
- const panToTopRef = React12.useRef(config.panToTop);
3570
+ const panToTopRef = React13.useRef(config.panToTop);
3397
3571
  panToTopRef.current = config.panToTop;
3398
- const expandedRef = React12.useRef(expandedControllers);
3572
+ const interactiveRef = React13.useRef(interactive);
3573
+ interactiveRef.current = interactive;
3574
+ const expandedRef = React13.useRef(expandedControllers);
3399
3575
  expandedRef.current = expandedControllers;
3400
- const toggleCollapseRef = React12.useRef(toggleCollapse);
3576
+ const toggleCollapseRef = React13.useRef(toggleCollapse);
3401
3577
  toggleCollapseRef.current = toggleCollapse;
3402
- const foldedRef = React12.useRef(foldedControllers);
3578
+ const foldedRef = React13.useRef(foldedControllers);
3403
3579
  foldedRef.current = foldedControllers;
3404
- const toggleFoldRef = React12.useRef(toggleFold);
3580
+ const toggleFoldRef = React13.useRef(toggleFold);
3405
3581
  toggleFoldRef.current = toggleFold;
3406
- const isFirstFoldEffect = React12.useRef(true);
3407
- const prevFoldSizeRef = React12.useRef(0);
3408
- const skipNextFoldEffectRef = React12.useRef(false);
3409
- const statusMapRef = React12.useRef(statusMap);
3582
+ const isFirstFoldEffect = React13.useRef(true);
3583
+ const prevFoldSizeRef = React13.useRef(0);
3584
+ const skipNextFoldEffectRef = React13.useRef(false);
3585
+ const statusMapRef = React13.useRef(statusMap);
3410
3586
  statusMapRef.current = statusMap;
3411
- const validationIssuesRef = React12.useRef(validationIssues);
3587
+ const validationIssuesRef = React13.useRef(validationIssues);
3412
3588
  validationIssuesRef.current = validationIssues;
3413
- const selectedNodeIdRef = React12.useRef(null);
3589
+ const selectedNodeIdRef = React13.useRef(null);
3414
3590
  selectedNodeIdRef.current = (_d = detailSelection == null ? void 0 : detailSelection.nodeId) != null ? _d : null;
3415
- const [validationOpen, setValidationOpen] = React12.useState(false);
3416
- const openValidationPanel = React12.useCallback(() => setValidationOpen(true), []);
3417
- const validationWidgetAvailable = validationState !== void 0 && !hideToolbar;
3418
- const validationWidgetAvailableRef = React12.useRef(validationWidgetAvailable);
3591
+ const [validationOpen, setValidationOpen] = React13.useState(false);
3592
+ const openValidationPanel = React13.useCallback(() => setValidationOpen(true), []);
3593
+ const validationWidgetAvailable = validationState !== void 0 && !hideToolbar && interactive;
3594
+ const validationWidgetAvailableRef = React13.useRef(validationWidgetAvailable);
3419
3595
  validationWidgetAvailableRef.current = validationWidgetAvailable;
3420
- const decorateNodes = React12.useCallback(
3596
+ const decorateNodes = React13.useCallback(
3421
3597
  (nodes2) => {
3422
3598
  var _a2, _b2, _c2;
3423
3599
  const raw = rawGraphDataRef.current;
@@ -3438,7 +3614,7 @@ function GraphViewer(props) {
3438
3614
  },
3439
3615
  [openValidationPanel]
3440
3616
  );
3441
- const frameLayout = React12.useCallback(
3617
+ const frameLayout = React13.useCallback(
3442
3618
  (style, layout, graphspec2, analysis) => GRAPH_STYLE_PIPELINES[style].frame({
3443
3619
  nodes: cloneCachedNodes(layout.nodes),
3444
3620
  edges: layout.edges,
@@ -3457,18 +3633,18 @@ function GraphViewer(props) {
3457
3633
  const data = initialDataRef.current;
3458
3634
  return cache !== null && data !== null && cache.graphspec === data._graphspec && cache.graphStyle === data._graphStyle;
3459
3635
  };
3460
- const nodesRef = React12.useRef([]);
3636
+ const nodesRef = React13.useRef([]);
3461
3637
  nodesRef.current = nodes;
3462
- const onValidationIssueClickRef = React12.useRef(onValidationIssueClick);
3638
+ const onValidationIssueClickRef = React13.useRef(onValidationIssueClick);
3463
3639
  onValidationIssueClickRef.current = onValidationIssueClick;
3464
- const flashTimeoutRef = React12.useRef(null);
3465
- React12.useEffect(
3640
+ const flashTimeoutRef = React13.useRef(null);
3641
+ React13.useEffect(
3466
3642
  () => () => {
3467
3643
  if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);
3468
3644
  },
3469
3645
  []
3470
3646
  );
3471
- const handleValidationIssueClick = React12.useCallback(
3647
+ const handleValidationIssueClick = React13.useCallback(
3472
3648
  (index, issue) => {
3473
3649
  var _a2, _b2, _c2;
3474
3650
  (_a2 = onValidationIssueClickRef.current) == null ? void 0 : _a2.call(onValidationIssueClickRef, index, issue);
@@ -3511,7 +3687,7 @@ function GraphViewer(props) {
3511
3687
  },
3512
3688
  [setNodes]
3513
3689
  );
3514
- React12.useEffect(() => {
3690
+ React13.useEffect(() => {
3515
3691
  if (!initialDataRef.current) return;
3516
3692
  let cancelled = false;
3517
3693
  void (async () => {
@@ -3544,7 +3720,7 @@ function GraphViewer(props) {
3544
3720
  setNodes(decorateNodes(withControllers.nodes));
3545
3721
  setEdges(toAppEdges(withControllers.edges));
3546
3722
  setTimeout(() => {
3547
- if (!cancelled && reactFlowRef.current) {
3723
+ if (!cancelled && reactFlowRef.current && interactiveRef.current) {
3548
3724
  void reactFlowRef.current.fitView({ padding: 0.1 });
3549
3725
  }
3550
3726
  }, 50);
@@ -3556,7 +3732,7 @@ function GraphViewer(props) {
3556
3732
  cancelled = true;
3557
3733
  };
3558
3734
  }, [direction, layoutConfig]);
3559
- React12.useEffect(() => {
3735
+ React13.useEffect(() => {
3560
3736
  const cache = layoutCacheRef.current;
3561
3737
  const data = initialDataRef.current;
3562
3738
  if (!cache || !data || !cacheMatchesData()) return;
@@ -3564,7 +3740,7 @@ function GraphViewer(props) {
3564
3740
  setNodes(decorateNodes(withControllers.nodes));
3565
3741
  setEdges(toAppEdges(withControllers.edges));
3566
3742
  }, [showControllers, expandedControllers, toggleCollapse, toggleFold, decorateNodes]);
3567
- React12.useEffect(() => {
3743
+ React13.useEffect(() => {
3568
3744
  var _a2;
3569
3745
  if (!graphspec) {
3570
3746
  initialDataRef.current = null;
@@ -3664,7 +3840,7 @@ function GraphViewer(props) {
3664
3840
  setNodes(decorateNodes(withControllers.nodes));
3665
3841
  setEdges(toAppEdges(withControllers.edges));
3666
3842
  setTimeout(() => {
3667
- if (!cancelled && reactFlowRef.current) {
3843
+ if (!cancelled && reactFlowRef.current && interactiveRef.current) {
3668
3844
  void reactFlowRef.current.fitView({ padding: 0.1 });
3669
3845
  if (initialZoomRef.current !== void 0 && initialZoomRef.current !== null) {
3670
3846
  void reactFlowRef.current.zoomTo(initialZoomRef.current);
@@ -3683,7 +3859,7 @@ function GraphViewer(props) {
3683
3859
  cancelled = true;
3684
3860
  };
3685
3861
  }, [graphspec, edgeType, graphStyle]);
3686
- React12.useEffect(() => {
3862
+ React13.useEffect(() => {
3687
3863
  if (isFirstFoldEffect.current) {
3688
3864
  isFirstFoldEffect.current = false;
3689
3865
  prevFoldSizeRef.current = foldedControllers.size;
@@ -3748,7 +3924,7 @@ function GraphViewer(props) {
3748
3924
  setNodes(decorateNodes(withControllers.nodes));
3749
3925
  setEdges(toAppEdges(withControllers.edges));
3750
3926
  setTimeout(() => {
3751
- if (!cancelled && reactFlowRef.current) {
3927
+ if (!cancelled && reactFlowRef.current && interactiveRef.current) {
3752
3928
  void reactFlowRef.current.fitView({ padding: 0.1 });
3753
3929
  }
3754
3930
  }, 50);
@@ -3760,7 +3936,7 @@ function GraphViewer(props) {
3760
3936
  cancelled = true;
3761
3937
  };
3762
3938
  }, [foldedControllers, toggleFold]);
3763
- React12.useEffect(() => {
3939
+ React13.useEffect(() => {
3764
3940
  const cache = layoutCacheRef.current;
3765
3941
  const data = initialDataRef.current;
3766
3942
  if (!cache || !data || !cacheMatchesData()) return;
@@ -3768,14 +3944,14 @@ function GraphViewer(props) {
3768
3944
  setNodes(decorateNodes(withControllers.nodes));
3769
3945
  setEdges(toAppEdges(withControllers.edges));
3770
3946
  }, [statusMap, decorateNodes]);
3771
- React12.useEffect(() => {
3947
+ React13.useEffect(() => {
3772
3948
  const cache = layoutCacheRef.current;
3773
3949
  const data = initialDataRef.current;
3774
3950
  if (!cache || !data || !cacheMatchesData()) return;
3775
3951
  const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);
3776
3952
  setNodes(decorateNodes(withControllers.nodes));
3777
3953
  }, [validationIssues, validationWidgetAvailable, decorateNodes]);
3778
- const onNodeClick = React12.useCallback(
3954
+ const onNodeClick = React13.useCallback(
3779
3955
  (event, node) => {
3780
3956
  const nodeData = node.data;
3781
3957
  onNodeSelect == null ? void 0 : onNodeSelect(node.id, nodeData, event);
@@ -3816,7 +3992,7 @@ function GraphViewer(props) {
3816
3992
  conceptOverride
3817
3993
  ]
3818
3994
  );
3819
- const onInit = React12.useCallback(
3995
+ const onInit = React13.useCallback(
3820
3996
  (reactFlowInstance) => {
3821
3997
  reactFlowRef.current = reactFlowInstance;
3822
3998
  if (onReactFlowInit) {
@@ -3825,12 +4001,28 @@ function GraphViewer(props) {
3825
4001
  },
3826
4002
  [onReactFlowInit]
3827
4003
  );
3828
- const handlePaneClick = React12.useCallback(() => {
4004
+ const prevInteractiveRef = React13.useRef(interactive);
4005
+ React13.useEffect(() => {
4006
+ if (prevInteractiveRef.current === interactive) return;
4007
+ prevInteractiveRef.current = interactive;
4008
+ if (!interactive) {
4009
+ setDetailSelection(null);
4010
+ setConceptOverride(null);
4011
+ setValidationOpen(false);
4012
+ return;
4013
+ }
4014
+ const timer = setTimeout(() => {
4015
+ var _a2;
4016
+ void ((_a2 = reactFlowRef.current) == null ? void 0 : _a2.fitView({ padding: 0.1 }));
4017
+ }, 50);
4018
+ return () => clearTimeout(timer);
4019
+ }, [interactive]);
4020
+ const handlePaneClick = React13.useCallback(() => {
3829
4021
  setDetailSelection(null);
3830
4022
  setConceptOverride(null);
3831
4023
  onPaneClick == null ? void 0 : onPaneClick();
3832
4024
  }, [onPaneClick]);
3833
- const handleConceptClick = React12.useCallback(
4025
+ const handleConceptClick = React13.useCallback(
3834
4026
  (conceptCode) => {
3835
4027
  if (!graphspec) return;
3836
4028
  const info = resolveConceptRef(graphspec, conceptCode);
@@ -3847,7 +4039,7 @@ function GraphViewer(props) {
3847
4039
  const rawAnalysis = (_e = rawGraphDataRef.current) == null ? void 0 : _e.analysis;
3848
4040
  const allControllerIds = rawAnalysis == null ? void 0 : rawAnalysis.controllerNodeIds;
3849
4041
  const foldControlsAvailable = styleCapabilities.foldAll && (!styleCapabilities.controllerFrameToggle || showControllers);
3850
- const foldAllProps = React12.useMemo(() => {
4042
+ const foldAllProps = React13.useMemo(() => {
3851
4043
  if (!foldControlsAvailable || !allControllerIds || allControllerIds.size === 0) {
3852
4044
  return {
3853
4045
  onFoldAll: void 0,
@@ -3869,34 +4061,37 @@ function GraphViewer(props) {
3869
4061
  expandAllDisabled: foldedControllers.size === 0
3870
4062
  };
3871
4063
  }, [foldControlsAvailable, allControllerIds, foldedControllers, markReaderFolds]);
3872
- const styleMenuOptions = React12.useMemo(() => resolveStyleMenu(styleMenu), [styleMenu]);
3873
- return /* @__PURE__ */ jsxs26(
4064
+ const styleMenuOptions = React13.useMemo(() => resolveStyleMenu(styleMenu), [styleMenu]);
4065
+ return /* @__PURE__ */ jsxs27(
3874
4066
  "div",
3875
4067
  {
3876
4068
  ref: containerRef,
3877
- className: `react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}`,
4069
+ className: `react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}${interactive ? "" : " react-flow-container--still"}`,
4070
+ style: interactive ? void 0 : { height: stillHeight },
4071
+ inert: !interactive,
3878
4072
  children: [
3879
- /* @__PURE__ */ jsxs26(
4073
+ /* @__PURE__ */ jsxs27(
3880
4074
  ReactFlow,
3881
- {
4075
+ __spreadProps(__spreadValues({
3882
4076
  nodes,
3883
4077
  edges,
3884
4078
  nodeTypes,
3885
4079
  edgeTypes,
3886
4080
  onNodesChange,
3887
4081
  onEdgesChange,
3888
- onNodeClick,
3889
- onPaneClick: handlePaneClick,
4082
+ onNodeClick: interactive ? onNodeClick : void 0,
4083
+ onPaneClick: interactive ? handlePaneClick : void 0,
3890
4084
  onInit,
3891
- fitView: true,
4085
+ fitView: interactive,
3892
4086
  fitViewOptions: { padding: 0.1 },
3893
4087
  defaultEdgeOptions: { type: edgeType },
3894
- panOnScroll: true,
3895
- minZoom: 0.1,
4088
+ panOnScroll: interactive,
4089
+ minZoom: interactive ? 0.1 : 0.01,
3896
4090
  proOptions: { hideAttribution: true },
3897
- panActivationKeyCode: null,
4091
+ panActivationKeyCode: null
4092
+ }, interactive ? {} : STILL_FLOW_PROPS), {
3898
4093
  children: [
3899
- /* @__PURE__ */ jsx28(
4094
+ interactive ? /* @__PURE__ */ jsx29(
3900
4095
  Background,
3901
4096
  {
3902
4097
  variant: BackgroundVariant.Dots,
@@ -3904,8 +4099,8 @@ function GraphViewer(props) {
3904
4099
  size: 1,
3905
4100
  color: "var(--color-bg-dots)"
3906
4101
  }
3907
- ),
3908
- !hideToolbar && /* @__PURE__ */ jsx28(
4102
+ ) : /* @__PURE__ */ jsx29(StillFit, { onHeight: setStillHeight }),
4103
+ interactive && !hideToolbar && /* @__PURE__ */ jsx29(
3909
4104
  GraphToolbar,
3910
4105
  {
3911
4106
  direction,
@@ -3943,9 +4138,9 @@ function GraphViewer(props) {
3943
4138
  }
3944
4139
  )
3945
4140
  ]
3946
- }
4141
+ })
3947
4142
  ),
3948
- /* @__PURE__ */ jsxs26(
4143
+ interactive && /* @__PURE__ */ jsxs27(
3949
4144
  DetailPanel,
3950
4145
  {
3951
4146
  isOpen: detailOpen,
@@ -3954,14 +4149,14 @@ function GraphViewer(props) {
3954
4149
  isDragging: isPanelDragging,
3955
4150
  onResizeHandleMouseDown: onResizeMouseDown,
3956
4151
  children: [
3957
- conceptOverride ? /* @__PURE__ */ jsx28(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx28(
4152
+ conceptOverride ? /* @__PURE__ */ jsx29(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx29(
3958
4153
  PipeDetailPanel,
3959
4154
  {
3960
4155
  node: selectedSpecNode,
3961
4156
  spec: graphspec,
3962
4157
  onConceptClick: handleConceptClick
3963
4158
  }
3964
- ) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx28(
4159
+ ) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx29(
3965
4160
  StuffNodeDetail,
3966
4161
  {
3967
4162
  nodeId: detailSelection.nodeId,