jscad-electronics 0.0.148 → 0.0.150

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/vanilla.js CHANGED
@@ -43,16 +43,23 @@ var jsx = (type, props, _key) => h(type, props);
43
43
  var jsxs = (type, props, _key) => h(type, props);
44
44
 
45
45
  // lib/FootprintPad.tsx
46
+ var PAD_THICKNESS = 0.01;
46
47
  var FootprintPad = ({
47
48
  pad,
48
49
  isPin1
49
50
  }) => {
51
+ const color = isPin1 ? [0, 255, 0] : [255, 0, 0];
50
52
  if (pad.shape === "rect") {
51
- const color = isPin1 ? [0, 255, 0] : [255, 0, 0];
52
- return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Translate, { offset: [pad.x, pad.y, -5e-3], children: /* @__PURE__ */ jsx(Cuboid, { size: [pad.width, pad.height, 0.01] }) }) });
53
- } else {
54
- throw new Error("Shape not supported: " + pad.shape);
53
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Translate, { offset: [pad.x, pad.y, -5e-3], children: /* @__PURE__ */ jsx(Cuboid, { size: [pad.width, pad.height, PAD_THICKNESS] }) }) });
54
+ }
55
+ if (pad.shape === "polygon") {
56
+ const points = (pad.points ?? []).map(
57
+ ({ x, y }) => [x, y]
58
+ );
59
+ if (points.length < 3) return null;
60
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Translate, { offset: [0, 0, -5e-3], children: /* @__PURE__ */ jsx(ExtrudeLinear, { height: PAD_THICKNESS, children: /* @__PURE__ */ jsx(Polygon, { points }) }) }) });
55
61
  }
62
+ throw new Error("Shape not supported: " + pad.shape);
56
63
  };
57
64
 
58
65
  // lib/FootprintPlatedHole.tsx
@@ -173,7 +180,7 @@ var ExtrudedPads = ({
173
180
  };
174
181
 
175
182
  // lib/Footprinter3d.tsx
176
- import { fp as fp2 } from "@tscircuit/footprinter";
183
+ import { fp as fp5 } from "@tscircuit/footprinter";
177
184
 
178
185
  // lib/ChipBody.tsx
179
186
  var ChipBody = ({
@@ -2210,8 +2217,8 @@ var SMA = () => {
2210
2217
 
2211
2218
  // lib/SMB.tsx
2212
2219
  var SMB = () => {
2213
- const bodyWidth = 4.4;
2214
- const bodyLength10 = 3.4;
2220
+ const bodyWidth = 4.6;
2221
+ const bodyLength10 = 4;
2215
2222
  const bodyHeight = 2.3;
2216
2223
  const padWidth = 1.45;
2217
2224
  const padThickness = 0.12;
@@ -2491,12 +2498,14 @@ var SOD123FL = () => {
2491
2498
  };
2492
2499
 
2493
2500
  // lib/sod-123W.tsx
2494
- var SOD123W = () => {
2495
- const fullWidth = 2.6;
2496
- const bodyLength10 = 1.7;
2497
- const bodyHeight = 1;
2498
- const padWidth = 0.9;
2499
- const padLength = 0.9;
2501
+ var SOD123W = ({
2502
+ bodyWidth = 2.6,
2503
+ bodyLength: bodyLength10 = 1.7,
2504
+ bodyHeight = 1
2505
+ } = {}) => {
2506
+ const fullWidth = bodyWidth;
2507
+ const padWidth = bodyLength10 * 0.53;
2508
+ const padLength = bodyWidth * 0.35;
2500
2509
  const padThickness = 0.2;
2501
2510
  const leftPadCenterX = -(fullWidth / 2 - 0.075);
2502
2511
  const rightPadCenterX = fullWidth / 2 - 0.075;
@@ -2758,17 +2767,19 @@ var SOD923 = () => {
2758
2767
  };
2759
2768
 
2760
2769
  // lib/SOT-223.tsx
2761
- var SOT223 = () => {
2762
- const fullWidth = 6.6;
2763
- const bodyWidth = 3.5;
2764
- const bodyLength10 = 6.5;
2765
- const bodyHeight = 1.7;
2766
- const leadWidth = 0.7;
2767
- const leftLeadWidth = 3;
2770
+ var SOT223 = ({
2771
+ fullWidth = 6.6,
2772
+ bodyWidth = 3.5,
2773
+ bodyLength: bodyLength10 = 6.5,
2774
+ bodyHeight = 1.7,
2775
+ leadWidth = 0.7,
2776
+ tabLeadWidth = 3,
2777
+ padPitch = 2.3,
2778
+ leadHeight = 0.75
2779
+ } = {}) => {
2780
+ const leftLeadWidth = tabLeadWidth;
2768
2781
  const leadThickness = 0.25;
2769
- const leadHeight = 0.75;
2770
2782
  const padContactLength = 0.5;
2771
- const padPitch = 2.3;
2772
2783
  const extendedBodyDistance = fullWidth - bodyWidth;
2773
2784
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
2774
2785
  /* @__PURE__ */ jsx(
@@ -3624,78 +3635,67 @@ var MS013 = ({
3624
3635
  };
3625
3636
 
3626
3637
  // lib/TO220.tsx
3627
- var TO220 = () => {
3628
- const fullLength10 = 20;
3629
- const bodyLength10 = 9.9;
3630
- const bodyHeight = 4.5;
3631
- const zOffset = 1;
3632
- const padWidth = 9.9;
3633
- const padLength = 6.5;
3634
- const padThickness = 1.3;
3635
- const padHoleDiameter = 3;
3636
- const prongWidth = 0.81;
3637
- const prongLength = 16;
3638
- const prongHeight = 0.5;
3639
- const prongPitch = 2.7;
3640
- const bodyWidth = padWidth;
3641
- const bodyFrontX = fullLength10 - bodyLength10 / 2;
3642
- const bodyBackX = fullLength10 + bodyLength10 / 2;
3643
- const prongCenterX = bodyFrontX - prongLength / 2;
3644
- const padCenterX = bodyBackX + padLength / 2;
3645
- return /* @__PURE__ */ jsx(Translate, { center: [0, 0, zOffset], children: /* @__PURE__ */ jsxs(Fragment2, { children: [
3646
- /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 55, -55], children: [
3647
- /* @__PURE__ */ jsxs(Subtract, { children: [
3648
- /* @__PURE__ */ jsx(
3649
- Cuboid,
3650
- {
3651
- color: "#ccc",
3652
- size: [padLength + 0.1, padWidth, padThickness],
3653
- center: [padCenterX, 0, padThickness - 2]
3654
- }
3655
- ),
3656
- /* @__PURE__ */ jsx(
3657
- Cylinder,
3658
- {
3659
- color: "black",
3660
- center: [padCenterX, 0, padThickness - 2],
3661
- radius: padHoleDiameter / 2,
3662
- height: padThickness * 1.2
3663
- }
3664
- )
3665
- ] }),
3666
- /* @__PURE__ */ jsx(Colorize, { color: "#222", children: /* @__PURE__ */ jsx(
3667
- ChipBody,
3638
+ var TO220_DEFAULT_LEADS = [
3639
+ { x: -2.54, y: -1 },
3640
+ { x: 0, y: -1 },
3641
+ { x: 2.54, y: -1 }
3642
+ ];
3643
+ var TO220 = ({
3644
+ mouldedTab = false,
3645
+ leads = TO220_DEFAULT_LEADS,
3646
+ bodyWidth = 10,
3647
+ bodyThickness = 4.5,
3648
+ bodyHeight = 9.2,
3649
+ tabHeight = 6.4,
3650
+ tabThickness = 1.4,
3651
+ mountingHoleDiameter = 3.6,
3652
+ standoff = 3,
3653
+ leadLength = 3,
3654
+ bodyColor = "#222",
3655
+ tabColor = "#ccc",
3656
+ leadColor = "#d4b106"
3657
+ } = {}) => {
3658
+ const centerX = leads.reduce((sum, lead) => sum + lead.x, 0) / leads.length;
3659
+ const centerY = leads.reduce((sum, lead) => sum + lead.y, 0) / leads.length;
3660
+ const bodyBottom = standoff;
3661
+ const bodyTop = bodyBottom + bodyHeight;
3662
+ const tabTop = bodyTop + tabHeight;
3663
+ const tabY = centerY + (bodyThickness - tabThickness) / 2;
3664
+ const holeZ = tabTop - Math.max(mountingHoleDiameter * 0.8, 2.6);
3665
+ const leadWidth = 0.8;
3666
+ const leadThickness = 0.5;
3667
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
3668
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
3669
+ Cuboid,
3670
+ {
3671
+ size: [bodyWidth, bodyThickness, bodyHeight],
3672
+ center: [centerX, centerY, bodyBottom + bodyHeight / 2]
3673
+ }
3674
+ ) }),
3675
+ /* @__PURE__ */ jsx(Colorize, { color: mouldedTab ? bodyColor : tabColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
3676
+ /* @__PURE__ */ jsx(
3677
+ Cuboid,
3668
3678
  {
3669
- width: bodyWidth,
3670
- length: bodyLength10,
3671
- height: bodyHeight,
3672
- center: { x: fullLength10, y: 0, z: -2.4 },
3673
- includeNotch: false,
3674
- straightHeightRatio: 0.3,
3675
- taperRatio: 0.04,
3676
- heightAboveSurface: 1
3679
+ size: [bodyWidth, tabThickness, tabHeight],
3680
+ center: [centerX, tabY, bodyTop + tabHeight / 2]
3677
3681
  }
3678
- ) })
3679
- ] }),
3680
- /* @__PURE__ */ jsx(Rotate, { rotation: [0, 55, 55], children: Array.from({ length: 3 }).map((_, i) => {
3681
- const x = prongCenterX;
3682
- const y = (i - 1) * prongPitch;
3683
- const z = -prongHeight - 0.6;
3684
- return /* @__PURE__ */ jsxs(Colorize, { color: "gold", children: [
3685
- /* @__PURE__ */ jsxs(Hull, { children: [
3686
- /* @__PURE__ */ jsx(Translate, { center: [bodyFrontX - bodyHeight / 2 + 0.1, y, z], children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyHeight, prongWidth + 1, prongHeight] }) }),
3687
- /* @__PURE__ */ jsx(
3688
- Translate,
3689
- {
3690
- center: [bodyFrontX - bodyHeight / 2 - 1 + 0.1, y, z],
3691
- children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyHeight, prongWidth, prongHeight] })
3692
- }
3693
- )
3694
- ] }),
3695
- /* @__PURE__ */ jsx(Translate, { center: [x, y, z], children: /* @__PURE__ */ jsx(Cuboid, { size: [prongLength + 0.1, prongWidth, prongHeight] }) })
3696
- ] }, `prong-${i}`);
3697
- }) })
3698
- ] }) });
3682
+ ),
3683
+ /* @__PURE__ */ jsx(Rotate, { rotation: ["90deg", 0, 0], children: /* @__PURE__ */ jsx(Translate, { center: [centerX, holeZ, -tabY], children: /* @__PURE__ */ jsx(
3684
+ Cylinder,
3685
+ {
3686
+ radius: mountingHoleDiameter / 2,
3687
+ height: tabThickness * 3
3688
+ }
3689
+ ) }) })
3690
+ ] }) }),
3691
+ leads.map((lead) => /* @__PURE__ */ jsx(Colorize, { color: leadColor, children: /* @__PURE__ */ jsx(
3692
+ Cuboid,
3693
+ {
3694
+ size: [leadWidth, leadThickness, standoff + leadLength],
3695
+ center: [lead.x, lead.y, (standoff - leadLength) / 2]
3696
+ }
3697
+ ) }, `lead-${lead.x}-${lead.y}`))
3698
+ ] });
3699
3699
  };
