@tscircuit/schematic-trace-solver 0.0.106 → 0.0.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -325,19 +325,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
325
325
  chipMap
326
326
  });
327
327
  if (restrictedCenterLines.size === 0) return false;
328
- const EPS11 = 1e-9;
328
+ const EPS12 = 1e-9;
329
329
  const crossesSegment = (a, b) => {
330
330
  for (const [, rcl] of restrictedCenterLines) {
331
331
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
332
- if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS11) return true;
332
+ if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS12) return true;
333
333
  }
334
334
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
335
- if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS11) return true;
335
+ if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS12) return true;
336
336
  }
337
337
  }
338
338
  return false;
339
339
  };
340
- if (Math.abs(p1.x - p2.x) < EPS11 || Math.abs(p1.y - p2.y) < EPS11) {
340
+ if (Math.abs(p1.x - p2.x) < EPS12 || Math.abs(p1.y - p2.y) < EPS12) {
341
341
  return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
342
342
  }
343
343
  const elbowHV = { x: p2.x, y: p1.y };
@@ -1299,8 +1299,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1299
1299
  if (!collision) {
1300
1300
  const first = path[0];
1301
1301
  const last = path[path.length - 1];
1302
- const EPS11 = 1e-9;
1303
- const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS11 && Math.abs(p.y - q.y) < EPS11;
1302
+ const EPS12 = 1e-9;
1303
+ const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS12 && Math.abs(p.y - q.y) < EPS12;
1304
1304
  if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
1305
1305
  this.solvedTracePath = path;
1306
1306
  this.solved = true;
@@ -1573,13 +1573,13 @@ var applyJogToTerminalSegment = ({
1573
1573
  segmentIndex: si,
1574
1574
  offset,
1575
1575
  JOG_SIZE,
1576
- EPS: EPS11 = 1e-6
1576
+ EPS: EPS12 = 1e-6
1577
1577
  }) => {
1578
1578
  if (si !== 0 && si !== pts.length - 2) return;
1579
1579
  const start = pts[si];
1580
1580
  const end = pts[si + 1];
1581
- const isVertical5 = Math.abs(start.x - end.x) < EPS11;
1582
- const isHorizontal4 = Math.abs(start.y - end.y) < EPS11;
1581
+ const isVertical5 = Math.abs(start.x - end.x) < EPS12;
1582
+ const isHorizontal4 = Math.abs(start.y - end.y) < EPS12;
1583
1583
  if (!isVertical5 && !isHorizontal4) return;
1584
1584
  const segDir = isVertical5 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
1585
1585
  if (pts.length === 2) {
@@ -1997,7 +1997,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1997
1997
  return islands;
1998
1998
  }
1999
1999
  findNextOverlapIssue() {
2000
- const EPS11 = 2e-3;
2000
+ const EPS12 = 2e-3;
2001
2001
  const netIds = Object.keys(this.traceNetIslands);
2002
2002
  for (let i = 0; i < netIds.length; i++) {
2003
2003
  for (let j = i + 1; j < netIds.length; j++) {
@@ -2024,7 +2024,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2024
2024
  segmentBIndex,
2025
2025
  rangeOverlap
2026
2026
  }) => {
2027
- if (rangeOverlap > EPS11) {
2027
+ if (rangeOverlap > EPS12) {
2028
2028
  const keyA = `${pathAIndex}:${segmentAIndex}`;
2029
2029
  const keyB = `${pathBIndex}:${segmentBIndex}`;
2030
2030
  if (!seenA.has(keyA)) {
@@ -2043,7 +2043,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2043
2043
  }
2044
2044
  return;
2045
2045
  }
2046
- if (rangeOverlap < -EPS11) return;
2046
+ if (rangeOverlap < -EPS12) return;
2047
2047
  const pathA = pathsA[pathAIndex].tracePath;
2048
2048
  const pathB = pathsB[pathBIndex].tracePath;
2049
2049
  const segmentAStart = pathA[segmentAIndex];
@@ -2066,8 +2066,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2066
2066
  for (let sa = 0; sa < ptsA.length - 1; sa++) {
2067
2067
  const a1 = ptsA[sa];
2068
2068
  const a2 = ptsA[sa + 1];
2069
- const aVert = Math.abs(a1.x - a2.x) < EPS11;
2070
- const aHorz = Math.abs(a1.y - a2.y) < EPS11;
2069
+ const aVert = Math.abs(a1.x - a2.x) < EPS12;
2070
+ const aHorz = Math.abs(a1.y - a2.y) < EPS12;
2071
2071
  if (!aVert && !aHorz) continue;
2072
2072
  for (let pb = 0; pb < pathsB.length; pb++) {
2073
2073
  const pathB = pathsB[pb];
@@ -2075,11 +2075,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2075
2075
  for (let sb = 0; sb < ptsB.length - 1; sb++) {
2076
2076
  const b1 = ptsB[sb];
2077
2077
  const b2 = ptsB[sb + 1];
2078
- const bVert = Math.abs(b1.x - b2.x) < EPS11;
2079
- const bHorz = Math.abs(b1.y - b2.y) < EPS11;
2078
+ const bVert = Math.abs(b1.x - b2.x) < EPS12;
2079
+ const bHorz = Math.abs(b1.y - b2.y) < EPS12;
2080
2080
  if (!bVert && !bHorz) continue;
2081
2081
  if (aVert && bVert) {
2082
- if (Math.abs(a1.x - b1.x) < EPS11) {
2082
+ if (Math.abs(a1.x - b1.x) < EPS12) {
2083
2083
  recordCollinearInteraction({
2084
2084
  pathAIndex: pa,
2085
2085
  segmentAIndex: sa,
@@ -2089,7 +2089,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2089
2089
  });
2090
2090
  }
2091
2091
  } else if (aHorz && bHorz) {
2092
- if (Math.abs(a1.y - b1.y) < EPS11) {
2092
+ if (Math.abs(a1.y - b1.y) < EPS12) {
2093
2093
  recordCollinearInteraction({
2094
2094
  pathAIndex: pa,
2095
2095
  segmentAIndex: sa,
@@ -2145,14 +2145,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2145
2145
  return null;
2146
2146
  }
2147
2147
  findNextDiagonalSegment() {
2148
- const EPS11 = 2e-3;
2148
+ const EPS12 = 2e-3;
2149
2149
  for (const mspPairId in this.correctedTraceMap) {
2150
2150
  const tracePath = this.correctedTraceMap[mspPairId].tracePath;
2151
2151
  for (let i = 0; i < tracePath.length - 1; i++) {
2152
2152
  const p1 = tracePath[i];
2153
2153
  const p2 = tracePath[i + 1];
2154
- const isHorizontal4 = Math.abs(p1.y - p2.y) < EPS11;
2155
- const isVertical5 = Math.abs(p1.x - p2.x) < EPS11;
2154
+ const isHorizontal4 = Math.abs(p1.y - p2.y) < EPS12;
2155
+ const isVertical5 = Math.abs(p1.x - p2.x) < EPS12;
2156
2156
  if (!isHorizontal4 && !isVertical5) {
2157
2157
  return { mspPairId, tracePath, i, p1, p2 };
2158
2158
  }
@@ -2166,13 +2166,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2166
2166
  return false;
2167
2167
  }
2168
2168
  const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
2169
- const EPS11 = 2e-3;
2169
+ const EPS12 = 2e-3;
2170
2170
  const p0 = i > 0 ? tracePath[i - 1] : null;
2171
2171
  const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
2172
- const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS11 : false;
2173
- const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS11 : false;
2174
- const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS11 : false;
2175
- const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS11 : false;
2172
+ const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS12 : false;
2173
+ const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS12 : false;
2174
+ const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS12 : false;
2175
+ const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS12 : false;
2176
2176
  const elbow1 = { x: p1.x, y: p2.y };
2177
2177
  const elbow2 = { x: p2.x, y: p1.y };
2178
2178
  let score1 = 0;
@@ -2299,24 +2299,24 @@ var ChipObstacleSpatialIndex = class {
2299
2299
  };
2300
2300
 
2301
2301
  // lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
2302
- function segmentIntersectsRect2(p1, p2, rect, EPS11 = 1e-9) {
2303
- const isVert = Math.abs(p1.x - p2.x) < EPS11;
2304
- const isHorz = Math.abs(p1.y - p2.y) < EPS11;
2302
+ function segmentIntersectsRect2(p1, p2, rect, EPS12 = 1e-9) {
2303
+ const isVert = Math.abs(p1.x - p2.x) < EPS12;
2304
+ const isHorz = Math.abs(p1.y - p2.y) < EPS12;
2305
2305
  if (!isVert && !isHorz) return false;
2306
2306
  if (isVert) {
2307
2307
  const x = p1.x;
2308
- if (x < rect.minX - EPS11 || x > rect.maxX + EPS11) return false;
2308
+ if (x < rect.minX - EPS12 || x > rect.maxX + EPS12) return false;
2309
2309
  const segMinY = Math.min(p1.y, p2.y);
2310
2310
  const segMaxY = Math.max(p1.y, p2.y);
2311
2311
  const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
2312
- return overlap > EPS11;
2312
+ return overlap > EPS12;
2313
2313
  } else {
2314
2314
  const y = p1.y;
2315
- if (y < rect.minY - EPS11 || y > rect.maxY + EPS11) return false;
2315
+ if (y < rect.minY - EPS12 || y > rect.maxY + EPS12) return false;
2316
2316
  const segMinX = Math.min(p1.x, p2.x);
2317
2317
  const segMaxX = Math.max(p1.x, p2.x);
2318
2318
  const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
2319
- return overlap > EPS11;
2319
+ return overlap > EPS12;
2320
2320
  }
2321
2321
  }
2322
2322
  function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
@@ -2713,14 +2713,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
2713
2713
  };
2714
2714
  let bestCandidate = null;
2715
2715
  let bestScore = -Infinity;
2716
- const EPS11 = 1e-6;
2716
+ const EPS12 = 1e-6;
2717
2717
  for (const curr of tracesToScan) {
2718
2718
  const pts = curr.tracePath.slice();
2719
2719
  for (let si = 0; si < pts.length - 1; si++) {
2720
2720
  const a = pts[si];
2721
2721
  const b = pts[si + 1];
2722
- const isH = Math.abs(a.y - b.y) < EPS11;
2723
- const isV = Math.abs(a.x - b.x) < EPS11;
2722
+ const isH = Math.abs(a.y - b.y) < EPS12;
2723
+ const isV = Math.abs(a.x - b.x) < EPS12;
2724
2724
  if (!isH && !isV) continue;
2725
2725
  const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
2726
2726
  const candidateOrients = orientations.filter(
@@ -5652,6 +5652,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
5652
5652
 
5653
5653
  // lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts
5654
5654
  import { getSegmentIntersection } from "@tscircuit/math-utils/line-intersections";
5655
+ var EPS7 = 1e-6;
5655
5656
  var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
5656
5657
  const intersections = [];
5657
5658
  for (const obstacle of obstacles) {
@@ -5670,10 +5671,38 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
5670
5671
  }
5671
5672
  return intersections;
5672
5673
  };
5674
+ var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS7 && Math.abs(first.y - second.y) < EPS7;
5675
+ var findPerpendicularPathCrossings = (path, otherPath) => {
5676
+ const crossings = [];
5677
+ for (let pathSegmentIndex = 1; pathSegmentIndex < path.length - 2; pathSegmentIndex++) {
5678
+ const start = path[pathSegmentIndex];
5679
+ const end = path[pathSegmentIndex + 1];
5680
+ const isVertical5 = Math.abs(start.x - end.x) < EPS7;
5681
+ for (let otherPathSegmentIndex = 1; otherPathSegmentIndex < otherPath.length - 2; otherPathSegmentIndex++) {
5682
+ const otherStart = otherPath[otherPathSegmentIndex];
5683
+ const otherEnd = otherPath[otherPathSegmentIndex + 1];
5684
+ const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS7;
5685
+ if (isVertical5 === otherIsVertical) continue;
5686
+ const intersection = getSegmentIntersection(
5687
+ start,
5688
+ end,
5689
+ otherStart,
5690
+ otherEnd
5691
+ );
5692
+ if (!intersection || [start, end, otherStart, otherEnd].some(
5693
+ (point) => isSamePoint(point, intersection)
5694
+ )) {
5695
+ continue;
5696
+ }
5697
+ crossings.push({ pathSegmentIndex, otherPathSegmentIndex });
5698
+ }
5699
+ }
5700
+ return crossings;
5701
+ };
5673
5702
 
5674
5703
  // lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
5675
- var EPS7 = 1e-6;
5676
- var isVertical3 = (a, b, eps = EPS7) => Math.abs(a.x - b.x) < eps;
5704
+ var EPS8 = 1e-6;
5705
+ var isVertical3 = (a, b, eps = EPS8) => Math.abs(a.x - b.x) < eps;
5677
5706
  var generateLShapeRerouteCandidates = ({
5678
5707
  lShape,
5679
5708
  rectangle,
@@ -5686,7 +5715,7 @@ var generateLShapeRerouteCandidates = ({
5686
5715
  let c2;
5687
5716
  let i1_padded = interactionPoint1;
5688
5717
  let i2_padded = interactionPoint2;
5689
- if (Math.abs(p2.x - x) < EPS7 && Math.abs(p2.y - (y + height)) < EPS7) {
5718
+ if (Math.abs(p2.x - x) < EPS8 && Math.abs(p2.y - (y + height)) < EPS8) {
5690
5719
  c2 = { x: x + width + padding, y: y - padding };
5691
5720
  if (isVertical3(p1, p2)) {
5692
5721
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -5698,7 +5727,7 @@ var generateLShapeRerouteCandidates = ({
5698
5727
  } else {
5699
5728
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
5700
5729
  }
5701
- } else if (Math.abs(p2.x - (x + width)) < EPS7 && Math.abs(p2.y - (y + height)) < EPS7) {
5730
+ } else if (Math.abs(p2.x - (x + width)) < EPS8 && Math.abs(p2.y - (y + height)) < EPS8) {
5702
5731
  c2 = { x: x - padding, y: y - padding };
5703
5732
  if (isVertical3(p1, p2)) {
5704
5733
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -5710,7 +5739,7 @@ var generateLShapeRerouteCandidates = ({
5710
5739
  } else {
5711
5740
  i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
5712
5741
  }
5713
- } else if (Math.abs(p2.x - x) < EPS7 && Math.abs(p2.y - y) < EPS7) {
5742
+ } else if (Math.abs(p2.x - x) < EPS8 && Math.abs(p2.y - y) < EPS8) {
5714
5743
  c2 = { x: x + width + padding, y: y + height + padding };
5715
5744
  if (isVertical3(p1, p2)) {
5716
5745
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -5722,7 +5751,7 @@ var generateLShapeRerouteCandidates = ({
5722
5751
  } else {
5723
5752
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
5724
5753
  }
5725
- } else if (Math.abs(p2.x - (x + width)) < EPS7 && Math.abs(p2.y - y) < EPS7) {
5754
+ } else if (Math.abs(p2.x - (x + width)) < EPS8 && Math.abs(p2.y - y) < EPS8) {
5726
5755
  c2 = { x: x - padding, y: y + height + padding };
5727
5756
  if (isVertical3(p1, p2)) {
5728
5757
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -5739,6 +5768,48 @@ var generateLShapeRerouteCandidates = ({
5739
5768
  }
5740
5769
  return [[i1_padded, c2, i2_padded]];
5741
5770
  };
5771
+ var generatePerpendicularTraceDetours = ({
5772
+ trace,
5773
+ segmentIndex,
5774
+ obstacleStart,
5775
+ obstacleEnd,
5776
+ chipBounds,
5777
+ clearance
5778
+ }) => {
5779
+ const buildDetours = (path, index) => {
5780
+ const start = path[index];
5781
+ const end = path[index + 1];
5782
+ const movingAxis = Math.abs(start.x - end.x) < EPS8 ? "y" : "x";
5783
+ const detourAxis = movingAxis === "x" ? "y" : "x";
5784
+ const gate = obstacleStart[movingAxis] + Math.sign(start[movingAxis] - obstacleStart[movingAxis]) * clearance;
5785
+ const obstacleRange = [obstacleStart[detourAxis], obstacleEnd[detourAxis]];
5786
+ const lowBound = detourAxis === "x" ? "minX" : "minY";
5787
+ const highBound = detourAxis === "x" ? "maxX" : "maxY";
5788
+ const detourCoordinates = [
5789
+ Math.min(...obstacleRange) - clearance,
5790
+ Math.max(...obstacleRange) + clearance,
5791
+ ...chipBounds.flatMap((bounds) => [
5792
+ bounds[lowBound] - clearance,
5793
+ bounds[highBound] + clearance
5794
+ ])
5795
+ ];
5796
+ return [...new Set(detourCoordinates)].map(
5797
+ (detour) => simplifyPath([
5798
+ ...path.slice(0, index + 1),
5799
+ { ...start, [movingAxis]: gate },
5800
+ { ...start, [movingAxis]: gate, [detourAxis]: detour },
5801
+ { ...end, [detourAxis]: detour },
5802
+ ...path.slice(index + 2)
5803
+ ])
5804
+ );
5805
+ };
5806
+ const reversedPath = [...trace.tracePath].reverse();
5807
+ const reversedIndex = trace.tracePath.length - 2 - segmentIndex;
5808
+ return [
5809
+ ...buildDetours(trace.tracePath, segmentIndex),
5810
+ ...buildDetours(reversedPath, reversedIndex).map((path) => path.reverse())
5811
+ ].map((path) => ({ traceId: trace.mspPairId, path }));
5812
+ };
5742
5813
 
5743
5814
  // lib/solvers/TraceCleanupSolver/sub-solver/isPathColliding.ts
5744
5815
  import { getSegmentIntersection as getSegmentIntersection2 } from "@tscircuit/math-utils/line-intersections";
@@ -5913,6 +5984,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
5913
5984
  input;
5914
5985
  chipObstacleSpatialIndex;
5915
5986
  lShapesToProcess = [];
5987
+ ignoredCrossings = /* @__PURE__ */ new Set();
5988
+ reroutedTraceIds = /* @__PURE__ */ new Set();
5989
+ processingCrossings = true;
5916
5990
  visualizationMode = "l_shapes";
5917
5991
  currentLShape = null;
5918
5992
  intersectionPoints = [];
@@ -5936,18 +6010,24 @@ var UntangleTraceSubsolver = class extends BaseSolver {
5936
6010
  if (!this.input.inputProblem._chipObstacleSpatialIndex) {
5937
6011
  this.input.inputProblem._chipObstacleSpatialIndex = this.chipObstacleSpatialIndex;
5938
6012
  }
5939
- for (const trace of this.input.allTraces) {
5940
- const lShapes = findAllLShapedTurns(trace.tracePath);
5941
- this.lShapesToProcess.push(
5942
- ...lShapes.map((l) => ({ ...l, traceId: trace.mspPairId }))
5943
- );
5944
- }
5945
6013
  }
5946
6014
  _step() {
5947
6015
  if (this.isInitialStep) {
5948
6016
  this.isInitialStep = false;
5949
6017
  return;
5950
6018
  }
6019
+ if (this.processingCrossings) {
6020
+ const crossing = this._findCrossing();
6021
+ if (crossing) {
6022
+ if (!this._resolveCrossing(crossing)) {
6023
+ this.ignoredCrossings.add(this._crossingKey(crossing));
6024
+ }
6025
+ return;
6026
+ }
6027
+ this.processingCrossings = false;
6028
+ this._initializeLShapes();
6029
+ return;
6030
+ }
5951
6031
  if (this.lShapeJustProcessed) {
5952
6032
  this._resetAfterLShapProcessing();
5953
6033
  return;
@@ -5971,6 +6051,110 @@ var UntangleTraceSubsolver = class extends BaseSolver {
5971
6051
  break;
5972
6052
  }
5973
6053
  }
6054
+ _initializeLShapes() {
6055
+ for (const trace of this.input.allTraces) {
6056
+ this.lShapesToProcess.push(
6057
+ ...findAllLShapedTurns(trace.tracePath).map((lShape) => ({
6058
+ ...lShape,
6059
+ traceId: trace.mspPairId
6060
+ }))
6061
+ );
6062
+ }
6063
+ }
6064
+ _crossingKey(crossing) {
6065
+ return `${crossing.trace.mspPairId}:${crossing.segmentIndex}:${crossing.otherTrace.mspPairId}:${crossing.otherSegmentIndex}`;
6066
+ }
6067
+ _isTraceBundle(first, second) {
6068
+ const componentPair = (trace) => trace.pins.map((pin) => pin.chipId).sort().join(":");
6069
+ if (componentPair(first) !== componentPair(second)) return false;
6070
+ return Object.values(this.input.mergedLabelNetIdMap).some(
6071
+ (netIds) => netIds.has(first.globalConnNetId) && netIds.has(second.globalConnNetId)
6072
+ );
6073
+ }
6074
+ _findCrossing() {
6075
+ const traces = this.input.allTraces;
6076
+ for (let firstIndex = 0; firstIndex < traces.length; firstIndex++) {
6077
+ const trace = traces[firstIndex];
6078
+ for (let secondIndex = firstIndex + 1; secondIndex < traces.length; secondIndex++) {
6079
+ const otherTrace = traces[secondIndex];
6080
+ if (trace.globalConnNetId === otherTrace.globalConnNetId) continue;
6081
+ const isInitialBundleCrossing = this._isTraceBundle(trace, otherTrace);
6082
+ if (!isInitialBundleCrossing && !this.reroutedTraceIds.has(trace.mspPairId) && !this.reroutedTraceIds.has(otherTrace.mspPairId)) {
6083
+ continue;
6084
+ }
6085
+ const crossings = findPerpendicularPathCrossings(
6086
+ trace.tracePath,
6087
+ otherTrace.tracePath
6088
+ );
6089
+ for (const { pathSegmentIndex, otherPathSegmentIndex } of crossings) {
6090
+ const crossing = {
6091
+ trace,
6092
+ segmentIndex: pathSegmentIndex,
6093
+ otherTrace,
6094
+ otherSegmentIndex: otherPathSegmentIndex,
6095
+ isInitialBundleCrossing
6096
+ };
6097
+ if (!this.ignoredCrossings.has(this._crossingKey(crossing))) {
6098
+ return crossing;
6099
+ }
6100
+ }
6101
+ }
6102
+ }
6103
+ return null;
6104
+ }
6105
+ _resolveCrossing(crossing) {
6106
+ const chipBounds = this.chipObstacleSpatialIndex.chips.map(
6107
+ (chip) => chip.bounds
6108
+ );
6109
+ const candidates = [
6110
+ ...generatePerpendicularTraceDetours({
6111
+ trace: crossing.trace,
6112
+ segmentIndex: crossing.segmentIndex,
6113
+ obstacleStart: crossing.otherTrace.tracePath[crossing.otherSegmentIndex],
6114
+ obstacleEnd: crossing.otherTrace.tracePath[crossing.otherSegmentIndex + 1],
6115
+ chipBounds,
6116
+ clearance: this.input.paddingBuffer
6117
+ }),
6118
+ ...generatePerpendicularTraceDetours({
6119
+ trace: crossing.otherTrace,
6120
+ segmentIndex: crossing.otherSegmentIndex,
6121
+ obstacleStart: crossing.trace.tracePath[crossing.segmentIndex],
6122
+ obstacleEnd: crossing.trace.tracePath[crossing.segmentIndex + 1],
6123
+ chipBounds,
6124
+ clearance: this.input.paddingBuffer
6125
+ })
6126
+ ];
6127
+ const chipObstacles = getObstacleRects(this.input.inputProblem).filter(
6128
+ (obstacle) => obstacle.kind === "chip"
6129
+ );
6130
+ const validCandidates = candidates.map((candidate) => ({
6131
+ ...candidate,
6132
+ collision: isPathColliding(
6133
+ candidate.path,
6134
+ this.input.allTraces,
6135
+ candidate.traceId
6136
+ )
6137
+ })).filter(
6138
+ (candidate) => !isPathCollidingWithChipInterior(candidate.path, chipObstacles) && !isPathColliding(
6139
+ candidate.path,
6140
+ [crossing.trace, crossing.otherTrace],
6141
+ candidate.traceId
6142
+ ).isColliding && (crossing.isInitialBundleCrossing || !candidate.collision.isColliding)
6143
+ ).sort(
6144
+ (first, second) => Number(first.collision.isColliding) - Number(second.collision.isColliding) || getPathLength(first.path) - getPathLength(second.path)
6145
+ );
6146
+ const bestCandidate = validCandidates[0];
6147
+ if (!bestCandidate) return false;
6148
+ const traceIndex = this.input.allTraces.findIndex(
6149
+ (trace) => trace.mspPairId === bestCandidate.traceId
6150
+ );
6151
+ this.input.allTraces[traceIndex] = {
6152
+ ...this.input.allTraces[traceIndex],
6153
+ tracePath: bestCandidate.path
6154
+ };
6155
+ this.reroutedTraceIds.add(bestCandidate.traceId);
6156
+ return true;
6157
+ }
5974
6158
  _resetAfterLShapProcessing() {
5975
6159
  this.lShapeProcessingStep = "idle";
5976
6160
  this.currentLShape = null;
@@ -6193,9 +6377,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
6193
6377
  };
6194
6378
 
6195
6379
  // lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
6196
- var EPS8 = 1e-6;
6197
- var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS8;
6198
- var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS8;
6380
+ var EPS9 = 1e-6;
6381
+ var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS9;
6382
+ var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS9;
6199
6383
  var is4PointRectangle = (path) => {
6200
6384
  if (path.length !== 4) return false;
6201
6385
  const [p0, p1, p2, p3] = path;
@@ -7255,16 +7439,16 @@ var createPortOnlyLabelConnectorTrace = ({
7255
7439
  // lib/solvers/AvailableNetOrientationSolver/constants.ts
7256
7440
  var LABEL_SEARCH_STEP = 0.05;
7257
7441
  var WICK_CLEARANCE = 1e-3;
7258
- var EPS9 = 1e-9;
7259
- var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS9;
7442
+ var EPS10 = 1e-9;
7443
+ var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS10;
7260
7444
  var CANDIDATE_SELECTED_COLOR2 = "blue";
7261
7445
  var CANDIDATE_REJECTED_COLOR2 = "red";
7262
7446
 
7263
7447
  // lib/solvers/AvailableNetOrientationSolver/geometry.ts
7264
7448
  var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
7265
7449
  var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
7266
- var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS9 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS9;
7267
- var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS9;
7450
+ var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS10 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS10;
7451
+ var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS10;
7268
7452
  var traceCrossesBoundsInterior = (bounds, traceMap) => {
7269
7453
  for (const trace of Object.values(traceMap)) {
7270
7454
  const points = trace.tracePath;
@@ -7287,7 +7471,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
7287
7471
  return false;
7288
7472
  }
7289
7473
  if (sameX2(p1, p2)) {
7290
- if (p1.x <= interiorBounds.minX + EPS9 || p1.x >= interiorBounds.maxX - EPS9) {
7474
+ if (p1.x <= interiorBounds.minX + EPS10 || p1.x >= interiorBounds.maxX - EPS10) {
7291
7475
  return false;
7292
7476
  }
7293
7477
  return rangesOverlap(
@@ -7298,7 +7482,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
7298
7482
  );
7299
7483
  }
7300
7484
  if (sameY2(p1, p2)) {
7301
- if (p1.y <= interiorBounds.minY + EPS9 || p1.y >= interiorBounds.maxY - EPS9) {
7485
+ if (p1.y <= interiorBounds.minY + EPS10 || p1.y >= interiorBounds.maxY - EPS10) {
7302
7486
  return false;
7303
7487
  }
7304
7488
  return rangesOverlap(
@@ -7354,8 +7538,8 @@ var simplifyOrthogonalPath = (path) => {
7354
7538
  return simplified;
7355
7539
  };
7356
7540
  var pointsEqual2 = (a, b) => sameX2(a, b) && sameY2(a, b);
7357
- var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS9;
7358
- var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS9;
7541
+ var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS10;
7542
+ var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS10;
7359
7543
  var getMaxSearchDistance = (inputProblem) => {
7360
7544
  const maxChipWidth = Math.max(
7361
7545
  ...inputProblem.chips.map((chip) => chip.width),
@@ -7610,11 +7794,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
7610
7794
  if (trace.globalConnNetId !== label.globalConnNetId) return false;
7611
7795
  const path = trace.tracePath;
7612
7796
  return path.some((point, pointIndex) => {
7613
- if (Math.abs(point.x - label.anchorPoint.x) > EPS9 || Math.abs(point.y - label.anchorPoint.y) > EPS9) {
7797
+ if (Math.abs(point.x - label.anchorPoint.x) > EPS10 || Math.abs(point.y - label.anchorPoint.y) > EPS10) {
7614
7798
  return false;
7615
7799
  }
7616
7800
  return [path[pointIndex - 1], path[pointIndex + 1]].some(
7617
- (neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS9 && (neighbor.y - point.y) * direction.y > EPS9
7801
+ (neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS10 && (neighbor.y - point.y) * direction.y > EPS10
7618
7802
  );
7619
7803
  });
7620
7804
  });
@@ -7693,7 +7877,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
7693
7877
  );
7694
7878
  const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
7695
7879
  const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
7696
- for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS9; outwardDistance += LABEL_SEARCH_STEP) {
7880
+ for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS10; outwardDistance += LABEL_SEARCH_STEP) {
7697
7881
  const baseAnchor = {
7698
7882
  x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
7699
7883
  y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
@@ -7767,7 +7951,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
7767
7951
  phase = "shift",
7768
7952
  stopOnTraceCollision = true
7769
7953
  } = params;
7770
- for (let distance4 = LABEL_SEARCH_STEP; distance4 <= maxSearchDistance + EPS9; distance4 += LABEL_SEARCH_STEP) {
7954
+ for (let distance4 = LABEL_SEARCH_STEP; distance4 <= maxSearchDistance + EPS10; distance4 += LABEL_SEARCH_STEP) {
7771
7955
  const anchorPoint = {
7772
7956
  x: baseAnchor.x + direction.x * distance4,
7773
7957
  y: baseAnchor.y + direction.y * distance4
@@ -8004,9 +8188,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8004
8188
  const { anchorPoint, orientation } = candidate;
8005
8189
  const chipBounds = chip.bounds;
8006
8190
  if (isYOrientation(orientation)) {
8007
- return anchorPoint.x < chipBounds.minX - EPS9 || anchorPoint.x > chipBounds.maxX + EPS9;
8191
+ return anchorPoint.x < chipBounds.minX - EPS10 || anchorPoint.x > chipBounds.maxX + EPS10;
8008
8192
  }
8009
- return anchorPoint.y < chipBounds.minY - EPS9 || anchorPoint.y > chipBounds.maxY + EPS9;
8193
+ return anchorPoint.y < chipBounds.minY - EPS10 || anchorPoint.y > chipBounds.maxY + EPS10;
8010
8194
  });
8011
8195
  }
8012
8196
  getBoundsStatus(candidateBoundsCheck) {
@@ -8080,8 +8264,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8080
8264
  sharesChipBoundary(bounds) {
8081
8265
  for (const chip of this.chipObstacleSpatialIndex.chips) {
8082
8266
  const chipBounds = chip.bounds;
8083
- const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS9 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS9;
8084
- const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS9 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS9;
8267
+ const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS10 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS10;
8268
+ const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS10 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS10;
8085
8269
  if (adjacentToVerticalSide && rangesOverlap(
8086
8270
  bounds.minY,
8087
8271
  bounds.maxY,
@@ -8129,7 +8313,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8129
8313
  let nearestDistance = Number.POSITIVE_INFINITY;
8130
8314
  for (const chip of this.chipObstacleSpatialIndex.chips) {
8131
8315
  const bounds = chip.bounds;
8132
- if (point.x < bounds.minX - EPS9 || point.x > bounds.maxX + EPS9 || point.y < bounds.minY - EPS9 || point.y > bounds.maxY + EPS9) {
8316
+ if (point.x < bounds.minX - EPS10 || point.x > bounds.maxX + EPS10 || point.y < bounds.minY - EPS10 || point.y > bounds.maxY + EPS10) {
8133
8317
  continue;
8134
8318
  }
8135
8319
  for (const [side, distance4] of getSideDistances(point, bounds)) {
@@ -8146,8 +8330,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8146
8330
  let nearestDistanceSq = Number.POSITIVE_INFINITY;
8147
8331
  for (const chip of this.chipObstacleSpatialIndex.chips) {
8148
8332
  const bounds = chip.bounds;
8149
- const dx = point.x < bounds.minX - EPS9 ? bounds.minX - point.x : point.x > bounds.maxX + EPS9 ? point.x - bounds.maxX : 0;
8150
- const dy = point.y < bounds.minY - EPS9 ? bounds.minY - point.y : point.y > bounds.maxY + EPS9 ? point.y - bounds.maxY : 0;
8333
+ const dx = point.x < bounds.minX - EPS10 ? bounds.minX - point.x : point.x > bounds.maxX + EPS10 ? point.x - bounds.maxX : 0;
8334
+ const dy = point.y < bounds.minY - EPS10 ? bounds.minY - point.y : point.y > bounds.maxY + EPS10 ? point.y - bounds.maxY : 0;
8151
8335
  if (dx === 0 && dy === 0) continue;
8152
8336
  const distanceSq = dx ** 2 + dy ** 2;
8153
8337
  if (distanceSq >= nearestDistanceSq) continue;
@@ -8525,11 +8709,11 @@ var getOrientationConstraint = (inputProblem, label) => {
8525
8709
  };
8526
8710
 
8527
8711
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
8528
- var EPS10 = 1e-6;
8712
+ var EPS11 = 1e-6;
8529
8713
  var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
8530
8714
  var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
8531
- var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS10 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS10;
8532
- var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS10 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS10;
8715
+ var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS11 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS11;
8716
+ var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS11 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS11;
8533
8717
  var traceCrossesBoundsInterior2 = (bounds, traces) => {
8534
8718
  for (const trace of traces) {
8535
8719
  const points = trace.tracePath;
@@ -8575,7 +8759,7 @@ var getPointAtTraceDistance = (trace, distance4) => {
8575
8759
  const end = trace.tracePath[i + 1];
8576
8760
  const segmentLength = getManhattanDistance(start, end);
8577
8761
  const nextDistance = pathDistance + segmentLength;
8578
- if (distance4 <= nextDistance + EPS10) {
8762
+ if (distance4 <= nextDistance + EPS11) {
8579
8763
  const offset = Math.max(
8580
8764
  0,
8581
8765
  Math.min(segmentLength, distance4 - pathDistance)
@@ -8614,7 +8798,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
8614
8798
  return false;
8615
8799
  }
8616
8800
  if (isVertical4(start, end)) {
8617
- if (start.x <= interior.minX + EPS10 || start.x >= interior.maxX - EPS10) {
8801
+ if (start.x <= interior.minX + EPS11 || start.x >= interior.maxX - EPS11) {
8618
8802
  return false;
8619
8803
  }
8620
8804
  return rangesOverlap2(
@@ -8625,7 +8809,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
8625
8809
  );
8626
8810
  }
8627
8811
  if (isHorizontal3(start, end)) {
8628
- if (start.y <= interior.minY + EPS10 || start.y >= interior.maxY - EPS10) {
8812
+ if (start.y <= interior.minY + EPS11 || start.y >= interior.maxY - EPS11) {
8629
8813
  return false;
8630
8814
  }
8631
8815
  return rangesOverlap2(
@@ -8639,10 +8823,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
8639
8823
  };
8640
8824
  var isPointOnSegment2 = (point, start, end) => {
8641
8825
  if (isHorizontal3(start, end)) {
8642
- return Math.abs(point.y - start.y) <= EPS10 && point.x >= Math.min(start.x, end.x) - EPS10 && point.x <= Math.max(start.x, end.x) + EPS10;
8826
+ return Math.abs(point.y - start.y) <= EPS11 && point.x >= Math.min(start.x, end.x) - EPS11 && point.x <= Math.max(start.x, end.x) + EPS11;
8643
8827
  }
8644
8828
  if (isVertical4(start, end)) {
8645
- return Math.abs(point.x - start.x) <= EPS10 && point.y >= Math.min(start.y, end.y) - EPS10 && point.y <= Math.max(start.y, end.y) + EPS10;
8829
+ return Math.abs(point.x - start.x) <= EPS11 && point.y >= Math.min(start.y, end.y) - EPS11 && point.y <= Math.max(start.y, end.y) + EPS11;
8646
8830
  }
8647
8831
  return false;
8648
8832
  };
@@ -8650,9 +8834,9 @@ var getSegmentDirection = (start, end) => ({
8650
8834
  x: isVertical4(start, end) ? 0 : Math.sign(end.x - start.x),
8651
8835
  y: isHorizontal3(start, end) ? 0 : Math.sign(end.y - start.y)
8652
8836
  });
8653
- var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS10;
8654
- var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS10;
8655
- var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS10;
8837
+ var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS11;
8838
+ var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS11;
8839
+ var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS11;
8656
8840
  var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
8657
8841
 
8658
8842
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
@@ -8709,7 +8893,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
8709
8893
  for (const distance4 of vertexDistances) {
8710
8894
  distances.add(roundDistance(distance4));
8711
8895
  }
8712
- return [...distances].filter((distance4) => distance4 >= -EPS10 && distance4 <= traceLength + EPS10).sort((a, b) => a - b);
8896
+ return [...distances].filter((distance4) => distance4 >= -EPS11 && distance4 <= traceLength + EPS11).sort((a, b) => a - b);
8713
8897
  };
8714
8898
  var getOrientationsForPoint = (params) => {
8715
8899
  const { inputProblem, label, point, orientationConstraint } = params;
@@ -8798,13 +8982,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
8798
8982
  };
8799
8983
  var getOutwardAxisOption = (params) => {
8800
8984
  const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
8801
- if (value > max + EPS10) {
8985
+ if (value > max + EPS11) {
8802
8986
  return {
8803
8987
  orientation: positiveOrientation,
8804
8988
  outwardScore: 1 + value - max
8805
8989
  };
8806
8990
  }
8807
- if (value < min - EPS10) {
8991
+ if (value < min - EPS11) {
8808
8992
  return {
8809
8993
  orientation: negativeOrientation,
8810
8994
  outwardScore: 1 + min - value
@@ -8815,7 +8999,7 @@ var getOutwardAxisOption = (params) => {
8815
8999
  outwardScore: getNormalizedCenterDistance(value, center, max - min)
8816
9000
  };
8817
9001
  };
8818
- var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS10, span / 2);
9002
+ var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS11, span / 2);
8819
9003
  var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
8820
9004
  var getFlippedOrientation = (orientation) => {
8821
9005
  switch (orientation) {
@@ -8888,7 +9072,7 @@ var getNetLabelHeight = (inputProblem, label) => {
8888
9072
  )?.netLabelHeight;
8889
9073
  };
8890
9074
  var roundDistance = (distance4) => Number(distance4.toFixed(6));
8891
- var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS10 && Math.abs(point.y - label.anchorPoint.y) <= EPS10 && orientation === label.orientation;
9075
+ var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS11 && Math.abs(point.y - label.anchorPoint.y) <= EPS11 && orientation === label.orientation;
8892
9076
 
8893
9077
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
8894
9078
  var CANDIDATE_SELECTED_COLOR4 = "blue";