@statelyai/layout 0.4.3 → 0.5.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.
Files changed (55) hide show
  1. package/README.md +32 -3
  2. package/dist/elkjs/index.cjs +2 -2
  3. package/dist/elkjs/index.d.cts +1 -1
  4. package/dist/elkjs/index.d.mts +1 -1
  5. package/dist/elkjs/index.mjs +2 -2
  6. package/dist/elkjs/main.cjs +1 -1
  7. package/dist/elkjs/main.mjs +1 -1
  8. package/dist/elkjs/worker.cjs +2 -2
  9. package/dist/elkjs/worker.mjs +2 -2
  10. package/dist/{elkjs-B5kN_zS6.mjs → elkjs-DBkalvt1.mjs} +3 -3
  11. package/dist/{elkjs-Cj-lWiK1.cjs → elkjs-DonMqGjf.cjs} +3 -3
  12. package/dist/{index-B6cWNrMw.d.cts → index-0YVSvMvA.d.mts} +13 -3
  13. package/dist/{index-CJQLUKD9.d.mts → index-C0J4ttZe.d.cts} +13 -3
  14. package/dist/{index-DT6lPMfS.d.cts → index-Xc4R6y3z.d.cts} +9 -2
  15. package/dist/{index-F1U-fCTu.d.mts → index-lSp0oCJC.d.mts} +9 -2
  16. package/dist/index.cjs +7 -4
  17. package/dist/index.d.cts +4 -4
  18. package/dist/index.d.mts +4 -4
  19. package/dist/index.mjs +4 -4
  20. package/dist/layered/index.cjs +1 -1
  21. package/dist/layered/index.d.cts +2 -2
  22. package/dist/layered/index.d.mts +2 -2
  23. package/dist/layered/index.mjs +1 -1
  24. package/dist/{layered-BsAdm_u8.mjs → layered-CmL7oynw.mjs} +245 -69
  25. package/dist/{layered-BJu8A21s.cjs → layered-SB2mlAqt.cjs} +245 -69
  26. package/dist/{layout-engine-DnlmGxHL.mjs → layout-engine-BXoIpYL4.mjs} +1 -1
  27. package/dist/{layout-engine-BFP1TZbF.cjs → layout-engine-CAyJ-I-u.cjs} +1 -1
  28. package/dist/routing/index.cjs +5 -2
  29. package/dist/routing/index.d.cts +3 -3
  30. package/dist/routing/index.d.mts +3 -3
  31. package/dist/routing/index.mjs +2 -2
  32. package/dist/routing-D-LfMXOF.mjs +5189 -0
  33. package/dist/routing-Phxu1R0x.cjs +5423 -0
  34. package/dist/{types-CT2akdK0.d.mts → types-D8pYSn8I.d.cts} +112 -2
  35. package/dist/{types-uxPlGRof.d.cts → types-MAUtJfKQ.d.mts} +112 -2
  36. package/package.json +4 -1
  37. package/src/authoring/partial.ts +1 -7
  38. package/src/authoring/routing.ts +64 -19
  39. package/src/layered/feedback-chains.ts +22 -4
  40. package/src/layered/index.ts +173 -41
  41. package/src/layered/north-south-ports.ts +17 -4
  42. package/src/layered/strategies.ts +143 -15
  43. package/src/routing/algorithms.ts +1436 -148
  44. package/src/routing/bezier-fit.ts +605 -0
  45. package/src/routing/bezier-visibility.ts +107 -0
  46. package/src/routing/bezier.ts +596 -0
  47. package/src/routing/engine.ts +65 -13
  48. package/src/routing/index.ts +14 -0
  49. package/src/routing/model.ts +185 -1
  50. package/src/routing/path.ts +1 -1
  51. package/src/routing/policy-geometry.ts +536 -0
  52. package/src/routing/search.ts +10 -2
  53. package/src/routing/types.ts +77 -1
  54. package/dist/routing-CR8flv8b.mjs +0 -2780
  55. package/dist/routing-QIdGGFBe.cjs +0 -2996
@@ -1,4 +1,4 @@
1
- const require_routing = require('./routing-QIdGGFBe.cjs');
1
+ const require_routing = require('./routing-Phxu1R0x.cjs');
2
2
  let _statelyai_graph_layout = require("@statelyai/graph/layout");
3
3
  let _statelyai_graph = require("@statelyai/graph");
4
4
 
@@ -3719,6 +3719,19 @@ function assertNorthSouthPortSides(graph) {
3719
3719
  //#region src/layered/strategies.ts
3720
3720
  const modelSweepInputs = /* @__PURE__ */ new WeakSet();
3721
3721
  const nodeRelativePortRanksByInput = /* @__PURE__ */ new WeakMap();
3722
+ const labelPortSideFeedbackByInput = /* @__PURE__ */ new WeakMap();
3723
+ /**
3724
+ * @internal Collect the feedback segments routed to a center-label dummy's port
3725
+ * sides. Exempt segments keep the plain feedback detour instead.
3726
+ */
3727
+ function trackLabelPortSideFeedback(input, exempt) {
3728
+ const routed = /* @__PURE__ */ new Set();
3729
+ labelPortSideFeedbackByInput.set(input, {
3730
+ exempt,
3731
+ routed
3732
+ });
3733
+ return routed;
3734
+ }
3722
3735
  function getOrientedEndpoints(edge, orientation) {
3723
3736
  return orientation.reversedEdgeIds.has(edge.id) ? [edge.targetId, edge.sourceId] : [edge.sourceId, edge.targetId];
3724
3737
  }
@@ -4923,7 +4936,7 @@ const assignLayersWithCoffmanGraham = (input, orientation) => {
4923
4936
  seedOrder: [...layerMembers].reverse().flat()
4924
4937
  };
4925
4938
  };