3700
3700
 
3701
3701
  // lib/SOT-457.tsx
@@ -3893,39 +3893,95 @@ var SOT963 = () => {
3893
3893
  };
3894
3894
 
3895
3895
  // lib/TO92.tsx
3896
- var TO92 = () => {
3897
- const bodyRadius = 2.4;
3898
- const bodyHeight = 4.5;
3899
- const flatCut = 1.1;
3896
+ var TO92_DEFAULT_LEADS = [
3897
+ { x: -1.27, y: 0.98 },
3898
+ { x: 0, y: 2.25 },
3899
+ { x: 1.27, y: 0.98 }
3900
+ ];
3901
+ var splitOuterLeads = (leads) => {
3902
+ let outer = [leads[0], leads[leads.length - 1]];
3903
+ let best = -1;
3904
+ for (let i = 0; i < leads.length; i++) {
3905
+ for (let j = i + 1; j < leads.length; j++) {
3906
+ const separation = Math.hypot(
3907
+ leads[i].x - leads[j].x,
3908
+ leads[i].y - leads[j].y
3909
+ );
3910
+ if (separation > best) {
3911
+ best = separation;
3912
+ outer = [leads[i], leads[j]];
3913
+ }
3914
+ }
3915
+ }
3916
+ return { outer, separation: best };
3917
+ };
3918
+ var TO92 = ({
3919
+ bodyDiameter = 4.8,
3920
+ bodyHeight = 4.5,
3921
+ flatCut = 1.1,
3922
+ leads = TO92_DEFAULT_LEADS,
3923
+ standoff = 1.5,
3924
+ leadLength = 3,
3925
+ bodyColor = "#222"
3926
+ } = {}) => {
3927
+ const bodyRadius = bodyDiameter / 2;
3900
3928
  const legWidth = 0.4;
3901
3929
  const legThickness = 0.25;
3902
- const bodyZ = bodyHeight / 2;
3903
- const bodyColor = "#222";
3904
- const leadLength = 0.43;
3905
- const leadTipSize = [leadLength, legWidth, 1.32];
3906
- const leadSmallSize = [
3907
- leadLength,
3930
+ const { outer, separation } = splitOuterLeads(leads);
3931
+ const [first, last] = outer;
3932
+ const bodyCenter = {
3933
+ x: (first.x + last.x) / 2,
3934
+ y: (first.y + last.y) / 2
3935
+ };
3936
+ const axisLength = Math.max(separation, 1e-3);
3937
+ const axis = {
3938
+ x: (last.x - first.x) / axisLength,
3939
+ y: (last.y - first.y) / axisLength
3940
+ };
3941
+ const exitPitch = separation / 2;
3942
+ const exitFor = (index) => {
3943
+ const offset = (index - (leads.length - 1) / 2) * exitPitch;
3944
+ return {
3945
+ x: bodyCenter.x + axis.x * offset,
3946
+ y: bodyCenter.y + axis.y * offset
3947
+ };
3948
+ };
3949
+ const leadSize = [
3950
+ legThickness,
3908
3951
  legWidth,
3909
3952
  legThickness
3910
3953
  ];
3911
- const leadTipPos1 = [0, 0, -0.66];
3912
- const leadMidPosA = [0, 0, -1.32];
3913
- const leadMidPosB = [0, 1.28, -2.72];
3914
- const leadTipPos2 = [0, 1.28, -8.9];
3915
- const sideLeadZ = -7.5;
3916
- return /* @__PURE__ */ jsxs(Translate, { center: [0, 1, 10.5], children: [
3954
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
3917
3955
  /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
3918
- /* @__PURE__ */ jsx(Translate, { center: [0, 0, bodyZ], children: /* @__PURE__ */ jsx(Cylinder, { radius: bodyRadius, height: bodyHeight }) }),
3919
- /* @__PURE__ */ jsx(Translate, { center: [0, -(bodyRadius - flatCut / 2), bodyZ], children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyRadius * 2, flatCut, bodyHeight + 0.2] }) })
3956
+ /* @__PURE__ */ jsx(
3957
+ Translate,
3958
+ {
3959
+ center: [bodyCenter.x, bodyCenter.y, standoff + bodyHeight / 2],
3960
+ children: /* @__PURE__ */ jsx(Cylinder, { radius: bodyRadius, height: bodyHeight })
3961
+ }
3962
+ ),
3963
+ /* @__PURE__ */ jsx(
3964
+ Translate,
3965
+ {
3966
+ center: [
3967
+ bodyCenter.x,
3968
+ bodyCenter.y - (bodyRadius - flatCut / 2),
3969
+ standoff + bodyHeight / 2
3970
+ ],
3971
+ children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyRadius * 2, flatCut, bodyHeight + 0.2] })
3972
+ }
3973
+ )
3920
3974
  ] }) }),
