@tscircuit/schematic-trace-solver 0.0.64 → 0.0.66

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
@@ -271,19 +271,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
271
271
  chipMap
272
272
  });
273
273
  if (restrictedCenterLines.size === 0) return false;
274
- const EPS10 = 1e-9;
274
+ const EPS11 = 1e-9;
275
275
  const crossesSegment = (a, b) => {
276
276
  for (const [, rcl] of restrictedCenterLines) {
277
277
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
278
- if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS10) return true;
278
+ if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS11) return true;
279
279
  }
280
280
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
281
- if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS10) return true;
281
+ if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS11) return true;
282
282
  }
283
283
  }
284
284
  return false;
285
285
  };
286
- if (Math.abs(p1.x - p2.x) < EPS10 || Math.abs(p1.y - p2.y) < EPS10) {
286
+ if (Math.abs(p1.x - p2.x) < EPS11 || Math.abs(p1.y - p2.y) < EPS11) {
287
287
  return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
288
288
  }
289
289
  const elbowHV = { x: p2.x, y: p1.y };
@@ -850,8 +850,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
850
850
  if (!collision) {
851
851
  const first = path[0];
852
852
  const last = path[path.length - 1];
853
- const EPS10 = 1e-9;
854
- const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS10 && Math.abs(p.y - q.y) < EPS10;
853
+ const EPS11 = 1e-9;
854
+ const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS11 && Math.abs(p.y - q.y) < EPS11;
855
855
  if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
856
856
  this.solvedTracePath = path;
857
857
  this.solved = true;
@@ -1050,15 +1050,41 @@ var applyJogToTerminalSegment = ({
1050
1050
  segmentIndex: si,
1051
1051
  offset,
1052
1052
  JOG_SIZE,
1053
- EPS: EPS10 = 1e-6
1053
+ EPS: EPS11 = 1e-6
1054
1054
  }) => {
1055
1055
  if (si !== 0 && si !== pts.length - 2) return;
1056
1056
  const start = pts[si];
1057
1057
  const end = pts[si + 1];
1058
- const isVertical4 = Math.abs(start.x - end.x) < EPS10;
1059
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS10;
1058
+ const isVertical4 = Math.abs(start.x - end.x) < EPS11;
1059
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS11;
1060
1060
  if (!isVertical4 && !isHorizontal3) return;
1061
1061
  const segDir = isVertical4 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
1062
+ if (pts.length === 2) {
1063
+ if (isVertical4) {
1064
+ const jogYNearStart = start.y + segDir * JOG_SIZE;
1065
+ const jogYNearEnd = end.y - segDir * JOG_SIZE;
1066
+ pts.splice(
1067
+ 1,
1068
+ 0,
1069
+ { x: start.x, y: jogYNearStart },
1070
+ { x: start.x + offset, y: jogYNearStart },
1071
+ { x: end.x + offset, y: jogYNearEnd },
1072
+ { x: end.x, y: jogYNearEnd }
1073
+ );
1074
+ } else {
1075
+ const jogXNearStart = start.x + segDir * JOG_SIZE;
1076
+ const jogXNearEnd = end.x - segDir * JOG_SIZE;
1077
+ pts.splice(
1078
+ 1,
1079
+ 0,
1080
+ { x: jogXNearStart, y: start.y },
1081
+ { x: jogXNearStart, y: start.y + offset },
1082
+ { x: jogXNearEnd, y: end.y + offset },
1083
+ { x: jogXNearEnd, y: end.y }
1084
+ );
1085
+ }
1086
+ return;
1087
+ }
1062
1088
  if (si === 0) {
1063
1089
  if (isVertical4) {
1064
1090
  const jogY = start.y + segDir * JOG_SIZE;
@@ -1103,15 +1129,18 @@ var applyJogToTerminalSegment = ({
1103
1129
  };
1104
1130
 
1105
1131
  // lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
1132
+ var EPS4 = 1e-6;
1106
1133
  var TraceOverlapIssueSolver = class extends BaseSolver {
1107
1134
  overlappingTraceSegments;
1108
1135
  traceNetIslands;
1136
+ obstacleRects;
1109
1137
  SHIFT_DISTANCE = 0.1;
1110
1138
  correctedTraceMap = {};
1111
1139
  constructor(params) {
1112
1140
  super();
1113
1141
  this.overlappingTraceSegments = params.overlappingTraceSegments;
1114
1142
  this.traceNetIslands = params.traceNetIslands;
1143
+ this.obstacleRects = getObstacleRects(params.inputProblem);
1115
1144
  for (const { connNetId, pathsWithOverlap } of this.overlappingTraceSegments) {
1116
1145
  for (const {
1117
1146
  solvedTracePathIndex,
@@ -1123,16 +1152,30 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1123
1152
  }
1124
1153
  }
1125
1154
  _step() {
1126
- const EPS10 = 1e-6;
1127
- const offsets = this.overlappingTraceSegments.map((_, idx) => {
1155
+ const containsStraightPinToPinTrace = (group) => group.pathsWithOverlap.some(({ solvedTracePathIndex }) => {
1156
+ const path = this.traceNetIslands[group.connNetId][solvedTracePathIndex];
1157
+ return path.tracePath.length === 2;
1158
+ });
1159
+ const groupShouldStayInPlace = this.overlappingTraceSegments.map(
1160
+ containsStraightPinToPinTrace
1161
+ );
1162
+ const someGroupCanShift = groupShouldStayInPlace.some(
1163
+ (shouldStay) => !shouldStay
1164
+ );
1165
+ const offsets = this.overlappingTraceSegments.map((group, idx) => {
1166
+ if (someGroupCanShift && groupShouldStayInPlace[idx]) return 0;
1128
1167
  const n = Math.floor(idx / 2) + 1;
1129
1168
  const signed = idx % 2 === 0 ? -n : n;
1130
- return signed * this.SHIFT_DISTANCE;
1169
+ return this.getObstacleAwareOffset({
1170
+ group,
1171
+ offset: signed * this.SHIFT_DISTANCE
1172
+ });
1131
1173
  });
1132
- const eq = (a, b) => Math.abs(a - b) < EPS10;
1174
+ const eq = (a, b) => Math.abs(a - b) < EPS4;
1133
1175
  const samePoint = (p, q) => !!p && !!q && eq(p.x, q.x) && eq(p.y, q.y);
1134
1176
  this.overlappingTraceSegments.forEach((group, gidx) => {
1135
1177
  const offset = offsets[gidx];
1178
+ if (offset === 0) return;
1136
1179
  const byPath = /* @__PURE__ */ new Map();
1137
1180
  for (const loc of group.pathsWithOverlap) {
1138
1181
  if (!byPath.has(loc.solvedTracePathIndex)) {
@@ -1144,7 +1187,6 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1144
1187
  const original = this.traceNetIslands[group.connNetId][pathIdx];
1145
1188
  const current = this.correctedTraceMap[original.mspPairId] ?? original;
1146
1189
  const pts = current.tracePath.map((p) => ({ ...p }));
1147
- const segIdxs = Array.from(segIdxSet).sort((a, b) => a - b);
1148
1190
  const segIdxsRev = Array.from(segIdxSet).sort((a, b) => a - b).reverse();
1149
1191
  const JOG_SIZE = this.SHIFT_DISTANCE;
1150
1192
  for (const si of segIdxsRev) {
@@ -1155,13 +1197,13 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1155
1197
  segmentIndex: si,
1156
1198
  offset,
1157
1199
  JOG_SIZE,
1158
- EPS: EPS10
1200
+ EPS: EPS4
1159
1201
  });
1160
1202
  } else {
1161
1203
  const start = pts[si];
1162
1204
  const end = pts[si + 1];
1163
- const isVertical4 = Math.abs(start.x - end.x) < EPS10;
1164
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS10;
1205
+ const isVertical4 = Math.abs(start.x - end.x) < EPS4;
1206
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS4;
1165
1207
  if (!isVertical4 && !isHorizontal3) continue;
1166
1208
  if (isVertical4) {
1167
1209
  start.x += offset;
@@ -1186,6 +1228,53 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1186
1228
  });
1187
1229
  this.solved = true;
1188
1230
  }
1231
+ getObstacleAwareOffset({
1232
+ group,
1233
+ offset
1234
+ }) {
1235
+ const blockingCollisions = this.getBlockingCollisions({ group, offset });
1236
+ if (blockingCollisions.length === 0) return offset;
1237
+ return blockingCollisions.flatMap(({ start, isVertical: isVertical4, obstacle }) => [
1238
+ (isVertical4 ? obstacle.minX - start.x : obstacle.minY - start.y) - this.SHIFT_DISTANCE,
1239
+ (isVertical4 ? obstacle.maxX - start.x : obstacle.maxY - start.y) + this.SHIFT_DISTANCE
1240
+ ]).filter(
1241
+ (candidateOffset) => this.getBlockingCollisions({ group, offset: candidateOffset }).length === 0
1242
+ ).sort((a, b) => Math.abs(a - offset) - Math.abs(b - offset))[0] ?? offset;
1243
+ }
1244
+ getBlockingCollisions({
1245
+ group,
1246
+ offset
1247
+ }) {
1248
+ const blockingCollisions = [];
1249
+ for (const {
1250
+ solvedTracePathIndex,
1251
+ traceSegmentIndex
1252
+ } of group.pathsWithOverlap) {
1253
+ const trace = this.traceNetIslands[group.connNetId][solvedTracePathIndex];
1254
+ const start = trace.tracePath[traceSegmentIndex];
1255
+ const end = trace.tracePath[traceSegmentIndex + 1];
1256
+ if (!start || !end) continue;
1257
+ const isVertical4 = Math.abs(start.x - end.x) < EPS4;
1258
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS4;
1259
+ if (!isVertical4 && !isHorizontal3) continue;
1260
+ const shiftedSegment = isVertical4 ? [
1261
+ { ...start, x: start.x + offset },
1262
+ { ...end, x: end.x + offset }
1263
+ ] : [
1264
+ { ...start, y: start.y + offset },
1265
+ { ...end, y: end.y + offset }
1266
+ ];
1267
+ const collision = findFirstCollision(shiftedSegment, this.obstacleRects);
1268
+ if (collision) {
1269
+ blockingCollisions.push({
1270
+ start,
1271
+ isVertical: isVertical4,
1272
+ obstacle: collision.rect
1273
+ });
1274
+ }
1275
+ }
1276
+ return blockingCollisions;
1277
+ }
1189
1278
  visualize() {
1190
1279
  const graphics = {
1191
1280
  lines: [],
@@ -1258,7 +1347,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1258
1347
  return islands;
1259
1348
  }
1260
1349
  findNextOverlapIssue() {
1261
- const EPS10 = 2e-3;
1350
+ const EPS11 = 2e-3;
1262
1351
  const netIds = Object.keys(this.traceNetIslands);
1263
1352
  for (let i = 0; i < netIds.length; i++) {
1264
1353
  for (let j = i + 1; j < netIds.length; j++) {
@@ -1276,7 +1365,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1276
1365
  const minB = Math.min(b1, b2);
1277
1366
  const maxB = Math.max(b1, b2);
1278
1367
  const overlap = Math.min(maxA, maxB) - Math.max(minA, minB);
1279
- return overlap > EPS10;
1368
+ return overlap > EPS11;
1280
1369
  };
1281
1370
  for (let pa = 0; pa < pathsA.length; pa++) {
1282
1371
  const pathA = pathsA[pa];
@@ -1284,8 +1373,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1284
1373
  for (let sa = 0; sa < ptsA.length - 1; sa++) {
1285
1374
  const a1 = ptsA[sa];
1286
1375
  const a2 = ptsA[sa + 1];
1287
- const aVert = Math.abs(a1.x - a2.x) < EPS10;
1288
- const aHorz = Math.abs(a1.y - a2.y) < EPS10;
1376
+ const aVert = Math.abs(a1.x - a2.x) < EPS11;
1377
+ const aHorz = Math.abs(a1.y - a2.y) < EPS11;
1289
1378
  if (!aVert && !aHorz) continue;
1290
1379
  for (let pb = 0; pb < pathsB.length; pb++) {
1291
1380
  const pathB = pathsB[pb];
@@ -1293,11 +1382,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1293
1382
  for (let sb = 0; sb < ptsB.length - 1; sb++) {
1294
1383
  const b1 = ptsB[sb];
1295
1384
  const b2 = ptsB[sb + 1];
1296
- const bVert = Math.abs(b1.x - b2.x) < EPS10;
1297
- const bHorz = Math.abs(b1.y - b2.y) < EPS10;
1385
+ const bVert = Math.abs(b1.x - b2.x) < EPS11;
1386
+ const bHorz = Math.abs(b1.y - b2.y) < EPS11;
1298
1387
  if (!bVert && !bHorz) continue;
1299
1388
  if (aVert && bVert) {
1300
- if (Math.abs(a1.x - b1.x) < EPS10) {
1389
+ if (Math.abs(a1.x - b1.x) < EPS11) {
1301
1390
  if (overlaps1D(a1.y, a2.y, b1.y, b2.y)) {
1302
1391
  const keyA = `${pa}:${sa}`;
1303
1392
  const keyB = `${pb}:${sb}`;
@@ -1318,7 +1407,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1318
1407
  }
1319
1408
  }
1320
1409
  } else if (aHorz && bHorz) {
1321
- if (Math.abs(a1.y - b1.y) < EPS10) {
1410
+ if (Math.abs(a1.y - b1.y) < EPS11) {
1322
1411
  if (overlaps1D(a1.x, a2.x, b1.x, b2.x)) {
1323
1412
  const keyA = `${pa}:${sa}`;
1324
1413
  const keyB = `${pb}:${sb}`;
@@ -1356,14 +1445,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1356
1445
  return null;
1357
1446
  }
1358
1447
  findNextDiagonalSegment() {
1359
- const EPS10 = 2e-3;
1448
+ const EPS11 = 2e-3;
1360
1449
  for (const mspPairId in this.correctedTraceMap) {
1361
1450
  const tracePath = this.correctedTraceMap[mspPairId].tracePath;
1362
1451
  for (let i = 0; i < tracePath.length - 1; i++) {
1363
1452
  const p1 = tracePath[i];
1364
1453
  const p2 = tracePath[i + 1];
1365
- const isHorizontal3 = Math.abs(p1.y - p2.y) < EPS10;
1366
- const isVertical4 = Math.abs(p1.x - p2.x) < EPS10;
1454
+ const isHorizontal3 = Math.abs(p1.y - p2.y) < EPS11;
1455
+ const isVertical4 = Math.abs(p1.x - p2.x) < EPS11;
1367
1456
  if (!isHorizontal3 && !isVertical4) {
1368
1457
  return { mspPairId, tracePath, i, p1, p2 };
1369
1458
  }
@@ -1377,13 +1466,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1377
1466
  return false;
1378
1467
  }
1379
1468
  const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
1380
- const EPS10 = 2e-3;
1469
+ const EPS11 = 2e-3;
1381
1470
  const p0 = i > 0 ? tracePath[i - 1] : null;
1382
1471
  const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
1383
- const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS10 : false;
1384
- const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS10 : false;
1385
- const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS10 : false;
1386
- const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS10 : false;
1472
+ const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS11 : false;
1473
+ const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS11 : false;
1474
+ const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS11 : false;
1475
+ const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS11 : false;
1387
1476
  const elbow1 = { x: p1.x, y: p2.y };
1388
1477
  const elbow2 = { x: p2.x, y: p1.y };
1389
1478
  let score1 = 0;
@@ -1428,6 +1517,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1428
1517
  }
1429
1518
  const { overlappingTraceSegments } = overlapIssue;
1430
1519
  this.activeSubSolver = new TraceOverlapIssueSolver({
1520
+ inputProblem: this.inputProblem,
1431
1521
  overlappingTraceSegments,
1432
1522
  traceNetIslands: this.traceNetIslands
1433
1523
  });
@@ -1548,24 +1638,24 @@ function getRectBounds(center, w, h) {
1548
1638
  }
1549
1639
 
1550
1640
  // lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
1551
- function segmentIntersectsRect2(p1, p2, rect, EPS10 = 1e-9) {
1552
- const isVert = Math.abs(p1.x - p2.x) < EPS10;
1553
- const isHorz = Math.abs(p1.y - p2.y) < EPS10;
1641
+ function segmentIntersectsRect2(p1, p2, rect, EPS11 = 1e-9) {
1642
+ const isVert = Math.abs(p1.x - p2.x) < EPS11;
1643
+ const isHorz = Math.abs(p1.y - p2.y) < EPS11;
1554
1644
  if (!isVert && !isHorz) return false;
1555
1645
  if (isVert) {
1556
1646
  const x = p1.x;
1557
- if (x < rect.minX - EPS10 || x > rect.maxX + EPS10) return false;
1647
+ if (x < rect.minX - EPS11 || x > rect.maxX + EPS11) return false;
1558
1648
  const segMinY = Math.min(p1.y, p2.y);
1559
1649
  const segMaxY = Math.max(p1.y, p2.y);
1560
1650
  const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
1561
- return overlap > EPS10;
1651
+ return overlap > EPS11;
1562
1652
  } else {
1563
1653
  const y = p1.y;
1564
- if (y < rect.minY - EPS10 || y > rect.maxY + EPS10) return false;
1654
+ if (y < rect.minY - EPS11 || y > rect.maxY + EPS11) return false;
1565
1655
  const segMinX = Math.min(p1.x, p2.x);
1566
1656
  const segMaxX = Math.max(p1.x, p2.x);
1567
1657
  const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
1568
- return overlap > EPS10;
1658
+ return overlap > EPS11;
1569
1659
  }
1570
1660
  }
1571
1661
  function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
@@ -1949,14 +2039,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1949
2039
  };
1950
2040
  let bestCandidate = null;
1951
2041
  let bestScore = -Infinity;
1952
- const EPS10 = 1e-6;
2042
+ const EPS11 = 1e-6;
1953
2043
  for (const curr of tracesToScan) {
1954
2044
  const pts = curr.tracePath.slice();
1955
2045
  for (let si = 0; si < pts.length - 1; si++) {
1956
2046
  const a = pts[si];
1957
2047
  const b = pts[si + 1];
1958
- const isH = Math.abs(a.y - b.y) < EPS10;
1959
- const isV = Math.abs(a.x - b.x) < EPS10;
2048
+ const isH = Math.abs(a.y - b.y) < EPS11;
2049
+ const isV = Math.abs(a.x - b.x) < EPS11;
1960
2050
  if (!isH && !isV) continue;
1961
2051
  const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
1962
2052
  const candidateOrients = orientations.filter(
@@ -2094,6 +2184,7 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2094
2184
  overlappingSameNetTraceGroups;
2095
2185
  queuedOverlappingSameNetTraceGroups;
2096
2186
  netLabelPlacements = [];
2187
+ failedGroups = [];
2097
2188
  currentGroup = null;
2098
2189
  triedAnyOrientationFallbackForCurrentGroup = false;
2099
2190
  constructor(params) {
@@ -2299,8 +2390,12 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2299
2390
  });
2300
2391
  return;
2301
2392
  }
2302
- this.failed = true;
2303
- this.error = this.activeSubSolver.error;
2393
+ if (this.currentGroup) {
2394
+ this.failedGroups.push(this.currentGroup);
2395
+ }
2396
+ this.activeSubSolver = null;
2397
+ this.currentGroup = null;
2398
+ this.triedAnyOrientationFallbackForCurrentGroup = false;
2304
2399
  return;
2305
2400
  }
2306
2401
  if (this.activeSubSolver) {
@@ -2961,6 +3056,38 @@ var generateRerouteCandidates = ({
2961
3056
 
2962
3057
  // lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver.ts
2963
3058
  var MAX_TRIES = 5;
3059
+ var COINCIDENT_EPS = 2e-3;
3060
+ var doesPathCoincideWithTraces = (path, traces) => {
3061
+ const rangesOverlap1D = (a1, a2, b1, b2) => Math.min(Math.max(a1, a2), Math.max(b1, b2)) - Math.max(Math.min(a1, a2), Math.min(b1, b2)) > COINCIDENT_EPS;
3062
+ for (let i = 0; i < path.length - 1; i++) {
3063
+ const pathSegStart = path[i];
3064
+ const pathSegEnd = path[i + 1];
3065
+ const isVertical4 = Math.abs(pathSegStart.x - pathSegEnd.x) < COINCIDENT_EPS;
3066
+ const isHorizontal3 = Math.abs(pathSegStart.y - pathSegEnd.y) < COINCIDENT_EPS;
3067
+ if (!isVertical4 && !isHorizontal3) continue;
3068
+ const crossAxis = isVertical4 ? "x" : "y";
3069
+ const alongAxis = isVertical4 ? "y" : "x";
3070
+ for (const trace of traces) {
3071
+ for (let j = 0; j < trace.tracePath.length - 1; j++) {
3072
+ const traceSegStart = trace.tracePath[j];
3073
+ const traceSegEnd = trace.tracePath[j + 1];
3074
+ const isParallel = Math.abs(traceSegStart[crossAxis] - traceSegEnd[crossAxis]) < COINCIDENT_EPS;
3075
+ if (!isParallel) continue;
3076
+ const isCoincident = Math.abs(pathSegStart[crossAxis] - traceSegStart[crossAxis]) < COINCIDENT_EPS;
3077
+ if (!isCoincident) continue;
3078
+ if (rangesOverlap1D(
3079
+ pathSegStart[alongAxis],
3080
+ pathSegEnd[alongAxis],
3081
+ traceSegStart[alongAxis],
3082
+ traceSegEnd[alongAxis]
3083
+ )) {
3084
+ return true;
3085
+ }
3086
+ }
3087
+ }
3088
+ }
3089
+ return false;
3090
+ };
2964
3091
  var SingleOverlapSolver = class extends BaseSolver {
2965
3092
  queuedCandidatePaths;
2966
3093
  solvedTracePath = null;
@@ -2968,12 +3095,14 @@ var SingleOverlapSolver = class extends BaseSolver {
2968
3095
  problem;
2969
3096
  obstacles;
2970
3097
  label;
3098
+ tracesToAvoidOverlapping;
2971
3099
  _tried = 0;
2972
3100
  constructor(solverInput) {
2973
3101
  super();
2974
3102
  this.initialTrace = solverInput.trace;
2975
3103
  this.problem = solverInput.problem;
2976
3104
  this.label = solverInput.label;
3105
+ this.tracesToAvoidOverlapping = (solverInput.tracesToAvoidOverlapping ?? []).filter((t) => t.globalConnNetId !== solverInput.trace.globalConnNetId);
2977
3106
  const effectivePadding = solverInput.paddingBuffer + solverInput.detourCount * solverInput.paddingBuffer;
2978
3107
  const candidates = generateRerouteCandidates({
2979
3108
  ...solverInput,
@@ -3002,7 +3131,7 @@ var SingleOverlapSolver = class extends BaseSolver {
3002
3131
  this._tried++;
3003
3132
  const nextCandidatePath = this.queuedCandidatePaths.shift();
3004
3133
  const simplifiedPath = simplifyPath(nextCandidatePath);
3005
- if (!isPathCollidingWithObstacles(simplifiedPath, this.obstacles)) {
3134
+ if (!isPathCollidingWithObstacles(simplifiedPath, this.obstacles) && !doesPathCoincideWithTraces(simplifiedPath, this.tracesToAvoidOverlapping)) {
3006
3135
  this.solvedTracePath = simplifiedPath;
3007
3136
  this.solved = true;
3008
3137
  }
@@ -3107,6 +3236,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
3107
3236
  mergedNetLabelPlacements;
3108
3237
  mergedLabelNetIdMap;
3109
3238
  allTraces;
3239
+ tracesToAvoidOverlapping;
3110
3240
  modifiedTraces = [];
3111
3241
  PADDING_BUFFER = 0.1;
3112
3242
  detourCounts = /* @__PURE__ */ new Map();
@@ -3122,6 +3252,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
3122
3252
  this.mergedNetLabelPlacements = solverInput.mergedNetLabelPlacements;
3123
3253
  this.mergedLabelNetIdMap = solverInput.mergedLabelNetIdMap;
3124
3254
  this.allTraces = [...solverInput.traces];
3255
+ this.tracesToAvoidOverlapping = solverInput.tracesToAvoidOverlapping ?? [];
3125
3256
  this.detourCounts = solverInput.detourCounts;
3126
3257
  }
3127
3258
  _step() {
@@ -3203,7 +3334,8 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
3203
3334
  label: actualOverlapLabel,
3204
3335
  problem: this.inputProblem,
3205
3336
  paddingBuffer: this.PADDING_BUFFER,
3206
- detourCount: detourCount2
3337
+ detourCount: detourCount2,
3338
+ tracesToAvoidOverlapping: this.tracesToAvoidOverlapping
3207
3339
  });
3208
3340
  } else {
3209
3341
  const overlapId = `${traceToFix.mspPairId}-${labelToAvoid.globalConnNetId}`;
@@ -3238,7 +3370,8 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
3238
3370
  label: actualOverlapLabel,
3239
3371
  problem: this.inputProblem,
3240
3372
  paddingBuffer: this.PADDING_BUFFER,
3241
- detourCount: detourCount2
3373
+ detourCount: detourCount2,
3374
+ tracesToAvoidOverlapping: this.tracesToAvoidOverlapping
3242
3375
  });
3243
3376
  } else {
3244
3377
  const overlapId = `${traceToFix.mspPairId}-${labelToAvoid.globalConnNetId}`;
@@ -3253,7 +3386,8 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
3253
3386
  label: labelToAvoid,
3254
3387
  problem: this.inputProblem,
3255
3388
  paddingBuffer: this.PADDING_BUFFER,
3256
- detourCount
3389
+ detourCount,
3390
+ tracesToAvoidOverlapping: this.tracesToAvoidOverlapping
3257
3391
  });
3258
3392
  }
3259
3393
  }
@@ -3321,10 +3455,12 @@ var TraceLabelOverlapAvoidanceSolver = class extends BaseSolver {
3321
3455
  phase = "searching_for_overlaps";
3322
3456
  detourCounts = /* @__PURE__ */ new Map();
3323
3457
  labelMergingSolver;
3458
+ allInputTraces;
3324
3459
  constructor(solverInput) {
3325
3460
  super();
3326
3461
  this.inputProblem = solverInput.inputProblem;
3327
3462
  this.unprocessedTraces = [...solverInput.traces];
3463
+ this.allInputTraces = solverInput.traces;
3328
3464
  this.netLabelPlacements = solverInput.netLabelPlacements;
3329
3465
  this.cleanTraces = [];
3330
3466
  this.subSolvers = [];
@@ -3360,7 +3496,10 @@ var TraceLabelOverlapAvoidanceSolver = class extends BaseSolver {
3360
3496
  initialNetLabelPlacements: this.netLabelPlacements,
3361
3497
  mergedNetLabelPlacements: mergingOutput.netLabelPlacements,
3362
3498
  mergedLabelNetIdMap: mergingOutput.mergedLabelNetIdMap,
3363
- detourCounts: this.detourCounts
3499
+ detourCounts: this.detourCounts,
3500
+ tracesToAvoidOverlapping: this.allInputTraces.filter(
3501
+ (t) => t.mspPairId !== currentTargetTrace.mspPairId
3502
+ )
3364
3503
  });
3365
3504
  this.subSolvers.push(subSolver);
3366
3505
  }
@@ -4172,8 +4311,8 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
4172
4311
  };
4173
4312
 
4174
4313
  // lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
4175
- var EPS4 = 1e-6;
4176
- var isVertical2 = (a, b, eps = EPS4) => Math.abs(a.x - b.x) < eps;
4314
+ var EPS5 = 1e-6;
4315
+ var isVertical2 = (a, b, eps = EPS5) => Math.abs(a.x - b.x) < eps;
4177
4316
  var generateLShapeRerouteCandidates = ({
4178
4317
  lShape,
4179
4318
  rectangle,
@@ -4186,7 +4325,7 @@ var generateLShapeRerouteCandidates = ({
4186
4325
  let c2;
4187
4326
  let i1_padded = interactionPoint1;
4188
4327
  let i2_padded = interactionPoint2;
4189
- if (Math.abs(p2.x - x) < EPS4 && Math.abs(p2.y - (y + height)) < EPS4) {
4328
+ if (Math.abs(p2.x - x) < EPS5 && Math.abs(p2.y - (y + height)) < EPS5) {
4190
4329
  c2 = { x: x + width + padding, y: y - padding };
4191
4330
  if (isVertical2(p1, p2)) {
4192
4331
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -4198,7 +4337,7 @@ var generateLShapeRerouteCandidates = ({
4198
4337
  } else {
4199
4338
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
4200
4339
  }
4201
- } else if (Math.abs(p2.x - (x + width)) < EPS4 && Math.abs(p2.y - (y + height)) < EPS4) {
4340
+ } else if (Math.abs(p2.x - (x + width)) < EPS5 && Math.abs(p2.y - (y + height)) < EPS5) {
4202
4341
  c2 = { x: x - padding, y: y - padding };
4203
4342
  if (isVertical2(p1, p2)) {
4204
4343
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -4210,7 +4349,7 @@ var generateLShapeRerouteCandidates = ({
4210
4349
  } else {
4211
4350
  i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
4212
4351
  }
4213
- } else if (Math.abs(p2.x - x) < EPS4 && Math.abs(p2.y - y) < EPS4) {
4352
+ } else if (Math.abs(p2.x - x) < EPS5 && Math.abs(p2.y - y) < EPS5) {
4214
4353
  c2 = { x: x + width + padding, y: y + height + padding };
4215
4354
  if (isVertical2(p1, p2)) {
4216
4355
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -4222,7 +4361,7 @@ var generateLShapeRerouteCandidates = ({
4222
4361
  } else {
4223
4362
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
4224
4363
  }
4225
- } else if (Math.abs(p2.x - (x + width)) < EPS4 && Math.abs(p2.y - y) < EPS4) {
4364
+ } else if (Math.abs(p2.x - (x + width)) < EPS5 && Math.abs(p2.y - y) < EPS5) {
4226
4365
  c2 = { x: x - padding, y: y + height + padding };
4227
4366
  if (isVertical2(p1, p2)) {
4228
4367
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -4667,9 +4806,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
4667
4806
  };
4668
4807
 
4669
4808
  // lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
4670
- var EPS5 = 1e-6;
4671
- var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS5;
4672
- var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS5;
4809
+ var EPS6 = 1e-6;
4810
+ var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS6;
4811
+ var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS6;
4673
4812
  var is4PointRectangle = (path) => {
4674
4813
  if (path.length !== 4) return false;
4675
4814
  const [p0, p1, p2, p3] = path;
@@ -4803,7 +4942,7 @@ var TraceCleanupSolver = class extends BaseSolver {
4803
4942
  };
4804
4943
 
4805
4944
  // lib/solvers/Example28Solver/types.ts
4806
- var EPS6 = 1e-9;
4945
+ var EPS7 = 1e-9;
4807
4946
 
4808
4947
  // lib/solvers/Example28Solver/geometry.ts
4809
4948
  var getPathKey = (path) => path.map((point) => `${point.x},${point.y}`).join(";");
@@ -4815,10 +4954,10 @@ var getPathLength = (path) => {
4815
4954
  return length;
4816
4955
  };
4817
4956
  var getDistance = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
4818
- var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS6 || Math.abs(start.y - end.y) < EPS6;
4819
- var getSegmentOrientation = (start, end) => Math.abs(start.y - end.y) < EPS6 ? "horizontal" : "vertical";
4957
+ var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS7 || Math.abs(start.y - end.y) < EPS7;
4958
+ var getSegmentOrientation = (start, end) => Math.abs(start.y - end.y) < EPS7 ? "horizontal" : "vertical";
4820
4959
  var projectPointToSegment = (point, start, end) => {
4821
- if (Math.abs(start.x - end.x) < EPS6) {
4960
+ if (Math.abs(start.x - end.x) < EPS7) {
4822
4961
  return {
4823
4962
  x: start.x,
4824
4963
  y: Math.min(
@@ -4827,7 +4966,7 @@ var projectPointToSegment = (point, start, end) => {
4827
4966
  )
4828
4967
  };
4829
4968
  }
4830
- if (Math.abs(start.y - end.y) < EPS6) {
4969
+ if (Math.abs(start.y - end.y) < EPS7) {
4831
4970
  return {
4832
4971
  x: Math.min(
4833
4972
  Math.max(point.x, Math.min(start.x, end.x)),
@@ -4870,9 +5009,9 @@ var findSegmentContainingPoint = (path, point) => {
4870
5009
  };
4871
5010
  var isPointWithinSegmentPrimaryRange = (point, segment) => {
4872
5011
  if (segment.orientation === "horizontal") {
4873
- return point.x >= Math.min(segment.start.x, segment.end.x) - EPS6 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS6;
5012
+ return point.x >= Math.min(segment.start.x, segment.end.x) - EPS7 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS7;
4874
5013
  }
4875
- return point.y >= Math.min(segment.start.y, segment.end.y) - EPS6 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS6;
5014
+ return point.y >= Math.min(segment.start.y, segment.end.y) - EPS7 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS7;
4876
5015
  };
4877
5016
  var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
4878
5017
  const matchingSegments = getSegments(path).filter(
@@ -4900,18 +5039,18 @@ var projectPointToPath = (point, path) => {
4900
5039
  return bestPoint;
4901
5040
  };
4902
5041
  var segmentsIntersect = (a1, a2, b1, b2) => {
4903
- const aVertical = Math.abs(a1.x - a2.x) < EPS6;
4904
- const bVertical = Math.abs(b1.x - b2.x) < EPS6;
4905
- const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS6 && value <= Math.max(p1, p2) + EPS6;
5042
+ const aVertical = Math.abs(a1.x - a2.x) < EPS7;
5043
+ const bVertical = Math.abs(b1.x - b2.x) < EPS7;
5044
+ const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS7 && value <= Math.max(p1, p2) + EPS7;
4906
5045
  if (aVertical && bVertical) {
4907
- if (Math.abs(a1.x - b1.x) > EPS6) return false;
5046
+ if (Math.abs(a1.x - b1.x) > EPS7) return false;
4908
5047
  const overlap = Math.min(Math.max(a1.y, a2.y), Math.max(b1.y, b2.y)) - Math.max(Math.min(a1.y, a2.y), Math.min(b1.y, b2.y));
4909
- return overlap > EPS6;
5048
+ return overlap > EPS7;
4910
5049
  }
4911
5050
  if (!aVertical && !bVertical) {
4912
- if (Math.abs(a1.y - b1.y) > EPS6) return false;
5051
+ if (Math.abs(a1.y - b1.y) > EPS7) return false;
4913
5052
  const overlap = Math.min(Math.max(a1.x, a2.x), Math.max(b1.x, b2.x)) - Math.max(Math.min(a1.x, a2.x), Math.min(b1.x, b2.x));
4914
- return overlap > EPS6;
5053
+ return overlap > EPS7;
4915
5054
  }
4916
5055
  const verticalA = aVertical ? a1 : b1;
4917
5056
  const verticalB = aVertical ? a2 : b2;
@@ -4943,13 +5082,13 @@ var isPathCollidingWithChipInterior = (path, chipObstacles) => {
4943
5082
  return false;
4944
5083
  };
4945
5084
  var segmentRunsAlongRectBoundary = (start, end, rect) => {
4946
- const isVertical4 = Math.abs(start.x - end.x) < EPS6;
4947
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS6;
5085
+ const isVertical4 = Math.abs(start.x - end.x) < EPS7;
5086
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS7;
4948
5087
  if (isVertical4) {
4949
- return Math.abs(start.x - rect.minX) < EPS6 || Math.abs(start.x - rect.maxX) < EPS6;
5088
+ return Math.abs(start.x - rect.minX) < EPS7 || Math.abs(start.x - rect.maxX) < EPS7;
4950
5089
  }
4951
5090
  if (isHorizontal3) {
4952
- return Math.abs(start.y - rect.minY) < EPS6 || Math.abs(start.y - rect.maxY) < EPS6;
5091
+ return Math.abs(start.y - rect.minY) < EPS7 || Math.abs(start.y - rect.maxY) < EPS7;
4953
5092
  }
4954
5093
  return false;
4955
5094
  };
@@ -5573,16 +5712,16 @@ var Example28Solver = class extends BaseSolver {
5573
5712
  // lib/solvers/AvailableNetOrientationSolver/constants.ts
5574
5713
  var LABEL_SEARCH_STEP = 0.05;
5575
5714
  var WICK_CLEARANCE = 1e-3;
5576
- var EPS7 = 1e-9;
5577
- var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS7;
5715
+ var EPS8 = 1e-9;
5716
+ var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS8;
5578
5717
  var CANDIDATE_SELECTED_COLOR2 = "blue";
5579
5718
  var CANDIDATE_REJECTED_COLOR2 = "red";
5580
5719
 
5581
5720
  // lib/solvers/AvailableNetOrientationSolver/geometry.ts
5582
5721
  var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
5583
5722
  var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
5584
- var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS7 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS7;
5585
- var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS7;
5723
+ var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
5724
+ var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS8;
5586
5725
  var traceCrossesBoundsInterior = (bounds, traceMap) => {
5587
5726
  for (const trace of Object.values(traceMap)) {
5588
5727
  const points = trace.tracePath;
@@ -5605,7 +5744,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
5605
5744
  return false;
5606
5745
  }
5607
5746
  if (sameX2(p1, p2)) {
5608
- if (p1.x <= interiorBounds.minX + EPS7 || p1.x >= interiorBounds.maxX - EPS7) {
5747
+ if (p1.x <= interiorBounds.minX + EPS8 || p1.x >= interiorBounds.maxX - EPS8) {
5609
5748
  return false;
5610
5749
  }
5611
5750
  return rangesOverlap(
@@ -5616,7 +5755,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
5616
5755
  );
5617
5756
  }
5618
5757
  if (sameY2(p1, p2)) {
5619
- if (p1.y <= interiorBounds.minY + EPS7 || p1.y >= interiorBounds.maxY - EPS7) {
5758
+ if (p1.y <= interiorBounds.minY + EPS8 || p1.y >= interiorBounds.maxY - EPS8) {
5620
5759
  return false;
5621
5760
  }
5622
5761
  return rangesOverlap(
@@ -5664,10 +5803,10 @@ var tracePathCrossesAnyTrace = (tracePath, traceMap) => {
5664
5803
  };
5665
5804
  var segmentsStrictlyCross = (a1, a2, b1, b2) => {
5666
5805
  if (sameX2(a1, a2) && sameY2(b1, b2)) {
5667
- return a1.x > Math.min(b1.x, b2.x) + EPS7 && a1.x < Math.max(b1.x, b2.x) - EPS7 && b1.y > Math.min(a1.y, a2.y) + EPS7 && b1.y < Math.max(a1.y, a2.y) - EPS7;
5806
+ return a1.x > Math.min(b1.x, b2.x) + EPS8 && a1.x < Math.max(b1.x, b2.x) - EPS8 && b1.y > Math.min(a1.y, a2.y) + EPS8 && b1.y < Math.max(a1.y, a2.y) - EPS8;
5668
5807
  }
5669
5808
  if (sameY2(a1, a2) && sameX2(b1, b2)) {
5670
- return b1.x > Math.min(a1.x, a2.x) + EPS7 && b1.x < Math.max(a1.x, a2.x) - EPS7 && a1.y > Math.min(b1.y, b2.y) + EPS7 && a1.y < Math.max(b1.y, b2.y) - EPS7;
5809
+ return b1.x > Math.min(a1.x, a2.x) + EPS8 && b1.x < Math.max(a1.x, a2.x) - EPS8 && a1.y > Math.min(b1.y, b2.y) + EPS8 && a1.y < Math.max(b1.y, b2.y) - EPS8;
5671
5810
  }
5672
5811
  return false;
5673
5812
  };
@@ -5699,8 +5838,8 @@ var simplifyOrthogonalPath = (path) => {
5699
5838
  return simplified;
5700
5839
  };
5701
5840
  var pointsEqual = (a, b) => sameX2(a, b) && sameY2(a, b);
5702
- var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS7;
5703
- var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS7;
5841
+ var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS8;
5842
+ var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS8;
5704
5843
  var getMaxSearchDistance = (inputProblem) => {
5705
5844
  const maxChipWidth = Math.max(
5706
5845
  ...inputProblem.chips.map((chip) => chip.width),
@@ -5988,7 +6127,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
5988
6127
  );
5989
6128
  const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
5990
6129
  const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
5991
- for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS7; outwardDistance += LABEL_SEARCH_STEP) {
6130
+ for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS8; outwardDistance += LABEL_SEARCH_STEP) {
5992
6131
  const baseAnchor = {
5993
6132
  x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
5994
6133
  y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
@@ -6061,7 +6200,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6061
6200
  outwardDistance,
6062
6201
  phase = "shift"
6063
6202
  } = params;
6064
- for (let distance3 = LABEL_SEARCH_STEP; distance3 <= maxSearchDistance + EPS7; distance3 += LABEL_SEARCH_STEP) {
6203
+ for (let distance3 = LABEL_SEARCH_STEP; distance3 <= maxSearchDistance + EPS8; distance3 += LABEL_SEARCH_STEP) {
6065
6204
  const anchorPoint = {
6066
6205
  x: baseAnchor.x + direction.x * distance3,
6067
6206
  y: baseAnchor.y + direction.y * distance3
@@ -6299,8 +6438,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6299
6438
  sharesChipBoundary(bounds) {
6300
6439
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6301
6440
  const chipBounds = chip.bounds;
6302
- const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS7 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS7;
6303
- const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS7 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS7;
6441
+ const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS8;
6442
+ const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS8;
6304
6443
  if (adjacentToVerticalSide && rangesOverlap(
6305
6444
  bounds.minY,
6306
6445
  bounds.maxY,
@@ -6348,7 +6487,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6348
6487
  let nearestDistance = Number.POSITIVE_INFINITY;
6349
6488
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6350
6489
  const bounds = chip.bounds;
6351
- if (point.x < bounds.minX - EPS7 || point.x > bounds.maxX + EPS7 || point.y < bounds.minY - EPS7 || point.y > bounds.maxY + EPS7) {
6490
+ if (point.x < bounds.minX - EPS8 || point.x > bounds.maxX + EPS8 || point.y < bounds.minY - EPS8 || point.y > bounds.maxY + EPS8) {
6352
6491
  continue;
6353
6492
  }
6354
6493
  for (const [side, distance3] of getSideDistances(point, bounds)) {
@@ -6365,8 +6504,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6365
6504
  let nearestDistanceSq = Number.POSITIVE_INFINITY;
6366
6505
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6367
6506
  const bounds = chip.bounds;
6368
- const dx = point.x < bounds.minX - EPS7 ? bounds.minX - point.x : point.x > bounds.maxX + EPS7 ? point.x - bounds.maxX : 0;
6369
- const dy = point.y < bounds.minY - EPS7 ? bounds.minY - point.y : point.y > bounds.maxY + EPS7 ? point.y - bounds.maxY : 0;
6507
+ const dx = point.x < bounds.minX - EPS8 ? bounds.minX - point.x : point.x > bounds.maxX + EPS8 ? point.x - bounds.maxX : 0;
6508
+ const dy = point.y < bounds.minY - EPS8 ? bounds.minY - point.y : point.y > bounds.maxY + EPS8 ? point.y - bounds.maxY : 0;
6370
6509
  if (dx === 0 && dy === 0) continue;
6371
6510
  const distanceSq = dx ** 2 + dy ** 2;
6372
6511
  if (distanceSq >= nearestDistanceSq) continue;
@@ -6405,9 +6544,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6405
6544
  };
6406
6545
 
6407
6546
  // lib/solvers/VccNetLabelCornerPlacementSolver/geometry.ts
6408
- var EPS8 = 1e-6;
6547
+ var EPS9 = 1e-6;
6409
6548
  var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
6410
- var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
6549
+ 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;
6411
6550
  var getTraceCorners = (path) => {
6412
6551
  const corners = [];
6413
6552
  for (let i = 1; i < path.length - 1; i++) {
@@ -6431,11 +6570,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
6431
6570
  var isTraceCorner = (a, b, c) => getSegmentOrientation2(a, b) !== getSegmentOrientation2(b, c);
6432
6571
  var isPointOnSegment = (point, start, end) => {
6433
6572
  if (getSegmentOrientation2(start, end) === "horizontal") {
6434
- return Math.abs(point.y - start.y) <= EPS8 && point.x >= Math.min(start.x, end.x) - EPS8 && point.x <= Math.max(start.x, end.x) + EPS8;
6573
+ return Math.abs(point.y - start.y) <= EPS9 && point.x >= Math.min(start.x, end.x) - EPS9 && point.x <= Math.max(start.x, end.x) + EPS9;
6435
6574
  }
6436
- return Math.abs(point.x - start.x) <= EPS8 && point.y >= Math.min(start.y, end.y) - EPS8 && point.y <= Math.max(start.y, end.y) + EPS8;
6575
+ return Math.abs(point.x - start.x) <= EPS9 && point.y >= Math.min(start.y, end.y) - EPS9 && point.y <= Math.max(start.y, end.y) + EPS9;
6437
6576
  };
6438
- var getSegmentOrientation2 = (a, b) => Math.abs(a.y - b.y) <= EPS8 ? "horizontal" : "vertical";
6577
+ var getSegmentOrientation2 = (a, b) => Math.abs(a.y - b.y) <= EPS9 ? "horizontal" : "vertical";
6439
6578
 
6440
6579
  // lib/solvers/VccNetLabelCornerPlacementSolver/visualize.ts
6441
6580
  var CANDIDATE_SELECTED_COLOR3 = "blue";
@@ -6713,11 +6852,11 @@ var VccNetLabelCornerPlacementSolver = class extends BaseSolver {
6713
6852
  };
6714
6853
 
6715
6854
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
6716
- var EPS9 = 1e-6;
6855
+ var EPS10 = 1e-6;
6717
6856
  var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
6718
6857
  var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
6719
- var rectsOverlap3 = (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;
6720
- var rectsTouchOrOverlap = (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;
6858
+ 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;
6859
+ 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;
6721
6860
  var traceCrossesBoundsInterior2 = (bounds, traces) => {
6722
6861
  for (const trace of traces) {
6723
6862
  const points = trace.tracePath;
@@ -6763,7 +6902,7 @@ var getPointAtTraceDistance = (trace, distance3) => {
6763
6902
  const end = trace.tracePath[i + 1];
6764
6903
  const segmentLength = getManhattanDistance(start, end);
6765
6904
  const nextDistance = pathDistance + segmentLength;
6766
- if (distance3 <= nextDistance + EPS9) {
6905
+ if (distance3 <= nextDistance + EPS10) {
6767
6906
  const offset = Math.max(
6768
6907
  0,
6769
6908
  Math.min(segmentLength, distance3 - pathDistance)
@@ -6802,7 +6941,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6802
6941
  return false;
6803
6942
  }
6804
6943
  if (isVertical3(start, end)) {
6805
- if (start.x <= interior.minX + EPS9 || start.x >= interior.maxX - EPS9) {
6944
+ if (start.x <= interior.minX + EPS10 || start.x >= interior.maxX - EPS10) {
6806
6945
  return false;
6807
6946
  }
6808
6947
  return rangesOverlap2(
@@ -6813,7 +6952,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6813
6952
  );
6814
6953
  }
6815
6954
  if (isHorizontal2(start, end)) {
6816
- if (start.y <= interior.minY + EPS9 || start.y >= interior.maxY - EPS9) {
6955
+ if (start.y <= interior.minY + EPS10 || start.y >= interior.maxY - EPS10) {
6817
6956
  return false;
6818
6957
  }
6819
6958
  return rangesOverlap2(
@@ -6827,10 +6966,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6827
6966
  };
6828
6967
  var isPointOnSegment2 = (point, start, end) => {
6829
6968
  if (isHorizontal2(start, end)) {
6830
- return Math.abs(point.y - start.y) <= EPS9 && point.x >= Math.min(start.x, end.x) - EPS9 && point.x <= Math.max(start.x, end.x) + EPS9;
6969
+ 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;
6831
6970
  }
6832
6971
  if (isVertical3(start, end)) {
6833
- return Math.abs(point.x - start.x) <= EPS9 && point.y >= Math.min(start.y, end.y) - EPS9 && point.y <= Math.max(start.y, end.y) + EPS9;
6972
+ 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;
6834
6973
  }
6835
6974
  return false;
6836
6975
  };
@@ -6838,9 +6977,9 @@ var getSegmentDirection = (start, end) => ({
6838
6977
  x: isVertical3(start, end) ? 0 : Math.sign(end.x - start.x),
6839
6978
  y: isHorizontal2(start, end) ? 0 : Math.sign(end.y - start.y)
6840
6979
  });
6841
- var isHorizontal2 = (start, end) => Math.abs(start.y - end.y) <= EPS9;
6842
- var isVertical3 = (start, end) => Math.abs(start.x - end.x) <= EPS9;
6843
- var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS9;
6980
+ var isHorizontal2 = (start, end) => Math.abs(start.y - end.y) <= EPS10;
6981
+ var isVertical3 = (start, end) => Math.abs(start.x - end.x) <= EPS10;
6982
+ var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS10;
6844
6983
  var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
6845
6984
 
6846
6985
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
@@ -6897,7 +7036,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
6897
7036
  for (const distance3 of vertexDistances) {
6898
7037
  distances.add(roundDistance(distance3));
6899
7038
  }
6900
- return [...distances].filter((distance3) => distance3 >= -EPS9 && distance3 <= traceLength + EPS9).sort((a, b) => a - b);
7039
+ return [...distances].filter((distance3) => distance3 >= -EPS10 && distance3 <= traceLength + EPS10).sort((a, b) => a - b);
6901
7040
  };
6902
7041
  var getOrientationsForPoint = (params) => {
6903
7042
  const { inputProblem, label, point, orientationConstraint } = params;
@@ -7006,13 +7145,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
7006
7145
  };
7007
7146
  var getOutwardAxisOption = (params) => {
7008
7147
  const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
7009
- if (value > max + EPS9) {
7148
+ if (value > max + EPS10) {
7010
7149
  return {
7011
7150
  orientation: positiveOrientation,
7012
7151
  outwardScore: 1 + value - max
7013
7152
  };
7014
7153
  }
7015
- if (value < min - EPS9) {
7154
+ if (value < min - EPS10) {
7016
7155
  return {
7017
7156
  orientation: negativeOrientation,
7018
7157
  outwardScore: 1 + min - value
@@ -7023,7 +7162,7 @@ var getOutwardAxisOption = (params) => {
7023
7162
  outwardScore: getNormalizedCenterDistance(value, center, max - min)
7024
7163
  };
7025
7164
  };
7026
- var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS9, span / 2);
7165
+ var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS10, span / 2);
7027
7166
  var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
7028
7167
  var getFlippedOrientation = (orientation) => {
7029
7168
  switch (orientation) {
@@ -7118,7 +7257,7 @@ var normalizeFacingDirection = (value) => {
7118
7257
  var dedupeStrings = (values) => [
7119
7258
  ...new Set(values.filter((value) => value !== void 0))
7120
7259
  ];
7121
- var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS9 && Math.abs(point.y - label.anchorPoint.y) <= EPS9 && orientation === label.orientation;
7260
+ var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS10 && Math.abs(point.y - label.anchorPoint.y) <= EPS10 && orientation === label.orientation;
7122
7261
 
7123
7262
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
7124
7263
  var CANDIDATE_SELECTED_COLOR4 = "blue";