@statelyai/layout 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,6 +71,10 @@ The adapter accepts ELK JSON and option aliases, translates to
71
71
  `@statelyai/graph`, runs native algorithms, and translates the result back.
72
72
  Native algorithms never consume ELK JSON directly.
73
73
 
74
+ <!-- fixed-port placement and inline center-label guarantees from src/layered/index.ts and src/layered/strategies.ts -->
75
+
76
+ Fixed port sides constrain routes without collapsing fan-out targets onto each other. Port preferences cannot reintroduce cycles before layering. Inline center labels use reserved inter-rank space; dedicated label layers and route-track compaction retain their placement strategies. Inline self-loop labels reserve clearance on their assigned sides from both their owner and neighboring nodes. Hierarchy decomposition preserves native self-loop routes for ancestor-to-descendant edges. FIRST/FIRST_SEPARATE nodes may have self-loops.
77
+
74
78
  Advanced layered settings use shorter names such as
75
79
  `layering.strategy`, `spacing.edgeNode`, and `nodePlacement.strategy`.
76
80
  `toElkLayeredOptions` and `fromElkLayeredOptionId` provide the exact one-to-one
@@ -166,3 +170,13 @@ workflow opens or updates a version pull request. Merging that pull request
166
170
  publishes the package to npm and creates the GitHub release and tag.
167
171
 
168
172
  Publishing uses npm Trusted Publishing through `.github/workflows/release.yml`.
173
+
174
+ ## Statechart reading order
175
+
176
+ <!-- statechart policy API from src/elkjs/statechart.ts -->
177
+
178
+ The opt-in `layoutStatechart` export from `@statelyai/layout/elkjs` compiles
179
+ initial-state and preferred-path hints into scoped settings, then selects among
180
+ at most three fresh layout attempts. It returns all quality scores, including
181
+ remaining defects. See [statechart policies](docs/statechart-layout.md) for the
182
+ API, supported controls, tradeoffs and reproducible visual comparison.
@@ -86,6 +86,49 @@ type LaidOutElkNode<T extends ElkNode> = Omit<T, "children" | "edges"> & Omit<El
86
86
  edges?: Array<NonNullable<T["edges"]>[number] & ElkEdge>;
87
87
  };
88
88
  //#endregion
89
+ //#region src/elkjs/statechart.d.ts
90
+ interface StatechartScope {
91
+ /** Direct child of this container; never inferred from state names. */
92
+ initialNodeId?: ElkId;
93
+ /** Connected direct-child path. Explicit paths resolve branching ambiguity. */
94
+ preferredPath?: readonly ElkId[];
95
+ direction?: "UP" | "DOWN" | "LEFT" | "RIGHT";
96
+ }
97
+ interface StatechartLayoutOptions {
98
+ scopes: Readonly<Record<string, StatechartScope>>;
99
+ /** Total engine calls, including baseline; integer from 1 to 3. Default 3. */
100
+ maxAttempts?: number;
101
+ }
102
+ interface StatechartLayoutScore {
103
+ invalid: number;
104
+ overlaps: number;
105
+ pathOrder: number;
106
+ crossings: number;
107
+ bends: number;
108
+ routeLength: number;
109
+ }
110
+ interface StatechartLayoutPlan {
111
+ graph: ElkNode;
112
+ paths: Record<string, ElkId[]>;
113
+ commonExits: Record<string, ElkId[]>;
114
+ }
115
+ /** Compile semantic hints into settings implemented by this package's ELK adapter. */
116
+ declare function compileStatechartLayout(input: ElkNode, scopes: StatechartLayoutOptions["scopes"]): StatechartLayoutPlan;
117
+ /** Diagnostic objective, not a proof of geometric validity. Coordinates are container-relative. */
118
+ declare function scoreStatechartLayout(graph: ElkNode, paths?: StatechartLayoutPlan["paths"]): StatechartLayoutScore;
119
+ /** Each attempt starts from original input. No post-layout geometry edits. */
120
+ declare function layoutStatechart<T extends ElkNode>(input: T, options: StatechartLayoutOptions): Promise<{
121
+ attempts: {
122
+ kind: "baseline" | "policy" | "spacing";
123
+ score: StatechartLayoutScore;
124
+ }[];
125
+ paths: Record<string, ElkId[]>;
126
+ commonExits: Record<string, ElkId[]>;
127
+ graph: LaidOutElkNode<T>;
128
+ score: StatechartLayoutScore;
129
+ attempt: number;
130
+ }>;
131
+ //#endregion
89
132
  //#region src/elkjs/index.d.ts