3921
- /* @__PURE__ */ jsx(Translate, { center: leadTipPos1, children: /* @__PURE__ */ jsx(Cuboid, { size: leadTipSize }) }),
3922
- /* @__PURE__ */ jsxs(Hull, { children: [
3923
- /* @__PURE__ */ jsx(Translate, { center: leadMidPosA, children: /* @__PURE__ */ jsx(Cuboid, { size: leadSmallSize }) }),
3924
- /* @__PURE__ */ jsx(Translate, { center: leadMidPosB, children: /* @__PURE__ */ jsx(Cuboid, { size: leadSmallSize }) })
3925
- ] }),
3926
- /* @__PURE__ */ jsx(Translate, { center: leadTipPos2, children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, legWidth, 12.2] }) }),
3927
- /* @__PURE__ */ jsx(Translate, { center: [1.3, 0, sideLeadZ], children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, legWidth, 15] }) }),
3928
- /* @__PURE__ */ jsx(Translate, { center: [-1.3, 0, sideLeadZ], children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, legWidth, 15] }) })
3975
+ leads.map((lead, index) => {
3976
+ const exit = exitFor(index);
3977
+ return /* @__PURE__ */ jsxs(Translate, { center: [0, 0, 0], children: [
3978
+ /* @__PURE__ */ jsxs(Hull, { children: [
3979
+ /* @__PURE__ */ jsx(Translate, { center: [lead.x, lead.y, 0], children: /* @__PURE__ */ jsx(Cuboid, { size: leadSize }) }),
3980
+ /* @__PURE__ */ jsx(Translate, { center: [exit.x, exit.y, standoff], children: /* @__PURE__ */ jsx(Cuboid, { size: leadSize }) })
3981
+ ] }),
3982
+ /* @__PURE__ */ jsx(Translate, { center: [lead.x, lead.y, -leadLength / 2], children: /* @__PURE__ */ jsx(Cuboid, { size: [legThickness, legWidth, leadLength] }) })
3983
+ ] }, `lead-${lead.x}-${lead.y}`);
3984
+ })
3929
3985
  ] });
3930
3986
  };
3931
3987
 
