@dilipod/ui 0.4.34 → 0.4.36
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.
- package/dist/components/file-preview.d.ts +1 -0
- package/dist/components/file-preview.d.ts.map +1 -1
- package/dist/components/flowchart-diagram.d.ts.map +1 -1
- package/dist/components/sidebar.d.ts +2 -1
- package/dist/components/sidebar.d.ts.map +1 -1
- package/dist/index.js +369 -164
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +370 -165
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/file-preview.tsx +29 -15
- package/src/components/flowchart-diagram.tsx +446 -216
- package/src/components/sidebar.tsx +24 -10
package/dist/index.js
CHANGED
|
@@ -2392,7 +2392,18 @@ var Sidebar = React51__namespace.forwardRef(
|
|
|
2392
2392
|
]
|
|
2393
2393
|
}
|
|
2394
2394
|
),
|
|
2395
|
-
helpLink && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2395
|
+
helpLink && (helpLink.onClick ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2396
|
+
"button",
|
|
2397
|
+
{
|
|
2398
|
+
type: "button",
|
|
2399
|
+
onClick: helpLink.onClick,
|
|
2400
|
+
className: "flex w-full items-center gap-3 rounded-sm px-3 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
|
|
2401
|
+
children: [
|
|
2402
|
+
helpLink.icon && /* @__PURE__ */ jsxRuntime.jsx(helpLink.icon, { className: "h-4 w-4" }),
|
|
2403
|
+
helpLink.label
|
|
2404
|
+
]
|
|
2405
|
+
}
|
|
2406
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2396
2407
|
"a",
|
|
2397
2408
|
{
|
|
2398
2409
|
href: helpLink.href,
|
|
@@ -2402,7 +2413,7 @@ var Sidebar = React51__namespace.forwardRef(
|
|
|
2402
2413
|
helpLink.label
|
|
2403
2414
|
]
|
|
2404
2415
|
}
|
|
2405
|
-
)
|
|
2416
|
+
))
|
|
2406
2417
|
] })
|
|
2407
2418
|
]
|
|
2408
2419
|
}
|
|
@@ -3991,7 +4002,8 @@ function FilePreview({
|
|
|
3991
4002
|
const FileIcon = getFileIcon(file.type);
|
|
3992
4003
|
const typeLabel = getTypeLabel(file.type);
|
|
3993
4004
|
const sizeLabel = formatSize(file.size);
|
|
3994
|
-
const
|
|
4005
|
+
const isProcessing = file.processing === true;
|
|
4006
|
+
const isPreviewable = !isProcessing && canPreview(file);
|
|
3995
4007
|
const previewType = getPreviewType(file);
|
|
3996
4008
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3997
4009
|
"div",
|
|
@@ -4001,20 +4013,20 @@ function FilePreview({
|
|
|
4001
4013
|
children: [
|
|
4002
4014
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
4003
4015
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
|
|
4004
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-sm bg-white border border-gray-200 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(FileIcon, { className: "w-5 h-5 text-[var(--cyan)]", weight: "fill" }) }),
|
|
4005
|
-
previewType === "video" && /* @__PURE__ */ jsxRuntime.jsx(react_star.Play, { className: "absolute -bottom-0.5 -right-0.5 w-3.5 h-3.5 text-[var(--cyan)] bg-white rounded-full", weight: "fill" })
|
|
4016
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-sm bg-white border border-gray-200 flex items-center justify-center", children: isProcessing ? /* @__PURE__ */ jsxRuntime.jsx(react_star.CircleNotch, { className: "w-5 h-5 text-[var(--cyan)] animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(FileIcon, { className: "w-5 h-5 text-[var(--cyan)]", weight: "fill" }) }),
|
|
4017
|
+
!isProcessing && previewType === "video" && /* @__PURE__ */ jsxRuntime.jsx(react_star.Play, { className: "absolute -bottom-0.5 -right-0.5 w-3.5 h-3.5 text-[var(--cyan)] bg-white rounded-full", weight: "fill" })
|
|
4006
4018
|
] }),
|
|
4007
4019
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
4008
4020
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-[var(--black)] truncate", children: file.filename }),
|
|
4009
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4021
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: isProcessing ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-amber-600", children: "Processing video \u2014 this takes about a minute" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4010
4022
|
typeLabel,
|
|
4011
4023
|
" \xB7 ",
|
|
4012
4024
|
sizeLabel,
|
|
4013
4025
|
isPreviewable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[var(--cyan)] ml-1", children: "\xB7 Click to preview" })
|
|
4014
|
-
] })
|
|
4026
|
+
] }) })
|
|
4015
4027
|
] })
|
|
4016
4028
|
] }),
|
|
4017
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4029
|
+
!isProcessing && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4018
4030
|
"button",
|
|
4019
4031
|
{
|
|
4020
4032
|
onClick: (e) => handleDownload(e, file),
|
|
@@ -6287,190 +6299,383 @@ function WorkflowViewer({
|
|
|
6287
6299
|
] })
|
|
6288
6300
|
] });
|
|
6289
6301
|
}
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
+
var NODE_WIDTH = 180;
|
|
6303
|
+
var NODE_HEIGHT = 44;
|
|
6304
|
+
var DIAMOND_SIZE = 72;
|
|
6305
|
+
var X_GAP = 50;
|
|
6306
|
+
var Y_GAP = 64;
|
|
6307
|
+
var PADDING = 40;
|
|
6308
|
+
var FONT_SIZE = 11;
|
|
6309
|
+
var CHAR_WIDTH = 6.2;
|
|
6310
|
+
var LINE_HEIGHT = 14;
|
|
6311
|
+
function stripQuotes(s) {
|
|
6312
|
+
const t = s.trim();
|
|
6313
|
+
if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) {
|
|
6314
|
+
return t.slice(1, -1);
|
|
6315
|
+
}
|
|
6316
|
+
return t;
|
|
6317
|
+
}
|
|
6318
|
+
function parseNodeRef(raw) {
|
|
6319
|
+
const s = raw.trim();
|
|
6320
|
+
const decision = s.match(/^([A-Za-z0-9_]+)\{(.+)\}$/);
|
|
6321
|
+
if (decision) return { id: decision[1], label: stripQuotes(decision[2]), type: "decision" };
|
|
6322
|
+
const stadium = s.match(/^([A-Za-z0-9_]+)\(\[(.+)\]\)$/);
|
|
6323
|
+
if (stadium) return { id: stadium[1], label: stripQuotes(stadium[2]), type: "terminal" };
|
|
6324
|
+
const circle = s.match(/^([A-Za-z0-9_]+)\(\((.+)\)\)$/);
|
|
6325
|
+
if (circle) return { id: circle[1], label: stripQuotes(circle[2]), type: "terminal" };
|
|
6326
|
+
const rounded = s.match(/^([A-Za-z0-9_]+)\(([^[(].+?)\)$/);
|
|
6327
|
+
if (rounded) return { id: rounded[1], label: stripQuotes(rounded[2]), type: "action" };
|
|
6328
|
+
const rect = s.match(/^([A-Za-z0-9_]+)\[([^(].+?)\]$/);
|
|
6329
|
+
if (rect) {
|
|
6330
|
+
const label = stripQuotes(rect[2]);
|
|
6331
|
+
const isTerminal = /^(start|end|begin|finish|done|stop)$/i.test(label);
|
|
6332
|
+
return { id: rect[1], label, type: isTerminal ? "terminal" : "action" };
|
|
6333
|
+
}
|
|
6334
|
+
const bareId = s.match(/^([A-Za-z0-9_]+)$/);
|
|
6335
|
+
if (bareId) return { id: bareId[1] };
|
|
6336
|
+
return { id: s };
|
|
6337
|
+
}
|
|
6338
|
+
function registerNode(map, ref) {
|
|
6339
|
+
if (!ref.id) return;
|
|
6340
|
+
const existing = map.get(ref.id);
|
|
6341
|
+
if (existing) {
|
|
6342
|
+
if (ref.label && existing.label === existing.id) {
|
|
6343
|
+
existing.label = ref.label;
|
|
6302
6344
|
}
|
|
6303
|
-
|
|
6345
|
+
if (ref.type && ref.type !== "action" && existing.type === "action") {
|
|
6346
|
+
existing.type = ref.type;
|
|
6347
|
+
}
|
|
6348
|
+
return;
|
|
6304
6349
|
}
|
|
6350
|
+
map.set(ref.id, {
|
|
6351
|
+
id: ref.id,
|
|
6352
|
+
label: ref.label || ref.id,
|
|
6353
|
+
type: ref.type || "action"
|
|
6354
|
+
});
|
|
6355
|
+
}
|
|
6356
|
+
function parseMermaidFlowchart(mermaid) {
|
|
6357
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
6358
|
+
const edges = [];
|
|
6359
|
+
const lines = mermaid.split(/\\n|\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith("%%"));
|
|
6305
6360
|
for (const line of lines) {
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6361
|
+
if (/^(flowchart|graph|subgraph|end|style|classDef|class|click|linkStyle)\b/i.test(line)) continue;
|
|
6362
|
+
const edgeMatch = line.match(
|
|
6363
|
+
/^(.+?)\s*(?:-->|==>|-\.->|---)\s*(?:\|([^|]*)\|)?\s*(.+)$/
|
|
6364
|
+
);
|
|
6365
|
+
if (edgeMatch) {
|
|
6366
|
+
const leftNode = parseNodeRef(edgeMatch[1].trim());
|
|
6367
|
+
const edgeLabel = edgeMatch[2]?.trim() || void 0;
|
|
6368
|
+
const rightNode = parseNodeRef(edgeMatch[3].trim());
|
|
6369
|
+
registerNode(nodeMap, leftNode);
|
|
6370
|
+
registerNode(nodeMap, rightNode);
|
|
6371
|
+
edges.push({ from: leftNode.id, to: rightNode.id, label: edgeLabel });
|
|
6372
|
+
continue;
|
|
6315
6373
|
}
|
|
6316
|
-
|
|
6317
|
-
|
|
6374
|
+
const nodeDef = parseNodeRef(line);
|
|
6375
|
+
if (nodeDef.label) {
|
|
6376
|
+
registerNode(nodeMap, nodeDef);
|
|
6318
6377
|
}
|
|
6319
|
-
|
|
6320
|
-
|
|
6378
|
+
}
|
|
6379
|
+
return { nodes: Array.from(nodeMap.values()), edges };
|
|
6380
|
+
}
|
|
6381
|
+
function computeLayout(nodes, edges) {
|
|
6382
|
+
if (nodes.length === 0) return { layoutNodes: [], svgWidth: 0, svgHeight: 0 };
|
|
6383
|
+
const forward = /* @__PURE__ */ new Map();
|
|
6384
|
+
const backward = /* @__PURE__ */ new Map();
|
|
6385
|
+
for (const e of edges) {
|
|
6386
|
+
if (!forward.has(e.from)) forward.set(e.from, []);
|
|
6387
|
+
forward.get(e.from).push(e.to);
|
|
6388
|
+
if (!backward.has(e.to)) backward.set(e.to, []);
|
|
6389
|
+
backward.get(e.to).push(e.from);
|
|
6390
|
+
}
|
|
6391
|
+
const roots = nodes.filter((n) => !backward.has(n.id) || backward.get(n.id).length === 0);
|
|
6392
|
+
if (roots.length === 0) roots.push(nodes[0]);
|
|
6393
|
+
const layers = /* @__PURE__ */ new Map();
|
|
6394
|
+
const queue = [];
|
|
6395
|
+
for (const r of roots) {
|
|
6396
|
+
layers.set(r.id, 0);
|
|
6397
|
+
queue.push(r.id);
|
|
6398
|
+
}
|
|
6399
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6400
|
+
while (queue.length > 0) {
|
|
6401
|
+
const id = queue.shift();
|
|
6402
|
+
if (visited.has(id)) continue;
|
|
6403
|
+
visited.add(id);
|
|
6404
|
+
const myLayer = layers.get(id) || 0;
|
|
6405
|
+
for (const child of forward.get(id) || []) {
|
|
6406
|
+
const childLayer = layers.get(child);
|
|
6407
|
+
if (childLayer === void 0 || myLayer + 1 > childLayer) {
|
|
6408
|
+
layers.set(child, myLayer + 1);
|
|
6409
|
+
}
|
|
6410
|
+
if (!visited.has(child)) queue.push(child);
|
|
6321
6411
|
}
|
|
6322
|
-
|
|
6323
|
-
|
|
6412
|
+
}
|
|
6413
|
+
const maxLayer = Math.max(0, ...Array.from(layers.values()));
|
|
6414
|
+
for (const n of nodes) {
|
|
6415
|
+
if (!layers.has(n.id)) layers.set(n.id, maxLayer + 1);
|
|
6416
|
+
}
|
|
6417
|
+
const nodesByLayer = /* @__PURE__ */ new Map();
|
|
6418
|
+
for (const n of nodes) {
|
|
6419
|
+
const layer = layers.get(n.id);
|
|
6420
|
+
if (!nodesByLayer.has(layer)) nodesByLayer.set(layer, []);
|
|
6421
|
+
nodesByLayer.get(layer).push(n);
|
|
6422
|
+
}
|
|
6423
|
+
const sortedLayers = Array.from(nodesByLayer.keys()).sort((a, b) => a - b);
|
|
6424
|
+
const posInLayer = /* @__PURE__ */ new Map();
|
|
6425
|
+
for (let li = 0; li < sortedLayers.length; li++) {
|
|
6426
|
+
const layer = sortedLayers[li];
|
|
6427
|
+
const nodesInLayer = nodesByLayer.get(layer);
|
|
6428
|
+
if (li > 0) {
|
|
6429
|
+
nodesInLayer.sort((a, b) => {
|
|
6430
|
+
const parentsA = backward.get(a.id) || [];
|
|
6431
|
+
const parentsB = backward.get(b.id) || [];
|
|
6432
|
+
const avgA = parentsA.length > 0 ? parentsA.reduce((s, p) => s + (posInLayer.get(p) ?? 0), 0) / parentsA.length : 0;
|
|
6433
|
+
const avgB = parentsB.length > 0 ? parentsB.reduce((s, p) => s + (posInLayer.get(p) ?? 0), 0) / parentsB.length : 0;
|
|
6434
|
+
return avgA - avgB;
|
|
6435
|
+
});
|
|
6324
6436
|
}
|
|
6325
|
-
|
|
6437
|
+
nodesInLayer.forEach((n, i) => posInLayer.set(n.id, i));
|
|
6438
|
+
}
|
|
6439
|
+
const layoutNodes = [];
|
|
6440
|
+
for (const layer of sortedLayers) {
|
|
6441
|
+
const nodesInLayer = nodesByLayer.get(layer);
|
|
6442
|
+
const widths = nodesInLayer.map((n) => nodeWidth(n));
|
|
6443
|
+
const heights = nodesInLayer.map((n) => nodeHeight(n));
|
|
6444
|
+
const totalWidth = widths.reduce((s, w) => s + w, 0) + (nodesInLayer.length - 1) * X_GAP;
|
|
6445
|
+
let startX = -totalWidth / 2;
|
|
6446
|
+
nodesInLayer.forEach((n, i) => {
|
|
6447
|
+
layoutNodes.push({
|
|
6448
|
+
id: n.id,
|
|
6449
|
+
x: startX + widths[i] / 2,
|
|
6450
|
+
y: layer * (NODE_HEIGHT + Y_GAP),
|
|
6451
|
+
width: widths[i],
|
|
6452
|
+
height: heights[i],
|
|
6453
|
+
layer,
|
|
6454
|
+
node: n
|
|
6455
|
+
});
|
|
6456
|
+
startX += widths[i] + X_GAP;
|
|
6457
|
+
});
|
|
6326
6458
|
}
|
|
6327
|
-
|
|
6459
|
+
const minX = Math.min(...layoutNodes.map((n) => n.x - n.width / 2));
|
|
6460
|
+
const minY = Math.min(...layoutNodes.map((n) => n.y - n.height / 2));
|
|
6461
|
+
const offsetX = PADDING - minX;
|
|
6462
|
+
const offsetY = PADDING - minY;
|
|
6463
|
+
for (const n of layoutNodes) {
|
|
6464
|
+
n.x += offsetX;
|
|
6465
|
+
n.y += offsetY;
|
|
6466
|
+
}
|
|
6467
|
+
const svgWidth = Math.max(...layoutNodes.map((n) => n.x + n.width / 2)) + PADDING;
|
|
6468
|
+
const svgHeight = Math.max(...layoutNodes.map((n) => n.y + n.height / 2)) + PADDING;
|
|
6469
|
+
return { layoutNodes, svgWidth, svgHeight };
|
|
6470
|
+
}
|
|
6471
|
+
function nodeWidth(n) {
|
|
6472
|
+
if (n.type === "decision") return Math.max(DIAMOND_SIZE * 1.4, 100);
|
|
6473
|
+
const textWidth = n.label.length * CHAR_WIDTH + 32;
|
|
6474
|
+
return Math.max(100, Math.min(NODE_WIDTH, textWidth));
|
|
6328
6475
|
}
|
|
6329
|
-
function
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6476
|
+
function nodeHeight(n) {
|
|
6477
|
+
if (n.type === "decision") return DIAMOND_SIZE;
|
|
6478
|
+
const w = nodeWidth(n);
|
|
6479
|
+
const lines = wrapText(n.label, w - 24);
|
|
6480
|
+
return Math.max(NODE_HEIGHT, lines.length * LINE_HEIGHT + 16);
|
|
6481
|
+
}
|
|
6482
|
+
function wrapText(text, maxPixelWidth) {
|
|
6483
|
+
const charsPerLine = Math.max(8, Math.floor(maxPixelWidth / CHAR_WIDTH));
|
|
6484
|
+
if (text.length <= charsPerLine) return [text];
|
|
6485
|
+
const words = text.split(" ");
|
|
6486
|
+
const lines = [];
|
|
6487
|
+
let cur = "";
|
|
6488
|
+
for (const word of words) {
|
|
6489
|
+
const test = cur ? `${cur} ${word}` : word;
|
|
6490
|
+
if (test.length > charsPerLine && cur) {
|
|
6491
|
+
lines.push(cur);
|
|
6492
|
+
cur = word;
|
|
6493
|
+
} else {
|
|
6494
|
+
cur = test;
|
|
6342
6495
|
}
|
|
6343
6496
|
}
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6497
|
+
if (cur) lines.push(cur);
|
|
6498
|
+
if (lines.length > 3) {
|
|
6499
|
+
lines.length = 3;
|
|
6500
|
+
lines[2] = lines[2].slice(0, -1) + "\u2026";
|
|
6501
|
+
}
|
|
6502
|
+
return lines;
|
|
6503
|
+
}
|
|
6504
|
+
function computeEdgePath(from, to) {
|
|
6505
|
+
let startX = from.x;
|
|
6506
|
+
let startY = from.y + from.height / 2;
|
|
6507
|
+
if (from.node.type === "decision") {
|
|
6508
|
+
const dx = to.x - from.x;
|
|
6509
|
+
const halfDiamond = DIAMOND_SIZE / 2;
|
|
6510
|
+
if (Math.abs(dx) > halfDiamond) {
|
|
6511
|
+
startX = from.x + (dx > 0 ? halfDiamond : -halfDiamond);
|
|
6512
|
+
startY = from.y;
|
|
6353
6513
|
}
|
|
6354
|
-
const outs = outgoing.get(id) || [];
|
|
6355
|
-
for (const e of outs) q.push(e.to);
|
|
6356
6514
|
}
|
|
6357
|
-
|
|
6515
|
+
const endX = to.x;
|
|
6516
|
+
const endY = to.y - to.height / 2;
|
|
6517
|
+
const midY = (startY + endY) / 2;
|
|
6518
|
+
return `M ${startX} ${startY} C ${startX} ${midY}, ${endX} ${midY}, ${endX} ${endY}`;
|
|
6358
6519
|
}
|
|
6359
|
-
function
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
if (visited.has(nextId)) break;
|
|
6373
|
-
items.push({ type: "arrow", label: outs[0].label });
|
|
6374
|
-
currentId = nextId;
|
|
6375
|
-
} else {
|
|
6376
|
-
currentId = null;
|
|
6377
|
-
}
|
|
6378
|
-
} else {
|
|
6379
|
-
visited.add(currentId);
|
|
6380
|
-
items.push({ type: "node", nodeId: currentId });
|
|
6381
|
-
const branchStarts = outs.map((e) => e.to);
|
|
6382
|
-
const mergeId = findMergePoint(branchStarts, outgoing);
|
|
6383
|
-
const branches = [];
|
|
6384
|
-
for (const edge of outs) {
|
|
6385
|
-
if (visited.has(edge.to) && edge.to !== mergeId) {
|
|
6386
|
-
branches.push({ label: edge.label, items: [] });
|
|
6387
|
-
continue;
|
|
6388
|
-
}
|
|
6389
|
-
const branchItems = buildLayout(edge.to, outgoing, incoming, nodeMap, visited);
|
|
6390
|
-
branches.push({ label: edge.label, items: branchItems });
|
|
6391
|
-
}
|
|
6392
|
-
items.push({ type: "branch", decision: currentId, branches, mergeId });
|
|
6393
|
-
if (mergeId && !visited.has(mergeId)) {
|
|
6394
|
-
items.push({ type: "arrow" });
|
|
6395
|
-
currentId = mergeId;
|
|
6396
|
-
} else {
|
|
6397
|
-
currentId = null;
|
|
6520
|
+
function SvgDefs() {
|
|
6521
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
|
|
6522
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6523
|
+
"marker",
|
|
6524
|
+
{
|
|
6525
|
+
id: "fc-arrowhead",
|
|
6526
|
+
viewBox: "0 0 10 7",
|
|
6527
|
+
refX: "10",
|
|
6528
|
+
refY: "3.5",
|
|
6529
|
+
markerWidth: "8",
|
|
6530
|
+
markerHeight: "6",
|
|
6531
|
+
orient: "auto-start-reverse",
|
|
6532
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "#D1D5DB" })
|
|
6398
6533
|
}
|
|
6534
|
+
),
|
|
6535
|
+
/* @__PURE__ */ jsxRuntime.jsx("filter", { id: "fc-shadow", x: "-4%", y: "-4%", width: "108%", height: "116%", children: /* @__PURE__ */ jsxRuntime.jsx("feDropShadow", { dx: "0", dy: "1", stdDeviation: "1.5", floodOpacity: "0.07" }) })
|
|
6536
|
+
] });
|
|
6537
|
+
}
|
|
6538
|
+
function TextBlock({ lines, x, y, fill, fontSize }) {
|
|
6539
|
+
const startY = y - (lines.length - 1) * LINE_HEIGHT / 2;
|
|
6540
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6541
|
+
"text",
|
|
6542
|
+
{
|
|
6543
|
+
x,
|
|
6544
|
+
textAnchor: "middle",
|
|
6545
|
+
fill,
|
|
6546
|
+
style: { fontSize: `${fontSize}px`, fontFamily: "var(--font-outfit, system-ui, sans-serif)", fontWeight: 500 },
|
|
6547
|
+
children: lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("tspan", { x, y: startY + i * LINE_HEIGHT, children: line }, i))
|
|
6399
6548
|
}
|
|
6400
|
-
|
|
6401
|
-
return items;
|
|
6549
|
+
);
|
|
6402
6550
|
}
|
|
6403
|
-
function
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6407
|
-
|
|
6551
|
+
function ActionNodeSvg({ n }) {
|
|
6552
|
+
const lines = wrapText(n.node.label, n.width - 24);
|
|
6553
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
6554
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6555
|
+
"rect",
|
|
6556
|
+
{
|
|
6557
|
+
x: n.x - n.width / 2,
|
|
6558
|
+
y: n.y - n.height / 2,
|
|
6559
|
+
width: n.width,
|
|
6560
|
+
height: n.height,
|
|
6561
|
+
rx: 3,
|
|
6562
|
+
fill: "white",
|
|
6563
|
+
stroke: "#E5E7EB",
|
|
6564
|
+
strokeWidth: 1,
|
|
6565
|
+
filter: "url(#fc-shadow)"
|
|
6566
|
+
}
|
|
6567
|
+
),
|
|
6568
|
+
/* @__PURE__ */ jsxRuntime.jsx(TextBlock, { lines, x: n.x, y: n.y, fill: "#0A0A0A", fontSize: FONT_SIZE })
|
|
6408
6569
|
] });
|
|
6409
6570
|
}
|
|
6410
|
-
function
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6571
|
+
function DecisionNodeSvg({ n }) {
|
|
6572
|
+
const half = DIAMOND_SIZE / 2;
|
|
6573
|
+
const points = `${n.x},${n.y - half} ${n.x + half},${n.y} ${n.x},${n.y + half} ${n.x - half},${n.y}`;
|
|
6574
|
+
const lines = wrapText(n.node.label, DIAMOND_SIZE - 16);
|
|
6575
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
6576
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6577
|
+
"polygon",
|
|
6414
6578
|
{
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
node.label
|
|
6420
|
-
]
|
|
6579
|
+
points,
|
|
6580
|
+
fill: "#FFFBEB",
|
|
6581
|
+
stroke: "#FCD34D",
|
|
6582
|
+
strokeWidth: 2
|
|
6421
6583
|
}
|
|
6422
|
-
)
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-gray-100 border border-gray-200 rounded-full px-5 py-1.5 text-xs font-medium text-gray-500 text-center my-1", children: node.label });
|
|
6426
|
-
}
|
|
6427
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200 rounded-sm px-4 py-2 text-xs font-medium text-[var(--black)] text-center shadow-sm my-1 max-w-[220px]", children: node.label });
|
|
6584
|
+
),
|
|
6585
|
+
/* @__PURE__ */ jsxRuntime.jsx(TextBlock, { lines, x: n.x, y: n.y, fill: "#92400E", fontSize: 10 })
|
|
6586
|
+
] });
|
|
6428
6587
|
}
|
|
6429
|
-
function
|
|
6430
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6588
|
+
function TerminalNodeSvg({ n }) {
|
|
6589
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
6590
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6591
|
+
"rect",
|
|
6592
|
+
{
|
|
6593
|
+
x: n.x - n.width / 2,
|
|
6594
|
+
y: n.y - n.height / 2,
|
|
6595
|
+
width: n.width,
|
|
6596
|
+
height: n.height,
|
|
6597
|
+
rx: n.height / 2,
|
|
6598
|
+
fill: "#F3F4F6",
|
|
6599
|
+
stroke: "#E5E7EB",
|
|
6600
|
+
strokeWidth: 1
|
|
6601
|
+
}
|
|
6602
|
+
),
|
|
6603
|
+
/* @__PURE__ */ jsxRuntime.jsx(TextBlock, { lines: [n.node.label], x: n.x, y: n.y, fill: "#6B7280", fontSize: FONT_SIZE })
|
|
6604
|
+
] });
|
|
6605
|
+
}
|
|
6606
|
+
function EdgeSvg({ from, to, label }) {
|
|
6607
|
+
const path = computeEdgePath(from, to);
|
|
6608
|
+
const midX = (from.x + to.x) / 2;
|
|
6609
|
+
const midY = (from.y + from.height / 2 + to.y - to.height / 2) / 2;
|
|
6610
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
6611
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6612
|
+
"path",
|
|
6613
|
+
{
|
|
6614
|
+
d: path,
|
|
6615
|
+
fill: "none",
|
|
6616
|
+
stroke: "#D1D5DB",
|
|
6617
|
+
strokeWidth: 1.5,
|
|
6618
|
+
markerEnd: "url(#fc-arrowhead)"
|
|
6619
|
+
}
|
|
6620
|
+
),
|
|
6621
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
6622
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6623
|
+
"rect",
|
|
6624
|
+
{
|
|
6625
|
+
x: midX - label.length * CHAR_WIDTH / 2 - 6,
|
|
6626
|
+
y: midY - 9,
|
|
6627
|
+
width: label.length * CHAR_WIDTH + 12,
|
|
6628
|
+
height: 18,
|
|
6629
|
+
rx: 9,
|
|
6630
|
+
fill: "#F5F3FF"
|
|
6631
|
+
}
|
|
6632
|
+
),
|
|
6633
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6634
|
+
"text",
|
|
6635
|
+
{
|
|
6636
|
+
x: midX,
|
|
6637
|
+
y: midY + 1,
|
|
6638
|
+
textAnchor: "middle",
|
|
6639
|
+
dominantBaseline: "central",
|
|
6640
|
+
fill: "#7C3AED",
|
|
6641
|
+
style: { fontSize: "10px", fontFamily: "var(--font-outfit, system-ui, sans-serif)", fontWeight: 500 },
|
|
6642
|
+
children: label
|
|
6643
|
+
}
|
|
6644
|
+
)
|
|
6645
|
+
] })
|
|
6646
|
+
] });
|
|
6454
6647
|
}
|
|
6455
6648
|
function FlowchartDiagram({ mermaid, className }) {
|
|
6456
6649
|
const { nodes, edges } = parseMermaidFlowchart(mermaid);
|
|
6457
6650
|
if (nodes.length === 0) {
|
|
6458
6651
|
return /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-white border border-gray-100 rounded-sm p-3 overflow-x-auto whitespace-pre-wrap", children: mermaid });
|
|
6459
6652
|
}
|
|
6460
|
-
const
|
|
6461
|
-
const
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6653
|
+
const { layoutNodes, svgWidth, svgHeight } = computeLayout(nodes, edges);
|
|
6654
|
+
const nodeById = new Map(layoutNodes.map((n) => [n.id, n]));
|
|
6655
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6656
|
+
"svg",
|
|
6657
|
+
{
|
|
6658
|
+
width: svgWidth,
|
|
6659
|
+
height: svgHeight,
|
|
6660
|
+
viewBox: `0 0 ${svgWidth} ${svgHeight}`,
|
|
6661
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
6662
|
+
className: "block",
|
|
6663
|
+
children: [
|
|
6664
|
+
/* @__PURE__ */ jsxRuntime.jsx(SvgDefs, {}),
|
|
6665
|
+
edges.map((e, i) => {
|
|
6666
|
+
const fromNode = nodeById.get(e.from);
|
|
6667
|
+
const toNode = nodeById.get(e.to);
|
|
6668
|
+
if (!fromNode || !toNode) return null;
|
|
6669
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EdgeSvg, { from: fromNode, to: toNode, label: e.label }, `e-${i}`);
|
|
6670
|
+
}),
|
|
6671
|
+
layoutNodes.map((n) => {
|
|
6672
|
+
if (n.node.type === "decision") return /* @__PURE__ */ jsxRuntime.jsx(DecisionNodeSvg, { n }, n.id);
|
|
6673
|
+
if (n.node.type === "terminal") return /* @__PURE__ */ jsxRuntime.jsx(TerminalNodeSvg, { n }, n.id);
|
|
6674
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ActionNodeSvg, { n }, n.id);
|
|
6675
|
+
})
|
|
6676
|
+
]
|
|
6677
|
+
}
|
|
6678
|
+
) }) });
|
|
6474
6679
|
}
|
|
6475
6680
|
var frequencyLabels = {
|
|
6476
6681
|
multiple_daily: "occurrence",
|