90
133
  declare class ELK {
91
134
  #private;
@@ -97,4 +140,4 @@ declare class ELK {
97
140
  layout<T extends ElkNode>(graph: T, arguments_?: ElkLayoutArguments): Promise<LaidOutElkNode<T>>;
98
141
  }
99
142
  //#endregion
100
- export { type ElkCommonDescription, type ElkConstructorArguments, type ElkEdge, type ElkEdgeSection, type ElkGraphElement, type ElkId, type ElkLabel, type ElkLayoutAlgorithmDescription, type ElkLayoutArguments, type ElkLayoutCategoryDescription, type ElkLayoutOptionDescription, type ElkLogging, type ElkNode, type ElkPoint, type ElkPort, type ElkShape, type LaidOutElkNode, ELK as default };
143
+ export { type ElkCommonDescription, type ElkConstructorArguments, type ElkEdge, type ElkEdgeSection, type ElkGraphElement, type ElkId, type ElkLabel, type ElkLayoutAlgorithmDescription, type ElkLayoutArguments, type ElkLayoutCategoryDescription, type ElkLayoutOptionDescription, type ElkLogging, type ElkNode, type ElkPoint, type ElkPort, type ElkShape, type LaidOutElkNode, type StatechartLayoutOptions, type StatechartLayoutPlan, type StatechartLayoutScore, type StatechartScope, compileStatechartLayout, ELK as default, layoutStatechart, scoreStatechartLayout };
@@ -1,7 +1,266 @@
1
- import { o as elkLayeredOptionDefinitions, t as getLayeredLayout } from "../layered-BYhTymAk.mjs";
2
- import { a as getRandomLayout, f as getFixedLayout, n as getSporeOverlapRemovalLayout, s as getRectanglePackingLayout, t as getSporeCompactionLayout, u as getBoxLayout } from "../spore-B504wOFR.mjs";
1
+ import { o as elkLayeredOptionDefinitions, t as getLayeredLayout } from "../layered-CZs9YWVx.mjs";
2
+ import { a as getRandomLayout, f as getFixedLayout, n as getSporeOverlapRemovalLayout, s as getRectanglePackingLayout, t as getSporeCompactionLayout, u as getBoxLayout } from "../spore-9N0W9dZn.mjs";
3
3
  import { createGraph } from "@statelyai/graph";
4
4
 
5
+ //#region src/elkjs/statechart.ts
6
+ function option(node, suffix) {
7
+ const settings = {
8
+ ...node.properties,
9
+ ...node.layoutOptions
10
+ };
11
+ return settings[suffix] ?? settings[`elk.${suffix}`] ?? settings[`org.eclipse.elk.${suffix}`];
12
+ }
13
+ const endpoint$1 = (edge, source) => source ? edge.sources?.[0] ?? edge.source : edge.targets?.[0] ?? edge.target;
14
+ /** Compile semantic hints into settings implemented by this package's ELK adapter. */
15
+ function compileStatechartLayout(input, scopes) {
16
+ const graph = structuredClone(input);
17
+ const paths = Object.create(null);
18
+ const commonExits = Object.create(null);
19
+ const containers = /* @__PURE__ */ new Map();
20
+ const edges = [];
21
+ const collect = (node) => {
22
+ if (node.id === void 0 || containers.has(String(node.id))) throw new Error("Statechart nodes require unique IDs");
23
+ containers.set(String(node.id), node);
24
+ edges.push(...node.edges ?? []);
25
+ node.children?.forEach(collect);
26
+ };
27
+ collect(graph);
28
+ for (const [id, scope] of Object.entries(scopes)) {
29
+ const container = containers.get(id);
30
+ if (!container) throw new Error(`Unknown statechart container: ${id}`);
31
+ const children = container.children ?? [];
32
+ const ids = new Set(children.map((node) => node.id));
33
+ const owner = /* @__PURE__ */ new Map();
34
+ const own = (node, childId) => {
35
+ owner.set(node.id, childId);
36
+ node.ports?.forEach((port) => owner.set(port.id, childId));
37
+ node.children?.forEach((descendant) => own(descendant, childId));
38
+ };
39
+ children.forEach((child) => own(child, child.id));
40
+ const localEdges = edges.filter((edge) => owner.has(endpoint$1(edge, true)) && owner.has(endpoint$1(edge, false)));
41
+ const successors = new Map(children.map((node) => [node.id, /* @__PURE__ */ new Set()]));
42
+ const predecessors = new Map(children.map((node) => [node.id, /* @__PURE__ */ new Set()]));
43
+ for (const edge of localEdges) {
44
+ const source = owner.get(endpoint$1(edge, true));
45
+ const target = owner.get(endpoint$1(edge, false));
46
+ if (source === target) continue;
47
+ successors.get(source).add(target);
48
+ predecessors.get(target).add(source);
49
+ }
50
+ const exits = children.filter((node) => successors.get(node.id).size === 0 && predecessors.get(node.id).size >= 2).map((node) => node.id);
51
+ commonExits[id] = exits;
52
+ const path = [...scope.preferredPath ?? (scope.initialNodeId === void 0 ? [] : [scope.initialNodeId])];
53
+ if (new Set(path).size !== path.length || path.some((nodeId) => !ids.has(nodeId))) throw new Error(`Path must contain distinct direct children of ${id}`);
54
+ if (scope.initialNodeId !== void 0 && (!ids.has(scope.initialNodeId) || path[0] !== scope.initialNodeId)) throw new Error(`Path must start at initial child of ${id}`);
55
+ if (scope.preferredPath) {
56
+ for (let i = 1; i < path.length; i++) if (!successors.get(path[i - 1])?.has(path[i])) throw new Error(`Disconnected preferred path in ${id}`);
57
+ } else while (path.length) {
58
+ const next = [...successors.get(path.at(-1))].filter((nodeId) => !path.includes(nodeId) && !exits.includes(nodeId));
59
+ if (next.length !== 1) break;
60
+ path.push(next[0]);
61
+ }
62
+ paths[id] = path;
63
+ container.children = [
64
+ ...path,
65
+ ...children.map((node) => node.id).filter((nodeId) => !path.includes(nodeId) && !exits.includes(nodeId)),
66
+ ...exits.filter((nodeId) => !path.includes(nodeId))
67
+ ].map((nodeId) => children.find((node) => node.id === nodeId));
68
+ container.layoutOptions = {
69
+ ...path.length > 1 && option(container, "layered.cycleBreaking.strategy") === void 0 ? { "elk.layered.cycleBreaking.strategy": "MODEL_ORDER" } : {},
70
+ ...path.length > 1 && option(container, "layered.feedbackEdges") === void 0 ? { "elk.layered.feedbackEdges": true } : {},
71
+ ...container.layoutOptions,
72
+ ...scope.direction ? { direction: scope.direction } : {}
73
+ };
74
+ }
75
+ return {
76
+ graph,
77
+ paths,
78
+ commonExits
79
+ };
80
+ }
81
+ const intersects = (a, b) => a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height;
82
+ const cross = (a, b, c) => (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
83
+ /** Diagnostic objective, not a proof of geometric validity. Coordinates are container-relative. */
84
+ function scoreStatechartLayout(graph, paths = {}) {
85
+ const score = {
86
+ invalid: 0,
87
+ overlaps: 0,
88
+ pathOrder: 0,
89
+ crossings: 0,
90
+ bends: 0,
91
+ routeLength: 0
92
+ };
93
+ const segments = [];
94
+ const boxes = [];
95
+ const rect = (shape, x, y) => {
96
+ if ([
97
+ shape.x,
98
+ shape.y,
99
+ shape.width,
100
+ shape.height
101
+ ].some((value) => value === void 0 || !Number.isFinite(value)) || (shape.width ?? 0) < 0 || (shape.height ?? 0) < 0) score.invalid++;
102
+ return {
103
+ x: x + (shape.x ?? 0),
104
+ y: y + (shape.y ?? 0),
105
+ width: shape.width ?? 0,
106
+ height: shape.height ?? 0
107
+ };
108
+ };
109
+ const visit = (node, x, y, ancestors) => {
110
+ const direction = String(option(node, "direction") ?? "RIGHT").toUpperCase();
111
+ const horizontal = direction === "RIGHT" || direction === "LEFT";
112
+ const sign = direction === "LEFT" || direction === "UP" ? -1 : 1;
113
+ const path = paths[String(node.id)] ?? [];
114
+ for (let i = 1; i < path.length; i++) {
115
+ const a = node.children?.find((child) => child.id === path[i - 1]);
116
+ const b = node.children?.find((child) => child.id === path[i]);
117
+ if (!a || !b || sign * (horizontal ? b.x - a.x : b.y - a.y) <= 0) score.pathOrder++;
118
+ }
119
+ for (const child of node.children ?? []) {
120
+ if (String(option(child, "noLayout")).toLowerCase() === "true") continue;
121
+ const box = rect(child, x, y);
122
+ if ((child.x ?? 0) < 0 || (child.y ?? 0) < 0 || (child.x ?? 0) + (child.width ?? 0) > (node.width ?? Infinity) + .001 || (child.y ?? 0) + (child.height ?? 0) > (node.height ?? Infinity) + .001) score.invalid++;
123
+ boxes.push({
124
+ rect: box,
125
+ ancestors,
126
+ node: child
127
+ });
128
+ visit(child, box.x, box.y, [...ancestors, child]);
129
+ }
130
+ for (const edge of node.edges ?? []) {
131
+ if (String(option(edge, "noLayout")).toLowerCase() === "true") continue;
132
+ if (!edge.sections?.length) score.invalid++;
133
+ for (const label of edge.labels ?? []) {
134
+ if (String(option(label, "noLayout")).toLowerCase() === "true") continue;
135
+ boxes.push({
136
+ rect: rect(label, x, y),
137
+ ancestors
138
+ });
139
+ }
140
+ for (const section of edge.sections ?? []) {
141
+ const points = [
142
+ section.startPoint,
143
+ ...section.bendPoints ?? [],
144
+ section.endPoint
145
+ ];
146
+ score.bends += section.bendPoints?.length ?? 0;
147
+ for (const point of points) if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) score.invalid++;
148
+ for (let i = 1; i < points.length; i++) {
149
+ const a = {
150
+ x: x + points[i - 1].x,
151
+ y: y + points[i - 1].y
152
+ };
153
+ const b = {
154
+ x: x + points[i].x,
155
+ y: y + points[i].y
156
+ };
157
+ score.routeLength += Math.hypot(b.x - a.x, b.y - a.y);
158
+ segments.push({
159
+ a,
160
+ b,
161
+ edge
162
+ });
163
+ }
164
+ }
165
+ }
166
+ };
167
+ visit(graph, 0, 0, [graph]);
168
+ for (let i = 0; i < boxes.length; i++) for (let j = i + 1; j < boxes.length; j++) {
169
+ const a = boxes[i], b = boxes[j];
170
+ if (a.node && b.ancestors.includes(a.node) || b.node && a.ancestors.includes(b.node)) continue;
171
+ if (intersects(a.rect, b.rect)) score.overlaps++;
172
+ }
173
+ for (let i = 0; i < segments.length; i++) for (let j = i + 1; j < segments.length; j++) {
174
+ const a = segments[i], b = segments[j];
175
+ if (a.edge === b.edge) continue;
176
+ if (cross(a.a, a.b, b.a) * cross(a.a, a.b, b.b) < 0 && cross(b.a, b.b, a.a) * cross(b.a, b.b, a.b) < 0) score.crossings++;
177
+ }
178
+ if (!Number.isFinite(score.routeLength)) score.routeLength = Number.MAX_VALUE;
179
+ return score;
180
+ }
181
+ const objectives = [
182
+ "invalid",
183
+ "overlaps",
184
+ "pathOrder",
185
+ "crossings",
186
+ "bends",
187
+ "routeLength"
188
+ ];
189
+ function better(a, b) {
190
+ for (const key of objectives) if (a[key] !== b[key]) return a[key] < b[key];
191
+ return false;
192
+ }
193
+ /** Each attempt starts from original input. No post-layout geometry edits. */
194
+ async function layoutStatechart(input, options) {
195
+ const maxAttempts = options.maxAttempts ?? 3;
196
+ if (!Number.isInteger(maxAttempts) || maxAttempts < 1 || maxAttempts > 3) throw new RangeError("maxAttempts must be an integer from 1 to 3");
197
+ const plan = compileStatechartLayout(input, options.scopes);
198
+ const attempts = [];
199
+ let selected;
200
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
201
+ const candidate = structuredClone(attempt === 0 ? input : plan.graph);
202
+ const configure = (node) => {
203
+ const scope = Object.hasOwn(options.scopes, String(node.id)) ? options.scopes[String(node.id)] : void 0;
204
+ if (scope?.direction) node.layoutOptions = {
205
+ ...node.layoutOptions,
206
+ direction: scope.direction
207
+ };
208
+ if (attempt === 2 && scope) node.layoutOptions = {
209
+ ...node.layoutOptions,
210
+ "spacing.nodeNode": Math.max(40, Number(option(node, "spacing.nodeNode") ?? 20) * 1.5),
211
+ "layered.spacing.nodeNodeBetweenLayers": Math.max(60, Number(option(node, "layered.spacing.nodeNodeBetweenLayers") ?? 20) * 1.5)
212
+ };
213
+ if (attempt === 2 && scope) {
214
+ const groups = /* @__PURE__ */ new Map();
215
+ for (const edge of node.edges ?? []) {
216
+ if (!edge.labels?.length) continue;
217
+ const key = JSON.stringify([endpoint$1(edge, true), endpoint$1(edge, false)]);
218
+ const group = groups.get(key) ?? [];
219
+ group.push(edge);
220
+ groups.set(key, group);
221
+ }
222
+ for (const group of groups.values()) for (let i = 1; i < Math.min(group.length, 3); i++) {
223
+ const edge = group[i];
224
+ if (option(edge, "edgeLabels.placement") === void 0 && edge.labels.every((label) => option(label, "edgeLabels.placement") === void 0)) {
225
+ const placement = i === 1 ? "HEAD" : "TAIL";
226
+ edge.layoutOptions = {
227
+ ...edge.layoutOptions,
228
+ "elk.edgeLabels.placement": placement
229
+ };
230
+ edge.labels = edge.labels.map((label) => ({
231
+ ...label,
232
+ layoutOptions: {
233
+ ...label.layoutOptions,
234
+ "elk.edgeLabels.placement": placement
235
+ }
236
+ }));
237
+ }
238
+ }
239
+ }
240
+ node.children?.forEach(configure);
241
+ };
242
+ configure(candidate);
243
+ const graph = await new ELK().layout(candidate);
244
+ const score = scoreStatechartLayout(graph, plan.paths);
245
+ attempts.push({
246
+ kind: attempt === 0 ? "baseline" : attempt === 1 ? "policy" : "spacing",
247
+ score
248
+ });
249
+ if (!selected || better(score, selected.score)) selected = {
250
+ graph,
251
+ score,
252
+ attempt
253
+ };
254
+ }
255
+ return {
256
+ ...selected,
257
+ attempts,
258
+ paths: plan.paths,
259
+ commonExits: plan.commonExits
260
+ };
261
+ }
262
+
263
+ //#endregion
5
264
  //#region src/elkjs/index.ts
