@tscircuit/schematic-trace-solver 0.0.118 → 0.0.119

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.
@@ -0,0 +1,58 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="-1,0.5 -1,0.25" data-type="line" data-label="" points="189.74358974358972,229.74358974358975 189.74358974358972,281.02564102564105" fill="none" stroke="hsl(271, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1,0.5 -1,0" data-type="line" data-label="" points="189.74358974358972,229.74358974358975 189.74358974358972,332.3076923076923" fill="none" stroke="hsl(271, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1,0.25 -1,0" data-type="line" data-label="" points="189.74358974358972,281.02564102564105 189.74358974358972,332.3076923076923" fill="none" stroke="hsl(271, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1,-0.25 -1,-0.5" data-type="line" data-label="" points="189.74358974358972,383.5897435897436 189.74358974358972,434.8717948717949" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1,0.25 -1.2,0.25 -1.2,0.5 -1,0.5" data-type="line" data-label="" points="189.74358974358972,281.02564102564105 148.7179487179487,281.02564102564105 148.7179487179487,229.74358974358975 189.74358974358972,229.74358974358975" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1,0 -1.2,0 -1.2,0.25 -1,0.25" data-type="line" data-label="" points="189.74358974358972,332.3076923076923 148.7179487179487,332.3076923076923 148.7179487179487,281.02564102564105 189.74358974358972,281.02564102564105" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1,-0.25 -1.2,-0.25 -1.2,-0.5 -1,-0.5" data-type="line" data-label="" points="189.74358974358972,383.5897435897436 148.7179487179487,383.5897435897436 148.7179487179487,434.8717948717949 189.74358974358972,434.8717948717949" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.2,0.5 -1.49,0.5" data-type="line" data-label="" points="148.7179487179487,229.74358974358975 89.23076923076923,229.74358974358975" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.2,-0.5 -1.49,-0.5" data-type="line" data-label="" points="148.7179487179487,434.8717948717949 89.23076923076923,434.8717948717949" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="189.74358974358972" y="188.71794871794873" width="410.2564102564103" height="287.1794871794872" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.004875"/></g><g><rect data-type="rect" data-label="U1 Power" data-x="-0.25" data-y="0.85" x="271.7948717948718" y="137.43589743589746" width="143.5897435897436" height="41.025641025640994" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.004875"/></g><g><rect data-type="rect" data-label="netId: VBAT
2
+ globalConnNetId: connectivity_net0" data-x="-1.49" data-y="0.74" x="40" y="131.2820512820513" width="98.46153846153845" height="98.46153846153845" fill="#ef444466" stroke="#ef4444" stroke-width="0.004875"/></g><g><rect data-type="rect" data-label="netId: GND
3
+ globalConnNetId: connectivity_net1" data-x="-1.49" data-y="-0.6799999999999999" x="40" y="434.8717948717949" width="98.46153846153845" height="73.84615384615387" fill="#00000066" stroke="#000000" stroke-width="0.004875"/></g><g><circle data-type="point" data-label="U1.1
4
+ x-" data-x="-1" data-y="0.5" cx="189.74358974358972" cy="229.74358974358975" r="3" fill="hsl(319, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.2
5
+ x-" data-x="-1" data-y="0.25" cx="189.74358974358972" cy="281.02564102564105" r="3" fill="hsl(320, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.3
6
+ x-" data-x="-1" data-y="0" cx="189.74358974358972" cy="332.3076923076923" r="3" fill="hsl(321, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.4
7
+ x-" data-x="-1" data-y="-0.25" cx="189.74358974358972" cy="383.5897435897436" r="3" fill="hsl(322, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.5
8
+ x-" data-x="-1" data-y="-0.5" cx="189.74358974358972" cy="434.8717948717949" r="3" fill="hsl(323, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.6
9
+ x+" data-x="1" data-y="0.5" cx="600" cy="229.74358974358975" r="3" fill="hsl(324, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.7
10
+ x+" data-x="1" data-y="0.25" cx="600" cy="281.02564102564105" r="3" fill="hsl(325, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.8
11
+ x+" data-x="1" data-y="0" cx="600" cy="332.3076923076923" r="3" fill="hsl(326, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.9
12
+ x+" data-x="1" data-y="-0.25" cx="600" cy="383.5897435897436" r="3" fill="hsl(327, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.10
13
+ x+" data-x="1" data-y="-0.5" cx="600" cy="434.8717948717949" r="3" fill="hsl(217, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
14
+ orientation: y+" data-x="-1.49" data-y="0.5" cx="89.23076923076923" cy="229.74358974358975" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
15
+ orientation: y-" data-x="-1.49" data-y="-0.5" cx="89.23076923076923" cy="434.8717948717949" 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[
16
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
17
+ const svg = e.currentTarget;
18
+ const rect = svg.getBoundingClientRect();
19
+ const x = e.clientX - rect.left;
20
+ const y = e.clientY - rect.top;
21
+ const crosshair = svg.getElementById('crosshair');
22
+ const h = svg.getElementById('crosshair-h');
23
+ const v = svg.getElementById('crosshair-v');
24
+ const coords = svg.getElementById('coordinates');
25
+
26
+ crosshair.style.display = 'block';
27
+ h.setAttribute('x1', '0');
28
+ h.setAttribute('x2', '640');
29
+ h.setAttribute('y1', y);
30
+ h.setAttribute('y2', y);
31
+ v.setAttribute('x1', x);
32
+ v.setAttribute('x2', x);
33
+ v.setAttribute('y1', '0');
34
+ v.setAttribute('y2', '640');
35
+
36
+ // Calculate real coordinates using inverse transformation
37
+ const matrix = {"a":205.12820512820514,"c":0,"e":394.87179487179486,"b":0,"d":-205.12820512820514,"f":332.3076923076923};
38
+ // Manually invert and apply the affine transform
39
+ // Since we only use translate and scale, we can directly compute:
40
+ // x' = (x - tx) / sx
41
+ // y' = (y - ty) / sy
42
+ const sx = matrix.a;
43
+ const sy = matrix.d;
44
+ const tx = matrix.e;
45
+ const ty = matrix.f;
46
+ const realPoint = {
47
+ x: (x - tx) / sx,
48
+ y: (y - ty) / sy // Flip y back since we used negative scale
49
+ }
50
+
51
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
52
+ coords.setAttribute('x', (x + 5).toString());
53
+ coords.setAttribute('y', (y - 5).toString());
54
+ });
55
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
56
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
57
+ });
58
+ ]]></script></svg>
@@ -0,0 +1,96 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="-1.35,0.9999999999999998 -1.35,2.8" data-type="line" data-label="" points="198.84615384615384,241.02564102564105 198.84615384615384,79.48717948717953" fill="none" stroke="hsl(68, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.35,0.9999999999999998 -1.35,-1.4000000000000004" data-type="line" data-label="" points="198.84615384615384,241.02564102564105 198.84615384615384,456.41025641025647" fill="none" stroke="hsl(68, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.35,2.8 -1.35,-1.4000000000000004" data-type="line" data-label="" points="198.84615384615384,79.48717948717953 198.84615384615384,456.41025641025647" fill="none" stroke="hsl(68, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.35,0.9999999999999998 1.35,2.8" data-type="line" data-label="" points="441.1538461538462,241.02564102564105 441.1538461538462,79.48717948717953" fill="none" stroke="hsl(271, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.35,0.9999999999999998 1.35,-1.4000000000000004" data-type="line" data-label="" points="441.1538461538462,241.02564102564105 441.1538461538462,456.41025641025647" fill="none" stroke="hsl(271, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.35,2.8 1.35,-1.4000000000000004" data-type="line" data-label="" points="441.1538461538462,79.48717948717953 441.1538461538462,456.41025641025647" fill="none" stroke="hsl(271, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.35,0.9999999999999998 -1.55,0.9999999999999998 -1.55,2.8 -1.35,2.8" data-type="line" data-label="" points="198.84615384615384,241.02564102564105 180.8974358974359,241.02564102564105 180.8974358974359,79.48717948717953 198.84615384615384,79.48717948717953" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.35,0.9999999999999998 1.55,0.9999999999999998 1.55,2.8 1.35,2.8" data-type="line" data-label="" points="441.1538461538462,241.02564102564105 459.1025641025641,241.02564102564105 459.1025641025641,79.48717948717953 441.1538461538462,79.48717948717953" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.55,2.8 -1.9000000000000001,2.8" data-type="line" data-label="" points="180.8974358974359,79.48717948717953 149.48717948717947,79.48717948717953" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.35,-1.4000000000000004 -1.701,-1.4000000000000004 -1.701,-1.3490000000000004" data-type="line" data-label="" points="198.84615384615384,456.41025641025647 167.34615384615384,456.41025641025647 167.34615384615384,451.83333333333337" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.55,2.8 1.9000000000000001,2.8" data-type="line" data-label="" points="459.1025641025641,79.48717948717953 490.51282051282055,79.48717948717953" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.35,-1.4000000000000004 1.701,-1.4000000000000004 1.701,-1.3490000000000004" data-type="line" data-label="" points="441.1538461538462,456.41025641025647 472.6538461538462,456.41025641025647 472.6538461538462,451.83333333333337" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="198.8461538461538" y="61.53846153846155" width="242.30769230769235" height="538.4615384615385" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011142857142857144"/></g><g><rect data-type="rect" data-label="U1" data-x="-0.83" data-y="3.115" x="229.35897435897436" y="40" width="32.30769230769232" height="22.43589743589746" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.011142857142857144"/></g><g><rect data-type="rect" data-label="netId: V3V3_LEFT
2
+ globalConnNetId: connectivity_net0" data-x="-1.9000000000000001" data-y="3.01" x="122.56410256410255" y="41.79487179487184" width="53.84615384615384" height="37.69230769230771" fill="#ef444466" stroke="#ef4444" stroke-width="0.011142857142857144"/></g><g><rect data-type="rect" data-label="netId: V3V3_LEFT
3
+ globalConnNetId: connectivity_net0" data-x="-1.701" data-y="-1.1390000000000005" x="140.4230769230769" y="414.14102564102575" width="53.84615384615384" height="37.69230769230768" fill="#ef444466" stroke="#ef4444" stroke-width="0.011142857142857144"/></g><g><rect data-type="rect" data-label="netId: V3V3_RIGHT
4
+ globalConnNetId: connectivity_net1" data-x="1.9000000000000001" data-y="3.01" x="463.58974358974365" y="41.79487179487184" width="53.84615384615387" height="37.69230769230771" fill="#ef444466" stroke="#ef4444" stroke-width="0.011142857142857144"/></g><g><rect data-type="rect" data-label="netId: V3V3_RIGHT
5
+ globalConnNetId: connectivity_net1" data-x="1.701" data-y="-1.1390000000000005" x="445.7307692307693" y="414.14102564102575" width="53.84615384615387" height="37.69230769230768" fill="#ef444466" stroke="#ef4444" stroke-width="0.011142857142857144"/></g><g><circle data-type="point" data-label="U1.left.1
6
+ x-" data-x="-1.35" data-y="2.8" cx="198.84615384615384" cy="79.48717948717953" r="3" fill="hsl(12, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.2
7
+ x-" data-x="-1.35" data-y="2.5999999999999996" cx="198.84615384615384" cy="97.43589743589749" r="3" fill="hsl(13, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.3
8
+ x-" data-x="-1.35" data-y="2.4" cx="198.84615384615384" cy="115.38461538461542" r="3" fill="hsl(14, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.4
9
+ x-" data-x="-1.35" data-y="2.1999999999999997" cx="198.84615384615384" cy="133.33333333333337" r="3" fill="hsl(15, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.5
10
+ x-" data-x="-1.35" data-y="1.9999999999999998" cx="198.84615384615384" cy="151.28205128205133" r="3" fill="hsl(16, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.6
11
+ x-" data-x="-1.35" data-y="1.7999999999999998" cx="198.84615384615384" cy="169.23076923076925" r="3" fill="hsl(17, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.7
12
+ x-" data-x="-1.35" data-y="1.5999999999999996" cx="198.84615384615384" cy="187.17948717948724" r="3" fill="hsl(18, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.8
13
+ x-" data-x="-1.35" data-y="1.3999999999999997" cx="198.84615384615384" cy="205.12820512820517" r="3" fill="hsl(19, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.9
14
+ x-" data-x="-1.35" data-y="1.1999999999999997" cx="198.84615384615384" cy="223.0769230769231" r="3" fill="hsl(20, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.10
15
+ x-" data-x="-1.35" data-y="0.9999999999999998" cx="198.84615384615384" cy="241.02564102564105" r="3" fill="hsl(60, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.11
16
+ x-" data-x="-1.35" data-y="0.7999999999999998" cx="198.84615384615384" cy="258.974358974359" r="3" fill="hsl(61, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.12
17
+ x-" data-x="-1.35" data-y="0.5999999999999996" cx="198.84615384615384" cy="276.92307692307696" r="3" fill="hsl(62, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.13
18
+ x-" data-x="-1.35" data-y="0.39999999999999947" cx="198.84615384615384" cy="294.8717948717949" r="3" fill="hsl(63, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.14
19
+ x-" data-x="-1.35" data-y="0.19999999999999973" cx="198.84615384615384" cy="312.8205128205129" r="3" fill="hsl(64, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.15
20
+ x-" data-x="-1.35" data-y="-4.440892098500626e-16" cx="198.84615384615384" cy="330.76923076923083" r="3" fill="hsl(65, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.16
21
+ x-" data-x="-1.35" data-y="-0.20000000000000018" cx="198.84615384615384" cy="348.71794871794873" r="3" fill="hsl(66, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.17
22
+ x-" data-x="-1.35" data-y="-0.40000000000000036" cx="198.84615384615384" cy="366.6666666666667" r="3" fill="hsl(67, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.18
23
+ x-" data-x="-1.35" data-y="-0.6000000000000005" cx="198.84615384615384" cy="384.61538461538464" r="3" fill="hsl(68, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.19
24
+ x-" data-x="-1.35" data-y="-0.8000000000000003" cx="198.84615384615384" cy="402.5641025641026" r="3" fill="hsl(69, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.20
25
+ x-" data-x="-1.35" data-y="-1.0000000000000004" cx="198.84615384615384" cy="420.51282051282055" r="3" fill="hsl(91, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.21
26
+ x-" data-x="-1.35" data-y="-1.2000000000000002" cx="198.84615384615384" cy="438.46153846153845" r="3" fill="hsl(92, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.left.22
27
+ x-" data-x="-1.35" data-y="-1.4000000000000004" cx="198.84615384615384" cy="456.41025641025647" r="3" fill="hsl(93, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.1
28
+ x+" data-x="1.35" data-y="2.8" cx="441.1538461538462" cy="79.48717948717953" r="3" fill="hsl(277, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.2
29
+ x+" data-x="1.35" data-y="2.5999999999999996" cx="441.1538461538462" cy="97.43589743589749" r="3" fill="hsl(278, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.3
30
+ x+" data-x="1.35" data-y="2.4" cx="441.1538461538462" cy="115.38461538461542" r="3" fill="hsl(279, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.4
31
+ x+" data-x="1.35" data-y="2.1999999999999997" cx="441.1538461538462" cy="133.33333333333337" r="3" fill="hsl(280, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.5
32
+ x+" data-x="1.35" data-y="1.9999999999999998" cx="441.1538461538462" cy="151.28205128205133" r="3" fill="hsl(281, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.6
33
+ x+" data-x="1.35" data-y="1.7999999999999998" cx="441.1538461538462" cy="169.23076923076925" r="3" fill="hsl(282, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.7
34
+ x+" data-x="1.35" data-y="1.5999999999999996" cx="441.1538461538462" cy="187.17948717948724" r="3" fill="hsl(283, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.8
35
+ x+" data-x="1.35" data-y="1.3999999999999997" cx="441.1538461538462" cy="205.12820512820517" r="3" fill="hsl(284, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.9
36
+ x+" data-x="1.35" data-y="1.1999999999999997" cx="441.1538461538462" cy="223.0769230769231" r="3" fill="hsl(285, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.10
37
+ x+" data-x="1.35" data-y="0.9999999999999998" cx="441.1538461538462" cy="241.02564102564105" r="3" fill="hsl(352, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.11
38
+ x+" data-x="1.35" data-y="0.7999999999999998" cx="441.1538461538462" cy="258.974358974359" r="3" fill="hsl(352, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.12
39
+ x+" data-x="1.35" data-y="0.5999999999999996" cx="441.1538461538462" cy="276.92307692307696" r="3" fill="hsl(352, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.13
40
+ x+" data-x="1.35" data-y="0.39999999999999947" cx="441.1538461538462" cy="294.8717948717949" r="3" fill="hsl(352, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.14
41
+ x+" data-x="1.35" data-y="0.19999999999999973" cx="441.1538461538462" cy="312.8205128205129" r="3" fill="hsl(352, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.15
42
+ x+" data-x="1.35" data-y="-4.440892098500626e-16" cx="441.1538461538462" cy="330.76923076923083" r="3" fill="hsl(0, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.16
43
+ x+" data-x="1.35" data-y="-0.20000000000000018" cx="441.1538461538462" cy="348.71794871794873" r="3" fill="hsl(0, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.17
44
+ x+" data-x="1.35" data-y="-0.40000000000000036" cx="441.1538461538462" cy="366.6666666666667" r="3" fill="hsl(0, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.18
45
+ x+" data-x="1.35" data-y="-0.6000000000000005" cx="441.1538461538462" cy="384.61538461538464" r="3" fill="hsl(0, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.19
46
+ x+" data-x="1.35" data-y="-0.8000000000000003" cx="441.1538461538462" cy="402.5641025641026" r="3" fill="hsl(0, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.20
47
+ x+" data-x="1.35" data-y="-1.0000000000000004" cx="441.1538461538462" cy="420.51282051282055" r="3" fill="hsl(24, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.21
48
+ x+" data-x="1.35" data-y="-1.2000000000000002" cx="441.1538461538462" cy="438.46153846153845" r="3" fill="hsl(24, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.right.22
49
+ x+" data-x="1.35" data-y="-1.4000000000000004" cx="441.1538461538462" cy="456.41025641025647" r="3" fill="hsl(24, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
50
+ orientation: y+" data-x="-1.9000000000000001" data-y="2.8" cx="149.48717948717947" cy="79.48717948717953" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
51
+ orientation: y+" data-x="-1.701" data-y="-1.3490000000000004" cx="167.34615384615384" cy="451.83333333333337" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
52
+ orientation: y+" data-x="1.9000000000000001" data-y="2.8" cx="490.51282051282055" cy="79.48717948717953" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
53
+ orientation: y+" data-x="1.701" data-y="-1.3490000000000004" cx="472.6538461538462" cy="451.83333333333337" 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[
54
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
55
+ const svg = e.currentTarget;
56
+ const rect = svg.getBoundingClientRect();
57
+ const x = e.clientX - rect.left;
58
+ const y = e.clientY - rect.top;
59
+ const crosshair = svg.getElementById('crosshair');
60
+ const h = svg.getElementById('crosshair-h');
61
+ const v = svg.getElementById('crosshair-v');
62
+ const coords = svg.getElementById('coordinates');
63
+
64
+ crosshair.style.display = 'block';
65
+ h.setAttribute('x1', '0');
66
+ h.setAttribute('x2', '640');
67
+ h.setAttribute('y1', y);
68
+ h.setAttribute('y2', y);
69
+ v.setAttribute('x1', x);
70
+ v.setAttribute('x2', x);
71
+ v.setAttribute('y1', '0');
72
+ v.setAttribute('y2', '640');
73
+
74
+ // Calculate real coordinates using inverse transformation
75
+ const matrix = {"a":89.74358974358974,"c":0,"e":320,"b":0,"d":-89.74358974358974,"f":330.7692307692308};
76
+ // Manually invert and apply the affine transform
77
+ // Since we only use translate and scale, we can directly compute:
78
+ // x' = (x - tx) / sx
79
+ // y' = (y - ty) / sy
80
+ const sx = matrix.a;
81
+ const sy = matrix.d;
82
+ const tx = matrix.e;
83
+ const ty = matrix.f;
84
+ const realPoint = {
85
+ x: (x - tx) / sx,
86
+ y: (y - ty) / sy // Flip y back since we used negative scale
87
+ }
88
+
89
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
90
+ coords.setAttribute('x', (x + 5).toString());
91
+ coords.setAttribute('y', (y - 5).toString());
92
+ });
93
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
94
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
95
+ });
96
+ ]]></script></svg>
@@ -0,0 +1,95 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import type { InputProblem } from "lib/types/InputProblem"
4
+ import "tests/fixtures/matcher"
5
+
6
+ const inputProblem: InputProblem = {
7
+ chips: [
8
+ {
9
+ chipId: "U1",
10
+ center: { x: 0, y: 0 },
11
+ width: 2,
12
+ height: 1.4,
13
+ pins: [
14
+ ...[0.5, 0.25, 0, -0.25, -0.5].map((y, index) => ({
15
+ pinId: `U1.${index + 1}`,
16
+ x: -1,
17
+ y,
18
+ _facingDirection: "x-" as const,
19
+ })),
20
+ ...[0.5, 0.25, 0, -0.25, -0.5].map((y, index) => ({
21
+ pinId: `U1.${index + 6}`,
22
+ x: 1,
23
+ y,
24
+ _facingDirection: "x+" as const,
25
+ })),
26
+ ],
27
+ },
28
+ ],
29
+ directConnections: [],
30
+ netConnections: [
31
+ {
32
+ netId: "VBAT",
33
+ pinIds: ["U1.1", "U1.2", "U1.3"],
34
+ netLabelWidth: 0.48,
35
+ netLabelHeight: 0.48,
36
+ },
37
+ {
38
+ netId: "GND",
39
+ pinIds: ["U1.4", "U1.5"],
40
+ netLabelWidth: 0.36,
41
+ netLabelHeight: 0.48,
42
+ },
43
+ ],
44
+ textBoxes: [
45
+ {
46
+ chipId: "U1",
47
+ center: { x: -0.25, y: 0.85 },
48
+ width: 0.7,
49
+ height: 0.2,
50
+ text: "U1 Power",
51
+ },
52
+ ],
53
+ availableNetLabelOrientations: {
54
+ VBAT: ["y+"],
55
+ GND: ["y-"],
56
+ },
57
+ maxMspPairDistance: 2.4,
58
+ }
59
+
60
+ test("places same-side VBAT and GND labels at opposite rail ends", () => {
61
+ const solver = new SchematicTracePipelineSolver(inputProblem)
62
+
63
+ solver.solve()
64
+
65
+ const outputLabels =
66
+ solver.netLabelNetLabelCollisionSolver!.getOutput().netLabelPlacements
67
+ const u1 = solver.inputProblem.chips.find((chip) => chip.chipId === "U1")!
68
+ const chipLeft = u1.center.x - u1.width / 2
69
+
70
+ for (const expected of [
71
+ { netId: "VBAT", orientation: "y+" as const, anchorY: 0.5 },
72
+ { netId: "GND", orientation: "y-" as const, anchorY: -0.5 },
73
+ ]) {
74
+ const label = outputLabels.find(
75
+ (candidate) => candidate.netId === expected.netId,
76
+ )!
77
+ const connector = solver.availableNetOrientationSolver!.traces.find(
78
+ (trace) =>
79
+ trace.userNetId === expected.netId &&
80
+ trace.mspPairId.startsWith("available-net-orientation-"),
81
+ )!
82
+ const [connectorSource, connectorTarget] = connector.tracePath
83
+ const labelRight = label.center.x + label.width / 2
84
+
85
+ expect(label.orientation).toBe(expected.orientation)
86
+ expect(label.anchorPoint.y).toBeCloseTo(expected.anchorY)
87
+ expect(labelRight).toBeLessThan(chipLeft)
88
+ expect(connector.tracePath).toHaveLength(2)
89
+ expect(connectorSource!.y).toBeCloseTo(connectorTarget!.y)
90
+ expect(connectorTarget!.x).toBeLessThan(connectorSource!.x)
91
+ expect(connectorSource!.x - connectorTarget!.x).toBeLessThan(0.5)
92
+ }
93
+
94
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
95
+ })
@@ -0,0 +1,102 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import type { InputProblem } from "lib/types/InputProblem"
4
+ import "tests/fixtures/matcher"
5
+
6
+ const createRp2040SidePins = (side: "left" | "right") =>
7
+ Array.from({ length: 22 }, (_, index) => ({
8
+ pinId: `U1.${side}.${index + 1}`,
9
+ x: side === "left" ? -1.35 : 1.35,
10
+ y: 2.8 - index * 0.2,
11
+ _facingDirection: side === "left" ? ("x-" as const) : ("x+" as const),
12
+ }))
13
+
14
+ // Reduced from the current @tscircuit/core input for an RP2040, then mirrored
15
+ // to cover both chip sides. The important details are the 0.2-unit pin pitch,
16
+ // 0.6-unit rail-label height, and a third distance-split member on each net.
17
+ // The reversed first pair preserves the MSP direction produced by the original
18
+ // multi-pin input (pin 10 to pin 1).
19
+ const inputProblem: InputProblem = {
20
+ chips: [
21
+ {
22
+ chipId: "U1",
23
+ center: { x: 0, y: 0 },
24
+ width: 1.9,
25
+ height: 6,
26
+ pins: [...createRp2040SidePins("left"), ...createRp2040SidePins("right")],
27
+ },
28
+ ],
29
+ directConnections: [],
30
+ netConnections: [
31
+ {
32
+ netId: "V3V3_LEFT",
33
+ pinIds: ["U1.left.10", "U1.left.1", "U1.left.22"],
34
+ netLabelWidth: 0.42,
35
+ netLabelHeight: 0.6,
36
+ },
37
+ {
38
+ netId: "V3V3_RIGHT",
39
+ pinIds: ["U1.right.10", "U1.right.1", "U1.right.22"],
40
+ netLabelWidth: 0.42,
41
+ netLabelHeight: 0.6,
42
+ },
43
+ ],
44
+ textBoxes: [
45
+ {
46
+ chipId: "U1",
47
+ center: { x: -0.83, y: 3.115 },
48
+ width: 0.36,
49
+ height: 0.25,
50
+ text: "U1",
51
+ },
52
+ ],
53
+ availableNetLabelOrientations: {
54
+ V3V3_LEFT: ["y+"],
55
+ V3V3_RIGHT: ["y+"],
56
+ },
57
+ maxMspPairDistance: 2.4,
58
+ }
59
+
60
+ test("places RP2040 rail labels above and outside both chip sides", () => {
61
+ const solver = new SchematicTracePipelineSolver(inputProblem)
62
+
63
+ solver.solve()
64
+
65
+ const outputLabels =
66
+ solver.netLabelNetLabelCollisionSolver!.getOutput().netLabelPlacements
67
+ const u1 = solver.inputProblem.chips.find((chip) => chip.chipId === "U1")!
68
+ const chipLeft = u1.center.x - u1.width / 2
69
+ const chipRight = u1.center.x + u1.width / 2
70
+
71
+ for (const side of ["left", "right"] as const) {
72
+ const netId = `V3V3_${side.toUpperCase()}`
73
+ const label = outputLabels.find(
74
+ (candidate) =>
75
+ candidate.netId === netId && candidate.pinIds.includes(`U1.${side}.1`),
76
+ )!
77
+ const connector = solver.availableNetOrientationSolver!.traces.find(
78
+ (trace) =>
79
+ trace.userNetId === netId &&
80
+ trace.mspPairId.startsWith("available-net-orientation-"),
81
+ )!
82
+ const [connectorSource, connectorTarget] = connector.tracePath
83
+ const labelLeft = label.center.x - label.width / 2
84
+ const labelRight = label.center.x + label.width / 2
85
+
86
+ expect(label.orientation).toBe("y+")
87
+ expect(label.anchorPoint.y).toBeCloseTo(2.8)
88
+ expect(connector.tracePath).toHaveLength(2)
89
+ expect(connectorSource!.y).toBeCloseTo(connectorTarget!.y)
90
+ expect(Math.abs(connectorSource!.x - connectorTarget!.x)).toBeLessThan(0.5)
91
+
92
+ if (side === "left") {
93
+ expect(labelRight).toBeLessThan(chipLeft)
94
+ expect(connectorTarget!.x).toBeLessThan(connectorSource!.x)
95
+ } else {
96
+ expect(labelLeft).toBeGreaterThan(chipRight)
97
+ expect(connectorTarget!.x).toBeGreaterThan(connectorSource!.x)
98
+ }
99
+ }
100
+
101
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
102
+ })