@tscircuit/cli 0.1.2278 → 0.1.2279

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 CHANGED
@@ -57778,6 +57778,613 @@ var init_dist = __esm(() => {
57778
57778
  MAT4: 16
57779
57779
  };
57780
57780
  });
57781
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/segments.ts
57782
+ function endpoint(p, outgoing) {
57783
+ if (p.route_type === "through_pad")
57784
+ return outgoing ? p.end : p.start;
57785
+ return { x: p.x, y: p.y };
57786
+ }
57787
+ function layer(p, outgoing) {
57788
+ if (p.route_type === "wire")
57789
+ return p.layer;
57790
+ if (p.route_type === "via")
57791
+ return outgoing ? p.to_layer : p.from_layer;
57792
+ return outgoing ? p.end_layer : p.start_layer;
57793
+ }
57794
+ function buildAnalysisContext(circuitJson) {
57795
+ const segments = [];
57796
+ for (const [circuitJsonIndex, item] of circuitJson.entries()) {
57797
+ if (item.type !== "pcb_trace")
57798
+ continue;
57799
+ for (let i = 0;i < item.route.length - 1; i++) {
57800
+ const a = item.route[i];
57801
+ const b = item.route[i + 1];
57802
+ const supported = (p) => ["wire", "via", "through_pad"].includes(p.route_type);
57803
+ if (!supported(a) || !supported(b))
57804
+ throw new Error(item.pcb_trace_id + ": unsupported route point at " + i);
57805
+ if (a.route_type !== "wire" && b.route_type !== "wire")
57806
+ continue;
57807
+ if (layer(a, true) !== layer(b, false))
57808
+ continue;
57809
+ const start = endpoint(a, true);
57810
+ const end = endpoint(b, false);
57811
+ if (![start.x, start.y, end.x, end.y].every(Number.isFinite))
57812
+ throw new Error(item.pcb_trace_id + ": nonfinite route coordinates at " + i);
57813
+ const lengthMm = Math.hypot(end.x - start.x, end.y - start.y);
57814
+ if (lengthMm <= 0.000000001)
57815
+ continue;
57816
+ const wire = a.route_type === "wire" ? a : b;
57817
+ const width = wire.route_type === "wire" ? Math.max(wire.width, wire.end_width ?? wire.width) : 0;
57818
+ if (!Number.isFinite(width) || width <= 0)
57819
+ throw new Error(item.pcb_trace_id + ": invalid wire width at " + i);
57820
+ segments.push({
57821
+ pcbTraceId: item.pcb_trace_id,
57822
+ sourceTraceId: item.source_trace_id,
57823
+ pcbGroupId: item.pcb_group_id,
57824
+ subcircuitId: item.subcircuit_id,
57825
+ circuitJsonIndex,
57826
+ startRouteIndex: i,
57827
+ endRouteIndex: i + 1,
57828
+ layer: layer(a, true),
57829
+ start: { ...start },
57830
+ end: { ...end },
57831
+ width,
57832
+ lengthMm
57833
+ });
57834
+ }
57835
+ }
57836
+ return { circuitJson, segments };
57837
+ }
57838
+
57839
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/issue-highlights.ts
57840
+ function getIssueHighlights(issues) {
57841
+ return issues.map((issue) => ({
57842
+ issue,
57843
+ color: "#ff5555",
57844
+ message: issue.message
57845
+ }));
57846
+ }
57847
+
57848
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/visualize.ts
57849
+ function visualizeIssues(ctx, issues) {
57850
+ const highlights = getIssueHighlights(issues);
57851
+ return {
57852
+ coordinateSystem: "cartesian",
57853
+ lines: [
57854
+ ...ctx.segments.map((s) => ({
57855
+ points: [s.start, s.end],
57856
+ strokeColor: s.layer === "bottom" ? "#60a5fa" : "#94a3b8",
57857
+ strokeWidth: s.width
57858
+ })),
57859
+ ...highlights.flatMap(({ issue, color, message }) => (issue.constituentSegments ?? [issue]).map((segment) => ({
57860
+ points: [segment.start, segment.end],
57861
+ strokeColor: color,
57862
+ strokeWidth: Math.max(segment.width * 2, 0.25),
57863
+ label: message
57864
+ })))
57865
+ ],
57866
+ points: highlights.map(({ issue, color, message }, i) => ({
57867
+ ...issue.location,
57868
+ color,
57869
+ label: i + 1 + ": " + message
57870
+ }))
57871
+ };
57872
+ }
57873
+ var init_visualize = () => {};
57874
+
57875
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/trace-runs.ts
57876
+ function distanceToSegment(p, a, b) {
57877
+ const dx = b.x - a.x;
57878
+ const dy = b.y - a.y;
57879
+ const lengthSquared = dx * dx + dy * dy;
57880
+ const t = lengthSquared ? Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lengthSquared)) : 0;
57881
+ return Math.hypot(p.x - a.x - t * dx, p.y - a.y - t * dy);
57882
+ }
57883
+ function buildTraceRuns(ctx) {
57884
+ const runs = [];
57885
+ const simplify = (segments) => {
57886
+ const pending = [[0, segments.length - 1]];
57887
+ while (pending.length) {
57888
+ const [lo, hi] = pending.pop();
57889
+ if (lo === hi)
57890
+ continue;
57891
+ const start = segments[lo].start;
57892
+ const end = segments[hi].end;
57893
+ let width = Infinity;
57894
+ let maxDistance = -1;
57895
+ let split = lo;
57896
+ for (let i = lo;i <= hi; i++) {
57897
+ width = Math.min(width, segments[i].width);
57898
+ if (i === hi)
57899
+ continue;
57900
+ const distance = distanceToSegment(segments[i].end, start, end);
57901
+ if (distance > maxDistance) {
57902
+ maxDistance = distance;
57903
+ split = i;
57904
+ }
57905
+ }
57906
+ if (maxDistance > width / 2 + 0.000000001) {
57907
+ pending.push([split + 1, hi], [lo, split]);
57908
+ continue;
57909
+ }
57910
+ const constituentSegments = segments.slice(lo, hi + 1);
57911
+ runs.push({
57912
+ ...segments[lo],
57913
+ endRouteIndex: segments[hi].endRouteIndex,
57914
+ end,
57915
+ width: constituentSegments.reduce((max, s) => Math.max(max, s.width), 0),
57916
+ lengthMm: Math.hypot(end.x - start.x, end.y - start.y),
57917
+ constituentSegments,
57918
+ maxCenterlineDeviationMm: maxDistance <= 0.000000001 ? 0 : maxDistance
57919
+ });
57920
+ }
57921
+ };
57922
+ for (const connected of getConnectedTraceSegments(ctx))
57923
+ simplify(connected);
57924
+ return [...ctx.segments, ...runs];
57925
+ }
57926
+ function getConnectedTraceSegments(ctx) {
57927
+ const chains = [];
57928
+ let connected = [];
57929
+ for (const segment of ctx.segments) {
57930
+ const previous = connected.at(-1);
57931
+ if (previous) {
57932
+ const trace = ctx.circuitJson[segment.circuitJsonIndex];
57933
+ const sameTrace = previous.circuitJsonIndex === segment.circuitJsonIndex;
57934
+ const wireJoin = sameTrace && trace.type === "pcb_trace" && trace.route.slice(previous.endRouteIndex, segment.startRouteIndex + 1).every((p) => p.route_type === "wire" && p.layer === segment.layer);
57935
+ if (!wireJoin || previous.layer !== segment.layer || Math.hypot(previous.end.x - segment.start.x, previous.end.y - segment.start.y) > 0.000000001) {
57936
+ chains.push(connected);
57937
+ connected = [];
57938
+ }
57939
+ }
57940
+ connected.push(segment);
57941
+ }
57942
+ if (connected.length)
57943
+ chains.push(connected);
57944
+ return chains;
57945
+ }
57946
+
57947
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/solvers/LongTraceSegmentSolver.ts
57948
+ import { BaseSolver } from "@tscircuit/solver-utils";
57949
+ var LongTraceSegmentSolver;
57950
+ var init_LongTraceSegmentSolver = __esm(() => {
57951
+ init_visualize();
57952
+ LongTraceSegmentSolver = class LongTraceSegmentSolver extends BaseSolver {
57953
+ params;
57954
+ segments = [];
57955
+ nextSegment = 0;
57956
+ candidates;
57957
+ constructor(params2) {
57958
+ super();
57959
+ this.params = params2;
57960
+ if (!Number.isFinite(params2.maxSegmentLengthMm) || params2.maxSegmentLengthMm <= 0)
57961
+ throw new Error("maxSegmentLengthMm must be finite and positive");
57962
+ this.candidates = buildTraceRuns(params2.ctx);
57963
+ this.MAX_ITERATIONS = this.candidates.length + 2;
57964
+ }
57965
+ _step() {
57966
+ const segment = this.candidates[this.nextSegment++];
57967
+ if (!segment) {
57968
+ this.solved = true;
57969
+ this.progress = 1;
57970
+ return;
57971
+ }
57972
+ if (segment.lengthMm > this.params.maxSegmentLengthMm)
57973
+ this.segments.push(segment);
57974
+ this.progress = this.nextSegment / this.candidates.length;
57975
+ this.stats = {
57976
+ segmentsChecked: this.nextSegment,
57977
+ candidateCount: this.segments.length
57978
+ };
57979
+ }
57980
+ getOutput() {
57981
+ return this.segments;
57982
+ }
57983
+ visualize() {
57984
+ return visualizeIssues(this.params.ctx, []);
57985
+ }
57986
+ getConstructorParams() {
57987
+ return [this.params];
57988
+ }
57989
+ };
57990
+ });
57991
+
57992
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/solvers/SegmentIssueSolver.ts
57993
+ import { BaseSolver as BaseSolver2 } from "@tscircuit/solver-utils";
57994
+ function locateIssue(segment, rule) {
57995
+ const { start, end } = segment;
57996
+ const parts = segment.constituentSegments ?? [segment];
57997
+ const bounds = parts.reduce((bounds, s) => ({
57998
+ minX: Math.min(bounds.minX, s.start.x - s.width / 2, s.end.x - s.width / 2),
57999
+ minY: Math.min(bounds.minY, s.start.y - s.width / 2, s.end.y - s.width / 2),
58000
+ maxX: Math.max(bounds.maxX, s.start.x + s.width / 2, s.end.x + s.width / 2),
58001
+ maxY: Math.max(bounds.maxY, s.start.y + s.width / 2, s.end.y + s.width / 2)
58002
+ }), { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity });
58003
+ return {
58004
+ ...segment,
58005
+ issueId: rule + ":" + segment.circuitJsonIndex + ":" + segment.startRouteIndex,
58006
+ severity: "error",
58007
+ message: "",
58008
+ location: { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 },
58009
+ bounds
58010
+ };
58011
+ }
58012
+ var SegmentIssueSolver;
58013
+ var init_SegmentIssueSolver = __esm(() => {
58014
+ init_visualize();
58015
+ SegmentIssueSolver = class SegmentIssueSolver extends BaseSolver2 {
58016
+ ctx;
58017
+ issues = [];
58018
+ nextSegment = 0;
58019
+ constructor(ctx) {
58020
+ super();
58021
+ this.ctx = ctx;
58022
+ this.MAX_ITERATIONS = ctx.segments.length + 2;
58023
+ }
58024
+ _step() {
58025
+ const segment = this.ctx.segments[this.nextSegment++];
58026
+ if (!segment) {
58027
+ this.solved = true;
58028
+ this.progress = 1;
58029
+ return;
58030
+ }
58031
+ const issue = this.checkSegment(segment);
58032
+ if (issue)
58033
+ this.issues.push(issue);
58034
+ this.progress = this.nextSegment / this.ctx.segments.length;
58035
+ this.stats = {
58036
+ segmentsChecked: this.nextSegment,
58037
+ issueCount: this.issues.length
58038
+ };
58039
+ }
58040
+ getOutput() {
58041
+ return this.issues;
58042
+ }
58043
+ visualize() {
58044
+ return visualizeIssues(this.ctx, this.issues);
58045
+ }
58046
+ };
58047
+ });
58048
+
58049
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/solvers/OddAngleTraceSegmentSolver.ts
58050
+ var OddAngleTraceSegmentSolver;
58051
+ var init_OddAngleTraceSegmentSolver = __esm(() => {
58052
+ init_visualize();
58053
+ init_SegmentIssueSolver();
58054
+ OddAngleTraceSegmentSolver = class OddAngleTraceSegmentSolver extends SegmentIssueSolver {
58055
+ params;
58056
+ constructor(params2) {
58057
+ super({
58058
+ ...params2.ctx,
58059
+ segments: params2.candidateSegments ?? buildTraceRuns(params2.ctx)
58060
+ });
58061
+ this.params = params2;
58062
+ if (!Number.isFinite(params2.maxSegmentLengthMm) || params2.maxSegmentLengthMm <= 0)
58063
+ throw new Error("maxSegmentLengthMm must be finite and positive");
58064
+ if (!Number.isFinite(params2.angleToleranceDegrees) || params2.angleToleranceDegrees < 0 || params2.angleToleranceDegrees >= 22.5)
58065
+ throw new Error("angleToleranceDegrees must be in [0, 22.5)");
58066
+ const covered = new Set;
58067
+ for (const segment of this.ctx.segments) {
58068
+ if (!segment.constituentSegments || !this.checkSegment(segment))
58069
+ continue;
58070
+ for (const part of segment.constituentSegments)
58071
+ covered.add(part.circuitJsonIndex + ":" + part.startRouteIndex);
58072
+ }
58073
+ this.ctx = {
58074
+ ...this.ctx,
58075
+ segments: this.ctx.segments.filter((s) => s.constituentSegments || !covered.has(s.circuitJsonIndex + ":" + s.startRouteIndex))
58076
+ };
58077
+ }
58078
+ checkSegment(s) {
58079
+ if (s.lengthMm <= this.params.maxSegmentLengthMm)
58080
+ return;
58081
+ const angleDegrees = (Math.atan2(s.end.y - s.start.y, s.end.x - s.start.x) * 180 / Math.PI + 360) % 360;
58082
+ const nearest = Math.round(angleDegrees / 45) * 45;
58083
+ const deviationDegrees = Math.abs(angleDegrees - nearest);
58084
+ const uncertaintyDegrees = Math.atan2(2 * (s.maxCenterlineDeviationMm ?? 0), s.lengthMm) * 180 / Math.PI;
58085
+ if (deviationDegrees <= this.params.angleToleranceDegrees + uncertaintyDegrees + 0.0000000001)
58086
+ return;
58087
+ return {
58088
+ ...locateIssue(s, "odd-angle"),
58089
+ lineItemType: "PcbTraceSegmentOddAngle",
58090
+ maxSegmentLengthMm: this.params.maxSegmentLengthMm,
58091
+ angleDegrees,
58092
+ nearestAllowedAngleDegrees: nearest % 360,
58093
+ deviationDegrees,
58094
+ angleToleranceDegrees: this.params.angleToleranceDegrees,
58095
+ ...s.constituentSegments ? { angleUncertaintyDegrees: uncertaintyDegrees } : {},
58096
+ message: s.pcbTraceId + (s.constituentSegments ? " run " + s.startRouteIndex + " → " + s.endRouteIndex : " segment " + s.startRouteIndex) + " on " + s.layer + " is " + s.lengthMm.toFixed(3) + " mm long (threshold " + this.params.maxSegmentLengthMm + " mm) and at " + angleDegrees.toFixed(3) + "°; nearest allowed direction " + nearest % 360 + "° (deviation " + deviationDegrees.toFixed(3) + "°, tolerance " + this.params.angleToleranceDegrees + "°" + (uncertaintyDegrees ? ", approximation allowance " + uncertaintyDegrees.toFixed(3) + "°" : "") + ")"
58097
+ };
58098
+ }
58099
+ visualize() {
58100
+ return visualizeIssues(this.params.ctx, this.issues);
58101
+ }
58102
+ getConstructorParams() {
58103
+ return [this.params];
58104
+ }
58105
+ };
58106
+ });
58107
+
58108
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/solvers/StaircaseTraceSolver.ts
58109
+ function direction(s) {
58110
+ const angle = (Math.atan2(s.end.y - s.start.y, s.end.x - s.start.x) * 180 / Math.PI + 360) % 360;
58111
+ return angle;
58112
+ }
58113
+ function angleDistance(a, b) {
58114
+ return Math.abs((a - b + 540) % 360 - 180);
58115
+ }
58116
+ var StaircaseTraceSolver;
58117
+ var init_StaircaseTraceSolver = __esm(() => {
58118
+ init_visualize();
58119
+ init_SegmentIssueSolver();
58120
+ StaircaseTraceSolver = class StaircaseTraceSolver extends SegmentIssueSolver {
58121
+ params;
58122
+ bendCounts = new Map;
58123
+ constructor(params2) {
58124
+ super({ ...params2.ctx, segments: [] });
58125
+ this.params = params2;
58126
+ const minBends = params2.minStaircaseBends ?? 6;
58127
+ const minLength = params2.minStaircaseLengthMm ?? 2;
58128
+ const maxStep = params2.maxStairStepLengthMm ?? 1;
58129
+ if (!Number.isInteger(minBends) || minBends < 2)
58130
+ throw new Error("minStaircaseBends must be an integer of at least 2");
58131
+ if (!Number.isFinite(minLength) || minLength <= 0)
58132
+ throw new Error("minStaircaseLengthMm must be finite and positive");
58133
+ if (!Number.isFinite(maxStep) || maxStep <= 0)
58134
+ throw new Error("maxStairStepLengthMm must be finite and positive");
58135
+ const candidates = [];
58136
+ for (const chain of getConnectedTraceSegments(params2.ctx)) {
58137
+ const steps = [];
58138
+ for (const s of chain) {
58139
+ const heading = direction(s);
58140
+ const last = steps.at(-1);
58141
+ if (last && angleDistance(last.direction, heading) <= 4 + 0.0000000001) {
58142
+ last.parts.push(s);
58143
+ last.lengthMm += s.lengthMm;
58144
+ } else
58145
+ steps.push({ direction: heading, parts: [s], lengthMm: s.lengthMm });
58146
+ }
58147
+ for (let i = 0;i < steps.length - 1; ) {
58148
+ const a = steps[i], b = steps[i + 1];
58149
+ const difference = angleDistance(a.direction, b.direction);
58150
+ if (difference < 15 - 0.0000000001 || difference > 90 + 0.0000000001 || a.lengthMm > maxStep + 0.000000001 || b.lengthMm > maxStep + 0.000000001) {
58151
+ i++;
58152
+ continue;
58153
+ }
58154
+ let end = i + 2;
58155
+ while (end < steps.length && angleDistance(steps[end].direction, steps[i + (end - i) % 2].direction) <= 4 + 0.0000000001 && steps[end].lengthMm <= maxStep + 0.000000001)
58156
+ end++;
58157
+ const parts = steps.slice(i, end).flatMap((s) => s.parts);
58158
+ const lengthMm = parts.reduce((n, s) => n + s.lengthMm, 0);
58159
+ if (end - i - 1 >= minBends && lengthMm + 0.000000001 >= minLength) {
58160
+ const candidate = {
58161
+ ...parts[0],
58162
+ end: parts.at(-1).end,
58163
+ endRouteIndex: parts.at(-1).endRouteIndex,
58164
+ width: parts.reduce((width, s) => Math.max(width, s.width), 0),
58165
+ lengthMm,
58166
+ constituentSegments: parts
58167
+ };
58168
+ candidates.push(candidate);
58169
+ this.bendCounts.set(candidate, end - i - 1);
58170
+ i = end;
58171
+ } else
58172
+ i = end - 1;
58173
+ }
58174
+ }
58175
+ this.ctx = { ...params2.ctx, segments: candidates };
58176
+ this.MAX_ITERATIONS = candidates.length + 2;
58177
+ }
58178
+ checkSegment(s) {
58179
+ const bendCount = this.bendCounts.get(s);
58180
+ return {
58181
+ ...locateIssue(s, "staircase"),
58182
+ lineItemType: "PcbTraceStaircase",
58183
+ bendCount,
58184
+ minStaircaseBends: this.params.minStaircaseBends ?? 6,
58185
+ minStaircaseLengthMm: this.params.minStaircaseLengthMm ?? 2,
58186
+ maxStairStepLengthMm: this.params.maxStairStepLengthMm ?? 1,
58187
+ message: `${s.pcbTraceId} route ${s.startRouteIndex} → ${s.endRouteIndex} on ${s.layer} has ${bendCount} alternating staircase bends over ${s.lengthMm.toFixed(3)} mm`
58188
+ };
58189
+ }
58190
+ visualize() {
58191
+ return visualizeIssues(this.params.ctx, this.issues);
58192
+ }
58193
+ getConstructorParams() {
58194
+ return [this.params];
58195
+ }
58196
+ };
58197
+ });
58198
+
58199
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/solvers/PcbStyleAnalysisPipeline.ts
58200
+ import {
58201
+ BasePipelineSolver,
58202
+ definePipelineStep
58203
+ } from "@tscircuit/solver-utils";
58204
+ var PcbStyleAnalysisPipeline;
58205
+ var init_PcbStyleAnalysisPipeline = __esm(() => {
58206
+ init_visualize();
58207
+ init_LongTraceSegmentSolver();
58208
+ init_OddAngleTraceSegmentSolver();
58209
+ init_StaircaseTraceSolver();
58210
+ PcbStyleAnalysisPipeline = class PcbStyleAnalysisPipeline extends BasePipelineSolver {
58211
+ options;
58212
+ ctx;
58213
+ pipelineDef = [
58214
+ definePipelineStep("LongTraceSegmentSolver", LongTraceSegmentSolver, (p) => [
58215
+ { ctx: p.ctx, maxSegmentLengthMm: p.options.maxSegmentLengthMm ?? 5 }
58216
+ ]),
58217
+ definePipelineStep("OddAngleTraceSegmentSolver", OddAngleTraceSegmentSolver, (p) => [
58218
+ {
58219
+ ctx: p.ctx,
58220
+ candidateSegments: p.getSolver("LongTraceSegmentSolver").getOutput(),
58221
+ maxSegmentLengthMm: p.options.maxSegmentLengthMm ?? 5,
58222
+ angleToleranceDegrees: p.options.angleToleranceDegrees ?? 4
58223
+ }
58224
+ ]),
58225
+ definePipelineStep("StaircaseTraceSolver", StaircaseTraceSolver, (p) => [
58226
+ {
58227
+ ctx: p.ctx,
58228
+ minStaircaseBends: p.options.minStaircaseBends,
58229
+ minStaircaseLengthMm: p.options.minStaircaseLengthMm,
58230
+ maxStairStepLengthMm: p.options.maxStairStepLengthMm
58231
+ }
58232
+ ])
58233
+ ];
58234
+ constructor(circuitJson, options = {}) {
58235
+ super(circuitJson);
58236
+ this.options = options;
58237
+ if (options.issueTypes) {
58238
+ const oddAngles = options.issueTypes.includes("PcbTraceSegmentOddAngle");
58239
+ const staircases = options.issueTypes.includes("PcbTraceStaircase");
58240
+ this.pipelineDef = this.pipelineDef.filter((step) => step.solverName === "StaircaseTraceSolver" ? staircases : oddAngles);
58241
+ }
58242
+ this.MAX_ITERATIONS = circuitJson.reduce((n, e) => n + (e.type === "pcb_trace" ? e.route.length * 5 : 0), 10);
58243
+ }
58244
+ _setup() {
58245
+ this.ctx = buildAnalysisContext(this.inputProblem);
58246
+ }
58247
+ getOutput() {
58248
+ return {
58249
+ issues: [
58250
+ ...this.getSolver("OddAngleTraceSegmentSolver")?.getOutput() ?? [],
58251
+ ...this.getSolver("StaircaseTraceSolver")?.getOutput() ?? []
58252
+ ]
58253
+ };
58254
+ }
58255
+ getConstructorParams() {
58256
+ return [this.inputProblem, this.options];
58257
+ }
58258
+ initialVisualize() {
58259
+ this.setup();
58260
+ return visualizeIssues(this.ctx, []);
58261
+ }
58262
+ finalVisualize() {
58263
+ this.setup();
58264
+ return visualizeIssues(this.ctx, this.getOutput().issues);
58265
+ }
58266
+ };
58267
+ });
58268
+
58269
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/analyze-pcb-style.ts
58270
+ function analyzePcbStyle(circuitJson, options = {}) {
58271
+ const solver = new PcbStyleAnalysisPipeline(circuitJson, options);
58272
+ solver.solve();
58273
+ if (solver.failed)
58274
+ throw new Error(solver.error ?? "PCB style analysis failed");
58275
+ return solver.getOutput();
58276
+ }
58277
+ var init_analyze_pcb_style = __esm(() => {
58278
+ init_PcbStyleAnalysisPipeline();
58279
+ });
58280
+
58281
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/create-pcb-style-issue-artifacts.ts
58282
+ function escapeXml(value) {
58283
+ return value.replace(/[&<>"']/g, (c) => ({
58284
+ "&": "&amp;",
58285
+ "<": "&lt;",
58286
+ ">": "&gt;",
58287
+ '"': "&quot;",
58288
+ "'": "&apos;"
58289
+ })[c]);
58290
+ }
58291
+ function describeIssueXml(issue) {
58292
+ return "<" + issue.lineItemType + ' severity="error" pcbTraceId="' + escapeXml(issue.pcbTraceId) + '" startRouteIndex="' + issue.startRouteIndex + '" endRouteIndex="' + issue.endRouteIndex + '" layer="' + escapeXml(issue.layer) + '" x="' + issue.location.x + '" y="' + issue.location.y + '" lengthMm="' + issue.lengthMm + '" message="' + escapeXml(issue.message) + '" />';
58293
+ }
58294
+ function renderPcbStyleSvg(circuitJson, issues, options = {}) {
58295
+ const ctx = buildAnalysisContext(circuitJson);
58296
+ const segments = ctx.segments.filter((s) => !options.layer || s.layer === options.layer);
58297
+ const points = segments.flatMap((s) => [s.start, s.end]);
58298
+ const bounds = options.bounds ?? {
58299
+ minX: Math.min(0, ...points.map((p) => p.x)) - 2,
58300
+ minY: Math.min(0, ...points.map((p) => p.y)) - 2,
58301
+ maxX: Math.max(0, ...points.map((p) => p.x)) + 2,
58302
+ maxY: Math.max(0, ...points.map((p) => p.y)) + 2
58303
+ };
58304
+ const scale = Math.min(740 / Math.max(1, bounds.maxX - bounds.minX), 350 / Math.max(1, bounds.maxY - bounds.minY));
58305
+ const cx = (bounds.minX + bounds.maxX) / 2;
58306
+ const cy = (bounds.minY + bounds.maxY) / 2;
58307
+ const x = (n) => Number((400 + (n - cx) * scale).toFixed(4));
58308
+ const y = (n) => Number((215 - (n - cy) * scale).toFixed(4));
58309
+ const line = (s, color, highlight = false) => '<line x1="' + x(s.start.x) + '" y1="' + y(s.start.y) + '" x2="' + x(s.end.x) + '" y2="' + y(s.end.y) + '" stroke="' + color + '" stroke-width="' + Number(Math.max(highlight ? 4 : 1, s.width * scale * (highlight ? 1.8 : 1)).toFixed(4)) + '" stroke-linecap="round"/>';
58310
+ const context = segments.filter((s) => Math.max(s.start.x, s.end.x) + s.width >= bounds.minX && Math.min(s.start.x, s.end.x) - s.width <= bounds.maxX && Math.max(s.start.y, s.end.y) + s.width >= bounds.minY && Math.min(s.start.y, s.end.y) - s.width <= bounds.maxY).map((s) => line(s, s.layer === "bottom" ? "#74a9d8" : "#9aa9a2")).join("");
58311
+ const individual = options.bounds !== undefined && issues.length === 1;
58312
+ const highlights = getIssueHighlights(issues).map(({ issue: s, color }, i) => (s.constituentSegments ?? [s]).map((part) => line(part, color, true)).join("") + (individual ? '<circle cx="' + x(s.location.x) + '" cy="' + y(s.location.y) + '" r="10" fill="#fff" stroke="' + color + '" stroke-width="2"/>' + '<text x="' + x(s.location.x) + '" y="' + (y(s.location.y) + 4) + '" text-anchor="middle" fill="#9b1111" font-size="11">' + (i + 1) + "</text>" : "")).join("");
58313
+ const title = options.title ?? "PCB style analysis — " + issues.length + " errors";
58314
+ const details = individual ? [
58315
+ issues[0].message,
58316
+ "Start (" + issues[0].start.x.toFixed(3) + ", " + issues[0].start.y.toFixed(3) + ") → End (" + issues[0].end.x.toFixed(3) + ", " + issues[0].end.y.toFixed(3) + ") mm",
58317
+ "Layer: " + issues[0].layer + " | Circuit JSON index: " + issues[0].circuitJsonIndex + " | Route indices: " + issues[0].startRouteIndex + " → " + issues[0].endRouteIndex
58318
+ ] : [
58319
+ "Red: PCB traces with detected style issues",
58320
+ "Coordinates in millimeters; Y points upward. " + issues.length + " located errors."
58321
+ ];
58322
+ return '<svg xmlns="http://www.w3.org/2000/svg" width="800" height="490" viewBox="0 0 800 490"><title>' + escapeXml(title) + '</title><rect width="800" height="490" fill="#10271c"/><style>text{font-family:monospace}</style><text x="20" y="26" fill="#fff" font-size="16">' + escapeXml(title) + '</text><defs><clipPath id="board"><rect x="15" y="40" width="770" height="350"/></clipPath></defs><g clip-path="url(#board)">' + context + highlights + '</g><rect x="0" y="400" width="800" height="90" fill="#f1f5f9"/>' + details.map((t, i) => '<text x="16" y="' + (423 + i * 22) + '" fill="#152d22" font-size="11">' + escapeXml(t) + "</text>").join("") + `</svg>
58323
+ `;
58324
+ }
58325
+ function createPcbStyleIssueArtifacts(circuitJson, options = {}) {
58326
+ const analysis = options.analysis ?? analyzePcbStyle(circuitJson, {
58327
+ maxSegmentLengthMm: options.maxSegmentLengthMm,
58328
+ angleToleranceDegrees: options.angleToleranceDegrees,
58329
+ minStaircaseBends: options.minStaircaseBends,
58330
+ minStaircaseLengthMm: options.minStaircaseLengthMm,
58331
+ maxStairStepLengthMm: options.maxStairStepLengthMm
58332
+ });
58333
+ return analysis.issues.flatMap((issue, issueIndex) => {
58334
+ if (options.layer && issue.layer !== options.layer)
58335
+ return [];
58336
+ if (options.issueTypes && !options.issueTypes.includes(issue.lineItemType))
58337
+ return [];
58338
+ const margin = Math.max(2, (issue.bounds.maxX - issue.bounds.minX) * 0.2, (issue.bounds.maxY - issue.bounds.minY) * 0.2);
58339
+ const crop = {
58340
+ minX: issue.bounds.minX - margin,
58341
+ minY: issue.bounds.minY - margin,
58342
+ maxX: issue.bounds.maxX + margin,
58343
+ maxY: issue.bounds.maxY + margin
58344
+ };
58345
+ return [
58346
+ {
58347
+ issueIndex,
58348
+ issue,
58349
+ layer: issue.layer,
58350
+ bounds: issue.bounds,
58351
+ descriptionXml: describeIssueXml(issue),
58352
+ fileName: "issue-" + String(issueIndex + 1).padStart(4, "0") + "-" + issue.lineItemType + ".svg",
58353
+ contentType: "image/svg+xml",
58354
+ content: renderPcbStyleSvg(circuitJson, [issue], {
58355
+ bounds: crop,
58356
+ layer: issue.layer,
58357
+ title: "Issue " + (issueIndex + 1) + " — " + issue.lineItemType
58358
+ })
58359
+ }
58360
+ ];
58361
+ });
58362
+ }
58363
+ var init_create_pcb_style_issue_artifacts = __esm(() => {
58364
+ init_analyze_pcb_style();
58365
+ });
58366
+
58367
+ // node_modules/@tscircuit/circuit-json-pcb-style-analysis/lib/index.ts
58368
+ var exports_lib = {};
58369
+ __export3(exports_lib, {
58370
+ LongTraceSegmentSolver: () => LongTraceSegmentSolver,
58371
+ OddAngleTraceSegmentSolver: () => OddAngleTraceSegmentSolver,
58372
+ PcbStyleAnalysisPipeline: () => PcbStyleAnalysisPipeline,
58373
+ StaircaseTraceSolver: () => StaircaseTraceSolver,
58374
+ analyzePcbStyle: () => analyzePcbStyle,
58375
+ createPcbStyleIssueArtifacts: () => createPcbStyleIssueArtifacts,
58376
+ describeIssueXml: () => describeIssueXml,
58377
+ escapeXml: () => escapeXml,
58378
+ renderPcbStyleSvg: () => renderPcbStyleSvg
58379
+ });
58380
+ var init_lib2 = __esm(() => {
58381
+ init_analyze_pcb_style();
58382
+ init_create_pcb_style_issue_artifacts();
58383
+ init_PcbStyleAnalysisPipeline();
58384
+ init_LongTraceSegmentSolver();
58385
+ init_OddAngleTraceSegmentSolver();
58386
+ init_StaircaseTraceSolver();
58387
+ });
57781
58388
 