6
265
  function isLayoutEdgeLabel(label) {
7
266
  return getBooleanOption(label.layoutOptions ?? {}, "noLayout") !== true && (Boolean(label.text) || label.width !== void 0 || label.height !== void 0);
@@ -344,6 +603,7 @@ var ELK = class {
344
603
  const graph_ = toGraph(graph, layoutOptions);
345
604
  const layerConstraintByNodeId = new Map((graph.children ?? []).map((node) => [String(node.id), String(getOption(node.layoutOptions ?? {}, "layered.layering.layerConstraint") ?? getOption(node.layoutOptions ?? {}, "layerConstraint") ?? "NONE")]));
346
605
  if (algorithm === "layered" && graph_.edges.some((edge) => {
606
+ if (edge.sourceId === edge.targetId) return false;
347
607
  const sourceConstraint = layerConstraintByNodeId.get(edge.sourceId);
348
608
  const targetConstraint = layerConstraintByNodeId.get(edge.targetId);
349
609
  return (sourceConstraint === "FIRST" || sourceConstraint === "FIRST_SEPARATE") && (targetConstraint === "FIRST" || targetConstraint === "FIRST_SEPARATE");
@@ -408,7 +668,7 @@ var ELK = class {
408
668
  if (hierarchyRestorations.length > 0) {
409
669
  const direction = getDirection(layoutOptions);
410
670
  const horizontal = direction === "right" || direction === "left";
411
- const cross = (point) => horizontal ? point.y : point.x;
671
+ const cross$1 = (point) => horizontal ? point.y : point.x;
412
672
  const nodeSpacing = getNumberOption(layoutOptions, "spacing.nodeNode") ?? 20;
413
673
  const shiftsByOutsideId = /* @__PURE__ */ new Map();
414
674
  for (const restoration of hierarchyRestorations) {
@@ -418,7 +678,7 @@ var ELK = class {
418
678
  const originalTargetId = String(restoration.targets?.[0] ?? restoration.target);
419
679
  const sourceInside = !laidOut.nodes.some((node) => node.id === originalSourceId);
420
680
  const outsideId = sourceInside ? originalTargetId : originalSourceId;
421
- const delta = sourceInside ? cross(route[0]) - cross(route.at(-1)) : cross(route.at(-1)) - cross(route[0]);
681
+ const delta = sourceInside ? cross$1(route[0]) - cross$1(route.at(-1)) : cross$1(route.at(-1)) - cross$1(route[0]);
422
682
  const candidates = shiftsByOutsideId.get(outsideId) ?? [];
423
683
  candidates.push(delta);
424
684
  shiftsByOutsideId.set(outsideId, candidates);
@@ -468,11 +728,13 @@ var ELK = class {
468
728
  }
469
729
  const edgeNodeSpacing = getNumberOption(layoutOptions, "spacing.edgeNodeBetweenLayers") ?? 10;
470
730
  for (const restoration of hierarchyRestorations) {
471
- const route = laidOut.edges.find((edge) => edge.id === String(restoration.edge.id))?.points;
731
+ const nativeEdge = laidOut.edges.find((edge) => edge.id === String(restoration.edge.id));
732
+ const route = nativeEdge?.points;
472
733
  if (!route || route.length < 2) continue;
473
734
  const start = route[0];
474
735
  const end = route.at(-1);
475
- if (Math.abs(cross(start) - cross(end)) < 1e-9) {
736
+ if (nativeEdge.sourceId === nativeEdge.targetId) continue;
737
+ if (Math.abs(cross$1(start) - cross$1(end)) < 1e-9) {
476
738
  route.splice(1, route.length - 2);
477
739
  continue;
478
740
  }
@@ -1220,4 +1482,4 @@ function placePortLabels(node, globalOptions) {
1220
1482
  }
1221
1483
 
1222
1484
  //#endregion
1223
- export { ELK as default };
1485
+ export { compileStatechartLayout, ELK as default, layoutStatechart, scoreStatechartLayout };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { A as minimizeCrossingsWithBarycenter, B as LayoutError, C as breakCyclesGreedilyByModelOrder, D as breakCyclesWithModelOrderDepthFirstSearch, E as breakCyclesWithModelOrderBreadthFirstSearch, I as routeEdgesOrthogonally, L as routeEdgesWithPolylines, M as minimizeCrossingsWithModelOrder, N as placeNodesInLayers, P as placeNodesInteractively, R as routeEdgesWithSplines, S as breakCyclesGreedily, T as breakCyclesWithDepthFirstSearch, V as UnsupportedLayoutError, _ as assignLayersInteractively, a as elkLayeredEnumValues, b as breakCyclesByStronglyConnectedConnectivity, d as assignLayersWithMinWidth, f as assignLayersWithNetworkSimplex, g as assignLayersByLongestPathToSink, h as assignLayersByLongestPath, i as toElkLayeredOptions, j as minimizeCrossingsWithMedian, k as minimizeCrossingsInteractively, m as assignLayersByDepthFirstModelOrder, n as layeredAlgorithm, o as elkLayeredOptionDefinitions, p as assignLayersByBreadthFirstModelOrder, r as fromElkLayeredOptionId, t as getLayeredLayout, u as assignLayersWithStretchWidth, v as assignLayersWithCoffmanGraham, w as breakCyclesInteractively, x as breakCyclesByStronglyConnectedNodeType, y as breakCyclesByModelOrder } from "./layered-BYhTymAk.mjs";
2
- import { a as getRandomLayout, c as rectanglePackingAlgorithm, d as fixedAlgorithm, f as getFixedLayout, i as sporeOverlapRemovalAlgorithm, l as boxAlgorithm, n as getSporeOverlapRemovalLayout, o as randomAlgorithm, r as sporeCompactionAlgorithm, s as getRectanglePackingLayout, t as getSporeCompactionLayout, u as getBoxLayout } from "./spore-B504wOFR.mjs";
1
+ import { A as minimizeCrossingsWithBarycenter, B as LayoutError, C as breakCyclesGreedilyByModelOrder, D as breakCyclesWithModelOrderDepthFirstSearch, E as breakCyclesWithModelOrderBreadthFirstSearch, I as routeEdgesOrthogonally, L as routeEdgesWithPolylines, M as minimizeCrossingsWithModelOrder, N as placeNodesInLayers, P as placeNodesInteractively, R as routeEdgesWithSplines, S as breakCyclesGreedily, T as breakCyclesWithDepthFirstSearch, V as UnsupportedLayoutError, _ as assignLayersInteractively, a as elkLayeredEnumValues, b as breakCyclesByStronglyConnectedConnectivity, d as assignLayersWithMinWidth, f as assignLayersWithNetworkSimplex, g as assignLayersByLongestPathToSink, h as assignLayersByLongestPath, i as toElkLayeredOptions, j as minimizeCrossingsWithMedian, k as minimizeCrossingsInteractively, m as assignLayersByDepthFirstModelOrder, n as layeredAlgorithm, o as elkLayeredOptionDefinitions, p as assignLayersByBreadthFirstModelOrder, r as fromElkLayeredOptionId, t as getLayeredLayout, u as assignLayersWithStretchWidth, v as assignLayersWithCoffmanGraham, w as breakCyclesInteractively, x as breakCyclesByStronglyConnectedNodeType, y as breakCyclesByModelOrder } from "./layered-CZs9YWVx.mjs";
2
+ import { a as getRandomLayout, c as rectanglePackingAlgorithm, d as fixedAlgorithm, f as getFixedLayout, i as sporeOverlapRemovalAlgorithm, l as boxAlgorithm, n as getSporeOverlapRemovalLayout, o as randomAlgorithm, r as sporeCompactionAlgorithm, s as getRectanglePackingLayout, t as getSporeCompactionLayout, u as getBoxLayout } from "./spore-9N0W9dZn.mjs";
3
3
  import { getGraphIssues } from "@statelyai/graph";
4
4
 
5
5
  //#region src/layout.ts
@@ -1,3 +1,3 @@
1
- import { A as minimizeCrossingsWithBarycenter, C as breakCyclesGreedilyByModelOrder, D as breakCyclesWithModelOrderDepthFirstSearch, E as breakCyclesWithModelOrderBreadthFirstSearch, I as routeEdgesOrthogonally, L as routeEdgesWithPolylines, M as minimizeCrossingsWithModelOrder, N as placeNodesInLayers, P as placeNodesInteractively, R as routeEdgesWithSplines, S as breakCyclesGreedily, T as breakCyclesWithDepthFirstSearch, _ as assignLayersInteractively, a as elkLayeredEnumValues, b as breakCyclesByStronglyConnectedConnectivity, c as placeNodesWithLinearSegments, d as assignLayersWithMinWidth, f as assignLayersWithNetworkSimplex, g as assignLayersByLongestPathToSink, h as assignLayersByLongestPath, i as toElkLayeredOptions, j as minimizeCrossingsWithMedian, k as minimizeCrossingsInteractively, l as placeNodesWithBrandesKoepf, m as assignLayersByDepthFirstModelOrder, n as layeredAlgorithm, o as elkLayeredOptionDefinitions, p as assignLayersByBreadthFirstModelOrder, r as fromElkLayeredOptionId, s as placeNodesWithNetworkSimplex, t as getLayeredLayout, u as assignLayersWithStretchWidth, v as assignLayersWithCoffmanGraham, w as breakCyclesInteractively, x as breakCyclesByStronglyConnectedNodeType, y as breakCyclesByModelOrder } from "../layered-BYhTymAk.mjs";
1
+ import { A as minimizeCrossingsWithBarycenter, C as breakCyclesGreedilyByModelOrder, D as breakCyclesWithModelOrderDepthFirstSearch, E as breakCyclesWithModelOrderBreadthFirstSearch, I as routeEdgesOrthogonally, L as routeEdgesWithPolylines, M as minimizeCrossingsWithModelOrder, N as placeNodesInLayers, P as placeNodesInteractively, R as routeEdgesWithSplines, S as breakCyclesGreedily, T as breakCyclesWithDepthFirstSearch, _ as assignLayersInteractively, a as elkLayeredEnumValues, b as breakCyclesByStronglyConnectedConnectivity, c as placeNodesWithLinearSegments, d as assignLayersWithMinWidth, f as assignLayersWithNetworkSimplex, g as assignLayersByLongestPathToSink, h as assignLayersByLongestPath, i as toElkLayeredOptions, j as minimizeCrossingsWithMedian, k as minimizeCrossingsInteractively, l as placeNodesWithBrandesKoepf, m as assignLayersByDepthFirstModelOrder, n as layeredAlgorithm, o as elkLayeredOptionDefinitions, p as assignLayersByBreadthFirstModelOrder, r as fromElkLayeredOptionId, s as placeNodesWithNetworkSimplex, t as getLayeredLayout, u as assignLayersWithStretchWidth, v as assignLayersWithCoffmanGraham, w as breakCyclesInteractively, x as breakCyclesByStronglyConnectedNodeType, y as breakCyclesByModelOrder } from "../layered-CZs9YWVx.mjs";
2
2
 
3
3
  export { assignLayersByBreadthFirstModelOrder, assignLayersByDepthFirstModelOrder, assignLayersByLongestPath, assignLayersByLongestPathToSink, assignLayersInteractively, assignLayersWithCoffmanGraham, assignLayersWithMinWidth, assignLayersWithNetworkSimplex, assignLayersWithStretchWidth, breakCyclesByModelOrder, breakCyclesByStronglyConnectedConnectivity, breakCyclesByStronglyConnectedNodeType, breakCyclesGreedily, breakCyclesGreedilyByModelOrder, breakCyclesInteractively, breakCyclesWithDepthFirstSearch, breakCyclesWithModelOrderBreadthFirstSearch, breakCyclesWithModelOrderDepthFirstSearch, elkLayeredEnumValues, elkLayeredOptionDefinitions, fromElkLayeredOptionId, getLayeredLayout, layeredAlgorithm, minimizeCrossingsInteractively, minimizeCrossingsWithBarycenter, minimizeCrossingsWithMedian, minimizeCrossingsWithModelOrder, placeNodesInLayers, placeNodesInteractively, placeNodesWithBrandesKoepf, placeNodesWithLinearSegments, placeNodesWithNetworkSimplex, routeEdgesOrthogonally, routeEdgesWithPolylines, routeEdgesWithSplines, toElkLayeredOptions };