jscad-electronics 0.0.149 → 0.0.151

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
@@ -180,7 +180,7 @@ var ExtrudedPads = ({
180
180
  };
181
181
 
182
182
  // lib/Footprinter3d.tsx
183
- import { fp as fp2 } from "@tscircuit/footprinter";
183
+ import { fp as fp5 } from "@tscircuit/footprinter";
184
184
 
185
185
  // lib/ChipBody.tsx
186
186
  var ChipBody = ({
@@ -2217,8 +2217,8 @@ var SMA = () => {
2217
2217
 
2218
2218
  // lib/SMB.tsx
2219
2219
  var SMB = () => {
2220
- const bodyWidth = 4.4;
2221
- const bodyLength10 = 3.4;
2220
+ const bodyWidth = 4.6;
2221
+ const bodyLength10 = 4;
2222
2222
  const bodyHeight = 2.3;
2223
2223
  const padWidth = 1.45;
2224
2224
  const padThickness = 0.12;
@@ -2498,12 +2498,14 @@ var SOD123FL = () => {
2498
2498
  };
2499
2499
 
2500
2500
  // lib/sod-123W.tsx
2501
- var SOD123W = () => {
2502
- const fullWidth = 2.6;
2503
- const bodyLength10 = 1.7;
2504
- const bodyHeight = 1;
2505
- const padWidth = 0.9;
2506
- 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;
2507
2509
  const padThickness = 0.2;
2508
2510
  const leftPadCenterX = -(fullWidth / 2 - 0.075);
2509
2511
  const rightPadCenterX = fullWidth / 2 - 0.075;
@@ -2765,17 +2767,19 @@ var SOD923 = () => {
2765
2767
  };
2766
2768
 
2767
2769
  // lib/SOT-223.tsx
2768
- var SOT223 = () => {
2769
- const fullWidth = 6.6;
2770
- const bodyWidth = 3.5;
2771
- const bodyLength10 = 6.5;
2772
- const bodyHeight = 1.7;
2773
- const leadWidth = 0.7;
2774
- 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;
2775
2781
  const leadThickness = 0.25;
2776
- const leadHeight = 0.75;
2777
2782
  const padContactLength = 0.5;
2778
- const padPitch = 2.3;
2779
2783
  const extendedBodyDistance = fullWidth - bodyWidth;
2780
2784
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
2781
2785
  /* @__PURE__ */ jsx(
@@ -3631,78 +3635,67 @@ var MS013 = ({
3631
3635
  };
3632
3636
 
3633
3637
  // lib/TO220.tsx
3634
- var TO220 = () => {
3635
- const fullLength10 = 20;
3636
- const bodyLength10 = 9.9;
3637
- const bodyHeight = 4.5;
3638
- const zOffset = 1;
3639
- const padWidth = 9.9;
3640
- const padLength = 6.5;
3641
- const padThickness = 1.3;
3642
- const padHoleDiameter = 3;
3643
- const prongWidth = 0.81;
3644
- const prongLength = 16;
3645
- const prongHeight = 0.5;
3646
- const prongPitch = 2.7;
3647
- const bodyWidth = padWidth;
3648
- const bodyFrontX = fullLength10 - bodyLength10 / 2;
3649
- const bodyBackX = fullLength10 + bodyLength10 / 2;
3650
- const prongCenterX = bodyFrontX - prongLength / 2;
3651
- const padCenterX = bodyBackX + padLength / 2;
3652
- return /* @__PURE__ */ jsx(Translate, { center: [0, 0, zOffset], children: /* @__PURE__ */ jsxs(Fragment2, { children: [
3653
- /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 55, -55], children: [
3654
- /* @__PURE__ */ jsxs(Subtract, { children: [
3655
- /* @__PURE__ */ jsx(
3656
- Cuboid,
3657
- {
3658
- color: "#ccc",
3659
- size: [padLength + 0.1, padWidth, padThickness],
3660
- center: [padCenterX, 0, padThickness - 2]
3661
- }
3662
- ),
3663
- /* @__PURE__ */ jsx(
3664
- Cylinder,
3665
- {
3666
- color: "black",
3667
- center: [padCenterX, 0, padThickness - 2],
3668
- radius: padHoleDiameter / 2,
3669
- height: padThickness * 1.2
3670
- }
3671
- )
3672
- ] }),
3673
- /* @__PURE__ */ jsx(Colorize, { color: "#222", children: /* @__PURE__ */ jsx(
3674
- 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,
3675
3678
  {
3676
- width: bodyWidth,
3677
- length: bodyLength10,
3678
- height: bodyHeight,
3679
- center: { x: fullLength10, y: 0, z: -2.4 },
3680
- includeNotch: false,
3681
- straightHeightRatio: 0.3,
3682
- taperRatio: 0.04,
3683
- heightAboveSurface: 1
3679
+ size: [bodyWidth, tabThickness, tabHeight],
3680
+ center: [centerX, tabY, bodyTop + tabHeight / 2]
3684
3681
  }
3685
- ) })
3686
- ] }),
3687
- /* @__PURE__ */ jsx(Rotate, { rotation: [0, 55, 55], children: Array.from({ length: 3 }).map((_, i) => {
3688
- const x = prongCenterX;
3689
- const y = (i - 1) * prongPitch;
3690
- const z = -prongHeight - 0.6;
3691
- return /* @__PURE__ */ jsxs(Colorize, { color: "gold", children: [
3692
- /* @__PURE__ */ jsxs(Hull, { children: [
3693
- /* @__PURE__ */ jsx(Translate, { center: [bodyFrontX - bodyHeight / 2 + 0.1, y, z], children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyHeight, prongWidth + 1, prongHeight] }) }),
3694
- /* @__PURE__ */ jsx(
3695
- Translate,
3696
- {
3697
- center: [bodyFrontX - bodyHeight / 2 - 1 + 0.1, y, z],
3698
- children: /* @__PURE__ */ jsx(Cuboid, { size: [bodyHeight, prongWidth, prongHeight] })
3699
- }
3700
- )
3701
- ] }),
3702
- /* @__PURE__ */ jsx(Translate, { center: [x, y, z], children: /* @__PURE__ */ jsx(Cuboid, { size: [prongLength + 0.1, prongWidth, prongHeight] }) })
3703
- ] }, `prong-${i}`);
3704
- }) })
3705
- ] }) });
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
+ ] });
3706
3699
  };
3707
3700
 
3708
3701
  // lib/SOT-457.tsx
@@ -3900,39 +3893,95 @@ var SOT963 = () => {
3900
3893
  };
3901
3894
 
3902
3895
  // lib/TO92.tsx
