@tscircuit/schematic-trace-solver 0.0.178 → 0.0.179

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.d.ts CHANGED
@@ -900,6 +900,12 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
900
900
  private evaluateCandidate;
901
901
  private recordCandidateResult;
902
902
  private getCandidateConnectorTrace;
903
+ /**
904
+ * A laterally shifted label can branch directly from the interior of its
905
+ * existing host trace. Prefer that tee over running a new connector beside
906
+ * the host trace from the old label anchor.
907
+ */
908
+ private findProjectedConnectorSourceOnHostTrace;
903
909
  private isStandaloneSinglePinNetLabel;
904
910
  private labelIntersectsDifferentNetTrace;
905
911
  private getSearchStartAnchor;
package/dist/index.js CHANGED
@@ -9784,11 +9784,16 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
9784
9784
  x: baseAnchor.x + direction.x * distance7,
9785
9785
  y: baseAnchor.y + direction.y * distance7
9786
9786
  };
9787
+ const projectedConnectorSource = connectorSource ?? (phase === "lateral-shift" ? this.findProjectedConnectorSourceOnHostTrace(
9788
+ label,
9789
+ anchorPoint,
9790
+ orientation
9791
+ ) : void 0);
9787
9792
  const candidate = this.createCandidate(
9788
9793
  label,
9789
9794
  anchorPoint,
9790
9795
  orientation,
9791
- connectorSource
9796
+ projectedConnectorSource
9792
9797
  );
9793
9798
  const result = this.evaluateCandidate(
9794
9799
  candidate,
@@ -9842,6 +9847,13 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
9842
9847
  candidate.anchorPoint
9843
9848
  ]);
9844
9849
  }
9850
+ if (candidate.connectorSource) {
9851
+ return getConnectorTracePath(
9852
+ candidate.connectorSource,
9853
+ candidate.anchorPoint,
9854
+ candidate.orientation
9855
+ );
9856
+ }
9845
9857
  if (candidate.phase === "lateral-shift") {
9846
9858
  const chipOutwardDir = this.crowdedPortOnlyLabelIndices.has(labelIndex) ? this.getChipOutwardDirection(label.anchorPoint) : (() => {
9847
9859
  const orientDir = dir(candidate.orientation);
@@ -9861,11 +9873,41 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
9861
9873
  ]);
9862
9874
  }
9863
9875
  return getConnectorTracePath(
9864
- candidate.connectorSource ?? label.anchorPoint,
9876
+ label.anchorPoint,
9865
9877
  candidate.anchorPoint,
9866
9878
  candidate.orientation
9867
9879
  );
9868
9880
  }