@@ -4121,8 +4177,8 @@ var SOT886 = () => {
4121
4177
  // lib/sod-323.tsx
4122
4178
  var SOD323 = () => {
4123
4179
  const fullWidth = 2.5;
4124
- const bodyLength10 = 1.25;
4125
- const bodyWidth = 1.7;
4180
+ const bodyLength10 = 1.4;
4181
+ const bodyWidth = 1.8;
4126
4182
  const bodyHeight = 0.95;
4127
4183
  const leadWidth = 0.3;
4128
4184
  const leadThickness = 0.175;
@@ -5406,6 +5462,84 @@ var SmdPinHeader = ({
5406
5462
  // lib/Footprinter3d.tsx
5407
5463
  import { mm } from "@tscircuit/mm";
5408
5464
 
5465
+ // lib/utils/getPlatedHoleCenters.ts
5466
+ import { fp as fp2 } from "@tscircuit/footprinter";
5467
+ var getPlatedHoleCenters = (footprint) => {
5468
+ const elements = fp2.string(footprint).circuitJson();
5469
+ return elements.filter(
5470
+ (element) => element.type === "pcb_plated_hole" && Number.isFinite(element.x) && Number.isFinite(element.y)
5471
+ ).map((element) => ({
5472
+ x: element.x,
5473
+ y: element.y,
5474
+ pin: element.port_hints?.[0]
5475
+ }));
5476
+ };
5477
+
5478
+ // lib/utils/getSmtPadRects.ts
5479
+ import { fp as fp3 } from "@tscircuit/footprinter";
5480
+ var getSmtPadRects = (footprint) => {
5481
+ const elements = fp3.string(footprint).circuitJson();
5482
+ return elements.filter(
5483
+ (element) => element.type === "pcb_smtpad" && element.shape === "rect" && Number.isFinite(element.x) && Number.isFinite(element.y)
5484
+ ).map((element) => ({
5485
+ x: element.x,
5486
+ y: element.y,
5487
+ width: element.width ?? 0.4,
5488
+ height: element.height ?? 0.4,
5489
+ pin: element.port_hints?.[0]
5490
+ }));
5491
+ };
5492
+
5493
+ // lib/GullWingBody.tsx
5494
+ var GullWingBody = ({
5495
+ bodyWidth,
5496
+ bodyLength: bodyLength10,
5497
+ bodyHeight = 1,
5498
+ pads,
5499
+ leadThickness = 0.15,
5500
+ leadHeightRatio = 0.75
5501
+ }) => {
5502
+ const centerX = pads.reduce((sum, pad) => sum + pad.x, 0) / (pads.length || 1);
5503
+ const centerY = pads.reduce((sum, pad) => sum + pad.y, 0) / (pads.length || 1);
5504
+ const leadHeight = bodyHeight * leadHeightRatio;
5505
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5506
+ /* @__PURE__ */ jsx(
5507
+ ChipBody,
5508
+ {
5509
+ center: { x: centerX, y: centerY, z: 0 },
5510
+ width: bodyWidth,
5511
+ length: bodyLength10,
5512
+ height: bodyHeight
5513
+ }
5514
+ ),
5515
+ pads.map((pad) => {
5516
+ const padWidth = pad.width ?? 0.4;
5517
+ const padLength = pad.height ?? 0.4;
5518
+ const side = pad.x >= centerX ? 1 : -1;
5519
+ const outerX = pad.x + side * padWidth / 2;
5520
+ const run = Math.max(Math.abs(outerX - centerX) - bodyWidth / 2, 0.1);
5521
+ const overlap = Math.min(0.15, bodyWidth * 0.15);
5522
+ return /* @__PURE__ */ jsx(
5523
+ SmdChipLead,
5524
+ {
5525
+ rotation: side > 0 ? Math.PI : 0,
5526
+ position: {
5527
+ x: outerX,
5528
+ y: pad.y,
5529
+ z: leadThickness / 2
5530
+ },
5531
+ width: padLength,
5532
+ thickness: leadThickness,
5533
+ padContactLength: padWidth * 0.6,
5534
+ bodyDistance: run + overlap,
5535
+ height: leadHeight
5536
+ },
5537
+ `lead-${pad.x}-${pad.y}`
5538
+ );
5539
+ })
5540
+ ] });
5541
+ };
5542
+
5409
5543
  // lib/ParametricChip.tsx
5410
5544
  var ParametricChip = ({
5411
5545
  padPitch,
@@ -5525,6 +5659,57 @@ var Led5050 = ({
5525
5659
  ] });
5526
5660
  };
5527
5661
 
5662
+ // lib/Led2835.tsx
5663
+ var Led2835 = ({
5664
+ bodyWidth = 3.5,
5665
+ bodyLength: bodyLength10 = 2.8,
5666
+ bodyHeight = 0.8,
5667
+ color = "#ffe08a",
5668
+ bodyColor = "#f2f2f2",
5669
+ padColor = "#cccccc",
5670
+ pad1X = -0.9,
5671
+ pad1Width = 2.2,
5672
+ pad2X = 1.375,
5673
+ pad2Width = 1.25,
5674
+ padLength = 2.2
5675
+ } = {}) => {
5676
+ const padThickness = 0.1;
5677
+ const lensHeight = 0.15;
5678
+ const bodyCenterX = (pad1X + pad2X) / 2;
5679
+ const lensWidth = bodyWidth * 0.55;
5680
+ const lensLength = bodyLength10 * 0.55;
5681
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5682
+ [
5683
+ { x: pad1X, w: pad1Width, key: "pad-1" },
5684
+ { x: pad2X, w: pad2Width, key: "pad-2" }
5685
+ ].map(({ x, w, key }) => /* @__PURE__ */ jsx(Colorize, { color: padColor, children: /* @__PURE__ */ jsx(
5686
+ Cuboid,
5687
+ {
5688
+ size: [w, padLength, padThickness],
5689
+ center: [x, 0, padThickness / 2]
5690
+ }
5691
+ ) }, key)),
5692
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
5693
+ Cuboid,
5694
+ {
5695
+ size: [bodyWidth, bodyLength10, bodyHeight],
5696
+ center: [bodyCenterX, 0, padThickness + bodyHeight / 2]
5697
+ }
5698
+ ) }),
5699
+ /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(
5700
+ Cuboid,
5701
+ {
5702
+ size: [lensWidth, lensLength, lensHeight],
5703
+ center: [
5704
+ bodyCenterX,
5705
+ 0,
5706
+ padThickness + bodyHeight + lensHeight / 2 - 0.05
5707
+ ]
5708
+ }
5709
+ ) })
5710
+ ] });
5711
+ };
5712
+
5528
5713
  // lib/RJ45.tsx
5529
5714
  var range2 = (length) => Array.from({ length }, (_, index) => index);
5530
5715
  var RJ45 = ({
@@ -5761,6 +5946,339 @@ var RJ45 = ({
5761
5946
  ] });
5762
5947
  };
5763
5948
 
