@tscircuit/3d-viewer 0.0.591 → 0.0.592

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.
Files changed (2) hide show
  1. package/dist/index.js +975 -4
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -28158,6 +28158,79 @@ var SOD123W = () => {
28158
28158
  )
28159
28159
  ] });
28160
28160
  };
28161
+ var SOD123 = ({
28162
+ fullWidth = 3.7,
28163
+ fullLength: fullLength10 = 1.55
28164
+ } = {}) => {
28165
+ const bodyWidth = fullWidth - 1;
28166
+ const bodyLength10 = fullLength10;
28167
+ const packageHeight = 1.175;
28168
+ const bodyStandoff = 0.1;
28169
+ const bodyHeight = packageHeight - bodyStandoff;
28170
+ const leadWidth = 0.55;
28171
+ const leadThickness = 0.12;
28172
+ const leadHeight = 0.35;
28173
+ const bodyDistance = (fullWidth - bodyWidth) / 2;
28174
+ const padContactLength = 0.25;
28175
+ const leadCurveLength = 0.2;
28176
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
28177
+ /* @__PURE__ */ jsx2(
28178
+ SmdChipLead,
28179
+ {
28180
+ position: {
28181
+ x: -fullWidth / 2,
28182
+ y: 0,
28183
+ z: leadThickness / 2
28184
+ },
28185
+ width: leadWidth,
28186
+ thickness: leadThickness,
28187
+ padContactLength,
28188
+ bodyDistance,
28189
+ curveLength: leadCurveLength,
28190
+ height: leadHeight
28191
+ }
28192
+ ),
28193
+ /* @__PURE__ */ jsx2(
28194
+ SmdChipLead,
28195
+ {
28196
+ rotation: Math.PI,
28197
+ position: {
28198
+ x: fullWidth / 2,
28199
+ y: 0,
28200
+ z: leadThickness / 2
28201
+ },
28202
+ width: leadWidth,
28203
+ thickness: leadThickness,
28204
+ padContactLength,
28205
+ bodyDistance,
28206
+ curveLength: leadCurveLength,
28207
+ height: leadHeight
28208
+ }
28209
+ ),
28210
+ /* @__PURE__ */ jsx2(
28211
+ ChipBody,
28212
+ {
28213
+ center: { x: 0, y: 0, z: 0 },
28214
+ width: bodyWidth,
28215
+ length: bodyLength10,
28216
+ height: bodyHeight,
28217
+ heightAboveSurface: bodyStandoff,
28218
+ includeNotch: false,
28219
+ color: "#222",
28220
+ taperRatio: 0.06,
28221
+ straightHeightRatio: 0.6
28222
+ }
28223
+ ),
28224
+ /* @__PURE__ */ jsx2(
28225
+ Cuboid,
28226
+ {
28227
+ color: "#777",
28228
+ size: [0.45, bodyLength10 - 0.15, 0.02],
28229
+ center: [-bodyWidth / 4, 0, packageHeight]
28230
+ }
28231
+ )
28232
+ ] });
28233
+ };
28161
28234
  var SOD128 = () => {
28162
28235
  const fullWidth = 3.8;
28163
28236
  const bodyLength10 = 2.5;
@@ -30391,6 +30464,822 @@ var JSTZH1_5mm = ({
30391
30464
  })
30392
30465
  ] });
30393
30466
  };