57782
58389
  // node_modules/@tscircuit/circuit-json-routing-analysis/dist/chunk-4ISXDEM5.js
57783
58390
  import * as Soup from "circuit-json";
@@ -99200,7 +99807,7 @@ var import_gerber_to_svg, renderTscircuitRepro = async (tsx, options = {}) => {
99200
99807
  x: rect.x + (point.x - bounds.minX) / (bounds.maxX - bounds.minX) * rect.width,
99201
99808
  y: rect.y + (bounds.maxY - point.y) / (bounds.maxY - bounds.minY) * rect.height
99202
99809
  };
99203
- }, escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;"), shortMarkerStroke = "#9b5cff", createShortDebugSvg = (circuitJson, shorts, options = {}) => {
99810
+ }, escapeXml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;"), shortMarkerStroke = "#9b5cff", createShortDebugSvg = (circuitJson, shorts, options = {}) => {
99204
99811
  const shortLayers = new Set(shorts.map((short) => short.layer));
99205
99812
  const layer = options.layer ?? (shortLayers.size === 1 ? [...shortLayers][0] : undefined);
99206
99813
  const baseSvg = convertCircuitJsonToPcbSvg22(circuitJson, { layer });
@@ -99217,8 +99824,8 @@ var import_gerber_to_svg, renderTscircuitRepro = async (tsx, options = {}) => {
99217
99824
  const secondLabel = short.secondOwnerLabels.join(", ");
99218
99825
  const text = `SHORT ${index + 1}: ${firstLabel} <-> ${secondLabel}`;
99219
99826
  return `
99220
- <g data-type="short-debug" data-mode="${escapeXml(short.mode)}" data-layer="${escapeXml(short.layer)}">
99221
- <title>${escapeXml(text)}</title>
99827
+ <g data-type="short-debug" data-mode="${escapeXml2(short.mode)}" data-layer="${escapeXml2(short.layer)}">
99828
+ <title>${escapeXml2(text)}</title>
99222
99829
  <circle cx="${point.x.toFixed(2)}" cy="${point.y.toFixed(2)}" r="14" fill="none" stroke="${shortMarkerStroke}" stroke-width="4"/>
99223
99830
  <circle cx="${point.x.toFixed(2)}" cy="${point.y.toFixed(2)}" r="6" fill="none" stroke="${shortMarkerStroke}" stroke-width="3"/>
99224
99831
  </g>`;
@@ -99427,9 +100034,9 @@ class Trace {
99427
100034
  }
99428
100035
  toString() {
99429
100036
  const lines = [
99430
- `<Trace id="${escapeXml2(this.id)}" label="${escapeXml2(this.label)}" connectionType="${escapeXml2(this.connectionType)}" lengthMm="${formatNumber3(this.lengthMm)}" straightLineDistanceMm="${formatNumber3(this.straightLineDistanceMm)}">`,
100037
+ `<Trace id="${escapeXml3(this.id)}" label="${escapeXml3(this.label)}" connectionType="${escapeXml3(this.connectionType)}" lengthMm="${formatNumber3(this.lengthMm)}" straightLineDistanceMm="${formatNumber3(this.straightLineDistanceMm)}">`,
99431
100038
  ` <ConnectedPins>`,
99432
- ...this.connectedPins.map((pin) => ` <Pin ref="${escapeXml2(pin.ref)}" />`),
100039
+ ...this.connectedPins.map((pin) => ` <Pin ref="${escapeXml3(pin.ref)}" />`),
99433
100040
  ` </ConnectedPins>`,
99434
100041
  ` <PinPositions>`,
99435
100042
  ...this.pinPositions.map((pin) => renderPinPosition(pin, " ")),
@@ -99439,7 +100046,7 @@ class Trace {
99439
100046
  `</Trace>`
99440
100047
  ];
99441
100048
  if (this.points.length > 0) {
99442
- lines.splice(lines.length - 1, 0, ` <Path>`, ...this.points.map((point) => ` <Point x="${formatNumber3(point.x)}" y="${formatNumber3(point.y)}" layer="${escapeXml2(point.layer)}" kind="${escapeXml2(point.kind)}" />`), ` </Path>`);
100049
+ lines.splice(lines.length - 1, 0, ` <Path>`, ...this.points.map((point) => ` <Point x="${formatNumber3(point.x)}" y="${formatNumber3(point.y)}" layer="${escapeXml3(point.layer)}" kind="${escapeXml3(point.kind)}" />`), ` </Path>`);
99443
100050
  }
99444
100051
  return lines.join(`
99445
100052
  `);
@@ -99468,7 +100075,7 @@ class TraceLengthAnalysis {
99468
100075
  }
99469
100076
  toString() {
99470
100077
  const lines = [
99471
- `<TraceLengthAnalysis requestedTarget="${escapeXml2(this.requestedTarget)}" resolvedTarget="${escapeXml2(this.resolvedTarget)}" targetKind="${escapeXml2(this.targetKind)}" traceCount="${this.traceCount}" totalLengthMm="${formatNumber3(this.totalLengthMm)}" totalStraightLineDistanceMm="${formatNumber3(this.totalStraightLineDistanceMm)}">`,
100078
+ `<TraceLengthAnalysis requestedTarget="${escapeXml3(this.requestedTarget)}" resolvedTarget="${escapeXml3(this.resolvedTarget)}" targetKind="${escapeXml3(this.targetKind)}" traceCount="${this.traceCount}" totalLengthMm="${formatNumber3(this.totalLengthMm)}" totalStraightLineDistanceMm="${formatNumber3(this.totalStraightLineDistanceMm)}">`,
99472
100079
  ...this.#traces.flatMap((trace) => trace.toString().split(`
99473
100080
  `).map((line) => ` ${line}`)),
99474
100081
  `</TraceLengthAnalysis>`
@@ -99936,16 +100543,16 @@ function classifyPcbTracePoint(point, index, pointCount) {
99936
100543
  }
99937
100544
  function renderPinPosition(pin, indent) {
99938
100545
  if (typeof pin.x !== "number" || typeof pin.y !== "number") {
99939
- return `${indent}<Pin ref="${escapeXml2(pin.ref)}" position="unavailable" />`;
100546
+ return `${indent}<Pin ref="${escapeXml3(pin.ref)}" position="unavailable" />`;
99940
100547
  }
99941
100548
  const layers = pin.layers.length > 0 ? pin.layers.join(",") : "unknown";
99942
- return `${indent}<Pin ref="${escapeXml2(pin.ref)}" x="${formatNumber3(pin.x)}" y="${formatNumber3(pin.y)}" layers="${escapeXml2(layers)}" />`;
100549
+ return `${indent}<Pin ref="${escapeXml3(pin.ref)}" x="${formatNumber3(pin.x)}" y="${formatNumber3(pin.y)}" layers="${escapeXml3(layers)}" />`;
99943
100550
  }
99944
100551
  function renderConnection(trace) {
99945
100552
  if (trace.connectionTargetPosition) {
99946
- return ` <Connection kind="${escapeXml2(trace.connectionType)}" target="${escapeXml2(trace.connectionTarget)}" x="${formatNumber3(trace.connectionTargetPosition.x)}" y="${formatNumber3(trace.connectionTargetPosition.y)}" layer="${escapeXml2(trace.connectionTargetPosition.layer)}" />`;
100553
+ return ` <Connection kind="${escapeXml3(trace.connectionType)}" target="${escapeXml3(trace.connectionTarget)}" x="${formatNumber3(trace.connectionTargetPosition.x)}" y="${formatNumber3(trace.connectionTargetPosition.y)}" layer="${escapeXml3(trace.connectionTargetPosition.layer)}" />`;
99947
100554
  }
99948
- return ` <Connection kind="${escapeXml2(trace.connectionType)}" target="${escapeXml2(trace.connectionTarget)}" />`;
100555
+ return ` <Connection kind="${escapeXml3(trace.connectionType)}" target="${escapeXml3(trace.connectionTarget)}" />`;
99949
100556
  }
99950
100557
  function renderRequirements(requirements, indent) {
99951
100558
  if (typeof requirements.maxLengthMm === "number") {
@@ -99992,12 +100599,12 @@ function distanceBetween(left, right) {
99992
100599
  function formatNumber3(value) {
99993
100600
  return value.toFixed(2);
99994
100601
  }
99995
- function escapeXml2(value) {
100602
+ function escapeXml3(value) {
99996
100603
  return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
99997
100604
  }
99998
100605
 
99999
100606
  // node_modules/circuit-json-trace-length-analysis/lib/index.ts
100000
- var init_lib2 = () => {};
100607
+ var init_lib3 = () => {};
100001
100608
 
100002
100609
  // node_modules/@edge-runtime/node-utils/dist/index.js
100003
100610
  var require_dist7 = __commonJS2(function(exports, module) {
@@ -169933,7 +170540,7 @@ var init_convert_circuit_json_to_altium_zip = __esm(() => {
169933
170540
  });
169934
170541
 
169935
170542
  // node_modules/circuit-json-to-altium/lib/index.ts
169936
- var init_lib3 = __esm(() => {
170543
+ var init_lib4 = __esm(() => {
169937
170544
  init_circuit_json_to_altium_converter();
169938
170545
  init_convert_circuit_json_to_altium_zip();
169939
170546
  });
@@ -171749,7 +172356,7 @@ var import_perfect_cli = __toESM3(require_dist3(), 1);
171749
172356
  // lib/getVersion.ts
171750
172357
  import { createRequire as createRequire2 } from "node:module";
171751
172358
  // package.json
171752
- var version = "0.1.2277";
172359
+ var version = "0.1.2278";
171753
172360
  var package_default = {
171754
172361
  name: "@tscircuit/cli",
171755
172362
  version,
@@ -171766,6 +172373,7 @@ var package_default = {
171766
172373
  "@babel/standalone": "^7.26.9",
171767
172374
  "@biomejs/biome": "^1.9.4",
171768
172375
  "@tscircuit/check-shorts": "https://jscdn.tscircuit.com/@tscircuit/check-shorts/0.0.26.tgz",
172376
+ "@tscircuit/circuit-json-pcb-style-analysis": "https://jscdn.tscircuit.com/@tscircuit/circuit-json-pcb-style-analysis/0.0.5.tgz",
171769
172377
  "@tscircuit/circuit-json-placement-analysis": "^0.0.15",
171770
172378
  "@tscircuit/circuit-json-routing-analysis": "^0.0.8",
171771
172379
  "@tscircuit/circuit-json-schematic-placement-analysis": "https://jscdn.tscircuit.com/@tscircuit/circuit-json-schematic-placement-analysis/0.0.50.tgz",
@@ -191030,12 +191638,9 @@ var registerCheckNetlist = (program) => {
191030
191638
  });
191031
191639
  };
191032
191640
 
191033
- // cli/check/pin-specification/register.ts
191034
- import { runAllPinSpecificationChecks } from "@tscircuit/checks";
191035
-
191036
- // cli/check/shared.ts
191037
- import fs44 from "node:fs";
191038
- import path49 from "node:path";
191641
+ // cli/check/pcb-style/register.ts
191642
+ import { mkdir as mkdir2, readFile as readFile2, writeFile } from "node:fs/promises";
191643
+ import path50 from "node:path";
191039
191644
 
191040
191645
  // lib/shared/is-circuit-json-file.ts
191041
191646
  var isCircuitJsonFile = (filePath) => {
@@ -191044,6 +191649,8 @@ var isCircuitJsonFile = (filePath) => {
191044
191649
  };
191045
191650
 
191046
191651
  // cli/check/shared.ts
191652
+ import fs44 from "node:fs";
191653
+ import path49 from "node:path";
191047
191654
  var resolveCheckInputFilePath = async (file) => {
191048
191655
  if (file) {
191049
191656
  return path49.isAbsolute(file) ? file : path49.resolve(process.cwd(), file);
@@ -191077,7 +191684,80 @@ var getCircuitJsonForCheck = async ({
191077
191684
  return circuitJson;
191078
191685
  };
191079
191686
 
191687
+ // cli/check/pcb-style/register.ts
191688
+ var PCB_STYLE_CDN_URL = "https://jscdn.tscircuit.com/@tscircuit/circuit-json-pcb-style-analysis/latest/+esm";
191689
+ var importFromPackage = async () => await Promise.resolve().then(() => (init_lib2(), exports_lib));
191690
+ var loadPcbStyleAnalysis = async (options = {}) => {
191691
+ const preferCdn = options.preferCdn ?? process.env.TSCI_TEST_MODE !== "true";
191692
+ if (!preferCdn)
191693
+ return importFromPackage();
191694
+ try {
191695
+ const analyzer = await (options.importFromCdn ?? ((url) => import(url)))(PCB_STYLE_CDN_URL);
191696
+ if (typeof analyzer.analyzePcbStyle !== "function" || typeof analyzer.renderPcbStyleSvg !== "function") {
191697
+ throw new Error("The jscdn module is missing PCB style analysis exports");
191698
+ }
191699
+ return analyzer;
191700
+ } catch (cdnError) {
191701
+ try {
191702
+ return await importFromPackage();
191703
+ } catch (packageError) {
191704
+ throw new AggregateError([cdnError, packageError], "Failed to load PCB style analysis from jscdn or the installed CLI package");
191705
+ }
191706
+ }
191707
+ };
191708
+ var checkPcbStyle = async (file, options = {}) => {
191709
+ const { analyzePcbStyle, renderPcbStyleSvg } = await loadPcbStyleAnalysis();
191710
+ const filePath = await resolveCheckInputFilePath(file);
191711
+ const svgPath = path50.resolve(options.svg ?? path50.join("checks", "check-pcb-style", "pcb.svg"));
191712
+ if (!svgPath.endsWith(".svg") || svgPath === filePath) {
191713
+ throw new Error("--svg must name an SVG output file different from the input");
191714
+ }
191715
+ const input = isCircuitJsonFile(filePath) ? JSON.parse(await readFile2(filePath, "utf8")) : await getCircuitJsonForCheck({
191716
+ filePath,
191717
+ platformConfig: { pcbDisabled: false, routingDisabled: false }
191718
+ });
191719
+ if (!Array.isArray(input) || input.some((item) => !item || typeof item !== "object" || typeof item.type !== "string" || item.type === "pcb_trace" && (!Array.isArray(item.route) || typeof item.pcb_trace_id !== "string"))) {
191720
+ throw new Error("Expected a Circuit JSON array; pcb_trace elements need pcb_trace_id and route");
191721
+ }
191722
+ const circuitJson = input;
191723
+ const analysis = analyzePcbStyle(circuitJson);
191724
+ const count = analysis.issues.length;
191725
+ const output = [
191726
+ count === 0 ? `No PCB style issues detected in ${path50.basename(filePath)}` : `Detected ${count} PCB style issue${count === 1 ? "" : "s"} in ${path50.basename(filePath)}`,
191727
+ ...analysis.issues.map((issue) => `${issue.lineItemType}: ${issue.message}
191728
+ Trace ${issue.pcbTraceId}, layer ${issue.layer}, circuit JSON index ${issue.circuitJsonIndex}, route ${issue.startRouteIndex} -> ${issue.endRouteIndex}`)
191729
+ ].join(`
191730
+ `);
191731
+ return {
191732
+ output,
191733
+ analysis,
191734
+ svg: renderPcbStyleSvg(circuitJson, analysis.issues),
191735
+ svgPath
191736
+ };
191737
+ };
191738
+ var registerCheckPcbStyle = (program) => {
191739
+ program.commands.find((command) => command.name() === "check").command("pcb-style").description("Detect long odd-angle runs and unnecessary staircase routing").argument("[file]", "Path to the entry file or prebuilt circuit JSON").option("--json", "Print the analysis as JSON").option("--svg <file>", "Save a highlighted overview (default: checks/check-pcb-style/pcb.svg)").action(async (file, options = {}) => {
191740
+ try {
191741
+ const result = await checkPcbStyle(file, options);
191742
+ await mkdir2(path50.dirname(result.svgPath), { recursive: true });
191743
+ await writeFile(result.svgPath, result.svg);
191744
+ console.log(options.json ? JSON.stringify(result.analysis, null, 2) : result.output);
191745
+ const artifactMessage = `PCB style overview written to ${result.svgPath}`;
191746
+ if (options.json)
191747
+ console.error(artifactMessage);
191748
+ else
191749
+ console.log(artifactMessage);
191750
+ if (result.analysis.issues.length > 0)
191751
+ process.exitCode = 1;
191752
+ } catch (error) {
191753
+ console.error(error instanceof Error ? error.message : String(error));
191754
+ process.exitCode = 1;
191755
+ }
191756
+ });
191757
+ };
191758
+
191080
191759
  // cli/check/pin-specification/register.ts
191760
+ import { runAllPinSpecificationChecks } from "@tscircuit/checks";
191081
191761
  var checkPinSpecification = async (file) => {
191082
191762
  const resolvedInputFilePath = await resolveCheckInputFilePath(file);
191083
191763
  const typedCircuitJson = await getCircuitJsonForCheck({
@@ -269419,7 +270099,7 @@ expectTypesMatch("extra props b");
269419
270099
  expectTypesMatch("missing props b");
269420
270100
  expectTypesMatch(true);
269421
270101
  expectTypesMatch("property a has mismatched types");
269422
- var direction = external_exports.enum(["up", "down", "left", "right"]);
270102
+ var direction2 = external_exports.enum(["up", "down", "left", "right"]);
269423
270103
  var directionAlongEdge = external_exports.enum([
269424
270104
  "top-to-bottom",
269425
270105
  "left-to-right",
@@ -286976,7 +287656,7 @@ var portProps = commonLayoutProps.extend({
286976
287656
  layers: external_exports.array(external_exports.string()).optional(),
286977
287657
  schX: external_exports.number().optional(),
286978
287658
  schY: external_exports.number().optional(),
286979
- direction,
287659
+ direction: direction2,
286980
287660
  connectsTo: external_exports.string().or(external_exports.array(external_exports.string())).optional(),
286981
287661
  kicadPinMetadata: kicadPinMetadata.optional(),
286982
287662
  hasInversionCircle: external_exports.boolean().optional()
@@ -297606,7 +298286,7 @@ function formatSiUnit2(value) {
297606
298286
  return `${formatted}${prefix.symbol}`;
297607
298287
  }
297608
298288
  var import_debug10 = __toESM4(require_src2(), 1);
297609
- var BaseSolver = class {
298289
+ var BaseSolver4 = class {
297610
298290
  MAX_ITERATIONS = 1e5;
297611
298291
  solved = false;
297612
298292
  failed = false;
@@ -297687,7 +298367,7 @@ var BaseSolver = class {
297687
298367
  };
297688
298368
  }
297689
298369
  };
297690
- var BasePipelineSolver = class extends BaseSolver {
298370
+ var BasePipelineSolver2 = class extends BaseSolver4 {
297691
298371
  startTimeOfPhase = {};
297692
298372
  endTimeOfPhase = {};
297693
298373
  timeSpentOnPhase = {};
@@ -298184,7 +298864,7 @@ var makeNumbersRounded = (obj) => {
298184
298864
  }
298185
298865
  return obj;
298186
298866
  };
298187
- var BaseSolver2 = class {
298867
+ var BaseSolver22 = class {
298188
298868
  MAX_ITERATIONS = 1e5;
298189
298869
  solved = false;
298190
298870
  failed = false;
@@ -298274,7 +298954,7 @@ var BaseSolver2 = class {
298274
298954
  this.timeToSolve = endTime - startTime;
298275
298955
  }
298276
298956
  };
298277
- var MultiOffsetIrlsSolver = class extends BaseSolver2 {
298957
+ var MultiOffsetIrlsSolver = class extends BaseSolver22 {
298278
298958
  offsetPadPoints;
298279
298959
  targetPointMap;
298280
298960
  currentPosition;
@@ -298490,7 +299170,7 @@ var MultiOffsetIrlsSolver = class extends BaseSolver2 {
298490
299170
  return this.optimalPosition ?? this.currentPosition;
298491
299171
  }
298492
299172
  };
298493
- var TwoPhaseIrlsSolver = class extends BaseSolver2 {
299173
+ var TwoPhaseIrlsSolver = class extends BaseSolver22 {
298494
299174
  offsetPadPoints;
298495
299175
  targetPointMap;
298496
299176
  constraintFn;
@@ -298786,7 +299466,7 @@ function getOutwardNormal(outlineSegment, ccwFullOutline) {
298786
299466
  }
298787
299467
  return geometricOutward;
298788
299468
  }
298789
- var LargestRectOutsideOutlineFromPointSolver = class extends BaseSolver {
299469
+ var LargestRectOutsideOutlineFromPointSolver = class extends BaseSolver4 {
298790
299470
  ccwFullOutline;
298791
299471
  origin;
298792
299472
  globalBounds;
@@ -299140,7 +299820,7 @@ function isPointInPolygon(point9, polygon2) {
299140
299820
  }
299141
299821
  return inside2;
299142
299822
  }
299143
- var OutlineSegmentCandidatePointSolver = class extends BaseSolver {
299823
+ var OutlineSegmentCandidatePointSolver = class extends BaseSolver4 {
299144
299824
  outlineSegment;
299145
299825
  viableOutlineSegment = null;
299146
299826
  ccwFullOutline;
@@ -299764,7 +300444,7 @@ function checkOverlapWithPackedComponents({
299764
300444
  hasOverlap: false
299765
300445
  };
299766
300446
  }
299767
- var SingleComponentPackSolver = class extends BaseSolver {
300447
+ var SingleComponentPackSolver = class extends BaseSolver4 {
299768
300448
  componentToPack;
299769
300449
  packedComponents;
299770
300450
  packPlacementStrategy;
@@ -300309,7 +300989,7 @@ function getPolygonCentroid(points) {
300309
300989
  cy2 /= 6 * signedArea2;
300310
300990
  return { x: cx2, y: cy2 };
300311
300991
  }
300312
- var PackSolver2 = class extends BaseSolver {
300992
+ var PackSolver2 = class extends BaseSolver4 {
300313
300993
  packInput;
300314
300994
  unpackedComponentQueue = [];
300315
300995
  packedComponents = [];
@@ -301228,7 +301908,7 @@ var generateBRep = (pourPolygons) => {
301228
301908
  }
301229
301909
  return brep_shapes;
301230
301910
  };
301231
- var CopperPourPipelineSolver = class extends BasePipelineSolver {
301911
+ var CopperPourPipelineSolver = class extends BasePipelineSolver2 {
301232
301912
  constructor(input) {
301233
301913
  super(input);
301234
301914
  this.input = input;
@@ -304158,7 +304838,7 @@ var layoutSchematicGraphVariants = (variants, {
304158
304838
  };
304159
304839
  };
304160
304840
  var import_debug12 = __toESM4(require_src2(), 1);
304161
- var BaseSolver3 = class {
304841
+ var BaseSolver32 = class {
304162
304842
  MAX_ITERATIONS = 1e5;
304163
304843
  solved = false;
304164
304844
  failed = false;
@@ -304431,7 +305111,7 @@ function doBasicInputProblemLayout(inputProblem) {
304431
305111
  cachedProblems.set(problemHash, outputLayout);
304432
305112
  return structuredClone(outputLayout);
304433
305113
  }
304434
- var ChipPartitionsSolver = class extends BaseSolver3 {
305114
+ var ChipPartitionsSolver = class extends BaseSolver32 {
304435
305115
  inputProblem;
304436
305116
  partitions = [];
304437
305117
  decouplingCapGroups;
@@ -304604,7 +305284,7 @@ var getColorFromString = (string, alpha = 1) => {
304604
305284
  }
304605
305285
  return `hsl(${Math.abs(hash) % 360}, 70%, 50%, ${alpha})`;
304606
305286
  };
304607
- var IdentifyDecouplingCapsSolver = class extends BaseSolver3 {
305287
+ var IdentifyDecouplingCapsSolver = class extends BaseSolver32 {
304608
305288
  inputProblem;
304609
305289
  queuedChips;
304610
305290
  outputDecouplingCapGroups = [];
@@ -304894,7 +305574,7 @@ var getPadsBoundingBox = (pads) => {
304894
305574
  return { minX, maxX, minY, maxY };
304895
305575
  };
304896
305576
  var PIN_SIZE = 0.1;
304897
- var SingleInnerPartitionPackingSolver = class extends BaseSolver3 {
305577
+ var SingleInnerPartitionPackingSolver = class extends BaseSolver32 {
304898
305578
  partitionInputProblem;
304899
305579
  layout = null;
304900
305580
  pinIdToStronglyConnectedPins;
@@ -305002,7 +305682,7 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver3 {
305002
305682
  return [this.partitionInputProblem];
305003
305683
  }
305004
305684
  };
305005
- var PackInnerPartitionsSolver = class extends BaseSolver3 {
305685
+ var PackInnerPartitionsSolver = class extends BaseSolver32 {
305006
305686
  partitions;
305007
305687
  packedPartitions = [];
305008
305688
  completedSolvers = [];
@@ -305065,7 +305745,7 @@ var PackInnerPartitionsSolver = class extends BaseSolver3 {
305065
305745
  return [this.partitions];
305066
305746
  }
305067
305747
  };
305068
- var PartitionPackingSolver = class extends BaseSolver3 {
305748
+ var PartitionPackingSolver = class extends BaseSolver32 {
305069
305749
  packedPartitions;
305070
305750
  inputProblem;
305071
305751
  finalLayout = null;
@@ -305321,7 +306001,7 @@ var getPinIdToStronglyConnectedPinsObj = (inputProblem) => {
305321
306001
  }
305322
306002
  return pinIdToStronglyConnectedPins;
305323
306003
  };
305324
- function definePipelineStep(solverName, solverClass, getConstructorParams, opts = {}) {
306004
+ function definePipelineStep2(solverName, solverClass, getConstructorParams, opts = {}) {
305325
306005
  return {
305326
306006
  solverName,
305327
306007
  solverClass,
@@ -305329,7 +306009,7 @@ function definePipelineStep(solverName, solverClass, getConstructorParams, opts
305329
306009
  onSolved: opts.onSolved
305330
306010
  };
305331
306011
  }
305332
- var LayoutPipelineSolver = class extends BaseSolver3 {
306012
+ var LayoutPipelineSolver = class extends BaseSolver32 {
305333
306013
  identifyDecouplingCapsSolver;
305334
306014
  chipPartitionsSolver;
305335
306015
  packInnerPartitionsSolver;
@@ -305343,10 +306023,10 @@ var LayoutPipelineSolver = class extends BaseSolver3 {
305343
306023
  chipPartitions;
305344
306024
  packedPartitions;
305345
306025
  pipelineDef = [
305346
- definePipelineStep("identifyDecouplingCapsSolver", IdentifyDecouplingCapsSolver, () => [this.inputProblem], {
306026
+ definePipelineStep2("identifyDecouplingCapsSolver", IdentifyDecouplingCapsSolver, () => [this.inputProblem], {
305347
306027
  onSolved: (_layoutSolver) => {}
305348
306028
  }),
305349
- definePipelineStep("chipPartitionsSolver", ChipPartitionsSolver, () => [
306029
+ definePipelineStep2("chipPartitionsSolver", ChipPartitionsSolver, () => [
305350
306030
  {
305351
306031
  inputProblem: this.inputProblem,
305352
306032
  decouplingCapGroups: this.identifyDecouplingCapsSolver?.outputDecouplingCapGroups
@@ -305356,7 +306036,7 @@ var LayoutPipelineSolver = class extends BaseSolver3 {
305356
306036
  this.chipPartitions = this.chipPartitionsSolver.partitions;
305357
306037
  }
305358
306038
  }),
305359
- definePipelineStep("packInnerPartitionsSolver", PackInnerPartitionsSolver, () => [
306039
+ definePipelineStep2("packInnerPartitionsSolver", PackInnerPartitionsSolver, () => [
305360
306040
  {
305361
306041
  partitions: this.chipPartitions,
305362
306042
  pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
@@ -305366,7 +306046,7 @@ var LayoutPipelineSolver = class extends BaseSolver3 {
305366
306046
  this.packedPartitions = this.packInnerPartitionsSolver.packedPartitions;
305367
306047
  }
305368
306048
  }),
305369
- definePipelineStep("partitionPackingSolver", PartitionPackingSolver, () => [
306049
+ definePipelineStep2("partitionPackingSolver", PartitionPackingSolver, () => [
305370
306050
  {
305371
306051
  packedPartitions: this.packedPartitions || [],
305372
306052
  inputProblem: this.inputProblem
@@ -305642,7 +306322,7 @@ var ConnectivityMap2 = class {
305642
306322
  return true;
305643
306323
  }
305644
306324
  };
305645
- var BaseSolver4 = class {
306325
+ var BaseSolver42 = class {
305646
306326
  MAX_ITERATIONS = 1e5;
305647
306327
  solved = false;
305648
306328
  failed = false;
@@ -305995,7 +306675,7 @@ ${pin._facingDirection ?? getPinDirection2(pin, chip)}`,
305995
306675
  }
305996
306676
  return graphics;
305997
306677
  };
305998
- var MspConnectionPairSolver = class extends BaseSolver4 {
306678
+ var MspConnectionPairSolver = class extends BaseSolver42 {
305999
306679
  inputProblem;
306000
306680
  mspConnectionPairs = [];
306001
306681
  dcConnMap;
@@ -306324,7 +307004,7 @@ var pathKey = (pts, decimals = 6) => {
306324
307004
  const key = pts.map((p2) => `${p2.x.toFixed(decimals)},${p2.y.toFixed(decimals)}`).join("|");
306325
307005
  return key;
306326
307006
  };
306327
- var SchematicTraceSingleLineSolver2 = class extends BaseSolver4 {
307007
+ var SchematicTraceSingleLineSolver2 = class extends BaseSolver42 {
306328
307008
  pins;
306329
307009
  inputProblem;
306330
307010
  chipMap;
@@ -306488,7 +307168,7 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver4 {
306488
307168
  return g2;
306489
307169
  }
306490
307170
  };
306491
- var SchematicTraceLinesSolver = class extends BaseSolver4 {
307171
+ var SchematicTraceLinesSolver = class extends BaseSolver42 {
306492
307172
  inputProblem;
306493
307173
  mspConnectionPairs;
306494
307174
  dcConnMap;
@@ -306618,7 +307298,7 @@ var applyJogToTerminalSegment = ({
306618
307298
  }
306619
307299
  }
306620
307300
  };
306621
- var TraceOverlapIssueSolver = class extends BaseSolver4 {
307301
+ var TraceOverlapIssueSolver = class extends BaseSolver42 {
306622
307302
  overlappingTraceSegments;
306623
307303
  traceNetIslands;
306624
307304
  SHIFT_DISTANCE = 0.1;
@@ -306734,7 +307414,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver4 {
306734
307414
  return graphics;
306735
307415
  }
306736
307416
  };
306737
- var TraceOverlapShiftSolver = class extends BaseSolver4 {
307417
+ var TraceOverlapShiftSolver = class extends BaseSolver42 {
306738
307418
  inputProblem;
306739
307419
  inputTracePaths;
306740
307420
  globalConnMap;
@@ -307313,7 +307993,7 @@ function visualizeSingleNetLabelPlacementSolver(solver) {
307313
307993
  }
307314
307994
  return graphics;
307315
307995
  }
307316
- var SingleNetLabelPlacementSolver = class extends BaseSolver4 {
307996
+ var SingleNetLabelPlacementSolver = class extends BaseSolver42 {
307317
307997
  inputProblem;
307318
307998
  inputTraceMap;
307319
307999
  overlappingSameNetTraceGroup;
@@ -307525,7 +308205,7 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver4 {
307525
308205
  return visualizeSingleNetLabelPlacementSolver(this);
307526
308206
  }
307527
308207
  };
307528
- var NetLabelPlacementSolver = class extends BaseSolver4 {
308208
+ var NetLabelPlacementSolver = class extends BaseSolver42 {
307529
308209
  inputProblem;
307530
308210
  inputTraceMap;
307531
308211
  overlappingSameNetTraceGroups;
@@ -307739,7 +308419,7 @@ var NetLabelPlacementSolver = class extends BaseSolver4 {
307739
308419
  return graphics;
307740
308420
  }
307741
308421
  };
307742
- var MergedNetLabelObstacleSolver = class extends BaseSolver4 {
308422
+ var MergedNetLabelObstacleSolver = class extends BaseSolver42 {
307743
308423
  input;
307744
308424
  output;
307745
308425
  inputProblem;
@@ -308117,7 +308797,7 @@ var generateRerouteCandidates = ({
308117
308797
  });
308118
308798
  return [...fourPointCandidates, ...snipReconnectCandidates];
308119
308799
  };
308120
- var SingleOverlapSolver = class extends BaseSolver4 {
308800
+ var SingleOverlapSolver = class extends BaseSolver42 {
308121
308801
  queuedCandidatePaths;
308122
308802
  solvedTracePath = null;
308123
308803
  initialTrace;
@@ -308191,7 +308871,7 @@ var SingleOverlapSolver = class extends BaseSolver4 {
308191
308871
  return graphics;
308192
308872
  }
308193
308873
  };
308194
- var OverlapAvoidanceStepSolver = class extends BaseSolver4 {
308874
+ var OverlapAvoidanceStepSolver = class extends BaseSolver42 {
308195
308875
  inputProblem;
308196
308876
  netLabelPlacements;
308197
308877
  mergedLabelNetIdMap;
@@ -308289,7 +308969,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver4 {
308289
308969
  return graphics;
308290
308970
  }
308291
308971
  };
308292
- var TraceLabelOverlapAvoidanceSolver = class extends BaseSolver4 {
308972
+ var TraceLabelOverlapAvoidanceSolver = class extends BaseSolver42 {
308293
308973
  inputProblem;
308294
308974
  traces;
308295
308975
  netLabelPlacements;
@@ -308443,7 +309123,7 @@ var NEAREST_NEIGHBOR_COUNT = 3;
308443
309123
  var distance48 = (p1, p2) => {
308444
309124
  return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
308445
309125
  };
308446
- var LongDistancePairSolver = class extends BaseSolver4 {
309126
+ var LongDistancePairSolver = class extends BaseSolver42 {
308447
309127
  constructor(params2) {
308448
309128
  super();
308449
309129
  this.params = params2;
@@ -309254,7 +309934,7 @@ var visualizeCollision = (collisionInfo) => {
309254
309934
  }
309255
309935
  return collisionGraphics;
309256
309936
  };
309257
- var UntangleTraceSubsolver = class extends BaseSolver4 {
309937
+ var UntangleTraceSubsolver = class extends BaseSolver42 {
309258
309938
  input;
309259
309939
  lShapesToProcess = [];
309260
309940
  visualizationMode = "l_shapes";
@@ -309487,7 +310167,7 @@ var is4PointRectangle = (path) => {
309487
310167
  const isVHVC = p0.x === p1.x && p1.y === p2.y && p2.x === p3.x && p0.y === p3.y;
309488
310168
  return isHVHC || isVHVC;
309489
310169
  };
309490
- var TraceCleanupSolver = class extends BaseSolver4 {
310170
+ var TraceCleanupSolver = class extends BaseSolver42 {
309491
310171
  input;
309492
310172
  outputTraces;
309493
310173
  traceIdQueue;
@@ -309608,7 +310288,7 @@ var TraceCleanupSolver = class extends BaseSolver4 {
309608
310288
  return graphics;
309609
310289
  }
309610
310290
  };
309611
- function definePipelineStep2(solverName, solverClass, getConstructorParams, opts = {}) {
310291
+ function definePipelineStep22(solverName, solverClass, getConstructorParams, opts = {}) {
309612
310292
  return {
309613
310293
  solverName,
309614
310294
  solverClass,
@@ -309617,7 +310297,7 @@ function definePipelineStep2(solverName, solverClass, getConstructorParams, opts
309617
310297
  shouldSkip: opts.shouldSkip
309618
310298
  };
309619
310299
  }
309620
- var SchematicTracePipelineSolver = class extends BaseSolver4 {
310300
+ var SchematicTracePipelineSolver = class extends BaseSolver42 {
309621
310301
  mspConnectionPairSolver;
309622
310302
  schematicTraceLinesSolver;
309623
310303
  longDistancePairSolver;
@@ -309632,10 +310312,10 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309632
310312
  firstIterationOfPhase;
309633
310313
  inputProblem;
309634
310314
  pipelineDef = [
309635
- definePipelineStep2("mspConnectionPairSolver", MspConnectionPairSolver, () => [{ inputProblem: this.inputProblem }], {
310315
+ definePipelineStep22("mspConnectionPairSolver", MspConnectionPairSolver, () => [{ inputProblem: this.inputProblem }], {
309636
310316
  onSolved: (mspSolver) => {}
309637
310317
  }),
309638
- definePipelineStep2("schematicTraceLinesSolver", SchematicTraceLinesSolver, () => [
310318
+ definePipelineStep22("schematicTraceLinesSolver", SchematicTraceLinesSolver, () => [
309639
310319
  {
309640
310320
  mspConnectionPairs: this.mspConnectionPairSolver.mspConnectionPairs,
309641
310321
  dcConnMap: this.mspConnectionPairSolver.dcConnMap,
@@ -309644,7 +310324,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309644
310324
  chipMap: this.mspConnectionPairSolver.chipMap
309645
310325
  }
309646
310326
  ]),
309647
- definePipelineStep2("longDistancePairSolver", LongDistancePairSolver, (instance) => [
310327
+ definePipelineStep22("longDistancePairSolver", LongDistancePairSolver, (instance) => [
309648
310328
  {
309649
310329
  inputProblem: instance.inputProblem,
309650
310330
  primaryMspConnectionPairs: instance.mspConnectionPairSolver.mspConnectionPairs,
@@ -309653,7 +310333,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309653
310333
  ], {
309654
310334
  onSolved: (schematicTraceLinesSolver) => {}
309655
310335
  }),
309656
- definePipelineStep2("traceOverlapShiftSolver", TraceOverlapShiftSolver, () => [
310336
+ definePipelineStep22("traceOverlapShiftSolver", TraceOverlapShiftSolver, () => [
309657
310337
  {
309658
310338
  inputProblem: this.inputProblem,
309659
310339
  inputTracePaths: this.longDistancePairSolver?.getOutput().allTracesMerged,
@@ -309662,7 +310342,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309662
310342
  ], {
309663
310343
  onSolved: (_solver) => {}
309664
310344
  }),
309665
- definePipelineStep2("netLabelPlacementSolver", NetLabelPlacementSolver, () => [
310345
+ definePipelineStep22("netLabelPlacementSolver", NetLabelPlacementSolver, () => [
309666
310346
  {
309667
310347
  inputProblem: this.inputProblem,
309668
310348
  inputTraceMap: this.traceOverlapShiftSolver?.correctedTraceMap ?? Object.fromEntries(this.longDistancePairSolver.getOutput().allTracesMerged.map((p2) => [p2.mspPairId, p2]))
@@ -309670,7 +310350,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309670
310350
  ], {
309671
310351
  onSolved: (_solver) => {}
309672
310352
  }),
309673
- definePipelineStep2("traceLabelOverlapAvoidanceSolver", TraceLabelOverlapAvoidanceSolver, (instance) => {
310353
+ definePipelineStep22("traceLabelOverlapAvoidanceSolver", TraceLabelOverlapAvoidanceSolver, (instance) => {
309674
310354
  const traceMap = instance.traceOverlapShiftSolver?.correctedTraceMap ?? Object.fromEntries(instance.longDistancePairSolver.getOutput().allTracesMerged.map((p2) => [p2.mspPairId, p2]));
309675
310355
  const traces = Object.values(traceMap);
309676
310356
  const netLabelPlacements = instance.netLabelPlacementSolver.netLabelPlacements;
@@ -309682,7 +310362,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309682
310362
  }
309683
310363
  ];
309684
310364
  }),
309685
- definePipelineStep2("traceCleanupSolver", TraceCleanupSolver, (instance) => {
310365
+ definePipelineStep22("traceCleanupSolver", TraceCleanupSolver, (instance) => {
309686
310366
  const prevSolverOutput = instance.traceLabelOverlapAvoidanceSolver.getOutput();
309687
310367
  const traces = prevSolverOutput.traces;
309688
310368
  const labelMergingOutput = instance.traceLabelOverlapAvoidanceSolver.labelMergingSolver.getOutput();
@@ -309696,7 +310376,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver4 {
309696
310376
  }
309697
310377
  ];
309698
310378
  }),
309699
- definePipelineStep2("netLabelPlacementSolver", NetLabelPlacementSolver, (instance) => {
310379
+ definePipelineStep22("netLabelPlacementSolver", NetLabelPlacementSolver, (instance) => {
309700
310380
  const traces = instance.traceCleanupSolver?.getOutput().traces ?? instance.traceLabelOverlapAvoidanceSolver.getOutput().traces;
309701
310381
  return [
309702
310382
  {
@@ -338840,7 +339520,7 @@ svg-path-commander/dist/index.js:
338840
339520
  */
338841
339521
 
338842
339522
  // cli/check/routing-difficulty/register.ts
338843
- import path50 from "node:path";
339523
+ import path51 from "node:path";
338844
339524
  var checkRoutingDifficulty = async (file) => {
338845
339525
  const resolvedInputFilePath = await resolveCheckInputFilePath(file);
338846
339526
  const circuitJson = await getCircuitJsonForCheck({
@@ -338854,7 +339534,7 @@ var checkRoutingDifficulty = async (file) => {
338854
339534
  const analysis = await analyzeRouting(circuitJson);
338855
339535
  const result = analysis.getString();
338856
339536
  if (!result) {
338857
- return `No congested regions in ${path50.basename(resolvedInputFilePath)}`;
339537
+ return `No congested regions in ${path51.basename(resolvedInputFilePath)}`;
338858
339538
  }
338859
339539
  return result;
338860
339540
  };
@@ -341243,8 +341923,8 @@ class CapacitorOrientationSolver extends BaseSolver21 {
341243
341923
  }
341244
341924
 
341245
341925
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/DecouplingCapacitorGroupingSolver/DecouplingCapacitorGroupingSolver.ts
341246
- import { BaseSolver as BaseSolver22 } from "@tscircuit/solver-utils";
341247
- class DecouplingCapacitorGroupingSolver extends BaseSolver22 {
341926
+ import { BaseSolver as BaseSolver23 } from "@tscircuit/solver-utils";
341927
+ class DecouplingCapacitorGroupingSolver extends BaseSolver23 {
341248
341928
  params;
341249
341929
  static MIN_BODY_GAP = 1;
341250
341930
  banks = [];
@@ -341388,8 +342068,8 @@ function getNetLabelBounds(label) {
341388
342068
  }
341389
342069
 
341390
342070
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/ComponentNetLabelCollisionSolver/ComponentNetLabelCollisionSolver.ts
341391
- import { BaseSolver as BaseSolver23 } from "@tscircuit/solver-utils";
341392
- class ComponentNetLabelCollisionSolver extends BaseSolver23 {
342071
+ import { BaseSolver as BaseSolver24 } from "@tscircuit/solver-utils";
342072
+ class ComponentNetLabelCollisionSolver extends BaseSolver24 {
341393
342073
  params;
341394
342074
  placements;
341395
342075
  netLabelsByComponentId;
@@ -341713,8 +342393,8 @@ class ComponentNetLabelCollisionSolver extends BaseSolver23 {
341713
342393
  }
341714
342394
 
341715
342395
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/ComponentPinAlignmentSolver/ComponentPinAlignmentSolver.ts
341716
- import { BaseSolver as BaseSolver24 } from "@tscircuit/solver-utils";
341717
- class ComponentPinAlignmentSolver extends BaseSolver24 {
342396
+ import { BaseSolver as BaseSolver25 } from "@tscircuit/solver-utils";
342397
+ class ComponentPinAlignmentSolver extends BaseSolver25 {
341718
342398
  static ALIGNMENT_EPSILON = 0.01;
341719
342399
  ctx;
341720
342400
  out;
@@ -341848,8 +342528,8 @@ class ComponentPinAlignmentSolver extends BaseSolver24 {
341848
342528
  }
341849
342529
 
341850
342530
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/CrystalLoadCapacitorPlacementSolver/CrystalLoadCapacitorPlacementSolver.ts
341851
- import { BaseSolver as BaseSolver25 } from "@tscircuit/solver-utils";
341852
- class CrystalLoadCapacitorPlacementSolver extends BaseSolver25 {
342531
+ import { BaseSolver as BaseSolver26 } from "@tscircuit/solver-utils";
342532
+ class CrystalLoadCapacitorPlacementSolver extends BaseSolver26 {
341853
342533
  static ALIGNMENT_TOLERANCE = 0.1;
341854
342534
  issues;
341855
342535
  networks;
@@ -342009,9 +342689,9 @@ var distance51 = (first, second) => Math.hypot(first.schX - second.schX, first.s
342009
342689
  var round2 = (value) => Math.round(value * 100) / 100;
342010
342690
 
342011
342691
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/DiodeResistorAlignmentSolver/DiodeResistorAlignmentSolver.ts
342012
- import { BaseSolver as BaseSolver26 } from "@tscircuit/solver-utils";
342692
+ import { BaseSolver as BaseSolver27 } from "@tscircuit/solver-utils";
342013
342693
  import { getSourcePortConnectivityMapFromCircuitJson as getSourcePortConnectivityMapFromCircuitJson2 } from "circuit-json-to-connectivity-map";
342014
- class DiodeResistorAlignmentSolver extends BaseSolver26 {
342694
+ class DiodeResistorAlignmentSolver extends BaseSolver27 {
342015
342695
  static DIODE_FTYPES = new Set(["simple_led", "simple_diode"]);
342016
342696
  ctx;
342017
342697
  out;
@@ -342177,8 +342857,8 @@ class DiodeResistorAlignmentSolver extends BaseSolver26 {
342177
342857
  }
342178
342858
 
342179
342859
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/FeedbackNetworkPlacementSolver/FeedbackNetworkPlacementSolver.ts
342180
- import { BaseSolver as BaseSolver27 } from "@tscircuit/solver-utils";
342181
- class FeedbackNetworkPlacementSolver extends BaseSolver27 {
342860
+ import { BaseSolver as BaseSolver28 } from "@tscircuit/solver-utils";
342861
+ class FeedbackNetworkPlacementSolver extends BaseSolver28 {
342182
342862
  static MIN_BODY_GAP = 4;
342183
342863
  index;
342184
342864
  amplifierIds;
@@ -342263,7 +342943,7 @@ function distanceBetweenBoxes(a, b) {
342263
342943
  }
342264
342944
 
342265
342945
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/PullResistorPlacementSolver/PullResistorPlacementSolver.ts
342266
- import { BaseSolver as BaseSolver28 } from "@tscircuit/solver-utils";
342946
+ import { BaseSolver as BaseSolver29 } from "@tscircuit/solver-utils";
342267
342947
 
342268
342948
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/switch-pull-resistor-pairs.ts
342269
342949
  function getSwitchPullResistorPairs(index) {
@@ -342327,7 +343007,7 @@ function getHorizontalPushbuttonComponentIds(index) {
342327
343007
  }
342328
343008
 
342329
343009
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/PullResistorPlacementSolver/PullResistorPlacementSolver.ts
342330
- class PullResistorPlacementSolver extends BaseSolver28 {
343010
+ class PullResistorPlacementSolver extends BaseSolver29 {
342331
343011
  static MIN_WRONG_SIDE_GAP = 1.5;
342332
343012
  index;
342333
343013
  resistorIds;
@@ -342427,8 +343107,8 @@ class PullResistorPlacementSolver extends BaseSolver28 {
342427
343107
  }
342428
343108
 
342429
343109
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentRailOrientationSolver/TwoPinComponentRailOrientationSolver.ts
342430
- import { BaseSolver as BaseSolver29 } from "@tscircuit/solver-utils";
342431
- class TwoPinComponentRailOrientationSolver extends BaseSolver29 {
343110
+ import { BaseSolver as BaseSolver30 } from "@tscircuit/solver-utils";
343111
+ class TwoPinComponentRailOrientationSolver extends BaseSolver30 {
342432
343112
  static EPSILON = 0.01;
342433
343113
  index;
342434
343114
  powerNets;
@@ -342743,8 +343423,8 @@ var polygonBounds = (polygons) => {
342743
343423
  };
342744
343424
 
342745
343425
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicBoxInnerLabelCollisionSolver/SchematicBoxInnerLabelCollisionSolver.ts
342746
- import { BaseSolver as BaseSolver30 } from "@tscircuit/solver-utils";
342747
- class SchematicBoxInnerLabelCollisionSolver extends BaseSolver30 {
343426
+ import { BaseSolver as BaseSolver31 } from "@tscircuit/solver-utils";
343427
+ class SchematicBoxInnerLabelCollisionSolver extends BaseSolver31 {
342748
343428
  params;
342749
343429
  entries;
342750
343430
  placementById;
@@ -342849,8 +343529,8 @@ class SchematicBoxInnerLabelCollisionSolver extends BaseSolver30 {
342849
343529
  }
342850
343530
 
342851
343531
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicBoxOverlapSolver/SchematicBoxOverlapSolver.ts
342852
- import { BaseSolver as BaseSolver31 } from "@tscircuit/solver-utils";
342853
- class SchematicBoxOverlapSolver extends BaseSolver31 {
343532
+ import { BaseSolver as BaseSolver33 } from "@tscircuit/solver-utils";
343533
+ class SchematicBoxOverlapSolver extends BaseSolver33 {
342854
343534
  params;
342855
343535
  placements;
342856
343536
  firstIndex = 0;
@@ -343109,8 +343789,8 @@ function contentsFit(resized, ports, labelBankGap = INNER_LABEL_COLLISION_PADDIN
343109
343789
  }
343110
343790
 
343111
343791
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicBoxTooWideSolver/SchematicBoxTooWideSolver.ts
343112
- import { BaseSolver as BaseSolver32 } from "@tscircuit/solver-utils";
343113
- class SchematicBoxTooWideSolver extends BaseSolver32 {
343792
+ import { BaseSolver as BaseSolver34 } from "@tscircuit/solver-utils";
343793
+ class SchematicBoxTooWideSolver extends BaseSolver34 {
343114
343794
  params;
343115
343795
  SCHEMATIC_BOX_TOO_WIDE_MESSAGE = "Shrink schematic box width";
343116
343796
  PIN_HEADER_MAX_ALLOWED_GAP = 0.1;
@@ -343270,8 +343950,8 @@ class SchematicBoxTooWideSolver extends BaseSolver32 {
343270
343950
  }
343271
343951
 
343272
343952
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicPinPaddingToEdgeSolver/SchematicPinPaddingToEdgeSolver.ts
343273
- import { BaseSolver as BaseSolver33 } from "@tscircuit/solver-utils";
343274
- class SchematicPinPaddingToEdgeSolver extends BaseSolver33 {
343953
+ import { BaseSolver as BaseSolver35 } from "@tscircuit/solver-utils";
343954
+ class SchematicPinPaddingToEdgeSolver extends BaseSolver35 {
343275
343955
  params;
343276
343956
  MESSAGE = "Move schematic pins closer to the box edge or change the schematic box";
343277
343957
  GAP_COMPARISON_EPSILON = 0.000000001;
@@ -343534,7 +344214,7 @@ class SchematicPinPaddingToEdgeSolver extends BaseSolver33 {
343534
344214
 
343535
344215
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicPlacementPipeline/SchematicPlacementPipeline.ts
343536
344216
  import {
343537
- BasePipelineSolver as BasePipelineSolver2,
344217
+ BasePipelineSolver as BasePipelineSolver3,
343538
344218
  definePipelineStep as definePipelineStep3
343539
344219
  } from "@tscircuit/solver-utils";
343540
344220
 
@@ -343642,8 +344322,8 @@ var buildSolverContext = (circuitJson) => {
343642
344322
  };
343643
344323
 
343644
344324
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SwitchPullResistorPlacementSolver/SwitchPullResistorPlacementSolver.ts
343645
- import { BaseSolver as BaseSolver34 } from "@tscircuit/solver-utils";
343646
- class SwitchPullResistorPlacementSolver extends BaseSolver34 {
344325
+ import { BaseSolver as BaseSolver36 } from "@tscircuit/solver-utils";
344326
+ class SwitchPullResistorPlacementSolver extends BaseSolver36 {
343647
344327
  params;
343648
344328
  constructor(params2) {
343649
344329
  super();
@@ -343712,8 +344392,8 @@ function getTraceName(circuitJson, trace) {
343712
344392
 
343713
344393
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TraceSimplificationSolver/TraceSimplificationSolver.ts
343714
344394
  import { calculateElbow as calculateElbow2 } from "calculate-elbow/lib";
343715
- import { BaseSolver as BaseSolver35 } from "@tscircuit/solver-utils";
343716
- class TraceSimplificationSolver extends BaseSolver35 {
344395
+ import { BaseSolver as BaseSolver37 } from "@tscircuit/solver-utils";
344396
+ class TraceSimplificationSolver extends BaseSolver37 {
343717
344397
  static EPSILON = 0.01;
343718
344398
  ctx;
343719
344399
  out;
@@ -344071,7 +344751,7 @@ class TraceSimplificationSolver extends BaseSolver35 {
344071
344751
  }
344072
344752
 
344073
344753
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentOrientationSolver/TwoPinComponentOrientationSolver.ts
344074
- import { BaseSolver as BaseSolver36 } from "@tscircuit/solver-utils";
344754
+ import { BaseSolver as BaseSolver38 } from "@tscircuit/solver-utils";
344075
344755
 
344076
344756
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentOrientationSolver/getPowerOrGroundConnectionIds.ts
344077
344757
  import {
@@ -344110,7 +344790,7 @@ function getPowerOrGroundConnectionIds(circuitJson) {
344110
344790
  }
344111
344791
 
344112
344792
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentOrientationSolver/TwoPinComponentOrientationSolver.ts
344113
- class TwoPinComponentOrientationSolver extends BaseSolver36 {
344793
+ class TwoPinComponentOrientationSolver extends BaseSolver38 {
344114
344794
  static EPSILON = 0.01;
344115
344795
  ctx;
344116
344796
  out;
@@ -344356,8 +345036,8 @@ class TwoPinComponentOrientationSolver extends BaseSolver36 {
344356
345036
  }
344357
345037
 
344358
345038
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/VerboseNetLabelSolver/VerboseNetLabelSolver.ts
344359
- import { BaseSolver as BaseSolver37 } from "@tscircuit/solver-utils";
344360
- class VerboseNetLabelSolver extends BaseSolver37 {
345039
+ import { BaseSolver as BaseSolver39 } from "@tscircuit/solver-utils";
345040
+ class VerboseNetLabelSolver extends BaseSolver39 {
344361
345041
  params;
344362
345042
  VERBOSE_NET_LABEL_MESSAGE = "Create trace with schDisplayLabel";
344363
345043
  netLabels;
@@ -344466,8 +345146,8 @@ class VerboseNetLabelSolver extends BaseSolver37 {
344466
345146
  }
344467
345147
 
344468
345148
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicTextClearanceSolver/SchematicTextClearanceSolver.ts
344469
- import { BaseSolver as BaseSolver38 } from "@tscircuit/solver-utils";
344470
- class SchematicTextClearanceSolver extends BaseSolver38 {
345149
+ import { BaseSolver as BaseSolver40 } from "@tscircuit/solver-utils";
345150
+ class SchematicTextClearanceSolver extends BaseSolver40 {
344471
345151
  params;
344472
345152
  texts;
344473
345153
  obstacles;
@@ -344619,8 +345299,8 @@ class SchematicTextClearanceSolver extends BaseSolver38 {
344619
345299
  }
344620
345300
 
344621
345301
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/ResetNetworkGroupingSolver/ResetNetworkGroupingSolver.ts
344622
- import { BaseSolver as BaseSolver39 } from "@tscircuit/solver-utils";
344623
- class ResetNetworkGroupingSolver extends BaseSolver39 {
345302
+ import { BaseSolver as BaseSolver41 } from "@tscircuit/solver-utils";
345303
+ class ResetNetworkGroupingSolver extends BaseSolver41 {
344624
345304
  params;
344625
345305
  static MIN_DISTANCE = 6;
344626
345306
  networks;
@@ -344826,7 +345506,7 @@ var solversByIssueType = {
344826
345506
  ]
344827
345507
  };
344828
345508
 
344829
- class SchematicPlacementPipeline extends BasePipelineSolver2 {
345509
+ class SchematicPlacementPipeline extends BasePipelineSolver3 {
344830
345510
  ctx;
344831
345511
  issues = [];
344832
345512
  pipelineDef = [
@@ -345463,8 +346143,8 @@ var registerCheckSchematicPlacement = (program) => {
345463
346143
  };
345464
346144
 
345465
346145
  // cli/check/shorts/register.ts
345466
- import { mkdir as mkdir2, writeFile } from "node:fs/promises";
345467
- import path51 from "node:path";
346146
+ import { mkdir as mkdir3, writeFile as writeFile2 } from "node:fs/promises";
346147
+ import path52 from "node:path";
345468
346148
  import { all_layers as all_layers2, layer_string } from "circuit-json";
345469
346149
 
345470
346150
  // cli/check/shorts/get-check-short-layers.ts
@@ -345550,8 +346230,8 @@ var formatShort = (short, index) => {
345550
346230
  ].join(`
345551
346231
  `);
345552
346232
  };
345553
- var getShortArtifactOutputPath = () => path51.resolve(process.cwd(), "checks", "check-shorts", "bitmap.png");
345554
- var getShortPcbSnapshotOutputPath = () => path51.resolve(process.cwd(), "checks", "check-shorts", "pcb.svg");
346233
+ var getShortArtifactOutputPath = () => path52.resolve(process.cwd(), "checks", "check-shorts", "bitmap.png");
346234
+ var getShortPcbSnapshotOutputPath = () => path52.resolve(process.cwd(), "checks", "check-shorts", "pcb.svg");
345555
346235
  var checkShorts = async (file, options = {}) => {
345556
346236
  const resolvedInputFilePath = await resolveCheckInputFilePath(file);
345557
346237
  const mode = parseMode(options.mode);
@@ -345578,7 +346258,7 @@ var checkShorts = async (file, options = {}) => {
345578
346258
  pixelsPerMm
345579
346259
  })));
345580
346260
  const shorts = debugRenders.flatMap((debugRender) => debugRender.shorts);
345581
- const filename = path51.basename(resolvedInputFilePath);
346261
+ const filename = path52.basename(resolvedInputFilePath);
345582
346262
  if (shorts.length === 0) {
345583
346263
  return {
345584
346264
  output: `No shorts detected in ${filename}`,
@@ -345617,8 +346297,8 @@ var registerCheckShorts = (program) => {
345617
346297
  if (result.artifacts) {
345618
346298
  for (const artifact of result.artifacts) {
345619
346299
  const outputPath = artifact.defaultOutputPath;
345620
- await mkdir2(path51.dirname(outputPath), { recursive: true });
345621
- await writeFile(outputPath, artifact.content);
346300
+ await mkdir3(path52.dirname(outputPath), { recursive: true });
346301
+ await writeFile2(outputPath, artifact.content);
345622
346302
  console.log(`Short debug artifact written to ${outputPath}`);
345623
346303
  }
345624
346304
  }
@@ -345664,16 +346344,16 @@ var registerCheckSource = (program) => {
345664
346344
  };
345665
346345
 
345666
346346
  // cli/check/trace-length/register.ts
345667
- import path52 from "node:path";
346347
+ import path53 from "node:path";
345668
346348
  var loadTraceLengthAnalyzer = async () => {
345669
- const mod = await Promise.resolve().then(() => (init_lib2(), {}));
346349
+ const mod = await Promise.resolve().then(() => (init_lib3(), {}));
345670
346350
  return analyzeCircuitJsonTraceLength;
345671
346351
  };
345672
346352
  var getAutorouterDiagnosticsOptions = (options = {}) => {
345673
346353
  const timeoutMs = options.autorouterTimeout ? parseAutorouterTimeout(options.autorouterTimeout) : undefined;
345674
346354
  const phaseName = options.autorouterPhase !== undefined ? parseAutorouterPhaseName(options.autorouterPhase) : undefined;
345675
346355
  const dumpSrj = parseAutorouterDumpSrjMode(options.autorouterDumpSrj);
345676
- const debugDir = options.autorouterDebugDir ? path52.resolve(process.cwd(), options.autorouterDebugDir) : path52.resolve(process.cwd(), "dist", "autorouter-debug");
346356
+ const debugDir = options.autorouterDebugDir ? path53.resolve(process.cwd(), options.autorouterDebugDir) : path53.resolve(process.cwd(), "dist", "autorouter-debug");
345677
346357
  return {
345678
346358
  enabled: options.autorouterDebug || phaseName !== undefined,
345679
346359
  phaseName,
@@ -345715,25 +346395,25 @@ var registerCheckTraceLength = (program) => {
345715
346395
 
345716
346396
  // cli/clone/register.ts
345717
346397
  import * as fs49 from "node:fs";
345718
- import * as path55 from "node:path";
346398
+ import * as path56 from "node:path";
345719
346399
 
345720
346400
  // cli/clone/clone-bug-report.ts
345721
346401
  var import_jszip3 = __toESM3(require_lib4(), 1);
345722
346402
  var import_prompts5 = __toESM3(require_prompts3(), 1);
345723
346403
  import * as fs48 from "node:fs";
345724
- import * as path54 from "node:path";
346404
+ import * as path55 from "node:path";
345725
346405
 
345726
346406
  // cli/clone/handle-existing-directory.ts
345727
346407
  var import_prompts4 = __toESM3(require_prompts3(), 1);
345728
346408
  import * as fs47 from "node:fs";
345729
- import * as path53 from "node:path";
346409
+ import * as path54 from "node:path";
345730
346410
  var handleExistingDirectory = async (dirPath) => {
345731
346411
  if (!fs47.existsSync(dirPath))
345732
346412
  return;
345733
346413
  const response = await import_prompts4.default({
345734
346414
  type: "select",
345735
346415
  name: "action",
345736
- message: `Directory "${path53.basename(dirPath)}" already exists. What would you like to do?`,
346416
+ message: `Directory "${path54.basename(dirPath)}" already exists. What would you like to do?`,
345737
346417
  choices: [
345738
346418
  { title: "Merge files into existing directory", value: "merge" },
345739
346419
  {
@@ -345774,12 +346454,12 @@ var getCommonDirectoryPrefix = (paths) => {
345774
346454
  return commonSegments.join("/");
345775
346455
  };
345776
346456
  var sanitizeRelativePath = (relativePath) => {
345777
- const normalizedPath = path54.normalize(relativePath);
346457
+ const normalizedPath = path55.normalize(relativePath);
345778
346458
  if (!normalizedPath)
345779
346459
  return null;
345780
- if (path54.isAbsolute(normalizedPath))
346460
+ if (path55.isAbsolute(normalizedPath))
345781
346461
  return null;
345782
- const segments = normalizedPath.split(path54.sep);
346462
+ const segments = normalizedPath.split(path55.sep);
345783
346463
  if (segments.some((segment) => segment === ".." || segment === "")) {
345784
346464
  return null;
345785
346465
  }
@@ -345794,7 +346474,7 @@ var cloneBugReport = async ({
345794
346474
  console.error("Bug report ID must not be empty.");
345795
346475
  process.exit(1);
345796
346476
  }
345797
- let dirPath = path54.resolve(`bug-report-${trimmedBugReportId}`);
346477
+ let dirPath = path55.resolve(`bug-report-${trimmedBugReportId}`);
345798
346478
  await handleExistingDirectory(dirPath);
345799
346479
  const ky = getRegistryApiKy();
345800
346480
  let zipBuffer;
@@ -345824,25 +346504,25 @@ var cloneBugReport = async ({
345824
346504
  console.warn(`Skipping potentially unsafe path: ${fileName}`);
345825
346505
  continue;
345826
346506
  }
345827
- const fullPath = path54.join(dirPath, sanitizedRelativePath);
345828
- fs48.mkdirSync(path54.dirname(fullPath), { recursive: true });
346507
+ const fullPath = path55.join(dirPath, sanitizedRelativePath);
346508
+ fs48.mkdirSync(path55.dirname(fullPath), { recursive: true });
345829
346509
  const fileContent = await entry.async("nodebuffer");
345830
346510
  fs48.writeFileSync(fullPath, fileContent);
345831
346511
  }
345832
- const packageJsonPath = path54.join(dirPath, "package.json");
346512
+ const packageJsonPath = path55.join(dirPath, "package.json");
345833
346513
  if (fs48.existsSync(packageJsonPath)) {
345834
346514
  try {
345835
346515
  const packageJson = JSON.parse(fs48.readFileSync(packageJsonPath, "utf-8"));
345836
346516
  const packageName = packageJson?.name;
345837
346517
  if (typeof packageName === "string" && packageName.trim()) {
345838
346518
  const sanitizedName = packageName.replace(/[^a-zA-Z0-9]/g, "_");
345839
- const suggestedDirPath = path54.resolve(`${sanitizedName}_${trimmedBugReportId.slice(7)}`);
346519
+ const suggestedDirPath = path55.resolve(`${sanitizedName}_${trimmedBugReportId.slice(7)}`);
345840
346520
  if (suggestedDirPath !== dirPath) {
345841
346521
  const response = await import_prompts5.default({
345842
346522
  type: "confirm",
345843
346523
  name: "rename",
345844
346524
  initial: true,
345845
- message: `Rename the directory to "${path54.basename(suggestedDirPath)}"?`
346525
+ message: `Rename the directory to "${path55.basename(suggestedDirPath)}"?`
345846
346526
  });
345847
346527
  if (response.rename) {
345848
346528
  await handleExistingDirectory(suggestedDirPath);
@@ -345855,9 +346535,9 @@ var cloneBugReport = async ({
345855
346535
  console.warn("Unable to read package name for renaming:", error);
345856
346536
  }
345857
346537
  }
345858
- fs48.writeFileSync(path54.join(dirPath, ".npmrc"), "@tsci:registry=https://npm.tscircuit.com");
346538
+ fs48.writeFileSync(path55.join(dirPath, ".npmrc"), "@tsci:registry=https://npm.tscircuit.com");
345859
346539
  generateTsConfig(dirPath);
345860
- const relativeDirPath = path54.relative(originalCwd, dirPath);
346540
+ const relativeDirPath = path55.relative(originalCwd, dirPath);
345861
346541
  console.log(kleur_default.green(`
345862
346542
  Successfully cloned bug report to:`));
345863
346543
  console.log(` ${dirPath}/
@@ -345896,7 +346576,7 @@ var registerClone = (program) => {
345896
346576
  const [, author, packageName] = match;
345897
346577
  console.log(`Cloning ${author}/${packageName}...`);
345898
346578
  const userSettingToIncludeAuthor = options.includeAuthor || cliConfig.get("alwaysCloneWithAuthorName");
345899
- const dirPath = userSettingToIncludeAuthor ? path55.resolve(`${author}.${packageName}`) : path55.resolve(packageName);
346579
+ const dirPath = userSettingToIncludeAuthor ? path56.resolve(`${author}.${packageName}`) : path56.resolve(packageName);
345900
346580
  await handleExistingDirectory(dirPath);
345901
346581
  const ky = getRegistryApiKy();
345902
346582
  let packageFileList = {
@@ -345922,8 +346602,8 @@ var registerClone = (program) => {
345922
346602
  const filePath = fileInfo.file_path.replace(/^\/+/, "");
345923
346603
  if (!filePath)
345924
346604
  continue;
345925
- const fullPath = path55.join(dirPath, filePath);
345926
- fs49.mkdirSync(path55.dirname(fullPath), { recursive: true });
346605
+ const fullPath = path56.join(dirPath, filePath);
346606
+ fs49.mkdirSync(path56.dirname(fullPath), { recursive: true });
345927
346607
  try {
345928
346608
  const fileContent = await ky.get("package_files/get", {
345929
346609
  searchParams: {
@@ -345949,10 +346629,10 @@ var registerClone = (program) => {
345949
346629
  console.warn(`Skipping ${filePath} due to error:`, error instanceof Error ? error.message : error);
345950
346630
  }
345951
346631
  }
345952
- fs49.writeFileSync(path55.join(dirPath, ".npmrc"), "@tsci:registry=https://npm.tscircuit.com");
346632
+ fs49.writeFileSync(path56.join(dirPath, ".npmrc"), "@tsci:registry=https://npm.tscircuit.com");
345953
346633
  generateTsConfig(dirPath);
345954
346634
  await setupTsciProject(dirPath);
345955
- const relativeDirPath = path55.relative(originalCwd, dirPath);
346635
+ const relativeDirPath = path56.relative(originalCwd, dirPath);
345956
346636
  console.log(kleur_default.green(`
345957
346637
  Successfully cloned to:`));
345958
346638
  console.log(` ${dirPath}/
@@ -346019,7 +346699,7 @@ var registerConfigSet = (program) => {
346019
346699
  };
346020
346700
 
346021
346701
  // cli/convert/register.ts
346022
- import path60 from "node:path";
346702
+ import path61 from "node:path";
346023
346703
 
346024
346704
  // node_modules/@tscircuit/mm/dist/index.js
346025
346705
  var unitToMm2 = {
@@ -346931,16 +347611,16 @@ var convertCircuitJsonToTscircuit = (circuitJson, opts) => {
346931
347611
 
346932
347612
  // cli/convert/convert-kicad-footprint-to-tsx.ts
346933
347613
  import fs51 from "node:fs/promises";
346934
- import path57 from "node:path";
347614
+ import path58 from "node:path";
346935
347615
 
346936
347616
  // cli/convert/convert-kicad-footprint-to-circuit-json.ts
346937
347617
  import fs50 from "node:fs/promises";
346938
- import path56 from "node:path";
347618
+ import path57 from "node:path";
346939
347619
  import { KicadFootprintToCircuitJsonConverter } from "kicad-to-circuit-json";
346940
347620
  var convertKicadFootprintToCircuitJson = async (inputPath) => {
346941
347621
  const modContent = await fs50.readFile(inputPath, "utf-8");
346942
347622
  const converter = new KicadFootprintToCircuitJsonConverter;
346943
- converter.addFile(path56.basename(inputPath), modContent);
347623
+ converter.addFile(path57.basename(inputPath), modContent);
346944
347624
  converter.runUntilFinished();
346945
347625
  return converter.getOutput();
346946
347626
  };
@@ -346952,9 +347632,9 @@ var convertKicadFootprintToTsx = async ({
346952
347632
  output
346953
347633
  }) => {
346954
347634
  const circuitJson = await convertKicadFootprintToCircuitJson(inputPath);
346955
- const componentName = name ?? path57.basename(inputPath, ".kicad_mod");
347635
+ const componentName = name ?? path58.basename(inputPath, ".kicad_mod");
346956
347636
  const tsx = convertCircuitJsonToTscircuit(circuitJson, { componentName });
346957
- const outputPath = output ? path57.resolve(output) : path57.join(path57.dirname(inputPath), `${componentName}.tsx`);
347637
+ const outputPath = output ? path58.resolve(output) : path58.join(path58.dirname(inputPath), `${componentName}.tsx`);
346958
347638
  await fs51.writeFile(outputPath, tsx);
346959
347639
  console.log(kleur_default.green(`Converted ${outputPath}`));
346960
347640
  };
@@ -353076,14 +353756,14 @@ var circuitJsonToFootprinter2 = circuitJsonToFootprinter;
353076
353756
 
353077
353757
  // cli/convert/discover-footprinter-from-file.ts
353078
353758
  import fs53 from "node:fs/promises";
353079
- import path59 from "node:path";
353759
+ import path60 from "node:path";
353080
353760
 
353081
353761
  // cli/convert/load-circuit-json-for-footprinter.ts
353082
353762
  import fs52 from "node:fs/promises";
353083
- import path58 from "node:path";
353763
+ import path59 from "node:path";
353084
353764
  var componentExtensions = new Set([".js", ".jsx", ".ts", ".tsx"]);
353085
353765
  var loadCircuitJsonForFootprinter = async (inputPath) => {
353086
- const extension = path58.extname(inputPath).toLowerCase();
353766
+ const extension = path59.extname(inputPath).toLowerCase();
353087
353767
  if (inputPath.toLowerCase().endsWith(".circuit.json")) {
353088
353768
  const parsed = JSON.parse(await fs52.readFile(inputPath, "utf-8"));
353089
353769
  if (!Array.isArray(parsed)) {
@@ -353120,7 +353800,7 @@ var discoverFootprinterFromFile = async ({
353120
353800
  const circuitJson = await loadCircuitJsonForFootprinter(inputPath);
353121
353801
  const inputText = await fs53.readFile(inputPath, "utf-8");
353122
353802
  const result = circuitJsonToFootprinter2(circuitJson, {
353123
- sourceHints: [path59.basename(inputPath), inputText.slice(0, 20000)]
353803
+ sourceHints: [path60.basename(inputPath), inputText.slice(0, 20000)]
353124
353804
  });
353125
353805
  if (!result.best) {
353126
353806
  throw new Error("No compatible footprinter string was found");
@@ -353131,7 +353811,7 @@ var discoverFootprinterFromFile = async ({
353131
353811
  diagnostics: result.diagnostics
353132
353812
  }, null, 2) : result.best.footprinterString;
353133
353813
  if (output) {
353134
- const outputPath = path59.resolve(output);
353814
+ const outputPath = path60.resolve(output);
353135
353815
  await fs53.writeFile(outputPath, `${resultText}
353136
353816
  `);
353137
353817
  console.log(kleur_default.green(`Converted ${outputPath}`));
@@ -353147,8 +353827,8 @@ var discoverFootprinterFromFile = async ({
353147
353827
  var registerConvert = (program) => {
353148
353828
  program.command("convert").description("Convert .kicad_mod to TSX, or discover a footprinter string with --footprinter").argument("<file>", "Path to .kicad_mod, TSX component, or Circuit JSON").option("-o, --output <path>", "Output TSX, footprinter, or JSON path").option("-n, --name <component>", "TSX component name for .kicad_mod conversion").option("--footprinter", "Discover a footprinter string instead of converting to TSX").option("--json", "Output footprinter discovery details as JSON (requires --footprinter)").action(async (file, options) => {
353149
353829
  try {
353150
- const inputPath = path60.resolve(file);
353151
- const extension = path60.extname(inputPath).toLowerCase();
353830
+ const inputPath = path61.resolve(file);
353831
+ const extension = path61.extname(inputPath).toLowerCase();
353152
353832
  if (options.json && !options.footprinter) {
353153
353833
  throw new Error("--json requires --footprinter");
353154
353834
  }
@@ -353178,11 +353858,11 @@ var registerConvert = (program) => {
353178
353858
  // cli/dev/register.ts
353179
353859
  import * as fs60 from "node:fs";
353180
353860
  import * as net from "node:net";
353181
- import * as path69 from "node:path";
353861
+ import * as path70 from "node:path";
353182
353862
 
353183
353863
  // cli/dev/resolve-dev-target.ts
353184
353864
  import * as fs54 from "node:fs";
353185
- import * as path61 from "node:path";
353865
+ import * as path62 from "node:path";
353186
353866
  var findSelectableFiles = (projectDir) => {
353187
353867
  const boardFiles = findBoardFiles({ projectDir }).filter((file) => fs54.existsSync(file)).sort();
353188
353868
  if (boardFiles.length > 0) {
@@ -353192,15 +353872,15 @@ var findSelectableFiles = (projectDir) => {
353192
353872
  cwd: projectDir,
353193
353873
  ignore: DEFAULT_IGNORED_PATTERNS
353194
353874
  });
353195
- return files.map((file) => path61.resolve(projectDir, file)).filter((file) => fs54.existsSync(file)).sort();
353875
+ return files.map((file) => path62.resolve(projectDir, file)).filter((file) => fs54.existsSync(file)).sort();
353196
353876
  };
353197
353877
  var isValidDevFile = (filePath) => {
353198
353878
  return filePath.endsWith(".tsx") || filePath.endsWith(".ts") || isCircuitJsonFile(filePath);
353199
353879
  };
353200
353880
  var resolveDevTarget = async (file, cwd = process.cwd()) => {
353201
- let projectDir = path61.resolve(cwd);
353881
+ let projectDir = path62.resolve(cwd);
353202
353882
  if (file) {
353203
- const resolvedPath = path61.resolve(projectDir, file);
353883
+ const resolvedPath = path62.resolve(projectDir, file);
353204
353884
  if (fs54.existsSync(resolvedPath) && fs54.statSync(resolvedPath).isDirectory()) {
353205
353885
  projectDir = resolvedPath;
353206
353886
  const availableFiles = findSelectableFiles(projectDir);
@@ -353208,7 +353888,7 @@ var resolveDevTarget = async (file, cwd = process.cwd()) => {
353208
353888
  console.log(`No .tsx, .ts, .circuit.json, or circuit.json files found in ${projectDir}. Run 'tsci init' to bootstrap a basic project.`);
353209
353889
  return null;
353210
353890
  }
353211
- console.log("Selected file:", path61.relative(projectDir, availableFiles[0]));
353891
+ console.log("Selected file:", path62.relative(projectDir, availableFiles[0]));
353212
353892
  return { absolutePath: availableFiles[0], projectDir };
353213
353893
  }
353214
353894
  if (!fs54.existsSync(resolvedPath)) {
@@ -353234,13 +353914,13 @@ var resolveDevTarget = async (file, cwd = process.cwd()) => {
353234
353914
  console.log("No .tsx, .ts, .circuit.json, or circuit.json files found in the project. Run 'tsci init' to bootstrap a basic project.");
353235
353915
  return null;
353236
353916
  }
353237
- console.log("Selected file:", path61.relative(projectDir, availableFiles[0]));
353917
+ console.log("Selected file:", path62.relative(projectDir, availableFiles[0]));
353238
353918
  return { absolutePath: availableFiles[0], projectDir };
353239
353919
  };
353240
353920
 
353241
353921
  // lib/dev/DevServer.ts
353242
353922
  import fs59 from "node:fs";
353243
- import path68 from "node:path";
353923
+ import path69 from "node:path";
353244
353924
 
353245
353925
  // node_modules/chokidar/esm/index.js
353246
353926
  import { stat as statcb } from "fs";
@@ -354815,10 +355495,10 @@ import Debug3 from "debug";
354815
355495
 
354816
355496
  // lib/dependency-analysis/getNodeModuleDependencies.ts
354817
355497
  import * as ts4 from "typescript";
354818
- import * as path62 from "path";
355498
+ import * as path63 from "path";
354819
355499
  import * as fs55 from "fs";
354820
355500
  function getAllDependencyPackages(projectDir) {
354821
- const packageJsonPath = path62.join(projectDir, "package.json");
355501
+ const packageJsonPath = path63.join(projectDir, "package.json");
354822
355502
  const allPackages = new Set;
354823
355503
  if (!fs55.existsSync(packageJsonPath)) {
354824
355504
  return allPackages;
@@ -354839,7 +355519,7 @@ function getAllDependencyPackages(projectDir) {
354839
355519
  return allPackages;
354840
355520
  }
354841
355521
  function getNodeModuleImports(filePath) {
354842
- const absolutePath = path62.resolve(filePath);
355522
+ const absolutePath = path63.resolve(filePath);
354843
355523
  if (!fs55.existsSync(absolutePath)) {
354844
355524
  return [];
354845
355525
  }
@@ -354893,17 +355573,17 @@ function resolveNodeModuleImport({
354893
355573
  }) {
354894
355574
  const packageName = getPackageNameFromImport(importPath);
354895
355575
  const searchPaths = [
354896
- path62.join(projectDir, "node_modules", packageName)
355576
+ path63.join(projectDir, "node_modules", packageName)
354897
355577
  ];
354898
355578
  if (searchFromDir) {
354899
- let currentDir = path62.dirname(searchFromDir);
354900
- const projectDirNormalized = path62.normalize(projectDir);
355579
+ let currentDir = path63.dirname(searchFromDir);
355580
+ const projectDirNormalized = path63.normalize(projectDir);
354901
355581
  while (currentDir.startsWith(projectDirNormalized)) {
354902
- const candidatePath = path62.join(currentDir, "node_modules", packageName);
355582
+ const candidatePath = path63.join(currentDir, "node_modules", packageName);
354903
355583
  if (!searchPaths.includes(candidatePath)) {
354904
355584
  searchPaths.push(candidatePath);
354905
355585
  }
354906
- const parentDir = path62.dirname(currentDir);
355586
+ const parentDir = path63.dirname(currentDir);
354907
355587
  if (parentDir === currentDir)
354908
355588
  break;
354909
355589
  currentDir = parentDir;
@@ -354919,22 +355599,22 @@ function resolveNodeModuleImport({
354919
355599
  if (!packageDir) {
354920
355600
  return [];
354921
355601
  }
354922
- const packageJsonPath = path62.join(packageDir, "package.json");
355602
+ const packageJsonPath = path63.join(packageDir, "package.json");
354923
355603
  const hasPackageJson = fs55.existsSync(packageJsonPath);
354924
355604
  const packageJson = hasPackageJson ? JSON.parse(fs55.readFileSync(packageJsonPath, "utf-8")) : null;
354925
355605
  const resolvedFiles = [];
354926
355606
  if (importPath !== packageName) {
354927
355607
  const subpath = importPath.slice(packageName.length + 1);
354928
355608
  const possiblePaths = [
354929
- path62.join(packageDir, subpath),
354930
- path62.join(packageDir, `${subpath}.js`),
354931
- path62.join(packageDir, `${subpath}.mjs`),
354932
- path62.join(packageDir, `${subpath}.ts`),
354933
- path62.join(packageDir, `${subpath}.tsx`),
354934
- path62.join(packageDir, subpath, "index.js"),
354935
- path62.join(packageDir, subpath, "index.mjs"),
354936
- path62.join(packageDir, subpath, "index.ts"),
354937
- path62.join(packageDir, subpath, "index.tsx")
355609
+ path63.join(packageDir, subpath),
355610
+ path63.join(packageDir, `${subpath}.js`),
355611
+ path63.join(packageDir, `${subpath}.mjs`),
355612
+ path63.join(packageDir, `${subpath}.ts`),
355613
+ path63.join(packageDir, `${subpath}.tsx`),
355614
+ path63.join(packageDir, subpath, "index.js"),
355615
+ path63.join(packageDir, subpath, "index.mjs"),
355616
+ path63.join(packageDir, subpath, "index.ts"),
355617
+ path63.join(packageDir, subpath, "index.tsx")
354938
355618
  ];
354939
355619
  for (const p of possiblePaths) {
354940
355620
  if (fs55.existsSync(p) && fs55.statSync(p).isFile()) {
@@ -354969,22 +355649,22 @@ function resolveNodeModuleImport({
354969
355649
  resolveExportValue(packageJson.exports?.["."]?.require)
354970
355650
  ].filter((entry) => typeof entry === "string");
354971
355651
  for (const entry of entryPoints) {
354972
- const entryPath = path62.join(packageDir, entry);
355652
+ const entryPath = path63.join(packageDir, entry);
354973
355653
  if (fs55.existsSync(entryPath) && fs55.statSync(entryPath).isFile()) {
354974
355654
  resolvedFiles.push(entryPath);
354975
355655
  }
354976
355656
  }
354977
355657
  if (resolvedFiles.length === 0) {
354978
355658
  const fallbackPaths = [
354979
- path62.join(packageDir, "index.js"),
354980
- path62.join(packageDir, "index.mjs"),
354981
- path62.join(packageDir, "index.ts"),
354982
- path62.join(packageDir, "index.tsx"),
354983
- path62.join(packageDir, "dist", "index.js"),
354984
- path62.join(packageDir, "dist", "index.mjs"),
354985
- path62.join(packageDir, "lib", "index.js"),
354986
- path62.join(packageDir, "src", "index.ts"),
354987
- path62.join(packageDir, "src", "index.tsx")
355659
+ path63.join(packageDir, "index.js"),
355660
+ path63.join(packageDir, "index.mjs"),
355661
+ path63.join(packageDir, "index.ts"),
355662
+ path63.join(packageDir, "index.tsx"),
355663
+ path63.join(packageDir, "dist", "index.js"),
355664
+ path63.join(packageDir, "dist", "index.mjs"),
355665
+ path63.join(packageDir, "lib", "index.js"),
355666
+ path63.join(packageDir, "src", "index.ts"),
355667
+ path63.join(packageDir, "src", "index.tsx")
354988
355668
  ];
354989
355669
  for (const p of fallbackPaths) {
354990
355670
  if (fs55.existsSync(p) && fs55.statSync(p).isFile()) {
@@ -355025,8 +355705,8 @@ function collectAllNodeModuleDependencies(entryFilePath, projectDir, maxDepth =
355025
355705
  }
355026
355706
  }
355027
355707
  function getLocalDependencies(filePath) {
355028
- const absolutePath = path62.resolve(filePath);
355029
- const baseDir = path62.dirname(absolutePath);
355708
+ const absolutePath = path63.resolve(filePath);
355709
+ const baseDir = path63.dirname(absolutePath);
355030
355710
  if (!fs55.existsSync(absolutePath)) {
355031
355711
  return [];
355032
355712
  }
@@ -355052,7 +355732,7 @@ function collectAllNodeModuleDependencies(entryFilePath, projectDir, maxDepth =
355052
355732
  }
355053
355733
  function resolveLocalImport(importPath, baseDir) {
355054
355734
  const extensions = [".tsx", ".ts", ".jsx", ".js", ".mjs"];
355055
- const resolvedPath = path62.resolve(baseDir, importPath);
355735
+ const resolvedPath = path63.resolve(baseDir, importPath);
355056
355736
  if (fs55.existsSync(resolvedPath) && fs55.statSync(resolvedPath).isFile()) {
355057
355737
  return resolvedPath;
355058
355738
  }
@@ -355064,7 +355744,7 @@ function collectAllNodeModuleDependencies(entryFilePath, projectDir, maxDepth =
355064
355744
  }
355065
355745
  if (fs55.existsSync(resolvedPath) && fs55.statSync(resolvedPath).isDirectory()) {
355066
355746
  for (const ext of extensions) {
355067
- const indexPath = path62.join(resolvedPath, `index${ext}`);
355747
+ const indexPath = path63.join(resolvedPath, `index${ext}`);
355068
355748
  if (fs55.existsSync(indexPath)) {
355069
355749
  return indexPath;
355070
355750
  }
@@ -355090,11 +355770,11 @@ var EXCLUDED_PACKAGE_DIRECTORIES = new Set([
355090
355770
  function collectLocalPackageFiles(packageDir) {
355091
355771
  const buildDirs = ["dist", "build"];
355092
355772
  for (const dirName of buildDirs) {
355093
- const dirPath = path62.join(packageDir, dirName);
355773
+ const dirPath = path63.join(packageDir, dirName);
355094
355774
  if (fs55.existsSync(dirPath)) {
355095
355775
  const files = walkDirectory(dirPath, new Set);
355096
355776
  if (files.length > 0) {
355097
- const packageJsonPath = path62.join(packageDir, "package.json");
355777
+ const packageJsonPath = path63.join(packageDir, "package.json");
355098
355778
  if (fs55.existsSync(packageJsonPath)) {
355099
355779
  files.push(packageJsonPath);
355100
355780
  }
@@ -355110,7 +355790,7 @@ function walkDirectory(dir, excludedDirs) {
355110
355790
  return files;
355111
355791
  const entries = fs55.readdirSync(dir, { withFileTypes: true });
355112
355792
  for (const entry of entries) {
355113
- const fullPath = path62.join(dir, entry.name);
355793
+ const fullPath = path63.join(dir, entry.name);
355114
355794
  if (entry.isDirectory()) {
355115
355795
  if (excludedDirs.has(entry.name)) {
355116
355796
  continue;
@@ -355171,10 +355851,10 @@ function getAllNodeModuleFilePaths(entryFilePath, projectDir) {
355171
355851
  processedPackages.add(packageName);
355172
355852
  if (resolvedFiles.length > 0) {
355173
355853
  const firstResolvedFile = resolvedFiles[0];
355174
- let packageDir = path62.dirname(firstResolvedFile);
355854
+ let packageDir = path63.dirname(firstResolvedFile);
355175
355855
  let hasPackageJson = false;
355176
355856
  while (packageDir.includes("node_modules")) {
355177
- const packageJsonPath = path62.join(packageDir, "package.json");
355857
+ const packageJsonPath = path63.join(packageDir, "package.json");
355178
355858
  if (fs55.existsSync(packageJsonPath)) {
355179
355859
  try {
355180
355860
  const pkgJson = JSON.parse(fs55.readFileSync(packageJsonPath, "utf-8"));
@@ -355185,10 +355865,10 @@ function getAllNodeModuleFilePaths(entryFilePath, projectDir) {
355185
355865
  } catch {}
355186
355866
  }
355187
355867
  const expectedPackagePath = packageName.startsWith("@") ? `node_modules/${packageName}` : `node_modules/${packageName}`;
355188
- if (packageDir.endsWith(expectedPackagePath) || packageDir.endsWith(expectedPackagePath.replace(/\//g, path62.sep))) {
355868
+ if (packageDir.endsWith(expectedPackagePath) || packageDir.endsWith(expectedPackagePath.replace(/\//g, path63.sep))) {
355189
355869
  break;
355190
355870
  }
355191
- const parentDir = path62.dirname(packageDir);
355871
+ const parentDir = path63.dirname(packageDir);
355192
355872
  if (parentDir === packageDir)
355193
355873
  break;
355194
355874
  packageDir = parentDir;
@@ -355262,7 +355942,7 @@ class EventsWatcher extends EventEmitter2 {
355262
355942
  import * as fs57 from "node:fs";
355263
355943
  import * as http from "node:http";
355264
355944
  import { createRequire as createRequire5 } from "node:module";
355265
- import * as path64 from "node:path";
355945
+ import * as path65 from "node:path";
355266
355946
 
355267
355947
  // node_modules/winterspec/dist/edge/transform-to-node.js
355268
355948
  var import_node_utils = __toESM3(require_dist7(), 1);
@@ -356825,13 +357505,13 @@ var getIndex = async (mainComponentPath, fileServerApiBaseUrl) => {
356825
357505
 
356826
357506
  // lib/server/kicad-pcm-proxy.ts
356827
357507
  import * as fs56 from "node:fs";
356828
- import * as path63 from "node:path";
357508
+ import * as path64 from "node:path";
356829
357509
  var getSourceFilesChecksum = (projectDir) => {
356830
357510
  const sourceFiles = globbySync(["**/*.tsx", "**/*.ts", "**/*.json", "!node_modules/**", "!dist/**"], { cwd: projectDir });
356831
357511
  let checksum = "";
356832
357512
  for (const file of sourceFiles) {
356833
357513
  try {
356834
- const stat = fs56.statSync(path63.join(projectDir, file));
357514
+ const stat = fs56.statSync(path64.join(projectDir, file));
356835
357515
  checksum += `${file}:${stat.mtimeMs};`;
356836
357516
  } catch {}
356837
357517
  }
@@ -356851,9 +357531,9 @@ var createKicadPcmProxy = ({
356851
357531
  };
356852
357532
  const handleRequest = async (url, res) => {
356853
357533
  const requestedFile = url.pathname.replace(/^\/pcm\/?/, "") || "repository.json";
356854
- const distDir = path63.join(projectDir, "dist");
356855
- const pcmDir = path63.join(distDir, "pcm");
356856
- const filePath = path63.join(pcmDir, requestedFile);
357534
+ const distDir = path64.join(projectDir, "dist");
357535
+ const pcmDir = path64.join(distDir, "pcm");
357536
+ const filePath = path64.join(pcmDir, requestedFile);
356857
357537
  const currentChecksum = getSourceFilesChecksum(projectDir);
356858
357538
  const needsRebuild = currentChecksum !== pcmState.lastFileChecksum;
356859
357539
  if (needsRebuild) {
@@ -356903,7 +357583,7 @@ Rebuilding KiCad PCM assets...`));
356903
357583
  res.end(`PCM file not found: ${requestedFile}`);
356904
357584
  return;
356905
357585
  }
356906
- const ext = path63.extname(filePath).toLowerCase();
357586
+ const ext = path64.extname(filePath).toLowerCase();
356907
357587
  let contentType = "application/octet-stream";
356908
357588
  if (ext === ".json") {
356909
357589
  contentType = "application/json";
@@ -356928,7 +357608,7 @@ var resolveLocalTscircuitStandalonePath = (projectDir) => {
356928
357608
  if (!projectDir)
356929
357609
  return;
356930
357610
  try {
356931
- const projectRequire = createRequire5(path64.join(projectDir, "package.json"));
357611
+ const projectRequire = createRequire5(path65.join(projectDir, "package.json"));
356932
357612
  const browserBundlePath = projectRequire.resolve("tscircuit/browser");
356933
357613
  if (fs57.existsSync(browserBundlePath))
356934
357614
  return browserBundlePath;
@@ -356950,7 +357630,7 @@ var createHttpServer = async ({
356950
357630
  entryFile
356951
357631
  }) => {
356952
357632
  const fileServerHandler = getNodeHandler(stdin_default, {});
356953
- const localCacheEngine = projectDir ? createLocalCacheEngine(path64.join(projectDir, ".tscircuit", "cache")) : undefined;
357633
+ const localCacheEngine = projectDir ? createLocalCacheEngine(path65.join(projectDir, ".tscircuit", "cache")) : undefined;
356954
357634
  const pcmProxy = kicadPcm && projectDir && entryFile ? createKicadPcmProxy({ projectDir, entryFile, port }) : null;
356955
357635
  const server = http.createServer(async (req, res) => {
356956
357636
  const requestHost = req.headers.host ?? `localhost:${port}`;
@@ -357108,7 +357788,7 @@ var createHttpServer = async ({
357108
357788
  // lib/shared/push-snippet.ts
357109
357789
  var import_semver6 = __toESM3(require_semver2(), 1);
357110
357790
  import * as fs58 from "node:fs";
357111
- import * as path67 from "node:path";
357791
+ import * as path68 from "node:path";
357112
357792
  import Debug2 from "debug";
357113
357793
 
357114
357794
  // lib/utils/validate-package-name.ts
@@ -357126,7 +357806,7 @@ var validatePackageName = (name) => {
357126
357806
  };
357127
357807
 
357128
357808
  // lib/dev/get-package-file-paths.ts
357129
- import * as path65 from "node:path";
357809
+ import * as path66 from "node:path";
357130
357810
  var getPackageFilePaths = (projectDir, ignored = []) => {
357131
357811
  const ignorePatterns = [
357132
357812
  ...DEFAULT_IGNORED_PATTERNS,
@@ -357137,7 +357817,7 @@ var getPackageFilePaths = (projectDir, ignored = []) => {
357137
357817
  ignore: ignorePatterns
357138
357818
  });
357139
357819
  fileNames.sort();
357140
- return fileNames.map((fileName) => path65.join(projectDir, fileName));
357820
+ return fileNames.map((fileName) => path66.join(projectDir, fileName));
357141
357821
  };
357142
357822
 
357143
357823
  // lib/utils/check-org-access.ts
@@ -357153,7 +357833,7 @@ var checkOrgAccess = async (ky, orgTscircuitHandle) => {
357153
357833
  };
357154
357834
 
357155
357835
  // lib/shared/is-binary-file.ts
357156
- import * as path66 from "node:path";
357836
+ import * as path67 from "node:path";
357157
357837
  var BINARY_FILE_EXTENSIONS = new Set([
357158
357838
  ".glb",
357159
357839
  ".gltf",
@@ -357169,7 +357849,7 @@ var BINARY_FILE_EXTENSIONS = new Set([
357169
357849
  ".tar"
357170
357850
  ]);
357171
357851
  var isBinaryFile = (filePath) => {
357172
- const ext = path66.extname(filePath).toLowerCase();
357852
+ const ext = path67.extname(filePath).toLowerCase();
357173
357853
  return BINARY_FILE_EXTENSIONS.has(ext);
357174
357854
  };
357175
357855
 
@@ -357206,14 +357886,14 @@ var findPushProject = async ({
357206
357886
  return null;
357207
357887
  }
357208
357888
  const packageJsonPath = [
357209
- path67.resolve(path67.join(path67.dirname(snippetFilePath), "package.json")),
357210
- path67.resolve(path67.join(process.cwd(), "package.json"))
357889
+ path68.resolve(path68.join(path68.dirname(snippetFilePath), "package.json")),
357890
+ path68.resolve(path68.join(process.cwd(), "package.json"))
357211
357891
  ].find((candidatePath) => fs58.existsSync(candidatePath));
357212
- const projectDir = packageJsonPath ? path67.dirname(packageJsonPath) : path67.dirname(snippetFilePath);
357892
+ const projectDir = packageJsonPath ? path68.dirname(packageJsonPath) : path68.dirname(snippetFilePath);
357213
357893
  return { snippetFilePath, packageJsonPath, projectDir };
357214
357894
  }
357215
357895
  const projectDir = process.cwd();
357216
- const packageJsonPath = path67.resolve(path67.join(projectDir, "package.json"));
357896
+ const packageJsonPath = path68.resolve(path68.join(projectDir, "package.json"));
357217
357897
  if (!fs58.existsSync(packageJsonPath)) {
357218
357898
  return { projectDir };
357219
357899
  }
@@ -357226,7 +357906,7 @@ var findPushProject = async ({
357226
357906
  };
357227
357907
  var getArchivePayload = (filePaths, projectDir, packageNameWithVersion) => {
357228
357908
  const files = filePaths.map((fullFilePath) => {
357229
- const relativeFilePath = path67.relative(projectDir, fullFilePath);
357909
+ const relativeFilePath = path68.relative(projectDir, fullFilePath);
357230
357910
  const fileBuffer = fs58.readFileSync(fullFilePath);
357231
357911
  const isBinary = isBinaryFile(relativeFilePath) || hasBinaryContent(fileBuffer);
357232
357912
  return isBinary ? {
@@ -357460,7 +358140,7 @@ var pushSnippet = async ({
357460
358140
  json: archivePayload
357461
358141
  });
357462
358142
  for (const fullFilePath of filePaths) {
357463
- const relativeFilePath = path67.relative(projectDir, fullFilePath);
358143
+ const relativeFilePath = path68.relative(projectDir, fullFilePath);
357464
358144
  uploadResults.succeeded.push(relativeFilePath);
357465
358145
  }
357466
358146
  log(kleur_default.gray(`\uD83D\uDCE6 Uploaded archive with ${filePaths.length} files`));
@@ -357470,7 +358150,7 @@ var pushSnippet = async ({
357470
358150
  }
357471
358151
  if (uploadResults.succeeded.length === 0) {
357472
358152
  for (const fullFilePath of filePaths) {
357473
- const relativeFilePath = path67.relative(projectDir, fullFilePath);
358153
+ const relativeFilePath = path68.relative(projectDir, fullFilePath);
357474
358154
  const fileBuffer = fs58.readFileSync(fullFilePath);
357475
358155
  const isBinary = isBinaryFile(relativeFilePath) || hasBinaryContent(fileBuffer);
357476
358156
  const payload = {
@@ -357590,7 +358270,7 @@ class DevServer {
357590
358270
  }) {
357591
358271
  this.port = port;
357592
358272
  this.componentFilePath = componentFilePath;
357593
- this.projectDir = projectDir ?? path68.dirname(componentFilePath);
358273
+ this.projectDir = projectDir ?? path69.dirname(componentFilePath);
357594
358274
  this.kicadPcm = kicadPcm ?? false;
357595
358275
  this.autorouterDebug = autorouterDebug ?? false;
357596
358276
  this.autorouterPhase = autorouterPhase?.trim() || undefined;
@@ -357603,7 +358283,7 @@ class DevServer {
357603
358283
  async start() {
357604
358284
  const { server } = await createHttpServer({
357605
358285
  port: this.port,
357606
- defaultMainComponentPath: path68.relative(this.projectDir, this.componentFilePath),
358286
+ defaultMainComponentPath: path69.relative(this.projectDir, this.componentFilePath),
357607
358287
  kicadPcm: this.kicadPcm,
357608
358288
  projectDir: this.projectDir,
357609
358289
  entryFile: this.componentFilePath
@@ -357631,7 +358311,7 @@ class DevServer {
357631
358311
  this.filesystemWatcher = watch(this.projectDir, {
357632
358312
  persistent: true,
357633
358313
  ignoreInitial: true,
357634
- ignored: (p) => shouldIgnorePath(path68.relative(this.projectDir, p), this.ignoredFiles)
358314
+ ignored: (p) => shouldIgnorePath(path69.relative(this.projectDir, p), this.ignoredFiles)
357635
358315
  });
357636
358316
  this.filesystemWatcher.on("change", (filePath) => this.handleFileChangedOnFilesystem(filePath));
357637
358317
  this.filesystemWatcher.on("add", (filePath) => this.handleFileChangedOnFilesystem(filePath));
@@ -357647,8 +358327,8 @@ class DevServer {
357647
358327
  const { file } = await this.fsKy.get("api/files/get", {
357648
358328
  searchParams: { file_path: ev.file_path }
357649
358329
  }).json();
357650
- const fullPath = path68.join(this.projectDir, ev.file_path);
357651
- const dirPath = path68.dirname(fullPath);
358330
+ const fullPath = path69.join(this.projectDir, ev.file_path);
358331
+ const dirPath = path69.dirname(fullPath);
357652
358332
  if (!fs59.existsSync(dirPath)) {
357653
358333
  fs59.mkdirSync(dirPath, { recursive: true });
357654
358334
  }
@@ -357660,14 +358340,14 @@ class DevServer {
357660
358340
  }
357661
358341
  }
357662
358342
  async handleFileDeletedEventFromServer(ev) {
357663
- const fullPath = path68.join(this.projectDir, ev.file_path);
358343
+ const fullPath = path69.join(this.projectDir, ev.file_path);
357664
358344
  if (fs59.existsSync(fullPath)) {
357665
358345
  debug12(`Deleting file ${ev.file_path} from filesystem`);
357666
358346
  fs59.unlinkSync(fullPath);
357667
358347
  }
357668
358348
  }
357669
358349
  async handleFileChangedOnFilesystem(absoluteFilePath) {
357670
- const relativeFilePath = path68.relative(this.projectDir, absoluteFilePath);
358350
+ const relativeFilePath = path69.relative(this.projectDir, absoluteFilePath);
357671
358351
  if (relativeFilePath.includes("manual-edits.json"))
357672
358352
  return;
357673
358353
  if (shouldIgnorePath(relativeFilePath, this.ignoredFiles))
@@ -357683,14 +358363,14 @@ class DevServer {
357683
358363
  await this.checkAndUploadNewNodeModules(absoluteFilePath);
357684
358364
  }
357685
358365
  async checkAndUploadNewNodeModules(filePath) {
357686
- const ext = path68.extname(filePath).toLowerCase();
358366
+ const ext = path69.extname(filePath).toLowerCase();
357687
358367
  const isSourceFile = [".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext);
357688
358368
  if (!isSourceFile)
357689
358369
  return;
357690
358370
  try {
357691
358371
  const nodeModuleFiles = getAllNodeModuleFilePaths(filePath, this.projectDir);
357692
358372
  const newFiles = nodeModuleFiles.filter((file) => {
357693
- const relativePath = path68.relative(this.projectDir, file);
358373
+ const relativePath = path69.relative(this.projectDir, file);
357694
358374
  return !this.uploadedNodeModules.has(relativePath);
357695
358375
  });
357696
358376
  if (newFiles.length === 0)
@@ -357703,7 +358383,7 @@ class DevServer {
357703
358383
  }
357704
358384
  }
357705
358385
  async handleFileRemovedFromFilesystem(absoluteFilePath) {
357706
- const relativeFilePath = path68.relative(this.projectDir, absoluteFilePath);
358386
+ const relativeFilePath = path69.relative(this.projectDir, absoluteFilePath);
357707
358387
  if (shouldIgnorePath(relativeFilePath, this.ignoredFiles))
357708
358388
  return;
357709
358389
  this.autorouterPhaseReached = false;
@@ -357742,8 +358422,8 @@ class DevServer {
357742
358422
  debug12(`Successfully deleted file ${relativeFilePath} from server`);
357743
358423
  }
357744
358424
  async handleFileRename(oldPath, newPath) {
357745
- const oldRelativePath = path68.relative(this.projectDir, oldPath);
357746
- const newRelativePath = path68.relative(this.projectDir, newPath);
358425
+ const oldRelativePath = path69.relative(this.projectDir, oldPath);
358426
+ const newRelativePath = path69.relative(this.projectDir, newPath);
357747
358427
  if (shouldIgnorePath(oldRelativePath, this.ignoredFiles) || shouldIgnorePath(newRelativePath, this.ignoredFiles))
357748
358428
  return;
357749
358429
  await this.handleFileRemovedFromFilesystem(oldPath);
@@ -357761,7 +358441,7 @@ class DevServer {
357761
358441
  });
357762
358442
  const filePaths = getPackageFilePaths(this.projectDir, this.ignoredFiles);
357763
358443
  for (const filePath of filePaths) {
357764
- const relativeFilePath = path68.relative(this.projectDir, filePath);
358444
+ const relativeFilePath = path69.relative(this.projectDir, filePath);
357765
358445
  const filePayload = this.createFileUploadPayload(filePath, relativeFilePath);
357766
358446
  await this.postFileUpsert({
357767
358447
  filePath: relativeFilePath,
@@ -357793,7 +358473,7 @@ class DevServer {
357793
358473
  }
357794
358474
  async uploadNodeModuleFiles(files) {
357795
358475
  for (const nodeModuleFile of files) {
357796
- const relativeFilePath = path68.relative(this.projectDir, nodeModuleFile);
358476
+ const relativeFilePath = path69.relative(this.projectDir, nodeModuleFile);
357797
358477
  this.uploadedNodeModules.add(relativeFilePath);
357798
358478
  const filePayload = this.createFileUploadPayload(nodeModuleFile, relativeFilePath);
357799
358479
  await this.postFileUpsert({
@@ -357832,7 +358512,7 @@ class DevServer {
357832
358512
  getInitialNodeModuleDependencyEntryFiles() {
357833
358513
  const entryFiles = [this.componentFilePath];
357834
358514
  for (const configFileName of CONFIG_MODULE_FILENAMES2) {
357835
- const configPath = path68.join(this.projectDir, configFileName);
358515
+ const configPath = path69.join(this.projectDir, configFileName);
357836
358516
  if (fs59.existsSync(configPath)) {
357837
358517
  entryFiles.push(configPath);
357838
358518
  }
@@ -357848,7 +358528,7 @@ class DevServer {
357848
358528
  formData.set("file_path", filePath);
357849
358529
  formData.set("initiator", initiator);
357850
358530
  const binaryBytes = Uint8Array.from(binaryContent);
357851
- formData.set("binary_file", new Blob([binaryBytes]), path68.basename(filePath));
358531
+ formData.set("binary_file", new Blob([binaryBytes]), path69.basename(filePath));
357852
358532
  const response = await fetch(`http://localhost:${this.port}/api/files/upsert-multipart`, {
357853
358533
  method: "POST",
357854
358534
  body: formData
@@ -357888,7 +358568,7 @@ class DevServer {
357888
358568
  await this.filesystemWatcher?.close();
357889
358569
  }
357890
358570
  createFileUploadPayload(absoluteFilePath, relativeFilePath) {
357891
- const ext = path68.extname(relativeFilePath).toLowerCase();
358571
+ const ext = path69.extname(relativeFilePath).toLowerCase();
357892
358572
  if (BINARY_FILE_EXTENSIONS2.has(ext)) {
357893
358573
  const fileBuffer = fs59.readFileSync(absoluteFilePath);
357894
358574
  return { binary_content: fileBuffer };
@@ -357934,7 +358614,7 @@ var isPortAvailable = (port) => {
357934
358614
  });
357935
358615
  };
357936
358616
  var warnIfTsconfigMissingTscircuitType = (projectDir) => {
357937
- const tsconfigPath = path69.join(projectDir, "tsconfig.json");
358617
+ const tsconfigPath = path70.join(projectDir, "tsconfig.json");
357938
358618
  if (!fs60.existsSync(tsconfigPath)) {
357939
358619
  return;
357940
358620
  }
@@ -357974,7 +358654,7 @@ var registerDev = (program) => {
357974
358654
 
357975
358655
  ${kleur_default.green(`@tscircuit/cli@${getVersion()}`)} ${kleur_default.gray("ready in")} ${kleur_default.white(`${Math.round(timeToStart)}ms`)}`);
357976
358656
  console.log(`
357977
- ${kleur_default.bold("➜ Local:")} ${kleur_default.underline(kleur_default.cyan(`http://localhost:${port}`))}${server.componentFilePath ? kleur_default.underline(kleur_default.cyan(`/#file=${encodeURIComponent(path69.relative(process.cwd(), server.componentFilePath).replaceAll("\\", "/"))}`)) : ""}
358657
+ ${kleur_default.bold("➜ Local:")} ${kleur_default.underline(kleur_default.cyan(`http://localhost:${port}`))}${server.componentFilePath ? kleur_default.underline(kleur_default.cyan(`/#file=${encodeURIComponent(path70.relative(process.cwd(), server.componentFilePath).replaceAll("\\", "/"))}`)) : ""}
357978
358658
 
357979
358659
  `);
357980
358660
  console.log(kleur_default.gray(`Watching ${kleur_default.underline(server.projectDir.split("/").slice(-2).join("/"))} for changes...`));
@@ -358007,13 +358687,13 @@ var checkLoggedIn = () => {
358007
358687
  import { spawnSync as spawnSync2 } from "node:child_process";
358008
358688
  import fs61 from "node:fs";
358009
358689
  import os7 from "node:os";
358010
- import path70 from "node:path";
358690
+ import path71 from "node:path";
358011
358691
  var hasBunInstalled = () => {
358012
358692
  const result = spawnSync2("bun", ["--version"], { stdio: "ignore" });
358013
358693
  return result.status === 0;
358014
358694
  };
358015
358695
  var createTempProject = (tempDir) => {
358016
- const packageJsonPath = path70.join(tempDir, "package.json");
358696
+ const packageJsonPath = path71.join(tempDir, "package.json");
358017
358697
  const packageJson = {
358018
358698
  name: "tsci-doctor-check",
358019
358699
  version: "0.0.0",
@@ -358033,7 +358713,7 @@ var checkGlobalNpmrcRegistry = async () => {
358033
358713
  details: "Bun is required to verify registry settings. Install Bun and rerun `tsci doctor`."
358034
358714
  };
358035
358715
  }
358036
- const tempDir = fs61.mkdtempSync(path70.join(os7.tmpdir(), "tsci-doctor-"));
358716
+ const tempDir = fs61.mkdtempSync(path71.join(os7.tmpdir(), "tsci-doctor-"));
358037
358717
  try {
358038
358718
  createTempProject(tempDir);
358039
358719
  const result = spawnSync2("bun", ["install"], {
@@ -358121,7 +358801,7 @@ function getPcbXRaySettings(options) {
358121
358801
 
358122
358802
  // lib/shared/export-snippet.ts
358123
358803
  import fs62 from "node:fs";
358124
- import path71 from "node:path";
358804
+ import path72 from "node:path";
358125
358805
  import { promisify as promisify4 } from "node:util";
358126
358806
 
358127
358807
  // node_modules/circuit-json-to-bom-csv/dist/index.js
@@ -361598,13 +362278,13 @@ var RELATIONSHIPS_XML = `<?xml version="1.0" encoding="UTF-8"?>
361598
362278
  <Relationship Target="/3D/3dmodel.model" Id="rel-1" Type="http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel" />
361599
362279
  </Relationships>
361600
362280
  `;
361601
- var escapeXml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
362281
+ var escapeXml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
361602
362282
  var formatNumber4 = (value) => {
361603
362283
  const normalized = Math.abs(value) < 0.0000005 ? 0 : value;
361604
362284
  return normalized.toFixed(6).replace(/(?:\.0+|(?<decimal>\.[0-9]*?)0+)$/, "$<decimal>");
361605
362285
  };
361606
362286
  var appendMeshObject = (output, mesh, objectId) => {
361607
- output.push(` <object id="${objectId}" type="model" name="${escapeXml3(mesh.name)}" pid="1" pindex="${mesh.materialIndex}">
362287
+ output.push(` <object id="${objectId}" type="model" name="${escapeXml4(mesh.name)}" pid="1" pindex="${mesh.materialIndex}">
361608
362288
  `, ` <mesh>
361609
362289
  `, ` <vertices>
361610
362290
  `);
@@ -361632,7 +362312,7 @@ var createBambuModelSettings = (meshes, assemblyId, title) => {
361632
362312
  `,
361633
362313
  ` <object id="${assemblyId}">
361634
362314
  `,
361635
- ` <metadata key="name" value="${escapeXml3(title)}"/>
362315
+ ` <metadata key="name" value="${escapeXml4(title)}"/>
361636
362316
  `,
361637
362317
  ` <metadata key="extruder" value="1"/>
361638
362318
  `
@@ -361641,7 +362321,7 @@ var createBambuModelSettings = (meshes, assemblyId, title) => {
361641
362321
  const objectId = index + 2;
361642
362322
  const extruder = mesh.materialIndex + 1;
361643
362323
  settings.push(` <part id="${objectId}" subtype="normal_part">
361644
- `, ` <metadata key="name" value="${escapeXml3(mesh.name)}"/>
362324
+ `, ` <metadata key="name" value="${escapeXml4(mesh.name)}"/>
361645
362325
  `, ` <metadata key="extruder" value="${extruder}"/>
361646
362326
  `, ` <mesh_stat face_count="${mesh.triangles.length / 3}" edges_fixed="0" degenerate_facets="0" facets_removed="0" facets_reversed="0" backwards_edges="0"/>
361647
362327
  `, ` </part>
@@ -361666,7 +362346,7 @@ var createThreeMf = ({
361666
362346
  `,
361667
362347
  `<model unit="millimeter" xml:lang="en-US" xmlns="http://schemas.microsoft.com/3dmanufacturing/core/2015/02">
361668
362348
  `,
361669
- ` <metadata name="Title">${escapeXml3(title)}</metadata>
362349
+ ` <metadata name="Title">${escapeXml4(title)}</metadata>
361670
362350
  `,
361671
362351
  ` <metadata name="Designer">tscircuit</metadata>
361672
362352
  `,
@@ -361690,7 +362370,7 @@ var createThreeMf = ({
361690
362370
  appendMeshObject(model, mesh, index + 2);
361691
362371
  }
361692
362372
  const assemblyId = meshes.length + 2;
361693
- model.push(` <object id="${assemblyId}" type="model" name="${escapeXml3(title)}">
362373
+ model.push(` <object id="${assemblyId}" type="model" name="${escapeXml4(title)}">
361694
362374
  `, ` <components>
361695
362375
  `);
361696
362376
  for (let objectId = 2;objectId < assemblyId; objectId += 1) {
@@ -363157,10 +363837,10 @@ var exportSnippet = async ({
363157
363837
  onError(`Invalid format: ${format}`);
363158
363838
  return onExit(1);
363159
363839
  }
363160
- const projectDir = path71.dirname(filePath);
363161
- const outputBaseName = path71.basename(filePath).replace(/\.[^.]+$/, "");
363840
+ const projectDir = path72.dirname(filePath);
363841
+ const outputBaseName = path72.basename(filePath).replace(/\.[^.]+$/, "");
363162
363842
  const outputFileName = `${outputBaseName}${OUTPUT_EXTENSIONS[format]}`;
363163
- const outputDestination = outputPath && path71.isAbsolute(outputPath) ? outputPath : path71.join(projectDir, outputPath ?? outputFileName);
363843
+ const outputDestination = outputPath && path72.isAbsolute(outputPath) ? outputPath : path72.join(projectDir, outputPath ?? outputFileName);
363164
363844
  if (format === "kicad-library") {
363165
363845
  try {
363166
363846
  const result = await convertToKicadLibrary({
@@ -363254,7 +363934,7 @@ var exportSnippet = async ({
363254
363934
  }
363255
363935
  break;
363256
363936
  case "altium": {
363257
- await Promise.resolve().then(() => init_lib3());
363937
+ await Promise.resolve().then(() => init_lib4());
363258
363938
  outputContent = Buffer.from(await convertCircuitJsonToAltiumZip(circuitJson, outputBaseName));
363259
363939
  break;
363260
363940
  }
@@ -363292,7 +363972,7 @@ var exportSnippet = async ({
363292
363972
  model3dSourcePaths: pcbConverter.getModel3dSourcePaths(),
363293
363973
  projectName: outputBaseName,
363294
363974
  fetch: platformConfig?.platformFetch ?? globalThis.fetch,
363295
- readFile: (modelPath) => fs62.promises.readFile(path71.resolve(projectDir, modelPath)),
363975
+ readFile: (modelPath) => fs62.promises.readFile(path72.resolve(projectDir, modelPath)),
363296
363976
  onModelFile: ({ outputPath, content }) => {
363297
363977
  zip.file(outputPath, content);
363298
363978
  },
@@ -363462,11 +364142,11 @@ var getSpiceWithPaddedSim = (circuitJson, options) => {
363462
364142
 
363463
364143
  // lib/eecircuit-engine/run-simulation.ts
363464
364144
  import { promises as fs63, existsSync as existsSync15 } from "node:fs";
363465
- import path72 from "node:path";
364145
+ import path73 from "node:path";
363466
364146
  import os8 from "node:os";
363467
364147
  var sim = null;
363468
364148
  var fetchSimulation = async () => {
363469
- const tempFilePath = path72.join(os8.tmpdir(), `tscircuit-eecircuit-engine-1.7.4.mjs`);
364149
+ const tempFilePath = path73.join(os8.tmpdir(), `tscircuit-eecircuit-engine-1.7.4.mjs`);
363470
364150
  if (!existsSync15(tempFilePath)) {
363471
364151
  const url = `https://jscdn.tscircuit.com/@tscircuit/eecircuit-engine/1.7.4/dist/eecircuit-engine.mjs`;
363472
364152
  const response = await fetch(url);
@@ -363563,7 +364243,7 @@ var resultToCsv = (result) => {
363563
364243
  };
363564
364244
 
363565
364245
  // cli/export/register.ts
363566
- import path73 from "node:path";
364246
+ import path74 from "node:path";
363567
364247
  import { promises as fs64 } from "node:fs";
363568
364248
  var registerExport = (program) => {
363569
364249
  addPcbXRayOptions(program.command("export")).description("Export tscircuit code to various formats").argument("<file>", "Path to the package file").option("-f, --format <format>", `Output format (${ALLOWED_EXPORT_FORMATS.join(", ")})`).option("-o, --output <path>", "Output file path").option("--layer <layer>", "PCB front layer: top or bottom").option("--disable-parts-engine", "Disable the parts engine").option("--show-courtyards", "Show courtyard outlines in PCB SVG output").action(async (file, options) => {
@@ -363589,7 +364269,7 @@ var registerExport = (program) => {
363589
364269
  });
363590
364270
  if (circuitJson) {
363591
364271
  const spiceString = getSpiceWithPaddedSim(circuitJson);
363592
- const outputSpicePath = options.output ?? path73.join(path73.dirname(file), `${path73.basename(file, path73.extname(file))}.spice.cir`);
364272
+ const outputSpicePath = options.output ?? path74.join(path74.dirname(file), `${path74.basename(file, path74.extname(file))}.spice.cir`);
363593
364273
  await fs64.writeFile(outputSpicePath, spiceString);
363594
364274
  const { result } = await runSimulation(spiceString);
363595
364275
  const csvContent = resultToCsv(result);
@@ -398687,7 +399367,7 @@ function normalizeManufacturerPartNumber2(partNumber) {
398687
399367
 
398688
399368
  // lib/import/import-component-from-jlcpcb.ts
398689
399369
  import fs66 from "node:fs/promises";
398690
- import path75 from "node:path";
399370
+ import path76 from "node:path";
398691
399371
 
398692
399372
  // lib/import/fetch-datasheet-pin-attributes.ts
398693
399373
  import { commonComponentProps as commonComponentProps2 } from "@tscircuit/props";
@@ -398752,7 +399432,7 @@ ${indentation}{...${propsName}}`);
398752
399432
 
398753
399433
  // lib/import/download-cad-model-assets.ts
398754
399434
  import fs65 from "node:fs/promises";
398755
- import path74 from "node:path";
399435
+ import path75 from "node:path";
398756
399436
  var downloadCadModelAssets = async ({
398757
399437
  cadComponent,
398758
399438
  componentDir,
@@ -398764,7 +399444,7 @@ var downloadCadModelAssets = async ({
398764
399444
  if (cadComponent?.model_step_url) {
398765
399445
  const stepFileName = `${componentName}.step`;
398766
399446
  const stepResp = await platformFetch(cadComponent.model_step_url);
398767
- await fs65.writeFile(path74.join(componentDir, stepFileName), Buffer.from(await stepResp.arrayBuffer()));
399447
+ await fs65.writeFile(path75.join(componentDir, stepFileName), Buffer.from(await stepResp.arrayBuffer()));
398768
399448
  tsx = `import stepPath from "./${stepFileName}"
398769
399449
  ` + tsx;
398770
399450
  tsx = tsx.replace(`"${cadComponent.model_step_url}"`, "stepPath");
@@ -398772,7 +399452,7 @@ var downloadCadModelAssets = async ({
398772
399452
  if (cadComponent?.model_obj_url) {
398773
399453
  const objFileName = `${componentName}.obj`;
398774
399454
  const objResp = await platformFetch(cadComponent.model_obj_url);
398775
- await fs65.writeFile(path74.join(componentDir, objFileName), Buffer.from(await objResp.arrayBuffer()));
399455
+ await fs65.writeFile(path75.join(componentDir, objFileName), Buffer.from(await objResp.arrayBuffer()));
398776
399456
  tsx = `import objPath from "./${objFileName}"
398777
399457
  ` + tsx;
398778
399458
  tsx = tsx.replace(`"${cadComponent.model_obj_url}"`, "objPath");
@@ -398993,7 +399673,7 @@ var importComponentFromJlcpcb = async (jlcpcbPartNumber, projectDir = process.cw
398993
399673
  stepUrl: cadComponent.model_step_url ? JSON.stringify(cadComponent.model_step_url) : undefined
398994
399674
  }, cadComponent);
398995
399675
  }
398996
- const componentDir = options.download ? path75.join(projectDir, "imports", componentName) : path75.join(projectDir, "imports");
399676
+ const componentDir = options.download ? path76.join(projectDir, "imports", componentName) : path76.join(projectDir, "imports");
398997
399677
  await fs66.mkdir(componentDir, { recursive: true });
398998
399678
  if (options.download) {
398999
399679
  tsx = await downloadCadModelAssets({
@@ -399003,7 +399683,7 @@ var importComponentFromJlcpcb = async (jlcpcbPartNumber, projectDir = process.cw
399003
399683
  tsx
399004
399684
  });
399005
399685
  }
399006
- const filePath = path75.join(componentDir, `${componentName}.tsx`);
399686
+ const filePath = path76.join(componentDir, `${componentName}.tsx`);
399007
399687
  await fs66.writeFile(filePath, tsx);
399008
399688
  return { filePath, footprintConversion };
399009
399689
  };
@@ -399165,12 +399845,12 @@ var registerImport = (program) => {
399165
399845
 
399166
399846
  // cli/init/register.ts
399167
399847
  import * as fs68 from "node:fs";
399168
- import * as path78 from "node:path";
399848
+ import * as path79 from "node:path";
399169
399849
 
399170
399850
  // lib/shared/generate-gitignore-file.ts
399171
- import path76 from "node:path";
399851
+ import path77 from "node:path";
399172
399852
  var generateGitIgnoreFile = (dir) => {
399173
- const gitignorePath = path76.join(dir, ".gitignore");
399853
+ const gitignorePath = path77.join(dir, ".gitignore");
399174
399854
  const gitignoreContent = `# Dependencies
399175
399855
  node_modules/
399176
399856
 
@@ -399206,7 +399886,7 @@ yarn-error.log*
399206
399886
 
399207
399887
  // lib/shared/setup-tscircuit-skill.ts
399208
399888
  import * as fs67 from "node:fs";
399209
- import * as path77 from "node:path";
399889
+ import * as path78 from "node:path";
399210
399890
  var SKILL_REPO_API_URL = "https://api.github.com/repos/tscircuit/skill/contents";
399211
399891
  var SKILL_INSTALL_PATHS = [
399212
399892
  ".claude/skills/tscircuit",
@@ -399229,7 +399909,7 @@ async function fetchFileContent(downloadUrl) {
399229
399909
  async function downloadDirectory(apiUrl, targetDir) {
399230
399910
  const contents = await fetchGitHubContents(apiUrl);
399231
399911
  for (const item of contents) {
399232
- const targetPath = path77.join(targetDir, item.name);
399912
+ const targetPath = path78.join(targetDir, item.name);
399233
399913
  if (item.type === "dir") {
399234
399914
  fs67.mkdirSync(targetPath, { recursive: true });
399235
399915
  await downloadDirectory(`${apiUrl}/${item.name}`, targetPath);
@@ -399246,7 +399926,7 @@ async function downloadSkillRepo(targetDir) {
399246
399926
  if (item.name === ".git" || item.name === ".github") {
399247
399927
  continue;
399248
399928
  }
399249
- const targetPath = path77.join(targetDir, item.name);
399929
+ const targetPath = path78.join(targetDir, item.name);
399250
399930
  if (item.type === "dir") {
399251
399931
  fs67.mkdirSync(targetPath, { recursive: true });
399252
399932
  await downloadDirectory(`${SKILL_REPO_API_URL}/${item.name}`, targetPath);
@@ -399257,7 +399937,7 @@ async function downloadSkillRepo(targetDir) {
399257
399937
  }
399258
399938
  }
399259
399939
  async function setupTscircuitSkill(projectDir, skipPrompt = false) {
399260
- const missingSkillPaths = SKILL_INSTALL_PATHS.filter((skillPath) => !fs67.existsSync(path77.join(projectDir, skillPath, "SKILL.md")));
399940
+ const missingSkillPaths = SKILL_INSTALL_PATHS.filter((skillPath) => !fs67.existsSync(path78.join(projectDir, skillPath, "SKILL.md")));
399261
399941
  if (missingSkillPaths.length === 0) {
399262
399942
  console.log("TSCircuit AI skills already exist, skipping...");
399263
399943
  return true;
@@ -399277,7 +399957,7 @@ async function setupTscircuitSkill(projectDir, skipPrompt = false) {
399277
399957
  console.info("Setting up tscircuit AI skills...");
399278
399958
  try {
399279
399959
  for (const skillPath of missingSkillPaths) {
399280
- const targetDir = path77.join(projectDir, skillPath);
399960
+ const targetDir = path78.join(projectDir, skillPath);
399281
399961
  await downloadSkillRepo(targetDir);
399282
399962
  console.info(`tscircuit skill installed at ${skillPath}`);
399283
399963
  }
@@ -399416,7 +400096,7 @@ var registerInit = (program) => {
399416
400096
  }
399417
400097
  }
399418
400098
  }
399419
- const projectDir = directory ? path78.resolve(process.cwd(), directory) : process.cwd();
400099
+ const projectDir = directory ? path79.resolve(process.cwd(), directory) : process.cwd();
399420
400100
  let tsciHandle = null;
399421
400101
  const token = getSessionToken();
399422
400102
  if (token) {
@@ -399427,7 +400107,7 @@ var registerInit = (program) => {
399427
400107
  }
399428
400108
  } catch {}
399429
400109
  }
399430
- const dirName = path78.basename(projectDir);
400110
+ const dirName = path79.basename(projectDir);
399431
400111
  let defaultPackageName = dirName;
399432
400112
  if (tsciHandle) {
399433
400113
  defaultPackageName = `@tsci/${tsciHandle}.${dirName}`;
@@ -399446,7 +400126,7 @@ var registerInit = (program) => {
399446
400126
  }
399447
400127
  }
399448
400128
  fs68.mkdirSync(projectDir, { recursive: true });
399449
- writeFileIfNotExists(path78.join(projectDir, "index.circuit.tsx"), `
400129
+ writeFileIfNotExists(path79.join(projectDir, "index.circuit.tsx"), `
399450
400130
  export default () => (
399451
400131
  <board>
399452
400132
  <resistor resistance="1k" footprint="0402" name="R1" />
@@ -399458,7 +400138,7 @@ export default () => (
399458
400138
  if (saveProjectConfig(null, projectDir)) {
399459
400139
  console.log("Created tscircuit.config.json with schema");
399460
400140
  }
399461
- writeFileIfNotExists(path78.join(projectDir, ".npmrc"), `
400141
+ writeFileIfNotExists(path79.join(projectDir, ".npmrc"), `
399462
400142
  @tsci:registry=https://npm.tscircuit.com
399463
400143
  `);
399464
400144
  console.log("Generating package.json");
@@ -399518,12 +400198,12 @@ var registerPush = (program) => {
399518
400198
 
399519
400199
  // cli/report/autorouter/register.ts
399520
400200
  import fs69 from "node:fs";
399521
- import path79 from "node:path";
400201
+ import path80 from "node:path";
399522
400202
  var import_prompts11 = __toESM3(require_prompts3(), 1);
399523
400203
  var AUTOROUTER_BUG_REPORT_VIEW_URL = "https://api.tscircuit.com/autorouting/bug_reports/view?autorouting_bug_report_id=";
399524
400204
  var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
399525
400205
  var readSimpleRouteJson = (filePath) => {
399526
- const resolvedFilePath = path79.resolve(filePath);
400206
+ const resolvedFilePath = path80.resolve(filePath);
399527
400207
  let fileContents;
399528
400208
  try {
399529
400209
  fileContents = fs69.readFileSync(resolvedFilePath, "utf8");
@@ -399601,7 +400281,7 @@ var registerReportAutorouter = (program) => {
399601
400281
  console.log("Report cancelled.");
399602
400282
  return;
399603
400283
  }
399604
- const title = options.title?.trim() || path79.basename(file, path79.extname(file));
400284
+ const title = options.title?.trim() || path80.basename(file, path80.extname(file));
399605
400285
  const { bugReportUrl } = await createAutorouterBugReport({
399606
400286
  title,
399607
400287
  simpleRouteJson
@@ -399701,7 +400381,7 @@ var registerRegistryPackagesCreate = (program) => {
399701
400381
 
399702
400382
  // cli/registry/packages/update/register.ts
399703
400383
  import fs70 from "node:fs";
399704
- import path80 from "node:path";
400384
+ import path81 from "node:path";
399705
400385
  var normalizeGithubRepo = (input) => {
399706
400386
  let repo = input;
399707
400387
  const urlMatch = /^https?:\/\/(?:www\.)?github\.com\/([^?#]+)(?:[?#].*)?$/i.exec(input);
@@ -399714,7 +400394,7 @@ var normalizeGithubRepo = (input) => {
399714
400394
  return repo;
399715
400395
  };
399716
400396
  var getCurrentDirectoryPackageName = () => {
399717
- const packageJsonPath = path80.join(process.cwd(), "package.json");
400397
+ const packageJsonPath = path81.join(process.cwd(), "package.json");
399718
400398
  if (!fs70.existsSync(packageJsonPath))
399719
400399
  return;
399720
400400
  try {
@@ -401643,20 +402323,20 @@ var registerSearch = (program) => {
401643
402323
 
401644
402324
  // lib/shared/setup-github-actions.ts
401645
402325
  import fs71 from "node:fs";
401646
- import path81 from "node:path";
402326
+ import path82 from "node:path";
401647
402327
  var setupGithubActions = (projectDir = process.cwd()) => {
401648
402328
  const findGitRoot = (startDir) => {
401649
- let dir = path81.resolve(startDir);
401650
- while (dir !== path81.parse(dir).root) {
401651
- if (fs71.existsSync(path81.join(dir, ".git"))) {
402329
+ let dir = path82.resolve(startDir);
402330
+ while (dir !== path82.parse(dir).root) {
402331
+ if (fs71.existsSync(path82.join(dir, ".git"))) {
401652
402332
  return dir;
401653
402333
  }
401654
- dir = path81.dirname(dir);
402334
+ dir = path82.dirname(dir);
401655
402335
  }
401656
402336
  return null;
401657
402337
  };
401658
402338
  const gitRoot = findGitRoot(projectDir) ?? projectDir;
401659
- const workflowsDir = path81.join(gitRoot, ".github", "workflows");
402339
+ const workflowsDir = path82.join(gitRoot, ".github", "workflows");
401660
402340
  fs71.mkdirSync(workflowsDir, { recursive: true });
401661
402341
  const buildWorkflow = `name: tscircuit Build
401662
402342
 
@@ -401696,8 +402376,8 @@ jobs:
401696
402376
  - run: bun install
401697
402377
  - run: bunx tsci snapshot
401698
402378
  `;
401699
- writeFileIfNotExists(path81.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
401700
- writeFileIfNotExists(path81.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
402379
+ writeFileIfNotExists(path82.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
402380
+ writeFileIfNotExists(path82.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
401701
402381
  };
401702
402382
 
401703
402383
  // cli/setup/register.ts
@@ -401814,21 +402494,21 @@ var registerSimulate = (program) => {
401814
402494
 
401815
402495
  // lib/shared/snapshot-project.ts
401816
402496
  import fs75 from "node:fs";
401817
- import path84 from "node:path";
402497
+ import path85 from "node:path";
401818
402498
 
401819
402499
  // cli/snapshot/worker-pool.ts
401820
402500
  import fs72 from "node:fs";
401821
- import path82 from "node:path";
402501
+ import path83 from "node:path";
401822
402502
  var getWorkerEntrypointPath2 = () => {
401823
- const tsPath = path82.join(import.meta.dir, "snapshot.worker.ts");
402503
+ const tsPath = path83.join(import.meta.dir, "snapshot.worker.ts");
401824
402504
  if (fs72.existsSync(tsPath)) {
401825
402505
  return tsPath;
401826
402506
  }
401827
- const jsBundledPath = path82.join(import.meta.dir, "snapshot", "snapshot.worker.js");
402507
+ const jsBundledPath = path83.join(import.meta.dir, "snapshot", "snapshot.worker.js");
401828
402508
  if (fs72.existsSync(jsBundledPath)) {
401829
402509
  return jsBundledPath;
401830
402510
  }
401831
- return path82.join(import.meta.dir, "snapshot.worker.js");
402511
+ return path83.join(import.meta.dir, "snapshot.worker.js");
401832
402512
  };
401833
402513
  var snapshotFilesWithWorkerPool = async (options) => {
401834
402514
  const cancellationError = new Error("Snapshot cancelled due to file failure");
@@ -401899,7 +402579,7 @@ var snapshotFilesWithWorkerPool = async (options) => {
401899
402579
 
401900
402580
  // lib/shared/process-snapshot-file.ts
401901
402581
  import fs74 from "node:fs";
401902
- import path83 from "node:path";
402582
+ import path84 from "node:path";
401903
402583
  import { convertCircuitJsonToStackedSchematicSheetsSvg as convertCircuitJsonToStackedSchematicSheetsSvg2 } from "circuit-to-svg";
401904
402584
 
401905
402585
  // lib/shared/compare-images.ts
@@ -401949,7 +402629,7 @@ var processSnapshotFile = async ({
401949
402629
  cameraPreset,
401950
402630
  pcbLayer
401951
402631
  }) => {
401952
- const relativeFilePath = path83.relative(projectDir, file);
402632
+ const relativeFilePath = path84.relative(projectDir, file);
401953
402633
  const successPaths = [];
401954
402634
  const warningMessages = [];
401955
402635
  const mismatches = [];
@@ -402045,11 +402725,11 @@ var processSnapshotFile = async ({
402045
402725
  } catch (error) {
402046
402726
  const errorMessage = error instanceof Error ? error.message : String(error);
402047
402727
  if (errorMessage.includes("No pcb_board found in circuit JSON")) {
402048
- const fileDir = path83.dirname(file);
402049
- const relativeDir = path83.relative(projectDir, fileDir);
402050
- const snapDir = snapshotsDirName ? path83.join(projectDir, snapshotsDirName, relativeDir) : path83.join(fileDir, "__snapshots__");
402051
- const base = path83.basename(file).replace(/\.[^.]+$/, "");
402052
- const snap3dPath = path83.join(snapDir, `${base}-3d.snap.png`);
402728
+ const fileDir = path84.dirname(file);
402729
+ const relativeDir = path84.relative(projectDir, fileDir);
402730
+ const snapDir = snapshotsDirName ? path84.join(projectDir, snapshotsDirName, relativeDir) : path84.join(fileDir, "__snapshots__");
402731
+ const base = path84.basename(file).replace(/\.[^.]+$/, "");
402732
+ const snap3dPath = path84.join(snapDir, `${base}-3d.snap.png`);
402053
402733
  const existing3dSnapshot = fs74.existsSync(snap3dPath);
402054
402734
  if (existing3dSnapshot) {
402055
402735
  return {
@@ -402061,7 +402741,7 @@ var processSnapshotFile = async ({
402061
402741
  errorMessage: kleur_default.red(`
402062
402742
  ❌ Failed to generate 3D snapshot for ${relativeFilePath}:
402063
402743
  `) + kleur_default.red(` No pcb_board found in circuit JSON
402064
- `) + kleur_default.red(` Existing snapshot: ${path83.relative(projectDir, snap3dPath)}
402744
+ `) + kleur_default.red(` Existing snapshot: ${path84.relative(projectDir, snap3dPath)}
402065
402745
  `)
402066
402746
  };
402067
402747
  }
@@ -402082,9 +402762,9 @@ var processSnapshotFile = async ({
402082
402762
  }
402083
402763
  }
402084
402764
  }
402085
- const snapDir = snapshotsDirName ? path83.join(projectDir, snapshotsDirName, path83.relative(projectDir, path83.dirname(file))) : path83.join(path83.dirname(file), "__snapshots__");
402765
+ const snapDir = snapshotsDirName ? path84.join(projectDir, snapshotsDirName, path84.relative(projectDir, path84.dirname(file))) : path84.join(path84.dirname(file), "__snapshots__");
402086
402766
  fs74.mkdirSync(snapDir, { recursive: true });
402087
- const base = path83.basename(file).replace(/\.[^.]+$/, "");
402767
+ const base = path84.basename(file).replace(/\.[^.]+$/, "");
402088
402768
  const snapshots = [];
402089
402769
  if (!simulationOnly && (pcbOnly || !schematicOnly)) {
402090
402770
  let pcbSnapshotType = "pcb";
@@ -402125,13 +402805,13 @@ var processSnapshotFile = async ({
402125
402805
  for (const snapshot of snapshots) {
402126
402806
  const { type } = snapshot;
402127
402807
  const is3d = type === "3d";
402128
- const snapPath = path83.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
402808
+ const snapPath = path84.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
402129
402809
  const existing = fs74.existsSync(snapPath);
402130
402810
  const newContentBuffer = snapshot.isBinary ? snapshot.content : Buffer.from(snapshot.content, "utf8");
402131
402811
  const newContentForFile = snapshot.content;
402132
402812
  if (!existing) {
402133
402813
  fs74.writeFileSync(snapPath, newContentForFile);
402134
- successPaths.push(path83.relative(projectDir, snapPath));
402814
+ successPaths.push(path84.relative(projectDir, snapPath));
402135
402815
  didUpdate = true;
402136
402816
  continue;
402137
402817
  }
@@ -402149,16 +402829,16 @@ var processSnapshotFile = async ({
402149
402829
  }
402150
402830
  if (update) {
402151
402831
  if (!forceUpdate && equal) {
402152
- successPaths.push(path83.relative(projectDir, snapPath));
402832
+ successPaths.push(path84.relative(projectDir, snapPath));
402153
402833
  } else {
402154
402834
  fs74.writeFileSync(snapPath, newContentForFile);
402155
- successPaths.push(path83.relative(projectDir, snapPath));
402835
+ successPaths.push(path84.relative(projectDir, snapPath));
402156
402836
  didUpdate = true;
402157
402837
  }
402158
402838
  } else if (!equal) {
402159
402839
  mismatches.push(diffPath ? `${snapPath} (diff: ${diffPath})` : snapPath);
402160
402840
  } else {
402161
- successPaths.push(path83.relative(projectDir, snapPath));
402841
+ successPaths.push(path84.relative(projectDir, snapPath));
402162
402842
  }
402163
402843
  }
402164
402844
  return {
@@ -402203,7 +402883,7 @@ var snapshotProject = async ({
402203
402883
  ...DEFAULT_IGNORED_PATTERNS,
402204
402884
  ...ignored.map(normalizeIgnorePattern)
402205
402885
  ];
402206
- const resolvedPaths = filePaths.map((f) => path84.resolve(projectDir, f));
402886
+ const resolvedPaths = filePaths.map((f) => path85.resolve(projectDir, f));
402207
402887
  const explicitDirectoryTarget = resolvedPaths.find((resolvedPath) => {
402208
402888
  if (!fs75.existsSync(resolvedPath)) {
402209
402889
  return false;
@@ -402217,7 +402897,7 @@ var snapshotProject = async ({
402217
402897
  });
402218
402898
  if (boardFiles.length === 0) {
402219
402899
  if (explicitDirectoryTarget) {
402220
- const relativeDirectory = path84.relative(projectDir, explicitDirectoryTarget) || ".";
402900
+ const relativeDirectory = path85.relative(projectDir, explicitDirectoryTarget) || ".";
402221
402901
  const runtimeIncludeBoardFilePatterns = projectConfig?.includeBoardFiles?.filter((pattern) => pattern.trim()) ?? [];
402222
402902
  const includeBoardFilePatterns = runtimeIncludeBoardFilePatterns.length > 0 ? runtimeIncludeBoardFilePatterns : getBoardFilePatterns(projectDir);
402223
402903
  const patternSourceMessage = hasConfiguredIncludeBoardFiles(projectConfig) ? "Searched using tscircuit.config.json includeBoardFiles" : "Searched using default includeBoardFiles";
@@ -402388,7 +403068,7 @@ var registerSnapshot = (program) => {
402388
403068
  };
402389
403069
 
402390
403070
  // cli/transpile/register.ts
402391
- import path85 from "node:path";
403071
+ import path86 from "node:path";
402392
403072
  var registerTranspile = (program) => {
402393
403073
  program.command("transpile").description("Transpile TypeScript/TSX to JavaScript (ESM, CommonJS, and type declarations)").argument("[file]", "Path to the entry file").action(async (file) => {
402394
403074
  try {
@@ -402396,7 +403076,7 @@ var registerTranspile = (program) => {
402396
403076
  fileOrDir: file,
402397
403077
  includeBoardFiles: false
402398
403078
  });
402399
- const distDir = path85.join(projectDir, "dist");
403079
+ const distDir = path86.join(projectDir, "dist");
402400
403080
  validateMainInDist(projectDir, distDir);
402401
403081
  console.log("Transpiling entry file...");
402402
403082
  const entryFile = mainEntrypoint || circuitFiles[0];
@@ -402434,12 +403114,12 @@ function registerUpgradeCommand(program) {
402434
403114
  }
402435
403115
 
402436
403116
  // lib/shared/update-package.ts
402437
- import * as path86 from "node:path";
403117
+ import * as path87 from "node:path";
402438
403118
  import * as fs76 from "node:fs";
402439
403119
  async function updatePackage(packageSpec, projectDir = process.cwd()) {
402440
403120
  const packageManager = getPackageManager();
402441
403121
  if (!packageSpec) {
402442
- const pkgJsonPath = path86.join(projectDir, "package.json");
403122
+ const pkgJsonPath = path87.join(projectDir, "package.json");
402443
403123
  if (!fs76.existsSync(pkgJsonPath)) {
402444
403124
  console.log(kleur_default.yellow("No package.json found. Cannot update all packages."));
402445
403125
  return;
@@ -402525,6 +403205,7 @@ registerReport(program2);
402525
403205
  registerReportAutorouter(program2);
402526
403206
  registerCheck(program2);
402527
403207
  registerCheckNetlist(program2);
403208
+ registerCheckPcbStyle(program2);
402528
403209
  registerCheckPinSpecification(program2);
402529
403210
  registerCheckPlacement(program2);
402530
403211
  registerCheckRoutingDifficulty(program2);