3903
- var TO92 = () => {
3904
- const bodyRadius = 2.4;
3905
- const bodyHeight = 4.5;
3906
- 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;
3907
3928
  const legWidth = 0.4;
3908
3929
  const legThickness = 0.25;
3909
- const bodyZ = bodyHeight / 2;
3910
- const bodyColor = "#222";
3911
- const leadLength = 0.43;
3912
- const leadTipSize = [leadLength, legWidth, 1.32];
3913
- const leadSmallSize = [
3914
- 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,
3915
3951
  legWidth,
3916
3952
  legThickness
3917
3953
  ];
3918
- const leadTipPos1 = [0, 0, -0.66];
3919
- const leadMidPosA = [0, 0, -1.32];
3920
- const leadMidPosB = [0, 1.28, -2.72];
3921
- const leadTipPos2 = [0, 1.28, -8.9];
3922
- const sideLeadZ = -7.5;
3923
- return /* @__PURE__ */ jsxs(Translate, { center: [0, 1, 10.5], children: [
3954
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
3924
3955
  /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
3925
- /* @__PURE__ */ jsx(Translate, { center: [0, 0, bodyZ], children: /* @__PURE__ */ jsx(Cylinder, { radius: bodyRadius, height: bodyHeight }) }),
3926
- /* @__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
+ )
3927
3974
  ] }) }),
3928
- /* @__PURE__ */ jsx(Translate, { center: leadTipPos1, children: /* @__PURE__ */ jsx(Cuboid, { size: leadTipSize }) }),
3929
- /* @__PURE__ */ jsxs(Hull, { children: [
3930
- /* @__PURE__ */ jsx(Translate, { center: leadMidPosA, children: /* @__PURE__ */ jsx(Cuboid, { size: leadSmallSize }) }),
3931
- /* @__PURE__ */ jsx(Translate, { center: leadMidPosB, children: /* @__PURE__ */ jsx(Cuboid, { size: leadSmallSize }) })
3932
- ] }),
3933
- /* @__PURE__ */ jsx(Translate, { center: leadTipPos2, children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, legWidth, 12.2] }) }),
3934
- /* @__PURE__ */ jsx(Translate, { center: [1.3, 0, sideLeadZ], children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, legWidth, 15] }) }),
3935
- /* @__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
+ })
3936
3985
  ] });
3937
3986
  };
3938
3987
 
@@ -4128,8 +4177,8 @@ var SOT886 = () => {
4128
4177
  // lib/sod-323.tsx
4129
4178
  var SOD323 = () => {
4130
4179
  const fullWidth = 2.5;
4131
- const bodyLength10 = 1.25;
4132
- const bodyWidth = 1.7;
4180
+ const bodyLength10 = 1.4;
4181
+ const bodyWidth = 1.8;
4133
4182
  const bodyHeight = 0.95;
4134
4183
  const leadWidth = 0.3;
4135
4184
  const leadThickness = 0.175;
@@ -4937,6 +4986,185 @@ var JSTZH1_5mm = ({
4937
4986
  ] });
4938
4987
  };
4939
4988
 
4989
+ // lib/JSTPH2_0mm.tsx
4990
+ var JSTPH2_0mm = ({
4991
+ numPins = 2,
4992
+ showPins = true,
4993
+ showFootprint = true,
4994
+ bodyColor = "#f5f5f5",
4995
+ pinColor = "#635959"
4996
+ }) => {
4997
+ const pitch = 2;
4998
+ const bodyHeight = 6;
4999
+ const bodyDepth = 4.5;
5000
+ const wallThickness = 0.5;
5001
+ const hollowHeight = bodyHeight * 0.6;
5002
+ const pinTailLength = 3.4;
5003
+ const pinTop = 5.5;
5004
+ const pinThickness = 0.5;
5005
+ const pinLength = pinTailLength + pinTop;
5006
+ const bodyWidth = (numPins - 1) * pitch + 3.9;
5007
+ const startX = -((numPins - 1) * pitch) / 2;
5008
+ const latchWindowWidth = 1;
5009
+ const latchWindowHeight = 1.8;
5010
+ const latchWindowInset = 0.7;
5011
+ const topReliefWidth = 0.8;
5012
+ const topReliefDepth = 0.65;
5013
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5014
+ /* @__PURE__ */ jsx(Translate, { offset: [0, 0, bodyHeight], children: /* @__PURE__ */ jsx(Rotate, { angles: [Math.PI, 0, 0], children: /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
5015
+ /* @__PURE__ */ jsx(
5016
+ Cuboid,
5017
+ {
5018
+ size: [bodyWidth, bodyDepth, bodyHeight],
5019
+ center: [0, 0, bodyHeight / 2]
5020
+ }
5021
+ ),
5022
+ /* @__PURE__ */ jsx(
5023
+ Cuboid,
5024
+ {
5025
+ size: [
5026
+ bodyWidth - wallThickness * 2,
5027
+ bodyDepth - wallThickness * 2,
5028
+ hollowHeight
5029
+ ],
5030
+ center: [0, 0, hollowHeight / 2]
5031
+ }
5032
+ ),
5033
+ /* @__PURE__ */ jsx(
5034
+ Cuboid,
5035
+ {
5036
+ size: [bodyWidth, bodyDepth / 3, hollowHeight],
5037
+ center: [0, 0, hollowHeight / 6]
5038
+ }
5039
+ ),
5040
+ /* @__PURE__ */ jsx(
5041
+ Cuboid,
5042
+ {
5043
+ size: [
5044
+ bodyWidth - wallThickness * 2,
5045
+ wallThickness / 2,
5046
+ hollowHeight
5047
+ ],
5048
+ center: [
5049
+ 0,
5050
+ bodyDepth / 2 - wallThickness / 4,
5051
+ hollowHeight / 2
5052
+ ]
5053
+ }
5054
+ ),
5055
+ /* @__PURE__ */ jsx(
5056
+ Cuboid,
5057
+ {
5058
+ size: [
5059
+ bodyWidth - wallThickness * 2,
5060
+ wallThickness / 2,
5061
+ hollowHeight
5062
+ ],
5063
+ center: [
5064
+ 0,
5065
+ -bodyDepth / 2 + wallThickness / 4,
5066
+ hollowHeight / 2
5067
+ ]
5068
+ }
5069
+ ),
5070
+ /* @__PURE__ */ jsx(
5071
+ Cuboid,
5072
+ {
5073
+ size: [
5074
+ latchWindowWidth,
5075
+ bodyDepth + wallThickness,
5076
+ latchWindowHeight
5077
+ ],
5078
+ center: [-bodyWidth / 2 + latchWindowInset, 0, bodyHeight / 2]
5079
+ }
5080
+ ),
5081
+ /* @__PURE__ */ jsx(
5082
+ Cuboid,
5083
+ {
5084
+ size: [
5085
+ latchWindowWidth,
5086
+ bodyDepth + wallThickness,
5087
+ latchWindowHeight
5088
+ ],
5089
+ center: [bodyWidth / 2 - latchWindowInset, 0, bodyHeight / 2]
5090
+ }
5091
+ ),
5092
+ /* @__PURE__ */ jsx(
5093
+ Cuboid,
5094
+ {
5095
+ size: [wallThickness * 3, topReliefWidth, topReliefDepth],
5096
+ center: [-bodyWidth / 2, 0, topReliefDepth / 2]
5097
+ }
5098
+ ),
5099
+ /* @__PURE__ */ jsx(Translate, { offset: [-bodyWidth / 2, 0, topReliefDepth], children: /* @__PURE__ */ jsx(Rotate, { angles: [0, Math.PI / 2, 0], children: /* @__PURE__ */ jsx(
5100
+ Cylinder,
5101
+ {
5102
+ height: wallThickness * 3,
5103
+ radius: topReliefWidth / 2
5104
+ }
5105
+ ) }) }),
5106
+ /* @__PURE__ */ jsx(
5107
+ Cuboid,
5108
+ {
5109
+ size: [wallThickness * 3, topReliefWidth, topReliefDepth],
5110
+ center: [bodyWidth / 2, 0, topReliefDepth / 2]
5111
+ }
5112
+ ),
5113
+ /* @__PURE__ */ jsx(Translate, { offset: [bodyWidth / 2, 0, topReliefDepth], children: /* @__PURE__ */ jsx(Rotate, { angles: [0, Math.PI / 2, 0], children: /* @__PURE__ */ jsx(
5114
+ Cylinder,
5115
+ {
5116
+ height: wallThickness * 3,
5117
+ radius: topReliefWidth / 2
5118
+ }
5119
+ ) }) })
5120
+ ] }) }) }) }),
5121
+ showPins && Array.from({ length: numPins }).map((_, i) => /* @__PURE__ */ jsx(Colorize, { color: pinColor, children: /* @__PURE__ */ jsx(
5122
+ Cuboid,
5123
+ {
5124
+ size: [pinThickness, pinThickness, pinLength],
5125
+ center: [startX + i * pitch, 0, (pinTop - pinTailLength) / 2]
5126
+ }
5127
+ ) }, i)),
5128
+ showFootprint && Array.from({ length: numPins }).map((_, i) => {
5129
+ const isPin1 = i === 0;
5130
+ const hole = isPin1 ? {
5131
+ type: "pcb_plated_hole",
5132
+ pcb_plated_hole_id: `jstph_${i}`,
5133
+ shape: "circular_hole_with_rect_pad",
5134
+ x: startX + i * pitch,
5135
+ y: 0,
5136
+ hole_diameter: 0.73,
5137
+ rect_pad_width: 1.2,
5138
+ rect_pad_height: 1.2,
5139
+ hole_shape: "circle",
5140
+ pad_shape: "rect",
5141
+ layers: ["top", "bottom"],
5142
+ port_hints: [`${i + 1}`]
5143
+ } : {
5144
+ type: "pcb_plated_hole",
5145
+ pcb_plated_hole_id: `jstph_${i}`,
5146
+ shape: "pill",
5147
+ x: startX + i * pitch,
5148
+ y: 0,
5149
+ hole_height: 0.73,
5150
+ hole_width: 0.73,
5151
+ outer_height: 1.2,
5152
+ outer_width: 1.2,
5153
+ layers: ["top", "bottom"],
5154
+ port_hints: [`${i + 1}`]
5155
+ };
5156
+ return /* @__PURE__ */ jsx(
5157
+ FootprintPlatedHole,
5158
+ {
5159
+ hole,
5160
+ isPin1
5161
+ },
5162
+ `footprint_${i}`
5163
+ );
5164
+ })
5165
+ ] });
5166
+ };
5167
+
4940
5168
  // lib/Crystal.tsx