30467
+ var getTerminalPoints = ([centerX, centerY], width10, length64, chamfer, isPinOne) => {
30468
+ const xDirection = Math.sign(centerX);
30469
+ const yDirection = Math.sign(centerY);
30470
+ const halfWidth = width10 / 2;
30471
+ const halfLength = length64 / 2;
30472
+ const innerChamfer = isPinOne ? Math.min(0.32, length64 * 0.36) : 0;
30473
+ const outerChamfer = Math.min(chamfer, halfWidth, halfLength);
30474
+ const points = [
30475
+ [-halfWidth, -halfLength],
30476
+ [halfWidth, -halfLength],
30477
+ [halfWidth, halfLength - outerChamfer],
30478
+ [halfWidth - outerChamfer, halfLength],
30479
+ [-halfWidth, halfLength]
30480
+ ];
30481
+ if (innerChamfer) {
30482
+ points[0] = [-halfWidth + innerChamfer, -halfLength];
30483
+ points.push([-halfWidth, -halfLength + innerChamfer]);
30484
+ }
30485
+ const oriented = points.map(
30486
+ ([x, y]) => [centerX + x * xDirection, centerY + y * yDirection]
30487
+ );
30488
+ return xDirection * yDirection < 0 ? oriented.reverse() : oriented;
30489
+ };
30490
+ var getRoundedRectProfile = ({
30491
+ width: width10,
30492
+ length: length64,
30493
+ radius,
30494
+ height: height10,
30495
+ z: z21
30496
+ }) => {
30497
+ const x = width10 / 2 - radius;
30498
+ const y = length64 / 2 - radius;
30499
+ return [
30500
+ [-x, -y],
30501
+ [x, -y],
30502
+ [x, y],
30503
+ [-x, y]
30504
+ ].map(([cornerX, cornerY], index2) => /* @__PURE__ */ jsx2(
30505
+ Cylinder,
30506
+ {
30507
+ center: [cornerX, cornerY, z21 + height10 / 2],
30508
+ height: height10,
30509
+ radius
30510
+ },
30511
+ `${z21}-${index2}`
30512
+ ));
30513
+ };
30514
+ var Crystal = ({
30515
+ horizontalPadPitch = 2.2,
30516
+ verticalPadPitch = 1.7,
30517
+ padWidth = 1.4,
30518
+ padHeight = 1.2,
30519
+ bodyHeight = 0.7
30520
+ }) => {
30521
+ const bodyWidth = horizontalPadPitch + padWidth * (5 / 7);
30522
+ const bodyLength10 = verticalPadPitch + padHeight * (2 / 3);
30523
+ const terminalThickness = Math.min(0.01, bodyHeight * 0.02);
30524
+ const terminalWidth = padWidth * (5 / 7);
30525
+ const terminalLength = padHeight * 0.75;
30526
+ const ceramicTopZ = bodyHeight * (5 / 7);
30527
+ const baseHeight = ceramicTopZ - terminalThickness;
30528
+ const sealHeight = bodyHeight * (2 / 35);
30529
+ const sealWidth = bodyWidth * 0.95;
30530
+ const sealLength = bodyLength10 * 0.94;
30531
+ const lidShoulderWidth = bodyWidth * 0.905;
30532
+ const lidShoulderLength = bodyLength10 * 0.9;
30533
+ const lidTopWidth = bodyWidth * 0.83;
30534
+ const lidTopLength = bodyLength10 * 0.82;
30535
+ const lidBaseZ = ceramicTopZ + sealHeight;
30536
+ const lidProfileHeight = Math.min(0.01, bodyHeight * 0.015);
30537
+ const bodyChamfer = Math.min(0.12, bodyLength10 * 0.05);
30538
+ const terminalX = (bodyWidth - terminalWidth) / 2;
30539
+ const terminalY = (bodyLength10 - terminalLength) / 2;
30540
+ const terminalPositions = [
30541
+ [-terminalX, -terminalY],
30542
+ [terminalX, -terminalY],
30543
+ [terminalX, terminalY],
30544
+ [-terminalX, terminalY]
30545
+ ];
30546
+ const sealProfile = getRoundedRectProfile({
30547
+ width: sealWidth,
30548
+ length: sealLength,
30549
+ radius: Math.min(0.13, sealLength * 0.08),
30550
+ height: sealHeight,
30551
+ z: ceramicTopZ
30552
+ });
30553
+ const lidProfiles = [
30554
+ ...getRoundedRectProfile({
30555
+ width: lidShoulderWidth,
30556
+ length: lidShoulderLength,
30557
+ radius: Math.min(0.14, lidShoulderLength * 0.08),
30558
+ height: lidProfileHeight,
30559
+ z: lidBaseZ
30560
+ }),
30561
+ ...getRoundedRectProfile({
30562
+ width: lidTopWidth,
30563
+ length: lidTopLength,
30564
+ radius: Math.min(0.15, lidTopLength * 0.09),
30565
+ height: lidProfileHeight,
30566
+ z: bodyHeight - lidProfileHeight
30567
+ })
30568
+ ];
30569
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
30570
+ terminalPositions.map((center, index2) => /* @__PURE__ */ jsx2(Colorize, { color: "#d6a258", children: /* @__PURE__ */ jsx2(ExtrudeLinear, { height: terminalThickness, children: /* @__PURE__ */ jsx2(
30571
+ Polygon,
30572
+ {
30573
+ points: getTerminalPoints(
30574
+ center,
30575
+ terminalWidth,
30576
+ terminalLength,
30577
+ bodyChamfer,
30578
+ index2 === 0
30579
+ )
30580
+ }
30581
+ ) }) }, index2)),
30582
+ /* @__PURE__ */ jsx2(
30583
+ ChipBody,
30584
+ {
30585
+ center: { x: 0, y: 0, z: terminalThickness },
30586
+ width: bodyWidth,
30587
+ length: bodyLength10,
30588
+ height: baseHeight - 5e-3,
30589
+ heightAboveSurface: 0,
30590
+ color: "#34343d",
30591
+ taperRatio: 0,
30592
+ straightHeightRatio: 1,
30593
+ includeNotch: false,
30594
+ chamferSize: bodyChamfer
30595
+ }
30596
+ ),
30597
+ /* @__PURE__ */ jsx2(Colorize, { color: "#d2a057", children: /* @__PURE__ */ jsx2(Hull, { children: sealProfile }) }),
30598
+ /* @__PURE__ */ jsx2(Colorize, { color: "#b9bec2", children: /* @__PURE__ */ jsx2(Hull, { children: lidProfiles }) })
30599
+ ] });
30600
+ };
30601
+ var HOUSING_COLOR = "#303339";
30602
+ var HOUSING_SHADOW = "#1f2227";
30603
+ var ACTUATOR_COLOR = "#eee8d8";
30604
+ var ACTUATOR_HIGHLIGHT = "#f8f3e7";
30605
+ var TIN_COLOR = "#b7bdc2";
30606
+ var TIN_HIGHLIGHT = "#d2d6d9";
30607
+ var HOLD_DOWN_COLOR = "#767d82";
30608
+ var HOLD_DOWN_HIGHLIGHT = "#9ba1a5";
30609
+ var FPC = ({
30610
+ pinCount = 12,
30611
+ pitch = 0.5,
30612
+ padWidth = 0.3,
30613
+ padLength = 1.25,
30614
+ staggered = false,
30615
+ reverse = false,
30616
+ rowPitch = 2.4,
30617
+ topPadLength = padLength,
30618
+ bottomPadLength = padLength,
30619
+ mountPadPitchX,
30620
+ mountPadOffsetY = 2.575,
30621
+ mountTop = false,
30622
+ mountPadWidth = 2,
30623
+ mountPadLength = 2.5
30624
+ }) => {
30625
+ const contactSpan = Math.max((pinCount - 1) * pitch, pitch);
30626
+ const contactStartX = -contactSpan / 2;
30627
+ const resolvedMountPitch = mountPadPitchX ?? contactSpan + (staggered ? 3.5 : 3.38);
30628
+ const mountY = mountPadOffsetY === 0 ? 0 : (mountTop ? 1 : -1) * mountPadOffsetY;
30629
+ const contactRows = Array.from({ length: pinCount }, (_, index2) => {
30630
+ const isUpperRow = staggered && index2 % 2 === 1 !== reverse;
30631
+ const y = staggered ? isUpperRow ? rowPitch / 2 : -rowPitch / 2 : 0;
30632
+ const length64 = isUpperRow ? topPadLength : bottomPadLength;
30633
+ return {
30634
+ index: index2,
30635
+ x: contactStartX + index2 * pitch,
30636
+ y,
30637
+ length: length64
30638
+ };
30639
+ });
30640
+ const contactMaxY = Math.max(
30641
+ ...contactRows.map((contact) => contact.y + contact.length / 2)
30642
+ );
30643
+ const contactMinY = Math.min(
30644
+ ...contactRows.map((contact) => contact.y - contact.length / 2)
30645
+ );
30646
+ const mountingMinY = mountY - mountPadLength / 2;
30647
+ const mountingMaxY = mountY + mountPadLength / 2;
30648
+ const signalSideY = mountTop ? contactMinY : contactMaxY;
30649
+ const cableSideY = mountTop ? Math.max(mountingMaxY, contactMaxY) + 0.67 : Math.min(mountingMinY, contactMinY) - 0.67;
30650
+ const directionToSignal = mountTop ? -1 : 1;
30651
+ const housingSignalY = signalSideY - directionToSignal * Math.max(padLength * 0.86, 1.05);
30652
+ const housingCableY = cableSideY + directionToSignal * 0.22;
30653
+ const housingDepth = Math.abs(housingSignalY - housingCableY);
30654
+ const housingCenterY = (housingSignalY + housingCableY) / 2;
30655
+ const cableEdgeY = housingCableY - directionToSignal * 0.01;
30656
+ const bodyWidth = Math.max(
30657
+ contactSpan + 4.9,
30658
+ resolvedMountPitch + mountPadWidth * 0.76
30659
+ );
30660
+ const openingWidth = Math.min(bodyWidth - 2.3, contactSpan + 1.1);
30661
+ const housingBaseHeight = 0.3;
30662
+ const housingHeight = 1.42;
30663
+ const overallHeight = 2;
30664
+ const throatDepth = Math.min(0.92, housingDepth * 0.28);
30665
+ const throatCenterY = cableEdgeY + directionToSignal * (throatDepth / 2 - 0.04);
30666
+ const throatHeight = 1.6;
30667
+ const throatCenterZ = 1.1;
30668
+ const actuatorDepth = Math.max(housingDepth - 0.78, 1.5);
30669
+ const actuatorCenterY = cableEdgeY + directionToSignal * (actuatorDepth / 2 + 0.68);
30670
+ const actuatorWidth = bodyWidth - 0.72;
30671
+ const actuatorHeight = 0.34;
30672
+ const actuatorCenterZ = overallHeight - actuatorHeight / 2;
30673
+ const hingeY = cableEdgeY + directionToSignal * Math.min(0.68, housingDepth * 0.22);
30674
+ const hingeZ = 1.48;
30675
+ const terminalWidth = Math.max(padWidth * 0.82, 0.15);
30676
+ const terminalOuterY = signalSideY;
30677
+ const terminalLength = Math.abs(terminalOuterY - housingSignalY);
30678
+ const terminalCenterY = (terminalOuterY + housingSignalY) / 2;
30679
+ const springLength = Math.max(throatDepth * 0.8, 0.5);
30680
+ const springCenterY = cableEdgeY + directionToSignal * (springLength / 2 + 0.08);
30681
+ const endClipX = resolvedMountPitch / 2;
30682
+ const clipHeight = 0.75;
30683
+ const clipWallX = bodyWidth / 2 - 0.04;
30684
+ const clipCapX = bodyWidth / 2 - 0.23;
30685
+ const sideBossX = bodyWidth / 2 - 0.32;
30686
+ const sideBossWidth = 0.68;
30687
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
30688
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
30689
+ Cuboid,
30690
+ {
30691
+ color: TIN_COLOR,
30692
+ center: [direction * endClipX, mountY, 0.07],
30693
+ size: [mountPadWidth, mountPadLength, 0.14]
30694
+ },
30695
+ `mount-pad:${direction}`
30696
+ )),
30697
+ contactRows.map((contact) => /* @__PURE__ */ jsx2(
30698
+ Cuboid,
30699
+ {
30700
+ color: TIN_COLOR,
30701
+ center: [contact.x, terminalCenterY, 0.065],
30702
+ size: [terminalWidth, terminalLength, 0.13]
30703
+ },
30704
+ `terminal:${contact.index}`
30705
+ )),
30706
+ /* @__PURE__ */ jsx2(
30707
+ RoundedCuboid,
30708
+ {
30709
+ color: HOUSING_SHADOW,
30710
+ center: [0, housingCenterY, housingBaseHeight / 2],
30711
+ size: [bodyWidth, housingDepth, housingBaseHeight],
30712
+ roundRadius: 0.1
30713
+ }
30714
+ ),
30715
+ /* @__PURE__ */ jsx2(Colorize, { color: HOUSING_COLOR, children: /* @__PURE__ */ jsxs(Subtract, { children: [
30716
+ /* @__PURE__ */ jsx2(
30717
+ RoundedCuboid,
30718
+ {
30719
+ center: [0, housingCenterY, housingBaseHeight + housingHeight / 2],
30720
+ size: [bodyWidth - 0.2, housingDepth - 0.12, housingHeight],
30721
+ roundRadius: 0.14
30722
+ }
30723
+ ),
30724
+ /* @__PURE__ */ jsx2(
30725
+ Cuboid,
30726
+ {
30727
+ center: [0, throatCenterY, throatCenterZ],
30728
+ size: [openingWidth, throatDepth, throatHeight]
30729
+ }
30730
+ ),
30731
+ /* @__PURE__ */ jsx2(
30732
+ Cuboid,
30733
+ {
30734
+ center: [0, actuatorCenterY, overallHeight - actuatorHeight * 0.72],
30735
+ size: [actuatorWidth - 0.32, actuatorDepth - 0.16, actuatorHeight]
30736
+ }
30737
+ )
30738
+ ] }) }),
30739
+ contactRows.map((contact) => /* @__PURE__ */ jsx2(
30740
+ RoundedCuboid,
30741
+ {
30742
+ color: TIN_HIGHLIGHT,
30743
+ center: [contact.x, springCenterY, housingBaseHeight + 0.82],
30744
+ size: [terminalWidth * 0.82, springLength, 0.14],
30745
+ roundRadius: 0.035
30746
+ },
30747
+ `spring:${contact.index}`
30748
+ )),
30749
+ contactRows.map((contact) => /* @__PURE__ */ jsx2(
30750
+ Cuboid,
30751
+ {
30752
+ color: TIN_COLOR,
30753
+ center: [
30754
+ contact.x,
30755
+ housingSignalY - directionToSignal * 0.03,
30756
+ housingBaseHeight + 0.32
30757
+ ],
30758
+ size: [terminalWidth, 0.13, 0.62]
30759
+ },
30760
+ `terminal-rise:${contact.index}`
30761
+ )),
30762
+ /* @__PURE__ */ jsx2(
30763
+ Cuboid,
30764
+ {
30765
+ color: HOUSING_SHADOW,
30766
+ center: [
30767
+ 0,
30768
+ cableEdgeY + directionToSignal * 0.1,
30769
+ housingBaseHeight + 0.71
30770
+ ],
30771
+ size: [openingWidth + 0.18, 0.16, 0.8]
30772
+ }
30773
+ ),
30774
+ /* @__PURE__ */ jsx2(
30775
+ RoundedCuboid,
30776
+ {
30777
+ color: ACTUATOR_COLOR,
30778
+ center: [0, actuatorCenterY, actuatorCenterZ],
30779
+ size: [actuatorWidth, actuatorDepth, actuatorHeight],
30780
+ roundRadius: 0.11
30781
+ }
30782
+ ),
30783
+ /* @__PURE__ */ jsx2(
30784
+ Cuboid,
30785
+ {
30786
+ color: ACTUATOR_HIGHLIGHT,
30787
+ center: [
30788
+ 0,
30789
+ actuatorCenterY - directionToSignal * (actuatorDepth / 2 - 0.12),
30790
+ overallHeight - 0.035
30791
+ ],
30792
+ size: [actuatorWidth - 0.36, 0.24, 0.07]
30793
+ }
30794
+ ),
30795
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
30796
+ RoundedCuboid,
30797
+ {
30798
+ color: ACTUATOR_COLOR,
30799
+ center: [direction * sideBossX, hingeY, hingeZ],
30800
+ size: [sideBossWidth, 0.92, 0.72],
30801
+ roundRadius: 0.1
30802
+ },
30803
+ `actuator-ear:${direction}`
30804
+ )),
30805
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
30806
+ Translate,
30807
+ {
30808
+ x: direction * sideBossX,
30809
+ y: hingeY,
30810
+ z: hingeZ,
30811
+ children: /* @__PURE__ */ jsx2(Rotate, { rotation: [0, Math.PI / 2, 0], children: /* @__PURE__ */ jsx2(
30812
+ Cylinder,
30813
+ {
30814
+ color: ACTUATOR_HIGHLIGHT,
30815
+ height: sideBossWidth + 0.12,
30816
+ radius: 0.24
30817
+ }
30818
+ ) })
30819
+ },
30820
+ `hinge:${direction}`
30821
+ )),
30822
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
30823
+ RoundedCuboid,
30824
+ {
30825
+ color: HOLD_DOWN_COLOR,
30826
+ center: [direction * clipWallX, mountY, clipHeight / 2],
30827
+ size: [0.17, Math.min(mountPadLength * 0.3, 0.7), clipHeight],
30828
+ roundRadius: 0.04
30829
+ },
30830
+ `hold-down-wall:${direction}`
30831
+ )),
30832
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
30833
+ RoundedCuboid,
30834
+ {
30835
+ color: HOLD_DOWN_HIGHLIGHT,
30836
+ center: [direction * clipCapX, mountY, clipHeight - 0.05],
30837
+ size: [0.42, Math.min(mountPadLength * 0.3, 0.7), 0.1],
30838
+ roundRadius: 0.035
30839
+ },
30840
+ `hold-down-cap:${direction}`
30841
+ )),
30842
+ /* @__PURE__ */ jsx2(
30843
+ Cuboid,
30844
+ {
30845
+ color: HOUSING_SHADOW,
30846
+ center: [0, housingCenterY, 0.025],
30847
+ size: [openingWidth + 0.7, housingDepth * 0.58, 0.05]
30848
+ }
30849
+ ),
30850
+ /* @__PURE__ */ jsx2(
30851
+ Cuboid,
30852
+ {
30853
+ color: HOUSING_SHADOW,
30854
+ center: [
30855
+ 0,
30856
+ housingSignalY - directionToSignal * 0.06,
30857
+ housingBaseHeight + 0.82
30858
+ ],
30859
+ size: [openingWidth + 0.4, 0.15, 0.92]
30860
+ }
30861
+ )
30862
+ ] });
30863
+ };
30864
+ var SmdPinHeader = ({
30865
+ numberOfPins,
30866
+ pitch = 2.54,
30867
+ pinThickness = 0.64,
30868
+ bodyWidth = 2.5,
30869
+ bodyHeight = 2.54,
30870
+ standoffHeight = 1.27,
30871
+ matingPinLength = 5.8,
30872
+ tailSpan = 5.08
30873
+ }) => {
30874
+ const xStart = -((numberOfPins - 1) * pitch) / 2;
30875
+ const bodyTop = standoffHeight + bodyHeight;
30876
+ const tailLength = tailSpan / 2;
30877
+ const tipChamferHeight = pinThickness * 0.35;
30878
+ return /* @__PURE__ */ jsx2(Fragment2, { children: Array.from({ length: numberOfPins }, (_, index2) => {
30879
+ const x = xStart + index2 * pitch;
30880
+ const tailDirection = index2 % 2 === 0 ? 1 : -1;
30881
+ const postBodyLength = matingPinLength - tipChamferHeight;
30882
+ const verticalTailLength = standoffHeight - pinThickness / 2;
30883
+ return /* @__PURE__ */ jsxs(Translate, { x, children: [
30884
+ /* @__PURE__ */ jsx2(
30885
+ Cuboid,
30886
+ {
30887
+ color: "#222",
30888
+ size: [pitch, bodyWidth, bodyHeight],
30889
+ center: [0, 0, standoffHeight + bodyHeight / 2]
30890
+ }
30891
+ ),
30892
+ /* @__PURE__ */ jsxs(Colorize, { color: "#d4af37", children: [
30893
+ /* @__PURE__ */ jsx2(
30894
+ Cuboid,
30895
+ {
30896
+ size: [pinThickness, tailLength, pinThickness],
30897
+ center: [0, tailDirection * (tailLength / 2), pinThickness / 2]
30898
+ }
30899
+ ),
30900
+ /* @__PURE__ */ jsx2(
30901
+ Cuboid,
30902
+ {
30903
+ size: [pinThickness, pinThickness, verticalTailLength],
30904
+ center: [0, 0, pinThickness / 2 + verticalTailLength / 2]
30905
+ }
30906
+ ),
30907
+ /* @__PURE__ */ jsx2(
30908
+ Cuboid,
30909
+ {
30910
+ size: [pinThickness, pinThickness, postBodyLength],
30911
+ center: [0, 0, bodyTop + postBodyLength / 2]
30912
+ }
30913
+ ),
30914
+ /* @__PURE__ */ jsxs(Hull, { children: [
30915
+ /* @__PURE__ */ jsx2(
30916
+ Cuboid,
30917
+ {
30918
+ size: [pinThickness, pinThickness, 0.01],
30919
+ center: [0, 0, bodyTop + postBodyLength]
30920
+ }
30921
+ ),
30922
+ /* @__PURE__ */ jsx2(
30923
+ Cuboid,
30924
+ {
30925
+ size: [pinThickness * 0.65, pinThickness * 0.65, 0.01],
30926
+ center: [0, 0, bodyTop + matingPinLength]
30927
+ }
30928
+ )
30929
+ ] })
30930
+ ] })
30931
+ ] }, index2);
30932
+ }) });
30933
+ };
30934
+ var ParametricChip = ({
30935
+ padPitch,
30936
+ padHeight,
30937
+ color = "#333"
30938
+ }) => {
30939
+ const fullLength10 = padPitch;
30940
+ const width10 = padHeight * 0.85;
30941
+ const height10 = width10;
30942
+ const terminatorWidth9 = fullLength10 * 0.2;
30943
+ const bodyLength10 = fullLength10 - terminatorWidth9 * 2;
30944
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
30945
+ /* @__PURE__ */ jsx2(
30946
+ Cuboid,
30947
+ {
30948
+ size: [bodyLength10, width10, height10],
30949
+ offset: [0, 0, height10 / 2],
30950
+ color
30951
+ }
30952
+ ),
30953
+ /* @__PURE__ */ jsx2(
30954
+ Cuboid,
30955
+ {
30956
+ size: [terminatorWidth9, height10, width10],
30957
+ offset: [fullLength10 / 2 - terminatorWidth9 / 2, 0, height10 / 2],
30958
+ color: "#ccc"
30959
+ }
30960
+ ),
30961
+ /* @__PURE__ */ jsx2(
30962
+ Cuboid,
30963
+ {
30964
+ size: [terminatorWidth9, height10, width10],
30965
+ offset: [-fullLength10 / 2 + terminatorWidth9 / 2, 0, height10 / 2],
30966
+ color: "#ccc"
30967
+ }
30968
+ )
30969
+ ] });
30970
+ };
30971
+ var Led5050 = ({
30972
+ color = "#ffff00",
30973
+ bodyColor = "#ffffff",
30974
+ leadColor = "#dedede"
30975
+ }) => {
30976
+ const bodySize = 5;
30977
+ const leadSpan = 5.4;
30978
+ const bodyBottom = 0.2;
30979
+ const bodyHeight = 1.3;
30980
+ const bodyTop = bodyBottom + bodyHeight;
30981
+ const leadLength = 1.4;
30982
+ const leadWidth = 1;
30983
+ const leadThickness = 0.2;
30984
+ const leadCenterX = leadSpan / 2 - leadLength / 2;
30985
+ const lensRadius = 2;
30986
+ const lensHeight = 0.25;
30987
+ const lensTop = 1.55;
30988
+ const cornerCutDepth = 0.3;
30989
+ const leadYPositions = [-1.7, 0, 1.7];
30990
+ const leadSides = [-1, 1];
30991
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
30992
+ leadYPositions.flatMap(
30993
+ (y) => leadSides.map((side) => /* @__PURE__ */ jsx2(
30994
+ Cuboid,
30995
+ {
30996
+ color: leadColor,
30997
+ size: [leadLength, leadWidth, leadThickness],
30998
+ center: [side * leadCenterX, y, leadThickness / 2]
30999
+ },
31000
+ `${side}-${y}`
31001
+ ))
31002
+ ),
31003
+ /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
31004
+ /* @__PURE__ */ jsx2(
31005
+ ChipBody,
31006
+ {
31007
+ width: bodySize,
31008
+ length: bodySize,
31009
+ height: bodyHeight,
31010
+ heightAboveSurface: bodyBottom,
31011
+ center: { x: 0, y: 0, z: 0 },
31012
+ color: bodyColor,
31013
+ taperRatio: 0.036,
31014
+ straightHeightRatio: 0.01,
31015
+ includeNotch: false
31016
+ }
31017
+ ),
31018
+ /* @__PURE__ */ jsx2(
31019
+ Cylinder,
31020
+ {
31021
+ radius: lensRadius,
31022
+ height: lensHeight,
31023
+ center: [0, 0, bodyTop - lensHeight / 2]
31024
+ }
31025
+ ),
31026
+ /* @__PURE__ */ jsx2(
31027
+ Translate,
31028
+ {
31029
+ offset: [
31030
+ -bodySize / 2,
31031
+ bodySize / 2,
31032
+ bodyTop - cornerCutDepth / 2 + 5e-3
31033
+ ],
31034
+ children: /* @__PURE__ */ jsx2(Rotate, { rotation: [0, 0, Math.PI / 4], children: /* @__PURE__ */ jsx2(Cuboid, { size: [0.9, 0.9, cornerCutDepth + 0.01] }) })
31035
+ }
31036
+ )
31037
+ ] }) }),
31038
+ /* @__PURE__ */ jsx2(
31039
+ Cylinder,
31040
+ {
31041
+ color,
31042
+ radius: lensRadius,
31043
+ height: lensHeight,
31044
+ center: [0, 0, lensTop - lensHeight / 2]
31045
+ }
31046
+ )
31047
+ ] });
31048
+ };
31049
+ var range2 = (length64) => Array.from({ length: length64 }, (_, index2) => index2);
31050
+ var RJ45 = ({
31051
+ bodyWidth = 16.26,
31052
+ bodyDepth = 15.88,
31053
+ bodyHeight = 13.5,
31054
+ bodyCenterY = -0.96,
31055
+ ledPins = false,
31056
+ firstPinLeft = false,
31057
+ firstPinTop = false,
31058
+ signalPitch = 1.02,
31059
+ signalRowPitch = 1.78,
31060
+ signalHoleDiameter = 0.9144,
31061
+ shieldPinX = 8.13,
31062
+ shieldPinY = 0.13,
31063
+ shieldHoleDiameter = 1.8,
31064
+ locatorHoleX = 6.35,
31065
+ locatorHoleY = -3.43,
31066
+ locatorHoleDiameter = 3.25,
31067
+ ledPinX = 4.57,
31068
+ ledPinPitch = 2.29,
31069
+ ledPinY = 5.7,
31070
+ openingDirection,
31071
+ shellColor = "#b7bdc2",
31072
+ housingColor = "#20242a",
31073
+ contactColor = "#d6a928"
31074
+ }) => {
31075
+ const frontDirection = openingDirection ?? (bodyCenterY > 0 ? 1 : -1);
31076
+ const frontY = bodyCenterY + frontDirection * bodyDepth / 2;
31077
+ const shellThickness = Math.min(0.38, bodyWidth * 0.024);
31078
+ const openingWidth = Math.max(bodyWidth - 2.5, bodyWidth * 0.72);
31079
+ const openingHeight = Math.min(bodyHeight - 2.4, 9.6);
31080
+ const openingCenterZ = 1.3 + openingHeight / 2;
31081
+ const cavityDepth = Math.min(4.4, bodyDepth * 0.34);
31082
+ const cavityCenterY = frontY - frontDirection * cavityDepth / 2;
31083
+ const backWallY = frontY - frontDirection * (cavityDepth + shellThickness * 0.7);
31084
+ const signalLeadRadius = Math.max(
31085
+ 0.22,
31086
+ Math.min(signalHoleDiameter * 0.36, 0.38)
31087
+ );
31088
+ const signalPinPositions = range2(8).map((index2) => {
31089
+ const defaultX = (3.5 - index2) * signalPitch;
31090
+ const defaultY = index2 % 2 === 0 ? -signalRowPitch / 2 : signalRowPitch / 2;
31091
+ return {
31092
+ x: firstPinLeft ? -defaultX : defaultX,
31093
+ y: firstPinTop ? -defaultY : defaultY
31094
+ };
31095
+ });
31096
+ const ledPinPositions = [
31097
+ -ledPinX - ledPinPitch,
31098
+ -ledPinX,
31099
+ ledPinX,
31100
+ ledPinX + ledPinPitch
31101
+ ];
31102
+ const contactPitch = openingWidth / 10;
31103
+ const contactY = frontY - frontDirection * Math.max(cavityDepth * 0.48, 1.2);
31104
+ const contactZ = openingCenterZ + openingHeight * 0.18;
31105
+ const frontLipY = frontY + frontDirection * shellThickness * 0.2;
31106
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
31107
+ /* @__PURE__ */ jsxs(Colorize, { color: shellColor, children: [
31108
+ /* @__PURE__ */ jsxs(Subtract, { children: [
31109
+ /* @__PURE__ */ jsx2(
31110
+ Cuboid,
31111
+ {
31112
+ center: [0, bodyCenterY, bodyHeight / 2],
31113
+ size: [bodyWidth, bodyDepth, bodyHeight]
31114
+ }
31115
+ ),
31116
+ /* @__PURE__ */ jsx2(
31117
+ Cuboid,
31118
+ {
31119
+ center: [0, cavityCenterY, openingCenterZ],
31120
+ size: [
31121
+ openingWidth,
31122
+ cavityDepth + shellThickness * 2,
31123
+ openingHeight
31124
+ ]
31125
+ }
31126
+ )
31127
+ ] }),
31128
+ /* @__PURE__ */ jsx2(
31129
+ Cuboid,
31130
+ {
31131
+ center: [0, frontLipY, 0.72],
31132
+ size: [openingWidth + 0.5, shellThickness * 1.25, 1.05]
31133
+ }
31134
+ ),
31135
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
31136
+ Cuboid,
31137
+ {
31138
+ center: [direction * shieldPinX, shieldPinY, 0.25],
31139
+ size: [
31140
+ Math.max(shieldHoleDiameter * 0.46, 0.65),
31141
+ Math.max(shieldHoleDiameter * 0.72, 1.1),
31142
+ 3.4
31143
+ ]
31144
+ },
31145
+ `shield-tab:${direction}`
31146
+ )),
31147
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
31148
+ Cuboid,
31149
+ {
31150
+ center: [
31151
+ direction * bodyWidth * 0.24,
31152
+ bodyCenterY - frontDirection * bodyDepth * 0.08,
31153
+ bodyHeight + 0.04
31154
+ ],
31155
+ size: [bodyWidth * 0.22, bodyDepth * 0.42, 0.1]
31156
+ },
31157
+ `top-seam:${direction}`
31158
+ ))
31159
+ ] }),
31160
+ /* @__PURE__ */ jsxs(Colorize, { color: housingColor, children: [
31161
+ /* @__PURE__ */ jsxs(Subtract, { children: [
31162
+ /* @__PURE__ */ jsx2(
31163
+ RoundedCuboid,
31164
+ {
31165
+ center: [0, cavityCenterY, openingCenterZ],
31166
+ size: [
31167
+ openingWidth - 0.2,
31168
+ cavityDepth + shellThickness * 0.5,
31169
+ openingHeight - 0.2
31170
+ ],
31171
+ roundRadius: 0.22
31172
+ }
31173
+ ),
31174
+ /* @__PURE__ */ jsx2(
31175
+ Cuboid,
31176
+ {
31177
+ center: [
31178
+ 0,
31179
+ cavityCenterY - frontDirection * shellThickness * 0.2,
31180
+ openingCenterZ - 0.05
31181
+ ],
31182
+ size: [
31183
+ openingWidth - 1.25,
31184
+ cavityDepth + shellThickness,
31185
+ openingHeight - 1.35
31186
+ ]
31187
+ }
31188
+ )
31189
+ ] }),
31190
+ /* @__PURE__ */ jsx2(
31191
+ Cuboid,
31192
+ {
31193
+ center: [0, backWallY, openingCenterZ],
31194
+ size: [openingWidth - 1.15, shellThickness, openingHeight - 1.25]
31195
+ }
31196
+ ),
31197
+ /* @__PURE__ */ jsx2(
31198
+ RoundedCuboid,
31199
+ {
31200
+ center: [0, frontY - frontDirection * cavityDepth * 0.28, 1.55],
31201
+ size: [openingWidth - 2.6, cavityDepth * 0.5, 1.15],
31202
+ roundRadius: 0.16
31203
+ }
31204
+ ),
31205
+ [-1, 1].map((direction) => /* @__PURE__ */ jsx2(
31206
+ Cylinder,
31207
+ {
31208
+ center: [direction * locatorHoleX, locatorHoleY, -0.25],
31209
+ radius: Math.max(locatorHoleDiameter * 0.41, 0.65),
31210
+ height: 2.7
31211
+ },
31212
+ `locator:${direction}`
31213
+ ))
31214
+ ] }),
31215
+ /* @__PURE__ */ jsxs(Colorize, { color: contactColor, children: [
31216
+ signalPinPositions.map(({ x, y }, index2) => /* @__PURE__ */ jsx2(
31217
+ Cylinder,
31218
+ {
31219
+ center: [x, y, 0.15],
31220
+ radius: signalLeadRadius,
31221
+ height: 3.1
31222
+ },
31223
+ `signal-lead:${index2}`
31224
+ )),
31225
+ range2(8).map((index2) => /* @__PURE__ */ jsx2(
31226
+ Translate,
31227
+ {
31228
+ offset: [
31229
+ (index2 - 3.5) * contactPitch,
31230
+ contactY,
31231
+ contactZ + (index2 % 2 === 0 ? 0.03 : -0.03)
31232
+ ],
31233
+ children: /* @__PURE__ */ jsx2(Rotate, { rotation: [frontDirection * 0.2, 0, 0], children: /* @__PURE__ */ jsx2(
31234
+ RoundedCuboid,
31235
+ {
31236
+ size: [Math.max(contactPitch * 0.28, 0.28), 3.25, 0.16],
31237
+ roundRadius: 0.05
31238
+ }
31239
+ ) })
31240
+ },
31241
+ `socket-contact:${index2}`
31242
+ )),
31243
+ ledPins && ledPinPositions.map((x, index2) => /* @__PURE__ */ jsx2(
31244
+ Cylinder,
31245
+ {
31246
+ center: [x, ledPinY, 0.15],
31247
+ radius: signalLeadRadius,
31248
+ height: 3.1
31249
+ },
31250
+ `led-lead:${index2}`
31251
+ ))
31252
+ ] }),
31253
+ ledPins && /* @__PURE__ */ jsxs(Fragment2, { children: [
31254
+ /* @__PURE__ */ jsx2(
31255
+ RoundedCuboid,
31256
+ {
31257
+ color: "#73b744",
31258
+ center: [
31259
+ -bodyWidth / 2 + 2.05,
31260
+ frontY + frontDirection * shellThickness * 0.35,
31261
+ bodyHeight - 2.05
31262
+ ],
31263
+ size: [2.15, shellThickness * 1.55, 1.45],
31264
+ roundRadius: 0.18
31265
+ }
31266
+ ),
31267
+ /* @__PURE__ */ jsx2(
31268
+ RoundedCuboid,
31269
+ {
31270
+ color: "#e0aa35",
31271
+ center: [
31272
+ bodyWidth / 2 - 2.05,
31273
+ frontY + frontDirection * shellThickness * 0.35,
31274
+ bodyHeight - 2.05
31275
+ ],
31276
+ size: [2.15, shellThickness * 1.55, 1.45],
31277
+ roundRadius: 0.18
31278
+ }
31279
+ )
31280
+ ] })
31281
+ ] });
31282
+ };
30394
31283
  var Footprinter3d = ({ footprint }) => {
30395
31284
  let normalizedFootprint = footprint;
30396
31285
  if (footprint.startsWith("jstzh1_5mm")) {
@@ -30399,7 +31288,19 @@ var Footprinter3d = ({ footprint }) => {
30399
31288
  normalizedFootprint = `zh${numPins}`;
30400
31289
  }
30401
31290
  const fpJson = fp.string(normalizedFootprint).json();
31291
+ const colorMatch = footprint.match(/_color\(([^)]+)\)/);
31292
+ const color = colorMatch ? colorMatch[1] : void 0;
30402
31293
  switch (fpJson.fn) {
31294
+ case "crystal":
31295
+ return /* @__PURE__ */ jsx2(
31296
+ Crystal,
31297
+ {
31298
+ horizontalPadPitch: fpJson.px,
31299
+ verticalPadPitch: fpJson.py,
31300
+ padWidth: fpJson.pw,
31301
+ padHeight: fpJson.ph
31302
+ }
31303
+ );
30403
31304
  case "dip":
30404
31305
  return /* @__PURE__ */ jsx2(Dip, { numPins: fpJson.num_pins, pitch: fpJson.p, bodyWidth: fpJson.w });
30405
31306
  case "axial":
@@ -30515,6 +31416,17 @@ var Footprinter3d = ({ footprint }) => {
30515
31416
  }
30516
31417
  );
30517
31418
  }
31419
+ case "smdpinheader":
31420
+ return /* @__PURE__ */ jsx2(
31421
+ SmdPinHeader,
31422
+ {
31423
+ numberOfPins: fpJson.num_pins,
31424
+ pitch: fpJson.p,
31425
+ bodyWidth: fpJson.bh
31426
+ }
31427
+ );
31428
+ case "led5050":
31429
+ return /* @__PURE__ */ jsx2(Led5050, { color });
30518
31430
  case "cap": {
30519
31431
  switch (fpJson.imperial) {
30520
31432
  case "0402":
@@ -30536,6 +31448,7 @@ var Footprinter3d = ({ footprint }) => {
30536
31448
  case "2512":
30537
31449
  return /* @__PURE__ */ jsx2(A2512, { color: "#856c4d" });
30538
31450
  }
31451
+ break;
30539
31452
  }
30540
31453
  case "sot235":
30541
31454
  return /* @__PURE__ */ jsx2(SOT_235_default, {});
@@ -30571,6 +31484,50 @@ var Footprinter3d = ({ footprint }) => {
30571
31484
  return /* @__PURE__ */ jsx2(JSTZH1_5mm, { numPins: fpJson.num_pins });
30572
31485
  }
30573
31486
  break;
31487
+ case "fpc":
31488
+ return /* @__PURE__ */ jsx2(
31489
+ FPC,
31490
+ {
31491
+ pinCount: fpJson.num_pins,
31492
+ pitch: fpJson.p,
31493
+ padWidth: fpJson.pw,
31494
+ padLength: fpJson.pl,
31495
+ staggered: fpJson.staggered,
31496
+ reverse: fpJson.reverse,
31497
+ rowPitch: fpJson.py,
31498
+ topPadLength: fpJson.toppl,
31499
+ bottomPadLength: fpJson.bottompl,
31500
+ mountPadPitchX: fpJson.mpx,
31501
+ mountPadOffsetY: fpJson.mpy,
31502
+ mountTop: fpJson.mounttop,
31503
+ mountPadWidth: fpJson.mpw,
31504
+ mountPadLength: fpJson.mpl
31505
+ }
31506
+ );
31507
+ case "rj45":
31508
+ return /* @__PURE__ */ jsx2(
31509
+ RJ45,
31510
+ {
31511
+ bodyWidth: fpJson.w,
31512
+ bodyDepth: fpJson.h,
31513
+ bodyCenterY: fpJson.bodyy,
31514
+ ledPins: fpJson.ledpins || fpJson.num_pins === 14,
31515
+ firstPinLeft: fpJson.firstpinleft,
31516
+ firstPinTop: fpJson.firstpintop,
31517
+ signalPitch: fpJson.p,
31518
+ signalRowPitch: fpJson.py,
31519
+ signalHoleDiameter: fpJson.id,
31520
+ shieldPinX: fpJson.shieldx,
31521
+ shieldPinY: fpJson.shieldy,
31522
+ shieldHoleDiameter: fpJson.shieldid,
31523
+ locatorHoleX: fpJson.holex,
31524
+ locatorHoleY: fpJson.holey,
31525
+ locatorHoleDiameter: fpJson.holed,
31526
+ ledPinX: fpJson.ledx,
31527
+ ledPinPitch: fpJson.ledp,
31528
+ ledPinY: fpJson.ledy
31529
+ }
31530
+ );
30574
31531
  case "soic":
30575
31532
  return /* @__PURE__ */ jsx2(
30576
31533
  SOIC,
@@ -30596,6 +31553,8 @@ var Footprinter3d = ({ footprint }) => {
30596
31553
  return /* @__PURE__ */ jsx2(SMC, {});
30597
31554
  case "smf":
30598
31555
  return /* @__PURE__ */ jsx2(SMF, {});
31556
+ case "sod123":
31557
+ return /* @__PURE__ */ jsx2(SOD123, {});
30599
31558
  case "sod123f":
30600
31559
  return /* @__PURE__ */ jsx2(SOD123F, {});
30601
31560
  case "sod123fl":
@@ -30693,8 +31652,6 @@ var Footprinter3d = ({ footprint }) => {
30693
31652
  );
30694
31653
  }
30695
31654
  }
30696
- const colorMatch = footprint.match(/_color\(([^)]+)\)/);
30697
- const color = colorMatch ? colorMatch[1] : void 0;
30698
31655
  switch (fpJson.imperial) {
30699
31656
  case "0402":
30700
31657
  return /* @__PURE__ */ jsx2(A0402, { color });
@@ -30715,6 +31672,20 @@ var Footprinter3d = ({ footprint }) => {
30715
31672
  case "2512":
30716
31673
  return /* @__PURE__ */ jsx2(A2512, { color });
30717
31674
  }
31675
+ if ((fpJson.fn === "res" || fpJson.fn === "cap") && fpJson.p !== void 0 && fpJson.ph !== void 0) {
31676
+ const padPitch = mm(fpJson.p);
31677
+ const padHeight = mm(fpJson.ph);
31678
+ if (Number.isFinite(padPitch) && Number.isFinite(padHeight)) {
31679
+ return /* @__PURE__ */ jsx2(
31680
+ ParametricChip,
31681
+ {
31682
+ padPitch,
31683
+ padHeight,
31684
+ color: color ?? (fpJson.fn === "cap" ? "#856c4d" : void 0)
31685
+ }
31686
+ );
31687
+ }
31688
+ }
30718
31689
  return null;
30719
31690
  };
30720
31691
  var isVNode = (n) => n && typeof n === "object" && "type" in n;
@@ -32725,7 +33696,7 @@ import * as THREE23 from "three";
32725
33696
  // package.json
32726
33697
  var package_default = {
32727
33698
  name: "@tscircuit/3d-viewer",
32728
- version: "0.0.590",
33699
+ version: "0.0.591",
32729
33700
  main: "./dist/index.js",
32730
33701
  module: "./dist/index.js",
32731
33702
  type: "module",
@@ -32786,7 +33757,7 @@ var package_default = {
32786
33757
  "bun-match-svg": "^0.0.9",
32787
33758
  "bun-types": "1.2.1",
32788
33759
  debug: "^4.4.0",
32789
- "jscad-electronics": "^0.0.138",
33760
+ "jscad-electronics": "^0.0.146",
32790
33761
  "jscad-planner": "^0.0.13",
32791
33762
  jsdom: "^26.0.0",
32792
33763
  "manifold-3d": "^3.2.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.591",
3
+ "version": "0.0.592",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -61,7 +61,7 @@
61
61
  "bun-match-svg": "^0.0.9",
62
62
  "bun-types": "1.2.1",
63
63
  "debug": "^4.4.0",
64
- "jscad-electronics": "^0.0.138",
64
+ "jscad-electronics": "^0.0.146",
65
65
  "jscad-planner": "^0.0.13",
66
66
  "jsdom": "^26.0.0",
67
67
  "manifold-3d": "^3.2.1",