@tscircuit/cli 0.1.2229 → 0.1.2230
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/cli/main.js +787 -256
- package/dist/lib/index.js +3 -3
- package/package.json +3 -3
package/dist/cli/main.js
CHANGED
|
@@ -154298,7 +154298,7 @@ var import_perfect_cli = __toESM3(require_dist3(), 1);
|
|
|
154298
154298
|
// lib/getVersion.ts
|
|
154299
154299
|
import { createRequire as createRequire2 } from "node:module";
|
|
154300
154300
|
// package.json
|
|
154301
|
-
var version = "0.1.
|
|
154301
|
+
var version = "0.1.2229";
|
|
154302
154302
|
var package_default = {
|
|
154303
154303
|
name: "@tscircuit/cli",
|
|
154304
154304
|
version,
|
|
@@ -154326,7 +154326,7 @@ var package_default = {
|
|
|
154326
154326
|
"@tscircuit/image-utils": "^0.0.8",
|
|
154327
154327
|
"@tscircuit/krt-wasm": "^0.1.6",
|
|
154328
154328
|
"@tscircuit/math-utils": "0.0.36",
|
|
154329
|
-
"@tscircuit/props": "^0.0.
|
|
154329
|
+
"@tscircuit/props": "^0.0.666",
|
|
154330
154330
|
"@tscircuit/runframe": "^0.0.2884",
|
|
154331
154331
|
"@tscircuit/schematic-match-adapt": "^0.0.22",
|
|
154332
154332
|
"@tscircuit/schematic-trace-solver": "^0.0.204",
|
|
@@ -154367,7 +154367,7 @@ var package_default = {
|
|
|
154367
154367
|
debug: "^4.4.0",
|
|
154368
154368
|
delay: "^6.0.0",
|
|
154369
154369
|
"dsn-converter": "^0.0.90",
|
|
154370
|
-
easyeda: "^0.0.
|
|
154370
|
+
easyeda: "^0.0.366",
|
|
154371
154371
|
"fuse.js": "^7.1.0",
|
|
154372
154372
|
"get-port": "^7.1.0",
|
|
154373
154373
|
globby: "^14.1.0",
|
|
@@ -365015,6 +365015,208 @@ var transformPCBElements2 = (elms, matrix) => {
|
|
|
365015
365015
|
}
|
|
365016
365016
|
return transformedElms;
|
|
365017
365017
|
};
|
|
365018
|
+
var mergeBounds4 = (currentBounds, nextBounds) => ({
|
|
365019
|
+
minX: Math.min(currentBounds.minX, nextBounds.minX),
|
|
365020
|
+
minY: Math.min(currentBounds.minY, nextBounds.minY),
|
|
365021
|
+
maxX: Math.max(currentBounds.maxX, nextBounds.maxX),
|
|
365022
|
+
maxY: Math.max(currentBounds.maxY, nextBounds.maxY)
|
|
365023
|
+
});
|
|
365024
|
+
var getCircleBounds2 = (x, y, diameter) => {
|
|
365025
|
+
const radius = diameter / 2;
|
|
365026
|
+
return {
|
|
365027
|
+
minX: x - radius,
|
|
365028
|
+
minY: y - radius,
|
|
365029
|
+
maxX: x + radius,
|
|
365030
|
+
maxY: y + radius
|
|
365031
|
+
};
|
|
365032
|
+
};
|
|
365033
|
+
var getRotatedRectBounds2 = (x, y, width, height, rotationDegrees) => {
|
|
365034
|
+
const halfWidth = width / 2;
|
|
365035
|
+
const halfHeight = height / 2;
|
|
365036
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
365037
|
+
const cosTheta = Math.cos(theta);
|
|
365038
|
+
const sinTheta = Math.sin(theta);
|
|
365039
|
+
const corners = [
|
|
365040
|
+
{ x: -halfWidth, y: -halfHeight },
|
|
365041
|
+
{ x: halfWidth, y: -halfHeight },
|
|
365042
|
+
{ x: halfWidth, y: halfHeight },
|
|
365043
|
+
{ x: -halfWidth, y: halfHeight }
|
|
365044
|
+
].map((corner) => ({
|
|
365045
|
+
x: x + corner.x * cosTheta - corner.y * sinTheta,
|
|
365046
|
+
y: y + corner.x * sinTheta + corner.y * cosTheta
|
|
365047
|
+
}));
|
|
365048
|
+
return {
|
|
365049
|
+
minX: Math.min(...corners.map((corner) => corner.x)),
|
|
365050
|
+
minY: Math.min(...corners.map((corner) => corner.y)),
|
|
365051
|
+
maxX: Math.max(...corners.map((corner) => corner.x)),
|
|
365052
|
+
maxY: Math.max(...corners.map((corner) => corner.y))
|
|
365053
|
+
};
|
|
365054
|
+
};
|
|
365055
|
+
var getRotatedOvalBounds = (x, y, width, height, rotationDegrees) => {
|
|
365056
|
+
const radiusX = width / 2;
|
|
365057
|
+
const radiusY = height / 2;
|
|
365058
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
365059
|
+
const cosTheta = Math.cos(theta);
|
|
365060
|
+
const sinTheta = Math.sin(theta);
|
|
365061
|
+
const halfWidth = Math.hypot(radiusX * cosTheta, radiusY * sinTheta);
|
|
365062
|
+
const halfHeight = Math.hypot(radiusX * sinTheta, radiusY * cosTheta);
|
|
365063
|
+
return {
|
|
365064
|
+
minX: x - halfWidth,
|
|
365065
|
+
minY: y - halfHeight,
|
|
365066
|
+
maxX: x + halfWidth,
|
|
365067
|
+
maxY: y + halfHeight
|
|
365068
|
+
};
|
|
365069
|
+
};
|
|
365070
|
+
var getRotatedPillBounds = (x, y, width, height, rotationDegrees) => {
|
|
365071
|
+
const radius = Math.min(width, height) / 2;
|
|
365072
|
+
const halfLineLength = Math.max(width, height) / 2 - radius;
|
|
365073
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
365074
|
+
const axis = width >= height ? { x: halfLineLength, y: 0 } : { x: 0, y: halfLineLength };
|
|
365075
|
+
const rotatedAxis = {
|
|
365076
|
+
x: axis.x * Math.cos(theta) - axis.y * Math.sin(theta),
|
|
365077
|
+
y: axis.x * Math.sin(theta) + axis.y * Math.cos(theta)
|
|
365078
|
+
};
|
|
365079
|
+
const halfWidth = Math.abs(rotatedAxis.x) + radius;
|
|
365080
|
+
const halfHeight = Math.abs(rotatedAxis.y) + radius;
|
|
365081
|
+
return {
|
|
365082
|
+
minX: x - halfWidth,
|
|
365083
|
+
minY: y - halfHeight,
|
|
365084
|
+
maxX: x + halfWidth,
|
|
365085
|
+
maxY: y + halfHeight
|
|
365086
|
+
};
|
|
365087
|
+
};
|
|
365088
|
+
var getBoundsFromPoints6 = (points) => {
|
|
365089
|
+
if (points.length === 0)
|
|
365090
|
+
return null;
|
|
365091
|
+
return {
|
|
365092
|
+
minX: Math.min(...points.map((point2) => point2.x)),
|
|
365093
|
+
minY: Math.min(...points.map((point2) => point2.y)),
|
|
365094
|
+
maxX: Math.max(...points.map((point2) => point2.x)),
|
|
365095
|
+
maxY: Math.max(...points.map((point2) => point2.y))
|
|
365096
|
+
};
|
|
365097
|
+
};
|
|
365098
|
+
var getRoutePoints = (route) => {
|
|
365099
|
+
if (!Array.isArray(route))
|
|
365100
|
+
return [];
|
|
365101
|
+
return route.flatMap((point2) => {
|
|
365102
|
+
if (!point2 || typeof point2 !== "object")
|
|
365103
|
+
return [];
|
|
365104
|
+
if ("x" in point2 && "y" in point2 && typeof point2.x === "number" && typeof point2.y === "number") {
|
|
365105
|
+
return [{ x: point2.x, y: point2.y }];
|
|
365106
|
+
}
|
|
365107
|
+
if ("start" in point2 && "end" in point2) {
|
|
365108
|
+
const positions = [point2.start, point2.end];
|
|
365109
|
+
return positions.filter((position2) => Boolean(position2 && typeof position2 === "object" && "x" in position2 && "y" in position2 && typeof position2.x === "number" && typeof position2.y === "number"));
|
|
365110
|
+
}
|
|
365111
|
+
return [];
|
|
365112
|
+
});
|
|
365113
|
+
};
|
|
365114
|
+
var getPcbElementBounds = (elm) => {
|
|
365115
|
+
if (!elm.type.startsWith("pcb_"))
|
|
365116
|
+
return null;
|
|
365117
|
+
if (elm.type === "pcb_smtpad" && elm.shape === "polygon" && Array.isArray(elm.points)) {
|
|
365118
|
+
return getBoundsFromPoints6(elm.points);
|
|
365119
|
+
}
|
|
365120
|
+
if (elm.type === "pcb_hole" && elm.hole_shape === "circle") {
|
|
365121
|
+
return getCircleBounds2(elm.x, elm.y, elm.hole_diameter);
|
|
365122
|
+
}
|
|
365123
|
+
if (elm.type === "pcb_plated_hole") {
|
|
365124
|
+
let platedHoleBounds;
|
|
365125
|
+
if ("outer_diameter" in elm && typeof elm.outer_diameter === "number") {
|
|
365126
|
+
platedHoleBounds = getCircleBounds2(elm.x, elm.y, elm.outer_diameter);
|
|
365127
|
+
} else if ("hole_diameter" in elm && typeof elm.hole_diameter === "number") {
|
|
365128
|
+
platedHoleBounds = getCircleBounds2(elm.x, elm.y, elm.hole_diameter);
|
|
365129
|
+
}
|
|
365130
|
+
if ((elm.shape === "oval" || elm.shape === "pill") && typeof elm.outer_width === "number" && typeof elm.outer_height === "number") {
|
|
365131
|
+
const getOuterBounds = elm.shape === "pill" ? getRotatedPillBounds : getRotatedOvalBounds;
|
|
365132
|
+
platedHoleBounds = getOuterBounds(elm.x, elm.y, elm.outer_width, elm.outer_height, elm.ccw_rotation ?? 0);
|
|
365133
|
+
}
|
|
365134
|
+
if ("rect_pad_width" in elm && typeof elm.rect_pad_width === "number" && "rect_pad_height" in elm && typeof elm.rect_pad_height === "number") {
|
|
365135
|
+
const rectBounds = getRotatedRectBounds2(elm.x, elm.y, elm.rect_pad_width, elm.rect_pad_height, "rect_ccw_rotation" in elm ? elm.rect_ccw_rotation ?? 0 : 0);
|
|
365136
|
+
platedHoleBounds = platedHoleBounds ? mergeBounds4(platedHoleBounds, rectBounds) : rectBounds;
|
|
365137
|
+
}
|
|
365138
|
+
if ("hole_diameter" in elm && typeof elm.hole_diameter === "number") {
|
|
365139
|
+
const drillBounds = getCircleBounds2(elm.x + ("hole_offset_x" in elm ? elm.hole_offset_x ?? 0 : 0), elm.y + ("hole_offset_y" in elm ? elm.hole_offset_y ?? 0 : 0), elm.hole_diameter);
|
|
365140
|
+
platedHoleBounds = platedHoleBounds ? mergeBounds4(platedHoleBounds, drillBounds) : drillBounds;
|
|
365141
|
+
}
|
|
365142
|
+
if (platedHoleBounds)
|
|
365143
|
+
return platedHoleBounds;
|
|
365144
|
+
}
|
|
365145
|
+
const elementRecord = elm;
|
|
365146
|
+
const routeBounds = getBoundsFromPoints6(getRoutePoints(elementRecord.route));
|
|
365147
|
+
if (routeBounds)
|
|
365148
|
+
return routeBounds;
|
|
365149
|
+
const outlineBounds = getBoundsFromPoints6(getRoutePoints(elementRecord.outline));
|
|
365150
|
+
if (outlineBounds)
|
|
365151
|
+
return outlineBounds;
|
|
365152
|
+
const pointsBounds = getBoundsFromPoints6(getRoutePoints(elementRecord.points));
|
|
365153
|
+
if (pointsBounds)
|
|
365154
|
+
return pointsBounds;
|
|
365155
|
+
let centerX;
|
|
365156
|
+
let centerY;
|
|
365157
|
+
let width;
|
|
365158
|
+
let height;
|
|
365159
|
+
if ("x" in elm && "y" in elm) {
|
|
365160
|
+
centerX = Number(elm.x);
|
|
365161
|
+
centerY = Number(elm.y);
|
|
365162
|
+
}
|
|
365163
|
+
if ("outer_diameter" in elm) {
|
|
365164
|
+
width = Number(elm.outer_diameter);
|
|
365165
|
+
height = Number(elm.outer_diameter);
|
|
365166
|
+
}
|
|
365167
|
+
if ("width" in elm) {
|
|
365168
|
+
width = Number(elm.width);
|
|
365169
|
+
}
|
|
365170
|
+
if ("height" in elm) {
|
|
365171
|
+
height = Number(elm.height);
|
|
365172
|
+
}
|
|
365173
|
+
if ("center" in elm && elm.center && typeof elm.center === "object" && "x" in elm.center && "y" in elm.center) {
|
|
365174
|
+
centerX = Number(elm.center.x);
|
|
365175
|
+
centerY = Number(elm.center.y);
|
|
365176
|
+
}
|
|
365177
|
+
let rotation2 = 0;
|
|
365178
|
+
if ("rotation" in elm && typeof elm.rotation === "number") {
|
|
365179
|
+
rotation2 = elm.rotation;
|
|
365180
|
+
}
|
|
365181
|
+
if ("ccw_rotation" in elm && typeof elm.ccw_rotation === "number") {
|
|
365182
|
+
rotation2 = elm.ccw_rotation;
|
|
365183
|
+
}
|
|
365184
|
+
if (centerX !== undefined && centerY !== undefined) {
|
|
365185
|
+
if (width !== undefined && height !== undefined) {
|
|
365186
|
+
return rotation2 ? getRotatedRectBounds2(centerX, centerY, width, height, rotation2) : {
|
|
365187
|
+
minX: centerX - width / 2,
|
|
365188
|
+
minY: centerY - height / 2,
|
|
365189
|
+
maxX: centerX + width / 2,
|
|
365190
|
+
maxY: centerY + height / 2
|
|
365191
|
+
};
|
|
365192
|
+
}
|
|
365193
|
+
if ("radius" in elm && typeof elm.radius === "number") {
|
|
365194
|
+
return getCircleBounds2(centerX, centerY, elm.radius * 2);
|
|
365195
|
+
}
|
|
365196
|
+
return { minX: centerX, minY: centerY, maxX: centerX, maxY: centerY };
|
|
365197
|
+
}
|
|
365198
|
+
const anchoredPoint = [elementRecord.anchor_position, elementRecord.position].filter((position2) => Boolean(position2 && typeof position2 === "object" && "x" in position2 && "y" in position2 && typeof position2.x === "number" && typeof position2.y === "number")).at(0);
|
|
365199
|
+
return anchoredPoint ? {
|
|
365200
|
+
minX: anchoredPoint.x,
|
|
365201
|
+
minY: anchoredPoint.y,
|
|
365202
|
+
maxX: anchoredPoint.x,
|
|
365203
|
+
maxY: anchoredPoint.y
|
|
365204
|
+
} : null;
|
|
365205
|
+
};
|
|
365206
|
+
var getBoundsOfPcbElements3 = (elements) => {
|
|
365207
|
+
let bounds = {
|
|
365208
|
+
minX: Number.POSITIVE_INFINITY,
|
|
365209
|
+
minY: Number.POSITIVE_INFINITY,
|
|
365210
|
+
maxX: Number.NEGATIVE_INFINITY,
|
|
365211
|
+
maxY: Number.NEGATIVE_INFINITY
|
|
365212
|
+
};
|
|
365213
|
+
for (const element of elements) {
|
|
365214
|
+
const elementBounds = getPcbElementBounds(element);
|
|
365215
|
+
if (elementBounds)
|
|
365216
|
+
bounds = mergeBounds4(bounds, elementBounds);
|
|
365217
|
+
}
|
|
365218
|
+
return bounds;
|
|
365219
|
+
};
|
|
365018
365220
|
function stringHash3(str) {
|
|
365019
365221
|
let hash = 0;
|
|
365020
365222
|
if (str.length == 0)
|
|
@@ -365226,6 +365428,116 @@ var PIN1_LOCATION_PARTS = {
|
|
|
365226
365428
|
bottomside_right: { side: "bottomside", alignment: "right" }
|
|
365227
365429
|
};
|
|
365228
365430
|
var PIN1_LOCATIONS2 = Object.keys(PIN1_LOCATION_PARTS);
|
|
365431
|
+
var normalizeActiveLowPinLabel = (label) => {
|
|
365432
|
+
const hasActiveLowMarker = label.startsWith("#") || label.endsWith("#");
|
|
365433
|
+
if (!hasActiveLowMarker)
|
|
365434
|
+
return label;
|
|
365435
|
+
const activeLowLabel = label.replace(/^#/, "").replace(/#$/, "");
|
|
365436
|
+
if (activeLowLabel.length === 0)
|
|
365437
|
+
return label;
|
|
365438
|
+
if (activeLowLabel.startsWith("N_"))
|
|
365439
|
+
return activeLowLabel;
|
|
365440
|
+
return `N_${activeLowLabel}`;
|
|
365441
|
+
};
|
|
365442
|
+
var normalizePinLabels = (inputPinLabels) => {
|
|
365443
|
+
const normalizedInputPinLabels = inputPinLabels.map((labels) => labels.map(normalizeActiveLowPinLabel));
|
|
365444
|
+
const uniqueInputPinLabels = normalizedInputPinLabels.map((labels) => [
|
|
365445
|
+
...new Set(labels)
|
|
365446
|
+
]);
|
|
365447
|
+
const result = uniqueInputPinLabels.map(() => []);
|
|
365448
|
+
const desiredNumbers = uniqueInputPinLabels.map(() => null);
|
|
365449
|
+
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
365450
|
+
for (const label of uniqueInputPinLabels[i]) {
|
|
365451
|
+
if (/^\d+$/.test(label)) {
|
|
365452
|
+
desiredNumbers[i] = Number.parseInt(label);
|
|
365453
|
+
break;
|
|
365454
|
+
}
|
|
365455
|
+
}
|
|
365456
|
+
}
|
|
365457
|
+
let highestPinNumber = 0;
|
|
365458
|
+
const acceptedDesiredNumbers = /* @__PURE__ */ new Set;
|
|
365459
|
+
for (let i = 0;i < desiredNumbers.length; i++) {
|
|
365460
|
+
const desiredNumber = desiredNumbers[i];
|
|
365461
|
+
if (desiredNumber === null || desiredNumber < 1)
|
|
365462
|
+
continue;
|
|
365463
|
+
if (!acceptedDesiredNumbers.has(desiredNumber)) {
|
|
365464
|
+
acceptedDesiredNumbers.add(desiredNumber);
|
|
365465
|
+
result[i].push(`pin${desiredNumber}`);
|
|
365466
|
+
highestPinNumber = Math.max(highestPinNumber, desiredNumber);
|
|
365467
|
+
continue;
|
|
365468
|
+
}
|
|
365469
|
+
let existingAltCount = 0;
|
|
365470
|
+
for (const label of result[i]) {
|
|
365471
|
+
if (label.startsWith(`pin${desiredNumber}_alt`)) {
|
|
365472
|
+
existingAltCount += 1;
|
|
365473
|
+
}
|
|
365474
|
+
}
|
|
365475
|
+
result[i].push(`pin${desiredNumber}_alt${existingAltCount + 1}`);
|
|
365476
|
+
}
|
|
365477
|
+
for (let i = 0;i < result.length; i++) {
|
|
365478
|
+
const firstLabel = result[i][0];
|
|
365479
|
+
if (firstLabel?.includes("_alt")) {
|
|
365480
|
+
highestPinNumber += 1;
|
|
365481
|
+
result[i].unshift(`pin${highestPinNumber}`);
|
|
365482
|
+
}
|
|
365483
|
+
}
|
|
365484
|
+
for (let i = 0;i < result.length; i++) {
|
|
365485
|
+
if (result[i].length === 0) {
|
|
365486
|
+
highestPinNumber += 1;
|
|
365487
|
+
result[i].push(`pin${highestPinNumber}`);
|
|
365488
|
+
}
|
|
365489
|
+
}
|
|
365490
|
+
const totalLabelCounts = {};
|
|
365491
|
+
for (const inputLabels of uniqueInputPinLabels) {
|
|
365492
|
+
for (const label of inputLabels) {
|
|
365493
|
+
if (/^\d+$/.test(label))
|
|
365494
|
+
continue;
|
|
365495
|
+
totalLabelCounts[label] = (totalLabelCounts[label] ?? 0) + 1;
|
|
365496
|
+
}
|
|
365497
|
+
}
|
|
365498
|
+
const incrementalLabelCounts = {};
|
|
365499
|
+
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
365500
|
+
for (const label of uniqueInputPinLabels[i]) {
|
|
365501
|
+
if (/^\d+$/.test(label))
|
|
365502
|
+
continue;
|
|
365503
|
+
if (totalLabelCounts[label] === 1) {
|
|
365504
|
+
result[i].push(label);
|
|
365505
|
+
} else {
|
|
365506
|
+
incrementalLabelCounts[label] = (incrementalLabelCounts[label] ?? 0) + 1;
|
|
365507
|
+
result[i].push(`${label}${incrementalLabelCounts[label]}`);
|
|
365508
|
+
}
|
|
365509
|
+
}
|
|
365510
|
+
}
|
|
365511
|
+
return result;
|
|
365512
|
+
};
|
|
365513
|
+
var normalizeEasyEdaPinLabel = (label) => {
|
|
365514
|
+
if (label.endsWith("+"))
|
|
365515
|
+
label = `${label.slice(0, -1)}_POS`;
|
|
365516
|
+
if (/[-–−]$/.test(label))
|
|
365517
|
+
label = `${label.slice(0, -1)}_NEG`;
|
|
365518
|
+
label = normalizeActiveLowPinLabel(label);
|
|
365519
|
+
if (/^\+\d+(?:\.\d+)?V$/i.test(label))
|
|
365520
|
+
label = `V${label.slice(1, -1)}`;
|
|
365521
|
+
if (label.startsWith("+"))
|
|
365522
|
+
label = `${label.slice(1)}_POS`;
|
|
365523
|
+
if (/^[-–−]/.test(label))
|
|
365524
|
+
label = `${label.slice(1)}_NEG`;
|
|
365525
|
+
return label;
|
|
365526
|
+
};
|
|
365527
|
+
var getEasyEdaPinAliases = (label) => {
|
|
365528
|
+
label = label.replace(/&#(x[0-9a-f]+|[0-9]+);/gi, (entity, code) => {
|
|
365529
|
+
let codePoint = Number(code);
|
|
365530
|
+
if (/^x/i.test(code))
|
|
365531
|
+
codePoint = Number.parseInt(code.slice(1), 16);
|
|
365532
|
+
const maximumUnicodeCodePoint = 1114111;
|
|
365533
|
+
if (codePoint > maximumUnicodeCodePoint)
|
|
365534
|
+
return entity;
|
|
365535
|
+
return String.fromCodePoint(codePoint);
|
|
365536
|
+
});
|
|
365537
|
+
if (label.includes("/") && !/[a-zA-Z0-9]/.test(label))
|
|
365538
|
+
return [];
|
|
365539
|
+
return label.split("/").map((alias) => normalizeEasyEdaPinLabel(alias.trim()).replace(/[`′]/g, "_PRIME").replace(/^[()]+|[()]+$/g, "").replace(/[^a-zA-Z0-9_]/g, "_")).filter((alias) => /[a-zA-Z0-9]/.test(alias));
|
|
365540
|
+
};
|
|
365229
365541
|
function orientation3(p, q, r) {
|
|
365230
365542
|
const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
365231
365543
|
if (val === 0)
|
|
@@ -365253,7 +365565,7 @@ var getBoundsCenter3 = (bounds) => ({
|
|
|
365253
365565
|
x: (bounds.minX + bounds.maxX) / 2,
|
|
365254
365566
|
y: (bounds.minY + bounds.maxY) / 2
|
|
365255
365567
|
});
|
|
365256
|
-
var
|
|
365568
|
+
var getBoundsFromPoints23 = (points) => {
|
|
365257
365569
|
if (points.length === 0) {
|
|
365258
365570
|
return null;
|
|
365259
365571
|
}
|
|
@@ -365500,96 +365812,6 @@ var getPolarizedPinMetadata = (pinLabels) => {
|
|
|
365500
365812
|
pinLabels: Object.fromEntries(polarizedPinEntries)
|
|
365501
365813
|
};
|
|
365502
365814
|
};
|
|
365503
|
-
var normalizeActiveLowPinLabel = (label) => {
|
|
365504
|
-
const hasActiveLowMarker = label.startsWith("#") || label.endsWith("#");
|
|
365505
|
-
if (!hasActiveLowMarker)
|
|
365506
|
-
return label;
|
|
365507
|
-
const activeLowLabel = label.replace(/^#/, "").replace(/#$/, "");
|
|
365508
|
-
if (activeLowLabel.length === 0)
|
|
365509
|
-
return label;
|
|
365510
|
-
if (activeLowLabel.startsWith("N_"))
|
|
365511
|
-
return activeLowLabel;
|
|
365512
|
-
return `N_${activeLowLabel}`;
|
|
365513
|
-
};
|
|
365514
|
-
var normalizePinLabels = (inputPinLabels) => {
|
|
365515
|
-
const normalizedInputPinLabels = inputPinLabels.map((labels) => labels.map(normalizeActiveLowPinLabel));
|
|
365516
|
-
const uniqueInputPinLabels = normalizedInputPinLabels.map((labels) => [
|
|
365517
|
-
...new Set(labels)
|
|
365518
|
-
]);
|
|
365519
|
-
const result = uniqueInputPinLabels.map(() => []);
|
|
365520
|
-
const desiredNumbers = uniqueInputPinLabels.map(() => null);
|
|
365521
|
-
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
365522
|
-
for (const label of uniqueInputPinLabels[i]) {
|
|
365523
|
-
if (/^\d+$/.test(label)) {
|
|
365524
|
-
desiredNumbers[i] = Number.parseInt(label);
|
|
365525
|
-
break;
|
|
365526
|
-
}
|
|
365527
|
-
}
|
|
365528
|
-
}
|
|
365529
|
-
let highestPinNumber = 0;
|
|
365530
|
-
const acceptedDesiredNumbers = /* @__PURE__ */ new Set;
|
|
365531
|
-
for (let i = 0;i < desiredNumbers.length; i++) {
|
|
365532
|
-
const desiredNumber = desiredNumbers[i];
|
|
365533
|
-
if (desiredNumber === null || desiredNumber < 1)
|
|
365534
|
-
continue;
|
|
365535
|
-
if (!acceptedDesiredNumbers.has(desiredNumber)) {
|
|
365536
|
-
acceptedDesiredNumbers.add(desiredNumber);
|
|
365537
|
-
result[i].push(`pin${desiredNumber}`);
|
|
365538
|
-
highestPinNumber = Math.max(highestPinNumber, desiredNumber);
|
|
365539
|
-
continue;
|
|
365540
|
-
}
|
|
365541
|
-
let existingAltCount = 0;
|
|
365542
|
-
for (const label of result[i]) {
|
|
365543
|
-
if (label.startsWith(`pin${desiredNumber}_alt`)) {
|
|
365544
|
-
existingAltCount += 1;
|
|
365545
|
-
}
|
|
365546
|
-
}
|
|
365547
|
-
result[i].push(`pin${desiredNumber}_alt${existingAltCount + 1}`);
|
|
365548
|
-
}
|
|
365549
|
-
for (let i = 0;i < result.length; i++) {
|
|
365550
|
-
const firstLabel = result[i][0];
|
|
365551
|
-
if (firstLabel?.includes("_alt")) {
|
|
365552
|
-
highestPinNumber += 1;
|
|
365553
|
-
result[i].unshift(`pin${highestPinNumber}`);
|
|
365554
|
-
}
|
|
365555
|
-
}
|
|
365556
|
-
for (let i = 0;i < result.length; i++) {
|
|
365557
|
-
if (result[i].length === 0) {
|
|
365558
|
-
highestPinNumber += 1;
|
|
365559
|
-
result[i].push(`pin${highestPinNumber}`);
|
|
365560
|
-
}
|
|
365561
|
-
}
|
|
365562
|
-
const totalLabelCounts = {};
|
|
365563
|
-
for (const inputLabels of uniqueInputPinLabels) {
|
|
365564
|
-
for (const label of inputLabels) {
|
|
365565
|
-
if (/^\d+$/.test(label))
|
|
365566
|
-
continue;
|
|
365567
|
-
totalLabelCounts[label] = (totalLabelCounts[label] ?? 0) + 1;
|
|
365568
|
-
}
|
|
365569
|
-
}
|
|
365570
|
-
const incrementalLabelCounts = {};
|
|
365571
|
-
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
365572
|
-
for (const label of uniqueInputPinLabels[i]) {
|
|
365573
|
-
if (/^\d+$/.test(label))
|
|
365574
|
-
continue;
|
|
365575
|
-
if (totalLabelCounts[label] === 1) {
|
|
365576
|
-
result[i].push(label);
|
|
365577
|
-
} else {
|
|
365578
|
-
incrementalLabelCounts[label] = (incrementalLabelCounts[label] ?? 0) + 1;
|
|
365579
|
-
result[i].push(`${label}${incrementalLabelCounts[label]}`);
|
|
365580
|
-
}
|
|
365581
|
-
}
|
|
365582
|
-
}
|
|
365583
|
-
return result;
|
|
365584
|
-
};
|
|
365585
|
-
var normalizeSymbolName = (name) => {
|
|
365586
|
-
const trimmedName = name.trim();
|
|
365587
|
-
if (trimmedName === "+")
|
|
365588
|
-
return "_POS";
|
|
365589
|
-
if (trimmedName === "-")
|
|
365590
|
-
return "_NEG";
|
|
365591
|
-
return trimmedName.replace(/(?<=[A-Za-z0-9])-(?=[A-Za-z0-9])/g, "_");
|
|
365592
|
-
};
|
|
365593
365815
|
var categoryValueContainsDiode = (value) => {
|
|
365594
365816
|
if (typeof value === "string") {
|
|
365595
365817
|
return /(^|[^a-z])diodes?([^a-z]|$)/i.test(value);
|
|
@@ -365683,7 +365905,7 @@ var getEasyEdaModelOriginOnBoardMm = ({
|
|
|
365683
365905
|
}
|
|
365684
365906
|
let modelOriginMm = null;
|
|
365685
365907
|
if (points.length > 0) {
|
|
365686
|
-
const bounds =
|
|
365908
|
+
const bounds = getBoundsFromPoints23(points);
|
|
365687
365909
|
modelOriginMm = bounds ? getBoundsCenter3(bounds) : null;
|
|
365688
365910
|
} else {
|
|
365689
365911
|
const [originX, originY] = String(svgNode.svgData.attrs?.c_origin ?? "0,0").split(",").map((value) => Number(value.trim()));
|
|
@@ -365772,6 +365994,45 @@ var parseCadOffsetsFromSvgNode = (svgNode) => {
|
|
|
365772
365994
|
})()
|
|
365773
365995
|
};
|
|
365774
365996
|
};
|
|
365997
|
+
var getCadModelOutlineBounds = (svgNode) => {
|
|
365998
|
+
const points = [];
|
|
365999
|
+
for (const childNode of svgNode?.svgData.childNodes ?? []) {
|
|
366000
|
+
if (typeof childNode !== "object" || childNode === null)
|
|
366001
|
+
continue;
|
|
366002
|
+
const attrs = childNode.attrs;
|
|
366003
|
+
if (typeof attrs !== "object" || attrs === null)
|
|
366004
|
+
continue;
|
|
366005
|
+
const rawPoints = attrs.points;
|
|
366006
|
+
if (typeof rawPoints !== "string")
|
|
366007
|
+
continue;
|
|
366008
|
+
const coordinates = rawPoints.trim().split(/\s+/).map(Number);
|
|
366009
|
+
for (let index = 0;index + 1 < coordinates.length; index += 2) {
|
|
366010
|
+
const x = coordinates[index];
|
|
366011
|
+
const y = coordinates[index + 1];
|
|
366012
|
+
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
366013
|
+
continue;
|
|
366014
|
+
points.push({ x: milx10(x), y: milx10(y) });
|
|
366015
|
+
}
|
|
366016
|
+
}
|
|
366017
|
+
if (points.length === 0)
|
|
366018
|
+
return;
|
|
366019
|
+
return {
|
|
366020
|
+
minX: Math.min(...points.map((point2) => point2.x)),
|
|
366021
|
+
minY: Math.min(...points.map((point2) => point2.y)),
|
|
366022
|
+
maxX: Math.max(...points.map((point2) => point2.x)),
|
|
366023
|
+
maxY: Math.max(...points.map((point2) => point2.y))
|
|
366024
|
+
};
|
|
366025
|
+
};
|
|
366026
|
+
var unionBounds2 = (first, second) => {
|
|
366027
|
+
if (!second)
|
|
366028
|
+
return first;
|
|
366029
|
+
return {
|
|
366030
|
+
minX: Math.min(first.minX, second.minX),
|
|
366031
|
+
minY: Math.min(first.minY, second.minY),
|
|
366032
|
+
maxX: Math.max(first.maxX, second.maxX),
|
|
366033
|
+
maxY: Math.max(first.maxY, second.maxY)
|
|
366034
|
+
};
|
|
366035
|
+
};
|
|
365775
366036
|
var readModelHeightMm = (raw) => {
|
|
365776
366037
|
const fallback = 3.5;
|
|
365777
366038
|
if (raw == null)
|
|
@@ -366012,13 +366273,11 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
|
|
|
366012
366273
|
const pads = easyEdaJson.packageDetail.dataStr.shape.filter((shape) => shape.type === "PAD");
|
|
366013
366274
|
const pins = easyEdaJson.dataStr.shape.filter((shape) => shape.type === "PIN");
|
|
366014
366275
|
const pinLabelSets = pads.map((pad) => {
|
|
366015
|
-
const
|
|
366016
|
-
if (pad.number)
|
|
366017
|
-
labels.push(pad.number.toString());
|
|
366276
|
+
const padAliases = pad.number ? getEasyEdaPinAliases(pad.number.toString()) : [];
|
|
366018
366277
|
const pin = pins.find((p) => p.pinNumber === pad.number);
|
|
366019
|
-
|
|
366020
|
-
|
|
366021
|
-
return
|
|
366278
|
+
const schematicAliases = pin ? getEasyEdaPinAliases(pin.label) : [];
|
|
366279
|
+
const hasNamedSchematicAlias = schematicAliases.some((alias) => !/^\d+$/.test(alias));
|
|
366280
|
+
return hasNamedSchematicAlias ? [...schematicAliases, ...padAliases] : [...padAliases, ...schematicAliases];
|
|
366022
366281
|
});
|
|
366023
366282
|
const padNumberKeys = pads.map((pad, index) => {
|
|
366024
366283
|
const padNumber = String(pad.number ?? "").trim();
|
|
@@ -366308,16 +366567,26 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
|
|
|
366308
366567
|
model_step_url: stepFileUrl
|
|
366309
366568
|
}));
|
|
366310
366569
|
}
|
|
366311
|
-
const hasExplicitCourtyard = circuitElements.some((e) => e.type === "pcb_courtyard_outline");
|
|
366570
|
+
const hasExplicitCourtyard = circuitElements.some((e) => e.type === "pcb_courtyard_outline" || e.type === "pcb_courtyard_rect");
|
|
366312
366571
|
if (!hasExplicitCourtyard) {
|
|
366313
366572
|
const bbox = easyEdaJson.packageDetail.dataStr.BBox;
|
|
366314
|
-
|
|
366573
|
+
const modelOutlineBounds = getCadModelOutlineBounds(svgNode);
|
|
366574
|
+
const packageElements = circuitElements.filter((element) => element.type === "pcb_smtpad" || element.type === "pcb_plated_hole" || element.type === "pcb_hole" || element.type === "pcb_via");
|
|
366575
|
+
const packageElementBounds = packageElements.length > 0 ? getBoundsOfPcbElements3(packageElements) : undefined;
|
|
366576
|
+
const fallbackBounds = bbox ? {
|
|
366577
|
+
minX: milx10(bbox.x),
|
|
366578
|
+
minY: milx10(bbox.y),
|
|
366579
|
+
maxX: milx10(bbox.x + bbox.width),
|
|
366580
|
+
maxY: milx10(bbox.y + bbox.height)
|
|
366581
|
+
} : undefined;
|
|
366582
|
+
const courtyardBounds = modelOutlineBounds ? unionBounds2(modelOutlineBounds, packageElementBounds) : fallbackBounds;
|
|
366583
|
+
if (courtyardBounds) {
|
|
366315
366584
|
const strokeWidth = 0.05;
|
|
366316
366585
|
const margin = 0.25;
|
|
366317
|
-
const x1 =
|
|
366318
|
-
const y1 =
|
|
366319
|
-
const x2 =
|
|
366320
|
-
const y2 =
|
|
366586
|
+
const x1 = courtyardBounds.minX - margin;
|
|
366587
|
+
const y1 = courtyardBounds.minY - margin;
|
|
366588
|
+
const x2 = courtyardBounds.maxX + margin;
|
|
366589
|
+
const y2 = courtyardBounds.maxY + margin;
|
|
366321
366590
|
circuitElements.push(pcb_courtyard_outline2.parse({
|
|
366322
366591
|
type: "pcb_courtyard_outline",
|
|
366323
366592
|
pcb_courtyard_outline_id: `pcb_courtyard_outline_${easyEdaJson.lcsc.number}_1`,
|
|
@@ -366848,19 +367117,10 @@ var PinShapeOutputSchema = external_exports2.object({
|
|
|
366848
367117
|
var parsePin = (pinString) => {
|
|
366849
367118
|
const parts = pinString.split("~");
|
|
366850
367119
|
const [, visibility, , pinNumber, x, y, rotation2, id] = parts;
|
|
366851
|
-
const
|
|
366852
|
-
let label =
|
|
366853
|
-
if (label.
|
|
366854
|
-
label =
|
|
366855
|
-
if (label.endsWith("-"))
|
|
366856
|
-
label = `${label.slice(0, -1)}_NEG`;
|
|
366857
|
-
label = normalizeActiveLowPinLabel(label);
|
|
366858
|
-
if (/^\+\d+(?:\.\d+)?V$/i.test(label))
|
|
366859
|
-
label = `V${label.slice(1, -1)}`;
|
|
366860
|
-
if (label.startsWith("+"))
|
|
366861
|
-
label = `${label.slice(1)}_POS`;
|
|
366862
|
-
if (label.startsWith("-"))
|
|
366863
|
-
label = `${label.slice(1)}_NEG`;
|
|
367120
|
+
const pinNameSection = pinString.split("^^")[3];
|
|
367121
|
+
let label = pinNameSection?.split("~")[4] ?? "";
|
|
367122
|
+
if (!label.includes("/"))
|
|
367123
|
+
label = normalizeEasyEdaPinLabel(label);
|
|
366864
367124
|
const colorMatch = pinString.match(/#[0-9A-F]{6}/);
|
|
366865
367125
|
const labelColor = colorMatch ? colorMatch[0] : "";
|
|
366866
367126
|
const path = pinString.split("^^")[2]?.split("~")[0] ?? "";
|
|
@@ -367350,6 +367610,14 @@ var getEasyEdaCadModelPlacement = async (easyEdaJson, { fetch: fetch2 = globalTh
|
|
|
367350
367610
|
placementCache.set(cacheKey, placementPromise);
|
|
367351
367611
|
return placementPromise;
|
|
367352
367612
|
};
|
|
367613
|
+
var normalizeSymbolName = (name) => {
|
|
367614
|
+
const trimmedName = name.trim();
|
|
367615
|
+
if (trimmedName === "+")
|
|
367616
|
+
return "_POS";
|
|
367617
|
+
if (trimmedName === "-")
|
|
367618
|
+
return "_NEG";
|
|
367619
|
+
return trimmedName.replace(/(?<=[A-Za-z0-9])-(?=[A-Za-z0-9])/g, "_");
|
|
367620
|
+
};
|
|
367353
367621
|
var round3 = (value) => Number(value.toFixed(6));
|
|
367354
367622
|
var EASYEDA_SCHEMATIC_UNIT_TO_TSCIRCUIT_UNIT = 0.02;
|
|
367355
367623
|
var toSchematicUnits = (value) => round3(value * EASYEDA_SCHEMATIC_UNIT_TO_TSCIRCUIT_UNIT);
|
|
@@ -367563,13 +367831,14 @@ var getPortMetadataByShapeId = (easyEdaJson, circuitJson) => {
|
|
|
367563
367831
|
portName ??= `pin${pinIndex + 1}`;
|
|
367564
367832
|
usedPortNames.add(portName);
|
|
367565
367833
|
const sourcePort = sourcePorts.find((port) => port.name === portName);
|
|
367834
|
+
let aliases = getEasyEdaPinAliases(pin.label);
|
|
367835
|
+
if (sourcePort?.port_hints?.length) {
|
|
367836
|
+
aliases = sourcePort.port_hints;
|
|
367837
|
+
}
|
|
367566
367838
|
metadataByShapeId.set(pin.id, {
|
|
367567
367839
|
name: portName,
|
|
367568
367840
|
pinNumber: sourcePort?.pin_number,
|
|
367569
|
-
aliases:
|
|
367570
|
-
...sourcePort?.port_hints ?? [],
|
|
367571
|
-
...pin.label ? [normalizeSymbolName(pin.label)] : []
|
|
367572
|
-
].filter((alias, index, aliases) => alias !== portName && aliases.indexOf(alias) === index)
|
|
367841
|
+
aliases: aliases.filter((alias, index, aliases2) => alias !== portName && aliases2.indexOf(alias) === index)
|
|
367573
367842
|
});
|
|
367574
367843
|
});
|
|
367575
367844
|
return metadataByShapeId;
|
|
@@ -367819,7 +368088,7 @@ var generateFootprintTsx2 = (circuitJson, options = {}) => {
|
|
|
367819
368088
|
</footprint>
|
|
367820
368089
|
`.trim();
|
|
367821
368090
|
};
|
|
367822
|
-
var POWER_PIN_LABEL = /^(?:VCC|VDD|VIN|VDDA)\d*$/;
|
|
368091
|
+
var POWER_PIN_LABEL = /^(?:VCC|VDD|VIN|VDDA|VBUS)\d*$/;
|
|
367823
368092
|
var GROUND_PIN_LABEL = /^(?:GND|VSS|PGND|AGND)\d*$/;
|
|
367824
368093
|
var NO_CONNECT_PIN_LABEL = /^NC\d*$/;
|
|
367825
368094
|
var getAttributeKind = (label) => {
|
|
@@ -368319,34 +368588,36 @@ var normalizeResistorValue = (value) => {
|
|
|
368319
368588
|
var isResistorComponent = (betterEasy) => {
|
|
368320
368589
|
const componentParameters = betterEasy.dataStr.head.c_para;
|
|
368321
368590
|
const packageName = componentParameters.package;
|
|
368322
|
-
|
|
368591
|
+
const hasResistorCategory = betterEasy.tags.some((tag) => /\bresistors?\b/i.test(tag));
|
|
368592
|
+
return (componentParameters.pre?.toUpperCase() === "R?" || hasResistorCategory) && typeof packageName === "string" && standardSmdResistorPackagePattern.test(packageName.trim()) && normalizeResistorValue(componentParameters.Value) !== undefined;
|
|
368323
368593
|
};
|
|
368324
|
-
var
|
|
368325
|
-
if (typeof
|
|
368326
|
-
|
|
368327
|
-
|
|
368328
|
-
|
|
368329
|
-
|
|
368330
|
-
return
|
|
368331
|
-
}
|
|
368332
|
-
if (Array.isArray(value)) {
|
|
368333
|
-
return value.some(categoryValueContainsSwitch);
|
|
368594
|
+
var getCategoryStrings = (category) => {
|
|
368595
|
+
if (typeof category === "string")
|
|
368596
|
+
return [category.toLowerCase()];
|
|
368597
|
+
if (Array.isArray(category))
|
|
368598
|
+
return category.flatMap(getCategoryStrings);
|
|
368599
|
+
if (category && typeof category === "object") {
|
|
368600
|
+
return Object.values(category).flatMap(getCategoryStrings);
|
|
368334
368601
|
}
|
|
368335
|
-
|
|
368336
|
-
|
|
368602
|
+
return [];
|
|
368603
|
+
};
|
|
368604
|
+
var categoryValueContainsSwitch = (category) => {
|
|
368605
|
+
const categoryStrings = getCategoryStrings(category);
|
|
368606
|
+
if (categoryStrings.some((category2) => /analog[\s-]+switch/.test(category2) || /multiplex/.test(category2) || /switching\s+diodes?/.test(category2) || /\bics?\b/.test(category2) || /\b(?:power[\s-]+distribution|load)[\s-]+switch(?:es)?\b/.test(category2))) {
|
|
368607
|
+
return false;
|
|
368337
368608
|
}
|
|
368338
|
-
return
|
|
368609
|
+
return categoryStrings.some((category2) => /(?:slide|toggle|dip|key|micro|limit)\s+switch(?:es)?/.test(category2) || /(^|[^a-z])switch(?:es)?([^a-z]|$)/.test(category2));
|
|
368339
368610
|
};
|
|
368340
368611
|
var isSwitchCategoryComponent = (betterEasy) => {
|
|
368341
368612
|
const cPara = betterEasy.dataStr.head.c_para;
|
|
368342
|
-
return [
|
|
368613
|
+
return categoryValueContainsSwitch([
|
|
368343
368614
|
betterEasy.tags,
|
|
368344
368615
|
cPara.category,
|
|
368345
368616
|
cPara.Category,
|
|
368346
368617
|
cPara["LCSC Category"],
|
|
368347
368618
|
cPara["JLCPCB Category"],
|
|
368348
368619
|
betterEasy.category
|
|
368349
|
-
]
|
|
368620
|
+
]);
|
|
368350
368621
|
};
|
|
368351
368622
|
var getGeneratedComponentType = (betterEasy, pinCount) => {
|
|
368352
368623
|
if (isLedCategoryComponent(betterEasy) && pinCount === 2)
|
|
@@ -368881,6 +369152,116 @@ var __export6 = (target, all) => {
|
|
|
368881
369152
|
for (var name in all)
|
|
368882
369153
|
__defProp7(target, name, { get: all[name], enumerable: true });
|
|
368883
369154
|
};
|
|
369155
|
+
var normalizeActiveLowPinLabel2 = (label) => {
|
|
369156
|
+
const hasActiveLowMarker = label.startsWith("#") || label.endsWith("#");
|
|
369157
|
+
if (!hasActiveLowMarker)
|
|
369158
|
+
return label;
|
|
369159
|
+
const activeLowLabel = label.replace(/^#/, "").replace(/#$/, "");
|
|
369160
|
+
if (activeLowLabel.length === 0)
|
|
369161
|
+
return label;
|
|
369162
|
+
if (activeLowLabel.startsWith("N_"))
|
|
369163
|
+
return activeLowLabel;
|
|
369164
|
+
return `N_${activeLowLabel}`;
|
|
369165
|
+
};
|
|
369166
|
+
var normalizePinLabels2 = (inputPinLabels) => {
|
|
369167
|
+
const normalizedInputPinLabels = inputPinLabels.map((labels) => labels.map(normalizeActiveLowPinLabel2));
|
|
369168
|
+
const uniqueInputPinLabels = normalizedInputPinLabels.map((labels) => [
|
|
369169
|
+
...new Set(labels)
|
|
369170
|
+
]);
|
|
369171
|
+
const result = uniqueInputPinLabels.map(() => []);
|
|
369172
|
+
const desiredNumbers = uniqueInputPinLabels.map(() => null);
|
|
369173
|
+
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
369174
|
+
for (const label of uniqueInputPinLabels[i]) {
|
|
369175
|
+
if (/^\d+$/.test(label)) {
|
|
369176
|
+
desiredNumbers[i] = Number.parseInt(label);
|
|
369177
|
+
break;
|
|
369178
|
+
}
|
|
369179
|
+
}
|
|
369180
|
+
}
|
|
369181
|
+
let highestPinNumber = 0;
|
|
369182
|
+
const acceptedDesiredNumbers = /* @__PURE__ */ new Set;
|
|
369183
|
+
for (let i = 0;i < desiredNumbers.length; i++) {
|
|
369184
|
+
const desiredNumber = desiredNumbers[i];
|
|
369185
|
+
if (desiredNumber === null || desiredNumber < 1)
|
|
369186
|
+
continue;
|
|
369187
|
+
if (!acceptedDesiredNumbers.has(desiredNumber)) {
|
|
369188
|
+
acceptedDesiredNumbers.add(desiredNumber);
|
|
369189
|
+
result[i].push(`pin${desiredNumber}`);
|
|
369190
|
+
highestPinNumber = Math.max(highestPinNumber, desiredNumber);
|
|
369191
|
+
continue;
|
|
369192
|
+
}
|
|
369193
|
+
let existingAltCount = 0;
|
|
369194
|
+
for (const label of result[i]) {
|
|
369195
|
+
if (label.startsWith(`pin${desiredNumber}_alt`)) {
|
|
369196
|
+
existingAltCount += 1;
|
|
369197
|
+
}
|
|
369198
|
+
}
|
|
369199
|
+
result[i].push(`pin${desiredNumber}_alt${existingAltCount + 1}`);
|
|
369200
|
+
}
|
|
369201
|
+
for (let i = 0;i < result.length; i++) {
|
|
369202
|
+
const firstLabel = result[i][0];
|
|
369203
|
+
if (firstLabel?.includes("_alt")) {
|
|
369204
|
+
highestPinNumber += 1;
|
|
369205
|
+
result[i].unshift(`pin${highestPinNumber}`);
|
|
369206
|
+
}
|
|
369207
|
+
}
|
|
369208
|
+
for (let i = 0;i < result.length; i++) {
|
|
369209
|
+
if (result[i].length === 0) {
|
|
369210
|
+
highestPinNumber += 1;
|
|
369211
|
+
result[i].push(`pin${highestPinNumber}`);
|
|
369212
|
+
}
|
|
369213
|
+
}
|
|
369214
|
+
const totalLabelCounts = {};
|
|
369215
|
+
for (const inputLabels of uniqueInputPinLabels) {
|
|
369216
|
+
for (const label of inputLabels) {
|
|
369217
|
+
if (/^\d+$/.test(label))
|
|
369218
|
+
continue;
|
|
369219
|
+
totalLabelCounts[label] = (totalLabelCounts[label] ?? 0) + 1;
|
|
369220
|
+
}
|
|
369221
|
+
}
|
|
369222
|
+
const incrementalLabelCounts = {};
|
|
369223
|
+
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
369224
|
+
for (const label of uniqueInputPinLabels[i]) {
|
|
369225
|
+
if (/^\d+$/.test(label))
|
|
369226
|
+
continue;
|
|
369227
|
+
if (totalLabelCounts[label] === 1) {
|
|
369228
|
+
result[i].push(label);
|
|
369229
|
+
} else {
|
|
369230
|
+
incrementalLabelCounts[label] = (incrementalLabelCounts[label] ?? 0) + 1;
|
|
369231
|
+
result[i].push(`${label}${incrementalLabelCounts[label]}`);
|
|
369232
|
+
}
|
|
369233
|
+
}
|
|
369234
|
+
}
|
|
369235
|
+
return result;
|
|
369236
|
+
};
|
|
369237
|
+
var normalizeEasyEdaPinLabel2 = (label) => {
|
|
369238
|
+
if (label.endsWith("+"))
|
|
369239
|
+
label = `${label.slice(0, -1)}_POS`;
|
|
369240
|
+
if (/[-–−]$/.test(label))
|
|
369241
|
+
label = `${label.slice(0, -1)}_NEG`;
|
|
369242
|
+
label = normalizeActiveLowPinLabel2(label);
|
|
369243
|
+
if (/^\+\d+(?:\.\d+)?V$/i.test(label))
|
|
369244
|
+
label = `V${label.slice(1, -1)}`;
|
|
369245
|
+
if (label.startsWith("+"))
|
|
369246
|
+
label = `${label.slice(1)}_POS`;
|
|
369247
|
+
if (/^[-–−]/.test(label))
|
|
369248
|
+
label = `${label.slice(1)}_NEG`;
|
|
369249
|
+
return label;
|
|
369250
|
+
};
|
|
369251
|
+
var getEasyEdaPinAliases2 = (label) => {
|
|
369252
|
+
label = label.replace(/&#(x[0-9a-f]+|[0-9]+);/gi, (entity, code) => {
|
|
369253
|
+
let codePoint = Number(code);
|
|
369254
|
+
if (/^x/i.test(code))
|
|
369255
|
+
codePoint = Number.parseInt(code.slice(1), 16);
|
|
369256
|
+
const maximumUnicodeCodePoint = 1114111;
|
|
369257
|
+
if (codePoint > maximumUnicodeCodePoint)
|
|
369258
|
+
return entity;
|
|
369259
|
+
return String.fromCodePoint(codePoint);
|
|
369260
|
+
});
|
|
369261
|
+
if (label.includes("/") && !/[a-zA-Z0-9]/.test(label))
|
|
369262
|
+
return [];
|
|
369263
|
+
return label.split("/").map((alias) => normalizeEasyEdaPinLabel2(alias.trim()).replace(/[`′]/g, "_PRIME").replace(/^[()]+|[()]+$/g, "").replace(/[^a-zA-Z0-9_]/g, "_")).filter((alias) => /[a-zA-Z0-9]/.test(alias));
|
|
369264
|
+
};
|
|
368884
369265
|
function orientation4(p, q, r) {
|
|
368885
369266
|
const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
368886
369267
|
if (val === 0)
|
|
@@ -374319,6 +374700,208 @@ var transformPCBElements3 = (elms, matrix) => {
|
|
|
374319
374700
|
}
|
|
374320
374701
|
return transformedElms;
|
|
374321
374702
|
};
|
|
374703
|
+
var mergeBounds5 = (currentBounds, nextBounds) => ({
|
|
374704
|
+
minX: Math.min(currentBounds.minX, nextBounds.minX),
|
|
374705
|
+
minY: Math.min(currentBounds.minY, nextBounds.minY),
|
|
374706
|
+
maxX: Math.max(currentBounds.maxX, nextBounds.maxX),
|
|
374707
|
+
maxY: Math.max(currentBounds.maxY, nextBounds.maxY)
|
|
374708
|
+
});
|
|
374709
|
+
var getCircleBounds3 = (x, y, diameter) => {
|
|
374710
|
+
const radius = diameter / 2;
|
|
374711
|
+
return {
|
|
374712
|
+
minX: x - radius,
|
|
374713
|
+
minY: y - radius,
|
|
374714
|
+
maxX: x + radius,
|
|
374715
|
+
maxY: y + radius
|
|
374716
|
+
};
|
|
374717
|
+
};
|
|
374718
|
+
var getRotatedRectBounds3 = (x, y, width, height, rotationDegrees) => {
|
|
374719
|
+
const halfWidth = width / 2;
|
|
374720
|
+
const halfHeight = height / 2;
|
|
374721
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
374722
|
+
const cosTheta = Math.cos(theta);
|
|
374723
|
+
const sinTheta = Math.sin(theta);
|
|
374724
|
+
const corners = [
|
|
374725
|
+
{ x: -halfWidth, y: -halfHeight },
|
|
374726
|
+
{ x: halfWidth, y: -halfHeight },
|
|
374727
|
+
{ x: halfWidth, y: halfHeight },
|
|
374728
|
+
{ x: -halfWidth, y: halfHeight }
|
|
374729
|
+
].map((corner) => ({
|
|
374730
|
+
x: x + corner.x * cosTheta - corner.y * sinTheta,
|
|
374731
|
+
y: y + corner.x * sinTheta + corner.y * cosTheta
|
|
374732
|
+
}));
|
|
374733
|
+
return {
|
|
374734
|
+
minX: Math.min(...corners.map((corner) => corner.x)),
|
|
374735
|
+
minY: Math.min(...corners.map((corner) => corner.y)),
|
|
374736
|
+
maxX: Math.max(...corners.map((corner) => corner.x)),
|
|
374737
|
+
maxY: Math.max(...corners.map((corner) => corner.y))
|
|
374738
|
+
};
|
|
374739
|
+
};
|
|
374740
|
+
var getRotatedOvalBounds2 = (x, y, width, height, rotationDegrees) => {
|
|
374741
|
+
const radiusX = width / 2;
|
|
374742
|
+
const radiusY = height / 2;
|
|
374743
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
374744
|
+
const cosTheta = Math.cos(theta);
|
|
374745
|
+
const sinTheta = Math.sin(theta);
|
|
374746
|
+
const halfWidth = Math.hypot(radiusX * cosTheta, radiusY * sinTheta);
|
|
374747
|
+
const halfHeight = Math.hypot(radiusX * sinTheta, radiusY * cosTheta);
|
|
374748
|
+
return {
|
|
374749
|
+
minX: x - halfWidth,
|
|
374750
|
+
minY: y - halfHeight,
|
|
374751
|
+
maxX: x + halfWidth,
|
|
374752
|
+
maxY: y + halfHeight
|
|
374753
|
+
};
|
|
374754
|
+
};
|
|
374755
|
+
var getRotatedPillBounds2 = (x, y, width, height, rotationDegrees) => {
|
|
374756
|
+
const radius = Math.min(width, height) / 2;
|
|
374757
|
+
const halfLineLength = Math.max(width, height) / 2 - radius;
|
|
374758
|
+
const theta = rotationDegrees * Math.PI / 180;
|
|
374759
|
+
const axis = width >= height ? { x: halfLineLength, y: 0 } : { x: 0, y: halfLineLength };
|
|
374760
|
+
const rotatedAxis = {
|
|
374761
|
+
x: axis.x * Math.cos(theta) - axis.y * Math.sin(theta),
|
|
374762
|
+
y: axis.x * Math.sin(theta) + axis.y * Math.cos(theta)
|
|
374763
|
+
};
|
|
374764
|
+
const halfWidth = Math.abs(rotatedAxis.x) + radius;
|
|
374765
|
+
const halfHeight = Math.abs(rotatedAxis.y) + radius;
|
|
374766
|
+
return {
|
|
374767
|
+
minX: x - halfWidth,
|
|
374768
|
+
minY: y - halfHeight,
|
|
374769
|
+
maxX: x + halfWidth,
|
|
374770
|
+
maxY: y + halfHeight
|
|
374771
|
+
};
|
|
374772
|
+
};
|
|
374773
|
+
var getBoundsFromPoints24 = (points) => {
|
|
374774
|
+
if (points.length === 0)
|
|
374775
|
+
return null;
|
|
374776
|
+
return {
|
|
374777
|
+
minX: Math.min(...points.map((point2) => point2.x)),
|
|
374778
|
+
minY: Math.min(...points.map((point2) => point2.y)),
|
|
374779
|
+
maxX: Math.max(...points.map((point2) => point2.x)),
|
|
374780
|
+
maxY: Math.max(...points.map((point2) => point2.y))
|
|
374781
|
+
};
|
|
374782
|
+
};
|
|
374783
|
+
var getRoutePoints2 = (route) => {
|
|
374784
|
+
if (!Array.isArray(route))
|
|
374785
|
+
return [];
|
|
374786
|
+
return route.flatMap((point2) => {
|
|
374787
|
+
if (!point2 || typeof point2 !== "object")
|
|
374788
|
+
return [];
|
|
374789
|
+
if ("x" in point2 && "y" in point2 && typeof point2.x === "number" && typeof point2.y === "number") {
|
|
374790
|
+
return [{ x: point2.x, y: point2.y }];
|
|
374791
|
+
}
|
|
374792
|
+
if ("start" in point2 && "end" in point2) {
|
|
374793
|
+
const positions = [point2.start, point2.end];
|
|
374794
|
+
return positions.filter((position2) => Boolean(position2 && typeof position2 === "object" && "x" in position2 && "y" in position2 && typeof position2.x === "number" && typeof position2.y === "number"));
|
|
374795
|
+
}
|
|
374796
|
+
return [];
|
|
374797
|
+
});
|
|
374798
|
+
};
|
|
374799
|
+
var getPcbElementBounds2 = (elm) => {
|
|
374800
|
+
if (!elm.type.startsWith("pcb_"))
|
|
374801
|
+
return null;
|
|
374802
|
+
if (elm.type === "pcb_smtpad" && elm.shape === "polygon" && Array.isArray(elm.points)) {
|
|
374803
|
+
return getBoundsFromPoints24(elm.points);
|
|
374804
|
+
}
|
|
374805
|
+
if (elm.type === "pcb_hole" && elm.hole_shape === "circle") {
|
|
374806
|
+
return getCircleBounds3(elm.x, elm.y, elm.hole_diameter);
|
|
374807
|
+
}
|
|
374808
|
+
if (elm.type === "pcb_plated_hole") {
|
|
374809
|
+
let platedHoleBounds;
|
|
374810
|
+
if ("outer_diameter" in elm && typeof elm.outer_diameter === "number") {
|
|
374811
|
+
platedHoleBounds = getCircleBounds3(elm.x, elm.y, elm.outer_diameter);
|
|
374812
|
+
} else if ("hole_diameter" in elm && typeof elm.hole_diameter === "number") {
|
|
374813
|
+
platedHoleBounds = getCircleBounds3(elm.x, elm.y, elm.hole_diameter);
|
|
374814
|
+
}
|
|
374815
|
+
if ((elm.shape === "oval" || elm.shape === "pill") && typeof elm.outer_width === "number" && typeof elm.outer_height === "number") {
|
|
374816
|
+
const getOuterBounds = elm.shape === "pill" ? getRotatedPillBounds2 : getRotatedOvalBounds2;
|
|
374817
|
+
platedHoleBounds = getOuterBounds(elm.x, elm.y, elm.outer_width, elm.outer_height, elm.ccw_rotation ?? 0);
|
|
374818
|
+
}
|
|
374819
|
+
if ("rect_pad_width" in elm && typeof elm.rect_pad_width === "number" && "rect_pad_height" in elm && typeof elm.rect_pad_height === "number") {
|
|
374820
|
+
const rectBounds = getRotatedRectBounds3(elm.x, elm.y, elm.rect_pad_width, elm.rect_pad_height, "rect_ccw_rotation" in elm ? elm.rect_ccw_rotation ?? 0 : 0);
|
|
374821
|
+
platedHoleBounds = platedHoleBounds ? mergeBounds5(platedHoleBounds, rectBounds) : rectBounds;
|
|
374822
|
+
}
|
|
374823
|
+
if ("hole_diameter" in elm && typeof elm.hole_diameter === "number") {
|
|
374824
|
+
const drillBounds = getCircleBounds3(elm.x + ("hole_offset_x" in elm ? elm.hole_offset_x ?? 0 : 0), elm.y + ("hole_offset_y" in elm ? elm.hole_offset_y ?? 0 : 0), elm.hole_diameter);
|
|
374825
|
+
platedHoleBounds = platedHoleBounds ? mergeBounds5(platedHoleBounds, drillBounds) : drillBounds;
|
|
374826
|
+
}
|
|
374827
|
+
if (platedHoleBounds)
|
|
374828
|
+
return platedHoleBounds;
|
|
374829
|
+
}
|
|
374830
|
+
const elementRecord = elm;
|
|
374831
|
+
const routeBounds = getBoundsFromPoints24(getRoutePoints2(elementRecord.route));
|
|
374832
|
+
if (routeBounds)
|
|
374833
|
+
return routeBounds;
|
|
374834
|
+
const outlineBounds = getBoundsFromPoints24(getRoutePoints2(elementRecord.outline));
|
|
374835
|
+
if (outlineBounds)
|
|
374836
|
+
return outlineBounds;
|
|
374837
|
+
const pointsBounds = getBoundsFromPoints24(getRoutePoints2(elementRecord.points));
|
|
374838
|
+
if (pointsBounds)
|
|
374839
|
+
return pointsBounds;
|
|
374840
|
+
let centerX;
|
|
374841
|
+
let centerY;
|
|
374842
|
+
let width;
|
|
374843
|
+
let height;
|
|
374844
|
+
if ("x" in elm && "y" in elm) {
|
|
374845
|
+
centerX = Number(elm.x);
|
|
374846
|
+
centerY = Number(elm.y);
|
|
374847
|
+
}
|
|
374848
|
+
if ("outer_diameter" in elm) {
|
|
374849
|
+
width = Number(elm.outer_diameter);
|
|
374850
|
+
height = Number(elm.outer_diameter);
|
|
374851
|
+
}
|
|
374852
|
+
if ("width" in elm) {
|
|
374853
|
+
width = Number(elm.width);
|
|
374854
|
+
}
|
|
374855
|
+
if ("height" in elm) {
|
|
374856
|
+
height = Number(elm.height);
|
|
374857
|
+
}
|
|
374858
|
+
if ("center" in elm && elm.center && typeof elm.center === "object" && "x" in elm.center && "y" in elm.center) {
|
|
374859
|
+
centerX = Number(elm.center.x);
|
|
374860
|
+
centerY = Number(elm.center.y);
|
|
374861
|
+
}
|
|
374862
|
+
let rotation2 = 0;
|
|
374863
|
+
if ("rotation" in elm && typeof elm.rotation === "number") {
|
|
374864
|
+
rotation2 = elm.rotation;
|
|
374865
|
+
}
|
|
374866
|
+
if ("ccw_rotation" in elm && typeof elm.ccw_rotation === "number") {
|
|
374867
|
+
rotation2 = elm.ccw_rotation;
|
|
374868
|
+
}
|
|
374869
|
+
if (centerX !== undefined && centerY !== undefined) {
|
|
374870
|
+
if (width !== undefined && height !== undefined) {
|
|
374871
|
+
return rotation2 ? getRotatedRectBounds3(centerX, centerY, width, height, rotation2) : {
|
|
374872
|
+
minX: centerX - width / 2,
|
|
374873
|
+
minY: centerY - height / 2,
|
|
374874
|
+
maxX: centerX + width / 2,
|
|
374875
|
+
maxY: centerY + height / 2
|
|
374876
|
+
};
|
|
374877
|
+
}
|
|
374878
|
+
if ("radius" in elm && typeof elm.radius === "number") {
|
|
374879
|
+
return getCircleBounds3(centerX, centerY, elm.radius * 2);
|
|
374880
|
+
}
|
|
374881
|
+
return { minX: centerX, minY: centerY, maxX: centerX, maxY: centerY };
|
|
374882
|
+
}
|
|
374883
|
+
const anchoredPoint = [elementRecord.anchor_position, elementRecord.position].filter((position2) => Boolean(position2 && typeof position2 === "object" && "x" in position2 && "y" in position2 && typeof position2.x === "number" && typeof position2.y === "number")).at(0);
|
|
374884
|
+
return anchoredPoint ? {
|
|
374885
|
+
minX: anchoredPoint.x,
|
|
374886
|
+
minY: anchoredPoint.y,
|
|
374887
|
+
maxX: anchoredPoint.x,
|
|
374888
|
+
maxY: anchoredPoint.y
|
|
374889
|
+
} : null;
|
|
374890
|
+
};
|
|
374891
|
+
var getBoundsOfPcbElements4 = (elements) => {
|
|
374892
|
+
let bounds = {
|
|
374893
|
+
minX: Number.POSITIVE_INFINITY,
|
|
374894
|
+
minY: Number.POSITIVE_INFINITY,
|
|
374895
|
+
maxX: Number.NEGATIVE_INFINITY,
|
|
374896
|
+
maxY: Number.NEGATIVE_INFINITY
|
|
374897
|
+
};
|
|
374898
|
+
for (const element of elements) {
|
|
374899
|
+
const elementBounds = getPcbElementBounds2(element);
|
|
374900
|
+
if (elementBounds)
|
|
374901
|
+
bounds = mergeBounds5(bounds, elementBounds);
|
|
374902
|
+
}
|
|
374903
|
+
return bounds;
|
|
374904
|
+
};
|
|
374322
374905
|
function stringHash4(str) {
|
|
374323
374906
|
let hash = 0;
|
|
374324
374907
|
if (str.length == 0)
|
|
@@ -374692,96 +375275,6 @@ var getPolarizedPinMetadata2 = (pinLabels) => {
|
|
|
374692
375275
|
pinLabels: Object.fromEntries(polarizedPinEntries)
|
|
374693
375276
|
};
|
|
374694
375277
|
};
|
|
374695
|
-
var normalizeActiveLowPinLabel2 = (label) => {
|
|
374696
|
-
const hasActiveLowMarker = label.startsWith("#") || label.endsWith("#");
|
|
374697
|
-
if (!hasActiveLowMarker)
|
|
374698
|
-
return label;
|
|
374699
|
-
const activeLowLabel = label.replace(/^#/, "").replace(/#$/, "");
|
|
374700
|
-
if (activeLowLabel.length === 0)
|
|
374701
|
-
return label;
|
|
374702
|
-
if (activeLowLabel.startsWith("N_"))
|
|
374703
|
-
return activeLowLabel;
|
|
374704
|
-
return `N_${activeLowLabel}`;
|
|
374705
|
-
};
|
|
374706
|
-
var normalizePinLabels2 = (inputPinLabels) => {
|
|
374707
|
-
const normalizedInputPinLabels = inputPinLabels.map((labels) => labels.map(normalizeActiveLowPinLabel2));
|
|
374708
|
-
const uniqueInputPinLabels = normalizedInputPinLabels.map((labels) => [
|
|
374709
|
-
...new Set(labels)
|
|
374710
|
-
]);
|
|
374711
|
-
const result = uniqueInputPinLabels.map(() => []);
|
|
374712
|
-
const desiredNumbers = uniqueInputPinLabels.map(() => null);
|
|
374713
|
-
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
374714
|
-
for (const label of uniqueInputPinLabels[i]) {
|
|
374715
|
-
if (/^\d+$/.test(label)) {
|
|
374716
|
-
desiredNumbers[i] = Number.parseInt(label);
|
|
374717
|
-
break;
|
|
374718
|
-
}
|
|
374719
|
-
}
|
|
374720
|
-
}
|
|
374721
|
-
let highestPinNumber = 0;
|
|
374722
|
-
const acceptedDesiredNumbers = /* @__PURE__ */ new Set;
|
|
374723
|
-
for (let i = 0;i < desiredNumbers.length; i++) {
|
|
374724
|
-
const desiredNumber = desiredNumbers[i];
|
|
374725
|
-
if (desiredNumber === null || desiredNumber < 1)
|
|
374726
|
-
continue;
|
|
374727
|
-
if (!acceptedDesiredNumbers.has(desiredNumber)) {
|
|
374728
|
-
acceptedDesiredNumbers.add(desiredNumber);
|
|
374729
|
-
result[i].push(`pin${desiredNumber}`);
|
|
374730
|
-
highestPinNumber = Math.max(highestPinNumber, desiredNumber);
|
|
374731
|
-
continue;
|
|
374732
|
-
}
|
|
374733
|
-
let existingAltCount = 0;
|
|
374734
|
-
for (const label of result[i]) {
|
|
374735
|
-
if (label.startsWith(`pin${desiredNumber}_alt`)) {
|
|
374736
|
-
existingAltCount += 1;
|
|
374737
|
-
}
|
|
374738
|
-
}
|
|
374739
|
-
result[i].push(`pin${desiredNumber}_alt${existingAltCount + 1}`);
|
|
374740
|
-
}
|
|
374741
|
-
for (let i = 0;i < result.length; i++) {
|
|
374742
|
-
const firstLabel = result[i][0];
|
|
374743
|
-
if (firstLabel?.includes("_alt")) {
|
|
374744
|
-
highestPinNumber += 1;
|
|
374745
|
-
result[i].unshift(`pin${highestPinNumber}`);
|
|
374746
|
-
}
|
|
374747
|
-
}
|
|
374748
|
-
for (let i = 0;i < result.length; i++) {
|
|
374749
|
-
if (result[i].length === 0) {
|
|
374750
|
-
highestPinNumber += 1;
|
|
374751
|
-
result[i].push(`pin${highestPinNumber}`);
|
|
374752
|
-
}
|
|
374753
|
-
}
|
|
374754
|
-
const totalLabelCounts = {};
|
|
374755
|
-
for (const inputLabels of uniqueInputPinLabels) {
|
|
374756
|
-
for (const label of inputLabels) {
|
|
374757
|
-
if (/^\d+$/.test(label))
|
|
374758
|
-
continue;
|
|
374759
|
-
totalLabelCounts[label] = (totalLabelCounts[label] ?? 0) + 1;
|
|
374760
|
-
}
|
|
374761
|
-
}
|
|
374762
|
-
const incrementalLabelCounts = {};
|
|
374763
|
-
for (let i = 0;i < uniqueInputPinLabels.length; i++) {
|
|
374764
|
-
for (const label of uniqueInputPinLabels[i]) {
|
|
374765
|
-
if (/^\d+$/.test(label))
|
|
374766
|
-
continue;
|
|
374767
|
-
if (totalLabelCounts[label] === 1) {
|
|
374768
|
-
result[i].push(label);
|
|
374769
|
-
} else {
|
|
374770
|
-
incrementalLabelCounts[label] = (incrementalLabelCounts[label] ?? 0) + 1;
|
|
374771
|
-
result[i].push(`${label}${incrementalLabelCounts[label]}`);
|
|
374772
|
-
}
|
|
374773
|
-
}
|
|
374774
|
-
}
|
|
374775
|
-
return result;
|
|
374776
|
-
};
|
|
374777
|
-
var normalizeSymbolName2 = (name) => {
|
|
374778
|
-
const trimmedName = name.trim();
|
|
374779
|
-
if (trimmedName === "+")
|
|
374780
|
-
return "_POS";
|
|
374781
|
-
if (trimmedName === "-")
|
|
374782
|
-
return "_NEG";
|
|
374783
|
-
return trimmedName.replace(/(?<=[A-Za-z0-9])-(?=[A-Za-z0-9])/g, "_");
|
|
374784
|
-
};
|
|
374785
375278
|
var categoryValueContainsDiode2 = (value) => {
|
|
374786
375279
|
if (typeof value === "string") {
|
|
374787
375280
|
return /(^|[^a-z])diodes?([^a-z]|$)/i.test(value);
|
|
@@ -374950,6 +375443,45 @@ var parseCadOffsetsFromSvgNode2 = (svgNode) => {
|
|
|
374950
375443
|
})()
|
|
374951
375444
|
};
|
|
374952
375445
|
};
|
|
375446
|
+
var getCadModelOutlineBounds2 = (svgNode) => {
|
|
375447
|
+
const points = [];
|
|
375448
|
+
for (const childNode of svgNode?.svgData.childNodes ?? []) {
|
|
375449
|
+
if (typeof childNode !== "object" || childNode === null)
|
|
375450
|
+
continue;
|
|
375451
|
+
const attrs = childNode.attrs;
|
|
375452
|
+
if (typeof attrs !== "object" || attrs === null)
|
|
375453
|
+
continue;
|
|
375454
|
+
const rawPoints = attrs.points;
|
|
375455
|
+
if (typeof rawPoints !== "string")
|
|
375456
|
+
continue;
|
|
375457
|
+
const coordinates = rawPoints.trim().split(/\s+/).map(Number);
|
|
375458
|
+
for (let index = 0;index + 1 < coordinates.length; index += 2) {
|
|
375459
|
+
const x = coordinates[index];
|
|
375460
|
+
const y = coordinates[index + 1];
|
|
375461
|
+
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
375462
|
+
continue;
|
|
375463
|
+
points.push({ x: milx102(x), y: milx102(y) });
|
|
375464
|
+
}
|
|
375465
|
+
}
|
|
375466
|
+
if (points.length === 0)
|
|
375467
|
+
return;
|
|
375468
|
+
return {
|
|
375469
|
+
minX: Math.min(...points.map((point2) => point2.x)),
|
|
375470
|
+
minY: Math.min(...points.map((point2) => point2.y)),
|
|
375471
|
+
maxX: Math.max(...points.map((point2) => point2.x)),
|
|
375472
|
+
maxY: Math.max(...points.map((point2) => point2.y))
|
|
375473
|
+
};
|
|
375474
|
+
};
|
|
375475
|
+
var unionBounds3 = (first, second) => {
|
|
375476
|
+
if (!second)
|
|
375477
|
+
return first;
|
|
375478
|
+
return {
|
|
375479
|
+
minX: Math.min(first.minX, second.minX),
|
|
375480
|
+
minY: Math.min(first.minY, second.minY),
|
|
375481
|
+
maxX: Math.max(first.maxX, second.maxX),
|
|
375482
|
+
maxY: Math.max(first.maxY, second.maxY)
|
|
375483
|
+
};
|
|
375484
|
+
};
|
|
374953
375485
|
var readModelHeightMm2 = (raw) => {
|
|
374954
375486
|
const fallback = 3.5;
|
|
374955
375487
|
if (raw == null)
|
|
@@ -375190,13 +375722,11 @@ var convertEasyEdaJsonToCircuitJson2 = (easyEdaJson, {
|
|
|
375190
375722
|
const pads = easyEdaJson.packageDetail.dataStr.shape.filter((shape) => shape.type === "PAD");
|
|
375191
375723
|
const pins = easyEdaJson.dataStr.shape.filter((shape) => shape.type === "PIN");
|
|
375192
375724
|
const pinLabelSets = pads.map((pad) => {
|
|
375193
|
-
const
|
|
375194
|
-
if (pad.number)
|
|
375195
|
-
labels.push(pad.number.toString());
|
|
375725
|
+
const padAliases = pad.number ? getEasyEdaPinAliases2(pad.number.toString()) : [];
|
|
375196
375726
|
const pin = pins.find((p) => p.pinNumber === pad.number);
|
|
375197
|
-
|
|
375198
|
-
|
|
375199
|
-
return
|
|
375727
|
+
const schematicAliases = pin ? getEasyEdaPinAliases2(pin.label) : [];
|
|
375728
|
+
const hasNamedSchematicAlias = schematicAliases.some((alias) => !/^\d+$/.test(alias));
|
|
375729
|
+
return hasNamedSchematicAlias ? [...schematicAliases, ...padAliases] : [...padAliases, ...schematicAliases];
|
|
375200
375730
|
});
|
|
375201
375731
|
const padNumberKeys = pads.map((pad, index) => {
|
|
375202
375732
|
const padNumber = String(pad.number ?? "").trim();
|
|
@@ -375486,16 +376016,26 @@ var convertEasyEdaJsonToCircuitJson2 = (easyEdaJson, {
|
|
|
375486
376016
|
model_step_url: stepFileUrl
|
|
375487
376017
|
}));
|
|
375488
376018
|
}
|
|
375489
|
-
const hasExplicitCourtyard = circuitElements.some((e) => e.type === "pcb_courtyard_outline");
|
|
376019
|
+
const hasExplicitCourtyard = circuitElements.some((e) => e.type === "pcb_courtyard_outline" || e.type === "pcb_courtyard_rect");
|
|
375490
376020
|
if (!hasExplicitCourtyard) {
|
|
375491
376021
|
const bbox = easyEdaJson.packageDetail.dataStr.BBox;
|
|
375492
|
-
|
|
376022
|
+
const modelOutlineBounds = getCadModelOutlineBounds2(svgNode);
|
|
376023
|
+
const packageElements = circuitElements.filter((element) => element.type === "pcb_smtpad" || element.type === "pcb_plated_hole" || element.type === "pcb_hole" || element.type === "pcb_via");
|
|
376024
|
+
const packageElementBounds = packageElements.length > 0 ? getBoundsOfPcbElements4(packageElements) : undefined;
|
|
376025
|
+
const fallbackBounds = bbox ? {
|
|
376026
|
+
minX: milx102(bbox.x),
|
|
376027
|
+
minY: milx102(bbox.y),
|
|
376028
|
+
maxX: milx102(bbox.x + bbox.width),
|
|
376029
|
+
maxY: milx102(bbox.y + bbox.height)
|
|
376030
|
+
} : undefined;
|
|
376031
|
+
const courtyardBounds = modelOutlineBounds ? unionBounds3(modelOutlineBounds, packageElementBounds) : fallbackBounds;
|
|
376032
|
+
if (courtyardBounds) {
|
|
375493
376033
|
const strokeWidth = 0.05;
|
|
375494
376034
|
const margin = 0.25;
|
|
375495
|
-
const x1 =
|
|
375496
|
-
const y1 =
|
|
375497
|
-
const x2 =
|
|
375498
|
-
const y2 =
|
|
376035
|
+
const x1 = courtyardBounds.minX - margin;
|
|
376036
|
+
const y1 = courtyardBounds.minY - margin;
|
|
376037
|
+
const x2 = courtyardBounds.maxX + margin;
|
|
376038
|
+
const y2 = courtyardBounds.maxY + margin;
|
|
375499
376039
|
circuitElements.push(pcb_courtyard_outline3.parse({
|
|
375500
376040
|
type: "pcb_courtyard_outline",
|
|
375501
376041
|
pcb_courtyard_outline_id: `pcb_courtyard_outline_${easyEdaJson.lcsc.number}_1`,
|
|
@@ -376048,19 +376588,10 @@ var PinShapeOutputSchema2 = z201.object({
|
|
|
376048
376588
|
var parsePin2 = (pinString) => {
|
|
376049
376589
|
const parts = pinString.split("~");
|
|
376050
376590
|
const [, visibility, , pinNumber, x, y, rotation2, id] = parts;
|
|
376051
|
-
const
|
|
376052
|
-
let label =
|
|
376053
|
-
if (label.
|
|
376054
|
-
label =
|
|
376055
|
-
if (label.endsWith("-"))
|
|
376056
|
-
label = `${label.slice(0, -1)}_NEG`;
|
|
376057
|
-
label = normalizeActiveLowPinLabel2(label);
|
|
376058
|
-
if (/^\+\d+(?:\.\d+)?V$/i.test(label))
|
|
376059
|
-
label = `V${label.slice(1, -1)}`;
|
|
376060
|
-
if (label.startsWith("+"))
|
|
376061
|
-
label = `${label.slice(1)}_POS`;
|
|
376062
|
-
if (label.startsWith("-"))
|
|
376063
|
-
label = `${label.slice(1)}_NEG`;
|
|
376591
|
+
const pinNameSection = pinString.split("^^")[3];
|
|
376592
|
+
let label = pinNameSection?.split("~")[4] ?? "";
|
|
376593
|
+
if (!label.includes("/"))
|
|
376594
|
+
label = normalizeEasyEdaPinLabel2(label);
|
|
376064
376595
|
const colorMatch = pinString.match(/#[0-9A-F]{6}/);
|
|
376065
376596
|
const labelColor = colorMatch ? colorMatch[0] : "";
|
|
376066
376597
|
const path = pinString.split("^^")[2]?.split("~")[0] ?? "";
|
package/dist/lib/index.js
CHANGED
|
@@ -69109,7 +69109,7 @@ var getNodeHandler = (winterSpec, { port, middleware = [] }) => {
|
|
|
69109
69109
|
}));
|
|
69110
69110
|
};
|
|
69111
69111
|
// package.json
|
|
69112
|
-
var version = "0.1.
|
|
69112
|
+
var version = "0.1.2229";
|
|
69113
69113
|
var package_default = {
|
|
69114
69114
|
name: "@tscircuit/cli",
|
|
69115
69115
|
version,
|
|
@@ -69137,7 +69137,7 @@ var package_default = {
|
|
|
69137
69137
|
"@tscircuit/image-utils": "^0.0.8",
|
|
69138
69138
|
"@tscircuit/krt-wasm": "^0.1.6",
|
|
69139
69139
|
"@tscircuit/math-utils": "0.0.36",
|
|
69140
|
-
"@tscircuit/props": "^0.0.
|
|
69140
|
+
"@tscircuit/props": "^0.0.666",
|
|
69141
69141
|
"@tscircuit/runframe": "^0.0.2884",
|
|
69142
69142
|
"@tscircuit/schematic-match-adapt": "^0.0.22",
|
|
69143
69143
|
"@tscircuit/schematic-trace-solver": "^0.0.204",
|
|
@@ -69178,7 +69178,7 @@ var package_default = {
|
|
|
69178
69178
|
debug: "^4.4.0",
|
|
69179
69179
|
delay: "^6.0.0",
|
|
69180
69180
|
"dsn-converter": "^0.0.90",
|
|
69181
|
-
easyeda: "^0.0.
|
|
69181
|
+
easyeda: "^0.0.366",
|
|
69182
69182
|
"fuse.js": "^7.1.0",
|
|
69183
69183
|
"get-port": "^7.1.0",
|
|
69184
69184
|
globby: "^14.1.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2230",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/tscircuit/cli"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@tscircuit/image-utils": "^0.0.8",
|
|
26
26
|
"@tscircuit/krt-wasm": "^0.1.6",
|
|
27
27
|
"@tscircuit/math-utils": "0.0.36",
|
|
28
|
-
"@tscircuit/props": "^0.0.
|
|
28
|
+
"@tscircuit/props": "^0.0.666",
|
|
29
29
|
"@tscircuit/runframe": "^0.0.2884",
|
|
30
30
|
"@tscircuit/schematic-match-adapt": "^0.0.22",
|
|
31
31
|
"@tscircuit/schematic-trace-solver": "^0.0.204",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"debug": "^4.4.0",
|
|
67
67
|
"delay": "^6.0.0",
|
|
68
68
|
"dsn-converter": "^0.0.90",
|
|
69
|
-
"easyeda": "^0.0.
|
|
69
|
+
"easyeda": "^0.0.366",
|
|
70
70
|
"fuse.js": "^7.1.0",
|
|
71
71
|
"get-port": "^7.1.0",
|
|
72
72
|
"globby": "^14.1.0",
|