5949
+ // lib/DPAK.tsx
5950
+ var DPAK = ({
5951
+ bodyWidth = 6.1,
5952
+ bodyLength: bodyLength10 = 6.5,
5953
+ bodyHeight = 2.3,
5954
+ tabWidth = 6.2,
5955
+ tabLength = 5.8,
5956
+ span = 6.85,
5957
+ pitch = 2.29,
5958
+ leadWidth = 0.9,
5959
+ leadContactLength = 1.5,
5960
+ color = "#222",
5961
+ tabColor = "#cccccc",
5962
+ leadColor = "#cccccc"
5963
+ }) => {
5964
+ const tabThickness = 0.5;
5965
+ const tabCenterX = span / 2;
5966
+ const leadPadX = -span / 2;
5967
+ const bodyCenterX = tabCenterX + (tabWidth - bodyWidth) / 2;
5968
+ const bodyFrontX = bodyCenterX - bodyWidth / 2;
5969
+ const leadZ = tabThickness / 2;
5970
+ const leadThickness = 0.4;
5971
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5972
+ /* @__PURE__ */ jsx(Colorize, { color: tabColor, children: /* @__PURE__ */ jsx(
5973
+ Cuboid,
5974
+ {
5975
+ size: [tabWidth, tabLength, tabThickness],
5976
+ center: [tabCenterX, 0, tabThickness / 2]
5977
+ }
5978
+ ) }),
5979
+ /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(
5980
+ Cuboid,
5981
+ {
5982
+ size: [bodyWidth, bodyLength10, bodyHeight],
5983
+ center: [bodyCenterX, 0, tabThickness + bodyHeight / 2]
5984
+ }
5985
+ ) }),
5986
+ [-1, 1].map((side) => {
5987
+ return /* @__PURE__ */ jsxs(Colorize, { color: leadColor, children: [
5988
+ /* @__PURE__ */ jsx(
5989
+ Cuboid,
5990
+ {
5991
+ size: [leadContactLength, leadWidth, leadThickness],
5992
+ center: [
5993
+ leadPadX + leadContactLength / 2,
5994
+ side * pitch,
5995
+ leadThickness / 2
5996
+ ]
5997
+ }
5998
+ ),
5999
+ /* @__PURE__ */ jsxs(Hull, { children: [
6000
+ /* @__PURE__ */ jsx(
6001
+ Cuboid,
6002
+ {
6003
+ size: [0.1, leadWidth, leadThickness],
6004
+ center: [
6005
+ leadPadX + leadContactLength,
6006
+ side * pitch,
6007
+ leadThickness / 2
6008
+ ]
6009
+ }
6010
+ ),
6011
+ /* @__PURE__ */ jsx(
6012
+ Cuboid,
6013
+ {
6014
+ size: [0.1, leadWidth, leadThickness],
6015
+ center: [bodyFrontX, side * pitch, leadZ + tabThickness / 2]
6016
+ }
6017
+ )
6018
+ ] })
6019
+ ] }, `lead-${side}`);
6020
+ })
6021
+ ] });
6022
+ };
6023
+
6024
+ // lib/ElectrolyticCapacitor.tsx
6025
+ var ElectrolyticCapacitor = ({
6026
+ diameter = 6.3,
6027
+ heightToDiameterRatio = 1.4,
6028
+ height: height10 = diameter * heightToDiameterRatio,
6029
+ leadPitch = 2.5,
6030
+ leadDiameter = 0.6,
6031
+ leadLength = 3,
6032
+ sleeveColor = "#1b2a6b",
6033
+ baseColor = "#1a1a1a"
6034
+ }) => {
6035
+ const radius = diameter / 2;
6036
+ const baseHeight = Math.min(1, diameter * 0.12);
6037
+ const canHeight = Math.max(height10 - baseHeight, 0.1);
6038
+ const canBottom = baseHeight;
6039
+ const canTop = canBottom + canHeight;
6040
+ const grooveWidth = Math.max(diameter * 0.06, 0.2);
6041
+ const grooveDepth = 0.3;
6042
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6043
+ /* @__PURE__ */ jsx(Colorize, { color: baseColor, children: /* @__PURE__ */ jsx(
6044
+ Cylinder,
6045
+ {
6046
+ radius: radius - 0.05,
6047
+ height: baseHeight,
6048
+ center: [0, 0, baseHeight / 2]
6049
+ }
6050
+ ) }),
6051
+ /* @__PURE__ */ jsx(Colorize, { color: sleeveColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
6052
+ /* @__PURE__ */ jsx(
6053
+ RoundedCylinder,
6054
+ {
6055
+ radius,
6056
+ height: canHeight,
6057
+ roundRadius: Math.min(0.3, radius * 0.15),
6058
+ center: [0, 0, canBottom + canHeight / 2]
6059
+ }
6060
+ ),
6061
+ /* @__PURE__ */ jsx(
6062
+ Cuboid,
6063
+ {
6064
+ size: [diameter, grooveWidth, grooveDepth * 2],
6065
+ center: [0, 0, canTop]
6066
+ }
6067
+ ),
6068
+ /* @__PURE__ */ jsx(
6069
+ Cuboid,
6070
+ {
6071
+ size: [grooveWidth, diameter, grooveDepth * 2],
6072
+ center: [0, 0, canTop]
6073
+ }
6074
+ )
6075
+ ] }) }),
6076
+ [-1, 1].map((side) => /* @__PURE__ */ jsx(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsx(
6077
+ Cylinder,
6078
+ {
6079
+ radius: leadDiameter / 2,
6080
+ height: leadLength + baseHeight,
6081
+ center: [side * leadPitch / 2, 0, (baseHeight - leadLength) / 2]
6082
+ }
6083
+ ) }, `lead-${side}`))
6084
+ ] });
6085
+ };
6086
+
6087
+ // lib/Potentiometer.tsx
6088
+ var Potentiometer = ({
6089
+ bodyWidth = 5.35,
6090
+ bodyLength: bodyLength10 = 14,
6091
+ bodyHeight = 4,
6092
+ bodyCenterX = bodyWidth / 2,
6093
+ adjusterDiameter = Math.min(bodyWidth, bodyLength10) * 0.55,
6094
+ shaftDiameter = 0,
6095
+ shaftHeight = 0,
6096
+ leads = [],
6097
+ leadDiameter = 0.6,
6098
+ leadLength = 3,
6099
+ bodyColor = "#1f4fa3",
6100
+ adjusterColor = "#d8d8d8"
6101
+ }) => {
6102
+ const adjusterHeight = 0.8;
6103
+ const adjusterZ = bodyHeight + adjusterHeight / 2;
6104
+ const slotWidth = Math.max(adjusterDiameter * 0.16, 0.3);
6105
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6106
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
6107
+ Cuboid,
6108
+ {
6109
+ size: [bodyWidth, bodyLength10, bodyHeight],
6110
+ center: [bodyCenterX, 0, bodyHeight / 2]
6111
+ }
6112
+ ) }),
6113
+ /* @__PURE__ */ jsx(Colorize, { color: adjusterColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
6114
+ /* @__PURE__ */ jsx(
6115
+ Cylinder,
6116
+ {
6117
+ radius: adjusterDiameter / 2,
6118
+ height: adjusterHeight,
6119
+ center: [bodyCenterX, 0, adjusterZ]
6120
+ }
6121
+ ),
6122
+ /* @__PURE__ */ jsx(
6123
+ Cuboid,
6124
+ {
6125
+ size: [adjusterDiameter, slotWidth, adjusterHeight * 0.6],
6126
+ center: [bodyCenterX, 0, adjusterZ + adjusterHeight / 2]
6127
+ }
6128
+ )
6129
+ ] }) }),
6130
+ shaftHeight > 0 && shaftDiameter > 0 ? /* @__PURE__ */ jsx(Colorize, { color: adjusterColor, children: /* @__PURE__ */ jsx(
6131
+ Cylinder,
6132
+ {
6133
+ radius: shaftDiameter / 2,
6134
+ height: shaftHeight,
6135
+ center: [bodyCenterX, 0, bodyHeight + shaftHeight / 2]
6136
+ }
6137
+ ) }) : null,
6138
+ leads.map((lead) => /* @__PURE__ */ jsx(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsx(
6139
+ Cylinder,
6140
+ {
6141
+ radius: leadDiameter / 2,
6142
+ height: bodyHeight / 2 + leadLength,
6143
+ center: [lead.x, lead.y, (bodyHeight / 2 - leadLength) / 2]
6144
+ }
6145
+ ) }, `lead-${lead.x}-${lead.y}`))
6146
+ ] });
6147
+ };
6148
+
6149
+ // lib/SmdPushButton.tsx
6150
+ var SmdPushButton = ({
6151
+ bodyWidth = 2.9,
6152
+ bodyLength: bodyLength10 = 3,
6153
+ bodyHeight = 1.4,
6154
+ actuatorDiameter = 1.5,
6155
+ actuatorHeight = 0.5,
6156
+ padSpanX = 4.2,
6157
+ padSpanY = 2.15,
6158
+ padWidth = 1.05,
6159
+ padLength = 0.7,
6160
+ bodyColor = "#2b2b2b",
6161
+ actuatorColor = "#d9d9d9",
6162
+ leadColor = "#cccccc"
6163
+ }) => {
6164
+ const leadThickness = 0.15;
6165
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6166
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
6167
+ Cuboid,
6168
+ {
6169
+ size: [bodyWidth, bodyLength10, bodyHeight],
6170
+ center: [0, 0, bodyHeight / 2]
6171
+ }
6172
+ ) }),
6173
+ /* @__PURE__ */ jsx(Colorize, { color: actuatorColor, children: /* @__PURE__ */ jsx(
6174
+ Cylinder,
6175
+ {
6176
+ radius: actuatorDiameter / 2,
6177
+ height: actuatorHeight,
6178
+ center: [0, 0, bodyHeight + actuatorHeight / 2]
6179
+ }
6180
+ ) }),
6181
+ [-1, 1].flatMap(
6182
+ (sx) => [-1, 1].map((sy) => /* @__PURE__ */ jsx(Colorize, { color: leadColor, children: /* @__PURE__ */ jsx(
6183
+ Cuboid,
6184
+ {
6185
+ size: [padWidth, padLength, leadThickness],
6186
+ center: [
6187
+ sx * padSpanX / 2,
6188
+ sy * padSpanY / 2,
6189
+ leadThickness / 2
6190
+ ]
6191
+ }
6192
+ ) }, `lead-${sx}-${sy}`))
6193
+ )
6194
+ ] });
6195
+ };
6196
+
6197
+ // lib/SOT-563.tsx
6198
+ var SOT563 = ({ fullWidth = 1.94, fullLength: fullLength10 = 1.6 }) => {
6199
+ const bodyWidth = 1.2;
6200
+ const bodyLength10 = 1.6;
6201
+ const bodyHeight = 0.55;
6202
+ const leadWidth = 0.3;
6203
+ const leadLength = 0.67;
6204
+ const leadHeight = 0.13;
6205
+ const leadSpacing = 0.5;
6206
+ const bodyZOffset = -0.4;
6207
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6208
+ /* @__PURE__ */ jsx(Rotate, { rotation: [45 * Math.PI, 0, 0], children: /* @__PURE__ */ jsx(Translate, { center: [0, 0, bodyZOffset], children: /* @__PURE__ */ jsx(Colorize, { color: "grey", children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyWidth, bodyLength10, bodyHeight] }) }) }) }),
6209
+ [-1, 0, 1].flatMap((yOffset, index) => [
6210
+ // Left lead
6211
+ /* @__PURE__ */ jsx(
6212
+ Translate,
6213
+ {
6214
+ center: [
6215
+ -bodyWidth / 2 - 0.03,
6216
+ yOffset * leadSpacing,
6217
+ leadHeight / 2
6218
+ ],
6219
+ children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, leadWidth, leadHeight] })
6220
+ },
6221
+ `left-${index}`
6222
+ ),
6223
+ // Right lead
6224
+ /* @__PURE__ */ jsx(
6225
+ Translate,
6226
+ {
6227
+ center: [bodyWidth / 2 + 0.03, yOffset * leadSpacing, leadHeight / 2],
6228
+ children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, leadWidth, leadHeight] })
6229
+ },
6230
+ `right-${index}`
6231
+ )
6232
+ ])
6233
+ ] });
6234
+ };
6235
+
6236
+ // lib/BGA.tsx
6237
+ import { fp as fp4 } from "@tscircuit/footprinter";
6238
+ var BGA = ({
6239
+ packageWidth = 10,
6240
+ packageLength = 10,
6241
+ packageHeight = 1.2,
6242
+ standoffHeight = 0.2,
6243
+ ballPitch = 0.8,
6244
+ ballDiameter = 0.5,
6245
+ ballRows = 8,
6246
+ ballColumns = 8,
6247
+ missingBalls = [],
6248
+ footprintString
6249
+ }) => {
6250
+ const bodyHeight = packageHeight - standoffHeight;
6251
+ const bodyOffset = standoffHeight + bodyHeight / 2;
6252
+ const ballOffset = Math.max(standoffHeight / 2, ballDiameter / 2);
6253
+ const ballsSoup = footprintString ? fp4.string(footprintString).circuitJson() : null;
6254
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6255
+ /* @__PURE__ */ jsx(Translate, { z: bodyOffset, children: /* @__PURE__ */ jsx(Colorize, { color: "#555", children: /* @__PURE__ */ jsx(Cuboid, { size: [packageWidth, packageLength, bodyHeight] }) }) }),
6256
+ !footprintString && Array.from({ length: ballRows * ballColumns }).map((_, index) => {
6257
+ if (missingBalls.includes(index + 1)) return null;
6258
+ const row = Math.floor(index / ballColumns);
6259
+ const col = index % ballColumns;
6260
+ const x = (col - (ballColumns - 1) / 2) * ballPitch;
6261
+ const y = (row - (ballRows - 1) / 2) * ballPitch;
6262
+ return /* @__PURE__ */ jsx(Translate, { x, y, z: ballOffset, children: /* @__PURE__ */ jsx(Sphere, { radius: ballDiameter / 2 }) }, index);
6263
+ }),
6264
+ ballsSoup && ballsSoup.map((elm, index) => {
6265
+ if (elm.type === "pcb_smtpad") {
6266
+ return /* @__PURE__ */ jsx(
6267
+ Translate,
6268
+ {
6269
+ x: elm.x,
6270
+ y: elm.y,
6271
+ z: ballOffset,
6272
+ children: /* @__PURE__ */ jsx(Sphere, { radius: ballDiameter / 2 })
6273
+ },
6274
+ index
6275
+ );
6276
+ }
6277
+ return null;
6278
+ })
6279
+ ] });
6280
+ };
6281
+
5764
6282
  // lib/Footprinter3d.tsx