4926
- function sortLayerByAdjacentPosition(layer, ranksByNodeId, statistic, random, preOrdered = true, sourceUnknownPlacement = true, perturbSummedWeight = true, units, sameLayerNeighbors = /* @__PURE__ */ new Map(), orderedVisits, forcedCompare) {
4939
+ function sortLayerByAdjacentPosition(layer, ranksByNodeId, statistic, random, preOrdered = true, sourceUnknownPlacement = true, perturbSummedWeight = true, units, sameLayerNeighbors = /* @__PURE__ */ new Map(), orderedVisits, forcedCompare, forcedTies) {
4927
4940
  const originalIndex = new Map(layer.map((nodeId, index) => [nodeId, index]));
4928
4941
  const adjacentPosition = /* @__PURE__ */ new Map();
4929
4942
  if (units && statistic === "mean") for (const [id, score] of associatedBarycenters(layer, ranksByNodeId, sameLayerNeighbors, units.associates, random, orderedVisits)) adjacentPosition.set(id, score);
@@ -4959,6 +4972,7 @@ function sortLayerByAdjacentPosition(layer, ranksByNodeId, statistic, random, pr
4959
4972
  }
4960
4973
  else for (const nodeId of layer) if (adjacentPosition.get(nodeId) === void 0) adjacentPosition.set(nodeId, originalIndex.get(nodeId) ?? 0);
4961
4974
  const compare = (a, b) => {
4975
+ if (forcedTies?.has(a) || forcedTies?.has(b)) return 0;
4962
4976
  return forcedCompare?.(a, b) || (adjacentPosition.get(a) ?? 0) - (adjacentPosition.get(b) ?? 0) || (originalIndex.get(a) ?? 0) - (originalIndex.get(b) ?? 0);
4963
4977
  };
4964
4978
  if (forcedCompare) insertionSort(layer, transitiveComparator((id) => id, compare));
@@ -5110,6 +5124,10 @@ function createLayerSweepSession(input, orientation, assignment, statistic = "me
5110
5124
  let initialOrderAttempt = usesInitialModelOrder;
5111
5125
  const sourceUnknownPlacement = true;
5112
5126
  const forcedCompare = usesInitialModelOrder && input.settings["crossingMinimization.forceNodeModelOrder"] === true ? normalModelComparator(input) : void 0;
5127
+ const forcedTies = forcedCompare ? new Set(input.graph.nodes.filter((node) => {
5128
+ const constraint = input.nodeSettings?.(node)?.["layering.layerConstraint"];
5129
+ return constraint === "FIRST_SEPARATE" || constraint === "LAST_SEPARATE";
5130
+ }).map((node) => node.id)) : void 0;
5113
5131
  const medianWeights = /* @__PURE__ */ new Map();
5114
5132
  const listedEdgeIds = /* @__PURE__ */ new Map();
5115
5133
  const listedEdgeId = (edgeId) => {
@@ -5251,7 +5269,7 @@ function createLayerSweepSession(input, orientation, assignment, statistic = "me
5251
5269
  const shuffleFirstLayer = (forward) => {
5252
5270
  const firstLayerIndex = forward ? 0 : Math.max(0, working.length - 1);
5253
5271
  const firstLayerWeights = new Map((working[firstLayerIndex] ?? []).map((id) => [id, random.nextDouble()]));
5254
- const compare = (left, right) => forcedCompare?.(left, right) || (firstLayerWeights.get(left) ?? 0) - (firstLayerWeights.get(right) ?? 0);
5272
+ const compare = (left, right) => forcedTies?.has(left) || forcedTies?.has(right) ? 0 : forcedCompare?.(left, right) || (firstLayerWeights.get(left) ?? 0) - (firstLayerWeights.get(right) ?? 0);
5255
5273
  const first = working[firstLayerIndex];
5256
5274
  if (first) if (forcedCompare) insertionSort(first, transitiveComparator((id) => id, compare));
5257
5275
  else first.sort(compare);
@@ -5347,7 +5365,7 @@ function createLayerSweepSession(input, orientation, assignment, statistic = "me
5347
5365
  if (statistic === "median") sortWithMedianWeights(current, previous);
5348
5366
  else {
5349
5367
  const adjacent = adjacentRanks(previous, current, true);
5350
- sortLayerByAdjacentPosition(current, adjacent.ranks, statistic, random, !firstSweep || initialOrderAttempt || canonicalNodes.get(current[0] ?? "")?.type === "EXTERNAL_PORT", sourceUnknownPlacement, true, units, sameLayerNeighbors(isForward), adjacent.visits, forcedCompare);
5368
+ sortLayerByAdjacentPosition(current, adjacent.ranks, statistic, random, !firstSweep || initialOrderAttempt || canonicalNodes.get(current[0] ?? "")?.type === "EXTERNAL_PORT", sourceUnknownPlacement, true, units, sameLayerNeighbors(isForward), adjacent.visits, forcedCompare, forcedTies);
5351
5369
  }
5352
5370
  groupMixedPortDirections(current, previous, working[layer + 1]);
5353
5371
  if (exactPortSweep) distributePorts(layer, true);
@@ -5361,7 +5379,7 @@ function createLayerSweepSession(input, orientation, assignment, statistic = "me
5361
5379
  if (statistic === "median") sortWithMedianWeights(current, next);
5362
5380
  else {
5363
5381
  const adjacent = adjacentRanks(next, current, false);
5364
- sortLayerByAdjacentPosition(current, adjacent.ranks, statistic, random, !firstSweep || initialOrderAttempt || canonicalNodes.get(current[0] ?? "")?.type === "EXTERNAL_PORT", sourceUnknownPlacement, true, units, sameLayerNeighbors(isForward), adjacent.visits, forcedCompare);
5382
+ sortLayerByAdjacentPosition(current, adjacent.ranks, statistic, random, !firstSweep || initialOrderAttempt || canonicalNodes.get(current[0] ?? "")?.type === "EXTERNAL_PORT", sourceUnknownPlacement, true, units, sameLayerNeighbors(isForward), adjacent.visits, forcedCompare, forcedTies);
5365
5383
  }
5366
5384
  groupMixedPortDirections(current, next, working[layer - 1]);
5367
5385
  if (exactPortSweep) distributePorts(layer, false);
@@ -7381,6 +7399,17 @@ function routeEdges(style) {
7381
7399
  };
7382
7400
  const start$1 = fixedSideFeedback ? getPortPoint(source, edge.sourcePort, sourceRect, sourceFallback$1, input.direction, input) : sourceFallback$1;
7383
7401
  const end$1 = fixedSideFeedback ? getPortPoint(target, edge.targetPort, targetRect, targetFallback$1, input.direction, input) : targetFallback$1;
7402
+ const [forwardSide, backwardSide] = {
7403
+ right: ["EAST", "WEST"],
7404
+ left: ["WEST", "EAST"],
7405
+ down: ["SOUTH", "NORTH"],
7406
+ up: ["NORTH", "SOUTH"]
7407
+ }[input.direction];
7408
+ const labelPortSides = labelPortSideFeedbackByInput.get(input);
7409
+ const faces = (node, side, away) => !fixedSideFeedback && !labelPortSides?.exempt.has(edge.id) && node.id.startsWith("__layout_dummy:label:") && side === away;
7410
+ const sourceFace = faces(source, feedbackSourcePortSide, backwardSide) ? -1 : 1;
7411
+ const targetFace = faces(target, feedbackTargetPortSide, forwardSide) ? -1 : 1;
7412
+ if (sourceFace < 0 || targetFace < 0) labelPortSides?.routed.add(edge.id);
7384
7413
  if (horizontal$1) {
7385
7414
  const sign = fixedSideFeedback ? Math.sign(sourceRect.x - targetRect.x) || 1 : reverse ? -1 : 1;
7386
7415
  const outerCross = Math.max(...[...placement.rectByNodeId.values()].map((rect) => rect.y + rect.height)) + crossSpacing + (fixedSideFeedback ? .5 : 0);
@@ -7388,11 +7417,11 @@ function routeEdges(style) {
7388
7417
  pointsByEdgeId.set(edge.id, [
7389
7418
  start$1,
7390
7419
  {
7391
- x: start$1.x + sign * flowSpacing,
7420
+ x: start$1.x + sourceFace * sign * flowSpacing,
7392
7421
  y: start$1.y
7393
7422
  },
7394
7423
  {
7395
- x: start$1.x + sign * flowSpacing,
7424
+ x: start$1.x + sourceFace * sign * flowSpacing,
7396
7425
  y: outerCross
7397
7426
  },
7398
7427
  ...preserveCenters ? [{
@@ -7403,11 +7432,11 @@ function routeEdges(style) {
7403
7432
  y: outerCross
7404
7433
  }] : [],
7405
7434
  {
7406
- x: end$1.x - sign * flowSpacing,
7435
+ x: end$1.x - targetFace * sign * flowSpacing,
7407
7436
  y: outerCross
7408
7437
  },
7409
7438
  {
7410
- x: end$1.x - sign * flowSpacing,
7439
+ x: end$1.x - targetFace * sign * flowSpacing,
7411
7440
  y: end$1.y
7412
7441
  },
7413
7442
  end$1
@@ -7420,11 +7449,11 @@ function routeEdges(style) {
7420
7449
  start$1,
7421
7450
  {
7422
7451
  x: start$1.x,
7423
- y: start$1.y + sign * flowSpacing
7452
+ y: start$1.y + sourceFace * sign * flowSpacing
7424
7453
  },
7425
7454
  {
7426
7455
  x: outerCross,
7427
- y: start$1.y + sign * flowSpacing
7456
+ y: start$1.y + sourceFace * sign * flowSpacing
7428
7457
  },
7429
7458
  ...preserveCenters ? [{
7430
7459
  x: outerCross,
@@ -7435,11 +7464,11 @@ function routeEdges(style) {
7435
7464
  }] : [],
7436
7465
  {
7437
7466
  x: outerCross,
7438
- y: end$1.y - sign * flowSpacing
7467
+ y: end$1.y - targetFace * sign * flowSpacing
7439
7468
  },
7440
7469
  {
7441
7470
  x: end$1.x,
7442
- y: end$1.y - sign * flowSpacing
7471
+ y: end$1.y - targetFace * sign * flowSpacing
7443
7472
  },
7444
7473
  end$1
7445
7474
  ]);
@@ -7924,6 +7953,55 @@ function routeEdges(style) {
7924
7953
  const routeEdgesOrthogonally = routeEdges("ORTHOGONAL");
7925
7954
  const routeEdgesWithPolylines = routeEdges("POLYLINE");
7926
7955
  const routeEdgesWithSplines = routeEdges("SPLINES");
7956
+ const sweptPortRanks = /* @__PURE__ */ new WeakMap();
7957
+ /**
7958
+ * Order movable ports along each physical side as crossing minimization left
7959
+ * them, as ELK places ports from its swept port lists. The lists are
7960
+ * clockwise per canonical side.
7961
+ */
7962
+ function recordSweptPortOrder(graph, direction, order) {
7963
+ const connected = new Set(graph.edges.flatMap((edge) => [JSON.stringify([edge.sourceId, edge.sourcePort]), JSON.stringify([edge.targetId, edge.targetPort])]));
7964
+ const vertical$1 = direction === "down" || direction === "up";
7965
+ const reverse = direction === "up" || direction === "left";
7966
+ const canonical = direction === "right" ? {
7967
+ NORTH: "NORTH",
7968
+ EAST: "EAST",
7969
+ SOUTH: "SOUTH",
7970
+ WEST: "WEST"
7971
+ } : direction === "left" ? {
7972
+ NORTH: "NORTH",
7973
+ EAST: "WEST",
7974
+ SOUTH: "SOUTH",
7975
+ WEST: "EAST"
7976
+ } : direction === "down" ? {
7977
+ NORTH: "WEST",
7978
+ EAST: "SOUTH",
7979
+ SOUTH: "EAST",
7980
+ WEST: "NORTH"
7981
+ } : {
7982
+ NORTH: "EAST",
7983
+ EAST: "SOUTH",
7984
+ SOUTH: "WEST",
7985
+ WEST: "NORTH"
7986
+ };
7987
+ for (const node of graph.nodes) {
7988
+ if (!node.ports) continue;
7989
+ const swept = order.physicalPortOrderByNodeId?.get(node.id);
7990
+ if (!swept) {
7991
+ sweptPortRanks.delete(node.ports);
7992
+ continue;
7993
+ }
7994
+ const index = new Map(swept.flatMap((id, i) => connected.has(id) ? [[id, i]] : []));
7995
+ const rankByPort = new Map(node.ports.map((port) => [port, index.get(JSON.stringify([node.id, port.name]))]));
7996
+ sweptPortRanks.set(node.ports, (port, side) => {
7997
+ const rank = rankByPort.get(port);
7998
+ if (rank === void 0) return void 0;
7999
+ const alongFlow = (side === "NORTH" || side === "SOUTH") !== vertical$1;
8000
+ const c$1 = canonical[side];
8001
+ return (alongFlow ? (c$1 === "NORTH" ? 1 : -1) * (reverse ? -1 : 1) : c$1 === "EAST" ? 1 : -1) * rank;
8002
+ });
8003
+ }
8004
+ }
7927
8005
  function placePorts(ports, rect, direction, portSettings, nodeSettings, portDirection) {
7928
8006
  if (!ports) return void 0;
7929
8007
  const horizontal$1 = direction === "left" || direction === "right";
@@ -7950,9 +8028,12 @@ function placePorts(ports, rect, direction, portSettings, nodeSettings, portDire
7950
8028
  group.push(port);
7951
8029
  grouped.set(side, group);
7952
8030
  }
8031
+ const swept = constraints === "FIXED_ORDER" || constraints === "FIXED_POS" || constraints === "FIXED_RATIO" ? void 0 : sweptPortRanks.get(ports);
7953
8032
  for (const group of grouped.values()) {
7954
- group.sort((left, right) => Number(portSettings?.(left)?.["port.index"] ?? ports.indexOf(left)) - Number(portSettings?.(right)?.["port.index"] ?? ports.indexOf(right)));
7955
8033
  const side = sideByPort.get(group[0]);
8034
+ const ranks = swept && group.map((port) => swept(port, side));
8035
+ const ranked = ranks?.every((rank) => rank !== void 0) && group.every((port) => portSettings?.(port)?.["port.index"] === void 0) ? new Map(group.map((port, i) => [port, ranks[i]])) : void 0;
8036
+ group.sort((left, right) => ranked ? ranked.get(left) - ranked.get(right) : Number(portSettings?.(left)?.["port.index"] ?? ports.indexOf(left)) - Number(portSettings?.(right)?.["port.index"] ?? ports.indexOf(right)));
7956
8037
  if (constraints === "FIXED_ORDER" && (side === "SOUTH" || side === "WEST")) group.reverse();
7957
8038
  }
7958
8039
  return ports.map((port) => {
@@ -12767,13 +12848,7 @@ function runPartialLayout(input, options, context, arrange, phase = "selection")
12767
12848
  if (routeAllowed) {
12768
12849
  if (options.settings?.edgeRouting === "SPLINES" || options.strategies?.routeEdges) throw new require_routing.UnsupportedLayoutError("Partial layout supports its built-in orthogonal router only");
12769
12850
  const ancestorIds = new Set([...ancestors(source.id), ...ancestors(target.id)]);
12770
- const nodeObstacles = graph.nodes.filter((n) => !ancestorIds.has(n.id)).map((n) => n.id === source.id || n.id === target.id ? n : {
12771
- ...n,
12772
- x: n.x - 1,
12773
- y: n.y - 1,
12774
- width: n.width + 2,
12775
- height: n.height + 2
12776
- });
12851
+ const nodeObstacles = graph.nodes.filter((n) => !ancestorIds.has(n.id));
12777
12852
  const labelObstacles = [...edgeById.values()].filter((e) => e.id !== edge.id && e.width > 0 && e.height > 0);
12778
12853
  const required = waypoints.filter((c$1) => (c$1.strength ?? "required") === "required");
12779
12854
  const accepted = new Set(required.map((c$1) => c$1.id));
@@ -13803,7 +13878,7 @@ function switchCenterLabelDummies(expansion, labels, order) {
13803
13878
  //#endregion
13804
13879
  //#region src/layered/north-south-ports.ts
13805
13880
  /** Detach fixed cross-axis ports into same-layer units before crossing minimization. */
13806
- function insertNorthSouthPortDummies(expansion) {
13881
+ function insertNorthSouthPortDummies(expansion, sortedPorts) {
13807
13882
  const { input, orientation } = expansion;
13808
13883
  const vertical$1 = input.direction === "down" || input.direction === "up";
13809
13884
  const forward = input.direction === "right" ? "EAST" : input.direction === "left" ? "WEST" : input.direction === "down" ? "SOUTH" : "NORTH";
@@ -13914,13 +13989,16 @@ function insertNorthSouthPortDummies(expansion) {
13914
13989
  for (const node of nodes) if (origins.has(node.id)) node.ports?.sort((a, b) => Number(a.name === "output") - Number(b.name === "output"));
13915
13990
  const roleOrder = (origin) => origin.input && origin.output ? 2 : origin.input ? 0 : 1;
13916
13991
  const negativeFlow = input.direction === "left" || input.direction === "up";
13992
+ const modelOrder = (input.settings["considerModelOrder.strategy"] ?? "NONE") !== "NONE";
13917
13993
  const orderedOrigins = input.graph.nodes.flatMap((node) => {
13918
13994
  const entries = [...origins].filter(([, origin]) => origin.node.id === node.id);
13919
13995
  const constraints = input.nodeSettings?.(node)?.portConstraints;
13996
+ const sorted = sortedPorts?.get(node.id);
13920
13997
  const coordinate = (origin) => {
13921
- if (constraints === "FIXED_POS" || constraints === "FIXED_RATIO") return (vertical$1 ? origin.port.y ?? 0 : origin.port.x ?? 0) * (negativeFlow ? -1 : 1);
13922
- const index = node.ports?.indexOf(origin.port) ?? 0;
13923
- return origin.beforeOwner ? index : -index;
13998
+ const flip = modelOrder && origin.output && !origin.input ? -1 : 1;
13999
+ if (constraints === "FIXED_POS" || constraints === "FIXED_RATIO") return (vertical$1 ? origin.port.y ?? 0 : origin.port.x ?? 0) * (negativeFlow ? -1 : 1) * flip;
14000
+ const index = sorted ? sorted.indexOf(JSON.stringify([node.id, origin.port.name])) : node.ports?.indexOf(origin.port) ?? 0;
14001
+ return (origin.beforeOwner ? index : -index) * flip;
13924
14002
  };
13925
14003
  return entries.sort(([, a], [, b]) => Number(!a.beforeOwner) - Number(!b.beforeOwner) || roleOrder(a) - roleOrder(b) || coordinate(a) - coordinate(b));
13926
14004
  });
@@ -16235,9 +16313,10 @@ function opposed(a, b) {
16235
16313
  * A reversed feedback edge split by label or inverted-port dummies is routed
16236
16314
  * one segment at a time, so each segment detours to the outer feedback track
16237
16315
  * and back to the next dummy. Rejoin the chain as one track: the label's own
16238
- * track, or the outer track with the label moved onto it, whichever is clear.
16316
+ * track, or the outer track with the label moved onto it, whichever is clear;
16317
+ * failing both, a fresh track past everything else with the label on it.
16239
16318
  */
16240
- function straightenFeedbackChains(chains, pointsByEdgeId, rectByNodeId, horizontal$1) {
16319
+ function straightenFeedbackChains(chains, pointsByEdgeId, rectByNodeId, horizontal$1, spacing) {
16241
16320
  const cross = (p) => horizontal$1 ? p.y : p.x;
16242
16321
  const flow = (p) => horizontal$1 ? p.x : p.y;
16243
16322
  const at = (f, c$1) => horizontal$1 ? {
@@ -16256,7 +16335,12 @@ function straightenFeedbackChains(chains, pointsByEdgeId, rectByNodeId, horizont
16256
16335
  const tail = points.at(-2), end = points.at(-1);
16257
16336
  const outer = Math.max(...points.map(cross));
16258
16337
  const labelRect = label && rectByNodeId.get(label.id);
16259
- for (const track of label ? [label.cross, outer] : [outer]) {
16338
+ const tracks = label ? [label.cross, outer] : [outer];
16339
+ if (labelRect) {
16340
+ const farthest = Math.max(...[...pointsByEdgeId.values()].flatMap((other) => other.map(cross)), ...[...rectByNodeId.values()].map((rect) => horizontal$1 ? rect.y + rect.height : rect.x + rect.width));
16341
+ tracks.push(farthest + spacing + label.cross - (horizontal$1 ? labelRect.y : labelRect.x));
16342
+ }
16343
+ for (const track of tracks) {
16260
16344
  const route = [
16261
16345
  start,
16262
16346
  lead,
@@ -16285,7 +16369,7 @@ function straightenFeedbackChains(chains, pointsByEdgeId, rectByNodeId, horizont
16285
16369
  }
16286
16370
  if (simple.at(-1) !== end) continue;
16287
16371
  if (simple.length >= points.length) break;
16288
- if ([...pointsByEdgeId].some(([id, other]) => id !== edgeId && opposed(simple, other))) continue;
16372
+ if ([...pointsByEdgeId].some(([id, other]) => id !== edgeId && opposed(simple, other) && !opposed(points, other))) continue;
16289
16373
  pointsByEdgeId.set(edgeId, simple);
16290
16374
  if (moved) rectByNodeId.set(label.id, moved);
16291
16375
  break;
@@ -18654,53 +18738,100 @@ function runSeparatedComponents(graph, options, context) {
18654
18738
  bottom: options.padding?.bottom ?? 12,
18655
18739
  left: options.padding?.left ?? 12
18656
18740
  };
18741
+ const direction = options.direction ?? graph.direction ?? "right";
18742
+ const drawnRects = (result) => {
18743
+ const rects = [];
18744
+ for (const node of result.nodes) {
18745
+ const x$1 = node.x ?? 0, y$1 = node.y ?? 0;
18746
+ rects.push({
18747
+ x: x$1,
18748
+ y: y$1,
18749
+ width: node.width ?? 0,
18750
+ height: node.height ?? 0
18751
+ });
18752
+ for (const port of node.ports ?? []) rects.push({
18753
+ x: x$1 + (port.x ?? 0),
18754
+ y: y$1 + (port.y ?? 0),
18755
+ width: port.width ?? 0,
18756
+ height: port.height ?? 0
18757
+ });
18758
+ }
18759
+ for (const edge of result.edges) {
18760
+ const points = edge.points ?? [];
18761
+ for (let index = 1; index < points.length; index++) {
18762
+ const from = points[index - 1], to = points[index];
18763
+ const x$1 = Math.min(from.x, to.x), y$1 = Math.min(from.y, to.y);
18764
+ rects.push({
18765
+ x: x$1,
18766
+ y: y$1,
18767
+ width: Math.max(from.x, to.x) - x$1,
18768
+ height: Math.max(from.y, to.y) - y$1
18769
+ });
18770
+ }
18771
+ if ((edge.width ?? 0) > 0 || (edge.height ?? 0) > 0) rects.push({
18772
+ x: edge.x ?? 0,
18773
+ y: edge.y ?? 0,
18774
+ width: edge.width ?? 0,
18775
+ height: edge.height ?? 0
18776
+ });
18777
+ }
18778
+ return rects;
18779
+ };
18780
+ const rows = [];
18657
18781
  let x = 0;
18782
+ for (const component of components) {
18783
+ if (x > 0 && x + component.bounds.width > maxRowWidth) x = 0;
18784
+ if (x === 0) rows.push([]);
18785
+ rows.at(-1).push({
18786
+ component,
18787
+ x
18788
+ });
18789
+ x += component.bounds.width + componentSpacing;
18790
+ }
18658
18791
  let y = 0;
18659
- let rowHeight = 0;
18660
18792
  const compactConnectedComponents = options.settings?.["compaction.connectedComponents"] === true;
18661
18793
  const placedShapes = [];
18662
18794
  const nodeResults = /* @__PURE__ */ new Map();
18663
18795
  const edgeResults = /* @__PURE__ */ new Map();
18664
18796
  const placements = [];
18665
- for (const component of components) {
18666
- if (x > 0 && x + component.bounds.width > maxRowWidth) {
18667
- x = 0;
18668
- y += rowHeight + componentSpacing;
18669
- rowHeight = 0;
18670
- }
18671
- let compactedY = y;
18672
- if (compactConnectedComponents && y > 0) {
18673
- let requiredY = 0;
18674
- for (const node of component.result.nodes) {
18675
- const localLeft = x + (node.x ?? 0) - component.bounds.left;
18676
- const localRight = localLeft + (node.width ?? 0);
18677
- const localTop = (node.y ?? 0) - component.bounds.top;
18678
- for (const placed of placedShapes) {
18679
- if (localRight <= placed.left || localLeft >= placed.right) continue;
18680
- requiredY = Math.max(requiredY, placed.bottom + componentSpacing - localTop);
18797
+ for (const row of rows) {
18798
+ const rowWidth = Math.max(...row.map((entry) => entry.x + entry.component.bounds.width));
18799
+ let rowHeight = 0;
18800
+ for (const { component, x: packedX } of row) {
18801
+ const { bounds } = component;
18802
+ const left = direction === "left" ? rowWidth - packedX - bounds.width : packedX;
18803
+ const shapes = drawnRects(component.result).map((rect) => ({
18804
+ left: left + rect.x - bounds.left,
18805
+ top: direction === "up" ? bounds.top + bounds.height - rect.y - rect.height : rect.y - bounds.top,
18806
+ width: rect.width,
18807
+ height: rect.height
18808
+ }));
18809
+ let compactedY = y;
18810
+ if (compactConnectedComponents && y > 0) {
18811
+ let requiredY = 0;
18812
+ for (const shape of shapes) for (const placed of placedShapes) {
18813
+ if (shape.left + shape.width <= placed.left || shape.left >= placed.right) continue;
18814
+ requiredY = Math.max(requiredY, placed.bottom + componentSpacing - shape.top);
18681
18815
  }
18816
+ compactedY = Math.min(y, requiredY);
18682
18817
  }
18683
- compactedY = Math.min(y, requiredY);
18818
+ for (const shape of shapes) placedShapes.push({
18819
+ left: shape.left,
18820
+ right: shape.left + shape.width,
18821
+ top: compactedY + shape.top,
18822
+ bottom: compactedY + shape.top + shape.height
18823
+ });
18824
+ placements.push({
18825
+ component,
18826
+ x: left,
18827
+ y: compactedY
18828
+ });
18829
+ rowHeight = Math.max(rowHeight, bounds.height);
18684
18830
  }
18685
- for (const node of component.result.nodes) placedShapes.push({
18686
- left: x + (node.x ?? 0) - component.bounds.left,
18687
- right: x + (node.x ?? 0) - component.bounds.left + (node.width ?? 0),
18688
- top: compactedY + (node.y ?? 0) - component.bounds.top,
18689
- bottom: compactedY + (node.y ?? 0) - component.bounds.top + (node.height ?? 0)
18690
- });
18691
- placements.push({
18692
- component,
18693
- x,
18694
- y: compactedY
18695
- });
18696
- x += component.bounds.width + componentSpacing;
18697
- rowHeight = Math.max(rowHeight, component.bounds.height);
18831
+ y += rowHeight + componentSpacing;
18698
18832
  }
18699
- const direction = options.direction ?? graph.direction ?? "right";
18700
- const packedWidth = Math.max(0, ...placements.map((p) => p.x + p.component.bounds.width));
18701
18833
  const packedHeight = Math.max(0, ...placements.map((p) => p.y + p.component.bounds.height));
18702
- for (const { component, x: packedX, y: packedY } of placements) {
18703
- const left = direction === "left" ? packedWidth - packedX - component.bounds.width : packedX;
18834
+ for (const { component, x: left, y: packedY } of placements) {
18704
18835
  const top = direction === "up" ? packedHeight - packedY - component.bounds.height : packedY;
18705
18836
  const dx = padding.left + left - component.bounds.left;
18706
18837
  const dy = padding.top + top - component.bounds.top;
@@ -18751,7 +18882,11 @@ function runLayeredPipeline(graph, options, context) {
18751
18882
  * coordinator can prepare every scope, share sweep state, then resume each
18752
18883
  * scope with its final order. The ordinary entry point drains this same pipeline.
18753
18884
  */
18754
- function* createLayeredScopePipeline(graph, options, context) {
18885
+ function* createLayeredScopePipeline(graph, options, context, fallbacks = {
18886
+ antiparallelPairs: /* @__PURE__ */ new Set(),
18887
+ feedbackSegments: /* @__PURE__ */ new Set()
18888
+ }) {
18889
+ const scopeOptions = options;
18755
18890
  if ((options.settings?.["spacing.edgeEdge"] ?? 10) < 2) options = {
18756
18891
  ...options,
18757
18892
  settings: {
@@ -18989,7 +19124,7 @@ function* createLayeredScopePipeline(graph, options, context) {
18989
19124
  }
18990
19125
  };
18991
19126
  }
18992
- const northSouth = insertNorthSouthPortDummies(expanded);
19127
+ const northSouth = insertNorthSouthPortDummies(expanded, preparedPorts);
18993
19128
  expanded = northSouth.expansion;
18994
19129
  if (prepareModelOrder) markInitialModelOrderPrepared(expanded.input, preparedPorts);
18995
19130
  const associates = /* @__PURE__ */ new Map(), unitMembers = /* @__PURE__ */ new Map();
@@ -19051,6 +19186,8 @@ function* createLayeredScopePipeline(graph, options, context) {
19051
19186
  minimize: minimizeScope,
19052
19187
  finishOrder: finishCrossingOrder
19053
19188
  };
19189
+ const crossingOrder = order;
19190
+ recordSweptPortOrder(graph, direction, order);
19054
19191
  traceLayeredPhase(() => ({
19055
19192
  kind: "crossing-order",
19056
19193
  scope: graph.id,
@@ -19295,6 +19432,7 @@ function* createLayeredScopePipeline(graph, options, context) {
19295
19432
  const edgeRouting = options.settings?.edgeRouting ?? "ORTHOGONAL";
19296
19433
  const edgeRouter = options.strategies?.routeEdges ?? (edgeRouting === "POLYLINE" ? routeEdgesWithPolylines : edgeRouting === "SPLINES" ? routeEdgesWithSplines : routeEdgesOrthogonally);
19297
19434
  if (options.strategies?.routeEdges) measure("post-compaction", () => applyPostCompaction(expanded.input, placement));
19435
+ const labelPortSideSegments = trackLabelPortSideFeedback(expanded.input, fallbacks.feedbackSegments);
19298
19436
  let expandedRoutes = measure("edge-routing", () => edgeRouter(expanded.input, expanded.orientation, placement));
19299
19437
  const restoredJunctionCounts = /* @__PURE__ */ new Map();
19300
19438
  expandedRoutes = restoreNorthSouthPortRoutes({
@@ -19342,6 +19480,7 @@ function* createLayeredScopePipeline(graph, options, context) {
19342
19480
  const outerAntiparallelLabelIds = /* @__PURE__ */ new Set();
19343
19481
  const parallelLabelPositions = /* @__PURE__ */ new Map();
19344
19482
  const postCompactionNodeCrossDeltas = /* @__PURE__ */ new Map();
19483
+ const flowOrderedPairs = /* @__PURE__ */ new Map();
19345
19484
  const horizontalAntiparallelFlow = direction === "left" || direction === "right";
19346
19485
  if (options.strategies?.routeEdges === void 0 && options.settings?.["cycleBreaking.strategy"] === "MODEL_ORDER" && options.settings?.["layering.strategy"] === "INTERACTIVE" && options.settings?.["crossingMinimization.forceNodeModelOrder"] === true && options.settings?.["nodePlacement.strategy"] === "BRANDES_KOEPF" && options.settings?.["nodePlacement.favorStraightEdges"] === true && options.settings?.["compaction.postCompaction.strategy"] === "LEFT" && options.settings?.["compaction.postCompaction.constraints"] === "SCANLINE") {
19347
19486
  const neighbors = new Map(graph.nodes.map((node) => [node.id, /* @__PURE__ */ new Set()]));
@@ -19411,6 +19550,7 @@ function* createLayeredScopePipeline(graph, options, context) {
19411
19550
  const horizontal$1 = horizontalAntiparallelFlow;
19412
19551
  const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
19413
19552
  const pairEdges = /* @__PURE__ */ new Map();
19553
+ const flowOrder = direction === "left" || direction === "up";
19414
19554
  for (const edge of graph.edges) {
19415
19555
  if (edge.sourceId === edge.targetId || (edge.width ?? 0) <= 0 || (edge.height ?? 0) <= 0) continue;
19416
19556
  const key = [edge.sourceId, edge.targetId].sort().join("\0");
@@ -19418,7 +19558,7 @@ function* createLayeredScopePipeline(graph, options, context) {
19418
19558
  pair.push(edge);
19419
19559
  pairEdges.set(key, pair);
19420
19560
  }
19421
- for (const pair of pairEdges.values()) {
19561
+ for (const [pairKey, pair] of pairEdges) {
19422
19562
  if (pair.length !== 2 || pair[0].sourceId !== pair[1].targetId || pair[0].targetId !== pair[1].sourceId || pair.some((edge) => {
19423
19563
  const settings = options.edgeSettings?.(edge);
19424
19564
  return (settings?.["edgeLabels.placement"] ?? "CENTER") !== "CENTER" || settings?.["edgeLabels.inline"] !== true;
@@ -19436,11 +19576,13 @@ function* createLayeredScopePipeline(graph, options, context) {
19436
19576
  };
19437
19577
  const hasFlexiblePairPorts = hasFlexiblePorts(firstNode) && hasFlexiblePorts(secondNode);
19438
19578
  if (isolatedAntiparallelPair && !hasFlexiblePairPorts) continue;
19439
- const firstBeforeSecond = horizontal$1 ? firstRect.x + firstRect.width / 2 < secondRect.x + secondRect.width / 2 : firstRect.y + firstRect.height / 2 < secondRect.y + secondRect.height / 2;
19579
+ const pairFlowOrder = flowOrder && !fallbacks.antiparallelPairs.has(pairKey);
19580
+ const firstBeforeSecond = (horizontal$1 ? firstRect.x + firstRect.width / 2 < secondRect.x + secondRect.width / 2 : firstRect.y + firstRect.height / 2 < secondRect.y + secondRect.height / 2) !== pairFlowOrder;
19440
19581
  const beforeRect = firstBeforeSecond ? firstRect : secondRect;
19441
19582
  const afterRect = firstBeforeSecond ? secondRect : firstRect;
19442
19583
  const forward = pair.find((edge) => firstBeforeSecond ? edge.sourceId === pair[0].sourceId : edge.sourceId === pair[0].targetId);
19443
19584
  if (!forward?.sourcePort || !forward.targetPort) continue;
19585
+ if (pairFlowOrder) flowOrderedPairs.set(pairKey, [firstNode.id, secondNode.id]);
19444
19586
  let cross = Math.min(horizontal$1 ? firstRect.y : firstRect.x, horizontal$1 ? secondRect.y : secondRect.x);
19445
19587
  const edgeSpacing = Number(options.settings?.["spacing.edgeEdge"] ?? 10);
19446
19588
  for (const edge of pair) {
@@ -19549,7 +19691,7 @@ function* createLayeredScopePipeline(graph, options, context) {
19549
19691
  cross: horizontal$1 ? anchor.y : anchor.x
19550
19692
  }
19551
19693
  }];
19552
- }), routes.pointsByEdgeId, placement.rectByNodeId, horizontal$1);
19694
+ }), routes.pointsByEdgeId, placement.rectByNodeId, horizontal$1, Number(options.settings?.["spacing.edgeEdge"] ?? 10));
19553
19695
  }
19554
19696
  if (options.settings?.["layering.nodePromotion.strategy"] === "MODEL_ORDER_LEFT_TO_RIGHT") {
19555
19697
  const horizontal$1 = direction === "right" || direction === "left";
@@ -19651,8 +19793,11 @@ function* createLayeredScopePipeline(graph, options, context) {
19651
19793
  }
19652
19794
  }
19653
19795
  if ((options.settings?.["layerUnzipping.strategy"] ?? "NONE") === "ALTERNATING" && !unzippingFanIn && edgeRouting === "ORTHOGONAL") routes = { pointsByEdgeId: adjustUnzippedSinkRoutes(graph, routes.pointsByEdgeId, direction, Number(options.settings?.["spacing.edgeNodeBetweenLayers"] ?? 10), Number(options.settings?.["spacing.edgeEdgeBetweenLayers"] ?? 10)) };
19796
+ const connectsOnlyTo = (nodeId, otherId) => graph.edges.every((edge) => edge.sourceId === edge.targetId || edge.sourceId !== nodeId && edge.targetId !== nodeId || edge.sourceId === otherId || edge.targetId === otherId);
19654
19797
  for (const pair of labeledEdgesByPair.values()) {
19655
19798
  if (pair.length < 2) continue;
19799
+ const { sourceId, targetId } = pair[0];
19800
+ if (!connectsOnlyTo(sourceId, targetId) || !connectsOnlyTo(targetId, sourceId)) continue;
19656
19801
  const sourceRect = mutableRects.get(pair[0].sourceId);
19657
19802
  const targetRect = mutableRects.get(pair[0].targetId);
19658
19803
  if (!sourceRect || !targetRect) continue;
@@ -19950,6 +20095,28 @@ function* createLayeredScopePipeline(graph, options, context) {
19950
20095
  };
19951
20096
  }
19952
20097
  });
20098
+ if (edgeRouting === "ORTHOGONAL") {
20099
+ const diagonalEdges = edges.filter((edge) => countDiagonals(edge.points) > 0);
20100
+ const antiparallelPairs = [...flowOrderedPairs].flatMap(([key, nodeIds]) => diagonalEdges.some((edge) => nodeIds.includes(edge.sourceId) || nodeIds.includes(edge.targetId)) ? [key] : []);
20101
+ const feedbackSegments = diagonalEdges.flatMap((edge) => {
20102
+ const segments = expanded.segmentIdsByEdgeId.get(edge.id) ?? [edge.id];
20103
+ return segments.some((id) => labelPortSideSegments.has(id)) ? segments : [];
20104
+ });
20105
+ if (antiparallelPairs.length > 0 || feedbackSegments.length > 0) {
20106
+ const retry = createLayeredScopePipeline(graph, scopeOptions, context && {
20107
+ ...context,
20108
+ diagnostics: []
20109
+ }, {
20110
+ antiparallelPairs: new Set([...fallbacks.antiparallelPairs, ...antiparallelPairs]),
20111
+ feedbackSegments: new Set([...fallbacks.feedbackSegments, ...feedbackSegments])
20112
+ });
20113
+ const prepared = retry.next();
20114
+ const resumed = prepared.done ? prepared : retry.next(crossingOrder);
20115
+ if (!resumed.done) throw new Error("Layered scope yielded more than one crossing phase");
20116
+ const diagonals = (routed) => routed.reduce((sum, edge) => sum + countDiagonals(edge.points), 0);
20117
+ if (diagonals(resumed.value.edges) < diagonals(edges)) return resumed.value;
20118
+ }
20119
+ }
19953
20120
  return setElkjs0111ResultPolicy({
19954
20121
  ...graph,
19955
20122
  direction,
@@ -19963,6 +20130,15 @@ function* createLayeredScopePipeline(graph, options, context) {
19963
20130
  junctionPointsByEdgeId: routes.junctionPointsByEdgeId
19964
20131
  });
19965
20132
  }
20133
+ function countDiagonals(points) {
20134
+ let count = 0;
20135
+ for (let index = 1; index < (points?.length ?? 0); index++) {
20136
+ const a = points[index - 1];
20137
+ const b = points[index];
20138
+ if (Math.abs(a.x - b.x) > 1e-6 && Math.abs(a.y - b.y) > 1e-6) count++;
20139
+ }
20140
+ return count;
20141
+ }
19966
20142
  /**
19967
20143
  * Deterministic native layered layout for an `@statelyai/graph` graph.
19968
20144
  *
@@ -1,4 +1,4 @@
1
- import { K as placePorts, X as JavaRandom, i as layeredAlgorithm, n as elkjs0111LayeredAlgorithm, x as setElkjs0111ResultPolicy, z as getPolylineMidpoint } from "./layered-BsAdm_u8.mjs";
1
+ import { K as placePorts, X as JavaRandom, i as layeredAlgorithm, n as elkjs0111LayeredAlgorithm, x as setElkjs0111ResultPolicy, z as getPolylineMidpoint } from "./layered-CmL7oynw.mjs";
2
2
  import { getNodeSize } from "@statelyai/graph/layout";
3
3
 
4
4
  //#region src/fixed.ts
@@ -1,4 +1,4 @@
1
- const require_layered = require('./layered-BJu8A21s.cjs');
1
+ const require_layered = require('./layered-SB2mlAqt.cjs');
2
2
  let _statelyai_graph_layout = require("@statelyai/graph/layout");
3
3
 
4
4
  //#region src/fixed.ts
@@ -1,4 +1,4 @@
1
- const require_routing = require('../routing-QIdGGFBe.cjs');
1
+ const require_routing = require('../routing-Phxu1R0x.cjs');
2
2
 
3
3
  exports.applyRoutePatches = require_routing.applyRoutePatches;
4
4
  exports.bezierRouting = require_routing.bezierRouting;
@@ -23,7 +23,10 @@ exports.roundCorners = require_routing.roundCorners;
23
23
  exports.routeToGraphPatch = require_routing.routeToGraphPatch;
24
24
  exports.routeToPoints = require_routing.routeToPoints;
25
25
  exports.routeToPolylines = require_routing.routeToPolylines;
26
+ exports.routingPolicies = require_routing.routingPolicies;
26
27
  exports.routingStrategies = require_routing.routingStrategies;
28
+ exports.segmentCrossesRect = require_routing.segmentCrossesRect;
27
29
  exports.selfLoopRouting = require_routing.selfLoopRouting;
28
30
  exports.straightRouting = require_routing.straightRouting;
29
- exports.toSvgPath = require_routing.toSvgPath;
31
+ exports.toSvgPath = require_routing.toSvgPath;
32
+ exports.trimBezierPathStart = require_routing.trimBezierPathStart;
@@ -1,3 +1,3 @@
1
- import { _ as RoutingMetrics, a as RouteBounds, b as RoutingStrategy, c as RoutePath, d as RouteSegment, f as RouteSide, g as RoutingGraph, h as RoutingDiagnosticCode, i as RouteAttachment, l as RoutePoint, m as RoutingDiagnostic, n as NativeRoutingStrategy, o as RouteEndpoint, p as RouteStyle, r as Route, s as RoutePatch, t as EdgeRoutingSettings, u as RouteSection, v as RoutingSettings, x as RoutingUpdate, y as RoutingSnapshot } from "../types-uxPlGRof.cjs";
2
- import { C as getPointAtLength, D as toSvgPath, E as roundCorners, O as applyRoutePatches, S as getPathLength, T as pathFromPoints, _ as routeToPoints, a as fanRouting, b as flattenPath, c as orthogonalRouting, d as routingStrategies, f as selfLoopRouting, g as routeToGraphPatch, h as pathFromSplinePoints, i as curvedRouting, l as parallelRouting, m as getLayoutRoutes, n as bundleRouting, o as octilinearRouting, p as straightRouting, r as busRouting, s as organicRouting, t as bezierRouting, u as polylineRouting, v as routeToPolylines, w as getTangentAtLength, x as getPathBounds, y as FlattenPathOptions } from "../index-B6cWNrMw.cjs";
3
- export { EdgeRoutingSettings, FlattenPathOptions, NativeRoutingStrategy, Route, RouteAttachment, RouteBounds, RouteEndpoint, RoutePatch, RoutePath, RoutePoint, RouteSection, RouteSegment, RouteSide, RouteStyle, RoutingDiagnostic, RoutingDiagnosticCode, RoutingGraph, RoutingMetrics, RoutingSettings, RoutingSnapshot, RoutingStrategy, RoutingUpdate, applyRoutePatches, bezierRouting, bundleRouting, busRouting, curvedRouting, fanRouting, flattenPath, getLayoutRoutes, getPathBounds, getPathLength, getPointAtLength, getTangentAtLength, octilinearRouting, organicRouting, orthogonalRouting, parallelRouting, pathFromPoints, pathFromSplinePoints, polylineRouting, roundCorners, routeToGraphPatch, routeToPoints, routeToPolylines, routingStrategies, selfLoopRouting, straightRouting, toSvgPath };
1
+ import { A as BezierGuide, C as RoutingPolicy, D as RoutingTangent, E as RoutingStrategy, O as RoutingUpdate, S as RoutingMetrics, T as RoutingSnapshot, _ as RoutingCurve, a as Route, b as RoutingGraph, c as RouteEndpoint, d as RoutePath, f as RoutePoint, g as RouteStyle, h as RouteSide, i as NativeRoutingStrategy, j as trimBezierPathStart, k as BezierEndpoint, l as RouteLabelPlacement, m as RouteSegment, n as BezierRoutingOptions, o as RouteAttachment, p as RouteSection, r as EdgeRoutingSettings, s as RouteBounds, t as BezierEdgeSettings, u as RoutePatch, v as RoutingDiagnostic, w as RoutingSettings, x as RoutingLabel, y as RoutingDiagnosticCode } from "../types-D8pYSn8I.cjs";
2
+ import { A as applyRoutePatches, C as getPathLength, D as roundCorners, E as pathFromPoints, O as segmentCrossesRect, S as getPathBounds, T as getTangentAtLength, _ as routeToGraphPatch, a as fanRouting, b as FlattenPathOptions, c as orthogonalRouting, d as routingStrategies, f as selfLoopRouting, g as pathFromSplinePoints, h as getLayoutRoutes, i as curvedRouting, k as toSvgPath, l as parallelRouting, m as routingPolicies, n as bundleRouting, o as octilinearRouting, p as straightRouting, r as busRouting, s as organicRouting, t as bezierRouting, u as polylineRouting, v as routeToPoints, w as getPointAtLength, x as flattenPath, y as routeToPolylines } from "../index-C0J4ttZe.cjs";
3
+ export { BezierEdgeSettings, BezierEndpoint, BezierGuide, BezierRoutingOptions, EdgeRoutingSettings, FlattenPathOptions, NativeRoutingStrategy, Route, RouteAttachment, RouteBounds, RouteEndpoint, RouteLabelPlacement, RoutePatch, RoutePath, RoutePoint, RouteSection, RouteSegment, RouteSide, RouteStyle, RoutingCurve, RoutingDiagnostic, RoutingDiagnosticCode, RoutingGraph, RoutingLabel, RoutingMetrics, RoutingPolicy, RoutingSettings, RoutingSnapshot, RoutingStrategy, RoutingTangent, RoutingUpdate, applyRoutePatches, bezierRouting, bundleRouting, busRouting, curvedRouting, fanRouting, flattenPath, getLayoutRoutes, getPathBounds, getPathLength, getPointAtLength, getTangentAtLength, octilinearRouting, organicRouting, orthogonalRouting, parallelRouting, pathFromPoints, pathFromSplinePoints, polylineRouting, roundCorners, routeToGraphPatch, routeToPoints, routeToPolylines, routingPolicies, routingStrategies, segmentCrossesRect, selfLoopRouting, straightRouting, toSvgPath, trimBezierPathStart };
@@ -1,3 +1,3 @@
1
- import { _ as RoutingMetrics, a as RouteBounds, b as RoutingStrategy, c as RoutePath, d as RouteSegment, f as RouteSide, g as RoutingGraph, h as RoutingDiagnosticCode, i as RouteAttachment, l as RoutePoint, m as RoutingDiagnostic, n as NativeRoutingStrategy, o as RouteEndpoint, p as RouteStyle, r as Route, s as RoutePatch, t as EdgeRoutingSettings, u as RouteSection, v as RoutingSettings, x as RoutingUpdate, y as RoutingSnapshot } from "../types-CT2akdK0.mjs";
2
- import { C as getPointAtLength, D as toSvgPath, E as roundCorners, O as applyRoutePatches, S as getPathLength, T as pathFromPoints, _ as routeToPoints, a as fanRouting, b as flattenPath, c as orthogonalRouting, d as routingStrategies, f as selfLoopRouting, g as routeToGraphPatch, h as pathFromSplinePoints, i as curvedRouting, l as parallelRouting, m as getLayoutRoutes, n as bundleRouting, o as octilinearRouting, p as straightRouting, r as busRouting, s as organicRouting, t as bezierRouting, u as polylineRouting, v as routeToPolylines, w as getTangentAtLength, x as getPathBounds, y as FlattenPathOptions } from "../index-CJQLUKD9.mjs";
3
- export { EdgeRoutingSettings, FlattenPathOptions, NativeRoutingStrategy, Route, RouteAttachment, RouteBounds, RouteEndpoint, RoutePatch, RoutePath, RoutePoint, RouteSection, RouteSegment, RouteSide, RouteStyle, RoutingDiagnostic, RoutingDiagnosticCode, RoutingGraph, RoutingMetrics, RoutingSettings, RoutingSnapshot, RoutingStrategy, RoutingUpdate, applyRoutePatches, bezierRouting, bundleRouting, busRouting, curvedRouting, fanRouting, flattenPath, getLayoutRoutes, getPathBounds, getPathLength, getPointAtLength, getTangentAtLength, octilinearRouting, organicRouting, orthogonalRouting, parallelRouting, pathFromPoints, pathFromSplinePoints, polylineRouting, roundCorners, routeToGraphPatch, routeToPoints, routeToPolylines, routingStrategies, selfLoopRouting, straightRouting, toSvgPath };
1
+ import { A as BezierGuide, C as RoutingPolicy, D as RoutingTangent, E as RoutingStrategy, O as RoutingUpdate, S as RoutingMetrics, T as RoutingSnapshot, _ as RoutingCurve, a as Route, b as RoutingGraph, c as RouteEndpoint, d as RoutePath, f as RoutePoint, g as RouteStyle, h as RouteSide, i as NativeRoutingStrategy, j as trimBezierPathStart, k as BezierEndpoint, l as RouteLabelPlacement, m as RouteSegment, n as BezierRoutingOptions, o as RouteAttachment, p as RouteSection, r as EdgeRoutingSettings, s as RouteBounds, t as BezierEdgeSettings, u as RoutePatch, v as RoutingDiagnostic, w as RoutingSettings, x as RoutingLabel, y as RoutingDiagnosticCode } from "../types-MAUtJfKQ.mjs";
2
+ import { A as applyRoutePatches, C as getPathLength, D as roundCorners, E as pathFromPoints, O as segmentCrossesRect, S as getPathBounds, T as getTangentAtLength, _ as routeToGraphPatch, a as fanRouting, b as FlattenPathOptions, c as orthogonalRouting, d as routingStrategies, f as selfLoopRouting, g as pathFromSplinePoints, h as getLayoutRoutes, i as curvedRouting, k as toSvgPath, l as parallelRouting, m as routingPolicies, n as bundleRouting, o as octilinearRouting, p as straightRouting, r as busRouting, s as organicRouting, t as bezierRouting, u as polylineRouting, v as routeToPoints, w as getPointAtLength, x as flattenPath, y as routeToPolylines } from "../index-0YVSvMvA.mjs";
3
+ export { BezierEdgeSettings, BezierEndpoint, BezierGuide, BezierRoutingOptions, EdgeRoutingSettings, FlattenPathOptions, NativeRoutingStrategy, Route, RouteAttachment, RouteBounds, RouteEndpoint, RouteLabelPlacement, RoutePatch, RoutePath, RoutePoint, RouteSection, RouteSegment, RouteSide, RouteStyle, RoutingCurve, RoutingDiagnostic, RoutingDiagnosticCode, RoutingGraph, RoutingLabel, RoutingMetrics, RoutingPolicy, RoutingSettings, RoutingSnapshot, RoutingStrategy, RoutingTangent, RoutingUpdate, applyRoutePatches, bezierRouting, bundleRouting, busRouting, curvedRouting, fanRouting, flattenPath, getLayoutRoutes, getPathBounds, getPathLength, getPointAtLength, getTangentAtLength, octilinearRouting, organicRouting, orthogonalRouting, parallelRouting, pathFromPoints, pathFromSplinePoints, polylineRouting, roundCorners, routeToGraphPatch, routeToPoints, routeToPolylines, routingPolicies, routingStrategies, segmentCrossesRect, selfLoopRouting, straightRouting, toSvgPath, trimBezierPathStart };