@oomol-lab/open-flow 0.1.0-beta.83 → 0.1.0-beta.85

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.
@@ -2497,6 +2497,76 @@ function _e(e) {
2497
2497
  }
2498
2498
  /*! For license information please see dagre.esm.js.LEGAL.txt */
2499
2499
  //#endregion
2500
+ //#region src/canvas/browser/base/routeCrossings.ts
2501
+ var epsilon = 1e-6;
2502
+ function samePoint(a, b) {
2503
+ return Math.abs(a.x - b.x) < epsilon && Math.abs(a.y - b.y) < epsilon;
2504
+ }
2505
+ function segment(a, b) {
2506
+ return {
2507
+ left: Math.min(a.x, b.x),
2508
+ right: Math.max(a.x, b.x),
2509
+ top: Math.min(a.y, b.y),
2510
+ bottom: Math.max(a.y, b.y)
2511
+ };
2512
+ }
2513
+ /** Allow only the common prefix/suffix, not later crossings between the same edges. */
2514
+ function sharedEnd(a, b, overlap, reverse) {
2515
+ const step = reverse ? -1 : 1;
2516
+ let i = reverse ? a.length - 1 : 0;
2517
+ let j = reverse ? b.length - 1 : 0;
2518
+ let start = a[i];
2519
+ if (!samePoint(start, b[j])) return false;
2520
+ if (Math.abs(overlap.left - start.x) < epsilon && Math.abs(overlap.right - start.x) < epsilon && Math.abs(overlap.top - start.y) < epsilon && Math.abs(overlap.bottom - start.y) < epsilon) return true;
2521
+ while (a[i + step] && b[j + step]) {
2522
+ const endA = a[i + step];
2523
+ const endB = b[j + step];
2524
+ const vertical = Math.abs(endA.x - start.x) < epsilon;
2525
+ const otherVertical = Math.abs(endB.x - start.x) < epsilon;
2526
+ const directionA = vertical ? endA.y - start.y : endA.x - start.x;
2527
+ const directionB = vertical ? endB.y - start.y : endB.x - start.x;
2528
+ if (vertical !== otherVertical || directionA * directionB < 0) return false;
2529
+ const end = Math.abs(directionA) <= Math.abs(directionB) ? endA : endB;
2530
+ const common = segment(start, end);
2531
+ if (overlap.left >= common.left - epsilon && overlap.right <= common.right + epsilon && overlap.top >= common.top - epsilon && overlap.bottom <= common.bottom + epsilon) return true;
2532
+ if (samePoint(end, endA)) i += step;
2533
+ if (samePoint(end, endB)) j += step;
2534
+ start = end;
2535
+ }
2536
+ return false;
2537
+ }
2538
+ /** Check orthogonal routes once after layout; stop at the first unrelated contact or overlap. */
2539
+ function hasRouteCrossings(routes) {
2540
+ const paths = [...routes.values()].map((points) => {
2541
+ const path = points.filter((point, index) => index === 0 || !samePoint(point, points[index - 1]));
2542
+ return {
2543
+ path,
2544
+ segments: path.slice(1).map((point, index) => segment(path[index], point))
2545
+ };
2546
+ });
2547
+ for (let i = 0; i < paths.length; i++) {
2548
+ const a = paths[i];
2549
+ for (let j = i + 1; j < paths.length; j++) {
2550
+ const b = paths[j];
2551
+ for (const first of a.segments) for (const second of b.segments) {
2552
+ const left = Math.max(first.left, second.left);
2553
+ const right = Math.min(first.right, second.right);
2554
+ const top = Math.max(first.top, second.top);
2555
+ const bottom = Math.min(first.bottom, second.bottom);
2556
+ if (left > right + epsilon || top > bottom + epsilon) continue;
2557
+ const overlap = {
2558
+ left,
2559
+ right,
2560
+ top,
2561
+ bottom
2562
+ };
2563
+ if (!sharedEnd(a.path, b.path, overlap, false) && !sharedEnd(a.path, b.path, overlap, true)) return true;
2564
+ }
2565
+ }
2566
+ }
2567
+ return false;
2568
+ }
2569
+ //#endregion
2500
2570
  //#region src/canvas/browser/base/routeLayout.ts
2501
2571
  var clearance = 16;
2502
2572
  var portOffset = 24;