5765
6283
  var Footprinter3d = ({ footprint }) => {
5766
6284
  let normalizedFootprint = footprint;
@@ -5769,9 +6287,14 @@ var Footprinter3d = ({ footprint }) => {
5769
6287
  const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "7";
5770
6288
  normalizedFootprint = `zh${numPins}`;
5771
6289
  }
5772
- const fpJson = fp2.string(normalizedFootprint).json();
6290
+ const fpJson = fp5.string(normalizedFootprint).json();
5773
6291
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
5774
6292
  const color = colorMatch ? colorMatch[1] : void 0;
6293
+ const dim = (value, fallback) => {
6294
+ if (value === void 0 || value === null) return fallback;
6295
+ const parsed = mm(value);
6296
+ return Number.isFinite(parsed) ? parsed : fallback;
6297
+ };
5775
6298
  switch (fpJson.fn) {
5776
6299
  case "crystal":
5777
6300
  return /* @__PURE__ */ jsx(
@@ -5940,6 +6463,39 @@ var Footprinter3d = ({ footprint }) => {
5940
6463
  return /* @__PURE__ */ jsx(SOT_235_default, {});
5941
6464
  }
5942
6465
  break;
6466
+ case "sot25":
6467
+ return /* @__PURE__ */ jsx(SOT_235_default, {});
6468
+ case "sot":
6469
+ case "sot343": {
6470
+ const isSc70 = fpJson.fn === "sot343";
6471
+ return /* @__PURE__ */ jsx(
6472
+ GullWingBody,
6473
+ {
6474
+ pads: getSmtPadRects(normalizedFootprint),
6475
+ bodyWidth: isSc70 ? 1.25 : 1.6,
6476
+ bodyLength: isSc70 ? 2 : 2.9,
6477
+ bodyHeight: isSc70 ? 1.1 : 1.3
6478
+ }
6479
+ );
6480
+ }
6481
+ case "sot563":
6482
+ return /* @__PURE__ */ jsx(SOT563, {});
6483
+ case "sot89": {
6484
+ const padSpan = dim(fpJson.w, 4.2);
6485
+ return /* @__PURE__ */ jsx(
6486
+ SOT223,
6487
+ {
6488
+ fullWidth: padSpan,
6489
+ bodyWidth: padSpan * 0.6,
6490
+ bodyLength: dim(fpJson.h, 4.8) * 0.94,
6491
+ bodyHeight: 1.5,
6492
+ leadWidth: dim(fpJson.pw, 0.48),
6493
+ tabLeadWidth: dim(fpJson.pw, 0.48) * 2,
6494
+ padPitch: dim(fpJson.p, 1.5),
6495
+ leadHeight: 0.66
6496
+ }
6497
+ );
6498
+ }
5943
6499
  case "sot457":
5944
6500
  return /* @__PURE__ */ jsx(SOT457, {});
5945
6501
  case "sot223":
@@ -6017,6 +6573,8 @@ var Footprinter3d = ({ footprint }) => {
6017
6573
  }
6018
6574
  );
6019
6575
  case "soic":
6576
+ case "sop8":
6577
+ case "ssop":
6020
6578
  return /* @__PURE__ */ jsx(
6021
6579
  SOIC,
6022
6580
  {
@@ -6027,6 +6585,80 @@ var Footprinter3d = ({ footprint }) => {
6027
6585
  bodyWidth: fpJson.w
6028
6586
  }
6029
6587
  );
6588
+ case "son":
6589
+ case "wson":
6590
+ case "vson": {
6591
+ const bodyWidth = fpJson.fn === "vson" ? dim(fpJson.grid?.x, 3) : dim(fpJson.w, 3);
6592
+ const bodyLength10 = fpJson.fn === "vson" ? dim(fpJson.grid?.y, 3) : dim(fpJson.h, 3);
6593
+ const thermalPadWidth = dim(fpJson.epw, 0);
6594
+ const thermalPadLength = dim(fpJson.eph, 0);
6595
+ const padLength = fpJson.pl !== void 0 ? dim(fpJson.pl, 0) : void 0;
6596
+ const padWidth = fpJson.pw !== void 0 ? dim(fpJson.pw, 0) : void 0;
6597
+ const signalPads = getSmtPadRects(normalizedFootprint).filter(
6598
+ (pad) => Number(pad.pin ?? 0) <= fpJson.num_pins
6599
+ );
6600
+ const distinct = (values) => new Set(values.map((value) => value.toFixed(3))).size;
6601
+ const rowsAlongY = signalPads.length > 2 && distinct(signalPads.map((pad) => pad.y)) === 2 && distinct(signalPads.map((pad) => pad.x)) > 2;
6602
+ const dfn = /* @__PURE__ */ jsx(
6603
+ DFN,
6604
+ {
6605
+ num_pins: fpJson.num_pins,
6606
+ bodyWidth: rowsAlongY ? bodyLength10 : bodyWidth,
6607
+ bodyLength: rowsAlongY ? bodyWidth : bodyLength10,
6608
+ pitch: dim(fpJson.p, 0.5),
6609
+ padLength,
6610
+ padWidth,
6611
+ thermalPadSize: fpJson.ep && thermalPadWidth > 0 && thermalPadLength > 0 ? {
6612
+ width: rowsAlongY ? thermalPadLength : thermalPadWidth,
6613
+ length: rowsAlongY ? thermalPadWidth : thermalPadLength
6614
+ } : void 0
6615
+ }
6616
+ );
6617
+ return rowsAlongY ? /* @__PURE__ */ jsx(Rotate, { rotation: [0, 0, "90deg"], children: dfn }) : dfn;
6618
+ }
6619
+ case "mlp":
6620
+ case "lga":
6621
+ case "quad": {
6622
+ if (fpJson.legsoutside) {
6623
+ return /* @__PURE__ */ jsx(
6624
+ QFP,
6625
+ {
6626
+ pinCount: fpJson.num_pins,
6627
+ pitch: dim(fpJson.p, 0.5),
6628
+ leadWidth: dim(fpJson.pw, 0.25),
6629
+ padContactLength: dim(fpJson.pl, 0.25),
6630
+ bodyWidth: dim(fpJson.w, 6)
6631
+ }
6632
+ );
6633
+ }
6634
+ return /* @__PURE__ */ jsx(
6635
+ qfn_default,
6636
+ {
6637
+ num_pins: fpJson.num_pins,
6638
+ bodyWidth: dim(fpJson.w, 6),
6639
+ bodyLength: dim(fpJson.h, 6),
6640
+ pitch: dim(fpJson.p, 0.5),
6641
+ padLength: dim(fpJson.pl, 0.25),
6642
+ padWidth: dim(fpJson.pw, 0.25)
6643
+ }
6644
+ );
6645
+ }
6646
+ case "bga": {
6647
+ const pitch = dim(fpJson.p, 0.8);
6648
+ const columns = fpJson.grid?.x ?? 8;
6649
+ const rows = fpJson.grid?.y ?? 8;
6650
+ return /* @__PURE__ */ jsx(
6651
+ BGA,
6652
+ {
6653
+ ballPitch: pitch,
6654
+ ballColumns: columns,
6655
+ ballRows: rows,
6656
+ ballDiameter: pitch * 0.625,
6657
+ packageWidth: columns * pitch,
6658
+ packageLength: rows * pitch
6659
+ }
6660
+ );
6661
+ }
6030
6662
  case "sod523":
6031
6663
  return /* @__PURE__ */ jsx(SOD523, {});
6032
6664
  case "sod723":
@@ -6049,10 +6681,70 @@ var Footprinter3d = ({ footprint }) => {
6049
6681
  return /* @__PURE__ */ jsx(SOD123FL, {});
6050
6682
  case "sod123w":
6051
6683
  return /* @__PURE__ */ jsx(SOD123W, {});
6684
+ case "sod110":
6685
+ return /* @__PURE__ */ jsx(SOD123W, { bodyWidth: 2.1, bodyLength: 1.4 });
6052
6686
  case "sod128":
6053
6687
  return /* @__PURE__ */ jsx(SOD128, {});
6054
6688
  case "sod323":
6055
6689
  return /* @__PURE__ */ jsx(SOD323, {});
6690
+ case "sod323w":
6691
+ return /* @__PURE__ */ jsx(SOD323, {});
6692
+ case "sod80":
6693
+ return /* @__PURE__ */ jsx(MINIMELF, {});
6694
+ case "sod882d":
6695
+ return /* @__PURE__ */ jsx(SOD882, {});
6696
+ case "smbf":
6697
+ return /* @__PURE__ */ jsx(SMB, {});
6698
+ case "led2835":
6699
+ return /* @__PURE__ */ jsx(
6700
+ Led2835,
6701
+ {
6702
+ color,
6703
+ bodyWidth: dim(fpJson.w, 3.5),
6704
+ bodyLength: dim(fpJson.h, 2.8),
6705
+ pad1X: dim(fpJson.p1x, -0.9),
6706
+ pad1Width: dim(fpJson.p1w, 2.2),
6707
+ pad2X: dim(fpJson.p2x, 1.375),
6708
+ pad2Width: dim(fpJson.p2w, 1.25),
6709
+ padLength: dim(fpJson.ph, 2.2)
6710
+ }
6711
+ );
6712
+ case "electrolytic":
6713
+ case "radial": {
6714
+ const pitch = dim(fpJson.p, 2.5);
6715
+ const namedDiameter = footprint.match(/_d([\d.]+)/);
6716
+ const diameter = fpJson.d !== void 0 ? dim(fpJson.d, pitch * 2) : namedDiameter ? Number(namedDiameter[1]) : pitch * 2;
6717
+ return /* @__PURE__ */ jsx(ElectrolyticCapacitor, { diameter, leadPitch: pitch });
6718
+ }
6719
+ case "potentiometer":
6720
+ return /* @__PURE__ */ jsx(
6721
+ Potentiometer,
6722
+ {
6723
+ bodyWidth: dim(fpJson.w, 5.35),
6724
+ bodyLength: dim(fpJson.ca, 14),
6725
+ bodyHeight: dim(fpJson.h, 4),
6726
+ leads: getPlatedHoleCenters(normalizedFootprint)
6727
+ }
6728
+ );
6729
+ case "smdpushbutton":
6730
+ return /* @__PURE__ */ jsx(
6731
+ SmdPushButton,
6732
+ {
6733
+ padSpanX: dim(fpJson.px, 4.2),
6734
+ padSpanY: dim(fpJson.py, 2.15),
6735
+ padWidth: dim(fpJson.pw, 1.05),
6736
+ padLength: dim(fpJson.ph, 0.7)
6737
+ }
6738
+ );
6739
+ case "breakoutheaders": {
6740
+ const pitch = dim(fpJson.p, 2.54);
6741
+ const halfWidth = dim(fpJson.w, 10) / 2;
6742
+ const sides = [
6743
+ { x: -halfWidth, pins: fpJson.left ?? 0, key: "left" },
6744
+ { x: halfWidth, pins: fpJson.right ?? 0, key: "right" }
6745
+ ];
6746
+ return /* @__PURE__ */ jsx(Fragment2, { children: sides.filter(({ pins }) => pins > 0).map(({ x, pins, key }) => /* @__PURE__ */ jsx(Translate, { center: [x, 0, 0], children: /* @__PURE__ */ jsx(Rotate, { rotation: [0, 0, "90deg"], children: /* @__PURE__ */ jsx(PinRow, { numberOfPins: pins, pitch }) }) }, key)) });
6747
+ }
6056
6748
  case "sod923":
6057
6749
  return /* @__PURE__ */ jsx(SOD923, {});
6058
6750
  case "hc49":
@@ -6086,9 +6778,50 @@ var Footprinter3d = ({ footprint }) => {
6086
6778
  case "sot723":
6087
6779
  return /* @__PURE__ */ jsx(SOT723, {});
6088
6780
  case "to220":
6089
- return /* @__PURE__ */ jsx(TO220, {});
6781
+ return /* @__PURE__ */ jsx(TO220, { leads: getPlatedHoleCenters(normalizedFootprint) });
6782
+ case "to220f":
6783
+ return /* @__PURE__ */ jsx(TO220, { mouldedTab: true, leads: getPlatedHoleCenters(normalizedFootprint) });
6090
6784
  case "to92":
6091
- return /* @__PURE__ */ jsx(TO92, {});
6785
+ return /* @__PURE__ */ jsx(TO92, { leads: getPlatedHoleCenters(normalizedFootprint) });
6786
+ case "to92l":
6787
+ case "to92s": {
6788
+ const across = dim(fpJson.w, 4.8);
6789
+ const along = dim(fpJson.h, 4);
6790
+ const diameter = Math.max(across, along);
6791
+ return /* @__PURE__ */ jsx(
6792
+ TO92,
6793
+ {
6794
+ bodyDiameter: diameter,
6795
+ flatCut: Math.max(diameter - Math.min(across, along), 0.4),
6796
+ leads: getPlatedHoleCenters(normalizedFootprint)
6797
+ }
6798
+ );
6799
+ }
6800
+ case "to252":
6801
+ case "dpak":
6802
+ case "to263":
6803
+ case "d2pak": {
6804
+ const isD2Pak = fpJson.fn === "to263" || fpJson.fn === "d2pak";
6805
+ const tabWidth = dim(fpJson.tabw, isD2Pak ? 8.38 : 6.2);
6806
+ const tabLength = Math.min(
6807
+ dim(fpJson.tabh, isD2Pak ? 10 : 5.8),
6808
+ isD2Pak ? 10 : 6.5
6809
+ );
6810
+ return /* @__PURE__ */ jsx(
6811
+ DPAK,
6812
+ {
6813
+ bodyWidth: tabWidth,
6814
+ bodyLength: dim(fpJson.w, isD2Pak ? 10.1 : 6.6),
6815
+ bodyHeight: isD2Pak ? 4.4 : 2.3,
6816
+ tabWidth,
6817
+ tabLength,
6818
+ span: dim(fpJson.span, isD2Pak ? 10.21 : 6.85),
6819
+ pitch: dim(fpJson.p, isD2Pak ? 2.54 : 2.29),
6820
+ leadWidth: dim(fpJson.pw, 1.5),
6821
+ leadContactLength: dim(fpJson.pl, 3)
6822
+ }
6823
+ );
6824
+ }
6092
6825
  case "stampboard":
6093
6826
  case "stampreceiver":
6094
6827
  return /* @__PURE__ */ jsx(