9881
+ /**
9882
+ * A laterally shifted label can branch directly from the interior of its
9883
+ * existing host trace. Prefer that tee over running a new connector beside
9884
+ * the host trace from the old label anchor.
9885
+ */
9886
+ findProjectedConnectorSourceOnHostTrace(label, targetAnchor, orientation) {
9887
+ const orientationDirection = dir(orientation);
9888
+ const projectedSources = [];
9889
+ for (const traceId of label.mspConnectionPairIds) {
9890
+ const hostTrace = this.traceMap[traceId];
9891
+ if (!hostTrace) continue;
9892
+ for (let pointIndex = 0; pointIndex < hostTrace.tracePath.length - 1; pointIndex++) {
9893
+ const start = hostTrace.tracePath[pointIndex];
9894
+ const end = hostTrace.tracePath[pointIndex + 1];
9895
+ const segmentIsPerpendicularToLabel = isYOrientation(orientation) ? Math.abs(start.y - end.y) <= EPS13 : Math.abs(start.x - end.x) <= EPS13;
9896
+ if (!segmentIsPerpendicularToLabel) continue;
9897
+ const source = isYOrientation(orientation) ? { x: targetAnchor.x, y: start.y } : { x: start.x, y: targetAnchor.y };
9898
+ if (!tracePathContainsPoint([start, end], label.anchorPoint) || !tracePathContainsPoint([start, end], source)) {
9899
+ continue;
9900
+ }
9901
+ const targetDistanceAlongOrientation = (targetAnchor.x - source.x) * orientationDirection.x + (targetAnchor.y - source.y) * orientationDirection.y;
9902
+ if (targetDistanceAlongOrientation >= -EPS13) {
9903
+ projectedSources.push(source);
9904
+ }
9905
+ }
9906
+ }
9907
+ return projectedSources.sort(
9908
+ (first, second) => Math.abs(first.x - targetAnchor.x) + Math.abs(first.y - targetAnchor.y) - (Math.abs(second.x - targetAnchor.x) + Math.abs(second.y - targetAnchor.y))
9909
+ )[0];
9910
+ }
9869
9911
  isStandaloneSinglePinNetLabel(label) {
9870
9912
  return this.inputProblem.netConnections.some(
9871
9913
  (connection) => connection.netId === label.netId && connection.pinIds.length === 1 && connection.pinIds[0] === label.pinIds[0]
@@ -10069,6 +10111,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
10069
10111
  label,
10070
10112
  {
10071
10113
  anchorPoint: candidate.anchorPoint,
10114
+ connectorSource: phase === "lateral-shift" ? candidate.connectorSource : void 0,
10072
10115
  orientation: candidate.orientation,
10073
10116
  phase
10074
10117
  },
@@ -1076,11 +1076,20 @@ export class AvailableNetOrientationSolver extends BaseSolver {
1076
1076
  x: baseAnchor.x + direction.x * distance,
1077
1077
  y: baseAnchor.y + direction.y * distance,
1078
1078
  }
1079
+ const projectedConnectorSource =
1080
+ connectorSource ??
1081
+ (phase === "lateral-shift"
1082
+ ? this.findProjectedConnectorSourceOnHostTrace(
1083
+ label,
1084
+ anchorPoint,
1085
+ orientation,
1086
+ )
1087
+ : undefined)
1079
1088
  const candidate = this.createCandidate(
1080
1089
  label,
1081
1090
  anchorPoint,
1082
1091
  orientation,
1083
- connectorSource,
1092
+ projectedConnectorSource,
1084
1093
  )
1085
1094
  const result = this.evaluateCandidate(
1086
1095
  candidate,
@@ -1163,6 +1172,14 @@ export class AvailableNetOrientationSolver extends BaseSolver {
1163
1172
  ])
1164
1173
  }
1165
1174
 
1175
+ if (candidate.connectorSource) {
1176
+ return getConnectorTracePath(
1177
+ candidate.connectorSource,
1178
+ candidate.anchorPoint,
1179
+ candidate.orientation,
1180
+ )
1181
+ }
1182
+
1166
1183
  if (candidate.phase === "lateral-shift") {
1167
1184
  const chipOutwardDir = this.crowdedPortOnlyLabelIndices.has(labelIndex)
1168
1185
  ? this.getChipOutwardDirection(label.anchorPoint)
@@ -1185,12 +1202,69 @@ export class AvailableNetOrientationSolver extends BaseSolver {
1185
1202
  }
1186
1203
 
1187
1204
  return getConnectorTracePath(
1188
- candidate.connectorSource ?? label.anchorPoint,
1205
+ label.anchorPoint,
1189
1206
  candidate.anchorPoint,
1190
1207
  candidate.orientation,
1191
1208
  )
1192
1209
  }
1193
1210
 
1211
+ /**
1212
+ * A laterally shifted label can branch directly from the interior of its
1213
+ * existing host trace. Prefer that tee over running a new connector beside
1214
+ * the host trace from the old label anchor.
1215
+ */
1216
+ private findProjectedConnectorSourceOnHostTrace(
1217
+ label: NetLabelPlacement,
1218
+ targetAnchor: Point,
1219
+ orientation: FacingDirection,
1220
+ ): Point | undefined {
1221
+ const orientationDirection = dir(orientation)
1222
+ const projectedSources: Point[] = []
1223
+
1224
+ for (const traceId of label.mspConnectionPairIds) {
1225
+ const hostTrace = this.traceMap[traceId]
1226
+ if (!hostTrace) continue
1227
+
1228
+ for (
1229
+ let pointIndex = 0;
1230
+ pointIndex < hostTrace.tracePath.length - 1;
1231
+ pointIndex++
1232
+ ) {
1233
+ const start = hostTrace.tracePath[pointIndex]!
1234
+ const end = hostTrace.tracePath[pointIndex + 1]!
1235
+ const segmentIsPerpendicularToLabel = isYOrientation(orientation)
1236
+ ? Math.abs(start.y - end.y) <= EPS
1237
+ : Math.abs(start.x - end.x) <= EPS
1238
+ if (!segmentIsPerpendicularToLabel) continue
1239
+
1240
+ const source = isYOrientation(orientation)
1241
+ ? { x: targetAnchor.x, y: start.y }
1242
+ : { x: start.x, y: targetAnchor.y }
1243
+ if (
1244
+ !tracePathContainsPoint([start, end], label.anchorPoint) ||
1245
+ !tracePathContainsPoint([start, end], source)
1246
+ ) {
1247
+ continue
1248
+ }
1249
+
1250
+ const targetDistanceAlongOrientation =
1251
+ (targetAnchor.x - source.x) * orientationDirection.x +
1252
+ (targetAnchor.y - source.y) * orientationDirection.y
1253
+ if (targetDistanceAlongOrientation >= -EPS) {
1254
+ projectedSources.push(source)
1255
+ }
1256
+ }
1257
+ }
1258
+
1259
+ return projectedSources.sort(
1260
+ (first, second) =>
1261
+ Math.abs(first.x - targetAnchor.x) +
1262
+ Math.abs(first.y - targetAnchor.y) -
1263
+ (Math.abs(second.x - targetAnchor.x) +
1264
+ Math.abs(second.y - targetAnchor.y)),
1265
+ )[0]
1266
+ }
1267
+
1194
1268
  private isStandaloneSinglePinNetLabel(label: NetLabelPlacement) {
1195
1269
  return this.inputProblem.netConnections.some(
1196
1270
  (connection) =>
@@ -1474,6 +1548,8 @@ export class AvailableNetOrientationSolver extends BaseSolver {
1474
1548
  label,
1475
1549
  {
1476
1550
  anchorPoint: candidate.anchorPoint,
1551
+ connectorSource:
1552
+ phase === "lateral-shift" ? candidate.connectorSource : undefined,
1477
1553
  orientation: candidate.orientation,
1478
1554
  phase,
1479
1555
  },
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/tscircuit/schematic-trace-solver.git"
6
6
  },
7
7
  "main": "dist/index.js",
8
- "version": "0.0.178",
8
+ "version": "0.0.179",
9
9
  "type": "module",
10
10
  "scripts": {
11
11
  "start": "cosmos",
@@ -0,0 +1,4 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import inputProblem from "../../tests/bug-reports/bug-report-20260902T092101Z/bug-report-20260902T092101Z.json"
3
+
4
+ export default () => <PipelineDebugger inputProblem={inputProblem as any} />
@@ -0,0 +1,4 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import inputProblem from "../../tests/bug-reports/bug-report-20260902T092425Z/bug-report-20260902T092425Z.json"
3
+
4
+ export default () => <PipelineDebugger inputProblem={inputProblem as any} />
@@ -0,0 +1,117 @@
1
+ <svg width="1200" height="2016" viewBox="0 0 1200 2016" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Solver debug visualization on top and Circuit JSON schematic on the bottom">
2
+ <g transform="translate(0, 0) scale(1.875, 1.875) translate(0, 0)">
3
+ <rect width="100%" height="100%" fill="white"/><g><polyline data-points="-3.3620875000000003,-4.00262455 -1.8,-3.58" data-type="line" data-label="" points="250.135315124748,321.4832999381943 381.60217766614755,285.91479073402303" fill="none" stroke="hsl(331, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.3620875000000003,-4.00262455 0.19999999999999998,-2.6199999999999997" data-type="line" data-label="" points="250.135315124748,321.4832999381943 549.9241987327005,205.1202206220776" fill="none" stroke="hsl(331, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.8,-3.58 0.19999999999999998,-2.6199999999999997" data-type="line" data-label="" points="381.60217766614755,285.91479073402303 549.9241987327005,205.1202206220776" fill="none" stroke="hsl(331, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.2,-3.58 0.20000000000000004,-3.3800000000000003" data-type="line" data-label="" points="432.09878398611346,285.91479073402303 549.9241987327005,269.0825886273678" fill="none" stroke="hsl(176, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.2,-3.58 -1.8,-5" data-type="line" data-label="" points="432.09878398611346,285.91479073402303 381.60217766614755,405.4234256912756" fill="none" stroke="hsl(176, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="0.20000000000000004,-3.3800000000000003 -1.8,-5" data-type="line" data-label="" points="549.9241987327005,269.0825886273678 381.60217766614755,405.4234256912756" fill="none" stroke="hsl(176, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.3620875000000003,-4.00262455 -2.58104375,-4.00262455 -2.58104375,-3.58 -1.8,-3.58" data-type="line" data-label="" points="250.135315124748,321.4832999381943 315.8687463954478,321.4832999381943 315.8687463954478,285.91479073402303 381.60217766614755,285.91479073402303" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.2,-3.58 0.20000000000000004,-3.58 0.20000000000000004,-3.3800000000000003" data-type="line" data-label="" points="432.09878398611346,285.91479073402303 549.9241987327005,285.91479073402303 549.9241987327005,269.0825886273678" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-4.4179125,-3.9973754500000007 -5.1389125,-3.9973754500000007 -5.1389125,-3.546375450000001" data-type="line" data-label="" points="161.2760161784514,321.0415303778041 100.59592758395905,321.0415303778041 100.59592758395905,283.0849146272964" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.0000000000000002,-3.58 -1.0000000000000002,-3.229" data-type="line" data-label="" points="448.9309860927687,285.91479073402303 448.9309860927687,256.374276036843" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.8,-5 -2.521,-5 -2.521,-4.649" data-type="line" data-label="" points="381.60217766614755,405.4234256912756 320.92208907165525,405.4234256912756 320.92208907165525,375.8829109940956" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.2,-5 -0.959,-5 -0.959,-5.351" data-type="line" data-label="" points="432.09878398611346,405.4234256912756 452.38158752463306,405.4234256912756 452.38158752463306,434.9639403884557" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="-3.89" data-y="-4" x="161.2760161784514" y="284.74744806157275" width="88.85929894629658" height="73.0299341928528" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="-1.5" data-y="-3.58" x="381.60217766614755" y="257.300047152709" width="50.496606319965906" height="57.22948716262806" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="0.2725" data-y="-3" x="512.0517439927262" y="205.12022062207757" width="87.94825600727393" height="63.96236800529019" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="-1.5" data-y="-5" x="381.60217766614755" y="376.80868210996164" width="50.496606319965906" height="57.229487162628004" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="netId: BUCK_0V9_SW
4
+ globalConnNetId: connectivity_net0" data-x="-5.1389125" data-y="-3.336375450000001" x="40" y="247.73729020332036" width="121.1918551679181" height="35.34762442397607" fill="#ef444466" stroke="#ef4444" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="netId: P0V9
5
+ globalConnNetId: connectivity_net1" data-x="-2.58104375" data-y="-3.37" x="290.62044323546485" y="250.56716631004693" width="50.49660631996585" height="35.34762442397613" fill="#ef444466" stroke="#ef4444" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="netId: P0V9
6
+ globalConnNetId: connectivity_net1" data-x="0.19999999999999998" data-y="-2.409" x="524.6758955727175" y="169.6884351875682" width="50.49660631996596" height="35.34762442397613" fill="#ef444466" stroke="#ef4444" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="netId: BUCK_0V9_FB
7
+ globalConnNetId: connectivity_net2" data-x="-1.0000000000000002" data-y="-3.019" x="388.33505850880965" y="221.02665161286689" width="121.1918551679181" height="35.34762442397613" fill="#ef444466" stroke="#ef4444" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="netId: BUCK_0V9_FB
8
+ globalConnNetId: connectivity_net2" data-x="-2.521" data-y="-4.439" x="260.3261614876962" y="340.5352865701195" width="121.1918551679181" height="35.34762442397613" fill="#ef444466" stroke="#ef4444" stroke-width="0.011881986607142856"/></g><g><rect data-type="rect" data-label="netId: GND
9
+ globalConnNetId: connectivity_net3" data-x="-0.959" data-y="-5.561" x="432.1829449966467" y="434.9639403884556" width="40.3972850559727" height="35.34762442397613" fill="#00000066" stroke="#000000" stroke-width="0.011881986607142856"/></g><g><circle data-type="point" data-label="anode
10
+ x-" data-x="-4.4179125" data-y="-3.9973754500000007" cx="161.2760161784514" cy="321.0415303778041" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="cathode
11
+ x+" data-x="-3.3620875000000003" data-y="-4.00262455" cx="250.135315124748" cy="321.4832999381943" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anode
12
+ x-" data-x="-1.8" data-y="-3.58" cx="381.60217766614755" cy="285.91479073402303" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="cathode
13
+ x+" data-x="-1.2" data-y="-3.58" cx="432.09878398611346" cy="285.91479073402303" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="1
14
+ y+" data-x="0.19999999999999998" data-y="-2.6199999999999997" cx="549.9241987327005" cy="205.1202206220776" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="2
15
+ y-" data-x="0.20000000000000004" data-y="-3.3800000000000003" cx="549.9241987327005" cy="269.0825886273678" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anode
16
+ x-" data-x="-1.8" data-y="-5" cx="381.60217766614755" cy="405.4234256912756" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="cathode
17
+ x+" data-x="-1.2" data-y="-5" cx="432.09878398611346" cy="405.4234256912756" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
18
+ orientation: y+" data-x="-5.1389125" data-y="-3.546375450000001" cx="100.59592758395905" cy="283.0849146272964" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
19
+ orientation: y+" data-x="-2.58104375" data-y="-3.58" cx="315.8687463954478" cy="285.91479073402303" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
20
+ orientation: y+" data-x="0.19999999999999998" data-y="-2.6199999999999997" cx="549.9241987327005" cy="205.1202206220776" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
21
+ orientation: y+" data-x="-1.0000000000000002" data-y="-3.229" cx="448.9309860927687" cy="256.374276036843" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
22
+ orientation: y+" data-x="-2.521" data-y="-4.649" cx="320.92208907165525" cy="375.8829109940956" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
23
+ orientation: y-" data-x="-0.959" data-y="-5.351" cx="452.38158752463306" cy="434.9639403884557" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5"/><line id="crosshair-v" x1="0" x2="640" stroke="#666" stroke-width="0.5"/><text id="coordinates" font-family="monospace" font-size="12" fill="#666"></text></g><script><![CDATA[
24
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
25
+ const svg = e.currentTarget;
26
+ const rect = svg.getBoundingClientRect();
27
+ const x = e.clientX - rect.left;
28
+ const y = e.clientY - rect.top;
29
+ const crosshair = svg.getElementById('crosshair');
30
+ const h = svg.getElementById('crosshair-h');
31
+ const v = svg.getElementById('crosshair-v');
32
+ const coords = svg.getElementById('coordinates');
33
+
34
+ crosshair.style.display = 'block';
35
+ h.setAttribute('x1', '0');
36
+ h.setAttribute('x2', '640');
37
+ h.setAttribute('y1', y);
38
+ h.setAttribute('y2', y);
39
+ v.setAttribute('x1', x);
40
+ v.setAttribute('x2', x);
41
+ v.setAttribute('y1', '0');
42
+ v.setAttribute('y2', '640');
43
+
44
+ // Calculate real coordinates using inverse transformation
45
+ const matrix = {"a":84.16101053327648,"c":0,"e":533.0919966260452,"b":0,"d":-84.16101053327648,"f":-15.38162697510677};
46
+ // Manually invert and apply the affine transform
47
+ // Since we only use translate and scale, we can directly compute:
48
+ // x' = (x - tx) / sx
49
+ // y' = (y - ty) / sy
50
+ const sx = matrix.a;
51
+ const sy = matrix.d;
52
+ const tx = matrix.e;
53
+ const ty = matrix.f;
54
+ const realPoint = {
55
+ x: (x - tx) / sx,
56
+ y: (y - ty) / sy // Flip y back since we used negative scale
57
+ }
58
+
59
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
60
+ coords.setAttribute('x', (x + 5).toString());
61
+ coords.setAttribute('y', (y - 5).toString());
62
+ });
63
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
64
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
65
+ });
66
+ ]]></script>
67
+ </g>
68
+ <g transform="translate(0, 1216)">
69
+ <style>
70
+ .boundary { fill: rgb(245, 241, 237); }
71
+ .schematic-boundary { fill: none; stroke: #fff; }
72
+ .component { fill: none; stroke: rgb(132, 0, 0); }
73
+ .chip { fill: rgb(255, 255, 194); stroke: rgb(132, 0, 0); }
74
+ .component-pin { fill: none; stroke: rgb(132, 0, 0); }
75
+ .text { font-family: sans-serif; fill: rgb(0, 150, 0); }
76
+ .pin-number { fill: rgb(169, 0, 0); }
77
+ .port-label { fill: rgb(0, 100, 100); }
78
+ .component-name { fill: rgb(0, 100, 100); }
79
+
80
+ </style><rect class="boundary" x="0" y="0" width="1200" height="800"/><g class="trace sch-trace" data-layer="base" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_0__stack1"><path d="M 405.4912539783111 402.9214835984178 L 538.7389308580355 402.9214835984178 L 538.7389308580355 330.82086250025407 L 671.98660773776 330.82086250025407" class="trace-invisible-hover-outline sch-trace-hitbox" stroke="rgb(0, 150, 0)" fill="none" stroke-width="27.296330456208004px" stroke-linecap="round" opacity="0" stroke-linejoin="round"/><path class="sch-trace-path" d="M 405.4912539783111 402.9214835984178 L 538.7389308580355 402.9214835984178 L 538.7389308580355 330.82086250025407 L 671.98660773776 330.82086250025407" stroke="rgb(0, 150, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round" stroke-linejoin="round"/></g><g class="trace sch-trace" data-layer="base" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_1__stack1"><path d="M 774.34784694854 330.82086250025407 L 1013.1907384403601 330.82086250025407 L 1013.1907384403601 296.70044942999414" class="trace-invisible-hover-outline sch-trace-hitbox" stroke="rgb(0, 150, 0)" fill="none" stroke-width="27.296330456208004px" stroke-linecap="round" opacity="0" stroke-linejoin="round"/><path class="sch-trace-path" d="M 774.34784694854 330.82086250025407 L 1013.1907384403601 330.82086250025407 L 1013.1907384403601 296.70044942999414" stroke="rgb(0, 150, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round" stroke-linejoin="round"/></g><g class="trace sch-trace" data-layer="base" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_2__stack1"><path d="M 225.3653283287748 402.0259762971824 L 102.3612392104875 402.0259762971824 L 102.3612392104875 325.08444482374614" class="trace-invisible-hover-outline sch-trace-hitbox" stroke="rgb(0, 150, 0)" fill="none" stroke-width="27.296330456208004px" stroke-linecap="round" opacity="0" stroke-linejoin="round"/><path class="sch-trace-path" d="M 225.3653283287748 402.0259762971824 L 102.3612392104875 402.0259762971824 L 102.3612392104875 325.08444482374614" stroke="rgb(0, 150, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round" stroke-linejoin="round"/></g><g class="trace sch-trace" data-layer="base" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_3__stack1"><path d="M 808.4682600188 330.82086250025407 L 808.4682600188 270.93953756194776" class="trace-invisible-hover-outline sch-trace-hitbox" stroke="rgb(0, 150, 0)" fill="none" stroke-width="27.296330456208004px" stroke-linecap="round" opacity="0" stroke-linejoin="round"/><path class="sch-trace-path" d="M 808.4682600188 330.82086250025407 L 808.4682600188 270.93953756194776" stroke="rgb(0, 150, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round" stroke-linejoin="round"/></g><g class="trace sch-trace" data-layer="base" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_4__stack1"><path d="M 671.98660773776 573.0757952991 L 548.9825186194728 573.0757952991 L 548.9825186194728 513.1944703607937" class="trace-invisible-hover-outline sch-trace-hitbox" stroke="rgb(0, 150, 0)" fill="none" stroke-width="27.296330456208004px" stroke-linecap="round" opacity="0" stroke-linejoin="round"/><path class="sch-trace-path" d="M 671.98660773776 573.0757952991 L 548.9825186194728 573.0757952991 L 548.9825186194728 513.1944703607937" stroke="rgb(0, 150, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round" stroke-linejoin="round"/></g><g class="trace sch-trace" data-layer="base" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_5__stack1"><path d="M 774.34784694854 573.0757952991 L 815.4629446982033 573.0757952991 L 815.4629446982033 632.9571202374063" class="trace-invisible-hover-outline sch-trace-hitbox" stroke="rgb(0, 150, 0)" fill="none" stroke-width="27.296330456208004px" stroke-linecap="round" opacity="0" stroke-linejoin="round"/><path class="sch-trace-path" d="M 774.34784694854 573.0757952991 L 815.4629446982033 573.0757952991 L 815.4629446982033 632.9571202374063" stroke="rgb(0, 150, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round" stroke-linejoin="round"/></g><g class="trace-overlays sch-trace-overlays" data-layer="overlay" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_0__stack1"/><g class="trace-overlays sch-trace-overlays" data-layer="overlay" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_1__stack1"/><g class="trace-overlays sch-trace-overlays" data-layer="overlay" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_2__stack1"/><g class="trace-overlays sch-trace-overlays" data-layer="overlay" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_3__stack1"/><g class="trace-overlays sch-trace-overlays" data-layer="overlay" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_4__stack1"/><g class="trace-overlays sch-trace-overlays" data-layer="overlay" data-circuit-json-type="schematic_trace" data-schematic-trace-id="schematic_trace_5__stack1"/><g class="sch-component" data-circuit-json-type="schematic_component" data-schematic-component-id="schematic_component_0__stack1"><rect class="component chip sch-component-body" x="293.6061544692949" y="328.4545521431086" width="43.644273368496215" height="148.03835560938296" stroke-width="3.4120413070260005px" fill="rgb(255, 255, 194)" stroke="rgb(132, 0, 0)"/><rect class="component-overlay sch-component-overlay" x="293.6061544692949" y="328.4545521431086" width="43.644273368496215" height="148.03835560938296" fill="transparent"/><line class="component-pin sch-component-pin sch-port-line" x1="293.6061544692949" y1="402.0259762971824" x2="225.3653283287748" y2="402.0259762971824" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_0_0__stack1"><rect x="221.95328702174882" y="398.6139349901564" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="259.48574139903485" y="398.6139349901564" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform=""></text><text class="pin-number sch-pin-label" x="310.66636100442486" y="402.0259762971824" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="start" dominant-baseline="middle" font-size="25.590309802695px" transform="">anode</text><line class="component-pin sch-component-pin sch-port-line" x1="337.2504278377911" y1="402.9214835984178" x2="405.4912539783111" y2="402.9214835984178" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_0_1__stack1"><rect x="402.07921267128506" y="399.5094422913918" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="371.37084090805104" y="399.5094422913918" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform=""></text><text class="pin-number sch-pin-label" x="320.19022130266103" y="402.9214835984178" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="end" dominant-baseline="middle" font-size="25.590309802695px" transform="">cathode</text></g><g class="sch-component" data-circuit-json-type="schematic_component" data-schematic-component-id="schematic_component_1__stack1"><rect class="component chip sch-component-body" x="714.637124075585" y="272.816160280812" width="17.060206535129964" height="116.00940443888408" stroke-width="3.4120413070260005px" fill="rgb(255, 255, 194)" stroke="rgb(132, 0, 0)"/><rect class="component-overlay sch-component-overlay" x="714.637124075585" y="272.816160280812" width="17.060206535129964" height="116.00940443888408" fill="transparent"/><line class="component-pin sch-component-pin sch-port-line" x1="714.637124075585" y1="330.82086250025407" x2="671.98660773776" y2="330.82086250025407" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_1_0__stack1"><rect x="668.574566430734" y="327.40882119322805" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="693.3118659066724" y="327.40882119322805" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform=""></text><text class="pin-number sch-pin-label" x="731.697330610715" y="330.82086250025407" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="start" dominant-baseline="middle" font-size="25.590309802695px" transform="">anode</text><line class="component-pin sch-component-pin sch-port-line" x1="731.697330610715" y1="330.82086250025407" x2="774.34784694854" y2="330.82086250025407" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_1_1__stack1"><rect x="770.935805641514" y="327.40882119322805" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="753.0225887796275" y="327.40882119322805" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform=""></text><text class="pin-number sch-pin-label" x="714.637124075585" y="330.82086250025407" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="end" dominant-baseline="middle" font-size="25.590309802695px" transform="">cathode</text></g><g class="sch-component" data-circuit-json-type="schematic_component" data-schematic-component-id="schematic_component_2__stack1"><rect class="component chip sch-component-body" x="936.419809032275" y="223.3415613289351" width="178.2791582921086" height="17.060206535129964" stroke-width="3.4120413070260005px" fill="rgb(255, 255, 194)" stroke="rgb(132, 0, 0)"/><rect class="component-overlay sch-component-overlay" x="936.419809032275" y="223.3415613289351" width="178.2791582921086" height="17.060206535129964" fill="transparent"/><line class="component-pin sch-component-pin sch-port-line" x1="1013.1907384403601" y1="223.3415613289351" x2="1013.1907384403601" y2="170.45492107003196" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_2_0__stack1"><circle class="component-pin sch-component-pin sch-port-terminal" cx="1013.1907384403601" cy="167.042879763006" r="3.4120413070260005" stroke-width="3.4120413070260005px"/><rect x="1009.778697133334" y="163.63083845598" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="1009.778697133334" y="195.19222054597049" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform="rotate(-90 1009.778697133334 195.19222054597049)">1</text><line class="component-pin sch-component-pin sch-port-line" x1="1013.1907384403601" y1="240.40176786406505" x2="1013.1907384403601" y2="296.70044942999414" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_2_1__stack1"><rect x="1009.778697133334" y="293.2884081229681" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="1009.778697133334" y="268.55110864702965" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform="rotate(-90 1009.778697133334 268.55110864702965)">2</text></g><g class="sch-component" data-circuit-json-type="schematic_component" data-schematic-component-id="schematic_component_3__stack1"><rect class="component chip sch-component-body" x="714.637124075585" y="515.0710930796581" width="17.060206535129964" height="116.00940443888396" stroke-width="3.4120413070260005px" fill="rgb(255, 255, 194)" stroke="rgb(132, 0, 0)"/><rect class="component-overlay sch-component-overlay" x="714.637124075585" y="515.0710930796581" width="17.060206535129964" height="116.00940443888396" fill="transparent"/><line class="component-pin sch-component-pin sch-port-line" x1="714.637124075585" y1="573.0757952991" x2="671.98660773776" y2="573.0757952991" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_3_0__stack1"><rect x="668.574566430734" y="569.663753992074" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="693.3118659066724" y="569.6637539920741" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform=""></text><text class="pin-number sch-pin-label" x="731.697330610715" y="573.0757952991" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="start" dominant-baseline="middle" font-size="25.590309802695px" transform="">anode</text><line class="component-pin sch-component-pin sch-port-line" x1="731.697330610715" y1="573.0757952991" x2="774.34784694854" y2="573.0757952991" stroke-width="3.4120413070260005px"/><g class="sch-port" data-schematic-port-id="source_port_3_1__stack1"><rect x="770.935805641514" y="569.663753992074" width="6.824082614052001" height="6.824082614052001" opacity="0"/></g><text class="pin-number sch-pin-number" x="753.0225887796275" y="569.6637539920741" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="middle" dominant-baseline="auto" font-size="25.590309802695px" transform=""></text><text class="pin-number sch-pin-label" x="714.637124075585" y="573.0757952991" style="font-family: sans-serif;" fill="rgb(169, 0, 0)" text-anchor="end" dominant-baseline="middle" font-size="25.590309802695px" transform="">cathode</text></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_0_0__stack1"><circle cx="225.3653283287748" cy="402.0259762971824" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_0_1__stack1"><circle cx="405.4912539783111" cy="402.9214835984178" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_1_0__stack1"><circle cx="671.98660773776" cy="330.82086250025407" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_1_1__stack1"><circle cx="774.34784694854" cy="330.82086250025407" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_2_0__stack1"><circle cx="1013.1907384403601" cy="167.042879763006" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_2_1__stack1"><circle cx="1013.1907384403601" cy="296.70044942999414" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_3_0__stack1"><circle cx="671.98660773776" cy="573.0757952991" r="6.824082614052001" fill="red" opacity="0"/></g><g class="schematic-port-hover sch-port-hover" data-schematic-port-id="source_port_3_1__stack1"><circle cx="774.34784694854" cy="573.0757952991" r="6.824082614052001" fill="red" opacity="0"/></g><path class="net-label sch-net-label" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_0__stack1" d="
81
+ M 102.3612392104875,325.08444482374614
82
+ L 85.30103267535749,315.87193329477594
83
+ L 85.3010326753575,257.36679835030344
84
+ L 119.4214457456175,257.36679835030344
85
+ L 119.4214457456175,315.87193329477594
86
+ Z
87
+ " fill="rgba(255, 255, 255, 0.6)" stroke="rgb(132, 0, 0)" stroke-width="3.4120413070260005px"/><text class="net-label-text sch-net-label-text" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_0__stack1" x="102.3612392104875" y="309.7302589421291" fill="rgb(132, 0, 0)" text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-variant-numeric="tabular-nums" font-size="30.708371763234002px" transform="rotate(-90 102.3612392104875 309.7302589421291)">XX</text><path class="net-label sch-net-label" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_1__stack1" d="
88
+ M 538.7389308580355,330.82086250025407
89
+ L 521.6787243229055,321.60835097128387
90
+ L 521.6787243229055,263.10321602681137
91
+ L 555.7991373931654,263.10321602681137
92
+ L 555.7991373931654,321.60835097128387
93
+ Z
94
+ " fill="rgba(255, 255, 255, 0.6)" stroke="rgb(132, 0, 0)" stroke-width="3.4120413070260005px"/><text class="net-label-text sch-net-label-text" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_1__stack1" x="538.7389308580355" y="315.46667661863705" fill="rgb(132, 0, 0)" text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-variant-numeric="tabular-nums" font-size="30.708371763234002px" transform="rotate(-90 538.7389308580355 315.46667661863705)">XX</text><path class="net-label sch-net-label" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_2__stack1" d="
95
+ M 1013.1907384403601,167.042879763006
96
+ L 996.1305319052301,157.8303682340358
97
+ L 996.1305319052301,99.32523328956331
98
+ L 1030.25094497549,99.32523328956331
99
+ L 1030.25094497549,157.8303682340358
100
+ Z
101
+ " fill="rgba(255, 255, 255, 0.6)" stroke="rgb(132, 0, 0)" stroke-width="3.4120413070260005px"/><text class="net-label-text sch-net-label-text" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_2__stack1" x="1013.1907384403601" y="151.68869388138899" fill="rgb(132, 0, 0)" text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-variant-numeric="tabular-nums" font-size="30.708371763234002px" transform="rotate(-90 1013.1907384403601 151.68869388138899)">XX</text><path class="net-label sch-net-label" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_3__stack1" d="
102
+ M 808.4682600188,270.93953756194776
103
+ L 791.4080534836701,261.72702603297756
104
+ L 791.4080534836701,203.22189108850506
105
+ L 825.52846655393,203.22189108850506
106
+ L 825.52846655393,261.72702603297756
107
+ Z
108
+ " fill="rgba(255, 255, 255, 0.6)" stroke="rgb(132, 0, 0)" stroke-width="3.4120413070260005px"/><text class="net-label-text sch-net-label-text" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_3__stack1" x="808.4682600188" y="255.58535168033075" fill="rgb(132, 0, 0)" text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-variant-numeric="tabular-nums" font-size="30.708371763234002px" transform="rotate(-90 808.4682600188 255.58535168033075)">XX</text><path class="net-label sch-net-label" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_4__stack1" d="
109
+ M 548.9825186194728,513.1944703607937
110
+ L 531.9223120843428,503.98195883182353
111
+ L 531.9223120843428,445.47682388735103
112
+ L 566.0427251546027,445.47682388735103
113
+ L 566.0427251546027,503.98195883182353
114
+ Z
115
+ " fill="rgba(255, 255, 255, 0.6)" stroke="rgb(132, 0, 0)" stroke-width="3.4120413070260005px"/><text class="net-label-text sch-net-label-text" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_4__stack1" x="548.9825186194728" y="497.8402844791767" fill="rgb(132, 0, 0)" text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-variant-numeric="tabular-nums" font-size="30.708371763234002px" transform="rotate(-90 548.9825186194728 497.8402844791767)">XX</text><rect class="component-overlay sch-component-overlay sch-net-label-overlay" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_5__stack1" x="794.9906968560473" y="632.9571202374063" width="40.94449568431196" height="30.708371763234027" fill="transparent"/><path class="sch-net-label-symbol-path" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_5__stack1" d="M 794.9906968560473 663.6654920006404 L 835.9351925403593 663.6654920006404" stroke="rgb(132, 0, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round"/><path class="sch-net-label-symbol-path" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_5__stack1" d="M 815.4629446982033 663.6654920006404 L 815.4629446982033 632.9571202374063" stroke="rgb(132, 0, 0)" fill="none" stroke-width="3.4120413070260005px" stroke-linecap="round"/><text class="sch-net-label-symbol-text" data-circuit-json-type="schematic_net_label" data-schematic-net-label-id="schematic_net_label_5__stack1" x="815.4629446982033" y="672.1955952682054" fill="rgb(15, 15, 15)" font-family="sans-serif" text-anchor="middle" dominant-baseline="hanging" font-size="30.708371763234002px">XX</text>
116
+ </g>
117
+ </svg>
@@ -0,0 +1,162 @@
1
+ {
2
+ "chips": [
3
+ {
4
+ "chipId": "schematic_component_0",
5
+ "center": {
6
+ "x": -3.89,
7
+ "y": -4
8
+ },
9
+ "width": 1.0558249999999996,
10
+ "height": 0.8677407000000006,
11
+ "pins": [
12
+ {
13
+ "pinId": "schematic_port_0",
14
+ "displayName": "anode",
15
+ "x": -4.4179125,
16
+ "y": -3.9973754500000007
17
+ },
18
+ {
19
+ "pinId": "schematic_port_1",
20
+ "displayName": "cathode",
21
+ "x": -3.3620875000000003,
22
+ "y": -4.00262455
23
+ }
24
+ ]
25
+ },
26
+ {
27
+ "chipId": "schematic_component_1",
28
+ "center": {
29
+ "x": -1.5,
30
+ "y": -3.58
31
+ },
32
+ "width": 0.6000000000000001,
33
+ "height": 0.6800000000000006,
34
+ "pins": [
35
+ {
36
+ "pinId": "schematic_port_2",
37
+ "displayName": "anode",
38
+ "x": -1.8,
39
+ "y": -3.58,
40
+ "_facingDirection": "x-"
41
+ },
42
+ {
43
+ "pinId": "schematic_port_3",
44
+ "displayName": "cathode",
45
+ "x": -1.2,
46
+ "y": -3.58,
47
+ "_facingDirection": "x+"
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ "chipId": "schematic_component_2",
53
+ "center": {
54
+ "x": 0.2725,
55
+ "y": -3
56
+ },
57
+ "width": 1.045,
58
+ "height": 0.7600000000000007,
59
+ "pins": [
60
+ {
61
+ "pinId": "schematic_port_4",
62
+ "displayName": "1",
63
+ "x": 0.19999999999999998,
64
+ "y": -2.6199999999999997,
65
+ "_facingDirection": "y+"
66
+ },
67
+ {
68
+ "pinId": "schematic_port_5",
69
+ "displayName": "2",
70
+ "x": 0.20000000000000004,
71
+ "y": -3.3800000000000003,
72
+ "_facingDirection": "y-"
73
+ }
74
+ ]
75
+ },
76
+ {
77
+ "chipId": "schematic_component_3",
78
+ "center": {
79
+ "x": -1.5,
80
+ "y": -5
81
+ },
82
+ "width": 0.6000000000000001,
83
+ "height": 0.6799999999999997,
84
+ "pins": [
85
+ {
86
+ "pinId": "schematic_port_6",
87
+ "displayName": "anode",
88
+ "x": -1.8,
89
+ "y": -5,
90
+ "_facingDirection": "x-"
91
+ },
92
+ {
93
+ "pinId": "schematic_port_7",
94
+ "displayName": "cathode",
95
+ "x": -1.2,
96
+ "y": -5,
97
+ "_facingDirection": "x+"
98
+ }
99
+ ]
100
+ }
101
+ ],
102
+ "directConnections": [],
103
+ "netConnections": [
104
+ {
105
+ "netId": "BUCK_0V9_SW",
106
+ "isGround": false,
107
+ "netLabelWidth": 0.42,
108
+ "netLabelHeight": 1.44,
109
+ "pinIds": [
110
+ "schematic_port_0"
111
+ ]
112
+ },
113
+ {
114
+ "netId": "P0V9",
115
+ "isGround": false,
116
+ "netLabelWidth": 0.42,
117
+ "netLabelHeight": 0.6,
118
+ "pinIds": [
119
+ "schematic_port_1",
120
+ "schematic_port_2",
121
+ "schematic_port_4"
122
+ ]
123
+ },
124
+ {
125
+ "netId": "BUCK_0V9_FB",
126
+ "isGround": false,
127
+ "netLabelWidth": 0.42,
128
+ "netLabelHeight": 1.44,
129
+ "pinIds": [
130
+ "schematic_port_3",
131
+ "schematic_port_5",
132
+ "schematic_port_6"
133
+ ]
134
+ },
135
+ {
136
+ "netId": "GND",
137
+ "isGround": true,
138
+ "netLabelWidth": 0.42,
139
+ "netLabelHeight": 0.48,
140
+ "pinIds": [
141
+ "schematic_port_7"
142
+ ]
143
+ }
144
+ ],
145
+ "textBoxes": [],
146
+ "availableNetLabelOrientations": {
147
+ "P0V9": [
148
+ "y+"
149
+ ],
150
+ "GND": [
151
+ "y-"
152
+ ],
153
+ "BUCK_0V9_SW": [
154
+ "y+"
155
+ ],
156
+ "BUCK_0V9_FB": [
157
+ "y+"
158
+ ]
159
+ },
160
+ "maxMspPairDistance": 0.8,
161
+ "_hideRatsNet": false
162
+ }
@@ -0,0 +1,28 @@
1
+ import { expect, test } from "bun:test"
2
+ import { tracePathContainsPoint } from "lib/solvers/RailNetLabelCornerPlacementSolver/geometry"
3
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
4
+ import inputProblem from "./bug-report-20260902T092101Z.json"
5
+ import "tests/fixtures/matcher"
6
+
7
+ test("bug-report-20260902T092101Z", () => {
8
+ const solver = new SchematicTracePipelineSolver(inputProblem as any)
9
+
10
+ solver.solve()
11
+
12
+ const output = solver.netLabelToTraceSolver!.getOutput()
13
+ const hostTrace = output.traces.find(
14
+ (trace) => trace.mspPairId === "schematic_port_3-schematic_port_5",
15
+ )!
16
+ const feedbackLabelConnector = output.traces.find(
17
+ (trace) => trace.mspPairId === "available-net-orientation-3-BUCK_0V9_FB",
18
+ )!
19
+
20
+ expect(feedbackLabelConnector.tracePath).toHaveLength(2)
21
+ expect(
22
+ tracePathContainsPoint(
23
+ hostTrace.tracePath,
24
+ feedbackLabelConnector.tracePath[0]!,
25
+ ),
26
+ ).toBe(true)
27
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
28
+ })