jscad-electronics 0.0.164 → 0.0.165

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
@@ -375,7 +375,7 @@ var TantalumCapacitor = ({
375
375
  };
376
376
 
377
377
  // lib/Footprinter3d.tsx
378
- import { fp as fp12 } from "@tscircuit/footprinter";
378
+ import { fp as fp14 } from "@tscircuit/footprinter";
379
379
  import { mp } from "@tscircuit/modelprinter";
380
380
 
381
381
  // lib/ChipBody.tsx
@@ -5489,6 +5489,107 @@ var JSTXH2_5mm = ({
5489
5489
  ] });
5490
5490
  };
5491
5491
 
5492
+ // lib/JstSh.tsx
5493
+ import { fp as fp7 } from "@tscircuit/footprinter";
5494
+ import { mm } from "@tscircuit/mm";
5495
+ function isJstShFootprint(footprint) {
5496
+ const p = fp7.string(footprint).json();
5497
+ if (p.fn !== "jst") return false;
5498
+ return Boolean(
5499
+ p.sh || p.smd && Math.abs(mm(p.p) - 1) < 0.01 && Math.abs(mm(p.mpx ?? 0) - (p.num_pins - 1 + 2.6)) < 0.15 && Math.abs(mm(p.mpy ?? 0) - 2.525) < 0.15
5500
+ );
5501
+ }
5502
+ var JstSh = ({ footprint = "jst6_sh" }) => {
5503
+ if (!isJstShFootprint(footprint))
5504
+ throw new Error(
5505
+ "JstSh requires a named SH or matching 1mm SH top-entry footprint"
5506
+ );
5507
+ const canonical = footprint.replace(/_pin1location\([^)]*\)/g, "");
5508
+ const params = fp7.string(canonical).json();
5509
+ const pads = fp7.string(canonical).circuitJson().filter((e) => e.type === "pcb_smtpad" && e.shape === "rect");
5510
+ const target = fp7.string(footprint).circuitJson().filter(
5511
+ (e) => e.type === "pcb_smtpad" && (e.shape === "rect" || e.shape === "rotated_rect")
5512
+ );
5513
+ const n = params.num_pins;
5514
+ if (!Number.isInteger(n) || n < 2 || n > 20 || pads.length !== n + 2)
5515
+ throw new Error("JstSh requires 2\u201320 contacts and two hold-down pads");
5516
+ const signals = pads.slice(0, n), mounts = pads.slice(n);
5517
+ const angle = Math.atan2(target[1].y - target[0].y, target[1].x - target[0].x) - Math.atan2(pads[1].y - pads[0].y, pads[1].x - pads[0].x);
5518
+ const x = signals.reduce((sum, p) => sum + p.x, 0) / n, rowY = signals[0].y;
5519
+ const direction = mounts[0].y > rowY ? 1 : -1;
5520
+ const y = rowY + direction * 1.8, width10 = n + 2, depth = 2.9, height10 = 4.2;
5521
+ const pinY = y - direction * 0.25;
5522
+ return /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 0, angle], children: [
5523
+ /* @__PURE__ */ jsx(Colorize, { color: "#e4e1d6", children: /* @__PURE__ */ jsxs(Subtract, { children: [
5524
+ /* @__PURE__ */ jsx(
5525
+ Cuboid,
5526
+ {
5527
+ size: [width10, depth, height10],
5528
+ center: [x, y, height10 / 2 + 0.05]
5529
+ }
5530
+ ),
5531
+ /* @__PURE__ */ jsx(
5532
+ Cuboid,
5533
+ {
5534
+ size: [width10 - 1.3, 1.8, height10],
5535
+ center: [x, y, height10 / 2 + 0.8]
5536
+ }
5537
+ ),
5538
+ mounts.map((pad, i) => /* @__PURE__ */ jsx(
5539
+ Cuboid,
5540
+ {
5541
+ size: [0.7, pad.height * 0.8, 1.5],
5542
+ center: [pad.x, pad.y, 0.75]
5543
+ },
5544
+ `recess-${i}`
5545
+ )),
5546
+ [-1, 1].map((side) => /* @__PURE__ */ jsx(
5547
+ Cuboid,
5548
+ {
5549
+ size: [0.55, 0.6, 1],
5550
+ center: [
5551
+ x + side * (width10 / 2 - 0.9),
5552
+ y + direction * depth / 2,
5553
+ 4
5554
+ ]
5555
+ },
5556
+ side
5557
+ ))
5558
+ ] }) }),
5559
+ /* @__PURE__ */ jsxs(Colorize, { color: "#c6c7c9", children: [
5560
+ signals.map((pad, i) => {
5561
+ const tailY = pad.y - direction * pad.height * 0.4;
5562
+ return /* @__PURE__ */ jsxs(Union, { children: [
5563
+ /* @__PURE__ */ jsx(
5564
+ Cuboid,
5565
+ {
5566
+ size: [0.2, Math.abs(pinY - tailY) + 0.1, 0.2],
5567
+ center: [pad.x, (pinY + tailY) / 2, 0.1]
5568
+ }
5569
+ ),
5570
+ /* @__PURE__ */ jsx(Cuboid, { size: [0.2, 0.2, 3.45], center: [pad.x, pinY, 1.725] })
5571
+ ] }, i);
5572
+ }),
5573
+ mounts.map((pad, i) => /* @__PURE__ */ jsxs(Union, { children: [
5574
+ /* @__PURE__ */ jsx(
5575
+ Cuboid,
5576
+ {
5577
+ size: [0.7, pad.height * 0.75, 0.2],
5578
+ center: [pad.x, pad.y, 0.1]
5579
+ }
5580
+ ),
5581
+ /* @__PURE__ */ jsx(
5582
+ Cuboid,
5583
+ {
5584
+ size: [0.2, pad.height * 0.6, 1.35],
5585
+ center: [pad.x, pad.y, 0.675]
5586
+ }
5587
+ )
5588
+ ] }, `mount-${i}`))
5589
+ ] })
5590
+ ] });
5591
+ };
5592
+
5492
5593
  // lib/Crystal.tsx
5493
5594
  var getTerminalPoints = ([centerX, centerY], width10, length, chamfer, isPinOne) => {
5494
5595
  const xDirection = Math.sign(centerX);
@@ -5963,12 +6064,12 @@ var SmdPinHeader = ({
5963
6064
  };
5964
6065
 
5965
6066
  // lib/Footprinter3d.tsx
5966
- import { mm } from "@tscircuit/mm";
6067
+ import { mm as mm2 } from "@tscircuit/mm";
5967
6068
 
5968
6069
  // lib/utils/getPlatedHoleCenters.ts
5969
- import { fp as fp7 } from "@tscircuit/footprinter";
6070
+ import { fp as fp8 } from "@tscircuit/footprinter";
5970
6071
  var getPlatedHoleCenters = (footprint) => {
5971
- const elements = fp7.string(footprint).circuitJson();
6072
+ const elements = fp8.string(footprint).circuitJson();
5972
6073
  return elements.filter(
5973
6074
  (element) => element.type === "pcb_plated_hole" && Number.isFinite(element.x) && Number.isFinite(element.y)
5974
6075
  ).map((element) => ({
@@ -5979,9 +6080,9 @@ var getPlatedHoleCenters = (footprint) => {
5979
6080
  };
5980
6081
 
5981
6082
  // lib/utils/getSmtPadRects.ts
5982
- import { fp as fp8 } from "@tscircuit/footprinter";
6083
+ import { fp as fp9 } from "@tscircuit/footprinter";
5983
6084
  var getSmtPadRects = (footprint) => {
5984
- const elements = fp8.string(footprint).circuitJson();
6085
+ const elements = fp9.string(footprint).circuitJson();
5985
6086
  return elements.filter(
5986
6087
  (element) => element.type === "pcb_smtpad" && element.shape === "rect" && Number.isFinite(element.x) && Number.isFinite(element.y)
5987
6088
  ).map((element) => ({
@@ -6697,6 +6798,84 @@ var SmdPushButton = ({
6697
6798
  ] });
6698
6799
  };
6699
6800
 
6801
+ // lib/SmdSlideSwitch.tsx
6802
+ import { fp as fp10 } from "@tscircuit/footprinter";
6803
+ var SmdSlideSwitch = ({
6804
+ footprint = "smdslideswitch7",
6805
+ position = 0
6806
+ }) => {
6807
+ const canonical = footprint.replace(/_pin1location\([^)]*\)/g, "");
6808
+ const params = fp10.string(canonical).json();
6809
+ const elements = fp10.string(canonical).circuitJson();
6810
+ const pads = elements.filter(
6811
+ (e) => e.type === "pcb_smtpad" && e.shape === "rect"
6812
+ );
6813
+ const target = fp10.string(footprint).circuitJson().filter(
6814
+ (e) => e.type === "pcb_smtpad" && (e.shape === "rect" || e.shape === "rotated_rect")
6815
+ );
6816
+ if (pads.length < 7 || !Number.isFinite(params.mpx) || params.mpx < 3)
6817
+ throw new Error("SmdSlideSwitch needs signal pads and four mounting pads");
6818
+ const angle = Math.atan2(target[1].y - target[0].y, target[1].x - target[0].x) - Math.atan2(pads[1].y - pads[0].y, pads[1].x - pads[0].x);
6819
+ const width10 = params.mpx - 0.5, depth = 2.7, height10 = params.mpx > 6 ? 1.5 : 1.4, y = params.mounty;
6820
+ return /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 0, angle], children: [
6821
+ /* @__PURE__ */ jsx(Colorize, { color: "#aeb4ba", children: /* @__PURE__ */ jsxs(Subtract, { children: [
6822
+ /* @__PURE__ */ jsx(Cuboid, { size: [width10, depth, height10], center: [0, y, height10 / 2] }),
6823
+ /* @__PURE__ */ jsx(
6824
+ Cuboid,
6825
+ {
6826
+ size: [width10 - 0.3, depth - 0.3, height10],
6827
+ center: [0, y, height10 / 2 - 0.15]
6828
+ }
6829
+ ),
6830
+ /* @__PURE__ */ jsx(Cuboid, { size: [2.7, 0.5, 0.9], center: [0, y - depth / 2, 0.65] })
6831
+ ] }) }),
6832
+ /* @__PURE__ */ jsxs(Colorize, { color: "#28292c", children: [
6833
+ /* @__PURE__ */ jsx(
6834
+ Cuboid,
6835
+ {
6836
+ size: [width10 - 0.32, depth - 0.32, 0.35],
6837
+ center: [0, y, 0.175]
6838
+ }
6839
+ ),
6840
+ /* @__PURE__ */ jsx(
6841
+ Cuboid,
6842
+ {
6843
+ size: [1, 2.25, 0.65],
6844
+ center: [position === 0 ? -0.5 : 0.5, y - 1.5, 0.65]
6845
+ }
6846
+ ),
6847
+ elements.filter((e) => e.type === "pcb_hole").map(
6848
+ (hole, i) => "hole_diameter" in hole && "x" in hole ? /* @__PURE__ */ jsx(
6849
+ Cylinder,
6850
+ {
6851
+ radius: hole.hole_diameter * 0.42,
6852
+ height: 0.6,
6853
+ center: [hole.x, hole.y, -0.2]
6854
+ },
6855
+ i
6856
+ ) : null
6857
+ )
6858
+ ] }),
6859
+ /* @__PURE__ */ jsx(Colorize, { color: "#c6c7c9", children: pads.map((pad, i) => {
6860
+ const signal = i < pads.length - 4;
6861
+ const outerY = pad.y + pad.height * 0.4;
6862
+ const innerY = Math.min(pad.y - pad.height * 0.4, y + depth / 2 - 0.2);
6863
+ return /* @__PURE__ */ jsx(
6864
+ Cuboid,
6865
+ {
6866
+ size: [
6867
+ pad.width * 0.8,
6868
+ signal ? outerY - innerY : pad.height * 0.8,
6869
+ 0.18
6870
+ ],
6871
+ center: [pad.x, signal ? (outerY + innerY) / 2 : pad.y, 0.09]
6872
+ },
6873
+ i
6874
+ );
6875
+ }) })
6876
+ ] });
6877
+ };
6878
+
6700
6879
  // lib/SOT-563.tsx
6701
6880
  var SOT563 = ({ fullWidth = 1.94, fullLength: fullLength10 = 1.6 }) => {
6702
6881
  const bodyWidth = 1.2;
@@ -6737,7 +6916,7 @@ var SOT563 = ({ fullWidth = 1.94, fullLength: fullLength10 = 1.6 }) => {
6737
6916
  };
6738
6917
 
6739
6918
  // lib/BGA.tsx
6740
- import { fp as fp9 } from "@tscircuit/footprinter";
6919
+ import { fp as fp11 } from "@tscircuit/footprinter";
6741
6920
  var BGA = ({
6742
6921
  packageWidth = 10,
6743
6922
  packageLength = 10,
@@ -6753,7 +6932,7 @@ var BGA = ({
6753
6932
  const bodyHeight = packageHeight - standoffHeight;
6754
6933
  const bodyOffset = standoffHeight + bodyHeight / 2;
6755
6934
  const ballOffset = Math.max(standoffHeight / 2, ballDiameter / 2);
6756
- const ballsSoup = footprintString ? fp9.string(footprintString).circuitJson() : null;
6935
+ const ballsSoup = footprintString ? fp11.string(footprintString).circuitJson() : null;
6757
6936
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
6758
6937
  /* @__PURE__ */ jsx(Translate, { z: bodyOffset, children: /* @__PURE__ */ jsx(Colorize, { color: "#555", children: /* @__PURE__ */ jsx(Cuboid, { size: [packageWidth, packageLength, bodyHeight] }) }) }),
6759
6938
  !footprintString && Array.from({ length: ballRows * ballColumns }).map((_, index) => {
@@ -6783,7 +6962,7 @@ var BGA = ({
6783
6962
  };
6784
6963
 
6785
6964
  // lib/UsbCMidmount.tsx
6786
- import { fp as fp10 } from "@tscircuit/footprinter";
6965
+ import { fp as fp12 } from "@tscircuit/footprinter";
6787
6966
  var Capsule = ({
6788
6967
  width: width10,
6789
6968
  height: height10,
@@ -6793,14 +6972,14 @@ var UsbCMidmount = ({
6793
6972
  footprint = "usbcmidmount16"
6794
6973
  }) => {
6795
6974
  const canonical = footprint.replace(/_pin1location\([^)]*\)/g, "");
6796
- const params = fp10.string(canonical).json();
6797
- const elements = fp10.string(canonical).circuitJson();
6975
+ const params = fp12.string(canonical).json();
6976
+ const elements = fp12.string(canonical).circuitJson();
6798
6977
  const pads = elements.filter(
6799
6978
  (e) => e.type === "pcb_smtpad" && e.shape === "rect"
6800
6979
  );
6801
6980
  const slots = elements.filter((e) => e.type === "pcb_plated_hole");
6802
6981
  const holes = elements.filter((e) => e.type === "pcb_hole");
6803
- const target = fp10.string(footprint).circuitJson().find((e) => e.type === "pcb_plated_hole");
6982
+ const target = fp12.string(footprint).circuitJson().find((e) => e.type === "pcb_plated_hole");
6804
6983
  const first = slots[0];
6805
6984
  const angle = first && target && "x" in target ? Math.atan2(target.y, target.x) - Math.atan2(first.y, first.x) : 0;
6806
6985
  const width10 = 8.94, height10 = 3.2, wall = 0.22;
@@ -6884,15 +7063,15 @@ var UsbCMidmount = ({
6884
7063
  };
6885
7064
 
6886
7065
  // lib/SOT143.tsx
6887
- import { fp as fp11 } from "@tscircuit/footprinter";
6888
- var getPads = (footprint) => fp11.string(footprint).circuitJson().filter(
7066
+ import { fp as fp13 } from "@tscircuit/footprinter";
7067
+ var getPads = (footprint) => fp13.string(footprint).circuitJson().filter(
6889
7068
  (element) => element.type === "pcb_smtpad" && (element.shape === "rect" || element.shape === "rotated_rect")
6890
7069
  ).map((pad) => ({ x: pad.x, y: pad.y, pin: pad.port_hints?.[0] }));
6891
7070
  var SOT143 = ({ footprint = "sot143" }) => {
6892
7071
  const pads = getPads(footprint);
6893
7072
  if (pads.length !== 4) throw new Error("SOT143 requires four signal pads");
6894
7073
  const canonical = getPads("sot143");
6895
- const options = fp11.string(footprint).json();
7074
+ const options = fp13.string(footprint).json();
6896
7075
  const origin = canonical[1];
6897
7076
  const target = pads.find((pad) => pad.pin === "2");
6898
7077
  const angle = options.pin1location ? Math.round(
@@ -7536,12 +7715,12 @@ var Footprinter3d = ({ footprint }) => {
7536
7715
  const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "2";
7537
7716
  normalizedFootprint = `jst${numPins}_xh`;
7538
7717
  }
7539
- const fpJson = fp12.string(normalizedFootprint).json();
7718
+ const fpJson = fp14.string(normalizedFootprint).json();
7540
7719
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
7541
7720
  const color = colorMatch ? colorMatch[1] : void 0;
7542
7721
  const dim = (value, fallback) => {
7543
7722
  if (value === void 0 || value === null) return fallback;
7544
- const parsed = mm(value);
7723
+ const parsed = mm2(value);
7545
7724
  return Number.isFinite(parsed) ? parsed : fallback;
7546
7725
  };
7547
7726
  switch (fpJson.fn) {
@@ -7746,6 +7925,8 @@ var Footprinter3d = ({ footprint }) => {
7746
7925
  }
7747
7926
  case "sot457":
7748
7927
  return /* @__PURE__ */ jsx(SOT457, {});
7928
+ case "smdslideswitch":
7929
+ return /* @__PURE__ */ jsx(SmdSlideSwitch, { footprint: normalizedFootprint });
7749
7930
  case "usbcmidmount":
7750
7931
  return /* @__PURE__ */ jsx(UsbCMidmount, { footprint: normalizedFootprint });
7751
7932
  case "sot143":
@@ -7776,6 +7957,9 @@ var Footprinter3d = ({ footprint }) => {
7776
7957
  }
7777
7958
  );
7778
7959
  case "jst":
7960
+ if (isJstShFootprint(normalizedFootprint)) {
7961
+ return /* @__PURE__ */ jsx(JstSh, { footprint: normalizedFootprint });
7962
+ }
7779
7963
  if (fpJson.zh) {
7780
7964
  return /* @__PURE__ */ jsx(JSTZH1_5mm, { numPins: fpJson.num_pins });
7781
7965
  }
@@ -8152,8 +8336,8 @@ var Footprinter3d = ({ footprint }) => {
8152
8336
  return /* @__PURE__ */ jsx(A2512, { color });
8153
8337
  }
8154
8338
  if ((fpJson.fn === "res" || fpJson.fn === "cap") && fpJson.p !== void 0 && fpJson.ph !== void 0) {
8155
- const padPitch = mm(fpJson.p);
8156
- const padHeight = mm(fpJson.ph);
8339
+ const padPitch = mm2(fpJson.p);
8340
+ const padHeight = mm2(fpJson.ph);
8157
8341
  if (Number.isFinite(padPitch) && Number.isFinite(padHeight)) {
8158
8342
  return /* @__PURE__ */ jsx(
8159
8343
  ParametricChip,