@tscircuit/schematic-trace-solver 0.0.105 → 0.0.106
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 +133 -80
- package/lib/solvers/TraceCleanupSolver/minimizeTurnsWithFilteredLabels.ts +78 -27
- package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry.ts +40 -20
- package/package.json +1 -1
- package/tests/examples/__snapshots__/example13.snap.svg +3 -3
- package/tests/examples/__snapshots__/example29.snap.svg +23 -23
- package/tests/examples/example19.test.ts +4 -0
- package/tests/repros/__snapshots__/repro-example35-minimize-trace-crossing.snap.svg +256 -0
- package/tests/repros/assets/repro-example35-minimize-trace-crossing.input.json +1561 -0
- package/tests/repros/repro-example35-minimize-trace-crossing.test.ts +22 -0
package/dist/index.js
CHANGED
|
@@ -4774,6 +4774,95 @@ var minimizeTurns = ({
|
|
|
4774
4774
|
return finalSimplifiedPath;
|
|
4775
4775
|
};
|
|
4776
4776
|
|
|
4777
|
+
// lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry.ts
|
|
4778
|
+
var RAIL_ALIGNMENT_EPSILON = 2e-3;
|
|
4779
|
+
var nearlyEqual = (a, b) => Math.abs(a - b) < RAIL_ALIGNMENT_EPSILON;
|
|
4780
|
+
var isHorizontal2 = (a, b) => nearlyEqual(a.y, b.y);
|
|
4781
|
+
var isVertical2 = (a, b) => nearlyEqual(a.x, b.x);
|
|
4782
|
+
var isPositiveLength = (a, b) => Math.abs(a.x - b.x) >= RAIL_ALIGNMENT_EPSILON || Math.abs(a.y - b.y) >= RAIL_ALIGNMENT_EPSILON;
|
|
4783
|
+
var getRailOrientation = (a, b) => {
|
|
4784
|
+
if (!isPositiveLength(a, b)) return null;
|
|
4785
|
+
if (isVertical2(a, b)) return "vertical";
|
|
4786
|
+
if (isHorizontal2(a, b)) return "horizontal";
|
|
4787
|
+
return null;
|
|
4788
|
+
};
|
|
4789
|
+
var rangesTouchOrOverlap = (a, b) => Math.min(a.maxAlong, b.maxAlong) - Math.max(a.minAlong, b.minAlong) >= -RAIL_ALIGNMENT_EPSILON;
|
|
4790
|
+
var pointsEqual = (a, b) => nearlyEqual(a.x, b.x) && nearlyEqual(a.y, b.y);
|
|
4791
|
+
var getDistinctCoordinates = (coordinates) => {
|
|
4792
|
+
const distinct = [];
|
|
4793
|
+
for (const coordinate of coordinates) {
|
|
4794
|
+
if (!distinct.some((item) => nearlyEqual(item, coordinate))) {
|
|
4795
|
+
distinct.push(coordinate);
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
return distinct;
|
|
4799
|
+
};
|
|
4800
|
+
var getMergedIntervalMetrics = (intervals) => {
|
|
4801
|
+
const groups = [];
|
|
4802
|
+
for (const interval of intervals) {
|
|
4803
|
+
const group = groups.find(
|
|
4804
|
+
(items) => nearlyEqual(items[0].coordinate, interval.coordinate)
|
|
4805
|
+
);
|
|
4806
|
+
if (group) group.push(interval);
|
|
4807
|
+
else groups.push([interval]);
|
|
4808
|
+
}
|
|
4809
|
+
return groups.reduce(
|
|
4810
|
+
(total, group) => {
|
|
4811
|
+
const sorted = [...group].sort((a, b) => a.min - b.min);
|
|
4812
|
+
let groupLength = 0;
|
|
4813
|
+
let segmentCount = 1;
|
|
4814
|
+
let currentMin = sorted[0].min;
|
|
4815
|
+
let currentMax = sorted[0].max;
|
|
4816
|
+
for (const interval of sorted.slice(1)) {
|
|
4817
|
+
if (interval.min <= currentMax + RAIL_ALIGNMENT_EPSILON) {
|
|
4818
|
+
currentMax = Math.max(currentMax, interval.max);
|
|
4819
|
+
} else {
|
|
4820
|
+
groupLength += currentMax - currentMin;
|
|
4821
|
+
segmentCount++;
|
|
4822
|
+
currentMin = interval.min;
|
|
4823
|
+
currentMax = interval.max;
|
|
4824
|
+
}
|
|
4825
|
+
}
|
|
4826
|
+
return {
|
|
4827
|
+
length: total.length + groupLength + currentMax - currentMin,
|
|
4828
|
+
segmentCount: total.segmentCount + segmentCount
|
|
4829
|
+
};
|
|
4830
|
+
},
|
|
4831
|
+
{ length: 0, segmentCount: 0 }
|
|
4832
|
+
);
|
|
4833
|
+
};
|
|
4834
|
+
var getVisibleTraceMetrics = (traces) => {
|
|
4835
|
+
const horizontal = [];
|
|
4836
|
+
const vertical = [];
|
|
4837
|
+
for (const trace of traces) {
|
|
4838
|
+
for (let index = 0; index < trace.tracePath.length - 1; index++) {
|
|
4839
|
+
const start = trace.tracePath[index];
|
|
4840
|
+
const end = trace.tracePath[index + 1];
|
|
4841
|
+
if (isHorizontal2(start, end)) {
|
|
4842
|
+
horizontal.push({
|
|
4843
|
+
coordinate: start.y,
|
|
4844
|
+
min: Math.min(start.x, end.x),
|
|
4845
|
+
max: Math.max(start.x, end.x)
|
|
4846
|
+
});
|
|
4847
|
+
} else if (isVertical2(start, end)) {
|
|
4848
|
+
vertical.push({
|
|
4849
|
+
coordinate: start.x,
|
|
4850
|
+
min: Math.min(start.y, end.y),
|
|
4851
|
+
max: Math.max(start.y, end.y)
|
|
4852
|
+
});
|
|
4853
|
+
}
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
const horizontalMetrics = getMergedIntervalMetrics(horizontal);
|
|
4857
|
+
const verticalMetrics = getMergedIntervalMetrics(vertical);
|
|
4858
|
+
return {
|
|
4859
|
+
length: horizontalMetrics.length + verticalMetrics.length,
|
|
4860
|
+
segmentCount: horizontalMetrics.segmentCount + verticalMetrics.segmentCount
|
|
4861
|
+
};
|
|
4862
|
+
};
|
|
4863
|
+
var getVisibleTraceLength = (traces) => getVisibleTraceMetrics(traces).length;
|
|
4864
|
+
var getVisibleTraceSegmentCount = (traces) => getVisibleTraceMetrics(traces).segmentCount;
|
|
4865
|
+
|
|
4777
4866
|
// lib/solvers/TraceCleanupSolver/minimizeTurnsWithFilteredLabels.ts
|
|
4778
4867
|
var minimizeTurnsWithFilteredLabels = ({
|
|
4779
4868
|
targetMspConnectionPairId,
|
|
@@ -4789,11 +4878,16 @@ var minimizeTurnsWithFilteredLabels = ({
|
|
|
4789
4878
|
if (!targetTrace) {
|
|
4790
4879
|
throw new Error(`Target trace ${targetMspConnectionPairId} not found`);
|
|
4791
4880
|
}
|
|
4792
|
-
const
|
|
4793
|
-
|
|
4881
|
+
const targetPinIds = new Set(targetTrace.pinIds);
|
|
4882
|
+
const otherTraces = traces.filter(
|
|
4883
|
+
(trace) => trace.mspPairId !== targetMspConnectionPairId
|
|
4794
4884
|
);
|
|
4885
|
+
const relaxedObstacleTraces = otherTraces.filter((trace) => {
|
|
4886
|
+
const sharesEndpoint = trace.pinIds.some((pinId) => targetPinIds.has(pinId));
|
|
4887
|
+
return trace.globalConnNetId !== targetTrace.globalConnNetId || !sharesEndpoint;
|
|
4888
|
+
});
|
|
4795
4889
|
const TRACE_WIDTH = 0.01;
|
|
4796
|
-
const
|
|
4890
|
+
const getTraceObstacles2 = (obstacleTraces) => obstacleTraces.flatMap(
|
|
4797
4891
|
(trace, i) => trace.tracePath.slice(0, -1).map((p1, pi) => {
|
|
4798
4892
|
const p2 = trace.tracePath[pi + 1];
|
|
4799
4893
|
return {
|
|
@@ -4814,7 +4908,6 @@ var minimizeTurnsWithFilteredLabels = ({
|
|
|
4814
4908
|
maxX: obs.maxX + PADDING,
|
|
4815
4909
|
maxY: obs.maxY + PADDING
|
|
4816
4910
|
}));
|
|
4817
|
-
const combinedObstacles = [...staticObstacles, ...traceObstacles];
|
|
4818
4911
|
const originalPath = targetTrace.tracePath;
|
|
4819
4912
|
const filteredLabels = allLabelPlacements.filter((label) => {
|
|
4820
4913
|
const originalNetIds = mergedLabelNetIdMap[label.globalConnNetId];
|
|
@@ -4829,12 +4922,46 @@ var minimizeTurnsWithFilteredLabels = ({
|
|
|
4829
4922
|
minY: nl.center.y - nl.height / 2 - paddingBuffer,
|
|
4830
4923
|
maxY: nl.center.y + nl.height / 2 + paddingBuffer
|
|
4831
4924
|
}));
|
|
4832
|
-
const
|
|
4925
|
+
const strictPath = minimizeTurns({
|
|
4833
4926
|
path: originalPath,
|
|
4834
|
-
obstacles:
|
|
4927
|
+
obstacles: [...staticObstacles, ...getTraceObstacles2(otherTraces)],
|
|
4835
4928
|
labelBounds,
|
|
4836
4929
|
originalPath
|
|
4837
4930
|
});
|
|
4931
|
+
const relaxedPath = minimizeTurns({
|
|
4932
|
+
path: originalPath,
|
|
4933
|
+
obstacles: [
|
|
4934
|
+
...staticObstacles,
|
|
4935
|
+
...getTraceObstacles2(relaxedObstacleTraces)
|
|
4936
|
+
],
|
|
4937
|
+
labelBounds,
|
|
4938
|
+
originalPath
|
|
4939
|
+
});
|
|
4940
|
+
const sameNetTraces = otherTraces.filter(
|
|
4941
|
+
(trace) => trace.globalConnNetId === targetTrace.globalConnNetId
|
|
4942
|
+
);
|
|
4943
|
+
const getSameNetReadability = (tracePath) => {
|
|
4944
|
+
const tracesWithCandidate = [
|
|
4945
|
+
...sameNetTraces,
|
|
4946
|
+
{ ...targetTrace, tracePath }
|
|
4947
|
+
];
|
|
4948
|
+
return {
|
|
4949
|
+
segmentCount: getVisibleTraceSegmentCount(tracesWithCandidate),
|
|
4950
|
+
visibleLength: getVisibleTraceLength(tracesWithCandidate)
|
|
4951
|
+
};
|
|
4952
|
+
};
|
|
4953
|
+
const strictTurns = countTurns(strictPath);
|
|
4954
|
+
const relaxedTurns = countTurns(relaxedPath);
|
|
4955
|
+
let newPath = strictPath;
|
|
4956
|
+
if (relaxedTurns < strictTurns) {
|
|
4957
|
+
newPath = relaxedPath;
|
|
4958
|
+
} else if (relaxedTurns === strictTurns) {
|
|
4959
|
+
const strictReadability = getSameNetReadability(strictPath);
|
|
4960
|
+
const relaxedReadability = getSameNetReadability(relaxedPath);
|
|
4961
|
+
if (relaxedReadability.segmentCount < strictReadability.segmentCount || relaxedReadability.segmentCount === strictReadability.segmentCount && relaxedReadability.visibleLength < strictReadability.visibleLength - RAIL_ALIGNMENT_EPSILON) {
|
|
4962
|
+
newPath = relaxedPath;
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4838
4965
|
return {
|
|
4839
4966
|
...targetTrace,
|
|
4840
4967
|
tracePath: newPath
|
|
@@ -4978,80 +5105,6 @@ var balanceZShapes = ({
|
|
|
4978
5105
|
};
|
|
4979
5106
|
};
|
|
4980
5107
|
|
|
4981
|
-
// lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry.ts
|
|
4982
|
-
var RAIL_ALIGNMENT_EPSILON = 2e-3;
|
|
4983
|
-
var nearlyEqual = (a, b) => Math.abs(a - b) < RAIL_ALIGNMENT_EPSILON;
|
|
4984
|
-
var isHorizontal2 = (a, b) => nearlyEqual(a.y, b.y);
|
|
4985
|
-
var isVertical2 = (a, b) => nearlyEqual(a.x, b.x);
|
|
4986
|
-
var isPositiveLength = (a, b) => Math.abs(a.x - b.x) >= RAIL_ALIGNMENT_EPSILON || Math.abs(a.y - b.y) >= RAIL_ALIGNMENT_EPSILON;
|
|
4987
|
-
var getRailOrientation = (a, b) => {
|
|
4988
|
-
if (!isPositiveLength(a, b)) return null;
|
|
4989
|
-
if (isVertical2(a, b)) return "vertical";
|
|
4990
|
-
if (isHorizontal2(a, b)) return "horizontal";
|
|
4991
|
-
return null;
|
|
4992
|
-
};
|
|
4993
|
-
var rangesTouchOrOverlap = (a, b) => Math.min(a.maxAlong, b.maxAlong) - Math.max(a.minAlong, b.minAlong) >= -RAIL_ALIGNMENT_EPSILON;
|
|
4994
|
-
var pointsEqual = (a, b) => nearlyEqual(a.x, b.x) && nearlyEqual(a.y, b.y);
|
|
4995
|
-
var getDistinctCoordinates = (coordinates) => {
|
|
4996
|
-
const distinct = [];
|
|
4997
|
-
for (const coordinate of coordinates) {
|
|
4998
|
-
if (!distinct.some((item) => nearlyEqual(item, coordinate))) {
|
|
4999
|
-
distinct.push(coordinate);
|
|
5000
|
-
}
|
|
5001
|
-
}
|
|
5002
|
-
return distinct;
|
|
5003
|
-
};
|
|
5004
|
-
var getMergedIntervalLength = (intervals) => {
|
|
5005
|
-
const groups = [];
|
|
5006
|
-
for (const interval of intervals) {
|
|
5007
|
-
const group = groups.find(
|
|
5008
|
-
(items) => nearlyEqual(items[0].coordinate, interval.coordinate)
|
|
5009
|
-
);
|
|
5010
|
-
if (group) group.push(interval);
|
|
5011
|
-
else groups.push([interval]);
|
|
5012
|
-
}
|
|
5013
|
-
return groups.reduce((total, group) => {
|
|
5014
|
-
const sorted = [...group].sort((a, b) => a.min - b.min);
|
|
5015
|
-
let groupLength = 0;
|
|
5016
|
-
let currentMin = sorted[0].min;
|
|
5017
|
-
let currentMax = sorted[0].max;
|
|
5018
|
-
for (const interval of sorted.slice(1)) {
|
|
5019
|
-
if (interval.min <= currentMax + RAIL_ALIGNMENT_EPSILON) {
|
|
5020
|
-
currentMax = Math.max(currentMax, interval.max);
|
|
5021
|
-
} else {
|
|
5022
|
-
groupLength += currentMax - currentMin;
|
|
5023
|
-
currentMin = interval.min;
|
|
5024
|
-
currentMax = interval.max;
|
|
5025
|
-
}
|
|
5026
|
-
}
|
|
5027
|
-
return total + groupLength + currentMax - currentMin;
|
|
5028
|
-
}, 0);
|
|
5029
|
-
};
|
|
5030
|
-
var getVisibleTraceLength = (traces) => {
|
|
5031
|
-
const horizontal = [];
|
|
5032
|
-
const vertical = [];
|
|
5033
|
-
for (const trace of traces) {
|
|
5034
|
-
for (let index = 0; index < trace.tracePath.length - 1; index++) {
|
|
5035
|
-
const start = trace.tracePath[index];
|
|
5036
|
-
const end = trace.tracePath[index + 1];
|
|
5037
|
-
if (isHorizontal2(start, end)) {
|
|
5038
|
-
horizontal.push({
|
|
5039
|
-
coordinate: start.y,
|
|
5040
|
-
min: Math.min(start.x, end.x),
|
|
5041
|
-
max: Math.max(start.x, end.x)
|
|
5042
|
-
});
|
|
5043
|
-
} else if (isVertical2(start, end)) {
|
|
5044
|
-
vertical.push({
|
|
5045
|
-
coordinate: start.x,
|
|
5046
|
-
min: Math.min(start.y, end.y),
|
|
5047
|
-
max: Math.max(start.y, end.y)
|
|
5048
|
-
});
|
|
5049
|
-
}
|
|
5050
|
-
}
|
|
5051
|
-
}
|
|
5052
|
-
return getMergedIntervalLength(horizontal) + getMergedIntervalLength(vertical);
|
|
5053
|
-
};
|
|
5054
|
-
|
|
5055
5108
|
// lib/solvers/TraceCleanupSolver/sameNetRailAlignment/moveRailSegments.ts
|
|
5056
5109
|
var moveRailSegments = (trace, segments, coordinate) => {
|
|
5057
5110
|
const pointsToMove = /* @__PURE__ */ new Set();
|
|
@@ -3,13 +3,18 @@ import { minimizeTurns } from "./turnMinimization"
|
|
|
3
3
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
4
4
|
import { getObstacleRects } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect"
|
|
5
5
|
import type { NetLabelPlacement } from "../NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
6
|
+
import { countTurns } from "./countTurns"
|
|
7
|
+
import {
|
|
8
|
+
getVisibleTraceLength,
|
|
9
|
+
getVisibleTraceSegmentCount,
|
|
10
|
+
RAIL_ALIGNMENT_EPSILON,
|
|
11
|
+
} from "./sameNetRailAlignment/geometry"
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
|
-
* Minimizes
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Finally, it uses a turn minimization algorithm to find a new path for the target trace that avoids these combined obstacles.
|
|
14
|
+
* Minimizes turns with a strict pass that treats every other trace as an
|
|
15
|
+
* obstacle and a relaxed pass that permits joining endpoint-sharing same-net
|
|
16
|
+
* branches. Equivalent-turn routes are compared by their rendered same-net
|
|
17
|
+
* complexity so aligned rails win without arbitrarily shifting local routes.
|
|
13
18
|
*/
|
|
14
19
|
export const minimizeTurnsWithFilteredLabels = ({
|
|
15
20
|
targetMspConnectionPairId,
|
|
@@ -33,27 +38,31 @@ export const minimizeTurnsWithFilteredLabels = ({
|
|
|
33
38
|
throw new Error(`Target trace ${targetMspConnectionPairId} not found`)
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
(t) =>
|
|
40
|
-
t.mspPairId !== targetMspConnectionPairId &&
|
|
41
|
-
t.globalConnNetId !== targetTrace.globalConnNetId,
|
|
41
|
+
const targetPinIds = new Set(targetTrace.pinIds)
|
|
42
|
+
const otherTraces = traces.filter(
|
|
43
|
+
(trace) => trace.mspPairId !== targetMspConnectionPairId,
|
|
42
44
|
)
|
|
45
|
+
const relaxedObstacleTraces = otherTraces.filter((trace) => {
|
|
46
|
+
const sharesEndpoint = trace.pinIds.some((pinId) => targetPinIds.has(pinId))
|
|
47
|
+
return (
|
|
48
|
+
trace.globalConnNetId !== targetTrace.globalConnNetId || !sharesEndpoint
|
|
49
|
+
)
|
|
50
|
+
})
|
|
43
51
|
|
|
44
52
|
const TRACE_WIDTH = 0.01
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
const getTraceObstacles = (obstacleTraces: SolvedTracePath[]) =>
|
|
54
|
+
obstacleTraces.flatMap((trace, i) =>
|
|
55
|
+
trace.tracePath.slice(0, -1).map((p1, pi) => {
|
|
56
|
+
const p2 = trace.tracePath[pi + 1]!
|
|
57
|
+
return {
|
|
58
|
+
chipId: `trace-obstacle-${i}-${pi}`,
|
|
59
|
+
minX: Math.min(p1.x, p2.x) - TRACE_WIDTH / 2,
|
|
60
|
+
minY: Math.min(p1.y, p2.y) - TRACE_WIDTH / 2,
|
|
61
|
+
maxX: Math.max(p1.x, p2.x) + TRACE_WIDTH / 2,
|
|
62
|
+
maxY: Math.max(p1.y, p2.y) + TRACE_WIDTH / 2,
|
|
63
|
+
}
|
|
64
|
+
}),
|
|
65
|
+
)
|
|
57
66
|
|
|
58
67
|
const staticObstaclesRaw = getObstacleRects(inputProblem)
|
|
59
68
|
const PADDING = 0.01
|
|
@@ -65,8 +74,6 @@ export const minimizeTurnsWithFilteredLabels = ({
|
|
|
65
74
|
maxY: obs.maxY + PADDING,
|
|
66
75
|
}))
|
|
67
76
|
|
|
68
|
-
const combinedObstacles = [...staticObstacles, ...traceObstacles]
|
|
69
|
-
|
|
70
77
|
const originalPath = targetTrace.tracePath
|
|
71
78
|
const filteredLabels = allLabelPlacements.filter((label) => {
|
|
72
79
|
const originalNetIds = mergedLabelNetIdMap[label.globalConnNetId]
|
|
@@ -83,13 +90,57 @@ export const minimizeTurnsWithFilteredLabels = ({
|
|
|
83
90
|
maxY: nl.center.y + nl.height / 2 + paddingBuffer,
|
|
84
91
|
}))
|
|
85
92
|
|
|
86
|
-
const
|
|
93
|
+
const strictPath = minimizeTurns({
|
|
87
94
|
path: originalPath,
|
|
88
|
-
obstacles:
|
|
95
|
+
obstacles: [...staticObstacles, ...getTraceObstacles(otherTraces)],
|
|
89
96
|
labelBounds,
|
|
90
97
|
originalPath: originalPath,
|
|
91
98
|
})
|
|
92
99
|
|
|
100
|
+
const relaxedPath = minimizeTurns({
|
|
101
|
+
path: originalPath,
|
|
102
|
+
obstacles: [
|
|
103
|
+
...staticObstacles,
|
|
104
|
+
...getTraceObstacles(relaxedObstacleTraces),
|
|
105
|
+
],
|
|
106
|
+
labelBounds,
|
|
107
|
+
originalPath: originalPath,
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const sameNetTraces = otherTraces.filter(
|
|
111
|
+
(trace) => trace.globalConnNetId === targetTrace.globalConnNetId,
|
|
112
|
+
)
|
|
113
|
+
const getSameNetReadability = (tracePath: SolvedTracePath["tracePath"]) => {
|
|
114
|
+
const tracesWithCandidate = [
|
|
115
|
+
...sameNetTraces,
|
|
116
|
+
{ ...targetTrace, tracePath },
|
|
117
|
+
]
|
|
118
|
+
return {
|
|
119
|
+
segmentCount: getVisibleTraceSegmentCount(tracesWithCandidate),
|
|
120
|
+
visibleLength: getVisibleTraceLength(tracesWithCandidate),
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const strictTurns = countTurns(strictPath)
|
|
125
|
+
const relaxedTurns = countTurns(relaxedPath)
|
|
126
|
+
let newPath = strictPath
|
|
127
|
+
|
|
128
|
+
if (relaxedTurns < strictTurns) {
|
|
129
|
+
newPath = relaxedPath
|
|
130
|
+
} else if (relaxedTurns === strictTurns) {
|
|
131
|
+
const strictReadability = getSameNetReadability(strictPath)
|
|
132
|
+
const relaxedReadability = getSameNetReadability(relaxedPath)
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
relaxedReadability.segmentCount < strictReadability.segmentCount ||
|
|
136
|
+
(relaxedReadability.segmentCount === strictReadability.segmentCount &&
|
|
137
|
+
relaxedReadability.visibleLength <
|
|
138
|
+
strictReadability.visibleLength - RAIL_ALIGNMENT_EPSILON)
|
|
139
|
+
) {
|
|
140
|
+
newPath = relaxedPath
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
93
144
|
return {
|
|
94
145
|
...targetTrace,
|
|
95
146
|
tracePath: newPath,
|
|
@@ -48,7 +48,7 @@ interface Interval {
|
|
|
48
48
|
max: number
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const getMergedIntervalMetrics = (intervals: Interval[]) => {
|
|
52
52
|
const groups: Interval[][] = []
|
|
53
53
|
for (const interval of intervals) {
|
|
54
54
|
const group = groups.find((items) =>
|
|
@@ -58,28 +58,35 @@ const getMergedIntervalLength = (intervals: Interval[]) => {
|
|
|
58
58
|
else groups.push([interval])
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
return groups.reduce(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
return groups.reduce(
|
|
62
|
+
(total, group) => {
|
|
63
|
+
const sorted = [...group].sort((a, b) => a.min - b.min)
|
|
64
|
+
let groupLength = 0
|
|
65
|
+
let segmentCount = 1
|
|
66
|
+
let currentMin = sorted[0]!.min
|
|
67
|
+
let currentMax = sorted[0]!.max
|
|
68
|
+
|
|
69
|
+
for (const interval of sorted.slice(1)) {
|
|
70
|
+
if (interval.min <= currentMax + RAIL_ALIGNMENT_EPSILON) {
|
|
71
|
+
currentMax = Math.max(currentMax, interval.max)
|
|
72
|
+
} else {
|
|
73
|
+
groupLength += currentMax - currentMin
|
|
74
|
+
segmentCount++
|
|
75
|
+
currentMin = interval.min
|
|
76
|
+
currentMax = interval.max
|
|
77
|
+
}
|
|
74
78
|
}
|
|
75
|
-
}
|
|
76
79
|
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
return {
|
|
81
|
+
length: total.length + groupLength + currentMax - currentMin,
|
|
82
|
+
segmentCount: total.segmentCount + segmentCount,
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{ length: 0, segmentCount: 0 },
|
|
86
|
+
)
|
|
79
87
|
}
|
|
80
88
|
|
|
81
|
-
|
|
82
|
-
export const getVisibleTraceLength = (traces: SolvedTracePath[]) => {
|
|
89
|
+
const getVisibleTraceMetrics = (traces: SolvedTracePath[]) => {
|
|
83
90
|
const horizontal: Interval[] = []
|
|
84
91
|
const vertical: Interval[] = []
|
|
85
92
|
|
|
@@ -104,5 +111,18 @@ export const getVisibleTraceLength = (traces: SolvedTracePath[]) => {
|
|
|
104
111
|
}
|
|
105
112
|
}
|
|
106
113
|
|
|
107
|
-
|
|
114
|
+
const horizontalMetrics = getMergedIntervalMetrics(horizontal)
|
|
115
|
+
const verticalMetrics = getMergedIntervalMetrics(vertical)
|
|
116
|
+
return {
|
|
117
|
+
length: horizontalMetrics.length + verticalMetrics.length,
|
|
118
|
+
segmentCount: horizontalMetrics.segmentCount + verticalMetrics.segmentCount,
|
|
119
|
+
}
|
|
108
120
|
}
|
|
121
|
+
|
|
122
|
+
/** Returns rendered length after overlapping collinear runs are merged. */
|
|
123
|
+
export const getVisibleTraceLength = (traces: SolvedTracePath[]) =>
|
|
124
|
+
getVisibleTraceMetrics(traces).length
|
|
125
|
+
|
|
126
|
+
/** Returns the number of distinct collinear runs visible on the schematic. */
|
|
127
|
+
export const getVisibleTraceSegmentCount = (traces: SolvedTracePath[]) =>
|
|
128
|
+
getVisibleTraceMetrics(traces).segmentCount
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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="-3.55,0 -1.15,1.125" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 215.507835171213,279.37318630296" fill="none" stroke="hsl(40, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="3.435,3 -2.45,2" data-type="line" data-label="" points="513.5461404526988,157.49274521183986 131.00406268136967,222.49564712710392" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.375 -2.45,0" data-type="line" data-label="" points="215.507835171213,328.12536273940805 131.00406268136967,352.5014509576321" fill="none" stroke="hsl(272, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.375 -3.55,-1.9999999999999998" data-type="line" data-label="" points="215.507835171213,328.12536273940805 59.50087057457921,482.5072547881602" fill="none" stroke="hsl(272, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.15,0.75 -1.15,-0.375" data-type="line" data-label="" points="365.01450957632034,303.749274521184 215.507835171213,376.8775391758561" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 -2.45,-1.9999999999999998" data-type="line" data-label="" points="365.01450957632034,303.749274521184 131.00406268136967,482.5072547881602" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 3.55,-1.5" data-type="line" data-label="" points="365.01450957632034,303.749274521184 521.0214741729542,450.0058038305282" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 3.55,0" data-type="line" data-label="" points="365.01450957632034,303.749274521184 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 4.5649999999999995,3" data-type="line" data-label="" points="365.01450957632034,303.749274521184 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 -2.45,-1.9999999999999998" data-type="line" data-label="" points="215.507835171213,376.8775391758561 131.00406268136967,482.5072547881602" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 3.55,-1.5" data-type="line" data-label="" points="215.507835171213,376.8775391758561 521.0214741729542,450.0058038305282" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 3.55,0" data-type="line" data-label="" points="215.507835171213,376.8775391758561 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 4.5649999999999995,3" data-type="line" data-label="" points="215.507835171213,376.8775391758561 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-2.45,-1.9999999999999998 3.55,-1.5" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 521.0214741729542,450.0058038305282" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-2.45,-1.9999999999999998 3.55,0" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-2.45,-1.9999999999999998 4.5649999999999995,3" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="3.55,-1.5 3.55,0" data-type="line" data-label="" points="521.0214741729542,450.0058038305282 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="3.55,-1.5 4.5649999999999995,3" data-type="line" data-label="" points="521.0214741729542,450.0058038305282 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="3.55,0 4.5649999999999995,3" data-type="line" data-label="" points="521.0214741729542,352.5014509576321 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0 -1.15,-1.125" data-type="line" data-label="" points="365.01450957632034,352.5014509576321 215.507835171213,425.62971561230415" fill="none" stroke="hsl(111, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0 2.45,-1.5" data-type="line" data-label="" points="365.01450957632034,352.5014509576321 449.5182820661637,450.0058038305282" fill="none" stroke="hsl(111, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-1.125 2.45,-1.5" data-type="line" data-label="" points="215.507835171213,425.62971561230415 449.5182820661637,450.0058038305282" fill="none" stroke="hsl(111, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,1.125 -3.55,0" data-type="line" data-label="" points="215.507835171213,279.37318630296 59.50087057457921,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,1.125 -3.55,2" data-type="line" data-label="" points="215.507835171213,279.37318630296 59.50087057457921,222.49564712710392" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,1.125 2.45,0" data-type="line" data-label="" points="215.507835171213,279.37318630296 449.5182820661637,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,0 -3.55,2" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 59.50087057457921,222.49564712710392" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,0 2.45,0" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 449.5182820661637,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,2 2.45,0" data-type="line" data-label="" points="59.50087057457921,222.49564712710392 449.5182820661637,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,2 -3.75,2 -3.75,1.125 -1.1500000000000004,1.125" data-type="line" data-label="" points="59.50087057457921,222.49564712710392 46.500290191526375,222.49564712710392 46.500290191526375,279.37318630296 215.50783517121295,279.37318630296" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-3.55,0 -3.75,0 -3.75,2 -3.55,2" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 46.500290191526375,352.5014509576321 46.500290191526375,222.49564712710392 59.50087057457921,222.49564712710392" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.45,0 -1.3499999999999999,0 -1.3499999999999999,0.375 -1.15,0.375" data-type="line" data-label="" points="131.00406268136967,352.5014509576321 202.5072547881602,352.5014509576321 202.5072547881602,328.12536273940805 215.507835171213,328.12536273940805" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-3.55,-1.9999999999999998 -3.75,-1.9999999999999998 -3.75,-0.9999999999999999 -2.25,-0.9999999999999999 -2.25,0 -2.45,0" data-type="line" data-label="" points="59.50087057457921,482.5072547881602 46.500290191526375,482.5072547881602 46.500290191526375,417.5043528728961 144.0046430644225,417.5043528728961 144.0046430644225,352.5014509576321 131.00406268136967,352.5014509576321" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="3.55,0 3.75,0 3.75,-1.5 3.55,-1.5" data-type="line" data-label="" points="521.0214741729542,352.5014509576321 534.022054556007,352.5014509576321 534.022054556007,450.0058038305282 521.0214741729542,450.0058038305282" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.15,0.75 3.75,0.75 3.75,0 3.55,0" data-type="line" data-label="" points="365.01450957632034,303.749274521184 534.022054556007,303.749274521184 534.022054556007,352.5014509576321 521.0214741729542,352.5014509576321" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="4.5649999999999995,3 4.765,3 4.765,0 3.55,0" data-type="line" data-label="" points="586.9994196169471,157.49274521183986 600,157.49274521183986 600,352.5014509576321 521.0214741729542,352.5014509576321" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.45,-1.9999999999999998 -1.8,-1.9999999999999998 -1.8,-0.375 -1.15,-0.375" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 173.25594892629132,482.5072547881602 173.25594892629132,376.8775391758561 215.507835171213,376.8775391758561" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.15,0 1.8,0 1.8,-1.5 2.45,-1.5" data-type="line" data-label="" points="365.01450957632034,352.5014509576321 407.266395821242,352.5014509576321 407.266395821242,450.0058038305282 449.5182820661637,450.0058038305282" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="3.435,3 0.49249999999999994,3 0.49249999999999994,2 -2.45,2" data-type="line" data-label="" points="513.5461404526988,157.49274521183986 322.2751015670342,157.49274521183986 322.2751015670342,222.49564712710392 131.00406268136967,222.49564712710392" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.15,-1.125 -1.301,-1.125 -1.301,-1.074" data-type="line" data-label="" points="215.507835171213,425.62971561230415 205.69239698200812,425.62971561230415 205.69239698200812,422.31456761462573" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="2.45,0 2.2990000000000004,0 2.2990000000000004,0.051000000000000004" data-type="line" data-label="" points="449.5182820661637,352.5014509576321 439.7028438769588,352.5014509576321 439.7028438769588,349.1863029599536" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="215.507835171213" y="230.62100986651194" width="149.50667440510733" height="243.76088218224027" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="-3" data-y="0" x="59.500870574579224" y="339.86128891468377" width="71.50319210679046" height="25.28032408589661" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-3" data-y="-2" x="59.500870574579224" y="469.86709274521195" width="71.50319210679046" height="25.280324085896666" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="-3" data-y="2" x="59.500870574579224" y="209.8554850841556" width="71.50319210679046" height="25.280324085896666" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_4" data-x="3" data-y="-1.5" x="449.51828206616364" y="422.7045850261173" width="71.5031921067905" height="54.60243760882179" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_5" data-x="3" data-y="0" x="449.51828206616364" y="325.2002321532212" width="71.5031921067905" height="54.60243760882179" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_6" data-x="4" data-y="3" x="513.5461404526989" y="136.366802089379" width="73.45327916424833" height="42.25188624492168" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: gnd
|
|
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="-3.55,0 -1.15,1.125" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 215.507835171213,279.37318630296" fill="none" stroke="hsl(40, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="3.435,3 -2.45,2" data-type="line" data-label="" points="513.5461404526988,157.49274521183986 131.00406268136967,222.49564712710392" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.375 -2.45,0" data-type="line" data-label="" points="215.507835171213,328.12536273940805 131.00406268136967,352.5014509576321" fill="none" stroke="hsl(272, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="-1.15,0.375 -3.55,-1.9999999999999998" data-type="line" data-label="" points="215.507835171213,328.12536273940805 59.50087057457921,482.5072547881602" fill="none" stroke="hsl(272, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.15,0.75 -1.15,-0.375" data-type="line" data-label="" points="365.01450957632034,303.749274521184 215.507835171213,376.8775391758561" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 -2.45,-1.9999999999999998" data-type="line" data-label="" points="365.01450957632034,303.749274521184 131.00406268136967,482.5072547881602" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 3.55,-1.5" data-type="line" data-label="" points="365.01450957632034,303.749274521184 521.0214741729542,450.0058038305282" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 3.55,0" data-type="line" data-label="" points="365.01450957632034,303.749274521184 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0.75 4.5649999999999995,3" data-type="line" data-label="" points="365.01450957632034,303.749274521184 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 -2.45,-1.9999999999999998" data-type="line" data-label="" points="215.507835171213,376.8775391758561 131.00406268136967,482.5072547881602" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 3.55,-1.5" data-type="line" data-label="" points="215.507835171213,376.8775391758561 521.0214741729542,450.0058038305282" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 3.55,0" data-type="line" data-label="" points="215.507835171213,376.8775391758561 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-0.375 4.5649999999999995,3" data-type="line" data-label="" points="215.507835171213,376.8775391758561 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-2.45,-1.9999999999999998 3.55,-1.5" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 521.0214741729542,450.0058038305282" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-2.45,-1.9999999999999998 3.55,0" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-2.45,-1.9999999999999998 4.5649999999999995,3" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="3.55,-1.5 3.55,0" data-type="line" data-label="" points="521.0214741729542,450.0058038305282 521.0214741729542,352.5014509576321" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="3.55,-1.5 4.5649999999999995,3" data-type="line" data-label="" points="521.0214741729542,450.0058038305282 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="3.55,0 4.5649999999999995,3" data-type="line" data-label="" points="521.0214741729542,352.5014509576321 586.9994196169471,157.49274521183986" fill="none" stroke="hsl(253, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0 -1.15,-1.125" data-type="line" data-label="" points="365.01450957632034,352.5014509576321 215.507835171213,425.62971561230415" fill="none" stroke="hsl(111, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.15,0 2.45,-1.5" data-type="line" data-label="" points="365.01450957632034,352.5014509576321 449.5182820661637,450.0058038305282" fill="none" stroke="hsl(111, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,-1.125 2.45,-1.5" data-type="line" data-label="" points="215.507835171213,425.62971561230415 449.5182820661637,450.0058038305282" fill="none" stroke="hsl(111, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,1.125 -3.55,0" data-type="line" data-label="" points="215.507835171213,279.37318630296 59.50087057457921,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,1.125 -3.55,2" data-type="line" data-label="" points="215.507835171213,279.37318630296 59.50087057457921,222.49564712710392" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.15,1.125 2.45,0" data-type="line" data-label="" points="215.507835171213,279.37318630296 449.5182820661637,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,0 -3.55,2" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 59.50087057457921,222.49564712710392" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,0 2.45,0" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 449.5182820661637,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,2 2.45,0" data-type="line" data-label="" points="59.50087057457921,222.49564712710392 449.5182820661637,352.5014509576321" fill="none" stroke="hsl(105, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-3.55,2 -3.75,2 -3.75,1.125 -1.1500000000000004,1.125" data-type="line" data-label="" points="59.50087057457921,222.49564712710392 46.500290191526375,222.49564712710392 46.500290191526375,279.37318630296 215.50783517121295,279.37318630296" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-3.55,0 -3.75,0 -3.75,2 -3.55,2" data-type="line" data-label="" points="59.50087057457921,352.5014509576321 46.500290191526375,352.5014509576321 46.500290191526375,222.49564712710392 59.50087057457921,222.49564712710392" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.45,0 -1.8,0 -1.8,0.375 -1.15,0.375" data-type="line" data-label="" points="131.00406268136967,352.5014509576321 173.25594892629132,352.5014509576321 173.25594892629132,328.12536273940805 215.507835171213,328.12536273940805" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-3.55,-1.9999999999999998 -3.75,-1.9999999999999998 -3.75,-0.9999999999999999 -2.25,-0.9999999999999999 -2.25,0 -2.45,0" data-type="line" data-label="" points="59.50087057457921,482.5072547881602 46.500290191526375,482.5072547881602 46.500290191526375,417.5043528728961 144.0046430644225,417.5043528728961 144.0046430644225,352.5014509576321 131.00406268136967,352.5014509576321" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="3.55,0 3.75,0 3.75,-1.5 3.55,-1.5" data-type="line" data-label="" points="521.0214741729542,352.5014509576321 534.022054556007,352.5014509576321 534.022054556007,450.0058038305282 521.0214741729542,450.0058038305282" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.15,0.75 3.75,0.75 3.75,0 3.55,0" data-type="line" data-label="" points="365.01450957632034,303.749274521184 534.022054556007,303.749274521184 534.022054556007,352.5014509576321 521.0214741729542,352.5014509576321" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="4.5649999999999995,3 4.765,3 4.765,0 3.55,0" data-type="line" data-label="" points="586.9994196169471,157.49274521183986 600,157.49274521183986 600,352.5014509576321 521.0214741729542,352.5014509576321" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.45,-1.9999999999999998 -1.8,-1.9999999999999998 -1.8,-0.375 -1.15,-0.375" data-type="line" data-label="" points="131.00406268136967,482.5072547881602 173.25594892629132,482.5072547881602 173.25594892629132,376.8775391758561 215.507835171213,376.8775391758561" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.15,0 1.8,0 1.8,-1.5 2.45,-1.5" data-type="line" data-label="" points="365.01450957632034,352.5014509576321 407.266395821242,352.5014509576321 407.266395821242,450.0058038305282 449.5182820661637,450.0058038305282" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="3.435,3 0.49249999999999994,3 0.49249999999999994,2 -2.45,2" data-type="line" data-label="" points="513.5461404526988,157.49274521183986 322.2751015670342,157.49274521183986 322.2751015670342,222.49564712710392 131.00406268136967,222.49564712710392" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.15,-1.125 -1.301,-1.125 -1.301,-1.074" data-type="line" data-label="" points="215.507835171213,425.62971561230415 205.69239698200812,425.62971561230415 205.69239698200812,422.31456761462573" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="2.45,0 2.2990000000000004,0 2.2990000000000004,0.051000000000000004" data-type="line" data-label="" points="449.5182820661637,352.5014509576321 439.7028438769588,352.5014509576321 439.7028438769588,349.1863029599536" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="215.507835171213" y="230.62100986651194" width="149.50667440510733" height="243.76088218224027" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="-3" data-y="0" x="59.500870574579224" y="339.86128891468377" width="71.50319210679046" height="25.28032408589661" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-3" data-y="-2" x="59.500870574579224" y="469.86709274521195" width="71.50319210679046" height="25.280324085896666" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="-3" data-y="2" x="59.500870574579224" y="209.8554850841556" width="71.50319210679046" height="25.280324085896666" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_4" data-x="3" data-y="-1.5" x="449.51828206616364" y="422.7045850261173" width="71.5031921067905" height="54.60243760882179" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_5" data-x="3" data-y="0" x="449.51828206616364" y="325.2002321532212" width="71.5031921067905" height="54.60243760882179" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="schematic_component_6" data-x="4" data-y="3" x="513.5461404526989" y="136.366802089379" width="73.45327916424833" height="42.25188624492168" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: gnd
|
|
2
2
|
globalConnNetId: connectivity_net3" data-x="3.75" data-y="-1.725" x="527.5217643644805" y="450.0058038305282" width="13.000580383052807" height="29.251305861868843" fill="#00000066" stroke="#000000" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: gnd
|
|
3
3
|
globalConnNetId: connectivity_net3" data-x="-2.125" data-y="-2.2249999999999996" x="145.6297156123041" y="482.50725478816025" width="13.000580383052835" height="29.251305861868843" fill="#00000066" stroke="#000000" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: v5
|
|
4
4
|
globalConnNetId: connectivity_net4" data-x="1.475" data-y="0.225" x="379.6401625072548" y="323.2501450957633" width="13.000580383052807" height="29.251305861868843" fill="#ef444466" stroke="#ef4444" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: v5
|
|
5
5
|
globalConnNetId: connectivity_net4" data-x="-1.301" data-y="-0.8490000000000001" x="199.19210679048172" y="393.06326175275683" width="13.000580383052807" height="29.251305861868843" fill="#ef444466" stroke="#ef4444" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: .PWR1 > .FB to .R6 > .pin2
|
|
6
|
-
globalConnNetId: connectivity_net2" data-x="-
|
|
6
|
+
globalConnNetId: connectivity_net2" data-x="-2.125" data-y="0.225" x="145.6297156123041" y="323.2501450957633" width="13.000580383052835" height="29.251305861868843" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: v3_3
|
|
7
7
|
globalConnNetId: connectivity_net0" data-x="-3.75" data-y="2.225" x="39.99999999999996" y="193.24434126523508" width="13.000580383052835" height="29.251305861868843" fill="#ef444466" stroke="#ef4444" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: v3_3
|
|
8
8
|
globalConnNetId: connectivity_net0" data-x="2.2990000000000004" data-y="0.276" x="433.20255368543235" y="319.93499709808475" width="13.000580383052863" height="29.251305861868843" fill="#ef444466" stroke="#ef4444" stroke-width="0.015383928571428571"/></g><g><rect data-type="rect" data-label="netId: .LED1 > .pos to .R8 > .pin2
|
|
9
9
|
globalConnNetId: connectivity_net1" data-x="1.96375" data-y="3.225" x="411.4103308183401" y="128.24143934997096" width="13.000580383052807" height="29.25130586186887" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015383928571428571"/></g><g><circle data-type="point" data-label="PWR1.7
|
|
@@ -30,7 +30,7 @@ orientation: y-" data-x="3.75" data-y="-1.5" cx="534.022054556007" cy="450.00580
|
|
|
30
30
|
orientation: y-" data-x="-2.125" data-y="-1.9999999999999998" cx="152.1300058038305" cy="482.5072547881602" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
31
31
|
orientation: y+" data-x="1.475" data-y="0" cx="386.1404526987812" cy="352.5014509576321" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
32
32
|
orientation: y+" data-x="-1.301" data-y="-1.074" cx="205.69239698200812" cy="422.31456761462573" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
33
|
-
orientation: y+" data-x="-
|
|
33
|
+
orientation: y+" data-x="-2.125" data-y="0" cx="152.1300058038305" cy="352.5014509576321" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
34
34
|
orientation: y+" data-x="-3.75" data-y="2" cx="46.500290191526375" cy="222.49564712710392" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
35
35
|
orientation: y+" data-x="2.2990000000000004" data-y="0.051000000000000004" cx="439.7028438769588" cy="349.1863029599536" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
36
36
|
orientation: y+" data-x="1.96375" data-y="3" cx="417.91062100986653" cy="157.49274521183986" 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[
|