@tscircuit/cli 0.1.2418 → 0.1.2421

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
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/cli/main.js
3
- size: 47821031 bytes
4
- sha256: f62635798b3691e5a8057eeb9784bad9bab73664e82ce9fb31f3a3ccc517cfc3
3
+ size: 47824087 bytes
4
+ sha256: cbeedff2456bd9fe1ff51dd5cffe17e05208295350e7ab33ff77bab5ad6b3af3
package/dist/lib/index.js CHANGED
@@ -74360,7 +74360,7 @@ import {
74360
74360
  import { Paper, Uuid as Uuid4 } from "kicadts";
74361
74361
  import { KicadPcb as KicadPcb2 } from "kicadts";
74362
74362
  import { cju as cju2 } from "@tscircuit/circuit-json-util";
74363
- import { compose as compose8, translate as translate8, scale as scale6 } from "transformation-matrix";
74363
+ import { compose as compose10, translate as translate10, scale as scale7 } from "transformation-matrix";
74364
74364
  import {
74365
74365
  Layer,
74366
74366
  Pts as Pts4,
@@ -74403,7 +74403,7 @@ import {
74403
74403
  TextEffectsFont as TextEffectsFont8
74404
74404
  } from "kicadts";
74405
74405
  import { FootprintAttr } from "kicadts";
74406
- import { applyToPoint as applyToPoint22 } from "transformation-matrix";
74406
+ import { applyToPoint as applyToPoint24 } from "transformation-matrix";
74407
74407
  import {
74408
74408
  Property as Property2,
74409
74409
  TextEffects as TextEffects9,
@@ -74415,40 +74415,44 @@ import {
74415
74415
  import { FpCircle, Stroke as Stroke5 } from "kicadts";
74416
74416
  import { applyToPoint as applyToPoint11, identity, rotate as rotate2 } from "transformation-matrix";
74417
74417
  import { FpCircle as FpCircle2, Stroke as Stroke6 } from "kicadts";
74418
- import { FpRect, Stroke as Stroke7 } from "kicadts";
74419
- import { FpRect as FpRect2, Stroke as Stroke8 } from "kicadts";
74420
- import { FpPoly, FpRect as FpRect3, Stroke as Stroke9 } from "kicadts";
74418
+ import { applyToPoint as applyToPoint12 } from "transformation-matrix";
74419
+ import { compose as compose4, rotateDEG, scale as scale2, translate as translate4 } from "transformation-matrix";
74420
+ import { FpRect as FpRect2 } from "kicadts";
74421
+ import { FpPoly, FpRect, Stroke as Stroke7 } from "kicadts";
74422
+ import { applyToPoint as applyToPoint13, compose as compose5, translate as translate5 } from "transformation-matrix";
74423
+ import { FpRect as FpRect3 } from "kicadts";
74424
+ import { FpPoly as FpPoly4, FpRect as FpRect4, Stroke as Stroke8 } from "kicadts";
74421
74425
  import {
74422
- applyToPoint as applyToPoint12,
74423
- compose as compose4,
74426
+ applyToPoint as applyToPoint14,
74427
+ compose as compose6,
74424
74428
  rotate as rotate3,
74425
- scale as scale2,
74426
- translate as translate4
74429
+ scale as scale3,
74430
+ translate as translate6
74427
74431
  } from "transformation-matrix";
74428
- import { FpPoly as FpPoly2, Pts as Pts6, Stroke as Stroke10, Xy as Xy6 } from "kicadts";
74432
+ import { FpPoly as FpPoly5, Pts as Pts6, Stroke as Stroke9, Xy as Xy6 } from "kicadts";
74429
74433
  import {
74430
- applyToPoint as applyToPoint13,
74431
- compose as compose5,
74434
+ applyToPoint as applyToPoint15,
74435
+ compose as compose7,
74432
74436
  rotate as rotate4,
74433
- scale as scale3,
74434
- translate as translate5
74437
+ scale as scale4,
74438
+ translate as translate7
74435
74439
  } from "transformation-matrix";
74436
74440
  import"kicadts";
74437
74441
  import { FpText, TextEffects as TextEffects10, TextEffectsFont as TextEffectsFont10 } from "kicadts";
74438
- import { applyToPoint as applyToPoint14, rotate as rotate5, identity as identity2 } from "transformation-matrix";
74442
+ import { applyToPoint as applyToPoint16, rotate as rotate5, identity as identity2 } from "transformation-matrix";
74439
74443
  import { TextEffectsJustify as TextEffectsJustify6 } from "kicadts";
74440
- import { FpLine, Stroke as Stroke11 } from "kicadts";
74441
- import { applyToPoint as applyToPoint15, identity as identity3, rotate as rotate6 } from "transformation-matrix";
74442
- import { FpPoly as FpPoly3, Stroke as Stroke12 } from "kicadts";
74444
+ import { FpLine, Stroke as Stroke10 } from "kicadts";
74445
+ import { applyToPoint as applyToPoint17, identity as identity3, rotate as rotate6 } from "transformation-matrix";
74446
+ import { FpPoly as FpPoly6, Stroke as Stroke11 } from "kicadts";
74443
74447
  import {
74444
- applyToPoint as applyToPoint16,
74445
- compose as compose6,
74448
+ applyToPoint as applyToPoint18,
74449
+ compose as compose8,
74446
74450
  rotate as rotate7,
74447
- scale as scale4,
74448
- translate as translate6
74451
+ scale as scale5,
74452
+ translate as translate8
74449
74453
  } from "transformation-matrix";
74450
74454
  import { FpText as FpText3, TextEffects as TextEffects11, TextEffectsFont as TextEffectsFont11 } from "kicadts";
74451
- import { applyToPoint as applyToPoint17, rotate as rotate8, identity as identity4 } from "transformation-matrix";
74455
+ import { applyToPoint as applyToPoint19, rotate as rotate8, identity as identity4 } from "transformation-matrix";
74452
74456
  import { FootprintModel as FootprintModel3 } from "kicadts";
74453
74457
  import {
74454
74458
  FootprintPad,
@@ -74460,26 +74464,29 @@ import {
74460
74464
  PadNet
74461
74465
  } from "kicadts";
74462
74466
  import {
74463
- applyToPoint as applyToPoint18,
74464
- compose as compose7,
74465
- translate as translate7,
74466
- scale as scale5,
74467
+ applyToPoint as applyToPoint20,
74468
+ compose as compose9,
74469
+ translate as translate9,
74470
+ scale as scale6,
74467
74471
  rotate as rotate9
74468
74472
  } from "transformation-matrix";
74469
74473
  import { FootprintPad as FootprintPad2, PadDrill, PadNet as PadNet2 } from "kicadts";
74470
- import { applyToPoint as applyToPoint19, rotate as rotate10, identity as identity5 } from "transformation-matrix";
74474
+ import { applyToPoint as applyToPoint21, rotate as rotate10, identity as identity5 } from "transformation-matrix";
74471
74475
  import { FootprintPad as FootprintPad3, PadDrill as PadDrill2 } from "kicadts";
74472
- import { applyToPoint as applyToPoint20, rotate as rotate11, identity as identity6 } from "transformation-matrix";
74473
- import { FpLine as FpLine2, Stroke as Stroke13 } from "kicadts";
74474
- import { applyToPoint as applyToPoint21, identity as identity7, rotate as rotate12 } from "transformation-matrix";
74476
+ import { applyToPoint as applyToPoint22, rotate as rotate11, identity as identity6 } from "transformation-matrix";
74477
+ import { FpLine as FpLine2, Stroke as Stroke12 } from "kicadts";
74478
+ import { applyToPoint as applyToPoint23, identity as identity7, rotate as rotate12 } from "transformation-matrix";
74475
74479
  import { Segment, SegmentNet } from "kicadts";
74476
- import { applyToPoint as applyToPoint23 } from "transformation-matrix";
74477
- import { isRouteViaCoveredByPhysicalVia } from "@tscircuit/circuit-json-util";
74480
+ import { applyToPoint as applyToPoint25 } from "transformation-matrix";
74481
+ import {
74482
+ createBoardOwnerMap,
74483
+ isRouteViaCoveredByPhysicalVia
74484
+ } from "@tscircuit/circuit-json-util";
74478
74485
  import { Via, ViaNet } from "kicadts";
74479
- import { applyToPoint as applyToPoint24 } from "transformation-matrix";
74486
+ import { applyToPoint as applyToPoint26 } from "transformation-matrix";
74480
74487
  import { ViaTenting } from "kicadts";
74481
74488
  import { Footprint as Footprint5 } from "kicadts";
74482
- import { applyToPoint as applyToPoint25 } from "transformation-matrix";
74489
+ import { applyToPoint as applyToPoint27 } from "transformation-matrix";
74483
74490
  import { GrLine } from "kicadts";
74484
74491
  import {
74485
74492
  At as At3,
@@ -74488,10 +74495,10 @@ import {
74488
74495
  TextEffectsFont as TextEffectsFont12,
74489
74496
  TextEffectsJustify as TextEffectsJustify7
74490
74497
  } from "kicadts";
74491
- import { applyToPoint as applyToPoint26 } from "transformation-matrix";
74492
- import { applyToPoint as applyToPoint28, rotate as rotate13 } from "transformation-matrix";
74498
+ import { applyToPoint as applyToPoint28 } from "transformation-matrix";
74499
+ import { applyToPoint as applyToPoint30, rotate as rotate13 } from "transformation-matrix";
74493
74500
  import { GrText as GrText2, TextEffects as TextEffects13, TextEffectsFont as TextEffectsFont13, At as At4 } from "kicadts";
74494
- import { applyToPoint as applyToPoint27 } from "transformation-matrix";
74501
+ import { applyToPoint as applyToPoint29 } from "transformation-matrix";
74495
74502
  import { cju as cju3 } from "@tscircuit/circuit-json-util";
74496
74503
  import { cju as cju4 } from "@tscircuit/circuit-json-util";
74497
74504
  import { parseKicadSexpr as parseKicadSexpr2, KicadSch as KicadSch2 } from "kicadts";
@@ -75261,7 +75268,7 @@ function transformSchematicPoint(transform, point) {
75261
75268
  function createArcFromPrimitive({
75262
75269
  primitive,
75263
75270
  transform,
75264
- scale: scale7
75271
+ scale: scale8
75265
75272
  }) {
75266
75273
  const start = transformSchematicPoint(transform, primitive.start);
75267
75274
  const mid = transformSchematicPoint(transform, primitive.mid);
@@ -75274,7 +75281,7 @@ function createArcFromPrimitive({
75274
75281
  "stroke",
75275
75282
  [
75276
75283
  "width",
75277
- roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale7)
75284
+ roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale8)
75278
75285
  ],
75279
75286
  ["type", primitive.isDashed ? "dash" : "default"]
75280
75287
  ],
@@ -75330,7 +75337,7 @@ function createSymbolFillSexprPrimitives({
75330
75337
  function createCircleFromPrimitive({
75331
75338
  primitive,
75332
75339
  transform,
75333
- scale: scale7
75340
+ scale: scale8
75334
75341
  }) {
75335
75342
  const scaledPos = transformSchematicPoint(transform, {
75336
75343
  x: primitive.x,
@@ -75338,12 +75345,12 @@ function createCircleFromPrimitive({
75338
75345
  });
75339
75346
  return SymbolCircle.fromSexprPrimitives([
75340
75347
  ["center", scaledPos.x, scaledPos.y],
75341
- ["radius", roundSchematicCoordinate(primitive.radius * scale7)],
75348
+ ["radius", roundSchematicCoordinate(primitive.radius * scale8)],
75342
75349
  [
75343
75350
  "stroke",
75344
75351
  [
75345
75352
  "width",
75346
- roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale7)
75353
+ roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale8)
75347
75354
  ],
75348
75355
  ["type", "default"]
75349
75356
  ],
@@ -75365,7 +75372,7 @@ function createPolylineFromPoints({
75365
75372
  fallbackFillType,
75366
75373
  strokeWidth,
75367
75374
  isDashed,
75368
- scale: scale7
75375
+ scale: scale8
75369
75376
  }) {
75370
75377
  const polyline = new SymbolPolyline;
75371
75378
  const xyPoints = points.map((p) => {
@@ -75375,7 +75382,7 @@ function createPolylineFromPoints({
75375
75382
  const pts = new Pts(xyPoints);
75376
75383
  polyline.points = pts;
75377
75384
  const stroke = new Stroke2;
75378
- stroke.width = roundSchematicCoordinate(strokeWidth == null ? 0.254 : strokeWidth * scale7);
75385
+ stroke.width = roundSchematicCoordinate(strokeWidth == null ? 0.254 : strokeWidth * scale8);
75379
75386
  stroke.type = isDashed ? "dash" : "default";
75380
75387
  polyline.stroke = stroke;
75381
75388
  const fill = SymbolPolylineFill.fromSexprPrimitives(createSymbolFillSexprPrimitives({
@@ -75389,7 +75396,7 @@ function createPolylineFromPoints({
75389
75396
  function createRectangleFromPrimitive({
75390
75397
  primitive,
75391
75398
  transform,
75392
- scale: scale7
75399
+ scale: scale8
75393
75400
  }) {
75394
75401
  const start = transformSchematicPoint(transform, primitive.start);
75395
75402
  const end = transformSchematicPoint(transform, primitive.end);
@@ -75400,7 +75407,7 @@ function createRectangleFromPrimitive({
75400
75407
  "stroke",
75401
75408
  [
75402
75409
  "width",
75403
- roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale7)
75410
+ roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale8)
75404
75411
  ],
75405
75412
  ["type", primitive.isDashed ? "dash" : "default"]
75406
75413
  ],
@@ -75416,7 +75423,7 @@ function createRectangleFromPrimitive({
75416
75423
  function createTextFromPrimitive({
75417
75424
  schText,
75418
75425
  transform,
75419
- scale: scale7
75426
+ scale: scale8
75420
75427
  }) {
75421
75428
  const symbolText = new SymbolText;
75422
75429
  const scaledPos = transformSchematicPoint(transform, {
@@ -75425,7 +75432,7 @@ function createTextFromPrimitive({
75425
75432
  });
75426
75433
  symbolText.value = schText.text;
75427
75434
  symbolText.at = [scaledPos.x, scaledPos.y, 0];
75428
- const scaledFontSize = roundSchematicCoordinate(schText.fontSize * scale7);
75435
+ const scaledFontSize = roundSchematicCoordinate(schText.fontSize * scale8);
75429
75436
  const font = new TextEffectsFont2;
75430
75437
  font.size = { height: scaledFontSize, width: scaledFontSize };
75431
75438
  symbolText.effects = new TextEffects2({ font });
@@ -76635,7 +76642,7 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
76635
76642
  });
76636
76643
  const symLibId = new SymbolLibId2(this.ctx.schematicComponentLibraryIds?.get(schematicComponent.schematic_component_id) ?? libraryId);
76637
76644
  symbol._sxLibId = symLibId;
76638
- const { reference, value, description } = this.getComponentMetadata(sourceComponent);
76645
+ const { reference, value, description } = this.getComponentMetadata(sourceComponent, schematicComponent);
76639
76646
  const hasManufacturerValueForValuePlacement = (sourceComponent.ftype === "simple_chip" || sourceComponent.ftype === "simple_connector") && Boolean(sourceComponent.manufacturer_part_number);
76640
76647
  const { refTextPos, valTextPos, refJustify, valJustify } = this.getTextPositions({
76641
76648
  schematicComponent,
@@ -76919,7 +76926,7 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
76919
76926
  justify: getTextJustificationFromAnchor(text.anchor)
76920
76927
  };
76921
76928
  }
76922
- getComponentMetadata(sourceComp) {
76929
+ getComponentMetadata(sourceComp, schematicComp) {
76923
76930
  const name = sourceComp.name || "?";
76924
76931
  const reference = getReferenceDesignator(sourceComp);
76925
76932
  if (sourceComp.ftype === "simple_resistor") {
@@ -76996,7 +77003,7 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
76996
77003
  }
76997
77004
  return {
76998
77005
  reference,
76999
- value: name,
77006
+ value: schematicComp.symbol_display_value ?? name,
77000
77007
  description: "Component"
77001
77008
  };
77002
77009
  }
@@ -78343,19 +78350,25 @@ function convertSilkscreenCircles(silkscreenCircles, { componentCenter, componen
78343
78350
  }
78344
78351
  return fpCircles;
78345
78352
  }
78346
- function convertCourtyardCircles(courtyardCircles, componentCenter) {
78353
+ function getBoardToFootprintTransform({
78354
+ footprintOrigin,
78355
+ ccwRotationDegrees = 0
78356
+ }) {
78357
+ return compose4(rotateDEG(ccwRotationDegrees), scale2(1, -1), translate4(-footprintOrigin.x, -footprintOrigin.y));
78358
+ }
78359
+ function convertCourtyardCircles(courtyardCircles, placement) {
78347
78360
  const fpCircles = [];
78361
+ const boardToFootprintTransform = getBoardToFootprintTransform(placement);
78348
78362
  for (const circle of courtyardCircles) {
78349
- const relX = circle.center.x - componentCenter.x;
78350
- const relY = -(circle.center.y - componentCenter.y);
78363
+ const center = applyToPoint12(boardToFootprintTransform, circle.center);
78351
78364
  const layerMap = {
78352
78365
  top: "F.CrtYd",
78353
78366
  bottom: "B.CrtYd"
78354
78367
  };
78355
78368
  const kicadLayer = layerMap[circle.layer] || "F.CrtYd";
78356
78369
  const fpCircle = new FpCircle2({
78357
- center: { x: relX, y: relY },
78358
- end: { x: relX + circle.radius, y: relY },
78370
+ center,
78371
+ end: { x: center.x + circle.radius, y: center.y },
78359
78372
  layer: kicadLayer,
78360
78373
  stroke: new Stroke6,
78361
78374
  fill: false
@@ -78368,55 +78381,83 @@ function convertCourtyardCircles(courtyardCircles, componentCenter) {
78368
78381
  }
78369
78382
  return fpCircles;
78370
78383
  }
78371
- function convertFabricationNoteRects(fabRects, componentCenter) {
78384
+ function convertNoteRectToFootprintGraphic({
78385
+ rect,
78386
+ layer,
78387
+ footprintOrigin,
78388
+ ccwRotationDegrees = 0
78389
+ }) {
78390
+ const rectToFootprintTransform = compose5(getBoardToFootprintTransform({ footprintOrigin, ccwRotationDegrees }), translate5(rect.center.x, rect.center.y));
78391
+ const halfWidth = rect.width / 2;
78392
+ const halfHeight = rect.height / 2;
78393
+ const corners = [
78394
+ { x: -halfWidth, y: -halfHeight },
78395
+ { x: halfWidth, y: -halfHeight },
78396
+ { x: halfWidth, y: halfHeight },
78397
+ { x: -halfWidth, y: halfHeight }
78398
+ ].map((point) => applyToPoint13(rectToFootprintTransform, point));
78399
+ const stroke = new Stroke7;
78400
+ stroke.width = rect.stroke_width || 0.1;
78401
+ stroke.type = "default";
78402
+ if (ccwRotationDegrees % 90 === 0) {
78403
+ return new FpRect({
78404
+ start: {
78405
+ x: Math.min(...corners.map((point) => point.x)),
78406
+ y: Math.min(...corners.map((point) => point.y))
78407
+ },
78408
+ end: {
78409
+ x: Math.max(...corners.map((point) => point.x)),
78410
+ y: Math.max(...corners.map((point) => point.y))
78411
+ },
78412
+ layer,
78413
+ stroke,
78414
+ fill: false
78415
+ });
78416
+ }
78417
+ return new FpPoly({
78418
+ points: corners,
78419
+ layer,
78420
+ stroke,
78421
+ fill: false,
78422
+ uuid: generateDeterministicUuid(rect.type === "pcb_note_rect" ? rect.pcb_note_rect_id : rect.pcb_fabrication_note_rect_id)
78423
+ });
78424
+ }
78425
+ function convertFabricationNoteRects(fabRects, placement) {
78372
78426
  const fpRects = [];
78427
+ const fpPolys = [];
78373
78428
  for (const rect of fabRects) {
78374
- const relX = rect.center.x - componentCenter.x;
78375
- const relY = -(rect.center.y - componentCenter.y);
78376
- const halfW = rect.width / 2;
78377
- const halfH = rect.height / 2;
78378
78429
  const layerMap = {
78379
78430
  top: "F.Fab",
78380
78431
  bottom: "B.Fab"
78381
78432
  };
78382
78433
  const kicadLayer = layerMap[rect.layer] || rect.layer || "F.Fab";
78383
- const fpRect = new FpRect({
78384
- start: { x: relX - halfW, y: relY - halfH },
78385
- end: { x: relX + halfW, y: relY + halfH },
78434
+ const graphic = convertNoteRectToFootprintGraphic({
78435
+ rect,
78386
78436
  layer: kicadLayer,
78387
- stroke: new Stroke7,
78388
- fill: false
78437
+ ...placement
78389
78438
  });
78390
- if (fpRect.stroke) {
78391
- fpRect.stroke.width = rect.stroke_width || 0.1;
78392
- fpRect.stroke.type = "default";
78393
- }
78394
- fpRects.push(fpRect);
78439
+ if (graphic instanceof FpRect2)
78440
+ fpRects.push(graphic);
78441
+ else
78442
+ fpPolys.push(graphic);
78395
78443
  }
78396
- return fpRects;
78444
+ return { fpRects, fpPolys };
78397
78445
  }
78398
- function convertNoteRects(noteRects, componentCenter) {
78446
+ function convertNoteRects(noteRects, placement) {
78399
78447
  const fpRects = [];
78448
+ const fpPolys = [];
78400
78449
  for (const rect of noteRects) {
78401
- const relX = rect.center.x - componentCenter.x;
78402
- const relY = -(rect.center.y - componentCenter.y);
78403
- const halfW = rect.width / 2;
78404
- const halfH = rect.height / 2;
78405
- const kicadLayer = "F.Fab";
78406
- const fpRect = new FpRect2({
78407
- start: { x: relX - halfW, y: relY - halfH },
78408
- end: { x: relX + halfW, y: relY + halfH },
78409
- layer: kicadLayer,
78410
- stroke: new Stroke8,
78411
- fill: false
78450
+ const graphic = convertNoteRectToFootprintGraphic({
78451
+ rect,
78452
+ layer: "F.Fab",
78453
+ ...placement
78412
78454
  });
78413
- if (fpRect.stroke) {
78414
- fpRect.stroke.width = rect.stroke_width || 0.1;
78415
- fpRect.stroke.type = "default";
78416
- }
78417
- fpRects.push(fpRect);
78455
+ if (graphic instanceof FpRect3)
78456
+ fpRects.push(graphic);
78457
+ else
78458
+ fpPolys.push(graphic);
78418
78459
  }
78419
- return fpRects;
78460
+ return { fpRects, fpPolys };
78420
78461
  }
78421
78462
  function rotateCenter(point, degrees) {
78422
78463
  switch ((degrees % 360 + 360) % 360) {
@@ -78429,7 +78470,7 @@ function rotateCenter(point, degrees) {
78429
78470
  case 270:
78430
78471
  return { x: point.y, y: -point.x };
78431
78472
  default:
78432
- return applyToPoint12(rotate3(degrees * Math.PI / 180), point);
78473
+ return applyToPoint14(rotate3(degrees * Math.PI / 180), point);
78433
78474
  }
78434
78475
  }
78435
78476
  function convertCourtyardRects({
@@ -78439,13 +78480,13 @@ function convertCourtyardRects({
78439
78480
  }) {
78440
78481
  const fpRects = [];
78441
78482
  const fpPolys = [];
78442
- const toLocal = compose4(rotate3(componentRotation * Math.PI / 180), scale2(1, -1), translate4(-componentCenter.x, -componentCenter.y));
78483
+ const toLocal = compose6(rotate3(componentRotation * Math.PI / 180), scale3(1, -1), translate6(-componentCenter.x, -componentCenter.y));
78443
78484
  for (const rect of courtyardRects) {
78444
78485
  const halfW = rect.width / 2;
78445
78486
  const halfH = rect.height / 2;
78446
78487
  const rotation = rect.ccw_rotation ?? 0;
78447
78488
  const layer = rect.layer === "bottom" ? "B.CrtYd" : "F.CrtYd";
78448
- const stroke = new Stroke9;
78489
+ const stroke = new Stroke8;
78449
78490
  stroke.width = 0.05;
78450
78491
  stroke.type = "default";
78451
78492
  const color = rect.color ? parseColor(rect.color) : undefined;
@@ -78459,7 +78500,7 @@ function convertCourtyardRects({
78459
78500
  const swapAxes = (rotation - componentRotation) % 180 !== 0;
78460
78501
  const localHalfW = swapAxes ? halfH : halfW;
78461
78502
  const localHalfH = swapAxes ? halfW : halfH;
78462
- fpRects.push(new FpRect3({
78503
+ fpRects.push(new FpRect4({
78463
78504
  start: {
78464
78505
  x: center.x - localHalfW,
78465
78506
  y: center.y - localHalfH
@@ -78473,14 +78514,14 @@ function convertCourtyardRects({
78473
78514
  fill: false
78474
78515
  }));
78475
78516
  } else {
78476
- const fromRectCenter = compose4(translate4(rect.center.x, rect.center.y), rotate3(rotation * Math.PI / 180));
78517
+ const fromRectCenter = compose6(translate6(rect.center.x, rect.center.y), rotate3(rotation * Math.PI / 180));
78477
78518
  const points = [
78478
78519
  { x: -halfW, y: -halfH },
78479
78520
  { x: halfW, y: -halfH },
78480
78521
  { x: halfW, y: halfH },
78481
78522
  { x: -halfW, y: halfH }
78482
- ].map((point) => applyToPoint12(toLocal, applyToPoint12(fromRectCenter, point)));
78483
- fpPolys.push(new FpPoly({
78523
+ ].map((point) => applyToPoint14(toLocal, applyToPoint14(fromRectCenter, point)));
78524
+ fpPolys.push(new FpPoly4({
78484
78525
  points,
78485
78526
  layer,
78486
78527
  stroke,
@@ -78494,7 +78535,7 @@ function convertCourtyardRects({
78494
78535
  function convertCourtyardOutlines(params2) {
78495
78536
  const { courtyardOutlines, componentCenter, componentRotation = 0 } = params2;
78496
78537
  const fpPolys = [];
78497
- const cj2kicadMatrix = compose5(componentRotation !== 0 ? rotate4(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale3(1, -1), translate5(-componentCenter.x, -componentCenter.y));
78538
+ const cj2kicadMatrix = compose7(componentRotation !== 0 ? rotate4(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale4(1, -1), translate7(-componentCenter.x, -componentCenter.y));
78498
78539
  for (const outline of courtyardOutlines) {
78499
78540
  if (!outline.outline || outline.outline.length < 2)
78500
78541
  continue;
@@ -78504,15 +78545,15 @@ function convertCourtyardOutlines(params2) {
78504
78545
  };
78505
78546
  const kicadLayer = layerMap[outline.layer] || "F.CrtYd";
78506
78547
  const xyPoints = outline.outline.map((point) => {
78507
- const transformedPoint = applyToPoint13(cj2kicadMatrix, point);
78548
+ const transformedPoint = applyToPoint15(cj2kicadMatrix, point);
78508
78549
  return new Xy6(transformedPoint.x, transformedPoint.y);
78509
78550
  });
78510
- const fpPoly = new FpPoly2;
78551
+ const fpPoly = new FpPoly5;
78511
78552
  fpPoly.points = new Pts6(xyPoints);
78512
78553
  fpPoly.layer = kicadLayer;
78513
78554
  fpPoly.fill = false;
78514
78555
  fpPoly.uuid = generateDeterministicUuid(outline.pcb_courtyard_outline_id);
78515
- const stroke = new Stroke10;
78556
+ const stroke = new Stroke9;
78516
78557
  stroke.width = 0.05;
78517
78558
  stroke.type = "default";
78518
78559
  fpPoly.stroke = stroke;
@@ -78578,7 +78619,7 @@ function createFpTextFromCircuitJson({
78578
78619
  const relativeX = textElement.anchor_position.x - componentCenter.x;
78579
78620
  const relativeY = -(textElement.anchor_position.y - componentCenter.y);
78580
78621
  const rotationMatrix = componentRotation !== 0 ? rotate5(componentRotation * Math.PI / 180) : identity2();
78581
- const rotatedPos = applyToPoint14(rotationMatrix, {
78622
+ const rotatedPos = applyToPoint16(rotationMatrix, {
78582
78623
  x: relativeX,
78583
78624
  y: relativeY
78584
78625
  });
@@ -78659,11 +78700,11 @@ function convertSilkscreenPaths(silkscreenPaths, { componentCenter, componentRot
78659
78700
  const endPoint = path.route[i + 1];
78660
78701
  if (!startPoint || !endPoint)
78661
78702
  continue;
78662
- const startRelative = applyToPoint15(rotationMatrix, {
78703
+ const startRelative = applyToPoint17(rotationMatrix, {
78663
78704
  x: startPoint.x - componentCenter.x,
78664
78705
  y: -(startPoint.y - componentCenter.y)
78665
78706
  });
78666
- const endRelative = applyToPoint15(rotationMatrix, {
78707
+ const endRelative = applyToPoint17(rotationMatrix, {
78667
78708
  x: endPoint.x - componentCenter.x,
78668
78709
  y: -(endPoint.y - componentCenter.y)
78669
78710
  });
@@ -78671,7 +78712,7 @@ function convertSilkscreenPaths(silkscreenPaths, { componentCenter, componentRot
78671
78712
  start: { x: startRelative.x, y: startRelative.y },
78672
78713
  end: { x: endRelative.x, y: endRelative.y },
78673
78714
  layer: kicadLayer,
78674
- stroke: new Stroke11
78715
+ stroke: new Stroke10
78675
78716
  });
78676
78717
  if (fpLine.stroke) {
78677
78718
  fpLine.stroke.width = path.stroke_width || 0.15;
@@ -78713,20 +78754,20 @@ function convertSilkscreenRects({
78713
78754
  componentCenter,
78714
78755
  componentRotation = 0
78715
78756
  }) {
78716
- const toLocal = compose6(rotate7(componentRotation * Math.PI / 180), scale4(1, -1), translate6(-componentCenter.x, -componentCenter.y));
78757
+ const toLocal = compose8(rotate7(componentRotation * Math.PI / 180), scale5(1, -1), translate8(-componentCenter.x, -componentCenter.y));
78717
78758
  return silkscreenRects.flatMap((rect) => {
78718
78759
  const hasStroke = rect.has_stroke ?? rect.stroke_width > 0;
78719
78760
  if (!hasStroke && !rect.is_filled)
78720
78761
  return [];
78721
- const fromRectCenter = compose6(translate6(rect.center.x, rect.center.y), rotate7((rect.ccw_rotation ?? 0) * Math.PI / 180));
78722
- const points = getRectanglePoints(rect).map((point) => applyToPoint16(toLocal, applyToPoint16(fromRectCenter, point)));
78723
- const stroke = hasStroke ? new Stroke12 : undefined;
78762
+ const fromRectCenter = compose8(translate8(rect.center.x, rect.center.y), rotate7((rect.ccw_rotation ?? 0) * Math.PI / 180));
78763
+ const points = getRectanglePoints(rect).map((point) => applyToPoint18(toLocal, applyToPoint18(fromRectCenter, point)));
78764
+ const stroke = hasStroke ? new Stroke11 : undefined;
78724
78765
  if (stroke) {
78725
78766
  stroke.width = rect.stroke_width;
78726
78767
  stroke.type = rect.is_stroke_dashed ? "dash" : "default";
78727
78768
  }
78728
78769
  return [
78729
- new FpPoly3({
78770
+ new FpPoly6({
78730
78771
  points,
78731
78772
  layer: rect.layer === "bottom" ? "B.SilkS" : "F.SilkS",
78732
78773
  stroke,
@@ -78743,7 +78784,7 @@ function convertNoteTexts(params2) {
78743
78784
  const relX = textElement.anchor_position.x - componentCenter.x;
78744
78785
  const relY = -(textElement.anchor_position.y - componentCenter.y);
78745
78786
  const rotationMatrix = componentRotation !== 0 ? rotate8(componentRotation * Math.PI / 180) : identity4();
78746
- const rotatedPos = applyToPoint17(rotationMatrix, { x: relX, y: relY });
78787
+ const rotatedPos = applyToPoint19(rotationMatrix, { x: relX, y: relY });
78747
78788
  const fontSize = textElement.font_size || 1;
78748
78789
  const font = new TextEffectsFont11;
78749
78790
  font.size = { width: fontSize, height: fontSize };
@@ -78857,8 +78898,8 @@ function create3DModelsFromCadComponent(cadComponent, componentCenter, options)
78857
78898
  model.offset = transform.offset;
78858
78899
  model.rotate = transform.rotation;
78859
78900
  if (cadComponent.model_unit_to_mm_scale_factor) {
78860
- const scale7 = cadComponent.model_unit_to_mm_scale_factor;
78861
- model.scale = { x: scale7, y: scale7, z: scale7 };
78901
+ const scale8 = cadComponent.model_unit_to_mm_scale_factor;
78902
+ model.scale = { x: scale8, y: scale8, z: scale8 };
78862
78903
  }
78863
78904
  models.push(model);
78864
78905
  return models;
@@ -78884,8 +78925,8 @@ function createSmdPadFromCircuitJson({
78884
78925
  } else {
78885
78926
  throw new Error("Pad must have either x/y coordinates or points array");
78886
78927
  }
78887
- const cj2kicadMatrix = compose7(componentRotation !== 0 ? rotate9(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale5(1, -1), translate7(-componentCenter.x, -componentCenter.y));
78888
- const rotatedPos = applyToPoint18(cj2kicadMatrix, {
78928
+ const cj2kicadMatrix = compose9(componentRotation !== 0 ? rotate9(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale6(1, -1), translate9(-componentCenter.x, -componentCenter.y));
78929
+ const rotatedPos = applyToPoint20(cj2kicadMatrix, {
78889
78930
  x: padX,
78890
78931
  y: padY
78891
78932
  });
@@ -78908,9 +78949,9 @@ function createSmdPadFromCircuitJson({
78908
78949
  ];
78909
78950
  } else if (pcbPad.shape === "polygon" && "points" in pcbPad) {
78910
78951
  const points = pcbPad.points;
78911
- const pointTransformMatrix = compose7(scale5(1, -1), translate7(-padX, -padY));
78952
+ const pointTransformMatrix = compose9(scale6(1, -1), translate9(-padX, -padY));
78912
78953
  const relativePoints = points.map((p) => {
78913
- const transformed = applyToPoint18(pointTransformMatrix, { x: p.x, y: p.y });
78954
+ const transformed = applyToPoint20(pointTransformMatrix, { x: p.x, y: p.y });
78914
78955
  return new Xy7(transformed.x, transformed.y);
78915
78956
  });
78916
78957
  const grPoly = new PadPrimitiveGrPoly;
@@ -79024,7 +79065,7 @@ function createThruHolePadFromCircuitJson({
79024
79065
  const relativeX = platedHole.x - componentCenter.x;
79025
79066
  const relativeY = -(platedHole.y - componentCenter.y);
79026
79067
  const rotationMatrix = componentRotation !== 0 ? rotate10(componentRotation * Math.PI / 180) : identity5();
79027
- const rotatedPos = applyToPoint19(rotationMatrix, {
79068
+ const rotatedPos = applyToPoint21(rotationMatrix, {
79028
79069
  x: relativeX,
79029
79070
  y: relativeY
79030
79071
  });
@@ -79040,7 +79081,7 @@ function createThruHolePadFromCircuitJson({
79040
79081
  y: platedHole.hole_offset_y ?? 0
79041
79082
  };
79042
79083
  if (rawOffset.x !== 0 || rawOffset.y !== 0) {
79043
- const rotatedOffset = applyToPoint19(rotationMatrix, {
79084
+ const rotatedOffset = applyToPoint21(rotationMatrix, {
79044
79085
  x: -rawOffset.x,
79045
79086
  y: rawOffset.y
79046
79087
  });
@@ -79156,7 +79197,7 @@ function createNpthPadFromCircuitJson({
79156
79197
  const relativeX = pcbHole.x - componentCenter.x;
79157
79198
  const relativeY = -(pcbHole.y - componentCenter.y);
79158
79199
  const rotationMatrix = componentRotation !== 0 ? rotate11(componentRotation * Math.PI / 180) : identity6();
79159
- const rotatedPos = applyToPoint20(rotationMatrix, {
79200
+ const rotatedPos = applyToPoint22(rotationMatrix, {
79160
79201
  x: relativeX,
79161
79202
  y: relativeY
79162
79203
  });
@@ -79240,15 +79281,15 @@ function convertFabricationNotePaths(fabricationNotePaths, {
79240
79281
  const endPoint = fabricationNotePath.route[index + 1];
79241
79282
  if (!startPoint || !endPoint)
79242
79283
  continue;
79243
- const startRelative = applyToPoint21(rotationMatrix, {
79284
+ const startRelative = applyToPoint23(rotationMatrix, {
79244
79285
  x: startPoint.x - componentCenter.x,
79245
79286
  y: -(startPoint.y - componentCenter.y)
79246
79287
  });
79247
- const endRelative = applyToPoint21(rotationMatrix, {
79288
+ const endRelative = applyToPoint23(rotationMatrix, {
79248
79289
  x: endPoint.x - componentCenter.x,
79249
79290
  y: -(endPoint.y - componentCenter.y)
79250
79291
  });
79251
- const stroke = new Stroke13;
79292
+ const stroke = new Stroke12;
79252
79293
  stroke.width = fabricationNotePath.stroke_width || 0.1;
79253
79294
  stroke.type = "default";
79254
79295
  fpLines.push(new FpLine2({
@@ -79279,6 +79320,7 @@ var AddFootprintsStage = class extends ConverterStage {
79279
79320
  if (!sourcePort)
79280
79321
  return;
79281
79322
  const keys = [
79323
+ sourcePortId,
79282
79324
  ...this.sourcePortNetKeys[sourcePortId] ?? [],
79283
79325
  sourcePort.subcircuit_connectivity_map_key
79284
79326
  ];
@@ -79334,9 +79376,10 @@ var AddFootprintsStage = class extends ConverterStage {
79334
79376
  const sourceComponent = component.source_component_id ? this.ctx.db.source_component.get(component.source_component_id) : null;
79335
79377
  const cadComponent = this.getCadComponentForPcbComponent(component.pcb_component_id);
79336
79378
  const footprintName = sourceComponent ? getKicadCompatibleComponentName(sourceComponent, cadComponent) : "Unknown";
79337
- const transformedPos = applyToPoint22(c2kMatPcb, {
79338
- x: component.center.x,
79339
- y: component.center.y
79379
+ const footprintOrigin = component.footprint_origin ?? component.center;
79380
+ const transformedPos = applyToPoint24(c2kMatPcb, {
79381
+ x: footprintOrigin.x,
79382
+ y: footprintOrigin.y
79340
79383
  });
79341
79384
  const footprintData = `footprint:${component.pcb_component_id}:${transformedPos.x},${transformedPos.y}`;
79342
79385
  const footprint = new Footprint4({
@@ -79349,26 +79392,26 @@ var AddFootprintsStage = class extends ConverterStage {
79349
79392
  const pcbSilkscreenTexts = this.ctx.db.pcb_silkscreen_text?.list().filter((text) => text.pcb_component_id === component.pcb_component_id) || [];
79350
79393
  fpTexts.push(...convertSilkscreenTexts({
79351
79394
  silkscreenTexts: pcbSilkscreenTexts,
79352
- componentCenter: component.center,
79395
+ componentCenter: footprintOrigin,
79353
79396
  componentRotation: component.rotation || 0,
79354
79397
  sourceComponentName: sourceComponent?.name
79355
79398
  }));
79356
79399
  const pcbNoteTexts = this.ctx.db.pcb_note_text?.list().filter((text) => text.pcb_component_id === component.pcb_component_id) || [];
79357
79400
  fpTexts.push(...convertNoteTexts({
79358
79401
  noteTexts: pcbNoteTexts,
79359
- componentCenter: component.center,
79402
+ componentCenter: footprintOrigin,
79360
79403
  componentRotation: component.rotation || 0
79361
79404
  }));
79362
79405
  footprint.fpTexts = fpTexts;
79363
79406
  const pcbSilkscreenPaths = this.ctx.db.pcb_silkscreen_path?.list().filter((path) => path.pcb_component_id === component.pcb_component_id) || [];
79364
79407
  const fpLines = footprint.fpLines ?? [];
79365
79408
  fpLines.push(...convertSilkscreenPaths(pcbSilkscreenPaths, {
79366
- componentCenter: component.center,
79409
+ componentCenter: footprintOrigin,
79367
79410
  componentRotation: component.rotation || 0
79368
79411
  }));
79369
79412
  const fabricationNotePaths = this.ctx.db.pcb_fabrication_note_path?.list().filter((path) => path.pcb_component_id === component.pcb_component_id) || [];
79370
79413
  fpLines.push(...convertFabricationNotePaths(fabricationNotePaths, {
79371
- componentCenter: component.center,
79414
+ componentCenter: footprintOrigin,
79372
79415
  componentRotation: component.rotation || 0
79373
79416
  }));
79374
79417
  footprint.fpLines = fpLines;
@@ -79377,7 +79420,7 @@ var AddFootprintsStage = class extends ConverterStage {
79377
79420
  const pcbPads = this.ctx.db.pcb_smtpad?.list().filter((pad) => pad.pcb_component_id === component.pcb_component_id) || [];
79378
79421
  const { pads: smdPads, nextPadNumber } = convertSmdPads({
79379
79422
  pcbPads,
79380
- componentCenter: component.center,
79423
+ componentCenter: footprintOrigin,
79381
79424
  componentRotation: component.rotation || 0,
79382
79425
  componentId: component.pcb_component_id,
79383
79426
  startPadNumber: 1,
@@ -79387,7 +79430,7 @@ var AddFootprintsStage = class extends ConverterStage {
79387
79430
  const pcbPlatedHoles = this.ctx.db.pcb_plated_hole?.list().filter((hole) => hole.pcb_component_id === component.pcb_component_id) || [];
79388
79431
  const { pads: thruHolePads } = convertPlatedHoles({
79389
79432
  platedHoles: pcbPlatedHoles,
79390
- componentCenter: component.center,
79433
+ componentCenter: footprintOrigin,
79391
79434
  componentRotation: component.rotation || 0,
79392
79435
  componentId: component.pcb_component_id,
79393
79436
  startPadNumber: nextPadNumber,
@@ -79397,7 +79440,7 @@ var AddFootprintsStage = class extends ConverterStage {
79397
79440
  const pcbHoles = this.ctx.db.pcb_hole?.list().filter((hole) => hole.pcb_component_id === component.pcb_component_id) || [];
79398
79441
  const npthPads = convertNpthHoles({
79399
79442
  pcbHoles,
79400
- componentCenter: component.center,
79443
+ componentCenter: footprintOrigin,
79401
79444
  componentRotation: component.rotation || 0
79402
79445
  });
79403
79446
  fpPads.push(...npthPads);
@@ -79405,21 +79448,32 @@ var AddFootprintsStage = class extends ConverterStage {
79405
79448
  const pcbSilkscreenCircles = this.ctx.db.pcb_silkscreen_circle?.list().filter((circle) => circle.pcb_component_id === component.pcb_component_id) || [];
79406
79449
  const fpCircles = footprint.fpCircles ?? [];
79407
79450
  fpCircles.push(...convertSilkscreenCircles(pcbSilkscreenCircles, {
79408
- componentCenter: component.center,
79451
+ componentCenter: footprintOrigin,
79409
79452
  componentRotation: component.rotation || 0
79410
79453
  }));
79411
79454
  const pcbCourtyardCircles = this.ctx.db.pcb_courtyard_circle?.list().filter((circle) => circle.pcb_component_id === component.pcb_component_id) || [];
79412
- fpCircles.push(...convertCourtyardCircles(pcbCourtyardCircles, component.center));
79455
+ fpCircles.push(...convertCourtyardCircles(pcbCourtyardCircles, {
79456
+ footprintOrigin,
79457
+ ccwRotationDegrees: component.rotation || 0
79458
+ }));
79413
79459
  footprint.fpCircles = fpCircles;
79414
79460
  const pcbFabRects = this.ctx.db.pcb_fabrication_note_rect?.list().filter((rect) => rect.pcb_component_id === component.pcb_component_id) || [];
79415
79461
  const fpRects = footprint.fpRects ?? [];
79416
- fpRects.push(...convertFabricationNoteRects(pcbFabRects, component.center));
79462
+ const fabricationNoteRects = convertFabricationNoteRects(pcbFabRects, {
79463
+ footprintOrigin,
79464
+ ccwRotationDegrees: component.rotation || 0
79465
+ });
79466
+ fpRects.push(...fabricationNoteRects.fpRects);
79417
79467
  const pcbNoteRects = this.ctx.db.pcb_note_rect?.list().filter((rect) => rect.pcb_component_id === component.pcb_component_id) || [];
79418
- fpRects.push(...convertNoteRects(pcbNoteRects, component.center));
79468
+ const noteRects = convertNoteRects(pcbNoteRects, {
79469
+ footprintOrigin,
79470
+ ccwRotationDegrees: component.rotation || 0
79471
+ });
79472
+ fpRects.push(...noteRects.fpRects);
79419
79473
  const pcbCourtyardRects = this.ctx.db.pcb_courtyard_rect?.list().filter((rect) => rect.pcb_component_id === component.pcb_component_id) || [];
79420
79474
  const courtyardRects = convertCourtyardRects({
79421
79475
  courtyardRects: pcbCourtyardRects,
79422
- componentCenter: component.center,
79476
+ componentCenter: footprintOrigin,
79423
79477
  componentRotation: component.rotation || 0
79424
79478
  });
79425
79479
  fpRects.push(...courtyardRects.fpRects);
@@ -79427,14 +79481,14 @@ var AddFootprintsStage = class extends ConverterStage {
79427
79481
  const pcbCourtyardOutlines = this.ctx.db.pcb_courtyard_outline?.list().filter((outline) => outline.pcb_component_id === component.pcb_component_id) || [];
79428
79482
  const fpPolys = convertCourtyardOutlines({
79429
79483
  courtyardOutlines: pcbCourtyardOutlines,
79430
- componentCenter: component.center,
79484
+ componentCenter: footprintOrigin,
79431
79485
  componentRotation: component.rotation || 0
79432
79486
  });
79433
- fpPolys.push(...courtyardRects.fpPolys);
79487
+ fpPolys.push(...fabricationNoteRects.fpPolys, ...noteRects.fpPolys, ...courtyardRects.fpPolys);
79434
79488
  const pcbSilkscreenRects = this.ctx.db.pcb_silkscreen_rect?.list().filter((rect) => rect.pcb_component_id === component.pcb_component_id) || [];
79435
79489
  fpPolys.push(...convertSilkscreenRects({
79436
79490
  silkscreenRects: pcbSilkscreenRects,
79437
- componentCenter: component.center,
79491
+ componentCenter: footprintOrigin,
79438
79492
  componentRotation: component.rotation || 0
79439
79493
  }));
79440
79494
  if (fpPolys.length > 0) {
@@ -79444,7 +79498,7 @@ var AddFootprintsStage = class extends ConverterStage {
79444
79498
  const pcbBoard = this.ctx.db.pcb_board?.list()[0];
79445
79499
  const boardThickness = pcbBoard?.thickness ?? 0;
79446
79500
  const boardLayerZOffset = component.layer === "bottom" ? -(boardThickness / 2) : boardThickness / 2;
79447
- const models = create3DModelsFromCadComponent(cadComponent, component.center, {
79501
+ const models = create3DModelsFromCadComponent(cadComponent, footprintOrigin, {
79448
79502
  boardLayerZOffset,
79449
79503
  footprintRotation: component.rotation || 0,
79450
79504
  layer: component.layer
@@ -79572,8 +79626,8 @@ var AddTracesStage = class extends ConverterStage {
79572
79626
  if (!startPosition || !endPosition) {
79573
79627
  throw new Error(`Unable to convert pcb_trace route segment ${trace.pcb_trace_id ?? this.tracesProcessed}:${i} to KiCad segment`);
79574
79628
  }
79575
- const transformedStart = applyToPoint23(c2kMatPcb, startPosition);
79576
- const transformedEnd = applyToPoint23(c2kMatPcb, endPosition);
79629
+ const transformedStart = applyToPoint25(c2kMatPcb, startPosition);
79630
+ const transformedEnd = applyToPoint25(c2kMatPcb, endPosition);
79577
79631
  if (transformedStart.x === transformedEnd.x && transformedStart.y === transformedEnd.y) {
79578
79632
  continue;
79579
79633
  }
@@ -79647,9 +79701,9 @@ var KicadViaTenting = class extends ViaTenting {
79647
79701
  return `(tenting (front ${this.front}) (back ${this.back}))`;
79648
79702
  }
79649
79703
  };
79650
- var createViaTenting = (via) => {
79651
- const top = via.tented_on_top ?? via.is_tented;
79652
- const bottom = via.tented_on_bottom ?? via.is_tented;
79704
+ var createViaTenting = (via, board) => {
79705
+ const top = via.tented_on_top ?? via.is_tented ?? board?.default_via_tented_on_top;
79706
+ const bottom = via.tented_on_bottom ?? via.is_tented ?? board?.default_via_tented_on_bottom;
79653
79707
  if (top === undefined && bottom === undefined)
79654
79708
  return;
79655
79709
  return new KicadViaTenting(toKicadTentingValue(top), toKicadTentingValue(bottom));
@@ -79657,6 +79711,7 @@ var createViaTenting = (via) => {
79657
79711
  var DEFAULT_VIA_OUTER_DIAMETER = 0.8;
79658
79712
  var DEFAULT_VIA_HOLE_DIAMETER = 0.4;
79659
79713
  var AddViasStage = class extends ConverterStage {
79714
+ boardOwnerMap;
79660
79715
  viasProcessed = 0;
79661
79716
  pcbVias;
79662
79717
  collectPcbVias() {
@@ -79757,7 +79812,10 @@ var AddViasStage = class extends ConverterStage {
79757
79812
  this.finished = true;
79758
79813
  return;
79759
79814
  }
79760
- const transformedPos = applyToPoint24(c2kMatPcb, {
79815
+ this.boardOwnerMap ??= createBoardOwnerMap(this.input);
79816
+ const boardOwnerId = via.pcb_via_id ?? via.pcb_trace_id;
79817
+ const board = boardOwnerId ? this.boardOwnerMap.get(boardOwnerId) : undefined;
79818
+ const transformedPos = applyToPoint26(c2kMatPcb, {
79761
79819
  x: via.x,
79762
79820
  y: via.y
79763
79821
  });
@@ -79772,7 +79830,7 @@ var AddViasStage = class extends ConverterStage {
79772
79830
  layers: viaLayers,
79773
79831
  net: new ViaNet(via.net?.id ?? 0),
79774
79832
  uuid: generateDeterministicUuid(viaData),
79775
- tenting: createViaTenting(via)
79833
+ tenting: createViaTenting(via, board)
79776
79834
  });
79777
79835
  const vias = kicadPcb.vias;
79778
79836
  vias.push(kicadVia);
@@ -79810,7 +79868,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
79810
79868
  const pcbPad = elm;
79811
79869
  const padCenter = this.getPcbSmtPadCenter(pcbPad);
79812
79870
  const footprintSeed = `standalone_smtpad:${pcbPad.pcb_smtpad_id}:${padCenter.x},${padCenter.y}`;
79813
- const kicadPos = applyToPoint25(c2kMatPcb, padCenter);
79871
+ const kicadPos = applyToPoint27(c2kMatPcb, padCenter);
79814
79872
  const footprint = new Footprint5({
79815
79873
  libraryLink: this.getSmtPadLibraryLink(pcbPad),
79816
79874
  layer: "F.Cu",
@@ -79834,7 +79892,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
79834
79892
  } else if (elm.type === "pcb_hole") {
79835
79893
  const hole = elm;
79836
79894
  const footprintSeed = `standalone_hole:${hole.pcb_hole_id}:${hole.x},${hole.y}`;
79837
- const kicadPos = applyToPoint25(c2kMatPcb, { x: hole.x, y: hole.y });
79895
+ const kicadPos = applyToPoint27(c2kMatPcb, { x: hole.x, y: hole.y });
79838
79896
  const libraryLink = this.getHoleLibraryLink(hole);
79839
79897
  const footprint = new Footprint5({
79840
79898
  libraryLink,
@@ -79857,7 +79915,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
79857
79915
  } else if (elm.type === "pcb_plated_hole") {
79858
79916
  const hole = elm;
79859
79917
  const footprintSeed = `standalone_plated_hole:${hole.pcb_plated_hole_id}:${hole.x},${hole.y}`;
79860
- const kicadPos = applyToPoint25(c2kMatPcb, { x: hole.x, y: hole.y });
79918
+ const kicadPos = applyToPoint27(c2kMatPcb, { x: hole.x, y: hole.y });
79861
79919
  const libraryLink = this.getPlatedHoleLibraryLink(hole);
79862
79920
  const footprint = new Footprint5({
79863
79921
  libraryLink,
@@ -79955,7 +80013,7 @@ function createFabricationNoteTextFromCircuitJson({
79955
80013
  if (!textElement.text || !textElement.anchor_position) {
79956
80014
  return null;
79957
80015
  }
79958
- const transformedPos = applyToPoint26(c2kMatPcb, {
80016
+ const transformedPos = applyToPoint28(c2kMatPcb, {
79959
80017
  x: textElement.anchor_position.x,
79960
80018
  y: textElement.anchor_position.y
79961
80019
  });
@@ -80013,7 +80071,7 @@ function createGrTextFromCircuitJson({
80013
80071
  if (!textElement.text || !textElement.anchor_position) {
80014
80072
  return null;
80015
80073
  }
80016
- const transformedPos = applyToPoint27(c2kMatPcb, {
80074
+ const transformedPos = applyToPoint29(c2kMatPcb, {
80017
80075
  x: textElement.anchor_position.x,
80018
80076
  y: textElement.anchor_position.y
80019
80077
  });
@@ -80073,7 +80131,7 @@ var appendGraphicLine = (kicadPcb, grLine) => {
80073
80131
  var rotatePointAroundOrigin = (point, rotationDegrees = 0) => {
80074
80132
  if (!rotationDegrees)
80075
80133
  return point;
80076
- return applyToPoint28(rotate13(rotationDegrees * Math.PI / 180), point);
80134
+ return applyToPoint30(rotate13(rotationDegrees * Math.PI / 180), point);
80077
80135
  };
80078
80136
  var getRectCutoutCorners = (cutout) => {
80079
80137
  const halfWidth = cutout.width / 2;
@@ -80111,11 +80169,11 @@ var AddGraphicsStage = class extends ConverterStage {
80111
80169
  const endPoint = path.route[i + 1];
80112
80170
  if (!startPoint || !endPoint)
80113
80171
  continue;
80114
- const transformedStart = applyToPoint28(c2kMatPcb, {
80172
+ const transformedStart = applyToPoint30(c2kMatPcb, {
80115
80173
  x: startPoint.x,
80116
80174
  y: startPoint.y
80117
80175
  });
80118
- const transformedEnd = applyToPoint28(c2kMatPcb, {
80176
+ const transformedEnd = applyToPoint30(c2kMatPcb, {
80119
80177
  x: endPoint.x,
80120
80178
  y: endPoint.y
80121
80179
  });
@@ -80199,7 +80257,7 @@ var AddGraphicsStage = class extends ConverterStage {
80199
80257
  }
80200
80258
  for (const poly of boardGeom) {
80201
80259
  for (const ring of poly) {
80202
- const transformedRing = ring.map((point) => applyToPoint28(c2kMatPcb, { x: point[0], y: point[1] }));
80260
+ const transformedRing = ring.map((point) => applyToPoint30(c2kMatPcb, { x: point[0], y: point[1] }));
80203
80261
  for (let i = 0;i < transformedRing.length; i++) {
80204
80262
  const start = transformedRing[i];
80205
80263
  const end = transformedRing[(i + 1) % transformedRing.length];
@@ -80228,8 +80286,8 @@ var AddGraphicsStage = class extends ConverterStage {
80228
80286
  const endPoint = cutout.route[i + 1];
80229
80287
  if (!startPoint || !endPoint)
80230
80288
  continue;
80231
- const transformedStart = applyToPoint28(c2kMatPcb, startPoint);
80232
- const transformedEnd = applyToPoint28(c2kMatPcb, endPoint);
80289
+ const transformedStart = applyToPoint30(c2kMatPcb, startPoint);
80290
+ const transformedEnd = applyToPoint30(c2kMatPcb, endPoint);
80233
80291
  appendGraphicLine(kicadPcb, new GrLine({
80234
80292
  start: transformedStart,
80235
80293
  end: transformedEnd,
@@ -80264,7 +80322,7 @@ var CircuitJsonToKicadPcbConverter = class {
80264
80322
  generator: "circuit-json-to-kicad",
80265
80323
  generatorVersion: "0.0.1"
80266
80324
  }),
80267
- c2kMatPcb: compose8(translate8(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale6(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE)),
80325
+ c2kMatPcb: compose10(translate10(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale7(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE)),
80268
80326
  projectName: options?.projectName,
80269
80327
  edgeCutsWidth: options?.edgeCutsWidth,
80270
80328
  pcbModel3dSourcePaths: []
@@ -80339,6 +80397,7 @@ var CircuitJsonToKicadProConverter = class {
80339
80397
  const minViaDrill = pcbBoard?.min_via_hole_diameter ?? 0.2;
80340
80398
  const minViaAnnularWidth = (minViaDiameter - minViaDrill) / 2;
80341
80399
  const minTraceToPadClearance = pcbBoard?.min_trace_to_pad_edge_clearance ?? 0.1;
80400
+ const minTraceToHoleClearance = pcbBoard?.min_trace_to_hole_edge_clearance ?? minTraceToPadClearance;
80342
80401
  const minTrackWidth = pcbBoard?.min_trace_width ?? 0.1;
80343
80402
  const netClasses = [
80344
80403
  this.createBaseNetClass({
@@ -80403,10 +80462,11 @@ var CircuitJsonToKicadProConverter = class {
80403
80462
  design_settings: {
80404
80463
  rules: {
80405
80464
  min_via_annular_width: minViaAnnularWidth,
80406
- min_hole_clearance: minTraceToPadClearance,
80465
+ min_hole_clearance: minTraceToHoleClearance,
80407
80466
  min_via_diameter: minViaDiameter,
80408
80467
  min_track_width: minTrackWidth,
80409
- min_through_hole_diameter: minViaDrill
80468
+ min_through_hole_diameter: minViaDrill,
80469
+ ...pcbBoard?.min_board_edge_clearance !== undefined ? { min_copper_edge_clearance: pcbBoard.min_board_edge_clearance } : {}
80410
80470
  }
80411
80471
  },
80412
80472
  last_opened_board: pcbFilename
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.2418",
3
+ "version": "0.1.2421",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/tscircuit/cli"
@@ -41,7 +41,7 @@
41
41
  "circuit-json-to-fdm-component-box": "^0.0.2",
42
42
  "circuit-json-to-footprinter": "^0.0.59",
43
43
  "circuit-json-to-gerber": "^0.0.120",
44
- "circuit-json-to-kicad": "0.0.253",
44
+ "circuit-json-to-kicad": "0.0.259",
45
45
  "circuit-json-to-readable-netlist": "^0.0.15",
46
46
  "circuit-json-to-step": "^0.0.47",
47
47
  "circuit-json-to-tscircuit": "^0.0.50",