4941
5169
  var getTerminalPoints = ([centerX, centerY], width10, length, chamfer, isPinOne) => {
4942
5170
  const xDirection = Math.sign(centerX);
@@ -5413,6 +5641,84 @@ var SmdPinHeader = ({
5413
5641
  // lib/Footprinter3d.tsx
5414
5642
  import { mm } from "@tscircuit/mm";
5415
5643
 
5644
+ // lib/utils/getPlatedHoleCenters.ts
5645
+ import { fp as fp2 } from "@tscircuit/footprinter";
5646
+ var getPlatedHoleCenters = (footprint) => {
5647
+ const elements = fp2.string(footprint).circuitJson();
5648
+ return elements.filter(
5649
+ (element) => element.type === "pcb_plated_hole" && Number.isFinite(element.x) && Number.isFinite(element.y)
5650
+ ).map((element) => ({
5651
+ x: element.x,
5652
+ y: element.y,
5653
+ pin: element.port_hints?.[0]
5654
+ }));
5655
+ };
5656
+
5657
+ // lib/utils/getSmtPadRects.ts
5658
+ import { fp as fp3 } from "@tscircuit/footprinter";
5659
+ var getSmtPadRects = (footprint) => {
5660
+ const elements = fp3.string(footprint).circuitJson();
5661
+ return elements.filter(
5662
+ (element) => element.type === "pcb_smtpad" && element.shape === "rect" && Number.isFinite(element.x) && Number.isFinite(element.y)
5663
+ ).map((element) => ({
5664
+ x: element.x,
5665
+ y: element.y,
5666
+ width: element.width ?? 0.4,
5667
+ height: element.height ?? 0.4,
5668
+ pin: element.port_hints?.[0]
5669
+ }));
5670
+ };
5671
+
5672
+ // lib/GullWingBody.tsx
5673
+ var GullWingBody = ({
5674
+ bodyWidth,
5675
+ bodyLength: bodyLength10,
5676
+ bodyHeight = 1,
5677
+ pads,
5678
+ leadThickness = 0.15,
5679
+ leadHeightRatio = 0.75
5680
+ }) => {
5681
+ const centerX = pads.reduce((sum, pad) => sum + pad.x, 0) / (pads.length || 1);
5682
+ const centerY = pads.reduce((sum, pad) => sum + pad.y, 0) / (pads.length || 1);
5683
+ const leadHeight = bodyHeight * leadHeightRatio;
5684
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5685
+ /* @__PURE__ */ jsx(
5686
+ ChipBody,
5687
+ {
5688
+ center: { x: centerX, y: centerY, z: 0 },
5689
+ width: bodyWidth,
5690
+ length: bodyLength10,
5691
+ height: bodyHeight
5692
+ }
5693
+ ),
5694
+ pads.map((pad) => {
5695
+ const padWidth = pad.width ?? 0.4;
5696
+ const padLength = pad.height ?? 0.4;
5697
+ const side = pad.x >= centerX ? 1 : -1;
5698
+ const outerX = pad.x + side * padWidth / 2;
5699
+ const run = Math.max(Math.abs(outerX - centerX) - bodyWidth / 2, 0.1);
5700
+ const overlap = Math.min(0.15, bodyWidth * 0.15);
5701
+ return /* @__PURE__ */ jsx(
5702
+ SmdChipLead,
5703
+ {
5704
+ rotation: side > 0 ? Math.PI : 0,
5705
+ position: {
5706
+ x: outerX,
5707
+ y: pad.y,
5708
+ z: leadThickness / 2
5709
+ },
5710
+ width: padLength,
5711
+ thickness: leadThickness,
5712
+ padContactLength: padWidth * 0.6,
5713
+ bodyDistance: run + overlap,
5714
+ height: leadHeight
5715
+ },
5716
+ `lead-${pad.x}-${pad.y}`
5717
+ );
5718
+ })
5719
+ ] });
5720
+ };
5721
+
5416
5722
  // lib/ParametricChip.tsx