@@ -2849,19 +2919,26 @@ function compactComponent(graph, insets, aspectRatio) {
2849
2919
  const gap = 48;
2850
2920
  const pathNodes = normalized.filter((node) => incoming.has(node.id) || outgoing.has(node.id));
2851
2921
  const crossSize = Math.max(...(pathNodes.length ? pathNodes : normalized).map((node) => node.height));
2852
- const bow = crossSize * .75;
2853
- const separation = crossSize + 48;
2922
+ const bow = crossSize * .5;
2923
+ const separation = crossSize + bow + gap;
2854
2924
  const bucketSize = Math.max(...normalized.map((node) => node.width)) + gap;
2855
2925
  const byId = new Map(normalized.map((node) => [node.id, node]));
2856
2926
  const forwardEdges = graph.edges.filter((edge) => byId.get(edge.source).column < byId.get(edge.target).column);
2857
2927
  const parents = Map.groupBy(forwardEdges, (edge) => edge.target);
2858
2928
  const children = Map.groupBy(forwardEdges, (edge) => edge.source);
2859
2929
  const ordered = normalized.toSorted((a, b) => a.column - b.column || a.y - b.y);
2860
- const remaining = /* @__PURE__ */ new Map();
2861
- for (const node of ordered.toReversed()) remaining.set(node.id, 1 + Math.max(0, ...(children.get(node.id) ?? []).filter((edge) => parents.get(edge.target)?.length === 1).map((edge) => remaining.get(edge.target))));
2862
2930
  const rankEnds = new Map([...Map.groupBy(normalized, (node) => node.column)].map(([rank, nodes]) => [rank, Math.max(...nodes.map((node) => node.x + node.width))]));
2931
+ const remaining = /* @__PURE__ */ new Map();
2932
+ for (const node of ordered.toReversed()) {
2933
+ const next = (children.get(node.id) ?? []).filter((edge) => parents.get(edge.target)?.length === 1).map((edge) => remaining.get(edge.target));
2934
+ remaining.set(node.id, {
2935
+ count: 1 + Math.max(0, ...next.map((path) => path.count)),
2936
+ size: Math.max(node.width, ...next.map((path) => rankEnds.get(node.column) - node.x + gap + path.size))
2937
+ });
2938
+ }
2863
2939
  const spans = /* @__PURE__ */ new Set([Infinity, ...rankEnds.values()]);
2864
- let best;
2940
+ const layouts = [];
2941
+ let unfolded;
2865
2942
  for (const span of spans) {
2866
2943
  const placed = /* @__PURE__ */ new Map();
2867
2944
  const buckets = /* @__PURE__ */ new Map();
@@ -2883,10 +2960,15 @@ function compactComponent(graph, insets, aspectRatio) {
2883
2960
  } else if (parent) {
2884
2961
  shift = parent.shift;
2885
2962
  start = parent.start;
2963
+ const length = primary - start + remaining.get(original.id).size;
2964
+ const capacity = Math.max(original.width, span - start);
2965
+ const runs = Math.max(1, Math.ceil((length + gap) / (capacity + gap)));
2966
+ const end = start + (length + gap) / runs - gap;
2967
+ const midpoint = (parent.node.x + parent.node.width + primary + original.width) / 2;
2886
2968
  if ((children.get(parent.node.id)?.length ?? 0) > 1) {
2887
2969
  shift = parent.node.y - byId.get(parent.node.id).y;
2888
2970
  start = primary;
2889
- } else if (primary + original.width > span && remaining.get(original.id) > 2) {
2971
+ } else if (midpoint > end + 1e-6 && remaining.get(original.id).count > 2) {
2890
2972
  primary = Math.max(0, start - span / 3);
2891
2973
  shift = parent.shift + side * separation;
2892
2974
  start = primary;
@@ -2915,7 +2997,7 @@ function compactComponent(graph, insets, aspectRatio) {
2915
2997
  order: placed.size,
2916
2998
  shift: node.y - original.y - drift,
2917
2999
  start,
2918
- extent: Math.max(node.x + node.width, ...upstream.map((entry) => entry.extent))
3000
+ extent: Math.max(node.x + node.width, parent && node.x < parent.node.x ? parent.node.x + parent.node.width + gap : 0, ...upstream.map((entry) => entry.extent))
2919
3001
  };
2920
3002
  placed.set(node.id, placement);
2921
3003
  for (let bucket = firstBucket; bucket <= lastBucket; bucket++) {
@@ -2929,23 +3011,37 @@ function compactComponent(graph, insets, aspectRatio) {
2929
3011
  const width = extent.height + insets.width + 48;
2930
3012
  const height = extent.width + insets.height + 48;
2931
3013
  const area = width * height;
2932
- const score = Math.max(width / aspectRatio, height);
2933
- if (!best || score < best.score - 1e-9 || Math.abs(score - best.score) < 1e-9 && (area < best.area || area === best.area && turns < best.turns)) best = {
3014
+ const candidate = {
2934
3015
  nodes,
2935
- score,
3016
+ score: Math.max(width / aspectRatio, height),
2936
3017
  area,
2937
3018
  turns
2938
3019
  };
3020
+ if (span === Infinity) unfolded = candidate;
3021
+ layouts.push(candidate);
3022
+ layouts.sort((a, b) => Math.abs(a.score - b.score) >= 1e-9 ? a.score - b.score : a.area - b.area || a.turns - b.turns);
3023
+ if (layouts.length > 2) layouts.pop();
2939
3024
  }
2940
- const routes = routeLayout(best.nodes, graph.edges.map((edge) => Object.assign({}, edge, {
3025
+ const edges = graph.edges.map((edge) => Object.assign({}, edge, {
2941
3026
  sourceOffset: edge.sourceOffset && layoutAxes(edge.sourceOffset, "vertical"),
2942
3027
  targetOffset: edge.targetOffset && layoutAxes(edge.targetOffset, "vertical")
2943
- })));
3028
+ }));
3029
+ if (!layouts.includes(unfolded)) layouts.push(unfolded);
3030
+ let best;
3031
+ for (const candidate of layouts) {
3032
+ const routes = routeLayout(candidate.nodes, edges);
3033
+ const crosses = hasRouteCrossings(routes);
3034
+ if (!best || !crosses) best = {
3035
+ nodes: candidate.nodes,
3036
+ routes
3037
+ };
3038
+ if (!crosses) break;
3039
+ }
2944
3040
  const physicalNodes = best.nodes.map((node) => Object.assign({}, node, layoutAxes(node, "vertical"), {
2945
3041
  width: node.height,
2946
3042
  height: node.width
2947
3043
  }));
2948
- const physicalRoutes = new Map([...routes].map(([id, points]) => [id, points.map((point) => layoutAxes(point, "vertical"))]));
3044
+ const physicalRoutes = new Map([...best.routes].map(([id, points]) => [id, points.map((point) => layoutAxes(point, "vertical"))]));
2949
3045
  return {
2950
3046
  positions: Object.fromEntries(physicalNodes.map(({ id, x, y }) => [id, {
2951
3047
  x,
@@ -3712,7 +3808,7 @@ var CanvasStore = class {
3712
3808
  #modelViewport;
3713
3809
  #runStatus;
3714
3810
  #selectedNodeIds;
3715
- constructor(model, editable, language, callbacks, autoLayout = false, interactiveMode$) {
3811
+ constructor(model, editable, language, callbacks, options = {}) {
3716
3812
  this.canDeleteNodes = true;
3717
3813
  this.dispose = disposableStore();
3718
3814
  this.connectionRoutes = this.dispose.add(val(/* @__PURE__ */ new Map()));
@@ -3900,7 +3996,7 @@ var CanvasStore = class {
3900
3996
  const commentNodes = this.dispose.add(reactiveMap(null, { onDeleted: dispose }));
3901
3997
  const viewport = this.dispose.add(val(model.viewport, { equal: isSameViewport }));
3902
3998
  this.rfCommand = this.dispose.add(createRFCommand(nodes));
3903
- this.layoutComplete = !autoLayout;
3999
+ this.layoutComplete = !options.autoLayout;
3904
4000
  this.#runStatus = this.dispose.add(val(model.runStatus == "running" ? FLOW_RUN_STATUS.Running : FLOW_RUN_STATUS.Idle));
3905
4001
  this.#connections = this.dispose.add(val([]));
3906
4002
  const edges = this.dispose.add(deriveEdges(this.#connections, nodes));
@@ -3908,9 +4004,9 @@ var CanvasStore = class {
3908
4004
  this.$$ = {
3909
4005
  initialized: this.dispose.add(val(false)),
3910
4006
  editable: this.dispose.add(val(editable)),
3911
- miniMapExpanded: this.dispose.add(val()),
4007
+ miniMapExpanded: this.dispose.add(val(options.defaultMiniMapExpanded)),
3912
4008
  viewport,
3913
- interactiveMode: interactiveMode$ ?? this.dispose.add(val("touchpad")),
4009
+ interactiveMode: options.interactiveMode$ ?? this.dispose.add(val(options.defaultInteractiveMode ?? "touchpad")),
3914
4010
  direction: this.dispose.add(val(canvasDirection(model.direction))),
3915
4011
  changingDirection: this.dispose.add(val(false)),
3916
4012
  nodes,
@@ -3937,6 +4033,7 @@ var CanvasStore = class {
3937
4033
  nodeMiniMapPhase: this.dispose.add(compute((get) => getNodeMinimap(get(nodes.$).size + get(commentNodes.$).size, get(viewport)?.zoom ?? 1)))
3938
4034
  };
3939
4035
  this.#syncModel(model);
4036
+ if (options.defaultDirection != null) this.changeDirection(options.defaultDirection);
3940
4037
  }
3941
4038
  async #saveDirection(positions) {
3942
4039
  try {
@@ -20838,7 +20935,7 @@ var markdownPreview_module_default = {
20838
20935
  };
20839
20936
  //#endregion
20840
20937
  //#region src/canvas/browser/preview/markdownPreview.tsx
20841
- var MarkdownContent = lazy(() => import("./markdownContent-B-GLj5DU.js"));
20938
+ var MarkdownContent = lazy(() => import("./markdownContent-DF39sd9T.js"));
20842
20939
  var MarkdownPreview = /* @__PURE__ */ memo(({ dark, unstyled, components, contentClassName, content, draggable, onDoubleClick }) => {
20843
20940
  const [focus, setFocus] = useState(false);
20844
20941
  return /* @__PURE__ */ jsx("div", {
@@ -1,5 +1,5 @@
1
1
  import { C as IconifyProvider, y as IconImageCrossOriginContext } from "./wrapLayout-C4moMKgb.js";
2
- import { E as getFlowPngAspectRatio, t as FlowCanvas, y as CanvasStore } from "./FlowCanvas-ChbukrDh.js";
2
+ import { E as getFlowPngAspectRatio, t as FlowCanvas, y as CanvasStore } from "./FlowCanvas-CZoHhB1y.js";
3
3
  import { createElement } from "react";
4
4
  import "react/jsx-runtime";
5
5
  import { createRoot } from "react-dom/client";
@@ -4,7 +4,7 @@ import { i as compute, l as val } from "./dist-bO8nvHFH.js";
4
4
  import { c as useLang, l as useTranslate, o as I18nProvider, r as isPlainObject, s as useI18n, u as useVal } from "./dist-BFmpkX4P.js";
5
5
  import { $ as useToolbarRootContext, A as string, Bn as transitionStatusMapping, Br as useStableCallback, Cr as cn, Er as useRenderElement, Fr as formatErrorMessage, In as useTransitionStatus, Ir as mergeProps, Ln as useOpenChangeComplete, Lr as useIsoLayoutEffect, Mr as useButton, Nn as useLabelableId, Or as EMPTY_OBJECT, Qt as useStore, Sr as buttonVariants, Un as useValueChanged, Wn as createChangeEventDetails, _r as fieldValidityMapping, a as createTooltipHandle, br as useControlled, c as TooltipPositioner, d as TooltipRoot, dr as useFormContext, fr as useRegisterFieldControl, i as TooltipTrigger, jr as useMergedRefs, l as TooltipPortal, mr as useBaseUiId, mt as triggerOpenStateMapping, n as TooltipContent, nn as require_builtin_esm_external_require_react, o as TooltipArrow, p as timeZoneOffsetMinutes, pr as useFieldRootContext, qn as clearPress, r as TooltipProvider, rr as none, s as TooltipPopup, t as Tooltip, u as TooltipTrigger$1, ur as useLabelableContext, vr as visuallyHidden, wr as cva, xr as Button$1, yr as visuallyHiddenInput, zr as error$1 } from "./tooltip-DGj5pudg.js";
6
6
  import { $ as waitAutoContinueSchema, A as comparisonIssue, At as variableInputCompatible, Bt as SelectChevron, Ct as limitDecisionQuestions, D as nodeSystemOutputPorts, Dt as matchesSchema, E as nodeErrorSchema, F as operatorsForType, Gt as SelectTrigger, Ht as SelectGroup, It as skipDuplicatesConfigSchema, J as webhookResponseAllowsBody, K as webhookHeaderValuePort, Kt as SelectValue, L as unaryOperator, O as supportsNodeErrorHandling, Ot as portsAssignable, P as operandHandle, Q as workflowOutputsPort, R as valueType, Rt as dequal, St as defaultDecisionQuestion, T as workflowToolNameIssue, Tt as webhookSupportsBody, U as decodeRevisionContent, Ut as SelectItem, Vt as SelectContent, Wt as SelectSeparator, X as webhookResponseTimeout, Y as webhookResponseInputs, Z as webhookStatusCodePort, _t as isHttpHost, a as DialogFooter, an as ChevronDown, at as httpHeaderSchema, b as nodeNameIssue, bt as decisionQuestionIssues, c as DialogTrigger, d as Field, et as defaultNodeRetry, f as FieldDescription, h as FieldLabel, i as DialogDescription, in as Input, kt as schemaObject, l as Icon, lt as httpRequestIssues, m as FieldGroup, n as DialogClose, nt as retryConfigurationSchema, o as DialogHeader, ot as httpQuerySchema, p as FieldError, pt as httpHeaderNameIssue, q as webhookHeadersPort, r as DialogContent, rn as Label, rt as supportsNodeRetry, s as DialogTitle, t as Dialog, tt as nodeRetryLimits, u as Spinner, ut as httpRequestTask, vt as decisionLimits, wt as webhookMethods, xt as decisionTask, zt as Select$1 } from "./dialog-BzoSxhXQ.js";
7
- import { C as isMac, S as toManifestNodeId, T as flowPngAspectRatios, _ as E$1, a as CanvasNodeIcon, b as toViewEdge, c as collapseAllNested, d as IconStack, f as selectableTimeZones, g as cronDescription, h as timeZoneOffset, i as pasteVideoLink, l as formatDuration, m as timeZoneLongLabel, n as setAddItemId, o as defaultTriggerIcon, p as timeZoneLabel, s as JSONViewer, t as FlowCanvas, u as useDebouncedValue, v as CanvasTooltip, w as isSameViewport, x as toManifestHandleName, y as CanvasStore } from "./FlowCanvas-ChbukrDh.js";
7
+ import { C as isMac, S as toManifestNodeId, T as flowPngAspectRatios, _ as E$1, a as CanvasNodeIcon, b as toViewEdge, c as collapseAllNested, d as IconStack, f as selectableTimeZones, g as cronDescription, h as timeZoneOffset, i as pasteVideoLink, l as formatDuration, m as timeZoneLongLabel, n as setAddItemId, o as defaultTriggerIcon, p as timeZoneLabel, s as JSONViewer, t as FlowCanvas, u as useDebouncedValue, v as CanvasTooltip, w as isSameViewport, x as toManifestHandleName, y as CanvasStore } from "./FlowCanvas-CZoHhB1y.js";
8
8
  import { $ as resourceValue, $t as WorkflowExportDialog, A as schemaForEditor, An as TabsTrigger, Ar as serverAddress, B as datePickerValue, Bn as EmptyMedia, Br as ApiError, Cn as selectors, Cr as inputValue, D as defaultValueEditorSchema, Dn as Tabs, Dr as openApiTask, Dt as diagnosticMessage, E as supportsFeishuChatFilter, En as IconPickerButton, Er as openApiFieldIssues, F as calendarChange, Fn as InputGroupInput, Fr as workflowCandidateGroup, G as indexAddNodeOptions, Gn as SourceSelect, H as isDateFormat, Hn as Badge, Hr as eventSourceKind, I as calendarDate, In as Empty, Ir as workflowCapability, Jn as EventSourceSetup, Kn as createI18n, L as dateFromTimeZone, Ln as EmptyContent, Lr as workflowSelectionTask, M as getDefaultValue, Mn as followWorkbenchLink, Mr as sameWorkflowInterface, N as isUnconstrainedSchema, Nn as InputGroup, Nr as workflowAgentTool, O as editorComponent, On as TabsContent, Or as securityOptions, Ot as diagnosticNodeId, P as typeOfSchema, Pn as InputGroupAddon, Q as resourceData, R as dateInTimeZone, Rn as EmptyDescription, Sn as ComboboxRoot, Sr as triggerConfigValues, St as revisionView, T as feishuResourceKind, Tn as useComboboxRootContext, Tr as object$1, V as dateTimeWall, Vn as EmptyTitle, Vr as controlErrorCode, Wn as SourceForm, Y as connectorActionPresentation, Yn as errorNotice, Z as observeResource, Zt as dequal$1, _n as ComboboxList, _t as actionSummary, ar as webhookResponseDiagnostics, bn as ComboboxInputGroup, bt as canCancelRun, cn as selectionMenuItemClass, dn as valueEditor_module_default, dr as isJsonObject, dt as loadJson, en as WorkflowExportMenuItem, er as decodeResultList, fn as ComboboxItemIndicator, ft as designerGraph, gn as ComboboxPortal, gt as triggerNodeIcon, hn as ComboboxPositioner, ht as semanticNodeIcon, ir as resolutionOutputPorts, it as decodeAppCatalogResponse, j as valueForEditor, jr as servers, jt as connectionCatalog, k as editorGroups, kn as TabsList, kr as selectOperation, kt as schemaMismatchMessage, ln as ValueControl, mn as ComboboxPopup, mt as nodeTitle, n as agentTool, nn as IdTooltip, nr as executionReachableNodes, or as sourceOutputLabel, ot as getAppCatalogCache, pn as ComboboxItem, pt as nodeIcon, q as mapSource, qn as FeishuEventPicker, rn as FlowSettingsButton, rr as inputSourceCandidates, sn as selectionMenuContentClass, sr as sourcePort, tn as useWorkflowExportAction, tt as provider, un as ValueEditorFeedback, ur as triggerOutputDefinitions, vn as GroupCollectionProvider, vt as providerIcon, wn as useComboboxInputValueContext, wr as listOperations, xn as ComboboxInput, xr as triggerConfigValue, xt as hasRunFilter, yn as ComboboxTrigger, z as datePickerChange, zn as EmptyHeader } from "./flowChanges-C567g-Pc.js";
9
9
  import { a as renameObjectField, i as objectValue, n as isJsonValue, o as setObjectField, r as jsonDataTypes, s as valueType$1, t as initialValue } from "./value-BbFQZZ_V.js";
10
10
  import { n as compile, r as validate } from "./flowRunInputEditorStore-ys1-w9GW.js";
@@ -231,7 +231,7 @@ function CanvasHistoryScope({ history, disabled, ...props }) {
231
231
  }
232
232
  //#endregion
233
233
  //#region src/workbench/browser/runtime/editor/commentInspector.tsx
234
- var MarkdownContent = lazy(() => import("./markdownContent-B-GLj5DU.js"));
234
+ var MarkdownContent = lazy(() => import("./markdownContent-DF39sd9T.js"));
235
235
  /** A comment is presentation data; editing it does not require the canvas store. */
236
236
  function CommentInspector({ title, content, disabled = false, readOnly, dark, onSave }) {
237
237
  const t = useTranslate();
@@ -29667,7 +29667,13 @@ function callbacksFromProps(props) {
29667
29667
  };
29668
29668
  }
29669
29669
  function FlowCanvasView(props) {
29670
- const store = useMemo(() => new CanvasStore(props.model, props.editable, props.language ?? "en", callbacksFromProps(props), props.autoLayout, props.interactiveMode$), [props.identity]);
29670
+ const store = useMemo(() => new CanvasStore(props.model, props.editable, props.language ?? "en", callbacksFromProps(props), {
29671
+ autoLayout: props.autoLayout,
29672
+ interactiveMode$: props.interactiveMode$,
29673
+ defaultInteractiveMode: props.defaultInteractiveMode,
29674
+ defaultDirection: props.defaultDirection,
29675
+ defaultMiniMapExpanded: props.defaultMiniMapExpanded
29676
+ }), [props.identity]);
29671
29677
  const previousStore = useRef(store);
29672
29678
  const propsRef = useRef(props);
29673
29679
  const selectedEdge = useRef();
@@ -30492,15 +30498,14 @@ function changeRevisionCanvasSession(session, graphId, change) {
30492
30498
  //#endregion
30493
30499
  //#region src/workbench/browser/runtime/editor/revisionCanvas.tsx
30494
30500
  /** The parent keys this session by snapshot identity. All movement is disposable view state. */
30495
- function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, background = "striped", showHeader = true }) {
30501
+ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, defaultInteractiveMode, defaultDirection, defaultMiniMapExpanded, defaultInspectorOpen = false, defaultSelectedNodeIds, nodesDraggable = true, layoutMotion, label, background = "striped", showHeader = true }) {
30496
30502
  const root = useRef(null);
30497
30503
  const t = useTranslate();
30498
30504
  const language = useLang();
30499
30505
  const revision = useMemo(() => revisionView(draft), [draft]);
30500
30506
  const graphId = "flow";
30501
30507
  const [sessions, setSessions] = useState({});
30502
- const [selected, setSelected] = useState([]);
30503
- const [inspectorOpen, setInspectorOpen] = useState(false);
30508
+ const [inspectorOpen, setInspectorOpen] = useState(defaultInspectorOpen);
30504
30509
  const [focus, setFocus] = useState();
30505
30510
  const [catalog, setCatalog] = useState();
30506
30511
  const needsProviders = revision.connectorProviderIds.size > 0;
@@ -30542,6 +30547,10 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
30542
30547
  t,
30543
30548
  providerMetadata
30544
30549
  ]);
30550
+ const [selected, setSelected] = useState(() => {
30551
+ const ids = new Set(defaultSelectedNodeIds);
30552
+ return baseline.nodes.filter((node) => ids.has(node.id)).map((node) => node.id);
30553
+ });
30545
30554
  const session = sessions[graphId];
30546
30555
  const model = useMemo(() => ({
30547
30556
  ...baseline,
@@ -30590,12 +30599,16 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
30590
30599
  model,
30591
30600
  editable: false,
30592
30601
  dottedBackground: background === "dotted",
30593
- nodesDraggable: true,
30602
+ nodesDraggable,
30603
+ layoutMotion,
30594
30604
  fitView: session?.viewport == null,
30595
30605
  className: background === "striped" ? "open-flow-canvas-locked" : void 0,
30596
30606
  dark: theme === "dark",
30597
30607
  language,
30598
30608
  interactiveMode$,
30609
+ defaultInteractiveMode,
30610
+ defaultDirection,
30611
+ defaultMiniMapExpanded,
30599
30612
  selectedNodeIds: selected,
30600
30613
  ignoredNodeIds: [],
30601
30614
  focusNodeRequest: focus,
@@ -34979,7 +34992,7 @@ function FlowEditor({ portalRoot, navigationIsland, onRun, onRunStarted, onClose
34979
34992
  const { ignoredNodeIds, onIgnoreNodes } = useIgnoredNodes(flowId ?? "");
34980
34993
  const renderPng = useCallback(async (options) => {
34981
34994
  const model = store.$.designer.value;
34982
- const { flowToPng } = await import("./exportPng-CrAFfOaD.js");
34995
+ const { flowToPng } = await import("./exportPng-CXVWVlLc.js");
34983
34996
  return flowToPng(model, language, {
34984
34997
  ...options,
34985
34998
  ignoredNodeIds
@@ -1,6 +1,6 @@
1
1
  import { o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
2
2
  import { i as isString, l as useTranslate } from "./dist-BFmpkX4P.js";
3
- import { r as getVideoLink } from "./FlowCanvas-ChbukrDh.js";
3
+ import { r as getVideoLink } from "./FlowCanvas-CZoHhB1y.js";
4
4
  import { memo, useEffect, useMemo, useRef } from "react";
5
5
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region ../../node_modules/.bun/deepmerge@4.3.1/node_modules/deepmerge/dist/cjs.js
@@ -1,15 +1,35 @@
1
1
  import type { ReactElement } from 'react';
2
+ import type { CanvasDirection } from '../common/canvas-direction.js';
3
+ import type { InteractiveMode } from '../common/canvas-interactive-mode.js';
2
4
  import type { Draft, Presentation } from '../common/control-api.js';
3
5
  import type { UiLanguage } from '../common/localization.js';
4
6
  export type { Draft, Presentation } from '../common/control-api.js';
5
7
  export type { UiLanguage } from '../common/localization.js';
8
+ export type { InteractiveMode } from '../common/canvas-interactive-mode.js';
9
+ export type { CanvasDirection } from '../common/canvas-direction.js';
6
10
  export interface OpenFlowPreviewProps {
7
11
  readonly draft: Draft;
8
12
  readonly presentation: Presentation | null;
9
13
  readonly language: UiLanguage;
10
14
  readonly theme: 'light' | 'dark';
15
+ /** Initial interaction mode. Defaults to touchpad. Later changes are session-local. */
16
+ readonly defaultInteractiveMode?: InteractiveMode;
17
+ /** Initial direction override. A different direction reflows nodes; restoring uses the supplied presentation. */
18
+ readonly defaultDirection?: CanvasDirection;
19
+ /** Whether the mini map starts expanded. Defaults to false. */
20
+ readonly defaultMiniMapExpanded?: boolean;
21
+ /** Whether the property panel starts open. Defaults to false. */
22
+ readonly defaultInspectorOpen?: boolean;
23
+ /** Initial selected node or comment IDs. Missing IDs are ignored. Defaults to no selection. */
24
+ readonly defaultSelectedNodeIds?: readonly string[];
25
+ /** Allows temporary node movement. Defaults to true. */
26
+ readonly nodesDraggable?: boolean;
27
+ /** Shows the canvas dot grid. Defaults to true. */
28
+ readonly dottedBackground?: boolean;
29
+ /** Animates layout changes, respecting reduced-motion preferences. Defaults to true. */
30
+ readonly layoutMotion?: boolean;
11
31
  readonly label?: string;
12
32
  readonly className?: string;
13
33
  }
14
34
  /** Offline workflow preview. Use a React key to start a new layout/selection session. */
15
- export declare function OpenFlowPreview({ draft, presentation, language, theme, label, className }: OpenFlowPreviewProps): ReactElement;
35
+ export declare function OpenFlowPreview({ draft, presentation, language, theme, defaultInteractiveMode, defaultDirection, defaultMiniMapExpanded, defaultInspectorOpen, defaultSelectedNodeIds, nodesDraggable, dottedBackground, layoutMotion, label, className, }: OpenFlowPreviewProps): ReactElement;
@@ -6636,6 +6636,76 @@ function _e(e) {
6636
6636
  }
6637
6637
  /*! For license information please see dagre.esm.js.LEGAL.txt */
6638
6638
  //#endregion
6639
+ //#region src/canvas/browser/base/routeCrossings.ts
6640
+ var epsilon = 1e-6;
6641
+ function samePoint(a, b) {
6642
+ return Math.abs(a.x - b.x) < epsilon && Math.abs(a.y - b.y) < epsilon;
6643
+ }
6644
+ function segment(a, b) {
6645
+ return {
6646
+ left: Math.min(a.x, b.x),
6647
+ right: Math.max(a.x, b.x),
6648
+ top: Math.min(a.y, b.y),
6649
+ bottom: Math.max(a.y, b.y)
6650
+ };
6651
+ }
6652
+ /** Allow only the common prefix/suffix, not later crossings between the same edges. */
6653
+ function sharedEnd(a, b, overlap, reverse) {
6654
+ const step = reverse ? -1 : 1;
6655
+ let i = reverse ? a.length - 1 : 0;
6656
+ let j = reverse ? b.length - 1 : 0;
6657
+ let start = a[i];
6658
+ if (!samePoint(start, b[j])) return false;
6659
+ if (Math.abs(overlap.left - start.x) < epsilon && Math.abs(overlap.right - start.x) < epsilon && Math.abs(overlap.top - start.y) < epsilon && Math.abs(overlap.bottom - start.y) < epsilon) return true;
6660
+ while (a[i + step] && b[j + step]) {
6661
+ const endA = a[i + step];
6662
+ const endB = b[j + step];
6663
+ const vertical = Math.abs(endA.x - start.x) < epsilon;
6664
+ const otherVertical = Math.abs(endB.x - start.x) < epsilon;
6665
+ const directionA = vertical ? endA.y - start.y : endA.x - start.x;
6666
+ const directionB = vertical ? endB.y - start.y : endB.x - start.x;
6667
+ if (vertical !== otherVertical || directionA * directionB < 0) return false;
6668
+ const end = Math.abs(directionA) <= Math.abs(directionB) ? endA : endB;
6669
+ const common = segment(start, end);
6670
+ if (overlap.left >= common.left - epsilon && overlap.right <= common.right + epsilon && overlap.top >= common.top - epsilon && overlap.bottom <= common.bottom + epsilon) return true;
6671
+ if (samePoint(end, endA)) i += step;
6672
+ if (samePoint(end, endB)) j += step;
6673
+ start = end;
6674
+ }
6675
+ return false;
6676
+ }
6677
+ /** Check orthogonal routes once after layout; stop at the first unrelated contact or overlap. */
6678
+ function hasRouteCrossings(routes) {
6679
+ const paths = [...routes.values()].map((points) => {
6680
+ const path = points.filter((point, index) => index === 0 || !samePoint(point, points[index - 1]));
6681
+ return {
6682
+ path,
6683
+ segments: path.slice(1).map((point, index) => segment(path[index], point))
6684
+ };
6685
+ });
6686
+ for (let i = 0; i < paths.length; i++) {
6687
+ const a = paths[i];
6688
+ for (let j = i + 1; j < paths.length; j++) {
6689
+ const b = paths[j];
6690
+ for (const first of a.segments) for (const second of b.segments) {
6691
+ const left = Math.max(first.left, second.left);
6692
+ const right = Math.min(first.right, second.right);
6693
+ const top = Math.max(first.top, second.top);
6694
+ const bottom = Math.min(first.bottom, second.bottom);
6695
+ if (left > right + epsilon || top > bottom + epsilon) continue;
6696
+ const overlap = {
6697
+ left,
6698
+ right,
6699
+ top,
6700
+ bottom
6701
+ };
6702
+ if (!sharedEnd(a.path, b.path, overlap, false) && !sharedEnd(a.path, b.path, overlap, true)) return true;
6703
+ }
6704
+ }
6705
+ }
6706
+ return false;
6707
+ }
6708
+ //#endregion
6639
6709
  //#region src/canvas/browser/base/routeLayout.ts
6640
6710
  var clearance = 16;
6641
6711
  var portOffset = 24;
@@ -7041,19 +7111,26 @@ function compactComponent(graph, insets, aspectRatio) {
7041
7111
  const gap = 48;
7042
7112
  const pathNodes = normalized.filter((node) => incoming.has(node.id) || outgoing.has(node.id));
7043
7113
  const crossSize = Math.max(...(pathNodes.length ? pathNodes : normalized).map((node) => node.height));
7044
- const bow = crossSize * .75;
7045
- const separation = crossSize + 48;
7114
+ const bow = crossSize * .5;
7115
+ const separation = crossSize + bow + gap;
7046
7116
  const bucketSize = Math.max(...normalized.map((node) => node.width)) + gap;
7047
7117
  const byId = new Map(normalized.map((node) => [node.id, node]));
7048
7118
  const forwardEdges = graph.edges.filter((edge) => byId.get(edge.source).column < byId.get(edge.target).column);
7049
7119
  const parents = Map.groupBy(forwardEdges, (edge) => edge.target);
7050
7120
  const children = Map.groupBy(forwardEdges, (edge) => edge.source);
7051
7121
  const ordered = normalized.toSorted((a, b) => a.column - b.column || a.y - b.y);
7052
- const remaining = /* @__PURE__ */ new Map();
7053
- for (const node of ordered.toReversed()) remaining.set(node.id, 1 + Math.max(0, ...(children.get(node.id) ?? []).filter((edge) => parents.get(edge.target)?.length === 1).map((edge) => remaining.get(edge.target))));
7054
7122
  const rankEnds = new Map([...Map.groupBy(normalized, (node) => node.column)].map(([rank, nodes]) => [rank, Math.max(...nodes.map((node) => node.x + node.width))]));
7123
+ const remaining = /* @__PURE__ */ new Map();
7124
+ for (const node of ordered.toReversed()) {
7125
+ const next = (children.get(node.id) ?? []).filter((edge) => parents.get(edge.target)?.length === 1).map((edge) => remaining.get(edge.target));
7126
+ remaining.set(node.id, {
7127
+ count: 1 + Math.max(0, ...next.map((path) => path.count)),
7128
+ size: Math.max(node.width, ...next.map((path) => rankEnds.get(node.column) - node.x + gap + path.size))
7129
+ });
7130
+ }
7055
7131
  const spans = /* @__PURE__ */ new Set([Infinity, ...rankEnds.values()]);
7056
- let best;
7132
+ const layouts = [];
7133
+ let unfolded;
7057
7134
  for (const span of spans) {
7058
7135
  const placed = /* @__PURE__ */ new Map();
7059
7136
  const buckets = /* @__PURE__ */ new Map();
@@ -7075,10 +7152,15 @@ function compactComponent(graph, insets, aspectRatio) {
7075
7152
  } else if (parent) {
7076
7153
  shift = parent.shift;
7077
7154
  start = parent.start;
7155
+ const length = primary - start + remaining.get(original.id).size;
7156
+ const capacity = Math.max(original.width, span - start);
7157
+ const runs = Math.max(1, Math.ceil((length + gap) / (capacity + gap)));
7158
+ const end = start + (length + gap) / runs - gap;
7159
+ const midpoint = (parent.node.x + parent.node.width + primary + original.width) / 2;
7078
7160
  if ((children.get(parent.node.id)?.length ?? 0) > 1) {
7079
7161
  shift = parent.node.y - byId.get(parent.node.id).y;
7080
7162
  start = primary;
7081
- } else if (primary + original.width > span && remaining.get(original.id) > 2) {
7163
+ } else if (midpoint > end + 1e-6 && remaining.get(original.id).count > 2) {
7082
7164
  primary = Math.max(0, start - span / 3);
7083
7165
  shift = parent.shift + side * separation;
7084
7166
  start = primary;
@@ -7107,7 +7189,7 @@ function compactComponent(graph, insets, aspectRatio) {
7107
7189
  order: placed.size,
7108
7190
  shift: node.y - original.y - drift,
7109
7191
  start,
7110
- extent: Math.max(node.x + node.width, ...upstream.map((entry) => entry.extent))
7192
+ extent: Math.max(node.x + node.width, parent && node.x < parent.node.x ? parent.node.x + parent.node.width + gap : 0, ...upstream.map((entry) => entry.extent))
7111
7193
  };
7112
7194
  placed.set(node.id, placement);
7113
7195
  for (let bucket = firstBucket; bucket <= lastBucket; bucket++) {
@@ -7121,23 +7203,37 @@ function compactComponent(graph, insets, aspectRatio) {
7121
7203
  const width = extent.height + insets.width + 48;
7122
7204
  const height = extent.width + insets.height + 48;
7123
7205
  const area = width * height;
7124
- const score = Math.max(width / aspectRatio, height);
7125
- if (!best || score < best.score - 1e-9 || Math.abs(score - best.score) < 1e-9 && (area < best.area || area === best.area && turns < best.turns)) best = {
7206
+ const candidate = {
7126
7207
  nodes,
7127
- score,
7208
+ score: Math.max(width / aspectRatio, height),
7128
7209
  area,
7129
7210
  turns
7130
7211
  };
7212
+ if (span === Infinity) unfolded = candidate;
7213
+ layouts.push(candidate);
7214
+ layouts.sort((a, b) => Math.abs(a.score - b.score) >= 1e-9 ? a.score - b.score : a.area - b.area || a.turns - b.turns);
7215
+ if (layouts.length > 2) layouts.pop();
7131
7216
  }
7132
- const routes = routeLayout(best.nodes, graph.edges.map((edge) => Object.assign({}, edge, {
7217
+ const edges = graph.edges.map((edge) => Object.assign({}, edge, {
7133
7218
  sourceOffset: edge.sourceOffset && layoutAxes(edge.sourceOffset, "vertical"),
7134
7219
  targetOffset: edge.targetOffset && layoutAxes(edge.targetOffset, "vertical")
7135
- })));
7220
+ }));
7221
+ if (!layouts.includes(unfolded)) layouts.push(unfolded);
7222
+ let best;
7223
+ for (const candidate of layouts) {
7224
+ const routes = routeLayout(candidate.nodes, edges);
7225
+ const crosses = hasRouteCrossings(routes);
7226
+ if (!best || !crosses) best = {
7227
+ nodes: candidate.nodes,
7228
+ routes
7229
+ };
7230
+ if (!crosses) break;
7231
+ }
7136
7232
  const physicalNodes = best.nodes.map((node) => Object.assign({}, node, layoutAxes(node, "vertical"), {
7137
7233
  width: node.height,
7138
7234
  height: node.width
7139
7235
  }));
7140
- const physicalRoutes = new Map([...routes].map(([id, points]) => [id, points.map((point) => layoutAxes(point, "vertical"))]));
7236
+ const physicalRoutes = new Map([...best.routes].map(([id, points]) => [id, points.map((point) => layoutAxes(point, "vertical"))]));
7141
7237
  return {
7142
7238
  positions: Object.fromEntries(physicalNodes.map(({ id, x, y }) => [id, {
7143
7239
  x,
@@ -12925,7 +13021,7 @@ var CanvasStore = class {
12925
13021
  #modelViewport;
12926
13022
  #runStatus;
12927
13023
  #selectedNodeIds;
12928
- constructor(model, editable, language, callbacks, autoLayout = false, interactiveMode$) {
13024
+ constructor(model, editable, language, callbacks, options = {}) {
12929
13025
  this.canDeleteNodes = true;
12930
13026
  this.dispose = disposableStore();
12931
13027
  this.connectionRoutes = this.dispose.add(val(/* @__PURE__ */ new Map()));
@@ -13113,7 +13209,7 @@ var CanvasStore = class {
13113
13209
  const commentNodes = this.dispose.add(reactiveMap(null, { onDeleted: dispose }));
13114
13210
  const viewport = this.dispose.add(val(model.viewport, { equal: isSameViewport }));
13115
13211
  this.rfCommand = this.dispose.add(createRFCommand(nodes));
13116
- this.layoutComplete = !autoLayout;
13212
+ this.layoutComplete = !options.autoLayout;
13117
13213
  this.#runStatus = this.dispose.add(val(model.runStatus == "running" ? FLOW_RUN_STATUS.Running : FLOW_RUN_STATUS.Idle));
13118
13214
  this.#connections = this.dispose.add(val([]));
13119
13215
  const edges = this.dispose.add(deriveEdges(this.#connections, nodes));
@@ -13121,9 +13217,9 @@ var CanvasStore = class {
13121
13217
  this.$$ = {
13122
13218
  initialized: this.dispose.add(val(false)),
13123
13219
  editable: this.dispose.add(val(editable)),
13124
- miniMapExpanded: this.dispose.add(val()),
13220
+ miniMapExpanded: this.dispose.add(val(options.defaultMiniMapExpanded)),
13125
13221
  viewport,
13126
- interactiveMode: interactiveMode$ ?? this.dispose.add(val("touchpad")),
13222
+ interactiveMode: options.interactiveMode$ ?? this.dispose.add(val(options.defaultInteractiveMode ?? "touchpad")),
13127
13223
  direction: this.dispose.add(val(canvasDirection(model.direction))),
13128
13224
  changingDirection: this.dispose.add(val(false)),
13129
13225
  nodes,
@@ -13150,6 +13246,7 @@ var CanvasStore = class {
13150
13246
  nodeMiniMapPhase: this.dispose.add(compute((get) => getNodeMinimap(get(nodes.$).size + get(commentNodes.$).size, get(viewport)?.zoom ?? 1)))
13151
13247
  };
13152
13248
  this.#syncModel(model);
13249
+ if (options.defaultDirection != null) this.changeDirection(options.defaultDirection);
13153
13250
  }
13154
13251
  async #saveDirection(positions) {
13155
13252
  try {
@@ -56031,7 +56128,13 @@ function callbacksFromProps(props) {
56031
56128
  };
56032
56129
  }
56033
56130
  function FlowCanvasView(props) {
56034
- const store = useMemo(() => new CanvasStore(props.model, props.editable, props.language ?? "en", callbacksFromProps(props), props.autoLayout, props.interactiveMode$), [props.identity]);
56131
+ const store = useMemo(() => new CanvasStore(props.model, props.editable, props.language ?? "en", callbacksFromProps(props), {
56132
+ autoLayout: props.autoLayout,
56133
+ interactiveMode$: props.interactiveMode$,
56134
+ defaultInteractiveMode: props.defaultInteractiveMode,
56135
+ defaultDirection: props.defaultDirection,
56136
+ defaultMiniMapExpanded: props.defaultMiniMapExpanded
56137
+ }), [props.identity]);
56035
56138
  const previousStore = useRef(store);
56036
56139
  const propsRef = useRef(props);
56037
56140
  const selectedEdge = useRef();
@@ -118767,15 +118870,14 @@ function WorkbenchInspectorToggle({ label, open, disabled = false, onToggle }) {
118767
118870
  //#endregion
118768
118871
  //#region src/workbench/browser/runtime/editor/revisionCanvas.tsx
118769
118872
  /** The parent keys this session by snapshot identity. All movement is disposable view state. */
118770
- function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, background = "striped", showHeader = true }) {
118873
+ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, defaultInteractiveMode, defaultDirection, defaultMiniMapExpanded, defaultInspectorOpen = false, defaultSelectedNodeIds, nodesDraggable = true, layoutMotion, label, background = "striped", showHeader = true }) {
118771
118874
  const root = useRef(null);
118772
118875
  const t = useTranslate();
118773
118876
  const language = useLang();
118774
118877
  const revision = useMemo(() => revisionView(draft), [draft]);
118775
118878
  const graphId = "flow";
118776
118879
  const [sessions, setSessions] = useState({});
118777
- const [selected, setSelected] = useState([]);
118778
- const [inspectorOpen, setInspectorOpen] = useState(false);
118880
+ const [inspectorOpen, setInspectorOpen] = useState(defaultInspectorOpen);
118779
118881
  const [focus, setFocus] = useState();
118780
118882
  const [catalog, setCatalog] = useState();
118781
118883
  const needsProviders = revision.connectorProviderIds.size > 0;
@@ -118817,6 +118919,10 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
118817
118919
  t,
118818
118920
  providerMetadata
118819
118921
  ]);
118922
+ const [selected, setSelected] = useState(() => {
118923
+ const ids = new Set(defaultSelectedNodeIds);
118924
+ return baseline.nodes.filter((node) => ids.has(node.id)).map((node) => node.id);
118925
+ });
118820
118926
  const session = sessions[graphId];
118821
118927
  const model = useMemo(() => ({
118822
118928
  ...baseline,
@@ -118865,12 +118971,16 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
118865
118971
  model,
118866
118972
  editable: false,
118867
118973
  dottedBackground: background === "dotted",
118868
- nodesDraggable: true,
118974
+ nodesDraggable,
118975
+ layoutMotion,
118869
118976
  fitView: session?.viewport == null,
118870
118977
  className: background === "striped" ? "open-flow-canvas-locked" : void 0,
118871
118978
  dark: theme === "dark",
118872
118979
  language,
118873
118980
  interactiveMode$,
118981
+ defaultInteractiveMode,
118982
+ defaultDirection,
118983
+ defaultMiniMapExpanded,
118874
118984
  selectedNodeIds: selected,
118875
118985
  ignoredNodeIds: [],
118876
118986
  focusNodeRequest: focus,
@@ -118941,7 +119051,7 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
118941
119051
  //#endregion
118942
119052
  //#region src/workbench/browser/runtime/openFlowPreview.tsx
118943
119053
  /** Offline workflow preview. Use a React key to start a new layout/selection session. */
118944
- function OpenFlowPreview({ draft, presentation, language, theme, label, className }) {
119054
+ function OpenFlowPreview({ draft, presentation, language, theme, defaultInteractiveMode, defaultDirection, defaultMiniMapExpanded, defaultInspectorOpen, defaultSelectedNodeIds, nodesDraggable = true, dottedBackground = true, layoutMotion = true, label, className }) {
118945
119055
  const [i18n] = useState(() => createI18n(language));
118946
119056
  useEffect(() => {
118947
119057
  if (i18n.lang !== language) i18n.switchLang(language);
@@ -118958,8 +119068,15 @@ function OpenFlowPreview({ draft, presentation, language, theme, label, classNam
118958
119068
  draft,
118959
119069
  presentation,
118960
119070
  theme,
119071
+ defaultInteractiveMode,
119072
+ defaultDirection,
119073
+ defaultMiniMapExpanded,
119074
+ defaultInspectorOpen,
119075
+ defaultSelectedNodeIds,
119076
+ nodesDraggable,
119077
+ layoutMotion,
118961
119078
  label,
118962
- background: "dotted",
119079
+ background: dottedBackground ? "dotted" : "none",
118963
119080
  showHeader: false
118964
119081
  })
118965
119082
  })
@@ -6978,7 +6978,7 @@ var WorkbenchStore = class {
6978
6978
  async downloadPng(result) {
6979
6979
  const title = this.workspace.$.flow.value?.name ?? this.workspace.$.flowId.value ?? "Workflow";
6980
6980
  try {
6981
- const { downloadPng } = await import("./exportPng-CrAFfOaD.js");
6981
+ const { downloadPng } = await import("./exportPng-CXVWVlLc.js");
6982
6982
  downloadPng(result, title);
6983
6983
  if (!this.#disposed) this.#notice.set({
6984
6984
  kind: "success",
@@ -7245,7 +7245,7 @@ var WorkbenchStore = class {
7245
7245
  };
7246
7246
  //#endregion
7247
7247
  //#region src/workbench/browser/runtime/openFlowWorkbench.tsx
7248
- var FlowWorkspace = lazy(() => import("./flowWorkspace-rvcneG4q.js"));
7248
+ var FlowWorkspace = lazy(() => import("./flowWorkspace-BNdBKtla.js"));
7249
7249
  function OpenFlowSessionGate({ action, description, error, onSubmit, onTokenChange, pending = false, title, token, tokenLabel }) {
7250
7250
  const hasToken = token != null && tokenLabel != null && onTokenChange != null;
7251
7251
  const tokenValue = token ?? "";
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var Fw=Object.defineProperty;var Mw=(e)=>e;function Zw(e,t){this[e]=Mw.bind(null,t)}var co=(e,t)=>{for(var n in t)Fw(e,n,{get:t[n],enumerable:!0,configurable:!0,set:Zw.bind(t,n)})};var Ot={};co(Ot,{anyString:()=>ra,base64:()=>Ws,base64url:()=>Gs,bigint:()=>ia,boolean:()=>sa,browserEmail:()=>Sv,cidrv4:()=>Us,cidrv6:()=>Ks,creditCard:()=>Io,cuid:()=>Ps,cuid2:()=>Ts,currencyCode:()=>Xs,date:()=>ea,datetime:()=>na,domain:()=>Qs,duration:()=>Vs,e164:()=>Ys,email:()=>Fs,emoji:()=>Ms,extendedDuration:()=>hv,guid:()=>Ls,hex:()=>da,hostname:()=>Hs,html5Email:()=>vv,httpProtocol:()=>er,iban:()=>Co,idnEmail:()=>xv,integer:()=>tr,ipv4:()=>Zs,ipv6:()=>Js,ksuid:()=>zs,lowercase:()=>la,mac:()=>Bs,md5_base64:()=>Ov,md5_base64url:()=>jv,md5_hex:()=>Ev,nanoid:()=>Ds,nanoidOfLength:()=>qs,null:()=>aa,number:()=>Bt,rfc5322Email:()=>kv,sha1_base64:()=>Rv,sha1_base64url:()=>Av,sha1_hex:()=>_v,sha256_base64:()=>Tv,sha256_base64url:()=>$v,sha256_hex:()=>Pv,sha384_base64:()=>zv,sha384_base64url:()=>Dv,sha384_hex:()=>Nv,sha512_base64:()=>Vv,sha512_base64url:()=>Lv,sha512_hex:()=>qv,string:()=>oa,time:()=>ta,ulid:()=>$s,undefined:()=>ca,unicodeEmail:()=>Pd,uppercase:()=>ua,uuid:()=>Jt,uuid4:()=>yv,uuid6:()=>bv,uuid7:()=>wv,xid:()=>Ns});var ul={};co(ul,{ZodAny:()=>lg,ZodArray:()=>mg,ZodBase64:()=>Xc,ZodBase64URL:()=>el,ZodBigInt:()=>il,ZodBigIntFormat:()=>sl,ZodBoolean:()=>ol,ZodCIDRv4:()=>Qc,ZodCIDRv6:()=>Yc,ZodCUID:()=>Jc,ZodCUID2:()=>Bc,ZodCatch:()=>$g,ZodCodec:()=>hi,ZodCreditCard:()=>rg,ZodCustom:()=>yi,ZodCustomStringFormat:()=>vn,ZodDate:()=>fg,ZodDefault:()=>jg,ZodDiscriminatedUnion:()=>hg,ZodE164:()=>tl,ZodEmail:()=>Lc,ZodEmoji:()=>Mc,ZodEnum:()=>br,ZodExactOptional:()=>cl,ZodFile:()=>Ig,ZodFunction:()=>Jg,ZodGUID:()=>Fc,ZodIBAN:()=>og,ZodIPv4:()=>Gc,ZodIPv6:()=>Hc,ZodISODate:()=>yn,ZodISODateTime:()=>hn,ZodISODuration:()=>wn,ZodISOTime:()=>bn,ZodInstanceOf:()=>Kg,ZodIntersection:()=>yg,ZodJWT:()=>nl,ZodKSUID:()=>Wc,ZodLazy:()=>Fg,ZodLiteral:()=>Sg,ZodMAC:()=>ng,ZodMap:()=>kg,ZodNaN:()=>zg,ZodNanoID:()=>Zc,ZodNever:()=>dg,ZodNonOptional:()=>ll,ZodNull:()=>ag,ZodNullable:()=>Og,ZodNumber:()=>rl,ZodNumberFormat:()=>kn,ZodObject:()=>pi,ZodOptional:()=>mi,ZodPipe:()=>gi,ZodPrefault:()=>Rg,ZodPreprocess:()=>Dg,ZodPromise:()=>Zg,ZodReadonly:()=>qg,ZodRecord:()=>yr,ZodSet:()=>xg,ZodString:()=>Vc,ZodStringFormat:()=>ce,ZodSuccess:()=>Tg,ZodSymbol:()=>ig,ZodTemplateLiteral:()=>Lg,ZodTransform:()=>Cg,ZodTuple:()=>wg,ZodType:()=>K,ZodULID:()=>Uc,ZodURL:()=>di,ZodUUID:()=>vt,ZodUndefined:()=>sg,ZodUnion:()=>fi,ZodUnknown:()=>ug,ZodVoid:()=>pg,ZodXID:()=>Kc,ZodXor:()=>gg,_ZodString:()=>qc,_default:()=>_g,_function:()=>Rx,any:()=>dx,array:()=>R,base64:()=>Bk,base64url:()=>Uk,bigint:()=>sx,boolean:()=>he,catch:()=>Ng,check:()=>Ax,cidrv4:()=>Zk,cidrv6:()=>Jk,codec:()=>Ex,creditCard:()=>Wk,cuid:()=>Nk,cuid2:()=>zk,currencyCode:()=>ex,custom:()=>Px,date:()=>fx,describe:()=>Tx,discriminatedUnion:()=>it,e164:()=>Kk,email:()=>Ck,emoji:()=>Tk,enum:()=>Z,exactOptional:()=>Eg,file:()=>xx,float32:()=>nx,float64:()=>rx,function:()=>Rx,guid:()=>Ek,hash:()=>tx,hex:()=>Xk,hostname:()=>Yk,httpUrl:()=>Pk,iban:()=>Gk,instanceof:()=>Nx,int:()=>xe,int32:()=>ox,int64:()=>ax,intersection:()=>bg,invertCodec:()=>Ox,ipv4:()=>Lk,ipv6:()=>Mk,json:()=>Pe,jwt:()=>Hk,keyof:()=>mx,ksuid:()=>Vk,lazy:()=>Mg,literal:()=>b,looseObject:()=>gx,looseRecord:()=>bx,mac:()=>Fk,map:()=>wx,meta:()=>$x,nan:()=>Cx,nanoid:()=>$k,nativeEnum:()=>kx,never:()=>ot,nonoptional:()=>Pg,null:()=>cg,nullable:()=>ui,nullish:()=>Sx,number:()=>B,object:()=>O,optional:()=>li,partialRecord:()=>yx,pipe:()=>Dc,prefault:()=>Ag,preprocess:()=>Wg,promise:()=>_x,readonly:()=>Vg,record:()=>oe,refine:()=>Bg,set:()=>vx,strictObject:()=>v,string:()=>C,stringFormat:()=>Qk,stringbool:()=>zx,success:()=>Ix,superRefine:()=>Ug,symbol:()=>lx,templateLiteral:()=>jx,transform:()=>al,tuple:()=>vg,uint32:()=>ix,uint64:()=>cx,ulid:()=>Dk,undefined:()=>ux,union:()=>Y,unknown:()=>rt,url:()=>Ak,uuid:()=>Ok,uuidv4:()=>jk,uuidv6:()=>_k,uuidv7:()=>Rk,void:()=>px,xid:()=>qk,xor:()=>hx});var ai={};co(ai,{endsWith:()=>Qo,gt:()=>_t,gte:()=>nt,includes:()=>Go,length:()=>lr,lowercase:()=>Ko,lt:()=>jt,lte:()=>tt,maxLength:()=>cr,maxSize:()=>dn,mime:()=>Xo,minLength:()=>Ut,minSize:()=>Rt,multipleOf:()=>un,negative:()=>fm,nonnegative:()=>gm,nonpositive:()=>mm,normalize:()=>ei,overwrite:()=>wt,positive:()=>pm,properties:()=>Yo,property:()=>hm,regex:()=>Uo,size:()=>ar,slugify:()=>oi,startsWith:()=>Ho,toLowerCase:()=>ni,toUpperCase:()=>ri,trim:()=>ti,uppercase:()=>Wo});var wr={};co(wr,{ZodISODate:()=>yn,ZodISODateTime:()=>hn,ZodISODuration:()=>wn,ZodISOTime:()=>bn,date:()=>qx,datetime:()=>Dx,duration:()=>Lx,time:()=>Vx});var Ku="0.1.0-beta.83";var gs=["en","zh-CN","zh-TW","ja","ko","ru","fr"],Wu="en";var ms=new Map(gs.map((e)=>[e.toLowerCase(),e])),Bw=new Set(["hk","mo","tw"]);function Gu(e){return typeof e=="string"&&ms.get(e.toLowerCase())==e}function lo(e,t="en"){for(let n of e){let r=n==null?void 0:Uw(n);if(r!=null)return r}return t}function Uw(e){let t=e.trim().toLowerCase();if(t.length==0)return;let n=ms.get(t);if(n!=null)return n;let r=t.split("-");if(r[0]=="zh"){if(r.includes("hant"))return"zh-TW";if(r.includes("hans"))return"zh-CN";return r.some((o)=>Bw.has(o))?"zh-TW":"zh-CN"}return ms.get(r[0])}function Hu(e){return{en:"Imported workflow","zh-CN":"\u5BFC\u5165\u7684\u5DE5\u4F5C\u6D41","zh-TW":"\u532F\u5165\u7684\u5DE5\u4F5C\u6D41",ja:"\u30A4\u30F3\u30DD\u30FC\u30C8\u3057\u305F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC",ko:"\uAC00\uC838\uC628 \uC6CC\uD06C\uD50C\uB85C",fr:"Workflow import\xE9",ru:"\u0418\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441"}[e]}import{spawn as PE}from"child_process";import{readFile as TE}from"fs/promises";import{setTimeout as $E}from"timers/promises";var sn="open-flow-engine/v10";var on=(e)=>`export const engineContract = ${JSON.stringify(e)}
2
+ var Fw=Object.defineProperty;var Mw=(e)=>e;function Zw(e,t){this[e]=Mw.bind(null,t)}var co=(e,t)=>{for(var n in t)Fw(e,n,{get:t[n],enumerable:!0,configurable:!0,set:Zw.bind(t,n)})};var Ot={};co(Ot,{anyString:()=>ra,base64:()=>Ws,base64url:()=>Gs,bigint:()=>ia,boolean:()=>sa,browserEmail:()=>Sv,cidrv4:()=>Us,cidrv6:()=>Ks,creditCard:()=>Io,cuid:()=>Ps,cuid2:()=>Ts,currencyCode:()=>Xs,date:()=>ea,datetime:()=>na,domain:()=>Qs,duration:()=>Vs,e164:()=>Ys,email:()=>Fs,emoji:()=>Ms,extendedDuration:()=>hv,guid:()=>Ls,hex:()=>da,hostname:()=>Hs,html5Email:()=>vv,httpProtocol:()=>er,iban:()=>Co,idnEmail:()=>xv,integer:()=>tr,ipv4:()=>Zs,ipv6:()=>Js,ksuid:()=>zs,lowercase:()=>la,mac:()=>Bs,md5_base64:()=>Ov,md5_base64url:()=>jv,md5_hex:()=>Ev,nanoid:()=>Ds,nanoidOfLength:()=>qs,null:()=>aa,number:()=>Bt,rfc5322Email:()=>kv,sha1_base64:()=>Rv,sha1_base64url:()=>Av,sha1_hex:()=>_v,sha256_base64:()=>Tv,sha256_base64url:()=>$v,sha256_hex:()=>Pv,sha384_base64:()=>zv,sha384_base64url:()=>Dv,sha384_hex:()=>Nv,sha512_base64:()=>Vv,sha512_base64url:()=>Lv,sha512_hex:()=>qv,string:()=>oa,time:()=>ta,ulid:()=>$s,undefined:()=>ca,unicodeEmail:()=>Pd,uppercase:()=>ua,uuid:()=>Jt,uuid4:()=>yv,uuid6:()=>bv,uuid7:()=>wv,xid:()=>Ns});var ul={};co(ul,{ZodAny:()=>lg,ZodArray:()=>mg,ZodBase64:()=>Xc,ZodBase64URL:()=>el,ZodBigInt:()=>il,ZodBigIntFormat:()=>sl,ZodBoolean:()=>ol,ZodCIDRv4:()=>Qc,ZodCIDRv6:()=>Yc,ZodCUID:()=>Jc,ZodCUID2:()=>Bc,ZodCatch:()=>$g,ZodCodec:()=>hi,ZodCreditCard:()=>rg,ZodCustom:()=>yi,ZodCustomStringFormat:()=>vn,ZodDate:()=>fg,ZodDefault:()=>jg,ZodDiscriminatedUnion:()=>hg,ZodE164:()=>tl,ZodEmail:()=>Lc,ZodEmoji:()=>Mc,ZodEnum:()=>br,ZodExactOptional:()=>cl,ZodFile:()=>Ig,ZodFunction:()=>Jg,ZodGUID:()=>Fc,ZodIBAN:()=>og,ZodIPv4:()=>Gc,ZodIPv6:()=>Hc,ZodISODate:()=>yn,ZodISODateTime:()=>hn,ZodISODuration:()=>wn,ZodISOTime:()=>bn,ZodInstanceOf:()=>Kg,ZodIntersection:()=>yg,ZodJWT:()=>nl,ZodKSUID:()=>Wc,ZodLazy:()=>Fg,ZodLiteral:()=>Sg,ZodMAC:()=>ng,ZodMap:()=>kg,ZodNaN:()=>zg,ZodNanoID:()=>Zc,ZodNever:()=>dg,ZodNonOptional:()=>ll,ZodNull:()=>ag,ZodNullable:()=>Og,ZodNumber:()=>rl,ZodNumberFormat:()=>kn,ZodObject:()=>pi,ZodOptional:()=>mi,ZodPipe:()=>gi,ZodPrefault:()=>Rg,ZodPreprocess:()=>Dg,ZodPromise:()=>Zg,ZodReadonly:()=>qg,ZodRecord:()=>yr,ZodSet:()=>xg,ZodString:()=>Vc,ZodStringFormat:()=>ce,ZodSuccess:()=>Tg,ZodSymbol:()=>ig,ZodTemplateLiteral:()=>Lg,ZodTransform:()=>Cg,ZodTuple:()=>wg,ZodType:()=>K,ZodULID:()=>Uc,ZodURL:()=>di,ZodUUID:()=>vt,ZodUndefined:()=>sg,ZodUnion:()=>fi,ZodUnknown:()=>ug,ZodVoid:()=>pg,ZodXID:()=>Kc,ZodXor:()=>gg,_ZodString:()=>qc,_default:()=>_g,_function:()=>Rx,any:()=>dx,array:()=>R,base64:()=>Bk,base64url:()=>Uk,bigint:()=>sx,boolean:()=>he,catch:()=>Ng,check:()=>Ax,cidrv4:()=>Zk,cidrv6:()=>Jk,codec:()=>Ex,creditCard:()=>Wk,cuid:()=>Nk,cuid2:()=>zk,currencyCode:()=>ex,custom:()=>Px,date:()=>fx,describe:()=>Tx,discriminatedUnion:()=>it,e164:()=>Kk,email:()=>Ck,emoji:()=>Tk,enum:()=>Z,exactOptional:()=>Eg,file:()=>xx,float32:()=>nx,float64:()=>rx,function:()=>Rx,guid:()=>Ek,hash:()=>tx,hex:()=>Xk,hostname:()=>Yk,httpUrl:()=>Pk,iban:()=>Gk,instanceof:()=>Nx,int:()=>xe,int32:()=>ox,int64:()=>ax,intersection:()=>bg,invertCodec:()=>Ox,ipv4:()=>Lk,ipv6:()=>Mk,json:()=>Pe,jwt:()=>Hk,keyof:()=>mx,ksuid:()=>Vk,lazy:()=>Mg,literal:()=>b,looseObject:()=>gx,looseRecord:()=>bx,mac:()=>Fk,map:()=>wx,meta:()=>$x,nan:()=>Cx,nanoid:()=>$k,nativeEnum:()=>kx,never:()=>ot,nonoptional:()=>Pg,null:()=>cg,nullable:()=>ui,nullish:()=>Sx,number:()=>B,object:()=>O,optional:()=>li,partialRecord:()=>yx,pipe:()=>Dc,prefault:()=>Ag,preprocess:()=>Wg,promise:()=>_x,readonly:()=>Vg,record:()=>oe,refine:()=>Bg,set:()=>vx,strictObject:()=>v,string:()=>C,stringFormat:()=>Qk,stringbool:()=>zx,success:()=>Ix,superRefine:()=>Ug,symbol:()=>lx,templateLiteral:()=>jx,transform:()=>al,tuple:()=>vg,uint32:()=>ix,uint64:()=>cx,ulid:()=>Dk,undefined:()=>ux,union:()=>Y,unknown:()=>rt,url:()=>Ak,uuid:()=>Ok,uuidv4:()=>jk,uuidv6:()=>_k,uuidv7:()=>Rk,void:()=>px,xid:()=>qk,xor:()=>hx});var ai={};co(ai,{endsWith:()=>Qo,gt:()=>_t,gte:()=>nt,includes:()=>Go,length:()=>lr,lowercase:()=>Ko,lt:()=>jt,lte:()=>tt,maxLength:()=>cr,maxSize:()=>dn,mime:()=>Xo,minLength:()=>Ut,minSize:()=>Rt,multipleOf:()=>un,negative:()=>fm,nonnegative:()=>gm,nonpositive:()=>mm,normalize:()=>ei,overwrite:()=>wt,positive:()=>pm,properties:()=>Yo,property:()=>hm,regex:()=>Uo,size:()=>ar,slugify:()=>oi,startsWith:()=>Ho,toLowerCase:()=>ni,toUpperCase:()=>ri,trim:()=>ti,uppercase:()=>Wo});var wr={};co(wr,{ZodISODate:()=>yn,ZodISODateTime:()=>hn,ZodISODuration:()=>wn,ZodISOTime:()=>bn,date:()=>qx,datetime:()=>Dx,duration:()=>Lx,time:()=>Vx});var Ku="0.1.0-beta.85";var gs=["en","zh-CN","zh-TW","ja","ko","ru","fr"],Wu="en";var ms=new Map(gs.map((e)=>[e.toLowerCase(),e])),Bw=new Set(["hk","mo","tw"]);function Gu(e){return typeof e=="string"&&ms.get(e.toLowerCase())==e}function lo(e,t="en"){for(let n of e){let r=n==null?void 0:Uw(n);if(r!=null)return r}return t}function Uw(e){let t=e.trim().toLowerCase();if(t.length==0)return;let n=ms.get(t);if(n!=null)return n;let r=t.split("-");if(r[0]=="zh"){if(r.includes("hant"))return"zh-TW";if(r.includes("hans"))return"zh-CN";return r.some((o)=>Bw.has(o))?"zh-TW":"zh-CN"}return ms.get(r[0])}function Hu(e){return{en:"Imported workflow","zh-CN":"\u5BFC\u5165\u7684\u5DE5\u4F5C\u6D41","zh-TW":"\u532F\u5165\u7684\u5DE5\u4F5C\u6D41",ja:"\u30A4\u30F3\u30DD\u30FC\u30C8\u3057\u305F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC",ko:"\uAC00\uC838\uC628 \uC6CC\uD06C\uD50C\uB85C",fr:"Workflow import\xE9",ru:"\u0418\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441"}[e]}import{spawn as PE}from"child_process";import{readFile as TE}from"fs/promises";import{setTimeout as $E}from"timers/promises";var sn="open-flow-engine/v10";var on=(e)=>`export const engineContract = ${JSON.stringify(e)}
3
3
  export function identity(value) { return value }
4
4
  `,uo={workflowTools:!0,httpRequests:!0,waitAutoContinue:!0,webhookResponses:!0,platformExports:new Set(["engineContract","identity"]),platformModule:"open-flow:platform",platformSource:on("open-flow-engine/v8")},po={...uo,builtinModules:new Set(["assert","assert/strict","buffer","console","constants","crypto","events","fs","fs/promises","os","path","path/posix","process","punycode","querystring","stream","stream/promises","stream/web","string_decoder","timers","timers/promises","url","util","zlib"].flatMap((e)=>[e,`node:${e}`])),platformSource:on("open-flow-engine/v8/nodejs-compat-v1")},Qu={...po,codeFetch:!0,platformSource:on("open-flow-engine/v9")},Kw={...Qu,flowState:!0,platformSource:on("open-flow-engine/v10")};function Yu(e){if(e=="open-flow-engine/v10")return Kw;if(e=="open-flow-engine/v9")return Qu;if(e=="open-flow-engine/v8")return uo;if(e=="open-flow-engine/v8/nodejs-compat-v1")return po;if(e=="open-flow-engine/v7"||e=="open-flow-engine/v7/nodejs-compat-v1")return{...e.endsWith("/nodejs-compat-v1")?po:uo,workflowTools:!1,httpRequests:!1,platformSource:on(e)};if(e=="open-flow-engine/v6"||e=="open-flow-engine/v6/nodejs-compat-v1")return{...e=="open-flow-engine/v6"?uo:po,workflowTools:!1,httpRequests:!1,waitAutoContinue:!1,webhookResponses:!1,platformSource:on(e)};return}function Kn(e){let t=Object.values(e).filter((r)=>typeof r==="number");return Object.entries(e).filter(([r,o])=>t.indexOf(+r)===-1).map(([r,o])=>o)}function ys(e,t="|"){return e.map((n)=>ks(n)).join(t)}function Wn(e,t){if(typeof t==="bigint")return t.toString();return t}class ed{constructor(e){this._getter=e,this._value=void 0}get value(){let e=this._getter;if(e!==void 0)this._value=e(),this._getter=void 0;return this._value}}function Gn(e){return new ed(e)}function bs(e){return e===null||e===void 0}function Et(e){let t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}function td(e,t){let n=e/t,r=Math.round(n),o=4*Number.EPSILON*Math.max(Math.abs(n),1);if(Math.abs(n-r)<o)return 0;return n-r}var Xu=Symbol("evaluating");function nd(e,t,n){let r=void 0;Object.defineProperty(e,t,{get(){if(r===Xu)return;if(r===void 0)r=Xu,r=n();return r},set(o){Object.defineProperty(e,t,{value:o})},configurable:!0})}function Re(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function Hn(e){let t=Object.getOwnPropertyDescriptor(e,"shape");return t?.get?t.get.raw:t?.value}function ht(e){return Hn(e._zod.def)??e._zod.def.shape}function rd(e,t,n){Object.defineProperty(e,t,{get(){let r=n();return Re(this,t,r),r},enumerable:!0,configurable:!0})}function od(e,t,n){if(t in e)Re(e,t,n);else e[t]=n}function Mt(e,t,n,r){let o=ht(t);for(let i of n){let s=Object.getOwnPropertyDescriptor(o,i);if(!s.enumerable)continue;if(s.get)rd(e,i,()=>{let a=t._zod.def.shape[i];return r?r(a,i):a});else od(e,i,r?r(s.value,i):s.value)}}function Ww(e,t){for(let n of Reflect.ownKeys(t)){let r=Object.getOwnPropertyDescriptor(t,n);if(!r.enumerable)continue;if(r.get)rd(e,n,()=>t[n]);else od(e,n,r.value)}}function Je(...e){let t={};for(let n of e){let r=Object.getOwnPropertyDescriptors(n);Object.assign(t,r)}return Object.defineProperties({},t)}function id(e){return JSON.stringify(e)}function sd(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}var ws="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function an(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}var ad=Gn(()=>{if(je.jitless)return!1;if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function bt(e){if(an(e)===!1)return!1;let t=e.constructor;if(t===void 0)return!0;if(typeof t!=="function")return!0;let n=t.prototype;if(an(n)===!1)return!1;if(Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")===!1)return!1;return!0}function vs(e){if(bt(e))return{...e};if(Array.isArray(e))return[...e];if(e instanceof Map)return new Map(e);if(e instanceof Set)return new Set(e);return e}var fo=new Set(["string","number","symbol"]),cd=new Set(["string","number","bigint","boolean","symbol","undefined"]);function et(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function lt(e,t,n){let r=new e._zod.constr(t??e._zod.def);if(!t||n?.parent)r._zod.parent=e;return r}function j(e){let t=e;if(!t)return{};if(typeof t==="string")return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error("Cannot specify both `message` and `error` params");t.error=t.message}if(delete t.message,typeof t.error==="string")return{...t,error:()=>t.error};return t}function ks(e){if(typeof e==="bigint")return e.toString()+"n";if(typeof e==="string")return`"${e}"`;return`${e}`}function ld(e){return Object.keys(e).filter((t)=>e[t]._zod.optin!==void 0&&e[t]._zod.optout==="optional")}var mo=(()=>({safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-340282346638528860000000000000000000000,340282346638528860000000000000000000000],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]}))(),go={int64:[BigInt("-9223372036854775808"),BigInt("9223372036854775807")],uint64:[BigInt(0),BigInt("18446744073709551615")]};function Gw(e,t){let n=e._zod.def,r=n.checks;if(r&&r.length>0)throw Error(".pick() cannot be used on object schemas containing refinements");let i={};return Mt(i,e,ho(e,t)),lt(e,Je(n,{shape:i,checks:[]}))}function ho(e,t){let n=ht(e),r=[];for(let o of Reflect.ownKeys(t)){if(!Object.getOwnPropertyDescriptor(n,o)?.enumerable)throw Error(`Unrecognized key: "${String(o)}"`);if(t[o])r.push(o)}return r}function Hw(e,t){let n=e._zod.def,r=n.checks;if(r&&r.length>0)throw Error(".omit() cannot be used on object schemas containing refinements");let i=new Set(ho(e,t)),s={};return Mt(s,e,Reflect.ownKeys(ht(e)).filter((a)=>!i.has(a))),lt(e,Je(n,{shape:s,checks:[]}))}function Qw(e,t){if(!bt(t))throw Error("Invalid input to extend: expected a plain object");let n=e._zod.def.checks;if(n&&n.length>0){let o=ht(e);for(let i of Reflect.ownKeys(t))if(Object.getOwnPropertyDescriptor(o,i)!==void 0)throw Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}return lt(e,Je(e._zod.def,{shape:ud(e,t)}))}function ud(e,t){let n={};return Mt(n,e,Reflect.ownKeys(ht(e))),Ww(n,t),n}function Yw(e,t){if(!bt(t))throw Error("Invalid input to safeExtend: expected a plain object");return lt(e,Je(e._zod.def,{shape:ud(e,t)}))}function Xw(e,t){if(!t?._zod?.def)throw Error("Invalid input to merge: expected an object schema. To merge a plain shape, use `.extend()`.");if(e._zod.def.checks?.length)throw Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");let n={};Mt(n,e,Reflect.ownKeys(ht(e))),Mt(n,t,Reflect.ownKeys(ht(t)));let r=Je(e._zod.def,{shape:n,get catchall(){return t._zod.def.catchall},checks:t._zod.def.checks??[]});return lt(e,r)}function dd(e,t,n,r="partial"){let i=t._zod.def.checks;if(i&&i.length>0)throw Error(`.${r}() cannot be used on object schemas containing refinements`);let a=n?new Set(ho(t,n)):void 0,c={};return Mt(c,t,Reflect.ownKeys(ht(t)),e&&((l,u)=>a&&!a.has(u)?l:new e({type:"optional",innerType:l}))),lt(t,Je(t._zod.def,{shape:c,checks:[]}))}function ev(e,t,n){let r=n?new Set(ho(t,n)):void 0,o={};return Mt(o,t,Reflect.ownKeys(ht(t)),(i,s)=>r&&!r.has(s)?i:new e({type:"nonoptional",innerType:i})),lt(t,Je(t._zod.def,{shape:o}))}function Ve(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function pd(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue===!1)return!0;return!1}function Be(e,t){return t.map((n)=>{var r;return(r=n).path??(r.path=[]),n.path.unshift(e),n})}function Un(e){return typeof e==="string"?e:e?.message}function xs(e,t,n){var r;for(let o=t;o<e.length;o++)(r=e[o]).schema??(r.schema=n)}function Ue(e,t,n){var r;let o=e.inst?._zod?.traits;if(o?.has("$ZodType"))if(o.has("$ZodCheck"))(r=e).schema??(r.schema=e.inst);else e.schema=e.inst;let i=e.schema!==e.inst?e.schema?._zod.def?.error:void 0,s=e.message?e.message:Un(e.inst?._zod.def?.error?.(e))??Un(i?.(e))??Un(t?.error?.(e))??Un(n.customError?.(e))??Un(n.localeError?.(e))??"Invalid input",a={};for(let c of Object.keys(e)){if(c==="inst"||c==="schema"||c==="continue"||c==="input"||c==="__proto__")continue;a[c]=e[c]}if(a.path??(a.path=[]),a.message=s,t?.reportInput)a.input=e.input;return a}function yo(e){if(e instanceof Set)return"set";if(e instanceof Map)return"map";if(e instanceof File)return"file";return"unknown"}var tv=/[\uD800-\uDBFF]/;function bo(e){let t=e.length;if(!tv.test(e))return t;let n=t;for(let r=0;r<t-1;r++)if((e.charCodeAt(r)&64512)===55296&&(e.charCodeAt(r+1)&64512)===56320)n--,r++;return n}function wo(e){if(Array.isArray(e))return"array";if(typeof e==="string")return"string";return"unknown"}function fd(e){let t=typeof e;switch(t){case"number":return Number.isNaN(e)?"nan":"number";case"object":{if(e===null)return"null";if(Array.isArray(e))return"array";let n=e;if(n&&Object.getPrototypeOf(n)!==Object.prototype&&"constructor"in n&&n.constructor)return n.constructor.name}}return t}function Zt(...e){let[t,n,r]=e;if(typeof t==="string")return{message:t,code:"custom",input:n,inst:r};return{...t}}function md(e,t){for(let n in t){let r=Object.getOwnPropertyDescriptor(t,n);if(r.get)Object.defineProperty(e,n,{...r,enumerable:!1});else nv(e,n,r.value)}}function yt(e,t,n,r=!0){return Object.defineProperty(e,t,{configurable:!0,writable:!0,enumerable:r,value:n}),n}function Qn(e,t,n){return yt(e,t,n,!1)}function vo(e,t){for(let n in e){let r=e[n];Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get(){return yt(this,n,r(this))},set(o){yt(this,n,o)}})}return t}function nv(e,t,n){Object.defineProperty(e,t,{configurable:!0,get(){return this==null?n:yt(this,t,n.bind(this))},set(r){yt(this,t,r)}})}function rv(e,t){let n=Object.getPrototypeOf(e);return t in n?void 0:n}var hs,Ct=!1,ov={configurable:!0,get(){Ct=!0;return}};function G(e,t,n){let r=Object.getPrototypeOf(e._zod);if(t in r&&hs!==e._zod){hs=void 0;return}hs=e._zod,Object.defineProperty(r,t,{configurable:!0,get(){Object.defineProperty(this,t,ov);let o=Ct;Ct=!1;try{let i=n(this);if(Ct)delete this[t];else Object.defineProperty(this,t,{configurable:!0,writable:!0,value:i});return Ct=Ct||o,i}catch(i){throw delete this[t],Ct=Ct||o,i}},set(o){Object.defineProperty(this,t,{configurable:!0,writable:!0,value:o})}})}function iv(e,t,n,r){let o=rv(e,t);if(!o)return;Object.defineProperty(o,t,{configurable:!0,get(){let i={configurable:!0,writable:!0,enumerable:r,value:void 0};return Object.defineProperty(this,t,i),i.value=n(this),Object.defineProperty(this,t,i),i.value},set(i){Object.defineProperty(this,t,{configurable:!0,writable:!0,enumerable:r,value:i})}})}var sv="~constantCatch";function gd(e){let t=()=>e;return t[sv]=!0,t}var hd;var Ss={value:void 0,enumerable:!1},yd="captureStackTrace"in Error?Error:null;function av(e){let t=yd;if(t){let n=t.stackTraceLimit;if(typeof n==="number"){try{t.stackTraceLimit=0}catch{return yd=null,new e}try{return new e}finally{t.stackTraceLimit=n}}}return new e}function m(e,t,n,r){let o={};function i(h){this.def=h,this.constr=d,this.traits=new Set}i.prototype=o;let s=n,a=s&&new WeakSet;function c(h,g){if(!h._zod){Ss.value=new i(g);try{Object.defineProperty(h,"_zod",Ss)}finally{Ss.value=void 0}}else if(h._zod.traits.has(e))return;if(h._zod.traits.add(e),t(h,g),a){let S=Object.getPrototypeOf(h),A=h._zod.constr.prototype,N=S;while(N&&N!==A)N=Object.getPrototypeOf(N);let L=N??S;if(!a.has(L))a.add(L),md(L,s)}let y=d.prototype;for(let S in y){if(!Object.prototype.hasOwnProperty.call(y,S))continue;if(!(S in h))h[S]=y[S].bind(h)}}let l=r?.Parent??Object;class u extends l{}Object.defineProperty(u,"name",{value:e});function d(h){let g=r?.Parent?av(u):this;c(g,h);let y=g._zod.deferred;if(y){for(let A of y)A();g._zod.deferred=void 0}let S=globalThis.__zod_globalConfig?.postProcessor;if(S)S(g);return g}return Object.defineProperty(d,"init",{value:c}),Object.defineProperty(d,Symbol.hasInstance,{value:(h)=>{if(r?.Parent&&h instanceof r.Parent)return!0;return h?._zod?.traits?.has(e)}}),Object.defineProperty(d,"name",{value:e}),d}class ut extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class cn extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`);this.name="ZodEncodeError"}}(hd=globalThis).__zod_globalConfig??(hd.__zod_globalConfig={});var je=globalThis.__zod_globalConfig;function Ae(e){if(e)Object.assign(je,e);return je}function cv(){let e=this._zod;return e.message??(e.message=JSON.stringify(e.def,Wn,2)),e.message}function lv(e){this._zod.message=e}var uv={get:cv,set:lv,enumerable:!0,configurable:!0},Cs={value:void 0,enumerable:!1},bd=new WeakSet([Object.prototype,Error.prototype]),wd=(e,t)=>{e.name="$ZodError",Cs.value=t,Object.defineProperty(e,"issues",Cs),Cs.value=void 0,Object.defineProperty(e,"message",uv);let n=Object.getPrototypeOf(e);if(!bd.has(n))bd.add(n),Object.defineProperty(n,"toString",{configurable:!0,enumerable:!1,get(){let r=()=>this.message;return Object.defineProperty(this,"toString",{value:r,configurable:!0,writable:!0}),r},set(r){Object.defineProperty(this,"toString",{value:r,configurable:!0,writable:!0})}})},vd=m("$ZodError",wd),Es=m("$ZodError",wd,void 0,{Parent:Error});function dv(e,t,n){if(!Object.prototype.hasOwnProperty.call(e,t))if(t==="__proto__")Object.defineProperty(e,t,{value:n(),writable:!0,enumerable:!0,configurable:!0});else e[t]=n();return e[t]}function kd(e,t=(n)=>n.message){let n={},r=[];for(let o of e.issues)if(o.path.length>0)dv(n,o.path[0],()=>[]).push(t(o));else r.push(t(o));return{formErrors:r,fieldErrors:n}}function xd(e,t=(n)=>n.message){let n={_errors:[]},r=(o,i=[])=>{for(let s of o.issues)if(s.code==="invalid_union"&&s.errors.length)s.errors.map((a)=>r({issues:a},[...i,...s.path]));else if(s.code==="invalid_key")r({issues:s.issues},[...i,...s.path]);else if(s.code==="invalid_element")r({issues:s.issues},[...i,...s.path]);else{let a=[...i,...s.path];if(a.length===0)n._errors.push(t(s));else{let c=n,l=0;while(l<a.length){let u=a[l],d=l===a.length-1;if(u==="_errors"){if(d)c._errors.push(t(s));l++;continue}if(!Object.prototype.hasOwnProperty.call(c,u))Object.defineProperty(c,u,{value:{_errors:[]},enumerable:!0,writable:!0,configurable:!0});let h=c[u];if(d)h._errors.push(t(s));c=h,l++}}}};return r(e),n}function ko(e,t){return{callee:t?.callee??e,Err:t?.Err}}var Yn=(e)=>{let t=(n,r,o,i)=>{let s=o?{...o,async:!1}:{async:!1},a=n._zod.run({value:r,issues:[]},s);if(a instanceof Promise)throw new ut;if(a.issues.length){let c=new(i?.Err??e)(a.issues.map((l)=>Ue(l,s,Ae())));throw ws(c,i?.callee??t),c}return a.value};return t},Os=Yn(Es),Xn=(e)=>{let t=async(n,r,o,i)=>{let s=o?{...o,async:!0}:{async:!0},a=n._zod.run({value:r,issues:[]},s);if(a instanceof Promise)a=await a;if(a.issues.length){let c=new(i?.Err??e)(a.issues.map((l)=>Ue(l,s,Ae())));throw ws(c,i?.callee??t),c}return a.value};return t},js=Xn(Es),xo=(e)=>(t,n,r)=>{let o=r?{...r,async:!1}:{async:!1},i=t._zod.run({value:n,issues:[]},o);if(i instanceof Promise)throw new ut;return i.issues.length?Sd(e,i.issues,o):{success:!0,data:i.value}};function Sd(e,t,n){let r;return{success:!1,get error(){if(!r)r=new e(t.map((o)=>Ue(o,n,Ae()))),t=void 0,n=void 0;return r},set error(o){r=o,t=void 0,n=void 0}}}var So=(e)=>async(t,n,r)=>{let o=r?{...r,async:!0}:{async:!0},i=t._zod.run({value:n,issues:[]},o);if(i instanceof Promise)i=await i;return i.issues.length?Sd(e,i.issues,o):{success:!0,data:i.value}};var fv=Symbol.for("zod.compile.invalid"),mv=Symbol.for("zod.compile.fallback"),_s=(e,t,n)=>{let r=e._zod.bag.validator;if(r!==void 0){if(r(t)!==fv)return!0;if(r.definite===!0&&n===void 0)return!1}return gv(e,t,n)};function gv(e,t,n){let r=n?{...n,async:!1,abortEarly:!0}:{async:!1,abortEarly:!0},o=e._zod.bag.fallbackRun,i;if(o)r[mv]=!0,i=o({value:t,issues:[]},r);else i=e._zod.run({value:t,issues:[]},r);if(i instanceof Promise)throw new ut;return i.issues.length===0}var Rs=async(e,t,n)=>{let r=n?{...n,async:!0,abortEarly:!0}:{async:!0,abortEarly:!0},o=e._zod.run({value:t,issues:[]},r);if(o instanceof Promise)o=await o;return o.issues.length===0},Id=(e)=>{let t=Yn(e),n=(r,o,i,s)=>{let a=i?{...i,direction:"backward"}:{direction:"backward"};return t(r,o,a,ko(n,s))};return n};var Cd=(e)=>{let t=Yn(e),n=(r,o,i,s)=>t(r,o,i,ko(n,s));return n};var Ed=(e)=>{let t=Xn(e),n=async(r,o,i,s)=>{let a=i?{...i,direction:"backward"}:{direction:"backward"};return await t(r,o,a,ko(n,s))};return n};var Od=(e)=>{let t=Xn(e),n=async(r,o,i,s)=>await t(r,o,i,ko(n,s));return n};var jd=(e)=>(t,n,r)=>{let o=r?{...r,direction:"backward"}:{direction:"backward"};return xo(e)(t,n,o)};var _d=(e)=>(t,n,r)=>xo(e)(t,n,r);var Rd=(e)=>async(t,n,r)=>{let o=r?{...r,direction:"backward"}:{direction:"backward"};return So(e)(t,n,o)};var Ad=(e)=>async(t,n,r)=>So(e)(t,n,r);var Ps=/^[cC][0-9a-z]{6,}$/,Ts=/^[0-9a-z]+$/,$s=/^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/,Ns=/^[0-9a-vA-V]{20}$/,zs=/^[A-Za-z0-9]{27}$/,Ds=/^[a-zA-Z0-9_-]{21}$/;function qs(e){return new RegExp(`^[a-zA-Z0-9_-]{${e}}$`)}var Vs=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,hv=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,Ls=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Jt=(e)=>{if(!e)return/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`)},yv=Jt(4),bv=Jt(6),wv=Jt(7),Fs=/^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,vv=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,kv=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,Pd=/^[^\s@"]{1,64}@[^\s@]{1,255}$/u,xv=Pd,Sv=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,Iv="^(?=[\\s\\S]*[\\p{Extended_Pictographic}\\p{Regional_Indicator}\\u20E3])[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$";function Ms(){return new RegExp(Iv,"u")}var Zs=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,Js=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,Bs=(e)=>{let t=et(e??":");return new RegExp(`^(?:[0-9A-F]{2}${t}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${t}){5}[0-9a-f]{2}$`)},Us=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,Ks=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,Ws=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,Gs=/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/,Hs=/^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/,Qs=/^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/,er=/^https?$/,Ys=/^\+[1-9]\d{6,14}$/,Io=/^\d(?:[ -]?\d){11,18}$/,Xs=/^(?:AED|AFN|ALL|AMD|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BHD|BIF|BMD|BND|BOB|BOV|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHE|CHF|CHW|CLF|CLP|CNY|COP|COU|CRC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MXV|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|USN|UYI|UYU|UYW|UZS|VED|VES|VND|VUV|WST|XAD|XAF|XAG|XAU|XBA|XBB|XBC|XBD|XCD|XCG|XDR|XOF|XPD|XPF|XPT|XSU|XTS|XUA|XXX|YER|ZAR|ZMW|ZWG)$/,Co=/^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/,Td="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))";function Cv(e){return new RegExp(`^${e}$`)}var ea=Cv(Td);function As(e){return typeof e.precision==="number"?e.precision===-1?"(?:[01]\\d|2[0-3]):[0-5]\\d":e.precision===0?"(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d":`(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{${e.precision}}`:e.seconds?"(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?":"(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?"}function ta(e){return new RegExp(`^${As(e)}$`)}function na(e){let t=["Z"];if(e.offset)t.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");let n=`${As({precision:e.precision,seconds:!0})}(?:${t.join("|")})`,r=e.local?`${n}|${As({precision:e.precision})}`:n;return new RegExp(`^${Td}T(?:${r})$`)}var ra=/^[\s\S]{0,}$/,oa=(e)=>{let t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${t}$`)},ia=/^-?\d+n?$/,tr=/^-?\d+$/,Bt=/^-?\d+(?:\.\d+)?$/,sa=/^(?:true|false)$/i,aa=/^null$/i;var ca=/^undefined$/i;var la=/^[^A-Z]*$/,ua=/^[^a-z]*$/,da=/^[0-9a-fA-F]*$/;function nr(e,t){return new RegExp(`^[A-Za-z0-9+/]{${e}}${t}$`)}function rr(e){return new RegExp(`^[A-Za-z0-9_-]{${e}}$`)}var Ev=/^[0-9a-fA-F]{32}$/,Ov=nr(22,"=="),jv=rr(22),_v=/^[0-9a-fA-F]{40}$/,Rv=nr(27,"="),Av=rr(27),Pv=/^[0-9a-fA-F]{64}$/,Tv=nr(43,"="),$v=rr(43),Nv=/^[0-9a-fA-F]{96}$/,zv=nr(64,""),Dv=rr(64),qv=/^[0-9a-fA-F]{128}$/,Vv=nr(86,"=="),Lv=rr(86);var ue=m("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),pa=(e)=>{let t=e.value;return!bs(t)&&t.size!==void 0},fa=(e)=>{let t=e.value;return!bs(t)&&t.length!==void 0},Eo={number:"number",bigint:"bigint",object:"date"},ma=m("$ZodCheckLessThan",(e,t)=>{ue.init(e,t);let n=Eo[typeof t.value];e._zod.check=(r)=>{if(t.inclusive?r.value<=t.value:r.value<t.value)return;r.issues.push({origin:Eo[typeof r.value]??n,code:"too_big",maximum:typeof t.value==="object"?t.value.getTime():t.value,input:r.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),ga=m("$ZodCheckGreaterThan",(e,t)=>{ue.init(e,t);let n=Eo[typeof t.value];e._zod.check=(r)=>{if(t.inclusive?r.value>=t.value:r.value>t.value)return;r.issues.push({origin:Eo[typeof r.value]??n,code:"too_small",minimum:typeof t.value==="object"?t.value.getTime():t.value,input:r.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),$d=m("$ZodCheckMultipleOf",(e,t)=>{ue.init(e,t),e._zod.check=(n)=>{if(typeof n.value!==typeof t.value)throw Error("Cannot mix number and bigint in multiple_of check.");if(typeof n.value==="bigint"?t.value!==BigInt(0)&&n.value%t.value===BigInt(0):td(n.value,t.value)===0)return;n.issues.push({origin:typeof n.value,code:"not_multiple_of",divisor:t.value,input:n.value,inst:e,continue:!t.abort})}}),Nd=m("$ZodCheckNumberFormat",(e,t)=>{ue.init(e,t),t.format=t.format||"float64";let n=t.format?.includes("int"),r=n?"int":"number",[o,i]=mo[t.format];e._zod.check=(s)=>{let a=s.value;if(n){if(!Number.isInteger(a)){s.issues.push({expected:r,format:t.format,code:"invalid_type",continue:!1,input:a,inst:e});return}if(!Number.isSafeInteger(a)){if(a>0)s.issues.push({input:a,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:r,inclusive:!0,continue:!t.abort});else s.issues.push({input:a,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:r,inclusive:!0,continue:!t.abort});return}}if(a<o)s.issues.push({origin:"number",input:a,code:"too_small",minimum:o,inclusive:!0,inst:e,continue:!t.abort});if(a>i)s.issues.push({origin:"number",input:a,code:"too_big",maximum:i,inclusive:!0,inst:e,continue:!t.abort})}}),zd=m("$ZodCheckBigIntFormat",(e,t)=>{ue.init(e,t);let[n,r]=go[t.format];e._zod.check=(o)=>{let i=o.value;if(i<n)o.issues.push({origin:"bigint",input:i,code:"too_small",minimum:n,inclusive:!0,inst:e,continue:!t.abort});if(i>r)o.issues.push({origin:"bigint",input:i,code:"too_big",maximum:r,inclusive:!0,inst:e,continue:!t.abort})}}),Dd=m("$ZodCheckMaxSize",(e,t)=>{var n;ue.init(e,t),(n=e._zod.def).when??(n.when=pa),e._zod.check=(r)=>{let o=r.value;if(o.size<=t.maximum)return;r.issues.push({origin:yo(o),code:"too_big",maximum:t.maximum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),qd=m("$ZodCheckMinSize",(e,t)=>{var n;ue.init(e,t),(n=e._zod.def).when??(n.when=pa),e._zod.check=(r)=>{let o=r.value;if(o.size>=t.minimum)return;r.issues.push({origin:yo(o),code:"too_small",minimum:t.minimum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),Vd=m("$ZodCheckSizeEquals",(e,t)=>{var n;ue.init(e,t),(n=e._zod.def).when??(n.when=pa),e._zod.check=(r)=>{let o=r.value,i=o.size;if(i===t.size)return;let s=i>t.size;r.issues.push({origin:yo(o),...s?{code:"too_big",maximum:t.size}:{code:"too_small",minimum:t.size},inclusive:!0,exact:!0,input:r.value,inst:e,continue:!t.abort})}}),Ld=m("$ZodCheckMaxLength",(e,t)=>{var n;ue.init(e,t),(n=e._zod.def).when??(n.when=fa),e._zod.check=(r)=>{let o=r.value,i=o.length;if((typeof o==="string"&&i>t.maximum?bo(o):i)<=t.maximum)return;let a=wo(o);r.issues.push({origin:a,code:"too_big",maximum:t.maximum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),Fd=m("$ZodCheckMinLength",(e,t)=>{var n;ue.init(e,t),(n=e._zod.def).when??(n.when=fa),e._zod.check=(r)=>{let o=r.value,i=o.length;if((typeof o==="string"&&i>=t.minimum&&i<t.minimum*2?bo(o):i)>=t.minimum)return;let a=wo(o);r.issues.push({origin:a,code:"too_small",minimum:t.minimum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),Md=m("$ZodCheckLengthEquals",(e,t)=>{var n;ue.init(e,t),(n=e._zod.def).when??(n.when=fa),e._zod.check=(r)=>{let o=r.value,i=o.length,s=typeof o==="string"&&i>=t.length&&i<=t.length*2?bo(o):i;if(s===t.length)return;let a=wo(o),c=s>t.length;r.issues.push({origin:a,...c?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:r.value,inst:e,continue:!t.abort})}}),or=m("$ZodCheckStringFormat",(e,t)=>{var n,r;if(ue.init(e,t),t.pattern)(n=e._zod).check??(n.check=(o)=>{if(t.pattern.lastIndex=0,t.pattern.test(o.value))return;o.issues.push({origin:"string",code:"invalid_format",format:t.format,input:o.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})});else(r=e._zod).check??(r.check=()=>{})}),Zd=m("$ZodCheckRegex",(e,t)=>{or.init(e,t),e._zod.check=(n)=>{if(t.pattern.lastIndex=0,t.pattern.test(n.value))return;n.issues.push({origin:"string",code:"invalid_format",format:"regex",input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),Jd=m("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=la),or.init(e,t)}),Bd=m("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=ua),or.init(e,t)}),Ud=m("$ZodCheckIncludes",(e,t)=>{ue.init(e,t);let n=et(t.includes),r=new RegExp(typeof t.position==="number"?`^.{${t.position},}${n}`:n);t.pattern=r,e._zod.check=(o)=>{if(o.value.includes(t.includes,t.position))return;o.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:o.value,inst:e,continue:!t.abort})}}),Kd=m("$ZodCheckStartsWith",(e,t)=>{ue.init(e,t);let n=new RegExp(`^${et(t.prefix)}.*`);t.pattern??(t.pattern=n),e._zod.check=(r)=>{if(r.value.startsWith(t.prefix))return;r.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:r.value,inst:e,continue:!t.abort})}}),Wd=m("$ZodCheckEndsWith",(e,t)=>{ue.init(e,t);let n=new RegExp(`.*${et(t.suffix)}$`);t.pattern??(t.pattern=n),e._zod.check=(r)=>{if(r.value.endsWith(t.suffix))return;r.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:r.value,inst:e,continue:!t.abort})}});function Oo(e,t,n){if(e.issues.length)t.issues.push(...Be(n,e.issues))}var Gd=m("$ZodCheckProperty",(e,t)=>{ue.init(e,t),e._zod.check=(n)=>{let r=t.schema._zod.run({value:n.value[t.property],issues:[]},{});if(r instanceof Promise)return r.then((o)=>Oo(o,n,t.property));Oo(r,n,t.property);return}}),Hd=m("$ZodCheckProperties",(e,t)=>{ue.init(e,t),Qn(e,Symbol.iterator,function*(){yield e});let n;e._zod.check=(r)=>{if(r.value==null){r.issues.push({expected:"object",code:"invalid_type",input:r.value,inst:e});return}n??(n=Reflect.ownKeys(t.shape).map((s)=>[s,t.shape[s]]));let o=r.value,i;for(let[s,a]of n){let c=a._zod.run({value:o[s],issues:[]},{});if(c instanceof Promise)i??(i=[]),i.push(c.then((l)=>Oo(l,r,s)));else Oo(c,r,s)}if(i)return Promise.all(i).then(()=>{return});return}}),Qd=m("$ZodCheckMimeType",(e,t)=>{ue.init(e,t);let n=new Set(t.mime);e._zod.check=(r)=>{if(n.has(r.value.type))return;r.issues.push({code:"invalid_value",values:t.mime,input:r.value.type,inst:e,continue:!t.abort})}}),Yd=m("$ZodCheckOverwrite",(e,t)=>{ue.init(e,t),e._zod.check=(n)=>{n.value=t.tx(n.value)}});class ha{constructor(e=[],t={}){this.content=[],this.indent=0,this.args=e,this.closed=t}indented(e){this.indent+=1;try{e(this)}finally{this.indent-=1}}write(e){if(typeof e==="function"){e(this,{execution:"sync"}),e(this,{execution:"async"});return}let n=e.split(`
5
5
  `).filter((i)=>i),r=Math.min(...n.map((i)=>i.length-i.trimStart().length)),o=n.map((i)=>i.slice(r)).map((i)=>" ".repeat(this.indent*2)+i);for(let i of o)this.content.push(i)}compile(){let e=Function,t=this?.content??[""];return new e(...Object.keys(this.closed),`return function (${this.args.join(", ")}) {
@@ -0,0 +1,3 @@
1
+ /** Presentation direction; omitted legacy layouts run from left to right. */
2
+ export type CanvasDirection = 'horizontal' | 'vertical';
3
+ export declare function canvasDirection(value: unknown): CanvasDirection;
@@ -0,0 +1 @@
1
+ export type InteractiveMode = 'mouse' | 'touchpad';
@@ -26621,6 +26621,76 @@ var OpenFlowRenderer = (function(exports) {
26621
26621
  }
26622
26622
  /*! For license information please see dagre.esm.js.LEGAL.txt */
26623
26623
  //#endregion
26624
+ //#region src/canvas/browser/base/routeCrossings.ts
26625
+ var epsilon = 1e-6;
26626
+ function samePoint(a, b) {
26627
+ return Math.abs(a.x - b.x) < epsilon && Math.abs(a.y - b.y) < epsilon;
26628
+ }
26629
+ function segment(a, b) {
26630
+ return {
26631
+ left: Math.min(a.x, b.x),
26632
+ right: Math.max(a.x, b.x),
26633
+ top: Math.min(a.y, b.y),
26634
+ bottom: Math.max(a.y, b.y)
26635
+ };
26636
+ }
26637
+ /** Allow only the common prefix/suffix, not later crossings between the same edges. */
26638
+ function sharedEnd(a, b, overlap, reverse) {
26639
+ const step = reverse ? -1 : 1;
26640
+ let i = reverse ? a.length - 1 : 0;
26641
+ let j = reverse ? b.length - 1 : 0;
26642
+ let start = a[i];
26643
+ if (!samePoint(start, b[j])) return false;
26644
+ if (Math.abs(overlap.left - start.x) < epsilon && Math.abs(overlap.right - start.x) < epsilon && Math.abs(overlap.top - start.y) < epsilon && Math.abs(overlap.bottom - start.y) < epsilon) return true;
26645
+ while (a[i + step] && b[j + step]) {
26646
+ const endA = a[i + step];
26647
+ const endB = b[j + step];
26648
+ const vertical = Math.abs(endA.x - start.x) < epsilon;
26649
+ const otherVertical = Math.abs(endB.x - start.x) < epsilon;
26650
+ const directionA = vertical ? endA.y - start.y : endA.x - start.x;
26651
+ const directionB = vertical ? endB.y - start.y : endB.x - start.x;
26652
+ if (vertical !== otherVertical || directionA * directionB < 0) return false;
26653
+ const end = Math.abs(directionA) <= Math.abs(directionB) ? endA : endB;
26654
+ const common = segment(start, end);
26655
+ if (overlap.left >= common.left - epsilon && overlap.right <= common.right + epsilon && overlap.top >= common.top - epsilon && overlap.bottom <= common.bottom + epsilon) return true;
26656
+ if (samePoint(end, endA)) i += step;
26657
+ if (samePoint(end, endB)) j += step;
26658
+ start = end;
26659
+ }
26660
+ return false;
26661
+ }
26662
+ /** Check orthogonal routes once after layout; stop at the first unrelated contact or overlap. */
26663
+ function hasRouteCrossings(routes) {
26664
+ const paths = [...routes.values()].map((points) => {
26665
+ const path = points.filter((point, index) => index === 0 || !samePoint(point, points[index - 1]));
26666
+ return {
26667
+ path,
26668
+ segments: path.slice(1).map((point, index) => segment(path[index], point))
26669
+ };
26670
+ });
26671
+ for (let i = 0; i < paths.length; i++) {
26672
+ const a = paths[i];
26673
+ for (let j = i + 1; j < paths.length; j++) {
26674
+ const b = paths[j];
26675
+ for (const first of a.segments) for (const second of b.segments) {
26676
+ const left = Math.max(first.left, second.left);
26677
+ const right = Math.min(first.right, second.right);
26678
+ const top = Math.max(first.top, second.top);
26679
+ const bottom = Math.min(first.bottom, second.bottom);
26680
+ if (left > right + epsilon || top > bottom + epsilon) continue;
26681
+ const overlap = {
26682
+ left,
26683
+ right,
26684
+ top,
26685
+ bottom
26686
+ };
26687
+ if (!sharedEnd(a.path, b.path, overlap, false) && !sharedEnd(a.path, b.path, overlap, true)) return true;
26688
+ }
26689
+ }
26690
+ }
26691
+ return false;
26692
+ }
26693
+ //#endregion
26624
26694
  //#region src/canvas/browser/base/routeLayout.ts
26625
26695
  var clearance = 16;
26626
26696
  var portOffset = 24;
@@ -27026,19 +27096,26 @@ var OpenFlowRenderer = (function(exports) {
27026
27096
  const gap = 48;
27027
27097
  const pathNodes = normalized.filter((node) => incoming.has(node.id) || outgoing.has(node.id));
27028
27098
  const crossSize = Math.max(...(pathNodes.length ? pathNodes : normalized).map((node) => node.height));
27029
- const bow = crossSize * .75;
27030
- const separation = crossSize + 48;
27099
+ const bow = crossSize * .5;
27100
+ const separation = crossSize + bow + gap;
27031
27101
  const bucketSize = Math.max(...normalized.map((node) => node.width)) + gap;
27032
27102
  const byId = new Map(normalized.map((node) => [node.id, node]));
27033
27103
  const forwardEdges = graph.edges.filter((edge) => byId.get(edge.source).column < byId.get(edge.target).column);
27034
27104
  const parents = Map.groupBy(forwardEdges, (edge) => edge.target);
27035
27105
  const children = Map.groupBy(forwardEdges, (edge) => edge.source);
27036
27106
  const ordered = normalized.toSorted((a, b) => a.column - b.column || a.y - b.y);
27037
- const remaining = /* @__PURE__ */ new Map();
27038
- for (const node of ordered.toReversed()) remaining.set(node.id, 1 + Math.max(0, ...(children.get(node.id) ?? []).filter((edge) => parents.get(edge.target)?.length === 1).map((edge) => remaining.get(edge.target))));
27039
27107
  const rankEnds = new Map([...Map.groupBy(normalized, (node) => node.column)].map(([rank, nodes]) => [rank, Math.max(...nodes.map((node) => node.x + node.width))]));
27108
+ const remaining = /* @__PURE__ */ new Map();
27109
+ for (const node of ordered.toReversed()) {
27110
+ const next = (children.get(node.id) ?? []).filter((edge) => parents.get(edge.target)?.length === 1).map((edge) => remaining.get(edge.target));
27111
+ remaining.set(node.id, {
27112
+ count: 1 + Math.max(0, ...next.map((path) => path.count)),
27113
+ size: Math.max(node.width, ...next.map((path) => rankEnds.get(node.column) - node.x + gap + path.size))
27114
+ });
27115
+ }
27040
27116
  const spans = /* @__PURE__ */ new Set([Infinity, ...rankEnds.values()]);
27041
- let best;
27117
+ const layouts = [];
27118
+ let unfolded;
27042
27119
  for (const span of spans) {
27043
27120
  const placed = /* @__PURE__ */ new Map();
27044
27121
  const buckets = /* @__PURE__ */ new Map();
@@ -27060,10 +27137,15 @@ var OpenFlowRenderer = (function(exports) {
27060
27137
  } else if (parent) {
27061
27138
  shift = parent.shift;
27062
27139
  start = parent.start;
27140
+ const length = primary - start + remaining.get(original.id).size;
27141
+ const capacity = Math.max(original.width, span - start);
27142
+ const runs = Math.max(1, Math.ceil((length + gap) / (capacity + gap)));
27143
+ const end = start + (length + gap) / runs - gap;
27144
+ const midpoint = (parent.node.x + parent.node.width + primary + original.width) / 2;
27063
27145
  if ((children.get(parent.node.id)?.length ?? 0) > 1) {
27064
27146
  shift = parent.node.y - byId.get(parent.node.id).y;
27065
27147
  start = primary;
27066
- } else if (primary + original.width > span && remaining.get(original.id) > 2) {
27148
+ } else if (midpoint > end + 1e-6 && remaining.get(original.id).count > 2) {
27067
27149
  primary = Math.max(0, start - span / 3);
27068
27150
  shift = parent.shift + side * separation;
27069
27151
  start = primary;
@@ -27092,7 +27174,7 @@ var OpenFlowRenderer = (function(exports) {
27092
27174
  order: placed.size,
27093
27175
  shift: node.y - original.y - drift,
27094
27176
  start,
27095
- extent: Math.max(node.x + node.width, ...upstream.map((entry) => entry.extent))
27177
+ extent: Math.max(node.x + node.width, parent && node.x < parent.node.x ? parent.node.x + parent.node.width + gap : 0, ...upstream.map((entry) => entry.extent))
27096
27178
  };
27097
27179
  placed.set(node.id, placement);
27098
27180
  for (let bucket = firstBucket; bucket <= lastBucket; bucket++) {
@@ -27106,23 +27188,37 @@ var OpenFlowRenderer = (function(exports) {
27106
27188
  const width = extent.height + insets.width + 48;
27107
27189
  const height = extent.width + insets.height + 48;
27108
27190
  const area = width * height;
27109
- const score = Math.max(width / aspectRatio, height);
27110
- if (!best || score < best.score - 1e-9 || Math.abs(score - best.score) < 1e-9 && (area < best.area || area === best.area && turns < best.turns)) best = {
27191
+ const candidate = {
27111
27192
  nodes,
27112
- score,
27193
+ score: Math.max(width / aspectRatio, height),
27113
27194
  area,
27114
27195
  turns
27115
27196
  };
27197
+ if (span === Infinity) unfolded = candidate;
27198
+ layouts.push(candidate);
27199
+ layouts.sort((a, b) => Math.abs(a.score - b.score) >= 1e-9 ? a.score - b.score : a.area - b.area || a.turns - b.turns);
27200
+ if (layouts.length > 2) layouts.pop();
27116
27201
  }
27117
- const routes = routeLayout(best.nodes, graph.edges.map((edge) => Object.assign({}, edge, {
27202
+ const edges = graph.edges.map((edge) => Object.assign({}, edge, {
27118
27203
  sourceOffset: edge.sourceOffset && layoutAxes(edge.sourceOffset, "vertical"),
27119
27204
  targetOffset: edge.targetOffset && layoutAxes(edge.targetOffset, "vertical")
27120
- })));
27205
+ }));
27206
+ if (!layouts.includes(unfolded)) layouts.push(unfolded);
27207
+ let best;
27208
+ for (const candidate of layouts) {
27209
+ const routes = routeLayout(candidate.nodes, edges);
27210
+ const crosses = hasRouteCrossings(routes);
27211
+ if (!best || !crosses) best = {
27212
+ nodes: candidate.nodes,
27213
+ routes
27214
+ };
27215
+ if (!crosses) break;
27216
+ }
27121
27217
  const physicalNodes = best.nodes.map((node) => Object.assign({}, node, layoutAxes(node, "vertical"), {
27122
27218
  width: node.height,
27123
27219
  height: node.width
27124
27220
  }));
27125
- const physicalRoutes = new Map([...routes].map(([id, points]) => [id, points.map((point) => layoutAxes(point, "vertical"))]));
27221
+ const physicalRoutes = new Map([...best.routes].map(([id, points]) => [id, points.map((point) => layoutAxes(point, "vertical"))]));
27126
27222
  return {
27127
27223
  positions: Object.fromEntries(physicalNodes.map(({ id, x, y }) => [id, {
27128
27224
  x,
@@ -33097,7 +33193,7 @@ var OpenFlowRenderer = (function(exports) {
33097
33193
  #modelViewport;
33098
33194
  #runStatus;
33099
33195
  #selectedNodeIds;
33100
- constructor(model, editable, language, callbacks, autoLayout = false, interactiveMode$) {
33196
+ constructor(model, editable, language, callbacks, options = {}) {
33101
33197
  this.canDeleteNodes = true;
33102
33198
  this.dispose = disposableStore();
33103
33199
  this.connectionRoutes = this.dispose.add(val(/* @__PURE__ */ new Map()));
@@ -33285,7 +33381,7 @@ var OpenFlowRenderer = (function(exports) {
33285
33381
  const commentNodes = this.dispose.add(reactiveMap(null, { onDeleted: dispose }));
33286
33382
  const viewport = this.dispose.add(val(model.viewport, { equal: isSameViewport }));
33287
33383
  this.rfCommand = this.dispose.add(createRFCommand(nodes));
33288
- this.layoutComplete = !autoLayout;
33384
+ this.layoutComplete = !options.autoLayout;
33289
33385
  this.#runStatus = this.dispose.add(val(model.runStatus == "running" ? FLOW_RUN_STATUS.Running : FLOW_RUN_STATUS.Idle));
33290
33386
  this.#connections = this.dispose.add(val([]));
33291
33387
  const edges = this.dispose.add(deriveEdges(this.#connections, nodes));
@@ -33293,9 +33389,9 @@ var OpenFlowRenderer = (function(exports) {
33293
33389
  this.$$ = {
33294
33390
  initialized: this.dispose.add(val(false)),
33295
33391
  editable: this.dispose.add(val(editable)),
33296
- miniMapExpanded: this.dispose.add(val()),
33392
+ miniMapExpanded: this.dispose.add(val(options.defaultMiniMapExpanded)),
33297
33393
  viewport,
33298
- interactiveMode: interactiveMode$ ?? this.dispose.add(val("touchpad")),
33394
+ interactiveMode: options.interactiveMode$ ?? this.dispose.add(val(options.defaultInteractiveMode ?? "touchpad")),
33299
33395
  direction: this.dispose.add(val(canvasDirection(model.direction))),
33300
33396
  changingDirection: this.dispose.add(val(false)),
33301
33397
  nodes,
@@ -33322,6 +33418,7 @@ var OpenFlowRenderer = (function(exports) {
33322
33418
  nodeMiniMapPhase: this.dispose.add(compute((get) => getNodeMinimap(get(nodes.$).size + get(commentNodes.$).size, get(viewport)?.zoom ?? 1)))
33323
33419
  };
33324
33420
  this.#syncModel(model);
33421
+ if (options.defaultDirection != null) this.changeDirection(options.defaultDirection);
33325
33422
  }
33326
33423
  async #saveDirection(positions) {
33327
33424
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oomol-lab/open-flow",
3
- "version": "0.1.0-beta.83",
3
+ "version": "0.1.0-beta.85",
4
4
  "description": "TypeScript contracts and Browser runtime for Open Flow.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {