@tscircuit/checks 0.0.208 → 0.0.209
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 +7 -4
- package/dist/index.js +365 -217
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,321 @@
|
|
|
1
|
+
// lib/check-pcb-trace-self-shorts.ts
|
|
2
|
+
import { cju } from "@tscircuit/circuit-json-util";
|
|
3
|
+
import { segmentToSegmentMinDistance } from "@tscircuit/math-utils";
|
|
4
|
+
import {
|
|
5
|
+
all_layers
|
|
6
|
+
} from "circuit-json";
|
|
7
|
+
|
|
8
|
+
// lib/check-each-pcb-trace-non-overlapping/getClosestPointBetweenSegments.ts
|
|
9
|
+
var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
10
|
+
const a1 = { x: segmentA.x1, y: segmentA.y1 };
|
|
11
|
+
const a2 = { x: segmentA.x2, y: segmentA.y2 };
|
|
12
|
+
const b1 = { x: segmentB.x1, y: segmentB.y1 };
|
|
13
|
+
const b2 = { x: segmentB.x2, y: segmentB.y2 };
|
|
14
|
+
const va = { x: a2.x - a1.x, y: a2.y - a1.y };
|
|
15
|
+
const vb = { x: b2.x - b1.x, y: b2.y - b1.y };
|
|
16
|
+
const lenSqrA = va.x * va.x + va.y * va.y;
|
|
17
|
+
const lenSqrB = vb.x * vb.x + vb.y * vb.y;
|
|
18
|
+
if (lenSqrA === 0 || lenSqrB === 0) {
|
|
19
|
+
if (lenSqrA === 0 && lenSqrB === 0) {
|
|
20
|
+
return {
|
|
21
|
+
x: (a1.x + b1.x) / 2,
|
|
22
|
+
y: (a1.y + b1.y) / 2
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (lenSqrA === 0) {
|
|
26
|
+
const t2 = clamp(
|
|
27
|
+
((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB,
|
|
28
|
+
0,
|
|
29
|
+
1
|
|
30
|
+
);
|
|
31
|
+
const closestOnB2 = {
|
|
32
|
+
x: b1.x + t2 * vb.x,
|
|
33
|
+
y: b1.y + t2 * vb.y
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
x: (a1.x + closestOnB2.x) / 2,
|
|
37
|
+
y: (a1.y + closestOnB2.y) / 2
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const t = clamp(
|
|
41
|
+
((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA,
|
|
42
|
+
0,
|
|
43
|
+
1
|
|
44
|
+
);
|
|
45
|
+
const closestOnA2 = {
|
|
46
|
+
x: a1.x + t * va.x,
|
|
47
|
+
y: a1.y + t * va.y
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
x: (closestOnA2.x + b1.x) / 2,
|
|
51
|
+
y: (closestOnA2.y + b1.y) / 2
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const w = { x: a1.x - b1.x, y: a1.y - b1.y };
|
|
55
|
+
const dotAA = va.x * va.x + va.y * va.y;
|
|
56
|
+
const dotAB = va.x * vb.x + va.y * vb.y;
|
|
57
|
+
const dotAW = va.x * w.x + va.y * w.y;
|
|
58
|
+
const dotBB = vb.x * vb.x + vb.y * vb.y;
|
|
59
|
+
const dotBW = vb.x * w.x + vb.y * w.y;
|
|
60
|
+
const denominator = dotAA * dotBB - dotAB * dotAB;
|
|
61
|
+
if (denominator < 1e-10) {
|
|
62
|
+
return closestPointsParallelSegments(
|
|
63
|
+
a1,
|
|
64
|
+
a2,
|
|
65
|
+
b1,
|
|
66
|
+
b2,
|
|
67
|
+
va,
|
|
68
|
+
vb,
|
|
69
|
+
lenSqrA,
|
|
70
|
+
lenSqrB
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
let tA = (dotAB * dotBW - dotBB * dotAW) / denominator;
|
|
74
|
+
let tB = (dotAA * dotBW - dotAB * dotAW) / denominator;
|
|
75
|
+
tA = clamp(tA, 0, 1);
|
|
76
|
+
tB = clamp(tB, 0, 1);
|
|
77
|
+
tB = (tA * dotAB + dotBW) / dotBB;
|
|
78
|
+
tB = clamp(tB, 0, 1);
|
|
79
|
+
tA = (tB * dotAB - dotAW) / dotAA;
|
|
80
|
+
tA = clamp(tA, 0, 1);
|
|
81
|
+
const closestOnA = {
|
|
82
|
+
x: a1.x + tA * va.x,
|
|
83
|
+
y: a1.y + tA * va.y
|
|
84
|
+
};
|
|
85
|
+
const closestOnB = {
|
|
86
|
+
x: b1.x + tB * vb.x,
|
|
87
|
+
y: b1.y + tB * vb.y
|
|
88
|
+
};
|
|
89
|
+
const dx = closestOnA.x - closestOnB.x;
|
|
90
|
+
const dy = closestOnA.y - closestOnB.y;
|
|
91
|
+
const distance3 = Math.sqrt(dx * dx + dy * dy);
|
|
92
|
+
const averagePoint = {
|
|
93
|
+
x: (closestOnA.x + closestOnB.x) / 2,
|
|
94
|
+
y: (closestOnA.y + closestOnB.y) / 2
|
|
95
|
+
};
|
|
96
|
+
return averagePoint;
|
|
97
|
+
};
|
|
98
|
+
var closestPointsParallelSegments = (a1, a2, b1, b2, va, vb, lenSqrA, lenSqrB) => {
|
|
99
|
+
let tA = ((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA;
|
|
100
|
+
tA = clamp(tA, 0, 1);
|
|
101
|
+
const pointOnA1 = { x: a1.x + tA * va.x, y: a1.y + tA * va.y };
|
|
102
|
+
let tA2 = ((b2.x - a1.x) * va.x + (b2.y - a1.y) * va.y) / lenSqrA;
|
|
103
|
+
tA2 = clamp(tA2, 0, 1);
|
|
104
|
+
const pointOnA2 = { x: a1.x + tA2 * va.x, y: a1.y + tA2 * va.y };
|
|
105
|
+
let tB = ((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB;
|
|
106
|
+
tB = clamp(tB, 0, 1);
|
|
107
|
+
const pointOnB1 = { x: b1.x + tB * vb.x, y: b1.y + tB * vb.y };
|
|
108
|
+
let tB2 = ((a2.x - b1.x) * vb.x + (a2.y - b1.y) * vb.y) / lenSqrB;
|
|
109
|
+
tB2 = clamp(tB2, 0, 1);
|
|
110
|
+
const pointOnB2 = { x: b1.x + tB2 * vb.x, y: b1.y + tB2 * vb.y };
|
|
111
|
+
const distances = [
|
|
112
|
+
{
|
|
113
|
+
pointA: pointOnA1,
|
|
114
|
+
pointB: b1,
|
|
115
|
+
distance: Math.sqrt(
|
|
116
|
+
(pointOnA1.x - b1.x) ** 2 + (pointOnA1.y - b1.y) ** 2
|
|
117
|
+
)
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
pointA: pointOnA2,
|
|
121
|
+
pointB: b2,
|
|
122
|
+
distance: Math.sqrt(
|
|
123
|
+
(pointOnA2.x - b2.x) ** 2 + (pointOnA2.y - b2.y) ** 2
|
|
124
|
+
)
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
pointA: a1,
|
|
128
|
+
pointB: pointOnB1,
|
|
129
|
+
distance: Math.sqrt(
|
|
130
|
+
(a1.x - pointOnB1.x) ** 2 + (a1.y - pointOnB1.y) ** 2
|
|
131
|
+
)
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
pointA: a2,
|
|
135
|
+
pointB: pointOnB2,
|
|
136
|
+
distance: Math.sqrt(
|
|
137
|
+
(a2.x - pointOnB2.x) ** 2 + (a2.y - pointOnB2.y) ** 2
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
const closestPair = distances.reduce(
|
|
142
|
+
(closest, current) => current.distance < closest.distance ? current : closest
|
|
143
|
+
);
|
|
144
|
+
return {
|
|
145
|
+
x: (closestPair.pointA.x + closestPair.pointB.x) / 2,
|
|
146
|
+
y: (closestPair.pointA.y + closestPair.pointB.y) / 2
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
var clamp = (value, min, max) => {
|
|
150
|
+
return Math.max(min, Math.min(max, value));
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// lib/check-each-pcb-trace-non-overlapping/getPcbPortIdsConnectedToTraces.ts
|
|
154
|
+
function getPcbPortIdsConnectedToRoutePoint(routePoint) {
|
|
155
|
+
if (routePoint.route_type !== "wire") return [];
|
|
156
|
+
return [routePoint.start_pcb_port_id, routePoint.end_pcb_port_id].filter(
|
|
157
|
+
(portId) => Boolean(portId)
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
function getPcbPortIdsConnectedToTrace(trace) {
|
|
161
|
+
const connectedPcbPorts = /* @__PURE__ */ new Set();
|
|
162
|
+
for (const segment of trace.route) {
|
|
163
|
+
for (const portId of getPcbPortIdsConnectedToRoutePoint(segment)) {
|
|
164
|
+
connectedPcbPorts.add(portId);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return Array.from(connectedPcbPorts);
|
|
168
|
+
}
|
|
169
|
+
function getPcbPortIdsConnectedToTraces(traces) {
|
|
170
|
+
const connectedPorts = /* @__PURE__ */ new Set();
|
|
171
|
+
for (const trace of traces) {
|
|
172
|
+
for (const portId of getPcbPortIdsConnectedToTrace(trace)) {
|
|
173
|
+
connectedPorts.add(portId);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return Array.from(connectedPorts);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// lib/check-pcb-trace-self-shorts.ts
|
|
180
|
+
function checkPcbTraceSelfShorts(circuitJson) {
|
|
181
|
+
const matchedSourceTraceIds = new Set(
|
|
182
|
+
circuitJson.flatMap(
|
|
183
|
+
(element) => element.type === "source_bus" && element.max_length_skew !== void 0 ? element.source_trace_ids : []
|
|
184
|
+
)
|
|
185
|
+
);
|
|
186
|
+
const db = cju(circuitJson);
|
|
187
|
+
const errors = [];
|
|
188
|
+
for (const trace of circuitJson) {
|
|
189
|
+
if (trace.type !== "pcb_trace") continue;
|
|
190
|
+
if (!trace.source_trace_id || !matchedSourceTraceIds.has(trace.source_trace_id))
|
|
191
|
+
continue;
|
|
192
|
+
const segments = [];
|
|
193
|
+
const routeDistances = [];
|
|
194
|
+
let distance3 = 0;
|
|
195
|
+
let run = 0;
|
|
196
|
+
for (let i = 0; i < trace.route.length - 1; i++) {
|
|
197
|
+
routeDistances[i] = distance3;
|
|
198
|
+
const a = trace.route[i];
|
|
199
|
+
const b = trace.route[i + 1];
|
|
200
|
+
if (a.route_type !== "wire" || b.route_type !== "wire" || a.layer !== b.layer) {
|
|
201
|
+
run++;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const length = Math.hypot(b.x - a.x, b.y - a.y);
|
|
205
|
+
if (length === 0) continue;
|
|
206
|
+
segments.push({
|
|
207
|
+
type: "pcb_trace_segment",
|
|
208
|
+
_pcbTrace: trace,
|
|
209
|
+
pcb_trace_id: trace.pcb_trace_id,
|
|
210
|
+
thickness: a.width,
|
|
211
|
+
layer: a.layer,
|
|
212
|
+
x1: a.x,
|
|
213
|
+
y1: a.y,
|
|
214
|
+
x2: b.x,
|
|
215
|
+
y2: b.y,
|
|
216
|
+
run,
|
|
217
|
+
startDistance: distance3,
|
|
218
|
+
endDistance: distance3 + length
|
|
219
|
+
});
|
|
220
|
+
distance3 += length;
|
|
221
|
+
}
|
|
222
|
+
routeDistances[trace.route.length - 1] = distance3;
|
|
223
|
+
let shortCenter;
|
|
224
|
+
pairs: for (let i = 0; i < segments.length; i++) {
|
|
225
|
+
const a = segments[i];
|
|
226
|
+
for (let j = i + 1; j < segments.length; j++) {
|
|
227
|
+
const b = segments[j];
|
|
228
|
+
if (a.layer !== b.layer) continue;
|
|
229
|
+
const contactDistance = (a.thickness + b.thickness) / 2;
|
|
230
|
+
const dot = (a.x2 - a.x1) * (b.x2 - b.x1) + (a.y2 - a.y1) * (b.y2 - b.y1);
|
|
231
|
+
const cross = (a.x2 - a.x1) * (b.y2 - b.y1) - (a.y2 - a.y1) * (b.x2 - b.x1);
|
|
232
|
+
const adjacent = a.run === b.run && b.startDistance === a.endDistance;
|
|
233
|
+
if (adjacent && !(dot < 0 && Math.abs(cross) < 1e-9)) continue;
|
|
234
|
+
if (!adjacent && a.run === b.run && b.startDistance - a.endDistance < contactDistance && dot >= 0)
|
|
235
|
+
continue;
|
|
236
|
+
const gap = segmentToSegmentMinDistance(
|
|
237
|
+
{ x: a.x1, y: a.y1 },
|
|
238
|
+
{ x: a.x2, y: a.y2 },
|
|
239
|
+
{ x: b.x1, y: b.y1 },
|
|
240
|
+
{ x: b.x2, y: b.y2 }
|
|
241
|
+
) - contactDistance;
|
|
242
|
+
if (gap > 1e-9) continue;
|
|
243
|
+
shortCenter = getClosestPointBetweenSegments(a, b);
|
|
244
|
+
break pairs;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (!shortCenter) {
|
|
248
|
+
const board = circuitJson.find((e) => e.type === "pcb_board");
|
|
249
|
+
const stack = [
|
|
250
|
+
"top",
|
|
251
|
+
...all_layers.filter((layer) => layer.startsWith("inner")).slice(0, board ? Math.max(0, board.num_layers - 2) : void 0),
|
|
252
|
+
...board?.num_layers === 1 ? [] : ["bottom"]
|
|
253
|
+
];
|
|
254
|
+
vias: for (let i = 0; i < trace.route.length; i++) {
|
|
255
|
+
const point2 = trace.route[i];
|
|
256
|
+
if (point2.route_type !== "via") continue;
|
|
257
|
+
const materialized = db.pcb_via.list().find(
|
|
258
|
+
(via) => (via.pcb_trace_id === trace.pcb_trace_id || !via.pcb_trace_id && via.source_trace_id === trace.source_trace_id) && Math.hypot(via.x - point2.x, via.y - point2.y) <= 1e-9
|
|
259
|
+
);
|
|
260
|
+
const diameter = materialized?.outer_diameter ?? point2.outer_diameter;
|
|
261
|
+
if (diameter === void 0 || !Number.isFinite(diameter) || diameter <= 0)
|
|
262
|
+
continue;
|
|
263
|
+
const from = stack.indexOf(point2.from_layer);
|
|
264
|
+
const to = stack.indexOf(point2.to_layer);
|
|
265
|
+
const layers = materialized?.layers ?? (from >= 0 && to >= 0 ? stack.slice(Math.min(from, to), Math.max(from, to) + 1) : []);
|
|
266
|
+
for (const segment of segments) {
|
|
267
|
+
if (!layers.includes(segment.layer)) continue;
|
|
268
|
+
const reach = (diameter + segment.thickness) / 2;
|
|
269
|
+
const alongRouteGap = Math.max(
|
|
270
|
+
segment.startDistance - routeDistances[i],
|
|
271
|
+
routeDistances[i] - segment.endDistance,
|
|
272
|
+
0
|
|
273
|
+
);
|
|
274
|
+
if (alongRouteGap <= reach + 1e-9) continue;
|
|
275
|
+
const viaSegment = {
|
|
276
|
+
...segment,
|
|
277
|
+
x1: point2.x,
|
|
278
|
+
y1: point2.y,
|
|
279
|
+
x2: point2.x,
|
|
280
|
+
y2: point2.y
|
|
281
|
+
};
|
|
282
|
+
const gap = segmentToSegmentMinDistance(
|
|
283
|
+
point2,
|
|
284
|
+
point2,
|
|
285
|
+
{ x: segment.x1, y: segment.y1 },
|
|
286
|
+
{ x: segment.x2, y: segment.y2 }
|
|
287
|
+
) - reach;
|
|
288
|
+
if (gap > 1e-9) continue;
|
|
289
|
+
shortCenter = getClosestPointBetweenSegments(segment, viaSegment);
|
|
290
|
+
break vias;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (shortCenter) {
|
|
295
|
+
const sourceTrace = db.source_trace.get(trace.source_trace_id);
|
|
296
|
+
const endpointNames = (sourceTrace?.connected_source_port_ids ?? []).map((id) => {
|
|
297
|
+
const port = db.source_port.get(id);
|
|
298
|
+
const component = port?.source_component_id ? db.source_component.get(port.source_component_id) : void 0;
|
|
299
|
+
return component?.name && port?.name ? `${component.name}.${port.name}` : void 0;
|
|
300
|
+
}).filter((name) => Boolean(name));
|
|
301
|
+
const traceName = sourceTrace?.name || sourceTrace?.display_name || endpointNames.join(" \u2192 ") || "unnamed";
|
|
302
|
+
errors.push({
|
|
303
|
+
type: "pcb_trace_error",
|
|
304
|
+
error_type: "pcb_trace_error",
|
|
305
|
+
pcb_trace_error_id: `self_short_${trace.pcb_trace_id}`,
|
|
306
|
+
pcb_trace_id: trace.pcb_trace_id,
|
|
307
|
+
source_trace_id: trace.source_trace_id,
|
|
308
|
+
message: `PCB trace "${traceName}" shorts to itself, bypassing part of its length-matched route`,
|
|
309
|
+
center: shortCenter,
|
|
310
|
+
pcb_component_ids: [],
|
|
311
|
+
pcb_port_ids: getPcbPortIdsConnectedToTraces([trace]),
|
|
312
|
+
subcircuit_id: trace.subcircuit_id
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return errors;
|
|
317
|
+
}
|
|
318
|
+
|
|
1
319
|
// lib/check-copper-pour-shorts.ts
|
|
2
320
|
import Flatbush from "flatbush";
|
|
3
321
|
import "@flatten-js/core";
|
|
@@ -717,7 +1035,7 @@ import {
|
|
|
717
1035
|
import Flatbush3 from "flatbush";
|
|
718
1036
|
|
|
719
1037
|
// lib/util/get-via-and-pour-connections.ts
|
|
720
|
-
import { all_layers } from "circuit-json";
|
|
1038
|
+
import { all_layers as all_layers2 } from "circuit-json";
|
|
721
1039
|
import {
|
|
722
1040
|
getPourPolygon,
|
|
723
1041
|
getTraceSegmentPolygon,
|
|
@@ -798,7 +1116,7 @@ function getViaAndPourConnections(circuit) {
|
|
|
798
1116
|
const board = circuit.find((e) => e.type === "pcb_board");
|
|
799
1117
|
const stack = [
|
|
800
1118
|
"top",
|
|
801
|
-
...
|
|
1119
|
+
...all_layers2.filter((l) => l.startsWith("inner")).slice(0, board ? Math.max(0, board.num_layers - 2) : void 0),
|
|
802
1120
|
...board?.num_layers === 1 ? [] : ["bottom"]
|
|
803
1121
|
];
|
|
804
1122
|
for (const copper of circuit) {
|
|
@@ -974,7 +1292,7 @@ import {
|
|
|
974
1292
|
getSegmentIntersection,
|
|
975
1293
|
isPointInsidePolygon,
|
|
976
1294
|
pointToSegmentClosestPoint,
|
|
977
|
-
segmentToSegmentMinDistance
|
|
1295
|
+
segmentToSegmentMinDistance as segmentToSegmentMinDistance2
|
|
978
1296
|
} from "@tscircuit/math-utils";
|
|
979
1297
|
var rotatePoint = (point2, angleDegrees) => {
|
|
980
1298
|
const angle = angleDegrees * Math.PI / 180;
|
|
@@ -1074,7 +1392,7 @@ var getClosestPointsBetweenSegments = (a1, a2, b1, b2) => {
|
|
|
1074
1392
|
}
|
|
1075
1393
|
}
|
|
1076
1394
|
return {
|
|
1077
|
-
distance:
|
|
1395
|
+
distance: segmentToSegmentMinDistance2(a1, a2, b1, b2),
|
|
1078
1396
|
pointOnA: best.pointOnA,
|
|
1079
1397
|
pointOnB: best.pointOnB,
|
|
1080
1398
|
center: {
|
|
@@ -1695,20 +2013,20 @@ function checkEachPcbPortConnectedToPcbTraces(circuitJson, {
|
|
|
1695
2013
|
}
|
|
1696
2014
|
|
|
1697
2015
|
// lib/check-each-pcb-trace-non-overlapping/check-each-pcb-trace-non-overlapping.ts
|
|
1698
|
-
import { cju as
|
|
2016
|
+
import { cju as cju3, getReadableNameForElement as getReadableNameForElement3 } from "@tscircuit/circuit-json-util";
|
|
1699
2017
|
import { getPrimaryId as getPrimaryId2 } from "@tscircuit/circuit-json-util";
|
|
1700
2018
|
import {
|
|
1701
2019
|
segmentToBoundsMinDistance,
|
|
1702
2020
|
segmentToCircleMinDistance as segmentToCircleMinDistance2
|
|
1703
2021
|
} from "@tscircuit/math-utils";
|
|
1704
|
-
import { segmentToSegmentMinDistance as
|
|
2022
|
+
import { segmentToSegmentMinDistance as segmentToSegmentMinDistance4 } from "@tscircuit/math-utils";
|
|
1705
2023
|
import {
|
|
1706
2024
|
getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson3
|
|
1707
2025
|
} from "circuit-json-to-connectivity-map";
|
|
1708
2026
|
|
|
1709
2027
|
// lib/check-pad-clearance/common.ts
|
|
1710
2028
|
import {
|
|
1711
|
-
cju,
|
|
2029
|
+
cju as cju2,
|
|
1712
2030
|
distanceBetweenCircleAndCircle,
|
|
1713
2031
|
distanceBetweenCircleAndPolygon,
|
|
1714
2032
|
distanceBetweenPolygonAndPolygon,
|
|
@@ -1718,7 +2036,7 @@ import {
|
|
|
1718
2036
|
midpoint,
|
|
1719
2037
|
pointToSegmentClosestPoint as pointToSegmentClosestPoint2,
|
|
1720
2038
|
segmentToCircleMinDistance,
|
|
1721
|
-
segmentToSegmentMinDistance as
|
|
2039
|
+
segmentToSegmentMinDistance as segmentToSegmentMinDistance3
|
|
1722
2040
|
} from "@tscircuit/math-utils";
|
|
1723
2041
|
|
|
1724
2042
|
// node_modules/@tscircuit/jlcpcb-manufacturing-specs/lib/jlcpcb-manufacturing-specs.ts
|
|
@@ -1885,7 +2203,7 @@ var getPadToPadGap = (padA, padB) => {
|
|
|
1885
2203
|
if (isPillPad(padA) && isPillPad(padB)) {
|
|
1886
2204
|
const pillA = getPillCenterLineForPad(padA);
|
|
1887
2205
|
const pillB = getPillCenterLineForPad(padB);
|
|
1888
|
-
return
|
|
2206
|
+
return segmentToSegmentMinDistance3(
|
|
1889
2207
|
pillA.start,
|
|
1890
2208
|
pillA.end,
|
|
1891
2209
|
pillB.start,
|
|
@@ -1940,11 +2258,11 @@ var getPadToPadGap = (padA, padB) => {
|
|
|
1940
2258
|
);
|
|
1941
2259
|
};
|
|
1942
2260
|
var getPads = (circuitJson) => [
|
|
1943
|
-
...
|
|
1944
|
-
...
|
|
2261
|
+
...cju2(circuitJson).pcb_smtpad.list(),
|
|
2262
|
+
...cju2(circuitJson).pcb_plated_hole.list()
|
|
1945
2263
|
];
|
|
1946
2264
|
var getTraceSegments = (circuitJson) => {
|
|
1947
|
-
const pcbTraces =
|
|
2265
|
+
const pcbTraces = cju2(circuitJson).pcb_trace.list();
|
|
1948
2266
|
return pcbTraces.flatMap((pcbTrace) => {
|
|
1949
2267
|
const segments = [];
|
|
1950
2268
|
for (let i = 0; i < pcbTrace.route.length - 1; i++) {
|
|
@@ -2162,7 +2480,7 @@ var SpatialObjectIndex = class {
|
|
|
2162
2480
|
};
|
|
2163
2481
|
|
|
2164
2482
|
// lib/util/getLayersOfPcbElement.ts
|
|
2165
|
-
import { all_layers as
|
|
2483
|
+
import { all_layers as all_layers3 } from "circuit-json";
|
|
2166
2484
|
function getLayersOfPcbElement(obj) {
|
|
2167
2485
|
if (obj.type === "pcb_trace_segment") {
|
|
2168
2486
|
return [obj.layer];
|
|
@@ -2171,13 +2489,13 @@ function getLayersOfPcbElement(obj) {
|
|
|
2171
2489
|
return [obj.layer];
|
|
2172
2490
|
}
|
|
2173
2491
|
if (obj.type === "pcb_plated_hole") {
|
|
2174
|
-
return Array.isArray(obj.layers) ? obj.layers : [...
|
|
2492
|
+
return Array.isArray(obj.layers) ? obj.layers : [...all_layers3];
|
|
2175
2493
|
}
|
|
2176
2494
|
if (obj.type === "pcb_hole") {
|
|
2177
|
-
return [...
|
|
2495
|
+
return [...all_layers3];
|
|
2178
2496
|
}
|
|
2179
2497
|
if (obj.type === "pcb_via") {
|
|
2180
|
-
return Array.isArray(obj.layers) ? obj.layers : [...
|
|
2498
|
+
return Array.isArray(obj.layers) ? obj.layers : [...all_layers3];
|
|
2181
2499
|
}
|
|
2182
2500
|
if (obj.type === "pcb_keepout") {
|
|
2183
2501
|
return Array.isArray(obj.layers) ? obj.layers : [];
|
|
@@ -2278,151 +2596,6 @@ var getClosestPointBetweenSegmentAndBounds = (segment, bounds) => {
|
|
|
2278
2596
|
return closestPoint;
|
|
2279
2597
|
};
|
|
2280
2598
|
|
|
2281
|
-
// lib/check-each-pcb-trace-non-overlapping/getClosestPointBetweenSegments.ts
|
|
2282
|
-
var getClosestPointBetweenSegments = (segmentA, segmentB) => {
|
|
2283
|
-
const a1 = { x: segmentA.x1, y: segmentA.y1 };
|
|
2284
|
-
const a2 = { x: segmentA.x2, y: segmentA.y2 };
|
|
2285
|
-
const b1 = { x: segmentB.x1, y: segmentB.y1 };
|
|
2286
|
-
const b2 = { x: segmentB.x2, y: segmentB.y2 };
|
|
2287
|
-
const va = { x: a2.x - a1.x, y: a2.y - a1.y };
|
|
2288
|
-
const vb = { x: b2.x - b1.x, y: b2.y - b1.y };
|
|
2289
|
-
const lenSqrA = va.x * va.x + va.y * va.y;
|
|
2290
|
-
const lenSqrB = vb.x * vb.x + vb.y * vb.y;
|
|
2291
|
-
if (lenSqrA === 0 || lenSqrB === 0) {
|
|
2292
|
-
if (lenSqrA === 0 && lenSqrB === 0) {
|
|
2293
|
-
return {
|
|
2294
|
-
x: (a1.x + b1.x) / 2,
|
|
2295
|
-
y: (a1.y + b1.y) / 2
|
|
2296
|
-
};
|
|
2297
|
-
}
|
|
2298
|
-
if (lenSqrA === 0) {
|
|
2299
|
-
const t2 = clamp(
|
|
2300
|
-
((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB,
|
|
2301
|
-
0,
|
|
2302
|
-
1
|
|
2303
|
-
);
|
|
2304
|
-
const closestOnB2 = {
|
|
2305
|
-
x: b1.x + t2 * vb.x,
|
|
2306
|
-
y: b1.y + t2 * vb.y
|
|
2307
|
-
};
|
|
2308
|
-
return {
|
|
2309
|
-
x: (a1.x + closestOnB2.x) / 2,
|
|
2310
|
-
y: (a1.y + closestOnB2.y) / 2
|
|
2311
|
-
};
|
|
2312
|
-
}
|
|
2313
|
-
const t = clamp(
|
|
2314
|
-
((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA,
|
|
2315
|
-
0,
|
|
2316
|
-
1
|
|
2317
|
-
);
|
|
2318
|
-
const closestOnA2 = {
|
|
2319
|
-
x: a1.x + t * va.x,
|
|
2320
|
-
y: a1.y + t * va.y
|
|
2321
|
-
};
|
|
2322
|
-
return {
|
|
2323
|
-
x: (closestOnA2.x + b1.x) / 2,
|
|
2324
|
-
y: (closestOnA2.y + b1.y) / 2
|
|
2325
|
-
};
|
|
2326
|
-
}
|
|
2327
|
-
const w = { x: a1.x - b1.x, y: a1.y - b1.y };
|
|
2328
|
-
const dotAA = va.x * va.x + va.y * va.y;
|
|
2329
|
-
const dotAB = va.x * vb.x + va.y * vb.y;
|
|
2330
|
-
const dotAW = va.x * w.x + va.y * w.y;
|
|
2331
|
-
const dotBB = vb.x * vb.x + vb.y * vb.y;
|
|
2332
|
-
const dotBW = vb.x * w.x + vb.y * w.y;
|
|
2333
|
-
const denominator = dotAA * dotBB - dotAB * dotAB;
|
|
2334
|
-
if (denominator < 1e-10) {
|
|
2335
|
-
return closestPointsParallelSegments(
|
|
2336
|
-
a1,
|
|
2337
|
-
a2,
|
|
2338
|
-
b1,
|
|
2339
|
-
b2,
|
|
2340
|
-
va,
|
|
2341
|
-
vb,
|
|
2342
|
-
lenSqrA,
|
|
2343
|
-
lenSqrB
|
|
2344
|
-
);
|
|
2345
|
-
}
|
|
2346
|
-
let tA = (dotAB * dotBW - dotBB * dotAW) / denominator;
|
|
2347
|
-
let tB = (dotAA * dotBW - dotAB * dotAW) / denominator;
|
|
2348
|
-
tA = clamp(tA, 0, 1);
|
|
2349
|
-
tB = clamp(tB, 0, 1);
|
|
2350
|
-
tB = (tA * dotAB + dotBW) / dotBB;
|
|
2351
|
-
tB = clamp(tB, 0, 1);
|
|
2352
|
-
tA = (tB * dotAB - dotAW) / dotAA;
|
|
2353
|
-
tA = clamp(tA, 0, 1);
|
|
2354
|
-
const closestOnA = {
|
|
2355
|
-
x: a1.x + tA * va.x,
|
|
2356
|
-
y: a1.y + tA * va.y
|
|
2357
|
-
};
|
|
2358
|
-
const closestOnB = {
|
|
2359
|
-
x: b1.x + tB * vb.x,
|
|
2360
|
-
y: b1.y + tB * vb.y
|
|
2361
|
-
};
|
|
2362
|
-
const dx = closestOnA.x - closestOnB.x;
|
|
2363
|
-
const dy = closestOnA.y - closestOnB.y;
|
|
2364
|
-
const distance3 = Math.sqrt(dx * dx + dy * dy);
|
|
2365
|
-
const averagePoint = {
|
|
2366
|
-
x: (closestOnA.x + closestOnB.x) / 2,
|
|
2367
|
-
y: (closestOnA.y + closestOnB.y) / 2
|
|
2368
|
-
};
|
|
2369
|
-
return averagePoint;
|
|
2370
|
-
};
|
|
2371
|
-
var closestPointsParallelSegments = (a1, a2, b1, b2, va, vb, lenSqrA, lenSqrB) => {
|
|
2372
|
-
let tA = ((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA;
|
|
2373
|
-
tA = clamp(tA, 0, 1);
|
|
2374
|
-
const pointOnA1 = { x: a1.x + tA * va.x, y: a1.y + tA * va.y };
|
|
2375
|
-
let tA2 = ((b2.x - a1.x) * va.x + (b2.y - a1.y) * va.y) / lenSqrA;
|
|
2376
|
-
tA2 = clamp(tA2, 0, 1);
|
|
2377
|
-
const pointOnA2 = { x: a1.x + tA2 * va.x, y: a1.y + tA2 * va.y };
|
|
2378
|
-
let tB = ((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB;
|
|
2379
|
-
tB = clamp(tB, 0, 1);
|
|
2380
|
-
const pointOnB1 = { x: b1.x + tB * vb.x, y: b1.y + tB * vb.y };
|
|
2381
|
-
let tB2 = ((a2.x - b1.x) * vb.x + (a2.y - b1.y) * vb.y) / lenSqrB;
|
|
2382
|
-
tB2 = clamp(tB2, 0, 1);
|
|
2383
|
-
const pointOnB2 = { x: b1.x + tB2 * vb.x, y: b1.y + tB2 * vb.y };
|
|
2384
|
-
const distances = [
|
|
2385
|
-
{
|
|
2386
|
-
pointA: pointOnA1,
|
|
2387
|
-
pointB: b1,
|
|
2388
|
-
distance: Math.sqrt(
|
|
2389
|
-
(pointOnA1.x - b1.x) ** 2 + (pointOnA1.y - b1.y) ** 2
|
|
2390
|
-
)
|
|
2391
|
-
},
|
|
2392
|
-
{
|
|
2393
|
-
pointA: pointOnA2,
|
|
2394
|
-
pointB: b2,
|
|
2395
|
-
distance: Math.sqrt(
|
|
2396
|
-
(pointOnA2.x - b2.x) ** 2 + (pointOnA2.y - b2.y) ** 2
|
|
2397
|
-
)
|
|
2398
|
-
},
|
|
2399
|
-
{
|
|
2400
|
-
pointA: a1,
|
|
2401
|
-
pointB: pointOnB1,
|
|
2402
|
-
distance: Math.sqrt(
|
|
2403
|
-
(a1.x - pointOnB1.x) ** 2 + (a1.y - pointOnB1.y) ** 2
|
|
2404
|
-
)
|
|
2405
|
-
},
|
|
2406
|
-
{
|
|
2407
|
-
pointA: a2,
|
|
2408
|
-
pointB: pointOnB2,
|
|
2409
|
-
distance: Math.sqrt(
|
|
2410
|
-
(a2.x - pointOnB2.x) ** 2 + (a2.y - pointOnB2.y) ** 2
|
|
2411
|
-
)
|
|
2412
|
-
}
|
|
2413
|
-
];
|
|
2414
|
-
const closestPair = distances.reduce(
|
|
2415
|
-
(closest, current) => current.distance < closest.distance ? current : closest
|
|
2416
|
-
);
|
|
2417
|
-
return {
|
|
2418
|
-
x: (closestPair.pointA.x + closestPair.pointB.x) / 2,
|
|
2419
|
-
y: (closestPair.pointA.y + closestPair.pointB.y) / 2
|
|
2420
|
-
};
|
|
2421
|
-
};
|
|
2422
|
-
var clamp = (value, min, max) => {
|
|
2423
|
-
return Math.max(min, Math.min(max, value));
|
|
2424
|
-
};
|
|
2425
|
-
|
|
2426
2599
|
// lib/check-each-pcb-trace-non-overlapping/getCollidableBounds.ts
|
|
2427
2600
|
import { getBoundsOfPcbElements as getBoundsOfPcbElements3 } from "@tscircuit/circuit-json-util";
|
|
2428
2601
|
var getCollidableBounds = (collidable) => {
|
|
@@ -2458,32 +2631,6 @@ var getCollidableBounds = (collidable) => {
|
|
|
2458
2631
|
return getBoundsOfPcbElements3([collidable]);
|
|
2459
2632
|
};
|
|
2460
2633
|
|
|
2461
|
-
// lib/check-each-pcb-trace-non-overlapping/getPcbPortIdsConnectedToTraces.ts
|
|
2462
|
-
function getPcbPortIdsConnectedToRoutePoint(routePoint) {
|
|
2463
|
-
if (routePoint.route_type !== "wire") return [];
|
|
2464
|
-
return [routePoint.start_pcb_port_id, routePoint.end_pcb_port_id].filter(
|
|
2465
|
-
(portId) => Boolean(portId)
|
|
2466
|
-
);
|
|
2467
|
-
}
|
|
2468
|
-
function getPcbPortIdsConnectedToTrace(trace) {
|
|
2469
|
-
const connectedPcbPorts = /* @__PURE__ */ new Set();
|
|
2470
|
-
for (const segment of trace.route) {
|
|
2471
|
-
for (const portId of getPcbPortIdsConnectedToRoutePoint(segment)) {
|
|
2472
|
-
connectedPcbPorts.add(portId);
|
|
2473
|
-
}
|
|
2474
|
-
}
|
|
2475
|
-
return Array.from(connectedPcbPorts);
|
|
2476
|
-
}
|
|
2477
|
-
function getPcbPortIdsConnectedToTraces(traces) {
|
|
2478
|
-
const connectedPorts = /* @__PURE__ */ new Set();
|
|
2479
|
-
for (const trace of traces) {
|
|
2480
|
-
for (const portId of getPcbPortIdsConnectedToTrace(trace)) {
|
|
2481
|
-
connectedPorts.add(portId);
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
return Array.from(connectedPorts);
|
|
2485
|
-
}
|
|
2486
|
-
|
|
2487
2634
|
// lib/check-each-pcb-trace-non-overlapping/getRadiusOfCircuitJsonElement.ts
|
|
2488
2635
|
var getRadiusOfCircuitJsonElement = (obj) => {
|
|
2489
2636
|
if (obj.type === "pcb_via") {
|
|
@@ -2513,12 +2660,12 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
2513
2660
|
connMap,
|
|
2514
2661
|
minClearance
|
|
2515
2662
|
} = {}) {
|
|
2516
|
-
const errors =
|
|
2663
|
+
const errors = checkPcbTraceSelfShorts(circuitJson);
|
|
2517
2664
|
addStartAndEndPortIdsIfMissing(circuitJson);
|
|
2518
2665
|
connMap ??= getFullConnectivityMapFromCircuitJson3(circuitJson);
|
|
2519
2666
|
const board = getPcbBoard(circuitJson);
|
|
2520
2667
|
minClearance ??= getBoardDrcValue(board, "min_trace_to_pad_edge_clearance") ?? DEFAULT_TRACE_MARGIN;
|
|
2521
|
-
const pcbTraces =
|
|
2668
|
+
const pcbTraces = cju3(circuitJson).pcb_trace.list();
|
|
2522
2669
|
const pcbTraceSegments = pcbTraces.flatMap((pcbTrace) => {
|
|
2523
2670
|
const segments = [];
|
|
2524
2671
|
for (let i = 0; i < pcbTrace.route.length - 1; i++) {
|
|
@@ -2541,12 +2688,12 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
2541
2688
|
}
|
|
2542
2689
|
return segments;
|
|
2543
2690
|
});
|
|
2544
|
-
const pcbSmtPads =
|
|
2545
|
-
const pcbPlatedHoles =
|
|
2546
|
-
const pcbPorts =
|
|
2547
|
-
const pcbHoles =
|
|
2548
|
-
const pcbVias =
|
|
2549
|
-
const pcbKeepouts =
|
|
2691
|
+
const pcbSmtPads = cju3(circuitJson).pcb_smtpad.list();
|
|
2692
|
+
const pcbPlatedHoles = cju3(circuitJson).pcb_plated_hole.list();
|
|
2693
|
+
const pcbPorts = cju3(circuitJson).pcb_port.list();
|
|
2694
|
+
const pcbHoles = cju3(circuitJson).pcb_hole.list();
|
|
2695
|
+
const pcbVias = cju3(circuitJson).pcb_via.list();
|
|
2696
|
+
const pcbKeepouts = cju3(circuitJson).pcb_keepout.list().filter((keepout) => !keepout.allow_traces);
|
|
2550
2697
|
const pcbComponentConnectionElements = [
|
|
2551
2698
|
...pcbPorts,
|
|
2552
2699
|
...pcbSmtPads,
|
|
@@ -2607,7 +2754,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
|
|
|
2607
2754
|
if (segmentA.layer !== segmentB.layer) continue;
|
|
2608
2755
|
if (connMap.areIdsConnected(segmentA.pcb_trace_id, segmentB.pcb_trace_id))
|
|
2609
2756
|
continue;
|
|
2610
|
-
const gap2 =
|
|
2757
|
+
const gap2 = segmentToSegmentMinDistance4(
|
|
2611
2758
|
{ x: segmentA.x1, y: segmentA.y1 },
|
|
2612
2759
|
{ x: segmentA.x2, y: segmentA.y2 },
|
|
2613
2760
|
{ x: segmentB.x1, y: segmentB.y1 },
|
|
@@ -3266,7 +3413,7 @@ function checkPcbComponentOverCutout(circuitJson) {
|
|
|
3266
3413
|
}
|
|
3267
3414
|
|
|
3268
3415
|
// lib/check-pcb-copper-over-keepout.ts
|
|
3269
|
-
import { cju as
|
|
3416
|
+
import { cju as cju4, getPrimaryId as getPrimaryId3 } from "@tscircuit/circuit-json-util";
|
|
3270
3417
|
var getErrorOwnerId = (copper) => "pcb_component_id" in copper && copper.pcb_component_id ? copper.pcb_component_id : getPrimaryId3(copper);
|
|
3271
3418
|
var getReadableCopperName = (circuitJson, copper) => {
|
|
3272
3419
|
if ("pcb_component_id" in copper && copper.pcb_component_id) {
|
|
@@ -3282,11 +3429,11 @@ var getReadableCopperName = (circuitJson, copper) => {
|
|
|
3282
3429
|
return copper.type === "pcb_via" ? `via ${copper.pcb_via_id}` : `${copper.type} ${getPrimaryId3(copper)}`;
|
|
3283
3430
|
};
|
|
3284
3431
|
function checkPcbCopperOverKeepout(circuitJson) {
|
|
3285
|
-
const keepouts =
|
|
3432
|
+
const keepouts = cju4(circuitJson).pcb_keepout.list();
|
|
3286
3433
|
if (keepouts.length === 0) return [];
|
|
3287
3434
|
const copper = [
|
|
3288
3435
|
...getPads(circuitJson),
|
|
3289
|
-
...
|
|
3436
|
+
...cju4(circuitJson).pcb_via.list()
|
|
3290
3437
|
];
|
|
3291
3438
|
const errors = /* @__PURE__ */ new Map();
|
|
3292
3439
|
for (const keepout of keepouts) {
|
|
@@ -3463,11 +3610,11 @@ function checkDifferentNetViaSpacing(circuitJson, {
|
|
|
3463
3610
|
}
|
|
3464
3611
|
|
|
3465
3612
|
// lib/check-source-traces-match-pcb-trace-thickness.ts
|
|
3466
|
-
import { cju as
|
|
3613
|
+
import { cju as cju5 } from "@tscircuit/circuit-json-util";
|
|
3467
3614
|
import { getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson6 } from "circuit-json-to-connectivity-map";
|
|
3468
3615
|
function checkSourceTracesMatchPcbTraceThickness(circuitJson) {
|
|
3469
3616
|
const warnings = [];
|
|
3470
|
-
const db =
|
|
3617
|
+
const db = cju5(circuitJson);
|
|
3471
3618
|
const sourceTraces = db.source_trace.list();
|
|
3472
3619
|
const pcbTraces = db.pcb_trace.list();
|
|
3473
3620
|
const pcbPorts = db.pcb_port.list();
|
|
@@ -3606,7 +3753,7 @@ import {
|
|
|
3606
3753
|
|
|
3607
3754
|
// lib/check-traces-are-contiguous/via-contact-index.ts
|
|
3608
3755
|
import {
|
|
3609
|
-
all_layers as
|
|
3756
|
+
all_layers as all_layers4
|
|
3610
3757
|
} from "circuit-json";
|
|
3611
3758
|
import { getPrimaryId as getPrimaryId4 } from "@tscircuit/circuit-json-util";
|
|
3612
3759
|
import { pointToSegmentDistance as pointToSegmentDistance2 } from "@tscircuit/math-utils";
|
|
@@ -3618,7 +3765,7 @@ function getViaContactIndex(circuitJson, connectivity) {
|
|
|
3618
3765
|
const vias = circuitJson.filter((element) => element.type === "pcb_via");
|
|
3619
3766
|
const board = circuitJson.find((element) => element.type === "pcb_board");
|
|
3620
3767
|
const layerCount = board?.num_layers;
|
|
3621
|
-
const innerLayers =
|
|
3768
|
+
const innerLayers = all_layers4.filter((layer) => layer.startsWith("inner"));
|
|
3622
3769
|
const stack = [
|
|
3623
3770
|
"top",
|
|
3624
3771
|
...innerLayers.slice(
|
|
@@ -4144,8 +4291,8 @@ function checkTracesAreContiguous(circuitJson, {
|
|
|
4144
4291
|
}
|
|
4145
4292
|
|
|
4146
4293
|
// lib/check-trace-out-of-board/checkTraceOutOfBoard.ts
|
|
4147
|
-
import { cju as
|
|
4148
|
-
import { segmentToSegmentMinDistance as
|
|
4294
|
+
import { cju as cju6 } from "@tscircuit/circuit-json-util";
|
|
4295
|
+
import { segmentToSegmentMinDistance as segmentToSegmentMinDistance5 } from "@tscircuit/math-utils";
|
|
4149
4296
|
function getBoardPolygonPoints(board) {
|
|
4150
4297
|
if (board.outline && board.outline.length > 0) {
|
|
4151
4298
|
return board.outline.map((p) => ({ x: p.x, y: p.y }));
|
|
@@ -4175,7 +4322,7 @@ function checkPcbTracesOutOfBoard(circuitJson, config = {}) {
|
|
|
4175
4322
|
const margin = config.margin ?? getBoardDrcValue(board, "min_board_edge_clearance") ?? jlcMinTolerances.min_board_edge_clearance;
|
|
4176
4323
|
const boardPoints = getBoardPolygonPoints(board);
|
|
4177
4324
|
if (!boardPoints) return errors;
|
|
4178
|
-
const pcbTraces =
|
|
4325
|
+
const pcbTraces = cju6(circuitJson).pcb_trace.list();
|
|
4179
4326
|
for (const trace of pcbTraces) {
|
|
4180
4327
|
if (trace.route.length < 2) continue;
|
|
4181
4328
|
for (let i = 0; i < trace.route.length - 1; i++) {
|
|
@@ -4189,7 +4336,7 @@ function checkPcbTracesOutOfBoard(circuitJson, config = {}) {
|
|
|
4189
4336
|
for (let j = 0; j < boardPoints.length; j++) {
|
|
4190
4337
|
const edgeStart = boardPoints[j];
|
|
4191
4338
|
const edgeEnd = boardPoints[(j + 1) % boardPoints.length];
|
|
4192
|
-
const distance3 =
|
|
4339
|
+
const distance3 = segmentToSegmentMinDistance5(
|
|
4193
4340
|
segmentStart,
|
|
4194
4341
|
segmentEnd,
|
|
4195
4342
|
edgeStart,
|
|
@@ -4224,7 +4371,7 @@ function checkPcbTracesOutOfBoard(circuitJson, config = {}) {
|
|
|
4224
4371
|
|
|
4225
4372
|
// lib/check-pcb-components-overlap/checkPcbComponentOverlap.ts
|
|
4226
4373
|
import {
|
|
4227
|
-
cju as
|
|
4374
|
+
cju as cju7,
|
|
4228
4375
|
getBoundsOfPcbElements as getBoundsOfPcbElements5,
|
|
4229
4376
|
getPrimaryId as getPrimaryId5
|
|
4230
4377
|
} from "@tscircuit/circuit-json-util";
|
|
@@ -4322,9 +4469,9 @@ function checkPcbComponentOverlap(circuitJson) {
|
|
|
4322
4469
|
)
|
|
4323
4470
|
);
|
|
4324
4471
|
const connMap = getFullConnectivityMapFromCircuitJson9(circuitJson);
|
|
4325
|
-
const smtPads =
|
|
4326
|
-
const platedHoles =
|
|
4327
|
-
const holes =
|
|
4472
|
+
const smtPads = cju7(circuitJson).pcb_smtpad.list();
|
|
4473
|
+
const platedHoles = cju7(circuitJson).pcb_plated_hole.list();
|
|
4474
|
+
const holes = cju7(circuitJson).pcb_hole.list();
|
|
4328
4475
|
const courtyards = circuitJson.filter(isCourtyardElement2);
|
|
4329
4476
|
const componentMap = /* @__PURE__ */ new Map();
|
|
4330
4477
|
for (const pad of smtPads) {
|
|
@@ -5066,7 +5213,7 @@ function checkTwoTerminalSwitchContactsOnDifferentNets(circuitJson) {
|
|
|
5066
5213
|
}
|
|
5067
5214
|
|
|
5068
5215
|
// lib/check-all-pins-in-component-are-underspecified.ts
|
|
5069
|
-
import { cju as
|
|
5216
|
+
import { cju as cju8 } from "@tscircuit/circuit-json-util";
|
|
5070
5217
|
var PIN_ATTRIBUTE_KEYS = [
|
|
5071
5218
|
"must_be_connected",
|
|
5072
5219
|
"provides_power",
|
|
@@ -5111,7 +5258,7 @@ function hasAnyPinAttribute(port) {
|
|
|
5111
5258
|
}
|
|
5112
5259
|
function checkAllPinsInComponentAreUnderspecified(circuitJson) {
|
|
5113
5260
|
const warnings = [];
|
|
5114
|
-
const db =
|
|
5261
|
+
const db = cju8(circuitJson);
|
|
5115
5262
|
const sourceComponents = db.source_component.list();
|
|
5116
5263
|
const sourcePorts = db.source_port.list();
|
|
5117
5264
|
const portsByComponent = /* @__PURE__ */ new Map();
|
|
@@ -5143,7 +5290,7 @@ function checkAllPinsInComponentAreUnderspecified(circuitJson) {
|
|
|
5143
5290
|
}
|
|
5144
5291
|
|
|
5145
5292
|
// lib/check-no-power-pin-defined.ts
|
|
5146
|
-
import { cju as
|
|
5293
|
+
import { cju as cju9 } from "@tscircuit/circuit-json-util";
|
|
5147
5294
|
|
|
5148
5295
|
// lib/util/should-check-chip-power-ground-pins.ts
|
|
5149
5296
|
var shouldCheckChipPowerGroundPins = (component, ports) => component.ftype === "simple_chip" && ports.filter((port) => port.do_not_connect !== true).length >= 2;
|
|
@@ -5151,7 +5298,7 @@ var shouldCheckChipPowerGroundPins = (component, ports) => component.ftype === "
|
|
|
5151
5298
|
// lib/check-no-power-pin-defined.ts
|
|
5152
5299
|
function checkNoPowerPinDefined(circuitJson) {
|
|
5153
5300
|
const warnings = [];
|
|
5154
|
-
const db =
|
|
5301
|
+
const db = cju9(circuitJson);
|
|
5155
5302
|
const sourceComponents = db.source_component.list();
|
|
5156
5303
|
const sourcePorts = db.source_port.list();
|
|
5157
5304
|
const portsByComponent = /* @__PURE__ */ new Map();
|
|
@@ -5182,10 +5329,10 @@ function checkNoPowerPinDefined(circuitJson) {
|
|
|
5182
5329
|
}
|
|
5183
5330
|
|
|
5184
5331
|
// lib/check-no-ground-pin-defined.ts
|
|
5185
|
-
import { cju as
|
|
5332
|
+
import { cju as cju10 } from "@tscircuit/circuit-json-util";
|
|
5186
5333
|
function checkNoGroundPinDefined(circuitJson) {
|
|
5187
5334
|
const warnings = [];
|
|
5188
|
-
const db =
|
|
5335
|
+
const db = cju10(circuitJson);
|
|
5189
5336
|
const sourceComponents = db.source_component.list();
|
|
5190
5337
|
const sourcePorts = db.source_port.list();
|
|
5191
5338
|
const portsByComponent = /* @__PURE__ */ new Map();
|
|
@@ -6046,6 +6193,7 @@ export {
|
|
|
6046
6193
|
checkPcbComponentsOutOfBoard,
|
|
6047
6194
|
checkPcbCopperOverKeepout,
|
|
6048
6195
|
checkPcbTraceLengths,
|
|
6196
|
+
checkPcbTraceSelfShorts,
|
|
6049
6197
|
checkPcbTraceViaCounts,
|
|
6050
6198
|
checkPcbTracesOutOfBoard,
|
|
6051
6199
|
checkPinMustBeConnected,
|