@crazyhappyone/auto-graph 0.2.9 → 0.2.11

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.
@@ -4740,7 +4740,7 @@ function segmentCrossesAnyObstacle(a, b, obstacles) {
4740
4740
  }
4741
4741
 
4742
4742
  // src/routing/routes.ts
4743
- function checkBacktracking(points, source, target, diagnostics) {
4743
+ function checkBacktracking(points, source, target, diagnostics, maxRatio) {
4744
4744
  if (points.length < 2) return;
4745
4745
  const direct = Math.hypot(target.x - source.x, target.y - source.y);
4746
4746
  if (direct <= 0) return;
@@ -4750,7 +4750,7 @@ function checkBacktracking(points, source, target, diagnostics) {
4750
4750
  const b = points[i + 1];
4751
4751
  routeLen += Math.hypot(b.x - a.x, b.y - a.y);
4752
4752
  }
4753
- const threshold = 10;
4753
+ const threshold = maxRatio ?? 20;
4754
4754
  if (routeLen > direct * threshold) {
4755
4755
  diagnostics.push({
4756
4756
  severity: "warning",
@@ -4768,8 +4768,20 @@ function routeEdge(input) {
4768
4768
  const diagnostics = [];
4769
4769
  const softObstacles = input.obstacles ?? [];
4770
4770
  const hardObstacles = input.hardObstacles ?? [];
4771
+ let bestRejectedPath;
4772
+ let bestRejectedCrossings = Number.POSITIVE_INFINITY;
4771
4773
  const softObstacleIndex = input.obstacleIndex ?? createBoxSpatialIndex(indexedBoxes(softObstacles));
4772
4774
  const hardObstacleIndex = input.hardObstacleIndex ?? createBoxSpatialIndex(indexedBoxes(hardObstacles));
4775
+ const recordRejected = (candidate) => {
4776
+ if (routeIntersectsObstacles(candidate, hardObstacles, hardObstacleIndex)) {
4777
+ return;
4778
+ }
4779
+ const crossings = countObstacleCrossings(candidate, softObstacles);
4780
+ if (crossings < bestRejectedCrossings) {
4781
+ bestRejectedCrossings = crossings;
4782
+ bestRejectedPath = candidate;
4783
+ }
4784
+ };
4773
4785
  const maxAttempts = input.maxRoutingAttempts ?? 5;
4774
4786
  const defaultAnchors = defaultAnchorsForGeometry(
4775
4787
  input.source.box,
@@ -4829,13 +4841,14 @@ function routeEdge(input) {
4829
4841
  targetAnchor
4830
4842
  );
4831
4843
  const allObstacles = [...softObstacles, ...hardObstacles];
4844
+ const corridorMargin = input.corridorMargin ?? 32;
4832
4845
  const corridorObstacles = filterObstaclesByCorridor(
4833
4846
  source,
4834
4847
  target,
4835
4848
  allObstacles,
4836
4849
  [],
4837
4850
  // endpointObstacles passed separately via options
4838
- 32
4851
+ corridorMargin
4839
4852
  );
4840
4853
  const cornerObstacles = corridorObstacles.length === 0 && allObstacles.length > 0 ? allObstacles : corridorObstacles;
4841
4854
  let cornerPath = findCornerGraphPath(
@@ -4858,7 +4871,7 @@ function routeEdge(input) {
4858
4871
  source,
4859
4872
  target,
4860
4873
  allObstacles,
4861
- { endpointObstacles, margin: 0 },
4874
+ { endpointObstacles, margin: 0, corridorMargin },
4862
4875
  diagnostics
4863
4876
  );
4864
4877
  if (path !== null && path.length >= 2) {
@@ -4875,9 +4888,16 @@ function routeEdge(input) {
4875
4888
  softObstacles,
4876
4889
  softObstacleIndex
4877
4890
  ) && !routeIntersectsObstacles(finalized, hardObstacles, hardObstacleIndex)) {
4878
- checkBacktracking(finalized, source, target, diagnostics);
4891
+ checkBacktracking(
4892
+ finalized,
4893
+ source,
4894
+ target,
4895
+ diagnostics,
4896
+ input.maxBacktrackingRatio
4897
+ );
4879
4898
  return { points: finalized, diagnostics };
4880
4899
  }
4900
+ recordRejected(finalized);
4881
4901
  if (cornerPath !== null) {
4882
4902
  const fullCornerPath = cornerObstacles.length < allObstacles.length ? findCornerGraphPath(
4883
4903
  source,
@@ -4904,15 +4924,22 @@ function routeEdge(input) {
4904
4924
  hardObstacles,
4905
4925
  hardObstacleIndex
4906
4926
  )) {
4907
- checkBacktracking(fullFinalized, source, target, diagnostics);
4927
+ checkBacktracking(
4928
+ fullFinalized,
4929
+ source,
4930
+ target,
4931
+ diagnostics,
4932
+ input.maxBacktrackingRatio
4933
+ );
4908
4934
  return { points: fullFinalized, diagnostics };
4909
4935
  }
4936
+ recordRejected(fullFinalized);
4910
4937
  }
4911
4938
  const gridPath = findObstacleFreePath(
4912
4939
  source,
4913
4940
  target,
4914
4941
  allObstacles,
4915
- { endpointObstacles, margin: 0 },
4942
+ { endpointObstacles, margin: 0, corridorMargin },
4916
4943
  diagnostics
4917
4944
  );
4918
4945
  if (gridPath !== null && gridPath.length >= 2) {
@@ -4933,9 +4960,16 @@ function routeEdge(input) {
4933
4960
  hardObstacles,
4934
4961
  hardObstacleIndex
4935
4962
  )) {
4936
- checkBacktracking(gridFinalized, source, target, diagnostics);
4963
+ checkBacktracking(
4964
+ gridFinalized,
4965
+ source,
4966
+ target,
4967
+ diagnostics,
4968
+ input.maxBacktrackingRatio
4969
+ );
4937
4970
  return { points: gridFinalized, diagnostics };
4938
4971
  }
4972
+ recordRejected(gridFinalized);
4939
4973
  }
4940
4974
  }
4941
4975
  }
@@ -4999,7 +5033,8 @@ function routeEdge(input) {
4999
5033
  finalizedClean,
5000
5034
  candidate.points[0],
5001
5035
  candidate.points[candidate.points.length - 1],
5002
- diagnostics
5036
+ diagnostics,
5037
+ input.maxBacktrackingRatio
5003
5038
  );
5004
5039
  return { points: finalizedClean, diagnostics };
5005
5040
  }
@@ -5065,13 +5100,41 @@ function routeEdge(input) {
5065
5100
  code: "routing.obstacle.unavoidable",
5066
5101
  message: "No bounded orthogonal route candidate avoided all soft obstacles."
5067
5102
  });
5068
- return {
5069
- points: finalizeRoute(
5070
- bestPoints2,
5103
+ const finalizedSoftBest = finalizeRoute(
5104
+ bestPoints2,
5105
+ softObstacles,
5106
+ hardObstacles,
5107
+ diagnostics
5108
+ );
5109
+ let softFallback = finalizedSoftBest;
5110
+ if (bestRejectedPath !== void 0) {
5111
+ const finalizedRejected = finalizeRoute(
5112
+ bestRejectedPath,
5071
5113
  softObstacles,
5072
5114
  hardObstacles,
5073
5115
  diagnostics
5074
- ),
5116
+ );
5117
+ const rejectedCrossings = countObstacleCrossings(
5118
+ finalizedRejected,
5119
+ softObstacles
5120
+ );
5121
+ const heuristicCrossings = countObstacleCrossings(
5122
+ finalizedSoftBest,
5123
+ softObstacles
5124
+ );
5125
+ if (rejectedCrossings < heuristicCrossings) {
5126
+ softFallback = finalizedRejected;
5127
+ }
5128
+ }
5129
+ checkBacktracking(
5130
+ softFallback,
5131
+ softFallback[0],
5132
+ softFallback[softFallback.length - 1],
5133
+ diagnostics,
5134
+ input.maxBacktrackingRatio
5135
+ );
5136
+ return {
5137
+ points: softFallback,
5075
5138
  diagnostics
5076
5139
  };
5077
5140
  }
@@ -5103,6 +5166,22 @@ function routeEdge(input) {
5103
5166
  maxAttempts
5104
5167
  );
5105
5168
  }
5169
+ if (bestRejectedPath !== void 0) {
5170
+ diagnostics.push({
5171
+ severity: "warning",
5172
+ code: "routing.obstacle.unavoidable",
5173
+ message: "Using A* route with minor soft-obstacle crossings to avoid hard evidence obstacles."
5174
+ });
5175
+ return {
5176
+ points: finalizeRoute(
5177
+ bestRejectedPath,
5178
+ softObstacles,
5179
+ hardObstacles,
5180
+ diagnostics
5181
+ ),
5182
+ diagnostics
5183
+ };
5184
+ }
5106
5185
  diagnostics.push({
5107
5186
  severity: "error",
5108
5187
  code: "routing.evidence.crossing_forbidden",
@@ -5150,13 +5229,41 @@ function routeEdge(input) {
5150
5229
  code: "routing.obstacle.unavoidable",
5151
5230
  message: "No bounded orthogonal route candidate avoided all obstacles."
5152
5231
  });
5153
- return {
5154
- points: finalizeRoute(
5155
- bestPoints,
5232
+ const finalizedBestPoints = finalizeRoute(
5233
+ bestPoints,
5234
+ softObstacles,
5235
+ hardObstacles,
5236
+ diagnostics
5237
+ );
5238
+ let fallbackPoints = finalizedBestPoints;
5239
+ if (bestRejectedPath !== void 0) {
5240
+ const finalizedRejected = finalizeRoute(
5241
+ bestRejectedPath,
5156
5242
  softObstacles,
5157
5243
  hardObstacles,
5158
5244
  diagnostics
5159
- ),
5245
+ );
5246
+ const rejectedCrossings = countObstacleCrossings(
5247
+ finalizedRejected,
5248
+ softObstacles
5249
+ );
5250
+ const heuristicCrossings = countObstacleCrossings(
5251
+ finalizedBestPoints,
5252
+ softObstacles
5253
+ );
5254
+ if (rejectedCrossings < heuristicCrossings) {
5255
+ fallbackPoints = finalizedRejected;
5256
+ }
5257
+ }
5258
+ checkBacktracking(
5259
+ fallbackPoints,
5260
+ fallbackPoints[0],
5261
+ fallbackPoints[fallbackPoints.length - 1],
5262
+ diagnostics,
5263
+ input.maxBacktrackingRatio
5264
+ );
5265
+ return {
5266
+ points: fallbackPoints,
5160
5267
  diagnostics
5161
5268
  };
5162
5269
  }
@@ -5655,6 +5762,24 @@ function routeIntersectsObstacles(points, obstacles, spatialIndex) {
5655
5762
  }
5656
5763
  return false;
5657
5764
  }
5765
+ function countObstacleCrossings(points, obstacles) {
5766
+ let count = 0;
5767
+ for (const obstacle of obstacles) {
5768
+ validateBox(obstacle);
5769
+ for (let pointIndex = 0; pointIndex < points.length - 1; pointIndex += 1) {
5770
+ const a = points[pointIndex];
5771
+ const b = points[pointIndex + 1];
5772
+ if (a === void 0 || b === void 0) {
5773
+ continue;
5774
+ }
5775
+ if (intersectsAabb(segmentBox2(a, b), obstacle)) {
5776
+ count += 1;
5777
+ break;
5778
+ }
5779
+ }
5780
+ }
5781
+ return count;
5782
+ }
5658
5783
  function routeIntersectsEndpointInteriors(points, endpointInteriors) {
5659
5784
  for (let index = 0; index < points.length - 1; index += 1) {
5660
5785
  const a = points[index];
@@ -5889,7 +6014,8 @@ function solveDiagram(diagram, options = {}) {
5889
6014
  constrained.boxes,
5890
6015
  constrained.locks,
5891
6016
  options?.overlapSpacing ?? 40,
5892
- Math.max(0, options?.minLaneGutter ?? 0)
6017
+ Math.max(0, options?.minLaneGutter ?? 0),
6018
+ options.distributeContainedChildren ?? true
5893
6019
  );
5894
6020
  removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
5895
6021
  diagnostics.push(...swimlaneContracts.diagnostics);
@@ -6056,7 +6182,8 @@ function solveDiagram(diagram, options = {}) {
6056
6182
  diagram.direction,
6057
6183
  options,
6058
6184
  diagnostics,
6059
- coordinatedGroups
6185
+ coordinatedGroups,
6186
+ contentBounds
6060
6187
  );
6061
6188
  const edgeTextAnnotations = coordinateEdgeTextAnnotations(
6062
6189
  coordinatedEdges,
@@ -6475,7 +6602,7 @@ function reportCjkTypographyDiagnostics(path, typography, previousStyle, diagnos
6475
6602
  function containsCjk(value) {
6476
6603
  return /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/u.test(value);
6477
6604
  }
6478
- function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottomFlow, nodeBoxes, locks, overlapSpacing, laneGutter) {
6605
+ function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottomFlow, nodeBoxes, locks, overlapSpacing, laneGutter, distributeContainedChildren) {
6479
6606
  const layouts = /* @__PURE__ */ new Map();
6480
6607
  const diagnostics = [];
6481
6608
  const movedChildIds = /* @__PURE__ */ new Set();
@@ -6494,7 +6621,9 @@ function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottom
6494
6621
  locks,
6495
6622
  diagnostics,
6496
6623
  movedChildIds,
6497
- laneGutter
6624
+ laneGutter,
6625
+ constraints,
6626
+ distributeContainedChildren
6498
6627
  );
6499
6628
  if (layout2 !== void 0) {
6500
6629
  layouts.set(swimlane.id, layout2);
@@ -6686,7 +6815,7 @@ function isStackRunaway(boxes, nodes, direction, options) {
6686
6815
  const maxWidth = Math.max(...nodeBoxes.map((box) => box.width));
6687
6816
  return xSpread <= Math.max(maxWidth, options.overlapSpacing ?? 40);
6688
6817
  }
6689
- function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, locks, diagnostics, movedChildIds, laneGutter) {
6818
+ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, locks, diagnostics, movedChildIds, laneGutter, constraints, distributeContainedChildren) {
6690
6819
  const headerHeight = swimlane.headerHeight ?? 28;
6691
6820
  const padding = swimlane.padding ?? 16;
6692
6821
  const laneBounds = swimlane.lanes.map((lane) => {
@@ -6711,7 +6840,9 @@ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes
6711
6840
  locks,
6712
6841
  diagnostics,
6713
6842
  movedChildIds,
6714
- laneGutter
6843
+ laneGutter,
6844
+ constraints,
6845
+ distributeContainedChildren
6715
6846
  );
6716
6847
  }
6717
6848
  return applyHorizontalSwimlaneContract(
@@ -6726,13 +6857,29 @@ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes
6726
6857
  laneGutter
6727
6858
  );
6728
6859
  }
6729
- function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, laneBounds, headerHeight, padding, locks, diagnostics, movedChildIds, laneGutter) {
6860
+ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, laneBounds, headerHeight, padding, locks, diagnostics, movedChildIds, laneGutter, constraints, distributeContainedChildren) {
6730
6861
  const populatedBounds = laneBounds.filter(
6731
6862
  (box) => box !== void 0
6732
6863
  );
6733
6864
  const top = Math.min(...populatedBounds.map((box) => box.y));
6734
6865
  const left = Math.min(...populatedBounds.map((box) => box.x));
6735
6866
  const maxChildHeight = Math.max(...populatedBounds.map((box) => box.height));
6867
+ const containedChildIds = /* @__PURE__ */ new Set();
6868
+ if (distributeContainedChildren) {
6869
+ for (const c of constraints) {
6870
+ if (c.kind !== "containment") continue;
6871
+ if (nodeBoxes.get(c.containerId) === void 0) continue;
6872
+ const distributable = c.childIds.filter((childId) => {
6873
+ if (nodeBoxes.get(childId) === void 0) return false;
6874
+ const lock = locks.get(childId);
6875
+ return lock === void 0 || lock.source === "fixed-position";
6876
+ });
6877
+ if (distributable.length < 2) continue;
6878
+ for (const childId of distributable) {
6879
+ containedChildIds.add(childId);
6880
+ }
6881
+ }
6882
+ }
6736
6883
  const flowRanks = topToBottomFlow ? rankVerticalSwimlaneChildren(swimlane, edges) : /* @__PURE__ */ new Map();
6737
6884
  const maxRank = flowRanks.size === 0 ? 0 : Math.max(...Array.from(flowRanks.values()));
6738
6885
  const rankStackGap = Math.max(8, padding / 2);
@@ -6749,7 +6896,8 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
6749
6896
  nodeBoxes,
6750
6897
  flowRanks,
6751
6898
  locks,
6752
- rankStackGap
6899
+ rankStackGap,
6900
+ containedChildIds
6753
6901
  );
6754
6902
  const slotWidth = Math.max(
6755
6903
  Math.max(...populatedBounds.map((box) => box.width)),
@@ -6771,7 +6919,10 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
6771
6919
  const distributable = lane.children.filter(
6772
6920
  (childId) => !locks.has(childId)
6773
6921
  );
6774
- if (distributable.length >= CROSS_AXIS_SPREAD_THRESHOLD) {
6922
+ const coveredByContainment = lane.children.some(
6923
+ (childId) => containedChildIds.has(childId)
6924
+ );
6925
+ if (!coveredByContainment && distributable.length >= CROSS_AXIS_SPREAD_THRESHOLD) {
6775
6926
  moveRankedVerticalLaneChildren(
6776
6927
  lane.children,
6777
6928
  nodeBoxes,
@@ -6799,6 +6950,9 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
6799
6950
  );
6800
6951
  continue;
6801
6952
  }
6953
+ const rankedCoveredByContainment = lane.children.some(
6954
+ (childId) => containedChildIds.has(childId)
6955
+ );
6802
6956
  moveRankedVerticalLaneChildren(
6803
6957
  lane.children,
6804
6958
  nodeBoxes,
@@ -6809,7 +6963,8 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
6809
6963
  rankSpacing,
6810
6964
  rankStackGap,
6811
6965
  { x: target.x, y: laneContentTop },
6812
- slotWidth - padding * 2
6966
+ slotWidth - padding * 2,
6967
+ rankedCoveredByContainment
6813
6968
  );
6814
6969
  }
6815
6970
  return {
@@ -6925,9 +7080,12 @@ function crossAxisSpreadWidth(items, gap) {
6925
7080
  0
6926
7081
  );
6927
7082
  }
6928
- function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap) {
7083
+ function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap, containedChildIds) {
6929
7084
  let maxWidth = 0;
6930
7085
  for (const lane of swimlane.lanes) {
7086
+ if (containedChildIds !== void 0 && lane.children.some((childId) => containedChildIds.has(childId))) {
7087
+ continue;
7088
+ }
6931
7089
  for (const stack of rankStacks(
6932
7090
  lane.children,
6933
7091
  nodeBoxes,
@@ -6940,7 +7098,7 @@ function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap) {
6940
7098
  }
6941
7099
  return maxWidth;
6942
7100
  }
6943
- function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics, movedChildIds, flowRanks, rankSpacing, rankStackGap, target, contentWidth) {
7101
+ function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics, movedChildIds, flowRanks, rankSpacing, rankStackGap, target, contentWidth, suppressSpread) {
6944
7102
  for (const [rank, stack] of rankStacks(childIds, nodeBoxes, flowRanks)) {
6945
7103
  const unlocked = [];
6946
7104
  for (const item of stack) {
@@ -6969,7 +7127,7 @@ function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics,
6969
7127
  }
6970
7128
  nodeBoxes.set(childId, next);
6971
7129
  } else {
6972
- const shouldSpread = unlocked.length >= CROSS_AXIS_SPREAD_THRESHOLD;
7130
+ const shouldSpread = !suppressSpread && unlocked.length >= CROSS_AXIS_SPREAD_THRESHOLD;
6973
7131
  if (!shouldSpread) {
6974
7132
  let yOffset = 0;
6975
7133
  for (const { childId, box } of unlocked) {
@@ -8098,14 +8256,21 @@ function evidenceOverlapDiagnostic(block, conflict) {
8098
8256
  }
8099
8257
  };
8100
8258
  }
8101
- function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacles, textObstacles, hardObstacles, direction, options, diagnostics, groups) {
8259
+ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacles, textObstacles, hardObstacles, direction, options, diagnostics, groups, contentBounds) {
8102
8260
  const coordinated = [];
8103
8261
  const coordinatedNodeById = new Map(
8104
8262
  coordinatedNodes.map((node) => [node.id, node])
8105
8263
  );
8264
+ const corridorMarginOption = options.corridorMargin ?? "auto";
8265
+ const corridorMargin = typeof corridorMarginOption === "number" ? corridorMarginOption : Math.max(
8266
+ 200,
8267
+ Math.hypot(contentBounds.width, contentBounds.height) * 0.3
8268
+ );
8269
+ const routingGutter = options.routingGutter ?? 160;
8270
+ const queryGutter = (options.routeKind ?? "orthogonal") === "obstacle-avoiding" ? Math.max(routingGutter, corridorMargin) : routingGutter;
8106
8271
  const nodeObstacleIndex = createBoxSpatialIndex(
8107
8272
  obstacles.map((box, index) => ({ id: `node-obstacle:${index}`, box })),
8108
- options.routingGutter ?? 160
8273
+ queryGutter
8109
8274
  );
8110
8275
  for (const edge of edges) {
8111
8276
  const source = nodes.get(edge.source.nodeId);
@@ -8127,11 +8292,7 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
8127
8292
  const sourcePort = coordinatedNodeById.get(edge.source.nodeId)?.ports?.find((port) => port.id === edge.source.portId);
8128
8293
  const targetPort = coordinatedNodeById.get(edge.target.nodeId)?.ports?.find((port) => port.id === edge.target.portId);
8129
8294
  const routeTextObstacles = textObstacles.filter((annotation) => !isEdgeConnectedTextAnnotation(edge, annotation)).map((annotation) => annotation.box);
8130
- const corridor = edgeCorridorBox(
8131
- source.box,
8132
- target.box,
8133
- options.routingGutter ?? 160
8134
- );
8295
+ const corridor = edgeCorridorBox(source.box, target.box, queryGutter);
8135
8296
  const routeNodeObstacles = queryBoxSpatialIndex(nodeObstacleIndex, corridor).map((entry) => entry.box).filter(
8136
8297
  (obstacle) => !sameBox(obstacle, source.obstacleBox) && !sameBox(obstacle, target.obstacleBox)
8137
8298
  );
@@ -8149,7 +8310,9 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
8149
8310
  ...routeTextObstacles
8150
8311
  ],
8151
8312
  hardObstacles,
8152
- ...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts }
8313
+ corridorMargin,
8314
+ ...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts },
8315
+ ...options.maxBacktrackingRatio === void 0 ? {} : { maxBacktrackingRatio: options.maxBacktrackingRatio }
8153
8316
  });
8154
8317
  diagnostics.push(
8155
8318
  ...route.diagnostics.map((diagnostic) => ({