5417
5723
  var ParametricChip = ({
5418
5724
  padPitch,
@@ -5532,6 +5838,57 @@ var Led5050 = ({
5532
5838
  ] });
5533
5839
  };
5534
5840
 
5841
+ // lib/Led2835.tsx
5842
+ var Led2835 = ({
5843
+ bodyWidth = 3.5,
5844
+ bodyLength: bodyLength10 = 2.8,
5845
+ bodyHeight = 0.8,
5846
+ color = "#ffe08a",
5847
+ bodyColor = "#f2f2f2",
5848
+ padColor = "#cccccc",
5849
+ pad1X = -0.9,
5850
+ pad1Width = 2.2,
5851
+ pad2X = 1.375,
5852
+ pad2Width = 1.25,
5853
+ padLength = 2.2
5854
+ } = {}) => {
5855
+ const padThickness = 0.1;
5856
+ const lensHeight = 0.15;
5857
+ const bodyCenterX = (pad1X + pad2X) / 2;
5858
+ const lensWidth = bodyWidth * 0.55;
5859
+ const lensLength = bodyLength10 * 0.55;
5860
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5861
+ [
5862
+ { x: pad1X, w: pad1Width, key: "pad-1" },
5863
+ { x: pad2X, w: pad2Width, key: "pad-2" }
5864
+ ].map(({ x, w, key }) => /* @__PURE__ */ jsx(Colorize, { color: padColor, children: /* @__PURE__ */ jsx(
5865
+ Cuboid,
5866
+ {
5867
+ size: [w, padLength, padThickness],
5868
+ center: [x, 0, padThickness / 2]
5869
+ }
5870
+ ) }, key)),
5871
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
5872
+ Cuboid,
5873
+ {
5874
+ size: [bodyWidth, bodyLength10, bodyHeight],
5875
+ center: [bodyCenterX, 0, padThickness + bodyHeight / 2]
5876
+ }
5877
+ ) }),
5878
+ /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(
5879
+ Cuboid,
5880
+ {
5881
+ size: [lensWidth, lensLength, lensHeight],
5882
+ center: [
5883
+ bodyCenterX,
5884
+ 0,
5885
+ padThickness + bodyHeight + lensHeight / 2 - 0.05
5886
+ ]
5887
+ }
5888
+ ) })
5889
+ ] });
5890
+ };
5891
+
5535
5892
  // lib/RJ45.tsx
5536
5893
  var range2 = (length) => Array.from({ length }, (_, index) => index);
5537
5894
  var RJ45 = ({
@@ -5768,6 +6125,339 @@ var RJ45 = ({
5768
6125
  ] });
5769
6126
  };
5770
6127
 
6128
+ // lib/DPAK.tsx
6129
+ var DPAK = ({
6130
+ bodyWidth = 6.1,
6131
+ bodyLength: bodyLength10 = 6.5,
6132
+ bodyHeight = 2.3,
6133
+ tabWidth = 6.2,
6134
+ tabLength = 5.8,
6135
+ span = 6.85,
6136
+ pitch = 2.29,
6137
+ leadWidth = 0.9,
6138
+ leadContactLength = 1.5,
6139
+ color = "#222",
6140
+ tabColor = "#cccccc",
6141
+ leadColor = "#cccccc"
6142
+ }) => {
6143
+ const tabThickness = 0.5;
6144
+ const tabCenterX = span / 2;
6145
+ const leadPadX = -span / 2;
6146
+ const bodyCenterX = tabCenterX + (tabWidth - bodyWidth) / 2;
6147
+ const bodyFrontX = bodyCenterX - bodyWidth / 2;
6148
+ const leadZ = tabThickness / 2;
6149
+ const leadThickness = 0.4;
6150
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6151
+ /* @__PURE__ */ jsx(Colorize, { color: tabColor, children: /* @__PURE__ */ jsx(
6152
+ Cuboid,
6153
+ {
6154
+ size: [tabWidth, tabLength, tabThickness],
6155
+ center: [tabCenterX, 0, tabThickness / 2]
6156
+ }
6157
+ ) }),
6158
+ /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(
6159
+ Cuboid,
6160
+ {
6161
+ size: [bodyWidth, bodyLength10, bodyHeight],
6162
+ center: [bodyCenterX, 0, tabThickness + bodyHeight / 2]
6163
+ }
6164
+ ) }),
6165
+ [-1, 1].map((side) => {
6166
+ return /* @__PURE__ */ jsxs(Colorize, { color: leadColor, children: [
6167
+ /* @__PURE__ */ jsx(
6168
+ Cuboid,
6169
+ {
6170
+ size: [leadContactLength, leadWidth, leadThickness],
6171
+ center: [
6172
+ leadPadX + leadContactLength / 2,
6173
+ side * pitch,
6174
+ leadThickness / 2
6175
+ ]
6176
+ }
6177
+ ),
6178
+ /* @__PURE__ */ jsxs(Hull, { children: [
6179
+ /* @__PURE__ */ jsx(
6180
+ Cuboid,
6181
+ {
6182
+ size: [0.1, leadWidth, leadThickness],
6183
+ center: [
6184
+ leadPadX + leadContactLength,
6185
+ side * pitch,
6186
+ leadThickness / 2
6187
+ ]
6188
+ }
6189
+ ),
6190
+ /* @__PURE__ */ jsx(
6191
+ Cuboid,
6192
+ {
6193
+ size: [0.1, leadWidth, leadThickness],
6194
+ center: [bodyFrontX, side * pitch, leadZ + tabThickness / 2]
6195
+ }
6196
+ )
6197
+ ] })
6198
+ ] }, `lead-${side}`);
6199
+ })
6200
+ ] });
6201
+ };
6202
+
6203
+ // lib/ElectrolyticCapacitor.tsx
6204
+ var ElectrolyticCapacitor = ({
6205
+ diameter = 6.3,
6206
+ heightToDiameterRatio = 1.4,
6207
+ height: height10 = diameter * heightToDiameterRatio,
6208
+ leadPitch = 2.5,
6209
+ leadDiameter = 0.6,
6210
+ leadLength = 3,
6211
+ sleeveColor = "#1b2a6b",
6212
+ baseColor = "#1a1a1a"
6213
+ }) => {
6214
+ const radius = diameter / 2;
6215
+ const baseHeight = Math.min(1, diameter * 0.12);
6216
+ const canHeight = Math.max(height10 - baseHeight, 0.1);
6217
+ const canBottom = baseHeight;
6218
+ const canTop = canBottom + canHeight;
6219
+ const grooveWidth = Math.max(diameter * 0.06, 0.2);
6220
+ const grooveDepth = 0.3;
6221
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6222
+ /* @__PURE__ */ jsx(Colorize, { color: baseColor, children: /* @__PURE__ */ jsx(
6223
+ Cylinder,
6224
+ {
6225
+ radius: radius - 0.05,
6226
+ height: baseHeight,
6227
+ center: [0, 0, baseHeight / 2]
6228
+ }
6229
+ ) }),
6230
+ /* @__PURE__ */ jsx(Colorize, { color: sleeveColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
6231
+ /* @__PURE__ */ jsx(
6232
+ RoundedCylinder,
6233
+ {
6234
+ radius,
6235
+ height: canHeight,
6236
+ roundRadius: Math.min(0.3, radius * 0.15),
6237
+ center: [0, 0, canBottom + canHeight / 2]
6238
+ }
6239
+ ),
6240
+ /* @__PURE__ */ jsx(
6241
+ Cuboid,
6242
+ {
6243
+ size: [diameter, grooveWidth, grooveDepth * 2],
6244
+ center: [0, 0, canTop]
6245
+ }
6246
+ ),
6247
+ /* @__PURE__ */ jsx(
6248
+ Cuboid,
6249
+ {
6250
+ size: [grooveWidth, diameter, grooveDepth * 2],
6251
+ center: [0, 0, canTop]
6252
+ }
6253
+ )
6254
+ ] }) }),
6255
+ [-1, 1].map((side) => /* @__PURE__ */ jsx(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsx(
6256
+ Cylinder,
6257
+ {
6258
+ radius: leadDiameter / 2,
6259
+ height: leadLength + baseHeight,
6260
+ center: [side * leadPitch / 2, 0, (baseHeight - leadLength) / 2]
6261
+ }
6262
+ ) }, `lead-${side}`))
6263
+ ] });
6264
+ };
6265
+
6266
+ // lib/Potentiometer.tsx
6267
+ var Potentiometer = ({
6268
+ bodyWidth = 5.35,
6269
+ bodyLength: bodyLength10 = 14,
6270
+ bodyHeight = 4,
6271
+ bodyCenterX = bodyWidth / 2,
6272
+ adjusterDiameter = Math.min(bodyWidth, bodyLength10) * 0.55,
6273
+ shaftDiameter = 0,
6274
+ shaftHeight = 0,
6275
+ leads = [],
6276
+ leadDiameter = 0.6,
6277
+ leadLength = 3,
6278
+ bodyColor = "#1f4fa3",
6279
+ adjusterColor = "#d8d8d8"
6280
+ }) => {
6281
+ const adjusterHeight = 0.8;
6282
+ const adjusterZ = bodyHeight + adjusterHeight / 2;
6283
+ const slotWidth = Math.max(adjusterDiameter * 0.16, 0.3);
6284
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6285
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
6286
+ Cuboid,
6287
+ {
6288
+ size: [bodyWidth, bodyLength10, bodyHeight],
6289
+ center: [bodyCenterX, 0, bodyHeight / 2]
6290
+ }
6291
+ ) }),
6292
+ /* @__PURE__ */ jsx(Colorize, { color: adjusterColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
6293
+ /* @__PURE__ */ jsx(
6294
+ Cylinder,
6295
+ {
6296
+ radius: adjusterDiameter / 2,
6297
+ height: adjusterHeight,
6298
+ center: [bodyCenterX, 0, adjusterZ]
6299
+ }
6300
+ ),
6301
+ /* @__PURE__ */ jsx(
6302
+ Cuboid,
6303
+ {
6304
+ size: [adjusterDiameter, slotWidth, adjusterHeight * 0.6],
6305
+ center: [bodyCenterX, 0, adjusterZ + adjusterHeight / 2]
6306
+ }
6307
+ )
6308
+ ] }) }),
6309
+ shaftHeight > 0 && shaftDiameter > 0 ? /* @__PURE__ */ jsx(Colorize, { color: adjusterColor, children: /* @__PURE__ */ jsx(
6310
+ Cylinder,
6311
+ {
6312
+ radius: shaftDiameter / 2,
6313
+ height: shaftHeight,
6314
+ center: [bodyCenterX, 0, bodyHeight + shaftHeight / 2]
6315
+ }
6316
+ ) }) : null,
6317
+ leads.map((lead) => /* @__PURE__ */ jsx(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsx(
6318
+ Cylinder,
6319
+ {
6320
+ radius: leadDiameter / 2,
6321
+ height: bodyHeight / 2 + leadLength,
6322
+ center: [lead.x, lead.y, (bodyHeight / 2 - leadLength) / 2]
6323
+ }
6324
+ ) }, `lead-${lead.x}-${lead.y}`))
6325
+ ] });
6326
+ };
6327
+
6328
+ // lib/SmdPushButton.tsx
6329
+ var SmdPushButton = ({
6330
+ bodyWidth = 2.9,
6331
+ bodyLength: bodyLength10 = 3,
6332
+ bodyHeight = 1.4,
6333
+ actuatorDiameter = 1.5,
6334
+ actuatorHeight = 0.5,
6335
+ padSpanX = 4.2,
6336
+ padSpanY = 2.15,
6337
+ padWidth = 1.05,
6338
+ padLength = 0.7,
6339
+ bodyColor = "#2b2b2b",
6340
+ actuatorColor = "#d9d9d9",
6341
+ leadColor = "#cccccc"
6342
+ }) => {
6343
+ const leadThickness = 0.15;
6344
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6345
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx(
6346
+ Cuboid,
6347
+ {
6348
+ size: [bodyWidth, bodyLength10, bodyHeight],
6349
+ center: [0, 0, bodyHeight / 2]
6350
+ }
6351
+ ) }),
6352
+ /* @__PURE__ */ jsx(Colorize, { color: actuatorColor, children: /* @__PURE__ */ jsx(
6353
+ Cylinder,
6354
+ {
6355
+ radius: actuatorDiameter / 2,
6356
+ height: actuatorHeight,
6357
+ center: [0, 0, bodyHeight + actuatorHeight / 2]
6358
+ }
6359
+ ) }),
6360
+ [-1, 1].flatMap(
6361
+ (sx) => [-1, 1].map((sy) => /* @__PURE__ */ jsx(Colorize, { color: leadColor, children: /* @__PURE__ */ jsx(
6362
+ Cuboid,
6363
+ {
6364
+ size: [padWidth, padLength, leadThickness],
6365
+ center: [
6366
+ sx * padSpanX / 2,
6367
+ sy * padSpanY / 2,
6368
+ leadThickness / 2
6369
+ ]
6370
+ }
6371
+ ) }, `lead-${sx}-${sy}`))
6372
+ )
6373
+ ] });
6374
+ };
6375
+
6376
+ // lib/SOT-563.tsx
6377
+ var SOT563 = ({ fullWidth = 1.94, fullLength: fullLength10 = 1.6 }) => {
6378
+ const bodyWidth = 1.2;
6379
+ const bodyLength10 = 1.6;
6380
+ const bodyHeight = 0.55;
6381
+ const leadWidth = 0.3;
6382
+ const leadLength = 0.67;
6383
+ const leadHeight = 0.13;
6384
+ const leadSpacing = 0.5;
6385
+ const bodyZOffset = -0.4;
6386
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6387
+ /* @__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] }) }) }) }),
6388
+ [-1, 0, 1].flatMap((yOffset, index) => [
6389
+ // Left lead
6390
+ /* @__PURE__ */ jsx(
6391
+ Translate,
6392
+ {
6393
+ center: [
6394
+ -bodyWidth / 2 - 0.03,
6395
+ yOffset * leadSpacing,
6396
+ leadHeight / 2
6397
+ ],
6398
+ children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, leadWidth, leadHeight] })
6399
+ },
6400
+ `left-${index}`
6401
+ ),
6402
+ // Right lead
6403
+ /* @__PURE__ */ jsx(
6404
+ Translate,
6405
+ {
6406
+ center: [bodyWidth / 2 + 0.03, yOffset * leadSpacing, leadHeight / 2],
6407
+ children: /* @__PURE__ */ jsx(Cuboid, { size: [leadLength, leadWidth, leadHeight] })
6408
+ },
6409
+ `right-${index}`
6410
+ )
6411
+ ])
6412
+ ] });
6413
+ };
6414
+
6415
+ // lib/BGA.tsx
6416
+ import { fp as fp4 } from "@tscircuit/footprinter";
6417
+ var BGA = ({
6418
+ packageWidth = 10,
6419
+ packageLength = 10,
6420
+ packageHeight = 1.2,
6421
+ standoffHeight = 0.2,
6422
+ ballPitch = 0.8,
6423
+ ballDiameter = 0.5,
6424
+ ballRows = 8,
6425
+ ballColumns = 8,
6426
+ missingBalls = [],
6427
+ footprintString
6428
+ }) => {
6429
+ const bodyHeight = packageHeight - standoffHeight;
6430
+ const bodyOffset = standoffHeight + bodyHeight / 2;
6431
+ const ballOffset = Math.max(standoffHeight / 2, ballDiameter / 2);
6432
+ const ballsSoup = footprintString ? fp4.string(footprintString).circuitJson() : null;
6433
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
6434
+ /* @__PURE__ */ jsx(Translate, { z: bodyOffset, children: /* @__PURE__ */ jsx(Colorize, { color: "#555", children: /* @__PURE__ */ jsx(Cuboid, { size: [packageWidth, packageLength, bodyHeight] }) }) }),
6435
+ !footprintString && Array.from({ length: ballRows * ballColumns }).map((_, index) => {
6436
+ if (missingBalls.includes(index + 1)) return null;
6437
+ const row = Math.floor(index / ballColumns);
6438
+ const col = index % ballColumns;
6439
+ const x = (col - (ballColumns - 1) / 2) * ballPitch;
6440
+ const y = (row - (ballRows - 1) / 2) * ballPitch;
6441
+ return /* @__PURE__ */ jsx(Translate, { x, y, z: ballOffset, children: /* @__PURE__ */ jsx(Sphere, { radius: ballDiameter / 2 }) }, index);
6442
+ }),
6443
+ ballsSoup && ballsSoup.map((elm, index) => {
6444
+ if (elm.type === "pcb_smtpad") {
6445
+ return /* @__PURE__ */ jsx(
6446
+ Translate,
6447
+ {
6448
+ x: elm.x,
6449
+ y: elm.y,
6450
+ z: ballOffset,
6451
+ children: /* @__PURE__ */ jsx(Sphere, { radius: ballDiameter / 2 })
6452
+ },
6453
+ index
6454
+ );
6455
+ }
6456
+ return null;
6457
+ })
6458
+ ] });
6459
+ };
6460
+
5771
6461
  // lib/Footprinter3d.tsx
5772
6462
  var Footprinter3d = ({ footprint }) => {
5773
6463
  let normalizedFootprint = footprint;
@@ -5775,10 +6465,19 @@ var Footprinter3d = ({ footprint }) => {
5775
6465
  const pinMatch = footprint.match(/jstzh1_5mm(\d+)?/);
5776
6466
  const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "7";
5777
6467
  normalizedFootprint = `zh${numPins}`;
6468
+ } else if (footprint.startsWith("jstph2_0mm")) {
6469
+ const pinMatch = footprint.match(/jstph2_0mm(\d+)?/);
6470
+ const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "2";
6471
+ normalizedFootprint = `jst${numPins}_ph`;
5778
6472
  }
5779
- const fpJson = fp2.string(normalizedFootprint).json();
6473
+ const fpJson = fp5.string(normalizedFootprint).json();
5780
6474
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
5781
6475
  const color = colorMatch ? colorMatch[1] : void 0;
6476
+ const dim = (value, fallback) => {
6477
+ if (value === void 0 || value === null) return fallback;
6478
+ const parsed = mm(value);
6479
+ return Number.isFinite(parsed) ? parsed : fallback;
6480
+ };
5782
6481
  switch (fpJson.fn) {
5783
6482
  case "crystal":
5784
6483
  return /* @__PURE__ */ jsx(
@@ -5947,6 +6646,39 @@ var Footprinter3d = ({ footprint }) => {
5947
6646
  return /* @__PURE__ */ jsx(SOT_235_default, {});
5948
6647
  }
5949
6648
  break;
6649
+ case "sot25":
6650
+ return /* @__PURE__ */ jsx(SOT_235_default, {});
6651
+ case "sot":
6652
+ case "sot343": {
6653
+ const isSc70 = fpJson.fn === "sot343";
6654
+ return /* @__PURE__ */ jsx(
6655
+ GullWingBody,
6656
+ {
6657
+ pads: getSmtPadRects(normalizedFootprint),
6658
+ bodyWidth: isSc70 ? 1.25 : 1.6,
6659
+ bodyLength: isSc70 ? 2 : 2.9,
6660
+ bodyHeight: isSc70 ? 1.1 : 1.3
6661
+ }
6662
+ );
6663
+ }
6664
+ case "sot563":
6665
+ return /* @__PURE__ */ jsx(SOT563, {});
6666
+ case "sot89": {
6667
+ const padSpan = dim(fpJson.w, 4.2);
6668
+ return /* @__PURE__ */ jsx(
6669
+ SOT223,
6670
+ {
6671
+ fullWidth: padSpan,
6672
+ bodyWidth: padSpan * 0.6,
6673
+ bodyLength: dim(fpJson.h, 4.8) * 0.94,
6674
+ bodyHeight: 1.5,
6675
+ leadWidth: dim(fpJson.pw, 0.48),
6676
+ tabLeadWidth: dim(fpJson.pw, 0.48) * 2,
6677
+ padPitch: dim(fpJson.p, 1.5),
6678
+ leadHeight: 0.66
6679
+ }
6680
+ );
6681
+ }
5950
6682
  case "sot457":
5951
6683
  return /* @__PURE__ */ jsx(SOT457, {});
5952
6684
  case "sot223":
@@ -5978,6 +6710,9 @@ var Footprinter3d = ({ footprint }) => {
5978
6710
  if (fpJson.zh) {
5979
6711
  return /* @__PURE__ */ jsx(JSTZH1_5mm, { numPins: fpJson.num_pins });
5980
6712
  }
6713
+ if (fpJson.ph) {
6714
+ return /* @__PURE__ */ jsx(JSTPH2_0mm, { numPins: fpJson.num_pins });
6715
+ }
5981
6716
  break;
5982
6717
  case "fpc":
5983
6718
  return /* @__PURE__ */ jsx(
@@ -6024,6 +6759,8 @@ var Footprinter3d = ({ footprint }) => {
6024
6759
  }
6025
6760
  );
6026
6761
  case "soic":
6762
+ case "sop8":
6763
+ case "ssop":
6027
6764
  return /* @__PURE__ */ jsx(
6028
6765
  SOIC,
6029
6766
  {
@@ -6034,6 +6771,80 @@ var Footprinter3d = ({ footprint }) => {
6034
6771
  bodyWidth: fpJson.w
6035
6772
  }
6036
6773
  );
6774
+ case "son":
6775
+ case "wson":
6776
+ case "vson": {
6777
+ const bodyWidth = fpJson.fn === "vson" ? dim(fpJson.grid?.x, 3) : dim(fpJson.w, 3);
6778
+ const bodyLength10 = fpJson.fn === "vson" ? dim(fpJson.grid?.y, 3) : dim(fpJson.h, 3);
6779
+ const thermalPadWidth = dim(fpJson.epw, 0);
6780
+ const thermalPadLength = dim(fpJson.eph, 0);
6781
+ const padLength = fpJson.pl !== void 0 ? dim(fpJson.pl, 0) : void 0;
6782
+ const padWidth = fpJson.pw !== void 0 ? dim(fpJson.pw, 0) : void 0;
6783
+ const signalPads = getSmtPadRects(normalizedFootprint).filter(
6784
+ (pad) => Number(pad.pin ?? 0) <= fpJson.num_pins
6785
+ );
6786
+ const distinct = (values) => new Set(values.map((value) => value.toFixed(3))).size;
6787
+ const rowsAlongY = signalPads.length > 2 && distinct(signalPads.map((pad) => pad.y)) === 2 && distinct(signalPads.map((pad) => pad.x)) > 2;
6788
+ const dfn = /* @__PURE__ */ jsx(
6789
+ DFN,
6790
+ {
6791
+ num_pins: fpJson.num_pins,
6792
+ bodyWidth: rowsAlongY ? bodyLength10 : bodyWidth,
6793
+ bodyLength: rowsAlongY ? bodyWidth : bodyLength10,
6794
+ pitch: dim(fpJson.p, 0.5),
6795
+ padLength,
6796
+ padWidth,
6797
+ thermalPadSize: fpJson.ep && thermalPadWidth > 0 && thermalPadLength > 0 ? {
6798
+ width: rowsAlongY ? thermalPadLength : thermalPadWidth,
6799
+ length: rowsAlongY ? thermalPadWidth : thermalPadLength
6800
+ } : void 0
6801
+ }
6802
+ );
6803
+ return rowsAlongY ? /* @__PURE__ */ jsx(Rotate, { rotation: [0, 0, "90deg"], children: dfn }) : dfn;
6804
+ }
6805
+ case "mlp":
6806
+ case "lga":
6807
+ case "quad": {
6808
+ if (fpJson.legsoutside) {
6809
+ return /* @__PURE__ */ jsx(
6810
+ QFP,
6811
+ {
6812
+ pinCount: fpJson.num_pins,
6813
+ pitch: dim(fpJson.p, 0.5),
6814
+ leadWidth: dim(fpJson.pw, 0.25),
6815
+ padContactLength: dim(fpJson.pl, 0.25),
6816
+ bodyWidth: dim(fpJson.w, 6)
6817
+ }
6818
+ );
6819
+ }
6820
+ return /* @__PURE__ */ jsx(
6821
+ qfn_default,
6822
+ {
6823
+ num_pins: fpJson.num_pins,
6824
+ bodyWidth: dim(fpJson.w, 6),
6825
+ bodyLength: dim(fpJson.h, 6),
6826
+ pitch: dim(fpJson.p, 0.5),
6827
+ padLength: dim(fpJson.pl, 0.25),
6828
+ padWidth: dim(fpJson.pw, 0.25)
6829
+ }
6830
+ );
6831
+ }
6832
+ case "bga": {
6833
+ const pitch = dim(fpJson.p, 0.8);
6834
+ const columns = fpJson.grid?.x ?? 8;
6835
+ const rows = fpJson.grid?.y ?? 8;
6836
+ return /* @__PURE__ */ jsx(
6837
+ BGA,
6838
+ {
6839
+ ballPitch: pitch,
6840
+ ballColumns: columns,
6841
+ ballRows: rows,
6842
+ ballDiameter: pitch * 0.625,
6843
+ packageWidth: columns * pitch,
6844
+ packageLength: rows * pitch
6845
+ }
6846
+ );
6847
+ }
6037
6848
  case "sod523":
6038
6849
  return /* @__PURE__ */ jsx(SOD523, {});
6039
6850
  case "sod723":
@@ -6056,10 +6867,70 @@ var Footprinter3d = ({ footprint }) => {
6056
6867
  return /* @__PURE__ */ jsx(SOD123FL, {});
6057
6868
  case "sod123w":
6058
6869
  return /* @__PURE__ */ jsx(SOD123W, {});
6870
+ case "sod110":
6871
+ return /* @__PURE__ */ jsx(SOD123W, { bodyWidth: 2.1, bodyLength: 1.4 });
6059
6872
  case "sod128":
6060
6873
  return /* @__PURE__ */ jsx(SOD128, {});
6061
6874
  case "sod323":
6062
6875
  return /* @__PURE__ */ jsx(SOD323, {});
6876
+ case "sod323w":
6877
+ return /* @__PURE__ */ jsx(SOD323, {});
6878
+ case "sod80":
6879
+ return /* @__PURE__ */ jsx(MINIMELF, {});
6880
+ case "sod882d":
6881
+ return /* @__PURE__ */ jsx(SOD882, {});
6882
+ case "smbf":
6883
+ return /* @__PURE__ */ jsx(SMB, {});
6884
+ case "led2835":
6885
+ return /* @__PURE__ */ jsx(
6886
+ Led2835,
6887
+ {
6888
+ color,
6889
+ bodyWidth: dim(fpJson.w, 3.5),
6890
+ bodyLength: dim(fpJson.h, 2.8),
6891
+ pad1X: dim(fpJson.p1x, -0.9),
6892
+ pad1Width: dim(fpJson.p1w, 2.2),
6893
+ pad2X: dim(fpJson.p2x, 1.375),
6894
+ pad2Width: dim(fpJson.p2w, 1.25),
6895
+ padLength: dim(fpJson.ph, 2.2)
6896
+ }
6897
+ );
6898
+ case "electrolytic":
6899
+ case "radial": {
6900
+ const pitch = dim(fpJson.p, 2.5);
6901
+ const namedDiameter = footprint.match(/_d([\d.]+)/);
6902
+ const diameter = fpJson.d !== void 0 ? dim(fpJson.d, pitch * 2) : namedDiameter ? Number(namedDiameter[1]) : pitch * 2;
6903
+ return /* @__PURE__ */ jsx(ElectrolyticCapacitor, { diameter, leadPitch: pitch });
6904
+ }
6905
+ case "potentiometer":
6906
+ return /* @__PURE__ */ jsx(
6907
+ Potentiometer,
6908
+ {
6909
+ bodyWidth: dim(fpJson.w, 5.35),
6910
+ bodyLength: dim(fpJson.ca, 14),
6911
+ bodyHeight: dim(fpJson.h, 4),
6912
+ leads: getPlatedHoleCenters(normalizedFootprint)
6913
+ }
6914
+ );
6915
+ case "smdpushbutton":
6916
+ return /* @__PURE__ */ jsx(
6917
+ SmdPushButton,
6918
+ {
6919
+ padSpanX: dim(fpJson.px, 4.2),
6920
+ padSpanY: dim(fpJson.py, 2.15),
6921
+ padWidth: dim(fpJson.pw, 1.05),
6922
+ padLength: dim(fpJson.ph, 0.7)
6923
+ }
6924
+ );
6925
+ case "breakoutheaders": {
6926
+ const pitch = dim(fpJson.p, 2.54);
6927
+ const halfWidth = dim(fpJson.w, 10) / 2;
6928
+ const sides = [
6929
+ { x: -halfWidth, pins: fpJson.left ?? 0, key: "left" },
6930
+ { x: halfWidth, pins: fpJson.right ?? 0, key: "right" }
6931
+ ];
6932
+ 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)) });
6933
+ }
6063
6934
  case "sod923":
6064
6935
  return /* @__PURE__ */ jsx(SOD923, {});
6065
6936
  case "hc49":
@@ -6093,9 +6964,50 @@ var Footprinter3d = ({ footprint }) => {
6093
6964
  case "sot723":
6094
6965
  return /* @__PURE__ */ jsx(SOT723, {});
6095
6966
  case "to220":
6096
- return /* @__PURE__ */ jsx(TO220, {});
6967
+ return /* @__PURE__ */ jsx(TO220, { leads: getPlatedHoleCenters(normalizedFootprint) });
6968
+ case "to220f":
6969
+ return /* @__PURE__ */ jsx(TO220, { mouldedTab: true, leads: getPlatedHoleCenters(normalizedFootprint) });
6097
6970
  case "to92":
6098
- return /* @__PURE__ */ jsx(TO92, {});
6971
+ return /* @__PURE__ */ jsx(TO92, { leads: getPlatedHoleCenters(normalizedFootprint) });
6972
+ case "to92l":
6973
+ case "to92s": {
6974
+ const across = dim(fpJson.w, 4.8);
6975
+ const along = dim(fpJson.h, 4);
6976
+ const diameter = Math.max(across, along);
6977
+ return /* @__PURE__ */ jsx(
6978
+ TO92,
6979
+ {
6980
+ bodyDiameter: diameter,
6981
+ flatCut: Math.max(diameter - Math.min(across, along), 0.4),
6982
+ leads: getPlatedHoleCenters(normalizedFootprint)
6983
+ }
6984
+ );
6985
+ }
6986
+ case "to252":
6987
+ case "dpak":
6988
+ case "to263":
6989
+ case "d2pak": {
6990
+ const isD2Pak = fpJson.fn === "to263" || fpJson.fn === "d2pak";
6991
+ const tabWidth = dim(fpJson.tabw, isD2Pak ? 8.38 : 6.2);
6992
+ const tabLength = Math.min(
6993
+ dim(fpJson.tabh, isD2Pak ? 10 : 5.8),
6994
+ isD2Pak ? 10 : 6.5
6995
+ );
6996
+ return /* @__PURE__ */ jsx(
6997
+ DPAK,
6998
+ {
6999
+ bodyWidth: tabWidth,
7000
+ bodyLength: dim(fpJson.w, isD2Pak ? 10.1 : 6.6),
7001
+ bodyHeight: isD2Pak ? 4.4 : 2.3,
7002
+ tabWidth,
7003
+ tabLength,
7004
+ span: dim(fpJson.span, isD2Pak ? 10.21 : 6.85),
7005
+ pitch: dim(fpJson.p, isD2Pak ? 2.54 : 2.29),
7006
+ leadWidth: dim(fpJson.pw, 1.5),
7007
+ leadContactLength: dim(fpJson.pl, 3)
7008
+ }
7009
+ );
7010
+ }
6099
7011
  case "stampboard":
6100
7012
  case "stampreceiver":
6101
7013
  return /* @__PURE__ */ jsx(